0025455: fixshape works at the second attempt
[occt.git] / src / ShapeFix / ShapeFix_Shape.cxx
CommitLineData
b311480e 1// Created on: 1999-08-09
2// Created by: Galina Kulikova
3// Copyright (c) 1999-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.
7fd59977 16
17#include <ShapeFix_Shape.ixx>
18
19#include <Precision.hxx>
20
21#include <TopoDS.hxx>
22#include <TopoDS_Edge.hxx>
23#include <TopoDS_Wire.hxx>
24#include <TopoDS_Face.hxx>
25#include <TopoDS_Iterator.hxx>
26#include <TopExp_Explorer.hxx>
27#include <TopAbs.hxx>
28#include <TopAbs_ShapeEnum.hxx>
29#include <BRepTools.hxx>
30#include <BRep_Builder.hxx>
31
32#include <ShapeFix.hxx>
33#include <ShapeBuild_ReShape.hxx>
34#include <ShapeFix_Edge.hxx>
35#include <ShapeFix_Wire.hxx>
36#include <ShapeFix_Face.hxx>
37#include <ShapeFix_Shell.hxx>
38#include <ShapeFix_Solid.hxx>
39
b485ee79
KD
40#include <Message_ProgressSentry.hxx>
41
7fd59977 42//=======================================================================
43//function : ShapeFix_Shape
44//purpose :
45//=======================================================================
46
47ShapeFix_Shape::ShapeFix_Shape()
48{
49 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
50 myFixSolidMode = -1;
51 myFixShellMode = -1;
52 myFixFaceMode = -1;
53 myFixWireMode = -1;
54 myFixSameParameterMode = -1;
55 myFixVertexPositionMode =0;
34e923b5 56 myFixVertexTolMode = -1;
7fd59977 57 myFixSolid = new ShapeFix_Solid;
58}
59
60//=======================================================================
61//function : ShapeFix_Shape
62//purpose :
63//=======================================================================
64
65ShapeFix_Shape::ShapeFix_Shape(const TopoDS_Shape& shape)
66{
67 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
68 myFixSolidMode = -1;
69 myFixShellMode = -1;
70 myFixFaceMode = -1;
71 myFixWireMode = -1;
72 myFixSameParameterMode = -1;
73 myFixSolid = new ShapeFix_Solid;
74 myFixVertexPositionMode =0;
34e923b5 75 myFixVertexTolMode = -1;
7fd59977 76 Init(shape);
77}
78
79//=======================================================================
80//function : Init
81//purpose :
82//=======================================================================
83
84void ShapeFix_Shape::Init(const TopoDS_Shape& shape)
85{
86 myShape = shape;
87 if ( Context().IsNull() ) {
88 SetContext ( new ShapeBuild_ReShape );
89 Context()->ModeConsiderLocation() = Standard_True;
90 }
91 myResult = myShape;
92}
93
94//=======================================================================
95//function : Perform
96//purpose :
97//=======================================================================
98
b485ee79 99Standard_Boolean ShapeFix_Shape::Perform(const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 100{
101 Standard_Integer savFixSmallAreaWireMode = 0;
34e923b5 102 Standard_Integer savFixVertexTolMode = myFixVertexTolMode;
b485ee79 103 Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast( FixFaceTool() );
7fd59977 104 if ( !fft.IsNull() ) {
105 savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
106 if ( savFixSmallAreaWireMode == -1 &&
107 myShape.ShapeType() == TopAbs_FACE ) {
108 fft->FixSmallAreaWireMode() = Standard_True;
109 }
110 }
111
112 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
113 Standard_Boolean status = Standard_False;
114 TopAbs_ShapeEnum st;
115
116 //gka fix for sharing assembly
117 TopLoc_Location nullLoc,L;
118 L = myShape.Location();
119 TopoDS_Shape aShapeNullLoc = myShape;
120 aShapeNullLoc.Location(nullLoc);
121 if(myMapFixingShape.Contains(aShapeNullLoc)) {
122 myShape.Location(L);
123 myResult = Context()->Apply(myShape);
124 status = Standard_True;
125 return status;
126 }
127 else myMapFixingShape.Add(aShapeNullLoc);
128 //---------------------------------------
129 myShape.Location(L);
130 TopoDS_Shape S = Context()->Apply(myShape);
131 if ( NeedFix ( myFixVertexPositionMode ) )
132 ShapeFix::FixVertexPosition(S,Precision(),Context());
133
134 st = S.ShapeType();
b485ee79
KD
135
136 // Open progress indication scope for the following fix stages:
137 // - Fix on Solid or Shell;
138 // - Fix same parameterization;
139 Message_ProgressSentry aPSentry(theProgress, "Fixing stage", 0, 2, 1);
140
7fd59977 141 switch ( st ) {
142 case TopAbs_COMPOUND:
143 case TopAbs_COMPSOLID: {
144 TopoDS_Shape shape = myShape;
145 Standard_Boolean savFixSameParameterMode = myFixSameParameterMode;
146 myFixSameParameterMode = Standard_False;
34e923b5 147 myFixVertexTolMode = Standard_False;
b485ee79
KD
148 Standard_Integer aShapesNb = 0;
149 for ( TopoDS_Iterator anIter(S); anIter.More(); anIter.Next() )
150 ++aShapesNb;
151
152 // Open progress indication scope for sub-shape fixing
153 Message_ProgressSentry aPSentry(theProgress, "Fixing sub-shape", 0, aShapesNb, 1);
154 for ( TopoDS_Iterator anIter(S); anIter.More() && aPSentry.More(); anIter.Next(), aPSentry.Next() )
155 {
156 myShape = anIter.Value();
157 if ( Perform(theProgress) )
158 status = Standard_True;
7fd59977 159 }
b485ee79
KD
160 if ( !aPSentry.More() )
161 return Standard_False; // aborted execution
162
7fd59977 163 myFixSameParameterMode = savFixSameParameterMode;
34e923b5 164 myFixVertexTolMode = savFixVertexTolMode;
7fd59977 165 myShape = shape;
7fd59977 166 break;
167 }
168 case TopAbs_SOLID: {
b485ee79
KD
169 if ( !NeedFix(myFixSolidMode) )
170 break;
7fd59977 171 myFixSolid->Init(TopoDS::Solid(S));
172 myFixSolid->SetContext(Context());
b485ee79
KD
173
174 if ( myFixSolid->Perform(theProgress) )
7fd59977 175 status = Standard_True;
b485ee79 176
7fd59977 177 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
178 break;
179 }
180 case TopAbs_SHELL: {
b485ee79
KD
181 if ( !NeedFix(myFixShellMode) )
182 break;
7fd59977 183 Handle(ShapeFix_Shell) sfsh = FixShellTool();
b485ee79
KD
184 sfsh->Init( TopoDS::Shell(S) );
185 sfsh->SetContext( Context() );
186
187 if ( sfsh->Perform(theProgress) )
7fd59977 188 status = Standard_True;
b485ee79 189
7fd59977 190 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
191 break;
192 }
193 case TopAbs_FACE: {
194 if ( ! NeedFix ( myFixFaceMode ) ) break;
195 Handle(ShapeFix_Face) sff = FixFaceTool();
196 Standard_Integer savTopoMode = sff->FixWireTool()->ModifyTopologyMode();
197 sff->FixWireTool()->ModifyTopologyMode() = Standard_True;
198 sff->Init(TopoDS::Face(S));
199 sff->SetContext(Context());
b485ee79 200
7fd59977 201 if(sff->Perform()) {
7fd59977 202 status = Standard_True;
203 }
204 sff->FixWireTool()->ModifyTopologyMode() = savTopoMode;
205 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
206 break;
207 }
208 case TopAbs_WIRE: {
209 if ( ! NeedFix ( myFixWireMode ) ) break;
210 Handle(ShapeFix_Wire) sfw = FixWireTool();
211 Standard_Integer savTopoMode = sfw->ModifyTopologyMode();
212 Standard_Integer savClosedMode = sfw->ClosedWireMode();
213 sfw->ModifyTopologyMode() = Standard_True;
214 if ( ! S.Closed() )
215 sfw->ClosedWireMode() = Standard_False;
7fd59977 216 sfw->SetFace(TopoDS_Face());
217 sfw->Load(TopoDS::Wire(S));
218 sfw->SetContext(Context());
219 if(sfw->Perform()) {
220 status = Standard_True;
221 Context()->Replace(S,sfw->Wire()); // replace for wire only
222 }
223 sfw->ModifyTopologyMode() = savTopoMode;
224 sfw->ClosedWireMode() = savClosedMode;
225 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
226 break;
227 }
228 case TopAbs_EDGE: {
229 Handle(ShapeFix_Edge) sfe = FixEdgeTool();
230 if(sfe->FixVertexTolerance(TopoDS::Edge(S)))
231 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
232 break;
233 }
234 case TopAbs_VERTEX:
235 case TopAbs_SHAPE :
236 default : break;
237 }
b485ee79
KD
238
239 // Switch to the second progress indication scope if it exists
240 aPSentry.Next();
7fd59977 241
b485ee79
KD
242 myResult = Context()->Apply(S);
243
244 if ( NeedFix(myFixSameParameterMode) )
245 {
246 SameParameter(myResult, Standard_False, theProgress);
247 }
34e923b5 248 if( NeedFix( myFixVertexTolMode))
249 {
250 Standard_Integer nbF = 0;
251 TopExp_Explorer anExpF(myResult, TopAbs_FACE);
252 for( ; anExpF.More() && nbF <= 1; anExpF.Next())
253 nbF++;
254 if( nbF > 1)
255 {
256 //fix for bug 0025455
257 // for case when vertex belong to the different faces it is necessary to check vertices tolerances
258 //after all fixes.
259 //This fix it should be performed for example for case when cutting edge was performed.
260
261 Handle(ShapeFix_Edge) sfe = FixEdgeTool();
262 TopExp_Explorer anExpE (myResult, TopAbs_EDGE);
263 for ( ; anExpE.More(); anExpE.Next())
264 sfe->FixVertexTolerance( TopoDS::Edge (anExpE.Current()));
265
266 }
267 }
7fd59977 268
269 if ( !fft.IsNull() )
270 fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
271
272 return status;
273}
274
275//=======================================================================
276//function : SameParameter
277//purpose :
278//=======================================================================
279
b485ee79
KD
280void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh,
281 const Standard_Boolean enforce,
282 const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 283{
b485ee79 284 ShapeFix::SameParameter(sh, enforce, 0.0, theProgress);
7fd59977 285}
286
287//=======================================================================
288//function : Shape
289//purpose :
290//=======================================================================
291
292TopoDS_Shape ShapeFix_Shape::Shape() const
293{
294 return myResult;
295}
296
297//=======================================================================
298//function : SetMsgRegistrator
299//purpose :
300//=======================================================================
301
302void ShapeFix_Shape::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
303{
304 ShapeFix_Root::SetMsgRegistrator ( msgreg );
305 myFixSolid->SetMsgRegistrator ( msgreg );
306}
307
308//=======================================================================
309//function : SetPrecision
310//purpose :
311//=======================================================================
312
313void ShapeFix_Shape::SetPrecision (const Standard_Real preci)
314{
315 ShapeFix_Root::SetPrecision ( preci );
316 myFixSolid->SetPrecision ( preci );
317}
318
319//=======================================================================
320//function : SetMinTolerance
321//purpose :
322//=======================================================================
323
324void ShapeFix_Shape::SetMinTolerance (const Standard_Real mintol)
325{
326 ShapeFix_Root::SetMinTolerance ( mintol );
327 myFixSolid->SetMinTolerance ( mintol );
328}
329
330//=======================================================================
331//function : SetMaxTolerance
332//purpose :
333//=======================================================================
334
335void ShapeFix_Shape::SetMaxTolerance (const Standard_Real maxtol)
336{
337 ShapeFix_Root::SetMaxTolerance ( maxtol );
338 myFixSolid->SetMaxTolerance ( maxtol );
339}
340//=======================================================================
341//function : Status
342//purpose :
343//=======================================================================
344
345Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const
346{
347 return ShapeExtend::DecodeStatus ( myStatus, status );
348}