Ticket #6488 - Cone surface returns wrong dv derivative

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
Chris_G
Veteran
Posts: 2596
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Ticket #6488 - Cone surface returns wrong dv derivative

Post by Chris_G »

Hello,
All is said in the title.
Here is a little script that demonstrates the bug.
- pick a face in the 3D view
- copy / paste following script in the python console
- this will show the du and dv derivative vectors of the face, at the picked point

Both vectors should be tangent to the surface at that point.
But, surprisingly, for cones, the dv vector is roughly normal to the surface ???

Code: Select all

s = Gui.Selection.getSelectionEx()[0]
surf = s.SubObjects[0].Surface
pp = s.PickedPoints[0]
u, v = surf.parameter(pp)

pt = surf.getD0(u, v)
du = surf.getDN(u, v, 1, 0)
dv = surf.getDN(u, v, 0, 1)
Part.show(Part.makeLine(pt, pt + du), "du")
Part.show(Part.makeLine(pt, pt + dv), "dv")

My FC info :

Code: Select all

OS: Manjaro Linux (KDE/plasma)
Word size of FreeCAD: 64-bit
Version: 0.20.27770 (Git)
Build type: Release
Branch: master
Hash: 14ff42be1332002fbca7561a203e3104a1fc3a79
Python 3.10.2, Qt 5.15.2, Coin 4.0.1, OCC 7.5.3
Locale: French/France (fr_FR)
Installed mods: 
  * CurvesWB 0.3.0
  * sheetmetal 0.2.49
  * workfeature
  * pivy_trackers
Last edited by Kunda1 on Tue Mar 01, 2022 12:53 pm, edited 1 time in total.
Reason: Added ticket number to thread title
Syres
Veteran
Posts: 2898
Joined: Thu Aug 09, 2018 11:14 am

Re: Cone surface returns wrong dv derivative ?

Post by Syres »

Confirmed

OS: Linux Mint 19.3 (X-Cinnamon/cinnamon)
Word size of FreeCAD: 64-bit
Version: 0.20.27786 (Git)
Build type: Release
Branch: master
Hash: b5965a48691ae45d5dffd1c6631f75245cbb61eb
Python 3.6.9, Qt 5.9.5, Coin 4.0.0a, OCC 7.6.1
Locale: English/UnitedKingdom (en_GB)
Installed mods:
* fasteners 0.3.38
* Silk
* Plot
* CfdOF 1.10.3
* BIM 2021.12.0
* FeedsAndSpeeds 0.3.0
* Curves 0.3.0
* fcgear 1.0.0
* ThreadProfile 1.81.0
* A2plus 0.4.54b
* sheetmetal 0.2.49
marioalexis
Posts: 124
Joined: Wed Jun 19, 2019 7:44 pm

Re: Cone surface returns wrong dv derivative ?

Post by marioalexis »

There is a bug in the Open Cascade function ElSLib::ConeDN.
On the v partial derivative, only the normal component to the cone axis is computed. Should be added the component of the partial derivative along the axis to get the vector tangent to the surface.

Code: Select all

gp_Vec 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(); 
   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));
     return gp_Vec(Xdir);     <- here should be Added Zdir.Multiply(cos(SAngle))
   }
   return gp_Vec(0.0,0.0,0.0);
}
User avatar
Chris_G
Veteran
Posts: 2596
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Cone surface returns wrong dv derivative ?

Post by Chris_G »

Thanks a lot, for the confirmation, and for the fix.
TheMarkster
Veteran
Posts: 5512
Joined: Thu Apr 05, 2018 1:53 am

Re: Cone surface returns wrong dv derivative ?

Post by TheMarkster »

Could this be tested for and fixed here: ?

https://github.com/FreeCAD/FreeCAD/blob ... p.cpp#L227

Code: Select all

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()));
        }
    }
    catch (Standard_Failure& e) {
        PyErr_SetString(PartExceptionOCCError, e.GetMessageString());
        return nullptr;
    }

    PyErr_SetString(PartExceptionOCCError, "Geometry is not a surface");
    return nullptr;
}
User avatar
tanderson69
Veteran
Posts: 1626
Joined: Thu Feb 18, 2010 1:07 am

Re: Cone surface returns wrong dv derivative ?

Post by tanderson69 »

marioalexis wrote: Sun Feb 27, 2022 2:29 pm There is a bug in the Open Cascade function ElSLib::ConeDN.
...
fix
User avatar
Chris_G
Veteran
Posts: 2596
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Cone surface returns wrong dv derivative ?

Post by Chris_G »

Bug report #6488.

Here is a python workaround :

Code: Select all

def getSurfaceDN(surf, u, v, uo, vo):
	if isinstance(surf, Part.Cone):
		eps = 0.1
		ts = Part.RectangularTrimmedSurface(surf, u-eps, u+eps, v-eps, v+eps)
		surf = ts.toBSpline()
	return surf.getDN(u, v, uo, vo)

s = Gui.Selection.getSelectionEx()[0]
surf = s.SubObjects[0].Surface
pp = s.PickedPoints[0]
u, v = surf.parameter(pp)

pt = surf.getD0(u, v)
du = surf.getDN(u, v, 1, 0)
dv = surf.getDN(u, v, 0, 1)
Part.show(Part.makeLine(pt, pt + du), "du")
Part.show(Part.makeLine(pt, pt + dv), "dv")

dv2 = getSurfaceDN(surf, u, v, 0, 1)
Part.show(Part.makeLine(pt, pt + dv2), "dv2")
tanderson69 wrote: Mon Feb 28, 2022 1:01 pm fix
Thanks. Does upstream OCC pick your fixes ?
wmayer
Founder
Posts: 20300
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Ticket #6488 - Cone surface returns wrong dv derivative

Post by wmayer »

Interesting is that only ElSLib::ConeDN is affected while ElSLib::ConeD1 works as expected. This means as a workaround you could use

Code: Select all

du, dv = surf.tangent(u, v)
Anyway, the problem is solved for FreeCAD's Python binding of GeomSurface: git commit 9252f5f9ec
User avatar
Chris_G
Veteran
Posts: 2596
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Ticket #6488 - Cone surface returns wrong dv derivative

Post by Chris_G »

Thanks.
And face.derivative1At(u, v) is also working OK.
User avatar
tanderson69
Veteran
Posts: 1626
Joined: Thu Feb 18, 2010 1:07 am

Re: Cone surface returns wrong dv derivative ?

Post by tanderson69 »

Chris_G wrote: Tue Mar 01, 2022 10:40 am Thanks. Does upstream OCC pick your fixes ?
No. I didn't sign the CLA, so I don't submit any changes. If I find an obvious bug and feel confident in a fix, I make the change and push it to gitlab. For bugs beyond my time/ability, I file a bug report to occt for them to ignore. ;)


wmayer wrote: Tue Mar 01, 2022 2:03 pm Interesting is that only ElSLib::ConeDN is affected while ElSLib::ConeD1 works as expected...
I noticed that also. There is a lot of duplicated code in that file.
Post Reply