7fd59977 |
1 | // File: BRepBlend_RstRstConstRad.cxx |
2 | // Created: Mon Feb 10 10:32:10 1997 |
3 | // Author: Laurent BOURESCHE |
4 | // Author: Jacques GOUSSARD |
5 | // <lbo@pomalox.paris1.matra-dtv.fr> |
0d969553 |
6 | |
7fd59977 |
7 | #include <BRepBlend_RstRstConstRad.ixx> |
8 | #include <math_Gauss.hxx> |
9 | #include <math_SVD.hxx> |
10 | |
11 | #include <ElCLib.hxx> |
12 | #include <gp.hxx> |
13 | #include <BlendFunc.hxx> |
14 | #include <GeomFill.hxx> |
15 | #include <Standard_DomainError.hxx> |
16 | #include <Standard_NotImplemented.hxx> |
17 | #include <Precision.hxx> |
18 | |
19 | #define Eps 1.e-15 |
20 | |
21 | static void t3dto2d(Standard_Real& a, |
22 | Standard_Real& b, |
23 | const gp_Vec& A, |
24 | const gp_Vec& B, |
25 | const gp_Vec& C) |
26 | { |
27 | Standard_Real AB = A.Dot(B); |
28 | Standard_Real AC = A.Dot(C); |
29 | Standard_Real BC = B.Dot(C); |
30 | Standard_Real BB = B.Dot(B); |
31 | Standard_Real CC = C.Dot(C); |
32 | Standard_Real deno = (BB*CC-BC*BC); |
33 | a = (AB*CC-AC*BC)/deno; |
34 | b = (AC*BB-AB*BC)/deno; |
35 | } |
36 | |
37 | //======================================================================= |
38 | //function : BRepBlend_RstRstConstRad |
39 | //purpose : |
40 | //======================================================================= |
41 | |
42 | BRepBlend_RstRstConstRad::BRepBlend_RstRstConstRad |
43 | (const Handle(Adaptor3d_HSurface)& Surf1, |
44 | const Handle(Adaptor2d_HCurve2d)& Rst1, |
45 | const Handle(Adaptor3d_HSurface)& Surf2, |
46 | const Handle(Adaptor2d_HCurve2d)& Rst2, |
47 | const Handle(Adaptor3d_HCurve)& CGuide): |
48 | surf1(Surf1), surf2(Surf2), rst1(Rst1), rst2(Rst2), |
49 | cons1(Rst1, Surf1), cons2(Rst2, Surf2), |
50 | guide(CGuide), tguide(CGuide), |
51 | istangent(Standard_True), maxang(RealFirst()), minang(RealLast()), |
52 | distmin(RealLast()), |
53 | mySShape(BlendFunc_Rational) |
54 | {} |
55 | |
56 | //======================================================================= |
57 | //function : NbVariables |
58 | //purpose : |
59 | //======================================================================= |
60 | |
61 | Standard_Integer BRepBlend_RstRstConstRad::NbVariables() const |
62 | { |
63 | return 2; |
64 | } |
65 | |
66 | //======================================================================= |
67 | //function : NbEquations |
68 | //purpose : |
69 | //======================================================================= |
70 | |
71 | Standard_Integer BRepBlend_RstRstConstRad::NbEquations() const |
72 | { |
73 | return 2; |
74 | } |
75 | |
76 | //======================================================================= |
77 | //function : Value |
78 | //purpose : |
79 | //======================================================================= |
80 | |
81 | Standard_Boolean BRepBlend_RstRstConstRad::Value(const math_Vector& X, |
82 | math_Vector& F) |
83 | { |
84 | ptrst1 = cons1.Value(X(1)); |
85 | ptrst2 = cons2.Value(X(2)); |
86 | |
87 | F(1) = nplan.XYZ().Dot(ptrst1.XYZ()) + theD; |
88 | F(2) = nplan.XYZ().Dot(ptrst2.XYZ()) + theD; |
89 | |
90 | return Standard_True; |
91 | } |
92 | |
93 | //======================================================================= |
94 | //function : Derivatives |
95 | //purpose : |
96 | //======================================================================= |
97 | |
98 | Standard_Boolean BRepBlend_RstRstConstRad::Derivatives(const math_Vector& X, |
99 | math_Matrix& D) |
100 | { |
101 | gp_Vec d11, d21; |
102 | |
103 | cons1.D1(X(1), ptrst1, d11); |
104 | cons2.D1(X(2), ptrst2, d21); |
105 | |
106 | D(1,1) = nplan.Dot(d11); |
107 | D(1,2) = 0.; |
108 | |
109 | D(2,1) = 0.; |
110 | D(2,2) = nplan.Dot(d21); |
111 | |
112 | return Standard_True; |
113 | } |
114 | |
115 | //======================================================================= |
116 | //function : Values |
117 | //purpose : |
118 | //======================================================================= |
119 | |
120 | Standard_Boolean BRepBlend_RstRstConstRad::Values(const math_Vector& X, |
121 | math_Vector& F, |
122 | math_Matrix& D) |
123 | { |
124 | Standard_Boolean Error; |
125 | |
126 | Error = Value(X, F); |
127 | Error = Derivatives(X, D); |
128 | |
129 | return Standard_True; |
130 | } |
131 | |
132 | //======================================================================= |
133 | //function : Set |
134 | //purpose : |
135 | //======================================================================= |
136 | |
137 | void BRepBlend_RstRstConstRad::Set(const Handle(Adaptor3d_HSurface)& SurfRef1, |
138 | const Handle(Adaptor2d_HCurve2d)& RstRef1, |
139 | const Handle(Adaptor3d_HSurface)& SurfRef2, |
140 | const Handle(Adaptor2d_HCurve2d)& RstRef2) |
141 | { |
142 | surfref1 = SurfRef1; |
143 | surfref2 = SurfRef2; |
144 | rstref1 = RstRef1; |
145 | rstref2 = RstRef2; |
146 | } |
147 | |
148 | //======================================================================= |
149 | //function : Set |
150 | //purpose : |
151 | //======================================================================= |
152 | |
153 | void BRepBlend_RstRstConstRad::Set(const Standard_Real Param) |
154 | { |
155 | tguide->D2(Param, ptgui, d1gui, d2gui); |
156 | normtg = d1gui.Magnitude(); |
157 | nplan = d1gui.Normalized(); |
158 | theD = - (nplan.XYZ().Dot(ptgui.XYZ())); |
159 | } |
160 | |
161 | //======================================================================= |
162 | //function : Set |
163 | //purpose : |
164 | //======================================================================= |
165 | |
166 | void BRepBlend_RstRstConstRad::Set(const Standard_Real First, |
167 | const Standard_Real Last) |
168 | { |
169 | tguide = guide->Trim(First, Last, 1.e-12); |
170 | } |
171 | |
172 | //======================================================================= |
173 | //function : GetTolerance |
174 | //purpose : |
175 | //======================================================================= |
176 | |
177 | void BRepBlend_RstRstConstRad::GetTolerance(math_Vector& Tolerance, |
178 | const Standard_Real Tol) const |
179 | { |
180 | Tolerance(1) = cons1.Resolution(Tol); |
181 | Tolerance(2) = cons2.Resolution(Tol); |
182 | } |
183 | |
184 | //======================================================================= |
185 | //function : GetBounds |
186 | //purpose : |
187 | //======================================================================= |
188 | |
189 | void BRepBlend_RstRstConstRad::GetBounds(math_Vector& InfBound, |
190 | math_Vector& SupBound) const |
191 | { |
192 | InfBound(1) = cons1.FirstParameter(); |
193 | InfBound(2) = cons2.FirstParameter(); |
194 | SupBound(1) = cons1.LastParameter(); |
195 | SupBound(2) = cons2.LastParameter(); |
196 | |
197 | } |
198 | |
199 | //======================================================================= |
200 | //function : IsSolution |
201 | //purpose : |
202 | //======================================================================= |
203 | |
204 | Standard_Boolean BRepBlend_RstRstConstRad::IsSolution(const math_Vector& Sol, |
205 | const Standard_Real Tol) |
206 | |
207 | |
208 | { |
209 | math_Vector valsol(1, 2), secmember(1, 2); |
210 | math_Matrix gradsol(1, 2, 1, 2); |
211 | |
212 | gp_Vec dnplan, d1urst1, d1vrst1, d1urst2, d1vrst2, d11, d21, temp; |
213 | gp_Pnt bid; |
214 | |
215 | Standard_Real Cosa, Sina, Angle; |
216 | |
217 | Values(Sol, valsol, gradsol); |
218 | |
219 | if (Abs(valsol(1)) <= Tol && |
220 | Abs(valsol(2)) <= Tol ) { |
221 | |
81bba717 |
222 | // Calculation of tangents |
7fd59977 |
223 | prmrst1 = Sol(1); |
224 | pt2drst1 = rst1->Value(prmrst1); |
225 | prmrst2 = Sol(2); |
226 | pt2drst2 = rst2->Value(prmrst2); |
227 | |
228 | cons1.D1(Sol(1), ptrst1, d11); |
229 | cons2.D1(Sol(2), ptrst2, d21); |
230 | |
231 | dnplan.SetLinearForm(1./normtg, d2gui, |
232 | -1./normtg * (nplan.Dot(d2gui)), nplan); |
233 | |
234 | temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ()); |
235 | secmember(1) = normtg - dnplan.Dot(temp); |
236 | |
237 | temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ()); |
238 | secmember(2) = normtg - dnplan.Dot(temp); |
239 | |
240 | math_Gauss Resol(gradsol); |
241 | |
242 | if (Resol.IsDone()) { |
243 | Resol.Solve(secmember); |
244 | istangent = Standard_False; |
245 | } |
246 | else { |
247 | math_SVD SingRS (gradsol); |
248 | if (SingRS.IsDone()) { |
249 | math_Vector DEDT(1,3); |
250 | DEDT = secmember; |
251 | SingRS.Solve(DEDT, secmember, 1.e-6); |
252 | istangent = Standard_False; |
253 | } |
254 | else istangent = Standard_True; |
255 | } |
256 | |
257 | |
258 | if (!istangent) { |
259 | tgrst1 = secmember(1) * d11; |
260 | tgrst2 = secmember(2) * d21; |
261 | |
262 | Standard_Real a, b; |
263 | surf1->D1(pt2drst1.X(), pt2drst1.Y(), bid, d1urst1, d1vrst1); |
264 | t3dto2d(a, b, tgrst1, d1urst1, d1vrst1); |
265 | tg2drst1.SetCoord(a, b); |
266 | surf2->D1(pt2drst2.X(), pt2drst2.Y(), bid, d1urst2, d1vrst2); |
267 | t3dto2d(a, b, tgrst1, d1urst2, d1vrst2); |
268 | tg2drst2.SetCoord(a, b); |
269 | } |
270 | |
271 | gp_Pnt Center; |
272 | gp_Vec NotUsed; |
273 | Standard_Boolean IsCenter; |
274 | |
275 | IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed); |
276 | |
277 | if (!IsCenter) return Standard_False; |
278 | |
279 | gp_Vec n1(Center, ptrst1) , n2(Center, ptrst2); |
280 | |
281 | n1.Normalize(); |
282 | n2.Normalize(); |
283 | |
284 | Cosa = n1.Dot(n2); |
285 | Sina = nplan.Dot(n1.Crossed(n2)); |
286 | |
287 | if (choix%2 != 0) { |
81bba717 |
288 | Sina = -Sina; //nplan is changed into -nplan |
7fd59977 |
289 | } |
290 | |
291 | Angle = ACos(Cosa); |
292 | if (Sina < 0.) { |
c6541a0c |
293 | Angle = 2.*M_PI - Angle; |
7fd59977 |
294 | } |
295 | |
296 | if (Angle > maxang) {maxang = Angle;} |
297 | if (Angle < minang) {minang = Angle;} |
298 | distmin = Min( distmin, ptrst1.Distance(ptrst2)); |
299 | |
300 | return Standard_True; |
301 | } |
302 | istangent = Standard_True; |
303 | return Standard_False; |
304 | } |
305 | |
306 | //======================================================================= |
307 | //function : GetMinimalDistance |
308 | //purpose : |
309 | //======================================================================= |
310 | |
311 | Standard_Real BRepBlend_RstRstConstRad::GetMinimalDistance() const |
312 | { |
313 | return distmin; |
314 | } |
315 | |
316 | //======================================================================= |
317 | //function : PointOnRst1 |
318 | //purpose : |
319 | //======================================================================= |
320 | |
321 | const gp_Pnt& BRepBlend_RstRstConstRad::PointOnRst1() const |
322 | { |
323 | return ptrst1; |
324 | } |
325 | |
326 | //======================================================================= |
327 | //function : PointOnRst2 |
328 | //purpose : |
329 | //======================================================================= |
330 | |
331 | const gp_Pnt& BRepBlend_RstRstConstRad::PointOnRst2() const |
332 | { |
333 | return ptrst2; |
334 | } |
335 | |
336 | //======================================================================= |
337 | //function : Pnt2dOnRst1 |
338 | //purpose : |
339 | //======================================================================= |
340 | |
341 | const gp_Pnt2d& BRepBlend_RstRstConstRad::Pnt2dOnRst1() const |
342 | { |
343 | return pt2drst1; |
344 | } |
345 | |
346 | //======================================================================= |
347 | //function : Pnt2dOnRst2 |
348 | //purpose : |
349 | //======================================================================= |
350 | |
351 | const gp_Pnt2d& BRepBlend_RstRstConstRad::Pnt2dOnRst2() const |
352 | { |
353 | return pt2drst2; |
354 | } |
355 | |
356 | //======================================================================= |
357 | //function : ParameterOnRst1 |
358 | //purpose : |
359 | //======================================================================= |
360 | |
361 | Standard_Real BRepBlend_RstRstConstRad::ParameterOnRst1() const |
362 | { |
363 | return prmrst1; |
364 | } |
365 | |
366 | //======================================================================= |
367 | //function : ParameterOnRst2 |
368 | //purpose : |
369 | //======================================================================= |
370 | |
371 | Standard_Real BRepBlend_RstRstConstRad::ParameterOnRst2() const |
372 | { |
373 | return prmrst2; |
374 | } |
375 | //======================================================================= |
376 | //function : IsTangencyPoint |
377 | //purpose : |
378 | //======================================================================= |
379 | |
380 | Standard_Boolean BRepBlend_RstRstConstRad::IsTangencyPoint() const |
381 | { |
382 | return istangent; |
383 | } |
384 | |
385 | //======================================================================= |
386 | //function : TangentOnRst1 |
387 | //purpose : |
388 | //======================================================================= |
389 | |
390 | const gp_Vec& BRepBlend_RstRstConstRad::TangentOnRst1() const |
391 | { |
392 | if (istangent) {Standard_DomainError::Raise();} |
393 | return tgrst1; |
394 | } |
395 | |
396 | //======================================================================= |
397 | //function : Tangent2dOnRst1 |
398 | //purpose : |
399 | //======================================================================= |
400 | |
401 | const gp_Vec2d& BRepBlend_RstRstConstRad::Tangent2dOnRst1() const |
402 | { |
403 | if (istangent) {Standard_DomainError::Raise();} |
404 | return tg2drst1; |
405 | } |
406 | |
407 | //======================================================================= |
408 | //function : TangentOnRst2 |
409 | //purpose : |
410 | //======================================================================= |
411 | |
412 | const gp_Vec& BRepBlend_RstRstConstRad::TangentOnRst2() const |
413 | { |
414 | if (istangent) {Standard_DomainError::Raise();} |
415 | return tgrst2; |
416 | } |
417 | |
418 | //======================================================================= |
419 | //function : Tangent2dOnRst2 |
420 | //purpose : |
421 | //======================================================================= |
422 | |
423 | const gp_Vec2d& BRepBlend_RstRstConstRad::Tangent2dOnRst2() const |
424 | { |
425 | if (istangent) {Standard_DomainError::Raise();} |
426 | return tg2drst2; |
427 | } |
428 | |
429 | //======================================================================= |
430 | //function : Decroch |
431 | //purpose : |
432 | //======================================================================= |
433 | |
434 | Blend_DecrochStatus BRepBlend_RstRstConstRad::Decroch(const math_Vector& Sol, |
435 | gp_Vec& NRst1, |
436 | gp_Vec& TgRst1, |
437 | gp_Vec& NRst2, |
438 | gp_Vec& TgRst2)const |
439 | { |
440 | gp_Vec NRst1InPlane, NRst2InPlane; |
441 | gp_Pnt PtTmp1, PtTmp2, Center; |
442 | gp_Vec d1u, d1v, centptrst, NotUsed; |
443 | Standard_Real norm, unsurnorm; |
444 | Standard_Real u,v; |
445 | |
446 | rstref1->Value(Sol(1)).Coord(u, v); |
447 | surfref1->D1(u, v,PtTmp1,d1u,d1v); |
81bba717 |
448 | // Normal to the reference surface 1 |
7fd59977 |
449 | NRst1 = d1u.Crossed(d1v); |
450 | rstref2->Value(Sol(2)).Coord(u, v); |
451 | surfref2->D1(u, v, PtTmp2, d1u, d1v); |
81bba717 |
452 | // Normal to the reference surface 2 |
7fd59977 |
453 | NRst2 = d1u.Crossed(d1v); |
454 | |
455 | Standard_Boolean IsCenter; |
456 | |
457 | IsCenter = CenterCircleRst1Rst2(PtTmp1, PtTmp2, nplan, Center, NotUsed); |
458 | |
459 | norm = nplan.Crossed(NRst1).Magnitude(); |
460 | unsurnorm = 1. / norm; |
461 | |
462 | NRst1InPlane.SetLinearForm(nplan.Dot(NRst1) * unsurnorm, nplan, -unsurnorm, NRst1); |
463 | |
464 | centptrst.SetXYZ(PtTmp1.XYZ() - Center.XYZ()); |
465 | |
466 | if (centptrst.Dot(NRst1InPlane) < 0.) NRst1InPlane.Reverse(); |
467 | |
468 | TgRst1 = nplan.Crossed(centptrst); |
469 | |
470 | norm = nplan.Crossed(NRst2).Magnitude(); |
471 | unsurnorm = 1./ norm; |
472 | NRst2InPlane.SetLinearForm(nplan.Dot(NRst2) * unsurnorm, nplan, -unsurnorm, NRst2); |
473 | centptrst.SetXYZ(PtTmp2.XYZ() - Center.XYZ()); |
474 | |
475 | |
476 | if (centptrst.Dot(NRst2InPlane) < 0.) NRst2InPlane.Reverse(); |
477 | |
478 | TgRst2 = nplan.Crossed(centptrst); |
479 | |
480 | if (choix %2 != 0) { |
481 | TgRst1.Reverse(); |
482 | TgRst2.Reverse(); |
483 | } |
484 | |
81bba717 |
485 | // The vectors are returned |
7fd59977 |
486 | if (NRst1InPlane.Dot(TgRst1) > -1.e-10) { |
487 | if (NRst2InPlane.Dot(TgRst2) < 1.e-10) { |
488 | return Blend_DecrochBoth; |
489 | } |
490 | else { |
491 | return Blend_DecrochRst1; |
492 | } |
493 | } |
494 | else { |
495 | if (NRst2InPlane.Dot(TgRst2) < 1.e-10) { |
496 | return Blend_DecrochRst2; |
497 | } |
498 | else { |
499 | return Blend_NoDecroch; |
500 | } |
501 | } |
502 | |
503 | } |
504 | |
505 | //======================================================================= |
506 | //function : Set |
507 | //purpose : |
508 | //======================================================================= |
509 | |
510 | void BRepBlend_RstRstConstRad::Set(const Standard_Real Radius, |
511 | const Standard_Integer Choix) |
512 | { |
513 | choix = Choix; |
514 | ray = Abs(Radius); |
515 | |
516 | } |
517 | |
518 | //======================================================================= |
519 | //function : Set |
520 | //purpose : |
521 | //======================================================================= |
522 | |
523 | void BRepBlend_RstRstConstRad::Set(const BlendFunc_SectionShape TypeSection) |
524 | { |
525 | mySShape = TypeSection; |
526 | } |
527 | |
528 | |
529 | |
530 | //======================================================================= |
531 | //function : CenterCircleRst1Rst2 |
81bba717 |
532 | //purpose : Calculate the center of the circle passing by two points of restrictions |
7fd59977 |
533 | //======================================================================= |
534 | Standard_Boolean BRepBlend_RstRstConstRad::CenterCircleRst1Rst2(const gp_Pnt& PtRst1, |
535 | const gp_Pnt& PtRst2, |
536 | const gp_Vec& np, |
537 | gp_Pnt& Center, |
538 | gp_Vec& VdMed) const |
539 | { |
540 | |
541 | gp_Vec rst1rst2(PtRst1, PtRst2); |
81bba717 |
542 | gp_Vec vdmedNor; //,NRst1; vdmedNor directong vector of the perpendicular bisector |
7fd59977 |
543 | Standard_Real norm2; |
81bba717 |
544 | Standard_Real Dist;// distance between the middle of PtRst1,PtRst2 and Center |
7fd59977 |
545 | |
81bba717 |
546 | // Calculate the center of the circle |
7fd59977 |
547 | VdMed = rst1rst2.Crossed(np); |
548 | norm2 = rst1rst2.SquareMagnitude(); |
549 | Dist = ray * ray - 0.25 * norm2; |
550 | |
551 | if (choix > 2) { |
552 | VdMed.Reverse(); |
553 | } |
554 | |
555 | if (Dist < - 1.E-07) return Standard_False; |
556 | |
557 | if (Dist > 1.E-07) { |
558 | Dist = sqrt(Dist); |
559 | vdmedNor = VdMed.Normalized(); |
560 | Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ() + Dist * vdmedNor.XYZ()); |
561 | } |
562 | else |
563 | { |
564 | Center.SetXYZ(0.5 * rst1rst2.XYZ() + PtRst1.XYZ()); |
565 | } |
566 | |
567 | return Standard_True; |
568 | |
569 | } |
570 | |
571 | |
572 | |
573 | |
574 | |
575 | |
576 | //======================================================================= |
577 | //function : Section |
578 | //purpose : |
579 | //======================================================================= |
580 | |
581 | void BRepBlend_RstRstConstRad::Section(const Standard_Real Param, |
582 | const Standard_Real U, |
583 | const Standard_Real V, |
584 | Standard_Real& Pdeb, |
585 | Standard_Real& Pfin, |
586 | gp_Circ& C) |
587 | { |
588 | gp_Vec ns, np, NotUsed; |
589 | gp_Pnt Center; |
590 | |
591 | tguide->D1(Param, ptgui, d1gui); |
592 | np = d1gui.Normalized(); |
593 | ptrst1 = cons1.Value(U); |
594 | ptrst2 = cons2.Value(V); |
595 | |
596 | Standard_Boolean IsCenter; |
597 | |
598 | IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, np, Center, NotUsed); |
599 | |
600 | C.SetRadius(Abs(ray)); |
601 | ns = gp_Vec(Center, ptrst1).Normalized(); |
602 | |
603 | if (choix%2 != 0) { |
604 | np.Reverse(); |
605 | } |
606 | |
607 | C.SetPosition(gp_Ax2(Center, np, ns)); |
608 | Pdeb = 0; //ElCLib::Parameter(C, pts); |
609 | Pfin = ElCLib::Parameter(C, ptrst2); |
610 | |
81bba717 |
611 | // Test of angles negative and almost null : Special Case |
c6541a0c |
612 | if (Pfin > 1.5 * M_PI) { |
7fd59977 |
613 | np.Reverse(); |
614 | C.SetPosition(gp_Ax2(Center, np, ns)); |
615 | Pfin = ElCLib::Parameter(C, ptrst2); |
616 | } |
617 | if (Pfin < Precision::PConfusion()) Pfin += Precision::PConfusion(); |
618 | } |
619 | |
620 | //======================================================================= |
621 | //function : IsRational |
622 | //purpose : |
623 | //======================================================================= |
624 | |
625 | Standard_Boolean BRepBlend_RstRstConstRad::IsRational () const |
626 | { |
627 | return (mySShape==BlendFunc_Rational || mySShape==BlendFunc_QuasiAngular); |
628 | } |
629 | |
630 | //======================================================================= |
631 | //function : GetSectionSize |
632 | //purpose : |
633 | //======================================================================= |
634 | |
635 | Standard_Real BRepBlend_RstRstConstRad::GetSectionSize() const |
636 | { |
637 | return maxang * Abs(ray); |
638 | } |
639 | |
640 | //======================================================================= |
641 | //function : GetMinimalWeight |
642 | //purpose : |
643 | //======================================================================= |
644 | |
645 | void BRepBlend_RstRstConstRad::GetMinimalWeight(TColStd_Array1OfReal& Weights) const |
646 | { |
647 | BlendFunc::GetMinimalWeights(mySShape, myTConv, minang, maxang, Weights ); |
81bba717 |
648 | // It is supposed that it does not depend on the Radius! |
7fd59977 |
649 | } |
650 | |
651 | //======================================================================= |
652 | //function : NbIntervals |
653 | //purpose : |
654 | //======================================================================= |
655 | |
656 | Standard_Integer BRepBlend_RstRstConstRad::NbIntervals (const GeomAbs_Shape S) const |
657 | { |
658 | return guide->NbIntervals(BlendFunc::NextShape(S)); |
659 | } |
660 | |
661 | //======================================================================= |
662 | //function : Intervals |
663 | //purpose : |
664 | //======================================================================= |
665 | |
666 | void BRepBlend_RstRstConstRad::Intervals (TColStd_Array1OfReal& T, |
667 | const GeomAbs_Shape S) const |
668 | { |
669 | guide->Intervals(T, BlendFunc::NextShape(S)); |
670 | } |
671 | |
672 | //======================================================================= |
673 | //function : GetShape |
674 | //purpose : |
675 | //======================================================================= |
676 | |
677 | void BRepBlend_RstRstConstRad::GetShape (Standard_Integer& NbPoles, |
678 | Standard_Integer& NbKnots, |
679 | Standard_Integer& Degree, |
680 | Standard_Integer& NbPoles2d) |
681 | { |
682 | NbPoles2d = 2; |
683 | BlendFunc::GetShape(mySShape, maxang, NbPoles, NbKnots, Degree, myTConv); |
684 | } |
685 | |
686 | //======================================================================= |
687 | //function : GetTolerance |
81bba717 |
688 | //purpose : Determine Tolerances to be used in approximations. |
7fd59977 |
689 | //======================================================================= |
690 | |
691 | void BRepBlend_RstRstConstRad::GetTolerance(const Standard_Real BoundTol, |
692 | const Standard_Real SurfTol, |
693 | const Standard_Real AngleTol, |
694 | math_Vector& Tol3d, |
695 | math_Vector& Tol1d) const |
696 | { |
697 | Standard_Integer low = Tol3d.Lower(), up = Tol3d.Upper(); |
698 | Standard_Real Tol; |
699 | Tol= GeomFill::GetTolerance(myTConv, minang, Abs(ray), |
700 | AngleTol, SurfTol); |
701 | Tol1d.Init(SurfTol); |
702 | Tol3d.Init(SurfTol); |
703 | Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol); |
704 | Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol); |
705 | } |
706 | |
707 | //======================================================================= |
708 | //function : Knots |
709 | //purpose : |
710 | //======================================================================= |
711 | |
712 | void BRepBlend_RstRstConstRad::Knots(TColStd_Array1OfReal& TKnots) |
713 | { |
714 | GeomFill::Knots(myTConv, TKnots); |
715 | } |
716 | |
717 | //======================================================================= |
718 | //function : Mults |
719 | //purpose : |
720 | //======================================================================= |
721 | |
722 | void BRepBlend_RstRstConstRad::Mults(TColStd_Array1OfInteger& TMults) |
723 | { |
724 | GeomFill::Mults(myTConv, TMults); |
725 | } |
726 | |
727 | //======================================================================= |
728 | //function : Section |
729 | //purpose : |
730 | //======================================================================= |
731 | |
732 | void BRepBlend_RstRstConstRad::Section(const Blend_Point& P, |
733 | TColgp_Array1OfPnt& Poles, |
734 | TColgp_Array1OfPnt2d& Poles2d, |
735 | TColStd_Array1OfReal& Weights) |
736 | { |
737 | gp_Vec ns, ns2, NotUsed; |
738 | gp_Pnt Center; |
739 | Standard_Real u, v; |
740 | |
741 | Standard_Real prm = P.Parameter(); |
742 | Standard_Integer low = Poles.Lower(); |
743 | Standard_Integer upp = Poles.Upper(); |
744 | |
745 | tguide->D1(prm,ptgui, d1gui); |
746 | nplan = d1gui.Normalized(); |
747 | |
748 | u = P.ParameterOnC1(); |
749 | v = P.ParameterOnC2(); |
750 | |
751 | gp_Pnt2d pt2d1 = rst1->Value(u); |
752 | gp_Pnt2d pt2d2 = rst2->Value(v); |
753 | |
754 | ptrst1 = cons1.Value(u); |
755 | ptrst2 = cons2.Value(v); |
756 | distmin = Min (distmin, ptrst1.Distance(ptrst2)); |
757 | |
758 | Poles2d(Poles2d.Lower()).SetCoord(pt2d1.X(),pt2d1.Y()); |
759 | Poles2d(Poles2d.Upper()).SetCoord(pt2d2.X(),pt2d2.Y()); |
760 | |
81bba717 |
761 | // Linear case |
7fd59977 |
762 | if (mySShape == BlendFunc_Linear) { |
763 | Poles(low) = ptrst1; |
764 | Poles(upp) = ptrst2; |
765 | Weights(low) = 1.0; |
766 | Weights(upp) = 1.0; |
767 | return; |
768 | } |
769 | |
81bba717 |
770 | // Calculate the center of the circle |
7fd59977 |
771 | Standard_Boolean IsCenter; |
772 | IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, NotUsed); |
773 | |
81bba717 |
774 | // normals to the section with points |
7fd59977 |
775 | ns = gp_Vec(Center, ptrst1).Normalized(); |
776 | ns2 = gp_Vec(Center, ptrst2).Normalized(); |
777 | |
778 | if (choix%2 != 0) { |
779 | nplan.Reverse(); |
780 | } |
781 | |
782 | GeomFill::GetCircle(myTConv, |
783 | ns, ns2, |
784 | nplan, ptrst1, ptrst2, |
785 | Abs(ray), Center, |
786 | Poles, Weights); |
787 | } |
788 | |
789 | //======================================================================= |
790 | //function : Section |
791 | //purpose : |
792 | //======================================================================= |
793 | |
794 | Standard_Boolean BRepBlend_RstRstConstRad::Section(const Blend_Point& P, |
795 | TColgp_Array1OfPnt& Poles, |
796 | TColgp_Array1OfVec& DPoles, |
797 | TColgp_Array1OfPnt2d& Poles2d, |
798 | TColgp_Array1OfVec2d& DPoles2d, |
799 | TColStd_Array1OfReal& Weights, |
800 | TColStd_Array1OfReal& DWeights) |
801 | { |
802 | |
803 | gp_Vec d11, d21; |
804 | gp_Vec dnplan, d1n1, d1n2;//,np2, dnp2; |
805 | gp_Vec temp, tgct; |
806 | gp_Vec d1urst, d1vrst; |
807 | gp_Pnt Center, NotUsed; |
808 | |
809 | Standard_Real norm2, normmed, Dist; |
810 | |
811 | math_Vector sol(1, 2), valsol(1, 2), secmember(1, 2); |
812 | math_Matrix gradsol(1, 2, 1, 2); |
813 | |
814 | Standard_Real prm = P.Parameter(); |
815 | #ifdef DEB |
816 | Standard_Integer NbSpan = (Poles.Length() - 1) / 2; |
817 | #endif |
818 | Standard_Integer low = Poles.Lower(); |
819 | Standard_Integer upp = Poles.Upper(); |
820 | Standard_Boolean istgt; |
821 | |
822 | tguide->D2(prm, ptgui, d1gui, d2gui); |
823 | normtg = d1gui.Magnitude(); |
824 | nplan = d1gui.Normalized(); |
825 | dnplan.SetLinearForm(1./normtg, d2gui, |
826 | -1./normtg * (nplan.Dot(d2gui)), nplan); |
827 | |
828 | sol(1) = prmrst1 = P.ParameterOnC1(); |
829 | sol(2) = prmrst2 = P.ParameterOnC2(); |
830 | pt2drst1 = rst1->Value(prmrst1); |
831 | pt2drst2 = rst2->Value(prmrst2); |
832 | |
833 | Values(sol, valsol, gradsol); |
834 | |
835 | cons1.D1(sol(1), ptrst1, d11); |
836 | cons2.D1(sol(2), ptrst2, d21); |
837 | |
838 | temp.SetXYZ(ptrst1.XYZ() - ptgui.XYZ()); |
839 | secmember(1) = normtg - dnplan.Dot(temp); |
840 | |
841 | temp.SetXYZ(ptrst2.XYZ() - ptgui.XYZ()); |
842 | secmember(2) = normtg - dnplan.Dot(temp); |
843 | |
844 | math_Gauss Resol(gradsol, 1.e-9); |
845 | |
846 | if (Resol.IsDone()) { |
847 | istgt = Standard_False; |
848 | Resol.Solve(secmember); |
849 | } |
850 | else { |
851 | math_SVD SingRS (gradsol); |
852 | if (SingRS.IsDone()) { |
853 | math_Vector DEDT(1,2); |
854 | DEDT = secmember; |
855 | SingRS.Solve(DEDT, secmember, 1.e-6); |
856 | istgt = Standard_False; |
857 | } |
858 | else istgt = Standard_True; |
859 | } |
860 | |
861 | gp_Vec med; |
862 | gp_Vec rst1rst2(ptrst1, ptrst2); |
863 | Standard_Boolean IsCenter; |
864 | |
865 | IsCenter = CenterCircleRst1Rst2(ptrst1, ptrst2, nplan, Center, med); |
866 | if (!IsCenter) return Standard_False; |
867 | |
868 | normmed = med.Magnitude(); |
869 | med.Normalize(); |
870 | gp_Vec n1(Center, ptrst1), n2(Center, ptrst2); |
871 | n1.Normalize(); |
872 | n2.Normalize(); |
873 | |
874 | if (!istgt) { |
81bba717 |
875 | // secmember contains derivatives of parameters on curves |
876 | // compared to t |
7fd59977 |
877 | tgrst1 = secmember(1) * d11; |
878 | tgrst2 = secmember(2) * d21; |
879 | |
880 | gp_Vec d1rst1rst2; |
881 | |
882 | norm2 = rst1rst2.SquareMagnitude(); |
883 | d1rst1rst2 = tgrst2 - tgrst1; |
884 | Dist = ray * ray - 0.25 * norm2; |
885 | |
886 | if (Dist > 1.E-07) { |
887 | gp_Vec d1P1P2CrosNp, dmed; |
888 | d1P1P2CrosNp = d1rst1rst2.Crossed(nplan) + rst1rst2.Crossed(dnplan); |
81bba717 |
889 | // derivative of the perpendicular bisector |
7fd59977 |
890 | dmed = d1P1P2CrosNp - med.Dot(d1P1P2CrosNp) * med; |
891 | dmed /= normmed; |
892 | Dist = sqrt(Dist); |
893 | Standard_Real d1Dist = - (0.25 / Dist) * rst1rst2.Dot(d1rst1rst2); |
894 | |
895 | if (choix > 2) { |
896 | dmed.Reverse(); |
897 | } |
898 | |
81bba717 |
899 | // the derivative of coefficient Dist is located in dmed |
7fd59977 |
900 | dmed.SetLinearForm(Dist, dmed, d1Dist, med); |
901 | d1rst1rst2 *= 0.5; |
81bba717 |
902 | // derivative of the Normal to the curve in P1 |
7fd59977 |
903 | d1n1 = - (dmed + d1rst1rst2) / ray; |
904 | |
81bba717 |
905 | // derivative of the Normal to the curve in P2 |
7fd59977 |
906 | d1n2 = (d1rst1rst2 - dmed) / ray; |
907 | } |
908 | else { |
909 | d1rst1rst2 *= 0.5; |
81bba717 |
910 | // Normal to the curve in P1 |
7fd59977 |
911 | d1n1 = - d1rst1rst2 / ray; |
912 | |
81bba717 |
913 | // Normal to the curve in P2 |
7fd59977 |
914 | d1n2 = d1rst1rst2 / ray; |
915 | } |
916 | } |
917 | |
81bba717 |
918 | // Tops 2d |
7fd59977 |
919 | |
920 | Poles2d(Poles2d.Lower()).SetCoord(pt2drst1.X(), pt2drst1.Y()); |
921 | Poles2d(Poles2d.Upper()).SetCoord(pt2drst2.X(), pt2drst2.Y()); |
922 | if (!istgt) { |
923 | Standard_Real a, b; |
924 | surf1->D1(pt2drst1.X(), pt2drst1.Y(), NotUsed, d1urst, d1vrst); |
925 | t3dto2d(a,b,tgrst1, d1urst, d1vrst); |
926 | DPoles2d(Poles2d.Lower()).SetCoord(a, b); |
927 | |
928 | surf2->D1(pt2drst2.X(), pt2drst2.Y(), NotUsed, d1urst, d1vrst); |
929 | t3dto2d(a, b, tgrst2, d1urst, d1vrst); |
930 | DPoles2d(Poles2d.Upper()).SetCoord(a, b); |
931 | } |
932 | |
81bba717 |
933 | // Linear case |
7fd59977 |
934 | if (mySShape == BlendFunc_Linear) { |
935 | Poles(low) = ptrst1; |
936 | Poles(upp) = ptrst2; |
937 | Weights(low) = 1.0; |
938 | Weights(upp) = 1.0; |
939 | if (!istgt) { |
940 | DPoles(low) = tgrst1; |
941 | DPoles(upp) = tgrst2; |
942 | DWeights(low) = 0.0; |
943 | DWeights(upp) = 0.0; |
944 | } |
945 | return (!istgt); |
946 | } |
947 | |
81bba717 |
948 | // Case of the circle |
949 | // tangent to the center of the circle |
7fd59977 |
950 | if (!istgt) { |
951 | tgct.SetLinearForm(-ray, d1n1, tgrst1); |
952 | } |
953 | |
954 | |
955 | if (choix%2 != 0) { |
956 | nplan.Reverse(); |
957 | dnplan.Reverse(); |
958 | } |
959 | |
960 | if (!istgt) { |
961 | return GeomFill::GetCircle(myTConv, |
962 | n1, n2, |
963 | d1n1, d1n2, |
964 | nplan, dnplan, |
965 | ptrst1, ptrst2, |
966 | tgrst1, tgrst2, |
967 | Abs(ray), 0, |
968 | Center, tgct, |
969 | Poles, |
970 | DPoles, |
971 | Weights, |
972 | DWeights); |
973 | } |
974 | else { |
975 | GeomFill::GetCircle(myTConv, |
976 | n1, n2, |
977 | nplan, ptrst1, ptrst2, |
978 | Abs(ray), Center, |
979 | Poles, Weights); |
980 | return Standard_False; |
981 | } |
982 | } |
983 | |
984 | //======================================================================= |
985 | //function : Section |
986 | //purpose : |
987 | //======================================================================= |
988 | |
989 | Standard_Boolean BRepBlend_RstRstConstRad::Section |
990 | (const Blend_Point&, |
991 | TColgp_Array1OfPnt&, |
992 | TColgp_Array1OfVec&, |
993 | TColgp_Array1OfVec&, |
994 | TColgp_Array1OfPnt2d&, |
995 | TColgp_Array1OfVec2d&, |
996 | TColgp_Array1OfVec2d&, |
997 | TColStd_Array1OfReal&, |
998 | TColStd_Array1OfReal&, |
999 | TColStd_Array1OfReal&) |
1000 | { |
1001 | return Standard_False; |
1002 | } |
1003 | |
1004 | |
1005 | void BRepBlend_RstRstConstRad::Resolution(const Standard_Integer IC2d, |
1006 | const Standard_Real Tol, |
1007 | Standard_Real& TolU, |
1008 | Standard_Real& TolV) const |
1009 | { |
1010 | if(IC2d == 1){ |
1011 | TolU = surf1->UResolution(Tol); |
1012 | TolV = surf1->VResolution(Tol); |
1013 | } |
1014 | else { |
1015 | TolU = surf2->UResolution(Tol); |
1016 | TolV = surf2->VResolution(Tol); |
1017 | } |
1018 | } |
1019 | |