#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 faceIn1,faceIn2,faceOut1,faceOut2, faceOn12,faceOn21; // vector onID; // int count = 0; // // vector 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 << "+++++++++++++++++++++++++++++++切船壳:"<solid2, this->solid1, faceIn2, faceOut2,faceOn21); // // finish=clock(); // totaltime=(double)(finish-start)/CLOCKS_PER_SEC; // cout << "+++++++++++++++++++++++++++++++切体:"< 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 << "+++++++++++++++++++++++++++++++清理面("<result = BRepBuilderAPI_MakeSolid(shell).Solid(); // isDone = true; //} TopoDS_Shape SolidBool::SplitShell(TopoDS_Shape& solid1,TopoDS_Shape& solid2, vector& faceIn, vector& faceOut, vector& 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 pntSet; vector 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 shellSet; CutSurfaceAlgo cutSurface(solid1, TopoTemp); cutSurface.TrimSurfaceTranslateInsec(shellSet); vector 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 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; }