Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: ShapeFix_Shell.cxx |
2 | // Created: Wed Aug 12 11:07:12 1998 | |
3 | // Author: Galina KULIKOVA | |
4 | // <gka@nnov.matra-dtv.fr> | |
5 | // pdn 17.12.98 ie_exhaust-A.stp | |
6 | ||
7 | #include <ShapeFix_Shell.ixx> | |
8 | ||
9 | #include <Precision.hxx> | |
10 | #include <TopAbs.hxx> | |
11 | #include <TopoDS_Iterator.hxx> | |
12 | #include <TopoDS_Shape.hxx> | |
13 | #include <TopoDS_Face.hxx> | |
14 | #include <TopoDS_Edge.hxx> | |
15 | #include <TopoDS_Shell.hxx> | |
16 | #include <TopoDS.hxx> | |
17 | #include <TopExp_Explorer.hxx> | |
18 | #include <TopExp.hxx> | |
19 | ||
20 | #include <TColStd_SequenceOfInteger.hxx> | |
21 | #include <TopTools_SequenceOfShape.hxx> | |
22 | #include <TopTools_MapOfShape.hxx> | |
23 | #include <TopTools_MapIteratorOfMapOfShape.hxx> | |
24 | #include <TopTools_IndexedMapOfShape.hxx> | |
25 | #include <TopTools_DataMapOfShapeShape.hxx> | |
26 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
27 | #include <TopTools_ListOfShape.hxx> | |
28 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
29 | ||
30 | #include <BRep_Builder.hxx> | |
31 | #include <BRep_Tool.hxx> | |
32 | ||
33 | #include <ShapeExtend.hxx> | |
34 | #include <ShapeBuild_ReShape.hxx> | |
35 | #include <Message_Msg.hxx> | |
b485ee79 | 36 | #include <Message_ProgressSentry.hxx> |
7fd59977 | 37 | #include <TopTools_DataMapOfShapeInteger.hxx> |
38 | #include <TopTools_DataMapOfShapeInteger.hxx> | |
39 | #include <TopTools_DataMapOfShapeInteger.hxx> | |
40 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
41 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
42 | #include <TColStd_DataMapOfIntegerListOfInteger.hxx> | |
43 | #include <Bnd_Box.hxx> | |
44 | #include <BRepBndLib.hxx> | |
45 | #include <Bnd_Array1OfBox.hxx> | |
46 | #include <TColStd_MapOfInteger.hxx> | |
47 | #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx> | |
48 | #include <TopoDS_Iterator.hxx> | |
49 | #include <TopTools_IndexedMapOfShape.hxx> | |
50 | #include <TopTools_IndexedDataMapOfShapeShape.hxx> | |
51 | ||
52 | //======================================================================= | |
53 | //function : ShapeFix_Shell | |
54 | //purpose : | |
55 | //======================================================================= | |
56 | ||
57 | ShapeFix_Shell::ShapeFix_Shell() | |
58 | { | |
59 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); | |
60 | myFixFaceMode = -1; | |
61 | myFixOrientationMode = -1; | |
62 | myFixFace = new ShapeFix_Face; | |
63 | myNbShells =0; | |
64 | } | |
65 | ||
66 | //======================================================================= | |
67 | //function : ShapeFix_Shell | |
68 | //purpose : | |
69 | //======================================================================= | |
70 | ||
71 | ShapeFix_Shell::ShapeFix_Shell(const TopoDS_Shell& shape) | |
72 | { | |
73 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); | |
74 | myFixFaceMode = -1; | |
75 | myFixOrientationMode = -1; | |
76 | myFixFace = new ShapeFix_Face; | |
77 | Init(shape); | |
78 | } | |
79 | ||
80 | //======================================================================= | |
81 | //function : Init | |
82 | //purpose : | |
83 | //======================================================================= | |
84 | ||
85 | void ShapeFix_Shell::Init(const TopoDS_Shell& shell) | |
86 | { | |
87 | myShape = shell; | |
88 | myShell = shell; | |
89 | myNbShells =0; | |
90 | } | |
91 | ||
92 | //======================================================================= | |
93 | //function : Perform | |
94 | //purpose : | |
95 | //======================================================================= | |
96 | ||
b485ee79 | 97 | Standard_Boolean ShapeFix_Shell::Perform(const Handle(Message_ProgressIndicator)& theProgress) |
7fd59977 | 98 | { |
99 | Standard_Boolean status = Standard_False; | |
b485ee79 KD |
100 | if ( Context().IsNull() ) |
101 | SetContext(new ShapeBuild_ReShape); | |
7fd59977 | 102 | myFixFace->SetContext(Context()); |
b485ee79 KD |
103 | |
104 | if ( NeedFix(myFixFaceMode) ) | |
105 | { | |
106 | TopoDS_Shape S = Context()->Apply(myShell); | |
107 | ||
108 | // Get the number of faces for progress indication | |
109 | Standard_Integer aNbFaces = 0; | |
110 | for ( TopExp_Explorer aFaceExp(S, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next() ) | |
111 | ++aNbFaces; | |
112 | ||
113 | // Start progress scope (no need to check if progress exists -- it is safe) | |
114 | Message_ProgressSentry aPSentry(theProgress, "Fixing face", 0, aNbFaces, 1); | |
115 | ||
116 | for( TopoDS_Iterator iter(S); iter.More() && aPSentry.More(); iter.Next(), aPSentry.Next() ) | |
117 | { | |
7fd59977 | 118 | TopoDS_Shape sh = iter.Value(); |
119 | TopoDS_Face tmpFace = TopoDS::Face(sh); | |
120 | myFixFace->Init(tmpFace); | |
b485ee79 KD |
121 | if ( myFixFace->Perform() ) |
122 | { | |
123 | status = Standard_True; | |
124 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); | |
7fd59977 | 125 | } |
126 | } | |
b485ee79 KD |
127 | |
128 | // Halt algorithm in case of user's abort | |
129 | if ( !aPSentry.More() ) | |
130 | return Standard_False; | |
7fd59977 | 131 | } |
132 | TopoDS_Shape newsh = Context()->Apply(myShell); | |
133 | if ( NeedFix ( myFixOrientationMode) ) | |
134 | FixFaceOrientation(TopoDS::Shell(newsh)); | |
135 | if ( status ) | |
136 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); | |
137 | if(Status(ShapeExtend_DONE2)) | |
138 | status = Standard_True; | |
139 | return status; | |
140 | } | |
141 | ||
142 | //======================================================================= | |
143 | // function : GetFreeEdges | |
144 | // purpose : | |
145 | //======================================================================= | |
146 | static Standard_Boolean GetFreeEdges(const TopoDS_Shape& aShape,TopTools_MapOfShape& MapEdges) | |
147 | { | |
148 | for(TopExp_Explorer aExpF(aShape,TopAbs_FACE); aExpF.More(); aExpF.Next()) { | |
149 | for(TopExp_Explorer aExpE(aExpF.Current(),TopAbs_EDGE); aExpE.More(); aExpE.Next()) { | |
150 | TopoDS_Edge edge = TopoDS::Edge(aExpE.Current()); | |
151 | if(!MapEdges.Contains(edge)) | |
152 | MapEdges.Add(edge); | |
153 | else MapEdges.Remove(edge); | |
154 | } | |
155 | } | |
156 | return (MapEdges.Extent()); | |
157 | } | |
158 | //======================================================================= | |
159 | // function : GetShells | |
160 | // purpose : If mode isMultiConnex = Standard_True gets max possible shell for | |
161 | // exception of multiconnexity parts. | |
162 | // Else if this mode is equal to Standard_False maximum possible | |
163 | // shell will be created without taking account of multiconnexity. | |
164 | // In this function map face - shell and sequence of mebius faces is formed. | |
165 | //======================================================================= | |
166 | static Standard_Boolean GetShells(TopTools_SequenceOfShape& Lface, | |
167 | const TopTools_MapOfShape& aMapMultiConnectEdges, | |
168 | TopTools_SequenceOfShape& aSeqShells, | |
169 | TopTools_DataMapOfShapeShape& aMapFaceShells, | |
170 | TopTools_SequenceOfShape& ErrFaces) | |
171 | { | |
172 | Standard_Boolean done = Standard_False; | |
173 | if(!Lface.Length()) return Standard_False; | |
174 | TopoDS_Shell nshell; | |
175 | TopTools_MapOfShape dire, reve; | |
176 | BRep_Builder B; | |
177 | B.MakeShell(nshell); | |
178 | Standard_Boolean isMultiConnex = !aMapMultiConnectEdges.IsEmpty(); | |
179 | Standard_Integer i=1, j=1; | |
180 | TopTools_SequenceOfShape aSeqUnconnectFaces; | |
181 | for( ; i<=Lface.Length(); i++) { | |
182 | TopTools_MapOfShape dtemp, rtemp; | |
183 | Standard_Integer nbbe=0, nbe = 0; | |
184 | TopoDS_Face F1 = TopoDS::Face(Lface.Value(i)); | |
185 | for(TopExp_Explorer expe(F1, TopAbs_EDGE); expe.More(); expe.Next()) { | |
186 | TopoDS_Edge edge = TopoDS::Edge(expe.Current()); | |
187 | ||
188 | // if multiconnexity mode is equal to Standard_True faces contains | |
189 | // the same multiconnexity edges are not added to one shell. | |
190 | if(isMultiConnex && aMapMultiConnectEdges.Contains(edge)) | |
191 | continue; | |
192 | ||
193 | if((edge.Orientation() == TopAbs_FORWARD && dire.Contains(edge)) | |
194 | || (edge.Orientation() == TopAbs_REVERSED && reve.Contains(edge))) | |
195 | nbbe++; | |
196 | else if((edge.Orientation() == TopAbs_FORWARD && reve.Contains(edge)) | |
197 | || (edge.Orientation() == TopAbs_REVERSED && dire.Contains(edge))) | |
198 | nbe++; | |
199 | ||
200 | if(dire.Contains(edge)) dire.Remove(edge); | |
201 | else | |
202 | if(reve.Contains(edge)) reve.Remove(edge); | |
203 | else { | |
204 | if(edge.Orientation() == TopAbs_FORWARD) dtemp.Add(edge); | |
205 | if(edge.Orientation() == TopAbs_REVERSED) rtemp.Add(edge); | |
206 | } | |
207 | } | |
208 | if(!nbbe && !nbe && dtemp.IsEmpty() && rtemp.IsEmpty()) | |
209 | continue; | |
210 | ||
211 | // if face can not be added to shell it added to sequence of error faces. | |
212 | ||
213 | if( nbe != 0 && nbbe != 0) { | |
214 | ErrFaces.Append(F1); | |
215 | Lface.Remove(i); | |
216 | j++; | |
217 | continue; | |
218 | } | |
219 | ||
220 | // Addition of face to shell. In the dependance of orientation faces in the shell | |
221 | // added face can be reversed. | |
222 | ||
223 | if((nbe != 0 || nbbe != 0) || j == 1) { | |
224 | if(nbbe != 0) { | |
225 | F1.Reverse(); | |
226 | for(TopTools_MapIteratorOfMapOfShape ite(dtemp); ite.More(); ite.Next()) | |
227 | reve.Add(ite.Key()); | |
228 | for(TopTools_MapIteratorOfMapOfShape ite1(rtemp); ite1.More(); ite1.Next()) | |
229 | dire.Add(ite1.Key()); | |
230 | done = Standard_True; | |
231 | } | |
232 | else { | |
233 | for(TopTools_MapIteratorOfMapOfShape ite(dtemp); ite.More(); ite.Next()) | |
234 | dire.Add(ite.Key()); | |
235 | for(TopTools_MapIteratorOfMapOfShape ite1(rtemp); ite1.More(); ite1.Next()) | |
236 | reve.Add(ite1.Key()); | |
237 | } | |
238 | j++; | |
239 | B.Add(nshell,F1); | |
240 | aMapFaceShells.Bind(F1,nshell); | |
241 | Lface.Remove(i); | |
242 | ||
243 | // if closed shell is obtained it adds to sequence of shells and new shell begin to construct. | |
244 | if(isMultiConnex && BRep_Tool::IsClosed(nshell)) { | |
245 | aSeqShells.Append(nshell); | |
246 | TopoDS_Shell nshellnext; | |
247 | B.MakeShell(nshellnext); | |
248 | nshell = nshellnext; | |
249 | j=1; | |
250 | } | |
251 | ||
252 | i=0; | |
253 | } | |
254 | //if shell contains of one face. This face is added to sequence of faces. | |
255 | // This shell is removed. | |
256 | if(Lface.Length() && i == Lface.Length() && j <=2) { | |
257 | TopoDS_Iterator aItf(nshell,Standard_False); | |
258 | if(aItf.More()) { | |
259 | aSeqUnconnectFaces.Append(aItf.Value()); | |
260 | aMapFaceShells.UnBind(aItf.Value()); | |
261 | } | |
262 | TopoDS_Shell nshellnext; | |
263 | B.MakeShell(nshellnext); | |
264 | nshell = nshellnext; | |
265 | i=0; | |
266 | j=1; | |
267 | } | |
268 | } | |
269 | Standard_Boolean isContains = Standard_False; | |
270 | for(Standard_Integer k =1 ; k <= aSeqShells.Length() && !isContains; k++) | |
271 | isContains = nshell.IsSame(aSeqShells.Value(k)); | |
272 | if(!isContains) { | |
273 | Standard_Integer numFace =0; | |
274 | TopoDS_Shape aFace; | |
275 | for(TopoDS_Iterator aItf(nshell,Standard_False) ; aItf.More(); aItf.Next()) { | |
276 | aFace = aItf.Value(); | |
277 | numFace++; | |
278 | } | |
279 | if(numFace >1) | |
280 | aSeqShells.Append(nshell); | |
281 | else if(numFace == 1) { | |
282 | if(aMapFaceShells.IsBound(aFace)) | |
283 | aMapFaceShells.UnBind(aFace); | |
284 | Lface.Append(aFace); | |
285 | } | |
286 | } | |
287 | ||
288 | //Sequence of faces Lface contains faces which can not be added to obtained shells. | |
289 | for(Standard_Integer j1 =1; j1 <= aSeqUnconnectFaces.Length(); j1++) { | |
290 | Lface.Append(aSeqUnconnectFaces); | |
291 | } | |
292 | ||
293 | return done; | |
294 | } | |
295 | //======================================================================= | |
296 | // function : AddMultiConexityFaces | |
297 | // purpose : In this function faces have only of multiconnexity boundary | |
298 | // are added to shells having free boundary contains the same | |
299 | // multiconnexity edges as faces. | |
300 | //======================================================================= | |
301 | static Standard_Boolean AddMultiConexityFaces(TopTools_SequenceOfShape& Lface, | |
302 | const TopTools_MapOfShape& aMapMultiConnectEdges, | |
303 | TopTools_SequenceOfShape& SeqShells, | |
304 | const TopTools_DataMapOfShapeShape& aMapFaceShells, | |
305 | const TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces, | |
306 | TopTools_SequenceOfShape& ErrFaces, | |
307 | const Standard_Boolean NonManifold) | |
308 | { | |
309 | Standard_Boolean done = Standard_False; | |
310 | // BRep_Builder aB; | |
311 | TopTools_SequenceOfShape llPosibleShells; | |
312 | TopTools_SequenceOfShape AddShapes; | |
313 | for(Standard_Integer i1 = 1 ; i1<=Lface.Length();i1++ ) { | |
314 | ||
315 | TopoDS_Shape aShape = Lface.Value(i1); | |
316 | ||
317 | Standard_Integer aNbMultEdges =0; | |
318 | ||
319 | //Finds faces having only multiconnexity boundary. | |
320 | for(TopoDS_Iterator aItWires(aShape,Standard_False); aItWires.More(); aItWires.Next()) { | |
321 | Standard_Integer aNbEdges =0; | |
322 | for(TopoDS_Iterator aItEdges(aItWires.Value(),Standard_False); aItEdges.More(); aItEdges.Next(),aNbEdges++) { | |
323 | TopoDS_Shape edge = aItEdges.Value(); | |
324 | if(!aMapMultiConnectEdges.Contains(edge)) continue; | |
325 | aNbMultEdges++; | |
326 | } | |
327 | if(!aNbMultEdges) continue; | |
328 | ||
329 | if(aNbMultEdges == aNbEdges) | |
330 | AddShapes.Append(aShape); | |
331 | else llPosibleShells.Append(aShape); | |
332 | } | |
333 | } | |
334 | ||
335 | // Attemp to create shell from unconnected which have not only multiconnexity boundary. | |
336 | TopTools_SequenceOfShape aTmpShells; | |
337 | if(!llPosibleShells.IsEmpty()) { | |
338 | TopTools_MapOfShape aMap; | |
339 | TopTools_SequenceOfShape aTmp; | |
340 | TopTools_DataMapOfShapeShape aTmpFaceShell; | |
341 | if(GetShells(llPosibleShells,aMap,aTmpShells,aTmpFaceShell,aTmp)) { | |
342 | for(Standard_Integer kk =1; kk <= aTmpShells.Length(); kk++) { | |
343 | TopoDS_Shape aSh = aTmpShells.Value(kk); | |
344 | TopTools_MapOfShape mapEdges; | |
345 | if(GetFreeEdges(aSh,mapEdges)) { | |
346 | Standard_Integer nbedge =0; | |
347 | for(TopTools_MapIteratorOfMapOfShape amapIter(mapEdges);amapIter.More(); amapIter.Next()) { | |
348 | if( aMapMultiConnectEdges.Contains(amapIter.Key())) | |
349 | nbedge++; | |
350 | } | |
351 | if(nbedge && nbedge == mapEdges.Extent()) | |
352 | AddShapes.Append(aSh); | |
353 | } | |
354 | } | |
355 | } | |
356 | } | |
357 | ||
358 | //Add choosen faces to shells. | |
359 | for(Standard_Integer k1 =1; k1 <= AddShapes.Length(); k1++) { | |
360 | TopTools_DataMapOfShapeInteger MapOtherShells; | |
361 | TopTools_MapOfShape dire,reve; | |
362 | TopoDS_Shape aSh = AddShapes.Value(k1); | |
363 | TopTools_MapOfShape mapEdges; | |
364 | if(!GetFreeEdges(aSh,mapEdges)) continue; | |
365 | TopTools_ListOfShape lfaces; | |
366 | ||
367 | //Fill MapOtherShells which will contain shells with orientation in which selected shape aSh will be add. | |
368 | ||
369 | for(TopTools_MapIteratorOfMapOfShape amapIter(mapEdges);amapIter.More(); amapIter.Next()) { | |
370 | if(!aMapMultiConnectEdges.Contains(amapIter.Key())) continue; | |
371 | TopoDS_Edge edge = TopoDS::Edge(amapIter.Key()); | |
372 | if( edge.Orientation() == TopAbs_FORWARD) dire.Add(edge); | |
373 | else reve.Add(edge); | |
374 | TopTools_ListOfShape lf; | |
375 | lf = aMapEdgeFaces.FindFromKey(edge); | |
376 | lfaces.Append(lf); | |
377 | } | |
378 | for(TopTools_ListIteratorOfListOfShape aItl(lfaces) ; aItl.More(); aItl.Next()) { | |
379 | TopoDS_Shape aF = aItl.Value(); | |
380 | if(!aMapFaceShells.IsBound( aF)) continue; | |
381 | ||
382 | TopoDS_Shape aOthershell; | |
383 | aOthershell = aMapFaceShells.Find(aF); | |
384 | if(MapOtherShells.IsBound(aOthershell)) continue; | |
385 | if(!NonManifold && BRep_Tool::IsClosed(aOthershell)) | |
386 | continue; | |
387 | ||
388 | TopTools_MapOfShape mapShellEdges; | |
389 | GetFreeEdges(aOthershell,mapShellEdges); | |
390 | Standard_Boolean isAdd = Standard_True; | |
391 | for(TopTools_MapIteratorOfMapOfShape amapIter1(mapEdges);amapIter1.More() && isAdd ; amapIter1.Next()) | |
392 | isAdd = mapShellEdges.Contains(amapIter1.Key()); | |
393 | ||
394 | if(!isAdd) continue; | |
395 | Standard_Integer nbdir =0, nbrev=0; | |
396 | ||
397 | //add only free face whome all edges contains in the shell as open boundary. | |
398 | for(TopTools_MapIteratorOfMapOfShape aIte( mapShellEdges);aIte.More() ;aIte.Next()) { | |
399 | TopoDS_Edge edgeS = TopoDS::Edge(aIte.Key()); | |
400 | if(!aMapMultiConnectEdges.Contains(edgeS)) continue; | |
401 | if( (edgeS.Orientation() == TopAbs_FORWARD && dire.Contains(edgeS)) || (edgeS.Orientation() == TopAbs_REVERSED && reve.Contains(edgeS))) nbrev++; | |
402 | else if((edgeS.Orientation() == TopAbs_FORWARD && reve.Contains(edgeS)) | |
403 | || (edgeS.Orientation() == TopAbs_REVERSED && dire.Contains(edgeS))) nbdir++; | |
404 | } | |
405 | if(nbdir && nbrev) { | |
406 | ErrFaces.Append(aSh); | |
407 | continue; | |
408 | } | |
409 | if(nbdir || nbrev) { | |
410 | Standard_Integer isReverse =(nbrev ? 1: 0); | |
411 | MapOtherShells.Bind(aOthershell,isReverse); | |
412 | } | |
413 | ||
414 | } | |
415 | if(MapOtherShells.IsEmpty()) { | |
416 | // i1++; | |
417 | continue; | |
418 | } | |
419 | ||
420 | //Adds face to open shells containg the same multishared edges. | |
421 | //For nonmanifold mode creation ine shell from face and shells containing the same multishared edges. | |
422 | // If one face can be added to a few shells (case of compsolid) face will be added to each shell. | |
423 | done = Standard_True; | |
424 | Standard_Integer FirstRev = 0,FirstInd =0; | |
425 | Standard_Integer ind =0; | |
426 | for(Standard_Integer l =1; l <= SeqShells.Length(); l++) { | |
427 | if(!MapOtherShells.IsBound(SeqShells.Value(l))) continue; | |
428 | ind++; | |
429 | Standard_Integer isRev = MapOtherShells.Find(SeqShells.Value(l)); | |
430 | TopoDS_Shape anewShape = (isRev ? aSh.Reversed() :aSh); | |
431 | ||
432 | BRep_Builder aB1; | |
433 | TopoDS_Shape aShell = SeqShells.Value(l); | |
434 | if(ind ==1 || !NonManifold) { | |
435 | if(ind ==1) { | |
436 | FirstRev = isRev; | |
437 | FirstInd = l; | |
438 | } | |
439 | for(TopExp_Explorer aE(anewShape,TopAbs_FACE); aE.More(); aE.Next()) | |
440 | aB1.Add(aShell,aE.Current()); | |
441 | SeqShells.ChangeValue(l) = aShell; | |
442 | } | |
443 | else if(NonManifold) { | |
444 | Standard_Boolean isReversed = !((!(isRev) && !FirstRev) || ((isRev) && FirstRev)); | |
445 | aShell = SeqShells.Value(FirstInd); | |
446 | for(TopoDS_Iterator aItF(SeqShells.Value(l),Standard_False); aItF.More(); aItF.Next()) { | |
447 | TopoDS_Shape nF = ( isReversed ? aItF.Value().Reversed() : aItF.Value()); | |
448 | aB1.Add(aShell,nF); | |
449 | } | |
450 | SeqShells.ChangeValue(FirstInd) = aShell; | |
451 | SeqShells.Remove(l--); | |
452 | } | |
453 | } | |
454 | ||
455 | dire.Clear(); | |
456 | reve.Clear(); | |
457 | for(TopExp_Explorer aEt(aSh,TopAbs_FACE); aEt.More(); aEt.Next()) { | |
458 | for(Standard_Integer kk =1 ; kk <= Lface.Length(); kk++) { | |
459 | if(aEt.Current().IsSame(Lface.Value(kk))) | |
460 | Lface.Remove(kk--); | |
461 | } | |
462 | } | |
463 | } | |
464 | return done; | |
465 | } | |
466 | ||
467 | //======================================================================= | |
468 | // function : BoxIn | |
469 | // purpose : Check if one face contains inside other. | |
470 | //======================================================================= | |
471 | static Standard_Integer BoxIn(const Bnd_Box& theBox1,const Bnd_Box& theBox2) | |
472 | { | |
473 | Standard_Integer aNumIn = 0; | |
474 | Standard_Real aXmin1,aYmin1,aXmax1,aYmax1,aXmin2,aYmin2,aXmax2,aYmax2,aZmin1,aZmax1,aZmin2,aZmax2; | |
475 | theBox1.Get(aXmin1,aYmin1,aZmin1,aXmax1,aYmax1,aZmax1); | |
476 | theBox2.Get(aXmin2,aYmin2,aZmin2,aXmax2,aYmax2,aZmax2); | |
477 | if(aXmin1 == aXmin2 && aXmax1 == aXmax2 && aYmin1 == aYmin2 && aYmax1 == aYmax2 && | |
478 | aZmin1 == aZmin2 && aZmax1 == aZmax2) | |
479 | aNumIn = 0; | |
480 | else if( aXmin1 >= aXmin2 && aXmax1 <= aXmax2 && aYmin1 >= aYmin2 && aYmax1 <= aYmax2 && | |
481 | aZmin1 >= aZmin2 && aZmax1 <= aZmax2) | |
482 | aNumIn = 1; | |
483 | else if( aXmin1 <= aXmin2 && aXmax1 >= aXmax2 && aYmin1 <= aYmin2 && aYmax1 >= aYmax2 && aZmin1 <= aZmin2 && aZmax1 >= aZmax2) | |
484 | aNumIn = 2; | |
485 | return aNumIn; | |
486 | } | |
487 | //======================================================================= | |
488 | // function : GetClosedShells | |
489 | // purpose : Check if one shell is a part from other shell. | |
490 | // For case of compsolid when afew shells are created from | |
491 | // the same set of faces. | |
492 | //======================================================================= | |
493 | static void GetClosedShells(TopTools_SequenceOfShape& Shells, TopTools_SequenceOfShape& aRemainShells) | |
494 | { | |
495 | Bnd_Array1OfBox aBoxes(1,Shells.Length()); | |
496 | for(Standard_Integer i =1; i <= Shells.Length(); i++) { | |
497 | Bnd_Box Box; | |
498 | BRepBndLib::AddClose(Shells.Value(i),Box); | |
499 | aBoxes.SetValue(i,Box); | |
500 | } | |
501 | TColStd_MapOfInteger aMapNum; | |
502 | for(Standard_Integer j = 1; j <= aBoxes.Length(); j++) { | |
503 | for(Standard_Integer k = j+1; k <= aBoxes.Length(); k++) { | |
504 | Standard_Integer NumIn = BoxIn(aBoxes.Value(j),aBoxes.Value(k)); | |
505 | switch(NumIn) { | |
506 | case 1:aMapNum.Add(k); break; | |
507 | case 2: aMapNum.Add(j); break; | |
508 | default : break; | |
509 | } | |
510 | } | |
511 | } | |
512 | for(Standard_Integer i1 =1; i1 <= Shells.Length(); i1++) { | |
513 | if(!aMapNum.Contains(i1)) | |
514 | aRemainShells.Append(Shells.Value(i1)); | |
515 | } | |
516 | ||
517 | } | |
518 | //======================================================================= | |
519 | // function : GlueClosedCandidate | |
520 | // purpose :Attemt firstly to create closed shells from sequence of open shells. | |
521 | //======================================================================= | |
522 | static void GlueClosedCandidate(TopTools_SequenceOfShape& OpenShells, | |
523 | const TopTools_MapOfShape& aMapMultiConnectEdges, | |
524 | TopTools_SequenceOfShape& aSeqNewShells) | |
525 | ||
526 | { | |
527 | // Creating new shells if some open shells contain the same free boundary. | |
528 | for(Standard_Integer i = 1 ; i < OpenShells.Length();i++ ) { | |
529 | TopoDS_Shape aShell = OpenShells.Value(i); | |
530 | TopTools_MapOfShape mapEdges1; | |
531 | TopTools_MapOfShape dire,reve; | |
532 | if(!GetFreeEdges(aShell,mapEdges1)) continue; | |
533 | ||
534 | for(TopTools_MapIteratorOfMapOfShape aIte( mapEdges1);aIte.More() ;aIte.Next()) { | |
535 | TopoDS_Edge edge1 = TopoDS::Edge(aIte.Key()); | |
536 | if(!aMapMultiConnectEdges.Contains(edge1)) break; | |
537 | if(edge1.Orientation() == TopAbs_FORWARD) dire.Add(edge1); | |
538 | else if(edge1.Orientation() == TopAbs_REVERSED) reve.Add(edge1); | |
539 | } | |
540 | if(mapEdges1.Extent() >(dire.Extent() + reve.Extent())) continue; | |
541 | ||
542 | //Filling map MapOtherShells which contains candidate to creation of closed shell | |
543 | // with aShell. | |
544 | ||
545 | TopTools_DataMapOfShapeInteger MapOtherShells; | |
546 | ||
547 | for(Standard_Integer j = i+1 ; j <= OpenShells.Length();j++ ) { | |
548 | Standard_Boolean isAddShell = Standard_True; | |
549 | Standard_Boolean isReversed = Standard_False; | |
550 | Standard_Integer nbedge =0; | |
551 | TopTools_MapOfShape mapEdges2; | |
552 | TopoDS_Shape aShell2 = OpenShells.Value(j); | |
553 | if(!GetFreeEdges(aShell2,mapEdges2)) continue; | |
554 | for(TopTools_MapIteratorOfMapOfShape aIte2( mapEdges2);aIte2.More() && isAddShell;aIte2.Next()) { | |
555 | TopoDS_Edge edge2 = TopoDS::Edge(aIte2.Key()); | |
556 | if(!aMapMultiConnectEdges.Contains(edge2)) { | |
557 | isAddShell = Standard_False; | |
558 | break; | |
559 | //continue; | |
560 | } | |
561 | isAddShell = (dire.Contains(edge2) || reve.Contains(edge2)); | |
562 | if((edge2.Orientation() == TopAbs_FORWARD && dire.Contains(edge2)) | |
563 | || (edge2.Orientation() == TopAbs_REVERSED && reve.Contains(edge2))) | |
564 | isReversed = Standard_True; | |
565 | nbedge++; | |
566 | } | |
567 | ||
568 | if(!isAddShell) continue; | |
569 | MapOtherShells.Bind(OpenShells.Value(j),isReversed); | |
570 | } | |
571 | if(!MapOtherShells.Extent()) continue; | |
572 | ||
573 | ||
574 | if(MapOtherShells.Extent() >1) { | |
575 | ||
576 | // Case of compsolid when more than two shells have the same free boundary. | |
577 | TopTools_SequenceOfShape aSeqCandidate; | |
578 | aSeqCandidate.Append(OpenShells.Value(i)); | |
579 | ||
580 | for(TopTools_DataMapIteratorOfDataMapOfShapeInteger aIt(MapOtherShells); aIt.More(); aIt.Next()) | |
581 | aSeqCandidate.Append(aIt.Key()); | |
582 | ||
583 | //Creation all possibly shells from choosen candidate.And | |
584 | // addition of them to temporary sequence. | |
585 | ||
586 | TopTools_SequenceOfShape aTmpSeq; | |
587 | for(Standard_Integer k =1; k <= aSeqCandidate.Length(); k++) { | |
588 | ||
589 | for(Standard_Integer l = k+1; l <= aSeqCandidate.Length(); l++) { | |
590 | TopoDS_Shell aNewSh; | |
591 | BRep_Builder aB; | |
592 | aB.MakeShell(aNewSh); | |
593 | for(TopoDS_Iterator aIt1(aSeqCandidate.Value(k),Standard_False); aIt1.More(); aIt1.Next()) | |
594 | aB.Add(aNewSh,aIt1.Value()); | |
595 | Standard_Integer isRev = MapOtherShells.Find(aSeqCandidate.Value(l)); | |
596 | if(k !=1) { | |
597 | isRev = ((isRev == MapOtherShells.Find(aSeqCandidate.Value(k))) ? 1 : 0); | |
598 | } | |
599 | for(TopExp_Explorer aExp(aSeqCandidate.Value(l),TopAbs_FACE); aExp.More(); aExp.Next()) { | |
600 | TopoDS_Shape aFace = (isRev ? aExp.Current().Reversed(): aExp.Current()); | |
601 | aB.Add(aNewSh,aFace); | |
602 | } | |
603 | aTmpSeq.Append(aNewSh); | |
604 | } | |
605 | } | |
606 | ||
607 | //Choice from temporary sequence shells contains different set of faces (case of compsolid) | |
608 | TopTools_SequenceOfShape aRemainShells; | |
609 | GetClosedShells(aTmpSeq,aRemainShells); | |
610 | aSeqNewShells.Append(aRemainShells); | |
611 | ||
612 | for(Standard_Integer j1 = i+1 ; j1 <= OpenShells.Length();j1++ ) { | |
613 | if(!MapOtherShells.IsBound(OpenShells.Value(j1))) continue; | |
614 | OpenShells.Remove(j1--); | |
615 | } | |
616 | ||
617 | } | |
618 | else { | |
619 | BRep_Builder aB; | |
620 | TopoDS_Shape aNewShell = aShell; | |
621 | TopoDS_Shape addShell; | |
622 | Standard_Boolean isReversed = Standard_False; | |
623 | for(Standard_Integer j1 = i+1 ; j1 <= OpenShells.Length();j1++ ) { | |
624 | if(!MapOtherShells.IsBound(OpenShells.Value(j1))) continue; | |
625 | addShell = OpenShells.Value(j1); | |
626 | isReversed = MapOtherShells.Find(addShell); | |
627 | OpenShells.Remove(j1); | |
628 | break; | |
629 | } | |
630 | ||
631 | for(TopExp_Explorer aExpF(addShell,TopAbs_FACE); aExpF.More(); aExpF.Next()) { | |
632 | TopoDS_Shape aFace = aExpF.Current(); | |
633 | if(isReversed) | |
634 | aFace.Reverse(); | |
635 | aB.Add(aNewShell,aFace); | |
636 | } | |
637 | aSeqNewShells.Append(aNewShell); | |
638 | } | |
639 | ||
640 | //OpenShells.ChangeValue(i) = aShell; | |
641 | OpenShells.Remove(i--); | |
642 | } | |
643 | } | |
644 | //======================================================================= | |
645 | // function : CreateNonManifoldShells | |
646 | // purpose : Attempt to create max possible shells from open shells. | |
647 | //======================================================================= | |
648 | ||
649 | static void CreateNonManifoldShells(TopTools_SequenceOfShape& SeqShells, | |
650 | const TopTools_MapOfShape& aMapMultiConnectEdges) | |
651 | { | |
652 | TopTools_IndexedDataMapOfShapeListOfShape aMap; | |
653 | for(Standard_Integer i =1 ; i <= SeqShells.Length(); i++) { | |
654 | TopoDS_Shape aShell = SeqShells.Value(i); | |
655 | TopTools_IndexedMapOfShape medeg; | |
656 | TopExp::MapShapes(aShell,TopAbs_EDGE,medeg); | |
657 | for(TopTools_MapIteratorOfMapOfShape mit(aMapMultiConnectEdges); mit.More(); mit.Next()) { | |
658 | //for(TopExp_Explorer aExp(aShell,TopAbs_EDGE); aExp.More(); aExp.Next(),nbe++) { | |
659 | //TopoDS_Shape ae = aExp.Current(); | |
660 | TopoDS_Shape ae =mit.Key(); | |
661 | //if( aMapMultiConnectEdges.Contains(aExp.Current())) { | |
662 | if(medeg.Contains(ae)) { | |
663 | if(aMap.Contains(ae)) | |
664 | aMap.ChangeFromKey(ae).Append(aShell); | |
665 | else { | |
666 | TopTools_ListOfShape al; | |
667 | al.Append(aShell); | |
668 | aMap.Add(ae,al); | |
669 | } | |
670 | } | |
671 | } | |
672 | } | |
673 | TopTools_IndexedDataMapOfShapeShape aMapShells; | |
674 | for(Standard_Integer j =1; j <= aMap.Extent(); j++) { | |
675 | const TopTools_ListOfShape& LShells = aMap.FindFromIndex(j); | |
676 | TopoDS_Shell aNewShell; | |
677 | BRep_Builder aB; | |
678 | aB.MakeShell(aNewShell); | |
679 | TopTools_MapOfShape mapmerge; | |
680 | Standard_Boolean ismerged = Standard_False; | |
681 | Standard_Integer num = 1; | |
682 | for(TopTools_ListIteratorOfListOfShape alit(LShells); alit.More();alit.Next(),num++) { | |
683 | if(!aMapShells.Contains(alit.Value())) { | |
684 | for(TopExp_Explorer aEf(alit.Value(),TopAbs_FACE); aEf.More(); aEf.Next()) { | |
685 | aB.Add(aNewShell,aEf.Current()); | |
686 | } | |
687 | ismerged = Standard_True; | |
688 | mapmerge.Add(alit.Value()); | |
689 | } | |
690 | else if(ismerged) { | |
691 | TopoDS_Shape arshell = aMapShells.FindFromKey(alit.Value()); | |
692 | while(aMapShells.Contains(arshell)){ | |
693 | TopoDS_Shape ss = aMapShells.FindFromKey(arshell); | |
694 | if(ss.IsSame(arshell)) break; | |
695 | arshell = ss; | |
696 | } | |
697 | ||
698 | if(!mapmerge.Contains(arshell)) { | |
699 | for(TopExp_Explorer aEf(arshell,TopAbs_FACE); aEf.More(); aEf.Next()) { | |
700 | aB.Add(aNewShell,aEf.Current()); | |
701 | } | |
702 | mapmerge.Add(arshell); | |
703 | } | |
704 | } | |
705 | else { | |
706 | TopoDS_Shape arshell = aMapShells.FindFromKey(alit.Value()); | |
707 | while(aMapShells.Contains(arshell)) { | |
708 | TopoDS_Shape ss = aMapShells.FindFromKey(arshell); | |
709 | if(ss.IsSame(arshell)) break; | |
710 | arshell = ss; | |
711 | } | |
712 | if(num == 1) { | |
713 | for(TopExp_Explorer aEf(arshell,TopAbs_FACE); aEf.More(); aEf.Next()) | |
714 | aB.Add(aNewShell,aEf.Current()); | |
715 | ||
716 | mapmerge.Add(arshell); | |
717 | } | |
718 | else if(!mapmerge.Contains(arshell)) { | |
719 | for(TopExp_Explorer aEf(arshell,TopAbs_FACE); aEf.More(); aEf.Next()) { | |
720 | aB.Add(aNewShell,aEf.Current()); | |
721 | } | |
722 | mapmerge.Add(arshell); | |
723 | } | |
724 | } | |
725 | } | |
726 | if(mapmerge.Extent() >1 || ismerged) { | |
727 | for(TopTools_MapIteratorOfMapOfShape alit1(mapmerge); alit1.More();alit1.Next()) { | |
728 | TopoDS_Shape oldShell = alit1.Key(); | |
729 | //while(aMapShells.Contains(oldShell)) { | |
730 | // TopoDS_Shape ss = aMapShells.FindFromKey(oldShell); | |
731 | // if(ss.IsSame(oldShell)) break; | |
732 | // oldShell = ss; | |
733 | //} | |
734 | aMapShells.Add(oldShell,aNewShell); | |
735 | } | |
736 | } | |
737 | } | |
738 | TopTools_IndexedMapOfShape MapNewShells; | |
739 | for(Standard_Integer nn = 1;nn <= SeqShells.Length(); nn++) { | |
740 | if(aMapShells.Contains(SeqShells.Value(nn))) { | |
741 | TopoDS_Shape aNewShell = aMapShells.FindFromKey(SeqShells.Value(nn)); | |
742 | while(aMapShells.Contains(aNewShell)) { | |
743 | TopoDS_Shape ss = aMapShells.FindFromKey(aNewShell); | |
744 | if(ss.IsSame(aNewShell)) break; | |
745 | aNewShell = ss; | |
746 | } | |
747 | MapNewShells.Add(aNewShell); | |
748 | ||
749 | SeqShells.Remove(nn--); | |
750 | } | |
751 | ||
752 | } | |
753 | for(Standard_Integer ii =1; ii <= MapNewShells.Extent(); ii++) | |
754 | SeqShells.Append(MapNewShells.FindKey(ii)); | |
755 | } | |
756 | //======================================================================= | |
757 | // function : CreateClosedShell | |
758 | // purpose : Attempt to create max possible shells from open shells. | |
759 | //======================================================================= | |
760 | ||
761 | static void CreateClosedShell(TopTools_SequenceOfShape& OpenShells, | |
762 | const TopTools_MapOfShape& aMapMultiConnectEdges) | |
763 | { | |
764 | TopTools_SequenceOfShape aNewShells; | |
765 | //Attemt firstly to create closed shells. | |
766 | GlueClosedCandidate(OpenShells,aMapMultiConnectEdges,aNewShells); | |
767 | ||
768 | // Creating new shells if some open shells contain the multishared same edges. | |
769 | for(Standard_Integer i = 1 ; i < OpenShells.Length();i++ ) { | |
770 | Standard_Boolean isAddShell = Standard_False; | |
771 | TopoDS_Shape aShell = OpenShells.Value(i); | |
772 | Standard_Boolean isReversed = Standard_False; | |
773 | for(Standard_Integer j = i+1 ; j <= OpenShells.Length();j++ ) { | |
774 | TopTools_MapOfShape mapEdges1; | |
775 | TopTools_MapOfShape dire,reve; | |
776 | if(!GetFreeEdges(aShell,mapEdges1)) break; | |
777 | for(TopTools_MapIteratorOfMapOfShape aIte( mapEdges1);aIte.More() ;aIte.Next()) { | |
778 | TopoDS_Edge edge1 = TopoDS::Edge(aIte.Key()); | |
779 | if(!aMapMultiConnectEdges.Contains(edge1)) continue; | |
780 | if(edge1.Orientation() == TopAbs_FORWARD) dire.Add(edge1); | |
781 | else if(edge1.Orientation() == TopAbs_REVERSED) reve.Add(edge1); | |
782 | } | |
783 | if(dire.IsEmpty() && reve.IsEmpty()) break; | |
784 | TopTools_MapOfShape mapEdges2; | |
785 | TopoDS_Shape aShell2 = OpenShells.Value(j); | |
786 | if(!GetFreeEdges(aShell2,mapEdges2)) continue; | |
787 | for(TopTools_MapIteratorOfMapOfShape aIte2( mapEdges2);aIte2.More() ;aIte2.Next()) { | |
788 | TopoDS_Edge edge2 = TopoDS::Edge(aIte2.Key()); | |
789 | if(!aMapMultiConnectEdges.Contains(edge2)) continue; | |
790 | if(!dire.Contains(edge2) && !reve.Contains(edge2)) continue; | |
791 | isAddShell = Standard_True; | |
792 | if((edge2.Orientation() == TopAbs_FORWARD && dire.Contains(edge2)) | |
793 | || (edge2.Orientation() == TopAbs_REVERSED && reve.Contains(edge2))) | |
794 | isReversed = Standard_True; | |
795 | } | |
796 | ||
797 | if(!isAddShell) continue; | |
798 | BRep_Builder aB; | |
799 | ||
800 | for(TopExp_Explorer aExpF21(OpenShells.Value(j),TopAbs_FACE); aExpF21.More(); aExpF21.Next()) { | |
801 | TopoDS_Shape aFace = aExpF21.Current(); | |
802 | if(isReversed) | |
803 | aFace.Reverse(); | |
804 | aB.Add( aShell,aFace); | |
805 | } | |
806 | ||
807 | OpenShells.ChangeValue(i) = aShell; | |
808 | OpenShells.Remove(j--); | |
809 | } | |
810 | } | |
811 | ||
812 | OpenShells.Append(aNewShells); | |
813 | ||
814 | } | |
815 | ||
816 | ||
817 | //======================================================================= | |
818 | // function : FixFaceOrientation | |
819 | // purpose : | |
820 | //======================================================================= | |
821 | ||
822 | Standard_Boolean ShapeFix_Shell::FixFaceOrientation(const TopoDS_Shell& shell,const Standard_Boolean isAccountMultiConex,const Standard_Boolean NonManifold) | |
823 | { | |
824 | //myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); | |
825 | Standard_Boolean done = Standard_False; | |
826 | TopTools_SequenceOfShape aSeqShells; | |
827 | TopTools_SequenceOfShape aErrFaces; // Compound of faces like to Mebiuce leaf. | |
828 | TopTools_SequenceOfShape Lface; | |
829 | TopTools_DataMapOfShapeShape aMapFaceShells; | |
830 | myShell = shell; | |
831 | myShape = shell; | |
832 | Standard_Integer aNumMultShell =0; | |
833 | for (TopoDS_Iterator iter(shell); iter.More(); iter.Next()) | |
834 | Lface.Append(iter.Value()); | |
835 | TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces; | |
836 | TopExp::MapShapesAndAncestors(myShell,TopAbs_EDGE,TopAbs_FACE,aMapEdgeFaces); | |
837 | TopTools_MapOfShape aMapMultiConnectEdges; | |
838 | if(isAccountMultiConex) { | |
839 | //Finds multishared edges | |
840 | for(Standard_Integer k = 1; k <= aMapEdgeFaces.Extent(); k++) { | |
841 | if(aMapEdgeFaces.FindFromIndex(k).Extent() >2) | |
842 | aMapMultiConnectEdges.Add(aMapEdgeFaces.FindKey(k)); | |
843 | } | |
844 | } | |
845 | Standard_Boolean isGetShells = Standard_True; | |
846 | //Gets possible shells with taking in account of multiconnexity. | |
847 | while(isGetShells && Lface.Length()) { | |
848 | TopTools_SequenceOfShape aTmpSeqShells; | |
849 | if(GetShells(Lface, aMapMultiConnectEdges, aTmpSeqShells,aMapFaceShells,aErrFaces)) { | |
850 | done = Standard_True; | |
851 | } | |
852 | isGetShells = !aTmpSeqShells.IsEmpty(); | |
853 | if(isGetShells) | |
854 | aSeqShells.Append(aTmpSeqShells); | |
855 | } | |
856 | if(!done) | |
857 | done = (aSeqShells.Length() >1); | |
858 | Standard_Boolean aIsDone = Standard_False; | |
859 | if(Lface.Length() > 0 && aSeqShells.Length()) { | |
860 | for(Standard_Integer jj =1; jj <= Lface.Length(); jj++) { | |
861 | if(aMapFaceShells.IsBound(Lface.Value(jj))) | |
862 | aMapFaceShells.UnBind(Lface.Value(jj)); | |
863 | } | |
864 | ||
865 | //Addition of faces having only multiconnexity boundary to shells having holes | |
866 | // containing only the multiconnexity edges | |
867 | aIsDone = AddMultiConexityFaces(Lface,aMapMultiConnectEdges,aSeqShells,aMapFaceShells, | |
868 | aMapEdgeFaces,aErrFaces,NonManifold); | |
869 | } | |
870 | aNumMultShell = aSeqShells.Length(); | |
871 | if (!aErrFaces.IsEmpty()) { | |
872 | ||
873 | //if Shell contains of Mebius faces one shell will be created from each those face. | |
874 | BRep_Builder B; | |
875 | B.MakeCompound(myErrFaces); | |
876 | TopoDS_Compound aCompShells; | |
877 | B.MakeCompound(aCompShells); | |
878 | for(Standard_Integer n =1; n <= aErrFaces.Length(); n++) | |
879 | B.Add(myErrFaces,aErrFaces.Value(n)); | |
880 | if(aNumMultShell) { | |
881 | if(aNumMultShell == 1) { | |
882 | B.Add(aCompShells,aSeqShells.Value(1)); | |
883 | for(Standard_Integer n1 =1; n1 <= aErrFaces.Length(); n1++) { | |
884 | TopoDS_Shell aSh; | |
885 | B.MakeShell(aSh); | |
886 | B.Add(aSh,aErrFaces.Value(n1)); | |
887 | B.Add(aCompShells,aSh); | |
888 | } | |
889 | myShape = aCompShells; | |
890 | } | |
891 | else { | |
892 | for(Standard_Integer i =1; i <= aSeqShells.Length(); i++) | |
893 | B.Add(aCompShells,aSeqShells.Value(i)); | |
894 | for(Standard_Integer n1 =1; n1 <= aErrFaces.Length(); n1++) { | |
895 | TopoDS_Shell aSh; | |
896 | B.MakeShell(aSh); | |
897 | B.Add(aSh,aErrFaces.Value(n1)); | |
898 | B.Add(aCompShells,aSh); | |
899 | } | |
900 | myShape = aCompShells; | |
901 | } | |
902 | } | |
903 | ||
904 | done = Standard_True; | |
905 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL); | |
906 | SendWarning (Message_Msg ("FixAdvShell.FixOrientation.MSG20"));//Faces were incorrectly oriented in the shell, a few shells were created; | |
907 | return Standard_True; | |
908 | } | |
909 | if(aNumMultShell >1) { | |
910 | TopTools_SequenceOfShape OpenShells; | |
911 | for(Standard_Integer i1 =1; i1 <= aSeqShells.Length(); i1++) { | |
912 | TopoDS_Shape aShell = aSeqShells.Value(i1); | |
913 | if(!BRep_Tool::IsClosed(aShell)) { | |
914 | OpenShells.Append(aShell); | |
915 | aSeqShells.Remove(i1--); | |
916 | } | |
917 | } | |
918 | if(OpenShells.Length() >1) | |
919 | //Attempt of creation closed shell from open shells with taking into account multiconnexity. | |
920 | CreateClosedShell(OpenShells,aMapMultiConnectEdges); | |
921 | aSeqShells.Append(OpenShells); | |
922 | ||
923 | } | |
924 | ||
925 | // In the case if NonManifold is equal to Standard_True one non-manifold shell will be created. | |
926 | //Else compound from shells will be created if length of sequence of shape >1. | |
927 | if(Lface.Length()) { | |
928 | ||
929 | for(Standard_Integer i = 1; i <= Lface.Length();i++) { | |
930 | BRep_Builder aB; | |
931 | TopoDS_Shell OneShell; | |
932 | aB.MakeShell(OneShell); | |
933 | aB.Add(OneShell, Lface.Value(i)); | |
934 | aSeqShells.Append(OneShell); | |
935 | } | |
936 | ||
937 | } | |
938 | if(NonManifold && aSeqShells.Length() >1 ) { | |
939 | CreateNonManifoldShells(aSeqShells,aMapMultiConnectEdges); | |
940 | } | |
941 | if(!done) | |
942 | done = (aSeqShells.Length() >1 || aIsDone); | |
943 | if(aSeqShells.Length() == 1) { | |
944 | myShell = TopoDS::Shell(aSeqShells.Value(1)); | |
945 | myShape =myShell; | |
946 | myNbShells =1; | |
947 | } | |
948 | else { | |
949 | BRep_Builder B; | |
950 | TopoDS_Compound aCompShells; | |
951 | B.MakeCompound(aCompShells); | |
952 | for(Standard_Integer i =1; i <= aSeqShells.Length(); i++) | |
953 | B.Add(aCompShells,aSeqShells.Value(i)); | |
954 | myShape = aCompShells; | |
955 | myNbShells = aSeqShells.Length(); | |
956 | } | |
957 | if(done) { | |
958 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2); | |
959 | if(!Context().IsNull()) | |
960 | Context()->Replace(shell, myShape); | |
961 | if( myNbShells == 1) | |
962 | SendWarning (Message_Msg ("FixAdvShell.FixOrientation.MSG0"));//Faces were incorrectly oriented in the shell, corrected | |
963 | else | |
964 | SendWarning (Message_Msg ("FixAdvShell.FixOrientation.MSG30"));//Bad connected shell ,a few shells were created. | |
965 | return Standard_True; | |
966 | } | |
967 | else return Standard_False; | |
968 | } | |
969 | ||
970 | //======================================================================= | |
971 | //function : Status | |
972 | //purpose : | |
973 | //======================================================================= | |
974 | ||
975 | Standard_Boolean ShapeFix_Shell::Status(const ShapeExtend_Status status) const | |
976 | { | |
977 | return ShapeExtend::DecodeStatus (myStatus, status); | |
978 | } | |
979 | ||
980 | //======================================================================= | |
981 | //function : Shell | |
982 | //purpose : | |
983 | //======================================================================= | |
984 | ||
985 | TopoDS_Shell ShapeFix_Shell::Shell() | |
986 | { | |
987 | return myShell; | |
988 | } | |
989 | //======================================================================= | |
990 | //function : Shell | |
991 | //purpose : | |
992 | //======================================================================= | |
993 | ||
994 | TopoDS_Shape ShapeFix_Shell::Shape() | |
995 | { | |
996 | return myShape; | |
997 | } | |
998 | ||
999 | //======================================================================= | |
1000 | //function : ErrorFaces | |
1001 | //purpose : | |
1002 | //======================================================================= | |
1003 | ||
1004 | TopoDS_Compound ShapeFix_Shell::ErrorFaces() const | |
1005 | { | |
1006 | return myErrFaces; | |
1007 | } | |
1008 | ||
1009 | //======================================================================= | |
1010 | //function : SetMsgRegistrator | |
1011 | //purpose : | |
1012 | //======================================================================= | |
1013 | ||
1014 | void ShapeFix_Shell::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg) | |
1015 | { | |
1016 | ShapeFix_Root::SetMsgRegistrator ( msgreg ); | |
1017 | myFixFace->SetMsgRegistrator ( msgreg ); | |
1018 | } | |
1019 | ||
1020 | //======================================================================= | |
1021 | //function : SetPrecision | |
1022 | //purpose : | |
1023 | //======================================================================= | |
1024 | ||
1025 | void ShapeFix_Shell::SetPrecision (const Standard_Real preci) | |
1026 | { | |
1027 | ShapeFix_Root::SetPrecision ( preci ); | |
1028 | myFixFace->SetPrecision ( preci ); | |
1029 | } | |
1030 | ||
1031 | //======================================================================= | |
1032 | //function : SetMinTolerance | |
1033 | //purpose : | |
1034 | //======================================================================= | |
1035 | ||
1036 | void ShapeFix_Shell::SetMinTolerance (const Standard_Real mintol) | |
1037 | { | |
1038 | ShapeFix_Root::SetMinTolerance ( mintol ); | |
1039 | myFixFace->SetMinTolerance ( mintol ); | |
1040 | } | |
1041 | ||
1042 | //======================================================================= | |
1043 | //function : SetMaxTolerance | |
1044 | //purpose : | |
1045 | //======================================================================= | |
1046 | ||
1047 | void ShapeFix_Shell::SetMaxTolerance (const Standard_Real maxtol) | |
1048 | { | |
1049 | ShapeFix_Root::SetMaxTolerance ( maxtol ); | |
1050 | myFixFace->SetMaxTolerance ( maxtol ); | |
1051 | } | |
1052 | //======================================================================= | |
1053 | //function : NbShells | |
1054 | //purpose : | |
1055 | //======================================================================= | |
1056 | ||
1057 | Standard_Integer ShapeFix_Shell::NbShells() const | |
1058 | { | |
1059 | return myNbShells; | |
1060 | } |