mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0026252: GeomAdaptor_Surface should use inner adaptor to calculate values of complex surfaces
* Implement GeomEvaluator package * Inject evaluators to GeomAdaptor_Surface to calculate values of complex surfaces * Inject evaluators to Geom_Surface classes to calculate values for offset surfaces, surfaces of revolution and surfaces of extrusion * Move Adaptor3d_SurfaceOfLinearExtrusion and Adaptor3d_SurfaceOfRevolution to GeomAdaptor and unify calculation of their values and derivatives * Code optimizations * Update test cases Update of test-cases according to the new behavior
This commit is contained in:
7
src/GeomEvaluator/FILES
Normal file
7
src/GeomEvaluator/FILES
Normal file
@@ -0,0 +1,7 @@
|
||||
GeomEvaluator_OffsetSurface.cxx
|
||||
GeomEvaluator_OffsetSurface.hxx
|
||||
GeomEvaluator_Surface.hxx
|
||||
GeomEvaluator_SurfaceOfExtrusion.cxx
|
||||
GeomEvaluator_SurfaceOfExtrusion.hxx
|
||||
GeomEvaluator_SurfaceOfRevolution.cxx
|
||||
GeomEvaluator_SurfaceOfRevolution.hxx
|
796
src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx
Normal file
796
src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx
Normal file
@@ -0,0 +1,796 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <GeomEvaluator_OffsetSurface.hxx>
|
||||
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <CSLib.hxx>
|
||||
#include <CSLib_NormalStatus.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_UndefinedValue.hxx>
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
|
||||
|
||||
template<class SurfOrAdapt>
|
||||
static void derivatives(Standard_Integer theMaxOrder,
|
||||
Standard_Integer theMinOrder,
|
||||
const Standard_Real theU,
|
||||
const Standard_Real theV,
|
||||
const SurfOrAdapt& theBasisSurf,
|
||||
const Standard_Integer theNU,
|
||||
const Standard_Integer theNV,
|
||||
const Standard_Boolean theAlongU,
|
||||
const Standard_Boolean theAlongV,
|
||||
const Handle(Geom_BSplineSurface)& theL,
|
||||
TColgp_Array2OfVec& theDerNUV,
|
||||
TColgp_Array2OfVec& theDerSurf);
|
||||
|
||||
|
||||
|
||||
GeomEvaluator_OffsetSurface::GeomEvaluator_OffsetSurface(
|
||||
const Handle(Geom_Surface)& theBase,
|
||||
const Standard_Real theOffset,
|
||||
const Handle(Geom_OsculatingSurface)& theOscSurf)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseSurf(theBase),
|
||||
myOffset(theOffset),
|
||||
myOscSurf(theOscSurf)
|
||||
{
|
||||
if (!myOscSurf.IsNull())
|
||||
return; // osculating surface already exists
|
||||
|
||||
// Create osculating surface for B-spline and Besier surfaces only
|
||||
if (myBaseSurf->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) ||
|
||||
myBaseSurf->IsKind(STANDARD_TYPE(Geom_BezierSurface)))
|
||||
myOscSurf = new Geom_OsculatingSurface(myBaseSurf, Precision::Confusion());
|
||||
}
|
||||
|
||||
GeomEvaluator_OffsetSurface::GeomEvaluator_OffsetSurface(
|
||||
const Handle(GeomAdaptor_HSurface)& theBase,
|
||||
const Standard_Real theOffset,
|
||||
const Handle(Geom_OsculatingSurface)& theOscSurf)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseAdaptor(theBase),
|
||||
myOffset(theOffset)
|
||||
{
|
||||
if (theOscSurf.IsNull())
|
||||
return; // osculating surface already exists
|
||||
|
||||
// Create osculating surface for B-spline and Besier surfaces only
|
||||
Handle(Geom_Surface) aBSurf;
|
||||
if (myBaseAdaptor->GetType() == GeomAbs_BSplineSurface)
|
||||
aBSurf = myBaseAdaptor->BSpline();
|
||||
else if (myBaseAdaptor->GetType() == GeomAbs_BezierSurface)
|
||||
aBSurf = myBaseAdaptor->Bezier();
|
||||
if (!aBSurf.IsNull())
|
||||
{
|
||||
myBaseSurf = aBSurf;
|
||||
myOscSurf = new Geom_OsculatingSurface(aBSurf, Precision::Confusion());
|
||||
}
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::D0(
|
||||
const Standard_Real theU, const Standard_Real theV, gp_Pnt& theValue) const
|
||||
{
|
||||
gp_Vec aD1U, aD1V;
|
||||
BaseD1(theU, theV, theValue, aD1U, aD1V);
|
||||
CalculateD0(theU, theV, theValue, aD1U, aD1V);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::D1(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
|
||||
{
|
||||
gp_Vec aD2U, aD2V, aD2UV;
|
||||
BaseD2(theU, theV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV);
|
||||
CalculateD1(theU, theV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::D2(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
|
||||
{
|
||||
gp_Vec aD3U, aD3V, aD3UUV, aD3UVV;
|
||||
BaseD3(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, aD3U, aD3V, aD3UUV, aD3UVV);
|
||||
CalculateD2(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, aD3U, aD3V, aD3UUV, aD3UVV);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::D3(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
|
||||
{
|
||||
BaseD3(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, theD3U, theD3V, theD3UUV, theD3UVV);
|
||||
CalculateD3(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, theD3U, theD3V, theD3UUV, theD3UVV);
|
||||
}
|
||||
|
||||
gp_Vec GeomEvaluator_OffsetSurface::DN(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
const Standard_Integer theDerU, const Standard_Integer theDerV) const
|
||||
{
|
||||
Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_OffsetSurface::DN(): theDerU < 0");
|
||||
Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_OffsetSurface::DN(): theDerV < 0");
|
||||
Standard_RangeError_Raise_if(theDerU + theDerV < 1,
|
||||
"GeomEvaluator_OffsetSurface::DN(): theDerU + theDerV < 1");
|
||||
|
||||
gp_Pnt aP;
|
||||
gp_Vec aD1U, aD1V;
|
||||
BaseD1(theU, theV, aP, aD1U, aD1V);
|
||||
return CalculateDN(theU, theV, theDerU, theDerV, aD1U, aD1V);
|
||||
}
|
||||
|
||||
|
||||
void GeomEvaluator_OffsetSurface::BaseD0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D0(theU, theV, theValue);
|
||||
else
|
||||
myBaseSurf->D0(theU, theV, theValue);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::BaseD1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D1(theU, theV, theValue, theD1U, theD1V);
|
||||
else
|
||||
myBaseSurf->D1(theU, theV, theValue, theD1U, theD1V);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::BaseD2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D2(theU, theV, theValue, theD1U, theD1V, theD2U, theD2V, theD2UV);
|
||||
else
|
||||
myBaseSurf->D2(theU, theV, theValue, theD1U, theD1V, theD2U, theD2V, theD2UV);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::BaseD3(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D3(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, theD3U, theD3V, theD3UUV, theD3UVV);
|
||||
else
|
||||
myBaseSurf->D3(theU, theV, theValue, theD1U, theD1V,
|
||||
theD2U, theD2V, theD2UV, theD3U, theD3V, theD3UUV, theD3UVV);
|
||||
}
|
||||
|
||||
|
||||
void GeomEvaluator_OffsetSurface::CalculateD0(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue,
|
||||
const gp_Vec& theD1U, const gp_Vec& theD1V) const
|
||||
{
|
||||
const Standard_Real MagTol = 1.e-9;
|
||||
|
||||
// Normalize derivatives before normal calculation because it gives more stable result.
|
||||
// There will be normalized only derivatives greater than 1.0 to avoid differences in last significant digit
|
||||
gp_Vec aD1U(theD1U);
|
||||
gp_Vec aD1V(theD1V);
|
||||
Standard_Real aD1UNorm2 = aD1U.SquareMagnitude();
|
||||
Standard_Real aD1VNorm2 = aD1V.SquareMagnitude();
|
||||
if (aD1UNorm2 > 1.0)
|
||||
aD1U /= Sqrt(aD1UNorm2);
|
||||
if (aD1VNorm2 > 1.0)
|
||||
aD1V /= Sqrt(aD1VNorm2);
|
||||
|
||||
gp_Vec aNorm = aD1U.Crossed(aD1V);
|
||||
if (aNorm.SquareMagnitude() > MagTol * MagTol)
|
||||
{
|
||||
// Non singular case. Simple computations.
|
||||
aNorm.Normalize();
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aNorm.XYZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Integer MaxOrder = 3;
|
||||
|
||||
Handle(Geom_BSplineSurface) L;
|
||||
Standard_Boolean isOpposite = Standard_False;
|
||||
Standard_Boolean AlongU = Standard_False;
|
||||
Standard_Boolean AlongV = Standard_False;
|
||||
if (!myOscSurf.IsNull())
|
||||
{
|
||||
AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
|
||||
AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
|
||||
}
|
||||
const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
|
||||
|
||||
TColgp_Array2OfVec DerNUV(0, MaxOrder, 0, MaxOrder);
|
||||
TColgp_Array2OfVec DerSurf(0, MaxOrder + 1, 0, MaxOrder + 1);
|
||||
Standard_Integer OrderU, OrderV;
|
||||
Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0;
|
||||
Bounds(Umin, Umax, Vmin, Vmax);
|
||||
|
||||
DerSurf.SetValue(1, 0, theD1U);
|
||||
DerSurf.SetValue(0, 1, theD1V);
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 1, theU, theV, myBaseSurf, 0, 0, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 1, theU, theV, myBaseAdaptor, 0, 0, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
|
||||
gp_Dir Normal;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax,
|
||||
NStatus, Normal, OrderU, OrderV);
|
||||
if (NStatus == CSLib_InfinityOfSolutions)
|
||||
{
|
||||
// Replace zero derivative and try to calculate normal
|
||||
gp_Vec aNewDU = theD1U;
|
||||
gp_Vec aNewDV = theD1V;
|
||||
if (ReplaceDerivative(theU, theV, aNewDU, aNewDV, MagTol * MagTol))
|
||||
CSLib::Normal(aNewDU, aNewDV, MagTol, NStatus, Normal);
|
||||
}
|
||||
|
||||
if (NStatus != CSLib_Defined)
|
||||
Geom_UndefinedValue::Raise(
|
||||
"GeomEvaluator_OffsetSurface::CalculateD0(): Unable to calculate normal");
|
||||
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ());
|
||||
}
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::CalculateD1(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
const gp_Vec& theD2U, const gp_Vec& theD2V, const gp_Vec& theD2UV) const
|
||||
{
|
||||
const Standard_Real MagTol = 1.e-9;
|
||||
|
||||
// Check offset side.
|
||||
Handle(Geom_BSplineSurface) L;
|
||||
Standard_Boolean isOpposite = Standard_False;
|
||||
Standard_Boolean AlongU = Standard_False;
|
||||
Standard_Boolean AlongV = Standard_False;
|
||||
if (!myOscSurf.IsNull())
|
||||
{
|
||||
AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
|
||||
AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
|
||||
}
|
||||
const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
|
||||
|
||||
// Normalize derivatives before normal calculation because it gives more stable result.
|
||||
// There will be normalized only derivatives greater than 1.0 to avoid differences in last significant digit
|
||||
gp_Vec aD1U(theD1U);
|
||||
gp_Vec aD1V(theD1V);
|
||||
Standard_Real aD1UNorm2 = aD1U.SquareMagnitude();
|
||||
Standard_Real aD1VNorm2 = aD1V.SquareMagnitude();
|
||||
if (aD1UNorm2 > 1.0)
|
||||
aD1U /= Sqrt(aD1UNorm2);
|
||||
if (aD1VNorm2 > 1.0)
|
||||
aD1V /= Sqrt(aD1VNorm2);
|
||||
|
||||
Standard_Integer MaxOrder = 0;
|
||||
gp_Vec aNorm = aD1U.Crossed(aD1V);
|
||||
if (aNorm.SquareMagnitude() > MagTol * MagTol)
|
||||
{
|
||||
if (!AlongV && !AlongU)
|
||||
{
|
||||
// AlongU or AlongV leads to more complex D1 computation
|
||||
// Try to compute D0 and D1 much simpler
|
||||
aNorm.Normalize();
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * aNorm.XYZ());
|
||||
|
||||
gp_Vec aN0(aNorm.XYZ()), aN1U, aN1V;
|
||||
Standard_Real aScale = (theD1U^theD1V).Dot(aN0);
|
||||
aN1U.SetX(theD2U.Y() * theD1V.Z() + theD1U.Y() * theD2UV.Z()
|
||||
- theD2U.Z() * theD1V.Y() - theD1U.Z() * theD2UV.Y());
|
||||
aN1U.SetY((theD2U.X() * theD1V.Z() + theD1U.X() * theD2UV.Z()
|
||||
- theD2U.Z() * theD1V.X() - theD1U.Z() * theD2UV.X()) * -1.0);
|
||||
aN1U.SetZ(theD2U.X() * theD1V.Y() + theD1U.X() * theD2UV.Y()
|
||||
- theD2U.Y() * theD1V.X() - theD1U.Y() * theD2UV.X());
|
||||
Standard_Real aScaleU = aN1U.Dot(aN0);
|
||||
aN1U.Subtract(aScaleU * aN0);
|
||||
aN1U /= aScale;
|
||||
|
||||
aN1V.SetX(theD2UV.Y() * theD1V.Z() + theD2V.Z() * theD1U.Y()
|
||||
- theD2UV.Z() * theD1V.Y() - theD2V.Y() * theD1U.Z());
|
||||
aN1V.SetY((theD2UV.X() * theD1V.Z() + theD2V.Z() * theD1U.X()
|
||||
- theD2UV.Z() * theD1V.X() - theD2V.X() * theD1U.Z()) * -1.0);
|
||||
aN1V.SetZ(theD2UV.X() * theD1V.Y() + theD2V.Y() * theD1U.X()
|
||||
- theD2UV.Y() * theD1V.X() - theD2V.X() * theD1U.Y());
|
||||
Standard_Real aScaleV = aN1V.Dot(aN0);
|
||||
aN1V.Subtract(aScaleV * aN0);
|
||||
aN1V /= aScale;
|
||||
|
||||
theD1U += myOffset * aSign * aN1U;
|
||||
theD1V += myOffset * aSign * aN1V;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
MaxOrder = 3;
|
||||
|
||||
Standard_Integer OrderU, OrderV;
|
||||
TColgp_Array2OfVec DerNUV(0, MaxOrder + 1, 0, MaxOrder + 1);
|
||||
TColgp_Array2OfVec DerSurf(0, MaxOrder + 2, 0, MaxOrder + 2);
|
||||
Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0;
|
||||
Bounds(Umin, Umax, Vmin, Vmax);
|
||||
|
||||
DerSurf.SetValue(1, 0, theD1U);
|
||||
DerSurf.SetValue(0, 1, theD1V);
|
||||
DerSurf.SetValue(1, 1, theD2UV);
|
||||
DerSurf.SetValue(2, 0, theD2U);
|
||||
DerSurf.SetValue(0, 2, theD2V);
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 2, theU, theV, myBaseSurf, 1, 1, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 2, theU, theV, myBaseAdaptor, 1, 1, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
|
||||
gp_Dir Normal;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax, NStatus, Normal, OrderU, OrderV);
|
||||
if (NStatus == CSLib_InfinityOfSolutions)
|
||||
{
|
||||
gp_Vec aNewDU = theD1U;
|
||||
gp_Vec aNewDV = theD1V;
|
||||
// Replace zero derivative and try to calculate normal
|
||||
if (ReplaceDerivative(theU, theV, aNewDU, aNewDV, MagTol * MagTol))
|
||||
{
|
||||
DerSurf.SetValue(1, 0, aNewDU);
|
||||
DerSurf.SetValue(0, 1, aNewDV);
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 2, theU, theV, myBaseSurf, 1, 1, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 2, theU, theV, myBaseAdaptor, 1, 1, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax,
|
||||
NStatus, Normal, OrderU, OrderV);
|
||||
}
|
||||
}
|
||||
|
||||
if (NStatus != CSLib_Defined)
|
||||
Geom_UndefinedValue::Raise(
|
||||
"GeomEvaluator_OffsetSurface::CalculateD1(): Unable to calculate normal");
|
||||
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ());
|
||||
|
||||
theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV);
|
||||
theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::CalculateD2(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
const gp_Vec& theD3U, const gp_Vec& theD3V, const gp_Vec& theD3UUV, const gp_Vec& theD3UVV) const
|
||||
{
|
||||
const Standard_Real MagTol = 1.e-9;
|
||||
|
||||
gp_Dir Normal;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal(theD1U, theD1V, MagTol, NStatus, Normal);
|
||||
|
||||
const Standard_Integer MaxOrder = (NStatus == CSLib_Defined) ? 0 : 3;
|
||||
Standard_Integer OrderU, OrderV;
|
||||
TColgp_Array2OfVec DerNUV(0, MaxOrder + 2, 0, MaxOrder + 2);
|
||||
TColgp_Array2OfVec DerSurf(0, MaxOrder + 3, 0, MaxOrder + 3);
|
||||
|
||||
Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0;
|
||||
Bounds(Umin, Umax, Vmin, Vmax);
|
||||
|
||||
DerSurf.SetValue(1, 0, theD1U);
|
||||
DerSurf.SetValue(0, 1, theD1V);
|
||||
DerSurf.SetValue(1, 1, theD2UV);
|
||||
DerSurf.SetValue(2, 0, theD2U);
|
||||
DerSurf.SetValue(0, 2, theD2V);
|
||||
DerSurf.SetValue(3, 0, theD3U);
|
||||
DerSurf.SetValue(2, 1, theD3UUV);
|
||||
DerSurf.SetValue(1, 2, theD3UVV);
|
||||
DerSurf.SetValue(0, 3, theD3V);
|
||||
//*********************
|
||||
|
||||
Handle(Geom_BSplineSurface) L;
|
||||
Standard_Boolean isOpposite = Standard_False;
|
||||
Standard_Boolean AlongU = Standard_False;
|
||||
Standard_Boolean AlongV = Standard_False;
|
||||
if (!myOscSurf.IsNull())
|
||||
{
|
||||
AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
|
||||
AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
|
||||
}
|
||||
const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
|
||||
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 3, theU, theV, myBaseSurf, 2, 2, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 3, theU, theV, myBaseAdaptor, 2, 2, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax,
|
||||
NStatus, Normal, OrderU, OrderV);
|
||||
if (NStatus != CSLib_Defined)
|
||||
Geom_UndefinedValue::Raise(
|
||||
"GeomEvaluator_OffsetSurface::CalculateD2(): Unable to calculate normal");
|
||||
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ());
|
||||
|
||||
theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV);
|
||||
theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV);
|
||||
|
||||
if (!myBaseSurf.IsNull())
|
||||
{
|
||||
theD2U = myBaseSurf->DN(theU, theV, 2, 0);
|
||||
theD2V = myBaseSurf->DN(theU, theV, 0, 2);
|
||||
theD2UV = myBaseSurf->DN(theU, theV, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
theD2U = myBaseAdaptor->DN(theU, theV, 2, 0);
|
||||
theD2V = myBaseAdaptor->DN(theU, theV, 0, 2);
|
||||
theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1);
|
||||
}
|
||||
|
||||
theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV);
|
||||
theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV);
|
||||
theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV);
|
||||
}
|
||||
|
||||
void GeomEvaluator_OffsetSurface::CalculateD3(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
|
||||
{
|
||||
const Standard_Real MagTol = 1.e-9;
|
||||
|
||||
gp_Dir Normal;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal(theD1U, theD1V, MagTol, NStatus, Normal);
|
||||
const Standard_Integer MaxOrder = (NStatus == CSLib_Defined) ? 0 : 3;
|
||||
Standard_Integer OrderU, OrderV;
|
||||
TColgp_Array2OfVec DerNUV(0, MaxOrder + 3, 0, MaxOrder + 3);
|
||||
TColgp_Array2OfVec DerSurf(0, MaxOrder + 4, 0, MaxOrder + 4);
|
||||
Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0;
|
||||
Bounds(Umin, Umax, Vmin, Vmax);
|
||||
|
||||
DerSurf.SetValue(1, 0, theD1U);
|
||||
DerSurf.SetValue(0, 1, theD1V);
|
||||
DerSurf.SetValue(1, 1, theD2UV);
|
||||
DerSurf.SetValue(2, 0, theD2U);
|
||||
DerSurf.SetValue(0, 2, theD2V);
|
||||
DerSurf.SetValue(3, 0, theD3U);
|
||||
DerSurf.SetValue(2, 1, theD3UUV);
|
||||
DerSurf.SetValue(1, 2, theD3UVV);
|
||||
DerSurf.SetValue(0, 3, theD3V);
|
||||
|
||||
|
||||
//*********************
|
||||
Handle(Geom_BSplineSurface) L;
|
||||
Standard_Boolean isOpposite = Standard_False;
|
||||
Standard_Boolean AlongU = Standard_False;
|
||||
Standard_Boolean AlongV = Standard_False;
|
||||
if (!myOscSurf.IsNull())
|
||||
{
|
||||
AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
|
||||
AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
|
||||
}
|
||||
const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
|
||||
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 3, theU, theV, myBaseSurf, 3, 3, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 3, theU, theV, myBaseAdaptor, 3, 3, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax,
|
||||
NStatus, Normal, OrderU, OrderV);
|
||||
if (NStatus != CSLib_Defined)
|
||||
Geom_UndefinedValue::Raise(
|
||||
"GeomEvaluator_OffsetSurface::CalculateD3(): Unable to calculate normal");
|
||||
|
||||
theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ());
|
||||
|
||||
theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV);
|
||||
theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV);
|
||||
|
||||
if (!myBaseSurf.IsNull())
|
||||
{
|
||||
theD2U = myBaseSurf->DN(theU, theV, 2, 0);
|
||||
theD2V = myBaseSurf->DN(theU, theV, 0, 2);
|
||||
theD2UV = myBaseSurf->DN(theU, theV, 1, 1);
|
||||
theD3U = myBaseSurf->DN(theU, theV, 3, 0);
|
||||
theD3V = myBaseSurf->DN(theU, theV, 0, 3);
|
||||
theD3UUV = myBaseSurf->DN(theU, theV, 2, 1);
|
||||
theD3UVV = myBaseSurf->DN(theU, theV, 1, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
theD2U = myBaseAdaptor->DN(theU, theV, 2, 0);
|
||||
theD2V = myBaseAdaptor->DN(theU, theV, 0, 2);
|
||||
theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1);
|
||||
theD3U = myBaseAdaptor->DN(theU, theV, 3, 0);
|
||||
theD3V = myBaseAdaptor->DN(theU, theV, 0, 3);
|
||||
theD3UUV = myBaseAdaptor->DN(theU, theV, 2, 1);
|
||||
theD3UVV = myBaseAdaptor->DN(theU, theV, 1, 2);
|
||||
}
|
||||
|
||||
theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV);
|
||||
theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV);
|
||||
theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV);
|
||||
theD3U += aSign * myOffset * CSLib::DNNormal(3, 0, DerNUV, OrderU, OrderV);
|
||||
theD3V += aSign * myOffset * CSLib::DNNormal(0, 3, DerNUV, OrderU, OrderV);
|
||||
theD3UUV += aSign * myOffset * CSLib::DNNormal(2, 1, DerNUV, OrderU, OrderV);
|
||||
theD3UVV += aSign * myOffset * CSLib::DNNormal(1, 2, DerNUV, OrderU, OrderV);
|
||||
}
|
||||
|
||||
gp_Vec GeomEvaluator_OffsetSurface::CalculateDN(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
const Standard_Integer theNu, const Standard_Integer theNv,
|
||||
const gp_Vec& theD1U, const gp_Vec& theD1V) const
|
||||
{
|
||||
const Standard_Real MagTol = 1.e-9;
|
||||
|
||||
gp_Dir Normal;
|
||||
CSLib_NormalStatus NStatus;
|
||||
CSLib::Normal(theD1U, theD1V, MagTol, NStatus, Normal);
|
||||
const Standard_Integer MaxOrder = (NStatus == CSLib_Defined) ? 0 : 3;
|
||||
Standard_Integer OrderU, OrderV;
|
||||
TColgp_Array2OfVec DerNUV(0, MaxOrder + theNu, 0, MaxOrder + theNu);
|
||||
TColgp_Array2OfVec DerSurf(0, MaxOrder + theNu + 1, 0, MaxOrder + theNv + 1);
|
||||
|
||||
Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0;
|
||||
Bounds(Umin, Umax, Vmin, Vmax);
|
||||
|
||||
DerSurf.SetValue(1, 0, theD1U);
|
||||
DerSurf.SetValue(0, 1, theD1V);
|
||||
|
||||
//*********************
|
||||
Handle(Geom_BSplineSurface) L;
|
||||
// Is there any osculatingsurface along U or V;
|
||||
Standard_Boolean isOpposite = Standard_False;
|
||||
Standard_Boolean AlongU = Standard_False;
|
||||
Standard_Boolean AlongV = Standard_False;
|
||||
if (!myOscSurf.IsNull())
|
||||
{
|
||||
AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
|
||||
AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
|
||||
}
|
||||
const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
|
||||
|
||||
if (!myBaseSurf.IsNull())
|
||||
derivatives(MaxOrder, 1, theU, theV, myBaseSurf, theNu, theNv, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
else
|
||||
derivatives(MaxOrder, 1, theU, theV, myBaseAdaptor, theNu, theNv, AlongU, AlongV, L, DerNUV, DerSurf);
|
||||
|
||||
CSLib::Normal(MaxOrder, DerNUV, MagTol, theU, theV, Umin, Umax, Vmin, Vmax,
|
||||
NStatus, Normal, OrderU, OrderV);
|
||||
if (NStatus != CSLib_Defined)
|
||||
Geom_UndefinedValue::Raise(
|
||||
"GeomEvaluator_OffsetSurface::CalculateDN(): Unable to calculate normal");
|
||||
|
||||
gp_Vec D;
|
||||
if (!myBaseSurf.IsNull())
|
||||
D = myBaseSurf->DN(theU, theV, theNu, theNv);
|
||||
else
|
||||
D = myBaseAdaptor->DN(theU, theV, theNu, theNv);
|
||||
|
||||
D += aSign * myOffset * CSLib::DNNormal(theNu, theNv, DerNUV, OrderU, OrderV);
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
void GeomEvaluator_OffsetSurface::Bounds(Standard_Real& theUMin, Standard_Real& theUMax,
|
||||
Standard_Real& theVMin, Standard_Real& theVMax) const
|
||||
{
|
||||
if (!myBaseSurf.IsNull())
|
||||
myBaseSurf->Bounds(theUMin, theUMax, theVMin, theVMax);
|
||||
else
|
||||
{
|
||||
theUMin = myBaseAdaptor->FirstUParameter();
|
||||
theUMax = myBaseAdaptor->LastUParameter();
|
||||
theVMin = myBaseAdaptor->FirstVParameter();
|
||||
theVMax = myBaseAdaptor->LastVParameter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Standard_Boolean GeomEvaluator_OffsetSurface::ReplaceDerivative(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Vec& theDU, gp_Vec& theDV,
|
||||
const Standard_Real theSquareTol) const
|
||||
{
|
||||
Standard_Boolean isReplaceDU = theDU.SquareMagnitude() < theSquareTol;
|
||||
Standard_Boolean isReplaceDV = theDV.SquareMagnitude() < theSquareTol;
|
||||
Standard_Boolean isReplaced = Standard_False;
|
||||
if (isReplaceDU ^ isReplaceDV)
|
||||
{
|
||||
Standard_Real aU = theU;
|
||||
Standard_Real aV = theV;
|
||||
Standard_Real aUMin = 0, aUMax = 0, aVMin = 0, aVMax = 0;
|
||||
Bounds(aUMin, aUMax, aVMin, aVMax);
|
||||
|
||||
// Calculate step along non-zero derivative
|
||||
Standard_Real aStep;
|
||||
Handle(Adaptor3d_HSurface) aSurfAdapt;
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
aSurfAdapt = myBaseAdaptor;
|
||||
else
|
||||
aSurfAdapt = new GeomAdaptor_HSurface(myBaseSurf);
|
||||
if (isReplaceDV)
|
||||
{
|
||||
aStep = Precision::Confusion() * theDU.Magnitude();
|
||||
if (aStep > aUMax - aUMin)
|
||||
aStep = (aUMax - aUMin) / 100.;
|
||||
}
|
||||
else
|
||||
{
|
||||
aStep = Precision::Confusion() * theDV.Magnitude();
|
||||
if (aStep > aVMax - aVMin)
|
||||
aStep = (aVMax - aVMin) / 100.;
|
||||
}
|
||||
|
||||
gp_Pnt aP;
|
||||
gp_Vec aDU, aDV;
|
||||
// Step away from currect parametric coordinates and calculate derivatives once again.
|
||||
// Replace zero derivative by the obtained.
|
||||
for (Standard_Real aStepSign = -1.0; aStepSign <= 1.0 && !isReplaced; aStepSign += 2.0)
|
||||
{
|
||||
if (isReplaceDV)
|
||||
{
|
||||
aU = theU + aStepSign * aStep;
|
||||
if (aU < aUMin || aU > aUMax)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
aV = theV + aStepSign * aStep;
|
||||
if (aV < aVMin || aV > aVMax)
|
||||
continue;
|
||||
}
|
||||
|
||||
BaseD1(aU, aV, aP, aDU, aDV);
|
||||
|
||||
if (isReplaceDU && aDU.SquareMagnitude() > theSquareTol)
|
||||
{
|
||||
theDU = aDU;
|
||||
isReplaced = Standard_True;
|
||||
}
|
||||
if (isReplaceDV && aDV.SquareMagnitude() > theSquareTol)
|
||||
{
|
||||
theDV = aDV;
|
||||
isReplaced = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isReplaced;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ===================== Auxiliary functions ===================================
|
||||
template<class SurfOrAdapt>
|
||||
void derivatives(Standard_Integer theMaxOrder,
|
||||
Standard_Integer theMinOrder,
|
||||
const Standard_Real theU,
|
||||
const Standard_Real theV,
|
||||
const SurfOrAdapt& theBasisSurf,
|
||||
const Standard_Integer theNU,
|
||||
const Standard_Integer theNV,
|
||||
const Standard_Boolean theAlongU,
|
||||
const Standard_Boolean theAlongV,
|
||||
const Handle(Geom_BSplineSurface)& theL,
|
||||
TColgp_Array2OfVec& theDerNUV,
|
||||
TColgp_Array2OfVec& theDerSurf)
|
||||
{
|
||||
Standard_Integer i, j;
|
||||
gp_Pnt P;
|
||||
gp_Vec DL1U, DL1V, DL2U, DL2V, DL2UV, DL3U, DL3UUV, DL3UVV, DL3V;
|
||||
|
||||
if (theAlongU || theAlongV)
|
||||
{
|
||||
theMaxOrder = 0;
|
||||
TColgp_Array2OfVec DerSurfL(0, theMaxOrder + theNU + 1, 0, theMaxOrder + theNV + 1);
|
||||
switch (theMinOrder)
|
||||
{
|
||||
case 1:
|
||||
theL->D1(theU, theV, P, DL1U, DL1V);
|
||||
DerSurfL.SetValue(1, 0, DL1U);
|
||||
DerSurfL.SetValue(0, 1, DL1V);
|
||||
break;
|
||||
case 2:
|
||||
theL->D2(theU, theV, P, DL1U, DL1V, DL2U, DL2V, DL2UV);
|
||||
DerSurfL.SetValue(1, 0, DL1U);
|
||||
DerSurfL.SetValue(0, 1, DL1V);
|
||||
DerSurfL.SetValue(1, 1, DL2UV);
|
||||
DerSurfL.SetValue(2, 0, DL2U);
|
||||
DerSurfL.SetValue(0, 2, DL2V);
|
||||
break;
|
||||
case 3:
|
||||
theL->D3(theU, theV, P, DL1U, DL1V, DL2U, DL2V, DL2UV, DL3U, DL3V, DL3UUV, DL3UVV);
|
||||
DerSurfL.SetValue(1, 0, DL1U);
|
||||
DerSurfL.SetValue(0, 1, DL1V);
|
||||
DerSurfL.SetValue(1, 1, DL2UV);
|
||||
DerSurfL.SetValue(2, 0, DL2U);
|
||||
DerSurfL.SetValue(0, 2, DL2V);
|
||||
DerSurfL.SetValue(3, 0, DL3U);
|
||||
DerSurfL.SetValue(2, 1, DL3UUV);
|
||||
DerSurfL.SetValue(1, 2, DL3UVV);
|
||||
DerSurfL.SetValue(0, 3, DL3V);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (theNU <= theNV)
|
||||
{
|
||||
for (i = 0; i <= theMaxOrder + 1 + theNU; i++)
|
||||
for (j = i; j <= theMaxOrder + theNV + 1; j++)
|
||||
if (i + j > theMinOrder)
|
||||
{
|
||||
DerSurfL.SetValue(i, j, theL->DN(theU, theV, i, j));
|
||||
theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j));
|
||||
if (i != j && j <= theNU + 1)
|
||||
{
|
||||
theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i));
|
||||
DerSurfL.SetValue(j, i, theL->DN(theU, theV, j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j <= theMaxOrder + 1 + theNV; j++)
|
||||
for (i = j; i <= theMaxOrder + theNU + 1; i++)
|
||||
if (i + j > theMinOrder)
|
||||
{
|
||||
DerSurfL.SetValue(i, j, theL->DN(theU, theV, i, j));
|
||||
theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j));
|
||||
if (i != j && i <= theNV + 1)
|
||||
{
|
||||
theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i));
|
||||
DerSurfL.SetValue(j, i, theL->DN(theU, theV, j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= theMaxOrder + theNU; i++)
|
||||
for (j = 0; j <= theMaxOrder + theNV; j++)
|
||||
{
|
||||
if (theAlongU)
|
||||
theDerNUV.SetValue(i, j, CSLib::DNNUV(i, j, DerSurfL, theDerSurf));
|
||||
if (theAlongV)
|
||||
theDerNUV.SetValue(i, j, CSLib::DNNUV(i, j, theDerSurf, DerSurfL));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i <= theMaxOrder + theNU+ 1; i++)
|
||||
for (j = i; j <= theMaxOrder + theNV + 1; j++)
|
||||
if (i + j > theMinOrder)
|
||||
{
|
||||
theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j));
|
||||
if (i != j)
|
||||
theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i));
|
||||
}
|
||||
for (i = 0; i <= theMaxOrder + theNU; i++)
|
||||
for (j = 0; j <= theMaxOrder + theNV; j++)
|
||||
theDerNUV.SetValue(i, j, CSLib::DNNUV(i, j, theDerSurf));
|
||||
}
|
||||
}
|
||||
|
131
src/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx
Normal file
131
src/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx
Normal file
@@ -0,0 +1,131 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _GeomEvaluator_OffsetSurface_HeaderFile
|
||||
#define _GeomEvaluator_OffsetSurface_HeaderFile
|
||||
|
||||
#include <GeomEvaluator_Surface.hxx>
|
||||
|
||||
#include <Geom_OsculatingSurface.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
|
||||
class GeomAdaptor_HSurface;
|
||||
|
||||
//! Allows to calculate values and derivatives for offset surfaces
|
||||
class GeomEvaluator_OffsetSurface : public GeomEvaluator_Surface
|
||||
{
|
||||
public:
|
||||
//! Initialize evaluator by surface
|
||||
Standard_EXPORT GeomEvaluator_OffsetSurface(
|
||||
const Handle(Geom_Surface)& theBase,
|
||||
const Standard_Real theOffset,
|
||||
const Handle(Geom_OsculatingSurface)& theOscSurf = Handle(Geom_OsculatingSurface)());
|
||||
//! Initialize evaluator by surface adaptor
|
||||
Standard_EXPORT GeomEvaluator_OffsetSurface(
|
||||
const Handle(GeomAdaptor_HSurface)& theBase,
|
||||
const Standard_Real theOffset,
|
||||
const Handle(Geom_OsculatingSurface)& theOscSurf = Handle(Geom_OsculatingSurface)());
|
||||
|
||||
//! Change the offset value
|
||||
void SetOffsetValue(Standard_Real theOffset)
|
||||
{ myOffset = theOffset; }
|
||||
|
||||
//! Value of surface
|
||||
Standard_EXPORT void D0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const Standard_OVERRIDE;
|
||||
//! Value and first derivatives of surface
|
||||
Standard_EXPORT void D1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const Standard_OVERRIDE;
|
||||
//! Value, first and second derivatives of surface
|
||||
Standard_EXPORT void D2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const Standard_OVERRIDE;
|
||||
//! Value, first, second and third derivatives of surface
|
||||
Standard_EXPORT void D3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V,
|
||||
gp_Vec& theD3UUV, gp_Vec& theD3UVV) const Standard_OVERRIDE;
|
||||
//! Calculates N-th derivatives of surface, where N = theDerU + theDerV.
|
||||
//!
|
||||
//! Raises if N < 1 or theDerU < 0 or theDerV < 0
|
||||
Standard_EXPORT gp_Vec DN(const Standard_Real theU,
|
||||
const Standard_Real theV,
|
||||
const Standard_Integer theDerU,
|
||||
const Standard_Integer theDerV) const Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI(GeomEvaluator_OffsetSurface, GeomEvaluator_Surface)
|
||||
|
||||
private:
|
||||
//! Returns bounds of a base surface
|
||||
void Bounds(Standard_Real& theUMin, Standard_Real& theUMax,
|
||||
Standard_Real& theVMin, Standard_Real& theVMax) const;
|
||||
|
||||
//! Recalculate D1 values of base surface into D0 value of offset surface
|
||||
void CalculateD0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue,
|
||||
const gp_Vec& theD1U, const gp_Vec& theD1V) const;
|
||||
//! Recalculate D2 values of base surface into D1 values of offset surface
|
||||
void CalculateD1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
const gp_Vec& theD2U, const gp_Vec& theD2V, const gp_Vec& theD2UV) const;
|
||||
//! Recalculate D3 values of base surface into D2 values of offset surface
|
||||
void CalculateD2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
const gp_Vec& theD3U, const gp_Vec& theD3V,
|
||||
const gp_Vec& theD3UUV, const gp_Vec& theD3UVV) const;
|
||||
//! Recalculate D3 values of base surface into D3 values of offset surface
|
||||
void CalculateD3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const;
|
||||
//! Calculate DN of offset surface based on derivatives of base surface
|
||||
gp_Vec CalculateDN(const Standard_Real theU, const Standard_Real theV,
|
||||
const Standard_Integer theNu, const Standard_Integer theNv,
|
||||
const gp_Vec& theD1U, const gp_Vec& theD1V) const;
|
||||
|
||||
//! Calculate value of base surface/adaptor
|
||||
void BaseD0(const Standard_Real theU, const Standard_Real theV, gp_Pnt& theValue) const;
|
||||
//! Calculate value and first derivatives of base surface/adaptor
|
||||
void BaseD1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const;
|
||||
//! Calculate value, first and second derivatives of base surface/adaptor
|
||||
void BaseD2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const;
|
||||
//! Calculate value, first, second and third derivatives of base surface/adaptor
|
||||
void BaseD3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const;
|
||||
|
||||
//! Replace zero derivative by the corresponding derivative in a near point.
|
||||
//! Return true, if the derivative was replaced.
|
||||
Standard_Boolean ReplaceDerivative(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Vec& theDU, gp_Vec& theDV,
|
||||
const Standard_Real theSquareTol) const;
|
||||
|
||||
private:
|
||||
Handle(Geom_Surface) myBaseSurf;
|
||||
Handle(GeomAdaptor_HSurface) myBaseAdaptor;
|
||||
|
||||
Standard_Real myOffset; ///< offset value
|
||||
Handle(Geom_OsculatingSurface) myOscSurf; ///< auxiliary osculating surface
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(GeomEvaluator_OffsetSurface, GeomEvaluator_Surface)
|
||||
|
||||
|
||||
#endif // _GeomEvaluator_OffsetSurface_HeaderFile
|
58
src/GeomEvaluator/GeomEvaluator_Surface.hxx
Normal file
58
src/GeomEvaluator/GeomEvaluator_Surface.hxx
Normal file
@@ -0,0 +1,58 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _GeomEvaluator_Surface_HeaderFile
|
||||
#define _GeomEvaluator_Surface_HeaderFile
|
||||
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
class gp_Pnt;
|
||||
class gp_Vec;
|
||||
|
||||
//! Interface for calculation of values and derivatives for different kinds of surfaces.
|
||||
//! Works both with adaptors and surfaces.
|
||||
class GeomEvaluator_Surface : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
GeomEvaluator_Surface() {}
|
||||
|
||||
//! Value of surface
|
||||
virtual void D0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const = 0;
|
||||
//! Value and first derivatives of surface
|
||||
virtual void D1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const = 0;
|
||||
//! Value, first and second derivatives of surface
|
||||
virtual void D2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const = 0;
|
||||
//! Value, first, second and third derivatives of surface
|
||||
virtual void D3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const = 0;
|
||||
//! Calculates N-th derivatives of surface, where N = theDerU + theDerV.
|
||||
//!
|
||||
//! Raises if N < 1 or theDerU < 0 or theDerV < 0
|
||||
virtual gp_Vec DN(const Standard_Real theU, const Standard_Real theV,
|
||||
const Standard_Integer theDerU, const Standard_Integer theDerV) const = 0;
|
||||
|
||||
DEFINE_STANDARD_RTTI(GeomEvaluator_Surface, Standard_Transient)
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(GeomEvaluator_Surface, Standard_Transient)
|
||||
|
||||
|
||||
#endif // _GeomEvaluator_Surface_HeaderFile
|
119
src/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx
Normal file
119
src/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx
Normal file
@@ -0,0 +1,119 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <GeomEvaluator_SurfaceOfExtrusion.hxx>
|
||||
|
||||
#include <GeomAdaptor_HCurve.hxx>
|
||||
|
||||
GeomEvaluator_SurfaceOfExtrusion::GeomEvaluator_SurfaceOfExtrusion(
|
||||
const Handle(Geom_Curve)& theBase, const gp_Dir& theExtrusionDir)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseCurve(theBase),
|
||||
myDirection(theExtrusionDir)
|
||||
{
|
||||
}
|
||||
|
||||
GeomEvaluator_SurfaceOfExtrusion::GeomEvaluator_SurfaceOfExtrusion(
|
||||
const Handle(Adaptor3d_HCurve)& theBase, const gp_Dir& theExtrusionDir)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseAdaptor(theBase),
|
||||
myDirection(theExtrusionDir)
|
||||
{
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfExtrusion::D0(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D0(theU, theValue);
|
||||
else
|
||||
myBaseCurve->D0(theU, theValue);
|
||||
|
||||
Shift(theV, theValue);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfExtrusion::D1(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D1(theU, theValue, theD1U);
|
||||
else
|
||||
myBaseCurve->D1(theU, theValue, theD1U);
|
||||
|
||||
theD1V = myDirection;
|
||||
Shift(theV, theValue);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfExtrusion::D2(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D2(theU, theValue, theD1U, theD2U);
|
||||
else
|
||||
myBaseCurve->D2(theU, theValue, theD1U, theD2U);
|
||||
|
||||
theD1V = myDirection;
|
||||
theD2V.SetCoord(0.0, 0.0, 0.0);
|
||||
theD2UV.SetCoord(0.0, 0.0, 0.0);
|
||||
|
||||
Shift(theV, theValue);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfExtrusion::D3(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D3(theU, theValue, theD1U, theD2U, theD3U);
|
||||
else
|
||||
myBaseCurve->D3(theU, theValue, theD1U, theD2U, theD3U);
|
||||
|
||||
theD1V = myDirection;
|
||||
theD2V.SetCoord(0.0, 0.0, 0.0);
|
||||
theD2UV.SetCoord(0.0, 0.0, 0.0);
|
||||
theD3V.SetCoord(0.0, 0.0, 0.0);
|
||||
theD3UUV.SetCoord(0.0, 0.0, 0.0);
|
||||
theD3UVV.SetCoord(0.0, 0.0, 0.0);
|
||||
|
||||
Shift(theV, theValue);
|
||||
}
|
||||
|
||||
gp_Vec GeomEvaluator_SurfaceOfExtrusion::DN(
|
||||
const Standard_Real theU, const Standard_Real ,
|
||||
const Standard_Integer theDerU, const Standard_Integer theDerV) const
|
||||
{
|
||||
Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfExtrusion::DN(): theDerU < 0");
|
||||
Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfExtrusion::DN(): theDerV < 0");
|
||||
Standard_RangeError_Raise_if(theDerU + theDerV < 1,
|
||||
"GeomEvaluator_SurfaceOfExtrusion::DN(): theDerU + theDerV < 1");
|
||||
|
||||
gp_Vec aResult(0.0, 0.0, 0.0);
|
||||
if (theDerV == 0)
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
aResult = myBaseAdaptor->DN(theU, theDerU);
|
||||
else
|
||||
aResult = myBaseCurve->DN(theU, theDerU);
|
||||
}
|
||||
else if (theDerU == 0 && theDerV == 1)
|
||||
aResult = gp_Vec(myDirection);
|
||||
return aResult;
|
||||
}
|
||||
|
83
src/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx
Normal file
83
src/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx
Normal file
@@ -0,0 +1,83 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _GeomEvaluator_SurfaceOfExtrusion_HeaderFile
|
||||
#define _GeomEvaluator_SurfaceOfExtrusion_HeaderFile
|
||||
|
||||
#include <GeomEvaluator_Surface.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
|
||||
class Adaptor3d_HCurve;
|
||||
|
||||
//! Allows to calculate values and derivatives for surfaces of linear extrusion
|
||||
class GeomEvaluator_SurfaceOfExtrusion : public GeomEvaluator_Surface
|
||||
{
|
||||
public:
|
||||
//! Initialize evaluator by surface
|
||||
Standard_EXPORT GeomEvaluator_SurfaceOfExtrusion(const Handle(Geom_Curve)& theBase,
|
||||
const gp_Dir& theExtrusionDir);
|
||||
//! Initialize evaluator by surface adaptor
|
||||
Standard_EXPORT GeomEvaluator_SurfaceOfExtrusion(const Handle(Adaptor3d_HCurve)& theBase,
|
||||
const gp_Dir& theExtrusionDir);
|
||||
|
||||
///! Changes the direction of extrusion
|
||||
void SetDirection(const gp_Dir& theDirection)
|
||||
{ myDirection = theDirection; }
|
||||
|
||||
//! Value of surface
|
||||
Standard_EXPORT void D0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const Standard_OVERRIDE;
|
||||
//! Value and first derivatives of surface
|
||||
Standard_EXPORT void D1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const Standard_OVERRIDE;
|
||||
//! Value, first and second derivatives of surface
|
||||
Standard_EXPORT void D2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const Standard_OVERRIDE;
|
||||
//! Value, first, second and third derivatives of surface
|
||||
Standard_EXPORT void D3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V,
|
||||
gp_Vec& theD3UUV, gp_Vec& theD3UVV) const Standard_OVERRIDE;
|
||||
//! Calculates N-th derivatives of surface, where N = theDerU + theDerV.
|
||||
//!
|
||||
//! Raises if N < 1 or theDerU < 0 or theDerV < 0
|
||||
Standard_EXPORT gp_Vec DN(const Standard_Real theU,
|
||||
const Standard_Real theV,
|
||||
const Standard_Integer theDerU,
|
||||
const Standard_Integer theDerV) const Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI(GeomEvaluator_SurfaceOfExtrusion, GeomEvaluator_Surface)
|
||||
|
||||
private:
|
||||
//! Shift the point along direction to the given distance (theShift)
|
||||
void Shift(const Standard_Real theShift, gp_Pnt& thePoint) const
|
||||
{
|
||||
thePoint.ChangeCoord() += myDirection.XYZ() * theShift;
|
||||
}
|
||||
|
||||
private:
|
||||
Handle(Geom_Curve) myBaseCurve;
|
||||
Handle(Adaptor3d_HCurve) myBaseAdaptor;
|
||||
|
||||
gp_Dir myDirection;
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(GeomEvaluator_SurfaceOfExtrusion, GeomEvaluator_Surface)
|
||||
|
||||
|
||||
#endif // _GeomEvaluator_SurfaceOfExtrusion_HeaderFile
|
202
src/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx
Normal file
202
src/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx
Normal file
@@ -0,0 +1,202 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <GeomEvaluator_SurfaceOfRevolution.hxx>
|
||||
|
||||
#include <Adaptor3d_HCurve.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
|
||||
GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
|
||||
const Handle(Geom_Curve)& theBase,
|
||||
const gp_Dir& theRevolDir,
|
||||
const gp_Pnt& theRevolLoc)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseCurve(theBase),
|
||||
myRotAxis(theRevolLoc, theRevolDir)
|
||||
{
|
||||
}
|
||||
|
||||
GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution(
|
||||
const Handle(Adaptor3d_HCurve)& theBase,
|
||||
const gp_Dir& theRevolDir,
|
||||
const gp_Pnt& theRevolLoc)
|
||||
: GeomEvaluator_Surface(),
|
||||
myBaseAdaptor(theBase),
|
||||
myRotAxis(theRevolLoc, theRevolDir)
|
||||
{
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfRevolution::D0(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D0(theV, theValue);
|
||||
else
|
||||
myBaseCurve->D0(theV, theValue);
|
||||
|
||||
gp_Trsf aRotation;
|
||||
aRotation.SetRotation(myRotAxis, theU);
|
||||
theValue.Transform(aRotation);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfRevolution::D1(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D1(theV, theValue, theD1V);
|
||||
else
|
||||
myBaseCurve->D1(theV, theValue, theD1V);
|
||||
|
||||
// vector from center of rotation to the point on rotated curve
|
||||
gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
|
||||
theD1U = gp_Vec(myRotAxis.Direction().XYZ().Crossed(aCQ));
|
||||
// If the point is placed on the axis of revolution then derivatives on U are undefined.
|
||||
// Manually set them to zero.
|
||||
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
|
||||
theD1U.SetCoord(0.0, 0.0, 0.0);
|
||||
|
||||
gp_Trsf aRotation;
|
||||
aRotation.SetRotation(myRotAxis, theU);
|
||||
theValue.Transform(aRotation);
|
||||
theD1U.Transform(aRotation);
|
||||
theD1V.Transform(aRotation);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfRevolution::D2(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D2(theV, theValue, theD1V, theD2V);
|
||||
else
|
||||
myBaseCurve->D2(theV, theValue, theD1V, theD2V);
|
||||
|
||||
// vector from center of rotation to the point on rotated curve
|
||||
gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
|
||||
const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
|
||||
theD1U = gp_Vec(aDir.Crossed(aCQ));
|
||||
// If the point is placed on the axis of revolution then derivatives on U are undefined.
|
||||
// Manually set them to zero.
|
||||
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
|
||||
theD1U.SetCoord(0.0, 0.0, 0.0);
|
||||
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
|
||||
theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
|
||||
|
||||
gp_Trsf aRotation;
|
||||
aRotation.SetRotation(myRotAxis, theU);
|
||||
theValue.Transform(aRotation);
|
||||
theD1U.Transform(aRotation);
|
||||
theD1V.Transform(aRotation);
|
||||
theD2U.Transform(aRotation);
|
||||
theD2V.Transform(aRotation);
|
||||
theD2UV.Transform(aRotation);
|
||||
}
|
||||
|
||||
void GeomEvaluator_SurfaceOfRevolution::D3(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V, gp_Vec& theD3UUV, gp_Vec& theD3UVV) const
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D3(theV, theValue, theD1V, theD2V, theD3V);
|
||||
else
|
||||
myBaseCurve->D3(theV, theValue, theD1V, theD2V, theD3V);
|
||||
|
||||
// vector from center of rotation to the point on rotated curve
|
||||
gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ();
|
||||
const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
|
||||
theD1U = gp_Vec(aDir.Crossed(aCQ));
|
||||
// If the point is placed on the axis of revolution then derivatives on U are undefined.
|
||||
// Manually set them to zero.
|
||||
if (theD1U.SquareMagnitude() < Precision::SquareConfusion())
|
||||
theD1U.SetCoord(0.0, 0.0, 0.0);
|
||||
theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ);
|
||||
theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ()));
|
||||
theD3U = -theD1U;
|
||||
theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ());
|
||||
theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ()));
|
||||
|
||||
gp_Trsf aRotation;
|
||||
aRotation.SetRotation(myRotAxis, theU);
|
||||
theValue.Transform(aRotation);
|
||||
theD1U.Transform(aRotation);
|
||||
theD1V.Transform(aRotation);
|
||||
theD2U.Transform(aRotation);
|
||||
theD2V.Transform(aRotation);
|
||||
theD2UV.Transform(aRotation);
|
||||
theD3U.Transform(aRotation);
|
||||
theD3V.Transform(aRotation);
|
||||
theD3UUV.Transform(aRotation);
|
||||
theD3UVV.Transform(aRotation);
|
||||
}
|
||||
|
||||
gp_Vec GeomEvaluator_SurfaceOfRevolution::DN(
|
||||
const Standard_Real theU, const Standard_Real theV,
|
||||
const Standard_Integer theDerU, const Standard_Integer theDerV) const
|
||||
{
|
||||
Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU < 0");
|
||||
Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerV < 0");
|
||||
Standard_RangeError_Raise_if(theDerU + theDerV < 1,
|
||||
"GeomEvaluator_SurfaceOfRevolution::DN(): theDerU + theDerV < 1");
|
||||
|
||||
gp_Trsf aRotation;
|
||||
aRotation.SetRotation(myRotAxis, theU);
|
||||
|
||||
gp_Pnt aP;
|
||||
gp_Vec aDV;
|
||||
gp_Vec aResult;
|
||||
if (theDerU == 0)
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
aResult = myBaseAdaptor->DN(theV, theDerV);
|
||||
else
|
||||
aResult = myBaseCurve->DN(theV, theDerV);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (theDerV == 0)
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
myBaseAdaptor->D0(theV, aP);
|
||||
else
|
||||
myBaseCurve->D0(theV, aP);
|
||||
aDV = gp_Vec(aP.XYZ() - myRotAxis.Location().XYZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!myBaseAdaptor.IsNull())
|
||||
aDV = myBaseAdaptor->DN(theV, theDerV);
|
||||
else
|
||||
aDV = myBaseCurve->DN(theV, theDerV);
|
||||
}
|
||||
|
||||
const gp_XYZ& aDir = myRotAxis.Direction().XYZ();
|
||||
if (theDerU % 4 == 1)
|
||||
aResult = gp_Vec(aDir.Crossed(aDV.XYZ()));
|
||||
else if (theDerU % 4 == 2)
|
||||
aResult = gp_Vec(aDir.Dot(aDV.XYZ()) * aDir - aDV.XYZ());
|
||||
else if (theDerU % 4 == 3)
|
||||
aResult = gp_Vec(aDir.Crossed(aDV.XYZ())) * (-1.0);
|
||||
else
|
||||
aResult = gp_Vec(aDV.XYZ() - aDir.Dot(aDV.XYZ()) * aDir);
|
||||
}
|
||||
|
||||
aResult.Transform(aRotation);
|
||||
return aResult;
|
||||
}
|
||||
|
87
src/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx
Normal file
87
src/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx
Normal file
@@ -0,0 +1,87 @@
|
||||
// Created on: 2015-09-21
|
||||
// Copyright (c) 2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _GeomEvaluator_SurfaceOfRevolution_HeaderFile
|
||||
#define _GeomEvaluator_SurfaceOfRevolution_HeaderFile
|
||||
|
||||
#include <GeomEvaluator_Surface.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Ax1.hxx>
|
||||
|
||||
class Adaptor3d_HCurve;
|
||||
|
||||
//! Allows to calculate values and derivatives for surfaces of revolution
|
||||
class GeomEvaluator_SurfaceOfRevolution : public GeomEvaluator_Surface
|
||||
{
|
||||
public:
|
||||
//! Initialize evaluator by revolved curve, the axis of revolution and the location
|
||||
Standard_EXPORT GeomEvaluator_SurfaceOfRevolution(const Handle(Geom_Curve)& theBase,
|
||||
const gp_Dir& theRevolDir,
|
||||
const gp_Pnt& theRevolLoc);
|
||||
//! Initialize evaluator by adaptor of the revolved curve, the axis of revolution and the location
|
||||
Standard_EXPORT GeomEvaluator_SurfaceOfRevolution(const Handle(Adaptor3d_HCurve)& theBase,
|
||||
const gp_Dir& theRevolDir,
|
||||
const gp_Pnt& theRevolLoc);
|
||||
|
||||
//! Change direction of the axis of revolution
|
||||
void SetDirection(const gp_Dir& theDirection)
|
||||
{ myRotAxis.SetDirection(theDirection); }
|
||||
|
||||
//! Change location of the axis of revolution
|
||||
void SetLocation(const gp_Pnt& theLocation)
|
||||
{ myRotAxis.SetLocation(theLocation); }
|
||||
|
||||
//! Change the axis of revolution
|
||||
void SetAxis(const gp_Ax1& theAxis)
|
||||
{ myRotAxis = theAxis; }
|
||||
|
||||
//! Value of surface
|
||||
Standard_EXPORT void D0(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue) const Standard_OVERRIDE;
|
||||
//! Value and first derivatives of surface
|
||||
Standard_EXPORT void D1(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V) const Standard_OVERRIDE;
|
||||
//! Value, first and second derivatives of surface
|
||||
Standard_EXPORT void D2(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV) const Standard_OVERRIDE;
|
||||
//! Value, first, second and third derivatives of surface
|
||||
Standard_EXPORT void D3(const Standard_Real theU, const Standard_Real theV,
|
||||
gp_Pnt& theValue, gp_Vec& theD1U, gp_Vec& theD1V,
|
||||
gp_Vec& theD2U, gp_Vec& theD2V, gp_Vec& theD2UV,
|
||||
gp_Vec& theD3U, gp_Vec& theD3V,
|
||||
gp_Vec& theD3UUV, gp_Vec& theD3UVV) const Standard_OVERRIDE;
|
||||
//! Calculates N-th derivatives of surface, where N = theDerU + theDerV.
|
||||
//!
|
||||
//! Raises if N < 1 or theDerU < 0 or theDerV < 0
|
||||
Standard_EXPORT gp_Vec DN(const Standard_Real theU,
|
||||
const Standard_Real theV,
|
||||
const Standard_Integer theDerU,
|
||||
const Standard_Integer theDerV) const Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI(GeomEvaluator_SurfaceOfRevolution, GeomEvaluator_Surface)
|
||||
|
||||
private:
|
||||
Handle(Geom_Curve) myBaseCurve;
|
||||
Handle(Adaptor3d_HCurve) myBaseAdaptor;
|
||||
gp_Ax1 myRotAxis;
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(GeomEvaluator_SurfaceOfRevolution, GeomEvaluator_Surface)
|
||||
|
||||
|
||||
#endif // _GeomEvaluator_SurfaceOfRevolution_HeaderFile
|
Reference in New Issue
Block a user