Blender V5.0
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`\n");
50static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
51{
52 static const char *kwlist_1[] = {"brother", nullptr};
53 static const char *kwlist_2[] = {"first_vertex", "second_vertex", nullptr};
54 PyObject *obj1 = nullptr, *obj2 = nullptr;
55
56 if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdge_Type, &obj1)) {
57 if (!obj1) {
58 self->fe = new FEdge();
59 }
60 else {
61 self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe));
62 }
63 }
64 else if ((void)PyErr_Clear(),
65 PyArg_ParseTupleAndKeywords(
66 args, kwds, "O!O!", (char **)kwlist_2, &SVertex_Type, &obj1, &SVertex_Type, &obj2))
67 {
68 self->fe = new FEdge(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
69 }
70 else {
71 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
72 return -1;
73 }
74 self->py_if1D.if1D = self->fe;
75 self->py_if1D.borrowed = false;
76 return 0;
77}
78
79/*----------------------FEdge sequence protocol ----------------------------*/
80
81static Py_ssize_t FEdge_sq_length(BPy_FEdge * /*self*/)
82{
83 return 2;
84}
85
86static PyObject *FEdge_sq_item(BPy_FEdge *self, Py_ssize_t keynum)
87{
88 if (keynum < 0) {
89 keynum += FEdge_sq_length(self);
90 }
91 if (ELEM(keynum, 0, 1)) {
92 SVertex *v = self->fe->operator[](keynum);
93 if (v) {
95 }
96 Py_RETURN_NONE;
97 }
98 PyErr_Format(PyExc_IndexError, "FEdge[index]: index %d out of range", keynum);
99 return nullptr;
100}
101
102static PySequenceMethods BPy_FEdge_as_sequence = {
103 /*sq_length*/ (lenfunc)FEdge_sq_length,
104 /*sq_concat*/ nullptr,
105 /*sq_repeat*/ nullptr,
106 /*sq_item*/ (ssizeargfunc)FEdge_sq_item,
107 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
108 /*sq_ass_item*/ nullptr,
109 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
110 /*sq_contains*/ nullptr,
111 /*sq_inplace_concat*/ nullptr,
112 /*sq_inplace_repeat*/ nullptr,
113};
114
115/*----------------------FEdge get/setters ----------------------------*/
116
118 /* Wrap. */
119 FEdge_first_svertex_doc,
120 "The first SVertex constituting this FEdge.\n"
121 "\n"
122 ":type: :class:`SVertex`\n");
123static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void * /*closure*/)
124{
125 SVertex *A = self->fe->vertexA();
126 if (A) {
128 }
129 Py_RETURN_NONE;
130}
131
132static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
133{
134 if (!BPy_SVertex_Check(value)) {
135 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
136 return -1;
137 }
138 self->fe->setVertexA(((BPy_SVertex *)value)->sv);
139 return 0;
140}
141
143 /* Wrap. */
144 FEdge_second_svertex_doc,
145 "The second SVertex constituting this FEdge.\n"
146 "\n"
147 ":type: :class:`SVertex`\n");
148static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void * /*closure*/)
149{
150 SVertex *B = self->fe->vertexB();
151 if (B) {
153 }
154 Py_RETURN_NONE;
155}
156
157static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
158{
159 if (!BPy_SVertex_Check(value)) {
160 PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
161 return -1;
162 }
163 self->fe->setVertexB(((BPy_SVertex *)value)->sv);
164 return 0;
165}
166
168 /* Wrap. */
169 FEdge_next_fedge_doc,
170 "The FEdge following this one in the ViewEdge. The value is None if\n"
171 "this FEdge is the last of the ViewEdge.\n"
172 "\n"
173 ":type: :class:`FEdge`\n");
174static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void * /*closure*/)
175{
176 FEdge *fe = self->fe->nextEdge();
177 if (fe) {
178 return Any_BPy_FEdge_from_FEdge(*fe);
179 }
180 Py_RETURN_NONE;
181}
182
183static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
184{
185 if (!BPy_FEdge_Check(value)) {
186 PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
187 return -1;
188 }
189 self->fe->setNextEdge(((BPy_FEdge *)value)->fe);
190 return 0;
191}
192
194 /* Wrap. */
195 FEdge_previous_fedge_doc,
196 "The FEdge preceding this one in the ViewEdge. The value is None if\n"
197 "this FEdge is the first one of the ViewEdge.\n"
198 "\n"
199 ":type: :class:`FEdge`\n");
200static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void * /*closure*/)
201{
202 FEdge *fe = self->fe->previousEdge();
203 if (fe) {
204 return Any_BPy_FEdge_from_FEdge(*fe);
205 }
206 Py_RETURN_NONE;
207}
208
209static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
210{
211 if (!BPy_FEdge_Check(value)) {
212 PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
213 return -1;
214 }
215 self->fe->setPreviousEdge(((BPy_FEdge *)value)->fe);
216 return 0;
217}
218
220 /* Wrap. */
221 FEdge_viewedge_doc,
222 "The ViewEdge to which this FEdge belongs to.\n"
223 "\n"
224 ":type: :class:`ViewEdge`\n");
225static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void * /*closure*/)
226{
227 ViewEdge *ve = self->fe->viewedge();
228 if (ve) {
229 return BPy_ViewEdge_from_ViewEdge(*ve);
230 }
231 Py_RETURN_NONE;
232}
233
234static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
235{
236 if (!BPy_ViewEdge_Check(value)) {
237 PyErr_SetString(PyExc_TypeError, "value must be an ViewEdge");
238 return -1;
239 }
240 self->fe->setViewEdge(((BPy_ViewEdge *)value)->ve);
241 return 0;
242}
243
245 /* Wrap. */
246 FEdge_is_smooth_doc,
247 "True if this FEdge is a smooth FEdge.\n"
248 "\n"
249 ":type: bool\n");
250static PyObject *FEdge_is_smooth_get(BPy_FEdge *self, void * /*closure*/)
251{
252 return PyBool_from_bool(self->fe->isSmooth());
253}
254
255static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
256{
257 if (!PyBool_Check(value)) {
258 PyErr_SetString(PyExc_TypeError, "value must be boolean");
259 return -1;
260 }
261 self->fe->setSmooth(bool_from_PyBool(value));
262 return 0;
263}
264
266 /* Wrap. */
267 FEdge_id_doc,
268 "The Id of this FEdge.\n"
269 "\n"
270 ":type: :class:`Id`\n");
271static PyObject *FEdge_id_get(BPy_FEdge *self, void * /*closure*/)
272{
273 Id id(self->fe->getId());
274 return BPy_Id_from_Id(id); // return a copy
275}
276
277static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
278{
279 if (!BPy_Id_Check(value)) {
280 PyErr_SetString(PyExc_TypeError, "value must be an Id");
281 return -1;
282 }
283 self->fe->setId(*(((BPy_Id *)value)->id));
284 return 0;
285}
286
288 /* Wrap. */
289 FEdge_nature_doc,
290 "The nature of this FEdge.\n"
291 "\n"
292 ":type: :class:`Nature`\n");
293static PyObject *FEdge_nature_get(BPy_FEdge *self, void * /*closure*/)
294{
295 return BPy_Nature_from_Nature(self->fe->getNature());
296}
297
298static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
299{
300 if (!BPy_Nature_Check(value)) {
301 PyErr_SetString(PyExc_TypeError, "value must be a Nature");
302 return -1;
303 }
304 self->fe->setNature(PyLong_AsLong((PyObject *)&((BPy_Nature *)value)->i));
305 return 0;
306}
307
308static PyGetSetDef BPy_FEdge_getseters[] = {
309 {"first_svertex",
312 FEdge_first_svertex_doc,
313 nullptr},
314 {"second_svertex",
317 FEdge_second_svertex_doc,
318 nullptr},
319 {"next_fedge",
320 (getter)FEdge_next_fedge_get,
321 (setter)FEdge_next_fedge_set,
322 FEdge_next_fedge_doc,
323 nullptr},
324 {"previous_fedge",
327 FEdge_previous_fedge_doc,
328 nullptr},
329 {"viewedge",
330 (getter)FEdge_viewedge_get,
331 (setter)FEdge_viewedge_set,
332 FEdge_viewedge_doc,
333 nullptr},
334 {"is_smooth",
335 (getter)FEdge_is_smooth_get,
336 (setter)FEdge_is_smooth_set,
337 FEdge_is_smooth_doc,
338 nullptr},
339 {"id", (getter)FEdge_id_get, (setter)FEdge_id_set, FEdge_id_doc, nullptr},
340 {"nature", (getter)FEdge_nature_get, (setter)FEdge_nature_set, FEdge_nature_doc, nullptr},
341 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
342};
343
344/*-----------------------BPy_FEdge type definition ------------------------------*/
345
346PyTypeObject FEdge_Type = {
347 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
348 /*tp_name*/ "FEdge",
349 /*tp_basicsize*/ sizeof(BPy_FEdge),
350 /*tp_itemsize*/ 0,
351 /*tp_dealloc*/ nullptr,
352 /*tp_vectorcall_offset*/ 0,
353 /*tp_getattr*/ nullptr,
354 /*tp_setattr*/ nullptr,
355 /*tp_as_async*/ nullptr,
356 /*tp_repr*/ nullptr,
357 /*tp_as_number*/ nullptr,
358 /*tp_as_sequence*/ &BPy_FEdge_as_sequence,
359 /*tp_as_mapping*/ nullptr,
360 /*tp_hash*/ nullptr,
361 /*tp_call*/ nullptr,
362 /*tp_str*/ nullptr,
363 /*tp_getattro*/ nullptr,
364 /*tp_setattro*/ nullptr,
365 /*tp_as_buffer*/ nullptr,
366 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
367 /*tp_doc*/ FEdge_doc,
368 /*tp_traverse*/ nullptr,
369 /*tp_clear*/ nullptr,
370 /*tp_richcompare*/ nullptr,
371 /*tp_weaklistoffset*/ 0,
372 /*tp_iter*/ nullptr,
373 /*tp_iternext*/ nullptr,
374 /*tp_methods*/ nullptr,
375 /*tp_members*/ nullptr,
376 /*tp_getset*/ BPy_FEdge_getseters,
377 /*tp_base*/ &Interface1D_Type,
378 /*tp_dict*/ nullptr,
379 /*tp_descr_get*/ nullptr,
380 /*tp_descr_set*/ nullptr,
381 /*tp_dictoffset*/ 0,
382 /*tp_init*/ (initproc)FEdge_init,
383 /*tp_alloc*/ nullptr,
384 /*tp_new*/ nullptr,
385};
386
#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`\n")
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:86
static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void *)
static Py_ssize_t FEdge_sq_length(BPy_FEdge *)
Definition BPy_FEdge.cpp:81
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:50
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