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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRepTools.hxx>
20 #include <Message_ProgressIndicator.hxx>
21 #include <Message_ProgressSentry.hxx>
22 #include <Precision.hxx>
23 #include <ShapeBuild_ReShape.hxx>
24 #include <ShapeExtend_BasicMsgRegistrator.hxx>
25 #include <ShapeFix.hxx>
26 #include <ShapeFix_Edge.hxx>
27 #include <ShapeFix_Face.hxx>
28 #include <ShapeFix_Shape.hxx>
29 #include <ShapeFix_Shell.hxx>
30 #include <ShapeFix_Solid.hxx>
31 #include <ShapeFix_Wire.hxx>
32 #include <Standard_Type.hxx>
34 #include <TopAbs_ShapeEnum.hxx>
35 #include <TopExp_Explorer.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>
43 //=======================================================================
44 //function : ShapeFix_Shape
46 //=======================================================================
47 ShapeFix_Shape::ShapeFix_Shape()
49 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
54 myFixSameParameterMode = -1;
55 myFixVertexPositionMode =0;
56 myFixVertexTolMode = -1;
57 myFixSolid = new ShapeFix_Solid;
60 //=======================================================================
61 //function : ShapeFix_Shape
63 //=======================================================================
65 ShapeFix_Shape::ShapeFix_Shape(const TopoDS_Shape& shape)
67 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
72 myFixSameParameterMode = -1;
73 myFixSolid = new ShapeFix_Solid;
74 myFixVertexPositionMode =0;
75 myFixVertexTolMode = -1;
79 //=======================================================================
82 //=======================================================================
84 void ShapeFix_Shape::Init(const TopoDS_Shape& shape)
87 if ( Context().IsNull() ) {
88 SetContext ( new ShapeBuild_ReShape );
89 Context()->ModeConsiderLocation() = Standard_True;
94 //=======================================================================
97 //=======================================================================
99 Standard_Boolean ShapeFix_Shape::Perform(const Handle(Message_ProgressIndicator)& theProgress)
101 Standard_Integer savFixSmallAreaWireMode = 0;
102 Standard_Integer savFixVertexTolMode = myFixVertexTolMode;
103 Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast( FixFaceTool() );
104 if ( !fft.IsNull() ) {
105 savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
106 if ( savFixSmallAreaWireMode == -1 &&
107 myShape.ShapeType() == TopAbs_FACE ) {
108 fft->FixSmallAreaWireMode() = Standard_True;
112 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
113 Standard_Boolean status = Standard_False;
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)) {
123 myResult = Context()->Apply(myShape);
124 status = Standard_True;
127 else myMapFixingShape.Add(aShapeNullLoc);
128 //---------------------------------------
130 TopoDS_Shape S = Context()->Apply(myShape);
131 if ( NeedFix ( myFixVertexPositionMode ) )
132 ShapeFix::FixVertexPosition(S,Precision(),Context());
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);
142 case TopAbs_COMPOUND:
143 case TopAbs_COMPSOLID: {
144 TopoDS_Shape shape = myShape;
145 Standard_Boolean savFixSameParameterMode = myFixSameParameterMode;
146 myFixSameParameterMode = Standard_False;
147 myFixVertexTolMode = Standard_False;
148 Standard_Integer aShapesNb = 0;
149 for ( TopoDS_Iterator anIter(S); anIter.More(); anIter.Next() )
152 // Open progress indication scope for sub-shape fixing
153 Message_ProgressSentry aPSentrySubShape(theProgress, "Fixing sub-shape", 0, aShapesNb, 1);
154 for ( TopoDS_Iterator anIter(S); anIter.More() && aPSentrySubShape.More(); anIter.Next(), aPSentrySubShape.Next() )
156 myShape = anIter.Value();
157 if ( Perform(theProgress) )
158 status = Standard_True;
160 if ( !aPSentrySubShape.More() )
161 return Standard_False; // aborted execution
163 myFixSameParameterMode = savFixSameParameterMode;
164 myFixVertexTolMode = savFixVertexTolMode;
169 if ( !NeedFix(myFixSolidMode) )
171 myFixSolid->Init(TopoDS::Solid(S));
172 myFixSolid->SetContext(Context());
174 if ( myFixSolid->Perform(theProgress) )
175 status = Standard_True;
177 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
181 if ( !NeedFix(myFixShellMode) )
183 Handle(ShapeFix_Shell) sfsh = FixShellTool();
184 sfsh->Init( TopoDS::Shell(S) );
185 sfsh->SetContext( Context() );
187 if ( sfsh->Perform(theProgress) )
188 status = Standard_True;
190 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
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());
202 status = Standard_True;
204 sff->FixWireTool()->ModifyTopologyMode() = savTopoMode;
205 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
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;
215 sfw->ClosedWireMode() = Standard_False;
216 sfw->SetFace(TopoDS_Face());
217 sfw->Load(TopoDS::Wire(S));
218 sfw->SetContext(Context());
220 status = Standard_True;
221 Context()->Replace(S,sfw->Wire()); // replace for wire only
223 sfw->ModifyTopologyMode() = savTopoMode;
224 sfw->ClosedWireMode() = savClosedMode;
225 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
229 Handle(ShapeFix_Edge) sfe = FixEdgeTool();
230 if(sfe->FixVertexTolerance(TopoDS::Edge(S)))
231 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
239 // Switch to the second progress indication scope if it exists
242 myResult = Context()->Apply(S);
244 if ( NeedFix(myFixSameParameterMode) )
246 SameParameter(myResult, Standard_False, theProgress);
248 if( NeedFix( myFixVertexTolMode))
250 Standard_Integer nbF = 0;
251 TopExp_Explorer anExpF(myResult, TopAbs_FACE);
252 for( ; anExpF.More() && nbF <= 1; anExpF.Next())
256 //fix for bug 0025455
257 // for case when vertex belong to the different faces it is necessary to check vertices tolerances
259 //This fix it should be performed for example for case when cutting edge was performed.
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()));
270 fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
275 //=======================================================================
276 //function : SameParameter
278 //=======================================================================
280 void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh,
281 const Standard_Boolean enforce,
282 const Handle(Message_ProgressIndicator)& theProgress)
284 ShapeFix::SameParameter(sh, enforce, 0.0, theProgress);
287 //=======================================================================
290 //=======================================================================
292 TopoDS_Shape ShapeFix_Shape::Shape() const
297 //=======================================================================
298 //function : SetMsgRegistrator
300 //=======================================================================
302 void ShapeFix_Shape::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
304 ShapeFix_Root::SetMsgRegistrator ( msgreg );
305 myFixSolid->SetMsgRegistrator ( msgreg );
308 //=======================================================================
309 //function : SetPrecision
311 //=======================================================================
313 void ShapeFix_Shape::SetPrecision (const Standard_Real preci)
315 ShapeFix_Root::SetPrecision ( preci );
316 myFixSolid->SetPrecision ( preci );
319 //=======================================================================
320 //function : SetMinTolerance
322 //=======================================================================
324 void ShapeFix_Shape::SetMinTolerance (const Standard_Real mintol)
326 ShapeFix_Root::SetMinTolerance ( mintol );
327 myFixSolid->SetMinTolerance ( mintol );
330 //=======================================================================
331 //function : SetMaxTolerance
333 //=======================================================================
335 void ShapeFix_Shape::SetMaxTolerance (const Standard_Real maxtol)
337 ShapeFix_Root::SetMaxTolerance ( maxtol );
338 myFixSolid->SetMaxTolerance ( maxtol );
340 //=======================================================================
343 //=======================================================================
345 Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const
347 return ShapeExtend::DecodeStatus ( myStatus, status );