b311480e |
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 | |
7fd59977 |
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 | */ |