Back to index

salome-geom  6.5.0
NMTTools_Tools.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:        NMTTools_Tools.cxx
00024 // Created:     Mon Dec  8 10:35:15 2003
00025 // Author:      Peter KURNEV
00026 //              <pkv@irinox>
00027 //
00028 #include <NMTTools_Tools.hxx>
00029 
00030 #include <TColStd_IndexedMapOfInteger.hxx>
00031 
00032 #include <gp_Pnt.hxx>
00033 #include <gp_XYZ.hxx>
00034 #include <gp_Pnt2d.hxx>
00035 
00036 #include <Geom_Surface.hxx>
00037 #include <GeomAPI_ProjectPointOnSurf.hxx>
00038 
00039 #include <TopoDS.hxx>
00040 #include <TopoDS_Vertex.hxx>
00041 #include <TopoDS_Shape.hxx>
00042 #include <TopoDS_Edge.hxx>
00043 
00044 #include <TopExp.hxx>
00045 
00046 #include <TopTools_ListIteratorOfListOfShape.hxx>
00047 #include <TopTools_IndexedMapOfShape.hxx>
00048 
00049 #include <BRep_Tool.hxx>
00050 #include <BRep_Builder.hxx>
00051 #include <BRepTools.hxx>
00052 
00053 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
00054 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
00055 
00056 #include <BOPTools_VVInterference.hxx>
00057 #include <BOPTools_SSInterference.hxx>
00058 
00059 #include <BOPTools_Tools2D.hxx>
00060 #include <BOPTools_Tools.hxx>
00061 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
00062 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
00063 #include <NMTTools_CoupleOfShape.hxx>
00064 #include <TopTools_IndexedMapOfShape.hxx>
00065 #include <Geom2d_Curve.hxx>
00066 #include <Geom_Curve.hxx>
00067 #include <Geom_TrimmedCurve.hxx>
00068 #include <BOPTools_Tools2D.hxx>
00069 #include <BRepLib.hxx>
00070 #include <BOPTools_Tools3D.hxx>
00071 #include <TopExp_Explorer.hxx>
00072 //
00073 #include <TopTools_MapOfShape.hxx>
00074 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00075 #include <TopoDS_Iterator.hxx>
00076 
00077 static
00078   void ProcessBlock(const Standard_Integer iV,
00079                     const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
00080                     TColStd_IndexedMapOfInteger& aProcessed,
00081                     TColStd_IndexedMapOfInteger& aChain);
00082 static
00083   void ProcessBlock(const TopoDS_Shape& aF,
00084                     const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
00085                     TopTools_IndexedMapOfShape& aProcessed,
00086                     TopTools_IndexedMapOfShape& aChain);
00087 
00088 //modified by NIZNHY-PKV Thu Nov 16 10:46:53 2006f SKL/PartC5
00089 //=======================================================================
00090 // function: UpdateEdge
00091 // purpose:
00092 //=======================================================================
00093   void  NMTTools_Tools::UpdateEdge(const TopoDS_Edge& aE,
00094                                    const Standard_Real aTolR)
00095 {
00096   Standard_Real aTolE, aTolES, aTolV;
00097   TopoDS_Iterator aIt;
00098   BRep_Builder aBB;
00099   //
00100   aTolE=BRep_Tool::Tolerance(aE);
00101   aTolES=Max(aTolR, aTolE);
00102   aBB.UpdateEdge(aE, aTolES);
00103   //
00104   aIt.Initialize(aE);
00105   for (; aIt.More(); aIt.Next()) {
00106     const TopoDS_Vertex& aV=TopoDS::Vertex(aIt.Value());
00107     aTolV=BRep_Tool::Tolerance(aV);
00108     if (aTolV<aTolES) {
00109        aBB.UpdateVertex(aV, aTolES);
00110     }
00111   }
00112 }
00113 //=======================================================================
00114 // function: MakePCurve
00115 // purpose:
00116 //=======================================================================
00117   void  NMTTools_Tools::MakePCurve(const TopoDS_Edge& aE,
00118                                     const TopoDS_Face& aF,
00119                                     const Handle(Geom2d_Curve)& aC2Dx1)
00120 
00121 {
00122   Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
00123   Handle(Geom2d_Curve) aC2D, aC2DA;
00124   TopoDS_Face aFFWD;
00125   BRep_Builder aBB;
00126   //
00127   aFFWD=aF;
00128   aFFWD.Orientation(TopAbs_FORWARD);
00129   //
00130   aTolE=BRep_Tool::Tolerance(aE);
00131   //
00132   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
00133   Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
00134   //
00135   aC2D=aC2Dx1;
00136   if (aC2D.IsNull()) { // ?
00137     BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
00138     BOPTools_Tools2D::CurveOnSurface(aE, aFFWD, aC2D, aOutFirst, aOutLast, aOutTol, Standard_True);
00139   }
00140   //
00141   if (aC3DE->IsPeriodic()) {
00142     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2,  aC2D, aC2DA);
00143   }
00144   else {
00145     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA);
00146   }
00147   //
00148   aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
00149   BRepLib::SameParameter(aE);
00150 }
00151 /*
00152 //=======================================================================
00153 // function: MakePCurve
00154 // purpose:
00155 //=======================================================================
00156   void  NMTTools_Tools::MakePCurve(const TopoDS_Edge& aE,
00157                                    const TopoDS_Face& aF,
00158                                    const Handle(Geom2d_Curve)& aC2Dx,
00159                                    const Standard_Real aTolR2D)
00160 {
00161   Standard_Integer k, aNbV;
00162   Standard_Real aTolEdge, aTolFact, aTolV, aTolVmax;
00163   Standard_Real aTFirst, aTLast, aOutFirst, aOutLast, aOutTol;
00164   TopoDS_Face aFFWD;
00165   TopTools_IndexedMapOfShape aVMap;
00166   BRep_Builder aBB;
00167   //
00168   aFFWD=aF;
00169   aFFWD.Orientation(TopAbs_FORWARD);
00170   //
00171   aTolEdge=BRep_Tool::Tolerance(aE);
00172   aTolFact=Max(aTolEdge, aTolR2D);
00173   //
00174   TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
00175   //
00176   aTolVmax=-1.;
00177   aNbV=aVMap.Extent();
00178   for (k=1; k<=aNbV; ++k) {
00179     const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
00180     aTolV=BRep_Tool::Tolerance(aV);
00181     if (aTolV>aTolVmax) {
00182       aTolVmax=aTolV;
00183     }
00184   }
00185   //
00186   if (aTolFact>aTolVmax) {
00187     aTolFact=aTolVmax;
00188   }
00189   //
00190   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aTFirst, aTLast);
00191   Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aTFirst, aTLast);
00192   //
00193   Handle(Geom2d_Curve) aC2D, aC2DA;
00194   //
00195   aC2D=aC2Dx;
00196   if (aC2D.IsNull()) {
00197     BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
00198     BOPTools_Tools2D::CurveOnSurface(aE, aFFWD, aC2D, aOutFirst, aOutLast, aOutTol, Standard_True);
00199   }
00200   if (aC3DE->IsPeriodic()) {
00201     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aTFirst, aTLast,  aC2D, aC2DA);
00202   }
00203   else {
00204     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA);
00205   }
00206   //
00207   aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolFact);
00208   BRepLib::SameParameter(aE);
00209 }
00210 */
00211 //modified by NIZNHY-PKV Thu Nov 16 10:46:55 2006t
00212 //=======================================================================
00213 // function: IsSplitInOnFace
00214 // purpose:
00215 //=======================================================================
00216   Standard_Boolean NMTTools_Tools::IsSplitInOnFace(const TopoDS_Edge& aE,
00217                                                    const TopoDS_Face& aF,
00218                                                    const Handle(IntTools_Context)& aContext)
00219 {
00220   Standard_Boolean bFlag;
00221   Standard_Real aT, aTolE, aTolF, aTol, aDist, aU, aV;
00222   gp_Pnt aP;
00223   gp_Pnt2d aP2D;
00224   //
00225   aTolE=BRep_Tool::Tolerance(aE);
00226   aTolF=BRep_Tool::Tolerance(aF);
00227   aTol=aTolE+aTolF;
00228   //
00229   GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
00230   //
00231   aT=BOPTools_Tools2D::IntermediatePoint(aE);
00232   BOPTools_Tools::PointOnEdge(aE, aT, aP);
00233   //
00234   aProjector.Perform(aP);
00235   bFlag=aProjector.IsDone();
00236   if (!bFlag) {
00237     return bFlag;
00238   }
00239   //
00240   aDist=aProjector.LowerDistance();
00241   bFlag=(aDist <= aTol);
00242   if (!bFlag) {
00243     return bFlag;
00244   }
00245   //
00246   aProjector.LowerDistanceParameters(aU, aV);
00247   aP2D.SetCoord(aU, aV);
00248   bFlag=aContext->IsPointInOnFace (aF, aP2D);
00249   return bFlag;
00250 }
00251 //=======================================================================
00252 // function: NMTTools_Tools::MakeNewVertex
00253 // purpose :
00254 //=======================================================================
00255   void NMTTools_Tools::MakeNewVertex(const TopTools_ListOfShape& aLVs,
00256                                      TopoDS_Vertex& aNewVertex)
00257 {
00258   Standard_Integer aNb;
00259   Standard_Real aTi, aDi, aDmax=-1.e5;
00260   gp_Pnt aPi, aP;
00261   gp_XYZ aXYZ(0.,0.,0.), aXYZi;
00262   TopTools_ListIteratorOfListOfShape anIt;
00263   //
00264   aNb=aLVs.Extent();
00265   if (!aNb) {
00266     return;
00267   }
00268   //
00269   anIt.Initialize(aLVs);
00270   for (; anIt.More(); anIt.Next()) {
00271     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
00272     aPi=BRep_Tool::Pnt(aVi);
00273     aXYZi=aPi.XYZ();
00274     aXYZ=aXYZ+aXYZi;
00275   }
00276   //
00277   aXYZ.Divide((Standard_Real)aNb);
00278   aP.SetXYZ(aXYZ);
00279   //
00280   anIt.Initialize(aLVs);
00281   for (; anIt.More(); anIt.Next()) {
00282     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
00283     aPi=BRep_Tool::Pnt(aVi);
00284     aTi=BRep_Tool::Tolerance(aVi);
00285     aDi=aP.Distance(aPi);
00286     aDi=aDi+aTi;
00287     if (aDi > aDmax) {
00288       aDmax=aDi;
00289     }
00290   }
00291   BRep_Builder aBB;
00292   aBB.MakeVertex (aNewVertex, aP, aDmax);
00293 }
00294 //=======================================================================
00295 // function: FindChains
00296 // purpose :
00297 //=======================================================================
00298   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfSSInterference& FFs,
00299                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
00300 {
00301   Standard_Boolean bIsTangentFaces;
00302   Standard_Integer j, aNb, anIndex1, anIndex2;
00303   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
00304   //
00305   aNb=FFs.Extent();
00306   for (j=1; j<=aNb; ++j) {
00307     const BOPTools_SSInterference& aFF=FFs(j);
00308     //
00309     bIsTangentFaces=aFF.IsTangentFaces();
00310     if (!bIsTangentFaces) {
00311       continue;
00312     }
00313     //
00314     aFF.Indices(anIndex1, anIndex2);
00315     //
00316     if (aMCV.Contains(anIndex1)) {
00317       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
00318       aMV.Add(anIndex1);
00319       aMV.Add(anIndex2);
00320     }
00321     else {
00322       TColStd_IndexedMapOfInteger aMV;
00323       aMV.Add(anIndex1);
00324       aMV.Add(anIndex2);
00325       aMCV.Add(anIndex1, aMV);
00326     }
00327     //
00328     if (aMCV.Contains(anIndex2)) {
00329       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
00330       aMV.Add(anIndex1);
00331       aMV.Add(anIndex2);
00332     }
00333     else {
00334       TColStd_IndexedMapOfInteger aMV;
00335       aMV.Add(anIndex1);
00336       aMV.Add(anIndex2);
00337       aMCV.Add(anIndex2, aMV);
00338     }
00339   }
00340   NMTTools_Tools::FindChains(aMCV, aMapChains);
00341 }
00342 //=======================================================================
00343 // function: FindChains
00344 // purpose :
00345 //=======================================================================
00346   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfVVInterference& VVs,
00347                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
00348 {
00349   Standard_Integer j, aNb, anIndex1, anIndex2;
00350   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
00351   //
00352   aNb=VVs.Extent();
00353   for (j=1; j<=aNb; ++j) {
00354     const BOPTools_VVInterference& VV=VVs(j);
00355     VV.Indices(anIndex1, anIndex2);
00356     //
00357     if (aMCV.Contains(anIndex1)) {
00358       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
00359       aMV.Add(anIndex1);
00360       aMV.Add(anIndex2);
00361     }
00362     else {
00363       TColStd_IndexedMapOfInteger aMV;
00364       aMV.Add(anIndex1);
00365       aMV.Add(anIndex2);
00366       aMCV.Add(anIndex1, aMV);
00367     }
00368     //
00369     if (aMCV.Contains(anIndex2)) {
00370       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
00371       aMV.Add(anIndex1);
00372       aMV.Add(anIndex2);
00373     }
00374     else {
00375       TColStd_IndexedMapOfInteger aMV;
00376       aMV.Add(anIndex1);
00377       aMV.Add(anIndex2);
00378       aMCV.Add(anIndex2, aMV);
00379     }
00380   }
00381   NMTTools_Tools::FindChains(aMCV, aMapChains);
00382 }
00383 
00384 //=======================================================================
00385 // function: FindChains
00386 // purpose :
00387 //=======================================================================
00388   void NMTTools_Tools::FindChains(const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
00389                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
00390 {
00391   Standard_Integer  i, j, aNbCV, aNbV, iV, iVx;
00392   TColStd_IndexedMapOfInteger aProcessed, aChain;
00393   //
00394   aNbCV=aMCV.Extent();
00395   for (i=1; i<=aNbCV; ++i) {
00396     iV=aMCV.FindKey(i);
00397     if (aProcessed.Contains(iV)) {
00398       continue;
00399     }
00400     //
00401     aProcessed.Add(iV);
00402     aChain.Add(iV);
00403     //
00404     const TColStd_IndexedMapOfInteger& aMV=aMCV(i);
00405     aNbV=aMV.Extent();
00406     for (j=1; j<=aNbV; ++j) {
00407       iVx=aMV(j);
00408       ProcessBlock(iVx, aMCV, aProcessed, aChain);
00409     }
00410     aMapChains.Add(i, aChain);
00411     aChain.Clear();
00412   }
00413 }
00414 //=======================================================================
00415 // function: ProcessBlock
00416 // purpose:
00417 //=======================================================================
00418 void ProcessBlock(const Standard_Integer iV,
00419                   const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
00420                   TColStd_IndexedMapOfInteger& aProcessed,
00421                   TColStd_IndexedMapOfInteger& aChain)
00422 {
00423   Standard_Integer j, aNbV, iVx;
00424   //
00425   if (aProcessed.Contains(iV)) {
00426     return;
00427   }
00428   aProcessed.Add(iV);
00429   aChain.Add(iV);
00430   //
00431   const TColStd_IndexedMapOfInteger& aMV=aMCV.FindFromKey(iV);
00432   aNbV=aMV.Extent();
00433   for (j=1; j<=aNbV; ++j) {
00434     iVx=aMV(j);
00435     ProcessBlock(iVx, aMCV, aProcessed, aChain);
00436   }
00437 }
00438 //=======================================================================
00439 // function: AreFacesSameDomain
00440 // purpose :
00441 //=======================================================================
00442   Standard_Boolean NMTTools_Tools::AreFacesSameDomain(const TopoDS_Face& aF1x,
00443                                                       const TopoDS_Face& aF2y,
00444                                                       const Handle(IntTools_Context)& aCtx)
00445 {
00446   Standard_Boolean bFlag;
00447   // Modified  Thu Sep 14 14:35:18 2006
00448   // Contribution of Samtech www.samcef.com BEGIN
00449   Standard_Integer aNbE1, aNbE2;
00450   Standard_Real aTolF1, aTolF2, aTol;
00451   gp_Pnt2d aP2D;
00452   gp_Pnt aP;
00453   TopoDS_Face aF1, aF2;
00454   TopExp_Explorer aExp;
00455   TopTools_MapOfShape aME1, aME2;
00456   TopTools_MapIteratorOfMapOfShape aIt;
00457   //
00458   bFlag=Standard_False;
00459   // Contribution of Samtech www.samcef.com END
00460   //
00461   aF1=aF1x;
00462   aF1.Orientation(TopAbs_FORWARD);
00463   aF2=aF2y;
00464   aF2.Orientation(TopAbs_FORWARD);
00465   //
00466   // Modified  Thu Sep 14 14:35:18 2006
00467   // Contribution of Samtech www.samcef.com BEGIN
00468   //
00469   // 1
00470   aExp.Init(aF1, TopAbs_EDGE);
00471   for (; aExp.More(); aExp.Next()) {
00472     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
00473     if (!BRep_Tool::Degenerated(aE)) {
00474       aME1.Add(aE);
00475     }
00476   }
00477   //
00478   aExp.Init(aF2, TopAbs_EDGE);
00479   for (; aExp.More(); aExp.Next()) {
00480     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
00481     if (!BRep_Tool::Degenerated(aE)) {
00482       if (!aME1.Contains(aE)) {
00483         return bFlag;
00484       }
00485       aME2.Add(aE);
00486     }
00487   }
00488   //
00489   // Contribution of Samtech www.samcef.com END
00490   //
00491   aNbE1=aME1.Extent();
00492   aNbE2=aME2.Extent();
00493   //
00494   if(!aNbE1 || !aNbE2){
00495     return bFlag;
00496   }
00497   //
00498   if(aNbE1!=aNbE2) {
00499     return bFlag;
00500   }
00501   //
00502   // 2
00503   aTolF1=BRep_Tool::Tolerance(aF1);
00504   aTolF2=BRep_Tool::Tolerance(aF2);
00505   aTol=aTolF1+aTolF2;
00506   //
00507   aIt.Initialize(aME1);
00508   for (; aIt.More(); aIt.Next()) {
00509     const TopoDS_Edge& aE=TopoDS::Edge(aIt.Key());
00510     BOPTools_Tools3D::PointNearEdge(aE, aF1, aP2D, aP);
00511     bFlag=aCtx->IsValidPointForFace(aP, aF2, aTol);
00512     break;
00513   }
00514   //
00515   return bFlag;
00516 }
00517 //=======================================================================
00518 // function: FindChains
00519 // purpose :
00520 //=======================================================================
00521   void NMTTools_Tools::FindChains(const NMTTools_ListOfCoupleOfShape& aLCS,
00522                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
00523 {
00524   NMTTools_ListIteratorOfListOfCoupleOfShape aItCS;
00525   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMCV;
00526   //
00527   aItCS.Initialize(aLCS);
00528   for (; aItCS.More(); aItCS.Next()) {
00529     const NMTTools_CoupleOfShape& aCS=aItCS.Value();
00530     //
00531     const TopoDS_Shape& aF1=aCS.Shape1();
00532     const TopoDS_Shape& aF2=aCS.Shape2();
00533     //
00534     //
00535     if (aMCV.Contains(aF1)) {
00536       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF1);
00537       aMV.Add(aF1);
00538       aMV.Add(aF2);
00539     }
00540     else {
00541       TopTools_IndexedMapOfShape aMV;
00542       aMV.Add(aF1);
00543       aMV.Add(aF2);
00544       aMCV.Add(aF1, aMV);
00545     }
00546     //
00547     if (aMCV.Contains(aF2)) {
00548       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF2);
00549       aMV.Add(aF1);
00550       aMV.Add(aF2);
00551     }
00552     else {
00553       TopTools_IndexedMapOfShape aMV;
00554       aMV.Add(aF1);
00555       aMV.Add(aF2);
00556       aMCV.Add(aF2, aMV);
00557     }
00558   }
00559   NMTTools_Tools::FindChains(aMCV, aMapChains);
00560 }
00561 //=======================================================================
00562 // function: FindChains
00563 // purpose :
00564 //=======================================================================
00565   void NMTTools_Tools::FindChains(const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
00566                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
00567 {
00568   Standard_Integer  i, j, aNbCV, aNbV;
00569   TopTools_IndexedMapOfShape aProcessed, aChain;
00570   //
00571   aNbCV=aMCV.Extent();
00572   for (i=1; i<=aNbCV; ++i) {
00573     const TopoDS_Shape& aF=aMCV.FindKey(i);
00574     if (aProcessed.Contains(aF)) {
00575       continue;
00576     }
00577     //
00578     aProcessed.Add(aF);
00579     aChain.Add(aF);
00580     //
00581     const TopTools_IndexedMapOfShape& aMV=aMCV(i);
00582     aNbV=aMV.Extent();
00583     for (j=1; j<=aNbV; ++j) {
00584       const TopoDS_Shape& aFx=aMV(j);
00585       ProcessBlock(aFx, aMCV, aProcessed, aChain);
00586     }
00587     aMapChains.Add(aF, aChain);
00588     aChain.Clear();
00589   }
00590 }
00591 //=======================================================================
00592 // function: ProcessBlock
00593 // purpose:
00594 //=======================================================================
00595 void ProcessBlock(const TopoDS_Shape& aF,
00596                   const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
00597                   TopTools_IndexedMapOfShape& aProcessed,
00598                   TopTools_IndexedMapOfShape& aChain)
00599 {
00600   Standard_Integer j, aNbV;
00601   //
00602   if (aProcessed.Contains(aF)) {
00603     return;
00604   }
00605   aProcessed.Add(aF);
00606   aChain.Add(aF);
00607   //
00608   const TopTools_IndexedMapOfShape& aMV=aMCV.FindFromKey(aF);
00609   aNbV=aMV.Extent();
00610   for (j=1; j<=aNbV; ++j) {
00611     const TopoDS_Shape& aFx=aMV(j);
00612     ProcessBlock(aFx, aMCV, aProcessed, aChain);
00613   }
00614 }