Blender V4.5
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`");
46
48 PyObject *args,
49 PyObject *kwds)
50{
51 static const char *kwlist_1[] = {"brother", nullptr};
52 static const char *kwlist_2[] = {"stroke", nullptr};
53 PyObject *brother = nullptr, *stroke = nullptr;
54
55 if (PyArg_ParseTupleAndKeywords(
56 args, kwds, "O!", (char **)kwlist_1, &StrokeVertexIterator_Type, &brother))
57 {
59 *(((BPy_StrokeVertexIterator *)brother)->sv_it));
60 self->reversed = ((BPy_StrokeVertexIterator *)brother)->reversed;
61 self->at_start = ((BPy_StrokeVertexIterator *)brother)->at_start;
62 }
63
64 else if ((void)PyErr_Clear(),
65 PyArg_ParseTupleAndKeywords(
66 args, kwds, "|O!", (char **)kwlist_2, &Stroke_Type, &stroke))
67 {
68 if (!stroke) {
70 }
71 else {
73 ((BPy_Stroke *)stroke)->s->strokeVerticesBegin());
74 }
75 self->reversed = false;
76 self->at_start = true;
77 }
78 else {
79 PyErr_SetString(PyExc_TypeError, "argument 1 must be StrokeVertexIterator or Stroke");
80 return -1;
81 }
82 self->py_it.it = self->sv_it;
83 return 0;
84}
85
87{
88 Py_INCREF(self);
89 self->at_start = true;
90 return (PyObject *)self;
91}
92
94{
95 /* Because Freestyle iterators for which it.isEnd() holds true have no valid object
96 * (they point to the past-the-end element and can't be dereferenced), we have to check
97 * iterators for validity.
98 * Additionally, the at_start attribute is used to keep Freestyle iterator objects
99 * and Python for loops in sync. */
100
101 if (self->reversed) {
102 if (self->sv_it->isBegin()) {
103 PyErr_SetNone(PyExc_StopIteration);
104 return nullptr;
105 }
106 self->sv_it->decrement();
107 }
108 else {
109 /* If sv_it.isEnd() is true, the iterator can't be incremented. */
110 if (self->sv_it->isEnd()) {
111 PyErr_SetNone(PyExc_StopIteration);
112 return nullptr;
113 }
114 /* If at the start of the iterator, only return the object
115 * and don't increment, to keep for-loops in sync */
116 if (self->at_start) {
117 self->at_start = false;
118 }
119 /* If sv_it.atLast() is true, the iterator is currently pointing to the final valid element.
120 * Incrementing it further would lead to a state that the iterator can't be dereferenced. */
121 else if (self->sv_it->atLast()) {
122 PyErr_SetNone(PyExc_StopIteration);
123 return nullptr;
124 }
125 else {
126 self->sv_it->increment();
127 }
128 }
129 StrokeVertex *sv = self->sv_it->operator->();
131}
132
133/*----------------------StrokeVertexIterator methods ----------------------------*/
134
136 /* Wrap. */
137 StrokeVertexIterator_incremented_doc,
138 ".. method:: incremented()\n"
139 "\n"
140 " Returns a copy of an incremented StrokeVertexIterator.\n"
141 "\n"
142 " :return: A StrokeVertexIterator pointing the next StrokeVertex.\n"
143 " :rtype: :class:`StrokeVertexIterator`");
144
146{
147 if (self->sv_it->isEnd()) {
148 PyErr_SetString(PyExc_RuntimeError, "cannot increment any more");
149 return nullptr;
150 }
152 copy.increment();
154}
155
157 /* Wrap. */
158 StrokeVertexIterator_decremented_doc,
159 ".. method:: decremented()\n"
160 "\n"
161 " Returns a copy of a decremented StrokeVertexIterator.\n"
162 "\n"
163 " :return: A StrokeVertexIterator pointing the previous StrokeVertex.\n"
164 " :rtype: :class:`StrokeVertexIterator`");
165
167{
168 if (self->sv_it->isBegin()) {
169 PyErr_SetString(PyExc_RuntimeError, "cannot decrement any more");
170 return nullptr;
171 }
173 copy.decrement();
175}
176
178 /* Wrap. */
179 StrokeVertexIterator_reversed_doc,
180 ".. method:: reversed()\n"
181 "\n"
182 " Returns a StrokeVertexIterator that traverses stroke vertices in the\n"
183 " reversed order.\n"
184 "\n"
185 " :return: A StrokeVertexIterator traversing stroke vertices backward.\n"
186 " :rtype: :class:`StrokeVertexIterator`");
187
192
193#ifdef __GNUC__
194# ifdef __clang__
195# pragma clang diagnostic push
196# pragma clang diagnostic ignored "-Wcast-function-type"
197# else
198# pragma GCC diagnostic push
199# pragma GCC diagnostic ignored "-Wcast-function-type"
200# endif
201#endif
202
203static PyMethodDef BPy_StrokeVertexIterator_methods[] = {
204 {"incremented",
206 METH_NOARGS,
207 StrokeVertexIterator_incremented_doc},
208 {"decremented",
210 METH_NOARGS,
211 StrokeVertexIterator_decremented_doc},
212 {"reversed",
214 METH_NOARGS,
215 StrokeVertexIterator_reversed_doc},
216 {nullptr, nullptr, 0, nullptr},
217};
218
219#ifdef __GNUC__
220# ifdef __clang__
221# pragma clang diagnostic pop
222# else
223# pragma GCC diagnostic pop
224# endif
225#endif
226
227/*----------------------StrokeVertexIterator get/setters ----------------------------*/
228
230 /* Wrap. */
231 StrokeVertexIterator_object_doc,
232 "The StrokeVertex object currently pointed to by this iterator.\n"
233 "\n"
234 ":type: :class:`StrokeVertex`");
235
237 void * /*closure*/)
238{
239 if (self->sv_it->isEnd()) {
240 PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
241 return nullptr;
242 }
243 StrokeVertex *sv = self->sv_it->operator->();
244 if (sv) {
246 }
247 Py_RETURN_NONE;
248}
249
251 /* Wrap. */
252 StrokeVertexIterator_t_doc,
253 "The curvilinear abscissa of the current point.\n"
254 "\n"
255 ":type: float");
256
257static PyObject *StrokeVertexIterator_t_get(BPy_StrokeVertexIterator *self, void * /*closure*/)
258{
259 return PyFloat_FromDouble(self->sv_it->t());
260}
261
263 /* Wrap. */
264 StrokeVertexIterator_u_doc,
265 "The point parameter at the current point in the stroke (0 <= u <= 1).\n"
266 "\n"
267 ":type: float");
268
269static PyObject *StrokeVertexIterator_u_get(BPy_StrokeVertexIterator *self, void * /*closure*/)
270{
271 return PyFloat_FromDouble(self->sv_it->u());
272}
273
275 /* Wrap. */
276 StrokeVertexIterator_at_last_doc,
277 "True if the iterator points to the last valid element.\n"
278 "For its counterpart (pointing to the first valid element), use it.is_begin.\n"
279 "\n"
280 ":type: bool");
281
283{
284 return PyBool_from_bool(self->sv_it->atLast());
285}
286
287#ifdef __GNUC__
288# ifdef __clang__
289# pragma clang diagnostic push
290# pragma clang diagnostic ignored "-Wcast-function-type"
291# else
292# pragma GCC diagnostic push
293# pragma GCC diagnostic ignored "-Wcast-function-type"
294# endif
295#endif
296
298 {"object",
300 (setter) nullptr,
301 StrokeVertexIterator_object_doc,
302 nullptr},
303 {"t",
305 (setter) nullptr,
306 StrokeVertexIterator_t_doc,
307 nullptr},
308 {"u",
310 (setter) nullptr,
311 StrokeVertexIterator_u_doc,
312 nullptr},
313 {"at_last",
315 (setter) nullptr,
316 StrokeVertexIterator_at_last_doc,
317 nullptr},
318 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
319};
320
321#ifdef __GNUC__
322# ifdef __clang__
323# pragma clang diagnostic pop
324# else
325# pragma GCC diagnostic pop
326# endif
327#endif
328
329/*-----------------------BPy_StrokeVertexIterator type definition ------------------------------*/
330
332 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
333 /*tp_name*/ "StrokeVertexIterator",
334 /*tp_basicsize*/ sizeof(BPy_StrokeVertexIterator),
335 /*tp_itemsize*/ 0,
336 /*tp_dealloc*/ nullptr,
337 /*tp_vectorcall_offset*/ 0,
338 /*tp_getattr*/ nullptr,
339 /*tp_setattr*/ nullptr,
340 /*tp_as_async*/ nullptr,
341 /*tp_repr*/ nullptr,
342 /*tp_as_number*/ nullptr,
343 /*tp_as_sequence*/ nullptr,
344 /*tp_as_mapping*/ nullptr,
345 /*tp_hash*/ nullptr,
346 /*tp_call*/ nullptr,
347 /*tp_str*/ nullptr,
348 /*tp_getattro*/ nullptr,
349 /*tp_setattro*/ nullptr,
350 /*tp_as_buffer*/ nullptr,
351 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
352 /*tp_doc*/ StrokeVertexIterator_doc,
353 /*tp_traverse*/ nullptr,
354 /*tp_clear*/ nullptr,
355 /*tp_richcompare*/ nullptr,
356 /*tp_weaklistoffset*/ 0,
357 /*tp_iter*/ (getiterfunc)StrokeVertexIterator_iter,
358 /*tp_iternext*/ (iternextfunc)StrokeVertexIterator_iternext,
360 /*tp_members*/ nullptr,
362 /*tp_base*/ &Iterator_Type,
363 /*tp_dict*/ nullptr,
364 /*tp_descr_get*/ nullptr,
365 /*tp_descr_set*/ nullptr,
366 /*tp_dictoffset*/ 0,
367 /*tp_init*/ (initproc)StrokeVertexIterator_init,
368 /*tp_alloc*/ nullptr,
369 /*tp_new*/ nullptr,
370};
371
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)
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`")
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[]
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)