Archived issue #0032863
Cone surface returns wrong v derivative
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.
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";
}
#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.
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.
[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.
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/
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/
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
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
Branch [archived branch] has been deleted by Participant.
[revision removed]
[revision removed]