1 // File: NMTAlgo_Splitter_2.cxx
2 // Created: Mon Feb 9 15:07:51 2004
3 // Author: Igor FEOKTISTOV
4 // <ifv@philipox.nnov.matra-dtv.fr>
7 #include <NMTAlgo_Splitter.ixx>
8 #include <TopoDS_Iterator.hxx>
9 #include <TopTools_IndexedMapOfShape.hxx>
10 #include <TopoDS_Shape.hxx>
12 #include <TopoDS_Compound.hxx>
13 #include <TopExp_Explorer.hxx>
14 #include <TopoDS_Solid.hxx>
15 #include <TopoDS_Shell.hxx>
16 #include <TopTools_MapIteratorOfMapOfShape.hxx>
17 #include <TopoDS_Face.hxx>
19 #include <TopoDS_Wire.hxx>
20 #include <TopTools_ListOfShape.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
22 #include <NMTTools_DSFiller.hxx>
23 #include <NMTDS_ShapesDataStructure.hxx>
24 #include <NMTTools_PaveFiller.hxx>
25 #include <BOPTools_PInterferencePool.hxx>
26 #include <BOPTools_InterferencePool.hxx>
27 #include <BOPTools_CArray1OfEEInterference.hxx>
28 #include <BOPTools_EEInterference.hxx>
29 #include <BOPTools_CArray1OfESInterference.hxx>
30 #include <BOPTools_ESInterference.hxx>
32 //=======================================================================
33 //function : KeepShapesInside
34 //purpose : remove shapes that are outside of S from result
35 //=======================================================================
36 void NMTAlgo_Splitter::KeepShapesInside (const TopoDS_Shape& S)
39 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
40 for (it.Initialize( S ); it.More(); it.Next())
41 KeepShapesInside( it.Value());
45 Standard_Boolean isTool = Standard_False;
46 if (!myImageShape.HasImage( S )) {
47 //isTool = CheckTool( S );
48 //if (!isTool) return;
52 // build map of internal faces
53 TopTools_IndexedMapOfShape MIF;
54 TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
55 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF );
58 myBuilder.MakeCompound(C);
60 TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
63 // leave in the result only those shapes having a face in MIF
64 for (it.Initialize( myShape ); it.More(); it.Next()) {
65 const TopoDS_Shape & aResShape = it.Value();
66 TopExp_Explorer expResF( aResShape, TopAbs_FACE );
67 for (; expResF.More(); expResF.Next()) {
68 if ( MIF.Contains( expResF.Current())) {
69 myBuilder.Add( C, aResShape );
70 if (aResShape.ShapeType() < anInternalShapeType)
71 anInternalShapeType = aResShape.ShapeType();
78 // may be S was not split by internal faces then it is missing
81 (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
83 TopTools_IndexedMapOfShape MSF; // map of split faces of S
84 TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
86 // find a shape having all faces in MSF
87 for (it.Initialize( myShape ); it.More(); it.Next()) {
88 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
89 for (; expResF.More(); expResF.Next()) {
90 if (! MSF.Contains( expResF.Current()))
93 if (! expResF.More()) {
94 myBuilder.Add( C, it.Value() );
103 //=======================================================================
104 //function : RemoveShapesInside
105 //purpose : remove shapes that are inside S from result
106 //=======================================================================
107 void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& aS)
110 TopAbs_ShapeEnum aTypeS;
112 aTypeS=aS.ShapeType();
113 if (aTypeS < TopAbs_SOLID) { // compound or compsolid
115 for (; it.More(); it.Next()) {
116 const TopoDS_Shape& aSx=it.Value();
117 RemoveShapesInside(aSx);
122 Standard_Boolean bFromTool, bIsClosed;
123 Standard_Integer i, aNbE;
124 TopoDS_Shape aIntFacesComp;
126 TopTools_IndexedMapOfShape MIF; // map of internal faces
127 TopTools_MapOfShape RFM;
128 TopTools_MapIteratorOfMapOfShape itF;
129 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
131 bFromTool=myToolShapes.Contains(aS);
133 if (!myImageShape.HasImage(aS)) {
137 aIntFacesComp = FindFacesInside(aS, Standard_False, Standard_True);
139 TopExp::MapShapes(aIntFacesComp, TopAbs_FACE, MIF);
143 // add to MIF split faces of S
144 const TopoDS_Shape& aSIm=myImageShape.Image(aS).First();
145 TopExp::MapShapes(aSIm, TopAbs_FACE, MIF);
147 // leave in the result only those shapes not having all face in MIF
148 myBuilder.MakeCompound(aC);
150 // RFM : faces of removed shapes that encounter once
151 it.Initialize(myShape);
152 for (; it.More(); it.Next()) {
153 TopExp_Explorer expResF;
155 const TopoDS_Shape& aSR=it.Value();
157 expResF.Init(aSR, TopAbs_FACE);
158 for (; expResF.More(); expResF.Next()) {
159 const TopoDS_Shape& aFR=expResF.Current();
160 if (!MIF.Contains(aFR)) {
165 if (expResF.More()) {
166 // add shape to result
167 myBuilder.Add(aC, aSR);
170 // add faces of a removed shape to RFM
171 if (!bFromTool) { //modified by NIZNHY-PKV Thu Dec 23 09:55:39 2004 ft
172 for (expResF.ReInit(); expResF.More(); expResF.Next()) {
173 const TopoDS_Shape& aF = expResF.Current();
174 if (!RFM.Remove(aF)) {
178 }//modified by NIZNHY-PKV Thu Dec 23 09:55:29 2004 ft
180 }// for (; it.More(); it.Next())
188 bIsClosed = Standard_False;
189 if (aTypeS==TopAbs_SOLID) {
190 bIsClosed = Standard_True;
192 else if (aTypeS==TopAbs_SHELL) {
194 TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE, TopAbs_FACE, aMEF);
196 for (i=1; bIsClosed && i<=aNbE; ++i) {
197 bIsClosed=(aMEF(i).Extent()!=1);
201 // rebuild S, it must remain in the result
203 // add to a new shape external faces of removed shapes, ie those in RFM
206 myBuilder.MakeShell(aShell);
207 // exclude redundant internal face with edges encounterd only once
209 itF.Initialize (RFM);
210 for (; itF.More(); itF.Next()) {
211 const TopoDS_Shape& aF=itF.Key();
212 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
214 // add only faces forming a closed shell
215 for (itF.Reset() ; itF.More(); itF.Next()) {
216 const TopoDS_Shape& aF=itF.Key();
217 TopExp_Explorer expE (aF, TopAbs_EDGE);
218 for (; expE.More(); expE.Next()) {
219 if (aMEF.FindFromKey(expE.Current()).Extent()==1) {
224 myBuilder.Add(aShell, aF);
228 if (aTypeS==TopAbs_SOLID) {
231 myBuilder.MakeSolid(aSolid);
232 myBuilder.Add (aSolid, aShell);
233 myBuilder.Add (aC, aSolid);
236 myBuilder.Add (aC, aShell);
238 } // if (bIsClosed) {
242 for (; it.More(); it.Next()) {
243 const TopoDS_Shape& aSx=it.Value();
244 myBuilder.Add (aC, aSx);
251 //=======================================================================
252 //function : Modified
254 //=======================================================================
255 const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S)
259 TopTools_ListIteratorOfListOfShape it;
260 TopTools_MapOfShape aMap;
261 TopExp_Explorer anExp;
263 if(S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_EDGE) {
265 if(S.ShapeType() == TopAbs_FACE) {
266 if (myImagesFaces.HasImage( S )) {
267 it.Initialize(myImagesFaces.Image(S));
268 anExp.Init(myShape, TopAbs_FACE);
272 if (myImagesEdges.HasImage( S )) {
273 it.Initialize(myImagesEdges.Image(S));
274 anExp.Init(myShape, TopAbs_EDGE);
278 for(; anExp.More(); anExp.Next()) {
279 aMap.Add(anExp.Current());
282 for (; it.More(); it.Next()) {
283 if(aMap.Contains(it.Value())) {
284 myGenerated.Append(it.Value());
292 if(S.ShapeType() == TopAbs_VERTEX) {
294 const NMTTools_DSFiller& aDSF = Filler();
295 const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
296 const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
298 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
299 Standard_Integer anIndex = 0, i;
301 for(i = 1; i <= aNbS; ++i) {
303 const TopoDS_Shape& aS = aDS.Shape(i);
311 if(anIndex == 0) return myGenerated;
313 Standard_Integer aSDVInd = aPF.FindSDVertex(anIndex);
315 if(aSDVInd == 0) return myGenerated;
317 const TopoDS_Shape aSDV = aDS.Shape(aSDVInd);
319 anExp.Init(myShape, TopAbs_VERTEX);
320 for(; anExp.More(); anExp.Next()) {
322 if(aSDV.IsSame(anExp.Current())) {
323 myGenerated.Append(aSDV);
333 //=======================================================================
334 //function : Generated
336 //=======================================================================
337 const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S)
340 TopTools_ListIteratorOfListOfShape it;
341 TopTools_MapOfShape aMap;
342 TopExp_Explorer anExp;
343 Standard_Boolean bCheckVert = Standard_False;
345 if(S.ShapeType() == TopAbs_FACE) {
346 if (mySectionParts.Contains(S)) {
347 it.Initialize(mySectionParts.FindFromKey(S));
348 anExp.Init(myShape, TopAbs_EDGE);
350 for(; anExp.More(); anExp.Next()) {
351 aMap.Add(anExp.Current());
354 for (; it.More(); it.Next()) {
355 if(aMap.Contains(it.Value())) {
356 myGenerated.Append(it.Value());
361 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
362 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
363 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
365 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
366 Standard_Integer anIndex = 0, i;
368 for(i = 1; i <= aNbS; ++i) {
370 const TopoDS_Shape& aS = aDS.Shape(i);
378 if(anIndex == 0) return myGenerated;
379 if(!anIP->HasInterference(anIndex)) return myGenerated;
381 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
382 Standard_Integer aNbI = aESs.Extent();
384 if(aNbI == 0) return myGenerated;
386 for(i = 1; i <= aNbI; ++i) {
388 const BOPTools_ESInterference& aES = aESs(i);
389 Standard_Integer ind1, ind2;
390 aES.Indices(ind1, ind2);
392 if(ind1 == anIndex || ind2 == anIndex) {
394 Standard_Integer aNSI = aES.NewShape();
395 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
396 myGenerated.Append(aDS.Shape(aNSI));
397 bCheckVert = Standard_True;
406 anExp.Init(myShape, TopAbs_VERTEX);
408 for(; anExp.More(); anExp.Next()) {
409 aMap.Add(anExp.Current());
412 it.Initialize(myGenerated);
413 for (; it.More(); it.Next()) {
415 if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
417 if(!aMap.Contains(it.Value())) {
418 myGenerated.Remove(it);
427 if(S.ShapeType() == TopAbs_EDGE) {
429 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
430 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
431 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
433 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
434 Standard_Integer anIndex = 0, i;
436 for(i = 1; i <= aNbS; ++i) {
438 const TopoDS_Shape& aS = aDS.Shape(i);
446 if(anIndex == 0) return myGenerated;
447 if(!anIP->HasInterference(anIndex)) return myGenerated;
449 const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
450 Standard_Integer aNbI = aEEs.Extent();
452 for(i = 1; i <= aNbI; ++i) {
454 const BOPTools_EEInterference& aEE = aEEs(i);
455 Standard_Integer ind1, ind2;
456 aEE.Indices(ind1, ind2);
458 if(ind1 == anIndex || ind2 == anIndex) {
460 Standard_Integer aNSI = aEE.NewShape();
461 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
462 myGenerated.Append(aDS.Shape(aNSI));
463 bCheckVert = Standard_True;
470 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
471 aNbI = aESs.Extent();
473 for(i = 1; i <= aNbI; ++i) {
475 const BOPTools_ESInterference& aES = aESs(i);
476 Standard_Integer ind1, ind2;
477 aES.Indices(ind1, ind2);
479 if(ind1 == anIndex || ind2 == anIndex) {
481 Standard_Integer aNSI = aES.NewShape();
482 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
483 myGenerated.Append(aDS.Shape(aNSI));
484 bCheckVert = Standard_True;
493 anExp.Init(myShape, TopAbs_VERTEX);
495 for(; anExp.More(); anExp.Next()) {
496 aMap.Add(anExp.Current());
499 it.Initialize(myGenerated);
500 for (; it.More(); it.Next()) {
502 if(!aMap.Contains(it.Value())) {
503 myGenerated.Remove(it);
516 //=======================================================================
517 //function : IsDeleted
519 //=======================================================================
520 Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S)
523 const TopTools_ListOfShape& aL = Modified(S);
524 if(aL.Extent() != 0) return Standard_False;
526 TopTools_MapOfShape aMap;
527 TopExp_Explorer anExp;
529 TopAbs_ShapeEnum aType = S.ShapeType();
531 if(aType == TopAbs_VERTEX ||
532 aType == TopAbs_EDGE ||
533 aType == TopAbs_FACE ) {
535 anExp.Init(myShape, aType);
536 for(; anExp.More(); anExp.Next()) {
537 if(S.IsSame(anExp.Current())) return Standard_False;
542 return Standard_True;