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