Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BOPTools / BOPTools_WireStateFiller.cxx
1 // File:        BOPTools_WireStateFiller.cxx
2 // Created:     Mon Feb  4 10:18:15 2002
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <BOPTools_WireStateFiller.ixx>
8
9 #include <TopoDS.hxx>
10 #include <TopoDS_Shape.hxx>
11
12 #include <TopExp.hxx>
13 #include <TopTools_IndexedMapOfShape.hxx>
14
15 #include <TopAbs_ShapeEnum.hxx>
16
17 #include <BRep_Tool.hxx>
18
19 #include <BooleanOperations_ShapesDataStructure.hxx>
20 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
21 #include <BooleanOperations_StateOfShape.hxx>
22
23 #include <BOPTools_SplitShapesPool.hxx>
24 #include <BOPTools_CommonBlockPool.hxx>
25 #include <BOPTools_CommonBlock.hxx>
26 #include <BOPTools_PaveBlock.hxx>
27 #include <BOPTools_ListOfPaveBlock.hxx>
28 #include <BOPTools_ListOfCommonBlock.hxx>
29 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
30 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
31 #include <BOPTools_InterferencePool.hxx>
32
33
34 //=======================================================================
35 // function:  BOPTools_WireStateFiller::BOPTools_WireStateFiller
36 // purpose: 
37 //=======================================================================
38   BOPTools_WireStateFiller::BOPTools_WireStateFiller(const BOPTools_PaveFiller& aFiller)
39 :
40   BOPTools_StateFiller(aFiller)
41 {
42 }
43
44 //=======================================================================
45 // function: Do 
46 // purpose: 
47 //=======================================================================
48   void BOPTools_WireStateFiller::Do()
49 {
50   TopAbs_ShapeEnum aT1, aT2;
51
52   aT1=(myDS->Object()).ShapeType();
53   aT2=(myDS->Tool()).ShapeType();
54
55   myIsDone=Standard_True;
56   
57   if (aT1==TopAbs_WIRE && aT2==TopAbs_WIRE){
58     DoWires(1);
59     DoWires(2);
60   }
61   else if (aT1==TopAbs_WIRE  && aT2==TopAbs_SHELL){
62     DoWires(1);
63   }
64   else if (aT2==TopAbs_WIRE  && aT1==TopAbs_SHELL){
65     DoWires(2);
66   }
67   else if (aT1==TopAbs_WIRE && aT2==TopAbs_SOLID){
68     DoWireSolid(1);
69   }
70   else if (aT2==TopAbs_WIRE && aT1==TopAbs_SOLID){
71     DoWireSolid(2);
72   }
73   else {
74     myIsDone=!myIsDone;
75   }
76   
77 }
78
79 //=======================================================================
80 // function: DoWires
81 // purpose: 
82 //=======================================================================
83   void BOPTools_WireStateFiller::DoWires (const Standard_Integer iRankObj)
84 {
85   const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool(); 
86   //
87   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
88   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
89   const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
90   //
91   Standard_Integer i, aNbPaveBlocks, nSp, aNbE, nE;
92   BooleanOperations_StateOfShape aSt;
93   BOPTools_ListIteratorOfListOfPaveBlock anItPB;
94   BOPTools_ListIteratorOfListOfCommonBlock anItCB;
95   TopTools_IndexedMapOfShape aEM;
96   //
97   TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
98   aNbE=aEM.Extent();
99   //
100   // 1
101   for (i=1; i<=aNbE; i++) {
102     const TopoDS_Edge& aE=TopoDS::Edge(aEM(i));
103     nE=aDSMap.FindFromKey(aE);
104     //
105     if (BRep_Tool::Degenerated(aE)){
106       continue;
107     }
108     //
109     const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
110     //
111     anItCB.Initialize(aLCB);
112     for (; anItCB.More(); anItCB.Next()) {
113       BOPTools_CommonBlock& aCB=anItCB.Value();
114       BOPTools_PaveBlock& aPB=aCB.PaveBlock1(nE);
115       nSp=aPB.Edge();
116       myDS->SetState(nSp, BooleanOperations_ON);
117     }
118   }
119   //
120   // 2
121   for (i=1; i<=aNbE; i++) {
122     const TopoDS_Edge& aE=TopoDS::Edge(aEM(i));
123     nE=aDSMap.FindFromKey(aE);
124     //
125     if (BRep_Tool::Degenerated(aE)){
126       continue;
127     }
128     //
129     const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(myDS->RefEdge(nE));
130     //
131     aNbPaveBlocks=aLPB.Extent();
132     
133     if (!aNbPaveBlocks) {
134       myDS->SetState(nE, BooleanOperations_OUT);
135       continue;
136     }
137     //
138     anItPB.Initialize(aLPB);
139     for (; anItPB.More(); anItPB.Next()) {
140       const BOPTools_PaveBlock& aPB=anItPB.Value();
141       nSp=aPB.Edge();
142       aSt=myDS-> GetState(nSp);
143       if (aSt!=BooleanOperations_ON) {
144         myDS->SetState(nSp, BooleanOperations_OUT);
145       }
146     }
147   }
148 }
149 //=======================================================================
150
151 #include <TopoDS_Shape.hxx>
152 #include <TopoDS_Compound.hxx>
153 #include <TopExp.hxx>
154 #include <TopExp_Explorer.hxx>
155 #include <TopTools_ListIteratorOfListOfShape.hxx>
156
157 #include <TopTools_IndexedMapOfShape.hxx>
158 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
159
160 #include <BRep_Builder.hxx>
161
162 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
163
164 #include <BOPTools_SplitShapesPool.hxx>
165 #include <BOPTools_CommonBlockPool.hxx>
166 #include <BOPTools_ListOfPaveBlock.hxx>
167 #include <BOPTools_ListOfCommonBlock.hxx>
168 #include <BOPTools_PaveBlock.hxx>
169 #include <BOPTools_CommonBlock.hxx>
170 #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
171 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
172 #include <BOPTools_IndexedDataMapOfShapeWithState.hxx>
173 #include <BOPTools_StateFiller.hxx>
174
175 static
176   void PropagateState(const TopoDS_Shape& aS,
177                       const BooleanOperations_StateOfShape aState,
178                       BooleanOperations_ShapesDataStructure* pDS,
179                       const Standard_Integer iRank,
180                       BOPTools_IndexedDataMapOfShapeWithState& aSWS,
181                       TopTools_IndexedMapOfShape& aProcessedShapes);
182
183 static
184   Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
185                                const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
186                                const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
187                                BooleanOperations_StateOfShape& aState);
188
189 //=======================================================================
190 // function: DoWireSolid
191 // purpose: 
192 //=======================================================================
193   void BOPTools_WireStateFiller::DoWireSolid (const Standard_Integer iRankObj)
194 {
195   const TopoDS_Shape& anObj=(iRankObj==1) ? myDS->Object() : myDS->Tool();
196   const TopoDS_Shape& aTool=(iRankObj==1) ? myDS->Tool()   : myDS->Object();
197   //
198   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap=myDS->ShapeIndexMap(iRankObj);
199   const BOPTools_SplitShapesPool& aSplitShapesPool=myFiller->SplitShapesPool();
200   const BOPTools_CommonBlockPool& aCommonBlockPool=myFiller->CommonBlockPool();
201   //
202   Standard_Integer i, aNb, nE, aNbPB;
203   BooleanOperations_StateOfShape aState;
204   TopTools_IndexedMapOfShape aEM, anIntersectedShapes, aNonIntersectedShapes;
205   TopTools_IndexedDataMapOfShapeListOfShape aM, aMVE;
206   
207   //
208   // aM Map
209   TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_WIRE , aM);
210   // VE Map
211   TopExp::MapShapesAndAncestors (anObj, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
212   //
213   // 1.2. Edges that have Split parts
214   TopExp::MapShapes(anObj, TopAbs_EDGE, aEM);
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& aLPB=aSplitShapesPool(myDS->RefEdge(nE));
220     aNbPB=aLPB.Extent();
221     //
222     if (!aNbPB) {
223       continue;
224     }
225     //
226     if (aNbPB==1) {
227       const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
228       if (!aLCB.Extent()) {
229         const BOPTools_PaveBlock& aPB=aLPB.First();
230         Standard_Integer nEB=aPB.Edge();
231         if (nEB==aPB.OriginalEdge()) {
232           Standard_Boolean bHasInterference=Standard_False;// Wng in Gcc 3.0
233           Standard_Integer j, aNbSuc, nV;
234           aNbSuc=myDS->NumberOfSuccessors(nEB);
235           for (j=1; j<=aNbSuc; j++) {
236             nV=myDS->GetSuccessor(nE, j);
237             bHasInterference=myIntrPool->HasInterference(nV);
238             if (bHasInterference) {
239               break;
240             }
241           }
242           if (!bHasInterference) {
243             continue;
244           }
245         }
246       }
247     }
248     anIntersectedShapes.Add(aE);
249   }// for (i=1; i<=aNb; i++)
250   //
251   // 1.3. Write Intersected state for anIntersectedShapes to the DS
252   aNb=anIntersectedShapes.Extent();
253   for (i=1; i<=aNb; i++) {
254     const TopoDS_Shape& aS=anIntersectedShapes(i);
255     nE=aDSMap.FindFromKey(aS);
256     myDS->SetState(nE, BooleanOperations_INTERSECTED);
257   }
258   //
259   // 2. aNonIntersectedShapes
260   //
261   aNb=aM.Extent();
262   for (i=1; i<=aNb; i++) {
263     const TopoDS_Shape& aS=aM.FindKey(i);
264     if (!anIntersectedShapes.Contains(aS)) {
265       aNonIntersectedShapes.Add(aS);
266     }
267   }
268   //
269   // 2.1. Processing of Non-intersected shapes 
270   BRep_Builder BB;
271   TopoDS_Compound aCompound;
272   BB.MakeCompound(aCompound);
273   aNb=aNonIntersectedShapes.Extent();
274   for (i=1; i<=aNb; i++) {
275     const TopoDS_Shape& aS=aNonIntersectedShapes(i);
276     BB.Add(aCompound, aS);
277   }
278   //
279   TopTools_IndexedMapOfShape aProcessedShapes;
280   BOPTools_IndexedDataMapOfShapeWithState aSWS;
281   Standard_Boolean bHasConnexity;
282   //
283   aEM.Clear(); 
284   TopExp::MapShapes(aCompound, TopAbs_EDGE, aEM);
285   aNb=aEM.Extent();
286   for (i=1; i<=aNb; i++) {
287     const TopoDS_Shape& aS=aEM(i);
288     if (!aProcessedShapes.Contains(aS)) {
289       bHasConnexity=HasConnexity(aS, aSWS, aMVE, aState);
290       if (!bHasConnexity) {
291         aState=BOPTools_StateFiller::ClassifyShapeByRef (aS, aTool);
292       }
293       aSWS.Add(aS, aState);
294       aProcessedShapes.Add(aS);
295       PropagateState(aS, aState, myDS, iRankObj, aSWS, aProcessedShapes); 
296     }
297   }
298   //
299   // 2.2. Write Stats for Non-intersected Shapes to the DS
300   aNb=aSWS.Extent();
301   for (i=1; i<=aNb; i++) {
302     const TopoDS_Shape& aS=aSWS.FindKey(i);
303     aState=aSWS.FindFromIndex(i);
304     nE=aDSMap.FindFromKey(aS);
305     myDS->SetState(nE, aState);
306   }
307   //---------------------------------------------------
308   //
309   // 3.  Intersected Edges' Processing
310   //
311   //---------------------------------------------------
312   Standard_Integer nSp, aNBVertices, nV1, nV2;
313   BooleanOperations_StateOfShape aStV1, aStV2;
314
315   aNb=anIntersectedShapes.Extent();
316   for (i=1; i<=aNb; i++) {
317     const TopoDS_Shape& aS=anIntersectedShapes(i);
318     if (aS.ShapeType()==TopAbs_EDGE) {
319       nE=aDSMap.FindFromKey(aS);
320       //
321       // 3.1. On Parts Processing
322       const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(myDS->RefEdge(nE));
323       BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
324       for (; anItCB.More(); anItCB.Next()) {
325         const BOPTools_CommonBlock& aCB=anItCB.Value();
326         BOPTools_CommonBlock* pCB=(BOPTools_CommonBlock*) &aCB;
327         BOPTools_PaveBlock& aPB=pCB->PaveBlock1(nE);
328         nSp=aPB.Edge();
329         myDS->SetState(nSp, BooleanOperations_ON);
330       }
331       //
332       // 3.2. IN, OUT Parts Processing
333       const BOPTools_ListOfPaveBlock& aSplits=aSplitShapesPool(myDS->RefEdge(nE));
334       BOPTools_ListIteratorOfListOfPaveBlock anItPB(aSplits);
335       for (; anItPB.More(); anItPB.Next()) {
336         const BOPTools_PaveBlock& aPB=anItPB.Value();
337         nSp=aPB.Edge();
338         const TopoDS_Shape& aSplit=myDS->Shape(nSp);
339
340         aState=myDS->GetState(nSp);
341         if (aState==BooleanOperations_UNKNOWN|| aState==BooleanOperations_INTERSECTED){
342           aNBVertices=myDS->NumberOfSuccessors(nE);
343           if (aNBVertices==2) {
344             nV1=myDS->GetSuccessor(nSp, 1);
345             aStV1=myDS->GetState(nV1);
346             nV2=myDS->GetSuccessor(nSp, 2);
347             aStV2=myDS->GetState(nV2);
348             if      ((aStV1==BooleanOperations_IN || aStV1==BooleanOperations_OUT) 
349                      && (aStV2==BooleanOperations_ON)) {
350               myDS->SetState(nSp, aStV1);
351             }
352             else if ((aStV2==BooleanOperations_IN || aStV2==BooleanOperations_OUT)
353                      && (aStV1==BooleanOperations_ON)) {
354               myDS->SetState(nSp, aStV2);
355             }
356             else {
357               aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
358               myDS->SetState(nSp, aState);
359               if (aStV1==BooleanOperations_UNKNOWN) {
360                 myDS->SetState(nV1, aState);
361               }
362               if (aStV2==BooleanOperations_UNKNOWN) {
363                 myDS->SetState(nV2, aState);
364               }
365             }
366           }// if (aNBVertices==2)
367           else {
368             aState=BOPTools_StateFiller::ClassifyShapeByRef(aSplit, aTool);
369             myDS->SetState(nSp, aState);
370           }
371         }// if (aState==BooleanOperations_UNKNOWN || BooleanOperations_INTERSECTED)
372       }//for (; anItPB.More(); anItPB.Next())
373     }// if (aS.ShapeType()==TopAbs_EDGE)
374   }// next "Intersected" Edge
375   
376 }
377
378 //=======================================================================
379 // function:  HasConnexity
380 // purpose: 
381 //=======================================================================
382  Standard_Boolean HasConnexity(const TopoDS_Shape& aS,
383                                const BOPTools_IndexedDataMapOfShapeWithState& aSWS,
384                                const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
385                                BooleanOperations_StateOfShape& aState)
386 {
387   TopAbs_ShapeEnum aType;
388   BooleanOperations_StateOfShape aSt;
389   aType=aS.ShapeType();
390   if (aType!=TopAbs_EDGE) {
391     Standard_Integer i, aNb;
392     TopTools_IndexedMapOfShape aME;
393     TopExp::MapShapes(aS, TopAbs_EDGE, aME);
394     aNb=aME.Extent();
395     for (i=1; i<=aNb; i++) {
396       const TopoDS_Shape& aE=aME(i);
397       if (aSWS.Contains(aE)){
398         aSt=aSWS.FindFromKey(aE);
399         aState=aSt;
400         return Standard_True;
401       }
402     }
403   }
404   else {
405     TopExp_Explorer anExp (aS, TopAbs_VERTEX);
406     for (; anExp.More(); anExp.Next()) {
407       const TopoDS_Shape& aV=anExp.Current();
408       if (aMVE.Contains(aV)) {
409         const TopTools_ListOfShape& anEdgesList=aMVE.FindFromKey(aV);
410         TopTools_ListIteratorOfListOfShape anIt(anEdgesList);
411         for (; anIt.More(); anIt.Next()) {
412           const TopoDS_Shape& aEx=anIt.Value();
413           if (aSWS.Contains(aEx)) {
414             aSt=aSWS.FindFromKey(aEx);
415             aState=aSt;
416             return Standard_True;
417           }
418         }
419       }
420     }
421   }
422   
423   aState=BooleanOperations_UNKNOWN;
424   return Standard_False;
425 }
426
427 //=======================================================================
428 // function:  PropagateState
429 // purpose: 
430 //=======================================================================
431 void PropagateState(const TopoDS_Shape& aSS,
432                     const BooleanOperations_StateOfShape aState,
433                     BooleanOperations_ShapesDataStructure* pDS,
434                     const Standard_Integer iRank,
435                     BOPTools_IndexedDataMapOfShapeWithState& aSWS,
436                     TopTools_IndexedMapOfShape& aProcessedShapes)
437 {
438   TopAbs_ShapeEnum aSubType;
439
440   aSubType=BOPTools_StateFiller::SubType(aSS);
441   
442   if (aSubType==TopAbs_SHAPE) {
443     return;
444   }
445
446   const BooleanOperations_IndexedDataMapOfShapeInteger& aDSMap= pDS->ShapeIndexMap(iRank);
447
448   TopTools_IndexedMapOfShape aSubMap;
449   TopExp::MapShapes(aSS, aSubType, aSubMap);
450
451   Standard_Integer i, aNb, nV;
452   aNb=aSubMap.Extent();
453   for (i=1; i<=aNb; i++) {
454     const TopoDS_Shape& aS=aSubMap(i);
455     if (!aProcessedShapes.Contains(aS)) {
456       if (aSubType==TopAbs_VERTEX) {
457         nV=aDSMap.FindFromKey(aS);
458         BooleanOperations_StateOfShape aSt=pDS->GetState(nV);
459         if (aSt!=BooleanOperations_UNKNOWN){
460           aProcessedShapes.Add(aS);
461           continue;
462         }
463       }
464       aSWS.Add(aS, aState);
465       aProcessedShapes.Add(aS);
466       PropagateState (aS, aState, pDS, iRank, aSWS, aProcessedShapes);
467     }
468   }
469 }