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