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