Part: issue #6488: Cone surface returns wrong dv derivative
This is a workaround to fix a bug in ElSLib::ConeDN
This commit is contained in:
@@ -4246,6 +4246,12 @@ bool GeomSurface::normal(double u, double v, gp_Dir& dir) const
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Vec GeomSurface::getDN(double u, double v, int Nu, int Nv) const
|
||||
{
|
||||
Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle());
|
||||
return s->DN(u, v, Nu, Nv);
|
||||
}
|
||||
|
||||
bool GeomSurface::isUmbillic(double u, double v) const
|
||||
{
|
||||
Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle());
|
||||
@@ -4499,6 +4505,50 @@ PyObject *GeomCone::getPyObject(void)
|
||||
return new ConePy(static_cast<GeomCone*>(this->clone()));
|
||||
}
|
||||
|
||||
gp_Vec GeomCone::getDN(double u, double v, int Nu, int Nv) const
|
||||
{
|
||||
// Copied from ElSLib::ConeDN() and applied the needed fix
|
||||
auto ElSLib__ConeDN = [](const Standard_Real U,
|
||||
const Standard_Real V,
|
||||
const gp_Ax3& Pos,
|
||||
const Standard_Real Radius,
|
||||
const Standard_Real SAngle,
|
||||
const Standard_Integer Nu,
|
||||
const Standard_Integer Nv)
|
||||
{
|
||||
gp_XYZ Xdir = Pos.XDirection().XYZ();
|
||||
gp_XYZ Ydir = Pos.YDirection().XYZ();
|
||||
gp_XYZ ZDir = Pos.Direction ().XYZ();
|
||||
Standard_Real Um = U + Nu * M_PI_2; // M_PI * 0.5
|
||||
Xdir.Multiply(cos(Um));
|
||||
Ydir.Multiply(sin(Um));
|
||||
Xdir.Add(Ydir);
|
||||
if(Nv == 0) {
|
||||
Xdir.Multiply(Radius + V * sin(SAngle));
|
||||
if(Nu == 0) Xdir.Add(Pos.Location().XYZ());
|
||||
return gp_Vec(Xdir);
|
||||
}
|
||||
else if(Nv == 1) {
|
||||
Xdir.Multiply(sin(SAngle));
|
||||
ZDir.Multiply(cos(SAngle));
|
||||
Xdir.Add(ZDir);
|
||||
return gp_Vec(Xdir);
|
||||
}
|
||||
return gp_Vec(0.0,0.0,0.0);
|
||||
};
|
||||
|
||||
// Workaround for cones to get the correct derivatives
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=10&t=66677
|
||||
Handle(Geom_ConicalSurface) s = Handle(Geom_ConicalSurface)::DownCast(handle());
|
||||
Standard_RangeError_Raise_if (Nu + Nv < 1 || Nu < 0 || Nv < 0, " ");
|
||||
if (Nv > 1) {
|
||||
return gp_Vec (0.0, 0.0, 0.0);
|
||||
}
|
||||
else {
|
||||
return ElSLib__ConeDN(u, v, s->Position(), s->RefRadius(), s->SemiAngle(), Nu, Nv);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
TYPESYSTEM_SOURCE(Part::GeomToroid,Part::GeomSurface)
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
|
||||
#include <Mod/Part/PartGlobal.h>
|
||||
#include "GeometryExtension.h"
|
||||
|
||||
namespace Part {
|
||||
@@ -795,6 +796,11 @@ public:
|
||||
bool tangentU(double u, double v, gp_Dir& dirU) const;
|
||||
bool tangentV(double u, double v, gp_Dir& dirV) const;
|
||||
bool normal(double u, double v, gp_Dir& dir) const;
|
||||
/*!
|
||||
Computes the derivative of order Nu in the direction U and Nv
|
||||
in the direction V at the point P(U, V).
|
||||
*/
|
||||
virtual gp_Vec getDN(double u, double v, int Nu, int Nv) const;
|
||||
|
||||
/** @name Curvature information */
|
||||
//@{
|
||||
@@ -892,6 +898,9 @@ public:
|
||||
void setHandle(const Handle(Geom_ConicalSurface)&);
|
||||
const Handle(Geom_Geometry)& handle() const;
|
||||
|
||||
// Overloaded for Geom_ConicalSurface because of an OCC bug
|
||||
virtual gp_Vec getDN(double u, double v, int Nu, int Nv) const;
|
||||
|
||||
private:
|
||||
Handle(Geom_ConicalSurface) mySurface;
|
||||
};
|
||||
|
||||
@@ -226,17 +226,13 @@ PyObject* GeometrySurfacePy::getD0(PyObject *args)
|
||||
|
||||
PyObject* GeometrySurfacePy::getDN(PyObject *args)
|
||||
{
|
||||
Handle(Geom_Geometry) g = getGeometryPtr()->handle();
|
||||
Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(g);
|
||||
try {
|
||||
if (!s.IsNull()) {
|
||||
int nu, nv;
|
||||
double u,v;
|
||||
if (!PyArg_ParseTuple(args, "ddii", &u, &v, &nu, &nv))
|
||||
return nullptr;
|
||||
gp_Vec v1 = s->DN(u, v, nu, nv);
|
||||
return new Base::VectorPy(Base::Vector3d(v1.X(),v1.Y(),v1.Z()));
|
||||
}
|
||||
int nu, nv;
|
||||
double u,v;
|
||||
if (!PyArg_ParseTuple(args, "ddii", &u, &v, &nu, &nv))
|
||||
return nullptr;
|
||||
gp_Vec v1 = getGeomSurfacePtr()->getDN(u, v, nu, nv);
|
||||
return new Base::VectorPy(Base::Vector3d(v1.X(),v1.Y(),v1.Z()));
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
|
||||
|
||||
Reference in New Issue
Block a user