1 // Copyright (C) 2007-2008 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: NMTAlgo_Splitter_2.cxx
23 // Created: Mon Feb 9 15:07:51 2004
24 // Author: Igor FEOKTISTOV
25 // <ifv@philipox.nnov.matra-dtv.fr>
27 #include <NMTAlgo_Splitter.ixx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TopoDS_Solid.hxx>
32 #include <TopoDS_Shell.hxx>
33 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Wire.hxx>
36 #include <TopoDS_Iterator.hxx>
39 #include <TopExp_Explorer.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42 #include <TopTools_MapIteratorOfMapOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47 #include <BOPTools_PInterferencePool.hxx>
48 #include <BOPTools_InterferencePool.hxx>
49 #include <BOPTools_CArray1OfEEInterference.hxx>
50 #include <BOPTools_EEInterference.hxx>
51 #include <BOPTools_CArray1OfESInterference.hxx>
52 #include <BOPTools_ESInterference.hxx>
54 #include <NMTDS_ShapesDataStructure.hxx>
55 #include <NMTTools_PaveFiller.hxx>
56 #include <NMTTools_DSFiller.hxx>
57 #include <NMTAlgo_Tools.hxx>
59 //=======================================================================
60 //function : KeepShapesInside
61 //purpose : remove shapes that are outside of S from result
62 //=======================================================================
63 void NMTAlgo_Splitter::KeepShapesInside (const TopoDS_Shape& S)
66 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
67 for (it.Initialize( S ); it.More(); it.Next())
68 KeepShapesInside( it.Value());
72 Standard_Boolean isTool = Standard_False;
73 if (!myImageShape.HasImage( S )) {
74 //isTool = CheckTool( S );
75 //if (!isTool) return;
79 // build map of internal faces
80 TopTools_IndexedMapOfShape MIF;
81 TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
82 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF );
85 myBuilder.MakeCompound(C);
87 TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
90 // leave in the result only those shapes having a face in MIF
91 for (it.Initialize( myShape ); it.More(); it.Next()) {
92 const TopoDS_Shape & aResShape = it.Value();
93 TopExp_Explorer expResF( aResShape, TopAbs_FACE );
94 for (; expResF.More(); expResF.Next()) {
95 if ( MIF.Contains( expResF.Current())) {
96 myBuilder.Add( C, aResShape );
97 if (aResShape.ShapeType() < anInternalShapeType)
98 anInternalShapeType = aResShape.ShapeType();
105 // may be S was not split by internal faces then it is missing
106 // in myShape, add it
108 (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
110 TopTools_IndexedMapOfShape MSF; // map of split faces of S
111 TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
113 // find a shape having all faces in MSF
114 for (it.Initialize( myShape ); it.More(); it.Next()) {
115 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
116 for (; expResF.More(); expResF.Next()) {
117 if (! MSF.Contains( expResF.Current()))
120 if (! expResF.More()) {
121 myBuilder.Add( C, it.Value() );
130 //=======================================================================
131 //function : RemoveShapesInside
132 //purpose : remove shapes that are inside S from result
133 //=======================================================================
134 void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& S)
137 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
139 for (; it.More(); it.Next()) {
140 RemoveShapesInside( it.Value());
145 Standard_Boolean isTool;
146 TopoDS_Shape IntFacesComp;
148 TopTools_IndexedMapOfShape MIF; // map of internal faces
149 TopTools_MapOfShape RFM;
150 TopTools_MapIteratorOfMapOfShape itF;
152 isTool=myToolShapes.Contains(S);
153 //isTool = Standard_False;
154 if (!myImageShape.HasImage( S )) {
158 IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
160 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF);
164 // add to MIF split faces of S
165 const TopoDS_Shape& aSIm=myImageShape.Image(S).First();
166 TopExp::MapShapes(aSIm, TopAbs_FACE, MIF);
168 // leave in the result only those shapes not having all face in MIF
169 myBuilder.MakeCompound(C);
171 // RFM : faces of removed shapes that encounter once
172 it.Initialize(myShape);
173 for (; it.More(); it.Next()) {
174 TopExp_Explorer expResF;
176 const TopoDS_Shape& aSR=it.Value();
178 expResF.Init(aSR, TopAbs_FACE);
179 for (; expResF.More(); expResF.Next()) {
180 const TopoDS_Shape& aFR=expResF.Current();
181 if (!MIF.Contains(aFR)) {
186 if (expResF.More()) {
187 // add shape to result
188 myBuilder.Add(C, aSR);
191 // add faces of a removed shape to RFM
192 for (expResF.ReInit(); expResF.More(); expResF.Next()) {
193 const TopoDS_Shape& aF = expResF.Current();
194 if (!RFM.Remove(aF)) {
199 }// for (; it.More(); it.Next())
204 myBuilder.MakeCompound(aCx);
205 itF.Initialize (RFM);
206 for (; itF.More(); itF.Next()) {
207 const TopoDS_Shape& aF=itF.Key();
208 myBuilder.Add(aCx, aF);
212 // rebuild S, it must remain in the result
213 Standard_Boolean isClosed = Standard_False;
214 switch (S.ShapeType()) {
216 isClosed = Standard_True; break;
218 TopTools_IndexedDataMapOfShapeListOfShape MEF;
219 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
221 for (i=1; isClosed && i<=MEF.Extent(); ++i) {
222 isClosed = ( MEF(i).Extent() != 1 );
227 isClosed = Standard_False;
231 // add to a new shape external faces of removed shapes, ie those in RFM
233 myBuilder.MakeShell(Shell);
234 // exclude redundant internal face with edges encounterd only once
235 TopTools_IndexedDataMapOfShapeListOfShape MEF;
237 itF.Initialize (RFM);
238 for ( ; itF.More(); itF.Next()) {
239 const TopoDS_Shape& aF=itF.Key();
240 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, MEF);
242 // add only faces forming a closed shell
243 for (itF.Reset() ; itF.More(); itF.Next()) {
244 const TopoDS_Shape& aF=itF.Key();
245 TopExp_Explorer expE (aF, TopAbs_EDGE);
246 for (; expE.More(); expE.Next()) {
247 if (MEF.FindFromKey(expE.Current()).Extent() == 1) {
252 myBuilder.Add( Shell, aF);
259 if (S.ShapeType() == TopAbs_SOLID) {
261 myBuilder.MakeSolid( Solid );
262 myBuilder.Add (Solid, Shell);
263 myBuilder.Add (C, Solid);
266 myBuilder.Add (C, Shell);
271 for (; it.More(); it.Next()) {
272 myBuilder.Add (C, it.Value());
280 //modified by NIZNHY-PKV Tue Feb 1 16:02:29 2005 f
281 //=======================================================================
282 //function : Modified
284 //=======================================================================
285 const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S)
288 TopAbs_ShapeEnum aType;
299 FindImage(S, myGenerated);
314 //modified by NIZNHY-PKV Tue Feb 1 16:02:33 2005 t
315 //=======================================================================
316 //function : IsDeleted
318 //=======================================================================
319 Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S)
322 const TopTools_ListOfShape& aL = Modified(S);
323 if(aL.Extent() != 0) return Standard_False;
325 TopTools_MapOfShape aMap;
326 TopExp_Explorer anExp;
328 TopAbs_ShapeEnum aType = S.ShapeType();
330 if(aType == TopAbs_VERTEX ||
331 aType == TopAbs_EDGE ||
332 aType == TopAbs_FACE ) {
334 anExp.Init(myShape, aType);
335 for(; anExp.More(); anExp.Next()) {
336 if(S.IsSame(anExp.Current())) return Standard_False;
341 return Standard_True;
343 //=======================================================================
344 //function : Generated
346 //=======================================================================
347 const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S)
350 TopTools_ListIteratorOfListOfShape it;
351 TopTools_MapOfShape aMap;
352 TopExp_Explorer anExp;
353 Standard_Boolean bCheckVert = Standard_False;
355 if(S.ShapeType() == TopAbs_FACE) {
356 if (mySectionParts.Contains(S)) {
357 it.Initialize(mySectionParts.FindFromKey(S));
358 anExp.Init(myShape, TopAbs_EDGE);
360 for(; anExp.More(); anExp.Next()) {
361 aMap.Add(anExp.Current());
364 for (; it.More(); it.Next()) {
365 if(aMap.Contains(it.Value())) {
366 myGenerated.Append(it.Value());
371 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
372 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
373 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
375 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
376 Standard_Integer anIndex = 0, i;
378 for(i = 1; i <= aNbS; ++i) {
380 const TopoDS_Shape& aS = aDS.Shape(i);
388 if(anIndex == 0) return myGenerated;
389 if(!anIP->HasInterference(anIndex)) return myGenerated;
391 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
392 Standard_Integer aNbI = aESs.Extent();
394 if(aNbI == 0) return myGenerated;
396 for(i = 1; i <= aNbI; ++i) {
398 const BOPTools_ESInterference& aES = aESs(i);
399 Standard_Integer ind1, ind2;
400 aES.Indices(ind1, ind2);
402 if(ind1 == anIndex || ind2 == anIndex) {
404 Standard_Integer aNSI = aES.NewShape();
405 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
406 myGenerated.Append(aDS.Shape(aNSI));
407 bCheckVert = Standard_True;
416 anExp.Init(myShape, TopAbs_VERTEX);
418 for(; anExp.More(); anExp.Next()) {
419 aMap.Add(anExp.Current());
422 it.Initialize(myGenerated);
423 for (; it.More(); it.Next()) {
425 if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
427 if(!aMap.Contains(it.Value())) {
428 myGenerated.Remove(it);
437 if(S.ShapeType() == TopAbs_EDGE) {
439 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
440 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
441 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
443 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
444 Standard_Integer anIndex = 0, i;
446 for(i = 1; i <= aNbS; ++i) {
448 const TopoDS_Shape& aS = aDS.Shape(i);
456 if(anIndex == 0) return myGenerated;
457 if(!anIP->HasInterference(anIndex)) return myGenerated;
459 const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
460 Standard_Integer aNbI = aEEs.Extent();
462 for(i = 1; i <= aNbI; ++i) {
464 const BOPTools_EEInterference& aEE = aEEs(i);
465 Standard_Integer ind1, ind2;
466 aEE.Indices(ind1, ind2);
468 if(ind1 == anIndex || ind2 == anIndex) {
470 Standard_Integer aNSI = aEE.NewShape();
471 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
472 myGenerated.Append(aDS.Shape(aNSI));
473 bCheckVert = Standard_True;
480 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
481 aNbI = aESs.Extent();
483 for(i = 1; i <= aNbI; ++i) {
485 const BOPTools_ESInterference& aES = aESs(i);
486 Standard_Integer ind1, ind2;
487 aES.Indices(ind1, ind2);
489 if(ind1 == anIndex || ind2 == anIndex) {
491 Standard_Integer aNSI = aES.NewShape();
492 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
493 myGenerated.Append(aDS.Shape(aNSI));
494 bCheckVert = Standard_True;
503 anExp.Init(myShape, TopAbs_VERTEX);
505 for(; anExp.More(); anExp.Next()) {
506 aMap.Add(anExp.Current());
509 it.Initialize(myGenerated);
510 for (; it.More(); it.Next()) {
512 if(!aMap.Contains(it.Value())) {
513 myGenerated.Remove(it);
521 //modified by NIZNHY-PKV Tue Feb 1 10:26:18 2005f
522 //=======================================================================
523 //function : FindImage
525 //=======================================================================
526 void NMTAlgo_Splitter::FindImage(const TopoDS_Shape& aS,
527 TopTools_ListOfShape& aLIms)
529 TopAbs_ShapeEnum aType;
531 aType=aS.ShapeType();
533 if (aType==TopAbs_SOLID) {
534 Standard_Boolean bHasImage, bHasInternalFaces;
535 Standard_Integer i, aNbSd;
536 TopTools_IndexedMapOfShape aMSo, aMSd;
538 TopTools_IndexedDataMapOfShapeListOfShape aMFS;
539 TopTools_ListIteratorOfListOfShape aItLS;
541 bHasInternalFaces=myMapSIFC.IsBound(aS);
542 if (bHasInternalFaces){
543 TopExp::MapShapesAndAncestors(myShape, TopAbs_FACE, TopAbs_SOLID, aMFS);
545 const TopoDS_Shape& aIFC=myMapSIFC.Find(aS);
547 aIt.Initialize(aIFC);
548 for (; aIt.More(); aIt.Next()) {
549 const TopoDS_Shape& aIF=aIt.Value();
550 if (aMFS.Contains(aIF)) {
551 const TopTools_ListOfShape& aLS=aMFS.FindFromKey(aIF);
553 aItLS.Initialize(aLS);
554 for (; aItLS.More(); aItLS.Next()) {
555 const TopoDS_Shape& aSx=aItLS.Value();
563 for (i=1; i<=aNbSd; ++i) {
564 const TopoDS_Shape& aSx=aMSd(i);
565 if (!aSx.IsSame(aS)) {
573 bHasImage=myImageShape.HasImage(aS);
580 TopExp::MapShapes(myShape, TopAbs_SOLID, aMSo);
582 const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
583 bHasImage=NMTAlgo_Tools::FindImageSolid(aFC, aMSo, aSd);
585 if (!aSd.IsSame(aS)) {
589 } //if (aType==TopAbs_SOLID) {
591 else if (aType==TopAbs_FACE) {
592 TopTools_MapOfShape aMap;
593 TopTools_ListIteratorOfListOfShape aIt;
594 TopExp_Explorer anExp;
596 if (myModifiedFaces.IsBound(aS)) {
597 anExp.Init(myShape, aType);
598 for(; anExp.More(); anExp.Next()) {
599 aMap.Add(anExp.Current());
602 const TopTools_ListOfShape& aLS=myModifiedFaces.Find(aS);
604 for (; aIt.More(); aIt.Next()) {
605 const TopoDS_Shape& aFx=aIt.Value();
606 if (!aFx.IsSame(aS)) {
607 if (aMap.Contains(aFx)) {
613 } // else if (aType==TopAbs_FACE)
615 else if (aType==TopAbs_EDGE) {
616 TopTools_MapOfShape aMap;
617 TopTools_ListIteratorOfListOfShape aIt;
618 TopExp_Explorer anExp;
620 if (myImagesEdges.HasImage(aS)) {
621 anExp.Init(myShape, aType);
622 for(; anExp.More(); anExp.Next()) {
623 aMap.Add(anExp.Current());
626 const TopTools_ListOfShape& aLE=myImagesEdges.Image(aS);
628 for (; aIt.More(); aIt.Next()) {
629 const TopoDS_Shape& aEx=aIt.Value();
630 if (!aEx.IsSame(aS)) {
631 if(aMap.Contains(aEx)) {
637 }// else if (aType==TopAbs_EDGE)
639 else if (aType==TopAbs_VERTEX) {
640 Standard_Integer aNbS, anIndex, i, aSDVInd;
641 TopExp_Explorer anExp;
643 const NMTTools_DSFiller& aDSF = Filler();
644 const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
645 const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
647 aNbS = aDS.NumberOfSourceShapes();
650 for(i=1; i<=aNbS; ++i) {
651 const TopoDS_Shape& aSx = aDS.Shape(i);
662 aSDVInd=aPF.FindSDVertex(anIndex);
667 const TopoDS_Shape& aSDV=aDS.Shape(aSDVInd);
669 anExp.Init(myShape, aType);
670 for(; anExp.More(); anExp.Next()) {
671 const TopoDS_Shape& aVx=anExp.Current();
672 if(aSDV.IsSame(aVx)) {
677 }// else if (aType==TopAbs_VERTEX)
679 //modified by NIZNHY-PKV Tue Feb 1 10:26:22 2005t