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