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