Skip to content

Commit

Permalink
+ fix and improve discretize() method
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Aug 13, 2014
1 parent d0288de commit 3d2a2b0
Show file tree
Hide file tree
Showing 6 changed files with 344 additions and 83 deletions.
15 changes: 13 additions & 2 deletions src/Mod/Part/App/GeometryCurvePy.xml
Expand Up @@ -21,9 +21,20 @@
<UserDocu>Return the shape for the geometry.</UserDocu>
</Documentation>
</Methode>
<Methode Name="discretize">
<Methode Name="discretize" Const="true" Keyword="true">
<Documentation>
<UserDocu>Discretizes the curve using a given deflection or number of points and returns a list of points</UserDocu>
<UserDocu>Discretizes the curve and returns a list of points.
The function accepts keywords as argument:
discretize(Number=n) => gives a list of 'n' equidistant points
discretize(Distance=d) => gives a list of equidistant points with distance 'd'
discretize(Deflection=d) => gives a list of points with a maximum deflection 'd' to the curve
discretize(Angular=a,Curvatre=c) => gives a list of points with an angular deflection of 'a'
and a curvature deflection of 'c'

If no keyword is given then it depends on whether the argument is an int or float.
If it's an int then the behaviour is as if using the keyword 'Number', if it's float
then the behaviour is as if using the keyword 'Distance'.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="length">
Expand Down
116 changes: 97 additions & 19 deletions src/Mod/Part/App/GeometryCurvePyImp.cpp
Expand Up @@ -29,6 +29,8 @@
# include <gp_Vec.hxx>
# include <gp_Pln.hxx>
# include <GCPnts_UniformAbscissa.hxx>
# include <GCPnts_UniformDeflection.hxx>
# include <GCPnts_TangentialDeflection.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <Geom2dAPI_InterCurveCurve.hxx>
# include <GeomAPI.hxx>
Expand Down Expand Up @@ -112,30 +114,62 @@ PyObject* GeometryCurvePy::toShape(PyObject *args)
return 0;
}

PyObject* GeometryCurvePy::discretize(PyObject *args)
PyObject* GeometryCurvePy::discretize(PyObject *args, PyObject *kwds)
{
PyObject* defl_or_num;
if (!PyArg_ParseTuple(args, "O", &defl_or_num))
return 0;

try {
Handle_Geom_Geometry g = getGeometryPtr()->handle();
Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g);
if (!c.IsNull()) {
GeomAdaptor_Curve adapt(c);
GCPnts_UniformAbscissa discretizer;
if (PyInt_Check(defl_or_num)) {
int num = PyInt_AsLong(defl_or_num);
discretizer.Initialize (adapt, num);
if (c.IsNull()) {
PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
return 0;
}

GeomAdaptor_Curve adapt(c);
bool uniformAbscissaPoints = false;
bool uniformAbscissaDistance = false;
int numPoints = -1;
double distance = -1;

// use no kwds
PyObject* dist_or_num;
if (PyArg_ParseTuple(args, "O", &dist_or_num)) {
if (PyInt_Check(dist_or_num)) {
numPoints = PyInt_AsLong(dist_or_num);
uniformAbscissaPoints = true;
}
else if (PyFloat_Check(defl_or_num)) {
double defl = PyFloat_AsDouble(defl_or_num);
discretizer.Initialize (adapt, defl);
else if (PyFloat_Check(dist_or_num)) {
distance = PyFloat_AsDouble(dist_or_num);
uniformAbscissaDistance = true;
}
else {
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
return 0;
}
}
else {
// use Number kwds
static char* kwds_numPoints[] = {"Number",NULL};
PyErr_Clear();
if (PyArg_ParseTupleAndKeywords(args, kwds, "i", kwds_numPoints, &numPoints)) {
uniformAbscissaPoints = true;
}
else {
// use Abscissa kwds
static char* kwds_Distance[] = {"Distance",NULL};
PyErr_Clear();
if (PyArg_ParseTupleAndKeywords(args, kwds, "d", kwds_Distance, &distance)) {
uniformAbscissaDistance = true;
}
}
}

if (uniformAbscissaPoints || uniformAbscissaDistance) {
GCPnts_UniformAbscissa discretizer;
if (uniformAbscissaPoints)
discretizer.Initialize (adapt, numPoints);
else
discretizer.Initialize (adapt, distance);

if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
Expand All @@ -147,18 +181,62 @@ PyObject* GeometryCurvePy::discretize(PyObject *args)
return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
PyErr_SetString(PyExc_Exception, "Descretization of wire failed");
return 0;
}
}

// use Deflection kwds
static char* kwds_Deflection[] = {"Deflection",NULL};
PyErr_Clear();
double deflection;
if (PyArg_ParseTupleAndKeywords(args, kwds, "d", kwds_Deflection, &deflection)) {
GCPnts_UniformDeflection discretizer(adapt, deflection);
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = discretizer.Value (i);
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
}

return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of wire failed");
return 0;
}
}

// use TangentialDeflection kwds
static char* kwds_TangentialDeflection[] = {"Angular","Curvature",NULL};
PyErr_Clear();
double angular;
double curvature;
if (PyArg_ParseTupleAndKeywords(args, kwds, "dd", kwds_TangentialDeflection, &angular, &curvature)) {
GCPnts_TangentialDeflection discretizer(adapt, angular, curvature);
if (discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = discretizer.Value (i);
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
}

return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of wire failed");
return 0;
}
}
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PyExc_Exception, e->GetMessageString());
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}

PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
PyErr_SetString(PyExc_Exception,"Wrong arguments");
return 0;
}

Expand Down
15 changes: 13 additions & 2 deletions src/Mod/Part/App/TopoShapeEdgePy.xml
Expand Up @@ -69,9 +69,20 @@
<UserDocu>Set the tolerance for the edge.</UserDocu>
</Documentation>
</Methode>
<Methode Name="discretize" Const="true">
<Methode Name="discretize" Const="true" Keyword="true">
<Documentation>
<UserDocu>Discretizes the edge using a given deflection or number of points and returns a list of points</UserDocu>
<UserDocu>Discretizes the edge and returns a list of points.
The function accepts keywords as argument:
discretize(Number=n) => gives a list of 'n' equidistant points
discretize(Distance=d) => gives a list of equidistant points with distance 'd'
discretize(Deflection=d) => gives a list of points with a maximum deflection 'd' to the edge
discretize(Angular=a,Curvatre=c) => gives a list of points with an angular deflection of 'a'
and a curvature deflection of 'c'

If no keyword is given then it depends on whether the argument is an int or float.
If it's an int then the behaviour is as if using the keyword 'Number', if it's float
then the behaviour is as if using the keyword 'Distance'.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="split">
Expand Down
133 changes: 104 additions & 29 deletions src/Mod/Part/App/TopoShapeEdgePyImp.cpp
Expand Up @@ -58,6 +58,8 @@
#include <GProp_GProps.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <GCPnts_UniformDeflection.hxx>
#include <GCPnts_TangentialDeflection.hxx>

#include <Base/Vector3D.h>
#include <Base/VectorPy.h>
Expand Down Expand Up @@ -387,49 +389,122 @@ PyObject* TopoShapeEdgePy::derivative3At(PyObject *args)
}
}

