DiscussionsIssue archiveOCCT:Modeling Algorithms

Archived issue #0032863

Cone surface returns wrong v derivative

CommunityOCCT:Modeling Algorithmsclosed4 public notes

Search issues

Description

When using Geom_ConicalSurface::DN to compute the tangents then for "V" the result is always incorrect.
When using Geom_ConicalSurface::D1 instead then it's correct.

The error is caused by the implementation of ElSLib::ConeDN

The error was tested with OCC 7.3.0 but it's still present in current master.

Steps to reproduce

Here is the C++ test code. It was built under Ubuntu with: g++ main.cpp -I/usr/include/opencascade -lTKG3d -lTKernel -lTKGeomBase

#include <Geom_ConicalSurface.hxx>
#include <GC_MakeConicalSurface.hxx>
#include <GeomLProp_SLProps.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <iostream>

gp_Vec DN(Handle(Geom_ConicalSurface) s, double u, double v, int Nu, int Nv)
{
    // 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);
    };

    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);
    }
}

int main()
{
    double u = 5.23290599890759;
    double v = 5.06498283391571;
    GC_MakeConicalSurface gc(gp_Pnt(0,0,0), gp_Pnt(0,0,10), 2, 4);
    Handle(Geom_ConicalSurface) cone = gc.Value();
    gp_Vec du = cone->DN(u, v, 1, 0);
    gp_Vec dv = cone->DN(u, v, 0, 1);
    du.Normalize();
    dv.Normalize();

    std::cout << "\nResult of DN\n";
    std::cout << "(" << du.X() << ", " << du.Y() << ", " << du.Z() << ")\n";
    std::cout << "(" << dv.X() << ", " << dv.Y() << ", " << dv.Z() << ")\n";

    gp_Pnt pnt;
    cone->D1(u, v, pnt, du, dv);
    du.Normalize();
    dv.Normalize();

    std::cout << "\nResult of D1\n";
    std::cout << "(" << du.X() << ", " << du.Y() << ", " << du.Z() << ")\n";
    std::cout << "(" << dv.X() << ", " << dv.Y() << ", " << dv.Z() << ")\n";

    GeomLProp_SLProps prop(cone, u, v, 2, Precision::Confusion());
    if (prop.IsTangentVDefined()) {
        gp_Dir du, dv;
        prop.TangentU(du);
        prop.TangentV(dv);
        std::cout << "\nResult of GeomLProp_SLProps\n";
        std::cout << "(" << du.X() << ", " << du.Y() << ", " << du.Z() << ")\n";
        std::cout << "(" << dv.X() << ", " << dv.Y() << ", " << dv.Z() << ")\n";
    }

    du = DN(cone, u, v, 1, 0);
    dv = DN(cone, u, v, 0, 1);
    du.Normalize();
    dv.Normalize();

    std::cout << "\nResult of fixed ElSLib::ConeDN\n";
    std::cout << "(" << du.X() << ", " << du.Y() << ", " << du.Z() << ")\n";
    std::cout << "(" << dv.X() << ", " << dv.Y() << ", " << dv.Z() << ")\n";
}

Additional information

The error was reported in the FreeCAD forum: https://forum.freecadweb.org/viewtopic.php?f=10&t=66677

Public activity

4 archived notes

Participants are labeled by their role within this record.

01Commenter 1
Branch [archived branch] has been created by Participant.

[revision removed]


Detailed log of new commits:

Author: azv
Date: Thu Mar 24 22:21:06 2022 +0300

    0032863: Cone surface returns wrong v derivative
    
    * Fix error on computing V first derivative on a cone (take into account the slope of the conical generatrix).
    * Add DRAW command 'sderivative' to compute certain derivative on a surface.
02Commenter 2
Dear Mikhail,

Could you review the solution?

The following branches to be integrated:
OCCT: CR32863
Products: NOT
Test results: http://jenkins-test-occt/view/CR32863-master-AZV/view/COMPARE/
03Commenter 3
Combination -
OCCT branch : [archived branch]
master SHA - [revision removed]
[revision removed]
Products branch : [archived branch] SHA - [revision removed]
was compiled on Linux, MacOS and Windows platforms and tested in optimize mode.

Number of compiler warnings:
No new/fixed warnings

Regressions/Differences/Improvements:
No regressions/differences

CPU differences:
Debian80-64:
OCCT
Total CPU difference: 18507.51000000038 / 18488.570000000385 [+0.10%]
Products
Total CPU difference: 11703.320000000122 / 11709.530000000132 [-0.05%]
Windows-64-VC14:
OCCT
Total CPU difference: 20451.96875 / 20413.53125 [+0.19%]
Products
Total CPU difference: 13191.96875 / 13181.65625 [+0.08%]


Image differences :
No differences that require special attention

Memory differences :
No differences that require special attention
04Commenter 1
Branch [archived branch] has been deleted by Participant.

[revision removed]