0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / ShapeCustom / ShapeCustom_ConvertToRevolution.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <ShapeCustom_ConvertToRevolution.ixx>
19 #include <Geom_ElementarySurface.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepTools.hxx>
23 #include <TopoDS.hxx>
24 #include <Precision.hxx>
25
26 #include <BRep_TEdge.hxx>
27 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
28 #include <BRep_GCurve.hxx>
29 #include <Geom_SphericalSurface.hxx>
30 #include <Geom_ToroidalSurface.hxx>
31 #include <Geom_CylindricalSurface.hxx>
32 #include <Geom_ConicalSurface.hxx>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_OffsetSurface.hxx>
35 #include <Geom_Circle.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <Geom_Line.hxx>
38 #include <Geom_SurfaceOfRevolution.hxx>
39
40 //=======================================================================
41 //function : ShapeCustom_ConvertToRevolution
42 //purpose  : 
43 //=======================================================================
44
45 ShapeCustom_ConvertToRevolution::ShapeCustom_ConvertToRevolution()
46 {
47 }
48
49 // Analyze surface: is it to be converted?
50 static Standard_Boolean IsToConvert (const Handle(Geom_Surface) &S,
51                                      Handle(Geom_ElementarySurface) &ES)
52 {
53   ES = Handle(Geom_ElementarySurface)::DownCast(S);
54   if ( ES.IsNull() ) {
55     if ( S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ) {
56       Handle(Geom_RectangularTrimmedSurface) RTS = 
57         Handle(Geom_RectangularTrimmedSurface)::DownCast ( S );
58       ES = Handle(Geom_ElementarySurface)::DownCast ( RTS->BasisSurface() );
59     }
60     else if ( S->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) ) {
61       Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast ( S );
62       ES = Handle(Geom_ElementarySurface)::DownCast ( OS->BasisSurface() );
63     }
64     if ( ES.IsNull() ) return Standard_False;
65   }
66   
67   return ES->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
68          ES->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ||
69          ES->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ||
70          ES->IsKind(STANDARD_TYPE(Geom_ConicalSurface));
71 }
72
73 //=======================================================================
74 //function : NewSurface
75 //purpose  : 
76 //=======================================================================
77
78 Standard_Boolean ShapeCustom_ConvertToRevolution::NewSurface (const TopoDS_Face& F,
79                                                              Handle(Geom_Surface)& S,
80                                                              TopLoc_Location& L,
81                                                              Standard_Real& Tol,
82                                                              Standard_Boolean& RevWires,
83                                                              Standard_Boolean& RevFace) 
84 {
85   S = BRep_Tool::Surface(F,L);
86   
87   Handle(Geom_ElementarySurface) ES;
88   if ( ! IsToConvert ( S, ES ) ) return Standard_False;
89
90   // remove location if it contains inversion
91 /*
92   gp_Trsf t = L.Transformation();
93   gp_Mat m = t.VectorialPart();
94   Standard_Boolean neg = t.IsNegative();
95   Standard_Boolean det = ( m.Determinant() <0 ? Standard_True : Standard_False );
96   if ( neg != det ) {
97     ES = Handle(Geom_ElementarySurface)::DownCast ( ES->Transformed(t) );
98     L.Identity();
99   }
100 */
101   
102   gp_Ax3 Ax3 = ES->Position();
103   gp_Pnt pos = Ax3.Location();
104   gp_Dir dir = Ax3.Direction();
105   gp_Dir X   = Ax3.XDirection();
106
107   // create basis line to rotate
108   Handle(Geom_Curve) BasisCurve;
109   if ( ES->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
110     Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(ES);
111     gp_Ax2 Ax2 ( pos, X ^ dir, X );
112     Handle(Geom_Circle) Circ = new Geom_Circle ( Ax2, SS->Radius() );
113     BasisCurve = new Geom_TrimmedCurve ( Circ, -M_PI/2., M_PI/2. );
114   }
115   else if ( ES->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
116     Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(ES);
117     gp_Ax2 Ax2 ( pos.XYZ() + X.XYZ() * TS->MajorRadius(), X ^ dir, X );
118     BasisCurve = new Geom_Circle ( Ax2, TS->MinorRadius() );
119   }
120   else if ( ES->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) ) {
121     Handle(Geom_CylindricalSurface) CS = Handle(Geom_CylindricalSurface)::DownCast(ES);
122     gp_Ax1 Ax1 ( pos.XYZ() + X.XYZ() * CS->Radius(), dir );
123     BasisCurve = new Geom_Line ( Ax1 );
124   }
125   else if ( ES->IsKind(STANDARD_TYPE(Geom_ConicalSurface)) ) {
126     Handle(Geom_ConicalSurface) CS = Handle(Geom_ConicalSurface)::DownCast(ES);
127     gp_Dir N = dir.XYZ() + X.XYZ() * Tan ( CS->SemiAngle() );
128     gp_Ax1 Ax1 ( pos.XYZ() + X.XYZ() * CS->RefRadius(), N );
129     BasisCurve = new Geom_Line ( Ax1 );
130   }
131   
132   // create revolution with proper U parametrization
133   gp_Ax1 Axis = Ax3.Axis();
134
135   // if the surface is indirect (taking into account locations), reverse dir
136
137 /*
138   gp_Trsf t = L.Transformation();
139   gp_Mat m = t.VectorialPart();
140   Standard_Boolean neg = t.IsNegative();
141   Standard_Boolean det = ( m.Determinant() <0 ? Standard_True : Standard_False );
142   Standard_Boolean isdir = Ax3.Direct();
143   if ( ( neg != det ) == isdir ) Axis.Reverse();
144 */
145   if ( ! Ax3.Direct() ) Axis.Reverse();
146   
147   Handle(Geom_SurfaceOfRevolution) Rev = new Geom_SurfaceOfRevolution ( BasisCurve, Axis );
148
149   // set resulting surface and restore trimming or offsetting if necessary
150   if ( ES == S ) S = Rev;
151   else {
152     if ( S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ) {
153       Handle(Geom_RectangularTrimmedSurface) RTS = 
154         Handle(Geom_RectangularTrimmedSurface)::DownCast ( S );
155       Standard_Real U1, U2, V1, V2;
156       RTS->Bounds ( U1, U2, V1, V2 );
157       S = new Geom_RectangularTrimmedSurface ( Rev, U1, U2, V1, V2 );
158     }
159     else if ( S->IsKind(STANDARD_TYPE(Geom_OffsetSurface)) ) {
160       Handle(Geom_OffsetSurface) OS = Handle(Geom_OffsetSurface)::DownCast ( S );
161       S = new Geom_OffsetSurface ( Rev, OS->Offset() );
162     }
163     else S = Rev;
164   }
165   
166   Tol = BRep_Tool::Tolerance(F);
167   RevWires = Standard_False;
168   RevFace = Standard_False;
169   return Standard_True;
170 }
171
172 //=======================================================================
173 //function : NewCurve
174 //purpose  : 
175 //=======================================================================
176
177 Standard_Boolean ShapeCustom_ConvertToRevolution::NewCurve (const TopoDS_Edge& E,
178                                                            Handle(Geom_Curve)& C,
179                                                            TopLoc_Location& L,
180                                                            Standard_Real& Tol) 
181 {
182   //:p5 abv 26 Feb 99: force copying of edge if any its pcurve will be replaced
183   Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
184
185   // iterate on pcurves
186   BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
187   for ( ; itcr.More(); itcr.Next() ) {
188     Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
189     if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
190     Handle(Geom_Surface) S = GC->Surface();
191     Handle(Geom_ElementarySurface) ES;
192     if ( ! IsToConvert ( S, ES ) ) continue;
193     Standard_Real f, l;
194     C = BRep_Tool::Curve ( E, L, f, l );
195     if ( ! C.IsNull() ) C = Handle(Geom_Curve)::DownCast ( C->Copy() );
196     Tol = BRep_Tool::Tolerance ( E );
197     return Standard_True;
198   }
199   return Standard_False;
200 }
201
202 //=======================================================================
203 //function : NewPoint
204 //purpose  : 
205 //=======================================================================
206
207 Standard_Boolean ShapeCustom_ConvertToRevolution::NewPoint (const TopoDS_Vertex& /*V*/,
208                                                            gp_Pnt& /*P*/, Standard_Real& /*Tol*/) 
209 {
210   // 3d points are never modified
211   return Standard_False;
212 }
213
214 //=======================================================================
215 //function : NewCurve2d
216 //purpose  : 
217 //=======================================================================
218
219 Standard_Boolean ShapeCustom_ConvertToRevolution::NewCurve2d (const TopoDS_Edge& E,
220                                                              const TopoDS_Face& F,
221                                                              const TopoDS_Edge& NewE,
222                                                              const TopoDS_Face& /*NewF*/,
223                                                              Handle(Geom2d_Curve)& C,
224                                                              Standard_Real& Tol) 
225 {
226   TopLoc_Location L;
227   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
228   Handle(Geom_ElementarySurface) ES;
229   
230   // just copy pcurve if either its surface is changing or edge was copied
231   if ( ! IsToConvert ( S, ES ) && E.IsSame ( NewE ) ) return Standard_False;
232   
233   Standard_Real f, l;
234   C = BRep_Tool::CurveOnSurface(E,F,f,l);
235   if ( ! C.IsNull() ) {
236     C = Handle(Geom2d_Curve)::DownCast ( C->Copy() );
237     
238     // for spherical surface, surface of revolution since based on TrimmedCurve
239     // has V parametrisation shifted on 2PI; translate pcurve accordingly
240     if ( ! ES.IsNull() && ES->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
241       gp_Vec2d shift ( 0., 2*M_PI );
242       C->Translate ( shift );
243     }
244   }
245   
246   Tol = BRep_Tool::Tolerance ( E );
247   return Standard_True;
248 }
249
250 //=======================================================================
251 //function : NewParameter
252 //purpose  : 
253 //=======================================================================
254
255 Standard_Boolean ShapeCustom_ConvertToRevolution::NewParameter (const TopoDS_Vertex& /*V*/,
256                                                                const TopoDS_Edge& /*E*/,
257                                                                Standard_Real& /*P*/,
258                                                                Standard_Real& /*Tol*/) 
259 {
260   return Standard_False;
261 }
262
263 //=======================================================================
264 //function : Continuity
265 //purpose  : 
266 //=======================================================================
267
268 GeomAbs_Shape ShapeCustom_ConvertToRevolution::Continuity (const TopoDS_Edge& E,
269                                                           const TopoDS_Face& F1,
270                                                           const TopoDS_Face& F2,
271                                                           const TopoDS_Edge& /*NewE*/,
272                                                           const TopoDS_Face& /*NewF1*/,
273                                                           const TopoDS_Face& /*NewF2*/) 
274 {
275   return BRep_Tool::Continuity(E,F1,F2);
276 }
277