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 | |
4e57c75e |
15 | |
42cf5bc1 |
16 | #include <BOPAlgo_BOP.hxx> |
17 | #include <BOPAlgo_BuilderSolid.hxx> |
18 | #include <BOPAlgo_PaveFiller.hxx> |
19 | #include <BOPCol_DataMapOfShapeShape.hxx> |
20 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
21 | #include <BOPCol_IndexedMapOfShape.hxx> |
8620e18d |
22 | #include <BOPCol_ListOfShape.hxx> |
23 | #include <BOPCol_MapOfShape.hxx> |
8620e18d |
24 | #include <BOPDS_DS.hxx> |
4e57c75e |
25 | #include <BOPTools.hxx> |
26 | #include <BOPTools_AlgoTools.hxx> |
27 | #include <BOPTools_AlgoTools3D.hxx> |
955b3e71 |
28 | #include <BOPTools_Set.hxx> |
29 | #include <BOPTools_SetMapHasher.hxx> |
42cf5bc1 |
30 | #include <BRep_Builder.hxx> |
31 | #include <BRep_Tool.hxx> |
955b3e71 |
32 | #include <NCollection_DataMap.hxx> |
42cf5bc1 |
33 | #include <NCollection_IncAllocator.hxx> |
34 | #include <TopAbs_ShapeEnum.hxx> |
35 | #include <TopExp_Explorer.hxx> |
36 | #include <TopoDS_Compound.hxx> |
37 | #include <TopoDS_Edge.hxx> |
38 | #include <TopoDS_Iterator.hxx> |
39 | #include <TopoDS_Shape.hxx> |
49b0c452 |
40 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
955b3e71 |
41 | |
42cf5bc1 |
42 | // |
955b3e71 |
43 | typedef NCollection_DataMap |
44 | <BOPTools_Set, |
45 | TopoDS_Shape, |
46 | BOPTools_SetMapHasher> BOPTools_DataMapOfSetShape; |
47 | // |
48 | typedef BOPTools_DataMapOfSetShape::Iterator |
49 | BOPTools_DataMapIteratorOfDataMapOfSetShape; |
4e57c75e |
50 | |
51 | static |
52 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim); |
53 | |
8620e18d |
54 | |
4e57c75e |
55 | //======================================================================= |
56 | //function : |
57 | //purpose : |
58 | //======================================================================= |
8620e18d |
59 | BOPAlgo_BOP::BOPAlgo_BOP() |
4e57c75e |
60 | : |
61 | BOPAlgo_Builder(), |
62 | myTools(myAllocator), |
63 | myMapTools(100, myAllocator) |
64 | { |
4e57c75e |
65 | Clear(); |
66 | } |
67 | //======================================================================= |
68 | //function : |
69 | //purpose : |
70 | //======================================================================= |
8620e18d |
71 | BOPAlgo_BOP::BOPAlgo_BOP |
72 | (const Handle(NCollection_BaseAllocator)& theAllocator) |
4e57c75e |
73 | : |
74 | BOPAlgo_Builder(theAllocator), |
75 | myTools(myAllocator), |
76 | myMapTools(100, myAllocator) |
77 | { |
4e57c75e |
78 | Clear(); |
79 | } |
80 | //======================================================================= |
81 | //function : ~ |
82 | //purpose : |
83 | //======================================================================= |
8620e18d |
84 | BOPAlgo_BOP::~BOPAlgo_BOP() |
4e57c75e |
85 | { |
86 | } |
87 | //======================================================================= |
88 | //function : Clear |
89 | //purpose : |
90 | //======================================================================= |
8620e18d |
91 | void BOPAlgo_BOP::Clear() |
4e57c75e |
92 | { |
93 | myOperation=BOPAlgo_UNKNOWN; |
94 | myTools.Clear(); |
95 | myMapTools.Clear(); |
96 | myDims[0]=-1; |
97 | myDims[1]=-1; |
98 | // |
99 | BOPAlgo_Builder::Clear(); |
100 | } |
101 | //======================================================================= |
8620e18d |
102 | //function : SetOperation |
4e57c75e |
103 | //purpose : |
104 | //======================================================================= |
8620e18d |
105 | void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation) |
4e57c75e |
106 | { |
8620e18d |
107 | myOperation=theOperation; |
4e57c75e |
108 | } |
109 | //======================================================================= |
8620e18d |
110 | //function : Operation |
4e57c75e |
111 | //purpose : |
112 | //======================================================================= |
8620e18d |
113 | BOPAlgo_Operation BOPAlgo_BOP::Operation()const |
4e57c75e |
114 | { |
8620e18d |
115 | return myOperation; |
4e57c75e |
116 | } |
117 | //======================================================================= |
8620e18d |
118 | //function : AddTool |
4e57c75e |
119 | //purpose : |
120 | //======================================================================= |
8620e18d |
121 | void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape) |
4e57c75e |
122 | { |
8620e18d |
123 | if (myMapTools.Add(theShape)) { |
124 | myTools.Append(theShape); |
125 | } |
4e57c75e |
126 | } |
127 | //======================================================================= |
49b0c452 |
128 | //function : SetTools |
129 | //purpose : |
130 | //======================================================================= |
131 | void BOPAlgo_BOP::SetTools(const BOPCol_ListOfShape& theShapes) |
132 | { |
133 | BOPCol_ListIteratorOfListOfShape aIt; |
134 | // |
135 | myTools.Clear(); |
136 | aIt.Initialize(theShapes); |
137 | for (; aIt.More(); aIt.Next()) { |
138 | const TopoDS_Shape& aS = aIt.Value(); |
139 | AddTool(aS); |
140 | } |
141 | } |
142 | //======================================================================= |
4e57c75e |
143 | //function : CheckData |
144 | //purpose : |
145 | //======================================================================= |
8620e18d |
146 | void BOPAlgo_BOP::CheckData() |
4e57c75e |
147 | { |
8620e18d |
148 | Standard_Integer i, j, iDim, aNbArgs, aNbTools; |
4e57c75e |
149 | Standard_Boolean bFlag; |
8620e18d |
150 | BOPCol_ListIteratorOfListOfShape aItLS; |
4e57c75e |
151 | // |
152 | myErrorStatus=0; |
153 | // |
85915310 |
154 | if (!(myOperation==BOPAlgo_COMMON || |
155 | myOperation==BOPAlgo_FUSE || |
156 | myOperation==BOPAlgo_CUT|| |
157 | myOperation==BOPAlgo_CUT21)) { |
158 | // non-licit operation |
159 | myErrorStatus=14; |
160 | return; |
161 | } |
162 | // |
8620e18d |
163 | aNbArgs=myArguments.Extent(); |
164 | if (!aNbArgs) { |
85915310 |
165 | // invalid number of Arguments |
166 | myErrorStatus=100; |
8620e18d |
167 | return; |
168 | } |
169 | // |
170 | aNbTools=myTools.Extent(); |
85915310 |
171 | if (!aNbTools) { |
172 | // invalid number of Tools |
173 | myErrorStatus=100; |
8620e18d |
174 | return; |
7cfb3968 |
175 | } |
176 | // |
177 | if (!myPaveFiller) { |
178 | myErrorStatus=101; |
4e57c75e |
179 | return; |
180 | } |
181 | // |
7cfb3968 |
182 | myErrorStatus=myPaveFiller->ErrorStatus(); |
4e57c75e |
183 | if (myErrorStatus) { |
184 | return; |
185 | } |
186 | // |
85915310 |
187 | // myDims |
188 | myDims[0]=-1; |
189 | myDims[1]=-1; |
8620e18d |
190 | for (i=0; i<2; ++i) { |
191 | const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; |
192 | aItLS.Initialize(aLS); |
193 | for (j=0; aItLS.More(); aItLS.Next(), ++j) { |
194 | const TopoDS_Shape& aS=aItLS.Value(); |
195 | bFlag=BOPTools_AlgoTools3D::IsEmptyShape(aS); |
196 | if(bFlag) { |
197 | myWarningStatus=2; |
198 | } |
199 | // |
200 | iDim=BOPTools_AlgoTools::Dimension(aS); |
201 | if (iDim<0) { |
85915310 |
202 | // non-homogenious argument |
203 | myErrorStatus=13; |
8620e18d |
204 | return; |
205 | } |
206 | // |
207 | if (!j) { |
208 | myDims[i]=iDim; |
209 | continue; |
210 | } |
211 | // |
85915310 |
212 | if (iDim!=myDims[i]) { |
213 | // non-homogenious argument |
214 | myErrorStatus=13; |
8620e18d |
215 | return; |
216 | } |
4e57c75e |
217 | } |
218 | } |
219 | // |
85915310 |
220 | if (myDims[0]<myDims[1]) { |
4e57c75e |
221 | if (myOperation==BOPAlgo_FUSE || |
85915310 |
222 | myOperation==BOPAlgo_CUT21) { |
223 | // non-licit operation for the arguments |
224 | myErrorStatus=14; |
4e57c75e |
225 | return; |
226 | } |
227 | } |
228 | else if (myDims[0]>myDims[1]) { |
229 | if (myOperation==BOPAlgo_FUSE || |
230 | myOperation==BOPAlgo_CUT) { |
85915310 |
231 | // non-licit operation for the arguments |
232 | myErrorStatus=14; |
4e57c75e |
233 | return; |
234 | } |
235 | } |
236 | } |
237 | //======================================================================= |
238 | //function : Prepare |
239 | //purpose : |
240 | //======================================================================= |
8620e18d |
241 | void BOPAlgo_BOP::Prepare() |
4e57c75e |
242 | { |
4e57c75e |
243 | // |
244 | BOPAlgo_Builder::Prepare(); |
245 | // |
246 | if(myWarningStatus == 2) { |
8620e18d |
247 | Standard_Integer i; |
248 | BRep_Builder aBB; |
249 | BOPCol_ListIteratorOfListOfShape aItLS; |
250 | // |
4e57c75e |
251 | switch(myOperation) { |
8620e18d |
252 | case BOPAlgo_FUSE: { |
253 | for (i=0; i<2; ++i) { |
254 | const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; |
255 | aItLS.Initialize(aLS); |
256 | for (; aItLS.More(); aItLS.Next()) { |
257 | const TopoDS_Shape& aS=aItLS.Value(); |
258 | aBB.Add(myShape, aS); |
259 | } |
4e57c75e |
260 | } |
8620e18d |
261 | } |
4e57c75e |
262 | break; |
8620e18d |
263 | // |
264 | case BOPAlgo_CUT: { |
265 | aItLS.Initialize(myArguments); |
266 | for (; aItLS.More(); aItLS.Next()) { |
267 | const TopoDS_Shape& aS=aItLS.Value(); |
268 | if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { |
269 | aBB.Add(myShape, aS); |
270 | } |
4e57c75e |
271 | } |
8620e18d |
272 | } |
4e57c75e |
273 | break; |
8620e18d |
274 | |
275 | case BOPAlgo_CUT21: { |
276 | aItLS.Initialize(myTools); |
277 | for (; aItLS.More(); aItLS.Next()) { |
278 | const TopoDS_Shape& aS=aItLS.Value(); |
279 | if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { |
280 | aBB.Add(myShape, aS); |
281 | } |
4e57c75e |
282 | } |
8620e18d |
283 | } |
4e57c75e |
284 | break; |
8620e18d |
285 | // |
4e57c75e |
286 | default: |
287 | break; |
8620e18d |
288 | } |
289 | } |
290 | } |
291 | //======================================================================= |
292 | //function : BuildResult |
293 | //purpose : |
294 | //======================================================================= |
295 | void BOPAlgo_BOP::BuildResult(const TopAbs_ShapeEnum theType) |
296 | { |
297 | TopAbs_ShapeEnum aType; |
298 | BRep_Builder aBB; |
299 | BOPCol_MapOfShape aM; |
300 | BOPCol_ListIteratorOfListOfShape aIt, aItIm; |
301 | // |
302 | myErrorStatus=0; |
303 | // |
304 | const BOPCol_ListOfShape& aLA=myDS->Arguments(); |
305 | aIt.Initialize(aLA); |
306 | for (; aIt.More(); aIt.Next()) { |
307 | const TopoDS_Shape& aS=aIt.Value(); |
308 | aType=aS.ShapeType(); |
309 | if (aType==theType) { |
310 | if (myImages.IsBound(aS)){ |
311 | const BOPCol_ListOfShape& aLSIm=myImages.Find(aS); |
312 | aItIm.Initialize(aLSIm); |
313 | for (; aItIm.More(); aItIm.Next()) { |
314 | const TopoDS_Shape& aSIm=aItIm.Value(); |
315 | if (aM.Add(aSIm)) { |
316 | aBB.Add(myShape, aSIm); |
317 | } |
318 | } |
319 | } |
320 | else { |
321 | if (aM.Add(aS)) { |
322 | aBB.Add(myShape, aS); |
323 | } |
324 | } |
4e57c75e |
325 | } |
326 | } |
327 | } |
328 | //======================================================================= |
8620e18d |
329 | //function : Perform |
330 | //purpose : |
331 | //======================================================================= |
332 | void BOPAlgo_BOP::Perform() |
333 | { |
334 | Handle(NCollection_BaseAllocator) aAllocator; |
335 | BOPAlgo_PaveFiller* pPF; |
336 | BOPCol_ListIteratorOfListOfShape aItLS; |
337 | // |
338 | myErrorStatus=0; |
339 | // |
340 | if (myEntryPoint==1) { |
341 | if (myPaveFiller) { |
342 | delete myPaveFiller; |
343 | myPaveFiller=NULL; |
344 | } |
345 | } |
346 | // |
347 | aAllocator=new NCollection_IncAllocator; |
348 | BOPCol_ListOfShape aLS(aAllocator); |
349 | // |
350 | aItLS.Initialize(myArguments); |
351 | for (; aItLS.More(); aItLS.Next()) { |
352 | const TopoDS_Shape& aS=aItLS.Value(); |
353 | aLS.Append(aS); |
354 | } |
355 | // |
356 | aItLS.Initialize(myTools); |
357 | for (; aItLS.More(); aItLS.Next()) { |
358 | const TopoDS_Shape& aS=aItLS.Value(); |
359 | aLS.Append(aS); |
360 | } |
361 | // |
362 | pPF=new BOPAlgo_PaveFiller(aAllocator); |
363 | pPF->SetArguments(aLS); |
b1d15f53 |
364 | pPF->SetRunParallel(myRunParallel); |
365 | pPF->SetProgressIndicator(myProgressIndicator); |
366 | pPF->SetFuzzyValue(myFuzzyValue); |
8620e18d |
367 | // |
368 | pPF->Perform(); |
369 | // |
370 | myEntryPoint=1; |
371 | PerformInternal(*pPF); |
372 | } |
373 | //======================================================================= |
36f4947b |
374 | //function : PerformInternal1 |
4e57c75e |
375 | //purpose : |
376 | //======================================================================= |
36f4947b |
377 | void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller) |
4e57c75e |
378 | { |
379 | myErrorStatus=0; |
380 | myWarningStatus=0; |
381 | // |
382 | myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller; |
383 | myDS=myPaveFiller->PDS(); |
384 | myContext=myPaveFiller->Context(); |
385 | // |
386 | // 1. CheckData |
387 | CheckData(); |
388 | if (myErrorStatus && !myWarningStatus) { |
389 | return; |
390 | } |
391 | // |
392 | // 2. Prepare |
393 | Prepare(); |
394 | if (myErrorStatus) { |
395 | return; |
396 | } |
8620e18d |
397 | // |
4e57c75e |
398 | if(myWarningStatus == 2) { |
399 | return; |
400 | } |
4e57c75e |
401 | // 3. Fill Images |
402 | // 3.1 Vertices |
403 | FillImagesVertices(); |
404 | if (myErrorStatus) { |
405 | return; |
406 | } |
407 | // |
408 | BuildResult(TopAbs_VERTEX); |
409 | if (myErrorStatus) { |
410 | return; |
411 | } |
412 | // 3.2 Edges |
413 | FillImagesEdges(); |
414 | if (myErrorStatus) { |
415 | return; |
416 | } |
85915310 |
417 | // |
4e57c75e |
418 | BuildResult(TopAbs_EDGE); |
419 | if (myErrorStatus) { |
420 | return; |
421 | } |
4e57c75e |
422 | // |
423 | // 3.3 Wires |
424 | FillImagesContainers(TopAbs_WIRE); |
425 | if (myErrorStatus) { |
426 | return; |
427 | } |
85915310 |
428 | // |
4e57c75e |
429 | BuildResult(TopAbs_WIRE); |
430 | if (myErrorStatus) { |
431 | return; |
432 | } |
85915310 |
433 | // |
4e57c75e |
434 | // 3.4 Faces |
435 | FillImagesFaces(); |
436 | if (myErrorStatus) { |
437 | return; |
438 | } |
439 | |
440 | BuildResult(TopAbs_FACE); |
441 | if (myErrorStatus) { |
442 | return; |
443 | } |
85915310 |
444 | // |
4e57c75e |
445 | // 3.5 Shells |
4e57c75e |
446 | FillImagesContainers(TopAbs_SHELL); |
447 | if (myErrorStatus) { |
448 | return; |
449 | } |
85915310 |
450 | // |
4e57c75e |
451 | BuildResult(TopAbs_SHELL); |
452 | if (myErrorStatus) { |
453 | return; |
454 | } |
85915310 |
455 | // |
4e57c75e |
456 | // 3.6 Solids |
457 | FillImagesSolids(); |
458 | if (myErrorStatus) { |
459 | return; |
460 | } |
85915310 |
461 | // |
4e57c75e |
462 | BuildResult(TopAbs_SOLID); |
463 | if (myErrorStatus) { |
464 | return; |
465 | } |
85915310 |
466 | // |
4e57c75e |
467 | // 3.7 CompSolids |
468 | FillImagesContainers(TopAbs_COMPSOLID); |
469 | if (myErrorStatus) { |
470 | return; |
471 | } |
85915310 |
472 | // |
4e57c75e |
473 | BuildResult(TopAbs_COMPSOLID); |
474 | if (myErrorStatus) { |
475 | return; |
476 | } |
85915310 |
477 | // |
4e57c75e |
478 | // 3.8 Compounds |
479 | FillImagesCompounds(); |
480 | if (myErrorStatus) { |
481 | return; |
482 | } |
85915310 |
483 | // |
4e57c75e |
484 | BuildResult(TopAbs_COMPOUND); |
485 | if (myErrorStatus) { |
486 | return; |
487 | } |
488 | // |
8620e18d |
489 | // 4.BuildShape; |
4e57c75e |
490 | BuildShape(); |
8620e18d |
491 | if (myErrorStatus) { |
492 | return; |
493 | } |
4e57c75e |
494 | // |
8620e18d |
495 | // 5.History |
4e57c75e |
496 | PrepareHistory(); |
4e57c75e |
497 | // |
8620e18d |
498 | // 6 Post-treatment |
4e57c75e |
499 | PostTreat(); |
500 | } |
501 | //======================================================================= |
8620e18d |
502 | //function : BuildRC |
503 | //purpose : |
504 | //======================================================================= |
505 | void BOPAlgo_BOP::BuildRC() |
506 | { |
507 | Standard_Boolean bFlag1, bFlag2, bIsBound; |
508 | Standard_Integer aDmin; |
509 | TopAbs_ShapeEnum aTmin; |
510 | TopoDS_Compound aC; |
511 | TopoDS_Shape aSAIm, aSTIm; |
512 | BRep_Builder aBB; |
513 | TopExp_Explorer aExp; |
514 | BOPCol_DataMapOfShapeShape aDMSSA; |
955b3e71 |
515 | BOPCol_ListIteratorOfListOfShape aItLS, aItIm; |
516 | Standard_Boolean bHasInterf; |
517 | Standard_Integer iX; |
518 | BOPTools_DataMapOfSetShape aDMSTS; |
8620e18d |
519 | // |
520 | myErrorStatus=0; |
521 | // |
522 | aBB.MakeCompound(aC); |
523 | // |
524 | // A. Fuse |
525 | if (myOperation==BOPAlgo_FUSE) { |
526 | aTmin=TypeToExplore(myDims[0]); |
527 | aExp.Init(myShape, aTmin); |
528 | for (; aExp.More(); aExp.Next()) { |
529 | const TopoDS_Shape& aS=aExp.Current(); |
530 | aBB.Add(aC, aS); |
531 | } |
532 | myRC=aC; |
533 | return; |
534 | } |
535 | // |
536 | aDmin=myDims[1]; |
537 | if (myDims[0] < myDims[1]) { |
538 | aDmin=myDims[0]; |
539 | } |
540 | aTmin=TypeToExplore(aDmin); |
541 | // |
542 | // B. Common, Cut, Cut21 |
543 | // |
544 | bFlag1=(myOperation==BOPAlgo_COMMON || myOperation==BOPAlgo_CUT21); |
545 | bFlag2=(myOperation==BOPAlgo_CUT || myOperation==BOPAlgo_CUT21); |
546 | // |
547 | const BOPCol_ListOfShape& aLA=( bFlag1) ? myArguments : myTools; |
548 | aItLS.Initialize(aLA); |
549 | for (; aItLS.More(); aItLS.Next()) { |
550 | const TopoDS_Shape& aSA=aItLS.Value(); |
551 | // |
552 | if (myImages.IsBound(aSA)){ |
553 | const BOPCol_ListOfShape& aLSAIm=myImages.Find(aSA); |
554 | aItIm.Initialize(aLSAIm); |
555 | for (; aItIm.More(); aItIm.Next()) { |
556 | const TopoDS_Shape& aSAIm=aItIm.Value(); |
557 | aExp.Init(aSAIm, aTmin); |
558 | for (; aExp.More(); aExp.Next()) { |
559 | const TopoDS_Shape aSIm=aExp.Current(); |
560 | aDMSSA.Bind(aSIm, aSIm); |
561 | } |
562 | } |
563 | } |
564 | // |
565 | else { |
566 | aExp.Init(aSA, aTmin); |
567 | for (; aExp.More(); aExp.Next()) { |
568 | const TopoDS_Shape aSIm=aExp.Current(); |
569 | aDMSSA.Bind(aSIm, aSIm); |
955b3e71 |
570 | if (aTmin==TopAbs_SOLID) { |
571 | iX=myDS->Index(aSIm); |
572 | bHasInterf=myDS->HasInterf(iX); |
573 | if (!bHasInterf) { |
574 | BOPTools_Set aST; |
575 | // |
576 | aST.Add(aSIm, TopAbs_FACE); |
577 | // |
578 | aDMSTS.Bind(aST, aSIm); |
579 | } |
580 | } |
8620e18d |
581 | } |
582 | } |
583 | } //for (; aItLS.More(); aItLS.Next()) |
584 | // |
585 | const BOPCol_ListOfShape& aLT=(!bFlag1) ? myArguments : myTools; |
586 | aItLS.Initialize(aLT); |
587 | for (; aItLS.More(); aItLS.Next()) { |
588 | const TopoDS_Shape& aST=aItLS.Value(); |
589 | if (myImages.IsBound(aST)){ |
590 | const BOPCol_ListOfShape& aLSTIm=myImages.Find(aST); |
591 | aItIm.Initialize(aLSTIm); |
592 | for (; aItIm.More(); aItIm.Next()) { |
593 | const TopoDS_Shape& aSTIm=aItIm.Value(); |
594 | aExp.Init(aSTIm, aTmin); |
595 | for (; aExp.More(); aExp.Next()) { |
596 | const TopoDS_Shape aSIm=aExp.Current(); |
597 | // skip degenerated edges |
598 | if (aTmin==TopAbs_EDGE) { |
599 | const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); |
600 | if (BRep_Tool::Degenerated(aEIm)) { |
601 | continue; |
602 | } |
603 | } |
604 | // |
605 | bIsBound=aDMSSA.IsBound(aSIm); |
606 | if (!bFlag2) { // ie common |
607 | if (bIsBound) { |
608 | const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); |
609 | aBB.Add(aC, aSImA); |
610 | } |
611 | } |
612 | else {// ie cut or cut21 |
613 | if (!bIsBound) { |
614 | aBB.Add(aC, aSIm); |
615 | } |
616 | } |
617 | } |
618 | } |
955b3e71 |
619 | }// if (myImages.IsBound(aST)){ |
8620e18d |
620 | else { |
621 | aExp.Init(aST, aTmin); |
622 | for (; aExp.More(); aExp.Next()) { |
623 | const TopoDS_Shape aSIm=aExp.Current(); |
624 | // skip degenerated edges |
625 | if (aTmin==TopAbs_EDGE) { |
626 | const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); |
627 | if (BRep_Tool::Degenerated(aEIm)) { |
628 | continue; |
629 | } |
630 | } |
631 | bIsBound=aDMSSA.IsBound(aSIm); |
632 | if (!bFlag2) { // ie common |
633 | if (bIsBound) { |
634 | const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); |
635 | aBB.Add(aC, aSImA); |
636 | } |
955b3e71 |
637 | else { |
638 | if (aTmin==TopAbs_SOLID) { |
639 | BOPTools_Set aST; |
640 | // |
641 | aST.Add(aSIm, TopAbs_FACE); |
642 | // |
643 | if (aDMSTS.IsBound(aST)) { |
644 | const TopoDS_Shape& aSImA=aDMSTS.Find(aST); |
645 | aBB.Add(aC, aSImA); |
646 | } |
647 | } |
648 | } |
8620e18d |
649 | } |
650 | else {// ie cut or cut21 |
651 | if (!bIsBound) { |
955b3e71 |
652 | if (aTmin==TopAbs_SOLID) { |
653 | BOPTools_Set aST; |
654 | // |
655 | aST.Add(aSIm, TopAbs_FACE); |
656 | // |
657 | bIsBound=aDMSTS.IsBound(aST); |
658 | } |
659 | // |
660 | if (!bIsBound) { |
661 | aBB.Add(aC, aSIm); |
662 | } |
8620e18d |
663 | } |
664 | } |
665 | } |
666 | } |
667 | } //for (; aItLS.More(); aItLS.Next()) |
668 | // |
669 | // the squats around degeneracy |
670 | if (aTmin!=TopAbs_EDGE) { |
671 | myRC=aC; |
672 | return; |
673 | } |
674 | //--------------------------------------------------------- |
675 | // |
676 | // The squats around degenerated edges |
677 | Standard_Integer i, aNbS, nVD; |
678 | TopAbs_ShapeEnum aType; |
679 | BOPCol_IndexedMapOfShape aMVC; |
680 | // |
681 | // 1. Vertices of aC |
682 | BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC); |
683 | // |
684 | // 2. DE candidates |
685 | aNbS=myDS->NbSourceShapes(); |
686 | for (i=0; i<aNbS; ++i) { |
687 | const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i); |
688 | aType=aSI.ShapeType(); |
689 | if (aType!=aTmin) { |
690 | continue; |
691 | } |
692 | // |
693 | const TopoDS_Edge& aE=*((TopoDS_Edge*)&aSI.Shape()); |
694 | if (!BRep_Tool::Degenerated(aE)) { |
695 | continue; |
696 | } |
697 | // |
698 | nVD=aSI.SubShapes().First(); |
699 | const TopoDS_Shape& aVD=myDS->Shape(nVD); |
700 | // |
701 | if (!aMVC.Contains(aVD)) { |
702 | continue; |
703 | } |
704 | // |
705 | if (myDS->IsNewShape(nVD)) { |
706 | continue; |
707 | } |
708 | // |
709 | if (myDS->HasInterf(nVD)) { |
710 | continue; |
711 | } |
712 | // |
713 | aBB.Add(aC, aE); |
714 | } |
715 | // |
716 | myRC=aC; |
717 | } |
718 | //======================================================================= |
4e57c75e |
719 | //function : BuildShape |
720 | //purpose : |
721 | //======================================================================= |
8620e18d |
722 | void BOPAlgo_BOP::BuildShape() |
4e57c75e |
723 | { |
724 | Standard_Integer aDmin, aNbLCB; |
725 | TopAbs_ShapeEnum aT1, aT2, aTR; |
726 | TopoDS_Shape aR, aRC; |
727 | TopoDS_Iterator aIt; |
728 | BRep_Builder aBB; |
729 | BOPCol_ListOfShape aLCB; |
730 | BOPCol_ListIteratorOfListOfShape aItLCB; |
731 | // |
732 | myErrorStatus=0; |
733 | // |
734 | BuildRC(); |
4e57c75e |
735 | // |
736 | aDmin=myDims[1]; |
737 | if (myDims[0]<myDims[1]) { |
738 | aDmin=myDims[0]; |
739 | } |
740 | // |
741 | if (!aDmin) { |
742 | myShape=myRC; |
743 | return; |
744 | } |
745 | // |
746 | else if (aDmin==1 || aDmin==2) { //edges, faces |
747 | aT1=TopAbs_VERTEX; |
748 | aT2=TopAbs_EDGE; |
749 | aTR=TopAbs_WIRE; |
750 | if (aDmin==2) { |
751 | aT1=TopAbs_EDGE; |
752 | aT2=TopAbs_FACE; |
753 | aTR=TopAbs_SHELL; |
754 | } |
755 | // |
8620e18d |
756 | BOPTools_AlgoTools::MakeConnexityBlocks |
757 | (myRC, aT1, aT2, aLCB); |
4e57c75e |
758 | aNbLCB=aLCB.Extent(); |
759 | if (!aNbLCB) { |
760 | myShape=myRC; |
761 | return; |
762 | } |
763 | // |
764 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
765 | // |
766 | aItLCB.Initialize(aLCB); |
767 | for (; aItLCB.More(); aItLCB.Next()) { |
768 | BOPTools_AlgoTools::MakeContainer(aTR, aR); |
769 | // |
770 | const TopoDS_Shape& aCB=aItLCB.Value(); |
771 | aIt.Initialize(aCB); |
772 | for (; aIt.More(); aIt.Next()) { |
773 | const TopoDS_Shape& aS=aIt.Value(); |
774 | aBB.Add(aR, aS); |
775 | } |
776 | // |
777 | if (aTR==TopAbs_SHELL) { |
778 | BOPTools_AlgoTools::OrientFacesOnShell(aR); |
779 | } |
780 | // |
781 | aBB.Add(aRC, aR); |
782 | } |
783 | myShape=aRC; |
784 | }// elase if (aDmin==1 || aDmin==2) { |
785 | |
8620e18d |
786 | else {//aDmin=3 |
787 | Standard_Integer aNbObjs, aNbTools; |
788 | // |
789 | aNbObjs=myArguments.Extent(); |
790 | aNbTools=myTools.Extent(); |
791 | // |
792 | if (aNbObjs==1 && aNbTools==1) { |
793 | if (myOperation==BOPAlgo_FUSE) { |
794 | BuildSolid(); |
4e57c75e |
795 | } |
796 | else { |
8620e18d |
797 | myShape=myRC; |
4e57c75e |
798 | } |
799 | } |
8620e18d |
800 | else { |
801 | BuildSolid(); |
4e57c75e |
802 | } |
803 | } |
4e57c75e |
804 | } |
805 | //======================================================================= |
806 | //function : BuildSolid |
807 | //purpose : |
808 | //======================================================================= |
8620e18d |
809 | void BOPAlgo_BOP::BuildSolid() |
4e57c75e |
810 | { |
955b3e71 |
811 | Standard_Boolean bHasInterf, bHasSharedFaces; |
812 | Standard_Integer i, aNbF, aNbSx, iX, iErr, aNbZ; |
4e57c75e |
813 | TopAbs_Orientation aOr, aOr1; |
814 | TopoDS_Iterator aIt; |
815 | TopoDS_Shape aRC; |
816 | BRep_Builder aBB; |
817 | TopExp_Explorer aExp; |
818 | BOPCol_IndexedMapOfShape aMFI; |
819 | BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF; |
820 | BOPCol_ListIteratorOfListOfShape aItLS; |
821 | BOPCol_ListOfShape aSFS; |
955b3e71 |
822 | BOPAlgo_BuilderSolid aSB; |
823 | BOPCol_MapOfShape aMSA, aMZ; |
824 | BOPTools_DataMapOfSetShape aDMSTS; |
825 | BOPTools_DataMapIteratorOfDataMapOfSetShape aItDMSTS; |
4e57c75e |
826 | // |
827 | myErrorStatus=0; |
828 | // |
955b3e71 |
829 | // Map of of Solids of Arguments |
830 | for (i=0; i<2; ++i) { |
831 | const BOPCol_ListOfShape& aLSA=(i) ? myArguments : myTools; |
832 | aItLS.Initialize(aLSA); |
833 | for (; aItLS.More(); aItLS.Next()) { |
834 | const TopoDS_Shape& aSA=aItLS.Value(); |
835 | aExp.Init(aSA, TopAbs_SOLID); |
836 | for (; aExp.More(); aExp.Next()) { |
837 | const TopoDS_Shape& aZA=aExp.Current(); |
838 | aMSA.Add(aZA); |
839 | // |
840 | BOPTools::MapShapesAndAncestors(aZA, |
841 | TopAbs_FACE, |
842 | TopAbs_SOLID, |
843 | aMFS); |
844 | } |
845 | } |
846 | } |
847 | // |
848 | aNbF=aMFS.Extent(); |
849 | for (i=1; i<aNbF; ++i) { |
850 | //const TopoDS_Shape& aFA=aMFZA.FindKey(i); |
851 | const BOPCol_ListOfShape& aLZA=aMFS(i); |
852 | aNbZ=aLZA.Extent(); |
853 | if (aNbZ > 1) { |
854 | aItLS.Initialize(aLZA); |
855 | for(; aItLS.More(); aItLS.Next()) { |
856 | const TopoDS_Shape& aZA=aItLS.Value(); |
857 | aMZ.Add(aZA); |
858 | } |
859 | } |
860 | } |
861 | // |
862 | aMFS.Clear(); |
863 | // |
4e57c75e |
864 | aIt.Initialize(myRC); |
865 | for (; aIt.More(); aIt.Next()) { |
866 | const TopoDS_Shape& aSx=aIt.Value(); |
955b3e71 |
867 | if (aMSA.Contains(aSx)) { |
868 | iX=myDS->Index(aSx); |
869 | bHasInterf=myDS->HasInterf(iX); |
870 | bHasSharedFaces=aMZ.Contains(aSx); |
871 | // |
872 | if (!bHasInterf && !bHasSharedFaces) { |
873 | // It means that the solid aSx will be added |
874 | // to the result as is. |
875 | // The solid aSx will not participate |
876 | // in creation of a new solid(s). |
877 | BOPTools_Set aST; |
878 | // |
879 | aST.Add(aSx, TopAbs_FACE); |
880 | // |
881 | if (!aDMSTS.IsBound(aST)) { |
882 | aDMSTS.Bind(aST, aSx); |
883 | } |
884 | |
885 | continue; |
886 | } |
887 | } |
888 | // |
4e57c75e |
889 | aExp.Init(aSx, TopAbs_FACE); |
890 | for (; aExp.More(); aExp.Next()) { |
891 | const TopoDS_Shape& aFx=aExp.Current(); |
892 | // |
893 | aOr=aFx.Orientation(); |
894 | if (aOr==TopAbs_INTERNAL) { |
895 | aMFI.Add(aFx); |
896 | continue; |
897 | } |
898 | // |
899 | if (!aMFS.Contains(aFx)) { |
900 | BOPCol_ListOfShape aLSx; |
901 | // |
902 | aLSx.Append(aSx); |
903 | aMFS.Add(aFx, aLSx); |
904 | } |
905 | else { |
906 | iX=aMFS.FindIndex(aFx); |
907 | const TopoDS_Shape& aFx1=aMFS.FindKey(iX); |
908 | aOr1=aFx1.Orientation(); |
909 | if (aOr1!=aOr) { |
910 | BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx); |
911 | aLSx.Append(aSx); |
912 | aMFS.Add(aFx, aLSx); |
913 | } |
914 | } |
915 | } |
955b3e71 |
916 | } // for (; aIt.More(); aIt.Next()) { |
8620e18d |
917 | //faces that will be added in the end; |
918 | BOPCol_ListOfShape aLF, aLFx; |
4e57c75e |
919 | // SFS |
920 | aNbF=aMFS.Extent(); |
921 | for (i=1; i<=aNbF; ++i) { |
922 | const TopoDS_Shape& aFx=aMFS.FindKey(i); |
923 | const BOPCol_ListOfShape& aLSx=aMFS(i); |
924 | aNbSx=aLSx.Extent(); |
925 | if (aNbSx==1) { |
8620e18d |
926 | BOPTools::MapShapesAndAncestors |
927 | (aFx,TopAbs_EDGE, TopAbs_FACE, aMEF); |
4e57c75e |
928 | if (IsBoundSplits(aFx, aMEF)){ |
929 | aLFx.Append(aFx); |
930 | continue; |
931 | } |
932 | aLF.Append(aFx); |
933 | } |
934 | } |
935 | |
936 | aItLS.Initialize(aLF); |
937 | for(; aItLS.More(); aItLS.Next()) { |
938 | const TopoDS_Shape& aFx=aItLS.Value(); |
939 | aSFS.Append(aFx); |
940 | } |
941 | // add faces from aLFx to aSFS; |
942 | aItLS.Initialize(aLFx); |
943 | for (; aItLS.More(); aItLS.Next()) { |
944 | const TopoDS_Shape& aFx=aItLS.Value(); |
945 | aSFS.Append(aFx); |
946 | } |
947 | // |
948 | aNbF=aMFI.Extent(); |
949 | for (i=1; i<=aNbF; ++i) { |
950 | TopoDS_Shape aFx; |
951 | // |
952 | aFx=aMFI.FindKey(i); |
953 | aFx.Orientation(TopAbs_FORWARD); |
954 | aSFS.Append(aFx); |
955 | aFx.Orientation(TopAbs_REVERSED); |
956 | aSFS.Append(aFx); |
957 | } |
958 | // |
959 | // BuilderSolid |
960 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
961 | // |
962 | aSB.SetContext(myContext); |
963 | aSB.SetShapes(aSFS); |
964 | aSB.Perform(); |
965 | iErr=aSB.ErrorStatus(); |
966 | if (iErr) { |
967 | myErrorStatus=30; // SolidBuilder failed |
968 | return; |
969 | } |
970 | // |
971 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
972 | // |
973 | aItLS.Initialize(aLSR); |
974 | for (; aItLS.More(); aItLS.Next()) { |
975 | const TopoDS_Shape& aSR=aItLS.Value(); |
976 | aBB.Add(aRC, aSR); |
977 | } |
955b3e71 |
978 | // |
979 | aItDMSTS.Initialize(aDMSTS); |
980 | for (; aItDMSTS.More(); aItDMSTS.Next()) { |
981 | const TopoDS_Shape& aSx=aItDMSTS.Value(); |
982 | aBB.Add(aRC, aSx); |
983 | } |
984 | // |
4e57c75e |
985 | myShape=aRC; |
986 | } |
4e57c75e |
987 | //======================================================================= |
85915310 |
988 | //function : IsBoundSplits |
4e57c75e |
989 | //purpose : |
990 | //======================================================================= |
8620e18d |
991 | Standard_Boolean BOPAlgo_BOP::IsBoundSplits |
992 | (const TopoDS_Shape& aS, |
993 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF) |
4e57c75e |
994 | { |
995 | Standard_Boolean bRet = Standard_False; |
996 | if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) { |
997 | return !bRet; |
998 | } |
999 | |
1000 | BOPCol_ListIteratorOfListOfShape aIt; |
1001 | Standard_Integer aNbLS; |
1002 | TopAbs_Orientation anOr; |
1003 | // |
1004 | //check face aF may be connected to face from mySplits |
1005 | TopExp_Explorer aExp(aS, TopAbs_EDGE); |
1006 | for (; aExp.More(); aExp.Next()) { |
1007 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
1008 | // |
1009 | anOr = aE.Orientation(); |
1010 | if (anOr==TopAbs_INTERNAL) { |
1011 | continue; |
1012 | } |
1013 | // |
1014 | if (BRep_Tool::Degenerated(aE)) { |
1015 | continue; |
1016 | } |
1017 | // |
1018 | const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE); |
1019 | aNbLS = aLS.Extent(); |
1020 | if (!aNbLS) { |
1021 | continue; |
1022 | } |
1023 | // |
1024 | aIt.Initialize(aLS); |
1025 | for (; aIt.More(); aIt.Next()) { |
1026 | const TopoDS_Shape& aSx = aIt.Value(); |
8620e18d |
1027 | if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) { |
4e57c75e |
1028 | return !bRet; |
1029 | } |
1030 | } |
1031 | } |
8620e18d |
1032 | // |
4e57c75e |
1033 | return bRet; |
1034 | } |
8620e18d |
1035 | //======================================================================= |
1036 | //function : TypeToExplore |
1037 | //purpose : |
1038 | //======================================================================= |
1039 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim) |
1040 | { |
1041 | TopAbs_ShapeEnum aRet; |
1042 | // |
1043 | switch(theDim) { |
1044 | case 0: |
1045 | aRet=TopAbs_VERTEX; |
1046 | break; |
1047 | case 1: |
1048 | aRet=TopAbs_EDGE; |
1049 | break; |
1050 | case 2: |
1051 | aRet=TopAbs_FACE; |
1052 | break; |
1053 | case 3: |
1054 | aRet=TopAbs_SOLID; |
1055 | break; |
1056 | default: |
1057 | aRet=TopAbs_SHAPE; |
1058 | break; |
1059 | } |
1060 | return aRet; |
1061 | } |