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