Part: Extension of Geometry::Curve

Part: Extension of Geometry::Curve to wrap more functions of OCC

Apart from:
    bool tangent(double u, gp_Dir&) const;
that was already implemented, now it also implements:
    Base::Vector3d pointAtParameter(double u) const;
    Base::Vector3d firstDerivativeAtParameter(double u) const;
    Base::Vector3d secondDerivativeAtParameter(double u) const;
    bool normal(double u, gp_Dir& dir) const;
    bool closestParameter(Base::Vector3d point, double &u);

i.e. apart from giving the tangent vector for a given curve at parameter value u,
it also gives:
   - The point cartesian coordinates of the curve point at parameter value u
   - The vector of the first derivative at parameter value u
   - The vector of the second derivative at parameter value u
   - The normal vector to the curve at parameter value u
   - The parameter value of a curve closest ot a given point

Code cleanup: Changing Trim functionality of Ellipse to use OCC calculations

Part Curve functions extension: closestParameterToBasicCurve

It provides the parameter of the curve closest to a given point. If the curve is a Trimmed curve, the parameter of the basic underlaying curve closest to the point is provided.
This commit is contained in:
Abdullah Tahiri 2014-11-27 16:15:14 +01:00 committed by wmayer
parent a8dd528c1a
commit ec03fb541f
3 changed files with 107 additions and 12 deletions

View File

@ -87,6 +87,7 @@
# include <GC_MakeLine.hxx>
# include <GC_MakeSegment.hxx>
# include <Precision.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
#endif
@ -320,6 +321,97 @@ bool GeomCurve::tangent(double u, gp_Dir& dir) const
return false;
}
Base::Vector3d GeomCurve::pointAtParameter(double u) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
GeomLProp_CLProps prop(c,u,0,Precision::Confusion());
const gp_Pnt &point=prop.Value();
return Base::Vector3d(point.X(),point.Y(),point.Z());
}
Base::Vector3d GeomCurve::firstDerivativeAtParameter(double u) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
GeomLProp_CLProps prop(c,u,1,Precision::Confusion());
const gp_Vec &vec=prop.D1();
return Base::Vector3d(vec.X(),vec.Y(),vec.Z());
}
Base::Vector3d GeomCurve::secondDerivativeAtParameter(double u) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
GeomLProp_CLProps prop(c,u,2,Precision::Confusion());
const gp_Vec &vec=prop.D2();
return Base::Vector3d(vec.X(),vec.Y(),vec.Z());
}
bool GeomCurve::normal(double u, gp_Dir& dir) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
GeomLProp_CLProps prop(c,u,1,Precision::Confusion());
if (prop.IsTangentDefined()) {
prop.Normal(dir);
return true;
}
return false;
}
bool GeomCurve::closestParameter(Base::Vector3d point, double &u) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
try {
if (!c.IsNull()) {
gp_Pnt pnt(point.x,point.y,point.z);
GeomAPI_ProjectPointOnCurve ppc(pnt, c);
u = ppc.LowerDistanceParameter();
return true;
}
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
std::cout << e->GetMessageString() << std::endl;
return false;
}
return false;
}
bool GeomCurve::closestParameterToBasicCurve(Base::Vector3d point, double &u) const
{
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(handle());
if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))){
Handle_Geom_TrimmedCurve tc = Handle_Geom_TrimmedCurve::DownCast(handle());
Handle_Geom_Curve bc = Handle_Geom_Curve::DownCast(tc->BasisCurve());
try {
if (!bc.IsNull()) {
gp_Pnt pnt(point.x,point.y,point.z);
GeomAPI_ProjectPointOnCurve ppc(pnt, bc);
u = ppc.LowerDistanceParameter();
return true;
}
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
std::cout << e->GetMessageString() << std::endl;
return false;
}
return false;
}
else {
return this->closestParameter(point, u);
}
}
// -------------------------------------------------

View File

@ -115,6 +115,12 @@ public:
TopoDS_Shape toShape() const;
bool tangent(double u, gp_Dir&) const;
Base::Vector3d pointAtParameter(double u) const;
Base::Vector3d firstDerivativeAtParameter(double u) const;
Base::Vector3d secondDerivativeAtParameter(double u) const;
bool normal(double u, gp_Dir& dir) const;
bool closestParameter(Base::Vector3d point, double &u) const;
bool closestParameterToBasicCurve(Base::Vector3d point, double &u) const;
};
class PartExport GeomBezierCurve : public GeomCurve

View File

@ -969,19 +969,16 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse*>(geo);
Base::Vector3d center = ellipse->getCenter();
double theta0 = Base::fmod(
atan2(-ellipse->getMajorRadius()*((point.x-center.x)*sin(ellipse->getAngleXU())-(point.y-center.y)*cos(ellipse->getAngleXU())),
ellipse->getMinorRadius()*((point.x-center.x)*cos(ellipse->getAngleXU())+(point.y-center.y)*sin(ellipse->getAngleXU()))
), 2.f*M_PI);
double theta0;
ellipse->closestParameter(point,theta0);
theta0 = Base::fmod(theta0, 2.f*M_PI);
if (GeoId1 >= 0 && GeoId2 >= 0) {
double theta1 = Base::fmod(
atan2(-ellipse->getMajorRadius()*((point1.x-center.x)*sin(ellipse->getAngleXU())-(point1.y-center.y)*cos(ellipse->getAngleXU())),
ellipse->getMinorRadius()*((point1.x-center.x)*cos(ellipse->getAngleXU())+(point1.y-center.y)*sin(ellipse->getAngleXU()))
), 2.f*M_PI);
double theta2 = Base::fmod(
atan2(-ellipse->getMajorRadius()*((point2.x-center.x)*sin(ellipse->getAngleXU())-(point2.y-center.y)*cos(ellipse->getAngleXU())),
ellipse->getMinorRadius()*((point2.x-center.x)*cos(ellipse->getAngleXU())+(point2.y-center.y)*sin(ellipse->getAngleXU()))
), 2.f*M_PI);
double theta1;
ellipse->closestParameter(point1,theta1);
theta1 = Base::fmod(theta1, 2.f*M_PI);
double theta2;
ellipse->closestParameter(point2,theta2);
theta2 = Base::fmod(theta2, 2.f*M_PI);
if (Base::fmod(theta1 - theta0, 2.f*M_PI) > Base::fmod(theta2 - theta0, 2.f*M_PI)) {
std::swap(GeoId1,GeoId2);
std::swap(point1,point2);