Blender V5.0
mathutils_Color.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10
11#include <Python.h>
12
13#include "mathutils.hh"
14
15#include "BLI_utildefines.h"
16
19
20#ifndef MATH_STANDALONE
21# include "IMB_colormanagement.hh"
22#endif
23
24#ifndef MATH_STANDALONE
25# include "BLI_dynstr.h"
26#endif
27
28#define COLOR_SIZE 3
29
30/* -------------------------------------------------------------------- */
33
37static PyObject *Color_to_tuple_ex(ColorObject *self, int ndigits)
38{
39 PyObject *ret;
40 int i;
41
42 ret = PyTuple_New(COLOR_SIZE);
43
44 if (ndigits >= 0) {
45 for (i = 0; i < COLOR_SIZE; i++) {
46 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round(double(self->col[i]), ndigits)));
47 }
48 }
49 else {
50 for (i = 0; i < COLOR_SIZE; i++) {
51 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i]));
52 }
53 }
54
55 return ret;
56}
57
59
60/* -------------------------------------------------------------------- */
63
64static PyObject *Color_vectorcall(PyObject *type,
65 PyObject *const *args,
66 const size_t nargsf,
67 PyObject *kwnames)
68{
69 if (UNLIKELY(kwnames && PyTuple_GET_SIZE(kwnames))) {
70 PyErr_SetString(PyExc_TypeError,
71 "mathutils.Color(): "
72 "takes no keyword args");
73 return nullptr;
74 }
75
76 float col[3] = {0.0f, 0.0f, 0.0f};
77
78 const size_t nargs = PyVectorcall_NARGS(nargsf);
79 switch (nargs) {
80 case 0: {
81 break;
82 }
83 case 1: {
84 if (mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, args[0], "mathutils.Color()") == -1) {
85 return nullptr;
86 }
87 break;
88 }
89 default: {
90 PyErr_Format(PyExc_TypeError,
91 "mathutils.Color(): "
92 "takes at most 1 argument (%zd given)",
93 nargs);
94 return nullptr;
95 }
96 }
97 return Color_CreatePyObject(col, (PyTypeObject *)type);
98}
99
100static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
101{
102 /* Only called on sub-classes. */
103 if (UNLIKELY(kwds && PyDict_GET_SIZE(kwds))) {
104 PyErr_SetString(PyExc_TypeError,
105 "mathutils.Color(): "
106 "takes no keyword args");
107 return nullptr;
108 }
109 PyObject *const *args_array = &PyTuple_GET_ITEM(args, 0);
110 const size_t args_array_num = PyTuple_GET_SIZE(args);
111 return Color_vectorcall(reinterpret_cast<PyObject *>(type), args_array, args_array_num, nullptr);
112}
113
115
116/* -------------------------------------------------------------------- */
119
120#ifndef MATH_STANDALONE
121
123 /* Wrap. */
124 Color_from_scene_linear_to_srgb_doc,
125 ".. function:: from_scene_linear_to_srgb()\n"
126 "\n"
127 " Convert from scene linear to sRGB color space.\n"
128 "\n"
129 " :return: A color in sRGB color space.\n"
130 " :rtype: :class:`Color`\n");
132{
133 float col[3];
135 return Color_CreatePyObject(col, Py_TYPE(self));
136}
137
139 /* Wrap. */
140 Color_from_srgb_to_scene_linear_doc,
141 ".. function:: from_srgb_to_scene_linear()\n"
142 "\n"
143 " Convert from sRGB to scene linear color space.\n"
144 "\n"
145 " :return: A color in scene linear color space.\n"
146 " :rtype: :class:`Color`\n");
148{
149 float col[3];
151 return Color_CreatePyObject(col, Py_TYPE(self));
152}
153
155 /* Wrap. */
156 Color_from_scene_linear_to_xyz_d65_doc,
157 ".. function:: from_scene_linear_to_xyz_d65()\n"
158 "\n"
159 " Convert from scene linear to CIE XYZ (Illuminant D65) color space.\n"
160 "\n"
161 " :return: A color in XYZ color space.\n"
162 " :rtype: :class:`Color`\n");
164{
165 float col[3];
167 return Color_CreatePyObject(col, Py_TYPE(self));
168}
169
171 /* Wrap. */
172 Color_from_xyz_d65_to_scene_linear_doc,
173 ".. function:: from_xyz_d65_to_scene_linear()\n"
174 "\n"
175 " Convert from CIE XYZ (Illuminant D65) to scene linear color space.\n"
176 "\n"
177 " :return: A color in scene linear color space.\n"
178 " :rtype: :class:`Color`\n");
180{
181 float col[3];
183 return Color_CreatePyObject(col, Py_TYPE(self));
184}
185
187 /* Wrap. */
188 Color_from_scene_linear_to_aces_doc,
189 ".. function:: from_scene_linear_to_aces()\n"
190 "\n"
191 " Convert from scene linear to ACES2065-1 linear color space.\n"
192 "\n"
193 " :return: A color in ACES2065-1 linear color space.\n"
194 " :rtype: :class:`Color`\n");
196{
197 float col[3];
199 return Color_CreatePyObject(col, Py_TYPE(self));
200}
201
203 /* Wrap. */
204 Color_from_aces_to_scene_linear_doc,
205 ".. function:: from_aces_to_scene_linear()\n"
206 "\n"
207 " Convert from ACES2065-1 linear to scene linear color space.\n"
208 "\n"
209 " :return: A color in scene linear color space.\n"
210 " :rtype: :class:`Color`\n");
212{
213 float col[3];
215 return Color_CreatePyObject(col, Py_TYPE(self));
216}
217
219 /* Wrap. */
220 Color_from_scene_linear_to_acescg_doc,
221 ".. function:: from_scene_linear_to_acescg()\n"
222 "\n"
223 " Convert from scene linear to ACEScg linear color space.\n"
224 "\n"
225 " :return: A color in ACEScg linear color space.\n"
226 " :rtype: :class:`Color`\n");
228{
229 float col[3];
231 return Color_CreatePyObject(col, Py_TYPE(self));
232}
233
235 /* Wrap. */
236 Color_from_acescg_to_scene_linear_doc,
237 ".. function:: from_acescg_to_scene_linear()\n"
238 "\n"
239 " Convert from ACEScg linear to scene linear color space.\n"
240 "\n"
241 " :return: A color in scene linear color space.\n"
242 " :rtype: :class:`Color`\n");
244{
245 float col[3];
247 return Color_CreatePyObject(col, Py_TYPE(self));
248}
249
251 /* Wrap. */
252 Color_from_scene_linear_to_rec709_linear_doc,
253 ".. function:: from_scene_linear_to_rec709_linear()\n"
254 "\n"
255 " Convert from scene linear to Rec.709 linear color space.\n"
256 "\n"
257 " :return: A color in Rec.709 linear color space.\n"
258 " :rtype: :class:`Color`\n");
265
267 /* Wrap. */
268 Color_from_rec709_linear_to_scene_linear_doc,
269 ".. function:: from_rec709_linear_to_scene_linear()\n"
270 "\n"
271 " Convert from Rec.709 linear color space to scene linear color space.\n"
272 "\n"
273 " :return: A color in scene linear color space.\n"
274 " :rtype: :class:`Color`\n");
281
283 /* Wrap. */
284 Color_from_scene_linear_to_rec2020_linear_doc,
285 ".. function:: from_scene_linear_to_rec2020_linear()\n"
286 "\n"
287 " Convert from scene linear to Rec.2020 linear color space.\n"
288 "\n"
289 " :return: A color in Rec.2020 linear color space.\n"
290 " :rtype: :class:`Color`\n");
297
299 /* Wrap. */
300 Color_from_rec2020_linear_to_scene_linear_doc,
301 ".. function:: from_rec2020_linear_to_scene_linear()\n"
302 "\n"
303 " Convert from Rec.2020 linear color space to scene linear color space.\n"
304 "\n"
305 " :return: A color in scene linear color space.\n"
306 " :rtype: :class:`Color`\n");
313
314#endif /* !MATH_STANDALONE */
315
317
318/* -------------------------------------------------------------------- */
321
323 /* Wrap. */
324 Color_copy_doc,
325 ".. function:: copy()\n"
326 "\n"
327 " Returns a copy of this color.\n"
328 "\n"
329 " :return: A copy of the color.\n"
330 " :rtype: :class:`Color`\n"
331 "\n"
332 " .. note:: use this to get a copy of a wrapped color with\n"
333 " no reference to the original data.\n");
334static PyObject *Color_copy(ColorObject *self)
335{
336 if (BaseMath_ReadCallback(self) == -1) {
337 return nullptr;
338 }
339
340 return Color_CreatePyObject(self->col, Py_TYPE(self));
341}
342static PyObject *Color_deepcopy(ColorObject *self, PyObject *args)
343{
344 if (!PyC_CheckArgs_DeepCopy(args)) {
345 return nullptr;
346 }
347 return Color_copy(self);
348}
349
351
352/* -------------------------------------------------------------------- */
355
356static PyObject *Color_repr(ColorObject *self)
357{
358 PyObject *ret, *tuple;
359
360 if (BaseMath_ReadCallback(self) == -1) {
361 return nullptr;
362 }
363
364 tuple = Color_to_tuple_ex(self, -1);
365
366 ret = PyUnicode_FromFormat("Color(%R)", tuple);
367
368 Py_DECREF(tuple);
369 return ret;
370}
371
372#ifndef MATH_STANDALONE
373static PyObject *Color_str(ColorObject *self)
374{
375 DynStr *ds;
376
377 if (BaseMath_ReadCallback(self) == -1) {
378 return nullptr;
379 }
380
381 ds = BLI_dynstr_new();
382
384 ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>", self->col[0], self->col[1], self->col[2]);
385
386 return mathutils_dynstr_to_py(ds); /* frees ds */
387}
388#endif
389
391
392/* -------------------------------------------------------------------- */
395
396static int Color_getbuffer(PyObject *obj, Py_buffer *view, int flags)
397{
398 ColorObject *self = (ColorObject *)obj;
400 return -1;
401 }
402 if (UNLIKELY(BaseMath_ReadCallback(self) == -1)) {
403 return -1;
404 }
405
406 memset(view, 0, sizeof(*view));
407
408 view->obj = (PyObject *)self;
409 view->buf = (void *)self->col;
410 view->len = Py_ssize_t(COLOR_SIZE * sizeof(float));
411 view->itemsize = sizeof(float);
412 view->ndim = 1;
413 if ((flags & PyBUF_WRITABLE) == 0) {
414 view->readonly = 1;
415 }
416 if (flags & PyBUF_FORMAT) {
417 view->format = (char *)"f";
418 }
419
421
422 Py_INCREF(self);
423 return 0;
424}
425
426static void Color_releasebuffer(PyObject * /*exporter*/, Py_buffer *view)
427{
428 ColorObject *self = (ColorObject *)view->obj;
430
431 if (view->readonly == 0) {
433 PyErr_Print();
434 }
435 }
436}
437
438static PyBufferProcs Color_as_buffer = {
439 (getbufferproc)Color_getbuffer,
440 (releasebufferproc)Color_releasebuffer,
441};
442
444
445/* -------------------------------------------------------------------- */
448
449static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
450{
451 PyObject *res;
452 int ok = -1; /* zero is true */
453
455 ColorObject *colA = (ColorObject *)a;
456 ColorObject *colB = (ColorObject *)b;
457
458 if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) {
459 return nullptr;
460 }
461
462 ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1;
463 }
464
465 switch (op) {
466 case Py_NE: {
467 ok = !ok;
469 }
470 case Py_EQ: {
471 res = ok ? Py_False : Py_True;
472 break;
473 }
474 case Py_LT:
475 case Py_LE:
476 case Py_GT:
477 case Py_GE: {
478 res = Py_NotImplemented;
479 break;
480 }
481 default: {
482 PyErr_BadArgument();
483 return nullptr;
484 }
485 }
486
487 return Py_NewRef(res);
488}
489
491
492/* -------------------------------------------------------------------- */
495
496static Py_hash_t Color_hash(ColorObject *self)
497{
498 if (BaseMath_ReadCallback(self) == -1) {
499 return -1;
500 }
501
503 return -1;
504 }
505
507}
508
510
511/* -------------------------------------------------------------------- */
514
516static Py_ssize_t Color_len(ColorObject * /*self*/)
517{
518 return COLOR_SIZE;
519}
520
522static PyObject *Color_item(ColorObject *self, Py_ssize_t i)
523{
524 if (i < 0) {
525 i = COLOR_SIZE - i;
526 }
527
529 PyErr_SetString(PyExc_IndexError,
530 "color[item]: "
531 "array index out of range");
532 return nullptr;
533 }
534
535 if (BaseMath_ReadIndexCallback(self, i) == -1) {
536 return nullptr;
537 }
538
539 return PyFloat_FromDouble(self->col[i]);
540}
541
543static int Color_ass_item(ColorObject *self, Py_ssize_t i, PyObject *value)
544{
545 float f;
546
547 if (BaseMath_Prepare_ForWrite(self) == -1) {
548 return -1;
549 }
550
551 f = PyFloat_AsDouble(value);
552 if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
553 PyErr_SetString(PyExc_TypeError,
554 "color[item] = x: "
555 "assigned value not a number");
556 return -1;
557 }
558
559 if (i < 0) {
560 i = COLOR_SIZE - i;
561 }
562
564 PyErr_SetString(PyExc_IndexError,
565 "color[item] = x: "
566 "array assignment index out of range");
567 return -1;
568 }
569
570 self->col[i] = f;
571
572 if (BaseMath_WriteIndexCallback(self, i) == -1) {
573 return -1;
574 }
575
576 return 0;
577}
578
580static PyObject *Color_slice(ColorObject *self, int begin, int end)
581{
582 PyObject *tuple;
583 int count;
584
585 if (BaseMath_ReadCallback(self) == -1) {
586 return nullptr;
587 }
588
590 if (end < 0) {
591 end = (COLOR_SIZE + 1) + end;
592 }
593 CLAMP(end, 0, COLOR_SIZE);
594 begin = std::min(begin, end);
595
596 tuple = PyTuple_New(end - begin);
597 for (count = begin; count < end; count++) {
598 PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count]));
599 }
600
601 return tuple;
602}
603
605static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
606{
607 int i, size;
608 float col[COLOR_SIZE];
609
611 return -1;
612 }
613
615 if (end < 0) {
616 end = (COLOR_SIZE + 1) + end;
617 }
618 CLAMP(end, 0, COLOR_SIZE);
619 begin = std::min(begin, end);
620
621 if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) ==
622 -1)
623 {
624 return -1;
625 }
626
627 if (size != (end - begin)) {
628 PyErr_SetString(PyExc_ValueError,
629 "color[begin:end] = []: "
630 "size mismatch in slice assignment");
631 return -1;
632 }
633
634 for (i = 0; i < COLOR_SIZE; i++) {
635 self->col[begin + i] = col[i];
636 }
637
639 return 0;
640}
641
643static PyObject *Color_subscript(ColorObject *self, PyObject *item)
644{
645 if (PyIndex_Check(item)) {
646 Py_ssize_t i;
647 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
648 if (i == -1 && PyErr_Occurred()) {
649 return nullptr;
650 }
651 if (i < 0) {
652 i += COLOR_SIZE;
653 }
654 return Color_item(self, i);
655 }
656 if (PySlice_Check(item)) {
657 Py_ssize_t start, stop, step, slicelength;
658
659 if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
660 return nullptr;
661 }
662
663 if (slicelength <= 0) {
664 return PyTuple_New(0);
665 }
666 if (step == 1) {
667 return Color_slice(self, start, stop);
668 }
669
670 PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
671 return nullptr;
672 }
673
674 PyErr_Format(
675 PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
676 return nullptr;
677}
678
680static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value)
681{
682 if (PyIndex_Check(item)) {
683 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
684 if (i == -1 && PyErr_Occurred()) {
685 return -1;
686 }
687 if (i < 0) {
688 i += COLOR_SIZE;
689 }
690 return Color_ass_item(self, i, value);
691 }
692 if (PySlice_Check(item)) {
693 Py_ssize_t start, stop, step, slicelength;
694
695 if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
696 return -1;
697 }
698
699 if (step == 1) {
700 return Color_ass_slice(self, start, stop, value);
701 }
702
703 PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
704 return -1;
705 }
706
707 PyErr_Format(
708 PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
709 return -1;
710}
711
713
714/* -------------------------------------------------------------------- */
717
719static PyObject *Color_add(PyObject *v1, PyObject *v2)
720{
721 ColorObject *color1 = nullptr, *color2 = nullptr;
722 float col[COLOR_SIZE];
723
724 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
725 PyErr_Format(PyExc_TypeError,
726 "Color addition: (%s + %s) "
727 "invalid type for this operation",
728 Py_TYPE(v1)->tp_name,
729 Py_TYPE(v2)->tp_name);
730 return nullptr;
731 }
732 color1 = (ColorObject *)v1;
733 color2 = (ColorObject *)v2;
734
735 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
736 return nullptr;
737 }
738
739 add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
740
741 return Color_CreatePyObject(col, Py_TYPE(v1));
742}
743
745static PyObject *Color_iadd(PyObject *v1, PyObject *v2)
746{
747 ColorObject *color1 = nullptr, *color2 = nullptr;
748
749 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
750 PyErr_Format(PyExc_TypeError,
751 "Color addition: (%s += %s) "
752 "invalid type for this operation",
753 Py_TYPE(v1)->tp_name,
754 Py_TYPE(v2)->tp_name);
755 return nullptr;
756 }
757 color1 = (ColorObject *)v1;
758 color2 = (ColorObject *)v2;
759
760 if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
761 return nullptr;
762 }
763
764 add_vn_vn(color1->col, color2->col, COLOR_SIZE);
765
766 (void)BaseMath_WriteCallback(color1);
767 Py_INCREF(v1);
768 return v1;
769}
770
772static PyObject *Color_sub(PyObject *v1, PyObject *v2)
773{
774 ColorObject *color1 = nullptr, *color2 = nullptr;
775 float col[COLOR_SIZE];
776
777 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
778 PyErr_Format(PyExc_TypeError,
779 "Color subtraction: (%s - %s) "
780 "invalid type for this operation",
781 Py_TYPE(v1)->tp_name,
782 Py_TYPE(v2)->tp_name);
783 return nullptr;
784 }
785 color1 = (ColorObject *)v1;
786 color2 = (ColorObject *)v2;
787
788 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
789 return nullptr;
790 }
791
792 sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
793
794 return Color_CreatePyObject(col, Py_TYPE(v1));
795}
796
798static PyObject *Color_isub(PyObject *v1, PyObject *v2)
799{
800 ColorObject *color1 = nullptr, *color2 = nullptr;
801
802 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) {
803 PyErr_Format(PyExc_TypeError,
804 "Color subtraction: (%s -= %s) "
805 "invalid type for this operation",
806 Py_TYPE(v1)->tp_name,
807 Py_TYPE(v2)->tp_name);
808 return nullptr;
809 }
810 color1 = (ColorObject *)v1;
811 color2 = (ColorObject *)v2;
812
813 if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1) {
814 return nullptr;
815 }
816
817 sub_vn_vn(color1->col, color2->col, COLOR_SIZE);
818
819 (void)BaseMath_WriteCallback(color1);
820 Py_INCREF(v1);
821 return v1;
822}
823
824static PyObject *color_mul_float(ColorObject *color, const float scalar)
825{
826 float tcol[COLOR_SIZE];
827 mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar);
828 return Color_CreatePyObject(tcol, Py_TYPE(color));
829}
830
832static PyObject *Color_mul(PyObject *v1, PyObject *v2)
833{
834 ColorObject *color1 = nullptr, *color2 = nullptr;
835 float scalar;
836
837 if (ColorObject_Check(v1)) {
838 color1 = (ColorObject *)v1;
839 if (BaseMath_ReadCallback(color1) == -1) {
840 return nullptr;
841 }
842 }
843 if (ColorObject_Check(v2)) {
844 color2 = (ColorObject *)v2;
845 if (BaseMath_ReadCallback(color2) == -1) {
846 return nullptr;
847 }
848 }
849
850 /* make sure v1 is always the vector */
851 if (color1 && color2) {
852 /* col * col, don't support yet! */
853 }
854 else if (color1) {
855 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
856 return color_mul_float(color1, scalar);
857 }
858 }
859 else if (color2) {
860 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */
861 return color_mul_float(color2, scalar);
862 }
863 }
864 else {
865 BLI_assert_msg(0, "internal error");
866 }
867
868 PyErr_Format(PyExc_TypeError,
869 "Color multiplication: not supported between "
870 "'%.200s' and '%.200s' types",
871 Py_TYPE(v1)->tp_name,
872 Py_TYPE(v2)->tp_name);
873 return nullptr;
874}
875
877static PyObject *Color_div(PyObject *v1, PyObject *v2)
878{
879 ColorObject *color1 = nullptr;
880 float scalar;
881
882 if (ColorObject_Check(v1)) {
883 color1 = (ColorObject *)v1;
884 if (BaseMath_ReadCallback(color1) == -1) {
885 return nullptr;
886 }
887 }
888 else {
889 PyErr_SetString(PyExc_TypeError, "Color division not supported in this order");
890 return nullptr;
891 }
892
893 /* make sure v1 is always the vector */
894 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */
895 if (scalar == 0.0f) {
896 PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error");
897 return nullptr;
898 }
899 return color_mul_float(color1, 1.0f / scalar);
900 }
901
902 PyErr_Format(PyExc_TypeError,
903 "Color multiplication: not supported between "
904 "'%.200s' and '%.200s' types",
905 Py_TYPE(v1)->tp_name,
906 Py_TYPE(v2)->tp_name);
907 return nullptr;
908}
909
911static PyObject *Color_imul(PyObject *v1, PyObject *v2)
912{
913 ColorObject *color = (ColorObject *)v1;
914 float scalar;
915
916 if (BaseMath_ReadCallback_ForWrite(color) == -1) {
917 return nullptr;
918 }
919
920 /* only support color *= float */
921 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */
922 mul_vn_fl(color->col, COLOR_SIZE, scalar);
923 }
924 else {
925 PyErr_Format(PyExc_TypeError,
926 "Color multiplication: (%s *= %s) "
927 "invalid type for this operation",
928 Py_TYPE(v1)->tp_name,
929 Py_TYPE(v2)->tp_name);
930 return nullptr;
931 }
932
933 (void)BaseMath_WriteCallback(color);
934 Py_INCREF(v1);
935 return v1;
936}
937
939static PyObject *Color_idiv(PyObject *v1, PyObject *v2)
940{
941 ColorObject *color = (ColorObject *)v1;
942 float scalar;
943
944 if (BaseMath_ReadCallback_ForWrite(color) == -1) {
945 return nullptr;
946 }
947
948 /* only support color /= float */
949 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */
950 if (scalar == 0.0f) {
951 PyErr_SetString(PyExc_ZeroDivisionError, "Color division: divide by zero error");
952 return nullptr;
953 }
954
955 mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar);
956 }
957 else {
958 PyErr_Format(PyExc_TypeError,
959 "Color division: (%s /= %s) "
960 "invalid type for this operation",
961 Py_TYPE(v1)->tp_name,
962 Py_TYPE(v2)->tp_name);
963 return nullptr;
964 }
965
966 (void)BaseMath_WriteCallback(color);
967 Py_INCREF(v1);
968 return v1;
969}
970
972static PyObject *Color_neg(ColorObject *self)
973{
974 float tcol[COLOR_SIZE];
975
976 if (BaseMath_ReadCallback(self) == -1) {
977 return nullptr;
978 }
979
980 negate_vn_vn(tcol, self->col, COLOR_SIZE);
981 return Color_CreatePyObject(tcol, Py_TYPE(self));
982}
983
985
986/* -------------------------------------------------------------------- */
989
990static PySequenceMethods Color_SeqMethods = {
991 /*sq_length*/ (lenfunc)Color_len,
992 /*sq_concat*/ nullptr,
993 /*sq_repeat*/ nullptr,
994 /*sq_item*/ (ssizeargfunc)Color_item,
995 /*was_sq_slice*/ nullptr, /* DEPRECATED. */
996 /*sq_ass_item*/ (ssizeobjargproc)Color_ass_item,
997 /*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
998 /*sq_contains*/ nullptr,
999 /*sq_inplace_concat*/ nullptr,
1000 /*sq_inplace_repeat*/ nullptr,
1001};
1002
1003static PyMappingMethods Color_AsMapping = {
1004 /*mp_length*/ (lenfunc)Color_len,
1005 /*mp_subscript*/ (binaryfunc)Color_subscript,
1006 /*mp_ass_subscript*/ (objobjargproc)Color_ass_subscript,
1007};
1008
1009static PyNumberMethods Color_NumMethods = {
1010 /*nb_add*/ (binaryfunc)Color_add,
1011 /*nb_subtract*/ (binaryfunc)Color_sub,
1012 /*nb_multiply*/ (binaryfunc)Color_mul,
1013 /*nb_remainder*/ nullptr,
1014 /*nb_divmod*/ nullptr,
1015 /*nb_power*/ nullptr,
1016 /*nb_negative*/ (unaryfunc)Color_neg,
1017 /*nb_positive*/ (unaryfunc)Color_copy,
1018 /*nb_absolute*/ nullptr,
1019 /*nb_bool*/ nullptr,
1020 /*nb_invert*/ nullptr,
1021 /*nb_lshift*/ nullptr,
1022 /*nb_rshift*/ nullptr,
1023 /*nb_and*/ nullptr,
1024 /*nb_xor*/ nullptr,
1025 /*nb_or*/ nullptr,
1026 /*nb_int*/ nullptr,
1027 /*nb_reserved*/ nullptr,
1028 /*nb_float*/ nullptr,
1029 /*nb_inplace_add*/ Color_iadd,
1030 /*nb_inplace_subtract*/ Color_isub,
1031 /*nb_inplace_multiply*/ Color_imul,
1032 /*nb_inplace_remainder*/ nullptr,
1033 /*nb_inplace_power*/ nullptr,
1034 /*nb_inplace_lshift*/ nullptr,
1035 /*nb_inplace_rshift*/ nullptr,
1036 /*nb_inplace_and*/ nullptr,
1037 /*nb_inplace_xor*/ nullptr,
1038 /*nb_inplace_or*/ nullptr,
1039 /*nb_floor_divide*/ nullptr,
1040 /*nb_true_divide*/ Color_div,
1041 /*nb_inplace_floor_divide*/ nullptr,
1042 /*nb_inplace_true_divide*/ Color_idiv,
1043 /*nb_index*/ nullptr,
1044 /*nb_matrix_multiply*/ nullptr,
1045 /*nb_inplace_matrix_multiply*/ nullptr,
1046};
1047
1049
1050/* -------------------------------------------------------------------- */
1053
1054/* Color channel (RGB): `color.r/g/b`. */
1055
1057 /* Wrap. */
1058 Color_channel_r_doc,
1059 "Red color channel.\n"
1060 "\n"
1061 ":type: float\n");
1063 /* Wrap. */
1064 Color_channel_g_doc,
1065 "Green color channel.\n"
1066 "\n"
1067 ":type: float\n");
1069 /* Wrap. */
1070 Color_channel_b_doc,
1071 "Blue color channel.\n"
1072 "\n"
1073 ":type: float\n");
1074
1075static PyObject *Color_channel_get(ColorObject *self, void *type)
1076{
1077 return Color_item(self, POINTER_AS_INT(type));
1078}
1079
1080static int Color_channel_set(ColorObject *self, PyObject *value, void *type)
1081{
1082 return Color_ass_item(self, POINTER_AS_INT(type), value);
1083}
1084
1085/* Color channel (HSV): `color.h/s/v`. */
1086
1088 /* Wrap. */
1089 Color_channel_hsv_h_doc,
1090 "HSV Hue component in [0, 1].\n"
1091 "\n"
1092 ":type: float\n");
1094 /* Wrap. */
1095 Color_channel_hsv_s_doc,
1096 "HSV Saturation component in [0, 1].\n"
1097 "\n"
1098 ":type: float\n");
1100 /* Wrap. */
1101 Color_channel_hsv_v_doc,
1102 "HSV Value component in [0, 1].\n"
1103 "\n"
1104 ":type: float\n");
1105
1106static PyObject *Color_channel_hsv_get(ColorObject *self, void *type)
1107{
1108 float hsv[3];
1109 const int i = POINTER_AS_INT(type);
1110
1111 if (BaseMath_ReadCallback(self) == -1) {
1112 return nullptr;
1113 }
1114
1115 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
1116
1117 return PyFloat_FromDouble(hsv[i]);
1118}
1119
1120static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
1121{
1122 float hsv[3];
1123 const int i = POINTER_AS_INT(type);
1124 float f = PyFloat_AsDouble(value);
1125
1126 if (f == -1 && PyErr_Occurred()) {
1127 PyErr_SetString(PyExc_TypeError,
1128 "color.h/s/v = value: "
1129 "assigned value not a number");
1130 return -1;
1131 }
1132
1134 return -1;
1135 }
1136
1137 rgb_to_hsv_v(self->col, hsv);
1138 CLAMP(f, 0.0f, 1.0f);
1139 hsv[i] = f;
1140 hsv_to_rgb_v(hsv, self->col);
1141
1142 if (BaseMath_WriteCallback(self) == -1) {
1143 return -1;
1144 }
1145
1146 return 0;
1147}
1148
1150 /* Wrap. */
1151 Color_hsv_doc,
1152 "HSV Values in [0, 1].\n"
1153 "\n"
1154 ":type: tuple[float, float, float]\n");
1156static PyObject *Color_hsv_get(ColorObject *self, void * /*closure*/)
1157{
1158 float hsv[3];
1159 PyObject *ret;
1160
1161 if (BaseMath_ReadCallback(self) == -1) {
1162 return nullptr;
1163 }
1164
1165 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
1166
1167 ret = PyTuple_New(3);
1169 ret, PyFloat_FromDouble(hsv[0]), PyFloat_FromDouble(hsv[1]), PyFloat_FromDouble(hsv[2]));
1170 return ret;
1171}
1172
1174static int Color_hsv_set(ColorObject *self, PyObject *value, void * /*closure*/)
1175{
1176 float hsv[3];
1177
1178 if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1) {
1179 return -1;
1180 }
1181
1182 if (BaseMath_Prepare_ForWrite(self) == -1) {
1183 return -1;
1184 }
1185
1186 clamp_v3(hsv, 0.0f, 1.0f);
1187 hsv_to_rgb_v(hsv, self->col);
1188
1189 if (BaseMath_WriteCallback(self) == -1) {
1190 return -1;
1191 }
1192
1193 return 0;
1194}
1195
1197
1198/* -------------------------------------------------------------------- */
1201
1202static PyGetSetDef Color_getseters[] = {
1203 {"r",
1204 (getter)Color_channel_get,
1205 (setter)Color_channel_set,
1206 Color_channel_r_doc,
1207 POINTER_FROM_INT(0)},
1208 {"g",
1209 (getter)Color_channel_get,
1210 (setter)Color_channel_set,
1211 Color_channel_g_doc,
1212 POINTER_FROM_INT(1)},
1213 {"b",
1214 (getter)Color_channel_get,
1215 (setter)Color_channel_set,
1216 Color_channel_b_doc,
1217 POINTER_FROM_INT(2)},
1218
1219 {"h",
1220 (getter)Color_channel_hsv_get,
1221 (setter)Color_channel_hsv_set,
1222 Color_channel_hsv_h_doc,
1223 POINTER_FROM_INT(0)},
1224 {"s",
1225 (getter)Color_channel_hsv_get,
1226 (setter)Color_channel_hsv_set,
1227 Color_channel_hsv_s_doc,
1228 POINTER_FROM_INT(1)},
1229 {"v",
1230 (getter)Color_channel_hsv_get,
1231 (setter)Color_channel_hsv_set,
1232 Color_channel_hsv_v_doc,
1233 POINTER_FROM_INT(2)},
1234
1235 {"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, Color_hsv_doc, nullptr},
1236
1237 {"is_wrapped",
1239 (setter) nullptr,
1241 nullptr},
1242 {"is_frozen",
1244 (setter) nullptr,
1246 nullptr},
1247 {"is_valid",
1249 (setter) nullptr,
1251 nullptr},
1252 {"owner",
1254 (setter) nullptr,
1256 nullptr},
1257 {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
1258};
1259
1261
1262/* -------------------------------------------------------------------- */
1265
1266#ifdef __GNUC__
1267# ifdef __clang__
1268# pragma clang diagnostic push
1269# pragma clang diagnostic ignored "-Wcast-function-type"
1270# else
1271# pragma GCC diagnostic push
1272# pragma GCC diagnostic ignored "-Wcast-function-type"
1273# endif
1274#endif
1275
1276static PyMethodDef Color_methods[] = {
1277 {"copy", (PyCFunction)Color_copy, METH_NOARGS, Color_copy_doc},
1278 {"__copy__", (PyCFunction)Color_copy, METH_NOARGS, Color_copy_doc},
1279 {"__deepcopy__", (PyCFunction)Color_deepcopy, METH_VARARGS, Color_copy_doc},
1280
1281 /* base-math methods */
1282 {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
1283
1284/* Color-space methods. */
1285#ifndef MATH_STANDALONE
1286 {"from_scene_linear_to_srgb",
1288 METH_NOARGS,
1289 Color_from_scene_linear_to_srgb_doc},
1290 {"from_srgb_to_scene_linear",
1292 METH_NOARGS,
1293 Color_from_srgb_to_scene_linear_doc},
1294 {"from_scene_linear_to_xyz_d65",
1296 METH_NOARGS,
1297 Color_from_scene_linear_to_xyz_d65_doc},
1298 {"from_xyz_d65_to_scene_linear",
1300 METH_NOARGS,
1301 Color_from_xyz_d65_to_scene_linear_doc},
1302 {"from_scene_linear_to_aces",
1304 METH_NOARGS,
1305 Color_from_scene_linear_to_aces_doc},
1306 {"from_aces_to_scene_linear",
1308 METH_NOARGS,
1309 Color_from_aces_to_scene_linear_doc},
1310 {"from_scene_linear_to_acescg",
1312 METH_NOARGS,
1313 Color_from_scene_linear_to_acescg_doc},
1314 {"from_acescg_to_scene_linear",
1316 METH_NOARGS,
1317 Color_from_acescg_to_scene_linear_doc},
1318 {"from_scene_linear_to_rec709_linear",
1320 METH_NOARGS,
1321 Color_from_scene_linear_to_rec709_linear_doc},
1322 {"from_rec709_linear_to_scene_linear",
1324 METH_NOARGS,
1325 Color_from_rec709_linear_to_scene_linear_doc},
1326 {"from_scene_linear_to_rec2020_linear",
1328 METH_NOARGS,
1329 Color_from_scene_linear_to_rec2020_linear_doc},
1330 {"from_rec2020_linear_to_scene_linear",
1332 METH_NOARGS,
1333 Color_from_rec2020_linear_to_scene_linear_doc},
1334#endif /* !MATH_STANDALONE */
1335
1336 {nullptr, nullptr, 0, nullptr},
1337};
1338
1339#ifdef __GNUC__
1340# ifdef __clang__
1341# pragma clang diagnostic pop
1342# else
1343# pragma GCC diagnostic pop
1344# endif
1345#endif
1346
1348
1349/* -------------------------------------------------------------------- */
1352
1353#ifdef MATH_STANDALONE
1354# define Color_str nullptr
1355#endif
1356
1358 /* Wrap. */
1359 color_doc,
1360 ".. class:: Color(rgb=(0.0, 0.0, 0.0), /)\n"
1361 "\n"
1362 " This object gives access to Colors in Blender.\n"
1363 "\n"
1364 " Most colors returned by Blender APIs are in scene linear color space, as defined by "
1365 " the OpenColorIO configuration. The notable exception is user interface theming colors, "
1366 " which are in sRGB color space.\n"
1367 "\n"
1368 " :arg rgb: (red, green, blue) color values where (0, 0, 0) is black & (1, 1, 1) is white.\n"
1369 " :type rgb: Sequence[float]\n");
1370PyTypeObject color_Type = {
1371 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
1372 /*tp_name*/ "Color",
1373 /*tp_basicsize*/ sizeof(ColorObject),
1374 /*tp_itemsize*/ 0,
1375 /*tp_dealloc*/ (destructor)BaseMathObject_dealloc,
1376 /*tp_vectorcall_offset*/ 0,
1377 /*tp_getattr*/ nullptr,
1378 /*tp_setattr*/ nullptr,
1379 /*tp_as_async*/ nullptr,
1380 /*tp_repr*/ (reprfunc)Color_repr,
1381 /*tp_as_number*/ &Color_NumMethods,
1382 /*tp_as_sequence*/ &Color_SeqMethods,
1383 /*tp_as_mapping*/ &Color_AsMapping,
1384 /*tp_hash*/ (hashfunc)Color_hash,
1385 /*tp_call*/ nullptr,
1386 /*tp_str*/ (reprfunc)Color_str,
1387 /*tp_getattro*/ nullptr,
1388 /*tp_setattro*/ nullptr,
1389 /*tp_as_buffer*/ &Color_as_buffer,
1390 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1391 /*tp_doc*/ color_doc,
1392 /*tp_traverse*/ (traverseproc)BaseMathObject_traverse,
1393 /*tp_clear*/ (inquiry)BaseMathObject_clear,
1394 /*tp_richcompare*/ (richcmpfunc)Color_richcmpr,
1395 /*tp_weaklistoffset*/ 0,
1396 /*tp_iter*/ nullptr,
1397 /*tp_iternext*/ nullptr,
1398 /*tp_methods*/ Color_methods,
1399 /*tp_members*/ nullptr,
1400 /*tp_getset*/ Color_getseters,
1401 /*tp_base*/ nullptr,
1402 /*tp_dict*/ nullptr,
1403 /*tp_descr_get*/ nullptr,
1404 /*tp_descr_set*/ nullptr,
1405 /*tp_dictoffset*/ 0,
1406 /*tp_init*/ nullptr,
1407 /*tp_alloc*/ nullptr,
1408 /*tp_new*/ Color_new,
1409 /*tp_free*/ nullptr,
1410 /*tp_is_gc*/ (inquiry)BaseMathObject_is_gc,
1411 /*tp_bases*/ nullptr,
1412 /*tp_mro*/ nullptr,
1413 /*tp_cache*/ nullptr,
1414 /*tp_subclasses*/ nullptr,
1415 /*tp_weaklist*/ nullptr,
1416 /*tp_del*/ nullptr,
1417 /*tp_version_tag*/ 0,
1418 /*tp_finalize*/ nullptr,
1419 /*tp_vectorcall*/ Color_vectorcall,
1420};
1421
1422#ifdef MATH_STANDALONE
1423# define Color_str
1424#endif
1425
1427
1428/* -------------------------------------------------------------------- */
1431
1432PyObject *Color_CreatePyObject(const float col[3], PyTypeObject *base_type)
1433{
1435 float *col_alloc;
1436
1437 col_alloc = static_cast<float *>(PyMem_Malloc(COLOR_SIZE * sizeof(float)));
1438 if (UNLIKELY(col_alloc == nullptr)) {
1439 PyErr_SetString(PyExc_MemoryError,
1440 "Color(): "
1441 "problem allocating data");
1442 return nullptr;
1443 }
1444
1446 if (self) {
1447 self->col = col_alloc;
1448
1449 /* init callbacks as nullptr */
1450 self->cb_user = nullptr;
1451 self->cb_type = self->cb_subtype = 0;
1452
1453 /* NEW */
1454 if (col) {
1455 copy_v3_v3(self->col, col);
1456 }
1457 else {
1458 zero_v3(self->col);
1459 }
1460
1462 }
1463 else {
1464 PyMem_Free(col_alloc);
1465 }
1466
1467 return (PyObject *)self;
1468}
1469
1470PyObject *Color_CreatePyObject_wrap(float col[3], PyTypeObject *base_type)
1471{
1473
1475 if (self) {
1476 /* init callbacks as nullptr */
1477 self->cb_user = nullptr;
1478 self->cb_type = self->cb_subtype = 0;
1479
1480 /* WRAP */
1481 self->col = col;
1483 }
1484
1485 return (PyObject *)self;
1486}
1487
1488PyObject *Color_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_subtype)
1489{
1490 ColorObject *self = (ColorObject *)Color_CreatePyObject(nullptr, nullptr);
1491 if (self) {
1492 Py_INCREF(cb_user);
1493 self->cb_user = cb_user;
1494 self->cb_type = cb_type;
1495 self->cb_subtype = cb_subtype;
1496 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
1497 PyObject_GC_Track(self);
1498 }
1499
1500 return (PyObject *)self;
1501}
1502
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define ATTR_FALLTHROUGH
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:37
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
double double_round(double x, int ndigits)
Definition math_base.cc:28
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void add_vn_vn(float *array_tar, const float *array_src, int size)
void mul_vn_fl(float *array_tar, int size, float f)
MINLINE void clamp_v3(float vec[3], float min, float max)
void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, int size)
void negate_vn_vn(float *array_tar, const float *array_src, int size)
MINLINE void zero_v3(float r[3])
void mul_vn_vn_fl(float *array_tar, const float *array_src, int size, float f)
void sub_vn_vn(float *array_tar, const float *array_src, int size)
unsigned char uchar
#define CLAMP(a, b, c)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
static AppView * view
BLI_INLINE void IMB_colormanagement_srgb_to_scene_linear_v3(float scene_linear[3], const float srgb[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_rec2020(float rec2020[3], const float scene_linear[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_rec709(float rec709[3], const float scene_linear[3])
BLI_INLINE void IMB_colormanagement_aces_to_scene_linear(float scene_linear[3], const float aces[3])
BLI_INLINE void IMB_colormanagement_rec2020_to_scene_linear(float scene_linear[3], const float rec2020[3])
BLI_INLINE void IMB_colormanagement_xyz_to_scene_linear(float scene_linear[3], const float xyz[3])
BLI_INLINE void IMB_colormanagement_rec709_to_scene_linear(float scene_linear[3], const float rec709[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_xyz(float xyz[3], const float scene_linear[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_aces(float aces[3], const float scene_linear[3])
BLI_INLINE void IMB_colormanagement_acescg_to_scene_linear(float scene_linear[3], const float acescg[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_srgb_v3(float srgb[3], const float scene_linear[3])
BLI_INLINE void IMB_colormanagement_scene_linear_to_acescg(float acescg[3], const float scene_linear[3])
iter begin(iter)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
PyObject * self
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
nullptr float
uint col
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
int count
int BaseMathObject_is_gc(BaseMathObject *self)
Definition mathutils.cc:762
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
Definition mathutils.cc:68
void BaseMathObject_dealloc(BaseMathObject *self)
Definition mathutils.cc:740
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
Definition mathutils.cc:489
int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
Definition mathutils.cc:96
char BaseMathObject_is_valid_doc[]
Definition mathutils.cc:685
char BaseMathObject_is_wrapped_doc[]
Definition mathutils.cc:671
PyObject * BaseMathObject_owner_get(BaseMathObject *self, void *)
Definition mathutils.cc:665
char BaseMathObject_is_frozen_doc[]
Definition mathutils.cc:678
PyObject * mathutils_dynstr_to_py(DynStr *ds)
Definition mathutils.cc:501
PyObject * BaseMathObject_is_frozen_get(BaseMathObject *self, void *)
Definition mathutils.cc:680
PyObject * BaseMathObject_freeze(BaseMathObject *self)
Definition mathutils.cc:699
PyObject * BaseMathObject_is_wrapped_get(BaseMathObject *self, void *)
Definition mathutils.cc:673
char BaseMathObject_owner_doc[]
Definition mathutils.cc:664
char BaseMathObject_freeze_doc[]
Definition mathutils.cc:691
PyObject * BaseMathObject_is_valid_get(BaseMathObject *self, void *)
Definition mathutils.cc:686
int BaseMathObject_clear(BaseMathObject *self)
Definition mathutils.cc:722
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
Definition mathutils.cc:716
#define BaseMath_ReadCallback_ForWrite(_self)
Definition mathutils.hh:151
#define BaseMath_Prepare_ForBufferAccess(_self, _view, _flags)
Definition mathutils.hh:183
#define BaseMath_ReadIndexCallback(_self, _index)
Definition mathutils.hh:145
#define BaseMath_WriteCallback(_self)
Definition mathutils.hh:143
#define BASE_MATH_NEW(struct_name, root_type, base_type)
Definition mathutils.hh:27
#define BaseMathObject_Prepare_ForHash(_self)
Definition mathutils.hh:166
#define BASE_MATH_FLAG_DEFAULT
Definition mathutils.hh:52
#define BaseMath_Prepare_ForWrite(_self)
Definition mathutils.hh:161
@ BASE_MATH_FLAG_HAS_BUFFER_VIEW
Definition mathutils.hh:50
@ BASE_MATH_FLAG_IS_WRAP
Definition mathutils.hh:37
#define BaseMath_ReadCallback(_self)
Definition mathutils.hh:141
#define BaseMath_WriteIndexCallback(_self, _index)
Definition mathutils.hh:147
static PyObject * Color_from_scene_linear_to_rec709_linear(ColorObject *self)
static int Color_getbuffer(PyObject *obj, Py_buffer *view, int flags)
static PyObject * Color_str(ColorObject *self)
PyObject * Color_CreatePyObject(const float col[3], PyTypeObject *base_type)
static PyObject * Color_from_xyz_d65_to_scene_linear(ColorObject *self)
PyTypeObject color_Type
static Py_hash_t Color_hash(ColorObject *self)
static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value)
static PyObject * color_mul_float(ColorObject *color, const float scalar)
static PyObject * Color_imul(PyObject *v1, PyObject *v2)
static PyObject * Color_richcmpr(PyObject *a, PyObject *b, int op)
static void Color_releasebuffer(PyObject *, Py_buffer *view)
static PyObject * Color_channel_get(ColorObject *self, void *type)
static int Color_ass_item(ColorObject *self, Py_ssize_t i, PyObject *value)
static PySequenceMethods Color_SeqMethods
static PyObject * Color_to_tuple_ex(ColorObject *self, int ndigits)
PyDoc_STRVAR(Color_from_scene_linear_to_srgb_doc, ".. function:: from_scene_linear_to_srgb()\n" "\n" " Convert from scene linear to sRGB color space.\n" "\n" " :return: A color in sRGB color space.\n" " :rtype: :class:`Color`\n")
static PyObject * Color_channel_hsv_get(ColorObject *self, void *type)
static PyObject * Color_from_acescg_to_scene_linear(ColorObject *self)
static PyGetSetDef Color_getseters[]
static int Color_hsv_set(ColorObject *self, PyObject *value, void *)
static PyBufferProcs Color_as_buffer
static PyObject * Color_from_scene_linear_to_xyz_d65(ColorObject *self)
#define COLOR_SIZE
static Py_ssize_t Color_len(ColorObject *)
static PyObject * Color_deepcopy(ColorObject *self, PyObject *args)
static PyObject * Color_iadd(PyObject *v1, PyObject *v2)
static PyObject * Color_copy(ColorObject *self)
static PyObject * Color_idiv(PyObject *v1, PyObject *v2)
static PyObject * Color_neg(ColorObject *self)
static PyObject * Color_div(PyObject *v1, PyObject *v2)
static PyNumberMethods Color_NumMethods
static PyObject * Color_subscript(ColorObject *self, PyObject *item)
static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
static PyObject * Color_add(PyObject *v1, PyObject *v2)
static PyObject * Color_from_srgb_to_scene_linear(ColorObject *self)
static PyObject * Color_sub(PyObject *v1, PyObject *v2)
PyObject * Color_CreatePyObject_cb(PyObject *cb_user, uchar cb_type, uchar cb_subtype)
static PyObject * Color_repr(ColorObject *self)
static PyObject * Color_hsv_get(ColorObject *self, void *)
static PyMappingMethods Color_AsMapping
static PyObject * Color_isub(PyObject *v1, PyObject *v2)
static PyObject * Color_mul(PyObject *v1, PyObject *v2)
static PyObject * Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * Color_from_aces_to_scene_linear(ColorObject *self)
static PyMethodDef Color_methods[]
static PyObject * Color_from_scene_linear_to_acescg(ColorObject *self)
static int Color_channel_set(ColorObject *self, PyObject *value, void *type)
static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
static PyObject * Color_from_scene_linear_to_aces(ColorObject *self)
static PyObject * Color_item(ColorObject *self, Py_ssize_t i)
static PyObject * Color_vectorcall(PyObject *type, PyObject *const *args, const size_t nargsf, PyObject *kwnames)
PyObject * Color_CreatePyObject_wrap(float col[3], PyTypeObject *base_type)
static PyObject * Color_from_scene_linear_to_rec2020_linear(ColorObject *self)
static PyObject * Color_slice(ColorObject *self, int begin, int end)
static PyObject * Color_from_rec709_linear_to_scene_linear(ColorObject *self)
static PyObject * Color_from_scene_linear_to_srgb(ColorObject *self)
static PyObject * Color_from_rec2020_linear_to_scene_linear(ColorObject *self)
#define ColorObject_Check(v)
int PyC_CheckArgs_DeepCopy(PyObject *args)
Py_DECREF(oname)
header-only utilities
#define PyTuple_SET_ITEMS(op_arg,...)
return ret
i
Definition text_draw.cc:230