1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00
occt/src/Geom/Geom_SurfaceOfRevolution.cxx
2012-03-05 19:23:40 +04:00

1163 lines
37 KiB
C++
Executable File

// File: Geom_SurfaceOfRevolution.cxx
// Created: Wed Mar 10 10:51:26 1993
// Author: JCV
// <fid@phylox>
// Copyright: Matra Datavision 1993
//File Geom_SurfaceOfRevolution.cxx, JCV 4/03/91
#include <Geom_SurfaceOfRevolution.ixx>
#include <BSplSLib.hxx>
#include <BSplCLib.hxx>
#include <Geom_Circle.hxx>
#include <gp.hxx>
#include <gp_Ax2d.hxx>
#include <gp_XYZ.hxx>
#include <gp_Lin.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_RangeError.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Precision.hxx>
#define POLES (poles->Array2())
#define WEIGHTS (weights->Array2())
#define UKNOTS (uknots->Array1())
#define VKNOTS (vknots->Array1())
#define UFKNOTS (ufknots->Array1())
#define VFKNOTS (vfknots->Array1())
#define FMULTS (BSplCLib::NoMults())
typedef Geom_SurfaceOfRevolution SurfaceOfRevolution;
typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
typedef Handle(Geom_Geometry) Handle(Geometry);
typedef Geom_Curve Curve;
typedef Handle(Geom_Curve) Handle(Curve);
typedef gp_Ax1 Ax1;
typedef gp_Ax2 Ax2;
typedef gp_Dir Dir;
typedef gp_Lin Lin;
typedef gp_Pnt Pnt;
typedef gp_Trsf Trsf;
typedef gp_Vec Vec;
typedef gp_XYZ XYZ;
//=======================================================================
//function : LocateSide
//purpose : This method locates U parameter on basis BSpline curve
// and calls LocalDi methods corresponding an order of
// derivative and position of the surface side contained
// the point relatively the curve knots.
//=======================================================================
static void LocateSide(const Standard_Real U,
const Standard_Integer Side,
const Handle(Geom_BSplineCurve)& BSplC,
const Standard_Integer NDir,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D2U,
gp_Vec& D3U)
{
Standard_Integer Ideb, Ifin;
Standard_Real ParTol=Precision::PConfusion()/2;
BSplC->Geom_BSplineCurve::LocateU(U,ParTol,Ideb,Ifin,Standard_False);
if(Side == 1)
{
if(Ideb<1) Ideb=1;
if ((Ideb>=Ifin)) Ifin = Ideb+1;
}else
if(Side ==-1)
{
if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
if ((Ideb>=Ifin)) Ideb = Ifin-1;
}
switch(NDir) {
case 0 : BSplC->Geom_BSplineCurve::LocalD0(U,Ideb,Ifin,P); break;
case 1 : BSplC->Geom_BSplineCurve::LocalD1(U,Ideb,Ifin,P,D1U); break;
case 2 : BSplC->Geom_BSplineCurve::LocalD2(U,Ideb,Ifin,P,D1U,D2U); break;
case 3 : BSplC->Geom_BSplineCurve::LocalD3(U,Ideb,Ifin,P,D1U,D2U,D3U); break;
}
}
//=======================================================================
//function : LocateSideN
//purpose : This method locates U parameter on basis BSpline curve
// and calls LocalDN method corresponding position of surface side
// contained the point relatively the curve knots.
//=======================================================================
static gp_Vec LocateSideN(const Standard_Real V,
const Standard_Integer Side,
const Handle(Geom_BSplineCurve)& BSplC,
const Standard_Integer Nv )
{
Standard_Integer Ideb, Ifin;
Standard_Real ParTol=Precision::PConfusion()/2;
BSplC->Geom_BSplineCurve::LocateU(V,ParTol,Ideb,Ifin,Standard_False);
if(Side == 1)
{
if(Ideb<1) Ideb=1;
if ((Ideb>=Ifin)) Ifin = Ideb+1;
}else
if(Side ==-1)
{
if(Ifin > BSplC -> NbKnots()) Ifin=BSplC->NbKnots();
if ((Ideb>=Ifin)) Ideb = Ifin-1;
}
return BSplC->Geom_BSplineCurve::LocalDN(V,Ideb,Ifin,Nv);
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
Handle(Geom_Geometry) Geom_SurfaceOfRevolution::Copy () const {
return new Geom_SurfaceOfRevolution (basisCurve, Axis());
}
//=======================================================================
//function : Geom_SurfaceOfRevolution
//purpose :
//=======================================================================
Geom_SurfaceOfRevolution::Geom_SurfaceOfRevolution
(const Handle(Curve)& C ,
const Ax1& A1 ) : loc (A1.Location()) {
basisCurve = Handle(Curve)::DownCast(C->Copy());
direction = A1.Direction();
smooth = C->Continuity();
}
//=======================================================================
//function : UReverse
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::UReverse () {
direction.Reverse();
}
//=======================================================================
//function : UReversedParameter
//purpose :
//=======================================================================
Standard_Real Geom_SurfaceOfRevolution::UReversedParameter (const Standard_Real U) const {
return ( 2.*PI - U);
}
//=======================================================================
//function : VReverse
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::VReverse () {
basisCurve->Reverse();
}
//=======================================================================
//function : VReversedParameter
//purpose :
//=======================================================================
Standard_Real Geom_SurfaceOfRevolution::VReversedParameter (const Standard_Real V) const {
return basisCurve->ReversedParameter(V);
}
//=======================================================================
//function : Location
//purpose :
//=======================================================================
const gp_Pnt& Geom_SurfaceOfRevolution::Location () const {
return loc;
}
//=======================================================================
//function : IsUPeriodic
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsUPeriodic () const {
return Standard_True;
}
//=======================================================================
//function : IsCNu
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsCNu (const Standard_Integer ) const {
return Standard_True;
}
//=======================================================================
//function : Axis
//purpose :
//=======================================================================
Ax1 Geom_SurfaceOfRevolution::Axis () const {
return Ax1 (loc, direction);
}
//=======================================================================
//function : IsCNv
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsCNv (const Standard_Integer N) const {
Standard_RangeError_Raise_if (N < 0, " ");
return basisCurve->IsCN(N);
}
//=======================================================================
//function : IsUClosed
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsUClosed () const {
return Standard_True;
}
//=======================================================================
//function : IsVClosed
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsVClosed () const
{
return basisCurve->IsClosed();
}
//=======================================================================
//function : IsVPeriodic
//purpose :
//=======================================================================
Standard_Boolean Geom_SurfaceOfRevolution::IsVPeriodic () const {
return basisCurve->IsPeriodic();
}
//=======================================================================
//function : SetAxis
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::SetAxis (const Ax1& A1) {
direction = A1.Direction();
loc = A1.Location();
}
//=======================================================================
//function : SetDirection
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::SetDirection (const Dir& V) {
direction = V;
}
//=======================================================================
//function : SetBasisCurve
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::SetBasisCurve (const Handle(Curve)& C) {
basisCurve = Handle(Curve)::DownCast(C->Copy());
smooth = C->Continuity();
}
//=======================================================================
//function : SetLocation
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::SetLocation (const Pnt& P) {
loc = P;
}
//=======================================================================
//function : Bounds
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::Bounds ( Standard_Real& U1,
Standard_Real& U2,
Standard_Real& V1,
Standard_Real& V2 ) const {
U1 = 0.0;
U2 = 2.0 * PI;
V1 = basisCurve->FirstParameter();
V2 = basisCurve->LastParameter();
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::D0
(const Standard_Real U, const Standard_Real V, Pnt& P) const {
// C origine sur l'axe de revolution
// Vdir vecteur unitaire definissant la direction de l'axe de revolution
// Q(v) point de parametre V sur la courbe de revolution
// OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^CQ)* Sin(U)
Pnt Pc = basisCurve->Value (V); //Q(v)
XYZ Q = Pc.XYZ(); //Q
XYZ C = loc.XYZ(); //C
Q.Subtract(C); //CQ
XYZ Vdir = direction.XYZ(); //Vdir
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
XYZ VdotCQ =
Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
VdotCQ.Add (VcrossCQ); //addition des composantes
Q.Multiply (Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ(Q);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::D1
(const Standard_Real U, const Standard_Real V,
Pnt& P,
Vec& D1U, Vec& D1V ) const {
// C origine sur l'axe de revolution
// Vdir vecteur unitaire definissant la direction de l'axe de revolution
// Q(v) point de parametre V sur la courbe de revolution
// Q'(v) = DQ/DV
// OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^CQ) * Sin(U)
// D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
// (Vdir^CQ) * Cos(U)
// D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^Q') * Sin(U)
Pnt Pc;
Vec V1;
basisCurve->D1 (V, Pc, V1);
XYZ Q = Pc.XYZ(); //Q
XYZ DQv = V1.XYZ(); //Q'
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
VcrossDQv.Multiply (Sin(U));
VdotDQv.Multiply (1.0 - Cos(U));
VdotDQv.Add (VcrossDQv);
DQv.Multiply (Cos(U));
DQv.Add (VdotDQv);
D1V.SetXYZ (DQv);
XYZ DQu = Q.Multiplied (-Sin(U));
DQu.Add (VcrossCQ.Multiplied (Cos(U)));
DQu.Add (VdotCQ.Multiplied (Sin(U)));
D1U.SetXYZ (DQu);
Q.Multiply (Cos(U));
Q.Add (C);
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
P.SetXYZ (Q);
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::D2
(const Standard_Real U, const Standard_Real V,
Pnt& P,
Vec& D1U, Vec& D1V,
Vec& D2U, Vec& D2V, Vec& D2UV ) const {
// C origine sur l'axe de revolution
// V vecteur unitaire definissant la direction de l'axe de revolution
// Q(v) point de parametre V sur la courbe de revolution
// Q'(v) = D1Q/DV
// Q"(v) = D2Q/DV
// OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^CQ) * Sin(U)
// D1U_M(u,v) = - CQ * Sin(U) + (CQ.Vdir)(Sin(U)) * Vdir +
// (Vdir^CQ) * Cos(U)
// D1V_M(u,v) = Q' * Cos(U) + (Q'.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^Q') * Sin(U)
// D2U_M(u,v) = -CQ * Cos(U) + (CQ.Vdir)(Cos(U)) * Vdir +
// (Vdir^CQ) * -(Sin(U))
// D2V_M(u,v) = Q" * Cos(U) + (Q".Vdir)(1-Cos(U)) * Vdir +
// (Vdir^Q") * Sin(U)
// D2UV_M(u,v)= -Q' * Sin(U) + (Q'.Vdir)(Sin(U)) * Vdir +
// (Vdir^Q') * Cos(U)
Pnt Pc;
Vec V1 , V2;
basisCurve->D2 (V, Pc, V1, V2);
XYZ Q = Pc.XYZ(); //Q
XYZ D1Qv = V1.XYZ(); //Q'
XYZ D2Qv = V2.XYZ(); //Q"
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
D2UV.SetXYZ (D2Quv);
D1Qv.Multiply (Cos(U));
VcrossD1Qv.Multiply (Sin(U));
VdotD1Qv.Multiply (1.0 - Cos(U));
D1Qv.Add (VcrossD1Qv);
D1Qv.Add (VdotD1Qv);
D1V.SetXYZ (D1Qv);
VcrossD2Qv.Multiply (Sin(U));
VdotD2Qv.Multiply (1.0 - Cos(U));
VdotD2Qv.Add (VcrossD2Qv);
D2Qv.Multiply (Cos(U));
D2Qv.Add (VdotD2Qv);
D2V.SetXYZ (D2Qv);
XYZ D1Qu = Q.Multiplied (-Sin(U));
D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
D1U.SetXYZ (D1Qu);
Q.Multiply (Cos(U));
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
XYZ D2Qu = Q.Multiplied(-1.0);
D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
D2U.SetXYZ (D2Qu);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ (Q);
}
//=======================================================================
//function : D3
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::D3
(const Standard_Real U, const Standard_Real V,
Pnt& P,
Vec& D1U, Vec& D1V,
Vec& D2U, Vec& D2V, Vec& D2UV,
Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV ) const {
// C origine sur l'axe de revolution
// Vdir vecteur unitaire definissant la direction de l'axe de revolution
// Q(v) point de parametre V sur la courbe de revolution
// Q'(v) = D1Q/DV
// Q"(v) = D2Q/DV
// OM (u,v) = OC + CQ * Cos(u) + (CQ.Vdir)(1-Cos(u)) * Vdir +
// (Vdir^CQ) * Sin(u)
// D1U_M(u,v) = - CQ * Sin(u) + (CQ.Vdir)(Sin(u)) * Vdir +
// (Vdir^CQ) * Cos(u)
// D2U_M(u,v) = -CQ * Cos(u) + (CQ.Vdir)(Cos(u)) * Vdir +
// (Vdir^CQ) * -Sin(u)
// D2UV_M(u,v)= -Q' * Sin(u) + (Q'.Vdir)(Sin(u)) * Vdir +
// (Vdir^Q') * Cos(u)
// D3UUV_M(u,v) = -Q' * Cos(u) + (Q'.Vdir)(Cos(u)) * Vdir +
// (Vdir^Q') * -Sin(u)
// D3U_M(u,v) = CQ * Sin(u) + (CQ.Vdir)(-Sin(u)) * Vdir +
// (Vdir^CQ) * -Cos(u)
// D1V_M(u,v) = Q' * Cos(u) + (Q'.Vdir)(1-Cos(u)) * Vdir +
// (Vdir^Q') * Sin(u)
// D2V_M(u,v) = Q" * Cos(u) + (Q".Vdir)(1-Cos(u)) * Vdir +
// (Vdir^Q") * Sin(u)
// D3UVV_M(u,v) = -Q" * Sin(u) + (Q".Vdir)(Sin(u)) * Vdir +
// (Vdir^Q") * Cos(u)
// D3V_M(u,v) = Q'''* Cos(u) + (Q'''.Vdir)(1-Cos(u)) * Vdir +
// (Vdir^Q''') * Sin(u)
Pnt Pc;
Vec V1 , V2, V3;
basisCurve->D3 (V, Pc, V1, V2, V3);
XYZ Q = Pc.XYZ(); //Q
XYZ D1Qv = V1.XYZ(); //Q'
XYZ D2Qv = V2.XYZ(); //Q"
XYZ D3Qv = V3.XYZ(); //Q'''
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
D3UUV.SetXYZ (D3Quuv);
XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
D2UV.SetXYZ (D2Quv);
D1Qv.Multiply (Cos(U));
VcrossD1Qv.Multiply (Sin(U));
VdotD1Qv.Multiply (1.0 - Cos(U));
D1Qv.Add (VcrossD1Qv);
D1Qv.Add (VdotD1Qv);
D1V.SetXYZ (D1Qv);
XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
D3UVV.SetXYZ (D3Qvvu);
VcrossD2Qv.Multiply (Sin(U));
VdotD2Qv.Multiply (1.0 - Cos(U));
VdotD2Qv.Add (VcrossD2Qv);
D2Qv.Multiply (Cos(U));
D2Qv.Add (VdotD2Qv);
D2V.SetXYZ (D2Qv);
VcrossD3Qv.Multiply (Sin(U));
VdotD3Qv.Multiply (1.0 - Cos(U));
VdotD3Qv.Add (VcrossD2Qv);
D3Qv.Multiply (Cos(U));
D3Qv.Add (VdotD3Qv);
D3V.SetXYZ (D3Qv);
XYZ D1Qu = Q.Multiplied (- Sin(U));
D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
XYZ D3Qu = D1Qu.Multiplied (-1.0);
D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
D1U.SetXYZ (D1Qu);
D3U.SetXYZ (D3Qu);
Q.Multiply (Cos(U));
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
XYZ D2Qu = Q.Multiplied(-1.0);
D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
D2U.SetXYZ (D2Qu);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ (Q);
}
//=======================================================================
//function : DN
//purpose :
//=======================================================================
Vec Geom_SurfaceOfRevolution::DN (const Standard_Real U , const Standard_Real V,
const Standard_Integer Nu, const Standard_Integer Nv) const {
Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
if (Nu == 0) {
XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
VDot.Multiply (1-Cos(U));
XYZ VCross = Vdir.Crossed (Vn);
VCross.Multiply (Sin(U));
Vn.Multiply (Cos(U));
Vn.Add (VDot);
Vn.Add (VCross);
return Vec (Vn);
}
else if (Nv == 0) {
XYZ CQ = (basisCurve->Value (V)).XYZ() - loc.XYZ();
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
XYZ VCross = Vdir.Crossed (CQ);
if ((Nu + 6) % 4 == 0) {
CQ.Multiply (-Cos (U));
VDot.Multiply (Cos(U));
VCross.Multiply (-Sin(U));
}
else if ((Nu + 5) % 4 == 0) {
CQ.Multiply (Sin (U));
VDot.Multiply (-Sin(U));
VCross.Multiply (-Cos(U));
}
else if ((Nu+3) % 4 == 0) {
CQ.Multiply (-Sin (U));
VDot.Multiply (+Sin(U));
VCross.Multiply (Cos(U));
}
else if (Nu+4 % 4 == 0) {
CQ.Multiply (Cos (U));
VDot.Multiply (-Cos(U));
VCross.Multiply (Sin(U));
}
CQ.Add (VDot);
CQ.Add (VCross);
return Vec (CQ);
}
else {
XYZ Vn = (basisCurve->DN (V, Nv)).XYZ();
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
XYZ VCross = Vdir.Crossed (Vn);
if ((Nu + 6) % 4 == 0) {
Vn.Multiply (-Cos (U));
VDot.Multiply (Cos(U));
VCross.Multiply (-Sin(U));
}
else if ((Nu + 5) % 4 == 0) {
Vn.Multiply (Sin (U));
VDot.Multiply (-Sin(U));
VCross.Multiply (-Cos(U));
}
else if ((Nu+3) % 4 == 0) {
Vn.Multiply (-Sin (U));
VDot.Multiply (+Sin(U));
VCross.Multiply (Cos(U));
}
else if (Nu+4 % 4 == 0) {
Vn.Multiply (Cos (U));
VDot.Multiply (-Cos(U));
VCross.Multiply (Sin(U));
}
Vn.Add (VDot);
Vn.Add (VCross);
return Vec (Vn);
}
}
//=======================================================================
//function : LocalD0
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::LocalD0 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer VSide,
gp_Pnt& P ) const
{
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
gp_Vec D1V,D2V,D3V;
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
LocateSide(V,VSide,BSplC,0,P,D1V,D2V,D3V);
XYZ Q = P.XYZ(); //Q
XYZ C = loc.XYZ(); //C
Q.Subtract(C); //CQ
XYZ Vdir = direction.XYZ(); //Vdir
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
VcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
XYZ VdotCQ =
Vdir.Multiplied ((Vdir.Dot(Q))*(1.0 - Cos(U)));//(CQ.Vdir)(1-Cos(U))Vdir
VdotCQ.Add (VcrossCQ); //addition des composantes
Q.Multiply (Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ(Q);
}
else D0(U,V,P);
}
//=======================================================================
//function : LocalD1
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::LocalD1 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer VSide,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
Vec D2V,D3V;
Vec V1;
LocateSide(V,VSide,BSplC,1,P,V1,D2V,D3V);
XYZ Q = P.XYZ(); //Q
XYZ DQv = V1.XYZ(); //Q'
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossDQv = Vdir.Crossed (DQv); //(Vdir^Q')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotDQv = Vdir.Multiplied (Vdir.Dot(DQv)); //(Vdir.Q')Vdir
VcrossDQv.Multiply (Sin(U));
VdotDQv.Multiply (1.0 - Cos(U));
VdotDQv.Add (VcrossDQv);
DQv.Multiply (Cos(U));
DQv.Add (VdotDQv);
D1V.SetXYZ (DQv);
XYZ DQu = Q.Multiplied (-Sin(U));
DQu.Add (VcrossCQ.Multiplied (Cos(U)));
DQu.Add (VdotCQ.Multiplied (Sin(U)));
D1U.SetXYZ (DQu);
Q.Multiply (Cos(U));
Q.Add (C);
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
P.SetXYZ (Q);
}else
D1(U,V,P,D1U,D1V);
}
//=======================================================================
//function : LocalD2
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::LocalD2 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer VSide,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
{
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
Vec d3v;
LocateSide(V,VSide,BSplC,2,P,D1V,D2V,d3v);
XYZ Q = P.XYZ(); //Q
XYZ D1Qv = D1V.XYZ(); //Q'
XYZ D2Qv = D2V.XYZ(); //Q"
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
XYZ D2Quv = D1Qv.Multiplied(-Sin(U));
D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
D2UV.SetXYZ (D2Quv);
D1Qv.Multiply (Cos(U));
VcrossD1Qv.Multiply (Sin(U));
VdotD1Qv.Multiply (1.0 - Cos(U));
D1Qv.Add (VcrossD1Qv);
D1Qv.Add (VdotD1Qv);
D1V.SetXYZ (D1Qv);
VcrossD2Qv.Multiply (Sin(U));
VdotD2Qv.Multiply (1.0 - Cos(U));
VdotD2Qv.Add (VcrossD2Qv);
D2Qv.Multiply (Cos(U));
D2Qv.Add (VdotD2Qv);
D2V.SetXYZ (D2Qv);
XYZ D1Qu = Q.Multiplied (-Sin(U));
D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
D1U.SetXYZ (D1Qu);
Q.Multiply (Cos(U));
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
XYZ D2Qu = Q.Multiplied(-1.0);
D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
D2U.SetXYZ (D2Qu);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ (Q);
}
else
D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
}
//=======================================================================
//function : LocalD3
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::LocalD3 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer VSide,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV,
gp_Vec& D3U,
gp_Vec& D3V,
gp_Vec& D3UUV,
gp_Vec& D3UVV) const
{
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
LocateSide(V,VSide,BSplC,3,P,D1V,D2V,D3V);
XYZ Q = P.XYZ(); //Q
XYZ D1Qv = D1V.XYZ(); //Q'
XYZ D2Qv = D2V.XYZ(); //Q"
XYZ D3Qv = D3V.XYZ(); //Q'''
XYZ C = loc.XYZ(); //C
XYZ Vdir = direction.XYZ(); //Vdir
Q.Subtract(C); //CQ
XYZ VcrossCQ = Vdir.Crossed (Q); //Vdir^CQ
XYZ VcrossD1Qv = Vdir.Crossed (D1Qv); //(Vdir^Q')
XYZ VcrossD2Qv = Vdir.Crossed (D2Qv); //(Vdir^Q")
XYZ VcrossD3Qv = Vdir.Crossed (D3Qv); //(Vdir^Q''')
XYZ VdotCQ = Vdir.Multiplied (Vdir.Dot(Q)); //(Vdir.CQ)Vdir
XYZ VdotD1Qv = Vdir.Multiplied (Vdir.Dot(D1Qv)); //(Vdir.Q')Vdir
XYZ VdotD2Qv = Vdir.Multiplied (Vdir.Dot(D2Qv)); //(Vdir.Q")Vdir
XYZ VdotD3Qv = Vdir.Multiplied (Vdir.Dot(D3Qv)); //(Vdir.Q''')Vdir
XYZ D3Quuv = D1Qv.Multiplied (-Cos(U));
D3Quuv.Add (VcrossD1Qv.Multiplied (-Sin(U)));
D3Quuv.Add (VdotD1Qv.Multiplied (Cos(U)));
D3UUV.SetXYZ (D3Quuv);
XYZ D2Quv = D1Qv.Multiplied (-Sin(U));
D2Quv.Add (VcrossD1Qv.Multiplied (Cos(U)));
D2Quv.Add (VdotD1Qv.Multiplied (Sin(U)));
D2UV.SetXYZ (D2Quv);
D1Qv.Multiply (Cos(U));
VcrossD1Qv.Multiply (Sin(U));
VdotD1Qv.Multiply (1.0 - Cos(U));
D1Qv.Add (VcrossD1Qv);
D1Qv.Add (VdotD1Qv);
D1V.SetXYZ (D1Qv);
XYZ D3Qvvu = D2Qv.Multiplied (-Sin(U));
D3Qvvu.Add (VcrossD2Qv.Multiplied (Cos(U)));
D3Qvvu.Add (VdotD2Qv.Multiplied (Sin(U)));
D3UVV.SetXYZ (D3Qvvu);
VcrossD2Qv.Multiply (Sin(U));
VdotD2Qv.Multiply (1.0 - Cos(U));
VdotD2Qv.Add (VcrossD2Qv);
D2Qv.Multiply (Cos(U));
D2Qv.Add (VdotD2Qv);
D2V.SetXYZ (D2Qv);
VcrossD3Qv.Multiply (Sin(U));
VdotD3Qv.Multiply (1.0 - Cos(U));
VdotD3Qv.Add (VcrossD2Qv);
D3Qv.Multiply (Cos(U));
D3Qv.Add (VdotD3Qv);
D3V.SetXYZ (D3Qv);
XYZ D1Qu = Q.Multiplied (- Sin(U));
D1Qu.Add (VcrossCQ.Multiplied (Cos(U)));
XYZ D3Qu = D1Qu.Multiplied (-1.0);
D1Qu.Add (VdotCQ.Multiplied (Sin(U)));
D3Qu.Add (VdotCQ.Multiplied (-Sin(U)));
D1U.SetXYZ (D1Qu);
D3U.SetXYZ (D3Qu);
Q.Multiply (Cos(U));
VcrossCQ.Multiply (Sin(U));
Q.Add (VcrossCQ);
XYZ D2Qu = Q.Multiplied(-1.0);
D2Qu.Add (VdotCQ.Multiplied (Cos(U)));
D2U.SetXYZ (D2Qu);
VdotCQ.Multiply (1.0-Cos(U));
Q.Add (VdotCQ);
Q.Add (C);
P.SetXYZ (Q);
}
else
D3(U,V,P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
}
//=======================================================================
//function : LocalDN
//purpose :
//=======================================================================
gp_Vec Geom_SurfaceOfRevolution::LocalDN (const Standard_Real U,
const Standard_Real V,
const Standard_Integer VSide,
const Standard_Integer Nu,
const Standard_Integer Nv) const
{
Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
XYZ Vn, CQ;
if (Nu == 0) {
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
}else
return DN(U,V,Nu,Nv);
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
VDot.Multiply (1-Cos(U));
XYZ VCross = Vdir.Crossed (Vn);
VCross.Multiply (Sin(U));
Vn.Multiply (Cos(U));
Vn.Add (VDot);
Vn.Add (VCross);
return Vec (Vn);
}
else if (Nv == 0) {
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
CQ = LocateSideN(V,VSide,BSplC,Nv).XYZ() - loc.XYZ();
}else
return DN(U,V,Nu,Nv);
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (CQ.Dot (Vdir));
XYZ VCross = Vdir.Crossed (CQ);
if ((Nu + 6) % 4 == 0) {
CQ.Multiply (-Cos (U));
VDot.Multiply (Cos(U));
VCross.Multiply (-Sin(U));
}
else if ((Nu + 5) % 4 == 0) {
CQ.Multiply (Sin (U));
VDot.Multiply (-Sin(U));
VCross.Multiply (-Cos(U));
}
else if ((Nu+3) % 4 == 0) {
CQ.Multiply (-Sin (U));
VDot.Multiply (+Sin(U));
VCross.Multiply (Cos(U));
}
else if (Nu+4 % 4 == 0) {
CQ.Multiply (Cos (U));
VDot.Multiply (-Cos(U));
VCross.Multiply (Sin(U));
}
CQ.Add (VDot);
CQ.Add (VCross);
return Vec (CQ);
}
else {
if((VSide !=0 ) && basisCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle( Geom_BSplineCurve) BSplC;
BSplC= Handle(Geom_BSplineCurve)::DownCast(basisCurve);
Vn = LocateSideN(V,VSide,BSplC,Nv).XYZ();
}else
return DN(U,V,Nu,Nv);
XYZ Vdir = direction.XYZ();
XYZ VDot = Vdir.Multiplied (Vn.Dot (Vdir));
XYZ VCross = Vdir.Crossed (Vn);
if ((Nu + 6) % 4 == 0) {
Vn.Multiply (-Cos (U));
VDot.Multiply (Cos(U));
VCross.Multiply (-Sin(U));
}
else if ((Nu + 5) % 4 == 0) {
Vn.Multiply (Sin (U));
VDot.Multiply (-Sin(U));
VCross.Multiply (-Cos(U));
}
else if ((Nu+3) % 4 == 0) {
Vn.Multiply (-Sin (U));
VDot.Multiply (+Sin(U));
VCross.Multiply (Cos(U));
}
else if (Nu+4 % 4 == 0) {
Vn.Multiply (Cos (U));
VDot.Multiply (-Cos(U));
VCross.Multiply (Sin(U));
}
Vn.Add (VDot);
Vn.Add (VCross);
return Vec (Vn);
}
}
//=======================================================================
//function : ReferencePlane
//purpose :
//=======================================================================
Ax2 Geom_SurfaceOfRevolution::ReferencePlane() const {
Standard_NotImplemented::Raise ();
return gp_Ax2();
}
//=======================================================================
//function : UIso
//purpose :
//=======================================================================
Handle(Curve) Geom_SurfaceOfRevolution::UIso (const Standard_Real U) const {
Handle(Curve) C = Handle(Curve)::DownCast(basisCurve->Copy());
Ax1 RotAxis = Ax1 (loc, direction);
C->Rotate (RotAxis, U);
return C;
}
//=======================================================================
//function : VIso
//purpose :
//=======================================================================
Handle(Geom_Curve) Geom_SurfaceOfRevolution::VIso (const Standard_Real V) const {
Handle(Geom_Circle) Circ;
Pnt Pc = basisCurve->Value (V);
gp_Lin L1(loc,direction);
Standard_Real Rad= L1.Distance(Pc);
Ax2 Rep ;
if ( Rad > gp::Resolution()) {
XYZ P = Pc.XYZ();
XYZ C;
C.SetLinearForm((P-loc.XYZ()).Dot(direction.XYZ()),
direction.XYZ(), loc.XYZ() );
P = P-C;
if(P.Modulus() > gp::Resolution()) {
gp_Dir D = P.Normalized();
Rep = gp_Ax2(C, direction, D);
}
else
Rep = gp_Ax2(C, direction);
}
else
Rep = gp_Ax2(Pc, direction);
Circ = new Geom_Circle (Rep, Rad);
return Circ;
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::Transform (const Trsf& T) {
loc.Transform (T);
direction.Transform (T);
basisCurve->Transform (T);
if(T.ScaleFactor()*T.HVectorialPart().Determinant() < 0.) UReverse();
}
//=======================================================================
//function : TransformParameters
//purpose :
//=======================================================================
void Geom_SurfaceOfRevolution::TransformParameters(Standard_Real& ,
Standard_Real& V,
const gp_Trsf& T)
const
{
V = basisCurve->TransformedParameter(V,T);
}
//=======================================================================
//function : ParametricTransformation
//purpose :
//=======================================================================
gp_GTrsf2d Geom_SurfaceOfRevolution::ParametricTransformation
(const gp_Trsf& T) const
{
gp_GTrsf2d T2;
gp_Ax2d Axis(gp::Origin2d(),gp::DX2d());
T2.SetAffinity(Axis, basisCurve->ParametricTransformation(T));
return T2;
}