2f2e0ba971965c86b230af7b10696a67e82f2fc1
[occt.git] / src / BOPTools / BOPTools_PaveFiller_3.cxx
1 // File:        BOPTools_PaveFiller_3.cxx
2 // Created:     Tue Mar 13 16:12:16 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOPTools_PaveFiller.ixx>
8
9 #include <Geom_Curve.hxx>
10
11 #include <gp_Pnt.hxx>
12 #include <TColStd_SequenceOfInteger.hxx>
13 #include <TColStd_SequenceOfReal.hxx>
14
15 #include <TColStd_MapOfInteger.hxx>
16 #include <TColStd_ListOfInteger.hxx>
17 #include <TColStd_IndexedMapOfInteger.hxx>
18 #include <TColStd_ListIteratorOfListOfInteger.hxx>
19 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
20
21 #include <TopoDS.hxx>
22 #include <TopoDS_Face.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Vertex.hxx>
25
26 #include <BRep_Tool.hxx>
27 #include <BRep_Builder.hxx>
28
29 #include <BooleanOperations_ShapesDataStructure.hxx>
30 #include <BooleanOperations_OnceExplorer.hxx>
31 #include <BooleanOperations_AncestorsSeqAndSuccessorsSeq.hxx>
32
33 #include <IntTools_FaceFace.hxx>
34 #include <IntTools_SequenceOfCurves.hxx>
35 #include <IntTools_Curve.hxx>
36 #include <IntTools_Tools.hxx>
37 #include <IntTools_SequenceOfPntOn2Faces.hxx>
38 #include <IntTools_PntOn2Faces.hxx>
39 #include <IntTools_PntOnFace.hxx>
40
41 #include <BOPTools_IteratorOfCoupleOfShape.hxx>
42 #include <BOPTools_CArray1OfSSInterference.hxx>
43 #include <BOPTools_SSInterference.hxx>
44 #include <BOPTools_ListOfPaveBlock.hxx>
45 #include <BOPTools_PaveBlock.hxx>
46 #include <BOPTools_Pave.hxx>
47 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
48 #include <BOPTools_ListIteratorOfListOfPave.hxx>
49 #include <BOPTools_PaveBlockIterator.hxx>
50 #include <BOPTools_Tools.hxx>
51 #include <BOPTools_SequenceOfCurves.hxx>
52 #include <BOPTools_Curve.hxx>
53 #include <BOPTools_ListOfPave.hxx>
54 #include <BOPTools_PaveSet.hxx>
55 #include <BOPTools_CommonBlock.hxx>
56 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
57 #include <BOPTools_ListOfCommonBlock.hxx>
58
59 #include <BOPTools_InterferencePool.hxx>
60 #include <BOPTools_ListIteratorOfListOfInterference.hxx>
61 #include <BOPTools_InterferenceLine.hxx>
62 #include <BOPTools_ListOfInterference.hxx>
63 #include <BOPTools_Interference.hxx>
64 #include <BOPTools_CArray1OfInterferenceLine.hxx>
65
66 #include <Precision.hxx>
67 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
68
69 #include <TopExp_Explorer.hxx>
70 #include <Geom2d_Curve.hxx>
71 #include <Geom2dAPI_InterCurveCurve.hxx>
72 #include <IntRes2d_IntersectionPoint.hxx>
73 #include <BOPTools_ESInterference.hxx>
74 #include <BOPTools_VSInterference.hxx>
75 #include <BOPTools_VEInterference.hxx>
76 #include <BOPTools_VVInterference.hxx>
77 #include <BRepAdaptor_Surface.hxx>
78 #include <TopTools_ListOfShape.hxx>
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80
81 #include <BOPTools_EEInterference.hxx>
82 #include <IntTools_CommonPrt.hxx>
83 #include <BOPTools_ESInterference.hxx>
84 #include <BOPTools_ShapeShapeInterference.hxx>
85
86 #include <IntSurf_ListOfPntOn2S.hxx>
87
88 #include <GeomAPI_ProjectPointOnSurf.hxx>
89 #include <IntSurf_PntOn2S.hxx>
90 #include <TopTools_MapOfShape.hxx>
91
92
93 static
94   Standard_Boolean IsPaveBlock(const Standard_Integer nV1,
95                                const Standard_Integer nV2, 
96                                const BOPTools_ListOfPaveBlock& aLPBExisting);
97 static
98   Standard_Boolean IsFound(const TColStd_IndexedMapOfInteger& aMapWhat,
99                            const TColStd_IndexedMapOfInteger& aMapWith);
100 static
101   void FMapWith(const Standard_Integer nF,
102                 BOPTools_InterferencePool* myIntrPool,
103                 TColStd_IndexedMapOfInteger& aMapWith);
104 static
105   void FMapWhat(const Standard_Integer nF,
106                 BOPTools_InterferencePool* myIntrPool,
107                 TColStd_IndexedMapOfInteger& aMapWhat);
108
109 //wkar OCC334 f
110 static
111   void UnUsedMap(BOPTools_SequenceOfCurves& aSCvs,
112                  const BOPTools_PaveSet& aPSF,
113                  TColStd_IndexedMapOfInteger& aMapUnUsed);
114 static
115   Standard_Boolean VertexRangeTolerance(const Standard_Integer nV,
116                                         const Standard_Integer nF1,
117                                         const Standard_Integer nF2,
118                                         const BOPTools_InterferencePool& anIntrPool,
119                                         Standard_Real& aTolV);
120 static 
121   void FaceAndEdgeMap(const Standard_Integer nF,
122                       const BOPTools_InterferencePool& anIntrPool,
123                       TColStd_IndexedMapOfInteger& aMEF);
124 static
125   void ProcessAloneStickVertices(const Standard_Integer nF1,
126                                  const Standard_Integer nF2,
127                                  const BOPTools_PaveSet& aPSF,
128                                  BOPTools_SequenceOfCurves& aSCvs,
129                                  const BOPTools_InterferencePool& anIntrPool,
130                                  BOPTools_PaveFiller& aPF,
131                                  TColStd_SequenceOfInteger& aSeqVx,
132                                  TColStd_SequenceOfReal& aSeqTolVx);
133 //modified by NIZNHY-PKV Wed Aug 31 10:32:52 2011f 
134 static
135   void ProcessAloneStickVertices(const Standard_Integer nF1,
136                                  const Standard_Integer nF2,
137                                  const BOPTools_PaveSet& aPSF,
138                                  BOPTools_SequenceOfCurves& aSCvs,
139                                  BOPTools_PaveFiller& aPF,
140                                  TColStd_SequenceOfInteger& aSeqVx,
141                                  TColStd_SequenceOfReal& aSeqTolVx);
142 //modified by NIZNHY-PKV Wed Aug 31 10:32:59 2011t 
143 //wkar OCC334 t
144
145 static
146   Standard_Boolean IsPairFound(const Standard_Integer nF1,
147                                const Standard_Integer nF2,
148                                BOPTools_InterferencePool* myIntrPool,
149                                BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWhat,
150                                BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWith);
151
152 static Standard_Boolean CheckNewVertexAndUpdateData(const TopoDS_Vertex&              theVertex,
153                                                     const Standard_Real               theParamOnE,
154                                                     const TopoDS_Edge&                theEdge,
155                                                     const Standard_Real               theParamOnCurve,
156                                                     const Standard_Integer            theIndexF1,
157                                                     const Standard_Integer            theIndexF2,
158                                                     const Standard_Real               theTolerance,
159                                                     const BOPTools_PInterferencePool& theIntrPool,
160                                                     const BooleanOperations_PShapesDataStructure& theDS,
161                                                     IntTools_Context*                 theContext,
162                                                     const BOPTools_PaveSet&           theEdgePaveSet,
163                                                     const Standard_Boolean            bAddNewVertex,
164                                                     const Standard_Boolean            bAddOldVertex,
165                                                     BOPTools_Curve&                   theBC,
166                                                     BOPTools_Pave&                    thePaveToPut,
167                                                     Standard_Boolean&                 bAddNewVertexOut,
168                                                     Standard_Boolean&                 bAddOldVertexOut);
169
170 static void AddInterfForAdjacentFace(const Standard_Integer            theEdgeIndex,
171                                      const Standard_Integer            theIndexF1,
172                                      const Standard_Integer            theIndexF2,
173                                      BOPTools_PInterferencePool        theIntrPool,
174                                      const BooleanOperations_PShapesDataStructure& theDS);
175
176 static Standard_Boolean RejectPaveBlock(const IntTools_Curve& theC,
177                                         const Standard_Real   theT1,
178                                         const Standard_Real   theT2,
179                                         const TopoDS_Vertex&  theV,
180                                         Standard_Real&        theRT);
181
182 static Standard_Boolean ModifFFTol(const TopoDS_Face& theF1,
183                                    const TopoDS_Face& theF2,
184                                    Standard_Real&     theTF);
185
186 static Standard_Integer RejectBuildingEdge(const IntTools_Curve& theC,
187                                            const TopoDS_Vertex&  theV1,
188                                            const TopoDS_Vertex&  theV2,
189                                            const Standard_Real   theT1,
190                                            const Standard_Real   theT2,
191                                            const TopTools_ListOfShape& theL,
192                                            Standard_Real&        theTF);
193
194 //modified by NIZNHY-PKV Sat Mar 05 12:23:05 2011f
195 static
196   void CorrectTolR3D(BOPTools_PaveFiller& aPF,
197                      const BOPTools_SSInterference& aFF,
198                      const TColStd_MapOfInteger& aMVStick,
199                      Standard_Real& aTolR3D);
200 //modified by NIZNHY-PKV Sat Mar 05 12:23:07 2011t
201
202 //=======================================================================
203 // function: PerformFF
204 // purpose: 
205 //=======================================================================
206   void BOPTools_PaveFiller::PerformFF() 
207 {
208   myIsDone=Standard_False;
209   Standard_Boolean bIsFound;
210   Standard_Integer n1, n2, anIndexIn=0, nF1, nF2, aNbFFs, aBlockLength;
211   BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aMapWhat, aMapWith;
212   //
213   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
214   //
215   //  F/F Interferences  [BooleanOperations_SurfaceSurface]
216   myDSIt.Initialize(TopAbs_FACE, TopAbs_FACE);
217   //
218   // BlockLength correction
219   aNbFFs=ExpectedPoolLength();
220   aBlockLength=aFFs.BlockLength();
221   if (aNbFFs > aBlockLength) {
222     aFFs.SetBlockLength(aNbFFs);
223   }
224   //
225   for (; myDSIt.More(); myDSIt.Next()) {
226     Standard_Boolean justaddinterference = Standard_True;
227     myDSIt.Current(n1, n2, justaddinterference);
228
229     if(justaddinterference) {
230       if (!myIntrPool->IsComputed(n1, n2)) {
231
232         if(n1 < n2) {
233           nF1 = n1;
234           nF2 = n2;
235         }
236         else {
237           nF1 = n2;
238           nF2 = n1;
239         }
240         //
241         bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
242         //
243         if (!bIsFound) {
244           myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
245         }
246         else {
247           IntTools_SequenceOfPntOn2Faces aPnts;
248           IntTools_SequenceOfCurves aCvs;
249
250           BOPTools_SSInterference anInterf (nF1, nF2, 1.e-07, 1.e-07, aCvs, aPnts);
251           anIndexIn=aFFs.Append(anInterf);
252           myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
253         }
254       }
255       continue;
256     }
257     //
258     if (myIntrPool->IsComputed(n1, n2)) {
259       continue;
260     }
261     //
262     nF1=n1; 
263     nF2=n2; 
264     if (nF1 > nF2) {
265       Standard_Integer iTmp;
266       iTmp=nF1;
267       nF1=nF2;
268       nF2=iTmp;
269     }
270     //
271     TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
272     TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
273     //
274     IntSurf_ListOfPntOn2S aListOfPnts;
275     GeomAPI_ProjectPointOnSurf& aProj1 = myContext.ProjPS(aF1);
276     GeomAPI_ProjectPointOnSurf& aProj2 = myContext.ProjPS(aF2);
277
278     BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
279     TColStd_MapOfInteger aMapEdgeIndex1, aMapEdgeIndex2;
280     for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
281       Standard_Integer nF = (fIt == 0) ? nF1 : nF2;
282       for(Standard_Integer sIt1 = 1; sIt1 <= myDS->NumberOfSuccessors(nF); sIt1++) {
283         Standard_Integer nIndexS1 = myDS->GetSuccessor(nF, sIt1);
284         if(myDS->GetShapeType(nIndexS1) == TopAbs_EDGE) {
285           if(fIt == 0)
286             aMapEdgeIndex1.Add(nIndexS1);
287           else
288             aMapEdgeIndex2.Add(nIndexS1);
289         }
290         else {
291           for(Standard_Integer sIt2 = 1; sIt2 <= myDS->NumberOfSuccessors(nIndexS1); sIt2++) {
292             Standard_Integer nIndexS2 = myDS->GetSuccessor(nIndexS1, sIt2);
293             
294             if(myDS->GetShapeType(nIndexS2) == TopAbs_EDGE) {
295               if(fIt == 0)
296                 aMapEdgeIndex1.Add(nIndexS2);
297               else
298                 aMapEdgeIndex2.Add(nIndexS2);
299             }
300           }
301         }
302       }
303       
304       TColStd_MapIteratorOfMapOfInteger anIt;
305       if(fIt == 0)
306         anIt.Initialize(aMapEdgeIndex1);
307       else
308         anIt.Initialize(aMapEdgeIndex2);
309
310       Standard_Integer nFOpposite = (fIt == 0) ? nF2 : nF1;      
311
312       for(; anIt.More(); anIt.Next()) {
313         Standard_Integer nIndexE = anIt.Key();
314
315         for(Standard_Integer interIt = 1; interIt <= aEFs.Length(); interIt++) {
316           const BOPTools_ESInterference& aEF = aEFs(interIt);          
317
318           if((aEF.Index1() == nIndexE) && (nFOpposite == aEF.Index2())) {
319             IntTools_CommonPrt aCP = aEF.CommonPrt();
320
321             if(aCP.Type() == TopAbs_VERTEX) {
322               Standard_Real aPar = aCP.VertexParameter1();
323               // compute points and add to the list
324               Standard_Real f,l;
325               Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(myDS->GetShape(nIndexE)), f,l);
326               Handle(Geom2d_Curve) aPCurve;
327               if(fIt == 0) {
328                 aPCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myDS->GetShape(nIndexE)),
329                                                     aF1, f, l);
330               }
331               else {
332                 aPCurve = BRep_Tool::CurveOnSurface(TopoDS::Edge(myDS->GetShape(nIndexE)),
333                                                     aF2, f, l);
334               }         
335                                                                        
336               gp_Pnt aPoint;
337               aCurve->D0(aPar, aPoint);
338               Standard_Real U1,V1,U2,V2;
339               IntSurf_PntOn2S aPnt;
340               if(!aPCurve.IsNull()) {
341                 gp_Pnt2d aP2d = aPCurve->Value(aPar);
342                 if(fIt == 0) {
343                   aProj2.Perform(aPoint);
344                   if(aProj2.IsDone()) {
345                     aProj2.LowerDistanceParameters(U2,V2);
346                     aPnt.SetValue(aP2d.X(),aP2d.Y(),U2,V2);
347                     aListOfPnts.Append(aPnt); 
348                   }
349                 }
350                 else {
351                   aProj1.Perform(aPoint);
352                   if(aProj1.IsDone()) {
353                     aProj1.LowerDistanceParameters(U1,V1);
354                     aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
355                     aListOfPnts.Append(aPnt); 
356                   }
357                 }
358               }              
359               else {
360                 aProj1.Perform(aPoint);
361                 aProj2.Perform(aPoint);
362                 if(aProj1.IsDone() && aProj2.IsDone()){
363                   aProj1.LowerDistanceParameters(U1,V1);
364                   aProj2.LowerDistanceParameters(U2,V2);
365                   aPnt.SetValue(U1,V1,U2,V2);
366                   aListOfPnts.Append(aPnt);                
367                 }
368               }
369             }
370           }
371         }
372       }
373     }
374     //
375     // FF
376     Standard_Boolean bToApproxC3d, bToApproxC2dOnS1, bToApproxC2dOnS2, bIsDone;
377     Standard_Real anApproxTol, aTolR3D, aTolR2D;
378     //
379     bToApproxC3d     = mySectionAttribute.Approximation();
380     bToApproxC2dOnS1 = mySectionAttribute.PCurveOnS1();
381     bToApproxC2dOnS2 = mySectionAttribute.PCurveOnS2();
382     //
383     anApproxTol=1.e-7;
384
385     IntTools_FaceFace aFF;
386     aFF.SetParameters (bToApproxC3d, 
387                        bToApproxC2dOnS1, 
388                        bToApproxC2dOnS2,
389                        anApproxTol);
390     //
391     if (!aListOfPnts.IsEmpty()) {
392       aFF.SetList(aListOfPnts);
393     }
394     //
395     aFF.Perform(aF1, aF2);
396     //
397     bIsDone=aFF.IsDone();
398     if (bIsDone) {
399       // Add Interference to the Pool
400       aTolR3D=aFF.TolReached3d();
401       aTolR2D=aFF.TolReached2d();
402       if (aTolR3D < 1.e-7){
403         aTolR3D=1.e-7;
404       } 
405       aFF.PrepareLines3D();
406       //
407       anIndexIn=0;
408       Standard_Integer aNbCurves, aNbPoints;
409
410       const IntTools_SequenceOfCurves& aCvs=aFF.Lines();
411       aNbCurves=aCvs.Length();
412       //
413       const IntTools_SequenceOfPntOn2Faces& aPnts=aFF.Points();
414       aNbPoints=aPnts.Length();
415       
416       if (!aNbCurves && !aNbPoints) {
417         //
418         bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
419         //
420         if (!bIsFound) {
421           myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
422           continue;
423         }
424       }
425       //
426       BOPTools_SSInterference anInterf (nF1, nF2, aTolR3D, aTolR2D, aCvs, aPnts);
427       anIndexIn=aFFs.Append(anInterf);
428       
429       myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn);
430     } //if (bIsDone)
431     //
432     else {
433       anIndexIn=0;
434       //
435       bIsFound=IsPairFound(nF1, nF2, myIntrPool, aMapWhat, aMapWith);
436       //
437       if (!bIsFound) {
438         myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn); 
439       }
440       else {
441         IntTools_SequenceOfPntOn2Faces aPnts;
442         IntTools_SequenceOfCurves aCvs;
443         
444         BOPTools_SSInterference anInterf (nF1, nF2, 1.e-07, 1.e-07, aCvs, aPnts);
445         anIndexIn=aFFs.Append(anInterf);
446         myIntrPool->AddInterference (nF1, nF2, BooleanOperations_SurfaceSurface, anIndexIn);
447       }
448     }
449   }// for (; myDSIt.More(); myDSIt.Next()) 
450   myIsDone=Standard_True;
451 }
452 //=======================================================================
453 // function: MakeBlocks
454 // purpose: 
455 //=======================================================================
456   void BOPTools_PaveFiller::MakeBlocks()
457 {
458   Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, aBid=0, nV1, nV2;
459   Standard_Real aTolR3D, aT1, aT2;
460   Standard_Boolean bValid, bCoincide;
461
462   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
463   
464   aNbFFs=aFFs.Extent();
465
466   for (i=1; i<=aNbFFs; i++) {
467     BOPTools_SSInterference& aFFi=aFFs(i);
468     //  
469     nF1=aFFi.Index1();
470     nF2=aFFi.Index2();
471     //
472     // Curves' tolerance
473     aTolR3D=aFFi.TolR3D();
474     //
475     // Faces
476     const TopoDS_Face& aF1=TopoDS::Face(myDS->GetShape(nF1));
477     const TopoDS_Face& aF2=TopoDS::Face(myDS->GetShape(nF2));
478
479     TColStd_MapOfInteger aMap;
480     BOPTools_ListOfPaveBlock aLPB;
481     SplitsInFace (aBid, nF1, nF2, aLPB);
482     SplitsInFace (aBid, nF2, nF1, aLPB);
483     SplitsOnFace (aBid, nF1, nF2, aLPB);
484     
485     BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
486     for (; anIt.More(); anIt.Next()) {
487       const BOPTools_PaveBlock& aPB=anIt.Value();
488       aFFi.AppendBlock(aPB);
489       nV1=aPB.Pave1().Index();
490       nV2=aPB.Pave2().Index();
491       aMap.Add(nV1);
492       aMap.Add(nV2);
493     }
494     // Put existing paves on curves
495     //     BOPTools_PaveSet aPSF;
496     //     PrepareSetForFace (nF1, nF2, aPSF);
497
498     BOPTools_SequenceOfCurves& aSCvs = aFFi.Curves();
499     aNbCurves=aSCvs.Length();
500
501     // 
502     // Pave Blocks On Curves
503     // 
504     Standard_Boolean bIsPaveBlock;
505     Standard_Integer iCheckIntermediatePoint;
506     // 
507     for (j=1; j<=aNbCurves; j++) {
508       BOPTools_Curve& aBC=aSCvs(j);
509       const IntTools_Curve& aC= aBC.Curve();
510       
511       BOPTools_PaveSet& aPaveSet=aBC.Set();
512       BOPTools_PaveBlockIterator aPBIter(0, aPaveSet);
513       for (; aPBIter.More(); aPBIter.Next()) {
514         BOPTools_PaveBlock& aPBNew=aPBIter.Value();
515         aPBNew.SetCurve(aC);
516         aPBNew.SetFace1(nF1);
517         aPBNew.SetFace2(nF2);
518         //
519         nV1=aPBNew.Pave1().Index();
520         nV2=aPBNew.Pave2().Index();
521         
522         if (aMap.Contains(nV1) && aMap.Contains(nV2)) {
523           //
524           const BOPTools_ListOfPaveBlock& aLPBExisting=aFFi.PaveBlocks();
525           bIsPaveBlock=IsPaveBlock(nV1, nV2, aLPBExisting);
526           //
527           iCheckIntermediatePoint=1;
528           if (bIsPaveBlock) {
529             BOPTools_ListIteratorOfListOfPaveBlock anItLPB(aLPBExisting);
530             
531             for (; anItLPB.More(); anItLPB.Next()) {
532               const BOPTools_PaveBlock& aPBR=anItLPB.Value();
533               iCheckIntermediatePoint=
534                 CheckIntermediatePoint(aPBNew, aPBR, aTolR3D);
535               if (!iCheckIntermediatePoint) {
536                 break;
537               }
538             }
539             bIsPaveBlock=bIsPaveBlock && !iCheckIntermediatePoint;
540           }
541           //
542           if (bIsPaveBlock) {
543             continue;
544           }
545         }
546         //
547         else {
548           iCheckIntermediatePoint=0;
549         } 
550         //
551         aT1=aPBNew.Pave1().Param();
552         aT2=aPBNew.Pave2().Param();
553         // 
554         if((nV1 == nV2) && (Abs(aT2 - aT1) < Precision::PConfusion())) {
555             continue;
556         }
557         // 
558         // Checking of validity in 2D
559         //
560         Standard_Real aTolerance = (aTolR3D < 1.e-3) ? 1.e-3 : aTolR3D;
561         bValid=myContext.IsValidBlockForFaces(aT1, aT2, aC, aF1, aF2, aTolerance);
562         //
563         if (!bValid) {
564           continue;
565         }
566         //
567         // Checking the  paveblocks for coinsidence with aLPB
568         bCoincide=CheckCoincidence (aPBNew, aFFi);
569         //
570         bCoincide=bCoincide && !iCheckIntermediatePoint;
571         //
572         if (bCoincide) {
573           continue;
574         }
575         //
576         // reject pave block (FF) v1==v2 for too small sect. edge
577         TopoDS_Vertex aV1=TopoDS::Vertex(myDS->GetShape(nV1));
578         TopoDS_Vertex aV2=TopoDS::Vertex(myDS->GetShape(nV2));
579         Standard_Boolean rejectPaveBlock = Standard_False;
580         if(aV1.IsSame(aV2)) {
581           Standard_Real aRT = 1.e-7;
582           rejectPaveBlock = RejectPaveBlock(aC,aT1,aT2,aV1,aRT);
583           if(rejectPaveBlock) {
584             if(aRT > 1.e-7) {
585               BRep_Builder BB;
586               BB.UpdateVertex( aV1, 2*aRT );
587             }
588             continue;
589           }
590         }
591         //
592         aBC.AppendNewBlock(aPBNew);
593       }
594     } // end of for (j=1; j<=aNbCurves; j++)
595   }// end of for (i=1; i<=aNbFFs; i++)
596 }
597 //=======================================================================
598 // function: MakeAloneVertices
599 // purpose: 
600 //=======================================================================
601   void BOPTools_PaveFiller::MakeAloneVertices()
602 {
603   Standard_Integer i, j, k, aNbFFs, aNbCurves, nF1, nF2, nV, aNbAlone, aNbV;
604   Standard_Boolean bFlag=Standard_False;
605
606   BOPTools_ListIteratorOfListOfPave anIt;
607   TColStd_IndexedMapOfInteger aMap;
608   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
609   
610   aNbFFs=aFFs.Extent();
611   for (i=1; i<=aNbFFs; i++) {
612     BOPTools_SSInterference& aFFi=aFFs(i);
613
614     const IntTools_SequenceOfPntOn2Faces& aSeqAlonePnts=aFFi.AlonePnts();
615     aNbAlone=aSeqAlonePnts.Length();
616     
617     if (!aNbAlone) {
618       continue;
619     }
620
621     nF1=aFFi.Index1();
622     nF2=aFFi.Index2();
623     //
624     TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));
625     TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));
626     // 
627     // 1. fill aMap where all indices for (F/F) vertices are
628     aMap.Clear();
629     
630     BOPTools_PaveSet aPSF;
631     
632     PrepareSetForFace (nF1, nF2, aPSF);
633     const BOPTools_ListOfPave& aLPaves=aPSF.Set();
634     anIt.Initialize(aLPaves);
635     for (; anIt.More(); anIt.Next()) {
636       const BOPTools_Pave& aPave=anIt.Value();
637       nV=aPave.Index();
638       aMap.Add(nV);
639     }
640
641     BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
642     aNbCurves=aSCvs.Length();
643     for (j=1; j<=aNbCurves; j++) {
644       BOPTools_Curve& aBC=aSCvs(j);
645       const BOPTools_PaveSet& aCPSF=aBC.Set();
646       const BOPTools_ListOfPave& aLPs=aCPSF.Set();
647       anIt.Initialize(aLPs);
648       for (; anIt.More(); anIt.Next()) {
649         const BOPTools_Pave& aPv=anIt.Value();
650         nV=aPv.Index();
651         aMap.Add(nV);
652       }
653     }
654     //
655     // 2. check alone points on closure with aMap's vertices
656     Standard_Integer iVV;
657     Standard_Real aTolVAlone, aTolF1, aTolF2;
658     TopoDS_Vertex aVAlone;
659     BRep_Builder aBB;
660     
661     aTolF1=BRep_Tool::Tolerance(aF1);
662     aTolF2=BRep_Tool::Tolerance(aF2);
663     aTolVAlone=aTolF1+aTolF2;
664
665     aNbV=aMap.Extent();
666     for (j=1; j<=aNbAlone; ++j) {
667       const IntTools_PntOn2Faces& aP2F=aSeqAlonePnts(j);
668       const IntTools_PntOnFace& aPF1=aP2F.P1();
669       const gp_Pnt& aPAlone=aPF1.Pnt();
670       aBB.MakeVertex(aVAlone, aPAlone, aTolVAlone);
671       //
672       bFlag=Standard_True;
673       //
674       for (k=1; k<=aNbV; ++k) {
675         nV=aMap(k);
676         const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
677         
678         iVV= IntTools_Tools::ComputeVV (aVAlone, aV);
679         if (!iVV) {
680           // It means that aVAlone and aV coinsided so 
681           // we do not need to insert aVAlone into the DS
682           bFlag=Standard_False;
683           break;
684         }
685         
686       }
687       if (bFlag) {
688         Standard_Boolean bVF;
689         Standard_Integer aNewShape;
690         //
691         bVF=myContext.IsValidPointForFaces (aPAlone, aF1, aF2, 1.e-3);
692         //
693         if (bVF) {
694           BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
695           myDS->InsertShapeAndAncestorsSuccessors(aVAlone, anASSeq);
696           aNewShape=myDS->NumberOfInsertedShapes();
697           myDS->SetState (aNewShape, BooleanOperations_ON);
698           //
699           TColStd_ListOfInteger& anAloneVertices=aFFi.AloneVertices();
700           anAloneVertices.Append(aNewShape);
701         }
702       }
703     }
704     
705   }
706 }
707 //=======================================================================
708 // function: CheckCoincidence
709 // purpose: 
710 //=======================================================================
711   Standard_Boolean BOPTools_PaveFiller::CheckCoincidence(const BOPTools_PaveBlock& aPB,
712                                                          const BOPTools_SSInterference& aFFi)
713                                                          
714 {
715   Standard_Real aTolC, aTE, aT11, aT12;
716   Standard_Integer nV11, nV12, nV21, nV22, iVV, iVE, nE2, iCount=0, iCountExt=1;
717   Standard_Integer iV;
718
719   aTolC=aFFi.TolR3D();
720   // V11
721   const BOPTools_Pave& aPave11=aPB.Pave1();
722   nV11=aPave11.Index();
723   const TopoDS_Vertex& aV11=TopoDS::Vertex(myDS->GetShape(nV11));
724   aT11=aPave11.Param();
725   // V12
726   const BOPTools_Pave& aPave12=aPB.Pave2();
727   nV12=aPave12.Index();
728   const TopoDS_Vertex& aV12=TopoDS::Vertex(myDS->GetShape(nV12));
729   aT12=aPave12.Param();
730   //
731   const BOPTools_ListOfPaveBlock& aLPB=aFFi.PaveBlocks();
732   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
733   for (; anIt.More(); anIt.Next()) {
734     
735     iCount=0;
736     
737     const BOPTools_PaveBlock& aPBR=anIt.Value();
738     // V21
739     const BOPTools_Pave& aPave21=aPBR.Pave1();
740     nV21=aPave21.Index();
741     const TopoDS_Vertex& aV21=TopoDS::Vertex(myDS->GetShape(nV21));
742     // V22
743     const BOPTools_Pave& aPave22=aPBR.Pave2();
744     nV22=aPave22.Index();
745     const TopoDS_Vertex& aV22=TopoDS::Vertex(myDS->GetShape(nV22));
746     // E2
747     nE2=aPBR.Edge();
748     const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2));
749     //
750     // VV
751     iV=0;
752     iVV=IntTools_Tools::ComputeVV (aV11, aV21);
753     if (!iVV) {
754       iCount++;
755       iV++;
756       if (iCount>iCountExt) {
757         break;
758       }
759     }
760     
761     iVV=IntTools_Tools::ComputeVV (aV11, aV22);
762     if (!iVV) {
763       iCount++;
764       iV++;
765       if (iCount>iCountExt) {
766         break;
767       }
768     }
769
770     // VE
771     if (!iV) {
772       iVE=myContext.ComputeVE (aV11, aE2, aTE);
773       if (!iVE) {
774         iCount++;
775         if (iCount>iCountExt) {
776           break;
777         }
778       }
779     }
780     //
781     // VV
782     iV=0;
783     iVV=IntTools_Tools::ComputeVV (aV12, aV21);
784     if (!iVV) {
785       iCount++;
786       iV++;
787       if (iCount>iCountExt) {
788         break;
789       }
790     }
791
792     iVV=IntTools_Tools::ComputeVV (aV12, aV22);
793     if (!iVV) {
794       iCount++;
795       iV++;
796       if (iCount>iCountExt) {
797         break;
798       }
799     }
800     // VE
801     if (!iV) {
802       //
803       iVE=myContext.ComputeVE (aV12, aE2, aTE);
804       //
805       if (!iVE) {
806         iCount++;
807         if (iCount>iCountExt) {
808           break;
809         }
810       }
811     }
812     
813   } // next aPBR
814   return (iCount>iCountExt);
815 }
816 //=======================================================================
817 // function: CheckIntermediatePoint
818 // purpose: 
819 //=======================================================================
820   Standard_Integer BOPTools_PaveFiller::CheckIntermediatePoint(const BOPTools_PaveBlock& aPB,
821                                                                const BOPTools_PaveBlock& aPBR,
822                                                                const Standard_Real aTolC)
823                                                          
824 {
825   Standard_Real aT11, aT12, aTM, aTmp;
826   Standard_Integer iVM, nE2;
827
828   gp_Pnt aPM;
829   BRep_Builder aBB;
830   TopoDS_Vertex aVM;
831   // 
832   // Vertex
833   const BOPTools_Pave& aPave11=aPB.Pave1();
834   aT11=aPave11.Param();
835   // 
836   const BOPTools_Pave& aPave12=aPB.Pave2();
837   aT12=aPave12.Param();
838   //
839   aTM=IntTools_Tools::IntermediatePoint (aT11, aT12);
840   //
841   const IntTools_Curve& aIC=aPB.Curve();
842   aIC.D0(aTM, aPM);
843   //
844   aBB.MakeVertex (aVM, aPM, aTolC);
845   //
846   //Edge
847   nE2=aPBR.Edge();
848   const TopoDS_Edge& aE2=TopoDS::Edge(myDS->GetShape(nE2));
849   // VE
850   iVM=myContext.ComputeVE(aVM, aE2, aTmp); 
851   //
852   return iVM;
853 }
854 //=======================================================================
855 // function: PutBoundPaveOnCurve
856 // purpose: 
857 //=======================================================================
858   void BOPTools_PaveFiller::PutBoundPaveOnCurve(BOPTools_Curve& aBC,
859                                                 BOPTools_SSInterference& aFFi)
860
861   Standard_Boolean bHasBounds, bVF;
862   
863
864   const IntTools_Curve& aIC=aBC.Curve();
865   bHasBounds=aIC.HasBounds ();
866   
867   if (!bHasBounds){
868     return;
869   }
870
871   Standard_Integer nF1, nF2;
872   Standard_Real aT1, aT2, aTolR3D;
873   gp_Pnt aP1, aP2;
874   //
875   // Bounds
876   aIC.Bounds (aT1, aT2, aP1, aP2);
877   //
878   // Faces
879   nF1=aFFi.Index1();
880   nF2=aFFi.Index2();
881   //
882   aTolR3D=aFFi.TolR3D();
883   //
884   TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
885   TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
886   //
887   bVF=myContext.IsValidPointForFaces (aP1, aF1, aF2, aTolR3D);
888   //
889   if (bVF) {
890     PutBoundPaveOnCurve (aP1, aT1, aBC, aFFi);
891   }
892   //
893   bVF=myContext.IsValidPointForFaces (aP2, aF1, aF2, aTolR3D);
894   //
895   if (bVF) {
896     PutBoundPaveOnCurve (aP2, aT2, aBC, aFFi);
897   }
898 }
899 //=======================================================================
900 // function: PutBoundPaveOnCurve
901 // purpose: 
902 //=======================================================================
903   void BOPTools_PaveFiller::PutBoundPaveOnCurve(const gp_Pnt& aP,
904                                                 const Standard_Real aT,
905                                                 BOPTools_Curve& aBC,
906                                                 BOPTools_SSInterference& aFFi)
907
908   Standard_Boolean bFound1, bFound2;
909   Standard_Integer nV;
910   Standard_Real aTolV=aFFi.TolR3D();
911
912   BOPTools_Pave aPave1, aPave2, aPave;
913   BOPTools_PaveSet& aCPS=aBC.Set();
914   BOPTools_PaveSet& aFFiPS=aFFi.NewPaveSet();
915   const IntTools_Curve& aIC=aBC.Curve();
916
917   bFound1=FindPave(aP, aTolV, aCPS  , aPave1);
918   bFound2=FindPave(aP, aTolV, aFFiPS, aPave2);
919   
920   if (!bFound1 && !bFound2) {
921     TopoDS_Vertex aNewVertex;
922     BOPTools_Tools::MakeNewVertex(aP, aTolV, aNewVertex);
923     //
924     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
925     myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
926     nV=myDS->NumberOfInsertedShapes();
927     aPave.SetIndex(nV);
928     aPave.SetParam(aT);
929
930     aCPS.Append(aPave);
931     aFFiPS.Append(aPave);
932     //
933     // Append Techno Vertex to the Curve
934     TColStd_ListOfInteger& aTVs=aBC.TechnoVertices();
935     aTVs.Append(nV);
936   }
937   
938   if (bFound1 && !bFound2) {
939     nV=aPave1.Index();
940     aPave.SetIndex(nV);
941     aPave.SetParam(aT);
942     aFFiPS.Append(aPave);
943     //
944     const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
945     BOPTools_Tools::UpdateVertex (aIC, aT, aV);
946   }
947   
948   if (!bFound1 && bFound2) {
949     nV=aPave2.Index();
950     aPave.SetIndex(nV);
951     aPave.SetParam(aT);
952     aCPS.Append(aPave);
953     //
954     const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
955     BOPTools_Tools::UpdateVertex (aIC, aT, aV);
956   }
957 }
958
959 //=======================================================================
960 // function: PutBoundPaveOnCurveSpec
961 // purpose: 
962 //=======================================================================
963   void BOPTools_PaveFiller::PutBoundPaveOnCurveSpec(BOPTools_Curve& aBC,
964                                                     BOPTools_SSInterference& aFFi)
965
966   Standard_Boolean bHasBounds, bVF;
967   
968
969   const IntTools_Curve& aIC=aBC.Curve();
970   bHasBounds=aIC.HasBounds ();
971   
972   if (!bHasBounds){
973     return;
974   }
975
976   Standard_Integer nF1, nF2;
977   Standard_Real aT1, aT2, aTolR3D;
978   gp_Pnt aP1, aP2;
979   //
980   // Bounds
981   aIC.Bounds (aT1, aT2, aP1, aP2);
982   //
983   // Faces
984   nF1=aFFi.Index1();
985   nF2=aFFi.Index2();
986   //
987   aTolR3D=aFFi.TolR3D();
988   //
989   TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
990   TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
991   //
992   bVF=myContext.IsValidPointForFaces (aP1, aF1, aF2, aTolR3D);
993   //
994   if (bVF) {
995     PutBoundPaveOnCurveSpec (aP1, aT1, aBC, aFFi);
996   }
997   //
998   bVF=myContext.IsValidPointForFaces (aP2, aF1, aF2, aTolR3D);
999   //
1000   if (bVF) {
1001     PutBoundPaveOnCurveSpec (aP2, aT2, aBC, aFFi);
1002   }
1003 }
1004 //=======================================================================
1005 // function: PutBoundPaveOnCurveSpec
1006 // purpose: 
1007 //=======================================================================
1008   void BOPTools_PaveFiller::PutBoundPaveOnCurveSpec(const gp_Pnt& aP,
1009                                                     const Standard_Real aT,
1010                                                     BOPTools_Curve& aBC,
1011                                                     BOPTools_SSInterference& aFFi)
1012
1013   Standard_Boolean bFound1, bFound2;
1014   Standard_Integer nV;
1015   Standard_Real aTolV=aFFi.TolR3D();
1016
1017   BOPTools_Pave aPave1, aPave2, aPave;
1018   BOPTools_PaveSet& aCPS=aBC.Set();
1019   BOPTools_PaveSet& aFFiPS=aFFi.NewPaveSet();
1020   const IntTools_Curve& aIC=aBC.Curve();
1021
1022   bFound1=FindPave(aP, aTolV, aCPS  , aPave1);
1023   bFound2=FindPave(aP, aTolV, aFFiPS, aPave2);
1024   
1025   if (!bFound1 && !bFound2) {
1026     TopoDS_Vertex aNewVertex;
1027     BOPTools_Tools::MakeNewVertex(aP, aTolV, aNewVertex);
1028     //
1029     BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
1030     myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
1031     nV=myDS->NumberOfInsertedShapes();
1032     aPave.SetIndex(nV);
1033     aPave.SetParam(aT);
1034
1035     aCPS.Append(aPave);
1036     aFFiPS.Append(aPave);
1037     //
1038     // Append Techno Vertex to the Curve
1039     TColStd_ListOfInteger& aTVs=aBC.TechnoVertices();
1040     aTVs.Append(nV);
1041     //
1042     //To check, if face boundary must be split by new vertex
1043     TopTools_MapOfShape aMap;
1044     Standard_Real aPar;
1045     Standard_Integer anErrStat;
1046     Standard_Integer aWhat, aWith, anIndexIn;
1047     BOPTools_CArray1OfVEInterference& aVEs=myIntrPool->VEInterferences();
1048     // Faces
1049     Standard_Integer nF1=aFFi.Index1();
1050     const TopoDS_Shape aF1 = myDS->GetShape(nF1);
1051     //
1052     Standard_Integer nF2=aFFi.Index2();
1053     const TopoDS_Shape aF2 = myDS->GetShape(nF2);
1054     //
1055     //
1056     Standard_Integer aRank = myDS->Rank(nF1);
1057     TopExp_Explorer anExp(aF1, TopAbs_EDGE);
1058     for(; anExp.More(); anExp.Next()) {
1059
1060       const TopoDS_Shape& anE = anExp.Current();
1061       if (BRep_Tool::Degenerated(TopoDS::Edge(anE))){
1062         continue;
1063       }
1064
1065       if(!aMap.Add(anE)) continue;
1066
1067       anErrStat = 
1068         myContext.ComputeVE(aNewVertex, TopoDS::Edge(anE), aPar);
1069       if(anErrStat) continue;
1070       //
1071       Standard_Real aT1, aT2;
1072       gp_Pnt aP1, aP2;
1073       aIC.Bounds(aT1, aT2, aP1, aP2);
1074       //Check if any other point on curve belongs edge
1075       aT1 = 0.5*(aT1+aT2);
1076       aIC.D0(aT1, aP1);
1077       TopoDS_Vertex aNewVertex1;
1078       BOPTools_Tools::MakeNewVertex(aP1, aTolV, aNewVertex1);
1079       anErrStat = 
1080         myContext.ComputeVE(aNewVertex1, TopoDS::Edge(anE), aT1);
1081       if(!anErrStat) continue; //curve and edge seem to be coincide
1082       
1083       aWhat = nV;
1084       aWith = myDS->ShapeIndex(anE, aRank);
1085       BOPTools_VEInterference anInterf (aWhat, aWith, aPar);
1086       anIndexIn=aVEs.Append(anInterf);
1087       //
1088       // Add Pave to the Edge's myPavePool
1089       BOPTools_Pave aPave3(aWhat, aPar, BooleanOperations_VertexEdge);
1090       aPave3.SetInterference(anIndexIn);
1091       BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(aWith));
1092       aPaveSet.Append(aPave3);
1093
1094       //
1095       // State for the Vertex in DS;
1096       myDS->SetState (aWhat, BooleanOperations_ON);
1097       // Insert Vertex in Interference Object
1098       BOPTools_VEInterference& aVE=aVEs(anIndexIn);
1099       aVE.SetNewShape(aWhat);
1100
1101       PreparePaveBlocks(aWith);
1102       RecomputeCommonBlocks(aWith);
1103     }
1104     //
1105     aRank = myDS->Rank(nF2);
1106     anExp.Init(aF2, TopAbs_EDGE);
1107     for(; anExp.More(); anExp.Next()) {
1108       const TopoDS_Shape& anE = anExp.Current();
1109       if (BRep_Tool::Degenerated(TopoDS::Edge(anE))){
1110         continue;
1111       }
1112
1113       if(!aMap.Add(anE)) continue;
1114
1115       anErrStat = 
1116         myContext.ComputeVE(aNewVertex, TopoDS::Edge(anE), aPar);
1117       if(anErrStat) continue;
1118       //
1119       Standard_Real aT1, aT2;
1120       gp_Pnt aP1, aP2;
1121       aIC.Bounds(aT1, aT2, aP1, aP2);
1122       //Check if any other point on curve belongs edge
1123       aT1 = 0.5*(aT1+aT2);
1124       aIC.D0(aT1, aP1);
1125       TopoDS_Vertex aNewVertex1;
1126       BOPTools_Tools::MakeNewVertex(aP1, aTolV, aNewVertex1);
1127       anErrStat = 
1128         myContext.ComputeVE(aNewVertex1, TopoDS::Edge(anE), aT1);
1129       if(!anErrStat) continue; //curve and edge seem to be coincide
1130       
1131       aWhat = nV;
1132       aWith = myDS->ShapeIndex(anE, aRank);
1133       BOPTools_VEInterference anInterf (aWhat, aWith, aPar);
1134       anIndexIn=aVEs.Append(anInterf);
1135       //
1136       // Add Pave to the Edge's myPavePool
1137       BOPTools_Pave aPave3(aWhat, aPar, BooleanOperations_VertexEdge);
1138       aPave3.SetInterference(anIndexIn);
1139       BOPTools_PaveSet& aPaveSet= myPavePool(myDS->RefEdge(aWith));
1140       aPaveSet.Append(aPave3);
1141
1142       //
1143       // State for the Vertex in DS;
1144       myDS->SetState (aWhat, BooleanOperations_ON);
1145       // Insert Vertex in Interference Object
1146       BOPTools_VEInterference& aVE=aVEs(anIndexIn);
1147       aVE.SetNewShape(aWhat);
1148
1149       PreparePaveBlocks(aWith);
1150       RecomputeCommonBlocks(aWith);
1151     }
1152     //
1153   }
1154   
1155   if (bFound1 && !bFound2) {
1156     nV=aPave1.Index();
1157     aPave.SetIndex(nV);
1158     aPave.SetParam(aT);
1159     aFFiPS.Append(aPave);
1160     //
1161     const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
1162     BOPTools_Tools::UpdateVertex (aIC, aT, aV);
1163   }
1164   
1165   if (!bFound1 && bFound2) {
1166     nV=aPave2.Index();
1167     aPave.SetIndex(nV);
1168     aPave.SetParam(aT);
1169     aCPS.Append(aPave);
1170     //
1171     const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
1172     BOPTools_Tools::UpdateVertex (aIC, aT, aV);
1173   }
1174 }
1175 //=======================================================================
1176 // function: FindPave
1177 // purpose: 
1178 //=======================================================================
1179   Standard_Boolean BOPTools_PaveFiller::FindPave(const gp_Pnt& aP,
1180                                                  const Standard_Real aTolPV, 
1181                                                  const BOPTools_PaveSet& aPS,
1182                                                  BOPTools_Pave& aPave)
1183 {
1184   Standard_Integer nV;
1185   Standard_Boolean bIsVertex=Standard_False;
1186  
1187   const BOPTools_ListOfPave& aLP=aPS.Set();
1188   BOPTools_ListIteratorOfListOfPave anIt(aLP);
1189   for (; anIt.More(); anIt.Next()) {
1190     const BOPTools_Pave& aPC=anIt.Value();
1191     nV=aPC.Index();
1192     const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->GetShape(nV));
1193     bIsVertex=IntTools_Tools::IsVertex (aP, aTolPV, aV);
1194     if (bIsVertex) {
1195       aPave=aPC;
1196       return bIsVertex;
1197     }
1198   }
1199   return bIsVertex;
1200 }
1201 //=======================================================================
1202 // function: MakeSectionEdges
1203 // purpose: 
1204 //=======================================================================
1205   void BOPTools_PaveFiller::MakeSectionEdges()
1206 {
1207   Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, nV1, nV2, aNbPaveBlocks,
1208                    aNewShapeIndex ;
1209   Standard_Real    t1, t2;
1210   TopoDS_Edge aESect;
1211   TopoDS_Vertex aV1, aV2;
1212   BRep_Builder BB;
1213
1214   Standard_Integer pbi = 0;
1215
1216
1217   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
1218   
1219   aNbFFs=aFFs.Extent();
1220   for (i=1; i<=aNbFFs; i++) {
1221     BOPTools_SSInterference& aFFi=aFFs(i);
1222     nF1=aFFi.Index1();
1223     nF2=aFFi.Index2();
1224     //
1225     Standard_Real aTF = 1.e-7;
1226     TopoDS_Face aF1=TopoDS::Face(myDS->GetShape(nF1));
1227     TopoDS_Face aF2=TopoDS::Face(myDS->GetShape(nF2));
1228     Standard_Boolean isModT = ModifFFTol(aF1,aF2,aTF);
1229     Standard_Real aTolFF = (isModT) ? Max(aTF,aFFi.TolR3D()) : aFFi.TolR3D();
1230     BOPTools_ListOfPaveBlock aFFPBL;
1231     TopTools_ListOfShape aFFSEL;
1232     //
1233     BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
1234     aNbCurves=aSCvs.Length();
1235     for (j=1; j<=aNbCurves; j++) {
1236       BOPTools_Curve& aBC=aSCvs(j);
1237       const IntTools_Curve& aIC=aBC.Curve();
1238       //
1239       const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
1240       aNbPaveBlocks=aSectEdges.Extent();
1241       BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
1242       pbi = 0;
1243       for (; aPBIt.More(); aPBIt.Next()) {
1244         pbi++;
1245         BOPTools_PaveBlock& aPB=aPBIt.Value();
1246         //
1247         // Pave1
1248         const BOPTools_Pave& aPave1=aPB.Pave1(); 
1249         nV1=aPave1.Index();
1250         t1=aPave1.Param();
1251         aV1=TopoDS::Vertex(myDS->GetShape(nV1));
1252         aV1.Orientation(TopAbs_FORWARD);
1253         //
1254         // Pave2
1255         const BOPTools_Pave& aPave2=aPB.Pave2();
1256         nV2=aPave2.Index();
1257         t2=aPave2.Param();
1258         aV2=TopoDS::Vertex(myDS->GetShape(nV2));
1259         aV2.Orientation(TopAbs_REVERSED);
1260         //
1261         // MakeSplitEdge
1262         //
1263         // reject building parallel sect. edge on the same pave block,
1264         //          if distance between created and this edges is too small
1265         if(IsPaveBlock(nV1,nV2,aFFPBL)) {
1266           Standard_Real diffTol = 1.e-7;
1267           Standard_Integer eI = RejectBuildingEdge(aIC,aV1,aV2,t1,t2,aFFSEL,diffTol);
1268           if(eI != 0) {
1269             Standard_Integer eIndex = 0;
1270             TopTools_ListIteratorOfListOfShape aSEIt(aFFSEL);
1271             for(; aSEIt.More(); aSEIt.Next()) {
1272               eIndex++;
1273               if(eIndex == eI) {
1274                 const TopoDS_Edge & aE = TopoDS::Edge(aSEIt.Value());
1275                 TopoDS_Edge& anEdge = (TopoDS_Edge &) aE;
1276                 BOPTools_ListOfPaveBlock& aListPB = (BOPTools_ListOfPaveBlock&) aSectEdges;
1277                 aListPB.Remove(aPBIt);
1278                 BB.UpdateEdge( anEdge, 2*(aTolFF+diffTol) );
1279                 BB.UpdateVertex( aV1, 2*(aTolFF+diffTol) );
1280                 BB.UpdateVertex( aV2, 2*(aTolFF+diffTol) );
1281                 break;
1282               }
1283             }
1284             if(aPBIt.More())
1285               continue;
1286             else
1287               break;
1288           }
1289         }
1290        
1291         if(fabs(t1-t2) <= 1.e-10) continue;
1292         BOPTools_Tools::MakeSectEdge (aIC, aV1, t1, aV2, t2, aESect);
1293         //
1294         BB.UpdateEdge( aESect, aTolFF );
1295         BB.UpdateVertex( aV1, aTolFF );
1296         BB.UpdateVertex( aV2, aTolFF );
1297         ///////////////////////////////////
1298         // Add Sect Part to the DS
1299         BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
1300         
1301         anASSeq.SetNewSuccessor(nV1);
1302         anASSeq.SetNewOrientation(aV1.Orientation());
1303         
1304         anASSeq.SetNewSuccessor(nV2);
1305         anASSeq.SetNewOrientation(aV2.Orientation());
1306         //
1307         myDS->InsertShapeAndAncestorsSuccessors(aESect, anASSeq);
1308         aNewShapeIndex=myDS->NumberOfInsertedShapes();
1309         //
1310         aPB.SetEdge(aNewShapeIndex);
1311         //
1312         aFFSEL.Append(aESect);
1313         aFFPBL.Append(aPB);
1314       }
1315     }
1316   }
1317   
1318 }
1319 //=======================================================================
1320 // function: PutPaveOnCurve
1321 // purpose: 
1322 //=======================================================================
1323   void BOPTools_PaveFiller::PutPaveOnCurve(const BOPTools_PaveSet& aPaveSet,
1324                                            const Standard_Real aTolR3D,
1325                                            BOPTools_Curve& aBC)
1326
1327   const BOPTools_ListOfPave& aLP=aPaveSet.Set();
1328   BOPTools_ListIteratorOfListOfPave anIt(aLP);
1329   for (; anIt.More(); anIt.Next()) {
1330     const BOPTools_Pave& aPave=anIt.Value();
1331     PutPaveOnCurve (aPave, aTolR3D, aBC);
1332   }
1333 }
1334 //=======================================================================
1335 // function: PutPaveOnCurve
1336 // purpose: 
1337 //=======================================================================
1338   void BOPTools_PaveFiller::PutPaveOnCurve (const BOPTools_Pave& aPave,
1339                                             const Standard_Real aTolR3D,
1340                                             BOPTools_Curve& aBC)
1341 {
1342   Standard_Integer nV;
1343   Standard_Boolean bIsVertexOnLine;
1344   Standard_Real aT, aTolVExt, aTolTresh;
1345   BRep_Builder aBB;
1346   //
1347   aTolTresh=0.01;
1348   nV=aPave.Index();
1349   const TopoDS_Vertex& aV=TopoDS::Vertex(myDS->Shape(nV));
1350   const IntTools_Curve& aC=aBC.Curve();
1351   Handle (Geom_Curve) aC3D= aC.Curve();
1352   //
1353   aTolVExt=BRep_Tool::Tolerance(aV);
1354   ExtendedTolerance(nV, aTolVExt);
1355   bIsVertexOnLine=myContext.IsVertexOnLine(aV, aTolVExt, aC, aTolR3D, aT);
1356   //
1357   if (bIsVertexOnLine) {
1358     BOPTools_Pave aPaveNew(nV, aT, BooleanOperations_SurfaceSurface);
1359     BOPTools_PaveSet& aPaveSet=aBC.Set();
1360     aPaveSet.Append(aPaveNew);
1361     //<-B
1362     BOPTools_Tools::UpdateVertex (aC, aT, aV);
1363     //modified by NIZNHY-PKV Sat Mar 05 13:43:27 2011f
1364     if(aTolR3D<aTolTresh) {
1365     aBB.UpdateVertex(aV, aTolR3D);
1366     }
1367     //modified by NIZNHY-PKV Sat Mar 05 13:43:29 2011t
1368   }
1369 }
1370 //
1371 //=======================================================================
1372 // function: ExtendedTolerance
1373 // purpose: 
1374 //=======================================================================
1375   Standard_Boolean BOPTools_PaveFiller::ExtendedTolerance(const Standard_Integer nV,
1376                                                           Standard_Real& aTolVExt)
1377 {
1378   Standard_Boolean bFound, bIsNewShape;
1379   Standard_Integer k, i, aNbLines, aNewShape;
1380   Standard_Real aT11, aT12, aD1, aD2, aD;
1381   TopoDS_Vertex aV;
1382   gp_Pnt aPV, aP11, aP12;
1383   //
1384   bFound=Standard_False;
1385   //
1386   bIsNewShape=myDS->IsNewShape(nV);
1387   if (!bIsNewShape) {
1388     return bFound;
1389   }
1390   //
1391   aV=TopoDS::Vertex(myDS->Shape(nV));
1392   aPV=BRep_Tool::Pnt(aV);
1393   //
1394   const BOPTools_InterferencePool& anInterferencePool=*myIntrPool;
1395   const BOPTools_CArray1OfEEInterference&  aEEInterfs=anInterferencePool.EEInterfs();
1396   const BOPTools_CArray1OfESInterference&  aESInterfs=anInterferencePool.ESInterfs();
1397   //
1398   for (k=0; k<2; ++k) {
1399     aNbLines=(!k) ? aEEInterfs.Extent() : aESInterfs.Extent();
1400     for (i=1; i<=aNbLines; ++i) {
1401       BOPTools_ShapeShapeInterference *pI=(!k) ? 
1402         (BOPTools_ShapeShapeInterference *)&aEEInterfs(i):
1403           (BOPTools_ShapeShapeInterference *)&aESInterfs(i);
1404       //
1405       aNewShape=pI->NewShape();
1406       if (aNewShape==nV) {
1407         const IntTools_CommonPrt& aCPart=(!k) ? 
1408           aEEInterfs(i).CommonPrt() : 
1409             aESInterfs(i).CommonPrt();
1410         //
1411         const TopoDS_Edge& aE1=aCPart.Edge1();
1412         aCPart.Range1(aT11, aT12);
1413         BOPTools_Tools::PointOnEdge(aE1, aT11, aP11);
1414         BOPTools_Tools::PointOnEdge(aE1, aT12, aP12);
1415         aD1=aPV.Distance(aP11);
1416         aD2=aPV.Distance(aP12);
1417         aD=(aD1>aD2)? aD1 : aD2;
1418         if (aD>aTolVExt) {
1419           aTolVExt=aD;
1420         }
1421         bFound=!bFound;
1422         return bFound;
1423       }
1424     }
1425   }
1426   //
1427   return bFound;
1428 }
1429 //
1430 //=======================================================================
1431 // function: PutPavesOnCurves
1432 // purpose: 
1433 //=======================================================================
1434   void BOPTools_PaveFiller::PutPavesOnCurves ()
1435 {
1436   Standard_Integer i, j, aNbCurves, aNbFFs, nF1, nF2, nV;
1437   Standard_Real aTolR3D = 0.;
1438
1439   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
1440   
1441   aNbFFs=aFFs.Extent();
1442
1443   for (i=1; i<=aNbFFs; i++) {
1444     BOPTools_SSInterference& aFFi=aFFs(i);
1445     // 
1446     // Curves' tolerance
1447     aTolR3D=aFFi.TolR3D();
1448     //
1449     // Faces
1450     nF1=aFFi.Index1();
1451     nF2=aFFi.Index2();
1452
1453     //
1454     // Put existing paves on curves
1455     BOPTools_PaveSet aPSF;
1456     PrepareSetForFace (nF1, nF2, aPSF);
1457     //
1458     //modified by NIZNHY-PKV Sat Mar 05 12:12:05 2011f
1459     {
1460       Standard_Integer nVX;
1461       BOPTools_ListIteratorOfListOfPave aItLP;
1462       TColStd_MapOfInteger aMVStick;
1463       //
1464       const BOPTools_ListOfPave& aLPX=aPSF.Set();
1465       aItLP.Initialize(aLPX);
1466       for (; aItLP.More(); aItLP.Next()) {
1467         const BOPTools_Pave& aPX=aItLP.Value();
1468         nVX=aPX.Index();
1469         aMVStick.Add(nVX);
1470       }
1471       //
1472       CorrectTolR3D(*this, aFFi, aMVStick, aTolR3D);
1473     }
1474     //modified by NIZNHY-PKV Sat Mar 05 12:12:07 2011t
1475     //
1476     BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
1477     aNbCurves=aSCvs.Length();
1478     for (j=1; j<=aNbCurves; j++) {
1479       BOPTools_Curve& aBC=aSCvs(j);
1480       // DEBUG
1481       const IntTools_Curve& aC=aBC.Curve();
1482       Handle (Geom_Curve) aC3D= aC.Curve();
1483       //
1484       PutPaveOnCurve (aPSF, aTolR3D, aBC);
1485     }
1486     //modified by NIZNHY-PKV Tue Aug 30 14:54:50 2011f
1487     {
1488       Standard_Integer aNbVtx, jx;
1489       Standard_Real aTolVRange;
1490       TColStd_SequenceOfInteger aSeqVx;
1491       TColStd_SequenceOfReal    aSeqTolVx;
1492       //
1493       ProcessAloneStickVertices(nF1, 
1494                                 nF2, 
1495                                 aPSF, 
1496                                 aSCvs, 
1497                                 *this,
1498                                 aSeqVx, 
1499                                 aSeqTolVx);
1500       // 
1501       aNbVtx=aSeqVx.Length();
1502       for (jx=1; jx<=aNbVtx; ++jx) {
1503         BOPTools_PaveSet aPSFx;
1504         BOPTools_Pave aPVx;
1505
1506         nV=aSeqVx(jx);
1507         aTolVRange=aSeqTolVx(jx);
1508         
1509         aPVx.SetIndex(nV);
1510         aPSFx.Append(aPVx);
1511
1512         for (j=1; j<=aNbCurves; j++) {
1513           BOPTools_Curve& aBC=aSCvs(j);
1514           // DEBUG
1515           const IntTools_Curve& aC=aBC.Curve();
1516           Handle (Geom_Curve) aC3D= aC.Curve();
1517           //
1518           PutPaveOnCurve (aPSFx, aTolVRange, aBC);
1519         }
1520       }
1521     }
1522     //modified by NIZNHY-PKV Tue Aug 30 14:54:56 2011t
1523     //
1524     // Put bounding paves on curves
1525     //Check very specific case of cone-cone intersection (OCC13211)
1526
1527     Standard_Boolean bIsSpecific = Standard_False;
1528     if(aNbCurves >= 4) {
1529       const TopoDS_Shape aF1 = myDS->GetShape(nF1);
1530       BRepAdaptor_Surface aS1(TopoDS::Face(aF1), Standard_False);
1531       GeomAbs_SurfaceType aSType = aS1.GetType();
1532       if(aSType == GeomAbs_Cone) {
1533         const TopoDS_Shape aF2 = myDS->GetShape(nF2);
1534         BRepAdaptor_Surface aS2(TopoDS::Face(aF2), Standard_False);
1535         aSType = aS2.GetType();
1536         if(aSType == GeomAbs_Cone) {
1537           bIsSpecific = Standard_True;
1538         }
1539       }
1540     }
1541     //
1542     if(bIsSpecific) {
1543       for (j=1; j<=aNbCurves; j++) {
1544         BOPTools_Curve& aBC=aSCvs(j);
1545         PutBoundPaveOnCurveSpec (aBC, aFFi);
1546       }
1547     }
1548     else {
1549       for (j=1; j<=aNbCurves; j++) {
1550         BOPTools_Curve& aBC=aSCvs(j);
1551         PutBoundPaveOnCurve (aBC, aFFi);
1552       }
1553     }
1554     //
1555     // xxx
1556     for (j=1; j<=aNbCurves; j++) {
1557       BOPTools_Curve& aBC=aSCvs(j);
1558       BOPTools_ListOfPave anOldList;
1559       anOldList = aBC.Set().Set();
1560
1561       if (aBC.NewPaveBlocks().IsEmpty())
1562         continue;
1563       //
1564       
1565       BOPTools_CArray1OfESInterference& aESs = myIntrPool->ESInterferences();
1566       Standard_Integer k, fit;
1567       //
1568       // Among all aESs find those that are between nE1 from nF1(nE2 from nF2) and nF2(nF1)  
1569       for(k = 1; k <= aESs.Length(); k++) {
1570         BOPTools_ESInterference& aES = aESs(k);
1571
1572         if(aES.Index1() == nF1 || aES.Index2() == nF2) {
1573           Standard_Integer nE = (aES.Index1() == nF1) ? aES.Index2() : aES.Index1();
1574
1575           // check if it belongs to F1 or F2.begin
1576           Standard_Boolean edgefound = Standard_False;
1577
1578           for(fit = 0; !edgefound && (fit < 2); fit++) {
1579             Standard_Integer nF = (fit == 0) ? nF1 : nF2;
1580             Standard_Integer sit1 = 0, sit2 = 0;
1581
1582             for(sit1 = 1; !edgefound && (sit1 <= myDS->NumberOfSuccessors(nF)); sit1++) {
1583               Standard_Integer asuccessor = myDS->GetSuccessor(nF, sit1);
1584
1585               for(sit2 = 1; sit2 <= myDS->NumberOfSuccessors(asuccessor); sit2++) {
1586                 if(nE == myDS->GetSuccessor(asuccessor, sit2)) {
1587                   edgefound = Standard_True;
1588                   break;
1589                 }
1590               }
1591             }
1592           }
1593           // check if it belongs to F1 or F2.end
1594
1595           if(edgefound) {
1596             RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);// ->
1597           }
1598         }
1599       }// for(k = 1; k <= aESs.Length(); k++) 
1600
1601       for(fit = 1; fit <= 2; fit++) {
1602         Standard_Integer nF = (fit == 1) ? nF1 : nF2;
1603         Standard_Integer nFOpposite = (fit == 1) ? nF2 : nF1;
1604         TopExp_Explorer anExp(myDS->Shape(nF), TopAbs_EDGE);
1605
1606         for(; anExp.More(); anExp.Next()) {
1607           Standard_Integer nE = myDS->ShapeIndex(anExp.Current(), fit);
1608
1609           if(nE) {
1610             const BOPTools_ListOfInterference& aList =
1611               myIntrPool->InterferenceTable().Value(nE).GetOnType(BooleanOperations_EdgeSurface);
1612             BOPTools_ListIteratorOfListOfInterference anIt2(aList);
1613             Standard_Boolean bProcessed = Standard_False;
1614
1615             for(; anIt2.More(); anIt2.Next()) {
1616               if(anIt2.Value().With() == nFOpposite) {
1617                 if(!bProcessed) {
1618                   RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);
1619                   bProcessed = Standard_True;
1620                   break;
1621                 }
1622               }
1623             }
1624
1625             if(!myCommonBlockPool(myDS->RefEdge(nE)).IsEmpty() &&
1626                !bProcessed) {
1627               RestrictCurveIn2d (nE, nF1, nF2, aTolR3D, aBC);
1628             }
1629           }
1630         }
1631       }
1632       // end for(fit = 1...
1633
1634       // put new paves on other curves.begin
1635       BOPTools_ListOfPave aListOfNewPave;
1636       BOPTools_ListIteratorOfListOfPave anIt1, anIt2;
1637
1638       for(anIt1.Initialize(aBC.Set().Set()); anIt1.More(); anIt1.Next()) {
1639         Standard_Boolean bfound = Standard_False;
1640         for(anIt2.Initialize(anOldList); anIt2.More(); anIt2.Next()) {
1641           if(anIt1.Value().IsEqual(anIt2.Value())) {
1642             bfound = Standard_True;
1643             break;
1644           }
1645         }
1646
1647         if(!bfound) {
1648           aListOfNewPave.Append(anIt1.Value());
1649         }
1650       }
1651
1652       Standard_Integer m = 0, n = 0;
1653       for (m=1; m<=aNbFFs; m++) {
1654         BOPTools_SSInterference& aFFm = aFFs(m);
1655         // 
1656         // Curves' tolerance
1657         Standard_Real aTolR3D2 = aFFm.TolR3D();
1658
1659         BOPTools_SequenceOfCurves& aSCvs2 = aFFm.Curves();
1660         Standard_Integer aNbCurves2 = aSCvs2.Length();
1661
1662         for(n = 1; n <= aNbCurves2; n++) {
1663           if((n == j) && (m == i))
1664             continue;
1665           BOPTools_Curve& aBC2 = aSCvs2(n);
1666
1667           for(anIt1.Initialize(aListOfNewPave); anIt1.More(); anIt1.Next()) {
1668             Standard_Boolean bfound = Standard_False;
1669             for(anIt2.Initialize(aBC2.Set().Set()); anIt2.More(); anIt2.Next()) {
1670               if(anIt1.Value().Index() == anIt2.Value().Index()) {
1671                 bfound = Standard_True;
1672                 break;
1673               }       
1674             }
1675
1676             if(!bfound) {
1677               PutPaveOnCurve (anIt1.Value(), aTolR3D2, aBC2);
1678             }
1679           }
1680         }
1681       }
1682       // put new paves on other curves.end
1683     } // xxx for (j=1; j<=aNbCurves; j++)
1684
1685     //wkar OCC334 f
1686     {
1687       Standard_Integer aNbVtx, jx;
1688       Standard_Real aTolVRange;
1689       TColStd_SequenceOfInteger aSeqVx;
1690       TColStd_SequenceOfReal    aSeqTolVx;
1691       //
1692       ProcessAloneStickVertices(nF1, 
1693                                 nF2, 
1694                                 aPSF, 
1695                                 aSCvs, 
1696                                 *myIntrPool, 
1697                                 *this,
1698                                 aSeqVx, 
1699                                 aSeqTolVx);
1700       //
1701       aNbVtx=aSeqVx.Length();
1702       for (jx=1; jx<=aNbVtx; ++jx) {
1703         BOPTools_PaveSet aPSFx;
1704         BOPTools_Pave aPVx;
1705
1706         nV=aSeqVx(jx);
1707         aTolVRange=aSeqTolVx(jx);
1708         
1709         aPVx.SetIndex(nV);
1710         aPSFx.Append(aPVx);
1711
1712         for (j=1; j<=aNbCurves; j++) {
1713           BOPTools_Curve& aBC=aSCvs(j);
1714           // DEBUG
1715           const IntTools_Curve& aC=aBC.Curve();
1716           Handle (Geom_Curve) aC3D= aC.Curve();
1717           //
1718           PutPaveOnCurve (aPSFx, aTolVRange, aBC);
1719         }
1720       }
1721     }
1722     //wkar OCC334 t
1723   }
1724 }
1725 //=======================================================================
1726 // function: PrepareSetForFace
1727 // purpose: 
1728 //=======================================================================
1729   void BOPTools_PaveFiller::PrepareSetForFace(const Standard_Integer nF1,
1730                                               const Standard_Integer nF2,
1731                                               BOPTools_PaveSet& aPaveSet)
1732
1733   Standard_Integer i, aNbV, nV;
1734   TColStd_IndexedMapOfInteger aMV;
1735   //
1736   StickVertices(nF1, nF2, aMV);
1737   //
1738   aNbV=aMV.Extent();
1739   for (i=1; i<=aNbV; ++i) {
1740     nV=aMV(i);
1741     BOPTools_Pave aPV;
1742     aPV.SetIndex(nV);
1743     aPaveSet.Append(aPV);
1744   }
1745 }
1746 //=======================================================================
1747 // function: IsPaveBlock
1748 // purpose: 
1749 //=======================================================================
1750 Standard_Boolean IsPaveBlock(const Standard_Integer nV1,
1751                              const Standard_Integer nV2, 
1752                              const BOPTools_ListOfPaveBlock& aLPBExisting)
1753 {
1754   Standard_Boolean bFlag=Standard_True;
1755   Standard_Integer nVE1, nVE2;
1756
1757   BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPBExisting);
1758   for (; anIt.More(); anIt.Next()) {
1759     const BOPTools_PaveBlock& aPBR=anIt.Value();
1760     // 
1761     nVE1=aPBR.Pave1().Index();
1762     // 
1763     nVE2=aPBR.Pave2().Index();
1764     //
1765     if ((nVE1==nV1 && nVE2==nV2) || (nVE2==nV1 && nVE1==nV2)) {
1766       return bFlag;
1767     }
1768   }
1769    return !bFlag;
1770 }
1771
1772 //=======================================================================
1773 // function: FMapWhat
1774 // purpose: 
1775 //=======================================================================
1776   void FMapWhat(const Standard_Integer nF,
1777                     BOPTools_InterferencePool* myIntrPool,
1778                     TColStd_IndexedMapOfInteger& aMapWhat)
1779                     
1780 {
1781   Standard_Integer nE, nV;
1782  
1783   
1784
1785   BooleanOperations_ShapesDataStructure* myDS=myIntrPool->DS();
1786   BooleanOperations_OnceExplorer aExp(*myDS);
1787   //
1788   //  What
1789   aMapWhat.Add(nF);
1790   aExp.Init(nF, TopAbs_VERTEX);
1791   for (; aExp.More(); aExp.Next()) {
1792     nV=aExp.Current();
1793     aMapWhat.Add(nV);
1794   }
1795   //
1796   aExp.Init(nF, TopAbs_EDGE);
1797   for (; aExp.More(); aExp.Next()) {
1798     nE=aExp.Current();
1799     aMapWhat.Add(nE);
1800   }
1801 }
1802
1803 //=======================================================================
1804 // function: FMapWith
1805 // purpose: 
1806 //=======================================================================
1807   void FMapWith(const Standard_Integer nF,
1808                 BOPTools_InterferencePool* myIntrPool,
1809                 TColStd_IndexedMapOfInteger& aMapWith)
1810 {
1811   TColStd_IndexedMapOfInteger aMapWhat;
1812   
1813   FMapWhat(nF, myIntrPool, aMapWhat);
1814   //
1815   // With
1816   Standard_Integer i, aNb, anIndex, aWhat, aWith;
1817   BOPTools_ListIteratorOfListOfInterference anIt;
1818   
1819   const BOPTools_CArray1OfInterferenceLine& anArrIL= myIntrPool->InterferenceTable();
1820
1821   aNb=aMapWhat.Extent();
1822   for (i=1; i<=aNb; i++) {
1823     aWhat=aMapWhat(i);
1824     
1825     const BOPTools_InterferenceLine& aWithLine=anArrIL(aWhat);
1826   
1827     const BOPTools_ListOfInterference& aLI=aWithLine.List();
1828     anIt.Initialize(aLI);
1829     for (; anIt.More(); anIt.Next()) {
1830       const BOPTools_Interference& anIntf=anIt.Value();
1831       anIndex=anIntf.Index();
1832       if (anIndex) {
1833         aWith=anIntf.With();
1834         aMapWith.Add(aWith);
1835       }
1836     }
1837   }
1838 }
1839
1840 //=======================================================================
1841 // function: IsFound
1842 // purpose: 
1843 //=======================================================================
1844 Standard_Boolean IsFound(const TColStd_IndexedMapOfInteger& aMapWhat,
1845                          const TColStd_IndexedMapOfInteger& aMapWith)
1846 {
1847   Standard_Boolean bFlag=Standard_False;
1848   Standard_Integer i, aNb, aWhat;
1849
1850   aNb=aMapWhat.Extent();
1851   for (i=1; i<=aNb; i++) {
1852     aWhat=aMapWhat(i);
1853     if (aMapWith.Contains(aWhat)) {
1854       return !bFlag;
1855     }
1856   }
1857   return bFlag;
1858 }
1859
1860
1861 //wkar OCC334 f
1862 #include <BOPTools_CArray1OfESInterference.hxx>
1863 #include <BOPTools_CArray1OfEEInterference.hxx>
1864 #include <BOPTools_ESInterference.hxx>
1865 #include <BOPTools_EEInterference.hxx>
1866 #include <IntTools_CommonPrt.hxx>
1867 #include <gp_Pnt.hxx>
1868 #include <Geom_Curve.hxx>
1869 #include <GeomAbs_SurfaceType.hxx>
1870 #include <Geom_Surface.hxx>
1871 #include <GeomAdaptor_Surface.hxx>
1872 #include <GeomAPI_ProjectPointOnCurve.hxx>
1873 #include <BOPTools_Tools3D.hxx>
1874
1875 //=======================================================================
1876 // function: ProcessAloneStickVertices
1877 // purpose: 
1878 //=======================================================================
1879 void ProcessAloneStickVertices(const Standard_Integer nF1,
1880                                const Standard_Integer nF2,
1881                                const BOPTools_PaveSet& aPSF,
1882                                BOPTools_SequenceOfCurves& aSCvs,
1883                                const BOPTools_InterferencePool& anIntrPool, 
1884                                BOPTools_PaveFiller& aPF,
1885                                TColStd_SequenceOfInteger& aSeqVx,
1886                                TColStd_SequenceOfReal& aSeqTolVx)
1887 {
1888   Standard_Boolean bFound;
1889   Standard_Integer aNbVtx, jx, nV;
1890   Standard_Real aTolVRange;
1891   TColStd_IndexedMapOfInteger aMapUnUsed;
1892   GeomAbs_SurfaceType aType1, aType2;
1893   //
1894   BooleanOperations_PShapesDataStructure pDS=anIntrPool.DS();
1895   //
1896   const TopoDS_Face& aF1= TopoDS::Face(pDS->Shape(nF1));
1897   const TopoDS_Face& aF2= TopoDS::Face(pDS->Shape(nF2));
1898   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1899   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1900   GeomAdaptor_Surface aGAS1(aS1);
1901   GeomAdaptor_Surface aGAS2(aS2);
1902   
1903   aType1=aGAS1.GetType();
1904   aType2=aGAS2.GetType();
1905
1906   if((aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) 
1907      ||
1908      (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane)) {
1909     //
1910     UnUsedMap(aSCvs, aPSF, aMapUnUsed);
1911     // 
1912     aNbVtx=aMapUnUsed.Extent();
1913     for (jx=1; jx<=aNbVtx; ++jx) {
1914       nV=aMapUnUsed(jx);
1915       if (pDS->IsNewShape(nV)) {
1916         bFound=VertexRangeTolerance(nV, nF1, nF2, anIntrPool, aTolVRange);
1917         if (bFound) {
1918           aSeqVx.Append(nV);
1919           aSeqTolVx.Append(aTolVRange);
1920         }
1921       }
1922     }
1923   }
1924   //
1925   //wkar  pkv/904/F7
1926   if((aType1==GeomAbs_Torus && aType2==GeomAbs_Plane) ||
1927      (aType1==GeomAbs_Plane && aType2==GeomAbs_Torus)) {
1928     Standard_Integer aNbSCvs, aNbPoints;
1929     Standard_Real aDist, aTolV;
1930     gp_Pnt aPV;
1931     //
1932     UnUsedMap(aSCvs, aPSF, aMapUnUsed);
1933     aNbVtx=aMapUnUsed.Extent();
1934     if (aNbVtx) {
1935       IntTools_Context& aCtx=aPF.ChangeContext();
1936       //
1937       aNbSCvs=aSCvs.Length();
1938       if (aNbSCvs==1) {
1939         BOPTools_Curve& aBC=aSCvs(1);
1940         const IntTools_Curve& aC=aBC.Curve();
1941         Handle (Geom_Curve) aC3D= aC.Curve();
1942         GeomAPI_ProjectPointOnCurve& aProjPT=aCtx.ProjPT(aC3D);
1943         //
1944         for (jx=1; jx<=aNbVtx; ++jx) {
1945           nV=aMapUnUsed(jx);
1946           if (pDS->IsNewShape(nV)) {
1947             const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&pDS->Shape(nV));
1948             aTolV=BRep_Tool::Tolerance(aV);
1949             aPV=BRep_Tool::Pnt(aV);
1950             //
1951             aProjPT.Perform(aPV);
1952             aNbPoints=aProjPT.NbPoints();
1953             if (aNbPoints) {
1954               aDist=aProjPT.LowerDistance();
1955               aDist=(aDist>aTolV)?  aDist : aTolV;
1956               aSeqVx.Append(nV);
1957               aSeqTolVx.Append(aDist);
1958             }
1959           }
1960         }
1961       }
1962     }
1963   }
1964 }
1965 //modified by NIZNHY-PKV Wed Aug 31 10:29:29 2011f
1966 //=======================================================================
1967 // function: ProcessAloneStickVertices
1968 // purpose: 
1969 //=======================================================================
1970 void ProcessAloneStickVertices(const Standard_Integer nF1,
1971                                const Standard_Integer nF2,
1972                                const BOPTools_PaveSet& aPSF,
1973                                BOPTools_SequenceOfCurves& aSCvs,
1974                                BOPTools_PaveFiller& aPF,
1975                                TColStd_SequenceOfInteger& aSeqVx,
1976                                TColStd_SequenceOfReal& aSeqTolVx)
1977 {
1978   GeomAbs_SurfaceType aType1, aType2;
1979   //
1980   BooleanOperations_PShapesDataStructure pDS=aPF.DS();
1981   //
1982   const TopoDS_Face& aF1= TopoDS::Face(pDS->Shape(nF1));
1983   const TopoDS_Face& aF2= TopoDS::Face(pDS->Shape(nF2));
1984   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1985   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1986   GeomAdaptor_Surface aGAS1(aS1);
1987   GeomAdaptor_Surface aGAS2(aS2);
1988   //
1989   aType1=aGAS1.GetType();
1990   aType2=aGAS2.GetType();
1991   //
1992   if(aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
1993     Standard_Integer aNbSCvs, jVU, aNbVU, nVU, k, m, n;
1994     Standard_Real aTC[2], aD, aD2, aDT2, aU, aV, aScPr, aDScPr;
1995     TColStd_IndexedMapOfInteger aMVU;
1996     GeomAbs_CurveType aTypeC;
1997     gp_Pnt aPC[2], aPVU;
1998     gp_Dir aDN[2];
1999     gp_Pnt2d aP2D;
2000     
2001     Handle(Geom2d_Curve) aC2D[2];
2002     //
2003     aDT2=2e-7;     // the rich criteria
2004     aDScPr=5.e-9;  // the creasing criteria
2005     //
2006     UnUsedMap(aSCvs, aPSF, aMVU);
2007     //
2008     aNbVU=aMVU.Extent();
2009     for (jVU=1; jVU<=aNbVU; ++jVU) {
2010       nVU=aMVU(jVU);
2011       const TopoDS_Vertex& aVU=*((TopoDS_Vertex*)&pDS->Shape(nVU));
2012       aPVU=BRep_Tool::Pnt(aVU);
2013       //
2014       aNbSCvs=aSCvs.Length();
2015       for (k=1; k<=aNbSCvs; ++k) {
2016         BOPTools_Curve& aBC=aSCvs(k);
2017         const IntTools_Curve& aIC=aBC.Curve();
2018         //Handle(Geom_Curve) aC3D=aIC.Curve(); //DEB
2019         aTypeC=aIC.Type();
2020         if (!(aTypeC==GeomAbs_BezierCurve || GeomAbs_BSplineCurve)) {
2021           continue;
2022         }
2023         //
2024         aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
2025         aC2D[0]=aIC.FirstCurve2d();
2026         aC2D[1]=aIC.SecondCurve2d();
2027         if (aC2D[0].IsNull() || aC2D[1].IsNull()) {
2028            continue;
2029         }
2030         //
2031         for (m=0; m<2; ++m) {
2032           aD2=aPC[m].SquareDistance(aPVU);
2033           if (aD2>aDT2) {// no rich
2034             continue; 
2035           }
2036           //
2037           for (n=0; n<2; ++n) {
2038             Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
2039             aC2D[n]->D0(aTC[m], aP2D);
2040             aP2D.Coord(aU, aV);
2041             BOPTools_Tools3D::GetNormalToSurface(aS, aU, aV, aDN[n]);
2042           }
2043           // 
2044           aScPr=aDN[0]*aDN[1];
2045           if (aScPr<0.) {
2046             aScPr=-aScPr;
2047           }
2048           aScPr=1.-aScPr;
2049           //
2050           if (aScPr>aDScPr) {
2051             continue;
2052           }
2053           //
2054           // The intersection curve aIC is vanishing curve (the crease)
2055           aD=sqrt(aD2);
2056           //
2057           aSeqVx.Append(nVU);
2058           aSeqTolVx.Append(aD);
2059         }
2060       }//for (k=1; k<=aNbSCvs; ++k) {
2061     }//for (jVU=1; jVU=aNbVU; ++jVU) {
2062   }//if(aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
2063 }
2064 //modified by NIZNHY-PKV Wed Aug 31 10:29:37 2011t
2065 //=======================================================================
2066 // function: UnUsedMap
2067 // purpose: 
2068 //=======================================================================
2069 void UnUsedMap(BOPTools_SequenceOfCurves& aSCvs,
2070                const BOPTools_PaveSet& aPSF,
2071                TColStd_IndexedMapOfInteger& aMapUnUsed)
2072 {
2073   //
2074   // What stick/non-stick vertices we used 
2075   TColStd_IndexedMapOfInteger aMapUsed, aMapMustBeUsed;
2076   Standard_Integer j, aNbCurves, aNbVtx, nV1;//, nV2;
2077   BOPTools_ListIteratorOfListOfPave anLPIt;
2078
2079   aNbCurves=aSCvs.Length();
2080   for (j=1; j<=aNbCurves; ++j) {
2081     BOPTools_Curve& aBC=aSCvs(j);
2082     //const IntTools_Curve& aC= aBC.Curve();// Wng in Gcc 3.0
2083         
2084     const BOPTools_PaveSet& aPaveSet=aBC.Set();
2085     const BOPTools_ListOfPave& aLPAlreadyUsed=aPaveSet.Set();
2086     anLPIt.Initialize(aLPAlreadyUsed);
2087     for (; anLPIt.More(); anLPIt.Next()) {
2088       const BOPTools_Pave& aPave=anLPIt.Value();
2089       nV1=aPave.Index();
2090       aMapUsed.Add(nV1);
2091     }
2092   }
2093   // 
2094   // 2. Stick vertices that must be used
2095   const BOPTools_ListOfPave& aLPMustUsed=aPSF.Set();
2096   anLPIt.Initialize(aLPMustUsed);
2097   for (; anLPIt.More(); anLPIt.Next()) {
2098     const BOPTools_Pave& aPave=anLPIt.Value();
2099     nV1=aPave.Index();
2100     aMapMustBeUsed.Add(nV1);
2101   }
2102   //
2103   // 3.Unused Stick vertices .
2104   aNbVtx=aMapMustBeUsed.Extent();
2105   for (j=1; j<=aNbVtx; ++j) {
2106     nV1=aMapMustBeUsed(j);
2107     if (!aMapUsed.Contains(nV1)) {
2108       aMapUnUsed.Add(nV1);
2109     }
2110   }
2111   // 
2112 }
2113 //=======================================================================
2114 // function: VertexRangeTolerance
2115 // purpose: 
2116 //=======================================================================
2117 Standard_Boolean VertexRangeTolerance(const Standard_Integer nV,
2118                                       const Standard_Integer nF1,
2119                                       const Standard_Integer nF2,
2120                                       const BOPTools_InterferencePool& anIntrPool,
2121                                       Standard_Real& aTolV)
2122 {
2123   Standard_Boolean bFound=Standard_False;
2124   Standard_Integer i, aNbEFs, iWhat, iWith, iNewShape ;
2125   TColStd_IndexedMapOfInteger aMEF;
2126   //
2127   BooleanOperations_PShapesDataStructure pDS=anIntrPool.DS();
2128   //
2129   const TopoDS_Vertex& aV=TopoDS::Vertex(pDS->Shape(nV));
2130   //
2131   FaceAndEdgeMap(nF1, anIntrPool, aMEF);
2132   FaceAndEdgeMap(nF2, anIntrPool, aMEF);
2133   //
2134   // EF Interferences
2135   const BOPTools_CArray1OfESInterference& aEFs=anIntrPool.ESInterfs();
2136   
2137   aNbEFs=aEFs.Extent();
2138   for (i=1; i<=aNbEFs; ++i) {
2139     const BOPTools_ESInterference& aEF=aEFs(i);
2140     iNewShape=aEF.NewShape();
2141     if (iNewShape==nV) {
2142       aEF.Indices(iWhat, iWith);
2143       if (aMEF.Contains(iWhat) && aMEF.Contains(iWith)) {
2144         //...
2145         Standard_Real aTolVWas, aD1, aD2, aDMax;
2146         gp_Pnt aP3DV, aP3DV1, aP3DV2;
2147         //
2148         const IntTools_CommonPrt& aCommonPrt=aEF.CommonPrt();
2149         //const TopoDS_Edge& aE1= aCommonPrt.Edge1();// Wng in Gcc 3.0
2150         
2151         aP3DV=BRep_Tool::Pnt(aV);
2152         aTolVWas=BRep_Tool::Tolerance(aV);
2153         
2154         aCommonPrt.BoundingPoints(aP3DV1, aP3DV2);
2155         aD1=aP3DV.Distance(aP3DV1);
2156         aD2=aP3DV.Distance(aP3DV2);
2157         
2158         aDMax=Max(aD1, aD2);
2159
2160         aTolV=aTolVWas;
2161         if (aDMax>aTolVWas) {
2162           aTolV=aDMax;
2163         }
2164         return !bFound;
2165       }
2166     }
2167   }
2168   //
2169   // EE Interferences
2170   /*
2171   const BOPTools_CArray1OfEEInterference& aEEs=anIntrPool.EEInterfs();
2172   aNbEEs=aEEs.Extent();
2173   for (i=1; i<=aNbEEs; ++i) {
2174     const BOPTools_EEInterference& aEE=aEEs(i);
2175     iNewShape=aEE.NewShape();
2176     if (iNewShape==nV) {
2177       aEE.Indices(iWhat, iWith);
2178       if (aMEF.Contains(iWhat) && aMEF.Contains(iWith)) {
2179         //...
2180         aTolV=0.;
2181         return !bFound;
2182       }
2183     }
2184   }
2185   */
2186   //
2187   return bFound;
2188 }
2189
2190 //=======================================================================
2191 // function: FaceAndEdgeMap
2192 // purpose: 
2193 //=======================================================================
2194 void FaceAndEdgeMap(const Standard_Integer nF,
2195                     const BOPTools_InterferencePool& anIntrPool,
2196                     TColStd_IndexedMapOfInteger& aMEF)
2197 {
2198   Standard_Integer nEF;
2199   aMEF.Add(nF);
2200   BooleanOperations_PShapesDataStructure myDS=anIntrPool.DS();
2201   BooleanOperations_OnceExplorer aExp(*myDS);
2202   aExp.Init(nF, TopAbs_EDGE);
2203   for (; aExp.More(); aExp.Next()) {
2204     nEF=aExp.Current();
2205     aMEF.Add(nEF);
2206   }
2207 }
2208 //wkar OCC334 t
2209
2210 //=======================================================================
2211 // function: IsPairFound
2212 // purpose: 
2213 //=======================================================================
2214 Standard_Boolean IsPairFound(const Standard_Integer nF1,
2215                              const Standard_Integer nF2,
2216                              BOPTools_InterferencePool* myIntrPool,
2217                              BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWhat,
2218                              BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger& aMapWith)
2219 {
2220   Standard_Boolean bIsFound;
2221   //
2222   if (!aMapWhat.Contains(nF1)) {
2223     TColStd_IndexedMapOfInteger aMWhat;
2224     FMapWhat(nF1, myIntrPool, aMWhat);
2225     aMapWhat.Add(nF1, aMWhat);
2226   }
2227   //
2228   if (!aMapWith.Contains(nF2)) {
2229     TColStd_IndexedMapOfInteger aMWith;
2230     FMapWith(nF2, myIntrPool, aMWith);
2231     aMapWith.Add(nF2, aMWith);
2232   }
2233   //
2234   const TColStd_IndexedMapOfInteger& aMWht=aMapWhat.FindFromKey(nF1);
2235   const TColStd_IndexedMapOfInteger& aMWit=aMapWith.FindFromKey(nF2);
2236   //
2237   bIsFound=IsFound(aMWht, aMWit);
2238   //
2239   return bIsFound;
2240 }
2241
2242 //=======================================================================
2243 // function: RestrictCurveIn2d
2244 // purpose:  Intersects 2d curve of edge nE and 2d curve of theBC.
2245 //           Splits theBC by new vertex, also splits nE by new vertex.
2246 //           If nE has same domain with another edge, the same domain 
2247 //           edge is splitted too.
2248 //=======================================================================
2249   void BOPTools_PaveFiller::RestrictCurveIn2d(const Standard_Integer nE,
2250                                               const Standard_Integer nF1,
2251                                               const Standard_Integer nF2,
2252                                               const Standard_Real    theTolerance,
2253                                               BOPTools_Curve&        theBC) 
2254 {
2255   myPavePoolNew.Resize (myNbEdges);
2256   TopoDS_Shape atmpShape;
2257  
2258   BOPTools_CArray1OfESInterference& aESs = myIntrPool->ESInterferences();
2259
2260   BOPTools_PaveSet& aPS = myPavePool(myDS->RefEdge(nE));
2261   Standard_Boolean bSearchInter = Standard_True;
2262
2263   // 6841
2264   Standard_Integer pvVrtIndex = 0;
2265   //
2266
2267   BOPTools_ListIteratorOfListOfPave anIt1(aPS.Set());
2268   BOPTools_ListIteratorOfListOfPave anIt2;
2269
2270   for(; bSearchInter && anIt1.More(); anIt1.Next()) {
2271
2272     for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {
2273
2274       if(anIt1.Value().Index() == anIt2.Value().Index()) { // too hard condition for the algorithm
2275         // 6841
2276         pvVrtIndex = anIt1.Value().Index();
2277         //
2278         bSearchInter = Standard_False;
2279         break;
2280       }
2281     }
2282   }
2283   // -- 6841: test 2d intersection any way, but update vertex only
2284   if((!bSearchInter && pvVrtIndex != 0)) {
2285     Standard_Boolean OnFirst = (myDS->Rank(nE) == 1);
2286     TopoDS_Edge aE = TopoDS::Edge(myDS->Shape(nE));
2287     TopoDS_Face aF  = (OnFirst) ? TopoDS::Face(myDS->Shape(nF1)) : TopoDS::Face(myDS->Shape(nF2));
2288     Standard_Real pf2 = 0., pl2 = 0.;
2289     Handle(Geom_Curve)   aC2D3 = BRep_Tool::Curve(aE, pf2, pl2);
2290     Handle(Geom2d_Curve) aC2D2 = BRep_Tool::CurveOnSurface(aE, aF, pf2, pl2);
2291     Handle(Geom2d_Curve) aC1D2 = (OnFirst) ? theBC.Curve().FirstCurve2d() : theBC.Curve().SecondCurve2d();
2292     Handle(Geom_Curve)   aC1D3 = theBC.Curve().Curve();
2293     if((!aC2D3.IsNull() && !aC2D2.IsNull()) && (!aC1D2.IsNull() && !aC1D3.IsNull())) {
2294       Standard_Real pf1 = aC1D2->FirstParameter();
2295       Standard_Real pl1 = aC1D2->LastParameter();
2296       Geom2dAPI_InterCurveCurve aInt(aC1D2, aC2D2, Precision::PConfusion());
2297       if(aInt.NbPoints() > 0) {
2298         Standard_Integer jj = 1;
2299         for(; jj <= aInt.NbPoints(); jj++) {
2300           Standard_Real t1 = aInt.Intersector().Point(jj).ParamOnFirst();
2301           Standard_Real t2 = aInt.Intersector().Point(jj).ParamOnSecond();
2302           if((t1 >= pf1) && (t1 <= pl1) && (t2 >= pf2) && (t2 <= pl2)) {
2303 //             gp_Pnt2d aP2d = aInt.Point(jj);
2304             gp_Pnt   aP3d = aC2D3->Value(t2);
2305             gp_Pnt   aP3d2 = aC1D3->Value(t1);
2306             TopoDS_Vertex & aVrt = (TopoDS_Vertex &) myDS->Shape(pvVrtIndex);
2307             gp_Pnt aVP = BRep_Tool::Pnt(aVrt);
2308             Standard_Real aVTol  = BRep_Tool::Tolerance(aVrt);
2309             Standard_Real aD1 = aP3d.Distance(aVP);
2310             Standard_Real aD2 = aP3d2.Distance(aVP);
2311             Standard_Real aFD1 = fabs(aVTol-aD1);
2312             Standard_Real aFD2 = fabs(aVTol-aD2);
2313             if(aD1 > aVTol || aD2 > aVTol) {
2314               if(Max(aFD1,aFD2) <= 1.e-2) {
2315                 Standard_Real nTol = aVTol + 2. * Max(aFD1,aFD2) + 1.e-7;
2316                 BRep_Builder bb;
2317                 bb.UpdateVertex(aVrt, nTol);
2318               }
2319             }
2320           }
2321         }
2322       }
2323     }
2324   }
2325   //-- 6841
2326
2327   if(bSearchInter) {
2328     // search intersection in 2d. begin
2329     BOPTools_ListOfPave aPavesOnCurve, aPavesOnEdge;
2330     Standard_Boolean bIsOnFirst = (myDS->Rank(nE) == 1);
2331
2332     Handle(Geom2d_Curve) aC1 = (bIsOnFirst) ? theBC.Curve().FirstCurve2d() : theBC.Curve().SecondCurve2d();
2333
2334     if(aC1.IsNull())
2335       return;
2336     Standard_Real f1 = aC1->FirstParameter();
2337     Standard_Real l1 = aC1->LastParameter();
2338     
2339     // f1 and l1 may not correspond 
2340     // to boundary parameters of 3d curve
2341     if(theBC.Curve().HasBounds()) {
2342       gp_Pnt tmpp1, tmpp2;
2343       theBC.Curve().Bounds(f1, l1, tmpp1, tmpp2);
2344     }
2345
2346     atmpShape           = myDS->Shape(nE);
2347     TopoDS_Edge  anEdge = TopoDS::Edge(atmpShape);
2348     TopoDS_Shape aFace  = (bIsOnFirst) ? myDS->Shape(nF1) : myDS->Shape(nF2);
2349     Standard_Real f2=0., l2=0.;
2350     Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(anEdge, TopoDS::Face(aFace), f2, l2);
2351     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, f2, l2);
2352
2353     if(aC2.IsNull() || aCurve.IsNull())
2354       return;
2355
2356     Geom2dAPI_InterCurveCurve anIntersector(aC1, aC2, Precision::PConfusion());
2357
2358     if(anIntersector.NbPoints() > 0) {
2359       Standard_Integer j = 0;
2360
2361       for(j = 1; j <= anIntersector.NbPoints(); j++) {
2362         Standard_Real t1 = anIntersector.Intersector().Point(j).ParamOnFirst();
2363         Standard_Real t2 = anIntersector.Intersector().Point(j).ParamOnSecond();
2364
2365         if((t1 >= f1) && (t1 <= l1) &&
2366            (t2 >= f2) && (t2 <= l2)) {
2367           gp_Pnt2d aP2dOnFace = anIntersector.Point(j);
2368           atmpShape  = (!bIsOnFirst) ? myDS->Shape(nF1) : myDS->Shape(nF2);
2369           TopoDS_Face anOtherFace = TopoDS::Face(atmpShape);
2370           gp_Pnt aP3d = aCurve->Value(t2);
2371
2372           if(myContext.IsPointInOnFace(TopoDS::Face(aFace), aP2dOnFace) &&
2373              myContext.IsValidPointForFace(aP3d, anOtherFace, BRep_Tool::Tolerance(anEdge))) {
2374             BOPTools_Pave aPave1;
2375             aPave1.SetParam(t1);
2376             aPave1.SetIndex(-1);
2377             aPavesOnCurve.Append(aPave1);
2378             BOPTools_Pave aPave2;
2379             aPave2.SetParam(t2);
2380             aPave2.SetIndex(-1);
2381             aPavesOnEdge.Append(aPave2);
2382           }
2383         }
2384       }
2385     } // (anIntersector.NbPoints())
2386     // search intersection in 2d. end
2387
2388
2389     BOPTools_ListIteratorOfListOfPave aPaveIt1(aPavesOnCurve);
2390     BOPTools_ListIteratorOfListOfPave aPaveIt2(aPavesOnEdge);
2391
2392     // test common blocks. begin
2393     Standard_Boolean bFaceCBFound = Standard_False;
2394     Standard_Boolean bEdgeCBFound = Standard_False;
2395     const BOPTools_ListOfCommonBlock& aLCBTest = myCommonBlockPool(myDS->RefEdge(nE));
2396     BOPTools_ListIteratorOfListOfCommonBlock aCBListIt(aLCBTest);
2397     Standard_Boolean bHasCBOnFace = Standard_False;
2398     Standard_Boolean bHasCBOnEdge = Standard_False;
2399
2400     for(; aCBListIt.More(); aCBListIt.Next()) {
2401       if((aCBListIt.Value().Face() == nF1) ||
2402          (aCBListIt.Value().Face() == nF2)) {
2403         bHasCBOnFace = Standard_True;
2404       }
2405
2406       if(aCBListIt.Value().Face() == 0) {
2407         bHasCBOnEdge = Standard_True;
2408       }
2409     }
2410     
2411     if(!bHasCBOnFace || !bHasCBOnEdge) {
2412       BOPTools_PaveSet aTestPaveSet;
2413       aTestPaveSet.ChangeSet() = aPS.Set();
2414
2415       for(; aPaveIt2.More(); aPaveIt2.Next()) {
2416         aTestPaveSet.Append(aPaveIt2.Value());
2417       }
2418       BOPTools_PaveBlockIterator aPBIter(0, aTestPaveSet);
2419
2420       for (; aPBIter.More(); aPBIter.Next()) {
2421         const BOPTools_PaveBlock& aPB = aPBIter.Value();
2422         Standard_Real aT1=aPB.Pave1().Param();
2423         Standard_Real aT2=aPB.Pave2().Param();
2424         gp_Pnt aPMid = aCurve->Value((aT1 + aT2) * 0.5);
2425         Standard_Integer nFOpposite = (bIsOnFirst) ? nF2 : nF1;
2426         TopoDS_Shape aOppFace = myDS->Shape(nFOpposite);
2427
2428         if(!bHasCBOnFace && !bFaceCBFound &&
2429            myContext.IsValidPointForFace(aPMid, TopoDS::Face(aOppFace), 
2430                                          BRep_Tool::Tolerance(anEdge) +
2431                                          BRep_Tool::Tolerance(TopoDS::Face(aOppFace)))) {
2432           bFaceCBFound = Standard_True;
2433         }
2434
2435         if(!bHasCBOnEdge && !bEdgeCBFound) {
2436           TopoDS_Vertex aVMid;
2437           BRep_Builder aBB;
2438           aBB.MakeVertex(aVMid, aPMid, BRep_Tool::Tolerance(anEdge));
2439           TopExp_Explorer anExpE(aOppFace, TopAbs_EDGE);
2440
2441           for(; anExpE.More(); anExpE.Next()) {
2442             TopoDS_Shape aTmpEdge = anExpE.Current();
2443             Standard_Real aParameter = 0.;
2444
2445             if(myContext.ComputeVE(aVMid, TopoDS::Edge(aTmpEdge), aParameter) == 0) {
2446               bEdgeCBFound = Standard_True;
2447               break;
2448             }
2449           }
2450         }
2451       }
2452       aPaveIt2.Initialize(aPavesOnEdge);
2453     }
2454     // test common blocks. end
2455
2456     Standard_Boolean bChecknAddPaves = Standard_True;
2457
2458     if(bEdgeCBFound) {
2459       bChecknAddPaves = Standard_False;
2460     }
2461     else {
2462       if(!bHasCBOnEdge) {
2463         bChecknAddPaves = !bFaceCBFound;
2464       }
2465     }
2466
2467     if(bChecknAddPaves) {
2468       // add paves chaking if new pave is equal to existent. begin
2469       for(; aPaveIt1.More() && aPaveIt2.More(); aPaveIt1.Next(), aPaveIt2.Next()) {
2470         BOPTools_Pave& aPaveOnCurve = aPaveIt1.Value();
2471         BOPTools_Pave& aPaveOnEdge  = aPaveIt2.Value();
2472
2473         gp_Pnt aP1 = theBC.Curve().Curve()->Value(aPaveOnCurve.Param());
2474         gp_Pnt aP2 = aCurve->Value(aPaveOnEdge.Param());
2475
2476         Standard_Boolean bAddNewVertex = Standard_True;
2477         Standard_Boolean bAddOldVertex = Standard_False;
2478         Standard_Integer oldvertexindex = 0;
2479
2480         for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {
2481           atmpShape = myDS->Shape(anIt2.Value().Index());
2482           TopoDS_Vertex aVertex = TopoDS::Vertex(atmpShape);
2483           gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
2484           Standard_Real aTolerance = theTolerance + BRep_Tool::Tolerance(aVertex);
2485           if((aPoint.Distance(aP1) < aTolerance) ||
2486              (aPoint.Distance(aP2) < aTolerance)) {
2487             bAddNewVertex = Standard_False;
2488             bAddOldVertex = Standard_True;
2489             oldvertexindex = anIt2.Value().Index(); 
2490             break;
2491           }
2492         }
2493
2494         // treat equality with other vertices.begin
2495         if(bAddNewVertex || bAddOldVertex) {
2496           TopoDS_Vertex aNewVertex;
2497           BOPTools_Tools::MakeNewVertex(anEdge, aPaveOnEdge.Param(), 
2498                                         TopoDS::Face(aFace),  aNewVertex);
2499           
2500           BOPTools_Pave aPaveToPut;
2501           Standard_Boolean bAddNewVertextmp = bAddNewVertex, bAddOldVertextmp = bAddOldVertex;
2502
2503           if(!CheckNewVertexAndUpdateData(aNewVertex, aPaveOnEdge.Param(), anEdge, aPaveOnCurve.Param(), 
2504                                           nF1, nF2, theTolerance, myIntrPool, myDS, &myContext, aPS, 
2505                                           bAddNewVertextmp, bAddOldVertextmp, theBC, aPaveToPut, 
2506                                           bAddNewVertex, bAddOldVertex)) {
2507             bAddNewVertex = Standard_False;
2508             bAddOldVertex = Standard_False;
2509           }
2510           else {
2511             if((aPaveToPut.Index() != 0) && (aPaveToPut.Param() != 0.) &&
2512                aPaveToPut.Interference() != 0) {
2513               PutPaveOnCurve(aPaveToPut, theTolerance, theBC);
2514             }
2515           }
2516           // end for(anIt1.Initialize...
2517         }
2518         // treat equality with other vertices.end
2519         
2520         if(bAddNewVertex || (bAddOldVertex && oldvertexindex)) {
2521           TopoDS_Vertex aNewVertex;
2522
2523           Standard_Integer aNewShapeIndex = 0;
2524           
2525           // reject creation new vertex if there is a created one at a too small distance
2526           BOPTools_Tools::MakeNewVertex(anEdge,aPaveOnEdge.Param(),TopoDS::Face(aFace),aNewVertex);
2527           Standard_Real nvTol = BRep_Tool::Tolerance(aNewVertex);
2528           Standard_Integer chShNb = myDS->NumberOfInsertedShapes(), chShInd = 0;
2529           Standard_Boolean completeSearching = Standard_False;
2530           for(chShInd = 1; chShInd <= chShNb; chShInd++) {
2531             if(myDS->GetShapeType(chShInd) != TopAbs_VERTEX)
2532               continue;
2533             TopoDS_Vertex chV = TopoDS::Vertex(myDS->Shape(chShInd));
2534             Standard_Real distVV = BRep_Tool::Pnt(chV).Distance(BRep_Tool::Pnt(aNewVertex));
2535             if(distVV <= 1.e-5) {
2536               for(anIt1.Initialize(aPS.Set()); anIt1.More(); anIt1.Next()) {
2537                 if(anIt1.Value().Index() == chShInd) {
2538                   Standard_Real dParam = fabs(aPaveOnEdge.Param()-anIt1.Value().Param());
2539                   if(dParam <= 1.e-7) {
2540                     bAddNewVertex = Standard_False;
2541                     bAddOldVertex = Standard_True;
2542                     oldvertexindex = anIt1.Value().Index();
2543                     nvTol += BRep_Tool::Tolerance(chV) + distVV;
2544                     completeSearching = Standard_True;
2545                     break;
2546                   }
2547                 }
2548               }
2549             }
2550             if(completeSearching)
2551               break;
2552           }
2553           // -&&
2554
2555
2556           if(!bAddOldVertex) {
2557             BOPTools_Tools::MakeNewVertex(anEdge, aPaveOnEdge.Param(), 
2558                                           TopoDS::Face(aFace),  aNewVertex);
2559             BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq; 
2560             myDS->InsertShapeAndAncestorsSuccessors(aNewVertex, anASSeq);
2561             aNewShapeIndex = myDS->NumberOfInsertedShapes();
2562           }
2563           else {
2564             aNewShapeIndex = oldvertexindex;
2565             aNewVertex = TopoDS::Vertex(myDS->Shape(aNewShapeIndex));
2566             BRep_Builder aBB;
2567             //
2568             aBB.UpdateVertex(aNewVertex, aPaveOnEdge.Param(), anEdge, nvTol);
2569           }
2570
2571           BOPTools_ListIteratorOfListOfPave anItAll;
2572           Standard_Boolean samePFound = Standard_False;
2573           for(anItAll.Initialize(aPS.Set()); anItAll.More(); anItAll.Next()) {
2574             if(anItAll.Value().Index() == aNewShapeIndex) {
2575               BOPTools_Pave& aPV = anItAll.Value();
2576               aPV.SetParam(aPaveOnEdge.Param());
2577               samePFound = Standard_True; 
2578               break;
2579             }
2580           }
2581           if(samePFound)
2582             continue;
2583
2584
2585           myDS->SetState (aNewShapeIndex, BooleanOperations_ON);
2586
2587           IntTools_CommonPrt aCPart;
2588           aCPart.SetEdge1(anEdge);
2589           aCPart.SetType(TopAbs_VERTEX);
2590           aCPart.SetRange1(IntTools_Range(aPaveOnEdge.Param(), aPaveOnEdge.Param()));
2591           aCPart.SetVertexParameter1(aPaveOnEdge.Param());
2592
2593           Standard_Integer nFOpposite = (bIsOnFirst) ? nF2 : nF1;
2594           BOPTools_ESInterference anInterf (nE, nFOpposite, aCPart);
2595           Standard_Integer anIndexIn = aESs.Append(anInterf);
2596           myIntrPool->AddInterference (nE, nFOpposite, BooleanOperations_EdgeSurface, anIndexIn);
2597
2598           BOPTools_ESInterference& aESInterf = aESs(anIndexIn);
2599           aESInterf.SetNewShape(aNewShapeIndex);
2600
2601           // put pave on edge. begin 
2602           aPaveOnEdge.SetInterference(anIndexIn);
2603           aPaveOnEdge.SetType (BooleanOperations_EdgeSurface);
2604           aPaveOnEdge.SetIndex(aNewShapeIndex);
2605
2606           BOPTools_PaveSet& aPaveSet1 = myPavePoolNew(myDS->RefEdge(nE));
2607           aPaveSet1.Append(aPaveOnEdge);
2608           // put pave on edge. end
2609
2610           // put pave on curve. begin 
2611           aPaveOnCurve.SetIndex(aNewShapeIndex);
2612           aPaveOnCurve.SetType(BooleanOperations_SurfaceSurface);
2613           BOPTools_PaveSet& aPaveSet = theBC.Set();
2614           aPaveSet.Append(aPaveOnCurve);
2615
2616           BOPTools_Tools::UpdateVertex (theBC.Curve(), aPaveOnCurve.Param(), aNewVertex);
2617
2618           // put pave on curve. end
2619
2620           BOPTools_ListOfCommonBlock& aLCB1 = myCommonBlockPool(myDS->RefEdge(nE));
2621
2622           BOPTools_ListIteratorOfListOfCommonBlock  anIt(aLCB1);
2623
2624           for(; anIt.More(); anIt.Next()) {
2625             BOPTools_CommonBlock& aCB = anIt.Value();
2626
2627             if(aCB.Face()) {
2628               continue;
2629             }
2630
2631             Standard_Integer anOppIndex = aCB.PaveBlock2().OriginalEdge();
2632             IntTools_Range aRange = aCB.PaveBlock2().Range();
2633
2634             if(anOppIndex == nE) {
2635               anOppIndex = aCB.PaveBlock1().OriginalEdge();
2636               aRange = aCB.PaveBlock1().Range();
2637             }
2638             TopoDS_Edge anOppEdge = TopoDS::Edge(myDS->Shape(anOppIndex));
2639             Standard_Real aOppParameter = 0.;
2640
2641             if(myContext.ComputeVE(aNewVertex, anOppEdge, aOppParameter) == 0) {
2642             
2643               if((aOppParameter > aRange.First()) && (aOppParameter < aRange.Last())) {
2644                 // put pave on same domain edge. begin
2645                 BRep_Builder aBB;
2646                 aBB.UpdateVertex(aNewVertex, aOppParameter, anOppEdge, BRep_Tool::Tolerance(aNewVertex));
2647                 BOPTools_Pave aPaveOpp;
2648                 aPaveOpp.SetParam(aOppParameter);
2649                 aPaveOpp.SetIndex(aNewShapeIndex);
2650                 BOPTools_PaveSet& aPaveSetOpp = myPavePoolNew(myDS->RefEdge(anOppIndex));
2651                 aPaveSetOpp.Append(aPaveOpp);
2652                 // put pave on same domain edge. end
2653               }
2654             }
2655           }
2656
2657           // add SS interference for adjacent face.begin
2658           if(aLCB1.IsEmpty()) {
2659             AddInterfForAdjacentFace(nE, nF1, nF2, myIntrPool, myDS);
2660           }
2661           // add SS interference for adjacent face.end
2662
2663           RefinePavePool();
2664           myPavePoolNew.Resize(myNbEdges);
2665           //
2666
2667           RecomputeCommonBlocks(nE);
2668
2669         }
2670       } // end for(; aPaveIt1.More() && aPaveIt2.More()...
2671       // add paves chaking if new pave is equal to existent. end
2672     }
2673   } //(bSearchInter)
2674   myPavePoolNew.Destroy();
2675 }
2676 //=======================================================================
2677 //function : RecomputeCommonBlocks
2678 //purpose  : 
2679 //=======================================================================
2680   void BOPTools_PaveFiller::RecomputeCommonBlocks(const Standard_Integer nE) 
2681 {
2682   TopoDS_Shape atmpShape = myDS->Shape(nE);
2683   TopoDS_Edge  anEdge   = TopoDS::Edge(atmpShape);
2684   BOPTools_ListOfCommonBlock& aLCB1 = myCommonBlockPool(myDS->RefEdge(nE));
2685
2686   BOPTools_ListOfCommonBlock anOldLCB;
2687   anOldLCB = aLCB1;
2688   aLCB1.Clear();
2689   BOPTools_ListOfCommonBlock aNewLCB1;
2690   Standard_Boolean bReverse = Standard_False;
2691   BOPTools_ListIteratorOfListOfCommonBlock  anIt(anOldLCB);
2692
2693   for(; anIt.More(); anIt.Next()) {
2694     BOPTools_CommonBlock& anOldCB = anIt.Value();
2695
2696     Standard_Integer anIndex = anOldCB.PaveBlock1().OriginalEdge();
2697     Standard_Integer anIndexOpp = anOldCB.PaveBlock2().OriginalEdge();
2698     IntTools_Range aCBRange = anOldCB.PaveBlock1().Range();
2699
2700     if(anIndex != nE) {
2701       aCBRange = anOldCB.PaveBlock2().Range();
2702       anIndex = anOldCB.PaveBlock2().OriginalEdge();
2703       anIndexOpp = anOldCB.PaveBlock1().OriginalEdge();
2704       bReverse = Standard_True;
2705     }
2706
2707     BOPTools_ListOfPaveBlock& aSplitEdges1 = mySplitShapesPool(myDS->RefEdge(nE));
2708     BOPTools_ListIteratorOfListOfPaveBlock aLPBIt1(aSplitEdges1);
2709     Standard_Boolean found = Standard_False;
2710     BOPTools_ListOfCommonBlock aNewListOfCommonBlock;
2711
2712     for(; aLPBIt1.More(); aLPBIt1.Next()) {
2713       BOPTools_PaveBlock& aPBCurrent1 = aLPBIt1.Value();
2714       IntTools_Range aCurRange1 = aPBCurrent1.Range();
2715
2716       if((aCurRange1.First() > aCBRange.First() && aCurRange1.First() < aCBRange.Last()) ||
2717          (aCurRange1.Last() > aCBRange.First() && aCurRange1.Last() < aCBRange.Last())) {
2718         BOPTools_CommonBlock aNewCB;
2719
2720         if(!bReverse)
2721           aNewCB.SetPaveBlock1(aPBCurrent1);
2722         else
2723           aNewCB.SetPaveBlock2(aPBCurrent1);
2724
2725         Standard_Boolean foundpaveblock2 = Standard_False;
2726
2727         if(anOldCB.Face()) {
2728           foundpaveblock2 = Standard_True;
2729           aNewCB.SetFace(anOldCB.Face());
2730         }
2731         else {
2732           if(anIndexOpp <= 0)
2733             continue;
2734           BOPTools_ListIteratorOfListOfPaveBlock aLPBIt2(mySplitShapesPool(myDS->RefEdge(anIndexOpp)));
2735
2736           for(; aLPBIt2.More(); aLPBIt2.Next()) {
2737             BOPTools_PaveBlock& aPBCurrent2 = aLPBIt2.Value();
2738             IntTools_Range aCurRange2 = aPBCurrent2.Range();
2739
2740             if(((aPBCurrent1.Pave1().Index() == aPBCurrent2.Pave1().Index()) && 
2741                 (aPBCurrent1.Pave2().Index() == aPBCurrent2.Pave2().Index())) ||
2742                ((aPBCurrent1.Pave1().Index() == aPBCurrent2.Pave2().Index()) && 
2743                 (aPBCurrent1.Pave2().Index() == aPBCurrent2.Pave1().Index()))) {
2744               Standard_Real f = 0., l = 0.;
2745               Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, f, l);
2746               Standard_Real aMidPar = (aCurRange1.First() + aCurRange1.Last()) * 0.5;
2747               gp_Pnt aMidPnt = aCurve->Value(aMidPar);
2748               Standard_Real aProjPar = 0.;
2749               TopoDS_Vertex aTestpVertex;
2750               TopoDS_Edge aOppEdge = TopoDS::Edge(myDS->Shape(anIndexOpp));
2751               BRep_Builder aBB;
2752               aBB.MakeVertex(aTestpVertex, aMidPnt, BRep_Tool::Tolerance(anEdge));
2753
2754               if(myContext.ComputeVE(aTestpVertex, aOppEdge, aProjPar) == 0) {
2755                 if(aProjPar > aCurRange2.First() && aProjPar < aCurRange2.Last()) {
2756                   if(!bReverse)
2757                     aNewCB.SetPaveBlock2(aPBCurrent2);
2758                   else
2759                     aNewCB.SetPaveBlock1(aPBCurrent2);
2760                   foundpaveblock2 = Standard_True;
2761                   break;
2762                 }
2763               }
2764             }
2765           }
2766         }
2767
2768         if(foundpaveblock2) {
2769           found = Standard_True;
2770           aNewListOfCommonBlock.Append(aNewCB);
2771         }
2772       }
2773     }
2774     // end for(; aLPBIt1.More()...
2775
2776     if(!found) {
2777       aNewLCB1.Append(anOldCB);
2778     }
2779     else {
2780       BOPTools_ListOfCommonBlock tmplst;
2781       tmplst = aNewListOfCommonBlock;
2782       aNewLCB1.Append(tmplst);
2783
2784       if((anOldCB.Face() == 0) && (anIndexOpp > 0)) {
2785         tmplst = aNewListOfCommonBlock;
2786         BOPTools_ListOfCommonBlock& aLCB2 = myCommonBlockPool(myDS->RefEdge(anIndexOpp));
2787
2788         BOPTools_ListIteratorOfListOfCommonBlock anItLCB2(aLCB2);
2789
2790         for(; anItLCB2.More(); anItLCB2.Next()) {
2791           BOPTools_CommonBlock& anOldCB2 = anItLCB2.Value();
2792
2793           if(anOldCB2.Face())
2794             continue;
2795
2796           if(anOldCB.PaveBlock1().IsEqual(anOldCB2.PaveBlock1()) &&
2797              anOldCB.PaveBlock2().IsEqual(anOldCB2.PaveBlock2())) {
2798             aLCB2.Remove(anItLCB2);
2799             aLCB2.Append(tmplst);
2800             break;
2801           }
2802         }
2803       }
2804     }
2805   }
2806   // end for(; anIt.More()...
2807   aLCB1 = aNewLCB1;
2808 }
2809 //=======================================================================
2810 //function : CheckNewVertexAndUpdateData
2811 //purpose  : 
2812 //=======================================================================
2813 Standard_Boolean CheckNewVertexAndUpdateData(const TopoDS_Vertex&              theVertex,
2814                                              const Standard_Real               theParamOnE,
2815                                              const TopoDS_Edge&                theEdge,
2816                                              const Standard_Real               theParamOnCurve,
2817                                              const Standard_Integer            theIndexF1,
2818                                              const Standard_Integer            theIndexF2,
2819                                              const Standard_Real               theTolerance,
2820                                              const BOPTools_PInterferencePool& theIntrPool,
2821                                              const BooleanOperations_PShapesDataStructure& theDS,
2822                                              IntTools_Context*                 theContext,
2823                                              const BOPTools_PaveSet&           theEdgePaveSet,
2824                                              const Standard_Boolean            bAddNewVertex,
2825                                              const Standard_Boolean            bAddOldVertex,
2826                                              BOPTools_Curve&                   theBC,
2827                                              BOPTools_Pave&                    thePaveToPut,
2828                                              Standard_Boolean&                 bAddNewVertexOut,
2829                                              Standard_Boolean&                 bAddOldVertexOut) {
2830
2831   thePaveToPut.SetParam(0.);
2832   thePaveToPut.SetIndex(0);
2833   thePaveToPut.SetInterference(0);
2834
2835   bAddNewVertexOut = bAddNewVertex;
2836   bAddOldVertexOut = bAddOldVertex;
2837   TopoDS_Shape atmpShape;
2838   gp_Pnt aP1 = theBC.Curve().Curve()->Value(theParamOnCurve);
2839   Standard_Real f = 0., l = 0.;
2840   Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, f, l);
2841
2842   if(aCurve.IsNull())
2843     return Standard_False;
2844   gp_Pnt aP2 = aCurve->Value(theParamOnE);
2845
2846   BOPTools_ListIteratorOfListOfPave anIt1, anIt2;
2847
2848   for(anIt1.Initialize(theEdgePaveSet.Set()); anIt1.More(); anIt1.Next()) {
2849     atmpShape = theDS->Shape(anIt1.Value().Index());
2850     TopoDS_Vertex aVertex = TopoDS::Vertex(atmpShape);
2851     gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
2852     Standard_Real aTolerance = theTolerance + BRep_Tool::Tolerance(aVertex);
2853     aTolerance *= 4.;
2854
2855     if((aPoint.Distance(aP1) < aTolerance) ||
2856        (aPoint.Distance(aP2) < aTolerance)) {
2857       IntTools_Range aRange(anIt1.Value().Param(), theParamOnE);
2858       TopoDS_Vertex aV1 = aVertex;
2859       TopoDS_Vertex aV2 = theVertex;
2860
2861       if(anIt1.Value().Param() > theParamOnE) {
2862         aRange.SetFirst(theParamOnE);
2863         aRange.SetLast(anIt1.Value().Param());
2864         aV1 = theVertex;
2865         aV2 = aVertex;
2866       }
2867       gp_Pnt ptest1 = aCurve->Value(aRange.First());
2868       gp_Pnt ptest2 = aCurve->Value(aRange.Last());
2869       Standard_Boolean bUpdateVertex = Standard_True;
2870
2871       if(ptest1.Distance(ptest2) > (BRep_Tool::Tolerance(aVertex) + BRep_Tool::Tolerance(theEdge))) {
2872         IntTools_ShrunkRange aSR (theEdge, aV1, aV2, aRange, *theContext);
2873         bUpdateVertex = !aSR.IsDone() || (aSR.ErrorStatus() != 0);
2874       }
2875
2876       if(bUpdateVertex) {
2877         bAddNewVertexOut = Standard_False;
2878               
2879         if(bAddOldVertexOut) {
2880           bAddOldVertexOut = Standard_False;
2881           break;
2882         }
2883         BOPTools_Tools::UpdateVertex (theBC.Curve(), theParamOnCurve, aVertex);
2884
2885         Standard_Boolean bPutPave = Standard_True;
2886
2887         for(anIt2.Initialize(theBC.Set().Set()); anIt2.More(); anIt2.Next()) {
2888           if(anIt1.Value().Index() == anIt2.Value().Index()) {
2889             bPutPave = Standard_False;
2890             break;
2891           }
2892         }
2893
2894         Standard_Integer nbbefore = theBC.Set().Set().Extent();
2895
2896         if(bPutPave) {
2897           thePaveToPut = anIt1.Value();
2898         }
2899
2900         if(anIt1.Value().Index() > theDS->NumberOfSourceShapes())
2901           break;
2902
2903         Standard_Integer nbafter = theBC.Set().Set().Extent();
2904
2905         if(nbbefore < nbafter) {
2906           // update interferences.begin
2907           Standard_Integer nF = theIndexF1;
2908
2909           if(theDS->Rank(anIt1.Value().Index()) != theDS->Rank(theIndexF1)) {
2910             nF = theIndexF2;
2911           }
2912           atmpShape = theDS->Shape(nF);
2913           TopoDS_Face   aF = TopoDS::Face  (atmpShape);
2914           BOPTools_CArray1OfVSInterference& aVSs = theIntrPool->VSInterferences();
2915           Standard_Integer vsit = 0;
2916           Standard_Boolean interffound = Standard_False;
2917
2918           for(vsit = 1; vsit <= aVSs.Length(); vsit++) {
2919             if((aVSs.Value(vsit).Index1() == anIt1.Value().Index()) &&
2920                (aVSs.Value(vsit).Index2() == nF)) {
2921               interffound = Standard_True;
2922               break;
2923             }
2924           }
2925
2926           if(!interffound) {
2927             BOPTools_CArray1OfVEInterference& aVEs = theIntrPool->VEInterferences();
2928
2929             for(vsit = 1; vsit <= aVEs.Length(); vsit++) {
2930               if((aVEs.Value(vsit).Index1() == anIt1.Value().Index())) {
2931                 interffound = Standard_True;
2932                 break;
2933               }
2934             }
2935           }
2936
2937           if(!interffound) {
2938             BOPTools_CArray1OfVVInterference& aVVs = theIntrPool->VVInterferences();
2939
2940             for(vsit = 1; vsit <= aVVs.Length(); vsit++) {
2941               if((aVVs.Value(vsit).Index1() == anIt1.Value().Index())) {
2942                 interffound = Standard_True;
2943                 break;
2944               }
2945             }
2946           }
2947
2948           if(!interffound) {
2949             Standard_Real aU = 0., aV = 0.;
2950             Standard_Integer aFlag = theContext->ComputeVS (aVertex, aF, aU, aV);
2951             Standard_Integer anIndexIn = 0;
2952
2953             if (!aFlag) {
2954               //
2955               // Add Interference to the Pool
2956               BOPTools_VSInterference anInterf (anIt1.Value().Index(), nF, aU, aV);
2957               anIndexIn=aVSs.Append(anInterf);
2958               //
2959               // SetState for Vertex in DS;
2960               theDS->SetState (anIt1.Value().Index(), BooleanOperations_ON);
2961               // Insert Vertex in Interference Object
2962               BOPTools_VSInterference& aVS = aVSs(anIndexIn);
2963               aVS.SetNewShape(anIt1.Value().Index());
2964
2965               interffound = Standard_False;
2966               const BOPTools_ListOfInterference& aList1 =
2967                 theIntrPool->InterferenceTable().Value(anIt1.Value().Index()).GetOnType(BooleanOperations_EdgeSurface);
2968               BOPTools_ListOfInterference& amodifList1 = *((BOPTools_ListOfInterference*)&aList1); // not very good approach
2969               BOPTools_ListIteratorOfListOfInterference anInterfIt(amodifList1);
2970
2971               for(; anInterfIt.More(); anInterfIt.Next()) {
2972                 if(anInterfIt.Value().With() == nF) {
2973                   anInterfIt.Value().SetIndex(anIndexIn);
2974                   interffound = Standard_True;
2975                 }
2976               }
2977               const BOPTools_ListOfInterference& aList2 =
2978                 theIntrPool->InterferenceTable().Value(nF).GetOnType(BooleanOperations_EdgeSurface);
2979               BOPTools_ListOfInterference& amodifList2 = *((BOPTools_ListOfInterference*)&aList2); // not very good approach
2980               anInterfIt.Initialize(amodifList2);
2981
2982               for(; anInterfIt.More(); anInterfIt.Next()) {
2983                 if(anInterfIt.Value().With() == anIt1.Value().Index()) {
2984                   anInterfIt.Value().SetIndex(anIndexIn);
2985                   interffound = Standard_True;
2986                 }
2987               }
2988                       
2989               if(!interffound)
2990                 theIntrPool->AddInterference(anIt1.Value().Index(), nF, BooleanOperations_VertexSurface, anIndexIn);
2991             }
2992           }
2993           // update interferences.end
2994         }
2995         break;
2996       }
2997     }
2998   }
2999   // end for(anIt1.Initialize...
3000   return Standard_True;
3001 }
3002 //=======================================================================
3003 //function : AddInterfForAdjacentFace
3004 //purpose  : 
3005 //=======================================================================
3006 void AddInterfForAdjacentFace(const Standard_Integer            theEdgeIndex,
3007                               const Standard_Integer            theIndexF1,
3008                               const Standard_Integer            theIndexF2,
3009                               BOPTools_PInterferencePool        theIntrPool,
3010                               const BooleanOperations_PShapesDataStructure& theDS) {
3011   Standard_Boolean bIsOnFirst = (theDS->Rank(theEdgeIndex) == 1);
3012
3013   IntTools_SequenceOfPntOn2Faces aPnts;
3014   IntTools_SequenceOfCurves aCvs;
3015   Standard_Integer index1 = (bIsOnFirst) ? theIndexF1 : theIndexF2;
3016   Standard_Integer index2 = (bIsOnFirst) ? theIndexF2 : theIndexF1;
3017   Standard_Integer nbw = theDS->NumberOfAncestors(theEdgeIndex);
3018   Standard_Integer ancwit = 0, ancfit = 0;
3019   Standard_Boolean badjacentfound = Standard_False;
3020
3021   for(ancwit = 1; (!badjacentfound) && (ancwit <= nbw); ancwit++) {
3022     Standard_Integer ancestor1 = theDS->GetAncestor(theEdgeIndex, ancwit);
3023
3024     if(ancestor1 == index1)
3025       continue;
3026
3027     if(theDS->GetShapeType(ancestor1) == TopAbs_WIRE) {
3028       Standard_Integer nbf = theDS->NumberOfAncestors(ancestor1);
3029
3030       for(ancfit = 1; ancfit <= nbf; ancfit++) {
3031         Standard_Integer ancestor2 = theDS->GetAncestor(ancestor1, ancfit);
3032
3033         if(ancestor2 != index1) {
3034           index1 = ancestor2;
3035           badjacentfound = Standard_True;
3036           break;
3037         }
3038       }
3039     }
3040   }
3041
3042   if(index1 > index2) {
3043     Standard_Integer tmp = index1;
3044     index1 = index2;
3045     index2 = tmp;
3046   }
3047   Standard_Boolean bAddInterference = Standard_True;
3048   Standard_Integer ffit = 0;
3049   BOPTools_CArray1OfSSInterference& aFFs = theIntrPool->SSInterferences();
3050
3051   for(ffit = 1; ffit <= aFFs.Extent(); ffit++) {
3052     BOPTools_SSInterference& aFFi3 = aFFs(ffit);
3053
3054     if((index1 == aFFi3.Index1()) && (index2 == aFFi3.Index2())) {
3055       bAddInterference = Standard_False;
3056     }
3057   }
3058
3059   if(bAddInterference) {
3060     BOPTools_SSInterference anInterfSS (index1, index2, 1.e-07, 1.e-07, aCvs, aPnts);
3061     Standard_Integer anIndexInSS = aFFs.Append(anInterfSS);
3062     theIntrPool->AddInterference (index1, index2, BooleanOperations_SurfaceSurface, anIndexInSS); 
3063   }
3064 }
3065
3066 //=======================================================================
3067 //function : RejectPaveBlock
3068 //purpose  : 
3069 //=======================================================================
3070 Standard_Boolean RejectPaveBlock(const IntTools_Curve& theC,
3071                                  const Standard_Real   theT1,
3072                                  const Standard_Real   theT2,
3073                                  const TopoDS_Vertex&  theV,
3074                                  Standard_Real&        theRT)
3075 {
3076   theRT = BRep_Tool::Tolerance(theV);
3077   Handle(Geom_Curve) aC = theC.Curve();
3078  
3079   Standard_Real pf = aC->FirstParameter();
3080   Standard_Real pl = aC->LastParameter();
3081   Standard_Real dp = fabs(pl-pf);
3082   Standard_Boolean isp = (aC->IsPeriodic() && fabs(aC->Period()-dp) <= 1.e-9);
3083   Standard_Real dt = fabs(theT2-theT1);
3084   isp = (isp || (aC->IsPeriodic() && fabs(aC->Period()-dt) <= 1.e-9));
3085   Standard_Boolean c3d = (aC->IsClosed() || isp);
3086   
3087   if(c3d)
3088     return Standard_False;
3089
3090   Standard_Real p1 = Max(pf,theT1);
3091   Standard_Real p2 = Min(pl,theT2);
3092   if(p2 != p1) {
3093     if(p2 < p1) {
3094       Standard_Real tp = p1; p1 = p2; p2 = tp;
3095     }
3096     gp_Pnt pntf, pntl;
3097     aC->D0(p1,pntf);
3098     aC->D0(p2,pntl);
3099     Standard_Real d3d = pntf.Distance(pntl);
3100     if(d3d > theRT)
3101       theRT = d3d;
3102   }
3103   return Standard_True;
3104 }
3105
3106 //=======================================================================
3107 //function : ModifFFTol
3108 //purpose  : 
3109 //=======================================================================
3110 Standard_Boolean ModifFFTol(const TopoDS_Face& theF1,
3111                             const TopoDS_Face& theF2,
3112                             Standard_Real&     theTF)
3113 {
3114   Standard_Real t1 = BRep_Tool::Tolerance(theF1), t2 = BRep_Tool::Tolerance(theF2);
3115   theTF = 2* (t1 + t2);
3116   BRepAdaptor_Surface BAS1(theF1);
3117   BRepAdaptor_Surface BAS2(theF2);
3118   
3119   Standard_Boolean isAna1 = (BAS1.GetType() == GeomAbs_Plane ||
3120                              BAS1.GetType() == GeomAbs_Cylinder ||
3121                              BAS1.GetType() == GeomAbs_Cone ||
3122                              BAS1.GetType() == GeomAbs_Sphere);
3123   Standard_Boolean isAna2 = (BAS2.GetType() == GeomAbs_Plane ||
3124                              BAS2.GetType() == GeomAbs_Cylinder ||
3125                              BAS2.GetType() == GeomAbs_Cone ||
3126                              BAS2.GetType() == GeomAbs_Sphere);
3127
3128   isAna1=isAna1||(BAS1.GetType() == GeomAbs_Torus);
3129   isAna2=isAna2||(BAS2.GetType() == GeomAbs_Torus);
3130
3131   if(isAna1 && isAna2)
3132     return Standard_False;
3133
3134   theTF = Max(theTF, 5.e-6);
3135   return Standard_True;
3136 }
3137
3138
3139 //=======================================================================
3140 //function : RejectBuildingEdge
3141 //purpose  : 
3142 //=======================================================================
3143 Standard_Integer RejectBuildingEdge(const IntTools_Curve& theC,
3144                                     const TopoDS_Vertex&  theV1,
3145                                     const TopoDS_Vertex&  theV2,
3146                                     const Standard_Real   theT1,
3147                                     const Standard_Real   theT2,
3148                                     const TopTools_ListOfShape& theL,
3149                                     Standard_Real&        theTF)
3150 {
3151   theTF = 1.e-7;
3152   if(theL.Extent() == 0)
3153     return 0;
3154
3155   Handle(Geom_Curve) aTCurve;
3156   Standard_Real aTT;
3157   
3158   Standard_Integer eIndex = 0;
3159   Standard_Boolean edgeFound = Standard_False;
3160   Handle(Geom_Curve) aCurve = theC.Curve();
3161   TopTools_ListIteratorOfListOfShape anIt(theL);
3162   for(; anIt.More(); anIt.Next()) {
3163     eIndex++;
3164     const TopoDS_Edge & aE = TopoDS::Edge(anIt.Value());
3165     if(aE.IsNull()) continue;
3166     TopExp_Explorer ee(aE,TopAbs_VERTEX);
3167     Standard_Boolean v1Found = Standard_False;
3168     Standard_Boolean v2Found = Standard_False;
3169     Standard_Real v1P = 0., v2P = 0;
3170     for(; ee.More(); ee.Next()) {
3171       const TopoDS_Vertex aV = TopoDS::Vertex(ee.Current());
3172       if(aV.IsNull()) continue;
3173       if(aV.IsEqual(theV1)) {
3174         v1Found = Standard_True;
3175         v1P = BRep_Tool::Parameter(aV,aE);
3176       }
3177       if(aV.IsEqual(theV2)) {
3178         v2Found = Standard_True;
3179         v2P = BRep_Tool::Parameter(aV,aE);
3180       }
3181     }
3182     Standard_Boolean sameParam = Standard_False;
3183     if(v1Found && v2Found) {
3184       if(fabs(theT1-v1P) <= 1.e-8 && fabs(theT2-v2P) <= 1.e-8)
3185         sameParam = Standard_True;
3186     }
3187     if(sameParam) {
3188       Standard_Real f,l;
3189       aTCurve = BRep_Tool::Curve(aE,f,l);
3190       aTT = BRep_Tool::Tolerance(aE);
3191       edgeFound = Standard_True;
3192     }
3193     if(edgeFound)
3194       break;
3195   }
3196
3197   if(!edgeFound)
3198     return 0;
3199
3200   gp_Pnt p1 = aTCurve->Value(theT1);
3201   gp_Pnt p2 = aCurve->Value(theT1);
3202   Standard_Real dpf = p1.Distance(p2);
3203   p1 = aTCurve->Value(theT2);
3204   p2 = aCurve->Value(theT2);
3205   Standard_Real dpl = p1.Distance(p2);
3206   Standard_Real dplf = fabs(dpl-dpf);
3207   Standard_Real dpp = Max(dpl,dpf);
3208
3209   if(dplf > 1.e-7)
3210     return 0;
3211
3212   Standard_Real maxD = Max(dpl,dpf);
3213   Standard_Boolean inTol = Standard_True;
3214   Standard_Real dp = fabs(theT2-theT1)/23.;
3215   Standard_Integer di = 0;
3216   for(di = 1; di <= 21; di++) {
3217     Standard_Real cp = theT1 + dp*((Standard_Real)di);
3218     p1 = aTCurve->Value(cp);
3219     p2 = aCurve->Value(cp);
3220     Standard_Real d12 = p1.Distance(p2);
3221     maxD = Max(maxD,d12);
3222     if(fabs(d12-dpp) > 1.e-7) {
3223       inTol = Standard_False;
3224       break;
3225     }
3226   }
3227
3228   if(!inTol)
3229     return 0;
3230
3231   theTF = maxD;
3232   return eIndex;
3233 }
3234 //=======================================================================
3235 //function : CorrectTolR3D
3236 //purpose  : 
3237 //=======================================================================
3238 void CorrectTolR3D(BOPTools_PaveFiller& aPF,
3239                    const BOPTools_SSInterference& aFF,
3240                    const TColStd_MapOfInteger& aMVStick,
3241                    Standard_Real& aTolR3D)
3242 {
3243   Standard_Boolean bHasBounds;
3244   Standard_Integer i, nF[2], nV, aNbCurves;
3245   Standard_Real aT1, aT2, aU, aV, aT, aA, aTolV, aTolVmax;
3246   Standard_Real aTolR, aTolTresh, aAmin, aAmax;
3247   TColStd_MapIteratorOfMapOfInteger aIt;
3248   gp_Pnt aP, aP1, aP2;
3249   gp_Dir aDN[2];
3250   gp_Vec aVT;
3251   Handle(Geom_Surface) aS[2];
3252   Handle(Geom_Curve) aC3D;
3253   GeomAdaptor_Surface aGAS;
3254   GeomAbs_SurfaceType aType;
3255   TopoDS_Face aF[2];
3256   //
3257   BooleanOperations_PShapesDataStructure myDS=aPF.DS();
3258   IntTools_Context& myContext=aPF.ChangeContext();
3259   //
3260   aTolTresh=0.0005;
3261   aAmin=0.012;// 0.7-7 deg
3262   aAmax=0.12;
3263   //
3264   if (!aMVStick.Extent()) {
3265     return;
3266   }
3267   //
3268   BOPTools_SSInterference& aFFi=*((BOPTools_SSInterference*)&aFF);
3269   BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
3270   aNbCurves=aSCvs.Length();
3271   if (aNbCurves!=1){
3272     return;
3273   }
3274   //
3275   aFFi.Indices(nF[0], nF[1]);
3276   for (i=0; i<2; ++i) {
3277     aF[i]=*((TopoDS_Face*)(&myDS->Shape(nF[i])));
3278     aS[i]=BRep_Tool::Surface(aF[i]);
3279     aGAS.Load(aS[i]);
3280     aType=aGAS.GetType();
3281     if (aType!=GeomAbs_BSplineSurface) {
3282       return;
3283     }
3284   }
3285   //
3286   BOPTools_Curve& aBC=aSCvs(1);
3287   const IntTools_Curve& aIC=aBC.Curve();
3288   bHasBounds=aIC.HasBounds();
3289   if (!bHasBounds){
3290     return;
3291   }
3292   //
3293   aIC.Bounds (aT1, aT2, aP1, aP2);
3294   aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
3295   aC3D=aIC.Curve();
3296   aC3D->D0(aT, aP);
3297   //
3298   for (i=0; i<2; ++i) {
3299     GeomAPI_ProjectPointOnSurf& aPPS=myContext.ProjPS(aF[i]);
3300     aPPS.Perform(aP);
3301     aPPS.LowerDistanceParameters(aU, aV);
3302     BOPTools_Tools3D::GetNormalToSurface(aS[i], aU, aV, aDN[i]);
3303   }
3304   //
3305   aA=aDN[0].Angle(aDN[1]);
3306   aA=fabs(aA);
3307   if (aA>0.5*M_PI) {
3308     aA=M_PI-aA;
3309   }
3310   //
3311   if (aA<aAmin || aA>aAmax) {
3312     return;
3313   }
3314   //
3315   aTolVmax=-1.;
3316   aIt.Initialize(aMVStick);
3317   for (; aIt.More(); aIt.Next()) {
3318     nV=aIt.Key();
3319     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)(&myDS->Shape(nV)));
3320     aTolV=BRep_Tool::Tolerance(aV);
3321     if (aTolV>aTolVmax) {
3322       aTolVmax=aTolV;
3323     }
3324   }
3325   //
3326   aTolR=aTolVmax/aA;
3327   if (aTolR<aTolTresh) {
3328     aTolR3D=aTolR;
3329   }
3330 }