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