3 * ***** BEGIN GPL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * Contributor(s): Campbell Barton
21 * ***** END GPL LICENSE BLOCK *****
24 /** \file blender/python/mathutils/mathutils_Color.c
25 * \ingroup pymathutils
31 #include "mathutils.h"
34 #include "BLI_utildefines.h"
35 #include "BLI_dynstr.h"
39 //----------------------------------mathutils.Color() -------------------
40 //makes a new color for you to play with
41 static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
43 float col[3] = {0.0f, 0.0f, 0.0f};
45 if (kwds && PyDict_Size(kwds)) {
46 PyErr_SetString(PyExc_TypeError,
48 "takes no keyword args");
52 switch (PyTuple_GET_SIZE(args)) {
56 if ((mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1)
60 PyErr_SetString(PyExc_TypeError,
62 "more then a single arg given");
65 return Color_CreatePyObject(col, Py_NEW, type);
68 //-----------------------------METHODS----------------------------
70 /* note: BaseMath_ReadCallback must be called beforehand */
71 static PyObject *Color_ToTupleExt(ColorObject *self, int ndigits)
76 ret = PyTuple_New(COLOR_SIZE);
79 for (i = 0; i < COLOR_SIZE; i++) {
80 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits)));
84 for (i = 0; i < COLOR_SIZE; i++) {
85 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i]));
92 PyDoc_STRVAR(Color_copy_doc,
93 ".. function:: copy()\n"
95 " Returns a copy of this color.\n"
97 " :return: A copy of the color.\n"
98 " :rtype: :class:`Color`\n"
100 " .. note:: use this to get a copy of a wrapped color with\n"
101 " no reference to the original data.\n"
103 static PyObject *Color_copy(ColorObject *self)
105 if (BaseMath_ReadCallback(self) == -1)
108 return Color_CreatePyObject(self->col, Py_NEW, Py_TYPE(self));
111 //----------------------------print object (internal)--------------
112 //print the object to screen
114 static PyObject *Color_repr(ColorObject *self)
116 PyObject *ret, *tuple;
118 if (BaseMath_ReadCallback(self) == -1)
121 tuple = Color_ToTupleExt(self, -1);
123 ret = PyUnicode_FromFormat("Color(%R)", tuple);
129 static PyObject *Color_str(ColorObject *self)
133 if (BaseMath_ReadCallback(self) == -1)
136 ds = BLI_dynstr_new();
138 BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>",
139 self->col[0], self->col[1], self->col[2]);
141 return mathutils_dynstr_to_py(ds); /* frees ds */
144 //------------------------tp_richcmpr
145 //returns -1 execption, 0 false, 1 true
146 static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
149 int ok = -1; /* zero is true */
151 if (ColorObject_Check(a) && ColorObject_Check(b)) {
152 ColorObject *colA = (ColorObject *)a;
153 ColorObject *colB = (ColorObject *)b;
155 if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1)
158 ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
163 ok = !ok; /* pass through */
165 res = ok ? Py_False : Py_True;
172 res = Py_NotImplemented;
179 return Py_INCREF(res), res;
182 //---------------------SEQUENCE PROTOCOLS------------------------
183 //----------------------------len(object)------------------------
185 static int Color_len(ColorObject *UNUSED(self))
189 //----------------------------object[]---------------------------
190 //sequence accessor (get)
191 static PyObject *Color_item(ColorObject *self, int i)
193 if (i < 0) i = COLOR_SIZE - i;
195 if (i < 0 || i >= COLOR_SIZE) {
196 PyErr_SetString(PyExc_IndexError,
198 "array index out of range");
202 if (BaseMath_ReadIndexCallback(self, i) == -1)
205 return PyFloat_FromDouble(self->col[i]);
208 //----------------------------object[]-------------------------
209 //sequence accessor (set)
210 static int Color_ass_item(ColorObject *self, int i, PyObject *value)
212 float f = PyFloat_AsDouble(value);
214 if (f == -1 && PyErr_Occurred()) { // parsed item not a number
215 PyErr_SetString(PyExc_TypeError,
217 "argument not a number");
221 if (i < 0) i = COLOR_SIZE - i;
223 if (i < 0 || i >= COLOR_SIZE) {
224 PyErr_SetString(PyExc_IndexError, "color[item] = x: "
225 "array assignment index out of range");
231 if (BaseMath_WriteIndexCallback(self, i) == -1)
236 //----------------------------object[z:y]------------------------
237 //sequence slice (get)
238 static PyObject *Color_slice(ColorObject *self, int begin, int end)
243 if (BaseMath_ReadCallback(self) == -1)
246 CLAMP(begin, 0, COLOR_SIZE);
247 if (end < 0) end = (COLOR_SIZE + 1) + end;
248 CLAMP(end, 0, COLOR_SIZE);
249 begin = MIN2(begin, end);
251 tuple = PyTuple_New(end - begin);
252 for (count = begin; count < end; count++) {
253 PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count]));
258 //----------------------------object[z:y]------------------------
259 //sequence slice (set)
260 static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
263 float col[COLOR_SIZE];
265 if (BaseMath_ReadCallback(self) == -1)
268 CLAMP(begin, 0, COLOR_SIZE);
269 if (end < 0) end = (COLOR_SIZE + 1) + end;
270 CLAMP(end, 0, COLOR_SIZE);
271 begin = MIN2(begin, end);
273 if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1)
276 if (size != (end - begin)) {
277 PyErr_SetString(PyExc_ValueError,
278 "color[begin:end] = []: "
279 "size mismatch in slice assignment");
283 for (i = 0; i < COLOR_SIZE; i++)
284 self->col[begin + i] = col[i];
286 (void)BaseMath_WriteCallback(self);
290 static PyObject *Color_subscript(ColorObject *self, PyObject *item)
292 if (PyIndex_Check(item)) {
294 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
295 if (i == -1 && PyErr_Occurred())
299 return Color_item(self, i);
301 else if (PySlice_Check(item)) {
302 Py_ssize_t start, stop, step, slicelength;
304 if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0)
307 if (slicelength <= 0) {
308 return PyTuple_New(0);
310 else if (step == 1) {
311 return Color_slice(self, start, stop);
314 PyErr_SetString(PyExc_IndexError,
315 "slice steps not supported with color");
320 PyErr_Format(PyExc_TypeError,
321 "color indices must be integers, not %.200s",
322 Py_TYPE(item)->tp_name);
327 static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value)
329 if (PyIndex_Check(item)) {
330 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
331 if (i == -1 && PyErr_Occurred())
335 return Color_ass_item(self, i, value);
337 else if (PySlice_Check(item)) {
338 Py_ssize_t start, stop, step, slicelength;
340 if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0)
344 return Color_ass_slice(self, start, stop, value);
346 PyErr_SetString(PyExc_IndexError,
347 "slice steps not supported with color");
352 PyErr_Format(PyExc_TypeError,
353 "color indices must be integers, not %.200s",
354 Py_TYPE(item)->tp_name);
359 //-----------------PROTCOL DECLARATIONS--------------------------
360 static PySequenceMethods Color_SeqMethods = {
361 (lenfunc) Color_len, /* sq_length */
362 (binaryfunc) NULL, /* sq_concat */
363 (ssizeargfunc) NULL, /* sq_repeat */
364 (ssizeargfunc) Color_item, /* sq_item */
365 NULL, /* sq_slice, deprecated */
366 (ssizeobjargproc) Color_ass_item, /* sq_ass_item */
367 NULL, /* sq_ass_slice, deprecated */
368 (objobjproc) NULL, /* sq_contains */
369 (binaryfunc) NULL, /* sq_inplace_concat */
370 (ssizeargfunc) NULL, /* sq_inplace_repeat */
373 static PyMappingMethods Color_AsMapping = {
375 (binaryfunc)Color_subscript,
376 (objobjargproc)Color_ass_subscript
382 /* addition: obj + obj */
383 static PyObject *Color_add(PyObject *v1, PyObject *v2)
385 ColorObject *color1 = NULL, *color2 = NULL;
386 float col[COLOR_SIZE];
388 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
389 PyErr_Format(PyExc_TypeError,
390 "Color addition: (%s + %s) "
391 "invalid type for this operation",
392 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
395 color1 = (ColorObject *)v1;
396 color2 = (ColorObject *)v2;
398 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
401 add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
403 return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1));
406 /* addition in-place: obj += obj */
407 static PyObject *Color_iadd(PyObject *v1, PyObject *v2)
409 ColorObject *color1 = NULL, *color2 = NULL;
411 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
412 PyErr_Format(PyExc_TypeError,
413 "Color addition: (%s += %s) "
414 "invalid type for this operation",
415 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
418 color1 = (ColorObject *)v1;
419 color2 = (ColorObject *)v2;
421 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
424 add_vn_vn(color1->col, color2->col, COLOR_SIZE);
426 (void)BaseMath_WriteCallback(color1);
431 /* subtraction: obj - obj */
432 static PyObject *Color_sub(PyObject *v1, PyObject *v2)
434 ColorObject *color1 = NULL, *color2 = NULL;
435 float col[COLOR_SIZE];
437 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
438 PyErr_Format(PyExc_TypeError,
439 "Color subtraction: (%s - %s) "
440 "invalid type for this operation",
441 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
444 color1 = (ColorObject *)v1;
445 color2 = (ColorObject *)v2;
447 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
450 sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
452 return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1));
455 /* subtraction in-place: obj -= obj */
456 static PyObject *Color_isub(PyObject *v1, PyObject *v2)
458 ColorObject *color1 = NULL, *color2 = NULL;
460 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
461 PyErr_Format(PyExc_TypeError,
462 "Color subtraction: (%s -= %s) "
463 "invalid type for this operation",
464 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
467 color1 = (ColorObject *)v1;
468 color2 = (ColorObject *)v2;
470 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
473 sub_vn_vn(color1->col, color2->col, COLOR_SIZE);
475 (void)BaseMath_WriteCallback(color1);
480 static PyObject *color_mul_float(ColorObject *color, const float scalar)
482 float tcol[COLOR_SIZE];
483 mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar);
484 return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(color));
488 static PyObject *Color_mul(PyObject *v1, PyObject *v2)
490 ColorObject *color1 = NULL, *color2 = NULL;
493 if (ColorObject_Check(v1)) {
494 color1 = (ColorObject *)v1;
495 if (BaseMath_ReadCallback(color1) == -1)
498 if (ColorObject_Check(v2)) {
499 color2 = (ColorObject *)v2;
500 if (BaseMath_ReadCallback(color2) == -1)
505 /* make sure v1 is always the vector */
506 if (color1 && color2) {
507 /* col * col, don't support yet! */
510 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
511 return color_mul_float(color1, scalar);
515 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */
516 return color_mul_float(color2, scalar);
520 BLI_assert(!"internal error");
523 PyErr_Format(PyExc_TypeError,
524 "Color multiplication: not supported between "
525 "'%.200s' and '%.200s' types",
526 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
530 static PyObject *Color_div(PyObject *v1, PyObject *v2)
532 ColorObject *color1 = NULL;
535 if (ColorObject_Check(v1)) {
536 color1 = (ColorObject *)v1;
537 if (BaseMath_ReadCallback(color1) == -1)
541 PyErr_SetString(PyExc_TypeError,
542 "Color division not supported in this order");
546 /* make sure v1 is always the vector */
547 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
548 if (scalar == 0.0f) {
549 PyErr_SetString(PyExc_ZeroDivisionError,
550 "Color division: divide by zero error");
553 return color_mul_float(color1, 1.0f / scalar);
556 PyErr_Format(PyExc_TypeError,
557 "Color multiplication: not supported between "
558 "'%.200s' and '%.200s' types",
559 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
563 /* mulplication in-place: obj *= obj */
564 static PyObject *Color_imul(PyObject *v1, PyObject *v2)
566 ColorObject *color = (ColorObject *)v1;
569 if (BaseMath_ReadCallback(color) == -1)
572 /* only support color *= float */
573 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */
574 mul_vn_fl(color->col, COLOR_SIZE, scalar);
577 PyErr_Format(PyExc_TypeError,
578 "Color multiplication: (%s *= %s) "
579 "invalid type for this operation",
580 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
584 (void)BaseMath_WriteCallback(color);
589 /* mulplication in-place: obj *= obj */
590 static PyObject *Color_idiv(PyObject *v1, PyObject *v2)
592 ColorObject *color = (ColorObject *)v1;
595 if (BaseMath_ReadCallback(color) == -1)
598 /* only support color /= float */
599 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */
600 if (scalar == 0.0f) {
601 PyErr_SetString(PyExc_ZeroDivisionError,
602 "Color division: divide by zero error");
606 mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar);
609 PyErr_Format(PyExc_TypeError,
610 "Color division: (%s /= %s) "
611 "invalid type for this operation",
612 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name);
616 (void)BaseMath_WriteCallback(color);
622 * returns the negative of this object */
623 static PyObject *Color_neg(ColorObject *self)
625 float tcol[COLOR_SIZE];
627 if (BaseMath_ReadCallback(self) == -1)
630 negate_vn_vn(tcol, self->col, COLOR_SIZE);
631 return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(self));
635 static PyNumberMethods Color_NumMethods = {
636 (binaryfunc) Color_add, /*nb_add*/
637 (binaryfunc) Color_sub, /*nb_subtract*/
638 (binaryfunc) Color_mul, /*nb_multiply*/
639 NULL, /*nb_remainder*/
642 (unaryfunc) Color_neg, /*nb_negative*/
643 (unaryfunc) NULL, /*tp_positive*/
644 (unaryfunc) NULL, /*tp_absolute*/
645 (inquiry) NULL, /*tp_bool*/
646 (unaryfunc) NULL, /*nb_invert*/
648 (binaryfunc)NULL, /*nb_rshift*/
653 NULL, /*nb_reserved*/
655 Color_iadd, /* nb_inplace_add */
656 Color_isub, /* nb_inplace_subtract */
657 Color_imul, /* nb_inplace_multiply */
658 NULL, /* nb_inplace_remainder */
659 NULL, /* nb_inplace_power */
660 NULL, /* nb_inplace_lshift */
661 NULL, /* nb_inplace_rshift */
662 NULL, /* nb_inplace_and */
663 NULL, /* nb_inplace_xor */
664 NULL, /* nb_inplace_or */
665 NULL, /* nb_floor_divide */
666 Color_div, /* nb_true_divide */
667 NULL, /* nb_inplace_floor_divide */
668 Color_idiv, /* nb_inplace_true_divide */
672 /* color channel, vector.r/g/b */
673 PyDoc_STRVAR(Color_channel_r_doc, "Red color channel.\n\n:type: float");
674 PyDoc_STRVAR(Color_channel_g_doc, "Green color channel.\n\n:type: float");
675 PyDoc_STRVAR(Color_channel_b_doc, "Blue color channel.\n\n:type: float");
677 static PyObject *Color_channel_get(ColorObject *self, void *type)
679 return Color_item(self, GET_INT_FROM_POINTER(type));
682 static int Color_channel_set(ColorObject *self, PyObject *value, void *type)
684 return Color_ass_item(self, GET_INT_FROM_POINTER(type), value);
687 /* color channel (HSV), color.h/s/v */
688 PyDoc_STRVAR(Color_channel_hsv_h_doc, "HSV Hue component in [0, 1].\n\n:type: float");
689 PyDoc_STRVAR(Color_channel_hsv_s_doc, "HSV Saturation component in [0, 1].\n\n:type: float");
690 PyDoc_STRVAR(Color_channel_hsv_v_doc, "HSV Value component in [0, 1].\n\n:type: float");
692 static PyObject *Color_channel_hsv_get(ColorObject *self, void *type)
695 int i = GET_INT_FROM_POINTER(type);
697 if (BaseMath_ReadCallback(self) == -1)
700 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
702 return PyFloat_FromDouble(hsv[i]);
705 static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
708 int i = GET_INT_FROM_POINTER(type);
709 float f = PyFloat_AsDouble(value);
711 if (f == -1 && PyErr_Occurred()) {
712 PyErr_SetString(PyExc_TypeError,
713 "color.h/s/v = value: "
714 "argument not a number");
718 if (BaseMath_ReadCallback(self) == -1)
721 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
722 CLAMP(f, 0.0f, 1.0f);
724 hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2]));
726 if (BaseMath_WriteCallback(self) == -1)
732 /* color channel (HSV), color.h/s/v */
733 PyDoc_STRVAR(Color_hsv_doc, "HSV Values in [0, 1].\n\n:type: float triplet");
734 static PyObject *Color_hsv_get(ColorObject *self, void *UNUSED(closure))
739 if (BaseMath_ReadCallback(self) == -1)
742 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
744 ret = PyTuple_New(3);
745 PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0]));
746 PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1]));
747 PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2]));
751 static int Color_hsv_set(ColorObject *self, PyObject *value, void *UNUSED(closure))
755 if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1)
758 CLAMP(hsv[0], 0.0f, 1.0f);
759 CLAMP(hsv[1], 0.0f, 1.0f);
760 CLAMP(hsv[2], 0.0f, 1.0f);
762 hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2]));
764 if (BaseMath_WriteCallback(self) == -1)
770 /*****************************************************************************/
771 /* Python attributes get/set structure: */
772 /*****************************************************************************/
773 static PyGetSetDef Color_getseters[] = {
774 {(char *)"r", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_r_doc, (void *)0},
775 {(char *)"g", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_g_doc, (void *)1},
776 {(char *)"b", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_b_doc, (void *)2},
778 {(char *)"h", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_h_doc, (void *)0},
779 {(char *)"s", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_s_doc, (void *)1},
780 {(char *)"v", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_v_doc, (void *)2},
782 {(char *)"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, (char *)Color_hsv_doc, (void *)0},
784 {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
785 {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
786 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
790 //-----------------------METHOD DEFINITIONS ----------------------
791 static struct PyMethodDef Color_methods[] = {
792 {"__copy__", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
793 {"copy", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
794 {NULL, NULL, 0, NULL}
797 //------------------PY_OBECT DEFINITION--------------------------
798 PyDoc_STRVAR(color_doc,
799 "This object gives access to Colors in Blender."
801 PyTypeObject color_Type = {
802 PyVarObject_HEAD_INIT(NULL, 0)
803 "mathutils.Color", //tp_name
804 sizeof(ColorObject), //tp_basicsize
806 (destructor)BaseMathObject_dealloc, //tp_dealloc
811 (reprfunc) Color_repr, //tp_repr
812 &Color_NumMethods, //tp_as_number
813 &Color_SeqMethods, //tp_as_sequence
814 &Color_AsMapping, //tp_as_mapping
817 (reprfunc) Color_str, //tp_str
821 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
823 (traverseproc)BaseMathObject_traverse, //tp_traverse
824 (inquiry)BaseMathObject_clear, //tp_clear
825 (richcmpfunc)Color_richcmpr, //tp_richcompare
826 0, //tp_weaklistoffset
829 Color_methods, //tp_methods
831 Color_getseters, //tp_getset
845 NULL, //tp_subclasses
849 //------------------------Color_CreatePyObject (internal)-------------
850 //creates a new color object
851 /* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
852 * (i.e. it was allocated elsewhere by MEM_mallocN())
853 * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
854 * (i.e. it must be created here with PyMEM_malloc())*/
855 PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type)
859 self = base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) :
860 (ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
863 /* init callbacks as NULL */
864 self->cb_user = NULL;
865 self->cb_type = self->cb_subtype = 0;
867 if (type == Py_WRAP) {
869 self->wrapped = Py_WRAP;
871 else if (type == Py_NEW) {
872 self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
874 copy_v3_v3(self->col, col);
878 self->wrapped = Py_NEW;
881 Py_FatalError("Color(): invalid type!");
885 return (PyObject *)self;
888 PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
889 unsigned char cb_type, unsigned char cb_subtype)
891 ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL);
894 self->cb_user = cb_user;
895 self->cb_type = cb_type;
896 self->cb_subtype = cb_subtype;
897 PyObject_GC_Track(self);
900 return (PyObject *)self;