459 lines
9.7 KiB
C++
459 lines
9.7 KiB
C++
|
#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;
|
|||
|
}
|