Integration of OCCT 6.5.0 from SVN
[occt.git] / src / QANewModTopOpe / QANewModTopOpe_Tools.cxx
1 #include <QANewModTopOpe_Tools.ixx>
2
3 #include <BooleanOperations_ShapesDataStructure.hxx>
4 #include <BOPTools_InterferencePool.hxx>
5 #include <BOPTools_VVInterference.hxx>
6 #include <BOPTools_VEInterference.hxx>
7 #include <BOPTools_VSInterference.hxx>
8 #include <BOPTools_EEInterference.hxx>
9 #include <BOPTools_ESInterference.hxx>
10 #include <BOPTools_SSInterference.hxx>
11 #include <BOPTools_CArray1OfSSInterference.hxx>
12 #include <BOPTools_CArray1OfESInterference.hxx>
13 #include <BOPTools_CArray1OfEEInterference.hxx>
14 #include <BOPTools_CArray1OfVVInterference.hxx>
15 #include <BOPTools_CArray1OfVEInterference.hxx>
16 #include <BOPTools_CArray1OfVSInterference.hxx>
17 #include <BOPTools_DSFiller.hxx>
18 #include <BOPTools_PCurveMaker.hxx>
19 #include <BOPTools_DEProcessor.hxx>
20 #include <BOPTools_Tools3D.hxx>
21 #include <BOPTools_SplitShapesPool.hxx>
22 #include <BOPTools_PaveBlock.hxx>
23 #include <BOPTools_CommonBlock.hxx>
24 #include <BOPTools_CommonBlockPool.hxx>
25 #include <BOPTools_ListOfPaveBlock.hxx>
26 #include <BOPTools_ListOfCommonBlock.hxx>
27 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
28 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
29 #include <BOPTools_StateFiller.hxx>
30 #include <BOPTools_Curve.hxx>
31
32 #include <BRepAlgoAPI_Cut.hxx>
33 #include <BRepAlgoAPI_Common.hxx>
34
35 #include <TopoDS.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <BOP_WireEdgeSet.hxx>
39 #include <BOP_SDFWESFiller.hxx>
40 #include <BOP_FaceBuilder.hxx>
41
42 #include <BRepTools.hxx>
43 #include <BRep_Tool.hxx>
44 #include <BRep_Builder.hxx>
45 #include <Geom_Surface.hxx>
46 #include <IntTools_Context.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopExp.hxx>
49 #include <GeomAPI_ProjectPointOnSurf.hxx>
50 #include <TopTools_IndexedMapOfShape.hxx>
51 #include <TopTools_DataMapOfIntegerShape.hxx>
52
53 #include <TCollection_CompareOfReal.hxx>
54 #include <SortTools_QuickSortOfReal.hxx>
55
56 #include <TColStd_Array1OfReal.hxx>
57 #include <TColStd_IndexedMapOfReal.hxx>
58 #include <TColStd_ListOfInteger.hxx>
59 #include <TColStd_ListIteratorOfListOfInteger.hxx>
60
61 static Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
62                                                   const TopoDS_Face& theFace2);
63
64 static Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
65                                              const TopoDS_Shape& theNewShape,
66                                              TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
67
68 static void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation&              theBOP,
69                                TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
70
71 static void SortVertexOnEdge(const TopoDS_Edge&          theEdge,
72                              const TopTools_ListOfShape& theListOfVertex,
73                              TopTools_ListOfShape&       theListOfVertexSorted);
74
75 // ========================================================================================
76 // function: NbPoints
77 // purpose:
78 // ========================================================================================
79 Standard_Integer QANewModTopOpe_Tools::NbPoints(const BOPTools_PDSFiller& theDSFiller) 
80 {
81   Standard_Integer i = 0, anbpoints = 0;
82   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
83   BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
84   BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
85   Standard_Integer aNb=aFFs.Extent();
86
87   for (i = 1; i <= aNb; i++) {
88     BOPTools_SSInterference& aFFi = aFFs(i);
89     TColStd_ListOfInteger& anAloneVertices = aFFi.AloneVertices();
90     anbpoints += anAloneVertices.Extent();
91   }
92   BOPTools_CArray1OfESInterference& aEFs = anIntrPool->ESInterferences();
93   aNb = aEFs.Extent();
94
95   for (i = 1; i <= aNb; i++) {
96     BOPTools_ESInterference& aESInterf = aEFs(i);
97     Standard_Integer anIndex = aESInterf.NewShape();
98
99     if(anIndex == 0)
100       continue;
101
102     if(aDS.GetShapeType(anIndex) == TopAbs_VERTEX)
103       anbpoints++;
104   }
105
106   BOPTools_CArray1OfEEInterference& aEEs = anIntrPool->EEInterferences();
107   aNb = aEEs.Extent();
108
109   for (i = 1; i <= aNb; i++) {
110     BOPTools_EEInterference& aEEInterf = aEEs(i);
111     Standard_Integer anIndex = aEEInterf.NewShape();
112
113     if(anIndex == 0)
114       continue;
115
116     if(aDS.GetShapeType(anIndex) == TopAbs_VERTEX)
117       anbpoints++;
118   }
119   return anbpoints;
120 }
121
122 // ========================================================================================
123 // function: NewVertex
124 // purpose:
125 // ========================================================================================
126 TopoDS_Shape QANewModTopOpe_Tools::NewVertex(const BOPTools_PDSFiller& theDSFiller, 
127                                         const Standard_Integer    theIndex) 
128 {
129   TopoDS_Shape aVertex;
130
131   Standard_Integer i = 0, anbpoints = 0;
132   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
133   BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
134   BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
135   Standard_Integer aNb=aFFs.Extent();
136
137   for (i = 1; i <= aNb; i++) {
138     BOPTools_SSInterference& aFFi = aFFs(i);
139     TColStd_ListOfInteger& anAloneVertices = aFFi.AloneVertices();
140     TColStd_ListIteratorOfListOfInteger anIt(anAloneVertices);
141
142     for(; anIt.More(); anIt.Next()) {
143       anbpoints++;
144
145       if(theIndex == anbpoints) {
146         return aDS.Shape(anIt.Value());
147       }
148     }
149   }
150   BOPTools_CArray1OfESInterference& aEFs = anIntrPool->ESInterferences();
151   aNb = aEFs.Extent();
152
153   for (i = 1; i <= aNb; i++) {
154     BOPTools_ESInterference& aESInterf = aEFs(i);
155     Standard_Integer anIndex = aESInterf.NewShape();
156
157     if(anIndex == 0)
158       continue;
159
160     if(aDS.GetShapeType(anIndex) == TopAbs_VERTEX) {
161       anbpoints++;
162
163       if(theIndex == anbpoints) {
164         return aDS.Shape(anIndex);
165       }
166     }
167   }
168
169   BOPTools_CArray1OfEEInterference& aEEs = anIntrPool->EEInterferences();
170   aNb = aEEs.Extent();
171
172   for (i = 1; i <= aNb; i++) {
173     BOPTools_EEInterference& aEEInterf = aEEs(i);
174     Standard_Integer anIndex = aEEInterf.NewShape();
175
176     if(anIndex == 0)
177       continue;
178
179     if(aDS.GetShapeType(anIndex) == TopAbs_VERTEX) {
180       anbpoints++;
181
182       if(theIndex == anbpoints) {
183         return aDS.Shape(anIndex);
184       }
185     }
186   }
187   return aVertex;
188 }
189
190 // ========================================================================================
191 // function: HasSameDomain
192 // purpose:
193 // ========================================================================================
194 Standard_Boolean QANewModTopOpe_Tools::HasSameDomain(const BOPTools_PDSFiller& theDSFiller,
195                                                 const TopoDS_Shape&       theFace) 
196 {
197   if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
198     return Standard_False;
199   const BOPTools_PaveFiller& aPaveFiller = theDSFiller->PaveFiller();
200   BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
201   aPCurveMaker.Do();
202
203   BOPTools_DEProcessor aDEProcessor(aPaveFiller);
204   aDEProcessor.Do();
205
206   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
207   BOPTools_InterferencePool* pIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
208   BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
209   //
210   Standard_Boolean bFlag;
211   Standard_Integer i, aNb, nF1, nF2, iZone, aNbSps, iSenseFlag;
212   gp_Dir aDNF1, aDNF2;
213
214   aNb=aFFs.Extent();
215
216   for (i = 1; i <= aNb; i++) {
217     bFlag=Standard_False;
218     
219     BOPTools_SSInterference& aFF=aFFs(i);
220     
221     nF1=aFF.Index1();
222     nF2=aFF.Index2();
223     const TopoDS_Face& aF1 = TopoDS::Face(aDS.Shape(nF1));
224     const TopoDS_Face& aF2 = TopoDS::Face(aDS.Shape(nF2));
225
226     if(!theFace.IsSame(aF1) && !theFace.IsSame(aF2))
227       continue;
228
229     const BOPTools_ListOfPaveBlock& aLPB = aFF.PaveBlocks();
230     aNbSps = aLPB.Extent();
231
232     if (!aNbSps) {
233       continue;
234     }
235     const BOPTools_PaveBlock& aPB = aLPB.First();
236     const TopoDS_Edge& aSpE = TopoDS::Edge(aDS.Shape(aPB.Edge()));
237     
238     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1); 
239     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
240     iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
241
242     if (iSenseFlag==1 || iSenseFlag==-1) {
243     //
244     //
245       TopoDS_Face aF1FWD=aF1;
246       aF1FWD.Orientation (TopAbs_FORWARD);
247       
248       BOP_WireEdgeSet aWES (aF1FWD);
249       BOP_SDFWESFiller aWESFiller(nF1, nF2, *theDSFiller);
250       aWESFiller.SetSenseFlag(iSenseFlag);
251       aWESFiller.SetOperation(BOP_COMMON);
252       aWESFiller.Do(aWES);
253       
254       BOP_FaceBuilder aFB;
255       aFB.Do(aWES);
256       const TopTools_ListOfShape& aLF=aFB.NewFaces();
257
258       iZone = 0;
259       TopTools_ListIteratorOfListOfShape anIt(aLF);
260
261       for (; anIt.More(); anIt.Next()) {
262         const TopoDS_Shape& aFR=anIt.Value();
263
264         if (aFR.ShapeType()==TopAbs_FACE) {
265           const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
266           //
267           Standard_Boolean bIsValidIn2D, bNegativeFlag;
268           bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
269
270           if (bIsValidIn2D) { 
271
272             if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
273               iZone = 1;
274               break;
275             }
276           }
277         }
278       }
279
280       if (iZone) { 
281         bFlag = Standard_True;
282         aFF.SetStatesMap(aWESFiller.StatesMap());
283       }
284     }
285     aFF.SetTangentFacesFlag(bFlag);
286     aFF.SetSenseFlag (iSenseFlag);
287
288     if(bFlag) {
289       return Standard_True;
290     }
291   }
292   return Standard_False;
293 }
294
295 // ========================================================================================
296 // function: SameDomain
297 // purpose:
298 // ========================================================================================
299 void QANewModTopOpe_Tools::SameDomain(const BOPTools_PDSFiller& theDSFiller,
300                                  const TopoDS_Shape&       theFace,
301                                  TopTools_ListOfShape&     theResultList) 
302 {
303   theResultList.Clear();
304
305   if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
306     return;
307   const BOPTools_PaveFiller& aPaveFiller = theDSFiller->PaveFiller();
308   BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
309   aPCurveMaker.Do();
310
311   BOPTools_DEProcessor aDEProcessor(aPaveFiller);
312   aDEProcessor.Do();
313
314   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
315   BOPTools_InterferencePool* pIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
316   BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
317   //
318   Standard_Integer i, aNb, nF1, nF2,  aNbSps, iSenseFlag;
319   gp_Dir aDNF1, aDNF2;
320
321   aNb=aFFs.Extent();
322
323   for (i = 1; i <= aNb; i++) {
324     BOPTools_SSInterference& aFF=aFFs(i);
325     
326     nF1=aFF.Index1();
327     nF2=aFF.Index2();
328     const TopoDS_Face& aF1 = TopoDS::Face(aDS.Shape(nF1));
329     const TopoDS_Face& aF2 = TopoDS::Face(aDS.Shape(nF2));
330
331     if(!theFace.IsSame(aF1) && !theFace.IsSame(aF2))
332       continue;
333
334     if(aFF.IsTangentFaces()) {
335       if(theFace.IsSame(aF1))
336         theResultList.Append(aF2);
337       else
338         theResultList.Append(aF1);
339       continue;
340     }
341
342     const BOPTools_ListOfPaveBlock& aLPB = aFF.PaveBlocks();
343     aNbSps = aLPB.Extent();
344
345     if (!aNbSps) {
346       continue;
347     }
348     const BOPTools_PaveBlock& aPB = aLPB.First();
349     const TopoDS_Edge& aSpE = TopoDS::Edge(aDS.Shape(aPB.Edge()));
350     
351     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1); 
352     BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
353     iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
354
355     if (iSenseFlag==1 || iSenseFlag==-1) {
356     //
357     //
358       TopoDS_Face aF1FWD=aF1;
359       aF1FWD.Orientation (TopAbs_FORWARD);
360       
361       BOP_WireEdgeSet aWES (aF1FWD);
362       BOP_SDFWESFiller aWESFiller(nF1, nF2, *theDSFiller);
363       aWESFiller.SetSenseFlag(iSenseFlag);
364       aWESFiller.SetOperation(BOP_COMMON);
365       aWESFiller.Do(aWES);
366       
367       BOP_FaceBuilder aFB;
368       aFB.Do(aWES);
369       const TopTools_ListOfShape& aLF=aFB.NewFaces();
370
371       TopTools_ListIteratorOfListOfShape anIt(aLF);
372
373       for (; anIt.More(); anIt.Next()) {
374         const TopoDS_Shape& aFR=anIt.Value();
375
376         if (aFR.ShapeType()==TopAbs_FACE) {
377           const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
378           //
379           Standard_Boolean bIsValidIn2D, bNegativeFlag;
380           bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
381
382           if (bIsValidIn2D) { 
383
384             if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
385               if(theFace.IsSame(aF1))
386                 theResultList.Append(aF2);
387               else
388                 theResultList.Append(aF1);
389               break;
390             }
391           }
392         }
393       }
394     }
395   }
396 }
397
398 // ========================================================================================
399 // function: IsSplit
400 // purpose:
401 // ========================================================================================
402 Standard_Boolean QANewModTopOpe_Tools::IsSplit(const BOPTools_PDSFiller& theDSFiller,
403                                           const TopoDS_Shape&       theEdge,
404                                           const TopAbs_State        theState) 
405 {
406   if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
407     return Standard_False;
408   const BOPTools_SplitShapesPool& aSplitShapesPool = theDSFiller->SplitShapesPool();
409   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
410
411   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap1 = aDS.ShapeIndexMap(1);
412   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap2 = aDS.ShapeIndexMap(2);
413   Standard_Integer anIndex = 0;
414
415   if(aMap1.Contains(theEdge))
416     anIndex = aDS.ShapeIndex(theEdge, 1);
417   else if(aMap2.Contains(theEdge))
418     anIndex = aDS.ShapeIndex(theEdge, 2);
419   else
420     return Standard_False;
421
422   const BOPTools_ListOfPaveBlock& aSplits = aSplitShapesPool(aDS.RefEdge(anIndex));
423   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplits);
424
425   for (; aPBIt.More(); aPBIt.Next()) {
426     BOPTools_PaveBlock& aPB = aPBIt.Value();
427     Standard_Integer    nSp = aPB.Edge();
428     TopAbs_State aSplitState = BOPTools_StateFiller::ConvertState(aDS.GetState(nSp));
429
430     if(aSplitState == theState)
431       return Standard_True;
432   }
433
434 //   if(theState == TopAbs_ON) {
435 //     const BOPTools_CommonBlockPool& aCommonBlockPool= theDSFiller->CommonBlockPool();
436 //     const BOPTools_ListOfCommonBlock& aCBlocks = aCommonBlockPool(aDS.RefEdge(anIndex));
437
438 //     if(!aCBlocks.IsEmpty()) 
439 //       return Standard_True;
440 //   }
441   return Standard_False;
442 }
443
444 // ========================================================================================
445 // function: Splits
446 // purpose:
447 // ========================================================================================
448 void QANewModTopOpe_Tools::Splits(const BOPTools_PDSFiller& theDSFiller,
449                              const TopoDS_Shape&       theEdge,
450                              const TopAbs_State        theState,
451                              TopTools_ListOfShape&     theResultList) 
452 {
453   theResultList.Clear();
454
455   if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
456     return;
457   const BOPTools_SplitShapesPool& aSplitShapesPool = theDSFiller->SplitShapesPool();
458   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
459
460   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap1 = aDS.ShapeIndexMap(1);
461   const BooleanOperations_IndexedDataMapOfShapeInteger& aMap2 = aDS.ShapeIndexMap(2);
462   Standard_Integer anIndex = 0;
463
464   if(aMap1.Contains(theEdge))
465     anIndex = aDS.ShapeIndex(theEdge, 1);
466   else if(aMap2.Contains(theEdge))
467     anIndex = aDS.ShapeIndex(theEdge, 2);
468   else
469     return;
470
471   const BOPTools_ListOfPaveBlock& aSplits = aSplitShapesPool(aDS.RefEdge(anIndex));
472   BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplits);
473 //   TopTools_MapOfShape aMapE;
474
475   for (; aPBIt.More(); aPBIt.Next()) {
476     BOPTools_PaveBlock& aPB = aPBIt.Value();
477     Standard_Integer    nSp = aPB.Edge();
478     TopAbs_State aSplitState = BOPTools_StateFiller::ConvertState(aDS.GetState(nSp));
479
480     if(aSplitState == theState) {
481       TopoDS_Shape aSplit = aDS.Shape(nSp);
482       theResultList.Append(aSplit);
483 //       aMapE.Add(aSplit);
484     }
485   }
486
487 //   if(theState == TopAbs_ON) {
488 //     const BOPTools_CommonBlockPool& aCommonBlockPool= theDSFiller->CommonBlockPool();
489 //     const BOPTools_ListOfCommonBlock& aCBlocks = aCommonBlockPool(aDS.RefEdge(anIndex));
490 //     BOPTools_ListIteratorOfListOfCommonBlock anIt(aCBlocks);
491     
492 //     for(; anIt.More(); anIt.Next()) {
493 //       const BOPTools_CommonBlock& aCB = anIt.Value();
494 //       BOPTools_CommonBlock* pCB=(BOPTools_CommonBlock*) &aCB;
495 //       BOPTools_PaveBlock& aPB = pCB->PaveBlock1(anIndex);
496 //       Standard_Integer    nSp = aPB.Edge();
497 //       TopoDS_Shape aSplit = aDS.Shape(nSp);
498
499 //       if(aMapE.Contains(aSplit))
500 //      continue;
501 //       theResultList.Append(aSplit);
502 //       aMapE.Add(aSplit);
503 //     }
504 //   }
505 }
506
507 // ========================================================================================
508 // function: SplitE
509 // purpose:
510 // ========================================================================================
511 Standard_Boolean QANewModTopOpe_Tools::SplitE(const TopoDS_Edge&    theEdge,
512                                          TopTools_ListOfShape& theSplits) 
513 {
514   // prequesitory : <Eanc> is a valid edge.
515   TopAbs_Orientation oEanc = theEdge.Orientation();
516   TopoDS_Shape aLocalShape = theEdge.Oriented(TopAbs_FORWARD);
517   TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
518   TopTools_ListOfShape aListOfVertex;
519   TopExp_Explorer exv(EFOR,TopAbs_VERTEX);  
520
521   for (;exv.More(); exv.Next()) {
522     const TopoDS_Shape& v = exv.Current();
523     aListOfVertex.Append(v);
524   }
525   Standard_Integer nv = aListOfVertex.Extent();
526
527   if (nv <= 2) return Standard_False;
528   TopTools_ListOfShape aListOfVertexSorted;
529
530   SortVertexOnEdge(EFOR, aListOfVertex, aListOfVertexSorted);
531
532   TopoDS_Vertex v0;
533   TopTools_ListIteratorOfListOfShape anIt(aListOfVertexSorted);
534
535   if (anIt.More()) {
536     v0 = TopoDS::Vertex(anIt.Value()); 
537     anIt.Next();
538   }
539   else return Standard_False;
540
541   for (; anIt.More(); anIt.Next()) {
542     TopoDS_Vertex v = TopoDS::Vertex(anIt.Value());
543     
544     // prequesitory: par0 < par
545     Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR);
546     Standard_Real par  = BRep_Tool::Parameter(v, EFOR);
547
548     // here, ed has the same geometries than Ein, but with no subshapes.
549     TopoDS_Edge ed = TopoDS::Edge(EFOR.EmptyCopied());
550     BRep_Builder BB;
551     v0.Orientation(TopAbs_FORWARD); 
552     BB.Add(ed, v0);
553     v.Orientation(TopAbs_REVERSED); 
554     BB.Add(ed, v);
555     BB.Range(ed, par0, par);
556
557     theSplits.Append(ed.Oriented(oEanc));
558     v0 = v;
559   }
560   return Standard_True;
561 }
562
563
564 // ========================================================================================
565 // function: EdgeCurveAncestors
566 // purpose:
567 // ========================================================================================
568  Standard_Boolean QANewModTopOpe_Tools::EdgeCurveAncestors(const BOPTools_PDSFiller& theDSFiller,
569                                                       const TopoDS_Shape&       theEdge,
570                                                       TopoDS_Shape&             theFace1,
571                                                       TopoDS_Shape&             theFace2) 
572 {
573   theFace1.Nullify();
574   theFace2.Nullify();
575
576   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
577   BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
578   BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
579   Standard_Integer aNb = aFFs.Extent();
580   Standard_Integer i = 0, j = 0;
581
582   for (i = 1; i <= aNb; i++) {
583     BOPTools_SSInterference& aFFi = aFFs(i);
584     BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
585     Standard_Integer aNbCurves = aBCurves.Length();
586
587     for (j = 1; j <= aNbCurves; j++) {
588       BOPTools_Curve& aBC = aBCurves(j);
589       const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
590       
591       BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
592
593       for (; aPBIt.More(); aPBIt.Next()) {
594         BOPTools_PaveBlock& aPB=aPBIt.Value();
595         Standard_Integer nSect = aPB.Edge();
596
597         if(theEdge.IsSame(aDS.Shape(nSect))) {
598           Standard_Integer nF1 = aFFi.Index1();
599           Standard_Integer nF2 = aFFi.Index2();
600           theFace1 = aDS.Shape(nF1);
601           theFace2 = aDS.Shape(nF2);
602           return Standard_True;
603         }
604       }
605     }
606   }
607   return Standard_False;
608 }
609
610 // ========================================================================================
611 // function: EdgeSectionAncestors
612 // purpose:
613 // ========================================================================================
614 Standard_Boolean QANewModTopOpe_Tools::EdgeSectionAncestors(const BOPTools_PDSFiller& theDSFiller,
615                                                        const TopoDS_Shape&       theEdge,
616                                                        TopTools_ListOfShape&     LF1,
617                                                        TopTools_ListOfShape&     LF2,
618                                                        TopTools_ListOfShape&     LE1,
619                                                        TopTools_ListOfShape&     LE2) 
620 {
621   if(theEdge.ShapeType() != TopAbs_EDGE)
622     return Standard_False;
623   const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
624   Standard_Integer i = 0, nb = 0;
625   nb = aDS.NumberOfSourceShapes();
626
627   for(i = 1; i <= nb; i++) {
628     if(aDS.GetShapeType(i) != TopAbs_EDGE)
629       continue;
630
631     const BOPTools_CommonBlockPool&   aCommonBlockPool = theDSFiller->CommonBlockPool();
632     const BOPTools_ListOfCommonBlock& aCBlocks         = aCommonBlockPool(aDS.RefEdge(i));
633     BOPTools_ListIteratorOfListOfCommonBlock anIt(aCBlocks);
634     
635     for(; anIt.More(); anIt.Next()) {
636       const BOPTools_CommonBlock& aCB    = anIt.Value();
637       BOPTools_CommonBlock*       pCB    = (BOPTools_CommonBlock*) &aCB;
638       BOPTools_PaveBlock&         aPB    = pCB->PaveBlock1(i);
639       Standard_Integer            nSp    = aPB.Edge();
640       TopoDS_Shape                aSplit = aDS.Shape(nSp);
641
642       if(!theEdge.IsSame(aSplit))
643         continue;
644
645       if(aDS.Rank(i) == 1)
646         LE1.Append(aDS.Shape(i));
647       else
648         LE2.Append(aDS.Shape(i));
649       Standard_Integer nFace = aCB.Face();
650
651       if(aCB.Face()) {
652         if(aDS.Rank(nFace) == 1)
653           LF1.Append(aDS.Shape(nFace));
654         else
655           LF2.Append(aDS.Shape(nFace));
656       }
657       // find edge ancestors.begin
658       TopTools_IndexedMapOfShape aMapF;
659       Standard_Integer j = 0, k = 0;
660
661       for(j = 1; j <= aDS.NumberOfAncestors(i); j++) {
662         Standard_Integer aAncestor1 = aDS.GetAncestor(i, j);
663
664         for(k = 1; k <= aDS.NumberOfAncestors(aAncestor1); k++) {
665           Standard_Integer aAncestor2 = aDS.GetAncestor(aAncestor1, k);
666
667           if(aDS.GetShapeType(aAncestor2) == TopAbs_FACE) {
668             const TopoDS_Shape& aFace = aDS.Shape(aAncestor2);
669
670             if(aMapF.Contains(aFace))
671               continue;
672
673             if(aDS.Rank(i) == 1)
674               LF1.Append(aFace);
675             else
676               LF2.Append(aFace);
677             aMapF.Add(aFace);
678           }
679         }
680       }
681       // find edge ancestors.end
682     }
683   }
684   Standard_Boolean r = (!LF1.IsEmpty() && !LF2.IsEmpty());
685   r = r && (!LE1.IsEmpty() || !LE2.IsEmpty());
686   return r;
687 }
688
689 // ========================================================================================
690 // function: BoolOpe
691 // purpose:
692 // ========================================================================================
693 Standard_Boolean QANewModTopOpe_Tools::BoolOpe(const TopoDS_Shape& theFace1,
694                                           const TopoDS_Shape& theFace2,
695                                           Standard_Boolean&   IsCommonFound,
696                                           TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) 
697 {
698   IsCommonFound = Standard_False;
699   theHistoryMap.Clear();
700
701   BOPTools_DSFiller aDSFiller;
702   aDSFiller.SetShapes(theFace1, theFace2);
703
704   if (!aDSFiller.IsDone()) {
705     return Standard_False;
706   }
707   aDSFiller.Perform();
708   const BooleanOperations_ShapesDataStructure& aDS = aDSFiller.DS();
709   BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&aDSFiller.InterfPool();
710   Standard_Integer aNb = 0;
711   Standard_Integer i = 0, j = 0;
712   TopTools_IndexedMapOfShape aMapV;
713   {
714     BRepAlgoAPI_Common aCommon(theFace1, theFace2, aDSFiller);
715
716     if(!aCommon.IsDone()) {
717       return Standard_False;
718     }
719     TopExp_Explorer anExp(aCommon.Shape(), TopAbs_FACE);
720     
721     if(!anExp.More()) {
722       IsCommonFound = Standard_False;
723       return Standard_True;
724     }
725     IsCommonFound = Standard_True;
726     TopExp::MapShapes(aCommon.Shape(), TopAbs_VERTEX, aMapV);
727     // fill edge history.begin
728     FillEdgeHistoryMap(aCommon, theHistoryMap);
729     // fill edge history.end
730
731     // fill face history.begin
732     BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
733     aNb = aFFs.Extent();
734     Standard_Boolean bReverseFlag = Standard_True;
735     Standard_Boolean fillhistory = Standard_True;
736
737     for (i=1; i<=aNb; i++) {
738       BOPTools_SSInterference& aFF = aFFs(i);
739
740       if(aFF.SenseFlag() == 1) {
741         fillhistory = Standard_True;
742         bReverseFlag = Standard_False;
743       }
744       else if(aFF.SenseFlag() == -1) {
745         fillhistory = Standard_True;
746         bReverseFlag = Standard_True;
747       }
748       else
749         fillhistory = Standard_False;
750     }
751
752     if(fillhistory) {
753
754       for(; anExp.More(); anExp.Next()) {
755         TopoDS_Shape aResShape = anExp.Current();
756
757         if(theFace1.Orientation() == aResShape.Orientation()) {
758           AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
759
760           if(bReverseFlag)
761             aResShape.Reverse();
762           AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
763         }
764         else if(theFace2.Orientation() == aResShape.Orientation()) {
765           AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
766
767           if(bReverseFlag)
768             aResShape.Reverse();
769           AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
770         }
771         else {
772           aResShape.Orientation(theFace1.Orientation());
773           AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
774           aResShape.Orientation(theFace2.Orientation());
775
776           if(bReverseFlag)
777             aResShape.Reverse();
778           AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
779         }
780       }
781     }
782     // fill face history.end
783   }
784   {
785     BRepAlgoAPI_Cut aCut1(theFace1, theFace2, aDSFiller);
786
787     if(!aCut1.IsDone())
788       return Standard_False;
789     TopExp::MapShapes(aCut1.Shape(), TopAbs_VERTEX, aMapV);
790     // fill edge history.begin
791     FillEdgeHistoryMap(aCut1, theHistoryMap);
792     // fill edge history.end
793
794     // fill face history.begin
795     TopExp_Explorer anExp(aCut1.Shape(), TopAbs_FACE);
796
797     for(; anExp.More(); anExp.Next()) {
798       TopoDS_Shape aResShape = anExp.Current();
799       aResShape.Orientation(theFace1.Orientation());
800       AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
801     }
802     // fill face history.end
803   }
804
805   {
806     BRepAlgoAPI_Cut aCut2(theFace1, theFace2, aDSFiller, Standard_False);
807
808     if(!aCut2.IsDone())
809       return Standard_False;
810     TopExp::MapShapes(aCut2.Shape(), TopAbs_VERTEX, aMapV);
811     // fill edge history.begin
812     FillEdgeHistoryMap(aCut2, theHistoryMap);
813     // fill edge history.end
814
815     // fill face history.begin
816     TopExp_Explorer anExp(aCut2.Shape(), TopAbs_FACE);
817
818     for(; anExp.More(); anExp.Next()) {
819       TopoDS_Shape aResShape = anExp.Current();
820       aResShape.Orientation(theFace2.Orientation());
821       AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
822     }
823     // fill face history.end
824   }
825   
826   // fill vertex history.begin
827   BOPTools_CArray1OfVVInterference& aVVs = anIntrPool->VVInterferences();
828   aNb = aVVs.Extent();
829
830   for (i = 1; i <= aNb; i++) {
831     BOPTools_VVInterference& aVVi = aVVs(i);
832     Standard_Integer aNewShapeIndex = aVVi.NewShape();
833
834     if(aNewShapeIndex == 0)
835       continue;
836     const TopoDS_Shape& aNewVertex = aDS.Shape(aNewShapeIndex);
837
838     if(!aMapV.Contains(aNewVertex))
839       continue;
840     const TopoDS_Shape& aV1 = aDS.Shape(aVVi.Index1());
841     const TopoDS_Shape& aV2 = aDS.Shape(aVVi.Index2());
842     AddShapeToHistoryMap(aV1, aNewVertex, theHistoryMap);
843     AddShapeToHistoryMap(aV2, aNewVertex, theHistoryMap);
844   }
845   BOPTools_CArray1OfVEInterference& aVEs = anIntrPool->VEInterferences();
846   aNb = aVEs.Extent();
847
848   for (i = 1; i <= aNb; i++) {
849     BOPTools_VEInterference& aVEi = aVEs(i);
850     Standard_Integer aNewShapeIndex = aVEi.NewShape();
851
852     if(aNewShapeIndex == 0)
853       continue;
854     const TopoDS_Shape& aNewVertex = aDS.Shape(aNewShapeIndex);
855
856     if(!aMapV.Contains(aNewVertex))
857       continue;
858     Standard_Integer anIndex = 0;
859
860     if(aDS.GetShapeType(aVEi.Index1()) == TopAbs_VERTEX)
861       anIndex = aVEi.Index1();
862     else if(aDS.GetShapeType(aVEi.Index2()) == TopAbs_VERTEX)
863       anIndex = aVEi.Index2();
864     else
865       continue;
866     const TopoDS_Shape& aV = aDS.Shape(anIndex);
867     AddShapeToHistoryMap(aV, aNewVertex, theHistoryMap);
868   }
869   BOPTools_CArray1OfVSInterference& aVSs = anIntrPool->VSInterferences();
870   aNb = aVSs.Extent();
871
872   for (i = 1; i <= aNb; i++) {
873     BOPTools_VSInterference& aVSi = aVSs(i);
874     Standard_Integer aNewShapeIndex = aVSi.NewShape();
875
876     if(aNewShapeIndex == 0)
877       continue;
878     const TopoDS_Shape& aNewVertex = aDS.Shape(aNewShapeIndex);
879
880     if(!aMapV.Contains(aNewVertex))
881       continue;
882     Standard_Integer anIndex = 0;
883
884     if(aDS.GetShapeType(aVSi.Index1()) == TopAbs_VERTEX)
885       anIndex = aVSi.Index1();
886     else if(aDS.GetShapeType(aVSi.Index2()) == TopAbs_VERTEX)
887       anIndex = aVSi.Index2();
888     else
889       continue;
890     const TopoDS_Shape& aV = aDS.Shape(anIndex);
891     AddShapeToHistoryMap(aV, aNewVertex, theHistoryMap);
892   }
893   // fill vertex history.end
894   return Standard_True;
895 }
896
897 // -----------------------------------------------------------------
898 // static function: CheckSameDomainFaceInside
899 // purpose: Check if distance between several points of theFace1 and
900 //          theFace2 is not more than sum of maximum of tolerances of
901 //          theFace1's edges and tolerance of theFace2
902 // -----------------------------------------------------------------
903 Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
904                                            const TopoDS_Face& theFace2) {
905
906   Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
907   BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
908   IntTools_Context aContext;
909   Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace1);
910   Standard_Real aTolerance = BRep_Tool::Tolerance(theFace1);
911
912   TopExp_Explorer anExpE(theFace1, TopAbs_EDGE);
913
914   for(; anExpE.More(); anExpE.Next()) {
915     const TopoDS_Edge& anEdge = TopoDS::Edge(anExpE.Current());
916     Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
917     aTolerance = (aTolerance < anEdgeTol) ? anEdgeTol : aTolerance;
918   }
919   aTolerance += BRep_Tool::Tolerance(theFace2);
920
921   Standard_Integer nbpoints = 5;
922   Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
923   Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
924   Standard_Real U = umin + adeltau;
925   GeomAPI_ProjectPointOnSurf& aProjector = aContext.ProjPS(theFace2);
926
927   for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
928     Standard_Real V = vmin + adeltav;
929
930     for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
931       gp_Pnt2d aPoint(U,V);
932
933       if(aContext.IsPointInFace(theFace1, aPoint)) {
934         gp_Pnt aP3d = aSurface->Value(U, V);
935         aProjector.Perform(aP3d);
936
937         if(aProjector.IsDone()) {
938
939           if(aProjector.LowerDistance() > aTolerance)
940             return Standard_False;
941         }
942       }
943     }
944   }
945
946   return Standard_True;
947 }
948
949 // --------------------------------------------------------------------------------------------
950 // static function: AddShapeToHistoryMap
951 // purpose: 
952 // --------------------------------------------------------------------------------------------
953 Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
954                                       const TopoDS_Shape& theNewShape,
955                                       TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
956
957   if(!theHistoryMap.Contains(theOldShape)) {
958     TopTools_ListOfShape aList;
959     aList.Append(theNewShape);
960     theHistoryMap.Add(theOldShape, aList);
961     return Standard_True;
962   }
963   
964   Standard_Boolean found = Standard_False;
965   TopTools_ListOfShape& aList = theHistoryMap.ChangeFromKey(theOldShape);
966   TopTools_ListIteratorOfListOfShape aVIt(aList);
967
968   for(; aVIt.More(); aVIt.Next()) {
969     if(theNewShape.IsSame(aVIt.Value())) {
970       found = Standard_True;
971       break;
972     }
973   }
974
975   if(!found) {
976     aList.Append(theNewShape);
977   }
978   return !found;
979 }
980
981 // --------------------------------------------------------------------------------------------
982 // static function: FillEdgeHistoryMap
983 // purpose: 
984 // --------------------------------------------------------------------------------------------
985 void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation&              theBOP,
986                         TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
987
988   TopExp_Explorer anExp;
989   anExp.Init(theBOP.Shape1(), TopAbs_EDGE);
990
991   for(; anExp.More(); anExp.Next()) {
992     const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
993     TopTools_ListIteratorOfListOfShape anIt(aList);
994
995     for(; anIt.More(); anIt.Next()) {
996       AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
997     }
998   }
999
1000   anExp.Init(theBOP.Shape2(), TopAbs_EDGE);
1001
1002   for(; anExp.More(); anExp.Next()) {
1003     const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
1004     TopTools_ListIteratorOfListOfShape anIt(aList);
1005
1006     for(; anIt.More(); anIt.Next()) {
1007       AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
1008     }
1009   }
1010 }
1011
1012 // --------------------------------------------------------------------------------------------
1013 // static function: SortVertexOnEdge
1014 // purpose: 
1015 // --------------------------------------------------------------------------------------------
1016 void SortVertexOnEdge(const TopoDS_Edge&          theEdge,
1017                       const TopTools_ListOfShape& theListOfVertex,
1018                       TopTools_ListOfShape&       theListOfVertexSorted) {
1019
1020   TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V
1021   TColStd_IndexedMapOfReal mappar;     // mappar.FindIndex(parV) = iV
1022   TopTools_ListIteratorOfListOfShape itlove(theListOfVertex);
1023   
1024   for (; itlove.More(); itlove.Next()){
1025     const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
1026     Standard_Real par = BRep_Tool::Parameter(v, theEdge);
1027     Standard_Integer iv = mappar.Add(par);
1028     mapiv.Bind(iv,v);
1029   }
1030   Standard_Integer nv = mapiv.Extent();
1031   TColStd_Array1OfReal tabpar(1,nv);
1032   Standard_Integer i = 0;
1033
1034   for ( i = 1; i <= nv; i++) {
1035     Standard_Real p = mappar.FindKey(i);
1036     tabpar.SetValue(i,p);
1037   }
1038   theListOfVertexSorted.Clear();
1039   TCollection_CompareOfReal compare;
1040   SortTools_QuickSortOfReal::Sort(tabpar, compare);
1041
1042   for (i = 1; i <= nv; i++) {
1043     Standard_Real par = tabpar.Value(i);
1044     Standard_Integer iv = mappar.FindIndex(par);
1045     const TopoDS_Shape& v = mapiv.Find(iv);
1046     theListOfVertexSorted.Append(v);
1047   }
1048 }