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