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
17 /** \file
18 * \ingroup freestyle
19 */
20
21 #include "BPy_FEdgeSharp.h"
22
23 #include "../../BPy_Convert.h"
24 #include "../../Interface0D/BPy_SVertex.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 ///////////////////////////////////////////////////////////////////////////////////////////
31
32 /*----------------------FEdgeSharp methods ----------------------------*/
33
34 PyDoc_STRVAR(FEdgeSharp_doc,
35 "Class hierarchy: :class:`Interface1D` > :class:`FEdge` > :class:`FEdgeSharp`\n"
36 "\n"
37 "Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial\n"
38 "edge of the input mesh. It can be a silhouette, a crease or a border.\n"
39 "If it is a crease edge, then it is bordered by two faces of the mesh.\n"
40 "Face a lies on its right whereas Face b lies on its left. If it is a\n"
41 "border edge, then it doesn't have any face on its right, and thus Face\n"
42 "a is None.\n"
43 "\n"
44 ".. method:: __init__()\n"
45 " __init__(brother)\n"
46 " __init__(first_vertex, second_vertex)\n"
47 "\n"
48 " Builds an :class:`FEdgeSharp` using the default constructor,\n"
49 " copy constructor, or between two :class:`SVertex` objects.\n"
50 "\n"
51 " :arg brother: An FEdgeSharp object.\n"
52 " :type brother: :class:`FEdgeSharp`\n"
53 " :arg first_vertex: The first SVertex object.\n"
54 " :type first_vertex: :class:`SVertex`\n"
55 " :arg second_vertex: The second SVertex object.\n"
56 " :type second_vertex: :class:`SVertex`");
57
FEdgeSharp_init(BPy_FEdgeSharp * self,PyObject * args,PyObject * kwds)58 static int FEdgeSharp_init(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds)
59 {
60 static const char *kwlist_1[] = {"brother", NULL};
61 static const char *kwlist_2[] = {"first_vertex", "second_vertex", NULL};
62 PyObject *obj1 = 0, *obj2 = 0;
63
64 if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdgeSharp_Type, &obj1)) {
65 if (!obj1) {
66 self->fes = new FEdgeSharp();
67 }
68 else {
69 self->fes = new FEdgeSharp(*(((BPy_FEdgeSharp *)obj1)->fes));
70 }
71 }
72 else if ((void)PyErr_Clear(),
73 PyArg_ParseTupleAndKeywords(args,
74 kwds,
75 "O!O!",
76 (char **)kwlist_2,
77 &SVertex_Type,
78 &obj1,
79 &SVertex_Type,
80 &obj2)) {
81 self->fes = new FEdgeSharp(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
82 }
83 else {
84 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
85 return -1;
86 }
87 self->py_fe.fe = self->fes;
88 self->py_fe.py_if1D.if1D = self->fes;
89 self->py_fe.py_if1D.borrowed = false;
90 return 0;
91 }
92
93 /*----------------------mathutils callbacks ----------------------------*/
94
95 /* subtype */
96 #define MATHUTILS_SUBTYPE_NORMAL_A 1
97 #define MATHUTILS_SUBTYPE_NORMAL_B 2
98
FEdgeSharp_mathutils_check(BaseMathObject * bmo)99 static int FEdgeSharp_mathutils_check(BaseMathObject *bmo)
100 {
101 if (!BPy_FEdgeSharp_Check(bmo->cb_user)) {
102 return -1;
103 }
104 return 0;
105 }
106
FEdgeSharp_mathutils_get(BaseMathObject * bmo,int subtype)107 static int FEdgeSharp_mathutils_get(BaseMathObject *bmo, int subtype)
108 {
109 BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
110 switch (subtype) {
111 case MATHUTILS_SUBTYPE_NORMAL_A: {
112 Vec3r p(self->fes->normalA());
113 bmo->data[0] = p[0];
114 bmo->data[1] = p[1];
115 bmo->data[2] = p[2];
116 } break;
117 case MATHUTILS_SUBTYPE_NORMAL_B: {
118 Vec3r p(self->fes->normalB());
119 bmo->data[0] = p[0];
120 bmo->data[1] = p[1];
121 bmo->data[2] = p[2];
122 } break;
123 default:
124 return -1;
125 }
126 return 0;
127 }
128
FEdgeSharp_mathutils_set(BaseMathObject * bmo,int subtype)129 static int FEdgeSharp_mathutils_set(BaseMathObject *bmo, int subtype)
130 {
131 BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
132 switch (subtype) {
133 case MATHUTILS_SUBTYPE_NORMAL_A: {
134 Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
135 self->fes->setNormalA(p);
136 } break;
137 case MATHUTILS_SUBTYPE_NORMAL_B: {
138 Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
139 self->fes->setNormalB(p);
140 } break;
141 default:
142 return -1;
143 }
144 return 0;
145 }
146
FEdgeSharp_mathutils_get_index(BaseMathObject * bmo,int subtype,int index)147 static int FEdgeSharp_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
148 {
149 BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
150 switch (subtype) {
151 case MATHUTILS_SUBTYPE_NORMAL_A: {
152 Vec3r p(self->fes->normalA());
153 bmo->data[index] = p[index];
154 } break;
155 case MATHUTILS_SUBTYPE_NORMAL_B: {
156 Vec3r p(self->fes->normalB());
157 bmo->data[index] = p[index];
158 } break;
159 default:
160 return -1;
161 }
162 return 0;
163 }
164
FEdgeSharp_mathutils_set_index(BaseMathObject * bmo,int subtype,int index)165 static int FEdgeSharp_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
166 {
167 BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
168 switch (subtype) {
169 case MATHUTILS_SUBTYPE_NORMAL_A: {
170 Vec3r p(self->fes->normalA());
171 p[index] = bmo->data[index];
172 self->fes->setNormalA(p);
173 } break;
174 case MATHUTILS_SUBTYPE_NORMAL_B: {
175 Vec3r p(self->fes->normalB());
176 p[index] = bmo->data[index];
177 self->fes->setNormalB(p);
178 } break;
179 default:
180 return -1;
181 }
182 return 0;
183 }
184
185 static Mathutils_Callback FEdgeSharp_mathutils_cb = {
186 FEdgeSharp_mathutils_check,
187 FEdgeSharp_mathutils_get,
188 FEdgeSharp_mathutils_set,
189 FEdgeSharp_mathutils_get_index,
190 FEdgeSharp_mathutils_set_index,
191 };
192
193 static unsigned char FEdgeSharp_mathutils_cb_index = -1;
194
FEdgeSharp_mathutils_register_callback()195 void FEdgeSharp_mathutils_register_callback()
196 {
197 FEdgeSharp_mathutils_cb_index = Mathutils_RegisterCallback(&FEdgeSharp_mathutils_cb);
198 }
199
200 /*----------------------FEdgeSharp get/setters ----------------------------*/
201
202 PyDoc_STRVAR(FEdgeSharp_normal_right_doc,
203 "The normal to the face lying on the right of the FEdge. If this FEdge\n"
204 "is a border, it has no Face on its right and therefore no normal.\n"
205 "\n"
206 ":type: :class:`mathutils.Vector`");
207
FEdgeSharp_normal_right_get(BPy_FEdgeSharp * self,void * UNUSED (closure))208 static PyObject *FEdgeSharp_normal_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
209 {
210 return Vector_CreatePyObject_cb(
211 (PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_A);
212 }
213
FEdgeSharp_normal_right_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))214 static int FEdgeSharp_normal_right_set(BPy_FEdgeSharp *self,
215 PyObject *value,
216 void *UNUSED(closure))
217 {
218 float v[3];
219 if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
220 return -1;
221 }
222 Vec3r p(v[0], v[1], v[2]);
223 self->fes->setNormalA(p);
224 return 0;
225 }
226
227 PyDoc_STRVAR(FEdgeSharp_normal_left_doc,
228 "The normal to the face lying on the left of the FEdge.\n"
229 "\n"
230 ":type: :class:`mathutils.Vector`");
231
FEdgeSharp_normal_left_get(BPy_FEdgeSharp * self,void * UNUSED (closure))232 static PyObject *FEdgeSharp_normal_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
233 {
234 return Vector_CreatePyObject_cb(
235 (PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_B);
236 }
237
FEdgeSharp_normal_left_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))238 static int FEdgeSharp_normal_left_set(BPy_FEdgeSharp *self, PyObject *value, void *UNUSED(closure))
239 {
240 float v[3];
241 if (mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1) {
242 return -1;
243 }
244 Vec3r p(v[0], v[1], v[2]);
245 self->fes->setNormalB(p);
246 return 0;
247 }
248
249 PyDoc_STRVAR(FEdgeSharp_material_index_right_doc,
250 "The index of the material of the face lying on the right of the FEdge.\n"
251 "If this FEdge is a border, it has no Face on its right and therefore\n"
252 "no material.\n"
253 "\n"
254 ":type: int");
255
FEdgeSharp_material_index_right_get(BPy_FEdgeSharp * self,void * UNUSED (closure))256 static PyObject *FEdgeSharp_material_index_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
257 {
258 return PyLong_FromLong(self->fes->aFrsMaterialIndex());
259 }
260
FEdgeSharp_material_index_right_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))261 static int FEdgeSharp_material_index_right_set(BPy_FEdgeSharp *self,
262 PyObject *value,
263 void *UNUSED(closure))
264 {
265 unsigned int i = PyLong_AsUnsignedLong(value);
266 if (PyErr_Occurred()) {
267 return -1;
268 }
269 self->fes->setaFrsMaterialIndex(i);
270 return 0;
271 }
272
273 PyDoc_STRVAR(FEdgeSharp_material_index_left_doc,
274 "The index of the material of the face lying on the left of the FEdge.\n"
275 "\n"
276 ":type: int");
277
FEdgeSharp_material_index_left_get(BPy_FEdgeSharp * self,void * UNUSED (closure))278 static PyObject *FEdgeSharp_material_index_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
279 {
280 return PyLong_FromLong(self->fes->bFrsMaterialIndex());
281 }
282
FEdgeSharp_material_index_left_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))283 static int FEdgeSharp_material_index_left_set(BPy_FEdgeSharp *self,
284 PyObject *value,
285 void *UNUSED(closure))
286 {
287 unsigned int i = PyLong_AsUnsignedLong(value);
288 if (PyErr_Occurred()) {
289 return -1;
290 }
291 self->fes->setbFrsMaterialIndex(i);
292 return 0;
293 }
294
295 PyDoc_STRVAR(FEdgeSharp_material_right_doc,
296 "The material of the face lying on the right of the FEdge. If this FEdge\n"
297 "is a border, it has no Face on its right and therefore no material.\n"
298 "\n"
299 ":type: :class:`Material`");
300
FEdgeSharp_material_right_get(BPy_FEdgeSharp * self,void * UNUSED (closure))301 static PyObject *FEdgeSharp_material_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
302 {
303 return BPy_FrsMaterial_from_FrsMaterial(self->fes->aFrsMaterial());
304 }
305
306 PyDoc_STRVAR(FEdgeSharp_material_left_doc,
307 "The material of the face lying on the left of the FEdge.\n"
308 "\n"
309 ":type: :class:`Material`");
310
FEdgeSharp_material_left_get(BPy_FEdgeSharp * self,void * UNUSED (closure))311 static PyObject *FEdgeSharp_material_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
312 {
313 return BPy_FrsMaterial_from_FrsMaterial(self->fes->bFrsMaterial());
314 }
315
316 PyDoc_STRVAR(FEdgeSharp_face_mark_right_doc,
317 "The face mark of the face lying on the right of the FEdge. If this FEdge\n"
318 "is a border, it has no face on the right and thus this property is set to\n"
319 "false.\n"
320 "\n"
321 ":type: bool");
322
FEdgeSharp_face_mark_right_get(BPy_FEdgeSharp * self,void * UNUSED (closure))323 static PyObject *FEdgeSharp_face_mark_right_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
324 {
325 return PyBool_from_bool(self->fes->aFaceMark());
326 }
327
FEdgeSharp_face_mark_right_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))328 static int FEdgeSharp_face_mark_right_set(BPy_FEdgeSharp *self,
329 PyObject *value,
330 void *UNUSED(closure))
331 {
332 if (!PyBool_Check(value)) {
333 return -1;
334 }
335 self->fes->setaFaceMark(bool_from_PyBool(value));
336 return 0;
337 }
338
339 PyDoc_STRVAR(FEdgeSharp_face_mark_left_doc,
340 "The face mark of the face lying on the left of the FEdge.\n"
341 "\n"
342 ":type: bool");
343
FEdgeSharp_face_mark_left_get(BPy_FEdgeSharp * self,void * UNUSED (closure))344 static PyObject *FEdgeSharp_face_mark_left_get(BPy_FEdgeSharp *self, void *UNUSED(closure))
345 {
346 return PyBool_from_bool(self->fes->bFaceMark());
347 }
348
FEdgeSharp_face_mark_left_set(BPy_FEdgeSharp * self,PyObject * value,void * UNUSED (closure))349 static int FEdgeSharp_face_mark_left_set(BPy_FEdgeSharp *self,
350 PyObject *value,
351 void *UNUSED(closure))
352 {
353 if (!PyBool_Check(value)) {
354 return -1;
355 }
356 self->fes->setbFaceMark(bool_from_PyBool(value));
357 return 0;
358 }
359
360 static PyGetSetDef BPy_FEdgeSharp_getseters[] = {
361 {"normal_right",
362 (getter)FEdgeSharp_normal_right_get,
363 (setter)FEdgeSharp_normal_right_set,
364 FEdgeSharp_normal_right_doc,
365 NULL},
366 {"normal_left",
367 (getter)FEdgeSharp_normal_left_get,
368 (setter)FEdgeSharp_normal_left_set,
369 FEdgeSharp_normal_left_doc,
370 NULL},
371 {"material_index_right",
372 (getter)FEdgeSharp_material_index_right_get,
373 (setter)FEdgeSharp_material_index_right_set,
374 FEdgeSharp_material_index_right_doc,
375 NULL},
376 {"material_index_left",
377 (getter)FEdgeSharp_material_index_left_get,
378 (setter)FEdgeSharp_material_index_left_set,
379 FEdgeSharp_material_index_left_doc,
380 NULL},
381 {"material_right",
382 (getter)FEdgeSharp_material_right_get,
383 (setter)NULL,
384 FEdgeSharp_material_right_doc,
385 NULL},
386 {"material_left",
387 (getter)FEdgeSharp_material_left_get,
388 (setter)NULL,
389 FEdgeSharp_material_left_doc,
390 NULL},
391 {"face_mark_right",
392 (getter)FEdgeSharp_face_mark_right_get,
393 (setter)FEdgeSharp_face_mark_right_set,
394 FEdgeSharp_face_mark_right_doc,
395 NULL},
396 {"face_mark_left",
397 (getter)FEdgeSharp_face_mark_left_get,
398 (setter)FEdgeSharp_face_mark_left_set,
399 FEdgeSharp_face_mark_left_doc,
400 NULL},
401 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
402 };
403
404 /*-----------------------BPy_FEdgeSharp type definition ------------------------------*/
405
406 PyTypeObject FEdgeSharp_Type = {
407 PyVarObject_HEAD_INIT(NULL, 0) "FEdgeSharp", /* tp_name */
408 sizeof(BPy_FEdgeSharp), /* tp_basicsize */
409 0, /* tp_itemsize */
410 0, /* tp_dealloc */
411 0, /* tp_print */
412 0, /* tp_getattr */
413 0, /* tp_setattr */
414 0, /* tp_reserved */
415 0, /* tp_repr */
416 0, /* tp_as_number */
417 0, /* tp_as_sequence */
418 0, /* tp_as_mapping */
419 0, /* tp_hash */
420 0, /* tp_call */
421 0, /* tp_str */
422 0, /* tp_getattro */
423 0, /* tp_setattro */
424 0, /* tp_as_buffer */
425 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
426 FEdgeSharp_doc, /* tp_doc */
427 0, /* tp_traverse */
428 0, /* tp_clear */
429 0, /* tp_richcompare */
430 0, /* tp_weaklistoffset */
431 0, /* tp_iter */
432 0, /* tp_iternext */
433 0, /* tp_methods */
434 0, /* tp_members */
435 BPy_FEdgeSharp_getseters, /* tp_getset */
436 &FEdge_Type, /* tp_base */
437 0, /* tp_dict */
438 0, /* tp_descr_get */
439 0, /* tp_descr_set */
440 0, /* tp_dictoffset */
441 (initproc)FEdgeSharp_init, /* tp_init */
442 0, /* tp_alloc */
443 0, /* tp_new */
444 };
445
446 ///////////////////////////////////////////////////////////////////////////////////////////
447
448 #ifdef __cplusplus
449 }
450 #endif
451