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