Salome HOME
Merging with WPdev
[modules/geom.git] / src / NMTTools / NMTTools_PaveFiller_5.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_PaveFiller_5.cxx
21 // Created:     Mon Dec 15 11:28:33 2003
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <NMTTools_PaveFiller.ixx>
27
28 #include <TColStd_IndexedMapOfInteger.hxx>
29
30 #include <BRep_Tool.hxx>
31 #include <BRep_Builder.hxx>
32
33 #include <Bnd_Box.hxx>
34
35 #include <TopAbs_ShapeEnum.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Compound.hxx>
42
43 #include <TopTools_IndexedMapOfShape.hxx>
44
45 #include <IntTools_ShrunkRange.hxx>
46 #include <IntTools_Range.hxx>
47 #include <IntTools_EdgeFace.hxx>
48 #include <IntTools_PContext.hxx>
49 #include <IntTools_SequenceOfCommonPrts.hxx>
50 #include <IntTools_CommonPrt.hxx>
51 #include <IntTools_Tools.hxx>
52
53 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
54 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
55 #include <BooleanOperations_OnceExplorer.hxx>
56
57 #include <BOPTools_Tools.hxx>
58 #include <BOPTools_Pave.hxx>
59 #include <BOPTools_PaveSet.hxx>
60 #include <BOPTools_ListOfPave.hxx>
61 #include <BOPTools_ListIteratorOfListOfPave.hxx>
62 #include <BOPTools_PaveBlock.hxx>
63 #include <BOPTools_ListOfPaveBlock.hxx>
64 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
65 #include <BOPTools_ESInterference.hxx>
66 #include <BOPTools_InterferencePool.hxx>
67 #include <BOPTools_CArray1OfVVInterference.hxx>
68 #include <BOPTools_CArray1OfESInterference.hxx>
69 #include <BOPTools_VVInterference.hxx>
70 #include <BOPTools_ESInterference.hxx>
71 #include <BOPTools_IDMapOfPaveBlockIMapOfInteger.hxx>
72 #include <BOPTools_IMapOfPaveBlock.hxx>
73
74 #include <NMTDS_ShapesDataStructure.hxx>
75
76 #include <NMTTools_ListOfCommonBlock.hxx>
77 #include <NMTTools_CommonBlockAPI.hxx>
78 #include <NMTTools_IndexedDataMapOfIndexedMapOfInteger.hxx>
79 #include <NMTTools_CommonBlockAPI.hxx>
80 #include <NMTTools_ListOfCommonBlock.hxx>
81 #include <TopTools_IndexedMapOfShape.hxx>
82 #include <TopExp.hxx>
83
84 static
85   void VertexParameter(const IntTools_CommonPrt& aCPart,
86                        Standard_Real& aT);
87 static
88   Standard_Boolean IsOnPave(const Standard_Real& aTR,
89                             const IntTools_Range& aCPRange,
90                             const Standard_Real& aTolerance);
91 //
92 //=======================================================================
93 // function: PerformEF
94 // purpose: 
95 //=======================================================================
96   void NMTTools_PaveFiller::PerformEF() 
97 {
98   myIsDone=Standard_False;
99   
100   Standard_Integer n1, n2, anIndexIn=0, nE, nF, aNbEFs, aBlockLength;
101   Standard_Boolean bJustAdd;
102   Standard_Real aTolE, aTolF, aDeflection=0.01;
103   Standard_Integer aDiscretize=35;
104   BooleanOperations_IndexedDataMapOfShapeInteger aMapVI;
105   BOPTools_IDMapOfPaveBlockIMapOfInteger aMapCB;
106   BOPTools_IMapOfPaveBlock aIMPBx;
107   //
108   BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
109   //
110   myDSIt.Initialize(TopAbs_EDGE, TopAbs_FACE);
111   //
112   // BlockLength correction
113   aNbEFs=ExpectedPoolLength();
114   aBlockLength=aEFs.BlockLength();
115   if (aNbEFs > aBlockLength) {
116     aEFs.SetBlockLength(aNbEFs);
117   }
118   //
119   for (; myDSIt.More(); myDSIt.Next()) {
120     myDSIt.Current(n1, n2, bJustAdd);
121     anIndexIn = 0;
122     //
123     if (myIntrPool->IsComputed(n1, n2)) {
124       continue;
125     }
126     //
127     nE=n1; 
128     nF=n2; 
129     SortTypes(nE, nF);
130     //
131     // all Common Blocks for face nF
132     //XXX
133     NMTTools_ListOfCommonBlock aLCBF;
134     CommonBlocksFace(nF, aLCBF);
135     NMTTools_CommonBlockAPI aCBAPIF(aLCBF);
136     //XXX
137     if(bJustAdd) {
138       myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
139       continue;
140     }
141     // Edge
142     const TopoDS_Edge aE=TopoDS::Edge(myDS->GetShape(nE));//mpv
143     if (BRep_Tool::Degenerated(aE)){
144       continue;
145     }
146     // Face
147     const TopoDS_Face aF=TopoDS::Face(myDS->GetShape(nF));//mpv
148     //
149     // Modified 
150     // to avoid intersection between face and edge from that face
151     // Thu Sep 14 14:35:18 2006 
152     // Contribution of Samtech www.samcef.com BEGIN
153     TopTools_IndexedMapOfShape aME;
154     //
155     TopExp::MapShapes(aF, TopAbs_EDGE, aME);
156     if (aME.Contains(aE)) {
157       continue;
158     }
159     // Contribution of Samtech www.samcef.com END
160     //
161     aTolF=BRep_Tool::Tolerance(aF);
162     
163     // Modified  Thu Sep 14 14:35:18 2006 
164     // Contribution of Samtech www.samcef.com BEGIN
165     aTolE=BRep_Tool::Tolerance(aE);
166     // Contribution of Samtech www.samcef.com END
167     
168     const Bnd_Box& aBBF=myDS->GetBoundingBox(nF); 
169     //
170     // Process each PaveBlock on edge nE
171     BOPTools_ListOfPaveBlock& aLPB=mySplitShapesPool(myDS->RefEdge(nE));
172     //
173     BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
174     for (; anIt.More(); anIt.Next()) {
175       BOPTools_PaveBlock& aPB=anIt.Value();
176       //XXX
177       if (aCBAPIF.IsCommonBlock(aPB)) {
178         continue;
179       }
180       //XXX
181       const IntTools_ShrunkRange& aShrunkRange=aPB.ShrunkRange();
182       const IntTools_Range& aSR =aShrunkRange.ShrunkRange();
183       const Bnd_Box&        aBBE=aShrunkRange.BndBox();
184       //
185       if (aBBF.IsOut (aBBE)) {
186         continue;
187       }
188       // 
189       // EF
190       IntTools_EdgeFace aEF;
191       aEF.SetEdge (aE);
192       aEF.SetFace (aF);
193       aEF.SetTolE (aTolE);
194       aEF.SetTolF (aTolF);
195       aEF.SetDiscretize (aDiscretize);
196       aEF.SetDeflection (aDeflection);
197       // 
198       aEF.SetContext((IntTools_PContext)&myContext);
199       // 
200       IntTools_Range anewSR = aSR;
201       // 
202       // Correction of the Shrunk Range 
203       BOPTools_Tools::CorrectRange(aE, aF, aSR, anewSR);
204       aEF.SetRange (anewSR);
205       //
206       aEF.Perform();
207       //
208       if (aEF.IsDone()) {
209         const IntTools_SequenceOfCommonPrts& aCPrts=aEF.CommonParts();
210         Standard_Integer i, aNbCPrts;
211         aNbCPrts=aCPrts.Length();
212         for (i=1; i<=aNbCPrts; i++) {
213           //
214           anIndexIn=0;
215           //
216           const IntTools_CommonPrt& aCPart=aCPrts(i);
217           TopAbs_ShapeEnum aType=aCPart.Type();
218           switch (aType) {
219
220             case TopAbs_VERTEX:  {
221               Standard_Boolean bIsOnPave1, bIsOnPave2;
222               Standard_Integer nVF;
223               Standard_Real aT, aTolToDecide; 
224               TopoDS_Vertex aNewVertex;
225               //
226               const IntTools_Range& aR=aCPart.Range1();
227               //
228               // New Vertex
229               VertexParameter(aCPart, aT);
230               BOPTools_Tools::MakeNewVertex(aE, aT, aF, aNewVertex);
231               //
232               //decide to add pave or not
233               aTolToDecide=5.e-8;
234               //
235               bIsOnPave1=IsOnPave(anewSR.First(), aR, aTolToDecide); 
236               bIsOnPave2=IsOnPave(anewSR.Last() , aR, aTolToDecide); 
237               //
238               if (!bIsOnPave1 && !bIsOnPave2) {
239                 nVF=CheckFacePaves(aNewVertex, nF);
240                 if (!nVF) {
241                   // really new vertex
242                   // Add Interference to the Pool
243                   BOPTools_ESInterference anInterf (nE, nF, aCPart);
244                   anIndexIn=aEFs.Append(anInterf);
245                   anInterf.SetNewShape(0);
246                   //
247                   aMapVI.Add(aNewVertex, anIndexIn);
248                   aIMPBx.Add(aPB);
249                   //
250                 }// if (!nVF)
251               }// if (!bIsOnPave1 && !bIsOnPave2) 
252               myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
253             }// case TopAbs_VERTEX:
254               break;
255             //
256             case TopAbs_EDGE: {
257               Standard_Boolean aCoinsideFlag;
258               //
259               aCoinsideFlag=BOPTools_Tools::IsBlockInOnFace(aPB, aF, myContext);
260               if (!aCoinsideFlag) {
261                 myIntrPool->AddInterference (nE, nF, BooleanOperations_EdgeSurface, anIndexIn);
262                 break;
263               }
264               //
265               // Fill aMapCB
266               if (aMapCB.Contains(aPB)) {
267                 TColStd_IndexedMapOfInteger& aMapF=aMapCB.ChangeFromKey(aPB);
268                 aMapF.Add(nF);
269               }
270               else {
271                 TColStd_IndexedMapOfInteger aMapF;
272                 aMapF.Add(nF);
273                 aMapCB.Add(aPB, aMapF);
274               }
275               //modified by NIZNHY-PKV Fri Jan 23 14:13:08 2004 f
276               aIMPBx.Add(aPB);
277               //modified by NIZNHY-PKV Fri Jan 23 14:13:10 2004 t
278             }// case TopAbs_EDGE:
279               break;
280
281             default:
282               break;
283           } // switch (aType) 
284         } // for (i=1; i<=aNbCPrts; i++) 
285       } //if (aEF.IsDone())
286     } // for (; anIt.More(); anIt.Next()) 
287   }// for (; myDSIt.More(); myDSIt.Next()) 
288   //
289   // Treat New vertices
290   EFNewVertices(aMapVI);
291   //
292   // Add draft Common Blocks of EF type 
293   EFCommonBlocks(aMapCB);
294   //
295   // Collect all CB we suspected to split by new vertices
296   NMTTools_ListOfCommonBlock aLCBx;
297   {
298     Standard_Integer i, aNbPBx, nEx;
299     BOPTools_IMapOfPaveBlock aMx;
300     //
301     aNbPBx=aIMPBx.Extent();
302     for (i=1; i<=aNbPBx; ++i) {
303       const BOPTools_PaveBlock& aPBx=aIMPBx(i);
304       nEx=aPBx.OriginalEdge();
305       NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nEx));
306       if (aLCB.Extent()) {
307         NMTTools_CommonBlockAPI aCBAPIx(aLCB);
308         if (aCBAPIx.IsCommonBlock(aPBx)) {
309           NMTTools_CommonBlock& aCBx=aCBAPIx.CommonBlock(aPBx);
310           const BOPTools_PaveBlock& aPB1=aCBx.PaveBlock1();
311           if (!aMx.Contains(aPB1)){
312             aMx.Add(aPB1);
313             aLCBx.Append(aCBx);
314           }
315         }
316       }
317     }
318   }
319   //
320   // Split the common blocks above
321   if (aLCBx.Extent()) {
322     ReplaceCommonBlocks(aLCBx);
323   }
324   //
325   myIsDone=Standard_True;
326 }
327 //=======================================================================
328 // function:EFCommonBlocks
329 // purpose: 
330 //=======================================================================
331   void NMTTools_PaveFiller::EFCommonBlocks(const BOPTools_IDMapOfPaveBlockIMapOfInteger& aMapCB)
332 {
333   Standard_Integer i, aNbPB, nE, j, aNbF, nF;
334   //
335   aNbPB=aMapCB.Extent();
336   //
337   for (i=1; i<=aNbPB; ++i) {
338     const BOPTools_PaveBlock& aPB=aMapCB.FindKey(i);
339     const TColStd_IndexedMapOfInteger& aMapF=aMapCB.FindFromIndex(i);
340     aNbF=aMapF.Extent();
341     //
342     nE=aPB.OriginalEdge();
343     //
344     NMTTools_ListOfCommonBlock& aLCB=myCommonBlockPool(myDS->RefEdge(nE));
345     //
346     NMTTools_CommonBlockAPI aCBAPI(aLCB);
347     if (aCBAPI.IsCommonBlock(aPB)) {
348       NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
349       for (j=1; j<=aNbF; ++j) {
350         nF=aMapF(j);
351         aCB.AddFace(nF);
352       }
353     }
354     else {
355       NMTTools_CommonBlock aCB;
356       //
357       aCB.AddPaveBlock(aPB);
358       for (j=1; j<=aNbF; ++j) {
359         nF=aMapF(j);
360         aCB.AddFace(nF);
361       }
362       aLCB.Append(aCB);
363     }
364   }
365 }
366 //=======================================================================
367 // function:EFNewVertices
368 // purpose: 
369 //=======================================================================
370   void NMTTools_PaveFiller::EFNewVertices (const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
371 {
372   Standard_Integer i, j, aNb, aNewShape, aFlag, iX, aNbVV, aNbSimple;
373   Standard_Integer aWhat, aWith, nE, nF, nV, aNbIEF, aNbEdges;
374   Standard_Real aT;
375   TopoDS_Compound aCompound;
376   TopoDS_Vertex aNewVertex;
377   BRep_Builder aBB;
378   BOPTools_Pave aPave;
379   NMTTools_IndexedDataMapOfIndexedMapOfInteger aMNVE, aMNVIEF;
380   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
381   TopTools_IndexedMapOfShape aMNVComplex, aMNVSimple;
382   //
383   BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
384   //
385   aNb=aMapVI.Extent();
386   //
387   if (!aNb) { // no new vertices, no new problems 
388     return;
389   }
390   //
391   // 0.
392   if (aNb==1) {
393     aNewVertex=TopoDS::Vertex(aMapVI.FindKey(1));
394     EFNewVertices(aNewVertex, aMapVI);
395     return;
396   }
397   //
398   // 1. Make compound from new vertices
399   aBB.MakeCompound(aCompound);
400   for (i=1; i<=aNb; ++i) {
401     const TopoDS_Shape& aV=aMapVI.FindKey(i);
402     aBB.Add(aCompound, aV);
403   }
404   //
405   // 2. VV intersection between these vertices 
406   //       using the auxiliary Filler
407   NMTDS_ShapesDataStructure tDS;
408   //
409   tDS.SetCompositeShape(aCompound);
410   tDS.Init();
411   //
412   BOPTools_InterferencePool tInterfPool(tDS);
413   NMTTools_PaveFiller tPaveFiller(tInterfPool);
414   //
415   tPaveFiller.Init();
416   //
417   tPaveFiller.PerformVV();
418   tPaveFiller.PerformNewVertices();
419   //
420   const BOPTools_CArray1OfVVInterference& aVVInterfs=tInterfPool.VVInterfs();
421   //
422   // 3. Separate Comlex and Simple new vertices
423   aNbVV=aVVInterfs.Extent();
424    for (i=1; i<=aNbVV; ++i) {
425     const BOPTools_VVInterference& aVV=aVVInterfs(i);
426     aVV.Indices(aWhat, aWith);
427     const TopoDS_Shape& aV1=tDS.Shape(aWhat);
428     const TopoDS_Shape& aV2=tDS.Shape(aWith);
429     aMNVComplex.Add(aV1);
430     aMNVComplex.Add(aV2);
431   }
432   //
433   for (i=1; i<=aNb; ++i) {
434     const TopoDS_Shape& aV=aMapVI.FindKey(i);
435     if (!aMNVComplex.Contains(aV)) {
436       aMNVSimple.Add(aV);
437     }
438   }
439   //
440   // 4. Treat Simple new Vertices
441   aNbSimple=aMNVSimple.Extent();
442   for (i=1; i<=aNbSimple; ++i) {
443     const TopoDS_Vertex& aV=TopoDS::Vertex(aMNVSimple(i));
444     EFNewVertices(aV, aMapVI);
445   }
446   //
447   // 3. Fill Maps : NewVertex-edges (aMNVE) 
448   //                NewVertex-interferences (aMNVIEE)
449   aNb=aVVInterfs.Extent();
450   for (i=1; i<=aNb; ++i) {
451     const BOPTools_VVInterference& aVV=aVVInterfs(i);
452     aNewShape=aVV.NewShape();
453     if (!aNewShape) {
454       continue;
455     }
456     //
457     if (!aMNVE.Contains(aNewShape)) {
458       TColStd_IndexedMapOfInteger aMx;
459       aMNVE.Add(aNewShape, aMx);
460     }
461     if (!aMNVIEF.Contains(aNewShape)) {
462       TColStd_IndexedMapOfInteger aMx;
463       aMNVIEF.Add(aNewShape, aMx);
464     }
465     //
466     TColStd_IndexedMapOfInteger& aME=aMNVE.ChangeFromKey(aNewShape);
467     TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.ChangeFromKey(aNewShape);
468     //
469     aVV.Indices(aWhat, aWith);
470     //aWhat
471     const TopoDS_Shape& aV1=tDS.Shape(aWhat);
472     iX=aMapVI.FindFromKey(aV1);
473     const BOPTools_ESInterference& aEF1=aEFs(iX);
474     aEF1.Indices(nE, nF);
475     SortTypes(nE, nF);
476     aME.Add(nE);
477     aMIEF.Add(iX);
478     //aWith
479     const TopoDS_Shape& aV2=tDS.Shape(aWith);
480     iX=aMapVI.FindFromKey(aV2);
481     const BOPTools_ESInterference& aEF2=aEFs(iX);
482     aEF2.Indices(nE, nF);
483     SortTypes(nE, nF);
484     aME.Add(nE);
485     aMIEF.Add(iX);
486   }
487   // 4. Process new vertices
488   aNb=aMNVE.Extent();
489   for (i=1; i<=aNb; ++i) { // xx
490     //
491     //  new Vertex
492     nV=aMNVE.FindKey(i);
493     aNewVertex=TopoDS::Vertex(tDS.Shape(nV));
494     //
495     // Insert New Vertex in DS;
496     myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
497     aNewShape=myDS->NumberOfInsertedShapes();
498     myDS->SetState (aNewShape, BooleanOperations_ON);
499     //
500     // Update index of NewShape in EF interferences
501     const TColStd_IndexedMapOfInteger& aMIEF=aMNVIEF.FindFromKey(nV);
502     aNbIEF=aMIEF.Extent();
503     for (j=1; j<=aNbIEF; ++j) {
504       iX=aMIEF(j);
505       BOPTools_ESInterference& aEF=aEFs(iX);
506       aEF.SetNewShape(aNewShape);
507     }
508     // 
509     // Update Paves on all edges 
510     const TColStd_IndexedMapOfInteger& aME=aMNVE(i);
511     aNbEdges=aME.Extent();
512     for (j=1; j<=aNbEdges; ++j) {
513       nE=aME(j);
514       const TopoDS_Edge aE=TopoDS::Edge(myDS->Shape(nE));//mpv
515       //
516       aFlag=myContext.ComputeVE (aNewVertex, aE, aT);
517       //
518       if (!aFlag) {
519         aPave.SetInterference(-1);
520         aPave.SetType (BooleanOperations_EdgeSurface);
521         aPave.SetIndex(aNewShape);
522         aPave.SetParam(aT);
523         //
524         BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
525         aPaveSet.Append(aPave);
526       }
527     }
528   }
529 }
530 //=======================================================================
531 // function:EFNewVertices
532 // purpose: 
533 //=======================================================================
534   void NMTTools_PaveFiller::EFNewVertices (const TopoDS_Vertex& aNewVertex,
535                                            const BooleanOperations_IndexedDataMapOfShapeInteger& aMapVI) 
536 {
537   Standard_Integer i, aNewShape, nE, nF;
538   Standard_Real aT;
539   BOPTools_Pave aPave;
540   BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
541   //
542   BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
543   //
544   // Insert New Vertex in DS;
545   myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
546   aNewShape=myDS->NumberOfInsertedShapes();
547   myDS->SetState (aNewShape, BooleanOperations_ON);
548   // Insert New Vertex in EFInterference
549   i=aMapVI.FindFromKey(aNewVertex);
550   BOPTools_ESInterference& aEFInterf= aEFs(i);
551   aEFInterf.SetNewShape(aNewShape);
552   // Extract interference info
553   aEFInterf.Indices(nE, nF);
554   SortTypes(nE, nF);
555   const IntTools_CommonPrt& aCPart=aEFInterf.CommonPrt();
556   VertexParameter(aCPart, aT);
557   //
558   // Pave for edge nE
559   aPave.SetInterference(i);
560   aPave.SetType (BooleanOperations_EdgeSurface);
561   aPave.SetIndex(aNewShape);
562   aPave.SetParam(aT);
563   // Append the Pave to the myPavePoolNew
564   BOPTools_PaveSet& aPaveSet=myPavePoolNew(myDS->RefEdge(nE));
565   aPaveSet.Append(aPave);
566   //
567 }
568 //=======================================================================
569 // function: CheckFacePaves
570 // purpose: 
571 //=======================================================================
572   Standard_Integer NMTTools_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aNewVertex,
573                                                         const Standard_Integer nF)
574 {
575   Standard_Integer nEF, nVF, iFlag, i, aNbV;
576   BOPTools_ListIteratorOfListOfPave anIt;
577   TColStd_IndexedMapOfInteger aMVF;
578   // 
579   BooleanOperations_OnceExplorer aExp(*myDS);
580   //
581   aExp.Init(nF, TopAbs_EDGE);
582   for (; aExp.More(); aExp.Next()) {
583     nEF=aExp.Current();
584     BOPTools_PaveSet& aPaveSet=myPavePool(myDS->RefEdge(nEF));
585     const BOPTools_ListOfPave& aLP=aPaveSet.Set();
586     anIt.Initialize(aLP);
587     for (; anIt.More(); anIt.Next()) {
588       const BOPTools_Pave& aPave=anIt.Value();
589       nVF=aPave.Index();
590       aMVF.Add(nVF);
591     }
592   }
593   //
594   aNbV=aMVF.Extent();
595   for (i=1; i<=aNbV; ++i) {
596     nVF=aMVF(i);
597     const TopoDS_Vertex aVF=TopoDS::Vertex(myDS->Shape(nVF));//mpv
598     iFlag=IntTools_Tools::ComputeVV(aNewVertex, aVF);
599     if (!iFlag) {
600       return nVF;
601     }
602   }
603   return 0;
604 }
605
606 //
607 //=======================================================================
608 // function: VertexParameter
609 // purpose: 
610 //=======================================================================
611 void VertexParameter(const IntTools_CommonPrt& aCPart,
612                      Standard_Real& aT)
613 {
614   const IntTools_Range& aR=aCPart.Range1();
615   aT=0.5*(aR.First()+aR.Last());
616   //
617   if((aCPart.VertexParameter1() >= aR.First()) &&
618      (aCPart.VertexParameter1() <= aR.Last())) {
619     aT = aCPart.VertexParameter1();
620   }
621 }
622 //=======================================================================
623 // function: IsOnPave
624 // purpose: 
625 //=======================================================================
626 Standard_Boolean IsOnPave(const Standard_Real& aTR,
627                           const IntTools_Range& aCPRange,
628                           const Standard_Real& aTolerance)
629 {
630   Standard_Boolean bIsOnPave;
631   Standard_Real aT1, aT2, dT1, dT2;
632   //
633   aT1=aCPRange.First();
634   aT2=aCPRange.Last();
635   bIsOnPave=(aTR>=aT1 && aTR<=aT1);
636   if (bIsOnPave) {
637     return bIsOnPave;
638   }
639   dT1=Abs(aTR-aT1);  
640   dT2=Abs(aTR-aT2);
641   bIsOnPave=(dT1<=aTolerance || dT2<=aTolerance);
642   return bIsOnPave;
643 }