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