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