]> SALOME platform Git repositories - modules/geom.git/blob - src/NMTAlgo/NMTAlgo_Splitter_1.cxx
Salome HOME
Change comments style in geompy.py for right processing with HappyDoc
[modules/geom.git] / src / NMTAlgo / NMTAlgo_Splitter_1.cxx
1 // File:        NMTAlgo_Splitter_1.cxx
2 // Created:     Mon Feb  2 14:58:54 2004
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6
7 #include <NMTAlgo_Splitter.ixx>
8 #include <TopExp_Explorer.hxx>
9 #include <TopoDS_Shape.hxx>
10 #include <TopoDS_Compound.hxx>
11 #include <TopTools_MapOfShape.hxx>
12 #include <TopTools_DataMapOfShapeListOfShape.hxx>
13 #include <TopTools_MapIteratorOfMapOfShape.hxx>
14 #include <TopTools_ListOfShape.hxx>
15 #include <TopTools_ListIteratorOfListOfShape.hxx>
16 #include <TopExp.hxx>
17 #include <TopoDS_Iterator.hxx>
18 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
19 #include <TopoDS.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <NMTAlgo_Loop3d.hxx>
23 #include <Precision.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepClass3d_SolidClassifier.hxx>
26 #include <gp_Pnt.hxx>
27 #include <TopoDS_Solid.hxx>
28 #include <NMTAlgo_Loop3d.hxx>
29 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
30
31 //=======================================================================
32 //function : ShellsAndSolids
33 //purpose  : 
34 //=======================================================================
35   void NMTAlgo_Splitter::ShellsAndSolids()
36 {
37   Standard_Boolean bMakeSolids;
38   TopAbs_ShapeEnum aType;
39   TopTools_ListIteratorOfListOfShape aItS;
40   TopTools_ListOfShape aLNS;
41   //
42   myAddedFacesMap.Clear();
43   bMakeSolids=(myLimit==TopAbs_SHAPE || myLimit<TopAbs_SHELL);
44   //
45   aItS.Initialize(myListShapes);
46   for ( ;aItS.More(); aItS.Next()) {
47     const TopoDS_Shape& aS=aItS.Value();
48     //
49     if (myToolShapes.Contains(aS)) {
50       continue;
51     }
52     //
53     aType=aS.ShapeType();
54     if (aType > TopAbs_SHELL) {
55       continue;//face,wire,...
56     }
57     //
58     aLNS.Clear();
59     //
60     MakeShells (aS, aLNS);
61     //
62     if (bMakeSolids && aType==TopAbs_SOLID) {
63       MakeSolids(aS, aLNS);
64     }
65     //
66     TopTools_ListIteratorOfListOfShape it (aLNS);
67     for (; it.More(); it.Next()) {
68       myBuilder.Add (myShape, it.Value());
69     }
70   }
71   //
72   // add split faces
73   aItS.Initialize(myListShapes);
74   for ( ;aItS.More(); aItS.Next()) {
75     const TopoDS_Shape& aS=aItS.Value();
76     //
77     aType=aS.ShapeType();
78     if (aType!=TopAbs_FACE || myMapTools.Contains(aS)) {
79       continue; 
80     }
81     //
82     const TopoDS_Shape& aCSF=myImageShape.Image(aS).First();
83     TopoDS_Iterator itS(aCSF);
84     for (; itS.More(); itS.Next()){
85       const TopoDS_Shape& aF=itS.Value();
86       if (!myAddedFacesMap.Contains(aF)){
87         myBuilder.Add (myShape, aF);
88       }
89     }
90   }
91 }
92 //=======================================================================
93 //function : MakeShells
94 //purpose  : split S into compound of shells
95 //=======================================================================
96   void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
97                                     TopTools_ListOfShape& aLNS)
98 {
99   NMTAlgo_Loop3d aShellMaker;
100   //
101   // get compound of split faces of aS
102   const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
103   aShellMaker.AddConstFaces(aFC);
104   //
105   // add split faces inside aS
106   if (myClosedShapes.Contains(aS)) {
107     //
108     // internal faces compound  
109     //modified by NIZNHY-PKV Thu Dec 23 16:34:05 2004 f
110     Standard_Integer aNbIF;
111     //
112     aNbIF=myInternalFaces.Extent();
113     //modified by NIZNHY-PKV Thu Dec 23 16:34:07 2004 t
114     TopoDS_Shape aIFC=FindFacesInside(aS, Standard_True);
115     aNbIF=myInternalFaces.Extent();
116     aShellMaker.AddSectionFaces(aIFC);
117   }
118   //
119   aLNS=aShellMaker.MakeShells(myAddedFacesMap);
120   //
121   // Add faces added to new shell to myAddedFacesMap:
122   // avoid rebuilding twice common part of 2 solids.
123   
124   TopTools_ListIteratorOfListOfShape itS(aLNS);
125   TopExp_Explorer expF;
126   for (; itS.More(); itS.Next()) {
127     const TopoDS_Shape& aSh=itS.Value();
128     expF.Init (aSh, TopAbs_FACE);
129     for (; expF.More(); expF.Next()){
130       myAddedFacesMap.Add (expF.Current());
131     }
132   }
133   
134 }
135 //=======================================================================
136 //function : MakeSolids
137 //purpose  : make solids out of Shells
138 //=======================================================================
139   void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape&   theSolid,
140                                     TopTools_ListOfShape& theShellList)
141 {
142   // for a solid wrapping other shells or solids without intersection,
143   // it is necessary to find shells making holes in it
144   Standard_Boolean isWrapping;
145   TopTools_ListOfShape aNewSolids; // result
146   TopTools_ListOfShape aHoleShells;
147   TopoDS_Shape anInfinitePointShape;
148   TopTools_DataMapOfShapeShape aInOutMap;
149   TopTools_ListIteratorOfListOfShape aShellIt, aSolisIt;
150   //
151   isWrapping = myWrappingSolid.Contains(theSolid);
152   if (!isWrapping && !theShellList.IsEmpty())  {
153     // check if theSolid initially has internal shells
154     TopoDS_Iterator aShellExp (theSolid);
155     aShellExp.Next();
156     isWrapping = aShellExp.More();
157   }
158   //
159   aShellIt.Initialize(theShellList);
160   for ( ; aShellIt.More(); aShellIt.Next()) {
161     const TopoDS_Shape & aShell = aShellIt.Value();
162     // check if a shell is a hole of theSolid
163     if (isWrapping && IsInside(anInfinitePointShape, aShell)){
164       aHoleShells.Append(aShell);
165     }
166     else {
167       // make a solid from a shell
168       TopoDS_Solid Solid;
169       myBuilder.MakeSolid( Solid );
170       myBuilder.Add (Solid, aShell);
171
172       aNewSolids.Append (Solid);
173     }
174   }
175   //
176   // find outer a shell most close to each hole shell
177   aShellIt.Initialize(aHoleShells);
178   for (; aShellIt.More(); aShellIt.Next()){
179     const TopoDS_Shape & aHole = aShellIt.Value();
180     //
181     aSolisIt.Initialize(aNewSolids);
182     for ( ; aSolisIt.More(); aSolisIt.Next())    {
183       const TopoDS_Shape & aSolid = aSolisIt.Value();
184       //
185       if (! IsInside(aHole, aSolid)){
186         continue;
187       }
188       //
189       if ( aInOutMap.IsBound (aHole)){
190         const TopoDS_Shape & aSolid2 = aInOutMap( aHole );
191         if ( IsInside( aSolid, aSolid2 )) {
192           aInOutMap.UnBind( aHole );
193           aInOutMap.Bind ( aHole, aSolid );
194         }
195       }
196       else{
197         aInOutMap.Bind (aHole, aSolid);
198       }
199     }
200     //
201     // add aHole to a solid
202     if (aInOutMap.IsBound( aHole )){
203       TopoDS_Shape & aSolid=aInOutMap(aHole);
204       myBuilder.Add (aSolid, aHole);
205     }
206   }
207   theShellList.Clear();
208   theShellList.Append( aNewSolids );
209 }
210  
211 //=======================================================================
212 //function : FindFacesInside
213 //purpose  : return compound of faces  of other shapes that are
214 //           inside <theShape>. 
215 //           <theShape> is an object shape.
216 //           <CheckClosed> makes avoid faces that do not form a
217 //           closed shell
218 //           <All> makes return already added faces
219 //=======================================================================
220   TopoDS_Shape NMTAlgo_Splitter::FindFacesInside(const TopoDS_Shape& theShape,
221                                                 const Standard_Boolean CheckClosed,
222                                                 const Standard_Boolean All)
223 {
224   TopExp_Explorer expl;
225   //
226   // ================================================
227   // check if internal faces have been already found
228   // ================================================
229   if (myInternalFaces.IsBound(theShape)) {
230     TopoDS_Shape aIntFComp = myInternalFaces.Find (theShape);
231     TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find (theShape);
232
233     expl.Init( aIntRemFComp, TopAbs_FACE);
234     if (CheckClosed || !expl.More()){
235       return aIntFComp;
236     }
237     //
238     TopoDS_Compound C;
239     myBuilder.MakeCompound( C );
240     // add removed faces
241     for (; expl.More(); expl.Next()){
242       myBuilder.Add( C, expl.Current() );
243     }
244     // add good internal faces
245     expl.Init( aIntFComp, TopAbs_FACE);
246     for (; expl.More(); expl.Next()) {
247       myBuilder.Add( C, expl.Current() );
248     }
249     //
250     return C;
251   }
252
253   // ===================================
254   // get data for internal faces search
255   // ===================================
256   //
257   TopTools_MapOfShape MSE, MFP;
258   TopTools_DataMapOfShapeListOfShape DMSEFP;
259   TopTools_IndexedDataMapOfShapeListOfShape DMEF;
260   TopTools_MapIteratorOfMapOfShape itm;
261   TopTools_ListOfShape EmptyL;
262   TopTools_ListIteratorOfListOfShape itl;
263   //
264   // compound of split faces of theShape 
265   const TopoDS_Shape& CSF=myImageShape.Image(theShape).First();
266   // MSE filling: map of new section edges of CSF
267   expl.Init(CSF, TopAbs_EDGE);
268   for (; expl.More(); expl.Next()) {
269     const TopoDS_Shape& aE = expl.Current() ;
270     MSE.Add(aE);
271   }
272   //
273   // DMEF: map edge of CSF - faces of CSF
274   TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF);
275   //
276   // Fill
277   // 1.  MFP - a map of faces to process: map of resulting faces except
278   // those of theShape; we`ll add to C those of them which are inside CSF
279   // 2.  DMSEFP - edge of MSE => faces of MFP
280   //
281   itl.Initialize(myListShapes);
282   for (;itl.More(); itl.Next()) {
283     const TopoDS_Shape& aShape = itl.Value();
284     //
285     if ( theShape.IsSame(aShape)) {
286       continue;
287     }
288     // fill maps
289     // iterate on split faces of aShape
290     const TopoDS_Shape& CSF1 = myImageShape.Image(aShape).First();
291     TopoDS_Iterator itF (CSF1);
292     for ( ; itF.More(); itF.Next()) {
293       const TopoDS_Shape& aF1 = itF.Value();
294       MFP.Add(aF1);
295       // iterate on edges of split faces of aShape,
296       // add to DMSEFP edges that are new
297       expl.Init(aF1, TopAbs_EDGE);
298       for (; expl.More(); expl.Next()) {
299         TopoDS_Shape aE1 = expl.Current();
300         if ( MSE.Contains(aE1)) {// section edge
301           if (!DMSEFP.IsBound(aE1)) {
302             DMSEFP.Bind(aE1, EmptyL);
303           }
304           DMSEFP(aE1).Append(aF1);
305         }
306       }
307     }
308   }//for (;itl.More(); itl.Next()) 
309   //
310   // ===========================
311   // find faces inside theShape
312   // ===========================
313   Standard_Boolean skipAlreadyAdded = Standard_False;
314   Standard_Boolean GoodOri, inside, sameDom1, sameDom2, isSectionE;
315   Standard_Real dot;
316   TopoDS_Face aFace1, anOrigFace,  origF1, origF2; //, anOrigFace2;
317   TopTools_ListOfShape KeepFaces;
318   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
319   //
320   // iterate on section edges, check faces of other shapes
321   // sharing section edges and put internal faces to KeepFaces
322   Mapit.Initialize(DMSEFP);
323   for (; Mapit.More() ; Mapit.Next() ) {
324     // a new edge of theShape
325     const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
326     // 
327     isSectionE=IsSectionEdge(E); 
328     //
329     // split faces of other shapes sharing E
330     TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
331     //
332     itl.Initialize( LSF );
333     while (itl.More()) {
334       // a split faces of other shape
335       aFace1 = TopoDS::Face(itl.Value());
336       // remove aFace1 form DMSEFP and MFP
337       LSF.Remove( itl ); // == itl.Next();
338       if (!MFP.Remove( aFace1 ))
339         continue; // was not is MFP ( i.e already checked)
340       //
341       // check if aFace1 was already added to 2 shells
342       if (!All &&
343           myAddedFacesMap.Contains(aFace1) &&
344           myAddedFacesMap.Contains(aFace1.Reversed())) {
345         skipAlreadyAdded = Standard_True;
346       }
347       //
348       // find another face which originates from the same face as aFace1:
349       // usually aFace2 is internal if aFace1 is not and vice versa
350       anOrigFace = aFace1;
351       if (myImagesFaces.IsImage(aFace1)){
352         anOrigFace = TopoDS::Face(myImagesFaces.Root(aFace1));
353       }
354       //
355       //modified by NIZNHY-PKV Fri Dec 24 10:59:45 2004 f
356       /*
357       TopoDS_Face aFace2;
358       //
359       if (!isSectionE) {
360         while (itl.More()) { //#2
361           aFace2 = TopoDS::Face(itl.Value());
362           //
363           anOrigFace2 = aFace2;
364           if (myImagesFaces.IsImage(aFace2)) {
365             anOrigFace2 = TopoDS::Face(myImagesFaces.Root(aFace2));
366           }
367           //
368           if (!MFP.Contains( aFace2 )) {
369             LSF.Remove( itl );
370             continue;
371           }
372           //
373           if (anOrigFace.IsSame(anOrigFace2)) {
374             break;
375           }
376           itl.Next();
377         }// while (itl.More()) { #2
378         //
379         if (itl.More()) { // aFace2 found, remove it from maps
380           LSF.Remove( itl );
381           MFP.Remove(aFace2);
382         }
383         else{
384           aFace2.Nullify();
385         }
386         itl.Initialize( LSF );
387       } // if (!isSectionE) {
388       */
389       //modified by NIZNHY-PKV Fri Dec 24 10:59:52 2004 t
390       //
391       // check that anOrigFace is not same domain with CSF faces it intersects
392       //
393       //faces of CSF sharing E
394       //
395       const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); 
396       const TopoDS_Face& aFE1=TopoDS::Face(FL.First());
397       const TopoDS_Face& aFE2=TopoDS::Face(FL.Last());
398       //
399       origF1=aFE1;
400       if (myImagesFaces.IsImage(aFE1)) {
401         origF1=TopoDS::Face(myImagesFaces.Root(aFE1));
402       }
403       origF2=aFE2;
404       if (myImagesFaces.IsImage(aFE2)) {
405         origF2=TopoDS::Face(myImagesFaces.Root(aFE2));
406       }
407       //
408       sameDom1 = anOrigFace.IsSame( origF1 );
409       sameDom2 = anOrigFace.IsSame( origF2 );
410       //
411       if (!(sameDom1 || sameDom2) && HasSameDomainF(anOrigFace)) {       
412         sameDom1 = IsSameDomainF(anOrigFace, origF1);
413         if (origF1 == origF2) {
414           sameDom2 = sameDom1;
415         }
416       }
417       //
418       if (sameDom1 && sameDom2){
419         continue;
420       }
421       //
422       if (sameDom1 || sameDom2) {
423         inside = NMTAlgo_Loop3d::IsInside (E, aFE1, aFE2, 1, dot, GoodOri);
424         if (inside || (dot + Precision::Angular() >= 1.0)) {
425           continue; // E is convex between origF1 and origF2 or they are tangent
426         }
427       }
428       //
429       // Keep one of found faces
430       //
431       //face of CSF sharing E
432       const TopoDS_Face& aShapeFace = sameDom1 ? aFE2 : aFE1;
433       // analyse aFace1 state
434       inside = NMTAlgo_Loop3d::IsInside (E, aShapeFace, aFace1, 1, dot, GoodOri);
435       if (inside) { //IFV 27.08.04
436         // aFace1 must be tested with both adjacent faces of CSF
437         const TopoDS_Face& aShapeFace2 = sameDom1 ? aFE1 : aFE2;
438         if (aShapeFace2 != aShapeFace){
439           inside = 
440             NMTAlgo_Loop3d::IsInside(E, aShapeFace2, aFace1, 1, dot, GoodOri);
441         }
442       }
443       //
444       // store internal face
445       if (inside) {
446         KeepFaces.Append(aFace1);
447       }
448       //
449       //modified by NIZNHY-PKV Fri Dec 24 11:02:55 2004 f
450       /*
451       else if (!aFace2.IsNull()) {
452         if (dot + Precision::Angular() >= 1.0) {
453           // aFace2 state is not clear, it will be analysed alone, put it back to the maps
454           MFP.Add(aFace2);
455           LSF.Append(aFace2);
456         }
457         else {
458           KeepFaces.Append(aFace2);
459         }
460       }
461       */
462       //modified by NIZNHY-PKV Fri Dec 24 11:03:03 2004 t
463     }// while (itl.More()) {
464   }// for (; Mapit.More() ; Mapit.Next() ) {
465   //
466   // ===================================================
467   // add not distributed faces connected with KeepFaces
468   // ===================================================
469   // ultimate list of internal faces
470   TopTools_ListOfShape KeptFaces;
471   //
472   if (MFP.IsEmpty())
473     KeptFaces.Append (KeepFaces);
474   //
475   while (!KeepFaces.IsEmpty()) {
476     // KeepEdges : map of edges of faces kept last time
477     TopTools_IndexedMapOfShape KeepEdges;
478     for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) {
479       TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
480       KeptFaces.Append( itl.Value() );
481     }
482     //
483     KeepFaces.Clear();
484     //
485     // keep faces connected with already kept faces by KeepEdges
486     for ( itm.Initialize(MFP); itm.More(); itm.Next() ) {
487       const TopoDS_Shape& FP = itm.Key();
488       for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) {
489         const TopoDS_Shape& se = expl.Current();
490         if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
491           KeepFaces.Append(FP);
492           MFP.Remove(FP);
493           break;
494         }
495       }
496     }
497   }
498
499   // ===============================================================
500   // here MFP contains faces outer of theShape and those of shapes
501   // which do not interfere with theShape at all and between which
502   // there may be those wrapped by theShape and whose faces may be
503   // needed to be returned as well
504   // ===============================================================
505
506   Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
507   if (All || isSolid)  // All is for sub-result removal
508   {
509     for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
510       TopoDS_Shape aFace = itm.Key();
511
512       // find a shape aFace originates from
513       TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
514
515       // find out if all faces of anOrigShape are not in MFP
516       // and by the way remove them from MFP
517       Standard_Boolean isAllOut = Standard_True;
518       TopoDS_Shape aSplitFaces = anOrigShape;
519       if (myImageShape.HasImage(anOrigShape))
520         aSplitFaces = myImageShape.Image(anOrigShape).First();
521
522       TopTools_ListOfShape aSplitFaceL;
523       for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
524       {
525         const TopoDS_Shape & aSpFace = expl.Current();
526         // a tool face which become object has image but the whole tool shape has not
527         if (myImageShape.HasImage( aSpFace ))
528         {
529           TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
530           for ( ; exF.More(); exF.Next() )
531           {
532             aSplitFaceL.Append( exF.Current() );
533             if ( ! MFP.Remove( exF.Current() ))
534               isAllOut = Standard_False;
535           }
536         }
537         else
538         {
539           aSplitFaceL.Append( aSpFace );
540           if ( ! MFP.Remove( aSpFace ))
541             isAllOut = Standard_False;
542         }
543       }
544       itm.Initialize( MFP );
545       if ( !isAllOut )
546         continue;
547
548       // classify anOrigShape against theShape
549       if (IsInside (anOrigShape, theShape)) {
550         if (isSolid && myClosedShapes.Contains(anOrigShape)) {
551           // to make a special care at solid reconstruction
552           myWrappingSolid.Add ( theShape );
553         }
554         // keep faces of an internal shape anOrigShape
555         KeptFaces.Append( aSplitFaceL );
556       }
557     }
558   }
559
560   // ====================================================
561   // check if kept faces form a shell without free edges
562   // ====================================================
563
564   DMEF.Clear();  // edge - kept faces
565   MFP.Clear(); // reuse it for wrong faces
566   if (CheckClosed) {
567     for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) 
568       TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF);
569
570     Standard_Integer i, nb = DMEF.Extent();
571     Standard_Boolean isClosed = Standard_False;
572     while (!isClosed) {
573       isClosed = Standard_True;
574       for (i=1;  isClosed && i<=nb;  ++i) {
575         const TopoDS_Shape& E = DMEF.FindKey( i );
576         if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) &&
577             ! MSE.Contains( E ))
578           isClosed = ( DMEF(i).Extent() != 1 );
579       }
580       if (!isClosed) {
581         const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face
582         MFP.Add( F ); 
583         // remove bad face from DMEF
584         for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
585           const TopoDS_Shape& E = expl.Current();
586           TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E );
587           for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
588             if ( F.IsSame( itl.Value() )) {
589               FL.Remove( itl );
590               break;
591             }
592           }
593         }
594       }
595     }
596   }
597
598   // ==============
599   // make a result
600   // ==============
601
602   TopoDS_Compound C;
603   // compound of removed internal faces
604   TopoDS_Compound CNotCl;
605
606   myBuilder.MakeCompound(C);
607   myBuilder.MakeCompound(CNotCl);
608
609   // add to compounds
610   itl.Initialize(KeptFaces);
611   for (; itl.More(); itl.Next() ) {
612     TopoDS_Shape & aIntFace = itl.Value();
613     //
614     if (!All &&
615         myAddedFacesMap.Contains(aIntFace) &&
616         myAddedFacesMap.Contains(aIntFace.Reversed())) {
617       continue;
618     }
619     //
620     if (! MFP.Contains( aIntFace )){
621       myBuilder.Add(C, aIntFace);
622     }
623     else{
624       myBuilder.Add(CNotCl, aIntFace);
625     }
626   }
627   //
628   if (!skipAlreadyAdded && CheckClosed) {
629     myInternalFaces.Bind(theShape, C);
630     myIntNotClFaces.Bind(theShape, CNotCl);
631   }
632   //
633   //
634   if (!myMapSIFC.IsBound(theShape)) {
635     TopoDS_Compound aCIF;
636     myBuilder.MakeCompound(aCIF);
637     //
638     itl.Initialize(KeptFaces);
639     for (; itl.More(); itl.Next() ) {
640       TopoDS_Shape & aIntFace = itl.Value();
641       if (! MFP.Contains(aIntFace )){
642         myBuilder.Add(aCIF, aIntFace);
643       }
644     }
645     myMapSIFC.Bind(theShape, aCIF);
646   }
647   //
648   return C;
649 }
650 //=======================================================================
651 //function : IsInside
652 //purpose  : Return True if the first vertex of S1 inside S2.
653 //           If S1.IsNull(), check infinite point against S2.
654 //=======================================================================
655   Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
656                                                const TopoDS_Shape& theS2)
657 {
658   BRepClass3d_SolidClassifier aClassifier( theS2 );
659   //
660   TopExp_Explorer expl(theS1, TopAbs_VERTEX);
661   //
662   if (!expl.More()){
663     aClassifier.PerformInfinitePoint( ::RealSmall());
664   }
665   else  {
666     const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
667     aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
668                          BRep_Tool::Tolerance( aVertex ));
669   }
670   //
671   return ( aClassifier.State() == TopAbs_IN );
672 }
673
674 //=======================================================================
675 //function : GetOriginalShape
676 //purpose  : Return the  shape  aShape  originates from. aShape
677 //           should be a face or more complex result shape
678 //=======================================================================
679   TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
680 {
681   TopoDS_Shape anOrigShape;
682
683   TopExp_Explorer expl( theShape, TopAbs_FACE);
684   if (expl.More()) {
685     TopoDS_Shape aFace = expl.Current();
686     if (myImagesFaces.IsImage( aFace ))
687       aFace = myImagesFaces.Root( aFace );
688     anOrigShape = myFaceShapeMap.Find( aFace );
689   }
690   return anOrigShape;
691 }