4e57c75e |
1 | // Created by: Peter KURNEV |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
19 | |
20 | #include <BOPAlgo_BOP.ixx> |
21 | |
22 | #include <TopAbs_ShapeEnum.hxx> |
23 | |
24 | #include <TopoDS_Compound.hxx> |
25 | #include <TopoDS_Iterator.hxx> |
26 | #include <BRep_Builder.hxx> |
27 | #include <TopExp_Explorer.hxx> |
28 | |
29 | #include <BOPTools.hxx> |
30 | #include <BOPTools_AlgoTools.hxx> |
31 | #include <BOPTools_AlgoTools3D.hxx> |
32 | |
33 | #include <BOPCol_ListOfShape.hxx> |
34 | #include <BOPAlgo_BuilderSolid.hxx> |
35 | #include <TopoDS_Edge.hxx> |
36 | |
37 | static |
38 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim); |
39 | |
40 | //======================================================================= |
41 | //function : |
42 | //purpose : |
43 | //======================================================================= |
44 | BOPAlgo_BOP::BOPAlgo_BOP() |
45 | : |
46 | BOPAlgo_Builder(), |
47 | myTools(myAllocator), |
48 | myMapTools(100, myAllocator) |
49 | { |
50 | myNbArgs=2; |
51 | Clear(); |
52 | } |
53 | //======================================================================= |
54 | //function : |
55 | //purpose : |
56 | //======================================================================= |
57 | BOPAlgo_BOP::BOPAlgo_BOP(const Handle(NCollection_BaseAllocator)& theAllocator) |
58 | : |
59 | BOPAlgo_Builder(theAllocator), |
60 | myTools(myAllocator), |
61 | myMapTools(100, myAllocator) |
62 | { |
63 | myNbArgs=2; |
64 | Clear(); |
65 | } |
66 | //======================================================================= |
67 | //function : ~ |
68 | //purpose : |
69 | //======================================================================= |
70 | BOPAlgo_BOP::~BOPAlgo_BOP() |
71 | { |
72 | } |
73 | //======================================================================= |
74 | //function : Clear |
75 | //purpose : |
76 | //======================================================================= |
77 | void BOPAlgo_BOP::Clear() |
78 | { |
79 | myOperation=BOPAlgo_UNKNOWN; |
80 | myTools.Clear(); |
81 | myMapTools.Clear(); |
82 | myDims[0]=-1; |
83 | myDims[1]=-1; |
84 | // |
85 | BOPAlgo_Builder::Clear(); |
86 | } |
87 | //======================================================================= |
88 | //function : AddArgument |
89 | //purpose : |
90 | //======================================================================= |
91 | void BOPAlgo_BOP::AddArgument(const TopoDS_Shape& theShape) |
92 | { |
93 | if (myMapFence.Add(theShape)) { |
94 | myArguments.Append(theShape); |
95 | myArgs[0]=theShape; |
96 | } |
97 | } |
98 | //======================================================================= |
99 | //function : AddTool |
100 | //purpose : |
101 | //======================================================================= |
102 | void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape) |
103 | { |
104 | if (myMapTools.Add(theShape)) { |
105 | myTools.Append(theShape); |
106 | myArgs[1]=theShape; |
107 | // |
108 | if (myMapFence.Add(theShape)) { |
109 | myArguments.Append(theShape); |
110 | } |
111 | } |
112 | } |
113 | //======================================================================= |
114 | //function : Object |
115 | //purpose : |
116 | //======================================================================= |
117 | const TopoDS_Shape& BOPAlgo_BOP::Object()const |
118 | { |
119 | return myArgs[0]; |
120 | } |
121 | //======================================================================= |
122 | //function : Tool |
123 | //purpose : |
124 | //======================================================================= |
125 | const TopoDS_Shape& BOPAlgo_BOP::Tool()const |
126 | { |
127 | return myArgs[1]; |
128 | } |
129 | //======================================================================= |
130 | //function : SetOperation |
131 | //purpose : |
132 | //======================================================================= |
133 | void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation) |
134 | { |
135 | myOperation=theOperation; |
136 | } |
137 | //======================================================================= |
138 | //function : Operation |
139 | //purpose : |
140 | //======================================================================= |
141 | BOPAlgo_Operation BOPAlgo_BOP::Operation()const |
142 | { |
143 | return myOperation; |
144 | } |
145 | //======================================================================= |
146 | //function : CheckData |
147 | //purpose : |
148 | //======================================================================= |
149 | void BOPAlgo_BOP::CheckData() |
150 | { |
151 | Standard_Integer i, aNb; |
152 | Standard_Boolean bFlag; |
153 | // |
154 | myErrorStatus=0; |
155 | // |
156 | aNb=myArguments.Extent(); |
157 | if (aNb!=myNbArgs) { |
7cfb3968 |
158 | if (aNb!=1 || !(myArgs[0].IsSame(myArgs[1]))) { |
159 | myErrorStatus=10; // invalid number of arguments |
160 | return; |
161 | } |
162 | } |
163 | // |
164 | if (!myPaveFiller) { |
165 | myErrorStatus=101; |
4e57c75e |
166 | return; |
167 | } |
168 | // |
7cfb3968 |
169 | myErrorStatus=myPaveFiller->ErrorStatus(); |
4e57c75e |
170 | if (myErrorStatus) { |
171 | return; |
172 | } |
173 | // |
174 | for (i=0; i<myNbArgs; ++i) { |
175 | if (myArgs[i].IsNull()) { |
176 | myErrorStatus=11; // argument is null shape |
177 | return; |
178 | } |
179 | } |
180 | // |
181 | for (i=0; i<myNbArgs; ++i) { |
182 | bFlag = BOPTools_AlgoTools3D::IsEmptyShape(myArgs[i]); |
183 | if(bFlag) { |
184 | myWarningStatus = 2; |
185 | } |
186 | } |
187 | // |
188 | for (i=0; i<myNbArgs; ++i) { |
189 | myDims[i]=BOPTools_AlgoTools::Dimension(myArgs[i]); |
190 | if (myDims[i]<0) { |
191 | myErrorStatus=13; // non-homogenious argument |
192 | return; |
193 | } |
194 | } |
195 | // |
196 | if (myOperation==BOPAlgo_UNKNOWN) { |
7cfb3968 |
197 | myErrorStatus=14; // non-licit operation |
4e57c75e |
198 | return; |
199 | } |
200 | else if (myDims[0]<myDims[1]) { |
201 | if (myOperation==BOPAlgo_FUSE || |
202 | myOperation==BOPAlgo_CUT21) { |
7cfb3968 |
203 | myErrorStatus=14; // non-licit operation for the arguments |
4e57c75e |
204 | return; |
205 | } |
206 | } |
207 | else if (myDims[0]>myDims[1]) { |
208 | if (myOperation==BOPAlgo_FUSE || |
209 | myOperation==BOPAlgo_CUT) { |
7cfb3968 |
210 | myErrorStatus=14; // non-licit operation for the arguments |
4e57c75e |
211 | return; |
212 | } |
213 | } |
214 | } |
215 | //======================================================================= |
216 | //function : Prepare |
217 | //purpose : |
218 | //======================================================================= |
219 | void BOPAlgo_BOP::Prepare() |
220 | { |
221 | Standard_Integer i; |
222 | BRep_Builder aBB; |
223 | // |
224 | BOPAlgo_Builder::Prepare(); |
225 | // |
226 | if(myWarningStatus == 2) { |
227 | switch(myOperation) { |
228 | case BOPAlgo_FUSE: |
229 | for ( i = 0; i < myNbArgs; i++ ) { |
230 | aBB.Add(myShape, myArgs[i]); |
231 | } |
232 | break; |
233 | case BOPAlgo_COMMON: |
234 | case BOPAlgo_SECTION: |
235 | break; |
236 | case BOPAlgo_CUT: |
237 | if(BOPTools_AlgoTools3D::IsEmptyShape(myArgs[0])) { |
238 | break; |
239 | } else { |
240 | aBB.Add(myShape, myArgs[0]); |
241 | } |
242 | break; |
243 | case BOPAlgo_CUT21: |
244 | if(BOPTools_AlgoTools3D::IsEmptyShape(myArgs[1])) { |
245 | break; |
246 | } else { |
247 | aBB.Add(myShape, myArgs[1]); |
248 | } |
249 | break; |
250 | default: |
251 | break; |
252 | } |
253 | } |
254 | } |
255 | //======================================================================= |
256 | //function : PerformInternal |
257 | //purpose : |
258 | //======================================================================= |
259 | void BOPAlgo_BOP::PerformInternal(const BOPAlgo_PaveFiller& theFiller) |
260 | { |
261 | myErrorStatus=0; |
262 | myWarningStatus=0; |
263 | // |
264 | myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller; |
265 | myDS=myPaveFiller->PDS(); |
266 | myContext=myPaveFiller->Context(); |
267 | // |
268 | // 1. CheckData |
269 | CheckData(); |
270 | if (myErrorStatus && !myWarningStatus) { |
271 | return; |
272 | } |
273 | // |
274 | // 2. Prepare |
275 | Prepare(); |
276 | if (myErrorStatus) { |
277 | return; |
278 | } |
279 | if(myWarningStatus == 2) { |
280 | return; |
281 | } |
282 | // |
283 | // 3. Fill Images |
284 | // 3.1 Vertices |
285 | FillImagesVertices(); |
286 | if (myErrorStatus) { |
287 | return; |
288 | } |
289 | // |
290 | BuildResult(TopAbs_VERTEX); |
291 | if (myErrorStatus) { |
292 | return; |
293 | } |
294 | // 3.2 Edges |
295 | FillImagesEdges(); |
296 | if (myErrorStatus) { |
297 | return; |
298 | } |
299 | |
300 | BuildResult(TopAbs_EDGE); |
301 | if (myErrorStatus) { |
302 | return; |
303 | } |
304 | //-------------------------------- SECTION f |
305 | if (myOperation==BOPAlgo_SECTION) { |
306 | BuildSection(); |
307 | PrepareHistory(); |
308 | PostTreat(); |
309 | return; |
310 | } |
311 | //-------------------------------- SECTION t |
312 | // |
313 | // 3.3 Wires |
314 | FillImagesContainers(TopAbs_WIRE); |
315 | if (myErrorStatus) { |
316 | return; |
317 | } |
318 | |
319 | BuildResult(TopAbs_WIRE); |
320 | if (myErrorStatus) { |
321 | return; |
322 | } |
323 | |
324 | // 3.4 Faces |
325 | FillImagesFaces(); |
326 | if (myErrorStatus) { |
327 | return; |
328 | } |
329 | |
330 | BuildResult(TopAbs_FACE); |
331 | if (myErrorStatus) { |
332 | return; |
333 | } |
334 | // 3.5 Shells |
335 | |
336 | FillImagesContainers(TopAbs_SHELL); |
337 | if (myErrorStatus) { |
338 | return; |
339 | } |
340 | |
341 | BuildResult(TopAbs_SHELL); |
342 | if (myErrorStatus) { |
343 | return; |
344 | } |
345 | // 3.6 Solids |
346 | FillImagesSolids(); |
347 | if (myErrorStatus) { |
348 | return; |
349 | } |
350 | |
351 | BuildResult(TopAbs_SOLID); |
352 | if (myErrorStatus) { |
353 | return; |
354 | } |
355 | // 3.7 CompSolids |
356 | FillImagesContainers(TopAbs_COMPSOLID); |
357 | if (myErrorStatus) { |
358 | return; |
359 | } |
360 | |
361 | BuildResult(TopAbs_COMPSOLID); |
362 | if (myErrorStatus) { |
363 | return; |
364 | } |
365 | // 3.8 Compounds |
366 | FillImagesCompounds(); |
367 | if (myErrorStatus) { |
368 | return; |
369 | } |
370 | |
371 | BuildResult(TopAbs_COMPOUND); |
372 | if (myErrorStatus) { |
373 | return; |
374 | } |
375 | // |
376 | // 6.BuildShape; |
377 | BuildShape(); |
378 | // |
379 | // 4.History |
380 | PrepareHistory(); |
381 | |
382 | // |
383 | // 5 Post-treatment |
384 | PostTreat(); |
385 | } |
386 | //======================================================================= |
387 | //function : BuildShape |
388 | //purpose : |
389 | //======================================================================= |
390 | void BOPAlgo_BOP::BuildShape() |
391 | { |
392 | Standard_Integer aDmin, aNbLCB; |
393 | TopAbs_ShapeEnum aT1, aT2, aTR; |
394 | TopoDS_Shape aR, aRC; |
395 | TopoDS_Iterator aIt; |
396 | BRep_Builder aBB; |
397 | BOPCol_ListOfShape aLCB; |
398 | BOPCol_ListIteratorOfListOfShape aItLCB; |
399 | // |
400 | myErrorStatus=0; |
401 | // |
402 | BuildRC(); |
403 | //myShape=myRC; |
404 | // |
405 | aDmin=myDims[1]; |
406 | if (myDims[0]<myDims[1]) { |
407 | aDmin=myDims[0]; |
408 | } |
409 | // |
410 | if (!aDmin) { |
411 | myShape=myRC; |
412 | return; |
413 | } |
414 | // |
415 | else if (aDmin==1 || aDmin==2) { //edges, faces |
416 | aT1=TopAbs_VERTEX; |
417 | aT2=TopAbs_EDGE; |
418 | aTR=TopAbs_WIRE; |
419 | if (aDmin==2) { |
420 | aT1=TopAbs_EDGE; |
421 | aT2=TopAbs_FACE; |
422 | aTR=TopAbs_SHELL; |
423 | } |
424 | // |
425 | BOPTools_AlgoTools::MakeConnexityBlocks(myRC, aT1, aT2, aLCB); |
426 | aNbLCB=aLCB.Extent(); |
427 | if (!aNbLCB) { |
428 | myShape=myRC; |
429 | return; |
430 | } |
431 | // |
432 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
433 | // |
434 | aItLCB.Initialize(aLCB); |
435 | for (; aItLCB.More(); aItLCB.Next()) { |
436 | BOPTools_AlgoTools::MakeContainer(aTR, aR); |
437 | // |
438 | const TopoDS_Shape& aCB=aItLCB.Value(); |
439 | aIt.Initialize(aCB); |
440 | for (; aIt.More(); aIt.Next()) { |
441 | const TopoDS_Shape& aS=aIt.Value(); |
442 | aBB.Add(aR, aS); |
443 | } |
444 | // |
445 | if (aTR==TopAbs_SHELL) { |
446 | BOPTools_AlgoTools::OrientFacesOnShell(aR); |
447 | } |
448 | // |
449 | aBB.Add(aRC, aR); |
450 | } |
451 | myShape=aRC; |
452 | }// elase if (aDmin==1 || aDmin==2) { |
453 | |
454 | else { //aDmin=3 |
455 | if (myOperation==BOPAlgo_FUSE) { |
456 | BuildSolid(); |
457 | } |
458 | else { |
459 | myShape=myRC; |
460 | } |
461 | } |
462 | } |
463 | //======================================================================= |
464 | //function : BuildRC |
465 | //purpose : |
466 | //======================================================================= |
467 | void BOPAlgo_BOP::BuildRC() |
468 | { |
469 | Standard_Boolean bFlag; |
1d47d8d0 |
470 | Standard_Integer i, aDmin, aNb[2], iX = 0, iY = 0; |
4e57c75e |
471 | TopAbs_ShapeEnum aTmin; |
472 | TopoDS_Compound aC, aCS[2]; |
473 | BRep_Builder aBB; |
474 | TopExp_Explorer aExp; |
475 | BOPCol_ListIteratorOfListOfShape aItIm; |
476 | BOPCol_IndexedMapOfShape aMS[2]; |
477 | BOPCol_IndexedMapOfShape aMSV[2]; |
478 | // |
479 | myErrorStatus=0; |
480 | // |
481 | // A. Fuse |
482 | if (myOperation==BOPAlgo_FUSE) { |
483 | aBB.MakeCompound(aC); |
484 | aTmin=TypeToExplore(myDims[0]); |
485 | aExp.Init(myShape, aTmin); |
486 | for (; aExp.More(); aExp.Next()) { |
487 | const TopoDS_Shape& aS=aExp.Current(); |
488 | aBB.Add(aC, aS); |
489 | } |
490 | myRC=aC; |
491 | return; |
492 | } |
493 | // |
494 | // B. Non-Fuse |
495 | // |
496 | // 1. Compounds CS that consist of an Arg or Images of the Arg |
497 | for (i=0; i<myNbArgs; ++i) { |
498 | aBB.MakeCompound(aCS[i]); |
499 | const TopoDS_Shape& aS=myArgs[i]; |
500 | if (myImages.IsBound(aS)){ |
501 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aS); |
502 | aItIm.Initialize(aLSIm); |
503 | for (; aItIm.More(); aItIm.Next()) { |
504 | const TopoDS_Shape& aSIm=aItIm.Value(); |
505 | aBB.Add(aCS[i], aSIm); |
506 | } |
507 | } |
508 | else { |
509 | aBB.Add(aCS[i], aS); |
510 | } |
511 | } |
512 | // |
513 | aDmin=myDims[1]; |
514 | if (myDims[0]<myDims[1]) { |
515 | aDmin=myDims[0]; |
516 | } |
517 | aTmin=TypeToExplore(aDmin); |
518 | for (i=0; i<myNbArgs; ++i) { |
519 | aExp.Init(aCS[i], aTmin); |
520 | for (; aExp.More(); aExp.Next()) { |
521 | const TopoDS_Shape aS=aExp.Current(); |
522 | if (aTmin == TopAbs_EDGE) { |
523 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aS)); |
524 | if (BRep_Tool::Degenerated(aE)) { |
525 | TopExp_Explorer aExpE(aE, TopAbs_VERTEX); |
526 | TopoDS_Shape aS1 = aExpE.Current(); |
527 | if (myImages.IsBound(aS1)){ |
528 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aS1); |
529 | const TopoDS_Shape& aSIm=aLSIm.First(); |
530 | aMSV[i].Add(aSIm); |
531 | } else { |
532 | aMSV[i].Add(aS1); |
533 | } |
534 | } |
535 | } |
536 | // |
537 | if (myImages.IsBound(aS)){ |
538 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aS); |
539 | aItIm.Initialize(aLSIm); |
540 | for (; aItIm.More(); aItIm.Next()) { |
541 | const TopoDS_Shape& aSIm=aItIm.Value(); |
542 | aMS[i].Add(aSIm); |
543 | } |
544 | } |
545 | else { |
546 | aMS[i].Add(aS); |
547 | } |
548 | } |
549 | aNb[i]=aMS[i].Extent(); |
550 | } |
551 | // |
552 | aBB.MakeCompound(aC); |
553 | // |
554 | // 3. Find common parts |
555 | if (myOperation==BOPAlgo_COMMON) { |
093bfc49 |
556 | if (myDims[0]==myDims[1]) { |
557 | iX=(aNb[0]>aNb[1])? 1 : 0; |
558 | } else { |
559 | iX=(myDims[0]<myDims[1]) ? 0 : 1; |
560 | } |
4e57c75e |
561 | iY=(iX+1)%2; |
562 | } |
563 | else if (myOperation==BOPAlgo_CUT) { |
564 | iX=0; |
565 | iY=1; |
566 | } |
567 | else if (myOperation==BOPAlgo_CUT21) { |
568 | iX=1; |
569 | iY=0; |
570 | } |
571 | for (i=1; i<=aNb[iX]; ++i) { |
572 | const TopoDS_Shape& aSx=aMS[iX].FindKey(i); |
573 | bFlag=aMS[iY].Contains(aSx); |
574 | if (aTmin == TopAbs_EDGE) { |
575 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aSx)); |
576 | if (BRep_Tool::Degenerated(aE)) { |
577 | TopExp_Explorer aExpE(aE, TopAbs_VERTEX); |
578 | TopoDS_Shape aSx1 = aExpE.Current(); |
579 | TopoDS_Shape aSIm; |
580 | if (myImages.IsBound(aSx1)) { |
581 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aSx1); |
582 | aSIm=aLSIm.First(); |
583 | } else { |
584 | aSIm = aSx1; |
585 | } |
586 | bFlag=aMSV[iY].Contains(aSIm); |
587 | } |
588 | } |
589 | // |
590 | if (myOperation!=BOPAlgo_COMMON) { |
591 | bFlag=!bFlag; |
592 | } |
593 | // |
594 | if (bFlag) { |
595 | aBB.Add(aC, aSx); |
596 | } |
597 | } |
598 | // |
599 | myRC=aC; |
600 | } |
601 | // |
602 | //======================================================================= |
603 | //function : TypeToExplore |
604 | //purpose : |
605 | //======================================================================= |
606 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim) |
607 | { |
608 | TopAbs_ShapeEnum aRet; |
609 | // |
610 | switch(theDim) { |
611 | case 0: |
612 | aRet=TopAbs_VERTEX; |
613 | break; |
614 | case 1: |
615 | aRet=TopAbs_EDGE; |
616 | break; |
617 | case 2: |
618 | aRet=TopAbs_FACE; |
619 | break; |
620 | case 3: |
621 | aRet=TopAbs_SOLID; |
622 | break; |
623 | default: |
624 | aRet=TopAbs_SHAPE; |
625 | break; |
626 | } |
627 | return aRet; |
628 | } |
629 | //======================================================================= |
630 | //function : BuildSolid |
631 | //purpose : |
632 | //======================================================================= |
633 | void BOPAlgo_BOP::BuildSolid() |
634 | { |
635 | Standard_Integer i, aNbF, aNbSx, iX, iErr; |
636 | TopAbs_Orientation aOr, aOr1; |
637 | TopoDS_Iterator aIt; |
638 | TopoDS_Shape aRC; |
639 | BRep_Builder aBB; |
640 | TopExp_Explorer aExp; |
641 | BOPCol_IndexedMapOfShape aMFI; |
642 | BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF; |
643 | BOPCol_ListIteratorOfListOfShape aItLS; |
644 | BOPCol_ListOfShape aSFS; |
645 | BOPAlgo_BuilderSolid aSB; |
646 | // |
647 | myErrorStatus=0; |
648 | // |
649 | aIt.Initialize(myRC); |
650 | for (; aIt.More(); aIt.Next()) { |
651 | const TopoDS_Shape& aSx=aIt.Value(); |
652 | aExp.Init(aSx, TopAbs_FACE); |
653 | for (; aExp.More(); aExp.Next()) { |
654 | const TopoDS_Shape& aFx=aExp.Current(); |
655 | // |
656 | aOr=aFx.Orientation(); |
657 | if (aOr==TopAbs_INTERNAL) { |
658 | aMFI.Add(aFx); |
659 | continue; |
660 | } |
661 | // |
662 | if (!aMFS.Contains(aFx)) { |
663 | BOPCol_ListOfShape aLSx; |
664 | // |
665 | aLSx.Append(aSx); |
666 | aMFS.Add(aFx, aLSx); |
667 | } |
668 | else { |
669 | iX=aMFS.FindIndex(aFx); |
670 | const TopoDS_Shape& aFx1=aMFS.FindKey(iX); |
671 | aOr1=aFx1.Orientation(); |
672 | if (aOr1!=aOr) { |
673 | BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx); |
674 | aLSx.Append(aSx); |
675 | aMFS.Add(aFx, aLSx); |
676 | } |
677 | } |
678 | } |
679 | } |
680 | // |
681 | BOPCol_ListOfShape aLF, aLFx; //faces that will be added in the end; |
682 | // SFS |
683 | aNbF=aMFS.Extent(); |
684 | for (i=1; i<=aNbF; ++i) { |
685 | const TopoDS_Shape& aFx=aMFS.FindKey(i); |
686 | const BOPCol_ListOfShape& aLSx=aMFS(i); |
687 | aNbSx=aLSx.Extent(); |
688 | if (aNbSx==1) { |
689 | BOPTools::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF); |
690 | if (IsBoundSplits(aFx, aMEF)){ |
691 | aLFx.Append(aFx); |
692 | continue; |
693 | } |
694 | aLF.Append(aFx); |
695 | } |
696 | } |
697 | |
698 | aItLS.Initialize(aLF); |
699 | for(; aItLS.More(); aItLS.Next()) { |
700 | const TopoDS_Shape& aFx=aItLS.Value(); |
701 | aSFS.Append(aFx); |
702 | } |
703 | // add faces from aLFx to aSFS; |
704 | aItLS.Initialize(aLFx); |
705 | for (; aItLS.More(); aItLS.Next()) { |
706 | const TopoDS_Shape& aFx=aItLS.Value(); |
707 | aSFS.Append(aFx); |
708 | } |
709 | // |
710 | aNbF=aMFI.Extent(); |
711 | for (i=1; i<=aNbF; ++i) { |
712 | TopoDS_Shape aFx; |
713 | // |
714 | aFx=aMFI.FindKey(i); |
715 | aFx.Orientation(TopAbs_FORWARD); |
716 | aSFS.Append(aFx); |
717 | aFx.Orientation(TopAbs_REVERSED); |
718 | aSFS.Append(aFx); |
719 | } |
720 | // |
721 | // BuilderSolid |
722 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
723 | // |
724 | aSB.SetContext(myContext); |
725 | aSB.SetShapes(aSFS); |
726 | aSB.Perform(); |
727 | iErr=aSB.ErrorStatus(); |
728 | if (iErr) { |
729 | myErrorStatus=30; // SolidBuilder failed |
730 | return; |
731 | } |
732 | // |
733 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
734 | // |
735 | aItLS.Initialize(aLSR); |
736 | for (; aItLS.More(); aItLS.Next()) { |
737 | const TopoDS_Shape& aSR=aItLS.Value(); |
738 | aBB.Add(aRC, aSR); |
739 | } |
740 | myShape=aRC; |
741 | } |
742 | |
743 | //======================================================================= |
744 | //function : IsBoundImages |
745 | //purpose : |
746 | //======================================================================= |
747 | Standard_Boolean BOPAlgo_BOP::IsBoundSplits(const TopoDS_Shape& aS, |
748 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF) |
749 | { |
750 | Standard_Boolean bRet = Standard_False; |
751 | if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) { |
752 | return !bRet; |
753 | } |
754 | |
755 | BOPCol_ListIteratorOfListOfShape aIt; |
756 | Standard_Integer aNbLS; |
757 | TopAbs_Orientation anOr; |
758 | // |
759 | //check face aF may be connected to face from mySplits |
760 | TopExp_Explorer aExp(aS, TopAbs_EDGE); |
761 | for (; aExp.More(); aExp.Next()) { |
762 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
763 | // |
764 | anOr = aE.Orientation(); |
765 | if (anOr==TopAbs_INTERNAL) { |
766 | continue; |
767 | } |
768 | // |
769 | if (BRep_Tool::Degenerated(aE)) { |
770 | continue; |
771 | } |
772 | // |
773 | const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE); |
774 | aNbLS = aLS.Extent(); |
775 | if (!aNbLS) { |
776 | continue; |
777 | } |
778 | // |
779 | aIt.Initialize(aLS); |
780 | for (; aIt.More(); aIt.Next()) { |
781 | const TopoDS_Shape& aSx = aIt.Value(); |
782 | if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) { |
783 | return !bRet; |
784 | } |
785 | } |
786 | } |
787 | |
788 | return bRet; |
789 | } |