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