]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTTools/NMTTools_Tools.cxx
Salome HOME
Additional fix for bug NPAL19028 (see remarks from Olivier Giorgis).
[modules/geom.git] / src / NMTTools / NMTTools_Tools.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File:        NMTTools_Tools.cxx
21 // Created:     Mon Dec  8 10:35:15 2003
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <NMTTools_Tools.ixx>
27
28 #include <TColStd_IndexedMapOfInteger.hxx>
29
30 #include <gp_Pnt.hxx>
31 #include <gp_XYZ.hxx>
32 #include <gp_Pnt2d.hxx>
33
34 #include <Geom_Surface.hxx>
35 #include <GeomAPI_ProjectPointOnSurf.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Edge.hxx>
41
42 #include <TopExp.hxx>
43
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_IndexedMapOfShape.hxx>
46
47 #include <BRep_Tool.hxx>
48 #include <BRep_Builder.hxx>
49 #include <BRepTools.hxx>
50
51 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
52 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
53
54 #include <BOPTools_VVInterference.hxx>
55 #include <BOPTools_SSInterference.hxx>
56
57 #include <BOPTools_Tools2D.hxx>
58 #include <BOPTools_Tools.hxx>
59 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
60 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
61 #include <NMTTools_CoupleOfShape.hxx>
62 #include <TopTools_IndexedMapOfShape.hxx>
63 #include <Geom2d_Curve.hxx>
64 #include <Geom_Curve.hxx>
65 #include <Geom_TrimmedCurve.hxx>
66 #include <BOPTools_Tools2D.hxx>
67 #include <BRepLib.hxx>
68 #include <BOPTools_Tools3D.hxx>
69 #include <TopExp_Explorer.hxx>
70 //
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
73 #include <TopoDS_Iterator.hxx>
74
75 static 
76   void ProcessBlock(const Standard_Integer iV,
77                     const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
78                     TColStd_IndexedMapOfInteger& aProcessed,
79                     TColStd_IndexedMapOfInteger& aChain);
80 static
81   void ProcessBlock(const TopoDS_Shape& aF,
82                     const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
83                     TopTools_IndexedMapOfShape& aProcessed,
84                     TopTools_IndexedMapOfShape& aChain);
85
86 //modified by NIZNHY-PKV Thu Nov 16 10:46:53 2006f SKL/PartC5
87 //=======================================================================
88 // function: UpdateEdge
89 // purpose: 
90 //=======================================================================
91   void  NMTTools_Tools::UpdateEdge(const TopoDS_Edge& aE,
92                                    const Standard_Real aTolR)
93
94   Standard_Real aTolE, aTolES, aTolV;
95   TopoDS_Iterator aIt;
96   BRep_Builder aBB;
97   //
98   aTolE=BRep_Tool::Tolerance(aE);
99   aTolES=Max(aTolR, aTolE);
100   aBB.UpdateEdge(aE, aTolES);
101   //
102   aIt.Initialize(aE);
103   for (; aIt.More(); aIt.Next()) {
104     const TopoDS_Vertex& aV=TopoDS::Vertex(aIt.Value());
105     aTolV=BRep_Tool::Tolerance(aV);
106     if (aTolV<aTolES) {
107        aBB.UpdateVertex(aV, aTolES);
108     }
109   }
110 }
111 //=======================================================================
112 // function: MakePCurve
113 // purpose: 
114 //=======================================================================
115   void  NMTTools_Tools::MakePCurve(const TopoDS_Edge& aE,
116                                     const TopoDS_Face& aF,
117                                     const Handle(Geom2d_Curve)& aC2Dx1)
118                                     
119 {
120   Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
121   Handle(Geom2d_Curve) aC2D, aC2DA;
122   TopoDS_Face aFFWD;
123   BRep_Builder aBB;
124   //
125   aFFWD=aF;
126   aFFWD.Orientation(TopAbs_FORWARD);
127   //
128   aTolE=BRep_Tool::Tolerance(aE);
129   //
130   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
131   Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
132   //
133   aC2D=aC2Dx1;
134   if (aC2D.IsNull()) { // ?
135     BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
136     BOPTools_Tools2D::CurveOnSurface(aE, aFFWD, aC2D, aOutFirst, aOutLast, aOutTol, Standard_True);
137   }
138   //
139   if (aC3DE->IsPeriodic()) {
140     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2,  aC2D, aC2DA); 
141   }
142   else {
143     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA); 
144   }
145   //
146   aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
147   BRepLib::SameParameter(aE);
148 }
149 /*
150 //=======================================================================
151 // function: MakePCurve
152 // purpose: 
153 //=======================================================================
154   void  NMTTools_Tools::MakePCurve(const TopoDS_Edge& aE,
155                                    const TopoDS_Face& aF,
156                                    const Handle(Geom2d_Curve)& aC2Dx,
157                                    const Standard_Real aTolR2D)
158 {
159   Standard_Integer k, aNbV;   
160   Standard_Real aTolEdge, aTolFact, aTolV, aTolVmax;
161   Standard_Real aTFirst, aTLast, aOutFirst, aOutLast, aOutTol;
162   TopoDS_Face aFFWD;
163   TopTools_IndexedMapOfShape aVMap;
164   BRep_Builder aBB;
165   //
166   aFFWD=aF;
167   aFFWD.Orientation(TopAbs_FORWARD);
168   //
169   aTolEdge=BRep_Tool::Tolerance(aE);
170   aTolFact=Max(aTolEdge, aTolR2D);
171   //
172   TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
173   //
174   aTolVmax=-1.;
175   aNbV=aVMap.Extent();
176   for (k=1; k<=aNbV; ++k) {
177     const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
178     aTolV=BRep_Tool::Tolerance(aV);
179     if (aTolV>aTolVmax) {
180       aTolVmax=aTolV;
181     }
182   }
183   //
184   if (aTolFact>aTolVmax) {
185     aTolFact=aTolVmax;
186   }
187   //
188   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aTFirst, aTLast);
189   Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aTFirst, aTLast);
190   //
191   Handle(Geom2d_Curve) aC2D, aC2DA;
192   //
193   aC2D=aC2Dx;
194   if (aC2D.IsNull()) {
195     BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
196     BOPTools_Tools2D::CurveOnSurface(aE, aFFWD, aC2D, aOutFirst, aOutLast, aOutTol, Standard_True);
197   }
198   if (aC3DE->IsPeriodic()) {
199     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aTFirst, aTLast,  aC2D, aC2DA); 
200   }
201   else {
202     BOPTools_Tools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA); 
203   }
204   //
205   aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolFact);
206   BRepLib::SameParameter(aE);
207 }
208 */
209 //modified by NIZNHY-PKV Thu Nov 16 10:46:55 2006t 
210 //=======================================================================
211 // function: IsSplitInOnFace
212 // purpose: 
213 //=======================================================================
214   Standard_Boolean NMTTools_Tools::IsSplitInOnFace(const TopoDS_Edge& aE,
215                                                    const TopoDS_Face& aF,
216                                                    IntTools_Context& aContext)
217 {
218   Standard_Boolean bFlag;
219   Standard_Real aT, aTolE, aTolF, aTol, aDist, aU, aV;
220   gp_Pnt aP;
221   gp_Pnt2d aP2D;
222   //
223   aTolE=BRep_Tool::Tolerance(aE);
224   aTolF=BRep_Tool::Tolerance(aF);
225   aTol=aTolE+aTolF;
226   //
227   GeomAPI_ProjectPointOnSurf& aProjector=aContext.ProjPS(aF);
228   //
229   aT=BOPTools_Tools2D::IntermediatePoint(aE);
230   BOPTools_Tools::PointOnEdge(aE, aT, aP);
231   //
232   aProjector.Perform(aP);
233   bFlag=aProjector.IsDone();
234   if (!bFlag) {
235     return bFlag;
236   }
237   //
238   aDist=aProjector.LowerDistance();
239   bFlag=(aDist <= aTol);
240   if (!bFlag) {
241     return bFlag;
242   }
243   //
244   aProjector.LowerDistanceParameters(aU, aV);
245   aP2D.SetCoord(aU, aV);
246   bFlag=aContext.IsPointInOnFace (aF, aP2D);
247   return bFlag;
248 }
249 //=======================================================================
250 // function: NMTTools_Tools::MakeNewVertex
251 // purpose : 
252 //=======================================================================
253   void NMTTools_Tools::MakeNewVertex(const TopTools_ListOfShape& aLVs,
254                                      TopoDS_Vertex& aNewVertex)
255 {
256   Standard_Integer aNb;
257   Standard_Real aTi, aDi, aDmax=-1.e5;
258   gp_Pnt aPi, aP;
259   gp_XYZ aXYZ(0.,0.,0.), aXYZi;
260   TopTools_ListIteratorOfListOfShape anIt;
261   //
262   aNb=aLVs.Extent();
263   if (!aNb) {
264     return;
265   }
266   //
267   anIt.Initialize(aLVs);
268   for (; anIt.More(); anIt.Next()) {
269     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
270     aPi=BRep_Tool::Pnt(aVi);
271     aXYZi=aPi.XYZ();
272     aXYZ=aXYZ+aXYZi;
273   }
274   //
275   aXYZ.Divide((Standard_Real)aNb);
276   aP.SetXYZ(aXYZ);
277   //
278   anIt.Initialize(aLVs);
279   for (; anIt.More(); anIt.Next()) {
280     TopoDS_Vertex aVi=TopoDS::Vertex(anIt.Value());
281     aPi=BRep_Tool::Pnt(aVi);
282     aTi=BRep_Tool::Tolerance(aVi);
283     aDi=aP.Distance(aPi);
284     aDi=aDi+aTi;
285     if (aDi > aDmax) {
286       aDmax=aDi;
287     }
288   }
289   BRep_Builder aBB;
290   aBB.MakeVertex (aNewVertex, aP, aDmax);
291 }
292 //=======================================================================
293 // function: FindChains
294 // purpose : 
295 //=======================================================================
296   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfSSInterference& FFs,
297                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
298 {
299   Standard_Boolean bIsTangentFaces;
300   Standard_Integer j, aNb, anIndex1, anIndex2;
301   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
302   //
303   aNb=FFs.Extent();
304   for (j=1; j<=aNb; ++j) {
305     const BOPTools_SSInterference& aFF=FFs(j);
306     //
307     bIsTangentFaces=aFF.IsTangentFaces();
308     if (!bIsTangentFaces) {
309       continue;
310     }
311     //
312     aFF.Indices(anIndex1, anIndex2);
313     //
314     if (aMCV.Contains(anIndex1)) {
315       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
316       aMV.Add(anIndex1);
317       aMV.Add(anIndex2);
318     }
319     else {
320       TColStd_IndexedMapOfInteger aMV;
321       aMV.Add(anIndex1);
322       aMV.Add(anIndex2);
323       aMCV.Add(anIndex1, aMV);
324     }
325     //
326     if (aMCV.Contains(anIndex2)) {
327       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
328       aMV.Add(anIndex1);
329       aMV.Add(anIndex2);
330     }
331     else {
332       TColStd_IndexedMapOfInteger aMV;
333       aMV.Add(anIndex1);
334       aMV.Add(anIndex2);
335       aMCV.Add(anIndex2, aMV);
336     }
337   }
338   NMTTools_Tools::FindChains(aMCV, aMapChains);
339 }
340 //=======================================================================
341 // function: FindChains
342 // purpose : 
343 //=======================================================================
344   void NMTTools_Tools::FindChains(const BOPTools_CArray1OfVVInterference& VVs,
345                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
346 {
347   Standard_Integer j, aNb, anIndex1, anIndex2;
348   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMCV;
349   //
350   aNb=VVs.Extent();
351   for (j=1; j<=aNb; ++j) {
352     const BOPTools_VVInterference& VV=VVs(j);
353     VV.Indices(anIndex1, anIndex2);
354     //
355     if (aMCV.Contains(anIndex1)) {
356       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex1);
357       aMV.Add(anIndex1);
358       aMV.Add(anIndex2);
359     }
360     else {
361       TColStd_IndexedMapOfInteger aMV;
362       aMV.Add(anIndex1);
363       aMV.Add(anIndex2);
364       aMCV.Add(anIndex1, aMV);
365     }
366     //
367     if (aMCV.Contains(anIndex2)) {
368       TColStd_IndexedMapOfInteger& aMV=aMCV.ChangeFromKey(anIndex2);
369       aMV.Add(anIndex1);
370       aMV.Add(anIndex2);
371     }
372     else {
373       TColStd_IndexedMapOfInteger aMV;
374       aMV.Add(anIndex1);
375       aMV.Add(anIndex2);
376       aMCV.Add(anIndex2, aMV);
377     }
378   }
379   NMTTools_Tools::FindChains(aMCV, aMapChains);
380 }
381
382 //=======================================================================
383 // function: FindChains
384 // purpose : 
385 //=======================================================================
386   void NMTTools_Tools::FindChains(const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
387                                   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapChains)
388 {
389   Standard_Integer  i, j, aNbCV, aNbV, iV, iVx;
390   TColStd_IndexedMapOfInteger aProcessed, aChain;
391   //
392   aNbCV=aMCV.Extent();
393   for (i=1; i<=aNbCV; ++i) {
394     iV=aMCV.FindKey(i);
395     if (aProcessed.Contains(iV)) {
396       continue;
397     }
398     //
399     aProcessed.Add(iV);
400     aChain.Add(iV);
401     //
402     const TColStd_IndexedMapOfInteger& aMV=aMCV(i);
403     aNbV=aMV.Extent();
404     for (j=1; j<=aNbV; ++j) {
405       iVx=aMV(j);
406       ProcessBlock(iVx, aMCV, aProcessed, aChain);
407     }
408     aMapChains.Add(i, aChain);
409     aChain.Clear();
410   }
411 }
412 //=======================================================================
413 // function: ProcessBlock
414 // purpose: 
415 //=======================================================================
416 void ProcessBlock(const Standard_Integer iV,
417                   const BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMCV,
418                   TColStd_IndexedMapOfInteger& aProcessed,
419                   TColStd_IndexedMapOfInteger& aChain)
420 {
421   Standard_Integer j, aNbV, iVx;
422   //
423   if (aProcessed.Contains(iV)) {
424     return;
425   }
426   aProcessed.Add(iV);
427   aChain.Add(iV);
428   //
429   const TColStd_IndexedMapOfInteger& aMV=aMCV.FindFromKey(iV);
430   aNbV=aMV.Extent();
431   for (j=1; j<=aNbV; ++j) {
432     iVx=aMV(j);
433     ProcessBlock(iVx, aMCV, aProcessed, aChain);
434   }
435 }
436 //=======================================================================
437 // function: AreFacesSameDomain
438 // purpose : 
439 //=======================================================================
440   Standard_Boolean NMTTools_Tools::AreFacesSameDomain(const TopoDS_Face& aF1x,
441                                                       const TopoDS_Face& aF2y,
442                                                       IntTools_Context& aCtx)
443 {
444   Standard_Boolean bFlag;
445   // Modified  Thu Sep 14 14:35:18 2006 
446   // Contribution of Samtech www.samcef.com BEGIN
447   Standard_Integer aNbE1, aNbE2;
448   Standard_Real aTolF1, aTolF2, aTol;
449   gp_Pnt2d aP2D;
450   gp_Pnt aP;
451   TopoDS_Face aF1, aF2;
452   TopExp_Explorer aExp;
453   TopTools_MapOfShape aME1, aME2;
454   TopTools_MapIteratorOfMapOfShape aIt;
455   //
456   bFlag=Standard_False;
457   // Contribution of Samtech www.samcef.com END
458   //
459   aF1=aF1x;
460   aF1.Orientation(TopAbs_FORWARD);
461   aF2=aF2y;
462   aF2.Orientation(TopAbs_FORWARD);
463   //
464   // Modified  Thu Sep 14 14:35:18 2006 
465   // Contribution of Samtech www.samcef.com BEGIN
466   //
467   // 1
468   aExp.Init(aF1, TopAbs_EDGE);
469   for (; aExp.More(); aExp.Next()) {
470     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
471     if (!BRep_Tool::Degenerated(aE)) {
472       aME1.Add(aE);
473     }
474   }
475   //
476   aExp.Init(aF2, TopAbs_EDGE);
477   for (; aExp.More(); aExp.Next()) {
478     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
479     if (!BRep_Tool::Degenerated(aE)) {
480       if (!aME1.Contains(aE)) {
481         return bFlag;
482       }
483       aME2.Add(aE);
484     }
485   }
486   //
487   // Contribution of Samtech www.samcef.com END
488   //
489   aNbE1=aME1.Extent();
490   aNbE2=aME2.Extent();
491   //
492   if(!aNbE1 || !aNbE2){
493     return bFlag;
494   }
495   //
496   if(aNbE1!=aNbE2) {
497     return bFlag;
498   }
499   //
500   // 2
501   aTolF1=BRep_Tool::Tolerance(aF1);
502   aTolF2=BRep_Tool::Tolerance(aF2);
503   aTol=aTolF1+aTolF2;
504   //
505   aIt.Initialize(aME1);
506   for (; aIt.More(); aIt.Next()) {
507     const TopoDS_Edge& aE=TopoDS::Edge(aIt.Key());
508     BOPTools_Tools3D::PointNearEdge(aE, aF1, aP2D, aP);
509     bFlag=aCtx.IsValidPointForFace(aP, aF2, aTol);
510     break;
511   }
512   //
513   return bFlag;
514 }
515 //=======================================================================
516 // function: FindChains
517 // purpose : 
518 //=======================================================================
519   void NMTTools_Tools::FindChains(const NMTTools_ListOfCoupleOfShape& aLCS,
520                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
521 {
522   NMTTools_ListIteratorOfListOfCoupleOfShape aItCS; 
523   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMCV;
524   //
525   aItCS.Initialize(aLCS);
526   for (; aItCS.More(); aItCS.Next()) {
527     const NMTTools_CoupleOfShape& aCS=aItCS.Value();
528     //
529     const TopoDS_Shape& aF1=aCS.Shape1();
530     const TopoDS_Shape& aF2=aCS.Shape2();
531     //
532     //
533     if (aMCV.Contains(aF1)) {
534       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF1);
535       aMV.Add(aF1);
536       aMV.Add(aF2);
537     }
538     else {
539       TopTools_IndexedMapOfShape aMV;
540       aMV.Add(aF1);
541       aMV.Add(aF2);
542       aMCV.Add(aF1, aMV);
543     }
544     //
545     if (aMCV.Contains(aF2)) {
546       TopTools_IndexedMapOfShape& aMV=aMCV.ChangeFromKey(aF2);
547       aMV.Add(aF1);
548       aMV.Add(aF2);
549     }
550     else {
551       TopTools_IndexedMapOfShape aMV;
552       aMV.Add(aF1);
553       aMV.Add(aF2);
554       aMCV.Add(aF2, aMV);
555     }
556   }
557   NMTTools_Tools::FindChains(aMCV, aMapChains);
558 }
559 //=======================================================================
560 // function: FindChains
561 // purpose : 
562 //=======================================================================
563   void NMTTools_Tools::FindChains(const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
564                                   NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMapChains)
565 {
566   Standard_Integer  i, j, aNbCV, aNbV;
567   TopTools_IndexedMapOfShape aProcessed, aChain;
568   //
569   aNbCV=aMCV.Extent();
570   for (i=1; i<=aNbCV; ++i) {
571     const TopoDS_Shape& aF=aMCV.FindKey(i);
572     if (aProcessed.Contains(aF)) {
573       continue;
574     }
575     //
576     aProcessed.Add(aF);
577     aChain.Add(aF);
578     //
579     const TopTools_IndexedMapOfShape& aMV=aMCV(i);
580     aNbV=aMV.Extent();
581     for (j=1; j<=aNbV; ++j) {
582       const TopoDS_Shape& aFx=aMV(j);
583       ProcessBlock(aFx, aMCV, aProcessed, aChain);
584     }
585     aMapChains.Add(aF, aChain);
586     aChain.Clear();
587   }
588 }
589 //=======================================================================
590 // function: ProcessBlock
591 // purpose: 
592 //=======================================================================
593 void ProcessBlock(const TopoDS_Shape& aF,
594                   const NMTTools_IndexedDataMapOfShapeIndexedMapOfShape& aMCV,
595                   TopTools_IndexedMapOfShape& aProcessed,
596                   TopTools_IndexedMapOfShape& aChain)
597 {
598   Standard_Integer j, aNbV;
599   //
600   if (aProcessed.Contains(aF)) {
601     return;
602   }
603   aProcessed.Add(aF);
604   aChain.Add(aF);
605   //
606   const TopTools_IndexedMapOfShape& aMV=aMCV.FindFromKey(aF);
607   aNbV=aMV.Extent();
608   for (j=1; j<=aNbV; ++j) {
609     const TopoDS_Shape& aFx=aMV(j);
610     ProcessBlock(aFx, aMCV, aProcessed, aChain);
611   }
612 }