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