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