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); |
8620e18d |
378 | // |
379 | pPF->Perform(); |
380 | // |
381 | myEntryPoint=1; |
382 | PerformInternal(*pPF); |
383 | } |
384 | //======================================================================= |
36f4947b |
385 | //function : PerformInternal1 |
4e57c75e |
386 | //purpose : |
387 | //======================================================================= |
36f4947b |
388 | void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller) |
4e57c75e |
389 | { |
390 | myErrorStatus=0; |
391 | myWarningStatus=0; |
392 | // |
393 | myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller; |
394 | myDS=myPaveFiller->PDS(); |
395 | myContext=myPaveFiller->Context(); |
396 | // |
397 | // 1. CheckData |
398 | CheckData(); |
399 | if (myErrorStatus && !myWarningStatus) { |
400 | return; |
401 | } |
402 | // |
403 | // 2. Prepare |
404 | Prepare(); |
405 | if (myErrorStatus) { |
406 | return; |
407 | } |
8620e18d |
408 | // |
4e57c75e |
409 | if(myWarningStatus == 2) { |
410 | return; |
411 | } |
4e57c75e |
412 | // 3. Fill Images |
413 | // 3.1 Vertices |
414 | FillImagesVertices(); |
415 | if (myErrorStatus) { |
416 | return; |
417 | } |
418 | // |
419 | BuildResult(TopAbs_VERTEX); |
420 | if (myErrorStatus) { |
421 | return; |
422 | } |
423 | // 3.2 Edges |
424 | FillImagesEdges(); |
425 | if (myErrorStatus) { |
426 | return; |
427 | } |
85915310 |
428 | // |
4e57c75e |
429 | BuildResult(TopAbs_EDGE); |
430 | if (myErrorStatus) { |
431 | return; |
432 | } |
4e57c75e |
433 | // |
434 | // 3.3 Wires |
435 | FillImagesContainers(TopAbs_WIRE); |
436 | if (myErrorStatus) { |
437 | return; |
438 | } |
85915310 |
439 | // |
4e57c75e |
440 | BuildResult(TopAbs_WIRE); |
441 | if (myErrorStatus) { |
442 | return; |
443 | } |
85915310 |
444 | // |
4e57c75e |
445 | // 3.4 Faces |
446 | FillImagesFaces(); |
447 | if (myErrorStatus) { |
448 | return; |
449 | } |
450 | |
451 | BuildResult(TopAbs_FACE); |
452 | if (myErrorStatus) { |
453 | return; |
454 | } |
85915310 |
455 | // |
4e57c75e |
456 | // 3.5 Shells |
4e57c75e |
457 | FillImagesContainers(TopAbs_SHELL); |
458 | if (myErrorStatus) { |
459 | return; |
460 | } |
85915310 |
461 | // |
4e57c75e |
462 | BuildResult(TopAbs_SHELL); |
463 | if (myErrorStatus) { |
464 | return; |
465 | } |
85915310 |
466 | // |
4e57c75e |
467 | // 3.6 Solids |
468 | FillImagesSolids(); |
469 | if (myErrorStatus) { |
470 | return; |
471 | } |
85915310 |
472 | // |
4e57c75e |
473 | BuildResult(TopAbs_SOLID); |
474 | if (myErrorStatus) { |
475 | return; |
476 | } |
85915310 |
477 | // |
4e57c75e |
478 | // 3.7 CompSolids |
479 | FillImagesContainers(TopAbs_COMPSOLID); |
480 | if (myErrorStatus) { |
481 | return; |
482 | } |
85915310 |
483 | // |
4e57c75e |
484 | BuildResult(TopAbs_COMPSOLID); |
485 | if (myErrorStatus) { |
486 | return; |
487 | } |
85915310 |
488 | // |
4e57c75e |
489 | // 3.8 Compounds |
490 | FillImagesCompounds(); |
491 | if (myErrorStatus) { |
492 | return; |
493 | } |
85915310 |
494 | // |
4e57c75e |
495 | BuildResult(TopAbs_COMPOUND); |
496 | if (myErrorStatus) { |
497 | return; |
498 | } |
499 | // |
8620e18d |
500 | // 4.BuildShape; |
4e57c75e |
501 | BuildShape(); |
8620e18d |
502 | if (myErrorStatus) { |
503 | return; |
504 | } |
4e57c75e |
505 | // |
8620e18d |
506 | // 5.History |
4e57c75e |
507 | PrepareHistory(); |
4e57c75e |
508 | // |
8620e18d |
509 | // 6 Post-treatment |
4e57c75e |
510 | PostTreat(); |
511 | } |
512 | //======================================================================= |
8620e18d |
513 | //function : BuildRC |
514 | //purpose : |
515 | //======================================================================= |
516 | void BOPAlgo_BOP::BuildRC() |
517 | { |
9526aa6a |
518 | TopAbs_ShapeEnum aType; |
8620e18d |
519 | TopoDS_Compound aC; |
8620e18d |
520 | BRep_Builder aBB; |
8620e18d |
521 | // |
9526aa6a |
522 | myErrorStatus = 0; |
8620e18d |
523 | // |
524 | aBB.MakeCompound(aC); |
525 | // |
526 | // A. Fuse |
9526aa6a |
527 | if (myOperation == BOPAlgo_FUSE) { |
528 | BOPCol_MapOfShape aMFence; |
529 | aType = TypeToExplore(myDims[0]); |
530 | TopExp_Explorer aExp(myShape, aType); |
8620e18d |
531 | for (; aExp.More(); aExp.Next()) { |
9526aa6a |
532 | const TopoDS_Shape& aS = aExp.Current(); |
533 | if (aMFence.Add(aS)) { |
534 | aBB.Add(aC, aS); |
535 | } |
8620e18d |
536 | } |
9526aa6a |
537 | myRC = aC; |
8620e18d |
538 | return; |
8620e18d |
539 | } |
8620e18d |
540 | // |
541 | // B. Common, Cut, Cut21 |
542 | // |
9526aa6a |
543 | Standard_Integer i, j, aNb, iDim; |
544 | Standard_Boolean bCheckEdges, bContains, bCut21, bCommon; |
545 | BOPCol_IndexedMapOfShape aMArgs, aMTools; |
546 | BOPCol_IndexedMapOfShape aMArgsIm, aMToolsIm; |
547 | BOPCol_ListIteratorOfListOfShape aItLS; |
8620e18d |
548 | // |
9526aa6a |
549 | for (i = 0; i < 2; ++i) { |
550 | const BOPCol_ListOfShape& aLS = !i ? myArguments : myTools; |
551 | BOPCol_IndexedMapOfShape& aMS = !i ? aMArgs : aMTools; |
552 | aItLS.Initialize(aLS); |
553 | for (; aItLS.More(); aItLS.Next()) { |
554 | const TopoDS_Shape& aS = aItLS.Value(); |
555 | iDim = BOPTools_AlgoTools::Dimension(aS); |
556 | aType = TypeToExplore(iDim); |
557 | BOPTools::MapShapes(aS, aType, aMS); |
558 | } |
559 | } |
560 | // |
561 | bCheckEdges = Standard_False; |
562 | // |
563 | for (i = 0; i < 2; ++i) { |
564 | const BOPCol_IndexedMapOfShape& aMS = !i ? aMArgs : aMTools; |
565 | BOPCol_IndexedMapOfShape& aMSIm = !i ? aMArgsIm : aMToolsIm; |
8620e18d |
566 | // |
9526aa6a |
567 | aNb = aMS.Extent(); |
568 | for (j = 1; j <= aNb; ++j) { |
569 | const TopoDS_Shape& aS = aMS(j); |
570 | aType = aS.ShapeType(); |
571 | if (aType == TopAbs_EDGE) { |
572 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS; |
573 | bCheckEdges = Standard_True; |
574 | if (BRep_Tool::Degenerated(aE)) { |
575 | continue; |
8620e18d |
576 | } |
577 | } |
9526aa6a |
578 | // |
579 | if (myImages.IsBound(aS)) { |
580 | const BOPCol_ListOfShape& aLSIm = myImages.Find(aS); |
581 | aItLS.Initialize(aLSIm); |
582 | for (; aItLS.More(); aItLS.Next()) { |
583 | const TopoDS_Shape& aSIm = aItLS.Value(); |
584 | aMSIm.Add(aSIm); |
955b3e71 |
585 | } |
8620e18d |
586 | } |
9526aa6a |
587 | else { |
588 | aMSIm.Add(aS); |
589 | } |
8620e18d |
590 | } |
9526aa6a |
591 | } |
8620e18d |
592 | // |
9526aa6a |
593 | // compare the maps and make the result |
594 | // |
595 | Standard_Integer iDimMin, iDimMax; |
596 | // |
597 | iDimMin = Min(myDims[0], myDims[1]); |
598 | bCommon = (myOperation == BOPAlgo_COMMON); |
599 | bCut21 = (myOperation == BOPAlgo_CUT21); |
600 | // |
601 | const BOPCol_IndexedMapOfShape& aMIt = bCut21 ? aMToolsIm : aMArgsIm; |
602 | const BOPCol_IndexedMapOfShape& aMCheck = bCut21 ? aMArgsIm : aMToolsIm; |
603 | // |
604 | BOPCol_IndexedMapOfShape aMCheckExp, aMItExp; |
605 | // |
606 | if (bCommon) { |
607 | aNb = aMIt.Extent(); |
608 | for (i = 1; i <= aNb; ++i) { |
609 | const TopoDS_Shape& aS = aMIt(i); |
610 | iDimMax = BOPTools_AlgoTools::Dimension(aS); |
611 | for (iDim = iDimMin; iDim < iDimMax; ++iDim) { |
612 | aType = TypeToExplore(iDim); |
613 | BOPTools::MapShapes(aS, aType, aMItExp); |
614 | } |
615 | aMItExp.Add(aS); |
616 | } |
617 | } |
618 | else { |
619 | aMItExp = aMIt; |
620 | } |
621 | // |
622 | aNb = aMCheck.Extent(); |
623 | for (i = 1; i <= aNb; ++i) { |
624 | const TopoDS_Shape& aS = aMCheck(i); |
625 | iDimMax = BOPTools_AlgoTools::Dimension(aS); |
626 | for (iDim = iDimMin; iDim < iDimMax; ++iDim) { |
627 | aType = TypeToExplore(iDim); |
628 | BOPTools::MapShapes(aS, aType, aMCheckExp); |
629 | } |
630 | aMCheckExp.Add(aS); |
631 | } |
632 | // |
633 | aNb = aMItExp.Extent(); |
634 | for (i = 1; i <= aNb; ++i) { |
635 | const TopoDS_Shape& aS = aMItExp(i); |
636 | // |
637 | bContains = aMCheckExp.Contains(aS); |
638 | if (bCommon) { |
639 | if (bContains) { |
640 | aBB.Add(aC, aS); |
8620e18d |
641 | } |
9526aa6a |
642 | } |
8620e18d |
643 | else { |
9526aa6a |
644 | if (!bContains) { |
645 | aBB.Add(aC, aS); |
646 | } |
647 | } |
648 | } |
649 | // |
650 | // filter result for COMMON operation |
651 | if (bCommon) { |
652 | BOPCol_MapOfShape aMFence; |
653 | TopExp_Explorer aExp; |
654 | TopoDS_Compound aCx; |
655 | aBB.MakeCompound(aCx); |
656 | // |
657 | for (iDim = 3; iDim >= iDimMin; --iDim) { |
658 | aType = TypeToExplore(iDim); |
659 | aExp.Init(aC, aType); |
8620e18d |
660 | for (; aExp.More(); aExp.Next()) { |
9526aa6a |
661 | const TopoDS_Shape& aS = aExp.Current(); |
662 | if (aMFence.Add(aS)) { |
663 | aBB.Add(aCx, aS); |
664 | BOPTools::MapShapes(aS, aMFence); |
8620e18d |
665 | } |
666 | } |
667 | } |
9526aa6a |
668 | aC = aCx; |
669 | } |
8620e18d |
670 | // |
9526aa6a |
671 | if (!bCheckEdges) { |
672 | myRC = aC; |
8620e18d |
673 | return; |
674 | } |
8620e18d |
675 | // |
676 | // The squats around degenerated edges |
9526aa6a |
677 | Standard_Integer nVD; |
8620e18d |
678 | BOPCol_IndexedMapOfShape aMVC; |
679 | // |
680 | // 1. Vertices of aC |
681 | BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC); |
682 | // |
683 | // 2. DE candidates |
9526aa6a |
684 | aNb = myDS->NbSourceShapes(); |
685 | for (i = 0; i < aNb; ++i) { |
686 | const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); |
687 | aType = aSI.ShapeType(); |
688 | if (aType != TopAbs_EDGE) { |
8620e18d |
689 | continue; |
690 | } |
691 | // |
9526aa6a |
692 | const TopoDS_Edge& aE = *((TopoDS_Edge*)&aSI.Shape()); |
8620e18d |
693 | if (!BRep_Tool::Degenerated(aE)) { |
694 | continue; |
695 | } |
696 | // |
9526aa6a |
697 | nVD = aSI.SubShapes().First(); |
698 | const TopoDS_Shape& aVD = myDS->Shape(nVD); |
8620e18d |
699 | // |
700 | if (!aMVC.Contains(aVD)) { |
701 | continue; |
702 | } |
703 | // |
704 | if (myDS->IsNewShape(nVD)) { |
705 | continue; |
706 | } |
707 | // |
708 | if (myDS->HasInterf(nVD)) { |
709 | continue; |
710 | } |
711 | // |
712 | aBB.Add(aC, aE); |
713 | } |
714 | // |
715 | myRC=aC; |
716 | } |
717 | //======================================================================= |
4e57c75e |
718 | //function : BuildShape |
719 | //purpose : |
720 | //======================================================================= |
8620e18d |
721 | void BOPAlgo_BOP::BuildShape() |
4e57c75e |
722 | { |
9526aa6a |
723 | BuildRC(); |
724 | // |
725 | if ((myOperation == BOPAlgo_FUSE) && (myDims[0] == 3)) { |
726 | BuildSolid(); |
727 | return; |
728 | } |
729 | // |
730 | Standard_Integer i; |
731 | TopAbs_ShapeEnum aType, aT1, aT2; |
732 | TopTools_ListOfShape aLSC, aLCB; |
733 | BOPCol_ListIteratorOfListOfShape aItLS, aItLSIm, aItLCB; |
4e57c75e |
734 | TopoDS_Iterator aIt; |
735 | BRep_Builder aBB; |
9526aa6a |
736 | TopoDS_Shape aRC, aRCB; |
4e57c75e |
737 | // |
9526aa6a |
738 | TopoDS_Compound aResult; |
739 | aBB.MakeCompound(aResult); |
4e57c75e |
740 | // |
9526aa6a |
741 | BOPCol_MapOfShape aMSRC, aMFence; |
742 | BOPTools::MapShapes(myRC, aMSRC); |
4e57c75e |
743 | // |
9526aa6a |
744 | // collect images of containers |
745 | for (i = 0; i < 2; ++i) { |
746 | const BOPCol_ListOfShape& aLS = !i ? myArguments : myTools; |
747 | // |
748 | aItLS.Initialize(aLS); |
749 | for (; aItLS.More(); aItLS.Next()) { |
750 | const TopoDS_Shape& aS = aItLS.Value(); |
751 | // |
752 | CollectContainers(aS, aLSC); |
753 | } |
4e57c75e |
754 | } |
9526aa6a |
755 | // make containers |
756 | aItLS.Initialize(aLSC); |
757 | for (; aItLS.More(); aItLS.Next()) { |
758 | const TopoDS_Shape& aSC = aItLS.Value(); |
759 | // |
760 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
761 | // |
762 | aIt.Initialize(aSC); |
763 | for (; aIt.More(); aIt.Next()) { |
764 | const TopoDS_Shape& aS = aIt.Value(); |
765 | if (myImages.IsBound(aS)) { |
766 | const TopTools_ListOfShape& aLSIm = myImages.Find(aS); |
767 | // |
768 | aItLSIm.Initialize(aLSIm); |
769 | for (; aItLSIm.More(); aItLSIm.Next()) { |
770 | const TopoDS_Shape& aSIm = aItLSIm.Value(); |
771 | if (aMSRC.Contains(aSIm) && aMFence.Add(aSIm)) { |
772 | aBB.Add(aRC, aSIm); |
773 | } |
774 | } |
775 | } |
776 | else if (aMSRC.Contains(aS) && aMFence.Add(aS)) { |
777 | aBB.Add(aRC, aS); |
778 | } |
4e57c75e |
779 | } |
780 | // |
9526aa6a |
781 | aType = aSC.ShapeType(); |
782 | switch (aType) { |
783 | case TopAbs_WIRE: { |
784 | aT1 = TopAbs_VERTEX; |
785 | aT2 = TopAbs_EDGE; |
786 | break; |
787 | } |
788 | case TopAbs_SHELL: { |
789 | aT1 = TopAbs_EDGE; |
790 | aT2 = TopAbs_FACE; |
791 | break; |
792 | } |
793 | default: { |
794 | aT1 = TopAbs_FACE; |
795 | aT2 = TopAbs_SOLID; |
796 | } |
4e57c75e |
797 | } |
798 | // |
9526aa6a |
799 | aLCB.Clear(); |
800 | BOPTools_AlgoTools::MakeConnexityBlocks(aRC, aT1, aT2, aLCB); |
801 | if (aLCB.IsEmpty()) { |
802 | continue; |
803 | } |
4e57c75e |
804 | // |
805 | aItLCB.Initialize(aLCB); |
806 | for (; aItLCB.More(); aItLCB.Next()) { |
9526aa6a |
807 | BOPTools_AlgoTools::MakeContainer(aType, aRCB); |
4e57c75e |
808 | // |
9526aa6a |
809 | const TopoDS_Shape& aCB = aItLCB.Value(); |
4e57c75e |
810 | aIt.Initialize(aCB); |
811 | for (; aIt.More(); aIt.Next()) { |
9526aa6a |
812 | const TopoDS_Shape& aCBS = aIt.Value(); |
813 | aBB.Add(aRCB, aCBS); |
4e57c75e |
814 | } |
815 | // |
9526aa6a |
816 | if (aType == TopAbs_SHELL) { |
817 | BOPTools_AlgoTools::OrientFacesOnShell(aRCB); |
4e57c75e |
818 | } |
819 | // |
9526aa6a |
820 | aBB.Add(aResult, aRCB); |
4e57c75e |
821 | } |
9526aa6a |
822 | } |
823 | // |
824 | // add the rest of the shapes into result |
825 | BOPCol_MapOfShape aMSResult; |
826 | BOPTools::MapShapes(aResult, aMSResult); |
827 | // |
828 | aIt.Initialize(myRC); |
829 | for (; aIt.More(); aIt.Next()) { |
830 | const TopoDS_Shape& aS = aIt.Value(); |
831 | if (!aMSResult.Contains(aS)) { |
832 | aBB.Add(aResult, aS); |
4e57c75e |
833 | } |
834 | } |
9526aa6a |
835 | // |
836 | myShape = aResult; |
4e57c75e |
837 | } |
838 | //======================================================================= |
839 | //function : BuildSolid |
840 | //purpose : |
841 | //======================================================================= |
8620e18d |
842 | void BOPAlgo_BOP::BuildSolid() |
4e57c75e |
843 | { |
955b3e71 |
844 | Standard_Boolean bHasInterf, bHasSharedFaces; |
845 | Standard_Integer i, aNbF, aNbSx, iX, iErr, aNbZ; |
4e57c75e |
846 | TopAbs_Orientation aOr, aOr1; |
847 | TopoDS_Iterator aIt; |
848 | TopoDS_Shape aRC; |
849 | BRep_Builder aBB; |
850 | TopExp_Explorer aExp; |
851 | BOPCol_IndexedMapOfShape aMFI; |
852 | BOPCol_IndexedDataMapOfShapeListOfShape aMFS, aMEF; |
853 | BOPCol_ListIteratorOfListOfShape aItLS; |
854 | BOPCol_ListOfShape aSFS; |
955b3e71 |
855 | BOPAlgo_BuilderSolid aSB; |
856 | BOPCol_MapOfShape aMSA, aMZ; |
319da2e4 |
857 | BOPTools_IndexedDataMapOfSetShape aDMSTS; |
4e57c75e |
858 | // |
859 | myErrorStatus=0; |
860 | // |
955b3e71 |
861 | // Map of of Solids of Arguments |
862 | for (i=0; i<2; ++i) { |
863 | const BOPCol_ListOfShape& aLSA=(i) ? myArguments : myTools; |
864 | aItLS.Initialize(aLSA); |
865 | for (; aItLS.More(); aItLS.Next()) { |
866 | const TopoDS_Shape& aSA=aItLS.Value(); |
867 | aExp.Init(aSA, TopAbs_SOLID); |
868 | for (; aExp.More(); aExp.Next()) { |
869 | const TopoDS_Shape& aZA=aExp.Current(); |
870 | aMSA.Add(aZA); |
871 | // |
872 | BOPTools::MapShapesAndAncestors(aZA, |
873 | TopAbs_FACE, |
874 | TopAbs_SOLID, |
875 | aMFS); |
876 | } |
877 | } |
878 | } |
879 | // |
880 | aNbF=aMFS.Extent(); |
881 | for (i=1; i<aNbF; ++i) { |
882 | //const TopoDS_Shape& aFA=aMFZA.FindKey(i); |
883 | const BOPCol_ListOfShape& aLZA=aMFS(i); |
884 | aNbZ=aLZA.Extent(); |
885 | if (aNbZ > 1) { |
886 | aItLS.Initialize(aLZA); |
887 | for(; aItLS.More(); aItLS.Next()) { |
888 | const TopoDS_Shape& aZA=aItLS.Value(); |
889 | aMZ.Add(aZA); |
890 | } |
891 | } |
892 | } |
893 | // |
894 | aMFS.Clear(); |
895 | // |
4e57c75e |
896 | aIt.Initialize(myRC); |
897 | for (; aIt.More(); aIt.Next()) { |
898 | const TopoDS_Shape& aSx=aIt.Value(); |
955b3e71 |
899 | if (aMSA.Contains(aSx)) { |
900 | iX=myDS->Index(aSx); |
901 | bHasInterf=myDS->HasInterf(iX); |
902 | bHasSharedFaces=aMZ.Contains(aSx); |
903 | // |
904 | if (!bHasInterf && !bHasSharedFaces) { |
905 | // It means that the solid aSx will be added |
906 | // to the result as is. |
907 | // The solid aSx will not participate |
908 | // in creation of a new solid(s). |
909 | BOPTools_Set aST; |
910 | // |
911 | aST.Add(aSx, TopAbs_FACE); |
912 | // |
319da2e4 |
913 | if (!aDMSTS.Contains(aST)) { |
914 | aDMSTS.Add(aST, aSx); |
955b3e71 |
915 | } |
916 | |
917 | continue; |
918 | } |
919 | } |
920 | // |
4e57c75e |
921 | aExp.Init(aSx, TopAbs_FACE); |
922 | for (; aExp.More(); aExp.Next()) { |
923 | const TopoDS_Shape& aFx=aExp.Current(); |
924 | // |
925 | aOr=aFx.Orientation(); |
926 | if (aOr==TopAbs_INTERNAL) { |
927 | aMFI.Add(aFx); |
928 | continue; |
929 | } |
930 | // |
931 | if (!aMFS.Contains(aFx)) { |
932 | BOPCol_ListOfShape aLSx; |
933 | // |
934 | aLSx.Append(aSx); |
935 | aMFS.Add(aFx, aLSx); |
936 | } |
937 | else { |
938 | iX=aMFS.FindIndex(aFx); |
939 | const TopoDS_Shape& aFx1=aMFS.FindKey(iX); |
940 | aOr1=aFx1.Orientation(); |
941 | if (aOr1!=aOr) { |
942 | BOPCol_ListOfShape& aLSx=aMFS.ChangeFromKey(aFx); |
943 | aLSx.Append(aSx); |
944 | aMFS.Add(aFx, aLSx); |
945 | } |
946 | } |
947 | } |
955b3e71 |
948 | } // for (; aIt.More(); aIt.Next()) { |
8620e18d |
949 | //faces that will be added in the end; |
950 | BOPCol_ListOfShape aLF, aLFx; |
4e57c75e |
951 | // SFS |
952 | aNbF=aMFS.Extent(); |
953 | for (i=1; i<=aNbF; ++i) { |
954 | const TopoDS_Shape& aFx=aMFS.FindKey(i); |
955 | const BOPCol_ListOfShape& aLSx=aMFS(i); |
956 | aNbSx=aLSx.Extent(); |
957 | if (aNbSx==1) { |
8620e18d |
958 | BOPTools::MapShapesAndAncestors |
959 | (aFx,TopAbs_EDGE, TopAbs_FACE, aMEF); |
4e57c75e |
960 | if (IsBoundSplits(aFx, aMEF)){ |
961 | aLFx.Append(aFx); |
962 | continue; |
963 | } |
964 | aLF.Append(aFx); |
965 | } |
966 | } |
967 | |
968 | aItLS.Initialize(aLF); |
969 | for(; aItLS.More(); aItLS.Next()) { |
970 | const TopoDS_Shape& aFx=aItLS.Value(); |
971 | aSFS.Append(aFx); |
972 | } |
973 | // add faces from aLFx to aSFS; |
974 | aItLS.Initialize(aLFx); |
975 | for (; aItLS.More(); aItLS.Next()) { |
976 | const TopoDS_Shape& aFx=aItLS.Value(); |
977 | aSFS.Append(aFx); |
978 | } |
979 | // |
980 | aNbF=aMFI.Extent(); |
981 | for (i=1; i<=aNbF; ++i) { |
982 | TopoDS_Shape aFx; |
983 | // |
984 | aFx=aMFI.FindKey(i); |
985 | aFx.Orientation(TopAbs_FORWARD); |
986 | aSFS.Append(aFx); |
987 | aFx.Orientation(TopAbs_REVERSED); |
988 | aSFS.Append(aFx); |
989 | } |
990 | // |
991 | // BuilderSolid |
992 | BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC); |
993 | // |
994 | aSB.SetContext(myContext); |
995 | aSB.SetShapes(aSFS); |
996 | aSB.Perform(); |
997 | iErr=aSB.ErrorStatus(); |
998 | if (iErr) { |
999 | myErrorStatus=30; // SolidBuilder failed |
1000 | return; |
1001 | } |
1002 | // |
1003 | const BOPCol_ListOfShape& aLSR=aSB.Areas(); |
1004 | // |
1005 | aItLS.Initialize(aLSR); |
1006 | for (; aItLS.More(); aItLS.Next()) { |
1007 | const TopoDS_Shape& aSR=aItLS.Value(); |
1008 | aBB.Add(aRC, aSR); |
1009 | } |
955b3e71 |
1010 | // |
319da2e4 |
1011 | aNbSx = aDMSTS.Extent(); |
1012 | for (i = 1; i <= aNbSx; ++i) { |
1013 | const TopoDS_Shape& aSx = aDMSTS(i); |
955b3e71 |
1014 | aBB.Add(aRC, aSx); |
1015 | } |
1016 | // |
4e57c75e |
1017 | myShape=aRC; |
1018 | } |
4e57c75e |
1019 | //======================================================================= |
85915310 |
1020 | //function : IsBoundSplits |
4e57c75e |
1021 | //purpose : |
1022 | //======================================================================= |
8620e18d |
1023 | Standard_Boolean BOPAlgo_BOP::IsBoundSplits |
1024 | (const TopoDS_Shape& aS, |
1025 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF) |
4e57c75e |
1026 | { |
1027 | Standard_Boolean bRet = Standard_False; |
1028 | if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) { |
1029 | return !bRet; |
1030 | } |
1031 | |
1032 | BOPCol_ListIteratorOfListOfShape aIt; |
1033 | Standard_Integer aNbLS; |
1034 | TopAbs_Orientation anOr; |
1035 | // |
1036 | //check face aF may be connected to face from mySplits |
1037 | TopExp_Explorer aExp(aS, TopAbs_EDGE); |
1038 | for (; aExp.More(); aExp.Next()) { |
1039 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
1040 | // |
1041 | anOr = aE.Orientation(); |
1042 | if (anOr==TopAbs_INTERNAL) { |
1043 | continue; |
1044 | } |
1045 | // |
1046 | if (BRep_Tool::Degenerated(aE)) { |
1047 | continue; |
1048 | } |
1049 | // |
1050 | const BOPCol_ListOfShape& aLS=aMEF.FindFromKey(aE); |
1051 | aNbLS = aLS.Extent(); |
1052 | if (!aNbLS) { |
1053 | continue; |
1054 | } |
1055 | // |
1056 | aIt.Initialize(aLS); |
1057 | for (; aIt.More(); aIt.Next()) { |
1058 | const TopoDS_Shape& aSx = aIt.Value(); |
8620e18d |
1059 | if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) { |
4e57c75e |
1060 | return !bRet; |
1061 | } |
1062 | } |
1063 | } |
8620e18d |
1064 | // |
4e57c75e |
1065 | return bRet; |
1066 | } |
8620e18d |
1067 | //======================================================================= |
1068 | //function : TypeToExplore |
1069 | //purpose : |
1070 | //======================================================================= |
1071 | TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim) |
1072 | { |
1073 | TopAbs_ShapeEnum aRet; |
1074 | // |
1075 | switch(theDim) { |
1076 | case 0: |
1077 | aRet=TopAbs_VERTEX; |
1078 | break; |
1079 | case 1: |
1080 | aRet=TopAbs_EDGE; |
1081 | break; |
1082 | case 2: |
1083 | aRet=TopAbs_FACE; |
1084 | break; |
1085 | case 3: |
1086 | aRet=TopAbs_SOLID; |
1087 | break; |
1088 | default: |
1089 | aRet=TopAbs_SHAPE; |
1090 | break; |
1091 | } |
1092 | return aRet; |
1093 | } |
9526aa6a |
1094 | //======================================================================= |
1095 | //function : CollectContainers |
1096 | //purpose : |
1097 | //======================================================================= |
1098 | void CollectContainers(const TopoDS_Shape& theS, |
1099 | BOPCol_ListOfShape& theLSC) |
1100 | { |
1101 | TopAbs_ShapeEnum aType = theS.ShapeType(); |
1102 | if (aType == TopAbs_WIRE || |
1103 | aType == TopAbs_SHELL || |
1104 | aType == TopAbs_COMPSOLID) { |
1105 | theLSC.Append(theS); |
1106 | return; |
1107 | } |
1108 | // |
1109 | if (aType != TopAbs_COMPOUND) { |
1110 | return; |
1111 | } |
1112 | // |
1113 | TopoDS_Iterator aIt(theS); |
1114 | for (; aIt.More(); aIt.Next()) { |
1115 | const TopoDS_Shape& aS = aIt.Value(); |
1116 | CollectContainers(aS, theLSC); |
1117 | } |
1118 | } |
1119 | |