Blender V4.5
BPy_FEdge.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
9#include "BPy_FEdge.h"
10
11#include "../BPy_Convert.h"
12#include "../BPy_Id.h"
13#include "../BPy_Nature.h"
16
17using namespace Freestyle;
18
20
21/*----------------------FEdge methods ----------------------------*/
22
24 /* Wrap. */
25 FEdge_doc,
26 "Class hierarchy: :class:`Interface1D` > :class:`FEdge`\n"
27 "\n"
28 "Base Class for feature edges. This FEdge can represent a silhouette,\n"
29 "a crease, a ridge/valley, a border or a suggestive contour. For\n"
30 "silhouettes, the FEdge is oriented so that the visible face lies on\n"
31 "the left of the edge. For borders, the FEdge is oriented so that the\n"
32 "face lies on the left of the edge. An FEdge can represent an initial\n"
33 "edge of the mesh or runs across a face of the initial mesh depending\n"
34 "on the smoothness or sharpness of the mesh. This class is specialized\n"
35 "into a smooth and a sharp version since their properties slightly vary\n"
36 "from one to the other.\n"
37 "\n"
38 ".. method:: FEdge()\n"
39 " FEdge(brother)\n"
40 "\n"
41 " Builds an :class:`FEdge` using the default constructor,\n"
42 " copy constructor, or between two :class:`SVertex` objects.\n"
43 "\n"
44 " :arg brother: An FEdge object.\n"
45 " :type brother: :class:`FEdge`\n"
46 " :arg first_vertex: The first SVertex.\n"
47 " :type first_vertex: :class:`SVertex`\n"
48 " :arg second_vertex: The second SVertex.\n"
49 " :type second_vertex: :class:`SVertex`");
50
51static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
52{
53 static const char *kwlist_1[] = {"brother", nullptr};
54 static const char *kwlist_2[] = {"first_vertex", "second_vertex", nullptr};
55 PyObject *obj1 = nullptr, *obj2 = nullptr;
56
57 if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdge_Type, &obj1)) {
58 if (!obj1) {
59 self->fe = new FEdge();
60 }
61 else {
62 self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe));
63 }
64 }
65 else if ((void)PyErr_Clear(),
66 PyArg_ParseTupleAndKeywords(
67 args, kwds, "O!O!", (char **)kwlist_2, &SVertex_Type, &obj1, &SVertex_Type, &obj2))
68 {
69 self->fe = new FEdge(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
70 }
71 else {
72 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
73 return -1;
74 }
75 self->py_if1D.if1D = self->fe;
76 self->py_if1D.borrowed = false;
77 return 0;
78}
79
80/*----------------------FEdge sequence protocol ----------------------------*/
81
82static Py_ssize_t FEdge_sq_length(BPy_FEdge * /*self*/)
83{
84 return 2;
85}
86
87static PyObject *FEdge_sq_item(BPy_FEdge *self, Py_ssize_t keynum)
88{
89 if (keynum < 0) {
90 keynum += FEdge_sq_length(self);
91 }
92 if (ELEM(keynum, 0, 1)) {
93 SVertex *v = self->fe->operator[](keynum);
94 if (v) {
96 }
97 Py_RETURN_NONE;
98 }
99 PyErr_Format(PyExc_IndexError, "FEdge[index]: index %d out of range", keynum);
100 return nullptr;
101}
102
103static PySequenceMethods BPy_FEdge_as_sequence = {
104 /*sq_length*/ (lenfunc)FEdge_sq_length,
105 /*sq_concat*/ nullptr,
106 /*sq_repeat*/ nullptr,
107 /*sq_item*/ (ssizeargfunc)FEdge_sq_item,
108 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
109 /*sq_ass_item*/ nullptr,
110 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
111 /*sq_contains*/ nullptr,
112 /*sq_inplace_concat*/ nullptr,
113 /*sq_inplace_repeat*/ nullptr,
114};
115
116/*----------------------FEdge get/setters ----------------------------*/
117
119 /* Wrap. */
120 FEdge_first_svertex_doc,
121 "The first SVertex constituting this FEdge.\n"
122 "\n"
123 ":type: :class:`SVertex`");
124
125static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void * /*closure*/)
126{
127 SVertex *A = self->fe->vertexA();
128 if (A) {
130 }
131 Py_RETURN_NONE;
132}
133
134static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
135{
136 if (!BPy_SVertex_Check(value)) {
137 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
138 return -1;
139 }
140 self->fe->setVertexA(((BPy_SVertex *)value)->sv);
141 return 0;
142}
143
145 /* Wrap. */
146 FEdge_second_svertex_doc,
147 "The second SVertex constituting this FEdge.\n"
148 "\n"
149 ":type: :class:`SVertex`");
150
151static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void * /*closure*/)
152{
153 SVertex *B = self->fe->vertexB();
154 if (B) {
156 }
157 Py_RETURN_NONE;
158}
159
160static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
161{
162 if (!BPy_SVertex_Check(value)) {
163 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
164 return -1;
165 }
166 self->fe->setVertexB(((BPy_SVertex *)value)->sv);
167 return 0;
168}
169
171 /* Wrap. */
172 FEdge_next_fedge_doc,
173 "The FEdge following this one in the ViewEdge. The value is None if\n"
174 "this FEdge is the last of the ViewEdge.\n"
175 "\n"
176 ":type: :class:`FEdge`");
177
178static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void * /*closure*/)
179{
180 FEdge *fe = self->fe->nextEdge();
181 if (fe) {
182 return Any_BPy_FEdge_from_FEdge(*fe);
183 }
184 Py_RETURN_NONE;
185}
186
187static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
188{
189 if (!BPy_FEdge_Check(value)) {
190 PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
191 return -1;
192 }
193 self->fe->setNextEdge(((BPy_FEdge *)value)->fe);
194 return 0;
195}
196
198 /* Wrap. */
199 FEdge_previous_fedge_doc,
200 "The FEdge preceding this one in the ViewEdge. The value is None if\n"
201 "this FEdge is the first one of the ViewEdge.\n"
202 "\n"
203 ":type: :class:`FEdge`");
204
205static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void * /*closure*/)
206{
207 FEdge *fe = self->fe->previousEdge();
208 if (fe) {
209 return Any_BPy_FEdge_from_FEdge(*fe);
210 }
211 Py_RETURN_NONE;
212}
213
214static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
215{
216 if (!BPy_FEdge_Check(value)) {
217 PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
218 return -1;
219 }
220 self->fe->setPreviousEdge(((BPy_FEdge *)value)->fe);
221 return 0;
222}
223
225 /* Wrap. */
226 FEdge_viewedge_doc,
227 "The ViewEdge to which this FEdge belongs to.\n"
228 "\n"
229 ":type: :class:`ViewEdge`");
230
231static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void * /*closure*/)
232{
233 ViewEdge *ve = self->fe->viewedge();
234 if (ve) {
235 return BPy_ViewEdge_from_ViewEdge(*ve);
236 }
237 Py_RETURN_NONE;
238}
239
240static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
241{
242 if (!BPy_ViewEdge_Check(value)) {
243 PyErr_SetString(PyExc_TypeError, "value must be an ViewEdge");
244 return -1;
245 }
246 self->fe->setViewEdge(((BPy_ViewEdge *)value)->ve);
247 return 0;
248}
249
251 /* Wrap. */
252 FEdge_is_smooth_doc,
253 "True if this FEdge is a smooth FEdge.\n"
254 "\n"
255 ":type: bool");
256
257static PyObject *FEdge_is_smooth_get(BPy_FEdge *self, void * /*closure*/)
258{
259 return PyBool_from_bool(self->fe->isSmooth());
260}
261
262static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
263{
264 if (!PyBool_Check(value)) {
265 PyErr_SetString(PyExc_TypeError, "value must be boolean");
266 return -1;
267 }
268 self->fe->setSmooth(bool_from_PyBool(value));
269 return 0;
270}
271
273 /* Wrap. */
274 FEdge_id_doc,
275 "The Id of this FEdge.\n"
276 "\n"
277 ":type: :class:`Id`");
278
279static PyObject *FEdge_id_get(BPy_FEdge *self, void * /*closure*/)
280{
281 Id id(self->fe->getId());
282 return BPy_Id_from_Id(id); // return a copy
283}
284
285static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
286{
287 if (!BPy_Id_Check(value)) {
288 PyErr_SetString(PyExc_TypeError, "value must be an Id");
289 return -1;
290 }
291 self->fe->setId(*(((BPy_Id *)value)->id));
292 return 0;
293}
294
296 /* Wrap. */
297 FEdge_nature_doc,
298 "The nature of this FEdge.\n"
299 "\n"
300 ":type: :class:`Nature`");
301
302static PyObject *FEdge_nature_get(BPy_FEdge *self, void * /*closure*/)
303{
304 return BPy_Nature_from_Nature(self->fe->getNature());
305}
306
307static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
308{
309 if (!BPy_Nature_Check(value)) {
310 PyErr_SetString(PyExc_TypeError, "value must be a Nature");
311 return -1;
312 }
313 self->fe->setNature(PyLong_AsLong((PyObject *)&((BPy_Nature *)value)->i));
314 return 0;
315}
316
317static PyGetSetDef BPy_FEdge_getseters[] = {
318 {"first_svertex",
321 FEdge_first_svertex_doc,
322 nullptr},
323 {"second_svertex",
326 FEdge_second_svertex_doc,
327 nullptr},
328 {"next_fedge",
329 (getter)FEdge_next_fedge_get,
330 (setter)FEdge_next_fedge_set,
331 FEdge_next_fedge_doc,
332 nullptr},
333 {"previous_fedge",
336 FEdge_previous_fedge_doc,
337 nullptr},
338 {"viewedge",
339 (getter)FEdge_viewedge_get,
340 (setter)FEdge_viewedge_set,
341 FEdge_viewedge_doc,
342 nullptr},
343 {"is_smooth",
344 (getter)FEdge_is_smooth_get,
345 (setter)FEdge_is_smooth_set,
346 FEdge_is_smooth_doc,
347 nullptr},
348 {"id", (getter)FEdge_id_get, (setter)FEdge_id_set, FEdge_id_doc, nullptr},
349 {"nature", (getter)FEdge_nature_get, (setter)FEdge_nature_set, FEdge_nature_doc, nullptr},
350 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
351};
352
353/*-----------------------BPy_FEdge type definition ------------------------------*/
354
355PyTypeObject FEdge_Type = {
356 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
357 /*tp_name*/ "FEdge",
358 /*tp_basicsize*/ sizeof(BPy_FEdge),
359 /*tp_itemsize*/ 0,
360 /*tp_dealloc*/ nullptr,
361 /*tp_vectorcall_offset*/ 0,
362 /*tp_getattr*/ nullptr,
363 /*tp_setattr*/ nullptr,
364 /*tp_as_async*/ nullptr,
365 /*tp_repr*/ nullptr,
366 /*tp_as_number*/ nullptr,
367 /*tp_as_sequence*/ &BPy_FEdge_as_sequence,
368 /*tp_as_mapping*/ nullptr,
369 /*tp_hash*/ nullptr,
370 /*tp_call*/ nullptr,
371 /*tp_str*/ nullptr,
372 /*tp_getattro*/ nullptr,
373 /*tp_setattro*/ nullptr,
374 /*tp_as_buffer*/ nullptr,
375 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
376 /*tp_doc*/ FEdge_doc,
377 /*tp_traverse*/ nullptr,
378 /*tp_clear*/ nullptr,
379 /*tp_richcompare*/ nullptr,
380 /*tp_weaklistoffset*/ 0,
381 /*tp_iter*/ nullptr,
382 /*tp_iternext*/ nullptr,
383 /*tp_methods*/ nullptr,
384 /*tp_members*/ nullptr,
385 /*tp_getset*/ BPy_FEdge_getseters,
386 /*tp_base*/ &Interface1D_Type,
387 /*tp_dict*/ nullptr,
388 /*tp_descr_get*/ nullptr,
389 /*tp_descr_set*/ nullptr,
390 /*tp_dictoffset*/ 0,
391 /*tp_init*/ (initproc)FEdge_init,
392 /*tp_alloc*/ nullptr,
393 /*tp_new*/ nullptr,
394};
395
#define ELEM(...)
PyObject * BPy_Id_from_Id(Id &id)
bool bool_from_PyBool(PyObject *b)
PyObject * Any_BPy_FEdge_from_FEdge(FEdge &fe)
PyObject * BPy_Nature_from_Nature(ushort n)
PyObject * BPy_SVertex_from_SVertex(SVertex &sv)
PyObject * BPy_ViewEdge_from_ViewEdge(ViewEdge &ve)
PyObject * PyBool_from_bool(bool b)
static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void *)
static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void *)
static PyObject * FEdge_id_get(BPy_FEdge *self, void *)
static PyObject * FEdge_viewedge_get(BPy_FEdge *self, void *)
static PyObject * FEdge_first_svertex_get(BPy_FEdge *self, void *)
static PyObject * FEdge_is_smooth_get(BPy_FEdge *self, void *)
static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void *)
static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void *)
static PySequenceMethods BPy_FEdge_as_sequence
static PyObject * FEdge_previous_fedge_get(BPy_FEdge *self, void *)
PyDoc_STRVAR(FEdge_doc, "Class hierarchy: :class:`Interface1D` > :class:`FEdge`\n" "\n" "Base Class for feature edges. This FEdge can represent a silhouette,\n" "a crease, a ridge/valley, a border or a suggestive contour. For\n" "silhouettes, the FEdge is oriented so that the visible face lies on\n" "the left of the edge. For borders, the FEdge is oriented so that the\n" "face lies on the left of the edge. An FEdge can represent an initial\n" "edge of the mesh or runs across a face of the initial mesh depending\n" "on the smoothness or sharpness of the mesh. This class is specialized\n" "into a smooth and a sharp version since their properties slightly vary\n" "from one to the other.\n" "\n" ".. method:: FEdge()\n" " FEdge(brother)\n" "\n" " Builds an :class:`FEdge` using the default constructor,\n" " copy constructor, or between two :class:`SVertex` objects.\n" "\n" " :arg brother: An FEdge object.\n" " :type brother: :class:`FEdge`\n" " :arg first_vertex: The first SVertex.\n" " :type first_vertex: :class:`SVertex`\n" " :arg second_vertex: The second SVertex.\n" " :type second_vertex: :class:`SVertex`")
PyTypeObject FEdge_Type
static PyObject * FEdge_second_svertex_get(BPy_FEdge *self, void *)
static PyObject * FEdge_nature_get(BPy_FEdge *self, void *)
static PyObject * FEdge_sq_item(BPy_FEdge *self, Py_ssize_t keynum)
Definition BPy_FEdge.cpp:87
static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void *)
static Py_ssize_t FEdge_sq_length(BPy_FEdge *)
Definition BPy_FEdge.cpp:82
static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void *)
static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
Definition BPy_FEdge.cpp:51
static PyObject * FEdge_next_fedge_get(BPy_FEdge *self, void *)
static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void *)
static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void *)
static PyGetSetDef BPy_FEdge_getseters[]
#define BPy_FEdge_Check(v)
Definition BPy_FEdge.h:19
#define BPy_Id_Check(v)
Definition BPy_Id.h:23
PyTypeObject Interface1D_Type
#define BPy_Nature_Check(v)
Definition BPy_Nature.h:21
PyTypeObject SVertex_Type
#define BPy_SVertex_Check(v)
Definition BPy_SVertex.h:19
#define BPy_ViewEdge_Check(v)
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
PyObject * self
#define B
inherits from class Rep
Definition AppCanvas.cpp:20
i
Definition text_draw.cc:230