Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BOPTools / BOPTools_SolidStateFiller.cxx
1 // File:        BOPTools_SolidStateFiller.cxx
2 // Created:     Mon May 28 12:42:08 2001
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOPTools_SolidStateFiller.ixx>
8
9 #include <TopoDS.hxx>
10 #include <TopoDS_Shape.hxx>
11 #include <TopoDS_Compound.hxx>
12 #include <TopoDS_Edge.hxx>
13 #include <TopoDS_Vertex.hxx>
14
15 #include <TopExp.hxx>
16 #include <TopExp_Explorer.hxx>
17
18 #include <TopTools_IndexedMapOfShape.hxx>
19 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
20 #include <TopTools_ListIteratorOfListOfShape.hxx>
21 #include <TopTools_ListOfShape.hxx>
22
23 #include <TopAbs_ShapeEnum.hxx>
24 #include <TopAbs_State.hxx>
25
26 #include <Geom_Curve.hxx>
27
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRepClass3d_SolidClassifier.hxx>
31
32 #include <gp_Pnt.hxx>
33
34 #include <IntTools_Tools.hxx>
35
36 #include <BooleanOperations_StateOfShape.hxx>
37 #include <BooleanOperations_ShapesDataStructure.hxx>
38 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
39
40 #include <BOPTools_ListOfShapeEnum.hxx>
41 #include <BOPTools_ListIteratorOfListOfShapeEnum.hxx>
42 #include <BOPTools_IndexedDataMapOfShapeWithState.hxx>
43
44 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
45 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
46 #include <BOPTools_CommonBlock.hxx>
47 #include <BOPTools_SplitShapesPool.hxx>
48 #include <BOPTools_ListOfPaveBlock.hxx>
49 #include <BOPTools_InterferencePool.hxx>
50 #include <BOPTools_CArray1OfSSInterference.hxx>
51 #include <BOPTools_CArray1OfESInterference.hxx>
52 #include <BOPTools_InterferencePool.hxx>
53 #include <BOPTools_CArray1OfESInterference.hxx>
54 #include <BOPTools_ESInterference.hxx>
55 #include <BOPTools_CArray1OfSSInterference.hxx>
56 #include <BOPTools_SSInterference.hxx>
57 #include <BOPTools_SequenceOfCurves.hxx>
58 #include <BOPTools_Curve.hxx>
59 #include <BOPTools_PaveBlock.hxx>
60 #include <BOPTools_CommonBlockPool.hxx>
61 #include <BOPTools_ListOfCommonBlock.hxx>
62 #include <BOPTools_StateFiller.hxx>
63
64 static
65   void IntersectionStates(const TopoDS_Shape& aE,
66                           const TopTools_IndexedDataMapOfShapeListOfShape& aM,
67                           TopTools_IndexedMapOfShape& anIntersectedShapes);
68 static
69   void PropagateState(const TopoDS_Shape& aS,
70                       const BooleanOperations_StateOfShape aState,
71                       BooleanOperations_ShapesDataStructure* pDS,
72                       const Standard_Integer iRank,
73                       BOPTools_IndexedDataMapOfShapeWithState& aSWS,
74                       TopTools_IndexedMapOfShape& aProcessedShapes);
75 static
76   void PropagateState(const TopoDS_Shape& aF,
77                       const BooleanOperations_StateOfShape aState,
78                       BooleanOperations_ShapesDataStructure* pDS,
79                       const Standard_Integer iRank,
80                       BOPTools_IndexedDataMapOfShapeWithState& aSWS,
81                       const TopTools_IndexedDataMapOfShapeListOfShape& aEFMap,
82                       TopTools_IndexedMapOfShape& aProcessedShapes);
83 static
84   Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
85                                const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
86                                const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
87                                BooleanOperations_StateOfShape& aState);
88
89 // Peter KURNEV
90 // p-kurnev@opencascade.com
91
92 //=======================================================================
93 // function: BOPTools_SolidStateFiller::BOPTools_SolidStateFiller
94 // purpose: 
95 //=======================================================================
96   BOPTools_SolidStateFiller::BOPTools_SolidStateFiller(const BOPTools_PaveFiller& aFiller)
97 :
98   BOPTools_StateFiller(aFiller)
99 {
100 }
101
102 //=======================================================================
103 // function: Do
104 // purpose: 
105 //=======================================================================
106   void BOPTools_SolidStateFiller::Do()
107 {
108   const TopoDS_Shape& anObj=myDS->Object();
109   const TopoDS_Shape& aTool=myDS->Tool();
110   //
111   myIsDone=Standard_True;
112   //
113   TopAbs_ShapeEnum aT1, aT2;
114   aT1=anObj.ShapeType();
115   aT2=aTool.ShapeType();
116   
117   if (aT1==TopAbs_FACE) {
118     aT1=TopAbs_SHELL;
119   }
120   if (aT2==TopAbs_FACE) {
121     aT2=TopAbs_SHELL;
122   }
123   
124   if (aT1==TopAbs_SOLID && aT2==TopAbs_SOLID) {
125     DoNonSections(1);
126     DoNonSections(2);
127     DoSections();
128   }
129
130   else if (aT1==TopAbs_SHELL && aT2==TopAbs_SHELL) {
131     DoShellNonSections(1);
132     DoShellNonSections(2);
133     DoSections();
134   }
135   
136   else if (aT1==TopAbs_SHELL && aT2==TopAbs_SOLID) {
137     DoNonSections(1);
138     DoShellNonSections(2);
139     DoSections();
140   }
141   else if (aT1==TopAbs_SOLID && aT2==TopAbs_SHELL) {
142     DoShellNonSections(1);
143     DoNonSections(2);
144     DoSections();
145   }
146   else {
147     myIsDone=!myIsDone;
148   }
149 }
150
151 //=======================================================================
152 // function: DoNonSections
153 // purpose: 
154 //=======================================================================
155   void BOPTools_SolidStateFiller::DoNonSections(const Standard_Integer iRankObj)
156 {
157   //
158   // 0. Restore data and preparing 
159
160   const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool();
161   const TopoDS_Shape& aTool=(iRankObj==1) ? myDS->Tool()   : myDS->Object();
162  
163   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
164   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
165   const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
166
167   Standard_Integer i, nE, nF, aNbPaveBlocks, aNb;
168   BooleanOperations_StateOfShape aState;
169   TopTools_IndexedMapOfShape aEM, anIntersectedShapes, aNonIntersectedShapes;
170   TopTools_IndexedDataMapOfShapeListOfShape aM, aMVE, aMEF;
171   //
172   // aM Map
173   TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_WIRE , aM);
174   TopExp::MapShapesAndAncestors (anObj, TopAbs_WIRE , TopAbs_FACE , aM);
175   TopExp::MapShapesAndAncestors (anObj, TopAbs_FACE , TopAbs_SHELL, aM);
176   TopExp::MapShapesAndAncestors (anObj, TopAbs_SHELL, TopAbs_SOLID, aM);
177   //
178   // VE Map
179   TopExp::MapShapesAndAncestors (anObj, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
180   //
181   // 1. anIntersectedShapes 
182   //
183   // 1.1. Check EF FF interferences with nF 
184   TopExp::MapShapes(anObj, TopAbs_FACE, aEM);
185   aNb=aEM.Extent();
186   for (i=1; i<=aNb; i++) {
187     const TopoDS_Shape& aF=aEM(i);
188     nF=aDSMap.FindFromKey(aF);
189     Standard_Boolean bExists=IsFaceIntersected(nF);
190     if (bExists) {
191       anIntersectedShapes.Add(aF);
192       IntersectionStates (aF, aM, anIntersectedShapes);
193     }
194   }
195   //
196   aEM.Clear();
197   TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
198   //
199   // 1.2. Edges that have Split parts
200   aNb=aEM.Extent();
201   for (i=1; i<=aNb; i++) {
202     const TopoDS_Shape& aE=aEM(i);
203     nE=aDSMap.FindFromKey(aE);
204     const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nE));
205     aNbPaveBlocks=aSplitEdges.Extent();
206     //
207     if (!aNbPaveBlocks) {
208       continue;
209     }
210     //
211     if (aNbPaveBlocks==1) {
212       const BOPTools_ListOfCommonBlock& aCBlocks=aCommonBlockPool(myDS->RefEdge(nE));
213       if (!aCBlocks.Extent()) {
214         const BOPTools_PaveBlock& aPB=aSplitEdges.First();
215         Standard_Integer nEB=aPB.Edge();
216         if (nEB==aPB.OriginalEdge()) {
217           Standard_Boolean bHasInterference=//;
218             Standard_False; //LNX
219           Standard_Integer j, aNbSuc, nV;
220           
221           aNbSuc=myDS->NumberOfSuccessors(nEB);
222           for (j=1; j<=aNbSuc; j++) {
223             nV=myDS->GetSuccessor(nE, j);
224             bHasInterference=myIntrPool->HasInterference(nV);
225             if (bHasInterference) {
226               break;
227             }
228           }
229           if (!bHasInterference) {
230             continue;
231           }
232         }
233       }
234     }
235     //
236     anIntersectedShapes.Add(aE);
237     IntersectionStates (aE, aM, anIntersectedShapes);
238   } // for (i=1; i<=aNb; i++)
239
240   //
241   // 1.3. Write Intersected state for anIntersectedShapes to the DS
242   aNb=anIntersectedShapes.Extent();
243   for (i=1; i<=aNb; i++) {
244     const TopoDS_Shape& aS=anIntersectedShapes(i);
245     nE=aDSMap.FindFromKey(aS);
246     myDS->SetState(nE, BooleanOperations_INTERSECTED);
247   }
248   //
249   // 2. aNonIntersectedShapes
250   //
251   aNb=aM.Extent();
252   for (i=1; i<=aNb; i++) {
253     const TopoDS_Shape& aS=aM.FindKey(i);
254     if (!anIntersectedShapes.Contains(aS)) {
255       aNonIntersectedShapes.Add(aS);
256     }
257   }
258   //
259   // 2.1. Processing of Non-intersected shapes 
260   BRep_Builder BB;
261   TopoDS_Compound aCompound;
262   BB.MakeCompound(aCompound);
263   aNb=aNonIntersectedShapes.Extent();
264   for (i=1; i<=aNb; i++) {
265     const TopoDS_Shape& aS=aNonIntersectedShapes(i);
266     BB.Add(aCompound, aS);
267   }
268   
269   TopExp::MapShapesAndAncestors (aCompound, TopAbs_EDGE, TopAbs_FACE, aMEF);
270   //
271   TopTools_IndexedMapOfShape aProcessedShapes;
272   BOPTools_IndexedDataMapOfShapeWithState aSWS;
273   Standard_Boolean bHasConnexity;
274   //
275   BOPTools_ListOfShapeEnum aEnumList;
276   aEnumList.Append(TopAbs_SHELL);
277   aEnumList.Append(TopAbs_FACE);
278   aEnumList.Append(TopAbs_WIRE);
279   aEnumList.Append(TopAbs_EDGE);
280   
281   BOPTools_ListIteratorOfListOfShapeEnum anIt(aEnumList);
282   for (; anIt.More(); anIt.Next()) {
283     TopAbs_ShapeEnum anEnum=anIt.Value();
284     aEM.Clear(); 
285     TopExp::MapShapes(aCompound, anEnum, aEM);
286     aNb=aEM.Extent();
287     for (i=1; i<=aNb; i++) {
288       const TopoDS_Shape& aS=aEM(i);
289       //
290       // DEBUG
291       //nE=aDSMap.FindFromKey(aS);
292       //
293       if (!aProcessedShapes.Contains(aS)) {
294         bHasConnexity=HasConnexity(aS, aSWS, aMVE, aState);
295         if (!bHasConnexity) {
296           aState=BOPTools_StateFiller::ClassifyShapeByRef (aS, aTool);
297         }
298         aSWS.Add(aS, aState);
299         aProcessedShapes.Add(aS);
300         if (anEnum==TopAbs_FACE) {
301           PropagateState(aS, aState, myDS, iRankObj, aSWS, aMEF, aProcessedShapes); 
302         }
303         else {
304           PropagateState(aS, aState, myDS, iRankObj, aSWS, aProcessedShapes); 
305         }
306       }
307     }
308   }
309   //
310   // 2.2. Write Stats for Non-intersected Shapes to the DS
311   aNb=aSWS.Extent();
312   for (i=1; i<=aNb; i++) {
313     const TopoDS_Shape& aS=aSWS.FindKey(i);
314     aState=aSWS.FindFromIndex(i);
315     nE=aDSMap.FindFromKey(aS);
316     myDS->SetState(nE, aState);
317   }
318
319   //---------------------------------------------------
320   //
321   // 3.  Intersected Edges' Processing
322   //
323   //---------------------------------------------------
324   Standard_Integer nSp, aNBVertices, nV1, nV2;
325   BooleanOperations_StateOfShape aStV1, aStV2;
326
327   aNb=anIntersectedShapes.Extent();
328   for (i=1; i<=aNb; i++) {
329     const TopoDS_Shape& aS=anIntersectedShapes(i);
330     if (aS.ShapeType()==TopAbs_EDGE) {
331       nE=aDSMap.FindFromKey(aS);
332       //
333       // 3.1. On Parts Processing
334       const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
335       BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
336       for (; anItCB.More(); anItCB.Next()) {
337         const BOPTools_CommonBlock& aCB=anItCB.Value();
338         BOPTools_CommonBlock* pCB=(BOPTools_CommonBlock*) &aCB;
339         BOPTools_PaveBlock& aPB=pCB->PaveBlock1(nE);
340         nSp=aPB.Edge();
341         myDS->SetState(nSp, BooleanOperations_ON);
342       }
343       //
344       // 3.2. IN, OUT Parts Processing
345       const BOPTools_ListOfPaveBlock& aSplits=aSplitShapesPool(myDS->RefEdge(nE));
346       BOPTools_ListIteratorOfListOfPaveBlock anItPB(aSplits);
347       for (; anItPB.More(); anItPB.Next()) {
348         const BOPTools_PaveBlock& aPB=anItPB.Value();
349         nSp=aPB.Edge();
350         const TopoDS_Shape& aSplit=myDS->Shape(nSp);
351
352         aState=myDS->GetState(nSp);
353         if (aState==BooleanOperations_UNKNOWN|| aState==BooleanOperations_INTERSECTED){
354           aNBVertices=myDS->NumberOfSuccessors(nE);
355           if (aNBVertices==2) {
356             nV1=myDS->GetSuccessor(nSp, 1);
357             aStV1=myDS->GetState(nV1);
358             nV2=myDS->GetSuccessor(nSp, 2);
359             aStV2=myDS->GetState(nV2);
360             if      ((aStV1==BooleanOperations_IN || aStV1==BooleanOperations_OUT) 
361                      && (aStV2==BooleanOperations_ON)) {
362               myDS->SetState(nSp, aStV1);
363             }
364             else if ((aStV2==BooleanOperations_IN || aStV2==BooleanOperations_OUT)
365                      && (aStV1==BooleanOperations_ON)) {
366               myDS->SetState(nSp, aStV2);
367             }
368             else {
369               aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
370               myDS->SetState(nSp, aState);
371               if (aStV1==BooleanOperations_UNKNOWN) {
372                 myDS->SetState(nV1, aState);
373               }
374               if (aStV2==BooleanOperations_UNKNOWN) {
375                 myDS->SetState(nV2, aState);
376               }
377             }
378           }// if (aNBVertices==2)
379           else {
380             aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
381             myDS->SetState(nSp, aState);
382           }
383
384         }// if (aState==BooleanOperations_UNKNOWN || BooleanOperations_INTERSECTED)
385       }//for (; anItPB.More(); anItPB.Next())
386     }// if (aS.ShapeType()==TopAbs_EDGE)
387   }// next "Intersected" Edge
388 }
389 //
390 //=======================================================================
391 // function: DoShellNonSections
392 // purpose: 
393 //=======================================================================
394   void BOPTools_SolidStateFiller::DoShellNonSections(const Standard_Integer iRankObj)
395 {
396
397   const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool(); 
398   //
399   // 0. Restore data and preparing 
400   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
401
402   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
403   const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
404
405   Standard_Integer i, nE,  aNbPaveBlocks, aNb, nF1, nF2, iRank, nFx;
406   BooleanOperations_StateOfShape aState;
407   TopTools_IndexedMapOfShape aEM, anIntersectedShapes, aNonIntersectedShapes;
408   TopTools_IndexedDataMapOfShapeListOfShape aM;
409   //
410   // aM Map
411   TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_WIRE , aM);
412   TopExp::MapShapesAndAncestors (anObj, TopAbs_WIRE , TopAbs_FACE , aM);
413   TopExp::MapShapesAndAncestors (anObj, TopAbs_FACE , TopAbs_SHELL, aM);
414   TopExp::MapShapesAndAncestors (anObj, TopAbs_SHELL, TopAbs_SOLID, aM);
415   //
416   // 1. anIntersectedShapes 
417   //
418   // 1.1. Check EF FF interferences with nF 
419   const BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
420   
421   aNb=aFFs.Extent();
422   for (i=1; i<=aNb; i++) {
423     const BOPTools_SSInterference& aFF=aFFs(i);
424     // nF1
425     nF1=aFF.Index1();
426     nF2=aFF.Index2();
427
428     iRank=myDS->Rank(nF1);
429     nFx=(iRank==myDS->Rank(nF1)) ? nF1 : nF2;
430
431     const TopoDS_Shape& aFx=myDS->Shape(nFx);
432     anIntersectedShapes.Add(aFx);
433     IntersectionStates (aFx, aM, anIntersectedShapes);
434   }
435   
436   //
437   TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
438   //
439   // 1.2. Edges that have Split parts
440   aNb=aEM.Extent();
441   for (i=1; i<=aNb; i++) {
442     const TopoDS_Shape& aE=aEM(i);
443     nE=aDSMap.FindFromKey(aE);
444     const BOPTools_ListOfPaveBlock& aSplitEdges=aSplitShapesPool(myDS->RefEdge(nE));
445     aNbPaveBlocks=aSplitEdges.Extent();
446     //
447     if (!aNbPaveBlocks) {
448       continue;
449     }
450     //
451     if (aNbPaveBlocks==1) {
452       const BOPTools_ListOfCommonBlock& aCBlocks=aCommonBlockPool(myDS->RefEdge(nE));
453       if (!aCBlocks.Extent()) {
454         const BOPTools_PaveBlock& aPB=aSplitEdges.First();
455         Standard_Integer nEB=aPB.Edge();
456         if (nEB==aPB.OriginalEdge()) {
457           Standard_Boolean bHasInterference=//; LNX
458             Standard_False;//LNX
459           Standard_Integer j, aNbSuc, nV;
460           
461           aNbSuc=myDS->NumberOfSuccessors(nEB);
462           for (j=1; j<=aNbSuc; j++) {
463             nV=myDS->GetSuccessor(nE, j);
464             bHasInterference=myIntrPool->HasInterference(nV);
465             if (bHasInterference) {
466               break;
467             }
468           }
469           if (!bHasInterference) {
470             continue;
471           }
472         }
473       }
474     }
475     //
476     anIntersectedShapes.Add(aE);
477     IntersectionStates (aE, aM, anIntersectedShapes);
478   } // for (i=1; i<=aNb; i++)
479   //
480   // 1.3. Write Intersected state for anIntersectedShapes to the DS
481   aNb=anIntersectedShapes.Extent();
482   for (i=1; i<=aNb; i++) {
483     const TopoDS_Shape& aS=anIntersectedShapes(i);
484     if (aDSMap.Contains(aS)) {
485       nE=aDSMap.FindFromKey(aS);
486       myDS->SetState(nE, BooleanOperations_INTERSECTED);
487     }
488   }
489   //
490   // 2. aNonIntersectedShapes
491   //
492   aNb=aM.Extent();
493   for (i=1; i<=aNb; i++) {
494     const TopoDS_Shape& aS=aM.FindKey(i);
495     if (!anIntersectedShapes.Contains(aS)) {
496       aNonIntersectedShapes.Add(aS);
497     }
498   }
499   //
500   // 2.1. Write Stats for Non-intersected Shapes to the DS
501   aNb=aNonIntersectedShapes.Extent();
502   for (i=1; i<=aNb; i++) {
503     const TopoDS_Shape& aS=aNonIntersectedShapes(i);
504     nE=aDSMap.FindFromKey(aS);
505     myDS->SetState(nE, BooleanOperations_OUT);
506   }
507   //---------------------------------------------------
508   //
509   // 3.  Intersected Edges' Processing
510   //
511   //---------------------------------------------------
512   Standard_Integer nSp;
513   
514
515   aNb=anIntersectedShapes.Extent();
516   for (i=1; i<=aNb; i++) {
517     const TopoDS_Shape& aS=anIntersectedShapes(i);
518     if (aS.ShapeType()==TopAbs_EDGE) {
519       nE=aDSMap.FindFromKey(aS);
520       //
521       // 3.1. On Parts Processing
522       const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
523       BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
524       for (; anItCB.More(); anItCB.Next()) {
525         const BOPTools_CommonBlock& aCB=anItCB.Value();
526         BOPTools_CommonBlock* pCB=(BOPTools_CommonBlock*) &aCB;
527         BOPTools_PaveBlock& aPB=pCB->PaveBlock1(nE);
528         nSp=aPB.Edge();
529         myDS->SetState(nSp, BooleanOperations_ON);
530       }
531       //
532       // 3.2. IN, OUT Parts Processing
533       const BOPTools_ListOfPaveBlock& aSplits=aSplitShapesPool(myDS->RefEdge(nE));
534       BOPTools_ListIteratorOfListOfPaveBlock anItPB(aSplits);
535       for (; anItPB.More(); anItPB.Next()) {
536         const BOPTools_PaveBlock& aPB=anItPB.Value();
537         nSp=aPB.Edge();
538         //const TopoDS_Shape& aSplit=myDS->Shape(nSp);//LNX
539
540         aState=myDS->GetState(nSp);
541         if (aState==BooleanOperations_UNKNOWN|| aState==BooleanOperations_INTERSECTED){
542           myDS->SetState(nSp, BooleanOperations_OUT);
543         
544         }// if (aState==BooleanOperations_UNKNOWN || BooleanOperations_INTERSECTED)
545       }//for (; anItPB.More(); anItPB.Next())
546     }// if (aS.ShapeType()==TopAbs_EDGE)
547   }// next "Intersected" Edge
548 }
549 //
550 //=======================================================================
551 // function: DoSections
552 // purpose: 
553 //=======================================================================
554   void BOPTools_SolidStateFiller::DoSections()
555 {
556   Standard_Integer i, j, aNb, aNbCurves,  n1, n2, nE;
557   
558   BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
559   
560   aNb=aFFs.Extent();
561   for (i=1; i<=aNb; i++) {
562     BOPTools_SSInterference& aFF=aFFs(i);
563     n1=aFF.Index1();
564     n2=aFF.Index2();
565     BOPTools_SequenceOfCurves& aSC=aFF.Curves();
566     aNbCurves=aSC.Length();
567     for (j=1; j<=aNbCurves; j++) {
568       const BOPTools_Curve& aBC=aSC(j);
569       const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
570       BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
571       for (; anIt.More(); anIt.Next()) {
572         const BOPTools_PaveBlock& aPB=anIt.Value();
573         nE=aPB.Edge();
574         myDS->SetState(nE, BooleanOperations_ON);
575       }
576     }
577   } 
578 }
579
580 //=======================================================================
581 // function: IsFaceIntersected
582 // purpose: 
583 //=======================================================================
584   Standard_Boolean BOPTools_SolidStateFiller::IsFaceIntersected(const Standard_Integer nF) 
585 {
586   Standard_Boolean bFlag=Standard_False;
587   Standard_Integer i, aNb, n1, n2;
588   
589   const BOPTools_CArray1OfESInterference& aEFs=myIntrPool->ESInterferences();
590   aNb=aEFs.Extent();
591   for (i=1; i<=aNb; i++) {
592     const BOPTools_ESInterference& aEF=aEFs(i);
593     n1=aEF.Index1();
594     n2=aEF.Index2();
595     if (n1==nF || n2==nF) {
596       return !bFlag;
597     }
598   }
599
600   const BOPTools_CArray1OfSSInterference& aFFs=myIntrPool->SSInterferences();
601   aNb=aFFs.Extent();
602   for (i=1; i<=aNb; i++) {
603     const BOPTools_SSInterference& aFF=aFFs(i);
604     n1=aFF.Index1();
605     n2=aFF.Index2();
606     if (n1==nF || n2==nF) {
607       return !bFlag;
608     }
609   }
610   return bFlag;
611 }
612
613
614
615
616
617 //=======================================================================
618 // function: PropagateState [for faces]
619 // purpose: 
620 //=======================================================================
621   void PropagateState(const TopoDS_Shape& aF,
622                       const BooleanOperations_StateOfShape aState,
623                       BooleanOperations_ShapesDataStructure* pDS,
624                       const Standard_Integer iRank,
625                       BOPTools_IndexedDataMapOfShapeWithState& aSWS,
626                       const TopTools_IndexedDataMapOfShapeListOfShape& aEFMap,
627                       TopTools_IndexedMapOfShape& aProcessedShapes)
628 {
629   // PropagateState for Sub-Shapes
630   PropagateState (aF, aState, pDS, iRank, aSWS, aProcessedShapes);
631   // PropagateState for connected Faces;
632   TopTools_IndexedMapOfShape anEdgeMap;
633   TopExp::MapShapes(aF, TopAbs_EDGE, anEdgeMap);
634   
635   Standard_Integer i, aNbE;
636   aNbE=anEdgeMap.Extent();
637   
638   for (i=1; i<=aNbE; i++) {
639     const TopoDS_Shape& aE=anEdgeMap(i);
640     //
641     const TopTools_ListOfShape& aFacesList=aEFMap.FindFromKey(aE);
642     //
643     TopTools_ListIteratorOfListOfShape anIt(aFacesList);
644     for (; anIt.More(); anIt.Next()) {
645       const TopoDS_Shape& aFi=anIt.Value();
646       if (!aProcessedShapes.Contains(aFi)) {
647         if (!aFi.IsSame(aF)) {
648           aSWS.Add(aFi, aState);
649           aProcessedShapes.Add(aFi);
650           PropagateState(aFi, aState, pDS, iRank, aSWS, aEFMap, aProcessedShapes);
651         }
652       }
653     }
654   }
655 }
656
657 //=======================================================================
658 // function:  PropagateState
659 // purpose: 
660 //=======================================================================
661 void PropagateState(const TopoDS_Shape& aSS,
662                     const BooleanOperations_StateOfShape aState,
663                     BooleanOperations_ShapesDataStructure* pDS,
664                     const Standard_Integer iRank,
665                     BOPTools_IndexedDataMapOfShapeWithState& aSWS,
666                     TopTools_IndexedMapOfShape& aProcessedShapes)
667 {
668   TopAbs_ShapeEnum aSubType;
669
670   aSubType=BOPTools_StateFiller::SubType(aSS);
671   
672   if (aSubType==TopAbs_SHAPE) {
673     return;
674   }
675
676   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap= pDS->ShapeIndexMap(iRank);
677
678   TopTools_IndexedMapOfShape aSubMap;
679   TopExp::MapShapes(aSS, aSubType, aSubMap);
680
681   Standard_Integer i, aNb, nV;
682   aNb=aSubMap.Extent();
683   for (i=1; i<=aNb; i++) {
684     const TopoDS_Shape& aS=aSubMap(i);
685     if (!aProcessedShapes.Contains(aS)) {
686       if (aSubType==TopAbs_VERTEX) {
687         nV=aDSMap.FindFromKey(aS);
688         BooleanOperations_StateOfShape aSt=pDS->GetState(nV);
689         if (aSt!=BooleanOperations_UNKNOWN){
690           aProcessedShapes.Add(aS);
691           continue;
692         }
693       }
694       aSWS.Add(aS, aState);
695       aProcessedShapes.Add(aS);
696       PropagateState (aS, aState, pDS, iRank, aSWS, aProcessedShapes);
697     }
698   }
699 }           
700 //=======================================================================
701 // function: IntersectionStates 
702 // purpose: 
703 //=======================================================================
704 void IntersectionStates(const TopoDS_Shape& aE,
705                         const TopTools_IndexedDataMapOfShapeListOfShape& aM,
706                         TopTools_IndexedMapOfShape& anIntersectedShapes)
707 {
708   if (aM.Contains(aE)) {
709     const TopTools_ListOfShape& anAncesstors=aM.FindFromKey(aE);
710     TopTools_ListIteratorOfListOfShape anIt(anAncesstors);
711     for (; anIt.More(); anIt.Next()) {
712       const TopoDS_Shape& anAnc=anIt.Value();
713       anIntersectedShapes.Add(anAnc);
714       IntersectionStates(anAnc, aM, anIntersectedShapes);
715     }
716   }
717 }
718 //=======================================================================
719 // function:  HasConnexity
720 // purpose: 
721 //=======================================================================
722  Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
723                                const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
724                                const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
725                                BooleanOperations_StateOfShape& aState)
726 {
727   TopAbs_ShapeEnum aType;
728   BooleanOperations_StateOfShape aSt;
729   aType=aS.ShapeType();
730   if (aType!=TopAbs_EDGE) {
731     Standard_Integer i, aNb;
732     TopTools_IndexedMapOfShape aME;
733     TopExp::MapShapes(aS, TopAbs_EDGE, aME);
734     aNb=aME.Extent();
735     for (i=1; i<=aNb; i++) {
736       const TopoDS_Shape& aE=aME(i);
737       if (aSWS.Contains(aE)){
738         aSt=aSWS.FindFromKey(aE);
739         aState=aSt;
740         return Standard_True;
741       }
742     }
743   }
744   else {
745     TopExp_Explorer anExp (aS, TopAbs_VERTEX);
746     for (; anExp.More(); anExp.Next()) {
747       const TopoDS_Shape& aV=anExp.Current();
748       if (aMVE.Contains(aV)) {
749         const TopTools_ListOfShape& anEdgesList=aMVE.FindFromKey(aV);
750         TopTools_ListIteratorOfListOfShape anIt(anEdgesList);
751         for (; anIt.More(); anIt.Next()) {
752           const TopoDS_Shape& aEx=anIt.Value();
753           if (aSWS.Contains(aEx)) {
754             aSt=aSWS.FindFromKey(aEx);
755             aState=aSt;
756             return Standard_True;
757           }
758         }
759       }
760     }
761   }
762   
763   aState=BooleanOperations_UNKNOWN;
764   return Standard_False;
765 }
766
767 /*
768 //=======================================================================
769 // function:  ConvertState
770 // purpose: 
771 //=======================================================================
772 BooleanOperations_StateOfShape 
773     BOPTools_SolidStateFiller::ConvertState(const TopAbs_State aSt)
774 {
775   BooleanOperations_StateOfShape aState;
776   switch (aSt) {
777     case TopAbs_IN:
778       aState=BooleanOperations_IN;
779       break;
780     case TopAbs_OUT:
781       aState=BooleanOperations_OUT;
782       break;  
783     case TopAbs_ON:
784       aState=BooleanOperations_ON;
785       break;  
786     case TopAbs_UNKNOWN:
787       aState=BooleanOperations_UNKNOWN;
788       break;  
789     default:
790       aState=BooleanOperations_UNKNOWN;
791       break;  
792   }
793   return aState;
794 }
795
796 //=======================================================================
797 // function:  ConvertState
798 // purpose: 
799 //=======================================================================
800 TopAbs_State 
801     BOPTools_SolidStateFiller::ConvertState(const BooleanOperations_StateOfShape aSt)
802 {
803   TopAbs_State aState;
804   
805   switch (aSt) {
806     case BooleanOperations_IN:
807       aState=TopAbs_IN;
808       break;
809     case BooleanOperations_OUT:
810       aState=TopAbs_OUT;
811       break;  
812     case BooleanOperations_ON:
813       aState=TopAbs_ON;
814       break;  
815     case BooleanOperations_UNKNOWN:
816       aState=TopAbs_UNKNOWN;
817       break;  
818     default:
819       aState=TopAbs_UNKNOWN;
820       break;  
821   }
822   return aState;
823 }                                           
824 //=======================================================================
825 // function:  ClassifyShapeByRef
826 // purpose: 
827 //=======================================================================
828   BooleanOperations_StateOfShape 
829     BOPTools_SolidStateFiller::ClassifyShapeByRef (const TopoDS_Shape& aS,
830                                                    const TopoDS_Shape& aRef)
831 {
832   TopAbs_ShapeEnum aType;
833   aType=aS.ShapeType();
834
835   TopoDS_Edge aE;
836   if (aType!=TopAbs_EDGE) {
837     TopTools_IndexedMapOfShape aME;
838     TopExp::MapShapes(aS, TopAbs_EDGE, aME);
839     aE=TopoDS::Edge(aME(1));
840   }
841   else {
842     aE=TopoDS::Edge(aS);
843   }
844   
845   TopAbs_State aSt=BOPTools_SolidStateFiller::ClassifyEdgeToSolidByOnePoint(aE, aRef);
846   BooleanOperations_StateOfShape aState=BOPTools_SolidStateFiller::ConvertState(aSt) ;
847   
848   return aState;
849 }
850
851 //=======================================================================
852 // function:  ClassifyEdgeToSolidByOnePoint
853 // purpose: 
854 //=======================================================================
855 TopAbs_State 
856   BOPTools_SolidStateFiller::ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
857                                                            const TopoDS_Shape& Ref)
858 {
859   Standard_Real f2 = 0., l2 = 0., par = 0.;
860   
861   Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
862   gp_Pnt aP3d;
863
864   
865
866   if(C3D.IsNull()) {
867     //it means that we are in degenerated edge
868     const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
869     if(fv.IsNull()){
870       return TopAbs_UNKNOWN;
871     }
872     aP3d = BRep_Tool::Pnt(fv);
873   }
874   else {//usual case
875     par=IntTools_Tools::IntermediatePoint(f2, l2);
876     C3D -> D0(par, aP3d);
877   }
878     
879   BRepClass3d_SolidClassifier SC(Ref);
880   SC.Perform(aP3d, 1e-7);
881   
882   TopAbs_State aState=SC.State();
883   
884   return aState;
885 }
886 //=======================================================================
887 // function:  SubType
888 // purpose: 
889 //=======================================================================
890   TopAbs_ShapeEnum BOPTools_SolidStateFiller::SubType(const TopoDS_Shape& aS)
891 {
892   TopAbs_ShapeEnum aSourceType, aReturnType;
893   aSourceType=aS.ShapeType();
894
895   switch (aSourceType) {
896     case TopAbs_SOLID:
897       aReturnType=TopAbs_SHELL;
898       break;
899     case TopAbs_SHELL:
900       aReturnType=TopAbs_FACE;
901       break;
902     case TopAbs_FACE:
903       aReturnType=TopAbs_WIRE;
904       break;  
905     case TopAbs_WIRE:
906       aReturnType=TopAbs_EDGE;
907       break;   
908     case TopAbs_EDGE:
909       aReturnType=TopAbs_VERTEX;
910       break;     
911     default:
912       aReturnType=TopAbs_SHAPE;
913       break;
914   }
915   return aReturnType;
916 }
917 */