From b02705d79f2e1adc7773f0c845e0acc5ae8fde4b Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 27 May 2022 14:44:35 +0200 Subject: [PATCH] Part: apply OCC's fix for ElSLib::ConeDN and write a unit test --- src/Mod/Part/App/Geometry.cpp | 10 +++++++--- src/Mod/Part/TestPartApp.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index ae5ca04031..9158d69e84 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -4591,6 +4591,10 @@ PyObject *GeomCone::getPyObject(void) gp_Vec GeomCone::getDN(double u, double v, int Nu, int Nv) const { + // Will be fixed in OCC 7.7 +#if OCC_VERSION_HEX >= 0x070700 + return GeomSurface::getDN(u, v, Nu, Nv); +#else // Copied from ElSLib::ConeDN() and applied the needed fix auto ElSLib__ConeDN = [](const Standard_Real U, const Standard_Real V, @@ -4602,7 +4606,6 @@ gp_Vec GeomCone::getDN(double u, double v, int Nu, int Nv) const { 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)); @@ -4614,8 +4617,8 @@ gp_Vec GeomCone::getDN(double u, double v, int Nu, int Nv) const } else if(Nv == 1) { Xdir.Multiply(sin(SAngle)); - ZDir.Multiply(cos(SAngle)); - Xdir.Add(ZDir); + if (Nu == 0) + Xdir.Add(Pos.Direction().XYZ() * cos(SAngle)); return gp_Vec(Xdir); } return gp_Vec(0.0,0.0,0.0); @@ -4631,6 +4634,7 @@ gp_Vec GeomCone::getDN(double u, double v, int Nu, int Nv) const else { return ElSLib__ConeDN(u, v, s->Position(), s->RefRadius(), s->SemiAngle(), Nu, Nv); } +#endif } // ------------------------------------------------- diff --git a/src/Mod/Part/TestPartApp.py b/src/Mod/Part/TestPartApp.py index 2002d4b944..2777fffeea 100644 --- a/src/Mod/Part/TestPartApp.py +++ b/src/Mod/Part/TestPartApp.py @@ -20,7 +20,8 @@ #************************************************************************** import FreeCAD, unittest, Part -import copy +import copy +import math from FreeCAD import Units from FreeCAD import Base App = FreeCAD @@ -201,3 +202,31 @@ class PartTestCircle2D(unittest.TestCase): p3 = App.Base.Vector2d(0.04, 0.0399) with self.assertRaises(ValueError): Part.Geom2d.Circle2d.getCircleCenter(p1, p2, p3) + +class PartTestCone(unittest.TestCase): + def testderivatives(self): + def get_dn(surface, u, v): + pos = surface.value(u, v) + v10 = surface.getDN(u, v, 1, 0) + v01 = surface.getDN(u, v, 0, 1) + v11 = surface.getDN(u, v, 1, 1) + return (pos, v10, v01, v11) + + cone = Part.Cone() + cone.SemiAngle = 0.2 + cone.Radius = 2.0 + + u, v = (5.0, 5.0) + vp, v1, v2, v3 = get_dn(cone, u, v) + + shape = cone.toShape(0, 2*math.pi, 0, 10) + shape = shape.toNurbs() + spline = shape.Face1.Surface + + u, v = spline.parameter(vp) + wp, w1, w2, w3 = get_dn(spline, u, v) + + self.assertAlmostEqual(vp.distanceToPoint(wp), 0) + self.assertAlmostEqual(v1.getAngle(w1), 0) + self.assertAlmostEqual(v2.getAngle(w2), 0) + self.assertAlmostEqual(v3.getAngle(w3), 0)