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