Blender V4.5
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
16using namespace Freestyle;
17
19
20//-------------------MODULE INITIALIZATION--------------------------------
21int FrsMaterial_Init(PyObject *module)
22{
23 if (module == nullptr) {
24 return -1;
25 }
26
27 if (PyType_Ready(&FrsMaterial_Type) < 0) {
28 return -1;
29 }
30 PyModule_AddObjectRef(module, "Material", (PyObject *)&FrsMaterial_Type);
31
33
34 return 0;
35}
36
37//------------------------INSTANCE METHODS ----------------------------------
38
40 /* Wrap. */
41 FrsMaterial_doc,
42 "Class defining a material.\n"
43 "\n"
44 ".. method:: __init__()\n"
45 " __init__(brother)\n"
46 " __init__(line, diffuse, ambient, specular, emission, shininess, priority)\n"
47 "\n"
48 " Creates a :class:`FrsMaterial` using either default constructor,\n"
49 " copy constructor, or an overloaded constructor\n"
50 "\n"
51 " :arg brother: A Material object to be used as a copy constructor.\n"
52 " :type brother: :class:`Material`\n"
53 " :arg line: The line color.\n"
54 " :type line: :class:`mathutils.Vector` | tuple[float, float, float, float] | list[float]\n"
55 " :arg diffuse: The diffuse color.\n"
56 " :type diffuse: \n"
57 " :arg ambient: The ambient color.\n"
58 " :type ambient: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
59 "list[float]\n"
60 " :arg specular: The specular color.\n"
61 " :type specular: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
62 "list[float]\n"
63 " :arg emission: The emissive color.\n"
64 " :type emission: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
65 "list[float]\n"
66 " :arg shininess: The shininess coefficient.\n"
67 " :type shininess: float\n"
68 " :arg priority: The line color priority.\n"
69 " :type priority: int");
70
71static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds)
72{
73 static const char *kwlist_1[] = {"brother", nullptr};
74 static const char *kwlist_2[] = {
75 "line", "diffuse", "ambient", "specular", "emission", "shininess", "priority", nullptr};
76 PyObject *brother = nullptr;
77 float line[4], diffuse[4], ambient[4], specular[4], emission[4], shininess;
78 int priority;
79
80 if (PyArg_ParseTupleAndKeywords(
81 args, kwds, "|O!", (char **)kwlist_1, &FrsMaterial_Type, &brother))
82 {
83 if (!brother) {
84 self->m = new FrsMaterial();
85 }
86 else {
87 FrsMaterial *m = ((BPy_FrsMaterial *)brother)->m;
88 if (!m) {
89 PyErr_SetString(PyExc_RuntimeError, "invalid Material object");
90 return -1;
91 }
92 self->m = new FrsMaterial(*m);
93 }
94 }
95 else if ((void)PyErr_Clear(),
96 PyArg_ParseTupleAndKeywords(args,
97 kwds,
98 "O&O&O&O&O&fi",
99 (char **)kwlist_2,
101 line,
103 diffuse,
105 ambient,
107 specular,
109 emission,
110 &shininess,
111 &priority))
112 {
113 self->m = new FrsMaterial(line, diffuse, ambient, specular, emission, shininess, priority);
114 }
115 else {
116 PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
117 return -1;
118 }
119 return 0;
120}
121
123{
124 delete self->m;
125 Py_TYPE(self)->tp_free((PyObject *)self);
126}
127
128static PyObject *FrsMaterial_repr(BPy_FrsMaterial *self)
129{
130 return PyUnicode_FromFormat("Material - address: %p", self->m);
131}
132
133/*----------------------mathutils callbacks ----------------------------*/
134
135/* subtype */
136#define MATHUTILS_SUBTYPE_DIFFUSE 1
137#define MATHUTILS_SUBTYPE_SPECULAR 2
138#define MATHUTILS_SUBTYPE_AMBIENT 3
139#define MATHUTILS_SUBTYPE_EMISSION 4
140#define MATHUTILS_SUBTYPE_LINE 5
141
143{
144 if (!BPy_FrsMaterial_Check(bmo->cb_user)) {
145 return -1;
146 }
147 return 0;
148}
149
150static int FrsMaterial_mathutils_get(BaseMathObject *bmo, int subtype)
151{
152 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
153 switch (subtype) {
155 bmo->data[0] = self->m->lineR();
156 bmo->data[1] = self->m->lineG();
157 bmo->data[2] = self->m->lineB();
158 bmo->data[3] = self->m->lineA();
159 break;
161 bmo->data[0] = self->m->diffuseR();
162 bmo->data[1] = self->m->diffuseG();
163 bmo->data[2] = self->m->diffuseB();
164 bmo->data[3] = self->m->diffuseA();
165 break;
167 bmo->data[0] = self->m->specularR();
168 bmo->data[1] = self->m->specularG();
169 bmo->data[2] = self->m->specularB();
170 bmo->data[3] = self->m->specularA();
171 break;
173 bmo->data[0] = self->m->ambientR();
174 bmo->data[1] = self->m->ambientG();
175 bmo->data[2] = self->m->ambientB();
176 bmo->data[3] = self->m->ambientA();
177 break;
179 bmo->data[0] = self->m->emissionR();
180 bmo->data[1] = self->m->emissionG();
181 bmo->data[2] = self->m->emissionB();
182 bmo->data[3] = self->m->emissionA();
183 break;
184 default:
185 return -1;
186 }
187 return 0;
188}
189
190static int FrsMaterial_mathutils_set(BaseMathObject *bmo, int subtype)
191{
192 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
193 switch (subtype) {
195 self->m->setLine(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
196 break;
198 self->m->setDiffuse(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
199 break;
201 self->m->setSpecular(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
202 break;
204 self->m->setAmbient(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
205 break;
207 self->m->setEmission(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
208 break;
209 default:
210 return -1;
211 }
212 return 0;
213}
214
215static int FrsMaterial_mathutils_get_index(BaseMathObject *bmo, int subtype, int index)
216{
217 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
218 switch (subtype) {
220 const float *color = self->m->line();
221 bmo->data[index] = color[index];
222 break;
223 }
225 const float *color = self->m->diffuse();
226 bmo->data[index] = color[index];
227 break;
228 }
230 const float *color = self->m->specular();
231 bmo->data[index] = color[index];
232 break;
233 }
235 const float *color = self->m->ambient();
236 bmo->data[index] = color[index];
237 break;
238 }
240 const float *color = self->m->emission();
241 bmo->data[index] = color[index];
242 break;
243 }
244 default:
245 return -1;
246 }
247 return 0;
248}
249
250static int FrsMaterial_mathutils_set_index(BaseMathObject *bmo, int subtype, int index)
251{
252 BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
253 float color[4];
254 switch (subtype) {
256 copy_v4_v4(color, self->m->line());
257 color[index] = bmo->data[index];
258 self->m->setLine(color[0], color[1], color[2], color[3]);
259 break;
261 copy_v4_v4(color, self->m->diffuse());
262 color[index] = bmo->data[index];
263 self->m->setDiffuse(color[0], color[1], color[2], color[3]);
264 break;
266 copy_v4_v4(color, self->m->specular());
267 color[index] = bmo->data[index];
268 self->m->setSpecular(color[0], color[1], color[2], color[3]);
269 break;
271 copy_v4_v4(color, self->m->ambient());
272 color[index] = bmo->data[index];
273 self->m->setAmbient(color[0], color[1], color[2], color[3]);
274 break;
276 copy_v4_v4(color, self->m->emission());
277 color[index] = bmo->data[index];
278 self->m->setEmission(color[0], color[1], color[2], color[3]);
279 break;
280 default:
281 return -1;
282 }
283 return 0;
284}
285
293
295
300
301/*----------------------FrsMaterial get/setters ----------------------------*/
302
304 /* Wrap. */
305 FrsMaterial_line_doc,
306 "RGBA components of the line color of the material.\n"
307 "\n"
308 ":type: :class:`mathutils.Vector`");
309
310static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void * /*closure*/)
311{
314}
315
316static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
317{
318 float color[4];
319 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
320 return -1;
321 }
322 self->m->setLine(color[0], color[1], color[2], color[3]);
323 return 0;
324}
325
327 /* Wrap. */
328 FrsMaterial_diffuse_doc,
329 "RGBA components of the diffuse color of the material.\n"
330 "\n"
331 ":type: :class:`mathutils.Vector`");
332
333static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void * /*closure*/)
334{
337}
338
339static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
340{
341 float color[4];
342 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
343 return -1;
344 }
345 self->m->setDiffuse(color[0], color[1], color[2], color[3]);
346 return 0;
347}
348
350 /* Wrap. */
351 FrsMaterial_specular_doc,
352 "RGBA components of the specular color of the material.\n"
353 "\n"
354 ":type: :class:`mathutils.Vector`");
355
356static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void * /*closure*/)
357{
360}
361
362static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
363{
364 float color[4];
365 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
366 return -1;
367 }
368 self->m->setSpecular(color[0], color[1], color[2], color[3]);
369 return 0;
370}
371
373 /* Wrap. */
374 FrsMaterial_ambient_doc,
375 "RGBA components of the ambient color of the material.\n"
376 "\n"
377 ":type: :class:`mathutils.Color`");
378
379static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void * /*closure*/)
380{
383}
384
385static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
386{
387 float color[4];
388 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
389 return -1;
390 }
391 self->m->setAmbient(color[0], color[1], color[2], color[3]);
392 return 0;
393}
394
396 /* Wrap. */
397 FrsMaterial_emission_doc,
398 "RGBA components of the emissive color of the material.\n"
399 "\n"
400 ":type: :class:`mathutils.Color`");
401
402static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void * /*closure*/)
403{
406}
407
408static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
409{
410 float color[4];
411 if (mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") == -1) {
412 return -1;
413 }
414 self->m->setEmission(color[0], color[1], color[2], color[3]);
415 return 0;
416}
417
419 /* Wrap. */
420 FrsMaterial_shininess_doc,
421 "Shininess coefficient of the material.\n"
422 "\n"
423 ":type: float");
424
425static PyObject *FrsMaterial_shininess_get(BPy_FrsMaterial *self, void * /*closure*/)
426{
427 return PyFloat_FromDouble(self->m->shininess());
428}
429
430static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
431{
432 float scalar;
433 if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
434 /* parsed item not a number */
435 PyErr_SetString(PyExc_TypeError, "value must be a number");
436 return -1;
437 }
438 self->m->setShininess(scalar);
439 return 0;
440}
441
443 /* Wrap. */
444 FrsMaterial_priority_doc,
445 "Line color priority of the material.\n"
446 "\n"
447 ":type: int");
448
449static PyObject *FrsMaterial_priority_get(BPy_FrsMaterial *self, void * /*closure*/)
450{
451 return PyLong_FromLong(self->m->priority());
452}
453
454static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
455{
456 int scalar;
457 if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
458 PyErr_SetString(PyExc_TypeError, "value must be an integer");
459 return -1;
460 }
461 self->m->setPriority(scalar);
462 return 0;
463}
464
465static PyGetSetDef BPy_FrsMaterial_getseters[] = {
466 {"line",
467 (getter)FrsMaterial_line_get,
468 (setter)FrsMaterial_line_set,
469 FrsMaterial_line_doc,
470 nullptr},
471 {"diffuse",
474 FrsMaterial_diffuse_doc,
475 nullptr},
476 {"specular",
479 FrsMaterial_specular_doc,
480 nullptr},
481 {"ambient",
484 FrsMaterial_ambient_doc,
485 nullptr},
486 {"emission",
489 FrsMaterial_emission_doc,
490 nullptr},
491 {"shininess",
494 FrsMaterial_shininess_doc,
495 nullptr},
496 {"priority",
499 FrsMaterial_priority_doc,
500 nullptr},
501 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
502};
503
504static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
505 PyObject *objectB,
506 int comparison_type)
507{
508 const BPy_FrsMaterial *matA = nullptr, *matB = nullptr;
509 bool result = false;
510
511 if (!BPy_FrsMaterial_Check(objectA) || !BPy_FrsMaterial_Check(objectB)) {
512 if (comparison_type == Py_NE) {
513 Py_RETURN_TRUE;
514 }
515
516 Py_RETURN_FALSE;
517 }
518
519 matA = (BPy_FrsMaterial *)objectA;
520 matB = (BPy_FrsMaterial *)objectB;
521
522 switch (comparison_type) {
523 case Py_NE:
524 result = (*matA->m) != (*matB->m);
525 break;
526 case Py_EQ:
527 result = (*matA->m) == (*matB->m);
528 break;
529 default:
530 PyErr_SetString(PyExc_TypeError, "Material does not support this comparison type");
531 return nullptr;
532 }
533
534 if (result == true) {
535 Py_RETURN_TRUE;
536 }
537
538 Py_RETURN_FALSE;
539}
540
541static Py_hash_t FrsMaterial_hash(PyObject *self)
542{
543 return (Py_uhash_t)BLI_hash_mm2((const uchar *)self, sizeof(*self), 0);
544}
545/*-----------------------BPy_FrsMaterial type definition ------------------------------*/
546
547PyTypeObject FrsMaterial_Type = {
548 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
549 /*tp_name*/ "Material",
550 /*tp_basicsize*/ sizeof(BPy_FrsMaterial),
551 /*tp_itemsize*/ 0,
552 /*tp_dealloc*/ (destructor)FrsMaterial_dealloc,
553 /*tp_vectorcall_offset*/ 0,
554 /*tp_getattr*/ nullptr,
555 /*tp_setattr*/ nullptr,
556 /*tp_as_async*/ nullptr,
557 /*tp_repr*/ (reprfunc)FrsMaterial_repr,
558 /*tp_as_number*/ nullptr,
559 /*tp_as_sequence*/ nullptr,
560 /*tp_as_mapping*/ nullptr,
561 /*tp_hash*/ (hashfunc)FrsMaterial_hash,
562 /*tp_call*/ nullptr,
563 /*tp_str*/ nullptr,
564 /*tp_getattro*/ nullptr,
565 /*tp_setattro*/ nullptr,
566 /*tp_as_buffer*/ nullptr,
567 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
568 /*tp_doc*/ FrsMaterial_doc,
569 /*tp_traverse*/ nullptr,
570 /*tp_clear*/ nullptr,
571 /*tp_richcompare*/ (richcmpfunc)BPy_FrsMaterial_richcmpr,
572 /*tp_weaklistoffset*/ 0,
573 /*tp_iter*/ nullptr,
574 /*tp_iternext*/ nullptr,
575 /*tp_methods*/ nullptr,
576 /*tp_members*/ nullptr,
577 /*tp_getset*/ BPy_FrsMaterial_getseters,
578 /*tp_base*/ nullptr,
579 /*tp_dict*/ nullptr,
580 /*tp_descr_get*/ nullptr,
581 /*tp_descr_set*/ nullptr,
582 /*tp_dictoffset*/ 0,
583 /*tp_init*/ (initproc)FrsMaterial_init,
584 /*tp_alloc*/ nullptr,
585 /*tp_new*/ PyType_GenericNew,
586};
587
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)
PyDoc_STRVAR(FalseBP1D___doc__, "Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`FalseBP1D`\n" "\n" ".. method:: __call__(inter1, inter2)\n" "\n" " Always returns false.\n" "\n" " :arg inter1: The first Interface1D object.\n" " :type inter1: :class:`freestyle.types.Interface1D`\n" " :arg inter2: The second Interface1D object.\n" " :type inter2: :class:`freestyle.types.Interface1D`\n" " :return: False.\n" " :rtype: bool\n")
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)
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)
const float * ambient() const
void setShininess(float s)
const float ambientB() const
const float specularR() const
const float lineB() const
Definition FrsMaterial.h:74
const float * specular() const
const float specularB() const
const float specularG() const
void setPriority(int priority)
const float diffuseG() const
Definition FrsMaterial.h:98
const float emissionA() const
const float emissionR() const
void setDiffuse(float r, float g, float b, float a)
const float ambientG() const
void setLine(float r, float g, float b, float a)
void setAmbient(float r, float g, float b, float a)
const float ambientR() const
const float * diffuse() const
Definition FrsMaterial.h:86
const float lineR() const
Definition FrsMaterial.h:62
const float * line() const
Definition FrsMaterial.h:56
const int priority() const
const float * emission() const
void setSpecular(float r, float g, float b, float a)
const float emissionB() const
const float specularA() const
const float diffuseR() const
Definition FrsMaterial.h:92
const float diffuseA() const
const float lineA() const
Definition FrsMaterial.h:80
const float ambientA() const
void setEmission(float r, float g, float b, float a)
const float lineG() const
Definition FrsMaterial.h:68
const float diffuseB() const
const float shininess() const
const float emissionG() const
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition mathutils.cc:96
uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
Definition mathutils.cc:521
PyObject * Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
inherits from class Rep
Definition AppCanvas.cpp:20
PyObject_HEAD Freestyle::FrsMaterial * m