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