1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
22 #include <BOPAlgo_Builder.hxx>
24 #include <NCollection_IncAllocator.hxx>
26 #include <TopAbs_State.hxx>
29 #include <TopoDS_Iterator.hxx>
30 #include <TopoDS_Solid.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Solid.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shell.hxx>
36 #include <TopoDS_Compound.hxx>
39 #include <TopExp_Explorer.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRepTools.hxx>
43 #include <BRepClass3d_SolidClassifier.hxx>
45 #include <BOPCol_IndexedMapOfShape.hxx>
46 #include <BOPCol_MapOfShape.hxx>
47 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <BOPCol_ListOfShape.hxx>
50 #include <BOPDS_DS.hxx>
51 #include <BOPDS_ShapeInfo.hxx>
53 #include <BOPTools.hxx>
54 #include <BOPTools_AlgoTools.hxx>
56 #include <BOPTools_MapOfSet.hxx>
57 #include <BOPTools_Set.hxx>
59 #include <BOPAlgo_BuilderSolid.hxx>
63 void OwnInternalShapes(const TopoDS_Shape& ,
64 BOPCol_IndexedMapOfShape& );
66 //=======================================================================
67 //function : FillImagesSolids
69 //=======================================================================
70 void BOPAlgo_Builder::FillImagesSolids()
74 Handle(NCollection_IncAllocator) aAllocator;
75 //-----------------------------------------------------scope_1 f
76 aAllocator=new NCollection_IncAllocator();
78 BOPCol_DataMapOfShapeListOfShape theInParts(100, aAllocator);
79 BOPCol_DataMapOfShapeShape theDraftSolids(100, aAllocator);
81 FillIn3DParts(theInParts, theDraftSolids, aAllocator);
82 BuildSplitSolids(theInParts, theDraftSolids, aAllocator);
86 theDraftSolids.Clear();
87 //-----------------------------------------------------scope_1 t
89 //=======================================================================
90 //function : FillIn3DParts
92 //=======================================================================
93 void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts,
94 BOPCol_DataMapOfShapeShape& theDraftSolids,
95 const Handle(NCollection_BaseAllocator)& theAllocator)
99 Standard_Boolean bIsIN, bHasImage;
100 Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
101 TopAbs_ShapeEnum aType;
103 TopoDS_Iterator aIt, aItF;
105 TopoDS_Solid aSolidSp;
107 BOPCol_ListIteratorOfListOfShape aItS, aItFP, aItEx;
109 BOPCol_ListOfShape aLIF(theAllocator);
110 BOPCol_MapOfShape aMFDone(100, theAllocator);
111 BOPCol_IndexedMapOfShape aMSolids(100, theAllocator);
112 BOPCol_IndexedMapOfShape aMFaces(100, theAllocator);
113 BOPCol_IndexedMapOfShape aMFIN(100, theAllocator);
114 BOPCol_IndexedMapOfShape aMS(100, theAllocator);
115 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
117 theDraftSolids.Clear();
119 aNbS=myDS->NbSourceShapes();
120 for (i=0; i<aNbS; ++i) {
121 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
122 const TopoDS_Shape& aS=aSI.Shape();
124 aType=aSI.ShapeType();
132 // all faces (originals or images)
133 if (myImages.IsBound(aS)) {
134 const BOPCol_ListOfShape& aLS=myImages.Find(aS);
135 aItS.Initialize(aLS);
136 for (; aItS.More(); aItS.Next()) {
137 const TopoDS_Shape& aFx=aItS.Value();
152 aNbFaces=aMFaces.Extent();
153 aNbSolids=aMSolids.Extent();
155 for (i=1; i<=aNbSolids; ++i) {
156 const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aMSolids(i)));
162 aBB.MakeSolid(aSolidSp);
164 // Draft solid and its pure internal faces => aSolidSp, aLIF
166 BuildDraftSolid(aSolid, aSolidSp, aLIF);
167 aNbLIF=aLIF.Extent();
169 // 1 all faces/edges from aSolid [ aMS ]
170 bHasImage=Standard_False;
172 aIt.Initialize(aSolid);
173 for (; aIt.More(); aIt.Next()) {
174 const TopoDS_Shape& aShell=aIt.Value();
176 if (myImages.IsBound(aShell)) {
177 bHasImage=Standard_True;
179 const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
180 aItS.Initialize(aLS);
181 for (; aItS.More(); aItS.Next()) {
182 const TopoDS_Shape& aSx=aItS.Value();
184 BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
185 BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
186 BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
191 BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
192 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
196 // 2 all faces that are not from aSolid [ aLFP1 ]
197 BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, theAllocator);
198 BOPCol_ListOfShape aLFP1(theAllocator);
199 BOPCol_ListOfShape aLFP(theAllocator);
200 BOPCol_ListOfShape aLCBF(theAllocator);
201 BOPCol_ListOfShape aLFIN(theAllocator);
202 BOPCol_ListOfShape aLEx(theAllocator);
204 // for all non-solid faces build EF map [ aMEFP ]
205 for (j=1; j<=aNbFaces; ++j) {
206 const TopoDS_Shape& aFace=aMFaces(j);
207 if (!aMS.Contains(aFace)) {
208 BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
212 // among all faces from aMEFP select these that have same edges
213 // with the solid (i.e aMEF). These faces will be treated first
214 // to prevent the usage of 3D classifier.
215 // The full list of faces to process is aLFP1.
216 aNbEFP=aMEFP.Extent();
217 for (j=1; j<=aNbEFP; ++j) {
218 const TopoDS_Shape& aE=aMEFP.FindKey(j);
220 if (aMEF.Contains(aE)) { // !!
221 const BOPCol_ListOfShape& aLF=aMEFP(j);
222 aItFP.Initialize(aLF);
223 for (; aItFP.More(); aItFP.Next()) {
224 const TopoDS_Shape& aF=aItFP.Value();
225 if (aMFDone.Add(aF)) {
235 aItEx.Initialize(aLEx);
236 for (; aItEx.More(); aItEx.Next()) {
237 const TopoDS_Shape& aE=aItEx.Value();
238 const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
239 aItFP.Initialize(aLF);
240 for (; aItFP.More(); aItFP.Next()) {
241 const TopoDS_Shape& aF=aItFP.Value();
242 if (aMFDone.Add(aF)) {
251 // 3 Process faces aLFP1
253 aNbFP=aLFP1.Extent();
254 aItFP.Initialize(aLFP1);
255 for (; aItFP.More(); aItFP.Next()) {
256 const TopoDS_Shape& aSP=aItFP.Value();
257 if (!aMFDone.Add(aSP)) {
262 // first face to process
263 aFP=(*(TopoDS_Face*)(&aSP));
264 bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
265 aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
267 // collect faces to process [ aFP is the first ]
270 aItS.Initialize(aLFP1);
271 for (; aItS.More(); aItS.Next()) {
272 const TopoDS_Shape& aSk=aItS.Value();
273 if (!aMFDone.Contains(aSk)) {
278 // Connexity Block that spreads from aFP the Bound
279 // or till the end of the block itself
281 BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, theAllocator);
283 // fill states for the Connexity Block
284 aItS.Initialize(aLCBF);
285 for (; aItS.More(); aItS.Next()) {
286 const TopoDS_Shape& aSx=aItS.Value();
288 if (aState==TopAbs_IN) {
293 aNbFPx=aMFDone.Extent();
297 }//for (; aItFP.More(); aItFP.Next())
299 // faces Inside aSolid
301 aNbFIN=aMFIN.Extent();
302 if (aNbFIN || aNbLIF) {
303 for (j=1; j<=aNbFIN; ++j) {
304 const TopoDS_Shape& aFIn=aMFIN(j);
308 aItS.Initialize(aLIF);
309 for (; aItS.More(); aItS.Next()) {
310 const TopoDS_Shape& aFIN=aItS.Value();
314 theInParts.Bind(aSolid, aLFIN);
316 if (aNbFIN || bHasImage) {
317 theDraftSolids.Bind(aSolid, aSolidSp);
319 }// for (; aItMS.More(); aItMS.Next()) {
321 //=======================================================================
322 //function : BuildDraftSolid
324 //=======================================================================
325 void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
326 TopoDS_Shape& theDraftSolid,
327 BOPCol_ListOfShape& theLIF)
331 Standard_Boolean bToReverse;
332 Standard_Integer iFlag;
333 TopAbs_Orientation aOrF, aOrSh, aOrSd;
334 TopoDS_Iterator aIt1, aIt2;
336 TopoDS_Shape aFSDx, aFx;
338 BOPCol_ListIteratorOfListOfShape aItS;
340 aOrSd=theSolid.Orientation();
341 theDraftSolid.Orientation(aOrSd);
343 aIt1.Initialize(theSolid);
344 for (; aIt1.More(); aIt1.Next()) {
345 const TopoDS_Shape& aSh=aIt1.Value();
346 if(aSh.ShapeType()!=TopAbs_SHELL) {
347 continue; // mb internal edges,vertices
350 aOrSh=aSh.Orientation();
352 aShD.Orientation(aOrSh);
355 aIt2.Initialize(aSh);
356 for (; aIt2.More(); aIt2.Next()) {
357 const TopoDS_Shape& aF=aIt2.Value();
358 aOrF=aF.Orientation();
360 if (myImages.IsBound(aF)) {
361 const BOPCol_ListOfShape& aLSp=myImages.Find(aF);
362 aItS.Initialize(aLSp);
363 for (; aItS.More(); aItS.Next()) {
366 if (myShapesSD.IsBound(aFx)) {
367 aFSDx=myShapesSD.Find(aFx);
369 if (aOrF==TopAbs_INTERNAL) {
370 aFSDx.Orientation(aOrF);
371 theLIF.Append(aFSDx);
374 bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext);
380 aBB.Add(aShD, aFSDx);
382 }//if (myShapesSD.IsBound(aFx)) {
384 aFx.Orientation(aOrF);
385 if (aOrF==TopAbs_INTERNAL) {
394 } // if (myImages.IsBound(aF)) {
397 if (aOrF==TopAbs_INTERNAL) {
405 } //for (; aIt2.More(); aIt2.Next()) {
408 aBB.Add(theDraftSolid, aShD);
410 } //for (; aIt1.More(); aIt1.Next()) {
412 //=======================================================================
413 //function : BuildSplitSolids
415 //=======================================================================
416 void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts,
417 BOPCol_DataMapOfShapeShape& theDraftSolids,
418 const Handle(NCollection_BaseAllocator)& theAllocator)
422 Standard_Boolean bFlagSD;
423 Standard_Integer i, aNbS, iErr, aNbSFS;
424 TopExp_Explorer aExp;
425 BOPCol_ListIteratorOfListOfShape aIt;
426 BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1;
428 BOPCol_ListOfShape aSFS(theAllocator), aLSEmpty(theAllocator);
429 BOPCol_MapOfShape aMFence(100, theAllocator);
430 BOPTools_MapOfSet aMST(100, theAllocator);
432 // 0. Find same domain solids for non-interferred solids
433 aNbS=myDS->NbSourceShapes();
434 for (i=0; i<aNbS; ++i) {
435 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
437 if (aSI.ShapeType()!=TopAbs_SOLID) {
441 const TopoDS_Shape& aS=aSI.Shape();
442 if (!aMFence.Add(aS)) {
445 if(theDraftSolids.IsBound(aS)) {
451 aST.Add(aS, TopAbs_FACE);
454 } //for (i=1; i<=aNbS; ++i)
456 // 1. Build solids for interferred source solids
457 for (i=0; i<aNbS; ++i) {
458 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
460 if (aSI.ShapeType()!=TopAbs_SOLID) {
464 const TopoDS_Shape& aS=aSI.Shape();
465 if(!theDraftSolids.IsBound(aS)) {
468 const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
469 const BOPCol_ListOfShape& aLFIN=
470 (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
472 // 1.1 Fill Shell Faces Set
474 aExp.Init(aSD, TopAbs_FACE);
475 for (; aExp.More(); aExp.Next()) {
476 const TopoDS_Shape& aF=aExp.Current();
480 aIt.Initialize(aLFIN);
481 for (; aIt.More(); aIt.Next()) {
482 TopoDS_Shape aF=aIt.Value();
484 aF.Orientation(TopAbs_FORWARD);
486 aF.Orientation(TopAbs_REVERSED);
490 aNbSFS=aSFS.Extent();
495 // 1.3 Build new solids
496 BOPAlgo_BuilderSolid aSB(theAllocator);
498 //aSB.SetContext(myContext);
501 iErr=aSB.ErrorStatus();
503 myErrorStatus=30; // SolidBuilder failed
507 const BOPCol_ListOfShape& aLSR=aSB.Areas();
509 // 1.4 Collect resulting solids and theirs set of faces.
511 if (!myImages.IsBound(aS)) {
512 BOPCol_ListOfShape aLSx;
514 myImages.Bind(aS, aLSx);
515 BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS);
517 aIt.Initialize(aLSR);
518 for (; aIt.More(); aIt.Next()) {
521 const TopoDS_Shape& aSR=aIt.Value();
522 aST.Add(aSR, TopAbs_FACE);
524 bFlagSD=aMST.Contains(aST);
526 const BOPTools_Set& aSTx=aMST.Added(aST);
527 const TopoDS_Shape& aSx=aSTx.Shape();
531 myShapesSD.Bind(aSR, aSx);
535 } // for (; aIt1.More(); aIt1.Next()) {
538 //=======================================================================
539 //function :FillInternalShapes
541 //=======================================================================
542 void BOPAlgo_Builder::FillInternalShapes()
546 Standard_Integer i, j, aNbS, aNbSI, aNbSx, aNbSd;
547 TopAbs_ShapeEnum aType;
549 TopoDS_Iterator aItS;
551 BOPCol_MapIteratorOfMapOfShape aItM;
552 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
554 Handle(NCollection_IncAllocator) aAllocator;
555 //-----------------------------------------------------scope f
556 aAllocator=new NCollection_IncAllocator();
558 BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
559 BOPCol_IndexedMapOfShape aMx(100, aAllocator);
560 BOPCol_MapOfShape aMSI(100, aAllocator);
561 BOPCol_MapOfShape aMFence(100, aAllocator);
562 BOPCol_MapOfShape aMSOr(100, aAllocator);
563 BOPCol_ListOfShape aLSd(aAllocator);
564 BOPCol_ListOfShape aLArgs(aAllocator);
566 // 1. Shapes to process
568 // 1.1 Shapes from pure arguments aMSI
569 // 1.1.1 vertex, edge, wire
571 aIt.Initialize(myArguments);
572 for (; aIt.More(); aIt.Next()) {
573 const TopoDS_Shape& aS=aIt.Value();
574 if (!aMFence.Add(aS)) {
578 aType=aS.ShapeType();
579 if (aType==TopAbs_WIRE) {
581 for(; aItS.More(); aItS.Next()) {
582 const TopoDS_Shape& aE=aItS.Value();
583 if (aMFence.Add(aE)) {
588 else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
594 aIt.Initialize(aLArgs);
595 for (; aIt.More(); aIt.Next()) {
596 const TopoDS_Shape& aS=aIt.Value();
597 aType=aS.ShapeType();
598 if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) {
599 if (aMFence.Add(aS)) {
600 if (myImages.IsBound(aS)) {
601 const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
602 aIt1.Initialize(aLSp);
603 for (; aIt1.More(); aIt1.Next()) {
604 const TopoDS_Shape& aSp=aIt1.Value();
617 // 2. Internal vertices, edges from source solids
621 aNbS=myDS->NbSourceShapes();
622 for (i=0; i<aNbS; ++i) {
623 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
625 if (aSI.ShapeType()!=TopAbs_SOLID) {
629 const TopoDS_Shape& aS=aSI.Shape();
632 OwnInternalShapes(aS, aMx);
635 for (j=1; j<=aNbSx; ++j) {
636 const TopoDS_Shape& aSi=aMx(j);
637 if (myImages.IsBound(aSi)) {
638 const BOPCol_ListOfShape &aLSp=myImages.Find(aSi);
639 aIt1.Initialize(aLSp);
640 for (; aIt1.More(); aIt1.Next()) {
641 const TopoDS_Shape& aSp=aIt1.Value();
650 // build aux map from splits of solids
651 if (myImages.IsBound(aS)) {
652 const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
653 aIt.Initialize(aLSp);
654 for (; aIt.More(); aIt.Next()) {
655 const TopoDS_Shape& aSp=aIt.Value();
656 if (aMFence.Add(aSp)) {
657 BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
658 BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
659 BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx);
665 if (aMFence.Add(aS)) {
666 BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
667 BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
668 BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx);
673 }// for (i=0; i<aNbS; ++i) {
677 // 3. Some shapes of aMSI can be already tied with faces of
679 aItM.Initialize(aMSI);
680 for (; aItM.More(); aItM.Next()) {
681 const TopoDS_Shape& aSI=aItM.Key();
682 if (aMSx.Contains(aSI)) {
683 const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
697 // 5 Settle internal vertices and edges into solids
699 aIt.Initialize(aLSd);
700 for (; aIt.More(); aIt.Next()) {
701 TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
703 aItM.Initialize(aMSI);
704 for (; aItM.More(); aItM.Next()) {
705 TopoDS_Shape aSI=aItM.Key();
706 aSI.Orientation(TopAbs_INTERNAL);
708 aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
709 if (aState==TopAbs_IN) {
711 if(aMSOr.Contains(aSd)) {
716 aItS.Initialize(aSd);
717 for (; aItS.More(); aItS.Next()) {
718 const TopoDS_Shape& aSh=aItS.Value();
724 if (myImages.IsBound(aSdx)) {
725 BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx);
729 BOPCol_ListOfShape aLS;
731 myImages.Bind(aSd, aLS);
742 } //if (aState==TopAbs_IN) {
743 }// for (; aItM.More(); aItM.Next()) {
744 }//for (; aIt1.More(); aIt1.Next()) {
746 //-----------------------------------------------------scope t
755 //=======================================================================
756 //function : OwnInternalShapes
758 //=======================================================================
759 void OwnInternalShapes(const TopoDS_Shape& theS,
760 BOPCol_IndexedMapOfShape& theMx)
764 aIt.Initialize(theS);
765 for (; aIt.More(); aIt.Next()) {
766 const TopoDS_Shape& aSx=aIt.Value();
767 if (aSx.ShapeType()!=TopAbs_SHELL) {
774 // 30 - SolidBuilder failed
780 BOPCol_ListIteratorOfListOfShape aItx;
782 aBBx.MakeCompound(aCx);
783 aItx.Initialize(aSFS1);
784 for (; aItx.More(); aItx.Next()) {
785 const TopoDS_Shape& aFx=aItx.Value();
788 BRepTools::Write(aCx, "cxso");