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

459 lines
9.7 KiB
C++
Raw Normal View History

2025-06-25 15:06:42 +08:00
#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;
}