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