Back to index

salome-geom  6.5.0
GEOMAlgo_WireSplitter.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:        GEOMAlgo_WireSplitter.cxx
00024 // Author:      Peter KURNEV
00025 
00026 #include <GEOMAlgo_WireSplitter.hxx>
00027 
00028 #include <TColStd_SequenceOfReal.hxx>
00029 #include <Precision.hxx>
00030 
00031 #include <gp_Pnt2d.hxx>
00032 #include <gp_Vec2d.hxx>
00033 #include <TColgp_SequenceOfPnt2d.hxx>
00034 
00035 #include <Geom_Curve.hxx>
00036 #include <Geom2d_Curve.hxx>
00037 #include <GeomAdaptor_Surface.hxx>
00038 
00039 #include <TopAbs_Orientation.hxx>
00040 
00041 #include <TopoDS.hxx>
00042 #include <TopoDS_Vertex.hxx>
00043 #include <TopoDS_Edge.hxx>
00044 #include <TopoDS_Face.hxx>
00045 #include <TopoDS_Iterator.hxx>
00046 
00047 #include <BRep_Tool.hxx>
00048 #include <BRepAdaptor_Surface.hxx>
00049 #include <BRepAdaptor_Curve2d.hxx>
00050 
00051 #include <TopExp.hxx>
00052 #include <TopExp_Explorer.hxx>
00053 
00054 #include <TopTools_SequenceOfShape.hxx>
00055 #include <TopTools_ListOfShape.hxx>
00056 #include <TopTools_ListIteratorOfListOfShape.hxx>
00057 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00058 #include <TopTools_IndexedMapOfShape.hxx>
00059 
00060 #include <BOPTColStd_ListOfListOfShape.hxx>
00061 #include <BOPTColStd_ListIteratorOfListOfListOfShape.hxx>
00062 
00063 #include <BOPTools_Tools2D.hxx>
00064 
00065 #include <BOP_EdgeInfo.hxx>
00066 #include <BOP_ListOfEdgeInfo.hxx>
00067 #include <BOP_ListIteratorOfListOfEdgeInfo.hxx>
00068 #include <BOP_IndexedDataMapOfVertexListEdgeInfo.hxx>
00069 
00070 static
00071   void Path (const GeomAdaptor_Surface& aGAS,
00072              const TopoDS_Face& myFace,
00073              const TopoDS_Vertex& aVa,
00074              const TopoDS_Edge& aEOuta,
00075              BOP_EdgeInfo& anEdgeInfo,
00076              TopTools_SequenceOfShape& aLS,
00077              TopTools_SequenceOfShape& aVertVa,
00078              TColgp_SequenceOfPnt2d& aCoordVa,
00079              BOPTColStd_ListOfListOfShape& myShapes,
00080              BOP_IndexedDataMapOfVertexListEdgeInfo& mySmartMap);
00081 
00082 
00083 static
00084   Standard_Real Angle (const gp_Dir2d& aDir2D);
00085 
00086 
00087 static
00088   void GetNextVertex(const TopoDS_Vertex& aV,
00089                      const TopoDS_Edge& aE,
00090                      TopoDS_Vertex& aV1);
00091 static
00092   Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
00093                                const Standard_Real aAngleOut);
00094 
00095 static
00096   Standard_Real AngleIn(const TopoDS_Edge& aEIn,
00097                         const BOP_ListOfEdgeInfo& aLEInfo);
00098 
00099 static
00100   Standard_Real Angle2D (const TopoDS_Vertex& aV,
00101                          const TopoDS_Edge& anEdge,
00102                          const TopoDS_Face& myFace,
00103                          const GeomAdaptor_Surface& aGAS,
00104                          const Standard_Boolean aFlag);
00105 static
00106   gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
00107                     const TopoDS_Edge& aE1,
00108                     const TopoDS_Face& aF);
00109 static
00110   gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
00111                       const TopoDS_Face& aF);
00112 static
00113   Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
00114                             const GeomAdaptor_Surface& aGAS);
00115 
00116 
00117 //modified by NIZNHY-PKV Thu Apr 19 09:04:59 2012f
00118 static
00119   Standard_Integer NbWaysOut(const TopoDS_Edge& aEOuta,
00120                           const BOP_ListOfEdgeInfo& aLEInfo);
00121 //static
00122 //  Standard_Integer NbWaysOut(const BOP_ListOfEdgeInfo& );
00123 //modified by NIZNHY-PKV Thu Apr 19 09:04:53 2012t
00124 
00125 //=======================================================================
00126 // function:
00127 // purpose:
00128 //=======================================================================
00129   GEOMAlgo_WireSplitter::GEOMAlgo_WireSplitter()
00130 :
00131   GEOMAlgo_Algo(),
00132   myNothingToDo(Standard_False)
00133 {
00134 }
00135 //=======================================================================
00136 // function: ~
00137 // purpose:
00138 //=======================================================================
00139   GEOMAlgo_WireSplitter::~GEOMAlgo_WireSplitter()
00140 {
00141 }
00142 //=======================================================================
00143 // function: SetFace
00144 // purpose:
00145 //=======================================================================
00146   void GEOMAlgo_WireSplitter::SetFace(const TopoDS_Face& aFace)
00147 {
00148   myFace=aFace;
00149 }
00150 //=======================================================================
00151 // function: Face
00152 // purpose:
00153 //=======================================================================
00154   const TopoDS_Face& GEOMAlgo_WireSplitter::Face()const
00155 {
00156   return myFace;
00157 }
00158 //=======================================================================
00159 // function: SetEdges
00160 // purpose:
00161 //=======================================================================
00162   void GEOMAlgo_WireSplitter::SetEdges(const TopTools_ListOfShape& aLE)
00163 {
00164   TopTools_ListIteratorOfListOfShape anIt;
00165   //
00166   myEdges.Clear();
00167   anIt.Initialize(aLE);
00168   for (; anIt.More(); anIt.Next()) {
00169     const TopoDS_Shape& aE =anIt.Value();
00170     //
00171     if (aE.Orientation()==TopAbs_INTERNAL){
00172       continue;
00173     }
00174     //
00175     myEdges.Append(aE);
00176   }
00177 }
00178 //=======================================================================
00179 // function: Edges
00180 // purpose:
00181 //=======================================================================
00182   const TopTools_ListOfShape& GEOMAlgo_WireSplitter::Edges()const
00183 {
00184   return myEdges;
00185 }
00186 //=======================================================================
00187 // function: IsNothingToDo
00188 // purpose:
00189 //=======================================================================
00190   Standard_Boolean GEOMAlgo_WireSplitter::IsNothingToDo()const
00191 {
00192   return myNothingToDo;
00193 }
00194 //=======================================================================
00195 // function: Shapes
00196 // purpose:
00197 //=======================================================================
00198   const BOPTColStd_ListOfListOfShape& GEOMAlgo_WireSplitter::Shapes()const
00199 {
00200   return myShapes;
00201 }
00202 //=======================================================================
00203 // function: Perform
00204 // purpose:
00205 //=======================================================================
00206   void GEOMAlgo_WireSplitter::Perform()
00207 {
00208   myErrorStatus=2;
00209   myNothingToDo=Standard_True;
00210 
00211   Standard_Integer index, i, aNb, aCntIn, aCntOut;
00212   Standard_Boolean anIsIn;
00213   Standard_Real anAngle;
00214 
00215   BOP_ListOfEdgeInfo emptyInfo;
00216   TopTools_ListIteratorOfListOfShape anItList;
00217   //
00218   // 1.Filling mySmartMap
00219   mySmartMap.Clear();
00220 
00221   anItList.Initialize(myEdges);
00222   for (; anItList.More(); anItList.Next()) {
00223     const TopoDS_Edge& anEdge = TopoDS::Edge(anItList.Value());
00224     //
00225     if (!BOPTools_Tools2D::HasCurveOnSurface (anEdge, myFace)) {
00226       continue;
00227     }
00228     //
00229     TopExp_Explorer anExpVerts (anEdge, TopAbs_VERTEX);
00230     for (; anExpVerts.More(); anExpVerts.Next()) {
00231       const TopoDS_Shape& aVertex= anExpVerts.Current();
00232 
00233       index = mySmartMap.FindIndex(aVertex);
00234       if (!index) {
00235         index=mySmartMap.Add(aVertex, emptyInfo);
00236       }
00237 
00238       BOP_ListOfEdgeInfo& aListOfEInfo=mySmartMap(index);
00239 
00240       BOP_EdgeInfo aEInfo;
00241       aEInfo.SetEdge(anEdge);
00242 
00243       TopAbs_Orientation anOr=aVertex.Orientation();
00244 
00245       if (anOr==TopAbs_FORWARD) {
00246         aEInfo.SetInFlag(Standard_False);
00247       }
00248 
00249       else if (anOr==TopAbs_REVERSED) {
00250         aEInfo.SetInFlag(Standard_True);
00251       }
00252 
00253       aListOfEInfo.Append(aEInfo);
00254     }
00255   }
00256   //
00257   aNb=mySmartMap.Extent();
00258   //
00259   // 2. myNothingToDo
00260   myNothingToDo=Standard_True;
00261 
00262   for (i=1; i<=aNb; i++) {
00263     aCntIn=0;
00264     aCntOut=0;
00265     const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
00266     BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
00267     for (; anIt.More(); anIt.Next()) {
00268       const BOP_EdgeInfo& anEdgeInfo=anIt.Value();
00269       anIsIn=anEdgeInfo.IsIn();
00270       if (anIsIn) {
00271         aCntIn++;
00272       }
00273       else {
00274         aCntOut++;
00275       }
00276     }
00277     if (aCntIn!=1 || aCntOut!=1) {
00278       myNothingToDo=Standard_False;
00279       break;
00280     }
00281   }
00282   //
00283   // Each vertex has one edge In and one - Out. Good. But it is not enought
00284   // to consider that nothing to do with this. We must check edges on TShape
00285   // coinsidence. If there are such edges there is something to do with.
00286   //
00287   if (myNothingToDo) {
00288     Standard_Integer aNbE, aNbMapEE;
00289     TopTools_IndexedDataMapOfShapeListOfShape aMapEE;
00290     aNbE=myEdges.Extent();
00291 
00292     anItList.Initialize(myEdges);
00293     for (; anItList.More(); anItList.Next()) {
00294       const TopoDS_Shape& aE = anItList.Value();
00295 
00296       if (!aMapEE.Contains(aE)) {
00297         TopTools_ListOfShape aLEx;
00298         aLEx.Append(aE);
00299         aMapEE.Add(aE, aLEx);
00300       }
00301       else {
00302         TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
00303         aLEx.Append(aE);
00304       }
00305     }
00306 
00307     Standard_Boolean bFlag;
00308     bFlag=Standard_True;
00309     aNbMapEE=aMapEE.Extent();
00310     for (i=1; i<=aNbMapEE; i++) {
00311       const TopTools_ListOfShape& aLEx=aMapEE(i);
00312       aNbE=aLEx.Extent();
00313       if (aNbE==1) {
00314         // usual case
00315         continue;
00316       }
00317       else if (aNbE==2){
00318         const TopoDS_Shape& aE1=aLEx.First();
00319         const TopoDS_Shape& aE2=aLEx.Last();
00320         if (aE1.IsSame(aE2)) {
00321           bFlag=Standard_False;
00322           break;
00323         }
00324       }
00325       else {
00326         bFlag=Standard_False;
00327         break;
00328       }
00329     }
00330     myNothingToDo=myNothingToDo && bFlag;
00331   }
00332   //
00333   //
00334   if (myNothingToDo) {
00335     myErrorStatus=0;
00336     return;
00337   }
00338   //
00339   // 3. Angles in mySmartMap
00340   BRepAdaptor_Surface aBAS(myFace);
00341   const GeomAdaptor_Surface& aGAS=aBAS.Surface();
00342   for (i=1; i<=aNb; i++) {
00343     const TopoDS_Vertex& aV=TopoDS::Vertex (mySmartMap.FindKey(i));
00344     const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
00345 
00346     BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
00347     for (; anIt.More(); anIt.Next()) {
00348       BOP_EdgeInfo& anEdgeInfo=anIt.Value();
00349       const TopoDS_Edge& aE=anEdgeInfo.Edge();
00350       //
00351       TopoDS_Vertex aVV=aV;
00352       //
00353       anIsIn=anEdgeInfo.IsIn();
00354       if (anIsIn) {
00355         //
00356         aVV.Orientation(TopAbs_REVERSED);
00357         anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
00358       }
00359       //
00360       else { // OUT
00361         //
00362         aVV.Orientation(TopAbs_FORWARD);
00363         anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
00364       }
00365       anEdgeInfo.SetAngle(anAngle);
00366 
00367     }
00368   }
00369   //
00370   // 4. Do
00371   //
00372   Standard_Boolean anIsOut, anIsNotPassed;
00373 
00374   TopTools_SequenceOfShape aLS, aVertVa;
00375   TColgp_SequenceOfPnt2d aCoordVa;
00376 
00377   BOP_ListIteratorOfListOfEdgeInfo anIt;
00378 
00379   for (i=1; i<=aNb; i++) {
00380     const TopoDS_Vertex aVa=TopoDS::Vertex (mySmartMap.FindKey(i));
00381     const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap(i);
00382 
00383     anIt.Initialize(aLEInfo);
00384     for (; anIt.More(); anIt.Next()) {
00385       BOP_EdgeInfo& anEdgeInfo=anIt.Value();
00386       const TopoDS_Edge& aEOuta=anEdgeInfo.Edge();
00387 
00388       anIsOut=!anEdgeInfo.IsIn();
00389       anIsNotPassed=!anEdgeInfo.Passed();
00390 
00391       if (anIsOut && anIsNotPassed) {
00392         //
00393         aLS.Clear();
00394         aVertVa.Clear();
00395         aCoordVa.Clear();
00396         //
00397         Path(aGAS, myFace, aVa, aEOuta, anEdgeInfo, aLS,
00398              aVertVa, aCoordVa, myShapes, mySmartMap);
00399       }
00400     }
00401   }
00402   //
00403   {
00404     Standard_Integer aNbV, aNbE;
00405     TopoDS_Vertex aV1, aV2;
00406     BOPTColStd_ListOfListOfShape aShapes;
00407     BOPTColStd_ListIteratorOfListOfListOfShape anItW(myShapes);
00408 
00409     for (; anItW.More(); anItW.Next()) {
00410       TopTools_IndexedMapOfShape aMV, aME;
00411       const TopTools_ListOfShape& aLE=anItW.Value();
00412       TopTools_ListIteratorOfListOfShape anItE(aLE);
00413       for (; anItE.More(); anItE.Next()) {
00414         const TopoDS_Edge& aE=TopoDS::Edge(anItE.Value());
00415         aME.Add(aE);
00416         TopExp::Vertices(aE, aV1, aV2);
00417         aMV.Add(aV1);
00418         aMV.Add(aV2);
00419       }
00420       aNbV=aMV.Extent();
00421       aNbE=aME.Extent();
00422       if (aNbV<=aNbE) {
00423         aShapes.Append(aLE);
00424       }
00425     }
00426     //
00427     myShapes.Clear();
00428     anItW.Initialize(aShapes);
00429     for (; anItW.More(); anItW.Next()) {
00430       const TopTools_ListOfShape& aLE=anItW.Value();
00431       myShapes.Append(aLE);
00432     }
00433   }
00434   //
00435   myErrorStatus=0;
00436 }
00437 //=======================================================================
00438 // function: Path
00439 // purpose:
00440 //=======================================================================
00441   void Path (const GeomAdaptor_Surface& aGAS,
00442              const TopoDS_Face& myFace,
00443              const TopoDS_Vertex& aVa,
00444              const TopoDS_Edge& aEOuta,
00445              BOP_EdgeInfo& anEdgeInfo,
00446              TopTools_SequenceOfShape& aLS,
00447              TopTools_SequenceOfShape& aVertVa,
00448              TColgp_SequenceOfPnt2d& aCoordVa,
00449              BOPTColStd_ListOfListOfShape& myShapes,
00450              BOP_IndexedDataMapOfVertexListEdgeInfo& mySmartMap)
00451 {
00452   Standard_Integer i,j, aNb, aNbj, iCnt;
00453   Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle;
00454   Standard_Real aTol2D, aTol2D2;
00455   Standard_Real aTol2, aD2;
00456   Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
00457   BOP_ListIteratorOfListOfEdgeInfo anIt;
00458   TopoDS_Vertex aVb;
00459   TopoDS_Edge aEOutb;
00460   //
00461   aTol=1.e-7;
00462   //
00463   // append block
00464   //
00465   // Do not escape through edge from which you enter
00466   aNb=aLS.Length();
00467   if (aNb==1) {
00468     const TopoDS_Shape& anEPrev=aLS(aNb);
00469     if (anEPrev.IsSame(aEOuta)) {
00470       return;
00471     }
00472   }
00473   //
00474   //
00475   anEdgeInfo.SetPassed(Standard_True);
00476   aLS.Append(aEOuta);
00477   aVertVa.Append(aVa);
00478 
00479   TopoDS_Vertex pVa=aVa;
00480   pVa.Orientation(TopAbs_FORWARD);
00481   gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
00482   aCoordVa.Append(aPa);
00483 
00484   GetNextVertex (pVa, aEOuta, aVb);
00485 
00486   gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
00487   //
00488   aTol=2.*Tolerance2D(aVb, aGAS);
00489   aTol2=10.*aTol*aTol;
00490   //
00491   aNb=aLS.Length();
00492   if (aNb>0) {
00493     //
00494     TopTools_ListOfShape aBuf;
00495     //
00496     for (i=aNb; i>0; i--) {
00497       const TopoDS_Shape& aVPrev=aVertVa(i);
00498       const gp_Pnt2d& aPaPrev=aCoordVa(i);
00499       const TopoDS_Shape& aEPrev=aLS(i);
00500 
00501       aBuf.Append(aEPrev);
00502 
00503       anIsSameV=aVPrev.IsSame(aVb);
00504       anIsSameV2d=Standard_False;
00505 
00506       if (anIsSameV) {
00507         anIsSameV2d = Standard_True;
00508         //
00509         aD2=aPaPrev.SquareDistance(aPb);
00510         anIsSameV2d =aD2<aTol2;
00511       }//if (anIsSameV) {
00512       //
00513       if (anIsSameV && anIsSameV2d) {
00514         myShapes.Append(aBuf);
00515         //
00516         TopTools_SequenceOfShape aLSt, aVertVat;
00517         TColgp_SequenceOfPnt2d aCoordVat;
00518         //
00519         aNbj=i-1;
00520         if (aNbj<1) {
00521           //
00522           aLS.Clear();
00523           aVertVa.Clear();
00524           aCoordVa.Clear();
00525           //
00526           return;
00527         }
00528 
00529         aVb=TopoDS::Vertex(aVertVa(i));
00530 
00531         for (j=1; j<=aNbj; j++) {
00532           aLSt.Append(aLS(j));
00533           aVertVat.Append(aVertVa(j));
00534           aCoordVat.Append(aCoordVa(j));
00535         }
00536         //
00537         aLS.Clear();
00538         aVertVa.Clear();
00539         aCoordVa.Clear();
00540 
00541         aLS=aLSt;
00542         aVertVa=aVertVat;
00543         aCoordVa=aCoordVat;
00544         //
00545         break;
00546       }
00547     }
00548   }
00549   //
00550   aTol2D=2.*Tolerance2D(aVb, aGAS);
00551   aTol2D2=100.*aTol2D*aTol2D;
00552   //
00553   // anAngleIn in Vb from edge aEOuta
00554   const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
00555   //
00556   anAngleIn=AngleIn(aEOuta, aLEInfo);
00557   //
00558   // aEOutb
00559   BOP_EdgeInfo *pEdgeInfo=NULL;
00560 
00561   aMinAngle=100.;
00562   anIsFound=Standard_False;
00563   //
00564   //modified by NIZNHY-PKV Thu Apr 19 09:05:09 2012f
00565   iCnt=NbWaysOut (aEOuta, aLEInfo); 
00566   //iCnt=NbWaysOut (aLEInfo); 
00567   //modified by NIZNHY-PKV Thu Apr 19 09:05:12 2012t
00568   if (!iCnt) { // no way to go . (Error)
00569     return ;
00570   }
00571   //
00572   anIt.Initialize(aLEInfo);
00573   for (; anIt.More(); anIt.Next()) {
00574     BOP_EdgeInfo& anEI=anIt.Value();
00575     const TopoDS_Edge& aE=anEI.Edge();
00576     anIsOut=!anEI.IsIn();
00577     anIsNotPassed=!anEI.Passed();
00578     //
00579     if (anIsOut && anIsNotPassed) {
00580       if (aE.IsSame(aEOuta)) {
00581        continue;
00582       }
00583       //
00584       if (iCnt==1) {
00585         // the one and only way to go out .
00586         pEdgeInfo=&anEI;
00587         anIsFound=Standard_True;
00588         break;
00589       }
00590       //
00591       // Look for minimal angle and make the choice.
00592       gp_Pnt2d aP2Dx;
00593       //
00594       aP2Dx=Coord2dVf(aE, myFace);
00595       //
00596       aD2=aP2Dx.SquareDistance(aPb);
00597       if (aD2 > aTol2D2){
00598         continue;
00599       }
00600       //
00601       anAngleOut=anEI.Angle();
00602       //
00603       anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
00604       if (anAngle < aMinAngle) {
00605         aMinAngle=anAngle;
00606         pEdgeInfo=&anEI;
00607         anIsFound=Standard_True;
00608       }
00609     }
00610   } // for (; anIt.More(); anIt.Next())
00611   //
00612   if (!anIsFound) {
00613     // no way to go . (Error)
00614     return;
00615   }
00616   //
00617   aEOutb=pEdgeInfo->Edge();
00618   //
00619   Path (aGAS, myFace, aVb, aEOutb, *pEdgeInfo, aLS,
00620         aVertVa, aCoordVa, myShapes, mySmartMap);
00621 }
00622 //=======================================================================
00623 // function:  Coord2dVf
00624 // purpose:
00625 //=======================================================================
00626  gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
00627                      const TopoDS_Face& aF)
00628 {
00629   Standard_Real aCoord=99.;
00630   gp_Pnt2d aP2D1(aCoord, aCoord);
00631   TopoDS_Iterator aIt;
00632   //
00633   aIt.Initialize(aE);
00634   for (; aIt.More(); aIt.Next()) {
00635     const TopoDS_Shape& aVx=aIt.Value();
00636     if (aVx.Orientation()==TopAbs_FORWARD) {
00637       const TopoDS_Vertex& aVxx=TopoDS::Vertex(aVx);
00638       aP2D1=Coord2d(aVxx, aE, aF);
00639       return aP2D1;
00640     }
00641   }
00642   return aP2D1;
00643 }
00644 //=======================================================================
00645 // function:  Tolerance2D
00646 // purpose:
00647 //=======================================================================
00648  Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
00649                             const GeomAdaptor_Surface& aGAS)
00650 {
00651   Standard_Real aTol2D, anUr, aVr, aTolV3D;
00652   GeomAbs_SurfaceType aType;
00653   //
00654   aType=aGAS.GetType();
00655   aTolV3D=BRep_Tool::Tolerance(aV);
00656 
00657   anUr=aGAS.UResolution(aTolV3D);
00658   aVr =aGAS.VResolution(aTolV3D);
00659   aTol2D=(aVr>anUr) ? aVr : anUr;
00660   //
00661   if (aType==GeomAbs_BSplineSurface||
00662       aType==GeomAbs_Sphere||
00663       GeomAbs_SurfaceOfRevolution) {
00664     if (aTol2D < aTolV3D) {
00665       aTol2D=aTolV3D;
00666     }
00667   }
00668   if (aType==GeomAbs_BSplineSurface) {
00669     aTol2D=1.1*aTol2D;
00670   }
00671   //
00672   return aTol2D;
00673 }
00674 
00675 //=======================================================================
00676 // function:  Coord2d
00677 // purpose:
00678 //=======================================================================
00679  gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
00680                    const TopoDS_Edge& aE1,
00681                    const TopoDS_Face& aF)
00682 {
00683   Standard_Real aT, aFirst, aLast;
00684   Handle(Geom2d_Curve) aC2D;
00685   gp_Pnt2d aP2D1;
00686   //
00687   aT=BRep_Tool::Parameter (aV1, aE1, aF);
00688   aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
00689   aC2D->D0 (aT, aP2D1);
00690   //
00691   return aP2D1;
00692 }
00693 //=======================================================================
00694 // function:  AngleIn
00695 // purpose:
00696 //=======================================================================
00697  Standard_Real AngleIn(const TopoDS_Edge& aEIn,
00698                        const BOP_ListOfEdgeInfo& aLEInfo)
00699 {
00700   Standard_Real anAngleIn;
00701   Standard_Boolean anIsIn;
00702   BOP_ListIteratorOfListOfEdgeInfo anIt;
00703 
00704   anIt.Initialize(aLEInfo);
00705   for (; anIt.More(); anIt.Next()) {
00706     BOP_EdgeInfo& anEdgeInfo=anIt.Value();
00707     const TopoDS_Edge& aE=anEdgeInfo.Edge();
00708     anIsIn=anEdgeInfo.IsIn();
00709     //
00710     if (anIsIn && aE==aEIn) {
00711       anAngleIn=anEdgeInfo.Angle();
00712       return anAngleIn;
00713     }
00714   }
00715   anAngleIn=0.;
00716   return anAngleIn;
00717 }
00718 //=======================================================================
00719 // function:  ClockWiseAngle
00720 // purpose:
00721 //=======================================================================
00722  Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
00723                               const Standard_Real aAngleOut)
00724 {
00725   Standard_Real aTwoPi = M_PI+M_PI;
00726   Standard_Real dA, A1, A2, AIn, AOut ;
00727 
00728   AIn=aAngleIn;
00729   AOut=aAngleOut;
00730   if (AIn >= aTwoPi) {
00731     AIn=AIn-aTwoPi;
00732   }
00733 
00734   if (AOut >= aTwoPi) {
00735     AOut=AOut-aTwoPi;
00736   }
00737 
00738   A1 = AIn + M_PI;
00739 
00740   if (A1 >= aTwoPi) {
00741     A1=A1-aTwoPi;
00742   }
00743 
00744   A2=AOut;
00745 
00746   dA=A1-A2;
00747   if (dA <= 0.) {
00748     dA=aTwoPi+dA;
00749     if (dA <= 1.e-14) {
00750       dA=aTwoPi;
00751     }
00752   }
00753   //xx
00754   else if (dA <= 1.e-14) {
00755     dA=aTwoPi;
00756   }
00757   return dA;
00758 }
00759 //=======================================================================
00760 // function: GetNextVertex
00761 // purpose:
00762 //=======================================================================
00763  void GetNextVertex(const TopoDS_Vertex& aV,
00764                     const TopoDS_Edge& aE,
00765                     TopoDS_Vertex& aV1)
00766 {
00767   TopoDS_Iterator aIt;
00768   //
00769   aIt.Initialize(aE);
00770   for (; aIt.More(); aIt.Next()) {
00771     const TopoDS_Shape& aVx=aIt.Value();
00772     if (!aVx.IsEqual(aV)) {
00773       aV1=TopoDS::Vertex(aVx);
00774       return ;
00775     }
00776   }
00777   aV1=aV;
00778 }
00779 //=======================================================================
00780 // function: Angle2D
00781 // purpose:
00782 //=======================================================================
00783   Standard_Real Angle2D (const TopoDS_Vertex& aV,
00784                          const TopoDS_Edge& anEdge,
00785                          const TopoDS_Face& myFace,
00786                          const GeomAdaptor_Surface& aGAS,
00787                          const Standard_Boolean aFlag)
00788 {
00789   Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
00790   gp_Pnt2d aPV, aPV1;
00791   gp_Vec2d aV2D;
00792   Handle(Geom2d_Curve) aC2D;
00793   //
00794   aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
00795   if (Precision::IsInfinite(aTV)) {
00796     return 0.;
00797   }
00798   //
00799   BOPTools_Tools2D::CurveOnSurface (anEdge, myFace, aC2D,
00800                                     aFirst, aLast, aToler, Standard_True);
00801   //dt=1.e-7;
00802   dt=2.*Tolerance2D(aV, aGAS);
00803   //
00804   aTX=0.25*(aLast - aFirst);
00805   if(dt > aTX) {
00806     // to save direction of the curve as much as it possible
00807     // in the case of big tolerances
00808     dt = aTX;
00809   }
00810   //
00811   if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
00812     aTV1=aTV + dt;
00813   }
00814   else {
00815     aTV1=aTV - dt;
00816   }
00817   //
00818   aC2D->D0 (aTV, aPV);
00819   aC2D->D0 (aTV1, aPV1);
00820   //
00821   if (aFlag) {//IN
00822     gp_Vec2d aV2DIn(aPV1, aPV);
00823     aV2D=aV2DIn;
00824   }
00825   else {
00826     gp_Vec2d aV2DOut(aPV, aPV1);
00827     aV2D=aV2DOut;
00828   }
00829   //
00830   gp_Dir2d aDir2D(aV2D);
00831   anAngle=Angle(aDir2D);
00832   //
00833   return anAngle;
00834 }
00835 //=======================================================================
00836 // function: Angle
00837 // purpose:
00838 //=======================================================================
00839 Standard_Real Angle (const gp_Dir2d& aDir2D)
00840 {
00841   gp_Dir2d      aRefDir(1., 0.);
00842   Standard_Real anAngle = aRefDir.Angle(aDir2D);
00843 
00844   if (anAngle < 0.)
00845     anAngle += M_PI + M_PI;
00846 
00847   return anAngle;
00848 }
00849 //modified by NIZNHY-PKV Thu Apr 19 09:02:04 2012f
00850 //=======================================================================
00851 // function: NbWaysOut
00852 // purpose:
00853 //=======================================================================
00854 Standard_Integer NbWaysOut(const TopoDS_Edge& aEOuta,
00855                         const BOP_ListOfEdgeInfo& aLEInfo)
00856 {
00857   Standard_Boolean bIsOut, bIsNotPassed;
00858   Standard_Integer iCnt=0;
00859   BOP_ListIteratorOfListOfEdgeInfo anIt;
00860   //
00861   anIt.Initialize(aLEInfo);
00862   for (; anIt.More(); anIt.Next()) {
00863     BOP_EdgeInfo& aEI=anIt.Value();
00864     const TopoDS_Edge& aE=aEI.Edge();
00865     bIsOut=!aEI.IsIn();
00866     bIsNotPassed=!aEI.Passed();
00867     if (bIsOut && bIsNotPassed) {
00868       if (!aE.IsSame(aEOuta)) {
00869        iCnt++;
00870       }
00871     }
00872   }
00873   return iCnt;
00874 }
00875 /*
00876 //=======================================================================
00877 // function: NbWaysOut
00878 // purpose:
00879 //=======================================================================
00880 Standard_Integer NbWaysOut(const BOP_ListOfEdgeInfo& aLEInfo)
00881 {
00882   Standard_Boolean bIsOut, bIsNotPassed;
00883   Standard_Integer iCnt=0;
00884   BOP_ListIteratorOfListOfEdgeInfo anIt;
00885   //
00886   anIt.Initialize(aLEInfo);
00887   for (; anIt.More(); anIt.Next()) {
00888     BOP_EdgeInfo& anEI=anIt.Value();
00889     //
00890     bIsOut=!anEI.IsIn();
00891     bIsNotPassed=!anEI.Passed();
00892     if (bIsOut && bIsNotPassed) {
00893       iCnt++;
00894     }
00895   }
00896   return iCnt;
00897 }
00898 */
00899 //modified by NIZNHY-PKV Thu Apr 19 09:01:57 2012t