1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: NMTAlgo_Splitter_2.cxx
21 // Created: Mon Feb 9 15:07:51 2004
22 // Author: Igor FEOKTISTOV
23 // <ifv@philipox.nnov.matra-dtv.fr>
26 #include <NMTAlgo_Splitter.ixx>
28 #include <TopoDS_Shape.hxx>
29 #include <TopoDS_Compound.hxx>
30 #include <TopoDS_Solid.hxx>
31 #include <TopoDS_Shell.hxx>
32 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Wire.hxx>
35 #include <TopoDS_Iterator.hxx>
38 #include <TopExp_Explorer.hxx>
40 #include <TopTools_IndexedMapOfShape.hxx>
41 #include <TopTools_MapIteratorOfMapOfShape.hxx>
42 #include <TopTools_ListOfShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46 #include <BOPTools_PInterferencePool.hxx>
47 #include <BOPTools_InterferencePool.hxx>
48 #include <BOPTools_CArray1OfEEInterference.hxx>
49 #include <BOPTools_EEInterference.hxx>
50 #include <BOPTools_CArray1OfESInterference.hxx>
51 #include <BOPTools_ESInterference.hxx>
53 #include <NMTDS_ShapesDataStructure.hxx>
54 #include <NMTTools_PaveFiller.hxx>
55 #include <NMTTools_DSFiller.hxx>
56 #include <NMTAlgo_Tools.hxx>
58 //=======================================================================
59 //function : KeepShapesInside
60 //purpose : remove shapes that are outside of S from result
61 //=======================================================================
62 void NMTAlgo_Splitter::KeepShapesInside (const TopoDS_Shape& S)
65 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
66 for (it.Initialize( S ); it.More(); it.Next())
67 KeepShapesInside( it.Value());
71 Standard_Boolean isTool = Standard_False;
72 if (!myImageShape.HasImage( S )) {
73 //isTool = CheckTool( S );
74 //if (!isTool) return;
78 // build map of internal faces
79 TopTools_IndexedMapOfShape MIF;
80 TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
81 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF );
84 myBuilder.MakeCompound(C);
86 TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
89 // leave in the result only those shapes having a face in MIF
90 for (it.Initialize( myShape ); it.More(); it.Next()) {
91 const TopoDS_Shape & aResShape = it.Value();
92 TopExp_Explorer expResF( aResShape, TopAbs_FACE );
93 for (; expResF.More(); expResF.Next()) {
94 if ( MIF.Contains( expResF.Current())) {
95 myBuilder.Add( C, aResShape );
96 if (aResShape.ShapeType() < anInternalShapeType)
97 anInternalShapeType = aResShape.ShapeType();
104 // may be S was not split by internal faces then it is missing
105 // in myShape, add it
107 (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
109 TopTools_IndexedMapOfShape MSF; // map of split faces of S
110 TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
112 // find a shape having all faces in MSF
113 for (it.Initialize( myShape ); it.More(); it.Next()) {
114 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
115 for (; expResF.More(); expResF.Next()) {
116 if (! MSF.Contains( expResF.Current()))
119 if (! expResF.More()) {
120 myBuilder.Add( C, it.Value() );
129 //=======================================================================
130 //function : RemoveShapesInside
131 //purpose : remove shapes that are inside S from result
132 //=======================================================================
133 void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& S)
136 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
138 for (; it.More(); it.Next()) {
139 RemoveShapesInside( it.Value());
144 Standard_Boolean isTool;
145 TopoDS_Shape IntFacesComp;
147 TopTools_IndexedMapOfShape MIF; // map of internal faces
148 TopTools_MapOfShape RFM;
149 TopTools_MapIteratorOfMapOfShape itF;
151 isTool=myToolShapes.Contains(S);
152 //isTool = Standard_False;
153 if (!myImageShape.HasImage( S )) {
157 IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
159 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF);
163 // add to MIF split faces of S
164 const TopoDS_Shape& aSIm=myImageShape.Image(S).First();
165 TopExp::MapShapes(aSIm, TopAbs_FACE, MIF);
167 // leave in the result only those shapes not having all face in MIF
168 myBuilder.MakeCompound(C);
170 // RFM : faces of removed shapes that encounter once
171 it.Initialize(myShape);
172 for (; it.More(); it.Next()) {
173 TopExp_Explorer expResF;
175 const TopoDS_Shape& aSR=it.Value();
177 expResF.Init(aSR, TopAbs_FACE);
178 for (; expResF.More(); expResF.Next()) {
179 const TopoDS_Shape& aFR=expResF.Current();
180 if (!MIF.Contains(aFR)) {
185 if (expResF.More()) {
186 // add shape to result
187 myBuilder.Add(C, aSR);
190 // add faces of a removed shape to RFM
191 for (expResF.ReInit(); expResF.More(); expResF.Next()) {
192 const TopoDS_Shape& aF = expResF.Current();
193 if (!RFM.Remove(aF)) {
198 }// for (; it.More(); it.Next())
203 myBuilder.MakeCompound(aCx);
204 itF.Initialize (RFM);
205 for (; itF.More(); itF.Next()) {
206 const TopoDS_Shape& aF=itF.Key();
207 myBuilder.Add(aCx, aF);
211 // rebuild S, it must remain in the result
212 Standard_Boolean isClosed = Standard_False;
213 switch (S.ShapeType()) {
215 isClosed = Standard_True; break;
217 TopTools_IndexedDataMapOfShapeListOfShape MEF;
218 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
220 for (i=1; isClosed && i<=MEF.Extent(); ++i) {
221 isClosed = ( MEF(i).Extent() != 1 );
226 isClosed = Standard_False;
230 // add to a new shape external faces of removed shapes, ie those in RFM
232 myBuilder.MakeShell(Shell);
233 // exclude redundant internal face with edges encounterd only once
234 TopTools_IndexedDataMapOfShapeListOfShape MEF;
236 itF.Initialize (RFM);
237 for ( ; itF.More(); itF.Next()) {
238 const TopoDS_Shape& aF=itF.Key();
239 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, MEF);
241 // add only faces forming a closed shell
242 for (itF.Reset() ; itF.More(); itF.Next()) {
243 const TopoDS_Shape& aF=itF.Key();
244 TopExp_Explorer expE (aF, TopAbs_EDGE);
245 for (; expE.More(); expE.Next()) {
246 if (MEF.FindFromKey(expE.Current()).Extent() == 1) {
251 myBuilder.Add( Shell, aF);
258 if (S.ShapeType() == TopAbs_SOLID) {
260 myBuilder.MakeSolid( Solid );
261 myBuilder.Add (Solid, Shell);
262 myBuilder.Add (C, Solid);
265 myBuilder.Add (C, Shell);
270 for (; it.More(); it.Next()) {
271 myBuilder.Add (C, it.Value());
279 //modified by NIZNHY-PKV Tue Feb 1 16:02:29 2005 f
280 //=======================================================================
281 //function : Modified
283 //=======================================================================
284 const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S)
287 TopAbs_ShapeEnum aType;
298 FindImage(S, myGenerated);
313 //modified by NIZNHY-PKV Tue Feb 1 16:02:33 2005 t
314 //=======================================================================
315 //function : IsDeleted
317 //=======================================================================
318 Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S)
321 const TopTools_ListOfShape& aL = Modified(S);
322 if(aL.Extent() != 0) return Standard_False;
324 TopTools_MapOfShape aMap;
325 TopExp_Explorer anExp;
327 TopAbs_ShapeEnum aType = S.ShapeType();
329 if(aType == TopAbs_VERTEX ||
330 aType == TopAbs_EDGE ||
331 aType == TopAbs_FACE ) {
333 anExp.Init(myShape, aType);
334 for(; anExp.More(); anExp.Next()) {
335 if(S.IsSame(anExp.Current())) return Standard_False;
340 return Standard_True;
342 //=======================================================================
343 //function : Generated
345 //=======================================================================
346 const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S)
349 TopTools_ListIteratorOfListOfShape it;
350 TopTools_MapOfShape aMap;
351 TopExp_Explorer anExp;
352 Standard_Boolean bCheckVert = Standard_False;
354 if(S.ShapeType() == TopAbs_FACE) {
355 if (mySectionParts.Contains(S)) {
356 it.Initialize(mySectionParts.FindFromKey(S));
357 anExp.Init(myShape, TopAbs_EDGE);
359 for(; anExp.More(); anExp.Next()) {
360 aMap.Add(anExp.Current());
363 for (; it.More(); it.Next()) {
364 if(aMap.Contains(it.Value())) {
365 myGenerated.Append(it.Value());
370 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
371 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
372 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
374 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
375 Standard_Integer anIndex = 0, i;
377 for(i = 1; i <= aNbS; ++i) {
379 const TopoDS_Shape& aS = aDS.Shape(i);
387 if(anIndex == 0) return myGenerated;
388 if(!anIP->HasInterference(anIndex)) return myGenerated;
390 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
391 Standard_Integer aNbI = aESs.Extent();
393 if(aNbI == 0) return myGenerated;
395 for(i = 1; i <= aNbI; ++i) {
397 const BOPTools_ESInterference& aES = aESs(i);
398 Standard_Integer ind1, ind2;
399 aES.Indices(ind1, ind2);
401 if(ind1 == anIndex || ind2 == anIndex) {
403 Standard_Integer aNSI = aES.NewShape();
404 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
405 myGenerated.Append(aDS.Shape(aNSI));
406 bCheckVert = Standard_True;
415 anExp.Init(myShape, TopAbs_VERTEX);
417 for(; anExp.More(); anExp.Next()) {
418 aMap.Add(anExp.Current());
421 it.Initialize(myGenerated);
422 for (; it.More(); it.Next()) {
424 if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
426 if(!aMap.Contains(it.Value())) {
427 myGenerated.Remove(it);
436 if(S.ShapeType() == TopAbs_EDGE) {
438 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
439 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
440 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
442 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
443 Standard_Integer anIndex = 0, i;
445 for(i = 1; i <= aNbS; ++i) {
447 const TopoDS_Shape& aS = aDS.Shape(i);
455 if(anIndex == 0) return myGenerated;
456 if(!anIP->HasInterference(anIndex)) return myGenerated;
458 const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
459 Standard_Integer aNbI = aEEs.Extent();
461 for(i = 1; i <= aNbI; ++i) {
463 const BOPTools_EEInterference& aEE = aEEs(i);
464 Standard_Integer ind1, ind2;
465 aEE.Indices(ind1, ind2);
467 if(ind1 == anIndex || ind2 == anIndex) {
469 Standard_Integer aNSI = aEE.NewShape();
470 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
471 myGenerated.Append(aDS.Shape(aNSI));
472 bCheckVert = Standard_True;
479 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
480 aNbI = aESs.Extent();
482 for(i = 1; i <= aNbI; ++i) {
484 const BOPTools_ESInterference& aES = aESs(i);
485 Standard_Integer ind1, ind2;
486 aES.Indices(ind1, ind2);
488 if(ind1 == anIndex || ind2 == anIndex) {
490 Standard_Integer aNSI = aES.NewShape();
491 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
492 myGenerated.Append(aDS.Shape(aNSI));
493 bCheckVert = Standard_True;
502 anExp.Init(myShape, TopAbs_VERTEX);
504 for(; anExp.More(); anExp.Next()) {
505 aMap.Add(anExp.Current());
508 it.Initialize(myGenerated);
509 for (; it.More(); it.Next()) {
511 if(!aMap.Contains(it.Value())) {
512 myGenerated.Remove(it);
520 //modified by NIZNHY-PKV Tue Feb 1 10:26:18 2005f
521 //=======================================================================
522 //function : FindImage
524 //=======================================================================
525 void NMTAlgo_Splitter::FindImage(const TopoDS_Shape& aS,
526 TopTools_ListOfShape& aLIms)
528 TopAbs_ShapeEnum aType;
530 aType=aS.ShapeType();
532 if (aType==TopAbs_SOLID) {
533 Standard_Boolean bHasImage, bHasInternalFaces;
534 Standard_Integer i, aNbSd;
535 TopTools_IndexedMapOfShape aMSo, aMSd;
537 TopTools_IndexedDataMapOfShapeListOfShape aMFS;
538 TopTools_ListIteratorOfListOfShape aItLS;
540 bHasInternalFaces=myMapSIFC.IsBound(aS);
541 if (bHasInternalFaces){
542 TopExp::MapShapesAndAncestors(myShape, TopAbs_FACE, TopAbs_SOLID, aMFS);
544 const TopoDS_Shape& aIFC=myMapSIFC.Find(aS);
546 aIt.Initialize(aIFC);
547 for (; aIt.More(); aIt.Next()) {
548 const TopoDS_Shape& aIF=aIt.Value();
549 if (aMFS.Contains(aIF)) {
550 const TopTools_ListOfShape& aLS=aMFS.FindFromKey(aIF);
552 aItLS.Initialize(aLS);
553 for (; aItLS.More(); aItLS.Next()) {
554 const TopoDS_Shape& aSx=aItLS.Value();
562 for (i=1; i<=aNbSd; ++i) {
563 const TopoDS_Shape& aSx=aMSd(i);
564 if (!aSx.IsSame(aS)) {
572 bHasImage=myImageShape.HasImage(aS);
579 TopExp::MapShapes(myShape, TopAbs_SOLID, aMSo);
581 const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
582 bHasImage=NMTAlgo_Tools::FindImageSolid(aFC, aMSo, aSd);
584 if (!aSd.IsSame(aS)) {
588 } //if (aType==TopAbs_SOLID) {
590 else if (aType==TopAbs_FACE) {
591 TopTools_MapOfShape aMap;
592 TopTools_ListIteratorOfListOfShape aIt;
593 TopExp_Explorer anExp;
595 if (myModifiedFaces.IsBound(aS)) {
596 anExp.Init(myShape, aType);
597 for(; anExp.More(); anExp.Next()) {
598 aMap.Add(anExp.Current());
601 const TopTools_ListOfShape& aLS=myModifiedFaces.Find(aS);
603 for (; aIt.More(); aIt.Next()) {
604 const TopoDS_Shape& aFx=aIt.Value();
605 if (!aFx.IsSame(aS)) {
606 if (aMap.Contains(aFx)) {
612 } // else if (aType==TopAbs_FACE)
614 else if (aType==TopAbs_EDGE) {
615 TopTools_MapOfShape aMap;
616 TopTools_ListIteratorOfListOfShape aIt;
617 TopExp_Explorer anExp;
619 if (myImagesEdges.HasImage(aS)) {
620 anExp.Init(myShape, aType);
621 for(; anExp.More(); anExp.Next()) {
622 aMap.Add(anExp.Current());
625 const TopTools_ListOfShape& aLE=myImagesEdges.Image(aS);
627 for (; aIt.More(); aIt.Next()) {
628 const TopoDS_Shape& aEx=aIt.Value();
629 if (!aEx.IsSame(aS)) {
630 if(aMap.Contains(aEx)) {
636 }// else if (aType==TopAbs_EDGE)
638 else if (aType==TopAbs_VERTEX) {
639 Standard_Integer aNbS, anIndex, i, aSDVInd;
640 TopExp_Explorer anExp;
642 const NMTTools_DSFiller& aDSF = Filler();
643 const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
644 const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
646 aNbS = aDS.NumberOfSourceShapes();
649 for(i=1; i<=aNbS; ++i) {
650 const TopoDS_Shape& aSx = aDS.Shape(i);
661 aSDVInd=aPF.FindSDVertex(anIndex);
666 const TopoDS_Shape& aSDV=aDS.Shape(aSDVInd);
668 anExp.Init(myShape, aType);
669 for(; anExp.More(); anExp.Next()) {
670 const TopoDS_Shape& aVx=anExp.Current();
671 if(aSDV.IsSame(aVx)) {
676 }// else if (aType==TopAbs_VERTEX)
678 //modified by NIZNHY-PKV Tue Feb 1 10:26:22 2005t