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