1 // File: Geom_SurfaceOfRevolution.cxx
2 // Created: Wed Mar 10 10:51:26 1993
5 // Copyright: Matra Datavision 1993
7 //File Geom_SurfaceOfRevolution.cxx, JCV 4/03/91
10 #include <Geom_SurfaceOfRevolution.ixx>
11 #include <BSplSLib.hxx>
12 #include <BSplCLib.hxx>
13 #include <Geom_Circle.hxx>
15 #include <gp_Ax2d.hxx>
20 #include <Standard_ConstructionError.hxx>
21 #include <Standard_NotImplemented.hxx>
22 #include <Standard_RangeError.hxx>
23 #include <Geom_BSplineCurve.hxx>
24 #include <Precision.hxx>
25 #define POLES (poles->Array2())
26 #define WEIGHTS (weights->Array2())
27 #define UKNOTS (uknots->Array1())
28 #define VKNOTS (vknots->Array1())
29 #define UFKNOTS (ufknots->Array1())
30 #define VFKNOTS (vfknots->Array1())
31 #define FMULTS (BSplCLib::NoMults())
33 typedef Geom_SurfaceOfRevolution SurfaceOfRevolution;
34 typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
35 typedef Handle(Geom_Geometry) Handle(Geometry);
36 typedef Geom_Curve Curve;
37 typedef Handle(Geom_Curve) Handle(Curve);
46 //=======================================================================
47 //function : LocateSide
48 //purpose : This method locates U parameter on basis BSpline curve
49 // and calls LocalDi methods corresponding an order of
50 // derivative and position of the surface side contained
51 // the point relatively the curve knots.
52 //=======================================================================
53 static void LocateSide(const Standard_Real U,
54 const Standard_Integer Side,
55 const Handle(Geom_BSplineCurve)& BSplC,
56 const Standard_Integer NDir,
62 Standard_Integer Ideb, Ifin;
63 Standard_Real ParTol=Precision::PConfusion()/2;
64 BSplC->Geom_BSplineCurve::LocateU(U,ParTol,Ideb,Ifin,Standard_False);
68 if ((Ideb>=Ifin)) Ifin = Ideb+1;
72 if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
73 if ((Ideb>=Ifin)) Ideb = Ifin-1;
77 case 0 : BSplC->Geom_BSplineCurve::LocalD0(U,Ideb,Ifin,P); break;
78 case 1 : BSplC->Geom_BSplineCurve::LocalD1(U,Ideb,Ifin,P,D1U); break;
79 case 2 : BSplC->Geom_BSplineCurve::LocalD2(U,Ideb,Ifin,P,D1U,D2U); break;
80 case 3 : BSplC->Geom_BSplineCurve::LocalD3(U,Ideb,Ifin,P,D1U,D2U,D3U); break;
84 //=======================================================================
85 //function : LocateSideN
86 //purpose : This method locates U parameter on basis BSpline curve
87 // and calls LocalDN method corresponding position of surface side
88 // contained the point relatively the curve knots.
89 //=======================================================================
90 static gp_Vec LocateSideN(const Standard_Real V,
91 const Standard_Integer Side,
92 const Handle(Geom_BSplineCurve)& BSplC,
93 const Standard_Integer Nv )
95 Standard_Integer Ideb, Ifin;
96 Standard_Real ParTol=Precision::PConfusion()/2;
97 BSplC->Geom_BSplineCurve::LocateU(V,ParTol,Ideb,Ifin,Standard_False);
101 if ((Ideb>=Ifin)) Ifin = Ideb+1;
105 if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
106 if ((Ideb>=Ifin)) Ideb = Ifin-1;
108 return BSplC->Geom_BSplineCurve::LocalDN(V,Ideb,Ifin,Nv);
114 //=======================================================================
117 //=======================================================================
119 Handle(Geom_Geometry) Geom_SurfaceOfRevolution::Copy () const {
121 return new Geom_SurfaceOfRevolution (basisCurve, Axis());
125 //=======================================================================
126 //function : Geom_SurfaceOfRevolution
128 //=======================================================================
130 Geom_SurfaceOfRevolution::Geom_SurfaceOfRevolution
131 (const Handle(Curve)& C ,
132 const Ax1& A1 ) : loc (A1.Location()) {
134 basisCurve = Handle(Curve)::DownCast(C->Copy());
135 direction = A1.Direction();
136 smooth = C->Continuity();
140 //=======================================================================
141 //function : UReverse
143 //=======================================================================
145 void Geom_SurfaceOfRevolution::UReverse () {
151 //=======================================================================
152 //function : UReversedParameter
154 //=======================================================================
156 Standard_Real Geom_SurfaceOfRevolution::UReversedParameter (const Standard_Real U) const {
158 return ( 2.*M_PI - U);
162 //=======================================================================
163 //function : VReverse
165 //=======================================================================
167 void Geom_SurfaceOfRevolution::VReverse () {
169 basisCurve->Reverse();
173 //=======================================================================
174 //function : VReversedParameter
176 //=======================================================================
178 Standard_Real Geom_SurfaceOfRevolution::VReversedParameter (const Standard_Real V) const {
180 return basisCurve->ReversedParameter(V);
184 //=======================================================================
185 //function : Location
187 //=======================================================================
189 const gp_Pnt& Geom_SurfaceOfRevolution::Location () const {
194 //=======================================================================
195 //function : IsUPeriodic
197 //=======================================================================
199 Standard_Boolean Geom_SurfaceOfRevolution::IsUPeriodic () const {
201 return Standard_True;
204 //=======================================================================
207 //=======================================================================
209 Standard_Boolean Geom_SurfaceOfRevolution::IsCNu (const Standard_Integer ) const {
211 return Standard_True;
214 //=======================================================================
217 //=======================================================================
219 Ax1 Geom_SurfaceOfRevolution::Axis () const {
221 return Ax1 (loc, direction);
224 //=======================================================================
227 //=======================================================================
229 Standard_Boolean Geom_SurfaceOfRevolution::IsCNv (const Standard_Integer N) const {
231 Standard_RangeError_Raise_if (N < 0, " ");
232 return basisCurve->IsCN(N);
236 //=======================================================================
237 //function : IsUClosed
239 //=======================================================================
241 Standard_Boolean Geom_SurfaceOfRevolution::IsUClosed () const {
243 return Standard_True;
246 //=======================================================================
247 //function : IsVClosed
249 //=======================================================================
251 Standard_Boolean Geom_SurfaceOfRevolution::IsVClosed () const
253 return basisCurve->IsClosed();
257 //=======================================================================
258 //function : IsVPeriodic
260 //=======================================================================
262 Standard_Boolean Geom_SurfaceOfRevolution::IsVPeriodic () const {
264 return basisCurve->IsPeriodic();
268 //=======================================================================
271 //=======================================================================
273 void Geom_SurfaceOfRevolution::SetAxis (const Ax1& A1) {
275 direction = A1.Direction();
280 //=======================================================================
281 //function : SetDirection
283 //=======================================================================
285 void Geom_SurfaceOfRevolution::SetDirection (const Dir& V) {
291 //=======================================================================
292 //function : SetBasisCurve
294 //=======================================================================
296 void Geom_SurfaceOfRevolution::SetBasisCurve (const Handle(Curve)& C) {
298 basisCurve = Handle(Curve)::DownCast(C->Copy());
299 smooth = C->Continuity();
303 //=======================================================================
304 //function : SetLocation
306 //=======================================================================
308 void Geom_SurfaceOfRevolution::SetLocation (const Pnt& P) {
314 //=======================================================================
317 //=======================================================================
319 void Geom_SurfaceOfRevolution::Bounds ( Standard_Real& U1,
322 Standard_Real& V2 ) const {
326 V1 = basisCurve->FirstParameter();
327 V2 = basisCurve->LastParameter();
331 //=======================================================================
334 //=======================================================================
336 void Geom_SurfaceOfRevolution::D0
337 (const Standard_Real U, const Standard_Real V, Pnt& P) const {
339 // C origine sur l'axe de revolution
340 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
341 // Q(v) point de parametre V sur la courbe de revolution
342 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
346 Pnt Pc = basisCurve->Value (V); //Q(v)
347 XYZ Q = Pc.XYZ(); //Q
348 XYZ C = loc.XYZ(); //C
350 XYZ Vdir = direction.XYZ(); //Vdir
351 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
352 VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
354 Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
355 VdotCQ.Add (VcrossCQ); //addition des composantes
363 //=======================================================================
366 //=======================================================================
368 void Geom_SurfaceOfRevolution::D1
369 (const Standard_Real U, const Standard_Real V,
371 Vec& D1U, Vec& D1V ) const {
373 // C origine sur l'axe de revolution
374 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
375 // Q(v) point de parametre V sur la courbe de revolution
377 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
378 // (Vdir^CQ) * Sin(U)
379 // D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
380 // (Vdir^CQ) * Cos(U)
381 // D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
382 // (Vdir^Q') * Sin(U)
386 basisCurve->D1 (V, Pc, V1);
387 XYZ Q = Pc.XYZ(); //Q
388 XYZ DQv = V1.XYZ(); //Q'
389 XYZ C = loc.XYZ(); //C
390 XYZ Vdir = direction.XYZ(); //Vdir
392 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
393 XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
394 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
395 XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
397 VcrossDQv.Multiply (Sin(U));
398 VdotDQv.Multiply (1.0 - Cos(U));
399 VdotDQv.Add (VcrossDQv);
400 DQv.Multiply (Cos(U));
404 XYZ DQu = Q.Multiplied (-Sin(U));
405 DQu.Add (VcrossCQ.Multiplied (Cos(U)));
406 DQu.Add (VdotCQ.Multiplied (Sin(U)));
411 VcrossCQ.Multiply (Sin(U));
413 VdotCQ.Multiply (1.0-Cos(U));
418 //=======================================================================
421 //=======================================================================
423 void Geom_SurfaceOfRevolution::D2
424 (const Standard_Real U, const Standard_Real V,
427 Vec& D2U, Vec& D2V, Vec& D2UV ) const {
430 // C origine sur l'axe de revolution
431 // V vecteur unitaire definissant la direction de l'axe de revolution
432 // Q(v) point de parametre V sur la courbe de revolution
435 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
436 // (Vdir^CQ) * Sin(U)
437 // D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
438 // (Vdir^CQ) * Cos(U)
439 // D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
440 // (Vdir^Q') * Sin(U)
441 // D2U_M(u,v) = -CQ * Cos(U) + (CQ.Vdir)(Cos(U)) * Vdir +
442 // (Vdir^CQ) * -(Sin(U))
443 // D2V_M(u,v) = Q" * Cos(U) + (Q".Vdir)(1-Cos(U)) * Vdir +
444 // (Vdir^Q") * Sin(U)
445 // D2UV_M(u,v)= -Q' * Sin(U) + (Q'.Vdir)(Sin(U)) * Vdir +
446 // (Vdir^Q') * Cos(U)
451 basisCurve->D2 (V, Pc, V1, V2);
452 XYZ Q = Pc.XYZ(); //Q
453 XYZ D1Qv = V1.XYZ(); //Q'
454 XYZ D2Qv = V2.XYZ(); //Q"
455 XYZ C = loc.XYZ(); //C
456 XYZ Vdir = direction.XYZ(); //Vdir
458 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
459 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
460 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
461 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
462 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
463 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
466 XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
467 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
468 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
471 D1Qv.Multiply (Cos(U));
472 VcrossD1Qv.Multiply (Sin(U));
473 VdotD1Qv.Multiply (1.0 - Cos(U));
474 D1Qv.Add (VcrossD1Qv);
478 VcrossD2Qv.Multiply (Sin(U));
479 VdotD2Qv.Multiply (1.0 - Cos(U));
480 VdotD2Qv.Add (VcrossD2Qv);
481 D2Qv.Multiply (Cos(U));
485 XYZ D1Qu = Q.Multiplied (-Sin(U));
486 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
487 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
491 VcrossCQ.Multiply (Sin(U));
493 XYZ D2Qu = Q.Multiplied(-1.0);
494 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
496 VdotCQ.Multiply (1.0-Cos(U));
504 //=======================================================================
507 //=======================================================================
509 void Geom_SurfaceOfRevolution::D3
510 (const Standard_Real U, const Standard_Real V,
513 Vec& D2U, Vec& D2V, Vec& D2UV,
514 Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const {
516 // C origine sur l'axe de revolution
517 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
518 // Q(v) point de parametre V sur la courbe de revolution
521 // OM (u,v) = OC + CQ * Cos(u) + (CQ.Vdir)(1-Cos(u)) * Vdir +
522 // (Vdir^CQ) * Sin(u)
523 // D1U_M(u,v) = - CQ * Sin(u) + (CQ.Vdir)(Sin(u)) * Vdir +
524 // (Vdir^CQ) * Cos(u)
525 // D2U_M(u,v) = -CQ * Cos(u) + (CQ.Vdir)(Cos(u)) * Vdir +
526 // (Vdir^CQ) * -Sin(u)
527 // D2UV_M(u,v)= -Q' * Sin(u) + (Q'.Vdir)(Sin(u)) * Vdir +
528 // (Vdir^Q') * Cos(u)
529 // D3UUV_M(u,v) = -Q' * Cos(u) + (Q'.Vdir)(Cos(u)) * Vdir +
530 // (Vdir^Q') * -Sin(u)
531 // D3U_M(u,v) = CQ * Sin(u) + (CQ.Vdir)(-Sin(u)) * Vdir +
532 // (Vdir^CQ) * -Cos(u)
533 // D1V_M(u,v) = Q' * Cos(u) + (Q'.Vdir)(1-Cos(u)) * Vdir +
534 // (Vdir^Q') * Sin(u)
535 // D2V_M(u,v) = Q" * Cos(u) + (Q".Vdir)(1-Cos(u)) * Vdir +
536 // (Vdir^Q") * Sin(u)
537 // D3UVV_M(u,v) = -Q" * Sin(u) + (Q".Vdir)(Sin(u)) * Vdir +
538 // (Vdir^Q") * Cos(u)
539 // D3V_M(u,v) = Q'''* Cos(u) + (Q'''.Vdir)(1-Cos(u)) * Vdir +
540 // (Vdir^Q''') * Sin(u)
545 basisCurve->D3 (V, Pc, V1, V2, V3);
546 XYZ Q = Pc.XYZ(); //Q
547 XYZ D1Qv = V1.XYZ(); //Q'
548 XYZ D2Qv = V2.XYZ(); //Q"
549 XYZ D3Qv = V3.XYZ(); //Q'''
550 XYZ C = loc.XYZ(); //C
551 XYZ Vdir = direction.XYZ(); //Vdir
553 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
554 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
555 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
556 XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
557 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
558 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
559 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
560 XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
562 XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
563 D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
564 D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
565 D3UUV.SetXYZ (D3Quuv);
567 XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
568 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
569 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
572 D1Qv.Multiply (Cos(U));
573 VcrossD1Qv.Multiply (Sin(U));
574 VdotD1Qv.Multiply (1.0 - Cos(U));
575 D1Qv.Add (VcrossD1Qv);
579 XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
580 D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
581 D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
582 D3UVV.SetXYZ (D3Qvvu);
584 VcrossD2Qv.Multiply (Sin(U));
585 VdotD2Qv.Multiply (1.0 - Cos(U));
586 VdotD2Qv.Add (VcrossD2Qv);
587 D2Qv.Multiply (Cos(U));
591 VcrossD3Qv.Multiply (Sin(U));
592 VdotD3Qv.Multiply (1.0 - Cos(U));
593 VdotD3Qv.Add (VcrossD2Qv);
594 D3Qv.Multiply (Cos(U));
598 XYZ D1Qu = Q.Multiplied (- Sin(U));
599 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
600 XYZ D3Qu = D1Qu.Multiplied (-1.0);
601 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
602 D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
607 VcrossCQ.Multiply (Sin(U));
609 XYZ D2Qu = Q.Multiplied(-1.0);
610 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
612 VdotCQ.Multiply (1.0-Cos(U));
619 //=======================================================================
622 //=======================================================================
624 Vec Geom_SurfaceOfRevolution::DN (const Standard_Real U , const Standard_Real V,
625 const Standard_Integer Nu, const Standard_Integer Nv) const {
627 Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
629 XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
630 XYZ Vdir = direction.XYZ();
631 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
632 VDot.Multiply (1-Cos(U));
633 XYZ VCross = Vdir.Crossed (Vn);
634 VCross.Multiply (Sin(U));
635 Vn.Multiply (Cos(U));
641 XYZ CQ = (basisCurve->Value (V)).XYZ() - loc.XYZ();
642 XYZ Vdir = direction.XYZ();
643 XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
644 XYZ VCross = Vdir.Crossed (CQ);
645 if ((Nu + 6) % 4 == 0) {
646 CQ.Multiply (-Cos (U));
647 VDot.Multiply (Cos(U));
648 VCross.Multiply (-Sin(U));
650 else if ((Nu + 5) % 4 == 0) {
651 CQ.Multiply (Sin (U));
652 VDot.Multiply (-Sin(U));
653 VCross.Multiply (-Cos(U));
655 else if ((Nu+3) % 4 == 0) {
656 CQ.Multiply (-Sin (U));
657 VDot.Multiply (+Sin(U));
658 VCross.Multiply (Cos(U));
660 else if (Nu+4 % 4 == 0) {
661 CQ.Multiply (Cos (U));
662 VDot.Multiply (-Cos(U));
663 VCross.Multiply (Sin(U));
670 XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
671 XYZ Vdir = direction.XYZ();
672 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
673 XYZ VCross = Vdir.Crossed (Vn);
674 if ((Nu + 6) % 4 == 0) {
675 Vn.Multiply (-Cos (U));
676 VDot.Multiply (Cos(U));
677 VCross.Multiply (-Sin(U));
679 else if ((Nu + 5) % 4 == 0) {
680 Vn.Multiply (Sin (U));
681 VDot.Multiply (-Sin(U));
682 VCross.Multiply (-Cos(U));
684 else if ((Nu+3) % 4 == 0) {
685 Vn.Multiply (-Sin (U));
686 VDot.Multiply (+Sin(U));
687 VCross.Multiply (Cos(U));
689 else if (Nu+4 % 4 == 0) {
690 Vn.Multiply (Cos (U));
691 VDot.Multiply (-Cos(U));
692 VCross.Multiply (Sin(U));
700 //=======================================================================
703 //=======================================================================
705 void Geom_SurfaceOfRevolution::LocalD0 (const Standard_Real U,
706 const Standard_Real V,
707 const Standard_Integer VSide,
710 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
713 Handle( Geom_BSplineCurve) BSplC;
714 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
716 LocateSide(V,VSide,BSplC,0,P,D1V,D2V,D3V);
718 XYZ C = loc.XYZ(); //C
720 XYZ Vdir = direction.XYZ(); //Vdir
721 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
722 VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
724 Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
725 VdotCQ.Add (VcrossCQ); //addition des composantes
734 //=======================================================================
737 //=======================================================================
739 void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U,
740 const Standard_Real V,
741 const Standard_Integer VSide,
746 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
748 Handle( Geom_BSplineCurve) BSplC;
749 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
752 LocateSide(V,VSide,BSplC,1,P,V1,D2V,D3V);
754 XYZ DQv = V1.XYZ(); //Q'
755 XYZ C = loc.XYZ(); //C
756 XYZ Vdir = direction.XYZ(); //Vdir
758 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
759 XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
760 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
761 XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
763 VcrossDQv.Multiply (Sin(U));
764 VdotDQv.Multiply (1.0 - Cos(U));
765 VdotDQv.Add (VcrossDQv);
766 DQv.Multiply (Cos(U));
770 XYZ DQu = Q.Multiplied (-Sin(U));
771 DQu.Add (VcrossCQ.Multiplied (Cos(U)));
772 DQu.Add (VdotCQ.Multiplied (Sin(U)));
777 VcrossCQ.Multiply (Sin(U));
779 VdotCQ.Multiply (1.0-Cos(U));
786 //=======================================================================
789 //=======================================================================
791 void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U,
792 const Standard_Real V,
793 const Standard_Integer VSide,
801 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
803 Handle( Geom_BSplineCurve) BSplC;
804 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
806 LocateSide(V,VSide,BSplC,2,P,D1V,D2V,d3v);
808 XYZ D1Qv = D1V.XYZ(); //Q'
809 XYZ D2Qv = D2V.XYZ(); //Q"
810 XYZ C = loc.XYZ(); //C
811 XYZ Vdir = direction.XYZ(); //Vdir
813 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
814 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
815 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
816 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
817 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
818 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
821 XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
822 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
823 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
826 D1Qv.Multiply (Cos(U));
827 VcrossD1Qv.Multiply (Sin(U));
828 VdotD1Qv.Multiply (1.0 - Cos(U));
829 D1Qv.Add (VcrossD1Qv);
833 VcrossD2Qv.Multiply (Sin(U));
834 VdotD2Qv.Multiply (1.0 - Cos(U));
835 VdotD2Qv.Add (VcrossD2Qv);
836 D2Qv.Multiply (Cos(U));
840 XYZ D1Qu = Q.Multiplied (-Sin(U));
841 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
842 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
846 VcrossCQ.Multiply (Sin(U));
848 XYZ D2Qu = Q.Multiplied(-1.0);
849 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
851 VdotCQ.Multiply (1.0-Cos(U));
857 D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
859 //=======================================================================
862 //=======================================================================
864 void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U,
865 const Standard_Real V,
866 const Standard_Integer VSide,
878 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
880 Handle( Geom_BSplineCurve) BSplC;
881 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
883 LocateSide(V,VSide,BSplC,3,P,D1V,D2V,D3V);
885 XYZ D1Qv = D1V.XYZ(); //Q'
886 XYZ D2Qv = D2V.XYZ(); //Q"
887 XYZ D3Qv = D3V.XYZ(); //Q'''
888 XYZ C = loc.XYZ(); //C
889 XYZ Vdir = direction.XYZ(); //Vdir
891 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
892 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
893 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
894 XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
895 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
896 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
897 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
898 XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
900 XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
901 D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
902 D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
903 D3UUV.SetXYZ (D3Quuv);
905 XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
906 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
907 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
910 D1Qv.Multiply (Cos(U));
911 VcrossD1Qv.Multiply (Sin(U));
912 VdotD1Qv.Multiply (1.0 - Cos(U));
913 D1Qv.Add (VcrossD1Qv);
917 XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
918 D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
919 D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
920 D3UVV.SetXYZ (D3Qvvu);
922 VcrossD2Qv.Multiply (Sin(U));
923 VdotD2Qv.Multiply (1.0 - Cos(U));
924 VdotD2Qv.Add (VcrossD2Qv);
925 D2Qv.Multiply (Cos(U));
929 VcrossD3Qv.Multiply (Sin(U));
930 VdotD3Qv.Multiply (1.0 - Cos(U));
931 VdotD3Qv.Add (VcrossD2Qv);
932 D3Qv.Multiply (Cos(U));
936 XYZ D1Qu = Q.Multiplied (- Sin(U));
937 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
938 XYZ D3Qu = D1Qu.Multiplied (-1.0);
939 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
940 D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
945 VcrossCQ.Multiply (Sin(U));
947 XYZ D2Qu = Q.Multiplied(-1.0);
948 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
950 VdotCQ.Multiply (1.0-Cos(U));
956 D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
958 //=======================================================================
961 //=======================================================================
963 gp_Vec Geom_SurfaceOfRevolution::LocalDN (const Standard_Real U,
964 const Standard_Real V,
965 const Standard_Integer VSide,
966 const Standard_Integer Nu,
967 const Standard_Integer Nv) const
969 Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
972 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
974 Handle( Geom_BSplineCurve) BSplC;
975 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
976 Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
978 return DN(U,V,Nu,Nv);
979 XYZ Vdir = direction.XYZ();
980 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
981 VDot.Multiply (1-Cos(U));
982 XYZ VCross = Vdir.Crossed (Vn);
983 VCross.Multiply (Sin(U));
984 Vn.Multiply (Cos(U));
991 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
993 Handle( Geom_BSplineCurve) BSplC;
994 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
995 CQ = LocateSideN(V,VSide,BSplC,Nv).XYZ() - loc.XYZ();
997 return DN(U,V,Nu,Nv);
998 XYZ Vdir = direction.XYZ();
999 XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
1000 XYZ VCross = Vdir.Crossed (CQ);
1001 if ((Nu + 6) % 4 == 0) {
1002 CQ.Multiply (-Cos (U));
1003 VDot.Multiply (Cos(U));
1004 VCross.Multiply (-Sin(U));
1006 else if ((Nu + 5) % 4 == 0) {
1007 CQ.Multiply (Sin (U));
1008 VDot.Multiply (-Sin(U));
1009 VCross.Multiply (-Cos(U));
1011 else if ((Nu+3) % 4 == 0) {
1012 CQ.Multiply (-Sin (U));
1013 VDot.Multiply (+Sin(U));
1014 VCross.Multiply (Cos(U));
1016 else if (Nu+4 % 4 == 0) {
1017 CQ.Multiply (Cos (U));
1018 VDot.Multiply (-Cos(U));
1019 VCross.Multiply (Sin(U));
1027 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
1029 Handle( Geom_BSplineCurve) BSplC;
1030 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
1031 Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
1033 return DN(U,V,Nu,Nv);
1034 XYZ Vdir = direction.XYZ();
1035 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
1036 XYZ VCross = Vdir.Crossed (Vn);
1037 if ((Nu + 6) % 4 == 0) {
1038 Vn.Multiply (-Cos (U));
1039 VDot.Multiply (Cos(U));
1040 VCross.Multiply (-Sin(U));
1042 else if ((Nu + 5) % 4 == 0) {
1043 Vn.Multiply (Sin (U));
1044 VDot.Multiply (-Sin(U));
1045 VCross.Multiply (-Cos(U));
1047 else if ((Nu+3) % 4 == 0) {
1048 Vn.Multiply (-Sin (U));
1049 VDot.Multiply (+Sin(U));
1050 VCross.Multiply (Cos(U));
1052 else if (Nu+4 % 4 == 0) {
1053 Vn.Multiply (Cos (U));
1054 VDot.Multiply (-Cos(U));
1055 VCross.Multiply (Sin(U));
1063 //=======================================================================
1064 //function : ReferencePlane
1066 //=======================================================================
1068 Ax2 Geom_SurfaceOfRevolution::ReferencePlane() const {
1070 Standard_NotImplemented::Raise ();
1075 //=======================================================================
1078 //=======================================================================
1080 Handle(Curve) Geom_SurfaceOfRevolution::UIso (const Standard_Real U) const {
1082 Handle(Curve) C = Handle(Curve)::DownCast(basisCurve->Copy());
1083 Ax1 RotAxis = Ax1 (loc, direction);
1084 C->Rotate (RotAxis, U);
1089 //=======================================================================
1092 //=======================================================================
1094 Handle(Geom_Curve) Geom_SurfaceOfRevolution::VIso (const Standard_Real V) const {
1096 Handle(Geom_Circle) Circ;
1097 Pnt Pc = basisCurve->Value (V);
1098 gp_Lin L1(loc,direction);
1099 Standard_Real Rad= L1.Distance(Pc);
1102 if ( Rad > gp::Resolution()) {
1105 C.SetLinearForm((P-loc.XYZ()).Dot(direction.XYZ()),
1106 direction.XYZ(), loc.XYZ() );
1108 if(P.Modulus() > gp::Resolution()) {
1109 gp_Dir D = P.Normalized();
1110 Rep = gp_Ax2(C, direction, D);
1113 Rep = gp_Ax2(C, direction);
1116 Rep = gp_Ax2(Pc, direction);
1118 Circ = new Geom_Circle (Rep, Rad);
1123 //=======================================================================
1124 //function : Transform
1126 //=======================================================================
1128 void Geom_SurfaceOfRevolution::Transform (const Trsf& T) {
1131 direction.Transform (T);
1132 basisCurve->Transform (T);
1133 if(T.ScaleFactor()*T.HVectorialPart().Determinant() < 0.) UReverse();
1136 //=======================================================================
1137 //function : TransformParameters
1139 //=======================================================================
1141 void Geom_SurfaceOfRevolution::TransformParameters(Standard_Real& ,
1146 V = basisCurve->TransformedParameter(V,T);
1149 //=======================================================================
1150 //function : ParametricTransformation
1152 //=======================================================================
1154 gp_GTrsf2d Geom_SurfaceOfRevolution::ParametricTransformation
1155 (const gp_Trsf& T) const
1158 gp_Ax2d Axis(gp::Origin2d(),gp::DX2d());
1159 T2.SetAffinity(Axis, basisCurve->ParametricTransformation(T));