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