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