Commit | Line | Data |
---|---|---|
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 | 63 | IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Solid,ShapeFix_Root) |
64 | ||
7fd59977 | 65 | //====================================================== |
66 | //function : ShapeFix_Solid | |
67 | //purpose : | |
68 | //======================================================================= | |
7fd59977 | 69 | ShapeFix_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 | ||
83 | ShapeFix_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 | //======================================================================= | |
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 | } | |
4e18e72a | 135 | #endif |
136 | //======================================================================= | |
137 | //function : CollectSolids | |
138 | //purpose : | |
139 | //======================================================================= | |
7fd59977 | 140 | static 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 | 262 | static 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 | 389 | Standard_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 | ||
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 | } | |
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 | 601 | Standard_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 | ||
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 | } |