b2f97d33bb1a57b4ee65871d3da85c4dbc7b52b1
[occt.git] / src / ShapeFix / ShapeFix_Shape.cxx
1 // File:        ShapeFix_Shape.cxx
2 // Created:     Wed Aug 09 12:27:47 1999
3 // Author:      Galina Kulikova
4 //              <gka@nnov.matra-dtv.fr>
5
6 #include <ShapeFix_Shape.ixx>
7
8 #include <Precision.hxx>
9
10 #include <TopoDS.hxx>
11 #include <TopoDS_Edge.hxx>
12 #include <TopoDS_Wire.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS_Iterator.hxx>
15 #include <TopExp_Explorer.hxx>
16 #include <TopAbs.hxx>
17 #include <TopAbs_ShapeEnum.hxx>
18 #include <BRepTools.hxx>
19 #include <BRep_Builder.hxx>
20
21 #include <ShapeFix.hxx>
22 #include <ShapeBuild_ReShape.hxx>
23 #include <ShapeFix_Edge.hxx>
24 #include <ShapeFix_Wire.hxx>
25 #include <ShapeFix_Face.hxx>
26 #include <ShapeFix_Shell.hxx>
27 #include <ShapeFix_Solid.hxx>
28
29 //=======================================================================
30 //function : ShapeFix_Shape
31 //purpose  : 
32 //=======================================================================
33
34 ShapeFix_Shape::ShapeFix_Shape()
35 {  
36   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
37   myFixSolidMode = -1;
38   myFixShellMode = -1;
39   myFixFaceMode  = -1;
40   myFixWireMode  = -1;
41   myFixSameParameterMode = -1;
42   myFixVertexPositionMode =0;
43   myFixSolid = new ShapeFix_Solid;
44 }
45
46 //=======================================================================
47 //function : ShapeFix_Shape
48 //purpose  : 
49 //=======================================================================
50
51 ShapeFix_Shape::ShapeFix_Shape(const TopoDS_Shape& shape)
52 {
53   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
54   myFixSolidMode = -1;
55   myFixShellMode = -1;
56   myFixFaceMode  = -1;
57   myFixWireMode  = -1;
58   myFixSameParameterMode = -1;
59   myFixSolid = new ShapeFix_Solid;
60   myFixVertexPositionMode =0;
61   Init(shape);
62 }
63
64 //=======================================================================
65 //function : Init
66 //purpose  : 
67 //=======================================================================
68
69 void ShapeFix_Shape::Init(const TopoDS_Shape& shape) 
70 {
71   myShape = shape;
72   if ( Context().IsNull() ) {
73     SetContext ( new ShapeBuild_ReShape );
74     Context()->ModeConsiderLocation() = Standard_True;
75   }
76   myResult = myShape;
77 }
78
79 //=======================================================================
80 //function : Perform
81 //purpose  : 
82 //=======================================================================
83
84 Standard_Boolean ShapeFix_Shape::Perform() 
85 {
86   Standard_Integer savFixSmallAreaWireMode = 0;
87
88   Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast ( FixFaceTool() );
89   if ( !fft.IsNull() ) {
90     savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
91     if ( savFixSmallAreaWireMode == -1 &&
92          myShape.ShapeType() == TopAbs_FACE ) {
93       fft->FixSmallAreaWireMode() = Standard_True;
94     }
95   }
96
97   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
98   Standard_Boolean status = Standard_False;
99   TopAbs_ShapeEnum st;
100   
101   //gka fix for sharing assembly
102   TopLoc_Location nullLoc,L;
103   L = myShape.Location();
104   TopoDS_Shape aShapeNullLoc = myShape;
105   aShapeNullLoc.Location(nullLoc);
106   if(myMapFixingShape.Contains(aShapeNullLoc)) {
107     myShape.Location(L);
108     myResult = Context()->Apply(myShape);
109     status = Standard_True;
110     return status;
111   }
112   else myMapFixingShape.Add(aShapeNullLoc);
113   //---------------------------------------
114   myShape.Location(L);
115   TopoDS_Shape S = Context()->Apply(myShape);
116   if ( NeedFix (  myFixVertexPositionMode ) )
117     ShapeFix::FixVertexPosition(S,Precision(),Context());
118
119   st = S.ShapeType();
120   switch ( st ) {
121   case TopAbs_COMPOUND:  
122   case TopAbs_COMPSOLID: {
123     TopoDS_Shape shape = myShape;
124     Standard_Boolean savFixSameParameterMode = myFixSameParameterMode;
125     myFixSameParameterMode = Standard_False;
126     for( TopoDS_Iterator iter(S); iter.More(); iter.Next()) {
127       myShape = iter.Value();
128       if ( Perform() ) status = Standard_True;
129     }
130     myFixSameParameterMode = savFixSameParameterMode;
131     myShape = shape;
132 //    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
133     break;
134   }
135   case TopAbs_SOLID: {  
136     if ( ! NeedFix ( myFixSolidMode ) ) break;
137     myFixSolid->Init(TopoDS::Solid(S)); 
138     myFixSolid->SetContext(Context());
139     if(myFixSolid->Perform()) {
140 //      Context()->Replace(S,myFixSolid->Solid());
141       status = Standard_True;
142     }
143     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
144     break;
145   }
146   case TopAbs_SHELL:  {
147     if ( ! NeedFix ( myFixShellMode ) ) break;
148     Handle(ShapeFix_Shell) sfsh = FixShellTool(); 
149     sfsh->Init(TopoDS::Shell(S)); 
150     sfsh->SetContext(Context());
151     if(sfsh->Perform()) {
152 //      Context()->Replace(S,sfsh->Shell());
153       status = Standard_True;
154     }
155     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
156     break;
157   }
158   case TopAbs_FACE: {
159     if ( ! NeedFix ( myFixFaceMode ) ) break;
160     Handle(ShapeFix_Face) sff = FixFaceTool();
161     Standard_Integer savTopoMode = sff->FixWireTool()->ModifyTopologyMode();
162     sff->FixWireTool()->ModifyTopologyMode() = Standard_True;
163     sff->Init(TopoDS::Face(S)); 
164     sff->SetContext(Context());
165     if(sff->Perform()) {
166 //      Context()->Replace(S,sff->Face());
167       status = Standard_True;
168     }
169     sff->FixWireTool()->ModifyTopologyMode() = savTopoMode;
170     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
171     break;
172   }
173   case TopAbs_WIRE: {
174     if ( ! NeedFix ( myFixWireMode ) ) break;
175     Handle(ShapeFix_Wire) sfw = FixWireTool();
176     Standard_Integer savTopoMode = sfw->ModifyTopologyMode();
177     Standard_Integer savClosedMode = sfw->ClosedWireMode();
178     sfw->ModifyTopologyMode() = Standard_True;
179     if ( ! S.Closed() ) 
180       sfw->ClosedWireMode() = Standard_False;
181 //    sfw->FixEdgeCurvesMode() =0;
182     sfw->SetFace(TopoDS_Face());
183     sfw->Load(TopoDS::Wire(S));
184     sfw->SetContext(Context());
185     if(sfw->Perform()) {
186       status = Standard_True;
187       Context()->Replace(S,sfw->Wire()); // replace for wire only
188     }
189     sfw->ModifyTopologyMode() = savTopoMode;
190     sfw->ClosedWireMode() = savClosedMode;
191     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
192     break;
193   }
194   case TopAbs_EDGE: {
195     Handle(ShapeFix_Edge) sfe = FixEdgeTool();
196     if(sfe->FixVertexTolerance(TopoDS::Edge(S)))
197       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
198     break;
199   }
200   case TopAbs_VERTEX:
201   case TopAbs_SHAPE :    
202   default           : break;
203   }
204   
205   myResult  = Context()->Apply(S);  
206   if ( NeedFix ( myFixSameParameterMode ) ) 
207     SameParameter (myResult,Standard_False);
208
209   if ( !fft.IsNull() )
210     fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
211
212   return status;
213 }  
214
215 //=======================================================================
216 //function : SameParameter
217 //purpose  : 
218 //=======================================================================
219
220 void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh, const Standard_Boolean enforce)
221 {
222   ShapeFix::SameParameter(sh, enforce);
223 }
224
225 //=======================================================================
226 //function : Shape
227 //purpose  : 
228 //=======================================================================
229
230 TopoDS_Shape ShapeFix_Shape::Shape() const
231 {
232   return myResult;
233 }
234
235 //=======================================================================
236 //function : SetMsgRegistrator
237 //purpose  : 
238 //=======================================================================
239
240 void ShapeFix_Shape::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
241 {
242   ShapeFix_Root::SetMsgRegistrator ( msgreg );
243   myFixSolid->SetMsgRegistrator ( msgreg );
244 }
245
246 //=======================================================================
247 //function : SetPrecision
248 //purpose  : 
249 //=======================================================================
250
251 void ShapeFix_Shape::SetPrecision (const Standard_Real preci) 
252 {
253   ShapeFix_Root::SetPrecision ( preci );
254   myFixSolid->SetPrecision ( preci );
255 }
256
257 //=======================================================================
258 //function : SetMinTolerance
259 //purpose  : 
260 //=======================================================================
261
262 void ShapeFix_Shape::SetMinTolerance (const Standard_Real mintol) 
263 {
264   ShapeFix_Root::SetMinTolerance ( mintol );
265   myFixSolid->SetMinTolerance ( mintol );
266 }
267
268 //=======================================================================
269 //function : SetMaxTolerance
270 //purpose  : 
271 //=======================================================================
272
273 void ShapeFix_Shape::SetMaxTolerance (const Standard_Real maxtol) 
274 {
275   ShapeFix_Root::SetMaxTolerance ( maxtol );
276   myFixSolid->SetMaxTolerance ( maxtol );
277 }
278 //=======================================================================
279 //function : Status
280 //purpose  : 
281 //=======================================================================
282
283 Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const
284 {
285   return ShapeExtend::DecodeStatus ( myStatus, status ); 
286 }