#include "Stdafx.h" #include "OCCCabin_Bool.h" #include "OCCLib.h" #include "SolidBool.h" #include "BRepAlgoAPI_Section.hxx" #include "BRepAlgoAPI_Common.hxx" #include "BRepBuilderAPI_Copy.hxx" #include "BRepBndLib.hxx" #include "OCCCabin.h" // Added BY XUEFENG // 用于计算边对应该边所在面的PCurve #include "ShapeConstruct_ProjectCurveOnSurface.hxx" #include "GeomConvert.hxx" // XUEFENG ADDED 202009 #include "Geom_Surface.hxx" // XUEFENG ADDED 202009 #include "Geom_BSplineSurface.hxx" // XUEFENG ADDED 202009 #include "TopoDS_Shape.hxx" #include // ADDED BY XUEFENG 202012 using namespace std; // ADDED BY XUEFENG 202012 OCCCabin_Bool::OCCCabin_Bool(TopoDS_Shape solid) { this->solid = solid; SetWidth(40); SetHeight(40); SetDir(DIR_X); } OCCCabin_Bool::~OCCCabin_Bool(void) { } void OCCCabin_Bool::SetWidth( double width ) { this->width = width; } void OCCCabin_Bool::SetHeight( double height ) { this->height = height; } void OCCCabin_Bool::SetDir( DIR d ) { this->dir = d; } void OCCCabin_Bool::Perform(Space space) { OCCLib occLib; clock_t start,finish; //typedef long clock_t; double totaltime; start=clock(); //clock():确定处理器当前时间 // XUEFENG ADDED 202012 if(space.numSections>=1) { //this->MultiSectionSurface() int realSections = space.numSections-1; int numPoints = 0; int count = 0; while(space.FCharacterPoints[count]<999.9) { count++; } if(count%2!=0) return; int coupleNum = count/2; if(coupleNum%space.numSections!=0) return; int sectionPointsNum = coupleNum/space.numSections; TopoDS_Shape wholeShape; for(int i=0;i p2dSetFront = ConvertPoint2dSet(frontPoints, width, height); vector p2dSetBack = ConvertPoint2dSet(backpoints, width, height); if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0) { return; } vector pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]); vector pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]); */ // XUEFENG MODIFIED 20210623 vector pSetFront; vector pSetBack; if(sectionPointsNum>2) { for(int j=0; j<2*sectionPointsNum; j++) { frontPoints[j] = space.FCharacterPoints[i*2*sectionPointsNum + j]; backpoints[j] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + j]; } /* // XUEFENG DELETED 20210623 frontPoints[2*sectionPointsNum]= space.FCharacterPoints[i*2*sectionPointsNum + 0]; backpoints[2*sectionPointsNum] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 0]; frontPoints[2*sectionPointsNum+1]= space.FCharacterPoints[i*2*sectionPointsNum + 1]; backpoints[2*sectionPointsNum+1] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + 1]; */ frontPoints[2*sectionPointsNum]=1000; backpoints[2*sectionPointsNum]=1000; vector p2dSetFront = ConvertPoint2dSet(frontPoints, width, height); vector p2dSetBack = ConvertPoint2dSet(backpoints, width, height); if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0) { return; } //vector pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]); //vector pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]); pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]); pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]); // XUEFENG ADDED 20211020 gp_Pnt tmpCycleFPoint = pSetFront[0]; gp_Pnt tmpCycleBPoint = pSetBack[0]; pSetFront.push_back(tmpCycleFPoint); pSetBack.push_back(tmpCycleBPoint); // END ADDED } else if(sectionPointsNum==2) { for(int j=0; j<2*sectionPointsNum; j++) { frontPoints[j] = space.FCharacterPoints[i*2*sectionPointsNum + j]; backpoints[j] = space.FCharacterPoints[(i+1)*2*sectionPointsNum + j]; } frontPoints[2*sectionPointsNum]=1000; backpoints[2*sectionPointsNum]=1000; vector p2dSetFront = ConvertPoint2dSet(frontPoints, width, height); vector p2dSetBack = ConvertPoint2dSet(backpoints, width, height); if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0) { return; } pSetFront = CreatePointSet(p2dSetFront, space.LCharacterPoints[i]); pSetBack = CreatePointSet(p2dSetBack, space.LCharacterPoints[i+1]); } else return; // END MODIFIED TopoDS_Shape sectionShape = this->ConstructComplexBSplineShape(pSetFront, pSetBack); { GProp_GProps massProps; BRepGProp::VolumeProperties(sectionShape, massProps); Standard_Real myVolume = massProps.Mass(); if(myVolume<0) sectionShape.Reverse(); } if(wholeShape.IsNull()==true) wholeShape = sectionShape; else { BRepAlgoAPI_Fuse boolOper(wholeShape,sectionShape); if(boolOper.IsDone()) { wholeShape = boolOper.Shape(); } } } // XUEFENG ADDED 20230509 // FOR DEBUG { GProp_GProps massProps; BRepGProp::VolumeProperties(wholeShape, massProps); Standard_Real myVolume = massProps.Mass(); if(myVolume<0) wholeShape.Reverse(); } result = wholeShape; if(space.HullID==-99999) // FROM 0 { result = wholeShape; return; } //船体 TopoDS_Shape solidHULL = this->solid; //XUEFENG ADDED 20210623 { GProp_GProps massProps; BRepGProp::VolumeProperties(solidHULL, massProps); Standard_Real myVolume = massProps.Mass(); if(myVolume<0) solidHULL.Reverse(); } TopoDS_Shape S; BRepAlgoAPI_Common boolOper(solidHULL,wholeShape); if(boolOper.IsDone()) { S = boolOper.Shape(); result = S; return; } return; } // END ADDED if(space.X1 > space.X2) //尾端面应小于首端面 { return; } //体 TopoDS_Shape solid1 = this->solid; //BRepTools::Write(solid1, "C:\\CCS\\doc\\CabinError\\ComplexHull.brep"); //前后位置面 TopoDS_Face faceFront,faceBack; vector borderFront,borderBack; switch(dir) { case DIR_X: faceFront = occLib.CreatePlane(space.X1, PlaneX, width, height); faceBack = occLib.CreatePlane(space.X2, PlaneX, width, height); borderFront.push_back(gp_Pnt(space.X1, width / 2, height / 2)); borderFront.push_back(gp_Pnt(space.X1, -1 * width / 2, height / 2)); borderFront.push_back(gp_Pnt(space.X1, -1 * width / 2, -1 * height / 2)); borderFront.push_back(gp_Pnt(space.X1, width / 2, -1 * height / 2)); borderFront.push_back(gp_Pnt(space.X1, width / 2, height / 2)); borderBack.push_back(gp_Pnt(space.X2, width / 2, height / 2)); borderBack.push_back(gp_Pnt(space.X2, -1 * width / 2, height / 2)); borderBack.push_back(gp_Pnt(space.X2, -1 * width / 2, -1 * height / 2)); borderBack.push_back(gp_Pnt(space.X2, width / 2, -1 * height / 2)); borderBack.push_back(gp_Pnt(space.X2, width / 2, height / 2)); break; case DIR_Y: faceFront = occLib.CreatePlane(space.X1, PlaneY, width, height); faceBack = occLib.CreatePlane(space.X2, PlaneY, width, height); borderFront.push_back(gp_Pnt( width / 2, space.X1, height / 2)); borderFront.push_back(gp_Pnt(-1 * width / 2, space.X1, height / 2)); borderFront.push_back(gp_Pnt( -1 * width / 2, space.X1, -1 * height / 2)); borderFront.push_back(gp_Pnt( width / 2, space.X1, -1 * height / 2)); borderFront.push_back(gp_Pnt(width / 2, space.X1, height / 2)); borderBack.push_back(gp_Pnt(width / 2, space.X2, height / 2)); borderBack.push_back(gp_Pnt( -1 * width / 2, space.X2, height / 2)); borderBack.push_back(gp_Pnt(-1 * width / 2, space.X2, -1 * height / 2)); borderBack.push_back(gp_Pnt( width / 2, space.X2, -1 * height / 2)); borderBack.push_back(gp_Pnt( width / 2, space.X2, height / 2)); break; case DIR_Z: faceFront = occLib.CreatePlane(space.X1, PlaneZ, width, height); faceBack = occLib.CreatePlane(space.X2, PlaneZ, width, height); borderFront.push_back(gp_Pnt(width / 2, height / 2, space.X1)); borderFront.push_back(gp_Pnt(-1 * width / 2, height / 2, space.X1)); borderFront.push_back(gp_Pnt( -1 * width / 2, -1 * height / 2, space.X1)); borderFront.push_back(gp_Pnt( width / 2, -1 * height / 2, space.X1)); borderFront.push_back(gp_Pnt( width / 2, height / 2, space.X1)); borderBack.push_back(gp_Pnt(width / 2, height / 2, space.X2)); borderBack.push_back(gp_Pnt( -1 * width / 2, height / 2, space.X2)); borderBack.push_back(gp_Pnt(-1 * width / 2, -1 * height / 2, space.X2)); borderBack.push_back(gp_Pnt( width / 2, -1 * height / 2, space.X2)); borderBack.push_back(gp_Pnt(width / 2, height / 2, space.X2)); break; default: return; } //剪切面 TopoDS_Shell splitShell; vector p2dSetFront = ConvertPoint2dSet(space.FCharacterPoints, width, height); vector p2dSetBack = ConvertPoint2dSet(space.LCharacterPoints, width, height); if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0) { return; } vector pSetFront = CreatePointSet(p2dSetFront, space.X1); vector pSetBack = CreatePointSet(p2dSetBack, space.X2); // Added BY XUEFENG 2018.03 // 根据前后断面的特征点,按OCC的拓扑结构要求,构造一个立方体,用该立方体和原船体进行布尔操作 // 根据特征点构造的立方体的前后断面为平面,侧面按B样条曲面进行构造。 TopoDS_Shape trunctShape = this->ConstructComplexBSplineShape(pSetFront, pSetBack); // ADDED BY XUEFENG 202012 if(space.HullID==-99999) // FROM 0 { result = trunctShape; return; } // END ADDED // 求体积 // 体积为负一般意味着体的方向错了,需要进行反向 // Added BY XUEFENG 2018.03 { GProp_GProps massProps; BRepGProp::VolumeProperties(solid1, massProps); Standard_Real myVolume = massProps.Mass(); if(myVolume<0) solid1.Reverse(); } // End Added TopoDS_Shape S; BRepAlgoAPI_Common boolOper(solid1,trunctShape); if(boolOper.IsDone()) { S = boolOper.Shape(); result = S; return; } // // End ADDED int countBorderF = 0, countBorderB = 0; for(int j = 0; j < pSetFront.size(); j++) { gp_Pnt p = pSetFront[j]; bool isborderF = false; for(int i = 0; i < borderFront.size() - 1; i++) { if(p.Distance(borderFront[i]) < Precision::Confusion()) { isborderF = true; break; } } if(isborderF) { countBorderF++; } } for(int j = 0; j < pSetBack.size(); j++) { gp_Pnt p = pSetBack[j]; bool isborderB = false; for(int i = 0; i < borderBack.size() - 1; i++) { if(p.Distance(borderBack[i]) < Precision::Confusion()) { isborderB = true; break; } } if(isborderB) { countBorderB++; } } splitShell = CreateSplitShell(pSetFront, pSetBack); //throw splitShell; //剪切端面 //TopoDS_Face frontFace = CreateEndFace( pSetFront , width, height, space.X1); //TopoDS_Face backFace = CreateEndFace( pSetBack, width, height, space.X2); TopoDS_Face frontFace = CutEndFace(faceFront, splitShell, pSetFront, false);// 生成面的时候 边的方向与输入方向是反的 TopoDS_Face backFace = CutEndFace(faceBack, splitShell, pSetBack, false); //result = backFace; //return; //创建体 vector shapeSet; shapeSet.push_back(splitShell); shapeSet.push_back(frontFace); shapeSet.push_back(backFace); //TopoDS_Compound c; //BRep_Builder b; //b.MakeCompound(c); //b.Add(c,splitShell); //b.Add(c,frontFace); //b.Add(c,backFace); //throw c; int count = 0; for(int i = 0; i < borderFront.size() - 1; i++) { BRepExtrema_DistShapeShape dis(BRepBuilderAPI_MakeVertex(borderFront[i]), frontFace); dis.Perform(); if(dis.Value() < Precision::Confusion()) { count++; } } if(count == 4 && !(countBorderB == pSetBack.size() && countBorderF == pSetFront.size())) { TopoDS_Shell borderShell = CreateSplitShell(borderFront, borderBack); shapeSet.push_back(borderShell); } TopoDS_Shell shell = occLib.SewShell(shapeSet); TopoDS_Solid solid2 = BRepBuilderAPI_MakeSolid(shell).Solid(); if(IsReversed(solid2)) { solid2.Reverse(); } if(IsReversed(solid1)) { solid1.Reverse(); } //throw solid2; //BRepAlgoAPI_Common common(solid1 ,shell); //throw common.Shape(); //BRepAlgoAPI_Section asect(solid1,shell,Standard_False); //asect.ComputePCurveOn1(Standard_True); ////asect.ComputePCurveOn2(Standard_True); //asect.Approximation(Standard_True); //asect.Build(); //throw asect.Shape(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //finish=clock(); //totaltime=(double)(finish-start)/CLOCKS_PER_SEC; //cout << "+++++++++++++++++++++++++++++++准备工作:"< pSetFront,std::vector pSetBack) { // XUEFENG MODIFIED MANY MANY 202012 // This method only choose which way to use // Triangle face use 7.1.0, normal use 6.3.0 bool triangleFace=false; Standard_Real myTol = Precision::Confusion(); int pointNum = pSetFront.size(); for(int i=0;i pSetFront,std::vector pSetBack) // Handle(Geom_BSplineCurve) getBSplineCurveMultiPoints(gp_Pnt points[], int len) // 3个函数 /* * 根据前后断面特征点构造立方体 */ // XUEFENG ADDED 202102 // FOR CONSTRUCT SOLID in OCC 6.3.0 and 7.1.0 WAY // This is a 7.1.0 way! TopoDS_Shape OCCCabin_Bool::ConstructComplexBSplineShape710(std::vector pSetFront,std::vector pSetBack) { // XUEFENG MODIFIED MANY MANY 202012 TopoDS_Solid mySolid; TopoDS_Shell myShell; BRep_Builder myBrepBuilder; Standard_Real myTol = Precision::Confusion(); myBrepBuilder.MakeShell(myShell); myBrepBuilder.MakeSolid(mySolid); std::vector frontVertex, backVertex; std::vector frontBSplineLine, backBSplineLine, sideBSplineLine; std::vector frontBSplineEdge, backBSplineEdge, sideBSplineEdge; int pointNum = pSetFront.size(); for(int i=0;i myTol) frontBSPL = getBSplineCurveMultiPoints(pointsArray, 2); frontBSplineLine.push_back(frontBSPL); } { gp_Pnt pointsArray[2] = { pSetBack[i], pSetBack[next] }; Handle(Geom_BSplineCurve) backBSPL = NULL; if( pSetBack[i].SquareDistance( pSetBack[next]) > myTol) backBSPL = getBSplineCurveMultiPoints(pointsArray, 2); backBSplineLine.push_back(backBSPL); } { gp_Pnt pointsArray[2] = { pSetFront[i], pSetBack[i] }; Handle(Geom_BSplineCurve) sideBSPL = getBSplineCurveMultiPoints(pointsArray, 2); sideBSplineLine.push_back(sideBSPL); } } // Init edges // 构建前、后、侧面的 拓扑拓扑拓扑 边 for(int i=0;i!.IsNull() { myBrepBuilder.MakeEdge(fBSplineEdge, frontCurve, Precision::Confusion()); { TopoDS_Vertex bV = frontVertex[i]; TopoDS_Vertex eV = frontVertex[next]; bV.Orientation(TopAbs_FORWARD); eV.Orientation(TopAbs_REVERSED); myBrepBuilder.Add(fBSplineEdge, bV); myBrepBuilder.Add(fBSplineEdge, eV); BRepTools::Update(fBSplineEdge); } } if(fBSplineEdge.IsNull()) int stop = 10; frontBSplineEdge.push_back(fBSplineEdge); // Back BSpline Edge TopoDS_Edge bBSplineEdge; Handle(Geom_Curve) backCurve = backBSplineLine[i]; if(!backCurve.IsNull()) //pj change !=NULL->!.IsNull() { myBrepBuilder.MakeEdge(bBSplineEdge, backCurve, Precision::Confusion()); { TopoDS_Vertex bV = backVertex[i]; TopoDS_Vertex eV = backVertex[next]; bV.Orientation(TopAbs_FORWARD); eV.Orientation(TopAbs_REVERSED); myBrepBuilder.Add(bBSplineEdge, bV); myBrepBuilder.Add(bBSplineEdge, eV); BRepTools::Update(bBSplineEdge); } } if(bBSplineEdge.IsNull()) int stop = 10; backBSplineEdge.push_back(bBSplineEdge); TopoDS_Edge sBSplineEdge; Handle(Geom_Curve) sideCurve = sideBSplineLine[i]; myBrepBuilder.MakeEdge(sBSplineEdge, sideCurve, Precision::Confusion()); { TopoDS_Vertex bV = frontVertex[i]; TopoDS_Vertex eV = backVertex[i]; bV.Orientation(TopAbs_FORWARD); eV.Orientation(TopAbs_REVERSED); myBrepBuilder.Add(sBSplineEdge, bV); myBrepBuilder.Add(sBSplineEdge, eV); BRepTools::Update(sBSplineEdge); } sideBSplineEdge.push_back(sBSplineEdge); } // XUEFENG ADDED 20201208 // OCC 7.1.0. Simple Way TopoDS_Face frontFace,backFace; std::vector sideFaces; BRepBuilderAPI_Sewing mySewObj(Precision::Confusion()); { // Front and Back face TopoDS_Wire fWire,bWire; myBrepBuilder.MakeWire(fWire); myBrepBuilder.MakeWire(bWire); for(int i=0;i sideWires; for(int i=0;i!.IsNull() ==NULL->.IsNull() aGeomFill.Init( GL2, GL3, GL4, fillType); // XUEFENG MODIFIED 202102 //pj change else if(!GL1.IsNull() && !GL2.IsNull() && GL3.IsNull() && !GL4.IsNull()) //pj change aGeomFill.Init(GL1, GL2, GL4, fillType); else if(GL1.IsNull() && GL3.IsNull()) // XUEFENG MODIFIED 202102 NO face //pj change continue; // XUEFENG MODIFIED 202102 else aGeomFill.Init(GL1, GL2, GL3, GL4, fillType); Handle(Geom_BSplineSurface) aSurf = aGeomFill.Surface(); // XUEFENG ADDED 202009 OCC 7.1.0 TopoDS_Face sBSplineFace = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion()); // XUEFENG ADDED 202009 //backBSplineEdge[i].Reverse(); //sideBSplineEdge[i].Reverse(); //sideWires.push_back(sWire); sideFaces.push_back(sBSplineFace); mySewObj.Add(sBSplineFace); } } } mySewObj.Perform(); TopoDS_Shell mySewShell = TopoDS::Shell(mySewObj.SewedShape()); TopoDS_Solid mySewSolid = BRepBuilderAPI_MakeSolid(mySewShell); // 求体积 // 体积为负一般意味着体的方向错了,需要进行反向 // Added BY XUEFENG 2018.03 { GProp_GProps massProps; BRepGProp::VolumeProperties(mySewSolid, massProps); Standard_Real myVolume = massProps.Mass(); if(myVolume<0) mySewSolid.Reverse(); } // End Added // END ADDED return mySewSolid; } // This is a 6.3.0 Way! TopoDS_Shape OCCCabin_Bool::ConstructComplexBSplineShape630Original(std::vector pSetFront,std::vector pSetBack) { TopoDS_Solid mySolid; TopoDS_Shell myShell; BRep_Builder myBrepBuilder; Standard_Real myTol = Precision::Confusion(); myBrepBuilder.MakeShell(myShell); myBrepBuilder.MakeSolid(mySolid); std::vector frontVertex, backVertex; std::vector frontBSplineLine, backBSplineLine, sideBSplineLine; std::vector frontBSplineEdge, backBSplineEdge, sideBSplineEdge; // XUEFENG ADDED 20211020 /* gp_Pnt tmpCycleFPoint = pSetFront[0]; gp_Pnt tmpCycleBPoint = pSetBack[0]; pSetFront.push_back(tmpCycleFPoint); pSetBack.push_back(tmpCycleBPoint); */ // END ADDED int pointNum = pSetFront.size(); for(int i=0;i sideWires; std::vector sideFaces; for(int i=0;igetPCurve(aSurf, GL1), sBSplineFace, Precision::Confusion()); myBrepBuilder.UpdateEdge(sideBSplineEdge[next], this->getPCurve(aSurf, GL2), sBSplineFace, Precision::Confusion()); myBrepBuilder.UpdateEdge(backBSplineEdge[i], this->getPCurve(aSurf, GL3), sBSplineFace, Precision::Confusion()); myBrepBuilder.UpdateEdge(sideBSplineEdge[i], this->getPCurve(aSurf, GL4), sBSplineFace, Precision::Confusion()); BRepTools::Update(sBSplineFace); } backBSplineEdge[i].Reverse(); sideBSplineEdge[i].Reverse(); sideWires.push_back(sWire); sideFaces.push_back(sBSplineFace); myBrepBuilder.Add(myShell,sBSplineFace); } } } myBrepBuilder.Add(mySolid, myShell); return mySolid; } // END ADDED /* * 采用插值方式通过几个点连成线 * GeomAPI_PointsToBSpline 是拟合方式,误差较大 */ Handle(Geom_BSplineCurve) OCCCabin_Bool::getBSplineCurveMultiPoints(gp_Pnt points[], int len) { /* TColgp_Array1OfPnt SPLPoints(1,len); for(int i=1;i<=len;i++) SPLPoints(i)=points[i-1]; GeomAPI_PointsToBSpline aPointToSPL(SPLPoints); Handle(Geom_BSplineCurve) SPL = aPointToSPL.Curve(); */ Handle(TColgp_HArray1OfPnt) SPLPoints = new TColgp_HArray1OfPnt(1,len); for(int i=1;i<=len;i++) SPLPoints->SetValue(i, points[i-1]); GeomAPI_Interpolate PtB(SPLPoints, Standard_False, 0.0); PtB.Perform(); Handle(Geom_BSplineCurve) SPL; if(PtB.IsDone()) SPL=PtB.Curve(); return SPL; } /** * Get the pcurve from a curve on a surface * 得到一个几何曲线相对于其所在的几何面的参数曲线 */ Handle(Geom2d_Curve) OCCCabin_Bool::getPCurve(Handle(Geom_Surface) surfaceIn, Handle(Geom_Curve) curve3dIn) { Handle(Geom2d_Curve) pcurve = NULL; //try{ // ShapeConstruct_ProjectCurveOnSurface pCurveProjector; // pCurveProjector.Init(surfaceIn, 0.0); // Standard_Boolean success = pCurveProjector.PerformAdvanced(curve3dIn, // curve3dIn->FirstParameter(), // curve3dIn->LastParameter(), // pcurve); //}catch(...){ // Something error. //} return pcurve; } // 添加的3个函数实现部分结束 // BY XUEFENG 2018.03.10 //布尔运算 20170601 by czb,type: 0-并,1-差,2-交 TopoDS_Shape TopoSolidBrepAlgo(int type,TopoDS_Shape& solid1,TopoDS_Shape& solid2) { TopoDS_Shape toposhape; if (solid1.IsNull() || solid2.IsNull()) return toposhape; BaseAlgo algo; if(algo.IsReversed((solid1))) { solid1.Reverse(); } if(algo.IsReversed((solid2))) { solid2.Reverse(); } try { if(type==0)//并 { BRepAlgoAPI_Fuse newfuse(solid1 ,solid2); if (!newfuse.IsDone()) { return toposhape; } else { toposhape=newfuse.Shape(); } } else if(type==1)//差 { BRepAlgoAPI_Cut cut(solid1, solid2); if(!cut.IsDone()) { return toposhape; } toposhape = cut.Shape(); } else if(type==2)//交 { BRepAlgoAPI_Common comm(solid1, solid2); if(!comm.IsDone()) { return toposhape; } toposhape = comm.Shape(); } } catch(...) //20170601 by czb,防止出错后闪退 { toposhape.Nullify(); return toposhape; } return toposhape; } void OCCCabin_Bool::Perform2(Space space) //20170601 by czb { OCCLib occLib; clock_t start,finish; //typedef long clock_t; double totaltime; start=clock(); //clock():确定处理器当前时间 if(space.X1 > space.X2) //尾端面应小于首端面 { return; } //船体 BRepBuilderAPI_Copy cp(this->solid); TopoDS_Shape solid1 = cp.Shape(); //计算并设定船体坐标范围 Bnd_Box B; BRepBndLib::Add(solid1,B); Standard_Real axmin,aymin,azmin,axmax,aymax,azmax; B.Get(axmin,aymin,azmin,axmax,aymax,azmax); hullMinX = axmin - 0.001; hullMaxX = axmax + 0.001; hullMinY = aymin - 0.001; hullMaxY = aymax + 0.001; hullMinZ = azmin - 0.001; hullMaxZ = azmax + 0.001; //前后位置面特征点 vector p2dSetFront = ConvertPoint2dSet2(space.FCharacterPoints, width, height); vector p2dSetBack = ConvertPoint2dSet2(space.LCharacterPoints, width, height); if(p2dSetBack.size() == 0 || p2dSetFront.size() == 0) { return; } vector pSetFront = CreatePointSet(p2dSetFront, max(space.X1,this->hullMinX)); //space.X1); vector pSetBack = CreatePointSet(p2dSetBack, min(space.X2,this->hullMaxX));//space.X2); //参数体 TopoDS_Shell shell; shell = CreateShell(pSetFront, pSetBack); TopoDS_Solid solid2 = BRepBuilderAPI_MakeSolid(shell).Solid(); this->result = solid2; return; //this->result = TopoSolidBrepAlgo(2,solid1,solid2); /*if(IsReversed(solid2)) { solid2.Reverse(); } if(IsReversed(solid1)) { solid1.Reverse(); }*/ BRepAlgoAPI_Common com(solid2, solid1); if(com.IsDone()) { this->result = com.Shape(); } else { TopoDS_Compound c; BRep_Builder b; b.MakeCompound(c); b.Add(c,solid1); b.Add(c,solid2); this->result = c; } } vector OCCCabin_Bool::ConvertPoint2dSet(double* values, double width, double height) { vector pSet, result; double lw = -1 * width / 2; double rw = width / 2; double th = height / 2; double bh = -1 * height / 2+10; //20161107 by yangchen double len = (width + height) / 2; int count = 0; vector indexs; vector boundIndex; vector edgeSet; for(double* val = values; *val < 999.9; val++,count++) { double dy = (*val); double dz = (*(++val)); int y = (int)dy; int z = (int)dz; bool isBound = false; if(y == 777) // Y+,见Statics.convertSpecToDigital { dy = rw; isBound = true; } else if(y == -777) // Y- { dy = lw; isBound = true; } if(z == 888) // Z+ { dz = th; isBound = true; } else if(z == -888) //Z- { dz = bh; isBound = true; } if(abs(y) == 999) // P+ P- { indexs.push_back(count); isBound = true; } pSet.push_back(gp_Pnt2d(dy, dz)); if(isBound) { boundIndex.push_back(count); } } for(int i = 0; i < indexs.size(); i++) { int index = indexs[i]; gp_Pnt2d& p = pSet[index]; gp_Pnt2d temp; if(p.X() > 0) { temp = pSet[(index + 1) % count]; } else { temp = pSet[(index - 1+ count) % count]; } double angle = (p.Y() / 360.0) * 2 * PI; double y = cos(angle) * len + temp.X(); double z = sin(angle) * len + temp.Y(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); if(z > th) { z = th; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } else if(z < bh) { z = bh; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); if(z > th) { z = th; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } else if(z < bh) { z = bh; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } } if(z > th) { z = th; y = 1/ tan(angle) * (z - temp.Y()) + temp.X(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); } } else if(z < bh) { z = bh; y = 1/ tan(angle) * (z - temp.Y()) + temp.X(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); } } p.SetX(y); p.SetY(z); } //所有点必须在框内 for(int i = 0; i < pSet.size(); i++) { if(abs(pSet[i].X())>rw || abs(pSet[i].Y()) > th) { return result; } } //调整顺序 保证特殊点在首尾 pSet = Reorder(pSet, boundIndex); if(boundIndex.size() == 2) { boundIndex.clear(); boundIndex.push_back(0); boundIndex.push_back(pSet.size() - 1); } //调整顺序 if(boundIndex.size() < 2 || pSet.size() == 2) { result = pSet; return result; } //判断是否相交 TopoDS_Edge edge1, edge2; int index,nextInd; if(boundIndex[0] == 0 || (boundIndex[0] + pSet.size() - 1) % pSet.size() == boundIndex[1]) { index = (boundIndex[0] + 1) % pSet.size(); } else { index = (boundIndex[0] + pSet.size() - 1) % pSet.size(); } edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[0]].X(),pSet[boundIndex[0]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y())); if(boundIndex[1] == 0 || (boundIndex[1] + pSet.size() - 1) % pSet.size() == boundIndex[0]) { index = (boundIndex[1] + 1) % pSet.size(); } else { index = (boundIndex[1] + pSet.size() - 1) % pSet.size(); } edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[1]].X(),pSet[boundIndex[1]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y())); BaseAlgo algo; if(!algo.IsParallel(edge1, edge2) && pSet.size() > 3/*三个点时 会出现交点特征点的情况*/) { BRepExtrema_DistShapeShape dis(edge1, edge2); dis.Perform(); if(dis.Value() < Precision::Confusion()) { gp_Pnt p = dis.PointOnShape1(1); gp_Pnt2d p2d(p.Y(), p.Z()); result.push_back(p2d); for(int i = (boundIndex[0] + 1) % pSet.size(); i != boundIndex[1]; i = (i + 1) % pSet.size()) { result.push_back(pSet[i]); } result.push_back(p2d); return result; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// vector boundPoints; gp_Pnt2d p1 = pSet[boundIndex[0]]; gp_Pnt2d p2 = pSet[boundIndex[1]]; gp_Pnt2d pp1 = gp_Pnt2d(rw, th); gp_Pnt2d pp2 = gp_Pnt2d(lw, th); gp_Pnt2d pp3 = gp_Pnt2d(lw, bh); gp_Pnt2d pp4 = gp_Pnt2d(rw, bh); boundPoints.push_back(gp_Pnt2d(rw, th)); if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp2.Distance(p1) > Precision::Confusion()) { if(p1.X() < p.X()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp2.Distance(p2) > Precision::Confusion()) { if(p2.X() < p.X()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(lw, th)); if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp3.Distance(p1) > Precision::Confusion()) { if(p1.Y() < p.Y()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp3.Distance(p2) > Precision::Confusion()) { if(p2.Y() < p.Y()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(lw, bh)); if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp4.Distance(p1) > Precision::Confusion()) { if(p1.X() > p.X()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp4.Distance(p2) > Precision::Confusion()) { if(p2.X() > p.X()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(rw, bh)); if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp1.Distance(p1) > Precision::Confusion()) { if(p1.Y() > p.Y()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp1.Distance(p2) > Precision::Confusion()) { if(p2.Y() > p.Y()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } int index1,index2; for(int i = 0; i < boundPoints.size(); i++) { if(boundPoints[i].Distance(p1) < Precision::Confusion()) { index1 = i; } if(boundPoints[i].Distance(p2) < Precision::Confusion()) { index2 = i; } } // for(int i = boundIndex[0]; i != boundIndex[1]; i = (i + 1) % pSet.size()) { result.push_back(pSet[i]); } for(int i = index2; i != index1; i = (i + 1) % boundPoints.size()) { result.push_back(boundPoints[i]); } result.push_back(p1); // return result; } vector OCCCabin_Bool::ConvertPoint2dSet2(double* values, double width, double height) //20170601 by czb { vector pSet, result; double lw = this->hullMinY; double rw = this->hullMaxY; double th = this->hullMaxZ; double bh = this->hullMinZ; double len = (rw-lw + th-bh); int count = 0; vector indexs; vector boundIndex; vector edgeSet; for(double* val = values; *val < 999.9; val++,count++) { double dy = (*val); double dz = (*(++val)); int y = (int)dy; int z = (int)dz; bool isBound = false; if(y == 777) // Y+,见Statics.convertSpecToDigital { dy = rw; isBound = true; } else if(y == -777) // Y- { dy = lw; isBound = true; } if(z == 888) // Z+ { dz = th; isBound = true; } else if(z == -888) //Z- { dz = bh; isBound = true; } if(abs(y) == 999) // P+ P- { indexs.push_back(count); isBound = true; } pSet.push_back(gp_Pnt2d(dy, dz)); if(isBound) { boundIndex.push_back(count); } } //角度点处理 P for(int i = 0; i < indexs.size(); i++) { int index = indexs[i]; gp_Pnt2d& p = pSet[index]; gp_Pnt2d temp; if(p.X() > 0) { temp = pSet[(index + 1) % count]; } else { temp = pSet[(index - 1+ count) % count]; } double angle = (p.Y() / 360.0) * 2 * PI; double y = cos(angle) * len + temp.X(); double z = sin(angle) * len + temp.Y(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); if(z > th) { z = th; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } else if(z < bh) { z = bh; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); if(z > th) { z = th; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } else if(z < bh) { z = bh; y = 1 / tan(angle) * (z - temp.Y()) + temp.X(); } } if(z > th) { z = th; y = 1/ tan(angle) * (z - temp.Y()) + temp.X(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); } } else if(z < bh) { z = bh; y = 1/ tan(angle) * (z - temp.Y()) + temp.X(); if(y > rw) { y = rw; z = tan(angle) * (y - temp.X()) + temp.Y(); } else if(y < lw) { y = lw; z = tan(angle) * (y - temp.X()) + temp.Y(); } } p.SetX(y); p.SetY(z); } return pSet; /* //所有点必须在框内 for(int i = 0; i < pSet.size(); i++) { if(abs(pSet[i].X())>rw || abs(pSet[i].Y()) > th) { return result; } } //调整顺序 保证特殊点在首尾 pSet = Reorder(pSet, boundIndex); if(boundIndex.size() == 2) { boundIndex.clear(); boundIndex.push_back(0); boundIndex.push_back(pSet.size() - 1); } //调整顺序 if(boundIndex.size() < 2 || pSet.size() == 2) { result = pSet; return result; } //判断是否相交 TopoDS_Edge edge1, edge2; int index,nextInd; if(boundIndex[0] == 0 || (boundIndex[0] + pSet.size() - 1) % pSet.size() == boundIndex[1]) { index = (boundIndex[0] + 1) % pSet.size(); } else { index = (boundIndex[0] + pSet.size() - 1) % pSet.size(); } edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[0]].X(),pSet[boundIndex[0]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y())); if(boundIndex[1] == 0 || (boundIndex[1] + pSet.size() - 1) % pSet.size() == boundIndex[0]) { index = (boundIndex[1] + 1) % pSet.size(); } else { index = (boundIndex[1] + pSet.size() - 1) % pSet.size(); } edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, pSet[boundIndex[1]].X(),pSet[boundIndex[1]].Y()),gp_Pnt(0,pSet[index].X(),pSet[index].Y())); BaseAlgo algo; if(!algo.IsParallel(edge1, edge2) && pSet.size() > 3) //三个点时 会出现交点特征点的情况 { BRepExtrema_DistShapeShape dis(edge1, edge2); dis.Perform(); if(dis.Value() < Precision::Confusion()) { gp_Pnt p = dis.PointOnShape1(1); gp_Pnt2d p2d(p.Y(), p.Z()); result.push_back(p2d); for(int i = (boundIndex[0] + 1) % pSet.size(); i != boundIndex[1]; i = (i + 1) % pSet.size()) { result.push_back(pSet[i]); } result.push_back(p2d); return result; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// vector boundPoints; gp_Pnt2d p1 = pSet[boundIndex[0]]; gp_Pnt2d p2 = pSet[boundIndex[1]]; gp_Pnt2d pp1 = gp_Pnt2d(rw, th); gp_Pnt2d pp2 = gp_Pnt2d(lw, th); gp_Pnt2d pp3 = gp_Pnt2d(lw, bh); gp_Pnt2d pp4 = gp_Pnt2d(rw, bh); boundPoints.push_back(gp_Pnt2d(rw, th)); if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp2.Distance(p1) > Precision::Confusion()) { if(p1.X() < p.X()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp2.Distance(p2) > Precision::Confusion()) { if(p2.X() < p.X()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(lw, th)); if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp3.Distance(p1) > Precision::Confusion()) { if(p1.Y() < p.Y()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp3.Distance(p2) > Precision::Confusion()) { if(p2.Y() < p.Y()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(lw, bh)); if(abs(p1.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp4.Distance(p1) > Precision::Confusion()) { if(p1.X() > p.X()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.Y() - boundPoints.back().Y()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp4.Distance(p2) > Precision::Confusion()) { if(p2.X() > p.X()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } boundPoints.push_back(gp_Pnt2d(rw, bh)); if(abs(p1.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p1) > Precision::Confusion() && pp1.Distance(p1) > Precision::Confusion()) { if(p1.Y() > p.Y()) { boundPoints.push_back(p1); } else { boundPoints.pop_back(); boundPoints.push_back(p1); boundPoints.push_back(p); } } } if(abs(p2.X() - boundPoints.back().X()) < Precision::Confusion()) { gp_Pnt2d p = boundPoints.back(); if(p.Distance(p2) > Precision::Confusion() && pp1.Distance(p2) > Precision::Confusion()) { if(p2.Y() > p.Y()) { boundPoints.push_back(p2); } else { boundPoints.pop_back(); boundPoints.push_back(p2); boundPoints.push_back(p); } } } int index1,index2; for(int i = 0; i < boundPoints.size(); i++) { if(boundPoints[i].Distance(p1) < Precision::Confusion()) { index1 = i; } if(boundPoints[i].Distance(p2) < Precision::Confusion()) { index2 = i; } } // for(int i = boundIndex[0]; i != boundIndex[1]; i = (i + 1) % pSet.size()) { result.push_back(pSet[i]); } for(int i = index2; i != index1; i = (i + 1) % boundPoints.size()) { result.push_back(boundPoints[i]); } result.push_back(p1); // return result;*/ } TopoDS_Shell OCCCabin_Bool::CreateSplitShell(vector pSet1, vector pSet2) { TopoDS_Shell shell; OCCLib occLib; vector shapeSet; BRepOffsetAPI_Sewing sew; if(pSet2.size() != pSet1.size() || pSet1.size() == 0) { return shell; } for(int i = 0; i < pSet1.size() - 1; i++) { int j = (i+1) % pSet1.size(); TopoDS_Face face = occLib.CreateFaceByPoints(pSet1[i], pSet1[j], pSet2[j], pSet2[i]); shapeSet.push_back(face); //sew.Add(face); } //sew.Perform(); //shell = TopoDS::Shell(sew.SewedShape()); shell = occLib.SewShell(shapeSet); //throw shell; return shell; } TopoDS_Shell OCCCabin_Bool::CreateShell(vector pSet1, vector pSet2) { TopoDS_Shell shell; OCCLib occLib; vector shapeSet; BRepOffsetAPI_Sewing sew; if(pSet2.size() != pSet1.size() || pSet1.size() == 0) { return shell; } TopoDS_Face face; face = occLib.CreatePlaneByPoints(pSet1,Standard_True);//首端面方向反向 shapeSet.push_back(face); face = occLib.CreatePlaneByPoints(pSet2); shapeSet.push_back(face); for(int i = 0; i < pSet1.size() - 1; i++) { int j = (i+1) % pSet1.size(); face = occLib.CreateFaceByPoints(pSet1[i], pSet1[j], pSet2[j], pSet2[i]); shapeSet.push_back(face); //sew.Add(face); } //sew.Perform(); //shell = TopoDS::Shell(sew.SewedShape()); shell = occLib.SewShell(shapeSet); //throw shell; return shell; } vector OCCCabin_Bool::CreatePointSet(vector p2dSet, double d) { vector pSet; if(p2dSet.size() == 2) { //pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[0].Y())); //pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[1].Y())); //pSet.push_back(gp_Pnt(d, p2dSet[1].X(), p2dSet[1].Y())); //pSet.push_back(gp_Pnt(d, p2dSet[1].X(), p2dSet[0].Y())); //pSet.push_back(gp_Pnt(d, p2dSet[0].X(), p2dSet[0].Y())); double xmin = p2dSet[0].X() > p2dSet[1].X() ? p2dSet[1].X() : p2dSet[0].X(); double xmax = p2dSet[0].X() > p2dSet[1].X() ? p2dSet[0].X() : p2dSet[1].X(); double ymin = p2dSet[0].Y() > p2dSet[1].Y() ? p2dSet[1].Y() : p2dSet[0].Y(); double ymax = p2dSet[0].Y() > p2dSet[1].Y() ? p2dSet[0].Y() : p2dSet[1].Y(); switch(dir) { case DIR_X: pSet.push_back(gp_Pnt(d, xmax, ymax)); pSet.push_back(gp_Pnt(d, xmin, ymax)); pSet.push_back(gp_Pnt(d, xmin, ymin)); pSet.push_back(gp_Pnt(d, xmax, ymin)); pSet.push_back(gp_Pnt(d, xmax, ymax)); break; case DIR_Y: pSet.push_back(gp_Pnt(xmax, d, ymax)); pSet.push_back(gp_Pnt(xmin, d, ymax)); pSet.push_back(gp_Pnt(xmin, d, ymin)); pSet.push_back(gp_Pnt(xmax, d, ymin)); pSet.push_back(gp_Pnt(xmax, d, ymax)); break; case DIR_Z: pSet.push_back(gp_Pnt(xmax, ymax, d)); pSet.push_back(gp_Pnt(xmin, ymax, d)); pSet.push_back(gp_Pnt(xmin, ymin, d)); pSet.push_back(gp_Pnt(xmax, ymin, d)); pSet.push_back(gp_Pnt(xmax, ymax, d)); break; } } else { for(int i = 0; i < p2dSet.size(); i++) { switch(dir) { case DIR_X: pSet.push_back(gp_Pnt(d, p2dSet[i].X(), p2dSet[i].Y())); break; case DIR_Y: pSet.push_back(gp_Pnt(p2dSet[i].X(), d, p2dSet[i].Y())); break; case DIR_Z: pSet.push_back(gp_Pnt(p2dSet[i].X(), p2dSet[i].Y(), d)); break; } } } return pSet; } TopoDS_Face OCCCabin_Bool::CutEndFace(TopoDS_Face face, TopoDS_Shape shell, vector pSet, bool isLeft) { TopoDS_Face TopoShape; std::vector faceBorder; // 面的边界 for(TopExp_Explorer ex_face(face, TopAbs_EDGE);ex_face.More();ex_face.Next()) { TopoDS_Edge edge = TopoDS::Edge(ex_face.Current()); gp_Pnt p1,p2; GetEdgeStartEndPoint(edge,p1,p2); if(p1.Distance(p2) < Precision::Confusion()) { continue; } faceBorder.push_back(edge); } BRepAlgoAPI_Section asect(face,shell,Standard_False); asect.ComputePCurveOn1(Standard_True); asect.Approximation(Standard_True); asect.Build(); if(!asect.IsDone()) { throw face; } TopoDS_Shape splitResult = asect.Shape(); BRepFeat_SplitShape asplit(face); int count = 0; for (TopExp_Explorer Ex(splitResult,TopAbs_EDGE); Ex.More(); Ex.Next()) { TopoDS_Edge anEdge =TopoDS::Edge(Ex.Current()); gp_Pnt p1,p2; GetEdgeStartEndPoint(anEdge, p1,p2); bool isCoincide = false; for(int i = 0; i < faceBorder.size(); i++) { if(CheckTwoEdgeOverlapByLinePointProject(anEdge,faceBorder[i])) { isCoincide = true; break; } } if(isCoincide) { continue; } //bool isReverse = true; //for(int j = 0; j < pSet.size(); j++) //{ // if(pSet[j].Distance(p1) < Precision::Confusion()) // { // if(pSet[( j + 1) % pSet.size()].Distance(p2) < Precision::Confusion()) // { // isReverse = false; // break; // } // } //} //BaseAlgo algo; //algo.PutPCurve(anEdge, face); //if(isReverse ^ isLeft) //{ // anEdge.Reverse(); //} BaseAlgo algo; algo.PutPCurve(anEdge, face); if(!isLeft) { anEdge.Orientation(TopAbs_REVERSED); } else { anEdge.Orientation(TopAbs_FORWARD); } asplit.Add(anEdge, face); count++; } if(count == 0) { return face; } TopTools_ListIteratorOfListOfShape theList; try { asplit.Build(); } catch (Standard_Failure e) { throw face; } theList = asplit.Left(); for (;theList.More();theList.Next()) { TopoShape = TopoDS::Face(theList.Value()); } return TopoShape; } TopoDS_Shape OCCCabin_Bool::GetResult() { return this->result; } vector OCCCabin_Bool::Reorder( vector pSet, vector index ) { if(index.size() == 0 ) { return pSet; } if(index.size() == 1) //不保存这种情况 { return pSet; } if(index.size() > 2) //不保存这种情况 { return pSet; } int index1 = index[0]; int index2 = index[1]; if(index1 == 0 && index2 == pSet.size() - 1) { return pSet; } if(index2 != (index1+1)%pSet.size()) //不相邻 不保存这种情况 { return pSet; } vector result; for(int i = 0; i < pSet.size(); i++) { result.push_back(pSet[(i + index2)%pSet.size()]); } return result; }