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 resul
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 resul
106 //=======================================================================
107 void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& S)
110 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
111 for (it.Initialize( S ); it.More(); it.Next())
112 RemoveShapesInside( it.Value());
115 Standard_Boolean isTool = Standard_False;
116 if (!myImageShape.HasImage( S )) {
117 //isTool = CheckTool( S );
118 //if (!isTool) return;
122 TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
123 TopTools_IndexedMapOfShape MIF; // map of internal faces
124 TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF);
126 if (MIF.IsEmpty()) return;
128 // add to MIF split faces of S
129 if (myImageShape.HasImage(S))
130 TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF);
132 // leave in the result only those shapes not having all face in MIF
135 myBuilder.MakeCompound(C);
137 // RMF : faces of removed shapes that encounter once
138 TopTools_MapOfShape RFM;
140 for (it.Initialize( myShape ); it.More(); it.Next()) {
142 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
143 for (; expResF.More(); expResF.Next())
144 if (!MIF.Contains( expResF.Current()))
148 // add shape to result
149 myBuilder.Add( C, it.Value() );
151 // add faces of a removed shape to RFM
152 for (expResF.ReInit(); expResF.More(); expResF.Next()) {
153 const TopoDS_Shape& F = expResF.Current();
154 if ( ! RFM.Remove ( F ))
161 // rebuild S, it must remain in the result
163 Standard_Boolean isClosed = Standard_False;
164 switch (S.ShapeType()) {
166 isClosed = Standard_True; break;
168 TopTools_IndexedDataMapOfShapeListOfShape MEF;
169 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
171 for (i=1; isClosed && i<=MEF.Extent(); ++i)
172 isClosed = ( MEF(i).Extent() != 1 );
176 isClosed = Standard_False;
180 // add to a new shape external faces of removed shapes, ie those in RFM
183 myBuilder.MakeShell( Shell );
185 // exclude redundant internal face with edges encounterd only once
186 TopTools_IndexedDataMapOfShapeListOfShape MEF;
187 TopTools_MapIteratorOfMapOfShape itF (RFM);
188 for ( ; itF.More(); itF.Next())
189 TopExp::MapShapesAndAncestors(itF.Key(), TopAbs_EDGE, TopAbs_FACE, MEF);
191 // add only faces forming a closed shell
192 for (itF.Reset() ; itF.More(); itF.Next())
194 TopExp_Explorer expE (itF.Key(), TopAbs_EDGE);
195 for (; expE.More(); expE.Next())
196 if (MEF.FindFromKey(expE.Current()).Extent() == 1)
199 myBuilder.Add( Shell, itF.Key());
202 if (S.ShapeType() == TopAbs_SOLID) {
204 myBuilder.MakeSolid( Solid );
205 myBuilder.Add (Solid, Shell);
206 myBuilder.Add (C, Solid);
209 myBuilder.Add (C, Shell);
212 if (myImageShape.HasImage( S )) {
213 for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next())
214 myBuilder.Add (C, it.Value());
222 //=======================================================================
223 //function : Modified
225 //=======================================================================
226 const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S)
230 TopTools_ListIteratorOfListOfShape it;
231 TopTools_MapOfShape aMap;
232 TopExp_Explorer anExp;
234 if(S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_EDGE) {
236 if(S.ShapeType() == TopAbs_FACE) {
237 if (myImagesFaces.HasImage( S )) {
238 it.Initialize(myImagesFaces.Image(S));
239 anExp.Init(myShape, TopAbs_FACE);
243 if (myImagesEdges.HasImage( S )) {
244 it.Initialize(myImagesEdges.Image(S));
245 anExp.Init(myShape, TopAbs_EDGE);
249 for(; anExp.More(); anExp.Next()) {
250 aMap.Add(anExp.Current());
253 for (; it.More(); it.Next()) {
254 if(aMap.Contains(it.Value())) {
255 myGenerated.Append(it.Value());
263 if(S.ShapeType() == TopAbs_VERTEX) {
265 const NMTTools_DSFiller& aDSF = Filler();
266 const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
267 const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
269 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
270 Standard_Integer anIndex = 0, i;
272 for(i = 1; i <= aNbS; ++i) {
274 const TopoDS_Shape& aS = aDS.Shape(i);
282 if(anIndex == 0) return myGenerated;
284 Standard_Integer aSDVInd = aPF.FindSDVertex(anIndex);
286 if(aSDVInd == 0) return myGenerated;
288 const TopoDS_Shape aSDV = aDS.Shape(aSDVInd);
290 anExp.Init(myShape, TopAbs_VERTEX);
291 for(; anExp.More(); anExp.Next()) {
293 if(aSDV.IsSame(anExp.Current())) {
294 myGenerated.Append(aSDV);
304 //=======================================================================
305 //function : Generated
307 //=======================================================================
308 const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S)
311 TopTools_ListIteratorOfListOfShape it;
312 TopTools_MapOfShape aMap;
313 TopExp_Explorer anExp;
314 Standard_Boolean bCheckVert = Standard_False;
316 if(S.ShapeType() == TopAbs_FACE) {
317 if (mySectionParts.Contains(S)) {
318 it.Initialize(mySectionParts.FindFromKey(S));
319 anExp.Init(myShape, TopAbs_EDGE);
321 for(; anExp.More(); anExp.Next()) {
322 aMap.Add(anExp.Current());
325 for (; it.More(); it.Next()) {
326 if(aMap.Contains(it.Value())) {
327 myGenerated.Append(it.Value());
332 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
333 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
334 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
336 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
337 Standard_Integer anIndex = 0, i;
339 for(i = 1; i <= aNbS; ++i) {
341 const TopoDS_Shape& aS = aDS.Shape(i);
349 if(anIndex == 0) return myGenerated;
350 if(!anIP->HasInterference(anIndex)) return myGenerated;
352 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
353 Standard_Integer aNbI = aESs.Extent();
355 if(aNbI == 0) return myGenerated;
357 for(i = 1; i <= aNbI; ++i) {
359 const BOPTools_ESInterference& aES = aESs(i);
360 Standard_Integer ind1, ind2;
361 aES.Indices(ind1, ind2);
363 if(ind1 == anIndex || ind2 == anIndex) {
365 Standard_Integer aNSI = aES.NewShape();
366 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
367 myGenerated.Append(aDS.Shape(aNSI));
368 bCheckVert = Standard_True;
377 anExp.Init(myShape, TopAbs_VERTEX);
379 for(; anExp.More(); anExp.Next()) {
380 aMap.Add(anExp.Current());
383 it.Initialize(myGenerated);
384 for (; it.More(); it.Next()) {
386 if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
388 if(!aMap.Contains(it.Value())) {
389 myGenerated.Remove(it);
398 if(S.ShapeType() == TopAbs_EDGE) {
400 NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
401 const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
402 const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
404 Standard_Integer aNbS = aDS.NumberOfSourceShapes();
405 Standard_Integer anIndex = 0, i;
407 for(i = 1; i <= aNbS; ++i) {
409 const TopoDS_Shape& aS = aDS.Shape(i);
417 if(anIndex == 0) return myGenerated;
418 if(!anIP->HasInterference(anIndex)) return myGenerated;
420 const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
421 Standard_Integer aNbI = aEEs.Extent();
423 for(i = 1; i <= aNbI; ++i) {
425 const BOPTools_EEInterference& aEE = aEEs(i);
426 Standard_Integer ind1, ind2;
427 aEE.Indices(ind1, ind2);
429 if(ind1 == anIndex || ind2 == anIndex) {
431 Standard_Integer aNSI = aEE.NewShape();
432 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
433 myGenerated.Append(aDS.Shape(aNSI));
434 bCheckVert = Standard_True;
441 const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
442 aNbI = aESs.Extent();
444 for(i = 1; i <= aNbI; ++i) {
446 const BOPTools_ESInterference& aES = aESs(i);
447 Standard_Integer ind1, ind2;
448 aES.Indices(ind1, ind2);
450 if(ind1 == anIndex || ind2 == anIndex) {
452 Standard_Integer aNSI = aES.NewShape();
453 if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
454 myGenerated.Append(aDS.Shape(aNSI));
455 bCheckVert = Standard_True;
464 anExp.Init(myShape, TopAbs_VERTEX);
466 for(; anExp.More(); anExp.Next()) {
467 aMap.Add(anExp.Current());
470 it.Initialize(myGenerated);
471 for (; it.More(); it.Next()) {
473 if(!aMap.Contains(it.Value())) {
474 myGenerated.Remove(it);
487 //=======================================================================
488 //function : IsDeleted
490 //=======================================================================
491 Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S)
494 const TopTools_ListOfShape& aL = Modified(S);
495 if(aL.Extent() != 0) return Standard_False;
497 TopTools_MapOfShape aMap;
498 TopExp_Explorer anExp;
500 TopAbs_ShapeEnum aType = S.ShapeType();
502 if(aType == TopAbs_VERTEX ||
503 aType == TopAbs_EDGE ||
504 aType == TopAbs_FACE ) {
506 anExp.Init(myShape, aType);
507 for(; anExp.More(); anExp.Next()) {
508 if(S.IsSame(anExp.Current())) return Standard_False;
513 return Standard_True;