Commit | Line | Data |
---|---|---|
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 | 43 | IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Shape,ShapeFix_Root) |
44 | ||
7fd59977 | 45 | //======================================================================= |
46 | //function : ShapeFix_Shape | |
47 | //purpose : | |
48 | //======================================================================= | |
7fd59977 | 49 | ShapeFix_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 | ||
67 | ShapeFix_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 | ||
86 | void 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 | 101 | Standard_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 |
285 | void 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 | ||
297 | TopoDS_Shape ShapeFix_Shape::Shape() const | |
298 | { | |
299 | return myResult; | |
300 | } | |
301 | ||
302 | //======================================================================= | |
303 | //function : SetMsgRegistrator | |
304 | //purpose : | |
305 | //======================================================================= | |
306 | ||
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 | ||
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 | ||
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 | ||
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 | ||
350 | Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const | |
351 | { | |
352 | return ShapeExtend::DecodeStatus ( myStatus, status ); | |
353 | } |