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