Blender V4.3
BPy_FrsMaterial.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_FrsMaterial.h"
10
11#include "BPy_Convert.h"
12
13#include "BLI_hash_mm2a.hh"
14#include "BLI_math_vector.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20using namespace Freestyle;
21
23
24//-------------------MODULE INITIALIZATION--------------------------------
26{
27 if (module == nullptr) {
28 return -1;
29 }
30
31 if (PyType_Ready(&FrsMaterial_Type) < 0) {
32 return -1;
33 }
34 PyModule_AddObjectRef(module, "Material", (PyObject *)&FrsMaterial_Type);
35
37
38 return 0;
39}
40
41//------------------------INSTANCE METHODS ----------------------------------
42
44 /* Wrap. */
45 FrsMaterial_doc,
46 "Class defining a material.\n"
47 "\n"
48 ".. method:: __init__()\n"
49 " __init__(brother)\n"
50 " __init__(line, diffuse, ambient, specular, emission, shininess, priority)\n"
51 "\n"
52 " Creates a :class:`FrsMaterial` using either default constructor,\n"
53 " copy constructor, or an overloaded constructor\n"
54 "\n"
55 " :arg brother: A Material object to be used as a copy constructor.\n"
56 " :type brother: :class:`Material`\n"
57 " :arg line: The line color.\n"
58 " :type line: :class:`mathutils.Vector` | tuple[float, float, float, float] | list[float]\n"
59 " :arg diffuse: The diffuse color.\n"
60 " :type diffuse: \n"
61 " :arg ambient: The ambient color.\n"
62 " :type ambient: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
63 "list[float]\n"
64 " :arg specular: The specular color.\n"
65 " :type specular: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
66 "list[float]\n"
67 " :arg emission: The emissive color.\n"
68 " :type emission: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
69 "list[float]\n"
70 " :arg shininess: The shininess coefficient.\n"
71 " :type shininess: float\n"
72 " :arg priority: The line color priority.\n"
73 " :type priority: int");
74
75static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds)
76{
77 static const char *kwlist_1[] = {"brother", nullptr};
78 static const char *kwlist_2[] = {
79 "line", "diffuse", "ambient", "specular", "emission", "shininess", "priority", nullptr};
80 PyObject *brother = nullptr;
81 float line[4], diffuse[4], ambient[4], specular[4], emission[4], shininess;
82 int priority;
83
84 if (PyArg_ParseTupleAndKeywords(
85 args, kwds, "|O!", (char **)kwlist_1, &FrsMaterial_Type, &brother))
86 {
87 if (!brother) {
88 self->m = new FrsMaterial();
89 }
90 else {
91 FrsMaterial *m = ((BPy_FrsMaterial *)brother)->m;
92 if (!m) {
93 PyErr_SetString(PyExc_RuntimeError, "invalid Material object");
94 return -1;
95 }
96 self->m = new FrsMaterial(*m);
97 }
98 }
99 else if ((void)PyErr_Clear(),
100 PyArg_ParseTupleAndKeywords(args,
101 kwds,
102 "O&O&O&O&O&fi",
103 (char **)kwlist_2,
105 line,
107 diffuse,
109 ambient,
111 specular,
113 emission,
114 &shininess,
115 &priority))
116 {
117 self->m = new FrsMaterial(line, diffuse, ambient, specular, emission, shininess, priority);
118 }
119 else {
120 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
121 return -1;
122 }
123 return 0;
124}
125
127{
128 delete self->m;
129 Py_TYPE(self)->tp_free((PyObject *)self);
130}
131
133{
134 return PyUnicode_FromFormat("Material - address: %p", self->m);
135}
136
137/*----------------------mathutils callbacks ----------------------------*/
138
139/* subtype */
140#define MATHUTILS_SUBTYPE_DIFFUSE 1
141#define MATHUTILS_SUBTYPE_SPECULAR 2
142#define MATHUTILS_SUBTYPE_AMBIENT 3
143#define MATHUTILS_SUBTYPE_EMISSION 4
144#define MATHUTILS_SUBTYPE_LINE 5
145
147{
148 if (!BPy_FrsMaterial_Check(bmo->cb_user)) {
149 return -1;
150 }
151 return 0;
152}
153
154static int FrsMaterial_mathutils_get(BaseMathObject *bmo, int subtype)
155{
156 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
157 switch (subtype) {
159 bmo->data[0] = self->m->lineR();
160 bmo->data[1] = self->m->lineG();
161 bmo->data[2] = self->m->lineB();
162 bmo->data[3] = self->m->lineA();
163 break;
165 bmo->data[0] = self->m->diffuseR();
166 bmo->data[1] = self->m->diffuseG();
167 bmo->data[2] = self->m->diffuseB();
168 bmo->data[3] = self->m->diffuseA();
169 break;
171 bmo->data[0] = self->m->specularR();
172 bmo->data[1] = self->m->specularG();
173 bmo->data[2] = self->m->specularB();
174 bmo->data[3] = self->m->specularA();
175 break;
177 bmo->data[0] = self->m->ambientR();
178 bmo->data[1] = self->m->ambientG();
179 bmo->data[2] = self->m->ambientB();
180 bmo->data[3] = self->m->ambientA();
181 break;
183 bmo->data[0] = self->m->emissionR();
184 bmo->data[1] = self->m->emissionG();
185 bmo->data[2] = self->m->emissionB();
186 bmo->data[3] = self->m->emissionA();
187 break;
188 default:
189 return -1;
190 }
191 return 0;
192}
193
194static int FrsMaterial_mathutils_set(BaseMathObject *bmo, int subtype)
195{
196 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
197 switch (subtype) {
199 self->m->setLine(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
200 break;
202 self->m->setDiffuse(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
203 break;
205 self->m->setSpecular(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
206 break;
208 self->m->setAmbient(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
209 break;
211 self->m->setEmission(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
212 break;
213 default:
214 return -1;
215 }
216 return 0;
217}
218
219static int FrsMaterial_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
220{
221 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
222 switch (subtype) {
224 const float *color = self->m->line();
225 bmo->data[index] = color[index];
226 break;
227 }
229 const float *color = self->m->diffuse();
230 bmo->data[index] = color[index];
231 break;
232 }
234 const float *color = self->m->specular();
235 bmo->data[index] = color[index];
236 break;
237 }
239 const float *color = self->m->ambient();
240 bmo->data[index] = color[index];
241 break;
242 }
244 const float *color = self->m->emission();
245 bmo->data[index] = color[index];
246 break;
247 }
248 default:
249 return -1;
250 }
251 return 0;
252}
253
254static int FrsMaterial_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
255{
256 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
257 float color[4];
258 switch (subtype) {
260 copy_v4_v4(color, self->m->line());
261 color[index] = bmo->data[index];
262 self->m->setLine(color[0], color[1], color[2], color[3]);
263 break;
265 copy_v4_v4(color, self->m->diffuse());
266 color[index] = bmo->data[index];
267 self->m->setDiffuse(color[0], color[1], color[2], color[3]);
268 break;
270 copy_v4_v4(color, self->m->specular());
271 color[index] = bmo->data[index];
272 self->m->setSpecular(color[0], color[1], color[2], color[3]);
273 break;
275 copy_v4_v4(color, self->m->ambient());
276 color[index] = bmo->data[index];
277 self->m->setAmbient(color[0], color[1], color[2], color[3]);
278 break;
280 copy_v4_v4(color, self->m->emission());
281 color[index] = bmo->data[index];
282 self->m->setEmission(color[0], color[1], color[2], color[3]);
283 break;
284 default:
285 return -1;
286 }
287 return 0;
288}
289
297
299
304
305/*----------------------FrsMaterial get/setters ----------------------------*/
306
308 /* Wrap. */
309 FrsMaterial_line_doc,
310 "RGBA components of the line color of the material.\n"
311 "\n"
312 ":type: :class:`mathutils.Vector`");
313
314static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void * /*closure*/)
315{
318}
319
320static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
321{
322 float color[4];
323 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
324 return -1;
325 }
326 self->m->setLine(color[0], color[1], color[2], color[3]);
327 return 0;
328}
329
331 /* Wrap. */
332 FrsMaterial_diffuse_doc,
333 "RGBA components of the diffuse color of the material.\n"
334 "\n"
335 ":type: :class:`mathutils.Vector`");
336
337static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void * /*closure*/)
338{
341}
342
343static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
344{
345 float color[4];
346 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
347 return -1;
348 }
349 self->m->setDiffuse(color[0], color[1], color[2], color[3]);
350 return 0;
351}
352
354 /* Wrap. */
355 FrsMaterial_specular_doc,
356 "RGBA components of the specular color of the material.\n"
357 "\n"
358 ":type: :class:`mathutils.Vector`");
359
360static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void * /*closure*/)
361{
364}
365
366static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
367{
368 float color[4];
369 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
370 return -1;
371 }
372 self->m->setSpecular(color[0], color[1], color[2], color[3]);
373 return 0;
374}
375
377 /* Wrap. */
378 FrsMaterial_ambient_doc,
379 "RGBA components of the ambient color of the material.\n"
380 "\n"
381 ":type: :class:`mathutils.Color`");
382
383static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void * /*closure*/)
384{
387}
388
389static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
390{
391 float color[4];
392 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
393 return -1;
394 }
395 self->m->setAmbient(color[0], color[1], color[2], color[3]);
396 return 0;
397}
398
400 /* Wrap. */
401 FrsMaterial_emission_doc,
402 "RGBA components of the emissive color of the material.\n"
403 "\n"
404 ":type: :class:`mathutils.Color`");
405
406static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void * /*closure*/)
407{
410}
411
412static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
413{
414 float color[4];
415 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
416 return -1;
417 }
418 self->m->setEmission(color[0], color[1], color[2], color[3]);
419 return 0;
420}
421
423 /* Wrap. */
424 FrsMaterial_shininess_doc,
425 "Shininess coefficient of the material.\n"
426 "\n"
427 ":type: float");
428
429static PyObject *FrsMaterial_shininess_get(BPy_FrsMaterial *self, void * /*closure*/)
430{
431 return PyFloat_FromDouble(self->m->shininess());
432}
433
434static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
435{
436 float scalar;
437 if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
438 /* parsed item not a number */
439 PyErr_SetString(PyExc_TypeError, "value must be a number");
440 return -1;
441 }
442 self->m->setShininess(scalar);
443 return 0;
444}
445
447 /* Wrap. */
448 FrsMaterial_priority_doc,
449 "Line color priority of the material.\n"
450 "\n"
451 ":type: int");
452
453static PyObject *FrsMaterial_priority_get(BPy_FrsMaterial *self, void * /*closure*/)
454{
455 return PyLong_FromLong(self->m->priority());
456}
457
458static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
459{
460 int scalar;
461 if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
462 PyErr_SetString(PyExc_TypeError, "value must be an integer");
463 return -1;
464 }
465 self->m->setPriority(scalar);
466 return 0;
467}
468
469static PyGetSetDef BPy_FrsMaterial_getseters[] = {
470 {"line",
471 (getter)FrsMaterial_line_get,
472 (setter)FrsMaterial_line_set,
473 FrsMaterial_line_doc,
474 nullptr},
475 {"diffuse",
478 FrsMaterial_diffuse_doc,
479 nullptr},
480 {"specular",
483 FrsMaterial_specular_doc,
484 nullptr},
485 {"ambient",
488 FrsMaterial_ambient_doc,
489 nullptr},
490 {"emission",
493 FrsMaterial_emission_doc,
494 nullptr},
495 {"shininess",
498 FrsMaterial_shininess_doc,
499 nullptr},
500 {"priority",
503 FrsMaterial_priority_doc,
504 nullptr},
505 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
506};
507
508static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
509 PyObject *objectB,
510 int comparison_type)
511{
512 const BPy_FrsMaterial *matA = nullptr, *matB = nullptr;
513 bool result = false;
514
515 if (!BPy_FrsMaterial_Check(objectA) || !BPy_FrsMaterial_Check(objectB)) {
516 if (comparison_type == Py_NE) {
517 Py_RETURN_TRUE;
518 }
519
520 Py_RETURN_FALSE;
521 }
522
523 matA = (BPy_FrsMaterial *)objectA;
524 matB = (BPy_FrsMaterial *)objectB;
525
526 switch (comparison_type) {
527 case Py_NE:
528 result = (*matA->m) != (*matB->m);
529 break;
530 case Py_EQ:
531 result = (*matA->m) == (*matB->m);
532 break;
533 default:
534 PyErr_SetString(PyExc_TypeError, "Material does not support this comparison type");
535 return nullptr;
536 }
537
538 if (result == true) {
539 Py_RETURN_TRUE;
540 }
541
542 Py_RETURN_FALSE;
543}
544
545static Py_hash_t FrsMaterial_hash(PyObject *self)
546{
547 return (Py_uhash_t)BLI_hash_mm2((const uchar *)self, sizeof(*self), 0);
548}
549/*-----------------------BPy_FrsMaterial type definition ------------------------------*/
550
551PyTypeObject FrsMaterial_Type = {
552 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
553 /*tp_name*/ "Material",
554 /*tp_basicsize*/ sizeof(BPy_FrsMaterial),
555 /*tp_itemsize*/ 0,
556 /*tp_dealloc*/ (destructor)FrsMaterial_dealloc,
557 /*tp_vectorcall_offset*/ 0,
558 /*tp_getattr*/ nullptr,
559 /*tp_setattr*/ nullptr,
560 /*tp_as_async*/ nullptr,
561 /*tp_repr*/ (reprfunc)FrsMaterial_repr,
562 /*tp_as_number*/ nullptr,
563 /*tp_as_sequence*/ nullptr,
564 /*tp_as_mapping*/ nullptr,
565 /*tp_hash*/ (hashfunc)FrsMaterial_hash,
566 /*tp_call*/ nullptr,
567 /*tp_str*/ nullptr,
568 /*tp_getattro*/ nullptr,
569 /*tp_setattro*/ nullptr,
570 /*tp_as_buffer*/ nullptr,
571 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
572 /*tp_doc*/ FrsMaterial_doc,
573 /*tp_traverse*/ nullptr,
574 /*tp_clear*/ nullptr,
575 /*tp_richcompare*/ (richcmpfunc)BPy_FrsMaterial_richcmpr,
576 /*tp_weaklistoffset*/ 0,
577 /*tp_iter*/ nullptr,
578 /*tp_iternext*/ nullptr,
579 /*tp_methods*/ nullptr,
580 /*tp_members*/ nullptr,
581 /*tp_getset*/ BPy_FrsMaterial_getseters,
582 /*tp_base*/ nullptr,
583 /*tp_dict*/ nullptr,
584 /*tp_descr_get*/ nullptr,
585 /*tp_descr_set*/ nullptr,
586 /*tp_dictoffset*/ 0,
587 /*tp_init*/ (initproc)FrsMaterial_init,
588 /*tp_alloc*/ nullptr,
589 /*tp_new*/ PyType_GenericNew,
590};
591
593
594#ifdef __cplusplus
595}
596#endif
uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
Definition hash_mm2a.cc:100
MINLINE void copy_v4_v4(float r[4], const float a[4])
unsigned char uchar
int convert_v4(PyObject *obj, void *v)
void FrsMaterial_mathutils_register_callback()
int FrsMaterial_Init(PyObject *module)
static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void *)
#define MATHUTILS_SUBTYPE_DIFFUSE
static PyGetSetDef BPy_FrsMaterial_getseters[]
static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void *)
static PyObject * FrsMaterial_specular_get(BPy_FrsMaterial *self, void *)
static void FrsMaterial_dealloc(BPy_FrsMaterial *self)
static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void *)
static PyObject * BPy_FrsMaterial_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
static PyObject * FrsMaterial_line_get(BPy_FrsMaterial *self, void *)
static int FrsMaterial_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
static PyObject * FrsMaterial_emission_get(BPy_FrsMaterial *self, void *)
static PyObject * FrsMaterial_ambient_get(BPy_FrsMaterial *self, void *)
static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void *)
static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds)
#define MATHUTILS_SUBTYPE_EMISSION
#define MATHUTILS_SUBTYPE_LINE
static Mathutils_Callback FrsMaterial_mathutils_cb
PyTypeObject FrsMaterial_Type
static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void *)
static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void *)
static int FrsMaterial_mathutils_set(BaseMathObject *bmo, int subtype)
#define MATHUTILS_SUBTYPE_SPECULAR
static PyObject * FrsMaterial_shininess_get(BPy_FrsMaterial *self, void *)
static PyObject * FrsMaterial_repr(BPy_FrsMaterial *self)
#define MATHUTILS_SUBTYPE_AMBIENT
static int FrsMaterial_mathutils_get(BaseMathObject *bmo, int subtype)
PyDoc_STRVAR(FrsMaterial_doc, "Class defining a material.\n" "\n" ".. method:: __init__()\n" " __init__(brother)\n" " __init__(line, diffuse, ambient, specular, emission, shininess, priority)\n" "\n" " Creates a :class:`FrsMaterial` using either default constructor,\n" " copy constructor, or an overloaded constructor\n" "\n" " :arg brother: A Material object to be used as a copy constructor.\n" " :type brother: :class:`Material`\n" " :arg line: The line color.\n" " :type line: :class:`mathutils.Vector` | tuple[float, float, float, float] | list[float]\n" " :arg diffuse: The diffuse color.\n" " :type diffuse: \n" " :arg ambient: The ambient color.\n" " :type ambient: :class:`mathutils.Vector` | tuple[float, float, float, float] | " "list[float]\n" " :arg specular: The specular color.\n" " :type specular: :class:`mathutils.Vector` | tuple[float, float, float, float] | " "list[float]\n" " :arg emission: The emissive color.\n" " :type emission: :class:`mathutils.Vector` | tuple[float, float, float, float] | " "list[float]\n" " :arg shininess: The shininess coefficient.\n" " :type shininess: float\n" " :arg priority: The line color priority.\n" " :type priority: int")
static uchar FrsMaterial_mathutils_cb_index
static int FrsMaterial_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
static PyObject * FrsMaterial_priority_get(BPy_FrsMaterial *self, void *)
static PyObject * FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void *)
static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void *)
static int FrsMaterial_mathutils_check(BaseMathObject *bmo)
static Py_hash_t FrsMaterial_hash(PyObject *self)
#define BPy_FrsMaterial_Check(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
PyObject * self
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition mathutils.cc:97
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition mathutils.cc:522
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
inherits from class Rep
Definition AppCanvas.cpp:20
static struct PyModuleDef module
Definition python.cpp:991
PyObject_HEAD Freestyle::FrsMaterial * m