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