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