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