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