PageRenderTime 83ms CodeModel.GetById 12ms app.highlight 66ms RepoModel.GetById 1ms app.codeStats 1ms

/src/contrib/geom-5.1.2.7/src/NMTTools/NMTTools_Tools.cpp

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