Salome HOME
Change comments style in geompy.py for right processing with HappyDoc
[modules/geom.git] / src / NMTAlgo / NMTAlgo_Splitter_2.cxx
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>
5
6
7 #include <NMTAlgo_Splitter.ixx>
8 #include <TopoDS_Iterator.hxx>
9 #include <TopTools_IndexedMapOfShape.hxx>
10 #include <TopoDS_Shape.hxx>
11 #include <TopExp.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>
18 #include <TopoDS.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>
31
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)
37 {
38   TopoDS_Iterator it;
39   if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
40     for (it.Initialize( S ); it.More(); it.Next())
41       KeepShapesInside( it.Value());
42     return;
43   }
44
45   Standard_Boolean isTool = Standard_False;
46   if (!myImageShape.HasImage( S )) {
47     //isTool = CheckTool( S );
48     //if (!isTool) return;
49     return;
50   }
51
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 );
56
57   TopoDS_Compound C;
58   myBuilder.MakeCompound(C);
59
60   TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
61   if (!MIF.IsEmpty())
62   {
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();
72           break;
73         }
74       }
75     }
76   }
77
78   // may be S was not split by internal faces then it is missing
79   // in myShape, add it
80   if (!isTool &&
81       (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
82   {
83     TopTools_IndexedMapOfShape MSF; // map of split faces of S
84     TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
85
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())) 
91           break;
92       }
93       if (! expResF.More()) {
94         myBuilder.Add( C, it.Value() );
95         break;
96       }
97     }
98   }
99
100   myShape = C;
101 }
102
103 //=======================================================================
104 //function : RemoveShapesInside
105 //purpose  : remove shapes that are inside S from result
106 //=======================================================================
107   void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& aS)
108 {
109   TopoDS_Iterator it;
110   TopAbs_ShapeEnum aTypeS;
111   //
112   aTypeS=aS.ShapeType();
113   if (aTypeS < TopAbs_SOLID) { // compound or compsolid
114     it.Initialize(aS);
115     for (; it.More(); it.Next()) {
116       const TopoDS_Shape& aSx=it.Value();
117       RemoveShapesInside(aSx);
118     }
119     return;
120   }
121   //
122   Standard_Boolean bFromTool, bIsClosed;
123   Standard_Integer i, aNbE;
124   TopoDS_Shape aIntFacesComp;
125   TopoDS_Compound aC;
126   TopTools_IndexedMapOfShape MIF; // map of internal faces
127   TopTools_MapOfShape RFM;
128   TopTools_MapIteratorOfMapOfShape itF;
129   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
130   //
131   bFromTool=myToolShapes.Contains(aS);
132   //
133   if (!myImageShape.HasImage(aS)) {
134     return; 
135   }
136   //
137   aIntFacesComp = FindFacesInside(aS, Standard_False, Standard_True);
138   //
139   TopExp::MapShapes(aIntFacesComp, TopAbs_FACE, MIF);
140   if (MIF.IsEmpty()) {
141     return;
142   }
143   // add to MIF split faces of S
144   const TopoDS_Shape& aSIm=myImageShape.Image(aS).First();
145   TopExp::MapShapes(aSIm, TopAbs_FACE, MIF);
146   //
147   // leave in the result only those shapes not having all face in MIF
148   myBuilder.MakeCompound(aC);
149   //
150   // RFM : faces of removed shapes that encounter once
151   it.Initialize(myShape);
152   for (; it.More(); it.Next()) {
153     TopExp_Explorer expResF;
154     //
155     const TopoDS_Shape& aSR=it.Value();
156     //
157     expResF.Init(aSR, TopAbs_FACE);
158     for (; expResF.More(); expResF.Next()) {
159       const TopoDS_Shape& aFR=expResF.Current();
160       if (!MIF.Contains(aFR)) {
161         break;
162       }
163     }
164     //
165     if (expResF.More()) {
166       // add shape to result
167       myBuilder.Add(aC, aSR);
168     }
169     else {
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)) {
175             RFM.Add(aF);
176           }
177         }
178       }//modified by NIZNHY-PKV Thu Dec 23 09:55:29 2004 ft
179     }
180   }// for (; it.More(); it.Next())
181   //
182   if (bFromTool) {
183     myShape=aC;
184     return;
185   }
186   //
187   // bIsClosed
188   bIsClosed = Standard_False; 
189   if (aTypeS==TopAbs_SOLID) {
190     bIsClosed = Standard_True; 
191   }
192   else if (aTypeS==TopAbs_SHELL) {
193     aMEF.Clear();
194     TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE, TopAbs_FACE, aMEF);
195     aNbE=aMEF.Extent(); 
196     for (i=1; bIsClosed && i<=aNbE; ++i) {
197       bIsClosed=(aMEF(i).Extent()!=1);
198     }
199   }
200   //
201   // rebuild S, it must remain in the result
202   if (bIsClosed) {
203     // add to a new shape external faces of removed shapes, ie those in RFM
204     TopoDS_Shell aShell;
205     //
206     myBuilder.MakeShell(aShell);
207     // exclude redundant internal face with edges encounterd only once
208     aMEF.Clear();
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);
213     }
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) {
220           break;
221         }
222       }
223       if (!expE.More()) {
224         myBuilder.Add(aShell, aF);
225       }
226     }
227     //
228     if (aTypeS==TopAbs_SOLID) {
229       TopoDS_Solid aSolid;
230       //
231       myBuilder.MakeSolid(aSolid);
232       myBuilder.Add (aSolid, aShell);
233       myBuilder.Add (aC, aSolid);
234     }
235     else {
236       myBuilder.Add (aC, aShell);
237     }
238   } // if (bIsClosed) {
239   //
240   else {
241     it.Initialize(aSIm);
242     for (; it.More(); it.Next()) {
243       const TopoDS_Shape& aSx=it.Value();
244       myBuilder.Add (aC, aSx);
245     }
246   }
247   //
248   myShape=aC;
249 }
250
251 //=======================================================================
252 //function : Modified
253 //purpose  : 
254 //=======================================================================
255   const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S) 
256
257 {
258   myGenerated.Clear();
259   TopTools_ListIteratorOfListOfShape it;
260   TopTools_MapOfShape aMap;
261   TopExp_Explorer anExp;
262
263   if(S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_EDGE) {
264
265     if(S.ShapeType() == TopAbs_FACE) { 
266       if (myImagesFaces.HasImage( S )) {
267         it.Initialize(myImagesFaces.Image(S));
268         anExp.Init(myShape, TopAbs_FACE);
269       }
270     }
271     else {
272       if (myImagesEdges.HasImage( S )) {
273         it.Initialize(myImagesEdges.Image(S));
274         anExp.Init(myShape, TopAbs_EDGE);
275       }
276     }
277   
278     for(; anExp.More(); anExp.Next()) {
279       aMap.Add(anExp.Current());
280     }
281
282     for (; it.More(); it.Next()) {
283       if(aMap.Contains(it.Value())) {
284         myGenerated.Append(it.Value());
285       }
286     }
287
288     return myGenerated;
289
290   }
291
292   if(S.ShapeType() == TopAbs_VERTEX) {
293     
294     const NMTTools_DSFiller& aDSF = Filler();
295     const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
296     const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
297
298     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
299     Standard_Integer anIndex = 0, i;
300
301     for(i = 1; i <= aNbS; ++i) {
302
303       const TopoDS_Shape& aS = aDS.Shape(i);
304       if(S.IsSame(aS)) {
305         anIndex = i;
306         break;
307       }
308
309     }
310
311     if(anIndex == 0) return myGenerated;
312
313     Standard_Integer aSDVInd = aPF.FindSDVertex(anIndex);
314
315     if(aSDVInd == 0) return myGenerated;
316
317     const TopoDS_Shape aSDV = aDS.Shape(aSDVInd);
318
319     anExp.Init(myShape, TopAbs_VERTEX);
320     for(; anExp.More(); anExp.Next()) {
321
322       if(aSDV.IsSame(anExp.Current())) {
323         myGenerated.Append(aSDV);
324         break;
325       }
326
327     }
328     
329   }
330
331   return myGenerated;
332 }
333 //=======================================================================
334 //function : Generated
335 //purpose  : 
336 //=======================================================================
337   const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S) 
338 {
339   myGenerated.Clear();
340   TopTools_ListIteratorOfListOfShape it;
341   TopTools_MapOfShape aMap;
342   TopExp_Explorer anExp;
343   Standard_Boolean bCheckVert = Standard_False;
344
345   if(S.ShapeType() == TopAbs_FACE) {
346     if (mySectionParts.Contains(S)) {
347       it.Initialize(mySectionParts.FindFromKey(S));
348       anExp.Init(myShape, TopAbs_EDGE);
349   
350       for(; anExp.More(); anExp.Next()) {
351         aMap.Add(anExp.Current());
352       }
353
354       for (; it.More(); it.Next()) {
355         if(aMap.Contains(it.Value())) {
356           myGenerated.Append(it.Value());
357         }
358       }
359     }
360
361     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
362     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
363     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
364
365     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
366     Standard_Integer anIndex = 0, i;
367
368     for(i = 1; i <= aNbS; ++i) {
369
370       const TopoDS_Shape& aS = aDS.Shape(i);
371       if(S.IsSame(aS)) {
372         anIndex = i;
373         break;
374       }
375
376     }
377
378     if(anIndex == 0) return myGenerated;
379     if(!anIP->HasInterference(anIndex)) return myGenerated;
380
381     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
382     Standard_Integer aNbI = aESs.Extent();
383
384     if(aNbI == 0) return myGenerated;
385
386     for(i = 1; i <= aNbI; ++i) {
387
388       const BOPTools_ESInterference& aES = aESs(i);
389       Standard_Integer ind1, ind2;
390       aES.Indices(ind1, ind2);
391
392       if(ind1 == anIndex || ind2 == anIndex) {
393
394         Standard_Integer aNSI = aES.NewShape();
395         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
396           myGenerated.Append(aDS.Shape(aNSI));
397           bCheckVert = Standard_True;
398         }
399      
400       }
401
402     }
403           
404     if(bCheckVert) {
405       aMap.Clear();
406       anExp.Init(myShape, TopAbs_VERTEX);
407   
408       for(; anExp.More(); anExp.Next()) {
409         aMap.Add(anExp.Current());
410       }
411
412       it.Initialize(myGenerated);
413       for (; it.More(); it.Next()) {
414
415         if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
416         
417         if(!aMap.Contains(it.Value())) {
418           myGenerated.Remove(it);
419         }
420
421       }
422     }
423    
424     return myGenerated;
425   }
426
427   if(S.ShapeType() == TopAbs_EDGE) {
428
429     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
430     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
431     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
432
433     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
434     Standard_Integer anIndex = 0, i;
435
436     for(i = 1; i <= aNbS; ++i) {
437
438       const TopoDS_Shape& aS = aDS.Shape(i);
439       if(S.IsSame(aS)) {
440         anIndex = i;
441         break;
442       }
443
444     }
445
446     if(anIndex == 0) return myGenerated;
447     if(!anIP->HasInterference(anIndex)) return myGenerated;
448
449     const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
450     Standard_Integer aNbI = aEEs.Extent();
451
452     for(i = 1; i <= aNbI; ++i) {
453
454       const BOPTools_EEInterference& aEE = aEEs(i);
455       Standard_Integer ind1, ind2;
456       aEE.Indices(ind1, ind2);
457
458       if(ind1 == anIndex || ind2 == anIndex) {
459
460         Standard_Integer aNSI = aEE.NewShape();
461         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
462           myGenerated.Append(aDS.Shape(aNSI));
463           bCheckVert = Standard_True;
464         }
465      
466       }
467           
468     }    
469
470     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
471     aNbI = aESs.Extent();
472
473     for(i = 1; i <= aNbI; ++i) {
474
475       const BOPTools_ESInterference& aES = aESs(i);
476       Standard_Integer ind1, ind2;
477       aES.Indices(ind1, ind2);
478
479       if(ind1 == anIndex || ind2 == anIndex) {
480
481         Standard_Integer aNSI = aES.NewShape();
482         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
483           myGenerated.Append(aDS.Shape(aNSI));
484           bCheckVert = Standard_True;
485         }
486      
487       }
488           
489     }    
490
491     if(bCheckVert) {
492       aMap.Clear();
493       anExp.Init(myShape, TopAbs_VERTEX);
494   
495       for(; anExp.More(); anExp.Next()) {
496         aMap.Add(anExp.Current());
497       }
498
499       it.Initialize(myGenerated);
500       for (; it.More(); it.Next()) {
501
502         if(!aMap.Contains(it.Value())) {
503           myGenerated.Remove(it);
504         }
505
506       }
507     }
508
509     return myGenerated;
510   
511   }
512
513   return myGenerated;
514 }
515
516 //=======================================================================
517 //function : IsDeleted
518 //purpose  : 
519 //=======================================================================
520   Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S) 
521
522 {
523   const TopTools_ListOfShape& aL = Modified(S);
524   if(aL.Extent() != 0) return Standard_False;
525
526   TopTools_MapOfShape aMap;
527   TopExp_Explorer anExp;
528
529   TopAbs_ShapeEnum aType = S.ShapeType();
530
531   if(aType == TopAbs_VERTEX || 
532      aType == TopAbs_EDGE   || 
533      aType == TopAbs_FACE     ) {
534
535     anExp.Init(myShape, aType);
536     for(; anExp.More(); anExp.Next()) {
537       if(S.IsSame(anExp.Current())) return Standard_False;
538     }
539
540   }
541   
542   return Standard_True;
543 }
544