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