0028694: IGES reader produces too small edge covered by its vertices
[occt.git] / src / ShapeFix / ShapeFix_Solid.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
b311480e 14
42cf5bc1 15#include <Bnd_Box2d.hxx>
7fd59977 16#include <BRep_Builder.hxx>
42cf5bc1 17#include <BRep_Tool.hxx>
7fd59977 18#include <BRepClass3d_SolidClassifier.hxx>
42cf5bc1 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>
7fd59977 25#include <Precision.hxx>
42cf5bc1 26#include <ShapeAnalysis.hxx>
7fd59977 27#include <ShapeAnalysis_Curve.hxx>
42cf5bc1 28#include <ShapeAnalysis_Edge.hxx>
29#include <ShapeAnalysis_FreeBounds.hxx>
30#include <ShapeBuild_ReShape.hxx>
31#include <ShapeExtend.hxx>
32#include <ShapeExtend_BasicMsgRegistrator.hxx>
7fd59977 33#include <ShapeExtend_WireData.hxx>
42cf5bc1 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>
7fd59977 40#include <TopExp.hxx>
42cf5bc1 41#include <TopoDS.hxx>
42#include <TopoDS_CompSolid.hxx>
7fd59977 43#include <TopoDS_Edge.hxx>
42cf5bc1 44#include <TopoDS_Iterator.hxx>
45#include <TopoDS_Shape.hxx>
46#include <TopoDS_Shell.hxx>
7fd59977 47#include <TopoDS_Solid.hxx>
42cf5bc1 48#include <TopoDS_Vertex.hxx>
49#include <TopoDS_Wire.hxx>
50#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
7fd59977 51#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
42cf5bc1 52#include <TopTools_DataMapOfShapeInteger.hxx>
53#include <TopTools_DataMapOfShapeListOfShape.hxx>
54#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
7fd59977 55#include <TopTools_IndexedDataMapOfShapeShape.hxx>
7fd59977 56#include <TopTools_IndexedMapOfShape.hxx>
42cf5bc1 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>
b311480e 62
92efcf78 63IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Solid,ShapeFix_Root)
64
7fd59977 65//======================================================
66//function : ShapeFix_Solid
67//purpose :
68//=======================================================================
7fd59977 69ShapeFix_Solid::ShapeFix_Solid()
70{
71 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
72 myFixShellMode = -1;
bf961e3c 73 myFixShellOrientationMode = -1;
7fd59977 74 myFixShell = new ShapeFix_Shell;
75 myCreateOpenSolidMode = Standard_False;
76}
77
78//=======================================================================
79//function : ShapeFix_Solid
80//purpose :
81//=======================================================================
82
83ShapeFix_Solid::ShapeFix_Solid(const TopoDS_Solid& solid)
84{
85 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
86 myFixShellMode = -1;
bf961e3c 87 myFixShellOrientationMode = -1;
7fd59977 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}
0797d9d3 107#ifdef OCCT_DEBUG_GET_MIDDLE_POINT
7fd59977 108//=======================================================================
4e18e72a 109//function : GetMiddlePoint
7fd59977 110//purpose :
111//=======================================================================
112static 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}
4e18e72a 135#endif
136//=======================================================================
137//function : CollectSolids
138//purpose :
139//=======================================================================
7fd59977 140static void CollectSolids(const TopTools_SequenceOfShape& aSeqShells ,
a70f5823 141 TopTools_IndexedDataMapOfShapeListOfShape& anIndexedMapShellHoles,
7fd59977 142 TopTools_DataMapOfShapeInteger& theMapStatus)
143{
144 TopTools_MapOfShape aMapHoles;
a70f5823 145 TopTools_DataMapOfShapeListOfShape aMapShellHoles;
7fd59977 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) {
0797d9d3 209#ifdef OCCT_DEBUG_GET_MIDDLE_POINT
4e18e72a 210 gp_Pnt pmid;
211 GetMiddlePoint(aShell2,pmid);
212 bsc3d.Perform(pmid,Precision::Confusion());
213#endif
7fd59977 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 }
9775fa61 224 catch(Standard_Failure const& anException) {
0797d9d3 225#ifdef OCCT_DEBUG
7fd59977 226 cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
9775fa61 227 anException.Print(cout); cout << endl;
7fd59977 228#endif
9775fa61 229 (void)anException;
7fd59977 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())
a70f5823
RL
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 }
7fd59977 256}
257//=======================================================================
258//function : CreateSolids
259//purpose :
260//=======================================================================
261
464cd2fb 262static Standard_Boolean CreateSolids(const TopoDS_Shape theShape,TopTools_IndexedMapOfShape& aMapSolids)
7fd59977 263{
264 TopTools_SequenceOfShape aSeqShells;
265 Standard_Boolean isDone = Standard_False;
266
464cd2fb 267 for(TopExp_Explorer aExpShell(theShape,TopAbs_SHELL); aExpShell.More(); aExpShell.Next()) {
7fd59977 268 aSeqShells.Append(aExpShell.Current());
269 }
a70f5823 270 TopTools_IndexedDataMapOfShapeListOfShape aMapShellHoles;
7fd59977 271 TopTools_DataMapOfShapeInteger aMapStatus;
272 CollectSolids(aSeqShells,aMapShellHoles,aMapStatus);
273 TopTools_IndexedDataMapOfShapeShape ShellSolid;
7fd59977 274 //Defines correct orientation of shells
a70f5823
RL
275 for (Standard_Integer i = 1; i <= aMapShellHoles.Extent(); ++i) {
276 TopoDS_Shell aShell = TopoDS::Shell(aMapShellHoles.FindKey(i));
7fd59977 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 }
9775fa61 302 catch(Standard_Failure const& anException) {
0797d9d3 303#ifdef OCCT_DEBUG
7fd59977 304 cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
9775fa61 305 anException.Print(cout); cout << endl;
7fd59977 306#endif
9775fa61 307 (void)anException;
7fd59977 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
a70f5823 321 const TopTools_ListOfShape& lHoles = aMapShellHoles (i);
7fd59977 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;
464cd2fb 345 TopExp::MapShapesAndAncestors(theShape,TopAbs_FACE,TopAbs_SHELL,aMapFaceShells);
7fd59977 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);
464cd2fb 352 isDone = (theShape.ShapeType() != TopAbs_COMPSOLID || isDone);
cf8096ec 353 Standard_Integer nbSol = 0;
354
7fd59977 355 for(TopTools_ListIteratorOfListOfShape lItSh(lshells);lItSh.More(); lItSh.Next()) {
356 if(ShellSolid.Contains(lItSh.Value())) {
cf8096ec 357 const TopoDS_Shape& aShape = ShellSolid.FindFromKey(lItSh.Value());
358 TopExp_Explorer aExpSol(aShape, TopAbs_SOLID);
359
360 for(;aExpSol.More(); aExpSol.Next())
361 {
7fd59977 362 aB.Add(aCompSolid,aExpSol.Current());
cf8096ec 363 nbSol++;
364 }
365
7fd59977 366 }
367 }
cf8096ec 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
7fd59977 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
b485ee79 389Standard_Boolean ShapeFix_Solid::Perform(const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 390{
391
392 Standard_Boolean status = Standard_False;
b485ee79 393 if ( Context().IsNull() )
7fd59977 394 SetContext ( new ShapeBuild_ReShape );
395 myFixShell->SetContext(Context());
b485ee79
KD
396
397 Standard_Integer NbShells = 0;
7fd59977 398 TopoDS_Shape S = Context()->Apply ( myShape );
b485ee79
KD
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)
51740958 411 Message_ProgressSentry aPSentryFixShell(theProgress, "Fixing shell", 0, aNbShells, 1);
b485ee79
KD
412
413 // Fix shell by shell using ShapeFix_Shell tool
51740958 414 for ( TopExp_Explorer aExpSh(S, TopAbs_SHELL); aExpSh.More() && aPSentryFixShell.More(); aExpSh.Next(), aPSentryFixShell.Next() )
b485ee79
KD
415 {
416 TopoDS_Shape sh = aExpSh.Current();
417
418 myFixShell->Init( TopoDS::Shell(sh) );
419 if ( myFixShell->Perform(theProgress) )
420 {
7fd59977 421 status = Standard_True;
422 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
423 }
bf961e3c 424 NbShells += myFixShell->NbShells();
7fd59977 425 }
b485ee79
KD
426
427 // Halt algorithm in case of user's abort
51740958 428 if ( !aPSentryFixShell.More() )
b485ee79 429 return Standard_False;
bf961e3c 430 }
b485ee79
KD
431 else
432 {
433 NbShells = aNbShells;
7fd59977 434 }
b485ee79
KD
435
436 // Switch to the second stage
437 aPSentry.Next();
bf961e3c 438
439 if (!NeedFix(myFixShellOrientationMode))
440 {
441 myShape = Context()->Apply(myShape);
442 return status;
443 }
444
7fd59977 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) {
da72a17c 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;
7fd59977 475 }
476 }
477 mySolid = TopoDS::Solid(tmpShape);
478 }
479 else {
cf8096ec 480 status = Standard_True;
481 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
7fd59977 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);
51740958 514 Message_ProgressSentry aPSentryCreatingSolid(theProgress, "Creating solid",
b485ee79 515 0, aMapSolids.Extent(), 1);
51740958 516 for(Standard_Integer i =1; (i <= aMapSolids.Extent()) && (aPSentryCreatingSolid.More());
517 i++, aPSentryCreatingSolid.Next())
b485ee79 518 {
7fd59977 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 }
51740958 533 if ( !aPSentryCreatingSolid.More() )
b485ee79 534 return Standard_False; // aborted execution
7fd59977 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
547TopoDS_Shape ShapeFix_Solid::Shape()
548{
549 return myShape;
550}
551//=======================================================================
552//function : SolidFromShell
553//purpose :
554//=======================================================================
555
556TopoDS_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 }
9775fa61 585 catch(Standard_Failure const& anException) {
0797d9d3 586#ifdef OCCT_DEBUG
7fd59977 587 cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
9775fa61 588 anException.Print(cout); cout << endl;
7fd59977 589#endif
9775fa61 590 (void)anException;
7fd59977 591 return solid;
592 }
593 return solid;
594}
595
596//=======================================================================
597//function : Status
598//purpose :
599//=======================================================================
600
dde68833 601Standard_Boolean ShapeFix_Solid::Status (const ShapeExtend_Status theStatus) const
7fd59977 602{
dde68833 603 return ShapeExtend::DecodeStatus (myStatus, theStatus);
7fd59977 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
621void 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
632void 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
643void 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
654void ShapeFix_Solid::SetMaxTolerance (const Standard_Real maxtol)
655{
656 ShapeFix_Root::SetMaxTolerance ( maxtol );
657 myFixShell->SetMaxTolerance ( maxtol );
658}