7fd59977 |
1 | // File: GeomFill_GuideTrihedronAC.cxx |
2 | // Creted: Tue Jun 23 15:39:24 1998 |
3 | // Author: Stephanie HUMEAU |
4 | // <shu@sun17> |
5 | |
6 | |
7 | #include <GeomFill_GuideTrihedronAC.ixx> |
8 | |
9 | #include <gp_Pnt.hxx> |
10 | #include <gp_Dir.hxx> |
11 | #include <gp_Vec.hxx> |
12 | #include <Precision.hxx> |
13 | #include <TColStd_SequenceOfReal.hxx> |
14 | |
15 | #include <Approx_CurvlinFunc.hxx> |
16 | #include <Adaptor3d_Curve.hxx> |
17 | #include <GeomAdaptor.hxx> |
18 | #include <GeomAdaptor_HCurve.hxx> |
19 | |
20 | #include <GeomFill_Frenet.hxx> |
21 | #include <GeomLib.hxx> |
22 | |
23 | |
24 | //======================================================================= |
25 | //function : GuideTrihedron |
26 | //purpose : Constructor |
27 | //======================================================================= |
28 | GeomFill_GuideTrihedronAC::GeomFill_GuideTrihedronAC(const Handle(Adaptor3d_HCurve) & guide) |
29 | { |
30 | myCurve.Nullify(); |
31 | myGuide = guide; |
32 | myTrimG = guide; |
33 | myGuideAC = new (Approx_CurvlinFunc) (myGuide,1.e-7); |
34 | Lguide = myGuideAC->GetLength(); |
35 | UTol = STol = Precision::PConfusion(); |
36 | Orig1 = 0; // origines pour le cas path multi-edges |
37 | Orig2 = 1; |
38 | } |
39 | |
40 | //======================================================================= |
41 | //function : Guide |
42 | //purpose : calculation of trihedron |
43 | //======================================================================= |
44 | |
45 | Handle(Adaptor3d_HCurve) GeomFill_GuideTrihedronAC::Guide()const |
46 | { |
47 | return myGuide; |
48 | } |
49 | |
50 | //======================================================================= |
51 | //function : D0 |
52 | //purpose : calculation of trihedron |
53 | //======================================================================= |
54 | Standard_Boolean GeomFill_GuideTrihedronAC::D0(const Standard_Real Param, |
55 | gp_Vec& Tangent, |
56 | gp_Vec& Normal, |
57 | gp_Vec& BiNormal) |
58 | { |
59 | Standard_Real s = myCurveAC->GetSParameter(Param); // abscisse curviligne <=> Param |
60 | Standard_Real OrigG = Orig1 + s*(Orig2-Orig1); // abscisse curv sur le guide (cas multi-edges) |
61 | Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1); // param <=> s sur theGuide |
62 | |
63 | gp_Pnt P, PG; |
64 | gp_Vec To, B; |
65 | myTrimmed->D1(Param, P, To);//point et derivee au parametre Param sur myCurve |
66 | myTrimG->D0(tG, PG);// point au parametre tG sur myGuide |
67 | |
68 | gp_Vec n (P, PG); // vecteur definissant la normale |
69 | |
70 | Normal = n.Normalized(); |
71 | B = To.Crossed(Normal); |
72 | BiNormal = B/B.Magnitude(); |
73 | Tangent = Normal.Crossed(BiNormal); |
74 | Tangent.Normalize(); |
75 | |
76 | return Standard_True; |
77 | } |
78 | |
79 | //======================================================================= |
80 | //function : D1 |
81 | //purpose : calculation of trihedron and first derivative |
82 | //======================================================================= |
83 | Standard_Boolean GeomFill_GuideTrihedronAC::D1(const Standard_Real Param, |
84 | gp_Vec& Tangent, |
85 | gp_Vec& DTangent, |
86 | gp_Vec& Normal, |
87 | gp_Vec& DNormal, |
88 | gp_Vec& BiNormal, |
89 | gp_Vec& DBiNormal) |
90 | { |
91 | //triedre |
92 | Standard_Real s, OrigG, tG, dtg; |
93 | // abscisse curviligne <=> Param |
94 | s = myCurveAC->GetSParameter(Param); |
95 | // parametre <=> s sur theGuide |
96 | OrigG = Orig1 + s*(Orig2-Orig1); |
97 | // parametre <=> s sur theGuide |
98 | tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1); |
99 | |
100 | gp_Pnt P, PG; |
101 | gp_Vec To, DTo, TG, B, BPrim; |
102 | |
103 | myTrimmed->D2(Param, P, To, DTo); |
104 | myTrimG->D1(tG, PG, TG); |
105 | |
106 | gp_Vec n (P, PG), dn; |
107 | Standard_Real Norm = n.Magnitude(); |
108 | if (Norm < 1.e-12) { |
109 | Norm = 1; |
110 | #if DEB |
111 | cout << "GuideTrihedronAC : Normal indefinie" << endl; |
112 | #endif |
113 | } |
114 | |
115 | n /= Norm; |
116 | //derivee de n par rapport a Param |
117 | dtg = (Orig2-Orig1)*(To.Magnitude()/TG.Magnitude())*(Lguide/L); |
118 | dn.SetLinearForm(dtg, TG, -1, To); |
119 | dn /= Norm; |
120 | |
121 | // triedre |
122 | Normal = n; |
123 | B = To.Crossed(Normal); |
124 | Standard_Real NormB = B.Magnitude(); |
125 | B/= NormB; |
126 | |
127 | BiNormal = B; |
128 | |
129 | Tangent = Normal.Crossed(BiNormal); |
130 | Tangent.Normalize(); |
131 | |
132 | // derivee premiere |
133 | DNormal.SetLinearForm(-(n.Dot(dn)), n, dn); |
134 | |
135 | BPrim.SetLinearForm(DTo.Crossed(Normal), To.Crossed(DNormal)); |
136 | |
137 | DBiNormal.SetLinearForm(-(B.Dot(BPrim)), B, BPrim); |
138 | DBiNormal /= NormB; |
139 | |
140 | DTangent.SetLinearForm(Normal.Crossed(DBiNormal), DNormal.Crossed(BiNormal)); |
141 | |
142 | return Standard_True; |
143 | } |
144 | |
145 | |
146 | //======================================================================= |
147 | //function : D2 |
148 | //purpose : calculation of trihedron and derivatives |
149 | //======================================================================= |
150 | Standard_Boolean GeomFill_GuideTrihedronAC::D2(const Standard_Real Param, |
151 | gp_Vec& Tangent, |
152 | gp_Vec& DTangent, |
153 | gp_Vec& D2Tangent, |
154 | gp_Vec& Normal, |
155 | gp_Vec& DNormal, |
156 | gp_Vec& D2Normal, |
157 | gp_Vec& BiNormal, |
158 | gp_Vec& DBiNormal, |
159 | gp_Vec& D2BiNormal) |
160 | { |
161 | // abscisse curviligne <=> Param |
162 | Standard_Real s = myCurveAC->GetSParameter(Param); |
163 | // parametre <=> s sur theGuide |
164 | Standard_Real OrigG = Orig1 + s*(Orig2-Orig1); |
165 | Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(), |
166 | OrigG, 1); |
167 | |
168 | gp_Pnt P,PG; |
169 | gp_Vec TG,DTG; |
170 | // gp_Vec To,DTo,D2To,B; |
171 | gp_Vec To,DTo,D2To; |
172 | |
173 | myTrimmed->D3(Param, P, To, DTo, D2To); |
174 | myTrimG->D2(tG, PG, TG, DTG); |
175 | |
176 | Standard_Real NTo = To.Magnitude(); |
177 | Standard_Real N2To = To.SquareMagnitude(); |
178 | Standard_Real NTG = TG.Magnitude(); |
179 | Standard_Real N2Tp = TG.SquareMagnitude(); |
180 | Standard_Real d2tp_dt2, dtg_dt; |
181 | dtg_dt = (Orig2-Orig1)*(NTo/NTG)*(Lguide/L); |
182 | |
183 | gp_Vec n(P, PG); // vecteur definissant la normale |
184 | Standard_Real Norm = n.Magnitude(), ndn; |
7fd59977 |
185 | //derivee de n par rapport a Param |
186 | gp_Vec dn, d2n; |
187 | dn.SetLinearForm(dtg_dt, TG, -1, To); |
188 | |
189 | //derivee seconde de tG par rapport a Param |
190 | d2tp_dt2 = (Orig2-Orig1)*(Lguide/L) * |
191 | ( DTo.Dot(To) / (NTo*NTG) - N2To*TG*DTG*(Lguide/L) / (N2Tp*N2Tp)); |
192 | //derivee seconde de n par rapport a Param |
193 | d2n.SetLinearForm(dtg_dt*dtg_dt,DTG, d2tp_dt2, TG, -1, DTo); |
194 | |
195 | if (Norm > 1.e-9) { |
196 | n /= Norm; |
197 | dn /= Norm; |
198 | d2n /= Norm; |
199 | } |
200 | //triedre |
201 | Normal = n; |
202 | |
203 | gp_Vec TN, DTN, D2TN; |
204 | TN = To.Crossed(Normal); |
205 | |
206 | |
207 | Standard_Real Norma = TN.Magnitude(); |
208 | if (Norma > 1.e-9) TN /= Norma; |
209 | |
210 | BiNormal = TN; |
211 | |
212 | Tangent = Normal.Crossed(BiNormal); |
213 | // Tangent.Normalize(); |
214 | |
215 | // derivee premiere du triedre |
216 | // gp_Vec DTN = DTo.Crossed(Normal); |
217 | // gp_Vec TDN = To.Crossed(DNormal); |
218 | // gp_Vec DT = DTN + TDN; |
219 | |
220 | ndn = n.Dot(dn); |
221 | DNormal.SetLinearForm(-ndn, n, dn); |
222 | |
223 | DTN.SetLinearForm(DTo.Crossed(Normal), To.Crossed(DNormal)); |
224 | DTN /= Norma; |
225 | Standard_Real TNDTN = TN.Dot(DTN); |
226 | |
227 | DBiNormal.SetLinearForm(-TNDTN, TN, DTN); |
228 | |
229 | DTangent.SetLinearForm(Normal.Crossed(DBiNormal), |
230 | DNormal.Crossed(BiNormal)); |
231 | |
232 | |
233 | //derivee seconde du triedre |
234 | #ifdef DEB |
235 | gp_Vec DTDN = DTo.Crossed(DNormal); |
236 | #else |
237 | DTo.Crossed(DNormal); |
238 | #endif |
239 | Standard_Real TN2 = TN.SquareMagnitude(); |
240 | |
241 | D2Normal.SetLinearForm(-2*ndn, dn, |
242 | 3*ndn*ndn - (dn.SquareMagnitude() + n.Dot(d2n)),n, |
243 | d2n); |
244 | |
245 | |
246 | D2TN.SetLinearForm(1, D2To.Crossed(Normal), |
247 | 2, DTo.Crossed(DNormal), |
248 | To.Crossed(D2Normal)); |
249 | D2TN /= Norma; |
250 | |
251 | D2BiNormal.SetLinearForm(-2*TNDTN, DTN, |
252 | 3*TNDTN*TNDTN - (TN2 + TN.Dot(D2TN)), TN, |
253 | D2TN); |
254 | |
255 | D2Tangent.SetLinearForm(1, D2Normal.Crossed(BiNormal), |
256 | 2, DNormal.Crossed(DBiNormal), |
257 | Normal.Crossed(D2BiNormal) ); |
258 | |
259 | // return Standard_True; |
260 | return Standard_False; |
261 | |
262 | } |
263 | |
264 | |
265 | //======================================================================= |
266 | //function : Copy |
267 | //purpose : |
268 | //======================================================================= |
269 | Handle(GeomFill_TrihedronLaw) GeomFill_GuideTrihedronAC::Copy() const |
270 | { |
271 | Handle(GeomFill_GuideTrihedronAC) copy = |
272 | new (GeomFill_GuideTrihedronAC) (myGuide); |
273 | copy->SetCurve(myCurve); |
274 | copy->Origine(Orig1,Orig2); |
275 | return copy; |
276 | } |
277 | |
278 | //======================================================================= |
279 | //function : SetCurve |
280 | //purpose : |
281 | //======================================================================= |
282 | void GeomFill_GuideTrihedronAC::SetCurve(const Handle(Adaptor3d_HCurve)& C) |
283 | { |
284 | myCurve = C; |
285 | myTrimmed = C; |
286 | if (!myCurve.IsNull()) { |
287 | myCurveAC = new (Approx_CurvlinFunc) (C,1.e-7); |
288 | L = myCurveAC->GetLength(); |
289 | // CorrectOrient(myGuide); |
290 | } |
291 | } |
292 | |
293 | |
294 | //======================================================================= |
295 | //function : NbIntervals |
296 | //purpose : |
297 | //======================================================================= |
298 | Standard_Integer GeomFill_GuideTrihedronAC::NbIntervals(const GeomAbs_Shape S) const |
299 | { |
300 | Standard_Integer Nb; |
301 | Nb = myCurveAC->NbIntervals(S); |
302 | TColStd_Array1OfReal DiscC(1, Nb+1); |
303 | myCurveAC->Intervals(DiscC, S); |
304 | Nb = myGuideAC->NbIntervals(S); |
305 | TColStd_Array1OfReal DiscG(1, Nb+1); |
306 | myGuideAC->Intervals(DiscG, S); |
307 | |
308 | TColStd_SequenceOfReal Seq; |
309 | GeomLib::FuseIntervals(DiscC, DiscG, Seq); |
310 | |
311 | return Seq.Length()-1; |
312 | |
313 | } |
314 | |
315 | //====================================================================== |
316 | //function :Intervals |
317 | //purpose : |
318 | //======================================================================= |
319 | void GeomFill_GuideTrihedronAC::Intervals(TColStd_Array1OfReal& TT, |
320 | const GeomAbs_Shape S) const |
321 | { |
322 | Standard_Integer Nb, ii; |
323 | Nb = myCurveAC->NbIntervals(S); |
324 | TColStd_Array1OfReal DiscC(1, Nb+1); |
325 | myCurveAC->Intervals(DiscC, S); |
326 | Nb = myGuideAC->NbIntervals(S); |
327 | TColStd_Array1OfReal DiscG(1, Nb+1); |
328 | myGuideAC->Intervals(DiscG, S); |
329 | |
330 | TColStd_SequenceOfReal Seq; |
331 | GeomLib::FuseIntervals(DiscC, DiscG, Seq); |
332 | Nb = Seq.Length(); |
333 | |
334 | for (ii=1; ii<=Nb; ii++) { |
335 | TT(ii) = myCurveAC->GetUParameter(myCurve->GetCurve(), Seq(ii), 1); |
336 | } |
337 | |
338 | } |
339 | |
340 | //====================================================================== |
341 | //function :SetInterval |
342 | //purpose : |
343 | //======================================================================= |
344 | void GeomFill_GuideTrihedronAC::SetInterval(const Standard_Real First, |
345 | const Standard_Real Last) |
346 | { |
347 | myTrimmed = myCurve->Trim(First, Last, UTol); |
348 | Standard_Real Sf, Sl, U; |
349 | |
350 | Sf = myCurveAC->GetSParameter(First); |
351 | Sl = myCurveAC->GetSParameter(Last); |
352 | // if (Sl>1) Sl=1; |
353 | // myCurveAC->Trim(Sf, Sl, UTol); |
354 | |
355 | U = Orig1 + Sf*(Orig2-Orig1); |
356 | Sf = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1); |
357 | U = Orig1 + Sl*(Orig2-Orig1); |
358 | Sl = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1); |
359 | myTrimG = myGuide->Trim(Sf, Sl, UTol); |
360 | } |
361 | |
362 | |
363 | |
364 | //======================================================================= |
365 | //function : GetAverageLaw |
366 | //purpose : |
367 | //======================================================================= |
368 | void GeomFill_GuideTrihedronAC::GetAverageLaw(gp_Vec& ATangent, |
369 | gp_Vec& ANormal, |
370 | gp_Vec& ABiNormal) |
371 | { |
372 | Standard_Integer ii; |
373 | Standard_Real t, Delta = (myCurve->LastParameter() - |
374 | myCurve->FirstParameter())/20.001; |
375 | |
376 | ATangent.SetCoord(0.,0.,0.); |
377 | ANormal.SetCoord(0.,0.,0.); |
378 | ABiNormal.SetCoord(0.,0.,0.); |
379 | gp_Vec T, N, B; |
380 | |
381 | for (ii=1, T; ii<=20; ii++) { |
382 | t = myCurve->FirstParameter() +(ii-1)*Delta; |
383 | D0(t, T, N, B); |
384 | ATangent +=T; |
385 | ANormal +=N; |
386 | ABiNormal+=B; |
387 | } |
388 | ATangent /= 20; |
389 | ANormal /= 20; |
390 | ABiNormal /= 20; |
391 | } |
392 | |
393 | //======================================================================= |
394 | //function : IsConstant |
395 | //purpose : |
396 | //======================================================================= |
397 | Standard_Boolean GeomFill_GuideTrihedronAC::IsConstant() const |
398 | { |
399 | return Standard_False; |
400 | } |
401 | |
402 | //======================================================================= |
403 | //function : IsOnlyBy3dCurve |
404 | //purpose : |
405 | //======================================================================= |
406 | Standard_Boolean GeomFill_GuideTrihedronAC::IsOnlyBy3dCurve() const |
407 | { |
408 | return Standard_False; |
409 | } |
410 | |
411 | //======================================================================= |
412 | //function : Origine |
413 | //purpose : |
414 | //======================================================================= |
415 | void GeomFill_GuideTrihedronAC::Origine(const Standard_Real OrACR1, |
416 | const Standard_Real OrACR2) |
417 | { |
418 | Orig1 = OrACR1; |
419 | Orig2 = OrACR2; |
420 | } |