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