9f0660baa9b1ac3de1867c651964d6a04a44d6fd
[blender-staging.git] / source / blender / freestyle / intern / python / Interface0D / BPy_CurvePoint.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
22  *  \ingroup freestyle
23  */
24
25 #include "BPy_CurvePoint.h"
26
27 #include "../BPy_Convert.h"
28 #include "../Interface0D/BPy_SVertex.h"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 ///////////////////////////////////////////////////////////////////////////////////////////
35
36 /*----------------------CurvePoint methods----------------------------*/
37
38 PyDoc_STRVAR(CurvePoint_doc,
39 "Class hierarchy: :class:`Interface0D` > :class:`CurvePoint`\n"
40 "\n"
41 "Class to represent a point of a curve.  A CurvePoint can be any point\n"
42 "of a 1D curve (it doesn't have to be a vertex of the curve).  Any\n"
43 ":class:`Interface1D` is built upon ViewEdges, themselves built upon\n"
44 "FEdges.  Therefore, a curve is basically a polyline made of a list of\n"
45 ":class:`SVertex` objects.  Thus, a CurvePoint is built by linearly\n"
46 "interpolating two :class:`SVertex` instances.  CurvePoint can be used\n"
47 "as virtual points while querying 0D information along a curve at a\n"
48 "given resolution.\n"
49 "\n"
50 ".. method:: __init__()\n"
51 "\n"
52 "   Defult constructor.\n"
53 "\n"
54 ".. method:: __init__(brother)\n"
55 "\n"
56 "   Copy constructor.\n"
57 "\n"
58 "   :arg brother: A CurvePoint object.\n"
59 "   :type brother: :class:`CurvePoint`\n"
60 "\n"
61 ".. method:: __init__(first_vertex, second_vertex, t2d)\n"
62 "\n"
63 "   Builds a CurvePoint from two SVertex objects and an interpolation parameter.\n"
64 "\n"
65 "   :arg first_vertex: The first SVertex.\n"
66 "   :type first_vertex: :class:`SVertex`\n"
67 "   :arg second_vertex: The second SVertex.\n"
68 "   :type second_vertex: :class:`SVertex`\n"
69 "   :arg t2d: A 2D interpolation parameter used to linearly interpolate\n"
70 "             first_vertex and second_vertex.\n"
71 "   :type t2d: float\n"
72 "\n"
73 ".. method:: __init__(first_point, second_point, t2d)\n"
74 "\n"
75 "   Builds a CurvePoint from two CurvePoint objects and an interpolation\n"
76 "   parameter.\n"
77 "\n"
78 "   :arg first_point: The first CurvePoint.\n"
79 "   :type first_point: :class:`CurvePoint`\n"
80 "   :arg second_point: The second CurvePoint.\n"
81 "   :type second_point: :class:`CurvePoint`\n"
82 "   :arg t2d: The 2D interpolation parameter used to linearly interpolate\n"
83 "             first_point and second_point.\n"
84 "   :type t2d: float");
85
86 static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
87 {
88         static const char *kwlist_1[] = {"brother", NULL};
89         static const char *kwlist_2[] = {"first_vertex", "second_vertex", "t2d", NULL};
90         static const char *kwlist_3[] = {"first_point", "second_point", "t2d", NULL};
91         PyObject *obj1 = 0, *obj2 = 0;
92         float t2d;
93
94         if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &CurvePoint_Type, &obj1)) {
95                 if (!obj1)
96                         self->cp = new CurvePoint();
97                 else
98                         self->cp = new CurvePoint(*(((BPy_CurvePoint *)obj1)->cp));
99         }
100         else if (PyErr_Clear(),
101                  PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", (char **)kwlist_2,
102                                              &SVertex_Type, &obj1, &SVertex_Type, &obj2, &t2d))
103         {
104                 self->cp = new CurvePoint(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv, t2d);
105         }
106         else if (PyErr_Clear(),
107                  PyArg_ParseTupleAndKeywords(args, kwds, "O!O!f", (char **)kwlist_3,
108                                              &CurvePoint_Type, &obj1, &CurvePoint_Type, &obj2, &t2d))
109         {
110                 CurvePoint *cp1 = ((BPy_CurvePoint *)obj1)->cp;
111                 CurvePoint *cp2 = ((BPy_CurvePoint *)obj2)->cp;
112                 if (!cp1 || cp1->A() == 0 || cp1->B() == 0) {
113                         PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object");
114                         return -1;
115                 }
116                 if (!cp2 || cp2->A() == 0 || cp2->B() == 0) {
117                         PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid CurvePoint object");
118                         return -1;
119                 }
120                 self->cp = new CurvePoint(cp1, cp2, t2d);
121         }
122         else {
123                 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
124                 return -1;
125         }
126         self->py_if0D.if0D = self->cp;
127         self->py_if0D.borrowed = false;
128         return 0;
129 }
130
131 ///bool         operator== (const CurvePoint &b)
132
133 /*----------------------CurvePoint get/setters ----------------------------*/
134
135 PyDoc_STRVAR(CurvePoint_first_svertex_doc,
136 "The first SVertex upon which the CurvePoint is built.\n"
137 "\n"
138 ":type: :class:`SVertex`");
139
140 static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
141 {
142         SVertex *A = self->cp->A();
143         if (A)
144                 return BPy_SVertex_from_SVertex(*A);
145         Py_RETURN_NONE;
146 }
147
148 static int CurvePoint_first_svertex_set(BPy_CurvePoint *self, PyObject *value, void *UNUSED(closure))
149 {
150         if (!BPy_SVertex_Check(value)) {
151                 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
152                 return -1;
153         }
154         self->cp->setA(((BPy_SVertex *)value)->sv);
155         return 0;
156 }
157
158 PyDoc_STRVAR(CurvePoint_second_svertex_doc,
159 "The second SVertex upon which the CurvePoint is built.\n"
160 "\n"
161 ":type: :class:`SVertex`");
162
163 static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
164 {
165         SVertex *B = self->cp->B();
166         if (B)
167                 return BPy_SVertex_from_SVertex(*B);
168         Py_RETURN_NONE;
169 }
170
171 static int CurvePoint_second_svertex_set(BPy_CurvePoint *self, PyObject *value, void *UNUSED(closure))
172 {
173         if (!BPy_SVertex_Check(value)) {
174                 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
175                 return -1;
176         }
177         self->cp->setB(((BPy_SVertex *)value)->sv);
178         return 0;
179 }
180
181 PyDoc_STRVAR(CurvePoint_fedge_doc,
182 "Gets the FEdge for the two SVertices that given CurvePoints consists out of.\n"
183 "A shortcut for CurvePoint.first_svertex.get_fedge(CurvePoint.second_svertex).\n"
184 "\n"
185 ":type: :class:`FEdge`");
186
187 static PyObject *CurvePoint_fedge_get(BPy_CurvePoint *self, void *UNUSED(closure))
188 {
189         SVertex *A = self->cp->A();
190         Interface0D *B = (Interface0D *)self->cp->B();
191         // B can be NULL under certain circumstances
192         if (B)
193                 return Any_BPy_Interface1D_from_Interface1D(*(A->getFEdge(*B)));
194         Py_RETURN_NONE;
195 }
196
197 PyDoc_STRVAR(CurvePoint_t2d_doc,
198 "The 2D interpolation parameter.\n"
199 "\n"
200 ":type: float");
201
202 static PyObject *CurvePoint_t2d_get(BPy_CurvePoint *self, void *UNUSED(closure))
203 {
204         return PyFloat_FromDouble(self->cp->t2d());
205 }
206
207 static int CurvePoint_t2d_set(BPy_CurvePoint *self, PyObject *value, void *UNUSED(closure))
208 {
209         float scalar;
210         if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
211                 PyErr_SetString(PyExc_TypeError, "value must be a number");
212                 return -1;
213         }
214         self->cp->setT2d(scalar);
215         return 0;
216 }
217
218 static PyGetSetDef BPy_CurvePoint_getseters[] = {
219         {(char *)"first_svertex", (getter)CurvePoint_first_svertex_get, (setter)CurvePoint_first_svertex_set,
220                                   (char *)CurvePoint_first_svertex_doc, NULL},
221         {(char *)"second_svertex", (getter)CurvePoint_second_svertex_get, (setter)CurvePoint_second_svertex_set,
222                                    (char *)CurvePoint_second_svertex_doc, NULL},
223     {(char *)"fedge", (getter)CurvePoint_fedge_get, NULL,
224                                CurvePoint_fedge_doc, NULL},
225         {(char *)"t2d", (getter)CurvePoint_t2d_get, (setter)CurvePoint_t2d_set, (char *)CurvePoint_t2d_doc, NULL},
226         {NULL, NULL, NULL, NULL, NULL}  /* Sentinel */
227 };
228
229 /*-----------------------BPy_CurvePoint type definition ------------------------------*/
230 PyTypeObject CurvePoint_Type = {
231         PyVarObject_HEAD_INIT(NULL, 0)
232         "CurvePoint",                   /* tp_name */
233         sizeof(BPy_CurvePoint),         /* tp_basicsize */
234         0,                              /* tp_itemsize */
235         0,                              /* tp_dealloc */
236         0,                              /* tp_print */
237         0,                              /* tp_getattr */
238         0,                              /* tp_setattr */
239         0,                              /* tp_reserved */
240         0,                              /* tp_repr */
241         0,                              /* tp_as_number */
242         0,                              /* tp_as_sequence */
243         0,                              /* tp_as_mapping */
244         0,                              /* tp_hash  */
245         0,                              /* tp_call */
246         0,                              /* tp_str */
247         0,                              /* tp_getattro */
248         0,                              /* tp_setattro */
249         0,                              /* tp_as_buffer */
250         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
251         CurvePoint_doc,                 /* tp_doc */
252         0,                              /* tp_traverse */
253         0,                              /* tp_clear */
254         0,                              /* tp_richcompare */
255         0,                              /* tp_weaklistoffset */
256         0,                              /* tp_iter */
257         0,                              /* tp_iternext */
258         0,                              /* tp_methods */
259         0,                              /* tp_members */
260         BPy_CurvePoint_getseters,       /* tp_getset */
261         &Interface0D_Type,              /* tp_base */
262         0,                              /* tp_dict */
263         0,                              /* tp_descr_get */
264         0,                              /* tp_descr_set */
265         0,                              /* tp_dictoffset */
266         (initproc)CurvePoint_init,      /* tp_init */
267         0,                              /* tp_alloc */
268         0,                              /* tp_new */
269 };
270
271 ///////////////////////////////////////////////////////////////////////////////////////////
272
273 #ifdef __cplusplus
274 }
275 #endif