1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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>
36 #include <Message_Msg.hxx>
37 #include <Precision.hxx>
38 #include <ShapeCustom_ConvertToRevolution.hxx>
39 #include <Standard_Type.hxx>
40 #include <TopLoc_Location.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Vertex.hxx>
46 IMPLEMENT_STANDARD_RTTIEXT(ShapeCustom_ConvertToRevolution,ShapeCustom_Modification)
48 //=======================================================================
49 //function : ShapeCustom_ConvertToRevolution
51 //=======================================================================
52 ShapeCustom_ConvertToRevolution::ShapeCustom_ConvertToRevolution()
56 // Analyze surface: is it to be converted?
57 static Standard_Boolean IsToConvert (const Handle(Geom_Surface) &S,
58 Handle(Geom_ElementarySurface) &ES)
60 ES = Handle(Geom_ElementarySurface)::DownCast(S);
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() );
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() );
71 if ( ES.IsNull() ) return Standard_False;
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));
80 //=======================================================================
81 //function : NewSurface
83 //=======================================================================
85 Standard_Boolean ShapeCustom_ConvertToRevolution::NewSurface (const TopoDS_Face& F,
86 Handle(Geom_Surface)& S,
89 Standard_Boolean& RevWires,
90 Standard_Boolean& RevFace)
92 S = BRep_Tool::Surface(F,L);
94 Handle(Geom_ElementarySurface) ES;
95 if ( ! IsToConvert ( S, ES ) ) return Standard_False;
97 // remove location if it contains inversion
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 );
104 ES = Handle(Geom_ElementarySurface)::DownCast ( ES->Transformed(t) );
109 gp_Ax3 Ax3 = ES->Position();
110 gp_Pnt pos = Ax3.Location();
111 gp_Dir dir = Ax3.Direction();
112 gp_Dir X = Ax3.XDirection();
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. );
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() );
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 );
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 );
139 // create revolution with proper U parametrization
140 gp_Ax1 Axis = Ax3.Axis();
142 // if the surface is indirect (taking into account locations), reverse dir
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();
152 if ( ! Ax3.Direct() ) Axis.Reverse();
154 Handle(Geom_SurfaceOfRevolution) Rev = new Geom_SurfaceOfRevolution ( BasisCurve, Axis );
156 // set resulting surface and restore trimming or offsetting if necessary
157 if ( ES == S ) S = Rev;
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 );
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() );
172 SendMsg( F, Message_Msg("ConvertToRevolution.NewSurface.MSG0"));
174 Tol = BRep_Tool::Tolerance(F);
175 RevWires = Standard_False;
176 RevFace = Standard_False;
177 return Standard_True;
180 //=======================================================================
181 //function : NewCurve
183 //=======================================================================
185 Standard_Boolean ShapeCustom_ConvertToRevolution::NewCurve (const TopoDS_Edge& E,
186 Handle(Geom_Curve)& C,
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());
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;
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;
207 return Standard_False;
210 //=======================================================================
211 //function : NewPoint
213 //=======================================================================
215 Standard_Boolean ShapeCustom_ConvertToRevolution::NewPoint (const TopoDS_Vertex& /*V*/,
216 gp_Pnt& /*P*/, Standard_Real& /*Tol*/)
218 // 3d points are never modified
219 return Standard_False;
222 //=======================================================================
223 //function : NewCurve2d
225 //=======================================================================
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,
235 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
236 Handle(Geom_ElementarySurface) ES;
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;
242 C = BRep_Tool::CurveOnSurface(E,F,f,l);
243 if ( ! C.IsNull() ) {
244 C = Handle(Geom2d_Curve)::DownCast ( C->Copy() );
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 );
254 Tol = BRep_Tool::Tolerance ( E );
255 return Standard_True;
258 //=======================================================================
259 //function : NewParameter
261 //=======================================================================
263 Standard_Boolean ShapeCustom_ConvertToRevolution::NewParameter (const TopoDS_Vertex& /*V*/,
264 const TopoDS_Edge& /*E*/,
265 Standard_Real& /*P*/,
266 Standard_Real& /*Tol*/)
268 return Standard_False;
271 //=======================================================================
272 //function : Continuity
274 //=======================================================================
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*/)
283 return BRep_Tool::Continuity(E,F1,F2);