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