+ fix and improve discretize() method

This commit is contained in:
wmayer 2014-08-13 23:33:27 +02:00
parent d0288deabb
commit 3d2a2b06f0
6 changed files with 350 additions and 89 deletions

View File

@ -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">

View File

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

View File

@ -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">

View File

@ -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>
@ -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);
}
else {
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
return 0;
}
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())));
}
bool uniformAbscissaPoints = false;
bool uniformAbscissaDistance = false;
int numPoints = -1;
double distance = -1;
return Py::new_reference_to(points);
// 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_Exception, "Descretization of curve failed");
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 (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;
}
}
// 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;
}
}
// 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;
}

View File

@ -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">

View File

@ -38,6 +38,8 @@
#include <BRepGProp.hxx>
#include <GProp_GProps.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <GCPnts_UniformDeflection.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <Base/VectorPy.h>
#include <Base/GeometryPyCXX.h>
@ -328,49 +330,122 @@ PyObject* TopoShapeWirePy::approximate(PyObject *args)
}
}
PyObject* TopoShapeWirePy::discretize(PyObject *args)
PyObject* TopoShapeWirePy::discretize(PyObject *args, PyObject *kwds)
{
PyObject* defl_or_num;
if (!PyArg_ParseTuple(args, "O", &defl_or_num))
return 0;
try {
BRepAdaptor_CompCurve adapt(TopoDS::Wire(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);
}
else {
PyErr_SetString(PyExc_TypeError, "Either int or float expected");
return 0;
}
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())));
}
bool uniformAbscissaPoints = false;
bool uniformAbscissaDistance = false;
int numPoints = -1;
double distance = -1;
return Py::new_reference_to(points);
// 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_Exception, "Descretization of wire failed");
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 (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 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;
}