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