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