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 aMFIN(100, theAllocator);
112 //BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
113 //BOPCol_IndexedMapOfShape aMS(100, theAllocator);
114 BOPCol_IndexedMapOfShape aMSolids(100, theAllocator);
115 BOPCol_IndexedMapOfShape aMFaces(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 Handle(NCollection_IncAllocator) aAllocator1;
157 aAllocator1=new NCollection_IncAllocator();
159 BOPCol_MapOfShape aMFDone(100, aAllocator1);
160 BOPCol_IndexedMapOfShape aMFIN(100, aAllocator1);
161 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAllocator1);
162 BOPCol_ListOfShape aLIF(aAllocator1);
163 BOPCol_IndexedMapOfShape aMS(100, aAllocator1);
169 const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aMSolids(i)));
171 aBB.MakeSolid(aSolidSp);
173 // Draft solid and its pure internal faces => aSolidSp, aLIF
175 BuildDraftSolid(aSolid, aSolidSp, aLIF);
176 aNbLIF=aLIF.Extent();
178 // 1 all faces/edges from aSolid [ aMS ]
179 bHasImage=Standard_False;
181 aIt.Initialize(aSolid);
182 for (; aIt.More(); aIt.Next()) {
183 const TopoDS_Shape& aShell=aIt.Value();
185 if (myImages.IsBound(aShell)) {
186 bHasImage=Standard_True;
188 const BOPCol_ListOfShape& aLS=myImages.Find(aShell);
189 aItS.Initialize(aLS);
190 for (; aItS.More(); aItS.Next()) {
191 const TopoDS_Shape& aSx=aItS.Value();
193 BOPTools::MapShapes(aSx, TopAbs_FACE, aMS);
194 BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS);
195 BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
200 BOPTools::MapShapes(aShell, TopAbs_FACE, aMS);
201 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
205 // 2 all faces that are not from aSolid [ aLFP1 ]
206 BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAllocator1);
207 BOPCol_ListOfShape aLFP1(aAllocator1);
208 BOPCol_ListOfShape aLFP(aAllocator1);
209 BOPCol_ListOfShape aLCBF(aAllocator1);
210 BOPCol_ListOfShape aLFIN(aAllocator1);
211 BOPCol_ListOfShape aLEx(aAllocator1);
213 // for all non-solid faces build EF map [ aMEFP ]
214 for (j=1; j<=aNbFaces; ++j) {
215 const TopoDS_Shape& aFace=aMFaces(j);
216 if (!aMS.Contains(aFace)) {
217 BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
221 // among all faces from aMEFP select these that have same edges
222 // with the solid (i.e aMEF). These faces will be treated first
223 // to prevent the usage of 3D classifier.
224 // The full list of faces to process is aLFP1.
225 aNbEFP=aMEFP.Extent();
226 for (j=1; j<=aNbEFP; ++j) {
227 const TopoDS_Shape& aE=aMEFP.FindKey(j);
229 if (aMEF.Contains(aE)) { // !!
230 const BOPCol_ListOfShape& aLF=aMEFP(j);
231 aItFP.Initialize(aLF);
232 for (; aItFP.More(); aItFP.Next()) {
233 const TopoDS_Shape& aF=aItFP.Value();
234 if (aMFDone.Add(aF)) {
244 aItEx.Initialize(aLEx);
245 for (; aItEx.More(); aItEx.Next()) {
246 const TopoDS_Shape& aE=aItEx.Value();
247 const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE);
248 aItFP.Initialize(aLF);
249 for (; aItFP.More(); aItFP.Next()) {
250 const TopoDS_Shape& aF=aItFP.Value();
251 if (aMFDone.Add(aF)) {
260 // 3 Process faces aLFP1
262 aNbFP=aLFP1.Extent();
263 aItFP.Initialize(aLFP1);
264 for (; aItFP.More(); aItFP.Next()) {
265 const TopoDS_Shape& aSP=aItFP.Value();
266 if (!aMFDone.Add(aSP)) {
271 // first face to process
272 aFP=(*(TopoDS_Face*)(&aSP));
273 bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext);
274 aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
276 // collect faces to process [ aFP is the first ]
279 aItS.Initialize(aLFP1);
280 for (; aItS.More(); aItS.Next()) {
281 const TopoDS_Shape& aSk=aItS.Value();
282 if (!aMFDone.Contains(aSk)) {
287 // Connexity Block that spreads from aFP the Bound
288 // or till the end of the block itself
291 Handle(NCollection_IncAllocator) aAllocator;
292 aAllocator=new NCollection_IncAllocator();
294 BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, aAllocator);
299 // fill states for the Connexity Block
300 aItS.Initialize(aLCBF);
301 for (; aItS.More(); aItS.Next()) {
302 const TopoDS_Shape& aSx=aItS.Value();
304 if (aState==TopAbs_IN) {
309 aNbFPx=aMFDone.Extent();
313 }//for (; aItFP.More(); aItFP.Next())
315 // faces Inside aSolid
317 aNbFIN=aMFIN.Extent();
318 if (aNbFIN || aNbLIF) {
319 for (j=1; j<=aNbFIN; ++j) {
320 const TopoDS_Shape& aFIn=aMFIN(j);
324 aItS.Initialize(aLIF);
325 for (; aItS.More(); aItS.Next()) {
326 const TopoDS_Shape& aFIN=aItS.Value();
330 theInParts.Bind(aSolid, aLFIN);
332 if (aNbFIN || bHasImage) {
333 theDraftSolids.Bind(aSolid, aSolidSp);
335 }//for (i=1; i<=aNbSolids; ++i) {
337 //=======================================================================
338 //function : BuildDraftSolid
340 //=======================================================================
341 void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
342 TopoDS_Shape& theDraftSolid,
343 BOPCol_ListOfShape& theLIF)
347 Standard_Boolean bToReverse;
348 Standard_Integer iFlag;
349 TopAbs_Orientation aOrF, aOrSh, aOrSd;
350 TopoDS_Iterator aIt1, aIt2;
352 TopoDS_Shape aFSDx, aFx;
354 BOPCol_ListIteratorOfListOfShape aItS;
356 aOrSd=theSolid.Orientation();
357 theDraftSolid.Orientation(aOrSd);
359 aIt1.Initialize(theSolid);
360 for (; aIt1.More(); aIt1.Next()) {
361 const TopoDS_Shape& aSh=aIt1.Value();
362 if(aSh.ShapeType()!=TopAbs_SHELL) {
363 continue; // mb internal edges,vertices
366 aOrSh=aSh.Orientation();
368 aShD.Orientation(aOrSh);
371 aIt2.Initialize(aSh);
372 for (; aIt2.More(); aIt2.Next()) {
373 const TopoDS_Shape& aF=aIt2.Value();
374 aOrF=aF.Orientation();
376 if (myImages.IsBound(aF)) {
377 const BOPCol_ListOfShape& aLSp=myImages.Find(aF);
378 aItS.Initialize(aLSp);
379 for (; aItS.More(); aItS.Next()) {
382 if (myShapesSD.IsBound(aFx)) {
383 aFSDx=myShapesSD.Find(aFx);
385 if (aOrF==TopAbs_INTERNAL) {
386 aFSDx.Orientation(aOrF);
387 theLIF.Append(aFSDx);
390 bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aFSDx, aF, myContext);
396 aBB.Add(aShD, aFSDx);
398 }//if (myShapesSD.IsBound(aFx)) {
400 aFx.Orientation(aOrF);
401 if (aOrF==TopAbs_INTERNAL) {
410 } // if (myImages.IsBound(aF)) {
413 if (aOrF==TopAbs_INTERNAL) {
421 } //for (; aIt2.More(); aIt2.Next()) {
424 aBB.Add(theDraftSolid, aShD);
426 } //for (; aIt1.More(); aIt1.Next()) {
428 //=======================================================================
429 //function : BuildSplitSolids
431 //=======================================================================
432 void BOPAlgo_Builder::BuildSplitSolids(BOPCol_DataMapOfShapeListOfShape& theInParts,
433 BOPCol_DataMapOfShapeShape& theDraftSolids,
434 const Handle(NCollection_BaseAllocator)& theAllocator)
438 Standard_Boolean bFlagSD;
439 Standard_Integer i, aNbS, iErr, aNbSFS;
440 TopExp_Explorer aExp;
441 BOPCol_ListIteratorOfListOfShape aIt;
442 BOPCol_DataMapIteratorOfDataMapOfShapeShape aIt1;
444 BOPCol_ListOfShape aSFS(theAllocator), aLSEmpty(theAllocator);
445 BOPCol_MapOfShape aMFence(100, theAllocator);
446 BOPTools_MapOfSet aMST(100, theAllocator);
448 // 0. Find same domain solids for non-interferred solids
449 aNbS=myDS->NbSourceShapes();
450 for (i=0; i<aNbS; ++i) {
451 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
453 if (aSI.ShapeType()!=TopAbs_SOLID) {
457 const TopoDS_Shape& aS=aSI.Shape();
458 if (!aMFence.Add(aS)) {
461 if(theDraftSolids.IsBound(aS)) {
467 aST.Add(aS, TopAbs_FACE);
470 } //for (i=1; i<=aNbS; ++i)
472 // 1. Build solids for interferred source solids
473 for (i=0; i<aNbS; ++i) {
474 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
476 if (aSI.ShapeType()!=TopAbs_SOLID) {
480 const TopoDS_Shape& aS=aSI.Shape();
481 if(!theDraftSolids.IsBound(aS)) {
484 const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
485 const BOPCol_ListOfShape& aLFIN=
486 (theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
488 // 1.1 Fill Shell Faces Set
490 aExp.Init(aSD, TopAbs_FACE);
491 for (; aExp.More(); aExp.Next()) {
492 const TopoDS_Shape& aF=aExp.Current();
496 aIt.Initialize(aLFIN);
497 for (; aIt.More(); aIt.Next()) {
498 TopoDS_Shape aF=aIt.Value();
500 aF.Orientation(TopAbs_FORWARD);
502 aF.Orientation(TopAbs_REVERSED);
506 aNbSFS=aSFS.Extent();
511 // 1.3 Build new solids
512 BOPAlgo_BuilderSolid aSB(theAllocator);
514 //aSB.SetContext(myContext);
517 iErr=aSB.ErrorStatus();
519 myErrorStatus=30; // SolidBuilder failed
523 const BOPCol_ListOfShape& aLSR=aSB.Areas();
525 // 1.4 Collect resulting solids and theirs set of faces.
527 if (!myImages.IsBound(aS)) {
528 BOPCol_ListOfShape aLSx;
530 myImages.Bind(aS, aLSx);
531 BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS);
533 aIt.Initialize(aLSR);
534 for (; aIt.More(); aIt.Next()) {
537 const TopoDS_Shape& aSR=aIt.Value();
538 aST.Add(aSR, TopAbs_FACE);
540 bFlagSD=aMST.Contains(aST);
542 const BOPTools_Set& aSTx=aMST.Added(aST);
543 const TopoDS_Shape& aSx=aSTx.Shape();
547 myShapesSD.Bind(aSR, aSx);
551 } // for (; aIt1.More(); aIt1.Next()) {
554 //=======================================================================
555 //function :FillInternalShapes
557 //=======================================================================
558 void BOPAlgo_Builder::FillInternalShapes()
562 Standard_Integer i, j, aNbS, aNbSI, aNbSx, aNbSd;
563 TopAbs_ShapeEnum aType;
565 TopoDS_Iterator aItS;
567 BOPCol_MapIteratorOfMapOfShape aItM;
568 BOPCol_ListIteratorOfListOfShape aIt, aIt1;
570 Handle(NCollection_IncAllocator) aAllocator;
571 //-----------------------------------------------------scope f
572 aAllocator=new NCollection_IncAllocator();
574 BOPCol_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
575 BOPCol_IndexedMapOfShape aMx(100, aAllocator);
576 BOPCol_MapOfShape aMSI(100, aAllocator);
577 BOPCol_MapOfShape aMFence(100, aAllocator);
578 BOPCol_MapOfShape aMSOr(100, aAllocator);
579 BOPCol_ListOfShape aLSd(aAllocator);
580 BOPCol_ListOfShape aLArgs(aAllocator);
582 // 1. Shapes to process
584 // 1.1 Shapes from pure arguments aMSI
585 // 1.1.1 vertex, edge, wire
587 aIt.Initialize(myArguments);
588 for (; aIt.More(); aIt.Next()) {
589 const TopoDS_Shape& aS=aIt.Value();
590 if (!aMFence.Add(aS)) {
594 aType=aS.ShapeType();
595 if (aType==TopAbs_WIRE) {
597 for(; aItS.More(); aItS.Next()) {
598 const TopoDS_Shape& aE=aItS.Value();
599 if (aMFence.Add(aE)) {
604 else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
610 aIt.Initialize(aLArgs);
611 for (; aIt.More(); aIt.Next()) {
612 const TopoDS_Shape& aS=aIt.Value();
613 aType=aS.ShapeType();
614 if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE ||aType==TopAbs_WIRE) {
615 if (aMFence.Add(aS)) {
616 if (myImages.IsBound(aS)) {
617 const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
618 aIt1.Initialize(aLSp);
619 for (; aIt1.More(); aIt1.Next()) {
620 const TopoDS_Shape& aSp=aIt1.Value();
633 // 2. Internal vertices, edges from source solids
637 aNbS=myDS->NbSourceShapes();
638 for (i=0; i<aNbS; ++i) {
639 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
641 if (aSI.ShapeType()!=TopAbs_SOLID) {
645 const TopoDS_Shape& aS=aSI.Shape();
648 OwnInternalShapes(aS, aMx);
651 for (j=1; j<=aNbSx; ++j) {
652 const TopoDS_Shape& aSi=aMx(j);
653 if (myImages.IsBound(aSi)) {
654 const BOPCol_ListOfShape &aLSp=myImages.Find(aSi);
655 aIt1.Initialize(aLSp);
656 for (; aIt1.More(); aIt1.Next()) {
657 const TopoDS_Shape& aSp=aIt1.Value();
666 // build aux map from splits of solids
667 if (myImages.IsBound(aS)) {
668 const BOPCol_ListOfShape &aLSp=myImages.Find(aS);
669 aIt.Initialize(aLSp);
670 for (; aIt.More(); aIt.Next()) {
671 const TopoDS_Shape& aSp=aIt.Value();
672 if (aMFence.Add(aSp)) {
673 BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
674 BOPTools::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
675 BOPTools::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx);
681 if (aMFence.Add(aS)) {
682 BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
683 BOPTools::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
684 BOPTools::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx);
689 }// for (i=0; i<aNbS; ++i) {
693 // 3. Some shapes of aMSI can be already tied with faces of
695 aItM.Initialize(aMSI);
696 for (; aItM.More(); aItM.Next()) {
697 const TopoDS_Shape& aSI=aItM.Key();
698 if (aMSx.Contains(aSI)) {
699 const BOPCol_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
713 // 5 Settle internal vertices and edges into solids
715 aIt.Initialize(aLSd);
716 for (; aIt.More(); aIt.Next()) {
717 TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
719 aItM.Initialize(aMSI);
720 for (; aItM.More(); aItM.Next()) {
721 TopoDS_Shape aSI=aItM.Key();
722 aSI.Orientation(TopAbs_INTERNAL);
724 aState=BOPTools_AlgoTools::ComputeStateByOnePoint(aSI, aSd, 1.e-11, myContext);
725 if (aState==TopAbs_IN) {
727 if(aMSOr.Contains(aSd)) {
732 aItS.Initialize(aSd);
733 for (; aItS.More(); aItS.Next()) {
734 const TopoDS_Shape& aSh=aItS.Value();
740 if (myImages.IsBound(aSdx)) {
741 BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx);
745 BOPCol_ListOfShape aLS;
747 myImages.Bind(aSd, aLS);
758 } //if (aState==TopAbs_IN) {
759 }// for (; aItM.More(); aItM.Next()) {
760 }//for (; aIt1.More(); aIt1.Next()) {
762 //-----------------------------------------------------scope t
771 //=======================================================================
772 //function : OwnInternalShapes
774 //=======================================================================
775 void OwnInternalShapes(const TopoDS_Shape& theS,
776 BOPCol_IndexedMapOfShape& theMx)
780 aIt.Initialize(theS);
781 for (; aIt.More(); aIt.Next()) {
782 const TopoDS_Shape& aSx=aIt.Value();
783 if (aSx.ShapeType()!=TopAbs_SHELL) {
790 // 30 - SolidBuilder failed
796 BOPCol_ListIteratorOfListOfShape aItx;
798 aBBx.MakeCompound(aCx);
799 aItx.Initialize(aSFS1);
800 for (; aItx.More(); aItx.Next()) {
801 const TopoDS_Shape& aFx=aItx.Value();
804 BRepTools::Write(aCx, "cxso");