Blender  V2.93
BPy_StrokeVertexIterator.cpp
Go to the documentation of this file.
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 
22 
23 #include "../BPy_Convert.h"
24 #include "../Interface1D/BPy_Stroke.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 using namespace Freestyle;
32 
34 
35 //------------------------INSTANCE METHODS ----------------------------------
36 
37 PyDoc_STRVAR(StrokeVertexIterator_doc,
38  "Class hierarchy: :class:`Iterator` > :class:`StrokeVertexIterator`\n"
39  "\n"
40  "Class defining an iterator designed to iterate over the\n"
41  ":class:`StrokeVertex` of a :class:`Stroke`. An instance of a\n"
42  "StrokeVertexIterator can be obtained from a Stroke by calling\n"
43  "iter(), stroke_vertices_begin() or stroke_vertices_begin(). It is iterating\n"
44  "over the same vertices as an :class:`Interface0DIterator`. The difference\n"
45  "resides in the object access: an Interface0DIterator only allows\n"
46  "access to an Interface0D while one might need to access the\n"
47  "specialized StrokeVertex type. In this case, one should use a\n"
48  "StrokeVertexIterator. To call functions of the UnaryFuntion0D type,\n"
49  "a StrokeVertexIterator can be converted to an Interface0DIterator by\n"
50  "by calling Interface0DIterator(it).\n"
51  "\n"
52  ".. method:: __init__()\n"
53  " __init__(brother)\n"
54  "\n"
55  " Creates a :class:`StrokeVertexIterator` using either the\n"
56  " default constructor or the copy constructor.\n"
57  "\n"
58  " :arg brother: A StrokeVertexIterator object.\n"
59  " :type brother: :class:`StrokeVertexIterator`");
60 
62  PyObject *args,
63  PyObject *kwds)
64 {
65  static const char *kwlist_1[] = {"brother", nullptr};
66  static const char *kwlist_2[] = {"stroke", nullptr};
67  PyObject *brother = nullptr, *stroke = nullptr;
68 
69  if (PyArg_ParseTupleAndKeywords(
70  args, kwds, "O!", (char **)kwlist_1, &StrokeVertexIterator_Type, &brother)) {
71  self->sv_it = new StrokeInternal::StrokeVertexIterator(
72  *(((BPy_StrokeVertexIterator *)brother)->sv_it));
73  self->reversed = ((BPy_StrokeVertexIterator *)brother)->reversed;
74  self->at_start = ((BPy_StrokeVertexIterator *)brother)->at_start;
75  }
76 
77  else if ((void)PyErr_Clear(),
78  PyArg_ParseTupleAndKeywords(
79  args, kwds, "|O!", (char **)kwlist_2, &Stroke_Type, &stroke)) {
80  if (!stroke) {
81  self->sv_it = new StrokeInternal::StrokeVertexIterator();
82  }
83  else {
84  self->sv_it = new StrokeInternal::StrokeVertexIterator(
85  ((BPy_Stroke *)stroke)->s->strokeVerticesBegin());
86  }
87  self->reversed = false;
88  self->at_start = true;
89  }
90  else {
91  PyErr_SetString(PyExc_TypeError, "argument 1 must be StrokeVertexIterator or Stroke");
92  return -1;
93  }
94  self->py_it.it = self->sv_it;
95  return 0;
96 }
97 
99 {
100  Py_INCREF(self);
101  self->at_start = true;
102  return (PyObject *)self;
103 }
104 
106 {
107  /* Because Freestyle iterators for which it.isEnd() holds true have no valid object
108  * (they point to the past-the-end element and can't be dereferenced), we have to check
109  * iterators for validity.
110  * Additionally, the at_start attribute is used to keep Freestyle iterator objects
111  * and Python for loops in sync. */
112 
113  if (self->reversed) {
114  if (self->sv_it->isBegin()) {
115  PyErr_SetNone(PyExc_StopIteration);
116  return nullptr;
117  }
118  self->sv_it->decrement();
119  }
120  else {
121  /* If sv_it.isEnd() is true, the iterator can't be incremented. */
122  if (self->sv_it->isEnd()) {
123  PyErr_SetNone(PyExc_StopIteration);
124  return nullptr;
125  }
126  /* If at the start of the iterator, only return the object
127  * and don't increment, to keep for-loops in sync */
128  if (self->at_start) {
129  self->at_start = false;
130  }
131  /* If sv_it.atLast() is true, the iterator is currently pointing to the final valid element.
132  * Incrementing it further would lead to a state that the iterator can't be dereferenced. */
133  else if (self->sv_it->atLast()) {
134  PyErr_SetNone(PyExc_StopIteration);
135  return nullptr;
136  }
137  else {
138  self->sv_it->increment();
139  }
140  }
141  StrokeVertex *sv = self->sv_it->operator->();
143 }
144 
145 /*----------------------StrokeVertexIterator methods ----------------------------*/
146 
147 PyDoc_STRVAR(StrokeVertexIterator_incremented_doc,
148  ".. method:: incremented()\n"
149  "\n"
150  " Returns a copy of an incremented StrokeVertexIterator.\n"
151  "\n"
152  " :return: A StrokeVertexIterator pointing the next StrokeVertex.\n"
153  " :rtype: :class:`StrokeVertexIterator`");
154 
156 {
157  if (self->sv_it->isEnd()) {
158  PyErr_SetString(PyExc_RuntimeError, "cannot increment any more");
159  return nullptr;
160  }
162  copy.increment();
164 }
165 
166 PyDoc_STRVAR(StrokeVertexIterator_decremented_doc,
167  ".. method:: decremented()\n"
168  "\n"
169  " Returns a copy of a decremented StrokeVertexIterator.\n"
170  "\n"
171  " :return: A StrokeVertexIterator pointing the previous StrokeVertex.\n"
172  " :rtype: :class:`StrokeVertexIterator`");
173 
175 {
176  if (self->sv_it->isBegin()) {
177  PyErr_SetString(PyExc_RuntimeError, "cannot decrement any more");
178  return nullptr;
179  }
181  copy.decrement();
183 }
184 
185 PyDoc_STRVAR(StrokeVertexIterator_reversed_doc,
186  ".. method:: reversed()\n"
187  "\n"
188  " Returns a StrokeVertexIterator that traverses stroke vertices in the\n"
189  " reversed order.\n"
190  "\n"
191  " :return: A StrokeVertexIterator traversing stroke vertices backward.\n"
192  " :rtype: :class:`StrokeVertexIterator`");
193 
195 {
197 }
198 
199 static PyMethodDef BPy_StrokeVertexIterator_methods[] = {
200  {"incremented",
202  METH_NOARGS,
203  StrokeVertexIterator_incremented_doc},
204  {"decremented",
206  METH_NOARGS,
207  StrokeVertexIterator_decremented_doc},
208  {"reversed",
209  (PyCFunction)StrokeVertexIterator_reversed,
210  METH_NOARGS,
211  StrokeVertexIterator_reversed_doc},
212  {nullptr, nullptr, 0, nullptr},
213 };
214 
215 /*----------------------StrokeVertexIterator get/setters ----------------------------*/
216 
217 PyDoc_STRVAR(StrokeVertexIterator_object_doc,
218  "The StrokeVertex object currently pointed to by this iterator.\n"
219  "\n"
220  ":type: :class:`StrokeVertex`");
221 
223  void *UNUSED(closure))
224 {
225  if (self->sv_it->isEnd()) {
226  PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
227  return nullptr;
228  }
229  StrokeVertex *sv = self->sv_it->operator->();
230  if (sv) {
232  }
233  Py_RETURN_NONE;
234 }
235 
236 PyDoc_STRVAR(StrokeVertexIterator_t_doc,
237  "The curvilinear abscissa of the current point.\n"
238  "\n"
239  ":type: float");
240 
241 static PyObject *StrokeVertexIterator_t_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
242 {
243  return PyFloat_FromDouble(self->sv_it->t());
244 }
245 
246 PyDoc_STRVAR(StrokeVertexIterator_u_doc,
247  "The point parameter at the current point in the stroke (0 <= u <= 1).\n"
248  "\n"
249  ":type: float");
250 
251 static PyObject *StrokeVertexIterator_u_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
252 {
253  return PyFloat_FromDouble(self->sv_it->u());
254 }
255 
256 PyDoc_STRVAR(StrokeVertexIterator_at_last_doc,
257  "True if the iterator points to the last valid element.\n"
258  "For its counterpart (pointing to the first valid element), use it.is_begin.\n"
259  "\n"
260  ":type: bool");
261 
263 {
264  return PyBool_from_bool(self->sv_it->atLast());
265 }
266 
267 static PyGetSetDef BPy_StrokeVertexIterator_getseters[] = {
268  {"object",
270  (setter) nullptr,
271  StrokeVertexIterator_object_doc,
272  nullptr},
273  {"t",
275  (setter) nullptr,
276  StrokeVertexIterator_t_doc,
277  nullptr},
278  {"u",
280  (setter) nullptr,
281  StrokeVertexIterator_u_doc,
282  nullptr},
283  {"at_last",
285  (setter) nullptr,
286  StrokeVertexIterator_at_last_doc,
287  nullptr},
288  {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
289 };
290 
291 /*-----------------------BPy_StrokeVertexIterator type definition ------------------------------*/
292 
294  PyVarObject_HEAD_INIT(nullptr, 0) "StrokeVertexIterator", /* tp_name */
295  sizeof(BPy_StrokeVertexIterator), /* tp_basicsize */
296  0, /* tp_itemsize */
297  nullptr, /* tp_dealloc */
298  0, /* tp_vectorcall_offset */
299  nullptr, /* tp_getattr */
300  nullptr, /* tp_setattr */
301  nullptr, /* tp_reserved */
302  nullptr, /* tp_repr */
303  nullptr, /* tp_as_number */
304  nullptr, /* tp_as_sequence */
305  nullptr, /* tp_as_mapping */
306  nullptr, /* tp_hash */
307  nullptr, /* tp_call */
308  nullptr, /* tp_str */
309  nullptr, /* tp_getattro */
310  nullptr, /* tp_setattro */
311  nullptr, /* tp_as_buffer */
312  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
313  StrokeVertexIterator_doc, /* tp_doc */
314  nullptr, /* tp_traverse */
315  nullptr, /* tp_clear */
316  nullptr, /* tp_richcompare */
317  0, /* tp_weaklistoffset */
318  (getiterfunc)StrokeVertexIterator_iter, /* tp_iter */
319  (iternextfunc)StrokeVertexIterator_iternext, /* tp_iternext */
320  BPy_StrokeVertexIterator_methods, /* tp_methods */
321  nullptr, /* tp_members */
322  BPy_StrokeVertexIterator_getseters, /* tp_getset */
323  &Iterator_Type, /* tp_base */
324  nullptr, /* tp_dict */
325  nullptr, /* tp_descr_get */
326  nullptr, /* tp_descr_set */
327  0, /* tp_dictoffset */
328  (initproc)StrokeVertexIterator_init, /* tp_init */
329  nullptr, /* tp_alloc */
330  nullptr, /* tp_new */
331 };
332 
334 
335 #ifdef __cplusplus
336 }
337 #endif
#define UNUSED(x)
PyObject * PyBool_from_bool(bool b)
Definition: BPy_Convert.cpp:73
PyObject * BPy_StrokeVertex_from_StrokeVertex(StrokeVertex &sv)
PyObject * BPy_StrokeVertexIterator_from_StrokeVertexIterator(StrokeInternal::StrokeVertexIterator &sv_it, bool reversed)
PyTypeObject Iterator_Type
static int StrokeVertexIterator_init(BPy_StrokeVertexIterator *self, PyObject *args, PyObject *kwds)
static PyObject * StrokeVertexIterator_at_last_get(BPy_StrokeVertexIterator *self)
static PyObject * StrokeVertexIterator_reversed(BPy_StrokeVertexIterator *self)
static PyObject * StrokeVertexIterator_iternext(BPy_StrokeVertexIterator *self)
static PyObject * StrokeVertexIterator_t_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
static PyObject * StrokeVertexIterator_decremented(BPy_StrokeVertexIterator *self)
PyTypeObject StrokeVertexIterator_Type
static PyObject * StrokeVertexIterator_object_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
static PyGetSetDef BPy_StrokeVertexIterator_getseters[]
static PyMethodDef BPy_StrokeVertexIterator_methods[]
static PyObject * StrokeVertexIterator_incremented(BPy_StrokeVertexIterator *self)
static PyObject * StrokeVertexIterator_iter(BPy_StrokeVertexIterator *self)
static PyObject * StrokeVertexIterator_u_get(BPy_StrokeVertexIterator *self, void *UNUSED(closure))
PyDoc_STRVAR(StrokeVertexIterator_doc, "Class hierarchy: :class:`Iterator` > :class:`StrokeVertexIterator`\n" "\n" "Class defining an iterator designed to iterate over the\n" ":class:`StrokeVertex` of a :class:`Stroke`. An instance of a\n" "StrokeVertexIterator can be obtained from a Stroke by calling\n" "iter(), stroke_vertices_begin() or stroke_vertices_begin(). It is iterating\n" "over the same vertices as an :class:`Interface0DIterator`. The difference\n" "resides in the object access: an Interface0DIterator only allows\n" "access to an Interface0D while one might need to access the\n" "specialized StrokeVertex type. In this case, one should use a\n" "StrokeVertexIterator. To call functions of the UnaryFuntion0D type,\n" "a StrokeVertexIterator can be converted to an Interface0DIterator by\n" "by calling Interface0DIterator(it).\n" "\n" ".. method:: __init__()\n" " __init__(brother)\n" "\n" " Creates a :class:`StrokeVertexIterator` using either the\n" " default constructor or the copy constructor.\n" "\n" " :arg brother: A StrokeVertexIterator object.\n" " :type brother: :class:`StrokeVertexIterator`")
PyTypeObject Stroke_Type
Definition: BPy_Stroke.cpp:501
PyObject * self
Definition: bpy_driver.c:185
inherits from class Rep
Definition: AppCanvas.cpp:32
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)