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;
|
||
} |