1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMAlgo_Builder_3.cxx
24 // Author : Peter KURNEV
26 #include <GEOMAlgo_Builder.hxx>
28 #include <TopAbs_State.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Solid.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Solid.hxx>
36 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Shell.hxx>
38 #include <TopoDS_Compound.hxx>
41 #include <TopExp_Explorer.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRepTools.hxx>
45 #include <BRepClass3d_SolidClassifier.hxx>
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopTools_IndexedMapOfShape.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
50 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
51 #include <TopTools_IndexedMapOfShape.hxx>
52 #include <TopTools_MapIteratorOfMapOfShape.hxx>
53 #include <TopTools_DataMapOfShapeShape.hxx>
54 #include <TopTools_DataMapOfShapeInteger.hxx>
55 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
56 #include <TopTools_MapOfShape.hxx>
58 #include <IntTools_Context.hxx>
60 #include <NMTDS_ShapesDataStructure.hxx>
61 #include <NMTTools_PaveFiller.hxx>
63 #include <GEOMAlgo_Tools3D.hxx>
64 #include <GEOMAlgo_BuilderSolid.hxx>
65 #include <GEOMAlgo_ShapeSet.hxx>
66 #include <GEOMAlgo_DataMapOfShapeShapeSet.hxx>
67 #include <GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet.hxx>
72 void OwnInternalShapes(const TopoDS_Shape& ,
73 TopTools_IndexedMapOfShape& );
75 //=======================================================================
76 //function : FillImagesSolids
78 //=======================================================================
79 void GEOMAlgo_Builder::FillImagesSolids()
87 //=======================================================================
88 //function : BuildDraftSolid
90 //=======================================================================
91 void GEOMAlgo_Builder::BuildDraftSolid (const TopoDS_Shape& theSolid,
92 TopoDS_Shape& theDraftSolid,
93 TopTools_ListOfShape& theLIF)
97 NMTTools_PaveFiller* pPF=myPaveFiller;
98 const Handle(IntTools_Context)& aCtx= pPF->Context();
100 Standard_Boolean bToReverse;
101 Standard_Integer iFlag;
102 TopAbs_Orientation aOrF, aOrSh, aOrSd;
103 TopoDS_Iterator aIt1, aIt2;
104 TopTools_ListIteratorOfListOfShape aItS;
107 TopoDS_Shape aFSDx, aFx;
109 aOrSd=theSolid.Orientation();
110 theDraftSolid.Orientation(aOrSd);
112 aIt1.Initialize(theSolid);
113 for (; aIt1.More(); aIt1.Next()) {
114 const TopoDS_Shape& aSh=aIt1.Value();
115 if(aSh.ShapeType()!=TopAbs_SHELL) {
116 continue; // mb internal edges,vertices
119 aOrSh=aSh.Orientation();
121 aShD.Orientation(aOrSh);
124 aIt2.Initialize(aSh);
125 for (; aIt2.More(); aIt2.Next()) {
126 const TopoDS_Shape& aF=aIt2.Value();
127 aOrF=aF.Orientation();
129 if (myImages.HasImage(aF)) {
130 const TopTools_ListOfShape& aLSp=myImages.Image(aF);
131 aItS.Initialize(aLSp);
132 for (; aItS.More(); aItS.Next()) {
135 if (mySameDomainShapes.Contains(aFx)) {
136 aFSDx=mySameDomainShapes.FindFromKey(aFx);
138 if (aOrF==TopAbs_INTERNAL) {
139 aFSDx.Orientation(aOrF);
140 theLIF.Append(aFSDx);
143 bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFSDx, aF, aCtx);
149 aBB.Add(aShD, aFSDx);
151 }// if (mySameDomainShapes.Contains(aFx)) {
153 aFx.Orientation(aOrF);
154 if (aOrF==TopAbs_INTERNAL) {
163 } //if (myImages.HasImage(aF)) {
166 if (aOrF==TopAbs_INTERNAL) {
174 } //for (; aIt2.More(); aIt2.Next()) {
177 aBB.Add(theDraftSolid, aShD);
179 } //for (; aIt1.More(); aIt1.Next()) {
181 //=======================================================================
182 //function : FillIn3DParts
184 //=======================================================================
185 void GEOMAlgo_Builder::FillIn3DParts()
189 const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
190 NMTTools_PaveFiller* pPF=myPaveFiller;
191 const Handle(IntTools_Context)& aCtx= pPF->Context();
193 Standard_Boolean bIsIN, bHasImage;
194 Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF;
195 TopAbs_ShapeEnum aType;
197 TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN;
198 TopTools_MapOfShape aMFDone;
199 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
200 TopTools_ListIteratorOfListOfShape aItS;
201 TopoDS_Iterator aIt, aItF;
203 TopoDS_Solid aSolidSp;
206 myDraftSolids.Clear();
208 aNbS=aDS.NumberOfShapesOfTheObject();
209 for (i=1; i<=aNbS; ++i) {
210 const TopoDS_Shape& aS=aDS.Shape(i);
212 aType=aS.ShapeType();
213 if (aType==TopAbs_SOLID) {
214 // all solids from DS
217 else if (aType==TopAbs_FACE) {
218 // all faces (originals from DS or theirs images)
219 if (myImages.HasImage(aS)) {
220 const TopTools_ListOfShape& aLS=myImages.Image(aS);
221 aItS.Initialize(aLS);
222 for (; aItS.More(); aItS.Next()) {
223 const TopoDS_Shape& aFx=aItS.Value();
225 if (mySameDomainShapes.Contains(aFx)) {
226 const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx);
235 if (mySameDomainShapes.Contains(aS)) {
236 const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS);
246 aNbFaces=aMFaces.Extent();
247 aNbSolids=aMSolids.Extent();
249 for (i=1; i<=aNbSolids; ++i) {
250 const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i));
255 aBB.MakeSolid(aSolidSp);
257 TopTools_ListOfShape aLIF;
259 BuildDraftSolid(aSolid, aSolidSp, aLIF);
260 aNbLIF=aLIF.Extent();
262 // 1 all faces/edges from aSolid [ aMS ]
263 bHasImage=Standard_False;
265 aIt.Initialize(aSolid);
266 for (; aIt.More(); aIt.Next()) {
267 const TopoDS_Shape& aShell=aIt.Value();
269 if (myImages.HasImage(aShell)) {
270 bHasImage=Standard_True;
272 const TopTools_ListOfShape& aLS=myImages.Image(aShell);
273 aItS.Initialize(aLS);
274 for (; aItS.More(); aItS.Next()) {
275 const TopoDS_Shape& aSx=aItS.Value();
277 TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
278 TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
279 TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
284 TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
285 //modified by NIZNHY-PKV Fri Dec 03 11:18:45 2010f
286 TopExp::MapShapes(aShell, TopAbs_EDGE, aMS);
287 //modified by NIZNHY-PKV Fri Dec 03 11:18:51 2010t
288 TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
292 // 2 all faces that are not from aSolid [ aLFP1 ]
293 Standard_Integer aNbEFP;
294 TopTools_IndexedDataMapOfShapeListOfShape aMEFP;
295 TopTools_ListIteratorOfListOfShape aItFP, aItEx;
296 TopTools_MapOfShape aMFence;
297 TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP,
299 // for all non-solid faces build EF map [ aMEFP ]
300 for (j=1; j<=aNbFaces; ++j) {
301 const TopoDS_Shape& aFace=aMFaces(j);
302 if (!aMS.Contains(aFace)) {
303 TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
307 // among all faces from aMEFP select these that have same edges
308 // with the solid (i.e aMEF). These faces will be treated first
309 // to prevent the usage of 3D classifier.
310 // The full list of faces to process is aLFP1.
311 aNbEFP=aMEFP.Extent();
312 for (j=1; j<=aNbEFP; ++j) {
313 const TopoDS_Shape& aE=aMEFP.FindKey(j);
315 if (aMEF.Contains(aE)) { // !!
316 const TopTools_ListOfShape& aLF=aMEFP(j);
317 aItFP.Initialize(aLF);
318 for (; aItFP.More(); aItFP.Next()) {
319 const TopoDS_Shape& aF=aItFP.Value();
320 if (aMFence.Add(aF)) {
330 aItEx.Initialize(aLEx);
331 for (; aItEx.More(); aItEx.Next()) {
332 const TopoDS_Shape& aE=aItEx.Value();
333 const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
334 aItFP.Initialize(aLF);
335 for (; aItFP.More(); aItFP.Next()) {
336 const TopoDS_Shape& aF=aItFP.Value();
337 if (aMFence.Add(aF)) {
345 // 3 Process faces aLFP1
346 aNbFP=aLFP1.Extent();
347 aItFP.Initialize(aLFP1);
348 for (; aItFP.More(); aItFP.Next()) {
349 const TopoDS_Shape& aSP=aItFP.Value();
350 if (!aMFDone.Add(aSP)) {
355 // first face to process
356 aFP=TopoDS::Face(aSP);
357 bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx);
358 aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
360 // collect faces to process [ aFP is the first ]
363 aItS.Initialize(aLFP1);
364 for (; aItS.More(); aItS.Next()) {
365 const TopoDS_Shape& aSk=aItS.Value();
366 if (!aMFDone.Contains(aSk)) {
371 // Connexity Block that spreads from aFP the Bound
372 // or till the end of the block itself
374 GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF);
376 // fill states for the Connexity Block
377 aItS.Initialize(aLCBF);
378 for (; aItS.More(); aItS.Next()) {
379 const TopoDS_Shape& aSx=aItS.Value();
381 if (aState==TopAbs_IN) {
386 aNbFPx=aMFDone.Extent();
390 }//for (; aItFP.More(); aItFP.Next())
392 // faces Inside aSolid
394 aNbFIN=aMFIN.Extent();
395 if (aNbFIN || aNbLIF) {
396 for (j=1; j<=aNbFIN; ++j) {
397 const TopoDS_Shape& aFIN=aMFIN(j);
401 aItS.Initialize(aLIF);
402 for (; aItS.More(); aItS.Next()) {
403 const TopoDS_Shape& aFIN=aItS.Value();
407 myInParts.Add(aSolid, aLFIN);
409 if (aNbFIN || bHasImage) {
410 myDraftSolids.Add(aSolid, aSolidSp);
412 }//for (i=1; i<=aNbSolids; ++i) { // next solid
414 //=======================================================================
415 //function : BuildSplitSolids
417 //=======================================================================
418 void GEOMAlgo_Builder::BuildSplitSolids()
422 const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
423 NMTTools_PaveFiller* pPF=myPaveFiller;
424 const Handle(IntTools_Context)& aCtx= pPF->Context();
426 Standard_Integer i, aNbS, iErr;
427 TopExp_Explorer aExp;
428 TopTools_ListOfShape aSFS, aLSEmpty;
429 TopTools_MapOfShape aMFence;
430 TopTools_ListIteratorOfListOfShape aIt;
431 GEOMAlgo_BuilderSolid aSB;
432 GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet aItSS;
433 GEOMAlgo_DataMapOfShapeShapeSet aMSS;
434 GEOMAlgo_ShapeSet aSSi;
436 // 0. Find same domain solids for non-interferred solids
437 aNbS=aDS.NumberOfShapesOfTheObject();
438 for (i=1; i<=aNbS; ++i) {
439 const TopoDS_Shape& aS=aDS.Shape(i);
440 if (aS.ShapeType()!=TopAbs_SOLID) {
443 if (!aMFence.Add(aS)) {
446 if(myDraftSolids.Contains(aS)) {
451 aSSi.Add(aS, TopAbs_FACE);
454 } //for (i=1; i<=aNbS; ++i)
456 // 1. Build solids for interferred source solids
457 aSB.SetContext(aCtx);
458 aSB.ComputeInternalShapes(myComputeInternalShapes);
459 aNbS=myDraftSolids.Extent();
460 for (i=1; i<=aNbS; ++i) {
461 const TopoDS_Shape& aS =myDraftSolids.FindKey(i);
462 const TopoDS_Shape& aSD=myDraftSolids.FindFromIndex(i);
463 const TopTools_ListOfShape& aLFIN=
464 (myInParts.Contains(aS)) ? myInParts.FindFromKey(aS) : aLSEmpty;
466 // 1.1 Fill Shell Faces Set
469 aExp.Init(aSD, TopAbs_FACE);
470 for (; aExp.More(); aExp.Next()) {
471 const TopoDS_Shape& aF=aExp.Current();
475 aIt.Initialize(aLFIN);
476 for (; aIt.More(); aIt.Next()) {
477 TopoDS_Shape aF=aIt.Value();
479 aF.Orientation(TopAbs_FORWARD);
481 aF.Orientation(TopAbs_REVERSED);
485 Standard_Integer aNbSFS;
486 aNbSFS=aSFS.Extent();
489 // Check whether aSFS contains a subsets of faces
490 // of solids that have been already built.
491 // If yes, shrink aSFS by these subsets.
495 aItSS.Initialize(aMSS);
496 for (; aItSS.More(); aItSS.Next()) {
497 const TopoDS_Shape& aSR=aItSS.Key();
498 const GEOMAlgo_ShapeSet& aSSR=aItSS.Value();
499 if (aSSi.Contains(aSSR)) {
500 // the aSR is SD solid for aS
503 if(myImages.HasImage(aS)) {
504 myImages.Add(aS, aSR);
507 myImages.Bind(aS, aSR);
511 mySameDomainShapes.Add(aSR, aSR);
514 const TopTools_ListOfShape& aSFS1=aSSi.GetSet();
515 aNbSFS=aSFS1.Extent();
516 //modified by NIZNHY-PKV Wed Oct 27 09:53:15 2010f
520 //modified by NIZNHY-PKV Wed Oct 27 09:53:18 2010t
522 // 1.3 Build new solids
523 aSB.SetContext(aCtx);
524 aSB.SetShapes(aSFS1);
526 iErr=aSB.ErrorStatus();
528 myErrorStatus=30; // SolidBuilder failed
532 const TopTools_ListOfShape& aLSR=aSB.Areas();
534 // 1.4 Collect resulting solids and theirs set of faces
535 aIt.Initialize(aLSR);
536 for (; aIt.More(); aIt.Next()) {
537 const TopoDS_Shape& aSR=aIt.Value();
540 aExp.Init(aSR, TopAbs_FACE);
541 for (; aExp.More(); aExp.Next()) {
542 const TopoDS_Shape& aF=aExp.Current();
545 aMSS.Bind(aSR, aSSi);
549 if (myImages.HasImage(aS)) {
550 myImages.Add(aS, aLSR);
553 myImages.Bind(aS, aLSR);
555 } // for (i=1; i<=aNbS; ++i) {
557 //=======================================================================
558 //function :FillInternalShapes
560 //=======================================================================
561 void GEOMAlgo_Builder::FillInternalShapes()
565 const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
566 NMTTools_PaveFiller* pPF=myPaveFiller;
567 const Handle(IntTools_Context)& aCtx= pPF->Context();
569 //Standard_Boolean bHasImage;
570 Standard_Integer i, j, jT, aNbS, aNbSI, aNbSx, aNbSd;
571 TopAbs_ShapeEnum aType, aT[]={ TopAbs_VERTEX, TopAbs_EDGE };
573 TopTools_ListIteratorOfListOfShape aIt, aIt1;
574 TopTools_IndexedDataMapOfShapeListOfShape aMSx;
575 TopTools_IndexedMapOfShape aMx;
576 TopTools_MapOfShape aMSI, aMFence, aMSOr;
577 TopTools_MapIteratorOfMapOfShape aItM;
578 TopTools_ListOfShape aLSI, aLSd;
579 TopoDS_Iterator aItS;
582 // 1. Shapes to process
584 // 1.1 Shapes from pure arguments aMSI
585 // 1.1.1 vertex, edge
586 for (i=0; i<2; ++i) {
587 jT=(Standard_Integer)aT[i];
588 const TopTools_ListOfShape &aLS=myShapes1[jT];
590 for (; aIt.More(); aIt.Next()) {
591 const TopoDS_Shape& aS=aIt.Value();
592 if (aMFence.Add(aS)) {
599 jT=(Standard_Integer)TopAbs_WIRE;
600 const TopTools_ListOfShape &aLW=myShapes1[jT];
602 for (; aIt.More(); aIt.Next()) {
603 const TopoDS_Shape& aW=aIt.Value();
605 for (; aItS.More(); aItS.Next()) {
606 const TopoDS_Shape& aE=aItS.Value();
607 if (aMFence.Add(aE)) {
613 // 1.1.3 theirs images/sources
614 aIt1.Initialize(aLSI);
615 for (; aIt1.More(); aIt1.Next()) {
616 const TopoDS_Shape& aS=aIt1.Value();
617 if (myImages.HasImage(aS)) {
618 const TopTools_ListOfShape &aLSp=myImages.Image(aS);
619 aIt.Initialize(aLSp);
620 for (; aIt.More(); aIt.Next()) {
621 const TopoDS_Shape& aSI=aIt.Value();
632 // 2. Internal vertices, edges from source solids
636 aNbS=aDS.NumberOfShapesOfTheObject();
637 for (i=1; i<=aNbS; ++i) {
638 const TopoDS_Shape& aS=aDS.Shape(i);
639 aType=aS.ShapeType();
640 if (aType==TopAbs_SOLID) {
643 OwnInternalShapes(aS, aMx);
646 for (j=1; j<=aNbSx; ++j) {
647 const TopoDS_Shape& aSI=aMx(j);
648 if (myImages.HasImage(aSI)) {
649 const TopTools_ListOfShape &aLSp=myImages.Image(aSI);
650 aIt.Initialize(aLSp);
651 for (; aIt.More(); aIt.Next()) {
652 const TopoDS_Shape& aSp=aIt.Value();
661 // build aux map from splits of solids
662 if (myImages.HasImage(aS)) {
663 const TopTools_ListOfShape &aLSp=myImages.Image(aS);
664 aIt.Initialize(aLSp);
665 for (; aIt.More(); aIt.Next()) {
666 const TopoDS_Shape& aSp=aIt.Value();
667 if (aMFence.Add(aSp)) {
668 TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
669 TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
670 TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx);
676 if (aMFence.Add(aS)) {
677 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
678 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
679 TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx);
684 }//if (aType==TopAbs_SOLID)
689 // 3. Some shapes of aMSI can be already tied with faces of
691 aItM.Initialize(aMSI);
692 for (; aItM.More(); aItM.Next()) {
693 const TopoDS_Shape& aSI=aItM.Key();
694 if (aMSx.Contains(aSI)) {
695 const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
709 // 5 Settle internal vertices and edges into solids
711 aIt.Initialize(aLSd);
712 for (; aIt.More(); aIt.Next()) {
713 TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
715 aItM.Initialize(aMSI);
716 for (; aItM.More(); aItM.Next()) {
717 TopoDS_Shape aSI=aItM.Key();
718 aSI.Orientation(TopAbs_INTERNAL);
720 aState=GEOMAlgo_Tools3D::ComputeStateByOnePoint(aSI, aSd, 1.e-11, aCtx);
721 if (aState==TopAbs_IN) {
723 if(aMSOr.Contains(aSd)) {
728 aItS.Initialize(aSd);
729 for (; aItS.More(); aItS.Next()) {
730 const TopoDS_Shape& aSh=aItS.Value();
736 myImages.Bind(aSd, aSdx);
745 } //if (aState==TopAbs_IN) {
746 }// for (; aItM.More(); aItM.Next()) {
747 }//for (; aIt1.More(); aIt1.Next()) {
749 //=======================================================================
750 //function : OwnInternalShapes
752 //=======================================================================
753 void OwnInternalShapes(const TopoDS_Shape& theS,
754 TopTools_IndexedMapOfShape& theMx)
758 aIt.Initialize(theS);
759 for (; aIt.More(); aIt.Next()) {
760 const TopoDS_Shape& aSx=aIt.Value();
761 if (aSx.ShapeType()!=TopAbs_SHELL) {
768 // 30 - SolidBuilder failed