1 // Created on: 1993-03-10
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Geom_SurfaceOfRevolution.ixx>
18 #include <BSplSLib.hxx>
19 #include <BSplCLib.hxx>
20 #include <Geom_Circle.hxx>
22 #include <gp_Ax2d.hxx>
27 #include <Standard_ConstructionError.hxx>
28 #include <Standard_NotImplemented.hxx>
29 #include <Standard_RangeError.hxx>
30 #include <Geom_BSplineCurve.hxx>
31 #include <Precision.hxx>
32 #define POLES (poles->Array2())
33 #define WEIGHTS (weights->Array2())
34 #define UKNOTS (uknots->Array1())
35 #define VKNOTS (vknots->Array1())
36 #define UFKNOTS (ufknots->Array1())
37 #define VFKNOTS (vfknots->Array1())
38 #define FMULTS (BSplCLib::NoMults())
40 typedef Geom_SurfaceOfRevolution SurfaceOfRevolution;
41 typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
42 typedef Handle(Geom_Geometry) Handle(Geometry);
43 typedef Geom_Curve Curve;
44 typedef Handle(Geom_Curve) Handle(Curve);
53 //=======================================================================
54 //function : LocateSide
55 //purpose : This method locates U parameter on basis BSpline curve
56 // and calls LocalDi methods corresponding an order of
57 // derivative and position of the surface side contained
58 // the point relatively the curve knots.
59 //=======================================================================
60 static void LocateSide(const Standard_Real U,
61 const Standard_Integer Side,
62 const Handle(Geom_BSplineCurve)& BSplC,
63 const Standard_Integer NDir,
69 Standard_Integer Ideb, Ifin;
70 Standard_Real ParTol=Precision::PConfusion()/2;
71 BSplC->Geom_BSplineCurve::LocateU(U,ParTol,Ideb,Ifin,Standard_False);
75 if ((Ideb>=Ifin)) Ifin = Ideb+1;
79 if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
80 if ((Ideb>=Ifin)) Ideb = Ifin-1;
84 case 0 : BSplC->Geom_BSplineCurve::LocalD0(U,Ideb,Ifin,P); break;
85 case 1 : BSplC->Geom_BSplineCurve::LocalD1(U,Ideb,Ifin,P,D1U); break;
86 case 2 : BSplC->Geom_BSplineCurve::LocalD2(U,Ideb,Ifin,P,D1U,D2U); break;
87 case 3 : BSplC->Geom_BSplineCurve::LocalD3(U,Ideb,Ifin,P,D1U,D2U,D3U); break;
91 //=======================================================================
92 //function : LocateSideN
93 //purpose : This method locates U parameter on basis BSpline curve
94 // and calls LocalDN method corresponding position of surface side
95 // contained the point relatively the curve knots.
96 //=======================================================================
97 static gp_Vec LocateSideN(const Standard_Real V,
98 const Standard_Integer Side,
99 const Handle(Geom_BSplineCurve)& BSplC,
100 const Standard_Integer Nv )
102 Standard_Integer Ideb, Ifin;
103 Standard_Real ParTol=Precision::PConfusion()/2;
104 BSplC->Geom_BSplineCurve::LocateU(V,ParTol,Ideb,Ifin,Standard_False);
108 if ((Ideb>=Ifin)) Ifin = Ideb+1;
112 if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
113 if ((Ideb>=Ifin)) Ideb = Ifin-1;
115 return BSplC->Geom_BSplineCurve::LocalDN(V,Ideb,Ifin,Nv);
121 //=======================================================================
124 //=======================================================================
126 Handle(Geom_Geometry) Geom_SurfaceOfRevolution::Copy () const {
128 return new Geom_SurfaceOfRevolution (basisCurve, Axis());
132 //=======================================================================
133 //function : Geom_SurfaceOfRevolution
135 //=======================================================================
137 Geom_SurfaceOfRevolution::Geom_SurfaceOfRevolution
138 (const Handle(Curve)& C ,
139 const Ax1& A1 ) : loc (A1.Location()) {
141 basisCurve = Handle(Curve)::DownCast(C->Copy());
142 direction = A1.Direction();
143 smooth = C->Continuity();
147 //=======================================================================
148 //function : UReverse
150 //=======================================================================
152 void Geom_SurfaceOfRevolution::UReverse () {
158 //=======================================================================
159 //function : UReversedParameter
161 //=======================================================================
163 Standard_Real Geom_SurfaceOfRevolution::UReversedParameter (const Standard_Real U) const {
165 return ( 2.*M_PI - U);
169 //=======================================================================
170 //function : VReverse
172 //=======================================================================
174 void Geom_SurfaceOfRevolution::VReverse () {
176 basisCurve->Reverse();
180 //=======================================================================
181 //function : VReversedParameter
183 //=======================================================================
185 Standard_Real Geom_SurfaceOfRevolution::VReversedParameter (const Standard_Real V) const {
187 return basisCurve->ReversedParameter(V);
191 //=======================================================================
192 //function : Location
194 //=======================================================================
196 const gp_Pnt& Geom_SurfaceOfRevolution::Location () const {
201 //=======================================================================
202 //function : IsUPeriodic
204 //=======================================================================
206 Standard_Boolean Geom_SurfaceOfRevolution::IsUPeriodic () const {
208 return Standard_True;
211 //=======================================================================
214 //=======================================================================
216 Standard_Boolean Geom_SurfaceOfRevolution::IsCNu (const Standard_Integer ) const {
218 return Standard_True;
221 //=======================================================================
224 //=======================================================================
226 Ax1 Geom_SurfaceOfRevolution::Axis () const {
228 return Ax1 (loc, direction);
231 //=======================================================================
234 //=======================================================================
236 Standard_Boolean Geom_SurfaceOfRevolution::IsCNv (const Standard_Integer N) const {
238 Standard_RangeError_Raise_if (N < 0, " ");
239 return basisCurve->IsCN(N);
243 //=======================================================================
244 //function : IsUClosed
246 //=======================================================================
248 Standard_Boolean Geom_SurfaceOfRevolution::IsUClosed () const {
250 return Standard_True;
253 //=======================================================================
254 //function : IsVClosed
256 //=======================================================================
258 Standard_Boolean Geom_SurfaceOfRevolution::IsVClosed () const
260 return basisCurve->IsClosed();
264 //=======================================================================
265 //function : IsVPeriodic
267 //=======================================================================
269 Standard_Boolean Geom_SurfaceOfRevolution::IsVPeriodic () const {
271 return basisCurve->IsPeriodic();
275 //=======================================================================
278 //=======================================================================
280 void Geom_SurfaceOfRevolution::SetAxis (const Ax1& A1) {
282 direction = A1.Direction();
287 //=======================================================================
288 //function : SetDirection
290 //=======================================================================
292 void Geom_SurfaceOfRevolution::SetDirection (const Dir& V) {
298 //=======================================================================
299 //function : SetBasisCurve
301 //=======================================================================
303 void Geom_SurfaceOfRevolution::SetBasisCurve (const Handle(Curve)& C) {
305 basisCurve = Handle(Curve)::DownCast(C->Copy());
306 smooth = C->Continuity();
310 //=======================================================================
311 //function : SetLocation
313 //=======================================================================
315 void Geom_SurfaceOfRevolution::SetLocation (const Pnt& P) {
321 //=======================================================================
324 //=======================================================================
326 void Geom_SurfaceOfRevolution::Bounds ( Standard_Real& U1,
329 Standard_Real& V2 ) const {
333 V1 = basisCurve->FirstParameter();
334 V2 = basisCurve->LastParameter();
338 //=======================================================================
341 //=======================================================================
343 void Geom_SurfaceOfRevolution::D0
344 (const Standard_Real U, const Standard_Real V, Pnt& P) const {
346 // C origine sur l'axe de revolution
347 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
348 // Q(v) point de parametre V sur la courbe de revolution
349 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
353 Pnt Pc = basisCurve->Value (V); //Q(v)
354 XYZ Q = Pc.XYZ(); //Q
355 XYZ C = loc.XYZ(); //C
357 XYZ Vdir = direction.XYZ(); //Vdir
358 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
359 VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
361 Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
362 VdotCQ.Add (VcrossCQ); //addition des composantes
370 //=======================================================================
373 //=======================================================================
375 void Geom_SurfaceOfRevolution::D1
376 (const Standard_Real U, const Standard_Real V,
378 Vec& D1U, Vec& D1V ) const {
380 // C origine sur l'axe de revolution
381 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
382 // Q(v) point de parametre V sur la courbe de revolution
384 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
385 // (Vdir^CQ) * Sin(U)
386 // D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
387 // (Vdir^CQ) * Cos(U)
388 // D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
389 // (Vdir^Q') * Sin(U)
393 basisCurve->D1 (V, Pc, V1);
394 XYZ Q = Pc.XYZ(); //Q
395 XYZ DQv = V1.XYZ(); //Q'
396 XYZ C = loc.XYZ(); //C
397 XYZ Vdir = direction.XYZ(); //Vdir
399 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
400 // If the point is placed on the axis of revolution then derivatives on U are undefined.
401 // Manually set them to zero.
402 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
403 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
404 XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
405 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
406 XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
408 VcrossDQv.Multiply (Sin(U));
409 VdotDQv.Multiply (1.0 - Cos(U));
410 VdotDQv.Add (VcrossDQv);
411 DQv.Multiply (Cos(U));
415 XYZ DQu = Q.Multiplied (-Sin(U));
416 DQu.Add (VcrossCQ.Multiplied (Cos(U)));
417 DQu.Add (VdotCQ.Multiplied (Sin(U)));
422 VcrossCQ.Multiply (Sin(U));
424 VdotCQ.Multiply (1.0-Cos(U));
429 //=======================================================================
432 //=======================================================================
434 void Geom_SurfaceOfRevolution::D2
435 (const Standard_Real U, const Standard_Real V,
438 Vec& D2U, Vec& D2V, Vec& D2UV ) const {
441 // C origine sur l'axe de revolution
442 // V vecteur unitaire definissant la direction de l'axe de revolution
443 // Q(v) point de parametre V sur la courbe de revolution
446 // OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
447 // (Vdir^CQ) * Sin(U)
448 // D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
449 // (Vdir^CQ) * Cos(U)
450 // D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
451 // (Vdir^Q') * Sin(U)
452 // D2U_M(u,v) = -CQ * Cos(U) + (CQ.Vdir)(Cos(U)) * Vdir +
453 // (Vdir^CQ) * -(Sin(U))
454 // D2V_M(u,v) = Q" * Cos(U) + (Q".Vdir)(1-Cos(U)) * Vdir +
455 // (Vdir^Q") * Sin(U)
456 // D2UV_M(u,v)= -Q' * Sin(U) + (Q'.Vdir)(Sin(U)) * Vdir +
457 // (Vdir^Q') * Cos(U)
462 basisCurve->D2 (V, Pc, V1, V2);
463 XYZ Q = Pc.XYZ(); //Q
464 XYZ D1Qv = V1.XYZ(); //Q'
465 XYZ D2Qv = V2.XYZ(); //Q"
466 XYZ C = loc.XYZ(); //C
467 XYZ Vdir = direction.XYZ(); //Vdir
469 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
470 // If the point is placed on the axis of revolution then derivatives on U are undefined.
471 // Manually set them to zero.
472 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
473 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
474 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
475 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
476 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
477 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
478 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
481 XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
482 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
483 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
486 D1Qv.Multiply (Cos(U));
487 VcrossD1Qv.Multiply (Sin(U));
488 VdotD1Qv.Multiply (1.0 - Cos(U));
489 D1Qv.Add (VcrossD1Qv);
493 VcrossD2Qv.Multiply (Sin(U));
494 VdotD2Qv.Multiply (1.0 - Cos(U));
495 VdotD2Qv.Add (VcrossD2Qv);
496 D2Qv.Multiply (Cos(U));
500 XYZ D1Qu = Q.Multiplied (-Sin(U));
501 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
502 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
506 VcrossCQ.Multiply (Sin(U));
508 XYZ D2Qu = Q.Multiplied(-1.0);
509 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
511 VdotCQ.Multiply (1.0-Cos(U));
519 //=======================================================================
522 //=======================================================================
524 void Geom_SurfaceOfRevolution::D3
525 (const Standard_Real U, const Standard_Real V,
528 Vec& D2U, Vec& D2V, Vec& D2UV,
529 Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const {
531 // C origine sur l'axe de revolution
532 // Vdir vecteur unitaire definissant la direction de l'axe de revolution
533 // Q(v) point de parametre V sur la courbe de revolution
536 // OM (u,v) = OC + CQ * Cos(u) + (CQ.Vdir)(1-Cos(u)) * Vdir +
537 // (Vdir^CQ) * Sin(u)
538 // D1U_M(u,v) = - CQ * Sin(u) + (CQ.Vdir)(Sin(u)) * Vdir +
539 // (Vdir^CQ) * Cos(u)
540 // D2U_M(u,v) = -CQ * Cos(u) + (CQ.Vdir)(Cos(u)) * Vdir +
541 // (Vdir^CQ) * -Sin(u)
542 // D2UV_M(u,v)= -Q' * Sin(u) + (Q'.Vdir)(Sin(u)) * Vdir +
543 // (Vdir^Q') * Cos(u)
544 // D3UUV_M(u,v) = -Q' * Cos(u) + (Q'.Vdir)(Cos(u)) * Vdir +
545 // (Vdir^Q') * -Sin(u)
546 // D3U_M(u,v) = CQ * Sin(u) + (CQ.Vdir)(-Sin(u)) * Vdir +
547 // (Vdir^CQ) * -Cos(u)
548 // D1V_M(u,v) = Q' * Cos(u) + (Q'.Vdir)(1-Cos(u)) * Vdir +
549 // (Vdir^Q') * Sin(u)
550 // D2V_M(u,v) = Q" * Cos(u) + (Q".Vdir)(1-Cos(u)) * Vdir +
551 // (Vdir^Q") * Sin(u)
552 // D3UVV_M(u,v) = -Q" * Sin(u) + (Q".Vdir)(Sin(u)) * Vdir +
553 // (Vdir^Q") * Cos(u)
554 // D3V_M(u,v) = Q'''* Cos(u) + (Q'''.Vdir)(1-Cos(u)) * Vdir +
555 // (Vdir^Q''') * Sin(u)
560 basisCurve->D3 (V, Pc, V1, V2, V3);
561 XYZ Q = Pc.XYZ(); //Q
562 XYZ D1Qv = V1.XYZ(); //Q'
563 XYZ D2Qv = V2.XYZ(); //Q"
564 XYZ D3Qv = V3.XYZ(); //Q'''
565 XYZ C = loc.XYZ(); //C
566 XYZ Vdir = direction.XYZ(); //Vdir
568 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
569 // If the point is placed on the axis of revolution then derivatives on U are undefined.
570 // Manually set them to zero.
571 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
572 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
573 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
574 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
575 XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
576 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
577 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
578 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
579 XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
581 XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
582 D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
583 D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
584 D3UUV.SetXYZ (D3Quuv);
586 XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
587 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
588 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
591 D1Qv.Multiply (Cos(U));
592 VcrossD1Qv.Multiply (Sin(U));
593 VdotD1Qv.Multiply (1.0 - Cos(U));
594 D1Qv.Add (VcrossD1Qv);
598 XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
599 D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
600 D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
601 D3UVV.SetXYZ (D3Qvvu);
603 VcrossD2Qv.Multiply (Sin(U));
604 VdotD2Qv.Multiply (1.0 - Cos(U));
605 VdotD2Qv.Add (VcrossD2Qv);
606 D2Qv.Multiply (Cos(U));
610 VcrossD3Qv.Multiply (Sin(U));
611 VdotD3Qv.Multiply (1.0 - Cos(U));
612 VdotD3Qv.Add (VcrossD2Qv);
613 D3Qv.Multiply (Cos(U));
617 XYZ D1Qu = Q.Multiplied (- Sin(U));
618 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
619 XYZ D3Qu = D1Qu.Multiplied (-1.0);
620 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
621 D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
626 VcrossCQ.Multiply (Sin(U));
628 XYZ D2Qu = Q.Multiplied(-1.0);
629 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
631 VdotCQ.Multiply (1.0-Cos(U));
638 //=======================================================================
641 //=======================================================================
643 Vec Geom_SurfaceOfRevolution::DN (const Standard_Real U , const Standard_Real V,
644 const Standard_Integer Nu, const Standard_Integer Nv) const {
646 Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
648 XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
649 XYZ Vdir = direction.XYZ();
650 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
651 VDot.Multiply (1-Cos(U));
652 XYZ VCross = Vdir.Crossed (Vn);
653 VCross.Multiply (Sin(U));
654 Vn.Multiply (Cos(U));
660 XYZ CQ = (basisCurve->Value (V)).XYZ() - loc.XYZ();
661 XYZ Vdir = direction.XYZ();
662 XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
663 XYZ VCross = Vdir.Crossed (CQ);
664 if ((Nu + 6) % 4 == 0) {
665 CQ.Multiply (-Cos (U));
666 VDot.Multiply (Cos(U));
667 VCross.Multiply (-Sin(U));
669 else if ((Nu + 5) % 4 == 0) {
670 CQ.Multiply (Sin (U));
671 VDot.Multiply (-Sin(U));
672 VCross.Multiply (-Cos(U));
674 else if ((Nu+3) % 4 == 0) {
675 CQ.Multiply (-Sin (U));
676 VDot.Multiply (+Sin(U));
677 VCross.Multiply (Cos(U));
679 else if (Nu+4 % 4 == 0) {
680 CQ.Multiply (Cos (U));
681 VDot.Multiply (-Cos(U));
682 VCross.Multiply (Sin(U));
689 XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
690 XYZ Vdir = direction.XYZ();
691 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
692 XYZ VCross = Vdir.Crossed (Vn);
693 if ((Nu + 6) % 4 == 0) {
694 Vn.Multiply (-Cos (U));
695 VDot.Multiply (Cos(U));
696 VCross.Multiply (-Sin(U));
698 else if ((Nu + 5) % 4 == 0) {
699 Vn.Multiply (Sin (U));
700 VDot.Multiply (-Sin(U));
701 VCross.Multiply (-Cos(U));
703 else if ((Nu+3) % 4 == 0) {
704 Vn.Multiply (-Sin (U));
705 VDot.Multiply (+Sin(U));
706 VCross.Multiply (Cos(U));
708 else if (Nu+4 % 4 == 0) {
709 Vn.Multiply (Cos (U));
710 VDot.Multiply (-Cos(U));
711 VCross.Multiply (Sin(U));
719 //=======================================================================
722 //=======================================================================
724 void Geom_SurfaceOfRevolution::LocalD0 (const Standard_Real U,
725 const Standard_Real V,
726 const Standard_Integer VSide,
729 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
732 Handle( Geom_BSplineCurve) BSplC;
733 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
735 LocateSide(V,VSide,BSplC,0,P,D1V,D2V,D3V);
737 XYZ C = loc.XYZ(); //C
739 XYZ Vdir = direction.XYZ(); //Vdir
740 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
741 VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
743 Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
744 VdotCQ.Add (VcrossCQ); //addition des composantes
753 //=======================================================================
756 //=======================================================================
758 void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U,
759 const Standard_Real V,
760 const Standard_Integer VSide,
765 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
767 Handle( Geom_BSplineCurve) BSplC;
768 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
771 LocateSide(V,VSide,BSplC,1,P,V1,D2V,D3V);
773 XYZ DQv = V1.XYZ(); //Q'
774 XYZ C = loc.XYZ(); //C
775 XYZ Vdir = direction.XYZ(); //Vdir
777 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
778 // If the point is placed on the axis of revolution then derivatives on U are undefined.
779 // Manually set them to zero.
780 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
781 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
783 XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
784 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
785 XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
787 VcrossDQv.Multiply (Sin(U));
788 VdotDQv.Multiply (1.0 - Cos(U));
789 VdotDQv.Add (VcrossDQv);
790 DQv.Multiply (Cos(U));
794 XYZ DQu = Q.Multiplied (-Sin(U));
795 DQu.Add (VcrossCQ.Multiplied (Cos(U)));
796 DQu.Add (VdotCQ.Multiplied (Sin(U)));
801 VcrossCQ.Multiply (Sin(U));
803 VdotCQ.Multiply (1.0-Cos(U));
810 //=======================================================================
813 //=======================================================================
815 void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U,
816 const Standard_Real V,
817 const Standard_Integer VSide,
825 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
827 Handle( Geom_BSplineCurve) BSplC;
828 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
830 LocateSide(V,VSide,BSplC,2,P,D1V,D2V,d3v);
832 XYZ D1Qv = D1V.XYZ(); //Q'
833 XYZ D2Qv = D2V.XYZ(); //Q"
834 XYZ C = loc.XYZ(); //C
835 XYZ Vdir = direction.XYZ(); //Vdir
837 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
838 // If the point is placed on the axis of revolution then derivatives on U are undefined.
839 // Manually set them to zero.
840 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
841 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
843 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
844 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
845 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
846 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
847 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
850 XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
851 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
852 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
855 D1Qv.Multiply (Cos(U));
856 VcrossD1Qv.Multiply (Sin(U));
857 VdotD1Qv.Multiply (1.0 - Cos(U));
858 D1Qv.Add (VcrossD1Qv);
862 VcrossD2Qv.Multiply (Sin(U));
863 VdotD2Qv.Multiply (1.0 - Cos(U));
864 VdotD2Qv.Add (VcrossD2Qv);
865 D2Qv.Multiply (Cos(U));
869 XYZ D1Qu = Q.Multiplied (-Sin(U));
870 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
871 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
875 VcrossCQ.Multiply (Sin(U));
877 XYZ D2Qu = Q.Multiplied(-1.0);
878 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
880 VdotCQ.Multiply (1.0-Cos(U));
886 D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
888 //=======================================================================
891 //=======================================================================
893 void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U,
894 const Standard_Real V,
895 const Standard_Integer VSide,
907 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
909 Handle( Geom_BSplineCurve) BSplC;
910 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
912 LocateSide(V,VSide,BSplC,3,P,D1V,D2V,D3V);
914 XYZ D1Qv = D1V.XYZ(); //Q'
915 XYZ D2Qv = D2V.XYZ(); //Q"
916 XYZ D3Qv = D3V.XYZ(); //Q'''
917 XYZ C = loc.XYZ(); //C
918 XYZ Vdir = direction.XYZ(); //Vdir
920 XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
921 // If the point is placed on the axis of revolution then derivatives on U are undefined.
922 // Manually set them to zero.
923 if (VcrossCQ.SquareModulus() < Precision::SquareConfusion())
924 VcrossCQ.SetCoord(0.0, 0.0, 0.0);
926 XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
927 XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
928 XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
929 XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
930 XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
931 XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
932 XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
934 XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
935 D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
936 D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
937 D3UUV.SetXYZ (D3Quuv);
939 XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
940 D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
941 D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
944 D1Qv.Multiply (Cos(U));
945 VcrossD1Qv.Multiply (Sin(U));
946 VdotD1Qv.Multiply (1.0 - Cos(U));
947 D1Qv.Add (VcrossD1Qv);
951 XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
952 D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
953 D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
954 D3UVV.SetXYZ (D3Qvvu);
956 VcrossD2Qv.Multiply (Sin(U));
957 VdotD2Qv.Multiply (1.0 - Cos(U));
958 VdotD2Qv.Add (VcrossD2Qv);
959 D2Qv.Multiply (Cos(U));
963 VcrossD3Qv.Multiply (Sin(U));
964 VdotD3Qv.Multiply (1.0 - Cos(U));
965 VdotD3Qv.Add (VcrossD2Qv);
966 D3Qv.Multiply (Cos(U));
970 XYZ D1Qu = Q.Multiplied (- Sin(U));
971 D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
972 XYZ D3Qu = D1Qu.Multiplied (-1.0);
973 D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
974 D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
979 VcrossCQ.Multiply (Sin(U));
981 XYZ D2Qu = Q.Multiplied(-1.0);
982 D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
984 VdotCQ.Multiply (1.0-Cos(U));
990 D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
992 //=======================================================================
995 //=======================================================================
997 gp_Vec Geom_SurfaceOfRevolution::LocalDN (const Standard_Real U,
998 const Standard_Real V,
999 const Standard_Integer VSide,
1000 const Standard_Integer Nu,
1001 const Standard_Integer Nv) const
1003 Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
1006 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
1008 Handle( Geom_BSplineCurve) BSplC;
1009 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
1010 Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
1012 return DN(U,V,Nu,Nv);
1013 XYZ Vdir = direction.XYZ();
1014 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
1015 VDot.Multiply (1-Cos(U));
1016 XYZ VCross = Vdir.Crossed (Vn);
1017 VCross.Multiply (Sin(U));
1018 Vn.Multiply (Cos(U));
1025 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
1027 Handle( Geom_BSplineCurve) BSplC;
1028 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
1029 CQ = LocateSideN(V,VSide,BSplC,Nv).XYZ() - loc.XYZ();
1031 return DN(U,V,Nu,Nv);
1032 XYZ Vdir = direction.XYZ();
1033 XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
1034 XYZ VCross = Vdir.Crossed (CQ);
1035 if ((Nu + 6) % 4 == 0) {
1036 CQ.Multiply (-Cos (U));
1037 VDot.Multiply (Cos(U));
1038 VCross.Multiply (-Sin(U));
1040 else if ((Nu + 5) % 4 == 0) {
1041 CQ.Multiply (Sin (U));
1042 VDot.Multiply (-Sin(U));
1043 VCross.Multiply (-Cos(U));
1045 else if ((Nu+3) % 4 == 0) {
1046 CQ.Multiply (-Sin (U));
1047 VDot.Multiply (+Sin(U));
1048 VCross.Multiply (Cos(U));
1050 else if (Nu+4 % 4 == 0) {
1051 CQ.Multiply (Cos (U));
1052 VDot.Multiply (-Cos(U));
1053 VCross.Multiply (Sin(U));
1061 if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
1063 Handle( Geom_BSplineCurve) BSplC;
1064 BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
1065 Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
1067 return DN(U,V,Nu,Nv);
1068 XYZ Vdir = direction.XYZ();
1069 XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
1070 XYZ VCross = Vdir.Crossed (Vn);
1071 if ((Nu + 6) % 4 == 0) {
1072 Vn.Multiply (-Cos (U));
1073 VDot.Multiply (Cos(U));
1074 VCross.Multiply (-Sin(U));
1076 else if ((Nu + 5) % 4 == 0) {
1077 Vn.Multiply (Sin (U));
1078 VDot.Multiply (-Sin(U));
1079 VCross.Multiply (-Cos(U));
1081 else if ((Nu+3) % 4 == 0) {
1082 Vn.Multiply (-Sin (U));
1083 VDot.Multiply (+Sin(U));
1084 VCross.Multiply (Cos(U));
1086 else if (Nu+4 % 4 == 0) {
1087 Vn.Multiply (Cos (U));
1088 VDot.Multiply (-Cos(U));
1089 VCross.Multiply (Sin(U));
1097 //=======================================================================
1098 //function : ReferencePlane
1100 //=======================================================================
1102 Ax2 Geom_SurfaceOfRevolution::ReferencePlane() const {
1104 Standard_NotImplemented::Raise ();
1109 //=======================================================================
1112 //=======================================================================
1114 Handle(Curve) Geom_SurfaceOfRevolution::UIso (const Standard_Real U) const {
1116 Handle(Curve) C = Handle(Curve)::DownCast(basisCurve->Copy());
1117 Ax1 RotAxis = Ax1 (loc, direction);
1118 C->Rotate (RotAxis, U);
1123 //=======================================================================
1126 //=======================================================================
1128 Handle(Geom_Curve) Geom_SurfaceOfRevolution::VIso (const Standard_Real V) const {
1130 Handle(Geom_Circle) Circ;
1131 Pnt Pc = basisCurve->Value (V);
1132 gp_Lin L1(loc,direction);
1133 Standard_Real Rad= L1.Distance(Pc);
1136 if ( Rad > gp::Resolution()) {
1139 C.SetLinearForm((P-loc.XYZ()).Dot(direction.XYZ()),
1140 direction.XYZ(), loc.XYZ() );
1142 if(P.Modulus() > gp::Resolution()) {
1143 gp_Dir D = P.Normalized();
1144 Rep = gp_Ax2(C, direction, D);
1147 Rep = gp_Ax2(C, direction);
1150 Rep = gp_Ax2(Pc, direction);
1152 Circ = new Geom_Circle (Rep, Rad);
1157 //=======================================================================
1158 //function : Transform
1160 //=======================================================================
1162 void Geom_SurfaceOfRevolution::Transform (const Trsf& T) {
1165 direction.Transform (T);
1166 basisCurve->Transform (T);
1167 if(T.ScaleFactor()*T.HVectorialPart().Determinant() < 0.) UReverse();
1170 //=======================================================================
1171 //function : TransformParameters
1173 //=======================================================================
1175 void Geom_SurfaceOfRevolution::TransformParameters(Standard_Real& ,
1180 V = basisCurve->TransformedParameter(V,T);
1183 //=======================================================================
1184 //function : ParametricTransformation
1186 //=======================================================================
1188 gp_GTrsf2d Geom_SurfaceOfRevolution::ParametricTransformation
1189 (const gp_Trsf& T) const
1192 gp_Ax2d Axis(gp::Origin2d(),gp::DX2d());
1193 T2.SetAffinity(Axis, basisCurve->ParametricTransformation(T));