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