eb901c57e6a361e0e8f231563be3fe80647478b9
[occt.git] / src / ShapeFix / ShapeFix_Solid.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Bnd_Box2d.hxx>
16 #include <BRep_Builder.hxx>
17 #include <BRep_Tool.hxx>
18 #include <BRepClass3d_SolidClassifier.hxx>
19 #include <Geom_Curve.hxx>
20 #include <Geom_Surface.hxx>
21 #include <gp_Pnt.hxx>
22 #include <Message_Msg.hxx>
23 #include <Message_ProgressIndicator.hxx>
24 #include <Message_ProgressSentry.hxx>
25 #include <Precision.hxx>
26 #include <ShapeAnalysis.hxx>
27 #include <ShapeAnalysis_Curve.hxx>
28 #include <ShapeAnalysis_Edge.hxx>
29 #include <ShapeAnalysis_FreeBounds.hxx>
30 #include <ShapeBuild_ReShape.hxx>
31 #include <ShapeExtend.hxx>
32 #include <ShapeExtend_BasicMsgRegistrator.hxx>
33 #include <ShapeExtend_WireData.hxx>
34 #include <ShapeFix_Shell.hxx>
35 #include <ShapeFix_Solid.hxx>
36 #include <Standard_ErrorHandler.hxx>
37 #include <Standard_Failure.hxx>
38 #include <Standard_Type.hxx>
39 #include <TopAbs.hxx>
40 #include <TopExp.hxx>
41 #include <TopoDS.hxx>
42 #include <TopoDS_CompSolid.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Shell.hxx>
47 #include <TopoDS_Solid.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopoDS_Wire.hxx>
50 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
52 #include <TopTools_DataMapOfShapeInteger.hxx>
53 #include <TopTools_DataMapOfShapeListOfShape.hxx>
54 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
55 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
56 #include <TopTools_IndexedMapOfShape.hxx>
57 #include <TopTools_ListIteratorOfListOfShape.hxx>
58 #include <TopTools_ListOfShape.hxx>
59 #include <TopTools_MapIteratorOfMapOfShape.hxx>
60 #include <TopTools_MapOfShape.hxx>
61 #include <TopTools_SequenceOfShape.hxx>
62
63 IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Solid,ShapeFix_Root)
64
65 //======================================================
66 //function : ShapeFix_Solid
67 //purpose  : 
68 //=======================================================================
69 ShapeFix_Solid::ShapeFix_Solid()
70 {
71   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
72   myFixShellMode = -1;
73   myFixShell = new ShapeFix_Shell;
74   myCreateOpenSolidMode = Standard_False;
75 }
76
77 //=======================================================================
78 //function : ShapeFix_Solid
79 //purpose  : 
80 //=======================================================================
81
82 ShapeFix_Solid::ShapeFix_Solid(const TopoDS_Solid& solid)
83 {
84   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
85   myFixShellMode = -1;
86   myFixShell = new ShapeFix_Shell;
87   myCreateOpenSolidMode = Standard_False;
88   Init(solid);
89 }
90
91 //=======================================================================
92 //function : Init
93 //purpose  : 
94 //=======================================================================
95
96  void ShapeFix_Solid::Init(const TopoDS_Solid& solid) 
97 {
98   mySolid = solid;
99   //mySolid = TopoDS::Solid(shape.EmptyCopied());
100   //BRep_Builder B;
101  // for( TopoDS_Iterator iter(solid); iter.More(); iter.Next()) 
102  //  B.Add(mySolid,TopoDS::Shell(iter.Value()));
103   myShape = solid;
104 }
105 #ifdef OCCT_DEBUG_GET_MIDDLE_POINT
106 //=======================================================================
107 //function : GetMiddlePoint
108 //purpose  : 
109 //=======================================================================
110 static void GetMiddlePoint(const TopoDS_Shape& aShape, gp_Pnt& pmid)
111 {
112   TopExp_Explorer aExp(aShape,TopAbs_EDGE);
113   gp_XYZ center(0.0,0.0,0.0);
114   Standard_Integer numpoints =0;
115   for( ; aExp.More(); aExp.Next()) {
116     TopoDS_Edge e1 = TopoDS::Edge(aExp.Current());
117     Standard_Real f,l;
118     Handle(Geom_Curve) c3d = BRep_Tool::Curve(e1,f,l);
119     if(!c3d.IsNull()) {
120       for(Standard_Integer i =1 ; i <=5; i++) {
121         Standard_Real param = f+(l-f)/4*(i-1);
122         gp_Pnt pt;
123         numpoints++;
124         c3d->D0(param,pt);
125         center+=pt.XYZ();
126       
127       }
128     }
129   }
130   center /= numpoints;
131   pmid.SetXYZ(center);
132 }
133 #endif
134 //=======================================================================
135 //function : CollectSolids
136 //purpose  : 
137 //=======================================================================
138 static void CollectSolids(const TopTools_SequenceOfShape& aSeqShells , 
139                           TopTools_IndexedDataMapOfShapeListOfShape& anIndexedMapShellHoles,
140                           TopTools_DataMapOfShapeInteger& theMapStatus)
141 {
142   TopTools_MapOfShape aMapHoles;
143   TopTools_DataMapOfShapeListOfShape aMapShellHoles;
144   for ( Standard_Integer i1 = 1; i1 <= aSeqShells.Length(); i1++ ) {
145     TopoDS_Shell aShell1 = TopoDS::Shell(aSeqShells.Value(i1));
146     TopTools_ListOfShape lshells;
147     aMapShellHoles.Bind(aShell1,lshells);
148   }
149   //Finds roots shells and hole shells.
150   for ( Standard_Integer i = 1; i <= aSeqShells.Length(); i++ ) {
151     TopoDS_Shell aShell1 =  TopoDS::Shell(aSeqShells.Value(i));
152     TopExp_Explorer aExpEdges(aShell1,TopAbs_EDGE);
153     if(!BRep_Tool::IsClosed(aShell1) || !aExpEdges.More()) continue;
154     TopoDS_Solid solid;
155     BRep_Builder B;
156     B.MakeSolid (solid);
157     B.Add (solid,aShell1);
158     try {
159       OCC_CATCH_SIGNALS
160      TopAbs_State infinstatus = TopAbs_UNKNOWN;
161      BRepClass3d_SolidClassifier bsc3d (solid);
162      Standard_Integer st = 0;
163      if(!theMapStatus.IsBound(aShell1)) {
164          
165          bsc3d.PerformInfinitePoint(Precision::Confusion());
166          infinstatus = bsc3d.State();
167          
168          if(infinstatus != TopAbs_UNKNOWN &&  infinstatus !=TopAbs_ON)
169            st = (infinstatus == TopAbs_IN ? 1 :2);
170          theMapStatus.Bind(aShell1,st);
171          
172        
173        }
174       else {
175         st = theMapStatus.Find(aShell1);
176         if(st)
177           infinstatus =  (theMapStatus.Find(aShell1) == 1 ? TopAbs_IN : TopAbs_OUT);
178       }
179       if(!st) continue;
180       for ( Standard_Integer j = 1; j <= aSeqShells.Length(); j++ ) {
181         if(i==j) continue;
182         TopoDS_Shape aShell2 = aSeqShells.Value(j);
183         if(!BRep_Tool::IsClosed(aShell2)) continue;
184         if(aMapHoles.Contains(aShell2)) continue;
185         if(aMapShellHoles.IsBound(aShell2)) {
186           Standard_Boolean isAnalysis = Standard_False;
187           const TopTools_ListOfShape& ls = aMapShellHoles.Find(aShell2);
188           for(TopTools_ListIteratorOfListOfShape li(ls); li.More() && !isAnalysis; li.Next())
189             isAnalysis = li.Value().IsSame(aShell1);
190           if(isAnalysis) continue;
191         }
192         TopAbs_State pointstatus = TopAbs_UNKNOWN;
193         Standard_Integer numon =0;
194         TopTools_IndexedMapOfShape amapVert;
195         for(TopExp_Explorer aExpVert(aShell2,TopAbs_VERTEX); aExpVert.More() && amapVert.Extent() < 10; aExpVert.Next())
196           amapVert.Add(aExpVert.Current());
197         for(Standard_Integer k = 1; k <= amapVert.Extent() && 
198             (pointstatus ==TopAbs_UNKNOWN || (pointstatus ==TopAbs_ON && numon < 3)); k++) {
199           TopoDS_Vertex aV = TopoDS::Vertex(amapVert.FindKey(k));
200           gp_Pnt aPf =  BRep_Tool::Pnt(aV);
201           bsc3d.Perform(aPf,Precision::Confusion());
202           pointstatus =bsc3d.State();
203           if(pointstatus ==TopAbs_ON) numon++;
204         }
205         
206         if(numon == 3 && pointstatus ==TopAbs_ON) {
207 #ifdef OCCT_DEBUG_GET_MIDDLE_POINT
208           gp_Pnt pmid;
209           GetMiddlePoint(aShell2,pmid);
210           bsc3d.Perform(pmid,Precision::Confusion());
211 #endif
212           pointstatus = /*(bsc3d.State() == TopAbs_IN ? TopAbs_IN :*/TopAbs_OUT;
213         }
214         if(pointstatus != infinstatus) {
215           aMapShellHoles.ChangeFind(aShell1).Append(aShell2);
216           if( aMapHoles.Contains(aShell2))
217             aMapHoles.Remove(aShell2);
218           else aMapHoles.Add(aShell2);
219         }
220       }
221     }
222     catch(Standard_Failure const& anException) {
223 #ifdef OCCT_DEBUG
224       cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
225       anException.Print(cout); cout << endl;
226 #endif
227       (void)anException;
228       continue;
229     }
230   }
231   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItShellHoles( aMapShellHoles);
232   for(; aItShellHoles.More();aItShellHoles.Next()) {
233     if(aMapHoles.Contains(aItShellHoles.Key())) continue;
234     const TopTools_ListOfShape& lHoles =aItShellHoles.Value();
235     if(lHoles.IsEmpty()) continue;
236     for(TopTools_ListIteratorOfListOfShape lItHoles(lHoles);lItHoles.More(); lItHoles.Next()) {
237       if(aMapHoles.Contains(lItHoles.Value())) {
238         const TopTools_ListOfShape& lUnHoles = aMapShellHoles.Find(lItHoles.Value());
239         for(TopTools_ListIteratorOfListOfShape lItUnHoles(lUnHoles);lItUnHoles.More(); lItUnHoles.Next()) 
240           aMapHoles.Remove(lItUnHoles.Value());
241       }
242     }
243   }
244   for(TopTools_MapIteratorOfMapOfShape aIterHoles(aMapHoles);aIterHoles.More(); aIterHoles.Next())
245     aMapShellHoles.UnBind (aIterHoles.Key());
246
247   for (Standard_Integer i = 1; i <= aSeqShells.Length(); ++i) {
248     const TopoDS_Shape& aShell1 = aSeqShells.Value (i);
249     if (aMapShellHoles.IsBound (aShell1)) {
250       const TopTools_ListOfShape& ls = aMapShellHoles.Find (aShell1);
251       anIndexedMapShellHoles.Add (aShell1, ls);
252     }
253   }
254 }
255 //=======================================================================
256 //function : CreateSolids
257 //purpose  : 
258 //=======================================================================
259
260 static Standard_Boolean CreateSolids(const TopoDS_Shape theShape,TopTools_IndexedMapOfShape& aMapSolids)
261 {
262   TopTools_SequenceOfShape aSeqShells;
263   Standard_Boolean isDone = Standard_False;
264
265   for(TopExp_Explorer aExpShell(theShape,TopAbs_SHELL); aExpShell.More(); aExpShell.Next()) {
266     aSeqShells.Append(aExpShell.Current());
267   }
268   TopTools_IndexedDataMapOfShapeListOfShape aMapShellHoles;
269   TopTools_DataMapOfShapeInteger aMapStatus;
270   CollectSolids(aSeqShells,aMapShellHoles,aMapStatus);
271   TopTools_IndexedDataMapOfShapeShape ShellSolid;
272   //Defines correct orientation of shells
273   for (Standard_Integer i = 1; i <= aMapShellHoles.Extent(); ++i) {
274     TopoDS_Shell aShell = TopoDS::Shell(aMapShellHoles.FindKey(i));
275     TopExp_Explorer aExpEdges(aShell,TopAbs_EDGE);
276     if(!BRep_Tool::IsClosed(aShell) || !aExpEdges.More()) {
277       ShellSolid.Add(aShell,aShell);
278       isDone = Standard_True;
279       continue;
280     }
281     BRep_Builder B;
282     TopAbs_State infinstatus = TopAbs_UNKNOWN;
283     TopoDS_Solid aSolid;
284     B.MakeSolid (aSolid);
285     B.Add (aSolid,aShell);
286     if(aMapStatus.IsBound(aShell)) { 
287       Standard_Integer st = aMapStatus.Find(aShell);
288       if(st)
289         infinstatus =  (aMapStatus.Find(aShell) == 1 ? TopAbs_IN : TopAbs_OUT);
290     }
291
292     else {
293       
294     try {
295       OCC_CATCH_SIGNALS
296       BRepClass3d_SolidClassifier bsc3d (aSolid);
297       bsc3d.PerformInfinitePoint(Precision::Confusion());
298       infinstatus = bsc3d.State();
299       }
300     catch(Standard_Failure const& anException) {
301 #ifdef OCCT_DEBUG
302       cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
303       anException.Print(cout); cout << endl;
304 #endif
305       (void)anException;
306       ShellSolid.Add(aShell,aSolid);
307       continue;
308     } 
309   }
310   if (infinstatus == TopAbs_IN) {
311     isDone = Standard_True;
312     aShell.Reverse();
313     TopoDS_Solid aTmpSolid;
314     B.MakeSolid (aTmpSolid);
315     B.Add (aTmpSolid,aShell);
316     aSolid = aTmpSolid;
317   }
318     
319     const TopTools_ListOfShape& lHoles = aMapShellHoles (i);
320     for(TopTools_ListIteratorOfListOfShape lItHoles(lHoles); lItHoles.More();lItHoles.Next()) {
321       TopoDS_Shell aShellHole = TopoDS::Shell(lItHoles.Value());
322       if(aMapStatus.IsBound(aShellHole)) {
323         infinstatus = (aMapStatus.Find(aShellHole) == 1 ? TopAbs_IN : TopAbs_OUT);
324       }
325       else {
326         TopoDS_Solid solid;
327         B.MakeSolid (solid);
328         B.Add (solid,aShellHole);
329         BRepClass3d_SolidClassifier bsc3dHol (solid);
330         bsc3dHol.PerformInfinitePoint(Precision::Confusion());
331         infinstatus = bsc3dHol.State();
332       }
333       if (infinstatus == TopAbs_OUT) {
334         aShellHole.Reverse();
335         isDone = Standard_True;
336       }
337       B.Add(aSolid,aShellHole);
338     }
339     ShellSolid.Add(aShell,aSolid);
340   }
341   //Creation of compsolid from shells containing shared faces. 
342   TopTools_IndexedDataMapOfShapeListOfShape aMapFaceShells;
343   TopExp::MapShapesAndAncestors(theShape,TopAbs_FACE,TopAbs_SHELL,aMapFaceShells);
344   for(Standard_Integer i =1; i <= aMapFaceShells.Extent(); i++) {
345     const TopTools_ListOfShape& lshells = aMapFaceShells.FindFromIndex(i);
346     if(lshells.Extent() <2) continue;
347     TopoDS_CompSolid aCompSolid;
348     BRep_Builder aB;
349     aB.MakeCompSolid(aCompSolid);
350     isDone = (theShape.ShapeType() != TopAbs_COMPSOLID || isDone);
351     Standard_Integer nbSol = 0;
352
353     for(TopTools_ListIteratorOfListOfShape lItSh(lshells);lItSh.More(); lItSh.Next()) {
354       if(ShellSolid.Contains(lItSh.Value())) {
355         const TopoDS_Shape& aShape = ShellSolid.FindFromKey(lItSh.Value());
356         TopExp_Explorer aExpSol(aShape, TopAbs_SOLID);
357        
358         for(;aExpSol.More(); aExpSol.Next())
359         {
360           aB.Add(aCompSolid,aExpSol.Current());
361           nbSol++;
362         }
363       
364       }
365     }
366     if(nbSol >1)
367     {
368       for(TopTools_ListIteratorOfListOfShape lItSh1(lshells);lItSh1.More(); lItSh1.Next()) 
369       {
370         if(ShellSolid.Contains(lItSh1.Value())) 
371           ShellSolid.ChangeFromKey(lItSh1.Value()) = aCompSolid;
372       }
373     }
374     
375   }
376   for(Standard_Integer kk =1 ; kk <= ShellSolid.Extent();kk++)
377     if(!aMapSolids.Contains(ShellSolid.FindFromIndex(kk)))
378        aMapSolids.Add(ShellSolid.FindFromIndex(kk));
379   isDone = (aMapSolids.Extent() >1 || isDone);
380   return isDone;
381 }
382 //=======================================================================
383 //function : Perform
384 //purpose  : 
385 //=======================================================================
386
387 Standard_Boolean ShapeFix_Solid::Perform(const Handle(Message_ProgressIndicator)& theProgress) 
388 {
389
390   Standard_Boolean status = Standard_False;
391   if ( Context().IsNull() )
392     SetContext ( new ShapeBuild_ReShape );
393   myFixShell->SetContext(Context());
394
395   Standard_Integer NbShells = 0;
396   TopoDS_Shape S = Context()->Apply ( myShape );
397
398   // Calculate number of underlying shells
399   Standard_Integer aNbShells = 0;
400   for ( TopExp_Explorer aExpSh(S, TopAbs_SHELL); aExpSh.More(); aExpSh.Next() )
401     aNbShells++;
402
403   // Start progress scope (no need to check if progress exists -- it is safe)
404   Message_ProgressSentry aPSentry(theProgress, "Fixing solid stage", 0, 2, 1);
405
406   if ( NeedFix(myFixShellMode) )
407   {
408     // Start progress scope (no need to check if progress exists -- it is safe)
409     Message_ProgressSentry aPSentryFixShell(theProgress, "Fixing shell", 0, aNbShells, 1);
410
411     // Fix shell by shell using ShapeFix_Shell tool
412     for ( TopExp_Explorer aExpSh(S, TopAbs_SHELL); aExpSh.More() && aPSentryFixShell.More(); aExpSh.Next(), aPSentryFixShell.Next() )
413     { 
414       TopoDS_Shape sh = aExpSh.Current();
415
416       myFixShell->Init( TopoDS::Shell(sh) );
417       if ( myFixShell->Perform(theProgress) )
418       {
419         status = Standard_True;
420         myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
421       }
422       NbShells+= myFixShell->NbShells();
423     }
424
425     // Halt algorithm in case of user's abort
426     if ( !aPSentryFixShell.More() )
427       return Standard_False;
428   }
429   else 
430   {
431     NbShells = aNbShells;
432   }
433
434   // Switch to the second stage
435   aPSentry.Next();
436     
437   if(NbShells ==1) {
438     TopoDS_Shape tmpShape = Context()->Apply(myShape);
439     TopExp_Explorer aExp(tmpShape,TopAbs_SHELL);
440     Standard_Boolean isClosed = Standard_False;
441     if(aExp.More()) {
442       TopoDS_Shell  aShtmp = TopoDS::Shell(aExp.Current());
443       ShapeAnalysis_FreeBounds sfb(aShtmp);
444       TopoDS_Compound aC1 = sfb.GetClosedWires();
445       TopoDS_Compound aC2 = sfb.GetOpenWires();
446       Standard_Integer numedge =0;
447       TopExp_Explorer aExp1(aC1,TopAbs_EDGE); 
448       for( ; aExp1.More(); aExp1.Next())
449         numedge++;
450       for(aExp1.Init(aC2,TopAbs_EDGE) ; aExp1.More(); aExp1.Next())
451         numedge++;
452       isClosed = (!numedge);
453       aShtmp.Closed(isClosed);
454     }
455       
456     if(isClosed || myCreateOpenSolidMode) {
457       TopoDS_Iterator itersh(tmpShape);
458       TopoDS_Shell aShell;
459       if(itersh.More() && itersh.Value().ShapeType() == TopAbs_SHELL)
460         aShell = TopoDS::Shell(itersh.Value());
461       if(!aShell.IsNull()) {
462         TopoDS_Solid aSol = SolidFromShell(aShell);
463         if(ShapeExtend::DecodeStatus(myStatus,ShapeExtend_DONE2)) {
464           SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG20"));// Orientaion of shell was corrected.
465           Context()->Replace(tmpShape,aSol);
466           tmpShape = aSol;
467         }
468       }
469       mySolid  = TopoDS::Solid(tmpShape);
470     }
471     else {
472       status = Standard_True;
473       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
474       TopoDS_Iterator aIt(tmpShape,Standard_False);
475       Context()->Replace(tmpShape,aIt.Value());
476       SendFail (Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell. 
477     }
478   }
479   else {
480     TopoDS_Shape aResShape = Context()->Apply(myShape);
481     TopTools_SequenceOfShape aSeqShells;
482     TopTools_IndexedMapOfShape aMapSolids;
483     if(CreateSolids(aResShape,aMapSolids)) {
484       SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG20"));// Orientaion of shell was corrected.. 
485       if(aMapSolids.Extent() ==1) {
486         TopoDS_Shape aResSol = aMapSolids.FindKey(1);
487         if(aResShape.ShapeType() == TopAbs_SHELL && myCreateOpenSolidMode) {
488           TopoDS_Solid solid;
489           BRep_Builder B;
490           B.MakeSolid (solid);
491           B.Add (solid,aResSol);
492           mySolid = solid;
493         }
494         else {
495           mySolid =aResSol;
496           if(aResSol.ShapeType() == TopAbs_SHELL)
497             SendFail (Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell. 
498         }
499         Context()->Replace(aResShape,mySolid);
500       }
501       else if(aMapSolids.Extent() >1) {
502         SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG30"));// Bad connected solid a few solids were created.
503         BRep_Builder aB;
504         TopoDS_Compound aComp;
505         aB.MakeCompound(aComp);
506         Message_ProgressSentry aPSentryCreatingSolid(theProgress, "Creating solid",
507                                         0, aMapSolids.Extent(), 1);
508         for(Standard_Integer i =1; (i <= aMapSolids.Extent()) && (aPSentryCreatingSolid.More());
509             i++, aPSentryCreatingSolid.Next())
510         {
511           TopoDS_Shape aResSh =aMapSolids.FindKey(i);
512           if(aResShape.ShapeType() == TopAbs_SHELL && myCreateOpenSolidMode) {
513             aResSh.Closed(Standard_False);
514             TopoDS_Solid solid;
515             BRep_Builder B;
516             B.MakeSolid (solid);
517             B.Add (solid,aResSh);
518             aResSh = solid;
519           }
520           else if (aResShape.ShapeType() == TopAbs_SHELL)
521             SendFail(Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell. 
522           aB.Add(aComp,aResSh);
523           
524         }
525         if ( !aPSentryCreatingSolid.More() )
526           return Standard_False; // aborted execution
527         Context()->Replace(aResShape,aComp);
528       }
529     }
530   }
531   myShape = Context()->Apply(myShape);
532   return status;
533 }
534 //=======================================================================
535 //function : Shape
536 //purpose  : 
537 //=======================================================================
538
539 TopoDS_Shape ShapeFix_Solid::Shape() 
540 {
541  return myShape; 
542 }
543 //=======================================================================
544 //function : SolidFromShell
545 //purpose  : 
546 //=======================================================================
547
548 TopoDS_Solid ShapeFix_Solid::SolidFromShell (const TopoDS_Shell& shell) 
549 {
550   TopoDS_Shell sh = shell;
551   if (!sh.Free ()) sh.Free(Standard_True);
552
553   TopoDS_Solid solid;
554   BRep_Builder B;
555   B.MakeSolid (solid);
556   B.Add (solid,sh);
557 //   Pas encore fini : il faut une bonne orientation
558   try {
559     OCC_CATCH_SIGNALS
560     BRepClass3d_SolidClassifier bsc3d (solid);
561     Standard_Real t = Precision::Confusion();    // tolerance moyenne
562     bsc3d.PerformInfinitePoint(t);
563     
564     if (bsc3d.State() == TopAbs_IN) {
565       //         Ensuite, inverser C-A-D REPRENDRE LES SHELLS
566       //         (l inversion du solide n est pas bien prise en compte)
567       sh = shell;
568       if (!sh.Free ()) sh.Free(Standard_True);
569       TopoDS_Solid soli2;
570       B.MakeSolid (soli2);    // on recommence
571       sh.Reverse();
572       B.Add (soli2,sh);
573       solid = soli2;
574       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
575     }
576   }
577   catch(Standard_Failure const& anException) {
578 #ifdef OCCT_DEBUG
579     cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
580     anException.Print(cout); cout << endl;
581 #endif
582     (void)anException;
583     return solid;
584   }
585   return solid;
586 }
587
588 //=======================================================================
589 //function : Status
590 //purpose  : 
591 //=======================================================================
592
593 Standard_Boolean ShapeFix_Solid::Status (const ShapeExtend_Status theStatus) const
594 {
595   return ShapeExtend::DecodeStatus (myStatus, theStatus);
596 }
597
598 //=======================================================================
599 //function : Solid
600 //purpose  : 
601 //=======================================================================
602
603  TopoDS_Shape ShapeFix_Solid::Solid() const
604 {
605  return mySolid;
606 }
607
608 //=======================================================================
609 //function : SetMsgRegistrator
610 //purpose  : 
611 //=======================================================================
612
613 void ShapeFix_Solid::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
614 {
615   ShapeFix_Root::SetMsgRegistrator ( msgreg );
616   myFixShell->SetMsgRegistrator ( msgreg );
617 }
618
619 //=======================================================================
620 //function : SetPrecision
621 //purpose  : 
622 //=======================================================================
623
624 void ShapeFix_Solid::SetPrecision (const Standard_Real preci) 
625 {
626   ShapeFix_Root::SetPrecision ( preci );
627   myFixShell->SetPrecision ( preci );
628 }
629
630 //=======================================================================
631 //function : SetMinTolerance
632 //purpose  : 
633 //=======================================================================
634
635 void ShapeFix_Solid::SetMinTolerance (const Standard_Real mintol) 
636 {
637   ShapeFix_Root::SetMinTolerance ( mintol );
638   myFixShell->SetMinTolerance ( mintol );
639 }
640
641 //=======================================================================
642 //function : SetMaxTolerance
643 //purpose  : 
644 //=======================================================================
645
646 void ShapeFix_Solid::SetMaxTolerance (const Standard_Real maxtol) 
647 {
648   ShapeFix_Root::SetMaxTolerance ( maxtol );
649   myFixShell->SetMaxTolerance ( maxtol );
650 }