// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File: GEOMAlgo_Gluer.cxx // Created: Sat Dec 04 12:45:53 2004 // Author: Peter KURNEV // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #include #include #include #include #include #include #include #include #include #include #include #include #include #include // static void GetSubShapes(const TopoDS_Shape& aS, TopTools_IndexedMapOfShape& aMSS); //======================================================================= //function : GEOMAlgo_Gluer //purpose : //======================================================================= GEOMAlgo_Gluer::GEOMAlgo_Gluer() : GEOMAlgo_ShapeAlgo() { myTolerance=0.0001; myTol=myTolerance; myCheckGeometry=Standard_True; myKeepNonSolids=Standard_False; myNbAlone=0; } //======================================================================= //function : ~GEOMAlgo_Gluer //purpose : //======================================================================= GEOMAlgo_Gluer::~GEOMAlgo_Gluer() { } //======================================================================= //function : SetCheckGeometry //purpose : //======================================================================= void GEOMAlgo_Gluer::SetCheckGeometry(const Standard_Boolean aFlag) { myCheckGeometry=aFlag; } //======================================================================= //function : CheckGeometry //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::CheckGeometry() const { return myCheckGeometry; } //======================================================================= //function : SetKeepNonSolids //purpose : //======================================================================= void GEOMAlgo_Gluer::SetKeepNonSolids(const Standard_Boolean aFlag) { myKeepNonSolids=aFlag; } //======================================================================= //function : KeepNonSolids //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::KeepNonSolids()const { return myKeepNonSolids; } //======================================================================= //function : AloneShapes //purpose : //======================================================================= Standard_Integer GEOMAlgo_Gluer::AloneShapes()const { return myNbAlone; } //======================================================================= //function : Images //purpose : //======================================================================= const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer::Images()const { return myImages; } //======================================================================= //function : Origins //purpose : //======================================================================= const TopTools_DataMapOfShapeShape& GEOMAlgo_Gluer::Origins()const { return myOrigins; } //======================================================================= //function : Perform //purpose : //======================================================================= void GEOMAlgo_Gluer::Perform() { const Standard_Integer aNb=8; Standard_Integer i; // myErrorStatus=0; myWarningStatus=0; // // Initialize the context GEOMAlgo_ShapeAlgo::Perform(); // void (GEOMAlgo_Gluer::* pF[aNb])()={ &GEOMAlgo_Gluer::CheckData, &GEOMAlgo_Gluer::InnerTolerance, &GEOMAlgo_Gluer::MakeVertices, &GEOMAlgo_Gluer::MakeEdges, &GEOMAlgo_Gluer::MakeFaces, &GEOMAlgo_Gluer::MakeShells, &GEOMAlgo_Gluer::MakeSolids, &GEOMAlgo_Gluer::CheckResult }; // for (i=0; i*pF[i])(); if (myErrorStatus) { return; } } } //======================================================================= //function : MakeVertices //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeVertices() { myErrorStatus=0; // Standard_Integer j, i, aNbV, aNbVSD; Standard_Real aTolV; gp_Pnt aPV; TColStd_ListIteratorOfListOfInteger aIt; TopoDS_Shape aVF; TopoDS_Vertex aVnew; TopTools_IndexedMapOfShape aMV, aMVProcessed; TopTools_ListIteratorOfListOfShape aItS; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm; TopTools_DataMapOfShapeListOfShape aMVV; GEOMAlgo_IndexedDataMapOfIntegerShape aMIS; //modified by NIZNHY-PKV Thu Jan 21 10:03:07 2010f //GEOMAlgo_IndexedDataMapOfShapeBox aMSB; GEOMAlgo_IndexedDataMapOfShapeBndSphere aMSB; //modified by NIZNHY-PKV Thu Jan 21 10:03:10 2010t // GEOMAlgo_BndSphereTreeSelector aSelector; GEOMAlgo_BndSphereTree aBBTree; NCollection_UBTreeFiller aTreeFiller(aBBTree); // TopExp::MapShapes(myShape, TopAbs_VERTEX, aMV); aNbV=aMV.Extent(); if (!aNbV) { myErrorStatus=2; // no vertices in source shape return; } // for (i=1; i<=aNbV; ++i) { GEOMAlgo_BndSphere aBox; // const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i)); aPV=BRep_Tool::Pnt(aV); aTolV=BRep_Tool::Tolerance(aV); // aBox.SetGap(myTol); aBox.SetCenter(aPV); aBox.SetRadius(aTolV); // aTreeFiller.Add(i, aBox); // aMIS.Add(i, aV); aMSB.Add(aV, aBox); } // aTreeFiller.Fill(); // //------------------------------ // Chains for (i=1; i<=aNbV; ++i) { const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i)); // if (aMVProcessed.Contains(aV)) { continue; } // Standard_Integer aNbIP, aIP, aNbIP1, aIP1; TopTools_ListOfShape aLVSD; TColStd_MapOfInteger aMIP, aMIP1, aMIPC; TColStd_MapIteratorOfMapOfInteger aIt1; // aMIP.Add(i); while(1) { aNbIP=aMIP.Extent(); aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); if (aMIPC.Contains(aIP)) { continue; } // const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); //modified by NIZNHY-PKV Thu Jan 21 10:04:09 2010f const GEOMAlgo_BndSphere& aBoxVP=aMSB.FindFromKey(aVP); //const Bnd_Box& aBoxVP=aMSB.FindFromKey(aVP); //modified by NIZNHY-PKV Thu Jan 21 10:04:11 2010t // aSelector.Clear(); aSelector.SetBox(aBoxVP); // aNbVSD=aBBTree.Select(aSelector); if (!aNbVSD) { continue; // it must not be } // const TColStd_ListOfInteger& aLI=aSelector.Indices(); // aIt.Initialize(aLI); for (; aIt.More(); aIt.Next()) { aIP1=aIt.Value(); if (aMIP.Contains(aIP1)) { continue; } aMIP1.Add(aIP1); } //for (; aIt.More(); aIt.Next()) { }//for(; aIt1.More(); aIt1.Next()) { // aNbIP1=aMIP1.Extent(); if (!aNbIP1) { break; } // aIt1.Initialize(aMIP); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); aMIPC.Add(aIP); } // aMIP.Clear(); aIt1.Initialize(aMIP1); for(; aIt1.More(); aIt1.Next()) { aIP=aIt1.Key(); aMIP.Add(aIP); } aMIP1.Clear(); }// while(1) // // Fill myImages aNbIP=aMIPC.Extent(); // if (!aNbIP) {// no SD vertices founded aVF=aV; aLVSD.Append(aV); aMVProcessed.Add(aV); } else { // SD vertices founded [ aMIPC ] aIt1.Initialize(aMIPC); for(j=0; aIt1.More(); aIt1.Next(), ++j) { aIP=aIt1.Key(); const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP); if (!j) { aVF=aVP; } aLVSD.Append(aVP); aMVProcessed.Add(aVP); } } myImages.Bind(aVF, aLVSD); }// for (i=1; i<=aNbV; ++i) { //------------------------------ // // Make new vertices aMV.Clear(); aItIm.Initialize(myImages); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aItIm.Key()); const TopTools_ListOfShape& aLVSD=aItIm.Value(); aNbVSD=aLVSD.Extent(); if (aNbVSD>1) { aMV.Add(aV); MakeVertex(aLVSD, aVnew); aMVV.Bind(aVnew, aLVSD); } } // // UnBind old vertices aNbV=aMV.Extent(); for (i=1; i<=aNbV; ++i) { const TopoDS_Shape& aV=aMV(i); myImages.UnBind(aV); } // // Bind new vertices aItIm.Initialize(aMVV); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aV=aItIm.Key(); const TopTools_ListOfShape& aLVSD=aItIm.Value(); myImages.Bind(aV, aLVSD); } // // Origins aItIm.Initialize(myImages); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aV=aItIm.Key(); const TopTools_ListOfShape& aLVSD=aItIm.Value(); aItS.Initialize(aLVSD); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aVSD=aItS.Value(); if (!myOrigins.IsBound(aVSD)) { myOrigins.Bind(aVSD, aV); } } } } //======================================================================= //function : MakeSubShapes //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeSubShapes (const TopoDS_Shape& theShape, TopTools_MapOfShape& theMS, TopoDS_Compound& theResult) { if (theMS.Contains(theShape)) return; // BRep_Builder aBB; // theMS.Add(theShape); // if (theShape.ShapeType() == TopAbs_COMPOUND || theShape.ShapeType() == TopAbs_COMPSOLID) { TopoDS_Iterator It (theShape, Standard_True, Standard_True); for (; It.More(); It.Next()) { MakeSubShapes(It.Value(), theMS, theResult); } } else if (theShape.ShapeType() == TopAbs_SOLID) { // build a solid TopoDS_Solid aNewSolid; TopExp_Explorer aExpS, aExp; // const TopoDS_Solid& aSolid = TopoDS::Solid(theShape); // TopAbs_Orientation anOr = aSolid.Orientation(); // aBB.MakeSolid(aNewSolid); aNewSolid.Orientation(anOr); // aExp.Init(aSolid, TopAbs_SHELL); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aShell=aExp.Current(); const TopoDS_Shape& aShellR=myOrigins.Find(aShell); aBB.Add(aNewSolid, aShellR); } // TopTools_ListOfShape aLS; // aLS.Append(aSolid); myImages.Bind(aNewSolid, aLS); myOrigins.Bind(aSolid, aNewSolid); // aBB.Add(theResult, aNewSolid); } else if (theShape.ShapeType() == TopAbs_WIRE) { if (myKeepNonSolids) { // just add image if (!myOrigins.IsBound(theShape)) { // build wire const TopoDS_Wire& aW=TopoDS::Wire(theShape); // TopoDS_Wire newWire; aBB.MakeWire(newWire); // TopExp_Explorer aExpE (aW, TopAbs_EDGE); for (; aExpE.More(); aExpE.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aExpE.Current()); TopoDS_Edge aER=TopoDS::Edge(myOrigins.Find(aE)); // aER.Orientation(TopAbs_FORWARD); if (!BRep_Tool::Degenerated(aER)) { // orient image Standard_Boolean bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); if (bIsToReverse) { aER.Reverse(); } } else { aER.Orientation(aE.Orientation()); } // aBB.Add(newWire, aER); } // xf TopTools_ListOfShape aLW; // aLW.Append(aW); myImages.Bind(newWire, aLW); myOrigins.Bind(aW, newWire); } const TopoDS_Shape& aShapeR = myOrigins.Find(theShape); aBB.Add(theResult, aShapeR); } } else { if (myKeepNonSolids) { // just add image const TopoDS_Shape& aShapeR = myOrigins.Find(theShape); aBB.Add(theResult, aShapeR); } } } //======================================================================= //function : MakeSolids //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeSolids() { myErrorStatus=0; // BRep_Builder aBB; TopoDS_Compound aCmp; TopTools_MapOfShape aMS; // aBB.MakeCompound(aCmp); // // Add images of all initial sub-shapes in the result. // If myKeepNonSolids==false, add only solids images. MakeSubShapes(myShape, aMS, aCmp); // myResult=aCmp; // if (aMS.Extent()) { BOPTools_AlgoTools::CorrectCurveOnSurface(myResult, 0.0001); } } //======================================================================= //function : MakeShells //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeShells() { myErrorStatus=0; // Standard_Boolean bIsToReverse; Standard_Integer i, aNbS; TopAbs_Orientation anOr; TopoDS_Shell aNewShell; TopoDS_Face aFR; TopTools_IndexedMapOfShape aMS; TopExp_Explorer aExp; BRep_Builder aBB; // TopExp::MapShapes(myShape, TopAbs_SHELL, aMS); // aNbS=aMS.Extent(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shell& aShell=TopoDS::Shell(aMS(i)); anOr=aShell.Orientation(); // aBB.MakeShell(aNewShell); aNewShell.Orientation(anOr); aExp.Init(aShell, TopAbs_FACE); for (; aExp.More(); aExp.Next()) { const TopoDS_Face& aF=TopoDS::Face(aExp.Current()); aFR=TopoDS::Face(myOrigins.Find(aF)); if (aFR.IsSame(aF)) { aBB.Add(aNewShell, aF); continue; } bIsToReverse=IsToReverse(aFR, aF); if (bIsToReverse) { aFR.Reverse(); } aBB.Add(aNewShell, aFR); } // TopTools_ListOfShape aLS; // aLS.Append(aShell); myImages.Bind(aNewShell, aLS); myOrigins.Bind(aShell, aNewShell); } } //======================================================================= //function : MakeFaces //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeFaces() { MakeShapes(TopAbs_FACE); } //======================================================================= //function : MakeEdges //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeEdges() { MakeShapes(TopAbs_EDGE); } //======================================================================= //function : MakeShapes //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeShapes(const TopAbs_ShapeEnum aType) { myErrorStatus=0; // Standard_Boolean bHasNewSubShape; Standard_Integer i, aNbF, aNbSDF, iErr; TopoDS_Shape aNewShape; TopTools_IndexedMapOfShape aMF; TopTools_ListIteratorOfListOfShape aItS; GEOMAlgo_PassKeyShape aPKF; GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF; // TopExp::MapShapes(myShape, aType, aMF); // aNbF=aMF.Extent(); for (i=1; i<=aNbF; ++i) { const TopoDS_Shape& aS=aMF(i); // if (aType==TopAbs_FACE) { const TopoDS_Face& aF=TopoDS::Face(aS); FacePassKey(aF, aPKF); } else if (aType==TopAbs_EDGE) { const TopoDS_Edge& aE=TopoDS::Edge(aS); EdgePassKey(aE, aPKF); } // if (myErrorStatus) { return; } // if (aMPKLF.Contains(aPKF)) { TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF); aLSDF.Append(aS); } else { TopTools_ListOfShape aLSDF; // aLSDF.Append(aS); aMPKLF.Add(aPKF, aLSDF); } } // check geometric coincidence if (myCheckGeometry) { iErr=GEOMAlgo_AlgoTools::RefineSDShapes(aMPKLF, myTol, myContext); if (iErr) { myErrorStatus=200; return; } } // // Images/Origins // aNbF=aMPKLF.Extent(); for (i=1; i<=aNbF; ++i) { const TopTools_ListOfShape& aLSDF=aMPKLF(i); aNbSDF=aLSDF.Extent(); if (!aNbSDF) { myErrorStatus=4; // it must not be } // const TopoDS_Shape& aS1=aLSDF.First(); // bHasNewSubShape=Standard_True; // prevent creation of a new shape if there are not // new sub-shapes of aSS among the originals if (aNbSDF==1) { bHasNewSubShape=HasNewSubShape(aS1); if (!bHasNewSubShape) { aNewShape=aS1; aNewShape.Orientation(TopAbs_FORWARD); } } // if (bHasNewSubShape) { if (aType==TopAbs_FACE) { TopoDS_Face aNewFace; // const TopoDS_Face& aF1=TopoDS::Face(aS1); MakeFace(aF1, aNewFace); aNewShape=aNewFace; } else if (aType==TopAbs_EDGE) { TopoDS_Edge aNewEdge; // const TopoDS_Edge& aE1=TopoDS::Edge(aS1); MakeEdge(aE1, aNewEdge); aNewShape=aNewEdge; } } // myImages.Bind(aNewShape, aLSDF); // origins aItS.Initialize(aLSDF); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aFSD=aItS.Value(); if (!myOrigins.IsBound(aFSD)) { myOrigins.Bind(aFSD, aNewShape); } } } } //======================================================================= //function : CheckResult //purpose : //======================================================================= void GEOMAlgo_Gluer::CheckResult() { myErrorStatus=0; // if (myResult.IsNull()) { myErrorStatus=6; return; } // Standard_Boolean bFound; Standard_Integer i, j, aNbS, aNbFS, aNbSx; TopTools_IndexedMapOfShape aMS, aMFS; TopTools_IndexedDataMapOfShapeListOfShape aMFR; // TopExp::MapShapesAndAncestors(myResult, TopAbs_FACE, TopAbs_SOLID, aMFR); TopExp::MapShapes(myResult, TopAbs_SOLID, aMS); // myNbAlone=0; aNbS=aMS.Extent(); for (i=1; i<=aNbS; ++i) { const TopoDS_Shape& aSolid=aMS(i); // aMFS.Clear(); TopExp::MapShapes(aSolid, TopAbs_FACE, aMFS); // bFound=Standard_False; aNbFS=aMFS.Extent(); for (j=1; j<=aNbFS; ++j) { const TopoDS_Shape& aFS=aMFS(j); if (aMFR.Contains(aFS)) { const TopTools_ListOfShape& aLSx=aMFR.FindFromKey(aFS); aNbSx=aLSx.Extent(); if (aNbSx==2) { bFound=!bFound; break; } } } // if (!bFound) { myWarningStatus=1; ++myNbAlone; //break; } } } //======================================================================= //function : CheckData //purpose : //======================================================================= void GEOMAlgo_Gluer::CheckData() { myErrorStatus=0; // if (myShape.IsNull()) { myErrorStatus=5; return; } } //======================================================================= //function : InnerTolerance //purpose : //======================================================================= void GEOMAlgo_Gluer::InnerTolerance() { myErrorStatus=0; // /* Standard_Integer i; Standard_Real aX[3][2], dH, dHmin, aCoef, aTolTresh; Bnd_Box aBox; // BRepBndLib::Add(myShape, aBox); aBox.Get(aX[0][0], aX[1][0], aX[2][0], aX[0][1], aX[1][1], aX[2][1]); // dHmin=aX[0][1]-aX[0][0]; for (i=1; i<3; ++i) { dH=aX[i][1]-aX[i][0]; if (dHaTolTresh) { myTol=aTolTresh; } */ myTol=myTolerance; } //======================================================================= //function : FacePassKey //purpose : //======================================================================= void GEOMAlgo_Gluer::FacePassKey(const TopoDS_Face& aF, GEOMAlgo_PassKeyShape& aPK) { Standard_Integer i, aNbE; TopTools_ListOfShape aLE; TopTools_IndexedMapOfShape aME; // TopExp::MapShapes(aF, TopAbs_EDGE, aME); aNbE=aME.Extent(); // for (i=1; i<=aNbE; ++i) { const TopoDS_Shape& aE=aME(i); if (!myOrigins.IsBound(aE)) { myErrorStatus=102; return; } const TopoDS_Shape& aER=myOrigins.Find(aE); aLE.Append(aER); } aPK.SetShapes(aLE); } //======================================================================= //function : EdgePassKey //purpose : //======================================================================= void GEOMAlgo_Gluer::EdgePassKey(const TopoDS_Edge& aE, GEOMAlgo_PassKeyShape& aPK) { TopoDS_Vertex aV1, aV2; // TopExp::Vertices(aE, aV1, aV2); // if (!myOrigins.IsBound(aV1) || !myOrigins.IsBound(aV2) ) { myErrorStatus=100; return; } const TopoDS_Shape& aVR1=myOrigins.Find(aV1); const TopoDS_Shape& aVR2=myOrigins.Find(aV2); aPK.SetShapes(aVR1, aVR2); } //======================================================================= //function : MakeVertex //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeVertex(const TopTools_ListOfShape& aLV, TopoDS_Vertex& aNewVertex) { Standard_Integer aNbV; Standard_Real aTolV, aD, aDmax; gp_XYZ aGC; gp_Pnt aP3D, aPGC; TopoDS_Vertex aVx; BRep_Builder aBB; TopTools_ListIteratorOfListOfShape aIt; // aNbV=aLV.Extent(); if (!aNbV) { return; } // // center of gravity aGC.SetCoord(0.,0.,0.); aIt.Initialize(aLV); for (; aIt.More(); aIt.Next()) { aVx=TopoDS::Vertex(aIt.Value()); aP3D=BRep_Tool::Pnt(aVx); aGC+=aP3D.XYZ(); } aGC/=(Standard_Real)aNbV; aPGC.SetXYZ(aGC); // // tolerance value aDmax=-1.; aIt.Initialize(aLV); for (; aIt.More(); aIt.Next()) { aVx=TopoDS::Vertex(aIt.Value()); aP3D=BRep_Tool::Pnt(aVx); aTolV=BRep_Tool::Tolerance(aVx); aD=aPGC.Distance(aP3D)+aTolV; if (aD>aDmax) { aDmax=aD; } } // aBB.MakeVertex (aNewVertex, aPGC, aDmax); } //======================================================================= //function : MakeEdge //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeEdge(const TopoDS_Edge& aE, TopoDS_Edge& aNewEdge) { myErrorStatus=0; // Standard_Boolean bIsDE; Standard_Real aT1, aT2; TopoDS_Vertex aV1, aV2, aVR1, aVR2; TopoDS_Edge aEx; // bIsDE=BRep_Tool::Degenerated(aE); // aEx=aE; aEx.Orientation(TopAbs_FORWARD); // TopExp::Vertices(aEx, aV1, aV2); // aT1=BRep_Tool::Parameter(aV1, aEx); aT2=BRep_Tool::Parameter(aV2, aEx); // aVR1=TopoDS::Vertex(myOrigins.Find(aV1)); aVR1.Orientation(TopAbs_FORWARD); aVR2=TopoDS::Vertex(myOrigins.Find(aV2)); aVR2.Orientation(TopAbs_REVERSED); // if (bIsDE) { Standard_Real aTol; BRep_Builder aBB; TopoDS_Edge E; TopAbs_Orientation anOrE; // anOrE=aE.Orientation(); aTol=BRep_Tool::Tolerance(aE); // E=aEx; E.EmptyCopy(); // aBB.Add (E, aVR1); aBB.Add (E, aVR2); aBB.Range(E, aT1, aT2); aBB.Degenerated(E, Standard_True); aBB.UpdateEdge(E, aTol); // aNewEdge=E; } // else { BOPTools_AlgoTools::MakeSplitEdge(aEx, aVR1, aT1, aVR2, aT2, aNewEdge); } } //======================================================================= //function : MakeFace //purpose : //======================================================================= void GEOMAlgo_Gluer::MakeFace(const TopoDS_Face& aF, TopoDS_Face& aNewFace) { myErrorStatus=0; // Standard_Boolean bIsToReverse, bIsUPeriodic; Standard_Real aTol, aUMin, aUMax, aVMin, aVMax; TopoDS_Edge aER; TopoDS_Wire newWire; TopoDS_Face aFFWD, newFace; TopLoc_Location aLoc; Handle(Geom_Surface) aS; Handle(Geom2d_Curve) aC2D; TopExp_Explorer aExpW, aExpE; BRep_Builder aBB; // aFFWD=aF; aFFWD.Orientation(TopAbs_FORWARD); // aS=BRep_Tool::Surface(aFFWD, aLoc); bIsUPeriodic=GEOMAlgo_AlgoTools::IsUPeriodic(aS); aTol=BRep_Tool::Tolerance(aFFWD); BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax); // aBB.MakeFace (newFace, aS, aLoc, aTol); // aExpW.Init(aFFWD, TopAbs_WIRE); for (; aExpW.More(); aExpW.Next()) { aBB.MakeWire(newWire); const TopoDS_Wire& aW=TopoDS::Wire(aExpW.Current()); aExpE.Init(aW, TopAbs_EDGE); for (; aExpE.More(); aExpE.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aExpE.Current()); aER=TopoDS::Edge(myOrigins.Find(aE)); // aER.Orientation(TopAbs_FORWARD); if (!BRep_Tool::Degenerated(aER)) { // build p-curve if (bIsUPeriodic) { GEOMAlgo_AlgoTools::RefinePCurveForEdgeOnFace(aER, aFFWD, aUMin, aUMax); } BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aER, aFFWD); // orient image bIsToReverse=GEOMAlgo_AlgoTools::IsSplitToReverse(aER, aE, myContext); if (bIsToReverse) { aER.Reverse(); } } else { aER.Orientation(aE.Orientation()); } // aBB.Add(newWire, aER); } // xf TopTools_ListOfShape aLW; // aLW.Append(aW); myImages.Bind(newWire, aLW); myOrigins.Bind(aW, newWire); // xt aBB.Add(newFace, newWire); } aNewFace=newFace; } //======================================================================= //function : IsToReverse //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::IsToReverse(const TopoDS_Face& aFR, const TopoDS_Face& aF) { Standard_Boolean bRet; Standard_Real aT, aT1, aT2, aTR, aScPr; TopExp_Explorer aExp; Handle(Geom_Curve)aC3D; gp_Pnt aP; gp_Dir aDNF, aDNFR; // bRet=Standard_False; // aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current()); // if (BRep_Tool::Degenerated(aE)) { continue; } // const TopoDS_Edge& aER=TopoDS::Edge(myOrigins.Find(aE)); // aC3D=BRep_Tool::Curve(aE, aT1, aT2); aT=IntTools_Tools::IntermediatePoint(aT1, aT2); aC3D->D0(aT, aP); myContext->ProjectPointOnEdge(aP, aER, aTR); // BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF); if (aF.Orientation()==TopAbs_REVERSED) { aDNF.Reverse(); } // BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aER, aFR, aTR, aDNFR); if (aFR.Orientation()==TopAbs_REVERSED) { aDNFR.Reverse(); } // aScPr=aDNF*aDNFR; return (aScPr<0.); } return bRet; } //======================================================================= //function : HasNewSubShape //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::HasNewSubShape(const TopoDS_Shape& aS)const { Standard_Boolean bRet; Standard_Integer i, aNbSS; TopTools_IndexedMapOfShape aMSS; // GetSubShapes(aS, aMSS); // bRet=Standard_False; aNbSS=aMSS.Extent(); for (i=1; i<=aNbSS; ++i) { const TopoDS_Shape& aSS=aMSS(i); if (aSS.ShapeType()==TopAbs_WIRE) { continue; } // bRet=!myOrigins.IsBound(aSS); if (bRet) { return bRet; } // const TopoDS_Shape& aSSIm=myOrigins.Find(aSS); bRet=!aSSIm.IsSame(aSS); if (bRet) { return bRet; } } return bRet; } //======================================================================= //function : GetSubShapes //purpose : //======================================================================= void GetSubShapes(const TopoDS_Shape& aS, TopTools_IndexedMapOfShape& aMSS) { Standard_Integer aR; TopAbs_ShapeEnum aType; TopoDS_Iterator aIt; // aType=aS.ShapeType(); aR=(Standard_Integer)aType+1; if (aR>TopAbs_VERTEX) { return; } // aIt.Initialize(aS); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aSS=aIt.Value(); aMSS.Add(aSS); GetSubShapes(aSS, aMSS); } } //======================================================================= //function : Modified //purpose : //======================================================================= const TopTools_ListOfShape& GEOMAlgo_Gluer::Modified (const TopoDS_Shape& aS) { TopAbs_ShapeEnum aType; // myGenerated.Clear(); // aType=aS.ShapeType(); if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE || aType==TopAbs_WIRE || aType==TopAbs_FACE || aType==TopAbs_SHELL || aType==TopAbs_SOLID) { if(myOrigins.IsBound(aS)) { const TopoDS_Shape& aSnew=myOrigins.Find(aS); if (!aSnew.IsSame(aS)) { myGenerated.Append(aSnew); } } } // return myGenerated; } //======================================================================= //function : Generated //purpose : //======================================================================= const TopTools_ListOfShape& GEOMAlgo_Gluer::Generated(const TopoDS_Shape& ) { myGenerated.Clear(); return myGenerated; } //======================================================================= //function : IsDeleted //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Gluer::IsDeleted (const TopoDS_Shape& aS) { Standard_Boolean bRet=Standard_False; // const TopTools_ListOfShape& aL=Modified(aS); bRet=!aL.IsEmpty(); // return bRet; } // // ErrorStatus // // 1 - the object is just initialized // 2 - no vertices found in source shape // 3 - nb same domain vertices for the vertex Vi =0 // 4 - nb same domain edges(faces) for the edge Ei(face Fi) =0 // 5 - source shape is Null // 6 - result shape is Null // 101 - nb edges > PassKey.NbMax() in FacesPassKey() // 102 - the edge Ei can not be found in myOrigins Map // 100 - the vertex Vi can not be found in myOrigins Map // // WarningStatus // // 1 - some shapes can not be glued by faces //