7fd59977 |
1 | // File: BlendFunc.cxx |
2 | // Created: Wed Oct 4 11:35:28 1995 |
3 | // Author: Jacques GOUSSARD |
4 | // Copyright: OPEN CASCADE 1995 |
5 | |
6 | // 09/09/1996 PMN Ajout des methodes GetCircle et GetTolerance. |
7 | // 30/12/1996 PMN Ajout de GetMinimalWeight |
8 | // 23/09/1997 PMN Supprimme GetCircle et GetTol (passe dans GeomFill) |
9 | |
10 | #include <BlendFunc.ixx> |
11 | |
12 | #include <gp_Circ.hxx> |
13 | #include <gp_Pnt.hxx> |
14 | #include <gp_Dir.hxx> |
15 | #include <gp_Ax2.hxx> |
16 | #include <TColgp_Array2OfVec.hxx> |
17 | |
18 | #include <Geom_TrimmedCurve.hxx> |
19 | #include <Geom_BSplineCurve.hxx> |
20 | #include <Geom_Circle.hxx> |
21 | #include <GeomConvert.hxx> |
22 | #include <Precision.hxx> |
23 | #include <Standard_ConstructionError.hxx> |
24 | #include <CSLib.hxx> |
25 | #include <CSLib_NormalStatus.hxx> |
26 | |
27 | |
28 | //======================================================================= |
29 | //function : GetShape |
30 | //purpose : |
31 | //======================================================================= |
32 | |
33 | void BlendFunc::GetShape (const BlendFunc_SectionShape SShape, |
34 | const Standard_Real MaxAng, |
35 | Standard_Integer& NbPoles, |
36 | Standard_Integer& NbKnots, |
37 | Standard_Integer& Degree, |
38 | Convert_ParameterisationType& TConv) |
39 | { |
40 | switch (SShape) { |
41 | case BlendFunc_Rational: |
42 | { |
43 | Standard_Integer NbSpan = |
c6541a0c |
44 | (Standard_Integer)(Ceiling(3.*Abs(MaxAng)/2./M_PI)); |
7fd59977 |
45 | NbPoles = 2*NbSpan+1; |
46 | NbKnots = NbSpan+1; |
47 | Degree = 2; |
48 | if (NbSpan == 1) { |
49 | TConv = Convert_TgtThetaOver2_1; |
50 | } |
51 | else { // QuasiAngular affin d'etre C1 (et meme beaucoup plus) |
52 | NbPoles = 7 ; |
53 | NbKnots = 2 ; |
54 | Degree = 6 ; |
55 | TConv = Convert_QuasiAngular; |
56 | } |
57 | } |
58 | break; |
59 | case BlendFunc_QuasiAngular: |
60 | { |
61 | NbPoles = 7 ; |
62 | NbKnots = 2 ; |
63 | Degree = 6 ; |
64 | TConv = Convert_QuasiAngular; |
65 | } |
66 | break; |
67 | case BlendFunc_Polynomial: |
68 | { |
69 | NbPoles = 8; |
70 | NbKnots = 2; |
71 | Degree = 7; |
72 | TConv = Convert_Polynomial; |
73 | } |
74 | break; |
75 | case BlendFunc_Linear: |
76 | { |
77 | NbPoles = 2; |
78 | NbKnots = 2; |
79 | Degree = 1; |
80 | } |
81 | break; |
82 | } |
83 | |
84 | } |
85 | |
86 | //======================================================================= |
87 | //function : GetMinimalWeights |
88 | //purpose : On suppose les extremum de poids sont obtenus pour les |
89 | // extremums d'angles (A verifier eventuelement pour Quasi-Angular) |
90 | //======================================================================= |
91 | |
92 | void BlendFunc::GetMinimalWeights(const BlendFunc_SectionShape SShape, |
93 | const Convert_ParameterisationType TConv, |
94 | const Standard_Real MinAng, |
95 | const Standard_Real MaxAng, |
96 | TColStd_Array1OfReal& Weights) |
97 | |
98 | { |
99 | switch (SShape) { |
100 | case BlendFunc_Polynomial: |
101 | case BlendFunc_Linear: |
102 | { |
103 | Weights.Init(1); |
104 | } |
105 | break; |
106 | case BlendFunc_Rational: |
107 | case BlendFunc_QuasiAngular: |
108 | { |
109 | gp_Ax2 popAx2(gp_Pnt(0, 0, 0), gp_Dir(0,0,1)); |
110 | gp_Circ C (popAx2, 1); |
111 | Handle(Geom_TrimmedCurve) Sect1 = |
112 | new Geom_TrimmedCurve(new Geom_Circle(C), 0., MaxAng); |
113 | Handle(Geom_BSplineCurve) CtoBspl = |
114 | GeomConvert::CurveToBSplineCurve(Sect1, TConv); |
115 | CtoBspl->Weights(Weights); |
116 | |
117 | TColStd_Array1OfReal poids (Weights.Lower(), Weights.Upper()); |
118 | Standard_Real angle_min = Max(Precision::PConfusion(), MinAng); |
119 | |
120 | Handle(Geom_TrimmedCurve) Sect2 = |
121 | new Geom_TrimmedCurve(new Geom_Circle(C), 0., angle_min); |
122 | CtoBspl = GeomConvert::CurveToBSplineCurve(Sect2, TConv); |
123 | CtoBspl->Weights(poids); |
124 | |
125 | for (Standard_Integer ii=Weights.Lower(); ii<=Weights.Upper(); ii++) { |
126 | if (poids(ii) < Weights(ii)) { |
127 | Weights(ii) = poids(ii); |
128 | } |
129 | } |
130 | } |
131 | break; |
132 | } |
133 | } |
134 | |
135 | |
136 | //======================================================================= |
137 | //function : IncrementeShape |
138 | //purpose : |
139 | //======================================================================= |
140 | |
141 | GeomAbs_Shape BlendFunc::NextShape (const GeomAbs_Shape S) |
142 | { |
143 | switch (S) |
144 | { |
145 | case GeomAbs_C0 : return GeomAbs_C1; |
146 | case GeomAbs_C1 : return GeomAbs_C2; |
147 | case GeomAbs_C2 : return GeomAbs_C3; |
148 | default : break; |
149 | } |
150 | return GeomAbs_CN; |
151 | } |
152 | |
153 | |
154 | //======================================================================= |
155 | //function : ComputeNormal |
156 | //purpose : |
157 | //======================================================================= |
158 | |
159 | Standard_Boolean BlendFunc::ComputeNormal (const Handle(Adaptor3d_HSurface)& Surf, |
160 | const gp_Pnt2d& p2d, gp_Vec& Normal) |
161 | { |
162 | const Standard_Integer MaxOrder=3; |
163 | const Standard_Real U = p2d.X(); |
164 | const Standard_Real V = p2d.Y(); |
165 | |
166 | Standard_Integer i,j; |
167 | |
168 | TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1); |
169 | for(i=1;i<=MaxOrder+1;i++) |
170 | DerSurf.SetValue(i,0,Surf->DN(U,V,i,0)); |
171 | for(i=0;i<=MaxOrder+1;i++) |
172 | for(j=1;j<=MaxOrder+1;j++) |
173 | DerSurf.SetValue(i,j,Surf->DN(U,V,i,j)); |
174 | |
175 | TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder); |
176 | for(i=0;i<=MaxOrder;i++) |
177 | for(j=0;j<=MaxOrder;j++) |
178 | DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf)); |
179 | |
180 | gp_Dir thenormal; |
181 | CSLib_NormalStatus stat; |
182 | Standard_Integer OrderU,OrderV; |
183 | const Standard_Real Umin = Surf->FirstUParameter(); |
184 | const Standard_Real Umax = Surf->LastUParameter(); |
185 | const Standard_Real Vmin = Surf->FirstVParameter(); |
186 | const Standard_Real Vmax = Surf->LastVParameter(); //szv: was FirstVParameter! |
187 | CSLib::Normal(MaxOrder,DerNUV,Standard_Real(1.e-9),U,V,Umin,Umax,Vmin,Vmax, |
188 | stat,thenormal,OrderU,OrderV); |
189 | if (stat == CSLib_Defined) |
190 | { |
191 | Normal.SetXYZ(thenormal.XYZ()); |
192 | return Standard_True; |
193 | } |
194 | return Standard_False; |
195 | } |
196 | |
197 | |
198 | //======================================================================= |
199 | //function : ComputeDNormal |
200 | //purpose : |
201 | //======================================================================= |
202 | |
203 | Standard_Boolean BlendFunc::ComputeDNormal (const Handle(Adaptor3d_HSurface)& Surf, |
204 | const gp_Pnt2d& p2d, gp_Vec& Normal, |
205 | gp_Vec& DNu, gp_Vec& DNv) |
206 | { |
207 | const Standard_Integer MaxOrder=3; |
208 | const Standard_Real U = p2d.X(); |
209 | const Standard_Real V = p2d.Y(); |
210 | |
211 | Standard_Integer i,j; |
212 | |
213 | TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1); |
214 | for(i=1;i<=MaxOrder+1;i++) |
215 | DerSurf.SetValue(i,0,Surf->DN(U,V,i,0)); |
216 | for(i=0;i<=MaxOrder+1;i++) |
217 | for(j=1;j<=MaxOrder+1;j++) |
218 | DerSurf.SetValue(i,j,Surf->DN(U,V,i,j)); |
219 | |
220 | TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder); |
221 | for(i=0;i<=MaxOrder;i++) |
222 | for(j=0;j<=MaxOrder;j++) |
223 | DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf)); |
224 | |
225 | gp_Dir thenormal; |
226 | CSLib_NormalStatus stat; |
227 | Standard_Integer OrderU,OrderV; |
228 | const Standard_Real Umin = Surf->FirstUParameter(); |
229 | const Standard_Real Umax = Surf->LastUParameter(); |
230 | const Standard_Real Vmin = Surf->FirstVParameter(); |
231 | const Standard_Real Vmax = Surf->LastVParameter(); //szv: was FirstVParameter! |
232 | CSLib::Normal(MaxOrder,DerNUV,Standard_Real(1.e-9),U,V,Umin,Umax,Vmin,Vmax, |
233 | stat,thenormal,OrderU,OrderV); |
234 | if (stat == CSLib_Defined) |
235 | { |
236 | Normal.SetXYZ(thenormal.XYZ()); |
237 | DNu = CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); |
238 | DNv = CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); |
239 | return Standard_True; |
240 | } |
241 | return Standard_False; |
242 | } |