7fd59977 |
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, -PI/2., 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*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 | |