Salome HOME
8229af154c4fe120a4a5ca3d6aad3bc89a0ac211
[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
9 #include <TopoDS_Shape.hxx>
10 #include <TopoDS_Compound.hxx>
11 #include <TopoDS_Solid.hxx>
12 #include <TopoDS_Shell.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS.hxx>
15 #include <TopoDS_Wire.hxx>
16 #include <TopoDS_Iterator.hxx>
17
18 #include <TopExp.hxx>
19 #include <TopExp_Explorer.hxx>
20
21 #include <TopTools_IndexedMapOfShape.hxx>
22 #include <TopTools_MapIteratorOfMapOfShape.hxx>
23 #include <TopTools_ListOfShape.hxx>
24 #include <TopTools_ListIteratorOfListOfShape.hxx>
25 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
26
27 #include <BOPTools_PInterferencePool.hxx>
28 #include <BOPTools_InterferencePool.hxx>
29 #include <BOPTools_CArray1OfEEInterference.hxx>
30 #include <BOPTools_EEInterference.hxx>
31 #include <BOPTools_CArray1OfESInterference.hxx>
32 #include <BOPTools_ESInterference.hxx>
33
34 #include <NMTDS_ShapesDataStructure.hxx>
35 #include <NMTTools_PaveFiller.hxx>
36 #include <NMTTools_DSFiller.hxx>
37 #include <NMTAlgo_Tools.hxx>
38
39 //=======================================================================
40 //function : KeepShapesInside
41 //purpose  : remove shapes that are outside of S from result
42 //=======================================================================
43   void NMTAlgo_Splitter::KeepShapesInside (const TopoDS_Shape& S)
44 {
45   TopoDS_Iterator it;
46   if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
47     for (it.Initialize( S ); it.More(); it.Next())
48       KeepShapesInside( it.Value());
49     return;
50   }
51
52   Standard_Boolean isTool = Standard_False;
53   if (!myImageShape.HasImage( S )) {
54     //isTool = CheckTool( S );
55     //if (!isTool) return;
56     return;
57   }
58
59   // build map of internal faces
60   TopTools_IndexedMapOfShape MIF;
61   TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
62   TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF );
63
64   TopoDS_Compound C;
65   myBuilder.MakeCompound(C);
66
67   TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE;
68   if (!MIF.IsEmpty())
69   {
70     // leave in the result only those shapes having a face in MIF
71     for (it.Initialize( myShape ); it.More(); it.Next()) {
72       const TopoDS_Shape & aResShape = it.Value();
73       TopExp_Explorer expResF( aResShape, TopAbs_FACE );
74       for (; expResF.More(); expResF.Next()) {
75         if ( MIF.Contains( expResF.Current())) {
76           myBuilder.Add( C, aResShape );
77           if (aResShape.ShapeType() < anInternalShapeType)
78             anInternalShapeType = aResShape.ShapeType();
79           break;
80         }
81       }
82     }
83   }
84
85   // may be S was not split by internal faces then it is missing
86   // in myShape, add it
87   if (!isTool &&
88       (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID))
89   {
90     TopTools_IndexedMapOfShape MSF; // map of split faces of S
91     TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF);
92
93     // find a shape having all faces in MSF
94     for (it.Initialize( myShape ); it.More(); it.Next()) {
95       TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
96       for (; expResF.More(); expResF.Next()) {
97         if (! MSF.Contains( expResF.Current())) 
98           break;
99       }
100       if (! expResF.More()) {
101         myBuilder.Add( C, it.Value() );
102         break;
103       }
104     }
105   }
106
107   myShape = C;
108 }
109
110 //=======================================================================
111 //function : RemoveShapesInside
112 //purpose  : remove shapes that are inside S from result
113 //=======================================================================
114   void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& S)
115 {
116   TopoDS_Iterator it;
117   if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
118     it.Initialize( S );
119     for (; it.More(); it.Next()) {
120       RemoveShapesInside( it.Value());
121     }
122     return;
123   }
124   //
125   Standard_Boolean isTool;
126   TopoDS_Shape IntFacesComp;
127   TopoDS_Compound C;
128   TopTools_IndexedMapOfShape MIF; // map of internal faces
129   TopTools_MapOfShape RFM;
130   TopTools_MapIteratorOfMapOfShape itF;
131   //
132   isTool=myToolShapes.Contains(S);
133   //isTool = Standard_False;
134   if (!myImageShape.HasImage( S )) {
135     return;
136   }
137   //
138   IntFacesComp = FindFacesInside( S, Standard_False, Standard_True);
139   //
140   TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF);
141   if (MIF.IsEmpty()) {
142     return;
143   }
144   // add to MIF split faces of S
145   const TopoDS_Shape& aSIm=myImageShape.Image(S).First();
146   TopExp::MapShapes(aSIm, TopAbs_FACE, MIF);
147   //
148   // leave in the result only those shapes not having all face in MIF
149   myBuilder.MakeCompound(C);
150   //
151   // RFM : faces of removed shapes that encounter once
152   it.Initialize(myShape);
153   for (; it.More(); it.Next()) {
154     TopExp_Explorer expResF;
155     //
156     const TopoDS_Shape& aSR=it.Value();
157     //
158     expResF.Init(aSR, TopAbs_FACE);
159     for (; expResF.More(); expResF.Next()) {
160       const TopoDS_Shape& aFR=expResF.Current();
161       if (!MIF.Contains(aFR)) {
162         break;
163       }
164     }
165     //
166     if (expResF.More()) {
167       // add shape to result
168       myBuilder.Add(C, aSR);
169     }
170     else {
171       // add faces of a removed shape to RFM
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     }
179   }// for (; it.More(); it.Next())
180   //
181   //
182   TopoDS_Compound aCx;
183   //
184   myBuilder.MakeCompound(aCx);
185   itF.Initialize (RFM);
186   for (; itF.More(); itF.Next()) {
187     const TopoDS_Shape& aF=itF.Key();
188     myBuilder.Add(aCx, aF);
189   }
190   //
191   if (!isTool) {
192     // rebuild S, it must remain in the result
193     Standard_Boolean isClosed = Standard_False;
194     switch (S.ShapeType()) {
195     case TopAbs_SOLID :
196       isClosed = Standard_True; break;
197     case TopAbs_SHELL: {
198       TopTools_IndexedDataMapOfShapeListOfShape MEF;
199       TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
200       Standard_Integer i;
201       for (i=1;  isClosed && i<=MEF.Extent();  ++i) {
202         isClosed = ( MEF(i).Extent() != 1 );
203       }
204       break;
205     }
206     default:
207       isClosed = Standard_False;
208     }
209     //
210     if (isClosed) {
211       // add to a new shape external faces of removed shapes, ie those in RFM
212       TopoDS_Shell Shell;
213       myBuilder.MakeShell(Shell);
214       // exclude redundant internal face with edges encounterd only once
215       TopTools_IndexedDataMapOfShapeListOfShape MEF;
216       //
217       itF.Initialize (RFM);
218       for ( ; itF.More(); itF.Next()) {
219         const TopoDS_Shape& aF=itF.Key();
220         TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, MEF);
221       }
222       // add only faces forming a closed shell
223       for (itF.Reset() ; itF.More(); itF.Next())  {
224         const TopoDS_Shape& aF=itF.Key();
225         TopExp_Explorer expE (aF, TopAbs_EDGE);
226         for (; expE.More(); expE.Next()) {
227           if (MEF.FindFromKey(expE.Current()).Extent() == 1) {
228             break;
229           }
230         }
231         if (!expE.More()) {
232           myBuilder.Add( Shell, aF);
233         }
234         else {
235           //int a=0;
236         }
237       }
238       
239       if (S.ShapeType() == TopAbs_SOLID) {
240         TopoDS_Solid Solid;
241         myBuilder.MakeSolid( Solid );
242         myBuilder.Add (Solid, Shell);
243         myBuilder.Add (C, Solid);
244       }
245       else {
246         myBuilder.Add (C, Shell);
247       }
248     } // if (isClosed) {
249     else {
250       it.Initialize(aSIm);
251       for (; it.More(); it.Next()) {
252         myBuilder.Add (C, it.Value());
253       }
254     }
255   }
256   //
257   myShape = C;
258 }
259 //
260 //modified by NIZNHY-PKV Tue Feb  1 16:02:29 2005 f
261 //=======================================================================
262 //function : Modified
263 //purpose  : 
264 //=======================================================================
265 const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S) 
266
267 {
268   TopAbs_ShapeEnum aType;
269   //
270   myGenerated.Clear();
271   //
272   aType=S.ShapeType();
273   //
274   switch (aType) { 
275     case TopAbs_SOLID:
276     case TopAbs_FACE: 
277     case TopAbs_EDGE:
278     case TopAbs_VERTEX:
279       FindImage(S, myGenerated);
280       break;
281     
282     case TopAbs_SHELL:
283       break;
284       
285     case TopAbs_WIRE:
286       break;
287       
288     default:
289       break;
290   } 
291   //
292   return myGenerated;
293 }
294 //modified by NIZNHY-PKV Tue Feb  1 16:02:33 2005 t
295 //=======================================================================
296 //function : IsDeleted
297 //purpose  : 
298 //=======================================================================
299 Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S) 
300
301 {
302   const TopTools_ListOfShape& aL = Modified(S);
303   if(aL.Extent() != 0) return Standard_False;
304
305   TopTools_MapOfShape aMap;
306   TopExp_Explorer anExp;
307
308   TopAbs_ShapeEnum aType = S.ShapeType();
309
310   if(aType == TopAbs_VERTEX || 
311      aType == TopAbs_EDGE   || 
312      aType == TopAbs_FACE     ) {
313
314     anExp.Init(myShape, aType);
315     for(; anExp.More(); anExp.Next()) {
316       if(S.IsSame(anExp.Current())) return Standard_False;
317     }
318
319   }
320   
321   return Standard_True;
322 }
323 //=======================================================================
324 //function : Generated
325 //purpose  : 
326 //=======================================================================
327 const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S) 
328 {
329   myGenerated.Clear();
330   TopTools_ListIteratorOfListOfShape it;
331   TopTools_MapOfShape aMap;
332   TopExp_Explorer anExp;
333   Standard_Boolean bCheckVert = Standard_False;
334
335   if(S.ShapeType() == TopAbs_FACE) {
336     if (mySectionParts.Contains(S)) {
337       it.Initialize(mySectionParts.FindFromKey(S));
338       anExp.Init(myShape, TopAbs_EDGE);
339   
340       for(; anExp.More(); anExp.Next()) {
341         aMap.Add(anExp.Current());
342       }
343
344       for (; it.More(); it.Next()) {
345         if(aMap.Contains(it.Value())) {
346           myGenerated.Append(it.Value());
347         }
348       }
349     }
350
351     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
352     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
353     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
354
355     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
356     Standard_Integer anIndex = 0, i;
357
358     for(i = 1; i <= aNbS; ++i) {
359
360       const TopoDS_Shape& aS = aDS.Shape(i);
361       if(S.IsSame(aS)) {
362         anIndex = i;
363         break;
364       }
365
366     }
367
368     if(anIndex == 0) return myGenerated;
369     if(!anIP->HasInterference(anIndex)) return myGenerated;
370
371     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
372     Standard_Integer aNbI = aESs.Extent();
373
374     if(aNbI == 0) return myGenerated;
375
376     for(i = 1; i <= aNbI; ++i) {
377
378       const BOPTools_ESInterference& aES = aESs(i);
379       Standard_Integer ind1, ind2;
380       aES.Indices(ind1, ind2);
381
382       if(ind1 == anIndex || ind2 == anIndex) {
383
384         Standard_Integer aNSI = aES.NewShape();
385         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
386           myGenerated.Append(aDS.Shape(aNSI));
387           bCheckVert = Standard_True;
388         }
389      
390       }
391
392     }
393           
394     if(bCheckVert) {
395       aMap.Clear();
396       anExp.Init(myShape, TopAbs_VERTEX);
397   
398       for(; anExp.More(); anExp.Next()) {
399         aMap.Add(anExp.Current());
400       }
401
402       it.Initialize(myGenerated);
403       for (; it.More(); it.Next()) {
404
405         if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
406         
407         if(!aMap.Contains(it.Value())) {
408           myGenerated.Remove(it);
409         }
410
411       }
412     }
413    
414     return myGenerated;
415   }
416
417   if(S.ShapeType() == TopAbs_EDGE) {
418
419     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
420     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
421     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
422
423     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
424     Standard_Integer anIndex = 0, i;
425
426     for(i = 1; i <= aNbS; ++i) {
427
428       const TopoDS_Shape& aS = aDS.Shape(i);
429       if(S.IsSame(aS)) {
430         anIndex = i;
431         break;
432       }
433
434     }
435
436     if(anIndex == 0) return myGenerated;
437     if(!anIP->HasInterference(anIndex)) return myGenerated;
438
439     const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
440     Standard_Integer aNbI = aEEs.Extent();
441
442     for(i = 1; i <= aNbI; ++i) {
443
444       const BOPTools_EEInterference& aEE = aEEs(i);
445       Standard_Integer ind1, ind2;
446       aEE.Indices(ind1, ind2);
447
448       if(ind1 == anIndex || ind2 == anIndex) {
449
450         Standard_Integer aNSI = aEE.NewShape();
451         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
452           myGenerated.Append(aDS.Shape(aNSI));
453           bCheckVert = Standard_True;
454         }
455      
456       }
457           
458     }    
459
460     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
461     aNbI = aESs.Extent();
462
463     for(i = 1; i <= aNbI; ++i) {
464
465       const BOPTools_ESInterference& aES = aESs(i);
466       Standard_Integer ind1, ind2;
467       aES.Indices(ind1, ind2);
468
469       if(ind1 == anIndex || ind2 == anIndex) {
470
471         Standard_Integer aNSI = aES.NewShape();
472         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
473           myGenerated.Append(aDS.Shape(aNSI));
474           bCheckVert = Standard_True;
475         }
476      
477       }
478           
479     }    
480
481     if(bCheckVert) {
482       aMap.Clear();
483       anExp.Init(myShape, TopAbs_VERTEX);
484   
485       for(; anExp.More(); anExp.Next()) {
486         aMap.Add(anExp.Current());
487       }
488
489       it.Initialize(myGenerated);
490       for (; it.More(); it.Next()) {
491
492         if(!aMap.Contains(it.Value())) {
493           myGenerated.Remove(it);
494         }
495       }
496     }
497     return myGenerated;
498   }
499   return myGenerated;
500 }
501 //modified by NIZNHY-PKV Tue Feb  1 10:26:18 2005f
502 //=======================================================================
503 //function : FindImage
504 //purpose  : 
505 //=======================================================================
506 void NMTAlgo_Splitter::FindImage(const TopoDS_Shape& aS,
507                                  TopTools_ListOfShape& aLIms)
508 {
509   TopAbs_ShapeEnum aType;
510   //
511   aType=aS.ShapeType();
512   //
513   if (aType==TopAbs_SOLID) {
514     Standard_Boolean bHasImage, bHasInternalFaces;
515     Standard_Integer i, aNbSd;
516     TopTools_IndexedMapOfShape aMSo, aMSd;
517     TopoDS_Iterator aIt;
518     TopTools_IndexedDataMapOfShapeListOfShape aMFS;
519     TopTools_ListIteratorOfListOfShape aItLS;
520     //
521     bHasInternalFaces=myMapSIFC.IsBound(aS);
522     if (bHasInternalFaces){
523       TopExp::MapShapesAndAncestors(myShape, TopAbs_FACE, TopAbs_SOLID, aMFS);
524       //
525       const TopoDS_Shape& aIFC=myMapSIFC.Find(aS);
526       //
527       aIt.Initialize(aIFC);
528       for (; aIt.More(); aIt.Next()) {
529         const TopoDS_Shape& aIF=aIt.Value();
530         if (aMFS.Contains(aIF)) {
531           const TopTools_ListOfShape& aLS=aMFS.FindFromKey(aIF);
532           //
533           aItLS.Initialize(aLS);
534           for (; aItLS.More(); aItLS.Next()) {
535             const TopoDS_Shape& aSx=aItLS.Value();
536             aMSd.Add(aSx);
537           }
538         }
539       }
540       //
541       aNbSd=aMSd.Extent();
542       if (aNbSd) {
543         for (i=1; i<=aNbSd; ++i) {
544           const TopoDS_Shape& aSx=aMSd(i);
545           if (!aSx.IsSame(aS)) {
546             aLIms.Append(aSx);
547           }
548         }
549         return;
550       }
551     }
552     //
553     bHasImage=myImageShape.HasImage(aS);
554     if (!bHasImage) {
555       return;
556     }
557     //
558     TopoDS_Shape aSd;
559     //
560     TopExp::MapShapes(myShape, TopAbs_SOLID, aMSo);
561     //
562     const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
563     bHasImage=NMTAlgo_Tools::FindImageSolid(aFC, aMSo, aSd);
564     if (bHasImage) {
565       if (!aSd.IsSame(aS)) {
566         aLIms.Append(aSd);
567       }
568     }
569   } //if (aType==TopAbs_SOLID) {
570   //==
571   else if (aType==TopAbs_FACE) {
572     TopTools_MapOfShape aMap;
573     TopTools_ListIteratorOfListOfShape aIt;
574     TopExp_Explorer anExp;
575     //
576     if (myModifiedFaces.IsBound(aS)) {
577       anExp.Init(myShape, aType);
578       for(; anExp.More(); anExp.Next()) {
579         aMap.Add(anExp.Current());
580       }
581       //
582       const TopTools_ListOfShape& aLS=myModifiedFaces.Find(aS);
583       aIt.Initialize(aLS);
584       for (; aIt.More(); aIt.Next()) {
585         const TopoDS_Shape& aFx=aIt.Value();
586         if (!aFx.IsSame(aS)) {
587           if (aMap.Contains(aFx)) {
588             aLIms.Append(aFx);
589           }
590         }
591       }
592     }
593   } // else if (aType==TopAbs_FACE)
594   //==
595   else if (aType==TopAbs_EDGE) {
596     TopTools_MapOfShape aMap;
597     TopTools_ListIteratorOfListOfShape aIt;
598     TopExp_Explorer anExp;
599     //
600     if (myImagesEdges.HasImage(aS)) {
601       anExp.Init(myShape, aType);
602       for(; anExp.More(); anExp.Next()) {
603         aMap.Add(anExp.Current());
604       }
605       //
606       const TopTools_ListOfShape& aLE=myImagesEdges.Image(aS);
607       aIt.Initialize(aLE);
608       for (; aIt.More(); aIt.Next()) {
609         const TopoDS_Shape& aEx=aIt.Value();
610         if (!aEx.IsSame(aS)) {
611           if(aMap.Contains(aEx)) {
612             aLIms.Append(aEx);
613           }
614         }
615       }
616     }
617   }// else if (aType==TopAbs_EDGE)
618   //==
619   else if (aType==TopAbs_VERTEX) {
620     Standard_Integer aNbS, anIndex, i, aSDVInd;
621     TopExp_Explorer anExp;
622     //
623     const NMTTools_DSFiller& aDSF = Filler();
624     const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
625     const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
626     //
627     aNbS = aDS.NumberOfSourceShapes();
628     anIndex = 0;
629       //
630     for(i=1; i<=aNbS; ++i) {
631       const TopoDS_Shape& aSx = aDS.Shape(i);
632       if(aS.IsSame(aSx)) {
633         anIndex = i;
634         break;
635       }
636     }
637     //
638     if(!anIndex) {
639       return;
640     }
641     //
642     aSDVInd=aPF.FindSDVertex(anIndex);
643     if(!aSDVInd) {
644       return;
645     }
646     //
647     const TopoDS_Shape& aSDV=aDS.Shape(aSDVInd);
648     //
649     anExp.Init(myShape, aType);
650     for(; anExp.More(); anExp.Next()) {
651       const TopoDS_Shape& aVx=anExp.Current();
652       if(aSDV.IsSame(aVx)) {
653         aLIms.Append(aSDV);
654         break;
655       }
656     }
657   }// else if (aType==TopAbs_VERTEX) 
658 }
659 //modified by NIZNHY-PKV Tue Feb  1 10:26:22 2005t 
660