PyObject* TopoShapeEdgePy::discretize(PyObject *args)
PyObject* TopoShapeEdgePy::discretize(PyObject *args, PyObject *kwds)
{
PyObject* defl_or_num;
if (!PyArg_ParseTuple(args, "O", &defl_or_num))
return 0;

try {
BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->_Shape));
GCPnts_UniformAbscissa discretizer;
if (PyInt_Check(defl_or_num)) {
int num = PyInt_AsLong(defl_or_num);
discretizer.Initialize (adapt, num);
}
else if (PyFloat_Check(defl_or_num)) {
double defl = PyFloat_AsDouble(defl_or_num);
discretizer.Initialize (adapt, defl);
bool uniformAbscissaPoints = false;
bool uniformAbscissaDistance = false;
int numPoints = -1;
double distance = -1;

// use no kwds
PyObject* dist_or_num;
if (PyArg_ParseTuple(args, "O", &dist_or_num)) {
if (PyInt_Check(dist_or_num)) {
numPoints = PyInt_AsLong(dist_or_num);
uniformAbscissaPoints = true;
}
else if (PyFloat_Check(dist_or_num)) {
distance = PyFloat_AsDouble(dist_or_num);
uniformAbscissaDistance = true;
}
else {
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
return 0;
}
}
else {
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
return 0;
// use Number kwds
static char* kwds_numPoints[] = {"Number",NULL};
PyErr_Clear();
if (PyArg_ParseTupleAndKeywords(args, kwds, "i", kwds_numPoints, &numPoints)) {
uniformAbscissaPoints = true;
}
else {
// use Abscissa kwds
static char* kwds_Distance[] = {"Distance",NULL};
PyErr_Clear();
if (PyArg_ParseTupleAndKeywords(args, kwds, "d", kwds_Distance, &distance)) {
uniformAbscissaDistance = true;
}
}
}
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = adapt.Value (discretizer.Parameter (i));
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));

if (uniformAbscissaPoints || uniformAbscissaDistance) {
GCPnts_UniformAbscissa discretizer;
if (uniformAbscissaPoints)
discretizer.Initialize (adapt, numPoints);
else
discretizer.Initialize (adapt, distance);

if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = adapt.Value (discretizer.Parameter (i));
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
}

return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
return 0;
}
}

return Py::new_reference_to(points);
// use Deflection kwds
static char* kwds_Deflection[] = {"Deflection",NULL};
PyErr_Clear();
double deflection;
if (PyArg_ParseTupleAndKeywords(args, kwds, "d", kwds_Deflection, &deflection)) {
GCPnts_UniformDeflection discretizer(adapt, deflection);
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = discretizer.Value (i);
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
}

return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
return 0;
}
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
return 0;

// use TangentialDeflection kwds
static char* kwds_TangentialDeflection[] = {"Angular","Curvature",NULL};
PyErr_Clear();
double angular;
double curvature;
if (PyArg_ParseTupleAndKeywords(args, kwds, "dd", kwds_TangentialDeflection, &angular, &curvature)) {
GCPnts_TangentialDeflection discretizer(adapt, angular, curvature);
if (discretizer.NbPoints () > 0) {
Py::List points;
int nbPoints = discretizer.NbPoints ();
for (int i=1; i<=nbPoints; i++) {
gp_Pnt p = discretizer.Value (i);
points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z())));
}

return Py::new_reference_to(points);
}
else {
PyErr_SetString(PyExc_Exception, "Descretization of curve failed");
return 0;
}
}
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PyExc_Exception, e->GetMessageString());
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}

PyErr_SetString(PyExc_Exception, "Geometry is not a curve");
PyErr_SetString(PyExc_Exception,"Wrong arguments");
return 0;
}

Expand Down
15 changes: 13 additions & 2 deletions src/Mod/Part/App/TopoShapeWirePy.xml
Expand Up @@ -51,9 +51,20 @@ Make a loft defined by a list of profiles along a wire. Transition can be
<UserDocu>Approximate B-Spline-curve from this wire</UserDocu>
</Documentation>
</Methode>
<Methode Name="discretize" Const="true">
<Methode Name="discretize" Const="true" Keyword="true">
<Documentation>
<UserDocu>Discretizes the wire using a given deflection or number of points and returns a list of points</UserDocu>
<UserDocu>Discretizes the wire and returns a list of points.
The function accepts keywords as argument:
discretize(Number=n) => gives a list of 'n' equidistant points
discretize(Distance=d) => gives a list of equidistant points with distance 'd'
discretize(Deflection=d) => gives a list of points with a maximum deflection 'd' to the wire
discretize(Angular=a,Curvatre=c) => gives a list of points with an angular deflection of 'a'
and a curvature deflection of 'c'

If no keyword is given then it depends on whether the argument is an int or float.
If it's an int then the behaviour is as if using the keyword 'Number', if it's float
then the behaviour is as if using the keyword 'Distance'.
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="CenterOfMass" ReadOnly="true">
Expand Down

0 comments on commit 3d2a2b0

Please sign in to comment.