]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTAlgo/NMTAlgo_Splitter_2.cxx
Salome HOME
Merge with version on tag OCC-V2_1_0d
[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 resul
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 resul
106 //=======================================================================
107   void NMTAlgo_Splitter::RemoveShapesInside (const TopoDS_Shape& S)
108 {
109   TopoDS_Iterator it;
110   if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
111     for (it.Initialize( S ); it.More(); it.Next())
112       RemoveShapesInside( it.Value());
113     return;
114   }
115   Standard_Boolean isTool = Standard_False;
116   if (!myImageShape.HasImage( S )) {
117     //isTool = CheckTool( S );
118     //if (!isTool) return;
119     return;
120   }
121
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);
125
126   if (MIF.IsEmpty()) return;
127
128   // add to MIF split faces of S
129   if (myImageShape.HasImage(S))
130     TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF);
131
132   // leave in the result only those shapes not having all face in MIF
133   
134   TopoDS_Compound C;
135   myBuilder.MakeCompound(C);
136
137   // RMF : faces of removed shapes that encounter once
138   TopTools_MapOfShape RFM;
139   
140   for (it.Initialize( myShape ); it.More(); it.Next()) {
141     
142     TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
143     for (; expResF.More(); expResF.Next())
144       if (!MIF.Contains( expResF.Current()))
145         break;
146
147     if (expResF.More())
148       // add shape to result
149       myBuilder.Add( C, it.Value() );
150     else 
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 ))
155           RFM.Add( F );
156       }
157   }
158
159   if (!isTool) {
160
161     // rebuild S, it must remain in the result
162
163     Standard_Boolean isClosed = Standard_False;
164     switch (S.ShapeType()) {
165     case TopAbs_SOLID :
166       isClosed = Standard_True; break;
167     case TopAbs_SHELL: {
168       TopTools_IndexedDataMapOfShapeListOfShape MEF;
169       TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
170       Standard_Integer i;
171       for (i=1;  isClosed && i<=MEF.Extent();  ++i) 
172         isClosed = ( MEF(i).Extent() != 1 );
173       break;
174     }
175     default:
176       isClosed = Standard_False;
177     }
178     if (isClosed) {
179
180       // add to a new shape external faces of removed shapes, ie those in RFM
181
182       TopoDS_Shell Shell;
183       myBuilder.MakeShell( Shell );
184
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);
190
191       // add only faces forming a closed shell
192       for (itF.Reset() ; itF.More(); itF.Next())
193       {
194         TopExp_Explorer expE (itF.Key(), TopAbs_EDGE);
195         for (; expE.More(); expE.Next())
196           if (MEF.FindFromKey(expE.Current()).Extent() == 1)
197             break;
198         if (!expE.More())
199           myBuilder.Add( Shell, itF.Key());
200       }
201
202       if (S.ShapeType() == TopAbs_SOLID) {
203         TopoDS_Solid Solid;
204         myBuilder.MakeSolid( Solid );
205         myBuilder.Add (Solid, Shell);
206         myBuilder.Add (C, Solid);
207       }
208       else
209         myBuilder.Add (C, Shell);
210     }
211     else {
212       if (myImageShape.HasImage( S )) {
213         for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next())
214           myBuilder.Add (C, it.Value());
215       }
216     }
217   }
218   
219   myShape = C;
220 }
221
222 //=======================================================================
223 //function : Modified
224 //purpose  : 
225 //=======================================================================
226   const TopTools_ListOfShape& NMTAlgo_Splitter::Modified (const TopoDS_Shape& S) 
227
228 {
229   myGenerated.Clear();
230   TopTools_ListIteratorOfListOfShape it;
231   TopTools_MapOfShape aMap;
232   TopExp_Explorer anExp;
233
234   if(S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_EDGE) {
235
236     if(S.ShapeType() == TopAbs_FACE) { 
237       if (myImagesFaces.HasImage( S )) {
238         it.Initialize(myImagesFaces.Image(S));
239         anExp.Init(myShape, TopAbs_FACE);
240       }
241     }
242     else {
243       if (myImagesEdges.HasImage( S )) {
244         it.Initialize(myImagesEdges.Image(S));
245         anExp.Init(myShape, TopAbs_EDGE);
246       }
247     }
248   
249     for(; anExp.More(); anExp.Next()) {
250       aMap.Add(anExp.Current());
251     }
252
253     for (; it.More(); it.Next()) {
254       if(aMap.Contains(it.Value())) {
255         myGenerated.Append(it.Value());
256       }
257     }
258
259     return myGenerated;
260
261   }
262
263   if(S.ShapeType() == TopAbs_VERTEX) {
264     
265     const NMTTools_DSFiller& aDSF = Filler();
266     const NMTTools_PaveFiller& aPF = aDSF.PaveFiller();
267     const NMTDS_ShapesDataStructure& aDS = aDSF.DS();
268
269     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
270     Standard_Integer anIndex = 0, i;
271
272     for(i = 1; i <= aNbS; ++i) {
273
274       const TopoDS_Shape& aS = aDS.Shape(i);
275       if(S.IsSame(aS)) {
276         anIndex = i;
277         break;
278       }
279
280     }
281
282     if(anIndex == 0) return myGenerated;
283
284     Standard_Integer aSDVInd = aPF.FindSDVertex(anIndex);
285
286     if(aSDVInd == 0) return myGenerated;
287
288     const TopoDS_Shape aSDV = aDS.Shape(aSDVInd);
289
290     anExp.Init(myShape, TopAbs_VERTEX);
291     for(; anExp.More(); anExp.Next()) {
292
293       if(aSDV.IsSame(anExp.Current())) {
294         myGenerated.Append(aSDV);
295         break;
296       }
297
298     }
299     
300   }
301
302   return myGenerated;
303 }
304 //=======================================================================
305 //function : Generated
306 //purpose  : 
307 //=======================================================================
308   const TopTools_ListOfShape& NMTAlgo_Splitter::Generated(const TopoDS_Shape& S) 
309 {
310   myGenerated.Clear();
311   TopTools_ListIteratorOfListOfShape it;
312   TopTools_MapOfShape aMap;
313   TopExp_Explorer anExp;
314   Standard_Boolean bCheckVert = Standard_False;
315
316   if(S.ShapeType() == TopAbs_FACE) {
317     if (mySectionParts.Contains(S)) {
318       it.Initialize(mySectionParts.FindFromKey(S));
319       anExp.Init(myShape, TopAbs_EDGE);
320   
321       for(; anExp.More(); anExp.Next()) {
322         aMap.Add(anExp.Current());
323       }
324
325       for (; it.More(); it.Next()) {
326         if(aMap.Contains(it.Value())) {
327           myGenerated.Append(it.Value());
328         }
329       }
330     }
331
332     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
333     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
334     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
335
336     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
337     Standard_Integer anIndex = 0, i;
338
339     for(i = 1; i <= aNbS; ++i) {
340
341       const TopoDS_Shape& aS = aDS.Shape(i);
342       if(S.IsSame(aS)) {
343         anIndex = i;
344         break;
345       }
346
347     }
348
349     if(anIndex == 0) return myGenerated;
350     if(!anIP->HasInterference(anIndex)) return myGenerated;
351
352     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
353     Standard_Integer aNbI = aESs.Extent();
354
355     if(aNbI == 0) return myGenerated;
356
357     for(i = 1; i <= aNbI; ++i) {
358
359       const BOPTools_ESInterference& aES = aESs(i);
360       Standard_Integer ind1, ind2;
361       aES.Indices(ind1, ind2);
362
363       if(ind1 == anIndex || ind2 == anIndex) {
364
365         Standard_Integer aNSI = aES.NewShape();
366         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
367           myGenerated.Append(aDS.Shape(aNSI));
368           bCheckVert = Standard_True;
369         }
370      
371       }
372
373     }
374           
375     if(bCheckVert) {
376       aMap.Clear();
377       anExp.Init(myShape, TopAbs_VERTEX);
378   
379       for(; anExp.More(); anExp.Next()) {
380         aMap.Add(anExp.Current());
381       }
382
383       it.Initialize(myGenerated);
384       for (; it.More(); it.Next()) {
385
386         if(it.Value().ShapeType() != TopAbs_VERTEX) continue;
387         
388         if(!aMap.Contains(it.Value())) {
389           myGenerated.Remove(it);
390         }
391
392       }
393     }
394    
395     return myGenerated;
396   }
397
398   if(S.ShapeType() == TopAbs_EDGE) {
399
400     NMTTools_PaveFiller& aPF = myDSFiller->ChangePaveFiller();
401     const NMTDS_ShapesDataStructure& aDS = myDSFiller->DS();
402     const BOPTools_PInterferencePool& anIP = aPF.InterfPool();
403
404     Standard_Integer aNbS = aDS.NumberOfSourceShapes();
405     Standard_Integer anIndex = 0, i;
406
407     for(i = 1; i <= aNbS; ++i) {
408
409       const TopoDS_Shape& aS = aDS.Shape(i);
410       if(S.IsSame(aS)) {
411         anIndex = i;
412         break;
413       }
414
415     }
416
417     if(anIndex == 0) return myGenerated;
418     if(!anIP->HasInterference(anIndex)) return myGenerated;
419
420     const BOPTools_CArray1OfEEInterference& aEEs = anIP->EEInterferences();
421     Standard_Integer aNbI = aEEs.Extent();
422
423     for(i = 1; i <= aNbI; ++i) {
424
425       const BOPTools_EEInterference& aEE = aEEs(i);
426       Standard_Integer ind1, ind2;
427       aEE.Indices(ind1, ind2);
428
429       if(ind1 == anIndex || ind2 == anIndex) {
430
431         Standard_Integer aNSI = aEE.NewShape();
432         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
433           myGenerated.Append(aDS.Shape(aNSI));
434           bCheckVert = Standard_True;
435         }
436      
437       }
438           
439     }    
440
441     const BOPTools_CArray1OfESInterference& aESs = anIP->ESInterferences();
442     aNbI = aESs.Extent();
443
444     for(i = 1; i <= aNbI; ++i) {
445
446       const BOPTools_ESInterference& aES = aESs(i);
447       Standard_Integer ind1, ind2;
448       aES.Indices(ind1, ind2);
449
450       if(ind1 == anIndex || ind2 == anIndex) {
451
452         Standard_Integer aNSI = aES.NewShape();
453         if(aDS.GetShapeType(aNSI) == TopAbs_VERTEX) {
454           myGenerated.Append(aDS.Shape(aNSI));
455           bCheckVert = Standard_True;
456         }
457      
458       }
459           
460     }    
461
462     if(bCheckVert) {
463       aMap.Clear();
464       anExp.Init(myShape, TopAbs_VERTEX);
465   
466       for(; anExp.More(); anExp.Next()) {
467         aMap.Add(anExp.Current());
468       }
469
470       it.Initialize(myGenerated);
471       for (; it.More(); it.Next()) {
472
473         if(!aMap.Contains(it.Value())) {
474           myGenerated.Remove(it);
475         }
476
477       }
478     }
479
480     return myGenerated;
481   
482   }
483
484   return myGenerated;
485 }
486
487 //=======================================================================
488 //function : IsDeleted
489 //purpose  : 
490 //=======================================================================
491   Standard_Boolean NMTAlgo_Splitter::IsDeleted (const TopoDS_Shape& S) 
492
493 {
494   const TopTools_ListOfShape& aL = Modified(S);
495   if(aL.Extent() != 0) return Standard_False;
496
497   TopTools_MapOfShape aMap;
498   TopExp_Explorer anExp;
499
500   TopAbs_ShapeEnum aType = S.ShapeType();
501
502   if(aType == TopAbs_VERTEX || 
503      aType == TopAbs_EDGE   || 
504      aType == TopAbs_FACE     ) {
505
506     anExp.Init(myShape, aType);
507     for(; anExp.More(); anExp.Next()) {
508       if(S.IsSame(anExp.Current())) return Standard_False;
509     }
510
511   }
512   
513   return Standard_True;
514 }
515