b311480e |
1 | // Created on: 1998-06-02 |
2 | // Created by: Philippe NOUAILLE |
3 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <Blend_Point.hxx> |
7fd59977 |
19 | #include <BlendFunc.hxx> |
42cf5bc1 |
20 | #include <BlendFunc_ChAsym.hxx> |
7fd59977 |
21 | #include <ElCLib.hxx> |
42cf5bc1 |
22 | #include <gp_Lin.hxx> |
23 | #include <gp_Pnt.hxx> |
24 | #include <gp_Vec.hxx> |
25 | #include <gp_Vec2d.hxx> |
26 | #include <math_Gauss.hxx> |
27 | #include <math_Matrix.hxx> |
28 | #include <math_SVD.hxx> |
7fd59977 |
29 | #include <Precision.hxx> |
30 | #include <Standard_NotImplemented.hxx> |
31 | |
32 | //======================================================================= |
33 | //function : BlendFunc_ChAsym |
34 | //purpose : |
35 | //======================================================================= |
c22b52d6 |
36 | BlendFunc_ChAsym::BlendFunc_ChAsym(const Handle(Adaptor3d_Surface)& S1, |
37 | const Handle(Adaptor3d_Surface)& S2, |
38 | const Handle(Adaptor3d_Curve)& C) : |
7fd59977 |
39 | surf1(S1),surf2(S2), |
40 | curv(C), tcurv(C), |
d533dafb |
41 | param(0), |
42 | dist1(RealLast()), |
43 | angle(RealLast()), |
44 | tgang(RealLast()), |
7fd59977 |
45 | FX(1, 4), |
46 | DX(1, 4, 1, 4), |
47 | istangent(Standard_True), |
d533dafb |
48 | choix(0), |
7fd59977 |
49 | distmin(RealLast()) |
50 | { |
51 | } |
52 | |
53 | |
54 | //======================================================================= |
55 | //function : NbEquations |
56 | //purpose : |
57 | //======================================================================= |
58 | |
59 | Standard_Integer BlendFunc_ChAsym::NbEquations () const |
60 | { |
61 | return 4; |
62 | } |
63 | |
64 | |
65 | |
66 | //======================================================================= |
67 | //function : Set |
68 | //purpose : |
69 | //======================================================================= |
70 | |
71 | void BlendFunc_ChAsym::Set(const Standard_Real Param) |
72 | { |
73 | param = Param; |
74 | } |
75 | |
76 | //======================================================================= |
77 | //function : Set |
78 | //purpose : Segmente la courbe a sa partie utile. |
79 | // La precision est prise arbitrairement petite !? |
80 | //======================================================================= |
81 | |
82 | void BlendFunc_ChAsym::Set(const Standard_Real First, const Standard_Real Last) |
83 | { |
84 | tcurv = curv->Trim(First, Last, 1.e-12); |
85 | } |
86 | |
87 | //======================================================================= |
88 | //function : GetTolerance |
89 | //purpose : |
90 | //======================================================================= |
91 | |
92 | void BlendFunc_ChAsym::GetTolerance(math_Vector& Tolerance, const Standard_Real Tol) const |
93 | { |
94 | Tolerance(1) = surf1->UResolution(Tol); |
95 | Tolerance(2) = surf1->VResolution(Tol); |
96 | Tolerance(3) = surf2->UResolution(Tol); |
97 | Tolerance(4) = surf2->VResolution(Tol); |
98 | } |
99 | |
100 | |
101 | //======================================================================= |
102 | //function : GetBounds |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | void BlendFunc_ChAsym::GetBounds(math_Vector& InfBound, math_Vector& SupBound) const |
107 | { |
108 | InfBound(1) = surf1->FirstUParameter(); |
109 | InfBound(2) = surf1->FirstVParameter(); |
110 | InfBound(3) = surf2->FirstUParameter(); |
111 | InfBound(4) = surf2->FirstVParameter(); |
112 | SupBound(1) = surf1->LastUParameter(); |
113 | SupBound(2) = surf1->LastVParameter(); |
114 | SupBound(3) = surf2->LastUParameter(); |
115 | SupBound(4) = surf2->LastVParameter(); |
116 | |
117 | for(Standard_Integer i = 1; i <= 4; i++){ |
118 | if(!Precision::IsInfinite(InfBound(i)) && |
119 | !Precision::IsInfinite(SupBound(i))) { |
120 | const Standard_Real range = (SupBound(i) - InfBound(i)); |
121 | InfBound(i) -= range; |
122 | SupBound(i) += range; |
123 | } |
124 | } |
125 | } |
126 | |
127 | |
128 | //======================================================================= |
129 | //function : IsSolution |
130 | //purpose : |
131 | //======================================================================= |
132 | |
133 | Standard_Boolean BlendFunc_ChAsym::IsSolution(const math_Vector& Sol, const Standard_Real Tol) |
134 | { |
135 | math_Vector valsol(1, 4), secmember(1, 4); |
136 | math_Matrix gradsol(1, 4, 1, 4); |
137 | |
138 | gp_Pnt ptgui; |
139 | gp_Vec np, dnp, d1gui, d2gui, Nsurf1, dwtsurf1; |
140 | gp_Vec d1u1, d1v1, d1u2, d1v2; |
141 | Standard_Real Normg; |
142 | |
143 | tcurv->D2(param, ptgui, d1gui, d2gui); |
144 | Normg = d1gui.Magnitude(); |
145 | np = d1gui.Normalized(); |
146 | dnp = (d2gui - np.Dot(d2gui) * np) / Normg; |
147 | |
148 | if (choix%2 != 0) { |
149 | np.Reverse(); |
150 | dnp.Reverse(); |
151 | Normg = -Normg; |
152 | } |
153 | |
154 | surf1->D1(Sol(1), Sol(2), pt1, d1u1, d1v1); |
155 | Nsurf1 = d1u1.Crossed(d1v1); |
156 | tsurf1 = Nsurf1.Crossed(np); |
157 | dwtsurf1 = Nsurf1.Crossed(dnp); |
158 | |
159 | surf2->D1(Sol(3), Sol(4), pt2, d1u2, d1v2); |
160 | |
161 | gp_Vec pguis1(ptgui, pt1), pguis2(ptgui, pt2); |
162 | gp_Vec CrossVec, s1s2(pt1, pt2); |
163 | Standard_Real PScaInv = 1. / tsurf1.Dot(s1s2), F4, temp; |
164 | Standard_Real maxpiv = 1.e-9; |
165 | Standard_Real Nordu1 = d1u1.Magnitude(), |
166 | Nordv1 = d1v1.Magnitude(); |
167 | |
168 | temp = 2. * (Nordu1 + Nordv1) * s1s2.Magnitude() + 2. * Nordu1 * Nordv1; |
169 | |
170 | Values(Sol, valsol, gradsol); |
171 | |
172 | if (Abs(valsol(1)) < Tol && |
173 | Abs(valsol(2)) < Tol && |
174 | Abs(valsol(3)) < 2. * dist1 * Tol && |
175 | Abs(valsol(4)) < Tol * (1. + tgang) * Abs(PScaInv) * temp) { |
176 | |
177 | secmember(1) = Normg - dnp.Dot(pguis1); |
178 | secmember(2) = Normg - dnp.Dot(pguis2); |
179 | secmember(3) = - 2. * d1gui.Dot(pguis1); |
180 | |
181 | CrossVec = tsurf1.Crossed(s1s2); |
182 | F4 = np.Dot(CrossVec) * PScaInv; |
183 | temp = dnp.Dot(CrossVec) + np.Dot(dwtsurf1.Crossed(s1s2)); |
184 | |
185 | temp -= F4 * dwtsurf1.Dot(s1s2); |
186 | secmember(4) = PScaInv * temp; |
187 | |
188 | math_Gauss Resol(gradsol, maxpiv); |
189 | |
190 | if (Resol.IsDone()) { |
191 | Resol.Solve(secmember); |
192 | istangent = Standard_False; |
193 | } |
194 | else { |
195 | math_SVD SingRS (gradsol); |
196 | if (SingRS.IsDone()) { |
197 | math_Vector DEDT(1,4); |
198 | DEDT = secmember; |
199 | SingRS.Solve(DEDT, secmember, 1.e-6); |
200 | istangent = Standard_False; |
201 | } |
202 | else istangent = Standard_True; |
203 | } |
204 | |
205 | if (!istangent) { |
206 | tg1.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1); |
207 | tg2.SetLinearForm(secmember(3), d1u2, secmember(4), d1v2); |
208 | tg12d.SetCoord(secmember(1),secmember(2)); |
209 | tg22d.SetCoord(secmember(3),secmember(4)); |
210 | } |
211 | |
212 | distmin = Min( distmin, pt1.Distance(pt2)); |
213 | |
214 | return Standard_True; |
215 | } |
216 | |
217 | istangent = Standard_True; |
218 | return Standard_False; |
219 | } |
220 | |
221 | |
222 | //======================================================================= |
223 | //function : GetMinimalDistance |
224 | //purpose : |
225 | //======================================================================= |
226 | |
227 | Standard_Real BlendFunc_ChAsym::GetMinimalDistance() const |
228 | { |
229 | return distmin; |
230 | } |
231 | |
232 | //======================================================================= |
233 | //function : ComputeValues |
234 | //purpose : |
235 | //======================================================================= |
236 | Standard_Boolean BlendFunc_ChAsym::ComputeValues(const math_Vector& X, |
237 | const Standard_Integer DegF, |
238 | const Standard_Integer DegL) |
239 | { |
240 | if (DegF > DegL) return Standard_False; |
241 | |
242 | gp_Vec np, d1gui, d1u1, d1v1, d2u1, d2v1, d2uv1, d1u2, d1v2, Nsurf1; |
243 | gp_Pnt ptgui; |
244 | Standard_Real PScaInv, F4; |
245 | |
246 | tcurv->D1(param, ptgui, d1gui); |
247 | nplan = d1gui.Normalized(); |
248 | np = nplan; |
249 | |
250 | if (choix%2 != 0) np.Reverse(); |
251 | |
252 | if ( (DegF == 0) && (DegL == 0) ) { |
253 | surf1->D1(X(1), X(2), pt1, d1u1, d1v1); |
254 | pt2 = surf2->Value(X(3), X(4)); |
255 | } |
256 | else { |
257 | surf1->D2(X(1), X(2), pt1, d1u1, d1v1, d2u1, d2v1, d2uv1); |
258 | surf2->D1(X(3), X(4), pt2, d1u2, d1v2); |
259 | } |
260 | |
261 | Nsurf1 = d1u1.Crossed(d1v1); |
262 | tsurf1 = Nsurf1.Crossed(np); |
263 | |
264 | gp_Vec nps1(ptgui, pt1), s1s2(pt1, pt2);//, tempVec; |
265 | PScaInv = 1. / tsurf1.Dot(s1s2); |
266 | F4 = np.Dot(tsurf1.Crossed(s1s2)) * PScaInv; |
267 | |
268 | if (DegF == 0) { |
269 | Standard_Real Dist; |
270 | Dist = ptgui.XYZ().Dot(np.XYZ()); |
271 | |
272 | FX(1) = pt1.XYZ().Dot(np.XYZ()) - Dist; |
273 | FX(2) = pt2.XYZ().Dot(np.XYZ()) - Dist; |
274 | FX(3) = dist1 * dist1 - nps1.SquareMagnitude(); |
275 | FX(4) = tgang - F4; |
276 | } |
277 | |
278 | if (DegL == 1) { |
279 | Standard_Real temp; |
280 | gp_Vec tempVec; |
281 | gp_Vec d1utsurf1, d1vtsurf1; |
282 | d1utsurf1 = (d2u1.Crossed(d1v1) + d1u1.Crossed(d2uv1)).Crossed(np); |
283 | d1vtsurf1 = (d2uv1.Crossed(d1v1) + d1u1.Crossed(d2v1)).Crossed(np); |
284 | |
285 | DX(1, 1) = np.Dot(d1u1); |
286 | DX(1, 2) = np.Dot(d1v1); |
287 | DX(1, 3) = 0.; |
288 | DX(1, 4) = 0.; |
289 | |
290 | DX(2, 1) = 0.; |
291 | DX(2, 2) = 0.; |
292 | DX(2, 3) = np.Dot(d1u2); |
293 | DX(2, 4) = np.Dot(d1v2); |
294 | |
295 | tempVec = -2. * nps1; |
296 | DX(3, 1) = d1u1.Dot(tempVec); |
297 | DX(3, 2) = d1v1.Dot(tempVec); |
298 | DX(3, 3) = 0.; |
299 | DX(3, 4) = 0.; |
300 | |
301 | temp = F4 * (d1utsurf1.Dot(s1s2) - tsurf1.Dot(d1u1)); |
302 | temp += np.Dot(tsurf1.Crossed(d1u1) - d1utsurf1.Crossed(s1s2)); |
303 | DX(4, 1) = temp * PScaInv; |
304 | |
305 | temp = F4 * (d1vtsurf1.Dot(s1s2) - tsurf1.Dot(d1v1)); |
306 | temp += np.Dot(tsurf1.Crossed(d1v1) - d1vtsurf1.Crossed(s1s2)); |
307 | DX(4, 2) = temp * PScaInv; |
308 | |
309 | temp = F4 * tsurf1.Dot(d1u2) - np.Dot(tsurf1.Crossed(d1u2)); |
310 | DX(4, 3) = temp * PScaInv; |
311 | |
312 | temp = F4 * tsurf1.Dot(d1v2) - np.Dot(tsurf1.Crossed(d1v2)); |
313 | DX(4, 4) = temp * PScaInv; |
314 | } |
315 | |
316 | return Standard_True; |
317 | |
318 | } |
319 | |
320 | |
321 | //======================================================================= |
322 | //function : Value |
323 | //purpose : |
324 | //======================================================================= |
325 | |
326 | Standard_Boolean BlendFunc_ChAsym::Value(const math_Vector& X, math_Vector& F) |
327 | { |
328 | const Standard_Boolean Error = ComputeValues(X, 0, 0); |
329 | F = FX; |
330 | return Error; |
331 | } |
332 | |
333 | |
334 | //======================================================================= |
335 | //function : Derivatives |
336 | //purpose : |
337 | //======================================================================= |
338 | |
339 | Standard_Boolean BlendFunc_ChAsym::Derivatives(const math_Vector& X, math_Matrix& D) |
340 | { |
341 | const Standard_Boolean Error = ComputeValues(X, 1, 1); |
342 | D = DX; |
343 | return Error; |
344 | } |
345 | |
346 | |
347 | //======================================================================= |
348 | //function : Values |
349 | //purpose : |
350 | //======================================================================= |
351 | |
352 | Standard_Boolean BlendFunc_ChAsym::Values(const math_Vector& X, math_Vector& F, math_Matrix& D) |
353 | { |
354 | const Standard_Boolean Error = ComputeValues(X, 0, 1); |
355 | F = FX; |
356 | D = DX; |
357 | return Error; |
358 | } |
359 | |
360 | |
361 | //======================================================================= |
362 | //function : PointOnS1 |
363 | //purpose : |
364 | //======================================================================= |
365 | |
366 | const gp_Pnt& BlendFunc_ChAsym::PointOnS1 () const |
367 | { |
368 | return pt1; |
369 | } |
370 | |
371 | |
372 | //======================================================================= |
373 | //function : PointOnS2 |
374 | //purpose : |
375 | //======================================================================= |
376 | |
377 | const gp_Pnt& BlendFunc_ChAsym::PointOnS2 () const |
378 | { |
379 | return pt2; |
380 | } |
381 | |
382 | |
383 | //======================================================================= |
384 | //function : IsTangencyPoint |
385 | //purpose : |
386 | //======================================================================= |
387 | |
388 | Standard_Boolean BlendFunc_ChAsym::IsTangencyPoint () const |
389 | { |
390 | return istangent; |
391 | } |
392 | |
393 | |
394 | //======================================================================= |
395 | //function : TangentOnS1 |
396 | //purpose : |
397 | //======================================================================= |
398 | |
399 | const gp_Vec& BlendFunc_ChAsym::TangentOnS1 () const |
400 | { |
401 | if (istangent) |
9775fa61 |
402 | throw Standard_DomainError("BlendFunc_ChAsym::TangentOnS1"); |
7fd59977 |
403 | return tg1; |
404 | } |
405 | |
406 | |
407 | //======================================================================= |
408 | //function : Tangent2dOnS1 |
409 | //purpose : |
410 | //======================================================================= |
411 | |
412 | const gp_Vec2d& BlendFunc_ChAsym::Tangent2dOnS1 () const |
413 | { |
414 | if (istangent) |
9775fa61 |
415 | throw Standard_DomainError("BlendFunc_ChAsym::Tangent2dOnS1"); |
7fd59977 |
416 | return tg12d; |
417 | } |
418 | |
419 | //======================================================================= |
420 | //function : TangentOnS2 |
421 | //purpose : |
422 | //======================================================================= |
423 | |
424 | const gp_Vec& BlendFunc_ChAsym::TangentOnS2 () const |
425 | { |
426 | if (istangent) |
9775fa61 |
427 | throw Standard_DomainError("BlendFunc_ChAsym::TangentOnS2"); |
7fd59977 |
428 | return tg2; |
429 | } |
430 | |
431 | |
432 | //======================================================================= |
433 | //function : Tangent2dOnS2 |
434 | //purpose : |
435 | //======================================================================= |
436 | |
437 | const gp_Vec2d& BlendFunc_ChAsym::Tangent2dOnS2 () const |
438 | { |
439 | if (istangent) |
9775fa61 |
440 | throw Standard_DomainError("BlendFunc_ChAsym::Tangent2dOnS2"); |
7fd59977 |
441 | return tg22d; |
442 | } |
443 | |
444 | |
445 | //======================================================================= |
446 | //function : TwistOnS1 |
447 | //purpose : |
448 | //======================================================================= |
449 | |
450 | Standard_Boolean BlendFunc_ChAsym::TwistOnS1() const |
451 | { |
452 | if (istangent) |
9775fa61 |
453 | throw Standard_DomainError("BlendFunc_ChAsym::TwistOnS1"); |
7fd59977 |
454 | return tg1.Dot(nplan) < 0.; |
455 | } |
456 | |
457 | //======================================================================= |
458 | //function : TwistOnS2 |
459 | //purpose : |
460 | //======================================================================= |
461 | |
462 | Standard_Boolean BlendFunc_ChAsym::TwistOnS2() const |
463 | { |
464 | if (istangent) |
9775fa61 |
465 | throw Standard_DomainError("BlendFunc_ChAsym::TwistOnS2"); |
7fd59977 |
466 | return tg2.Dot(nplan) < 0.; |
467 | } |
468 | |
469 | //======================================================================= |
470 | //function : Tangent |
471 | //purpose : TgF,NmF et TgL,NmL les tangentes et normales respectives |
472 | // aux surfaces S1 et S2 |
473 | //======================================================================= |
474 | |
475 | void BlendFunc_ChAsym::Tangent(const Standard_Real U1, |
476 | const Standard_Real V1, |
477 | const Standard_Real U2, |
478 | const Standard_Real V2, |
479 | gp_Vec& TgF, |
480 | gp_Vec& TgL, |
481 | gp_Vec& NmF, |
482 | gp_Vec& NmL) const |
483 | { |
484 | gp_Pnt Pt1,Pt2,ptgui; |
485 | gp_Vec d1u1,d1v1,d1u2,d1v2; |
486 | gp_Vec np, d1gui; |
487 | Standard_Boolean revF = Standard_False; |
488 | Standard_Boolean revL = Standard_False; |
489 | |
490 | tcurv->D1(param, ptgui, d1gui); |
491 | np = d1gui.Normalized(); |
492 | |
493 | surf1->D1(U1,V1,Pt1,d1u1,d1v1); |
494 | NmF = d1u1.Crossed(d1v1); |
495 | |
496 | surf2->D1(U2,V2,Pt2,d1u2,d1v2); |
497 | NmL = d1u2.Crossed(d1v2); |
498 | |
499 | TgF = (np.Crossed(NmF)).Normalized(); |
500 | TgL = (np.Crossed(NmL)).Normalized(); |
501 | |
502 | if ( (choix == 2)||(choix == 5) ){ |
503 | revF = Standard_True; |
504 | revL = Standard_True; |
505 | } |
506 | |
507 | if ( (choix == 4)||(choix == 7) ) |
508 | revL = Standard_True; |
509 | |
510 | if ( (choix == 3)||(choix == 8) ) |
511 | revF = Standard_True; |
512 | |
513 | if ( revF ) |
514 | TgF.Reverse(); |
515 | if ( revL ) |
516 | TgL.Reverse(); |
517 | } |
518 | |
519 | |
520 | |
521 | //======================================================================= |
522 | //function : Section |
523 | //purpose : |
524 | //======================================================================= |
525 | |
35e08fe8 |
526 | void BlendFunc_ChAsym::Section(const Standard_Real /*Param*/, |
7fd59977 |
527 | const Standard_Real U1, |
528 | const Standard_Real V1, |
529 | const Standard_Real U2, |
530 | const Standard_Real V2, |
531 | Standard_Real& Pdeb, |
532 | Standard_Real& Pfin, |
533 | gp_Lin& C) |
534 | { |
535 | const gp_Pnt Pt1 = surf1->Value(U1,V1); |
536 | const gp_Pnt Pt2 = surf2->Value(U2,V2); |
537 | const gp_Dir dir( gp_Vec(Pt1,Pt2) ); |
538 | |
539 | C.SetLocation(Pt1); |
540 | C.SetDirection(dir); |
541 | |
542 | Pdeb = 0.; |
543 | Pfin = ElCLib::Parameter(C, Pt2); |
544 | } |
545 | |
546 | |
547 | //======================================================================= |
548 | //function : IsRational |
549 | //purpose : |
550 | //======================================================================= |
551 | |
552 | Standard_Boolean BlendFunc_ChAsym::IsRational () const |
553 | { |
554 | return Standard_False; |
555 | } |
556 | |
557 | //======================================================================= |
558 | //function : GetSectionSize |
559 | //purpose : |
560 | //======================================================================= |
561 | Standard_Real BlendFunc_ChAsym::GetSectionSize() const |
562 | { |
9775fa61 |
563 | throw Standard_NotImplemented("BlendFunc_ChAsym::GetSectionSize()"); |
7fd59977 |
564 | } |
565 | |
566 | //======================================================================= |
567 | //function : GetMinimalWeight |
568 | //purpose : |
569 | //======================================================================= |
570 | void BlendFunc_ChAsym::GetMinimalWeight(TColStd_Array1OfReal& Weights) const |
571 | { |
572 | Weights.Init(1); |
573 | } |
574 | |
575 | //======================================================================= |
576 | //function : NbIntervals |
577 | //purpose : |
578 | //======================================================================= |
579 | |
580 | Standard_Integer BlendFunc_ChAsym::NbIntervals (const GeomAbs_Shape S) const |
581 | { |
582 | return curv->NbIntervals(BlendFunc::NextShape(S)); |
583 | } |
584 | |
585 | |
586 | //======================================================================= |
587 | //function : Intervals |
588 | //purpose : |
589 | //======================================================================= |
590 | |
591 | void BlendFunc_ChAsym::Intervals (TColStd_Array1OfReal& T, const GeomAbs_Shape S) const |
592 | { |
593 | curv->Intervals(T, BlendFunc::NextShape(S)); |
594 | } |
595 | |
596 | //======================================================================= |
597 | //function : GetShape |
598 | //purpose : |
599 | //======================================================================= |
600 | |
601 | void BlendFunc_ChAsym::GetShape (Standard_Integer& NbPoles, |
602 | Standard_Integer& NbKnots, |
603 | Standard_Integer& Degree, |
604 | Standard_Integer& NbPoles2d) |
605 | { |
606 | NbPoles = 2; |
607 | NbPoles2d = 2; |
608 | NbKnots = 2; |
609 | Degree = 1; |
610 | } |
611 | |
612 | //======================================================================= |
613 | //function : GetTolerance |
614 | //purpose : Determine les Tolerances a utiliser dans les approximations. |
615 | //======================================================================= |
616 | void BlendFunc_ChAsym::GetTolerance(const Standard_Real BoundTol, |
35e08fe8 |
617 | const Standard_Real, |
618 | const Standard_Real, |
7fd59977 |
619 | math_Vector& Tol3d, |
35e08fe8 |
620 | math_Vector&) const |
7fd59977 |
621 | { |
622 | Tol3d.Init(BoundTol); |
623 | } |
624 | |
625 | //======================================================================= |
626 | //function : Knots |
627 | //purpose : |
628 | //======================================================================= |
629 | |
630 | void BlendFunc_ChAsym::Knots(TColStd_Array1OfReal& TKnots) |
631 | { |
632 | TKnots(1) = 0.; |
633 | TKnots(2) = 1.; |
634 | } |
635 | |
636 | |
637 | //======================================================================= |
638 | //function : Mults |
639 | //purpose : |
640 | //======================================================================= |
641 | |
642 | void BlendFunc_ChAsym::Mults(TColStd_Array1OfInteger& TMults) |
643 | { |
644 | TMults(1) = 2; |
645 | TMults(2) = 2; |
646 | } |
647 | |
648 | |
649 | //======================================================================= |
650 | //function : Section |
651 | //purpose : |
652 | //======================================================================= |
653 | |
654 | void BlendFunc_ChAsym::Section(const Blend_Point& P, |
655 | TColgp_Array1OfPnt& Poles, |
656 | TColgp_Array1OfPnt2d& Poles2d, |
657 | TColStd_Array1OfReal& Weights) |
658 | { |
659 | Standard_Real u1, v1, u2, v2, prm = P.Parameter(); |
660 | Standard_Integer low = Poles.Lower(); |
661 | Standard_Integer upp = Poles.Upper(); |
662 | math_Vector X(1,4), F(1,4); |
663 | |
664 | P.ParametersOnS1(u1, v1); |
665 | P.ParametersOnS2(u2, v2); |
666 | X(1) = u1; |
667 | X(2) = v1; |
668 | X(3) = u2; |
669 | X(4) = v2; |
670 | Poles2d(Poles2d.Lower()).SetCoord(u1,v1); |
671 | Poles2d(Poles2d.Upper()).SetCoord(u2,v2); |
672 | |
673 | Set(prm); |
674 | Value(X,F); |
675 | Poles(low) = PointOnS1(); |
676 | Poles(upp) = PointOnS2(); |
677 | Weights(low) = 1.0; |
678 | Weights(upp) = 1.0; |
679 | } |
680 | |
681 | |
682 | //======================================================================= |
683 | //function : Section |
684 | //purpose : |
685 | //======================================================================= |
686 | |
687 | Standard_Boolean BlendFunc_ChAsym::Section |
688 | (const Blend_Point& P, |
689 | TColgp_Array1OfPnt& Poles, |
690 | TColgp_Array1OfVec& DPoles, |
691 | TColgp_Array1OfPnt2d& Poles2d, |
692 | TColgp_Array1OfVec2d& DPoles2d, |
693 | TColStd_Array1OfReal& Weights, |
694 | TColStd_Array1OfReal& DWeights) |
695 | { |
696 | math_Vector Sol(1, 4), valsol(1, 4), secmember(1, 4); |
697 | math_Matrix gradsol(1, 4, 1, 4); |
698 | Standard_Real prm = P.Parameter(); |
699 | Standard_Integer low = Poles.Lower(); |
700 | Standard_Integer upp = Poles.Upper(); |
701 | |
702 | P.ParametersOnS1(Sol(1),Sol(2)); |
703 | P.ParametersOnS2(Sol(3),Sol(4)); |
704 | Set(prm); |
705 | |
706 | Poles2d(Poles2d.Lower()).SetCoord(Sol(1),Sol(2)); |
707 | Poles2d(Poles2d.Upper()).SetCoord(Sol(3),Sol(4)); |
708 | Poles(low) = PointOnS1(); |
709 | Poles(upp) = PointOnS2(); |
710 | Weights(low) = 1.0; |
711 | Weights(upp) = 1.0; |
712 | |
713 | gp_Pnt ptgui; |
714 | gp_Vec np, dnp, d1gui, d2gui, Nsurf1, dwtsurf1; |
715 | gp_Vec d1u1, d1v1, d1u2, d1v2; |
716 | Standard_Real Normg; |
717 | |
718 | tcurv->D2(param, ptgui, d1gui, d2gui); |
719 | Normg = d1gui.Magnitude(); |
720 | np = d1gui.Normalized(); |
721 | dnp = (d2gui - np.Dot(d2gui) * np) / Normg; |
722 | |
723 | if (choix%2 != 0) { |
724 | np.Reverse(); |
725 | dnp.Reverse(); |
726 | Normg = -Normg; |
727 | } |
728 | |
729 | surf1->D1(Sol(1), Sol(2), pt1, d1u1, d1v1); |
730 | Nsurf1 = d1u1.Crossed(d1v1); |
731 | tsurf1 = Nsurf1.Crossed(np); |
732 | dwtsurf1 = Nsurf1.Crossed(dnp); |
733 | |
734 | surf2->D1(Sol(3), Sol(4), pt2, d1u2, d1v2); |
735 | |
736 | gp_Vec pguis1(ptgui, pt1), pguis2(ptgui, pt2); |
737 | gp_Vec CrossVec, s1s2(pt1, pt2); |
738 | Standard_Real PScaInv = 1. / tsurf1.Dot(s1s2), F4, temp; |
739 | Standard_Real maxpiv = 1.e-9; |
740 | Standard_Real Nordu1 = d1u1.Magnitude(), |
741 | Nordv1 = d1v1.Magnitude(); |
742 | |
743 | temp = 2. * (Nordu1 + Nordv1) * s1s2.Magnitude() + 2. * Nordu1 * Nordv1; |
744 | |
745 | Values(Sol, valsol, gradsol); |
746 | |
747 | secmember(1) = Normg - dnp.Dot(pguis1); |
748 | secmember(2) = Normg - dnp.Dot(pguis2); |
749 | secmember(3) = - 2. * d1gui.Dot(pguis1); |
750 | |
751 | CrossVec = tsurf1.Crossed(s1s2); |
752 | F4 = np.Dot(CrossVec) * PScaInv; |
753 | temp = dnp.Dot(CrossVec) + np.Dot(dwtsurf1.Crossed(s1s2)); |
754 | temp -= F4 * dwtsurf1.Dot(s1s2); |
755 | secmember(4) = PScaInv * temp; |
756 | |
757 | math_Gauss Resol(gradsol, maxpiv); |
758 | |
759 | if (Resol.IsDone()) { |
760 | Resol.Solve(secmember); |
761 | istangent = Standard_False; |
762 | } |
763 | else { |
764 | math_SVD SingRS (gradsol); |
765 | if (SingRS.IsDone()) { |
766 | math_Vector DEDT(1,4); |
767 | DEDT = secmember; |
768 | SingRS.Solve(DEDT, secmember, 1.e-6); |
769 | istangent = Standard_False; |
770 | } |
771 | else istangent = Standard_True; |
772 | } |
773 | |
774 | if (!istangent) { |
775 | tg1.SetLinearForm(secmember(1), d1u1, secmember(2), d1v1); |
776 | tg2.SetLinearForm(secmember(3), d1u2, secmember(4), d1v2); |
777 | tg12d.SetCoord(secmember(1),secmember(2)); |
778 | tg22d.SetCoord(secmember(3),secmember(4)); |
779 | } |
780 | |
781 | distmin = Min( distmin, pt1.Distance(pt2)); |
782 | |
783 | if (!istangent) { |
784 | DPoles2d(Poles2d.Lower()).SetCoord(Tangent2dOnS1().X(), |
785 | Tangent2dOnS1().Y()); |
786 | DPoles2d(Poles2d.Upper()).SetCoord(Tangent2dOnS2().X(), |
787 | Tangent2dOnS2().Y()); |
788 | |
789 | DPoles(low) = TangentOnS1(); |
790 | DPoles(upp) = TangentOnS2(); |
791 | DWeights(low) = 0.0; |
792 | DWeights(upp) = 0.0; |
793 | } |
794 | |
795 | return (!istangent); |
796 | |
797 | } |
798 | |
799 | |
800 | //======================================================================= |
801 | //function : Section |
802 | //purpose : |
803 | //======================================================================= |
804 | |
805 | Standard_Boolean BlendFunc_ChAsym::Section |
35e08fe8 |
806 | (const Blend_Point& /*P*/, |
807 | TColgp_Array1OfPnt& /*Poles*/, |
808 | TColgp_Array1OfVec& /*DPoles*/, |
809 | TColgp_Array1OfVec& /*D2Poles*/, |
810 | TColgp_Array1OfPnt2d& /*Poles2d*/, |
811 | TColgp_Array1OfVec2d& /*DPoles2d*/, |
812 | TColgp_Array1OfVec2d& /*D2Poles2d*/, |
813 | TColStd_Array1OfReal& /*Weights*/, |
814 | TColStd_Array1OfReal& /*DWeights*/, |
815 | TColStd_Array1OfReal& /*D2Weights*/) |
7fd59977 |
816 | { |
817 | return Standard_False; |
818 | } |
819 | |
820 | |
821 | //======================================================================= |
822 | //function : Resolution |
823 | //purpose : |
824 | //======================================================================= |
825 | void BlendFunc_ChAsym::Resolution(const Standard_Integer IC2d, const Standard_Real Tol, |
826 | Standard_Real& TolU, Standard_Real& TolV) const |
827 | { |
828 | if(IC2d == 1){ |
829 | TolU = surf1->UResolution(Tol); |
830 | TolV = surf1->VResolution(Tol); |
831 | } |
832 | else { |
833 | TolU = surf2->UResolution(Tol); |
834 | TolV = surf2->VResolution(Tol); |
835 | } |
836 | } |
837 | |
838 | |
839 | //======================================================================= |
840 | //function : Set |
841 | //purpose : |
842 | //======================================================================= |
843 | void BlendFunc_ChAsym::Set(const Standard_Real Dist1, |
844 | const Standard_Real Angle, |
845 | const Standard_Integer Choix) |
846 | { |
847 | dist1 = Abs(Dist1); |
848 | angle = Angle; |
849 | tgang = Tan(Angle); |
850 | choix = Choix; |
851 | } |