b311480e |
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 | |
7fd59977 |
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 | //======================================================================= |
b311480e |
53 | BOPTools_WireStateFiller::BOPTools_WireStateFiller(const BOPTools_PaveFiller& aFiller) |
7fd59977 |
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 | } |