0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / BOPAlgo / BOPAlgo_CellsBuilder.cxx
CommitLineData
338434c7 1// Created by: Eugeny MALTCHIKOV
2// Copyright (c) 2015 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
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
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.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15
16#include <BOPAlgo_CellsBuilder.hxx>
17
33ba8565 18#include <BOPAlgo_Alerts.hxx>
803a8caf 19#include <BOPAlgo_BuilderSolid.hxx>
20#include <BOPDS_DS.hxx>
21#include <BOPTools_AlgoTools.hxx>
22#include <BOPTools_AlgoTools3D.hxx>
23#include <BRep_Builder.hxx>
24#include <ShapeUpgrade_UnifySameDomain.hxx>
1155d05a 25#include <TColStd_MapOfInteger.hxx>
26#include <TopExp.hxx>
803a8caf 27#include <TopExp_Explorer.hxx>
28#include <TopoDS_Compound.hxx>
338434c7 29
30
31static
32 TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim);
33
34static
35 void MakeTypedContainers(const TopoDS_Shape& theSC,
338434c7 36 TopoDS_Shape& theResult);
37
1155d05a 38static void CollectMaterialBoundaries(const TopTools_ListOfShape& theLS,
385d47dd 39 TopTools_MapOfShape& theMapKeepBnd);
40
338434c7 41//=======================================================================
42//function : empty constructor
43//purpose :
44//=======================================================================
45BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder()
46:
47 BOPAlgo_Builder(),
338434c7 48 myIndex(100, myAllocator),
49 myMaterials(100, myAllocator),
50 myShapeMaterial(100, myAllocator),
654c48b2 51 myMapModified(100, myAllocator)
338434c7 52{
53}
54
55//=======================================================================
56//function : empty constructor
57//purpose :
58//=======================================================================
59BOPAlgo_CellsBuilder::BOPAlgo_CellsBuilder
60 (const Handle(NCollection_BaseAllocator)& theAllocator)
61:
62 BOPAlgo_Builder(theAllocator),
338434c7 63 myIndex(100, myAllocator),
64 myMaterials(100, myAllocator),
65 myShapeMaterial(100, myAllocator),
654c48b2 66 myMapModified(100, myAllocator)
338434c7 67{
68}
69
70//=======================================================================
71//function : ~
72//purpose :
73//=======================================================================
74BOPAlgo_CellsBuilder::~BOPAlgo_CellsBuilder()
75{
76 Clear();
77}
78
338434c7 79//=======================================================================
80//function : Clear
81//purpose :
82//=======================================================================
83void BOPAlgo_CellsBuilder::Clear()
84{
85 BOPAlgo_Builder::Clear();
86 myIndex.Clear();
87 myMaterials.Clear();
88 myShapeMaterial.Clear();
654c48b2 89 myMapModified.Clear();
338434c7 90}
91
92//=======================================================================
93//function : GetAllParts
94//purpose :
95//=======================================================================
96const TopoDS_Shape& BOPAlgo_CellsBuilder::GetAllParts() const
97{
98 return myAllParts;
99}
100
338434c7 101//=======================================================================
102//function : PerformInternal1
103//purpose :
104//=======================================================================
105void BOPAlgo_CellsBuilder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
106{
948fe6ca 107 // Avoid filling history after GF operation as later
108 // in this method the result shape will be nullified
109 Standard_Boolean isHistory = HasHistory();
110 SetToFillHistory(Standard_False);
111 // Perform splitting of the arguments
338434c7 112 BOPAlgo_Builder::PerformInternal1(theFiller);
33ba8565 113 if (HasErrors()) {
338434c7 114 return;
115 }
948fe6ca 116
338434c7 117 // index all the parts to its origins
118 IndexParts();
948fe6ca 119
338434c7 120 // and nullify <myShape> for building the result;
121 RemoveAllFromResult();
948fe6ca 122
123 // Restore user's history settings
124 SetToFillHistory(isHistory);
338434c7 125}
126
338434c7 127//=======================================================================
128//function : IndexParts
129//purpose :
130//=======================================================================
131void BOPAlgo_CellsBuilder::IndexParts()
132{
e8b9db57 133 BRep_Builder aBB;
134 // all split parts of the shapes
135 TopoDS_Compound anAllParts;
136 aBB.MakeCompound(anAllParts);
338434c7 137 //
1155d05a 138 TopTools_MapOfShape aMFence;
139 TColStd_MapOfInteger aMDims;
e8b9db57 140 //
1155d05a 141 TopTools_ListIteratorOfListOfShape aIt(myArguments);
338434c7 142 for (; aIt.More(); aIt.Next()) {
143 const TopoDS_Shape& aS = aIt.Value();
739c7e59 144
145 TopTools_ListOfShape aLSubS;
146 BOPTools_AlgoTools::TreatCompound (aS, aLSubS);
147 for (TopTools_ListOfShape::Iterator itSub (aLSubS); itSub.More(); itSub.Next())
148 {
149 const TopoDS_Shape& aSS = itSub.Value();
150 Standard_Integer iDim = BOPTools_AlgoTools::Dimension (aSS);
151 aMDims.Add(iDim);
152 TopAbs_ShapeEnum aType = TypeToExplore (iDim);
153 TopExp_Explorer aExp (aSS, aType);
154 for (; aExp.More(); aExp.Next())
155 {
156 const TopoDS_Shape& aST = aExp.Current();
157 const TopTools_ListOfShape* pLSIm = myImages.Seek(aST);
158 if (!pLSIm) {
159 TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aST);
160 if (!pLS) {
161 pLS = &myIndex(myIndex.Add(aST, TopTools_ListOfShape()));
162 }
163 pLS->Append(aS);
164 //
165 if (aMFence.Add(aST)) {
166 aBB.Add(anAllParts, aST);
167 }
168 //
169 continue;
338434c7 170 }
e8b9db57 171 //
739c7e59 172 TopTools_ListIteratorOfListOfShape aItIm(*pLSIm);
173 for (; aItIm.More(); aItIm.Next()) {
174 const TopoDS_Shape& aSTIm = aItIm.Value();
175 //
176 TopTools_ListOfShape* pLS = myIndex.ChangeSeek(aSTIm);
177 if (!pLS) {
178 pLS = &myIndex(myIndex.Add(aSTIm, TopTools_ListOfShape()));
179 }
180 pLS->Append(aS);
181 //
182 if (aMFence.Add(aSTIm)) {
183 aBB.Add(anAllParts, aSTIm);
184 }
185 } // for (; aItIm.More(); aItIm.Next()) {
186 } // for (; aExp.More(); aExp.Next()) {
187 } // for (; itSub.More(); itSub.Next())
338434c7 188 } // for (; aIt.More(); aIt.Next()) {
e8b9db57 189 //
190 myAllParts = anAllParts;
191 //
192 if (aMDims.Extent() == 1) {
193 return;
194 }
195 //
196 // for the multi-dimensional case
197 // add sub-shapes of the splits into the <myIndex> map
198 //
199 Standard_Integer i, aNbS = myIndex.Extent();
200 for (i = 1; i <= aNbS; ++i) {
201 const TopoDS_Shape& aSP = myIndex.FindKey(i);
202 const TopTools_ListOfShape& aLSOr = myIndex(i);
203 //
204 Standard_Integer iType = BOPTools_AlgoTools::Dimension(aSP);
1155d05a 205 TColStd_MapIteratorOfMapOfInteger aItM(aMDims);
e8b9db57 206 for (; aItM.More(); aItM.Next()) {
207 Standard_Integer k = aItM.Value();
208 if (k >= iType) {
209 continue;
210 }
211 //
212 TopExp_Explorer aExp(aSP, TypeToExplore(k));
213 for (; aExp.More(); aExp.Next()) {
214 const TopoDS_Shape& aSS = aExp.Current();
1155d05a 215 TopTools_ListOfShape* pLSSOr = myIndex.ChangeSeek(aSS);
e8b9db57 216 if (!pLSSOr) {
217 myIndex.Add(aSS, aLSOr);
218 continue;
219 }
220 // add ancestors of the shape to the ancestors of the sub-shape
1155d05a 221 TopTools_ListIteratorOfListOfShape aItLS(aLSOr);
e8b9db57 222 for (; aItLS.More(); aItLS.Next()) {
223 const TopoDS_Shape& aSOr = aItLS.Value();
224 // provide uniqueness of the ancestors
1155d05a 225 TopTools_ListIteratorOfListOfShape aItLSS(*pLSSOr);
e8b9db57 226 for (; aItLSS.More(); aItLSS.Next()) {
227 if (aSOr.IsSame(aItLSS.Value())) {
228 break;
229 }
230 }
231 //
232 if (!aItLSS.More()) {
233 pLSSOr->Append(aSOr);
234 }
235 }
236 }
237 }
238 }
338434c7 239}
240
241//=======================================================================
242//function : AddToResult
243//purpose :
244//=======================================================================
1155d05a 245void BOPAlgo_CellsBuilder::AddToResult(const TopTools_ListOfShape& theLSToTake,
246 const TopTools_ListOfShape& theLSToAvoid,
338434c7 247 const Standard_Integer theMaterial,
248 const Standard_Boolean theUpdate)
249{
250 // find parts
1155d05a 251 TopTools_ListOfShape aParts;
338434c7 252 FindParts(theLSToTake, theLSToAvoid, aParts);
253 if (aParts.IsEmpty()) {
254 return;
255 }
256 //
338434c7 257 // collect result parts to avoid multiple adding of the same parts
1155d05a 258 TopTools_MapOfShape aResParts;
e8b9db57 259 TopoDS_Iterator aIt(myShape);
338434c7 260 for (; aIt.More(); aIt.Next()) {
e8b9db57 261 aResParts.Add(aIt.Value());
262 }
263 //
264 Standard_Boolean bChanged = Standard_False;
265 // add parts to result
1155d05a 266 TopTools_ListIteratorOfListOfShape aItLP(aParts);
e8b9db57 267 for (; aItLP.More(); aItLP.Next()) {
268 const TopoDS_Shape& aPart = aItLP.Value();
385d47dd 269 // provide uniqueness of the parts
270 if (aResParts.Add(aPart) && !myShapeMaterial.IsBound(aPart)) {
e8b9db57 271 BRep_Builder().Add(myShape, aPart);
338434c7 272 bChanged = Standard_True;
273 }
274 }
275 //
276 // update the material
277 if (theMaterial != 0) {
1155d05a 278 TopTools_ListOfShape aLSP;
e8b9db57 279 aItLP.Initialize(aParts);
280 for (; aItLP.More(); aItLP.Next()) {
281 const TopoDS_Shape& aPart = aItLP.Value();
338434c7 282 if (!myShapeMaterial.IsBound(aPart)) {
283 myShapeMaterial.Bind(aPart, theMaterial);
284 aLSP.Append(aPart);
285 }
286 } // for (; aIt.More(); aIt.Next()) {
287 //
288 if (aLSP.Extent()) {
1155d05a 289 TopTools_ListOfShape* pLS = myMaterials.ChangeSeek(theMaterial);
e8b9db57 290 if (!pLS) {
1155d05a 291 pLS = myMaterials.Bound(theMaterial, TopTools_ListOfShape());
338434c7 292 }
e8b9db57 293 pLS->Append(aLSP);
338434c7 294 } // if (aLSP.Extent()) {
295 } // if (theMaterial != 0) {
296 //
297 if (!theUpdate) {
298 if (bChanged) {
299 PrepareHistory();
300 }
301 }
302 else {
303 RemoveInternalBoundaries();
304 }
305}
306
307//=======================================================================
308//function : AddAllToResult
309//purpose :
310//=======================================================================
311void BOPAlgo_CellsBuilder::AddAllToResult(const Standard_Integer theMaterial,
312 const Standard_Boolean theUpdate)
313{
338434c7 314 myShapeMaterial.Clear();
315 myMaterials.Clear();
654c48b2 316 myMapModified.Clear();
338434c7 317 //
e8b9db57 318 myShape = myAllParts;
319 //
320 if (theMaterial != 0) {
1155d05a 321 TopTools_ListOfShape* pLSM = myMaterials.Bound(theMaterial, TopTools_ListOfShape());
338434c7 322 //
e8b9db57 323 TopoDS_Iterator aIt(myAllParts);
324 for (; aIt.More(); aIt.Next()) {
325 const TopoDS_Shape& aPart = aIt.Value();
338434c7 326 myShapeMaterial.Bind(aPart, theMaterial);
e8b9db57 327 pLSM->Append(aPart);
338434c7 328 }
329 }
330 //
338434c7 331 if (!theUpdate) {
332 PrepareHistory();
333 }
334 else {
335 RemoveInternalBoundaries();
336 }
337}
338
339//=======================================================================
340//function : RemoveFromResult
341//purpose :
342//=======================================================================
1155d05a 343void BOPAlgo_CellsBuilder::RemoveFromResult(const TopTools_ListOfShape& theLSToTake,
344 const TopTools_ListOfShape& theLSToAvoid)
338434c7 345{
346 // find parts
1155d05a 347 TopTools_ListOfShape aParts;
338434c7 348 FindParts(theLSToTake, theLSToAvoid, aParts);
349 if (aParts.IsEmpty()) {
350 return;
351 }
352 //
338434c7 353 // collect parts into the map and remove parts from materials
1155d05a 354 TopTools_MapOfShape aPartsToRemove;
355 TopTools_ListIteratorOfListOfShape aItP(aParts);
338434c7 356 for (; aItP.More(); aItP.Next()) {
357 const TopoDS_Shape& aPart = aItP.Value();
358 aPartsToRemove.Add(aPart);
359 //
e8b9db57 360 const Standard_Integer* pMaterial = myShapeMaterial.Seek(aPart);
361 if (pMaterial) {
1155d05a 362 TopTools_ListOfShape* pLSM = myMaterials.ChangeSeek(*pMaterial);
e8b9db57 363 if (pLSM) {
1155d05a 364 TopTools_ListIteratorOfListOfShape aItM(*pLSM);
e8b9db57 365 for (; aItM.More(); aItM.Next()) {
366 if (aPart.IsSame(aItM.Value())) {
367 pLSM->Remove(aItM);
368 break;
369 }
370 }
338434c7 371 }
338434c7 372 myShapeMaterial.UnBind(aPart);
e8b9db57 373 }
374 }
338434c7 375 //
338434c7 376 BRep_Builder aBB;
e8b9db57 377 TopoDS_Compound aResult;
338434c7 378 aBB.MakeCompound(aResult);
e8b9db57 379 Standard_Boolean bChanged = Standard_False;
338434c7 380 //
e8b9db57 381 TopoDS_Iterator aIt(myShape);
382 for (; aIt.More(); aIt.Next()) {
383 const TopoDS_Shape& aS = aIt.Value();
384 TopAbs_ShapeEnum aType = aS.ShapeType();
385 if (aType != TopAbs_WIRE &&
386 aType != TopAbs_SHELL &&
387 aType != TopAbs_COMPSOLID) {
338434c7 388 // basic element
389 if (aPartsToRemove.Contains(aS)) {
390 bChanged = Standard_True;
391 continue;
392 }
393 aBB.Add(aResult, aS);
e8b9db57 394 }
338434c7 395 else {
396 // container
338434c7 397 TopoDS_Compound aSC;
398 aBB.MakeCompound(aSC);
e8b9db57 399 Standard_Boolean bSCNotEmpty = Standard_False;
338434c7 400 //
e8b9db57 401 TopoDS_Iterator aItSC(aS);
402 for (; aItSC.More(); aItSC.Next()) {
403 const TopoDS_Shape& aSS = aItSC.Value();
338434c7 404 if (aPartsToRemove.Contains(aSS)) {
405 bChanged = Standard_True;
406 continue;
407 }
e8b9db57 408 //
409 bSCNotEmpty = Standard_True;
338434c7 410 aBB.Add(aSC, aSS);
e8b9db57 411 }
338434c7 412 //
e8b9db57 413 if (bSCNotEmpty) {
414 MakeTypedContainers(aSC, aResult);
338434c7 415 }
e8b9db57 416 }
417 }
338434c7 418 //
419 if (bChanged) {
420 myShape = aResult;
421 //
422 PrepareHistory();
423 }
424}
425
426//=======================================================================
427//function : RemoveAllFromResult
428//purpose :
429//=======================================================================
430void BOPAlgo_CellsBuilder::RemoveAllFromResult()
431{
432 // empty compound
433 TopoDS_Compound aC;
e8b9db57 434 BRep_Builder().MakeCompound(aC);
338434c7 435 myShape = aC;
436 //
437 myMaterials.Clear();
438 myShapeMaterial.Clear();
654c48b2 439 myMapModified.Clear();
338434c7 440 //
441 PrepareHistory();
442}
443
444//=======================================================================
445//function : RemoveInternalBoundaries
446//purpose :
447//=======================================================================
448void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
449{
450 if (myMaterials.IsEmpty()) {
451 return;
452 }
453 //
338434c7 454 BRep_Builder aBB;
e8b9db57 455 TopoDS_Compound aResult;
338434c7 456 aBB.MakeCompound(aResult);
338434c7 457 //
e8b9db57 458 Standard_Boolean bChanged = Standard_False;
459 // try to remove the internal boundaries between the
460 // shapes of the same material
1155d05a 461 TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape aItM(myMaterials);
462 TopTools_ListOfShape aLSUnify[2];
385d47dd 463 TopTools_MapOfShape aKeepMap[2];
338434c7 464 for (; aItM.More(); aItM.Next()) {
e8b9db57 465 Standard_Integer iMaterial = aItM.Key();
1155d05a 466 TopTools_ListOfShape& aLS = aItM.ChangeValue();
e8b9db57 467 //
468 if (aLS.IsEmpty()) {
469 continue;
470 }
471 //
472 if (aLS.Extent() == 1) {
473 TopAbs_ShapeEnum aType = aLS.First().ShapeType();
474 if (aType != TopAbs_WIRE &&
475 aType != TopAbs_SHELL &&
476 aType != TopAbs_COMPSOLID) {
477 aBB.Add(aResult, aLS.First());
478 continue;
479 }
480 }
481 //
482 // check the shapes of the same material to be of the same type
1155d05a 483 TopTools_ListIteratorOfListOfShape aItLS(aLS);
e8b9db57 484 TopAbs_ShapeEnum aType = aItLS.Value().ShapeType();
485 for (aItLS.Next(); aItLS.More(); aItLS.Next()) {
486 if (aType != aItLS.Value().ShapeType()) {
487 break;
488 }
489 }
385d47dd 490
491 if (aItLS.More())
492 {
33ba8565 493 // add the warning
385d47dd 494 TopoDS_Compound aMultiDimS;
495 aBB.MakeCompound(aMultiDimS);
496 aBB.Add(aMultiDimS, aLS.First());
497 aBB.Add(aMultiDimS, aItLS.Value());
498 AddWarning(new BOPAlgo_AlertRemovalOfIBForMDimShapes(aMultiDimS));
499 }
500 else
501 {
502 if (aType == TopAbs_EDGE || aType == TopAbs_FACE)
33ba8565 503 {
385d47dd 504 // for edges and faces, just collect shapes to unify them later after exiting the loop;
505 // collect boundaries of shapes of current material in the keep map
506 Standard_Integer iType = (aType == TopAbs_EDGE ? 0 : 1);
507 CollectMaterialBoundaries(aLS, aKeepMap[iType]);
508 // save shapes to unify later
1155d05a 509 TopTools_ListOfShape aCopy(aLS);
385d47dd 510 aLSUnify[iType].Append(aCopy);
511 continue;
33ba8565 512 }
385d47dd 513 else
514 {
515 // aType is Solid;
516 // remove internal faces between solids of the same material just now
1155d05a 517 TopTools_ListOfShape aLSNew;
385d47dd 518 if (RemoveInternals(aLS, aLSNew))
519 {
520 bChanged = Standard_True;
521 // update materials maps
522 for (aItLS.Initialize(aLSNew); aItLS.More(); aItLS.Next()) {
523 const TopoDS_Shape& aS = aItLS.Value();
524 myShapeMaterial.Bind(aS, iMaterial);
525 }
526 aLS.Assign(aLSNew);
527 }
e8b9db57 528 }
338434c7 529 }
385d47dd 530 // add shapes to result (multidimensional and solids)
531 for (aItLS.Initialize(aLS); aItLS.More(); aItLS.Next()) {
532 const TopoDS_Shape& aS = aItLS.Value();
533 aBB.Add(aResult, aS);
534 }
535 }
536
537 // remove internal boundaries for edges and faces
538 for (Standard_Integer iType = 0; iType < 2; ++iType)
539 {
540 if (aLSUnify[iType].IsEmpty())
541 continue;
1155d05a 542 TopTools_ListOfShape aLSN;
385d47dd 543 if (RemoveInternals(aLSUnify[iType], aLSN, aKeepMap[iType]))
544 bChanged = Standard_True;
545 // add shapes to result ([unified] edges or faces)
1155d05a 546 for (TopTools_ListIteratorOfListOfShape aItLS(aLSN); aItLS.More(); aItLS.Next()) {
e8b9db57 547 const TopoDS_Shape& aS = aItLS.Value();
338434c7 548 aBB.Add(aResult, aS);
338434c7 549 }
550 }
551 //
e8b9db57 552 if (bChanged) {
553 // add shapes without material into result
554 TopoDS_Iterator aIt(myShape);
555 for (; aIt.More(); aIt.Next()) {
556 const TopoDS_Shape& aS = aIt.Value();
557 //
558 if (myShapeMaterial.IsBound(aS)) {
559 continue;
560 }
561 //
562 // check if it is not a collection
563 TopAbs_ShapeEnum aType = aS.ShapeType();
564 if (aType != TopAbs_WIRE &&
565 aType != TopAbs_SHELL &&
566 aType != TopAbs_COMPSOLID) {
567 aBB.Add(aResult, aS);
568 }
569 else {
570 TopoDS_Compound aSC;
571 aBB.MakeCompound(aSC);
572 Standard_Boolean bSCEmpty(Standard_True), bSCChanged(Standard_False);
573 //
574 TopoDS_Iterator aItSC(aS);
575 for (; aItSC.More(); aItSC.Next()) {
576 const TopoDS_Shape& aSS = aItSC.Value();
577 if (!myShapeMaterial.IsBound(aSS)) {
578 aBB.Add(aSC, aSS);
579 bSCEmpty = Standard_False;
580 }
581 else {
582 bSCChanged = Standard_True;
583 }
584 }
585 //
586 if (bSCEmpty) {
587 continue;
588 }
589 //
590 if (bSCChanged) {
591 MakeTypedContainers(aSC, aResult);
592 }
593 else {
594 aBB.Add(aResult, aS);
595 }
596 }
597 }
598 //
599 myShape = aResult;
600 //
601 PrepareHistory();
602 }
338434c7 603}
604
605//=======================================================================
606//function : FindPart
607//purpose :
608//=======================================================================
1155d05a 609void BOPAlgo_CellsBuilder::FindParts(const TopTools_ListOfShape& theLSToTake,
610 const TopTools_ListOfShape& theLSToAvoid,
611 TopTools_ListOfShape& theParts)
338434c7 612{
613 if (theLSToTake.IsEmpty()) {
614 return;
615 }
616 //
e8b9db57 617 // map shapes to avoid
1155d05a 618 TopTools_MapOfShape aMSToAvoid;
619 TopTools_ListIteratorOfListOfShape aItArgs(theLSToAvoid);
338434c7 620 for (; aItArgs.More(); aItArgs.Next()) {
621 const TopoDS_Shape& aS = aItArgs.Value();
622 aMSToAvoid.Add(aS);
623 }
624 //
e8b9db57 625 // map shapes to be taken
1155d05a 626 TopTools_MapOfShape aMSToTake;
338434c7 627 aItArgs.Initialize(theLSToTake);
628 for (; aItArgs.More(); aItArgs.Next()) {
629 const TopoDS_Shape& aS = aItArgs.Value();
630 aMSToTake.Add(aS);
631 }
632 //
e8b9db57 633 Standard_Integer aNbS = aMSToTake.Extent();
634 //
635 // among the shapes to be taken into result, find any one
636 // of minimal dimension
637 Standard_Integer iDimMin = 10;
638 TopoDS_Shape aSMin;
639 //
640 aItArgs.Initialize(theLSToTake);
641 for (; aItArgs.More(); aItArgs.Next()) {
642 const TopoDS_Shape& aS = aItArgs.Value();
643 Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
644 if (iDim < iDimMin) {
645 iDimMin = iDim;
646 aSMin = aS;
647 }
648 }
338434c7 649 //
e8b9db57 650 // among the split parts of the shape of minimal dimension
651 // look for the parts to be taken into result
652 TopAbs_ShapeEnum aType = TypeToExplore(iDimMin);
653 TopExp_Explorer aExp(aSMin, aType);
338434c7 654 for (; aExp.More(); aExp.Next()) {
655 const TopoDS_Shape& aST = aExp.Current();
e8b9db57 656 // get split parts of the shape
1155d05a 657 TopTools_ListOfShape aLSTIm;
338434c7 658 if (!myImages.IsBound(aST)) {
659 aLSTIm.Append(aST);
660 } else {
661 aLSTIm = myImages.Find(aST);
662 }
663 //
1155d05a 664 TopTools_ListIteratorOfListOfShape aItIm(aLSTIm);
338434c7 665 for (; aItIm.More(); aItIm.Next()) {
666 const TopoDS_Shape& aPart = aItIm.Value();
667 //
668 if (!myIndex.Contains(aPart)) {
669 continue;
670 }
671 //
e8b9db57 672 // get input shapes in which the split part is contained
1155d05a 673 const TopTools_ListOfShape& aLS = myIndex.FindFromKey(aPart);
338434c7 674 if (aLS.Extent() < aNbS) {
675 continue;
676 }
677 //
e8b9db57 678 // check that input shapes containing the part should not be avoided
1155d05a 679 TopTools_MapOfShape aMS;
338434c7 680 aItArgs.Initialize(aLS);
e8b9db57 681 for (; aItArgs.More(); aItArgs.Next()) {
338434c7 682 const TopoDS_Shape& aS = aItArgs.Value();
338434c7 683 aMS.Add(aS);
e8b9db57 684 if (aMSToAvoid.Contains(aS)) {
685 break;
686 }
338434c7 687 }
688 //
e8b9db57 689 if (aItArgs.More()) {
338434c7 690 continue;
691 }
692 //
e8b9db57 693 // check that all shapes which should be taken contain the part
338434c7 694 aItArgs.Initialize(theLSToTake);
e8b9db57 695 for (; aItArgs.More(); aItArgs.Next()) {
696 if (!aMS.Contains(aItArgs.Value())) {
697 break;
698 }
338434c7 699 }
700 //
e8b9db57 701 if (!aItArgs.More()) {
338434c7 702 theParts.Append(aPart);
e8b9db57 703 }
704 }
705 }
338434c7 706}
707
708//=======================================================================
709//function : MakeContainers
710//purpose :
711//=======================================================================
712void BOPAlgo_CellsBuilder::MakeContainers()
713{
338434c7 714 BRep_Builder aBB;
e8b9db57 715 TopoDS_Compound aResult;
338434c7 716 aBB.MakeCompound(aResult);
e8b9db57 717 //
718 // basic elements of type EDGE, FACE and SOLID added into result
1155d05a 719 TopTools_ListOfShape aLS[3];
e8b9db57 720 //
721 TopoDS_Iterator aIt(myShape);
722 for (; aIt.More(); aIt.Next()) {
723 const TopoDS_Shape& aS = aIt.Value();
724 //
725 Standard_Integer iDim = BOPTools_AlgoTools::Dimension(aS);
726 if (iDim <= 0) {
727 aBB.Add(aResult, aS);
728 continue;
729 }
730 //
731 aLS[iDim-1].Append(aS);
732 }
733 //
734 for (Standard_Integer i = 0; i < 3; ++i) {
735 if (aLS[i].IsEmpty()) {
736 continue;
737 }
738 //
739 TopoDS_Compound aC;
740 aBB.MakeCompound(aC);
1155d05a 741 TopTools_ListIteratorOfListOfShape aItLS(aLS[i]);
e8b9db57 742 for (; aItLS.More(); aItLS.Next()) {
743 aBB.Add(aC, aItLS.Value());
744 }
745 //
746 MakeTypedContainers(aC, aResult);
747 }
338434c7 748 myShape = aResult;
749}
750
751//=======================================================================
752//function : RemoveInternals
753//purpose :
754//=======================================================================
1155d05a 755Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const TopTools_ListOfShape& theLS,
756 TopTools_ListOfShape& theLSNew,
385d47dd 757 const TopTools_MapOfShape& theMapKeepBnd)
338434c7 758{
e8b9db57 759 Standard_Boolean bRemoved = Standard_False;
338434c7 760 if (theLS.Extent() < 2) {
761 theLSNew = theLS;
e8b9db57 762 return bRemoved;
338434c7 763 }
338434c7 764 //
765 TopAbs_ShapeEnum aType = theLS.First().ShapeType();
766 //
767 if (aType == TopAbs_EDGE ||
768 aType == TopAbs_FACE) {
769 //
770 // make container
771 BRep_Builder aBB;
772 TopoDS_Shape aShape;
773 //
774 BOPTools_AlgoTools::MakeContainer
775 ((aType == TopAbs_FACE) ? TopAbs_SHELL : TopAbs_WIRE, aShape);
776 //
1155d05a 777 for (TopTools_ListIteratorOfListOfShape aIt(theLS); aIt.More(); aIt.Next()) {
338434c7 778 const TopoDS_Shape& aS = aIt.Value();
779 aBB.Add(aShape, aS);
780 }
781 //
782 // Unify same domain
783 Standard_Boolean bFaces, bEdges;
784 //
785 bFaces = (aType == TopAbs_FACE);
786 bEdges = (aType == TopAbs_EDGE);
338434c7 787 ShapeUpgrade_UnifySameDomain anUnify (aShape, bEdges, bFaces);
385d47dd 788 anUnify.KeepShapes(theMapKeepBnd);
338434c7 789 anUnify.Build();
790 const TopoDS_Shape& aSNew = anUnify.Shape();
791 //
e8b9db57 792 TopExp_Explorer aExp(aSNew, aType);
338434c7 793 for (; aExp.More(); aExp.Next()) {
794 const TopoDS_Shape& aSn = aExp.Current();
795 theLSNew.Append(aSn);
796 }
797 //
e8b9db57 798 if (theLSNew.IsEmpty()) {
33ba8565 799 // add the warning
800 if (bFaces)
801 AddWarning (new BOPAlgo_AlertRemovalOfIBForFacesFailed (aShape));
802 else
803 AddWarning (new BOPAlgo_AlertRemovalOfIBForEdgesFailed (aShape));
804 //
e8b9db57 805 theLSNew.Assign(theLS);
806 return bRemoved;
807 }
808 //
654c48b2 809 // fill map of modified shapes
1155d05a 810 TopTools_IndexedMapOfShape aMG;
338434c7 811 Standard_Integer i, aNb;
812 //
1155d05a 813 TopExp::MapShapes(aShape, TopAbs_VERTEX, aMG);
814 TopExp::MapShapes(aShape, TopAbs_EDGE, aMG);
815 TopExp::MapShapes(aShape, TopAbs_FACE, aMG);
338434c7 816 //
817 aNb = aMG.Extent();
818 for (i = 1; i <= aNb; ++i) {
819 const TopoDS_Shape& aSS = aMG(i);
385d47dd 820 const Standard_Integer* pMaterial = myShapeMaterial.Seek(aSS);
654c48b2 821 const TopTools_ListOfShape& aLSMod = anUnify.History()->Modified(aSS);
822 TopTools_ListIteratorOfListOfShape aIt(aLSMod);
20aa0d3f 823 for (; aIt.More(); aIt.Next()) {
811d6b7d 824 const TopoDS_Shape& aSU = aIt.Value();
385d47dd 825 myMapModified.Bind(aSS, aSU);
826 bRemoved = Standard_True;
827 if (pMaterial && !myShapeMaterial.IsBound(aSU))
828 myShapeMaterial.Bind(aSU, *pMaterial);
338434c7 829 }
830 }
831 }
832 else if (aType == TopAbs_SOLID) {
e8b9db57 833 BRep_Builder aBB;
834 TopoDS_Compound aSolids;
835 aBB.MakeCompound(aSolids);
338434c7 836 //
1155d05a 837 TopTools_ListIteratorOfListOfShape aItLS(theLS);
e8b9db57 838 for (; aItLS.More(); aItLS.Next()) {
839 const TopoDS_Shape& aSol = aItLS.Value();
840 aBB.Add(aSolids, aSol);
338434c7 841 }
842 //
e8b9db57 843 // Make connexity blocks of solids to create from each isolated block one solid.
844 // It will allow attaching internal entities of the solids to new solid.
1155d05a 845 TopTools_ListOfShape aLCB;
e8b9db57 846 BOPTools_AlgoTools::MakeConnexityBlocks(aSolids, TopAbs_FACE, TopAbs_SOLID, aLCB);
338434c7 847 //
e8b9db57 848 // for each block remove internal faces
1155d05a 849 TopTools_ListIteratorOfListOfShape aItLCB(aLCB);
e8b9db57 850 for (; aItLCB.More(); aItLCB.Next()) {
851 const TopoDS_Shape& aCB = aItLCB.Value();
338434c7 852 //
e8b9db57 853 // Map faces and solids to find boundary faces that can be removed
1155d05a 854 TopTools_IndexedDataMapOfShapeListOfShape aDMFS;
e8b9db57 855 // internal entities
1155d05a 856 TopTools_ListOfShape aLSInt;
e8b9db57 857 //
858 TopoDS_Iterator aItS(aCB);
859 for (; aItS.More(); aItS.Next()) {
860 const TopoDS_Shape& aSol = aItS.Value();
861 //
862 TopoDS_Iterator aItIS(aSol);
863 for (; aItIS.More(); aItIS.Next()) {
864 const TopoDS_Shape& aSI = aItIS.Value();
865 if (aSI.Orientation() == TopAbs_INTERNAL) {
866 aLSInt.Append(aSI);
867 }
868 else {
869 TopoDS_Iterator aItF(aSI);
870 for (; aItF.More(); aItF.Next()) {
871 const TopoDS_Shape& aF = aItF.Value();
1155d05a 872 TopTools_ListOfShape *pLSols = aDMFS.ChangeSeek(aF);
e8b9db57 873 if (!pLSols) {
1155d05a 874 pLSols = &aDMFS(aDMFS.Add(aF, TopTools_ListOfShape()));
e8b9db57 875 }
876 pLSols->Append(aSol);
877 }
878 }
338434c7 879 }
e8b9db57 880 }
881 //
882 // to build unified solid, select only faces attached to only one solid
1155d05a 883 TopTools_ListOfShape aLFUnique;
e8b9db57 884 Standard_Integer i, aNb = aDMFS.Extent();
885 for (i = 1; i <= aNb; ++i) {
886 if (aDMFS(i).Extent() == 1) {
887 aLFUnique.Append(aDMFS.FindKey(i));
338434c7 888 }
889 }
e8b9db57 890 //
891 if (aNb == aLFUnique.Extent()) {
892 // no faces to remove
811d6b7d 893 aItS.Initialize(aCB);
e8b9db57 894 for (; aItS.More(); aItS.Next()) {
895 theLSNew.Append(aItS.Value());
896 }
897 continue;
338434c7 898 }
e8b9db57 899 //
900 // build new solid
901 BOPAlgo_BuilderSolid aBS;
902 aBS.SetShapes(aLFUnique);
903 aBS.Perform();
904 //
33ba8565 905 if (aBS.HasErrors() || aBS.Areas().Extent() != 1) {
906 // add the warning
907 {
908 TopoDS_Compound aUniqeFaces;
909 aBB.MakeCompound(aUniqeFaces);
1155d05a 910 TopTools_ListIteratorOfListOfShape aItLFUniqe(aLFUnique);
33ba8565 911 for (; aItLFUniqe.More(); aItLFUniqe.Next()) {
912 aBB.Add(aUniqeFaces, aItLFUniqe.Value());
913 }
914 //
915 AddWarning (new BOPAlgo_AlertRemovalOfIBForSolidsFailed (aUniqeFaces));
916 }
e8b9db57 917 //
811d6b7d 918 aItS.Initialize(aCB);
e8b9db57 919 for (; aItS.More(); aItS.Next()) {
920 theLSNew.Append(aItS.Value());
921 }
922 continue;
923 }
924 //
7f3408c8 925 myReport->Merge(aBS.GetReport());
926 //
e8b9db57 927 TopoDS_Solid& aSNew = *(TopoDS_Solid*)&aBS.Areas().First();
928 //
929 // put all internal parts into new solid
930 aSNew.Free(Standard_True);
1155d05a 931 TopTools_ListIteratorOfListOfShape aItLSI(aLSInt);
e8b9db57 932 for (; aItLSI.More(); aItLSI.Next()) {
933 aBB.Add(aSNew, aItLSI.Value());
934 }
935 aSNew.Free(Standard_False);
936 //
937 theLSNew.Append(aSNew);
938 bRemoved = Standard_True;
803a8caf 939
940 // Save information about the fuse of the solids into a history map
941 aItS.Initialize(aCB);
942 for (; aItS.More(); aItS.Next())
943 myMapModified.Bind(aItS.Value(), aSNew);
338434c7 944 }
338434c7 945 }
e8b9db57 946 return bRemoved;
338434c7 947}
948
949//=======================================================================
803a8caf 950//function : LocModified
338434c7 951//purpose :
952//=======================================================================
803a8caf 953const TopTools_ListOfShape* BOPAlgo_CellsBuilder::LocModified(const TopoDS_Shape& theS)
338434c7 954{
803a8caf 955 // Get shape's modification coming from GF operation
956 const TopTools_ListOfShape* pLSp = BOPAlgo_Builder::LocModified(theS);
957 if (myMapModified.IsEmpty())
958 // No local modifications
959 return pLSp;
338434c7 960
338434c7 961 myHistShapes.Clear();
803a8caf 962
963 // Check if the shape (or its splits) has participated in unification
964 if (!pLSp)
965 {
966 // No splits from GF operation.
967 // Check if the shape has been unified with other shapes
968 const TopoDS_Shape* pSU = myMapModified.Seek(theS);
969 if (!pSU)
970 return NULL;
971
972 myHistShapes.Append(*pSU);
338434c7 973 }
803a8caf 974 else
975 {
4f7d41ea 976 TopTools_MapOfShape aMFence;
803a8caf 977 // Process all GF splits and check them for local unification with other shapes
978 TopTools_ListIteratorOfListOfShape aIt(*pLSp);
979 for (; aIt.More(); aIt.Next())
654c48b2 980 {
803a8caf 981 const TopoDS_Shape* pSp = &aIt.Value();
982 const TopoDS_Shape* pSU = myMapModified.Seek(*pSp);
983 if (pSU) pSp = pSU;
4f7d41ea 984 if (aMFence.Add(*pSp))
985 myHistShapes.Append(*pSp);
654c48b2 986 }
338434c7 987 }
803a8caf 988 return &myHistShapes;
338434c7 989}
990
991//=======================================================================
992//function : MakeTypedContainers
993//purpose :
994//=======================================================================
995void MakeTypedContainers(const TopoDS_Shape& theSC,
338434c7 996 TopoDS_Shape& theResult)
997{
998 TopAbs_ShapeEnum aContainerType, aConnexityType, aPartType;
999 //
e8b9db57 1000 aPartType = TypeToExplore(BOPTools_AlgoTools::Dimension(theSC));
338434c7 1001 switch (aPartType) {
1002 case TopAbs_EDGE: {
1003 aContainerType = TopAbs_WIRE;
1004 aConnexityType = TopAbs_VERTEX;
1005 break;
1006 }
1007 case TopAbs_FACE: {
1008 aContainerType = TopAbs_SHELL;
1009 aConnexityType = TopAbs_EDGE;
1010 break;
1011 }
1012 case TopAbs_SOLID: {
1013 aContainerType = TopAbs_COMPSOLID;
1014 aConnexityType = TopAbs_FACE;
1015 break;
1016 }
1017 default:
1018 return;
1019 }
1020 //
1155d05a 1021 TopTools_ListOfShape aLCB;
338434c7 1022 BOPTools_AlgoTools::MakeConnexityBlocks(theSC, aConnexityType, aPartType, aLCB);
1023 if (aLCB.IsEmpty()) {
1024 return;
1025 }
1026 //
1027 BRep_Builder aBB;
1028 TopExp_Explorer aExp;
1155d05a 1029 TopTools_ListIteratorOfListOfShape aItCB;
338434c7 1030 //
1031 aItCB.Initialize(aLCB);
1032 for (; aItCB.More(); aItCB.Next()) {
1033 TopoDS_Shape aRCB;
1034 BOPTools_AlgoTools::MakeContainer(aContainerType, aRCB);
1035 //
1036 const TopoDS_Shape& aCB = aItCB.Value();
1037 aExp.Init(aCB, aPartType);
1038 for (; aExp.More(); aExp.Next()) {
1039 const TopoDS_Shape& aCBS = aExp.Current();
1040 aBB.Add(aRCB, aCBS);
1041 }
1042 //
1043 if (aContainerType == TopAbs_SHELL) {
1044 BOPTools_AlgoTools::OrientFacesOnShell(aRCB);
1045 }
1046 //
1047 aBB.Add(theResult, aRCB);
1048 }
1049}
1050
385d47dd 1051//=======================================================================
1052//function : CollectMaterialBoundaries
1053//purpose : Add to theMapKeepBnd the boundary shapes of the area defined by shapes from the list
1054//=======================================================================
1155d05a 1055static void CollectMaterialBoundaries(const TopTools_ListOfShape& theLS,
385d47dd 1056 TopTools_MapOfShape& theMapKeepBnd)
1057{
1058 TopAbs_ShapeEnum aType = theLS.First().ShapeType();
1059 TopAbs_ShapeEnum aTypeSubsh = (aType == TopAbs_FACE ? TopAbs_EDGE : TopAbs_VERTEX);
1060 TopTools_IndexedDataMapOfShapeListOfShape aMapSubSh;
1155d05a 1061 TopTools_ListIteratorOfListOfShape anIt(theLS);
385d47dd 1062 for (; anIt.More(); anIt.Next())
1063 {
1064 const TopoDS_Shape& aS = anIt.Value();
1065 TopExp::MapShapesAndAncestors(aS, aTypeSubsh, aType, aMapSubSh);
1066 }
1067 for (int i = 1; i <= aMapSubSh.Extent(); i++)
1068 {
1069 // check if the subshape belongs to boundary of the area
1070 if (aMapSubSh(i).Extent() == 1)
1071 {
1072 // add to theMapKeepBnd
1073 theMapKeepBnd.Add(aMapSubSh.FindKey(i));
1074 }
1075 }
1076}
1077
338434c7 1078//=======================================================================
1079//function : TypeToExplore
1080//purpose :
1081//=======================================================================
1082TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
1083{
1084 TopAbs_ShapeEnum aRet;
1085 //
1086 switch(theDim) {
1087 case 0:
1088 aRet=TopAbs_VERTEX;
1089 break;
1090 case 1:
1091 aRet=TopAbs_EDGE;
1092 break;
1093 case 2:
1094 aRet=TopAbs_FACE;
1095 break;
1096 case 3:
1097 aRet=TopAbs_SOLID;
1098 break;
1099 default:
1100 aRet=TopAbs_SHAPE;
1101 break;
1102 }
1103 return aRet;
1104}