Files
test/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp

382 lines
13 KiB
C++
Raw Normal View History

2013-02-23 18:32:28 +00:00
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
* \ingroup freestyle
*/
#include "BPy_StrokeVertex.h"
#include "../../BPy_Freestyle.h"
#include "../../BPy_Convert.h"
#include "../../BPy_StrokeAttribute.h"
#include "../../Interface0D/BPy_SVertex.h"
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////////////////////////////////
//------------------------INSTANCE METHODS ----------------------------------
2013-02-14 23:50:30 +00:00
PyDoc_STRVAR(StrokeVertex_doc,
"Class hierarchy: :class:`Interface0D` > :class:`CurvePoint` > :class:`StrokeVertex`\n"
"\n"
"Class to define a stroke vertex.\n"
"\n"
".. method:: __init__()\n"
"\n"
" Default constructor.\n"
"\n"
".. method:: __init__(brother)\n"
"\n"
" Copy constructor.\n"
"\n"
" :arg brother: A StrokeVertex object.\n"
" :type brother: :class:`StrokeVertex`\n"
"\n"
".. method:: __init__(first_vertex, second_vertex, t3d)\n"
"\n"
" Build a stroke vertex from 2 stroke vertices and an interpolation\n"
" parameter.\n"
"\n"
" :arg first_vertex: The first StrokeVertex.\n"
" :type first_vertex: :class:`StrokeVertex`\n"
" :arg second_vertex: The second StrokeVertex.\n"
" :type second_vertex: :class:`StrokeVertex`\n"
" :arg t3d: An interpolation parameter.\n"
" :type t3d: float\n"
"\n"
".. method:: __init__(point)\n"
"\n"
" Build a stroke vertex from a CurvePoint\n"
"\n"
" :arg point: A CurvePoint object.\n"
" :type point: :class:`CurvePoint`\n"
"\n"
".. method:: __init__(svertex)\n"
"\n"
" Build a stroke vertex from a SVertex\n"
"\n"
" :arg svertex: An SVertex object.\n"
" :type svertex: :class:`SVertex`\n"
"\n"
".. method:: __init__(svertex, attribute)\n"
"\n"
" Build a stroke vertex from an SVertex and a StrokeAttribute object.\n"
"\n"
" :arg svertex: An SVertex object.\n"
" :type svertex: :class:`SVertex`\n"
" :arg attribute: A StrokeAttribute object.\n"
" :type attribute: :class:`StrokeAttribute`");
2013-02-14 23:50:30 +00:00
static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *kwds)
{
static const char *kwlist_1[] = {"brother", NULL};
static const char *kwlist_2[] = {"first_vertex", "second_vertex", "t3d", NULL};
static const char *kwlist_3[] = {"point", NULL};
static const char *kwlist_4[] = {"svertex", "attribute", NULL};
PyObject *obj1 = 0, *obj2 = 0;
float t3d;
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &StrokeVertex_Type, &obj1)) {
if (!obj1) {
self->sv = new StrokeVertex();
}
else {
if (!((BPy_StrokeVertex *)obj1)->sv) {
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
return -1;
}
self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv));
}
}
else if (PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", (char **)kwlist_2,
&StrokeVertex_Type, &obj1, &StrokeVertex_Type, &obj2, &t3d))
{
StrokeVertex *sv1 = ((BPy_StrokeVertex *)obj1)->sv;
StrokeVertex *sv2 = ((BPy_StrokeVertex *)obj2)->sv;
2013-02-14 23:50:30 +00:00
if (!sv1 || (sv1->A() == 0 && sv1->B() == 0)) {
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
return -1;
}
2013-02-14 23:50:30 +00:00
if (!sv2 || (sv2->A() == 0 && sv2->B() == 0)) {
PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid StrokeVertex object");
return -1;
}
self->sv = new StrokeVertex(sv1, sv2, t3d);
}
else if (PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1))
{
CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp;
if (!cp || cp->A() == 0 || cp->B() == 0) {
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object");
return -1;
}
self->sv = new StrokeVertex(cp);
}
else if (PyErr_Clear(), (obj2 = 0),
PyArg_ParseTupleAndKeywords(args, kwds, "O!|O!", (char **)kwlist_4,
&SVertex_Type, &obj1, &StrokeAttribute_Type, &obj2))
{
if (!obj2)
self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv);
else
self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv, *(((BPy_StrokeAttribute *)obj2)->sa));
}
else {
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
return -1;
}
self->py_cp.cp = self->sv;
self->py_cp.py_if0D.if0D = self->sv;
SWIG/directors dependency removal (cont'd) * Added to python/BPy_Convert.{cpp,h} 4 utility converters below for better introspection-based automatic type conversion. PyObject * Any_BPy_Interface0D_from_Interface0D( Interface0D& if0D ); PyObject * Any_BPy_Interface1D_from_Interface1D( Interface1D& if1D ); PyObject * Any_BPy_FEdge_from_FEdge( FEdge& fe ); PyObject * Any_BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ); There are 4 corresponding converters without the "Any_" prefix. All calls of them in the code base were replaced with these new converters so that the introspection-based automatic conversion would take place universally. * python/BPy_Convert.{cpp,h}: Those C++ to Python converters having had a "_ptr" suffix were renamed to a name without the suffix, and their arguments were changed so as to take a reference (e.g., ViewVertex&) instead of a pointer (e.g., ViewVertex *). The changed converters and their new function prototypes are listed below. These converters now return a Python wrapper object that retains the passed reference, instead of retaining a newly created C++ object by the converters. // Interface0D converters PyObject * BPy_Interface0D_from_Interface0D( Interface0D& if0D ); PyObject * BPy_CurvePoint_from_CurvePoint( CurvePoint& cp ); PyObject * BPy_StrokeVertex_from_StrokeVertex( StrokeVertex& sv ); PyObject * BPy_SVertex_from_SVertex( SVertex& sv ); PyObject * BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ); PyObject * BPy_TVertex_from_TVertex( TVertex& tv ); PyObject * BPy_NonTVertex_from_NonTVertex( NonTVertex& ntv ); // Interface1D converters PyObject * BPy_Interface1D_from_Interface1D( Interface1D& if1D ); PyObject * BPy_Chain_from_Chain( Chain& c ); PyObject * BPy_FEdge_from_FEdge( FEdge& fe ); PyObject * BPy_FEdgeSharp_from_FEdgeSharp( FEdgeSharp& fes ); PyObject * BPy_FEdgeSmooth_from_FEdgeSmooth( FEdgeSmooth& fes ); PyObject * BPy_Stroke_from_Stroke( Stroke& s ); PyObject * BPy_ViewEdge_from_ViewEdge( ViewEdge& ve ); PyObject * BPy_directedViewEdge_from_directedViewEdge( ViewVertex::directedViewEdge& dve ); // some other converters PyObject * BPy_ViewShape_from_ViewShape( ViewShape& vs ); PyObject * BPy_SShape_from_SShape( SShape& ss ); PyObject * BPy_FrsMaterial_from_FrsMaterial( FrsMaterial& m ); PyObject * BPy_StrokeAttribute_from_StrokeAttribute( StrokeAttribute& sa ); * Added a "borrowed" flag to the definitions of Python types being used to wrap C++ components of Freestyle's internal data structures. The flag indicates whether or not a Python wrapper object has a reference to a C++ object that comprises the internal data structures. The deallocation routines of the Python types check this flag and release a wrapped C++ object only when it is not part of the internal data structures. The following files were modified: python/BPy_FrsMaterial.{cpp,h} python/BPy_Interface0D.{cpp,h} python/BPy_Interface1D.{cpp,h} python/BPy_SShape.{cpp,h} python/BPy_StrokeAttribute.{cpp,h} python/BPy_ViewShape.{cpp,h} python/Interface0D/BPy_CurvePoint.cpp python/Interface0D/BPy_SVertex.cpp python/Interface0D/BPy_ViewVertex.cpp python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp python/Interface0D/ViewVertex/BPy_NonTVertex.cpp python/Interface0D/ViewVertex/BPy_TVertex.cpp python/Interface1D/BPy_FEdge.cpp python/Interface1D/BPy_FrsCurve.cpp python/Interface1D/BPy_Stroke.cpp python/Interface1D/BPy_ViewEdge.cpp python/Interface1D/Curve/BPy_Chain.cpp python/Interface1D/FEdge/BPy_FEdgeSharp.cpp python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp * view_map/Interface[01]D.h, python/BPy_Interface[01]D.cpp: Removed from the Interface0D and Interface1D C++ classes a back pointer to a Python wrapper object and all "director" calls. These classes (and their subclasses) are used to build Freestyle's main data structures (such as a view map and strokes) and their class hierarchy is static. Python wrappers of these C++ classes are only used to access the data structures from the Python layer, and not intended to extend the data structures by subclassing the Python wrappers. Without the necessity of subclassing in the Python layer, the back pointer to a wrapping Python object and "director" calls would be useless (actually they were not used at all), so they were all removed. * python/Director.{cpp,h}: Removed the definitions of directors that were no longer used. * stroke/Stroke.{cpp,h}: Removed an (unused) back pointer to a Python wrapper object. * python/BPy_ViewMap.cpp: Fixed a possible null pointer reference. * python/Interface1D/BPy_FEdge.cpp: Fixed parameter checking in FEdge___init__().
2009-08-02 16:23:18 +00:00
self->py_cp.py_if0D.borrowed = 0;
return 0;
}
// real operator[] (const int i) const
// real & operator[] (const int i)
/*----------------------mathutils callbacks ----------------------------*/
static int StrokeVertex_mathutils_check(BaseMathObject *bmo)
{
if (!BPy_StrokeVertex_Check(bmo->cb_user))
return -1;
return 0;
}
static int StrokeVertex_mathutils_get(BaseMathObject *bmo, int subtype)
{
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
bmo->data[0] = (float)self->sv->x();
bmo->data[1] = (float)self->sv->y();
return 0;
}
static int StrokeVertex_mathutils_set(BaseMathObject *bmo, int subtype)
{
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
self->sv->setX((real)bmo->data[0]);
self->sv->setY((real)bmo->data[1]);
return 0;
}
static int StrokeVertex_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
{
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
switch (index) {
case 0: bmo->data[0] = (float)self->sv->x(); break;
case 1: bmo->data[1] = (float)self->sv->y(); break;
default:
return -1;
}
return 0;
}
static int StrokeVertex_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
{
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
switch (index) {
case 0: self->sv->setX((real)bmo->data[0]); break;
case 1: self->sv->setY((real)bmo->data[1]); break;
default:
return -1;
}
return 0;
}
static Mathutils_Callback StrokeVertex_mathutils_cb = {
StrokeVertex_mathutils_check,
StrokeVertex_mathutils_get,
StrokeVertex_mathutils_set,
StrokeVertex_mathutils_get_index,
StrokeVertex_mathutils_set_index
};
static unsigned char StrokeVertex_mathutils_cb_index = -1;
void StrokeVertex_mathutils_register_callback()
{
StrokeVertex_mathutils_cb_index = Mathutils_RegisterCallback(&StrokeVertex_mathutils_cb);
}
/*----------------------StrokeVertex get/setters ----------------------------*/
PyDoc_STRVAR(StrokeVertex_attribute_doc,
"StrokeAttribute for this StrokeVertex.\n"
"\n"
":type: StrokeAttribute");
static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
return BPy_StrokeAttribute_from_StrokeAttribute(self->sv->attribute());
}
static int StrokeVertex_attribute_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
{
if (!BPy_StrokeAttribute_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be a StrokeAttribute object");
return -1;
}
self->sv->setAttribute(*(((BPy_StrokeAttribute *)value)->sa));
return 0;
}
PyDoc_STRVAR(StrokeVertex_curvilinear_abscissa_doc,
"Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
"\n"
":type: float");
static PyObject *StrokeVertex_curvilinear_abscissa_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
return PyFloat_FromDouble(self->sv->curvilinearAbscissa());
}
static int StrokeVertex_curvilinear_abscissa_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "value must be a number");
return -1;
}
self->sv->setCurvilinearAbscissa(scalar);
return 0;
}
PyDoc_STRVAR(StrokeVertex_point_doc,
"2D point coordinates.\n"
"\n"
":type: mathutils.Vector");
static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
return Vector_CreatePyObject_cb((PyObject *)self, 2, StrokeVertex_mathutils_cb_index, 0);
}
static int StrokeVertex_point_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
{
float v[2];
if (!float_array_from_PyObject(value, v, 2)) {
PyErr_SetString(PyExc_ValueError, "value must be a 2-dimensional vector");
return -1;
}
self->sv->setX(v[0]);
self->sv->setY(v[1]);
return 0;
}
PyDoc_STRVAR(StrokeVertex_stroke_length_doc,
"Stroke length (it is only a value retained by the StrokeVertex,\n"
"and it won't change the real stroke length).\n"
"\n"
":type: float");
static PyObject *StrokeVertex_stroke_length_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
return PyFloat_FromDouble(self->sv->strokeLength());
}
static int StrokeVertex_stroke_length_set(BPy_StrokeVertex *self, PyObject *value, void *UNUSED(closure))
{
float scalar;
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError, "value must be a number");
return -1;
}
self->sv->setStrokeLength(scalar);
return 0;
}
PyDoc_STRVAR(StrokeVertex_u_doc,
"Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
"\n"
":type: float");
static PyObject *StrokeVertex_u_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
return PyFloat_FromDouble(self->sv->u());
}
static PyGetSetDef BPy_StrokeVertex_getseters[] = {
{(char *)"attribute", (getter)StrokeVertex_attribute_get, (setter)StrokeVertex_attribute_set,
(char *)StrokeVertex_attribute_doc, NULL},
{(char *)"curvilinear_abscissa", (getter)StrokeVertex_curvilinear_abscissa_get,
(setter)StrokeVertex_curvilinear_abscissa_set,
(char *)StrokeVertex_curvilinear_abscissa_doc, NULL},
{(char *)"point", (getter)StrokeVertex_point_get, (setter)StrokeVertex_point_set,
(char *)StrokeVertex_point_doc, NULL},
{(char *)"stroke_length", (getter)StrokeVertex_stroke_length_get, (setter)StrokeVertex_stroke_length_set,
(char *)StrokeVertex_stroke_length_doc, NULL},
{(char *)"u", (getter)StrokeVertex_u_get, (setter)NULL, (char *)StrokeVertex_u_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/*-----------------------BPy_StrokeVertex type definition ------------------------------*/
PyTypeObject StrokeVertex_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"StrokeVertex", /* tp_name */
sizeof(BPy_StrokeVertex), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2013-02-14 23:50:30 +00:00
StrokeVertex_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
BPy_StrokeVertex_getseters, /* tp_getset */
&CurvePoint_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
2013-02-14 23:50:30 +00:00
(initproc)StrokeVertex_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
///////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif