COMPASSi/trunk/code/projects/OCC/OCCLib/SolidBool.cpp

459 lines
9.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Stdafx.h"
#include "SolidBool.h"
#include "CutSurfaceAlgo.h"
#include "BRepClass3d_SolidClassifier.hxx"
#include "OCCLib.h"
//#include "BOPTools_DSFiller.hxx" // XUEFENG DELETE 202009
#include "BOPAlgo_PaveFiller.hxx" // XUEFENG ADDED 202009
#include "BRepAlgoAPI_Cut.hxx"
#include "BRepAlgoAPI_Fuse.hxx"
#include "BRepAlgoAPI_Common.hxx"
SolidBool::SolidBool(void)
{
isDone = false;
isInit = false;
}
SolidBool::SolidBool( TopoDS_Solid solid1, TopoDS_Solid solid2, BoolType type )
{
Init(solid1, solid2, type);
}
SolidBool::~SolidBool(void)
{
}
void SolidBool::Init( TopoDS_Solid solid1, TopoDS_Solid solid2, BoolType type )
{
this->solid1 = solid1;
this->solid2 = solid2;
this->type = type;
isInit = true;
isDone = false;
}
void SolidBool::Perform()
{
//////////////////////////////////////////////////
//
//BOPTools_DSFiller aDF; // XUEFENG DELETE 202009
BOPAlgo_PaveFiller aDF; // XUEFENG ADDED 202009
if(IsReversed(solid1))
{
solid1.Reverse();
}
if(IsReversed(solid2))
{
solid2.Reverse();
}
//aDF.SetShapes (solid1, solid2); // XUEFENG DELETE 202009 6.3.0
// XUEFENG ADDED 202009
// OCC 7.1.0
//BOPCol_ListOfShape aLS; // NOT EXIST IN 7.6.0
TopTools_ListOfShape aLS; // OCC 7.6.0
aLS.Append(solid1);
aLS.Append(solid2);
aDF.SetArguments(aLS);
/* // XUEFENG DELETE 202009 6.3.0
if (!aDF.IsDone())
{
// ... some error handler
return;
}
*/
aDF.Perform();
//BRepAlgoAPI_Section fuse1(solid1 ,solid2, aDF);
//if(!fuse1.IsDone())
//{
// this->result=fuse1.Shape();
// isDone = true;
//}
switch(type)
{
case 0://并
{
BRepAlgoAPI_Fuse fuse(solid1 ,solid2, aDF);
if(!fuse.IsDone())
{
this->result=fuse.Shape();
isDone = true;
}
}
break;
case 1:
{
BRepAlgoAPI_Cut cut(solid1 ,solid2, aDF);
if(!cut.IsDone())
{
this->result=cut.Shape();
isDone = true;
}
}
break;
case 2://交
{
BRepAlgoAPI_Common common(solid1 ,solid2, aDF);
if(common.IsDone())
{
this->result=common.Shape();
isDone = true;
}
}
break;
default:
break;
}
}
//void SolidBool::Perform()
//{
// if(!isInit)
// {
// return;
// }
//
// TopoDS_Shape TopoShape;
// TopoDS_Solid solid1,solid2,solidResult;
// BRep_Builder builder;
// BRepOffsetAPI_Sewing sew;
// vector<TopoDS_Face> faceIn1,faceIn2,faceOut1,faceOut2, faceOn12,faceOn21;
// vector<int> onID;
// int count = 0;
//
// vector<TopoDS_Shape> faceSet;
//
// clock_t start,finish; //typedef long clock_t;
// double totaltime;
// start=clock(); //clock():确定处理器当前时间
//
// SplitShell(this->solid1,this->solid2, faceIn1,faceOut1,faceOn12);
//
// finish=clock();
// totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
// cout << "+++++++++++++++++++++++++++++++切船壳:"<<totaltime<<"s"<<endl;
//
// start=clock(); //clock():确定处理器当前时间
//
// SplitShell(this->solid2, this->solid1, faceIn2, faceOut2,faceOn21);
//
// finish=clock();
// totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
// cout << "+++++++++++++++++++++++++++++++切体:"<<totaltime<<"s"<<endl;
//
//
// builder.MakeSolid(solidResult);
//
// switch(type)
// {
// case 0://并
// for(int i = 0; i < faceOut1.size(); i++)
// {
// faceSet.push_back(faceOut1[i]);
// }
// for(int i = 0; i < faceOut2.size(); i++)
// {
// faceSet.push_back(faceOut2[i]);
// }
// if(faceOut2.size() == 0)
// {
// for(int i = 0; i < faceOn21.size(); i++)
// {
// faceSet.push_back(faceOn21[i]);
// onID.push_back(faceSet.size() - 1);
// }
// }
//
// if(faceOut1.size() == 0)
// {
// for(int i = 0; i < faceOn12.size(); i++)
// {
// faceSet.push_back(faceOn12[i]);
// onID.push_back(faceSet.size() - 1);
// }
// }
//
// break;
// case 1://差
// for(int i = 0; i < faceOut1.size(); i++)
// {
// faceSet.push_back(faceOut1[i]);
// }
// for(int i = 0; i < faceIn2.size(); i++)
// {
// faceSet.push_back(faceIn2[i]);
// }
// if(faceIn2.size() == 0)
// {
// for(int i = 0; i < faceOn21.size(); i++)
// {
// faceSet.push_back(faceOn21[i]);
// onID.push_back(faceSet.size() - 1);
// }
// }
// break;
// case 2://交
// for(int i = 0; i < faceIn1.size(); i++)
// {
// faceSet.push_back(faceIn1[i]);
// }
// for(int i = 0; i < faceIn2.size(); i++)
// {
// faceSet.push_back(faceIn2[i]);
// }
// if(faceOut1.size() ==0 && faceOut2.size() == 0)
// {
// for(int i = 0; i < faceOn21.size(); i++)
// {
// faceSet.push_back(faceOn21[i]);
// onID.push_back(faceSet.size() - 1);
// }
// }
// else if(faceIn1.size() > 0 || faceIn2.size() > 0)
// {
// for(int i = 0; i < faceOn21.size(); i++)
// {
// faceSet.push_back(faceOn21[i]);
// onID.push_back(faceSet.size() - 1);
// }
// }
// break;
// default:
// break;
// }
//
// start=clock();
//
// OCCLib occLib;
// faceSet = SolidSurfaceClear(faceSet, onID);
//
// finish=clock();
// totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
// cout << "+++++++++++++++++++++++++++++++清理面("<<faceSet.size()<<")"<<totaltime<<"s"<<endl;
//
//
// start=clock();
// TopoDS_Shell shell = occLib.SewShell(faceSet);
//
// finish=clock();
// totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
// cout << "+++++++++++++++++++++++++++++++缝合:"<<totaltime<<"s"<<endl;
//
// this->result = BRepBuilderAPI_MakeSolid(shell).Solid();
// isDone = true;
//}
TopoDS_Shape SolidBool::SplitShell(TopoDS_Shape& solid1,TopoDS_Shape& solid2, vector<TopoDS_Face>& faceIn, vector<TopoDS_Face>& faceOut, vector<TopoDS_Face>& faceOn)
{
TopoDS_Shape TopoShape,TopoTemp;
TopoDS_Shell TopoShell;
TopExp_Explorer ex,ex1;
//BRepOffsetAPI_Sewing sew;
BRepClass3d_SolidClassifier solidClassifier(TopoDS::Solid(solid2));
int count = 0;
BRep_Builder b;
b.MakeShell(TopoShell);
double areas = 0.0;
vector<gp_Pnt> pntSet;
vector<double> areaSet;
Bnd_Box shellBox;
static int hhh = 0;
hhh++;
//if(3==hhh)
//{
// throw solid2;
//}
bool isSurf = (solid2.ShapeType() == TopAbs_FACE || solid2.ShapeType() == TopAbs_SHELL);
for(TopExp_Explorer ex(solid2,TopAbs_FACE); ex.More(); ex.Next())
{
TopoDS_Face face = TopoDS::Face(ex.Current());
GProp_GProps System_;
gp_Pnt faceCenter;
BRepGProp::SurfaceProperties(face,System_);
faceCenter = System_.CentreOfMass();
double area = System_.Mass();
pntSet.push_back(faceCenter);
areaSet.push_back(area);
areas += area;
}
gp_Pnt solidCenter(0,0,0);
for(int i = 0; i < pntSet.size(); i++)
{
gp_Pnt g1 = pntSet[i];
solidCenter.SetX(solidCenter.X() + g1.X() * areaSet[i] / areas);
solidCenter.SetY(solidCenter.Y() + g1.Y() * areaSet[i] / areas);
solidCenter.SetZ(solidCenter.Z() + g1.Z() * areaSet[i] / areas);
}
//return TopoTemp;
for(TopExp_Explorer ex(solid2,TopAbs_FACE); ex.More(); ex.Next())
{
b.Add(TopoShell,TopoDS::Face(ex.Current()));
}
//throw TopoShell;
TopoTemp = TopoShell;
TopoShape = TopoTemp;
for(TopExp_Explorer ex(TopoTemp,TopAbs_VERTEX); ex.More(); ex.Next())
{
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(ex.Current()));
shellBox.Add(p);
}
//return TopoTemp;
vector<TopoDS_Shell> shellSet;
CutSurfaceAlgo cutSurface(solid1, TopoTemp);
cutSurface.TrimSurfaceTranslateInsec(shellSet);
vector<TopoDS_Face> faceSet;
for(int i = 0; i < shellSet.size(); i++)
{
TopoDS_Shell shelltmp = shellSet[i];
for(TopExp_Explorer ex(shelltmp, TopAbs_FACE); ex.More(); ex.Next())
{
faceSet.push_back(TopoDS::Face(ex.Current()));
}
}
for(int j = 0; j < faceSet.size(); j++)
{
TopoDS_Face facetmp = faceSet[j];
vector<gp_Pnt> vs,vs_center;
GProp_GProps System;
gp_Pnt faceCenter;
BRepGProp::SurfaceProperties(facetmp,System);
faceCenter = System.CentreOfMass();
for(TopExp_Explorer ex_f(facetmp, TopAbs_EDGE); ex_f.More(); ex_f.Next())
{
TopoDS_Edge edge = TopoDS::Edge(ex_f.Current());
gp_Pnt p1,p2;
GetEdgeStartEndPoint(edge, p1, p2);
vs.push_back(p1);
vs.push_back(p2);
//for(TopExp_Explorer e_t(solid1, TopAbs_EDGE);e_t.More(); e_t.Next())
//{
// TopoDS_Edge edgeTmp = TopoDS::Edge(e_t.Current());
// if(CheckTwoEdgeOverlapByLinePointProject(edgeTmp, edge))
// {
// double dl,df;
// Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df,dl);
// vs_center.push_back(cv->Value((df+dl) / 2));
// break;
// }
//}
//double dl,df;
//Handle(Geom_Curve) cv = BRep_Tool::Curve(edge, df,dl);
//vs_center.push_back(cv->Value((df+dl) / 2));
gp_Pnt p((p1.X() + p2.X()) / 2,(p1.Y() + p2.Y()) / 2,(p1.Z() + p2.Z()) / 2);
BRepExtrema_DistShapeShape inter(BRepBuilderAPI_MakeVertex(p),edge);
inter.Perform();
gp_Pnt center = inter.PointOnShape2(1);
vs_center.push_back(center);
}
bool isOn = true;
bool isIn = false;
int i = 0;
//isIn = !isSurf;
for(i = 0; i < vs.size(); i++)
{
TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(vs[i]);
if(isOn)
{
BRepExtrema_DistShapeShape inter(v,TopoTemp);
inter.Perform();
if(inter.Value() < Precision::Confusion()*100)
{
continue;
}
}
isOn = false;
break;
}
if(isOn)
{
BRepExtrema_DistShapeShape inter(BRepBuilderAPI_MakeVertex(faceCenter).Vertex(),TopoTemp);
inter.Perform();
if(inter.Value() > Precision::Confusion()*100)
{
isOn = false;
//isIn = true;
}
}
if(!isOn)
{
isIn = true;
for(int i = 0; i < vs_center.size(); i++)
{
solidClassifier.Perform(vs_center[i], 1E-5) ;
TopAbs_State state = solidClassifier.State() ;
if(state == TopAbs_IN || state == TopAbs_UNKNOWN)
{
isIn = false;
break;
}
}
}
if(isOn)
{
faceOn.push_back(facetmp);
}
else if(isIn)
{
faceIn.push_back(facetmp);
}
else
{
faceOut.push_back(facetmp);
}
}
return TopoShape;
}
TopoDS_Shape SolidBool::GetResult()
{
TopoDS_Shape shape;
if(isDone)
{
shape = this->result;
}
return shape;
}