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