Blender V2.61 - r43446
|
00001 /* 00002 * 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * Contributor(s): Campbell Barton 00020 * 00021 * ***** END GPL LICENSE BLOCK ***** 00022 */ 00023 00029 #include <Python.h> 00030 00031 #include "mathutils.h" 00032 00033 #include "BLI_math.h" 00034 #include "BLI_utildefines.h" 00035 #include "BLI_dynstr.h" 00036 00037 #define COLOR_SIZE 3 00038 00039 //----------------------------------mathutils.Color() ------------------- 00040 //makes a new color for you to play with 00041 static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 00042 { 00043 float col[3] = {0.0f, 0.0f, 0.0f}; 00044 00045 if (kwds && PyDict_Size(kwds)) { 00046 PyErr_SetString(PyExc_TypeError, 00047 "mathutils.Color(): " 00048 "takes no keyword args"); 00049 return NULL; 00050 } 00051 00052 switch (PyTuple_GET_SIZE(args)) { 00053 case 0: 00054 break; 00055 case 1: 00056 if ((mathutils_array_parse(col, COLOR_SIZE, COLOR_SIZE, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1) 00057 return NULL; 00058 break; 00059 default: 00060 PyErr_SetString(PyExc_TypeError, 00061 "mathutils.Color(): " 00062 "more then a single arg given"); 00063 return NULL; 00064 } 00065 return Color_CreatePyObject(col, Py_NEW, type); 00066 } 00067 00068 //-----------------------------METHODS---------------------------- 00069 00070 /* note: BaseMath_ReadCallback must be called beforehand */ 00071 static PyObject *Color_ToTupleExt(ColorObject *self, int ndigits) 00072 { 00073 PyObject *ret; 00074 int i; 00075 00076 ret = PyTuple_New(COLOR_SIZE); 00077 00078 if (ndigits >= 0) { 00079 for (i = 0; i < COLOR_SIZE; i++) { 00080 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->col[i], ndigits))); 00081 } 00082 } 00083 else { 00084 for (i = 0; i < COLOR_SIZE; i++) { 00085 PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->col[i])); 00086 } 00087 } 00088 00089 return ret; 00090 } 00091 00092 PyDoc_STRVAR(Color_copy_doc, 00093 ".. function:: copy()\n" 00094 "\n" 00095 " Returns a copy of this color.\n" 00096 "\n" 00097 " :return: A copy of the color.\n" 00098 " :rtype: :class:`Color`\n" 00099 "\n" 00100 " .. note:: use this to get a copy of a wrapped color with\n" 00101 " no reference to the original data.\n" 00102 ); 00103 static PyObject *Color_copy(ColorObject *self) 00104 { 00105 if (BaseMath_ReadCallback(self) == -1) 00106 return NULL; 00107 00108 return Color_CreatePyObject(self->col, Py_NEW, Py_TYPE(self)); 00109 } 00110 00111 //----------------------------print object (internal)-------------- 00112 //print the object to screen 00113 00114 static PyObject *Color_repr(ColorObject *self) 00115 { 00116 PyObject *ret, *tuple; 00117 00118 if (BaseMath_ReadCallback(self) == -1) 00119 return NULL; 00120 00121 tuple = Color_ToTupleExt(self, -1); 00122 00123 ret = PyUnicode_FromFormat("Color(%R)", tuple); 00124 00125 Py_DECREF(tuple); 00126 return ret; 00127 } 00128 00129 static PyObject *Color_str(ColorObject *self) 00130 { 00131 DynStr *ds; 00132 00133 if (BaseMath_ReadCallback(self) == -1) 00134 return NULL; 00135 00136 ds = BLI_dynstr_new(); 00137 00138 BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>", 00139 self->col[0], self->col[1], self->col[2]); 00140 00141 return mathutils_dynstr_to_py(ds); /* frees ds */ 00142 } 00143 00144 //------------------------tp_richcmpr 00145 //returns -1 execption, 0 false, 1 true 00146 static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op) 00147 { 00148 PyObject *res; 00149 int ok = -1; /* zero is true */ 00150 00151 if (ColorObject_Check(a) && ColorObject_Check(b)) { 00152 ColorObject *colA = (ColorObject *)a; 00153 ColorObject *colB = (ColorObject *)b; 00154 00155 if (BaseMath_ReadCallback(colA) == -1 || BaseMath_ReadCallback(colB) == -1) 00156 return NULL; 00157 00158 ok = EXPP_VectorsAreEqual(colA->col, colB->col, COLOR_SIZE, 1) ? 0 : -1; 00159 } 00160 00161 switch (op) { 00162 case Py_NE: 00163 ok = !ok; /* pass through */ 00164 case Py_EQ: 00165 res = ok ? Py_False : Py_True; 00166 break; 00167 00168 case Py_LT: 00169 case Py_LE: 00170 case Py_GT: 00171 case Py_GE: 00172 res = Py_NotImplemented; 00173 break; 00174 default: 00175 PyErr_BadArgument(); 00176 return NULL; 00177 } 00178 00179 return Py_INCREF(res), res; 00180 } 00181 00182 //---------------------SEQUENCE PROTOCOLS------------------------ 00183 //----------------------------len(object)------------------------ 00184 //sequence length 00185 static int Color_len(ColorObject *UNUSED(self)) 00186 { 00187 return COLOR_SIZE; 00188 } 00189 //----------------------------object[]--------------------------- 00190 //sequence accessor (get) 00191 static PyObject *Color_item(ColorObject *self, int i) 00192 { 00193 if (i < 0) i = COLOR_SIZE - i; 00194 00195 if (i < 0 || i >= COLOR_SIZE) { 00196 PyErr_SetString(PyExc_IndexError, 00197 "color[attribute]: " 00198 "array index out of range"); 00199 return NULL; 00200 } 00201 00202 if (BaseMath_ReadIndexCallback(self, i) == -1) 00203 return NULL; 00204 00205 return PyFloat_FromDouble(self->col[i]); 00206 00207 } 00208 //----------------------------object[]------------------------- 00209 //sequence accessor (set) 00210 static int Color_ass_item(ColorObject *self, int i, PyObject *value) 00211 { 00212 float f = PyFloat_AsDouble(value); 00213 00214 if (f == -1 && PyErr_Occurred()) { // parsed item not a number 00215 PyErr_SetString(PyExc_TypeError, 00216 "color[attribute] = x: " 00217 "argument not a number"); 00218 return -1; 00219 } 00220 00221 if (i < 0) i= COLOR_SIZE - i; 00222 00223 if (i < 0 || i >= COLOR_SIZE) { 00224 PyErr_SetString(PyExc_IndexError, "color[attribute] = x: " 00225 "array assignment index out of range"); 00226 return -1; 00227 } 00228 00229 self->col[i] = f; 00230 00231 if (BaseMath_WriteIndexCallback(self, i) == -1) 00232 return -1; 00233 00234 return 0; 00235 } 00236 //----------------------------object[z:y]------------------------ 00237 //sequence slice (get) 00238 static PyObject *Color_slice(ColorObject *self, int begin, int end) 00239 { 00240 PyObject *tuple; 00241 int count; 00242 00243 if (BaseMath_ReadCallback(self) == -1) 00244 return NULL; 00245 00246 CLAMP(begin, 0, COLOR_SIZE); 00247 if (end < 0) end = (COLOR_SIZE + 1) + end; 00248 CLAMP(end, 0, COLOR_SIZE); 00249 begin = MIN2(begin, end); 00250 00251 tuple = PyTuple_New(end - begin); 00252 for (count = begin; count < end; count++) { 00253 PyTuple_SET_ITEM(tuple, count - begin, PyFloat_FromDouble(self->col[count])); 00254 } 00255 00256 return tuple; 00257 } 00258 //----------------------------object[z:y]------------------------ 00259 //sequence slice (set) 00260 static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq) 00261 { 00262 int i, size; 00263 float col[COLOR_SIZE]; 00264 00265 if (BaseMath_ReadCallback(self) == -1) 00266 return -1; 00267 00268 CLAMP(begin, 0, COLOR_SIZE); 00269 if (end < 0) end = (COLOR_SIZE + 1) + end; 00270 CLAMP(end, 0, COLOR_SIZE); 00271 begin = MIN2(begin, end); 00272 00273 if ((size = mathutils_array_parse(col, 0, COLOR_SIZE, seq, "mathutils.Color[begin:end] = []")) == -1) 00274 return -1; 00275 00276 if (size != (end - begin)) { 00277 PyErr_SetString(PyExc_ValueError, 00278 "color[begin:end] = []: " 00279 "size mismatch in slice assignment"); 00280 return -1; 00281 } 00282 00283 for (i = 0; i < COLOR_SIZE; i++) 00284 self->col[begin + i] = col[i]; 00285 00286 (void)BaseMath_WriteCallback(self); 00287 return 0; 00288 } 00289 00290 static PyObject *Color_subscript(ColorObject *self, PyObject *item) 00291 { 00292 if (PyIndex_Check(item)) { 00293 Py_ssize_t i; 00294 i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00295 if (i == -1 && PyErr_Occurred()) 00296 return NULL; 00297 if (i < 0) 00298 i += COLOR_SIZE; 00299 return Color_item(self, i); 00300 } 00301 else if (PySlice_Check(item)) { 00302 Py_ssize_t start, stop, step, slicelength; 00303 00304 if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) 00305 return NULL; 00306 00307 if (slicelength <= 0) { 00308 return PyTuple_New(0); 00309 } 00310 else if (step == 1) { 00311 return Color_slice(self, start, stop); 00312 } 00313 else { 00314 PyErr_SetString(PyExc_IndexError, 00315 "slice steps not supported with color"); 00316 return NULL; 00317 } 00318 } 00319 else { 00320 PyErr_Format(PyExc_TypeError, 00321 "color indices must be integers, not %.200s", 00322 Py_TYPE(item)->tp_name); 00323 return NULL; 00324 } 00325 } 00326 00327 static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value) 00328 { 00329 if (PyIndex_Check(item)) { 00330 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); 00331 if (i == -1 && PyErr_Occurred()) 00332 return -1; 00333 if (i < 0) 00334 i += COLOR_SIZE; 00335 return Color_ass_item(self, i, value); 00336 } 00337 else if (PySlice_Check(item)) { 00338 Py_ssize_t start, stop, step, slicelength; 00339 00340 if (PySlice_GetIndicesEx((void *)item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) 00341 return -1; 00342 00343 if (step == 1) 00344 return Color_ass_slice(self, start, stop, value); 00345 else { 00346 PyErr_SetString(PyExc_IndexError, 00347 "slice steps not supported with color"); 00348 return -1; 00349 } 00350 } 00351 else { 00352 PyErr_Format(PyExc_TypeError, 00353 "color indices must be integers, not %.200s", 00354 Py_TYPE(item)->tp_name); 00355 return -1; 00356 } 00357 } 00358 00359 //-----------------PROTCOL DECLARATIONS-------------------------- 00360 static PySequenceMethods Color_SeqMethods = { 00361 (lenfunc) Color_len, /* sq_length */ 00362 (binaryfunc) NULL, /* sq_concat */ 00363 (ssizeargfunc) NULL, /* sq_repeat */ 00364 (ssizeargfunc) Color_item, /* sq_item */ 00365 NULL, /* sq_slice, deprecated */ 00366 (ssizeobjargproc) Color_ass_item, /* sq_ass_item */ 00367 NULL, /* sq_ass_slice, deprecated */ 00368 (objobjproc) NULL, /* sq_contains */ 00369 (binaryfunc) NULL, /* sq_inplace_concat */ 00370 (ssizeargfunc) NULL, /* sq_inplace_repeat */ 00371 }; 00372 00373 static PyMappingMethods Color_AsMapping = { 00374 (lenfunc)Color_len, 00375 (binaryfunc)Color_subscript, 00376 (objobjargproc)Color_ass_subscript 00377 }; 00378 00379 /* numeric */ 00380 00381 00382 /* addition: obj + obj */ 00383 static PyObject *Color_add(PyObject *v1, PyObject *v2) 00384 { 00385 ColorObject *color1 = NULL, *color2 = NULL; 00386 float col[COLOR_SIZE]; 00387 00388 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { 00389 PyErr_Format(PyExc_TypeError, 00390 "Color addition: (%s + %s) " 00391 "invalid type for this operation", 00392 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00393 return NULL; 00394 } 00395 color1 = (ColorObject *)v1; 00396 color2 = (ColorObject *)v2; 00397 00398 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) 00399 return NULL; 00400 00401 add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); 00402 00403 return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1)); 00404 } 00405 00406 /* addition in-place: obj += obj */ 00407 static PyObject *Color_iadd(PyObject *v1, PyObject *v2) 00408 { 00409 ColorObject *color1 = NULL, *color2 = NULL; 00410 00411 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { 00412 PyErr_Format(PyExc_TypeError, 00413 "Color addition: (%s += %s) " 00414 "invalid type for this operation", 00415 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00416 return NULL; 00417 } 00418 color1 = (ColorObject *)v1; 00419 color2 = (ColorObject *)v2; 00420 00421 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) 00422 return NULL; 00423 00424 add_vn_vn(color1->col, color2->col, COLOR_SIZE); 00425 00426 (void)BaseMath_WriteCallback(color1); 00427 Py_INCREF(v1); 00428 return v1; 00429 } 00430 00431 /* subtraction: obj - obj */ 00432 static PyObject *Color_sub(PyObject *v1, PyObject *v2) 00433 { 00434 ColorObject *color1 = NULL, *color2 = NULL; 00435 float col[COLOR_SIZE]; 00436 00437 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { 00438 PyErr_Format(PyExc_TypeError, 00439 "Color subtraction: (%s - %s) " 00440 "invalid type for this operation", 00441 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00442 return NULL; 00443 } 00444 color1 = (ColorObject *)v1; 00445 color2 = (ColorObject *)v2; 00446 00447 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) 00448 return NULL; 00449 00450 sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE); 00451 00452 return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1)); 00453 } 00454 00455 /* subtraction in-place: obj -= obj */ 00456 static PyObject *Color_isub(PyObject *v1, PyObject *v2) 00457 { 00458 ColorObject *color1 = NULL, *color2 = NULL; 00459 00460 if (!ColorObject_Check(v1) || !ColorObject_Check(v2)) { 00461 PyErr_Format(PyExc_TypeError, 00462 "Color subtraction: (%s -= %s) " 00463 "invalid type for this operation", 00464 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00465 return NULL; 00466 } 00467 color1 = (ColorObject *)v1; 00468 color2 = (ColorObject *)v2; 00469 00470 if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1) 00471 return NULL; 00472 00473 sub_vn_vn(color1->col, color2->col, COLOR_SIZE); 00474 00475 (void)BaseMath_WriteCallback(color1); 00476 Py_INCREF(v1); 00477 return v1; 00478 } 00479 00480 static PyObject *color_mul_float(ColorObject *color, const float scalar) 00481 { 00482 float tcol[COLOR_SIZE]; 00483 mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar); 00484 return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(color)); 00485 } 00486 00487 00488 static PyObject *Color_mul(PyObject *v1, PyObject *v2) 00489 { 00490 ColorObject *color1 = NULL, *color2 = NULL; 00491 float scalar; 00492 00493 if ColorObject_Check(v1) { 00494 color1 = (ColorObject *)v1; 00495 if (BaseMath_ReadCallback(color1) == -1) 00496 return NULL; 00497 } 00498 if ColorObject_Check(v2) { 00499 color2 = (ColorObject *)v2; 00500 if (BaseMath_ReadCallback(color2) == -1) 00501 return NULL; 00502 } 00503 00504 00505 /* make sure v1 is always the vector */ 00506 if (color1 && color2) { 00507 /* col * col, dont support yet! */ 00508 } 00509 else if (color1) { 00510 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */ 00511 return color_mul_float(color1, scalar); 00512 } 00513 } 00514 else if (color2) { 00515 if (((scalar = PyFloat_AsDouble(v1)) == -1.0f && PyErr_Occurred()) == 0) { /* FLOAT * COLOR */ 00516 return color_mul_float(color2, scalar); 00517 } 00518 } 00519 else { 00520 BLI_assert(!"internal error"); 00521 } 00522 00523 PyErr_Format(PyExc_TypeError, 00524 "Color multiplication: not supported between " 00525 "'%.200s' and '%.200s' types", 00526 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00527 return NULL; 00528 } 00529 00530 static PyObject *Color_div(PyObject *v1, PyObject *v2) 00531 { 00532 ColorObject *color1 = NULL; 00533 float scalar; 00534 00535 if ColorObject_Check(v1) { 00536 color1 = (ColorObject *)v1; 00537 if (BaseMath_ReadCallback(color1) == -1) 00538 return NULL; 00539 } 00540 else { 00541 PyErr_SetString(PyExc_TypeError, 00542 "Color division not supported in this order"); 00543 return NULL; 00544 } 00545 00546 /* make sure v1 is always the vector */ 00547 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR * FLOAT */ 00548 if (scalar == 0.0f) { 00549 PyErr_SetString(PyExc_ZeroDivisionError, 00550 "Color division: divide by zero error"); 00551 return NULL; 00552 } 00553 return color_mul_float(color1, 1.0f / scalar); 00554 } 00555 00556 PyErr_Format(PyExc_TypeError, 00557 "Color multiplication: not supported between " 00558 "'%.200s' and '%.200s' types", 00559 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00560 return NULL; 00561 } 00562 00563 /* mulplication in-place: obj *= obj */ 00564 static PyObject *Color_imul(PyObject *v1, PyObject *v2) 00565 { 00566 ColorObject *color = (ColorObject *)v1; 00567 float scalar; 00568 00569 if (BaseMath_ReadCallback(color) == -1) 00570 return NULL; 00571 00572 /* only support color *= float */ 00573 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR *= FLOAT */ 00574 mul_vn_fl(color->col, COLOR_SIZE, scalar); 00575 } 00576 else { 00577 PyErr_Format(PyExc_TypeError, 00578 "Color multiplication: (%s *= %s) " 00579 "invalid type for this operation", 00580 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00581 return NULL; 00582 } 00583 00584 (void)BaseMath_WriteCallback(color); 00585 Py_INCREF(v1); 00586 return v1; 00587 } 00588 00589 /* mulplication in-place: obj *= obj */ 00590 static PyObject *Color_idiv(PyObject *v1, PyObject *v2) 00591 { 00592 ColorObject *color = (ColorObject *)v1; 00593 float scalar; 00594 00595 if (BaseMath_ReadCallback(color) == -1) 00596 return NULL; 00597 00598 /* only support color /= float */ 00599 if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* COLOR /= FLOAT */ 00600 if (scalar == 0.0f) { 00601 PyErr_SetString(PyExc_ZeroDivisionError, 00602 "Color division: divide by zero error"); 00603 return NULL; 00604 } 00605 00606 mul_vn_fl(color->col, COLOR_SIZE, 1.0f / scalar); 00607 } 00608 else { 00609 PyErr_Format(PyExc_TypeError, 00610 "Color division: (%s /= %s) " 00611 "invalid type for this operation", 00612 Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); 00613 return NULL; 00614 } 00615 00616 (void)BaseMath_WriteCallback(color); 00617 Py_INCREF(v1); 00618 return v1; 00619 } 00620 00621 /* -obj 00622 returns the negative of this object */ 00623 static PyObject *Color_neg(ColorObject *self) 00624 { 00625 float tcol[COLOR_SIZE]; 00626 00627 if (BaseMath_ReadCallback(self) == -1) 00628 return NULL; 00629 00630 negate_vn_vn(tcol, self->col, COLOR_SIZE); 00631 return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(self)); 00632 } 00633 00634 00635 static PyNumberMethods Color_NumMethods = { 00636 (binaryfunc) Color_add, /*nb_add*/ 00637 (binaryfunc) Color_sub, /*nb_subtract*/ 00638 (binaryfunc) Color_mul, /*nb_multiply*/ 00639 NULL, /*nb_remainder*/ 00640 NULL, /*nb_divmod*/ 00641 NULL, /*nb_power*/ 00642 (unaryfunc) Color_neg, /*nb_negative*/ 00643 (unaryfunc) NULL, /*tp_positive*/ 00644 (unaryfunc) NULL, /*tp_absolute*/ 00645 (inquiry) NULL, /*tp_bool*/ 00646 (unaryfunc) NULL, /*nb_invert*/ 00647 NULL, /*nb_lshift*/ 00648 (binaryfunc)NULL, /*nb_rshift*/ 00649 NULL, /*nb_and*/ 00650 NULL, /*nb_xor*/ 00651 NULL, /*nb_or*/ 00652 NULL, /*nb_int*/ 00653 NULL, /*nb_reserved*/ 00654 NULL, /*nb_float*/ 00655 Color_iadd, /* nb_inplace_add */ 00656 Color_isub, /* nb_inplace_subtract */ 00657 Color_imul, /* nb_inplace_multiply */ 00658 NULL, /* nb_inplace_remainder */ 00659 NULL, /* nb_inplace_power */ 00660 NULL, /* nb_inplace_lshift */ 00661 NULL, /* nb_inplace_rshift */ 00662 NULL, /* nb_inplace_and */ 00663 NULL, /* nb_inplace_xor */ 00664 NULL, /* nb_inplace_or */ 00665 NULL, /* nb_floor_divide */ 00666 Color_div, /* nb_true_divide */ 00667 NULL, /* nb_inplace_floor_divide */ 00668 Color_idiv, /* nb_inplace_true_divide */ 00669 NULL, /* nb_index */ 00670 }; 00671 00672 /* color channel, vector.r/g/b */ 00673 PyDoc_STRVAR(Color_channel_r_doc, "Red color channel.\n\n:type: float"); 00674 PyDoc_STRVAR(Color_channel_g_doc, "Green color channel.\n\n:type: float"); 00675 PyDoc_STRVAR(Color_channel_b_doc, "Blue color channel.\n\n:type: float"); 00676 00677 static PyObject *Color_channel_get(ColorObject *self, void *type) 00678 { 00679 return Color_item(self, GET_INT_FROM_POINTER(type)); 00680 } 00681 00682 static int Color_channel_set(ColorObject *self, PyObject *value, void * type) 00683 { 00684 return Color_ass_item(self, GET_INT_FROM_POINTER(type), value); 00685 } 00686 00687 /* color channel (HSV), color.h/s/v */ 00688 PyDoc_STRVAR(Color_channel_hsv_h_doc, "HSV Hue component in [0, 1].\n\n:type: float"); 00689 PyDoc_STRVAR(Color_channel_hsv_s_doc, "HSV Saturation component in [0, 1].\n\n:type: float"); 00690 PyDoc_STRVAR(Color_channel_hsv_v_doc, "HSV Value component in [0, 1].\n\n:type: float"); 00691 00692 static PyObject *Color_channel_hsv_get(ColorObject *self, void *type) 00693 { 00694 float hsv[3]; 00695 int i = GET_INT_FROM_POINTER(type); 00696 00697 if (BaseMath_ReadCallback(self) == -1) 00698 return NULL; 00699 00700 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); 00701 00702 return PyFloat_FromDouble(hsv[i]); 00703 } 00704 00705 static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void * type) 00706 { 00707 float hsv[3]; 00708 int i = GET_INT_FROM_POINTER(type); 00709 float f = PyFloat_AsDouble(value); 00710 00711 if (f == -1 && PyErr_Occurred()) { 00712 PyErr_SetString(PyExc_TypeError, 00713 "color.h/s/v = value: " 00714 "argument not a number"); 00715 return -1; 00716 } 00717 00718 if (BaseMath_ReadCallback(self) == -1) 00719 return -1; 00720 00721 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); 00722 CLAMP(f, 0.0f, 1.0f); 00723 hsv[i] = f; 00724 hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2])); 00725 00726 if (BaseMath_WriteCallback(self) == -1) 00727 return -1; 00728 00729 return 0; 00730 } 00731 00732 /* color channel (HSV), color.h/s/v */ 00733 PyDoc_STRVAR(Color_hsv_doc, "HSV Values in [0, 1].\n\n:type: float triplet"); 00734 static PyObject *Color_hsv_get(ColorObject *self, void *UNUSED(closure)) 00735 { 00736 float hsv[3]; 00737 PyObject *ret; 00738 00739 if (BaseMath_ReadCallback(self) == -1) 00740 return NULL; 00741 00742 rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2])); 00743 00744 ret = PyTuple_New(3); 00745 PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0])); 00746 PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1])); 00747 PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2])); 00748 return ret; 00749 } 00750 00751 static int Color_hsv_set(ColorObject *self, PyObject *value, void *UNUSED(closure)) 00752 { 00753 float hsv[3]; 00754 00755 if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1) 00756 return -1; 00757 00758 CLAMP(hsv[0], 0.0f, 1.0f); 00759 CLAMP(hsv[1], 0.0f, 1.0f); 00760 CLAMP(hsv[2], 0.0f, 1.0f); 00761 00762 hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2])); 00763 00764 if (BaseMath_WriteCallback(self) == -1) 00765 return -1; 00766 00767 return 0; 00768 } 00769 00770 /*****************************************************************************/ 00771 /* Python attributes get/set structure: */ 00772 /*****************************************************************************/ 00773 static PyGetSetDef Color_getseters[] = { 00774 {(char *)"r", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_r_doc, (void *)0}, 00775 {(char *)"g", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_g_doc, (void *)1}, 00776 {(char *)"b", (getter)Color_channel_get, (setter)Color_channel_set, Color_channel_b_doc, (void *)2}, 00777 00778 {(char *)"h", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_h_doc, (void *)0}, 00779 {(char *)"s", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_s_doc, (void *)1}, 00780 {(char *)"v", (getter)Color_channel_hsv_get, (setter)Color_channel_hsv_set, (char *)Color_channel_hsv_v_doc, (void *)2}, 00781 00782 {(char *)"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, (char *)Color_hsv_doc, (void *)0}, 00783 00784 {(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL}, 00785 {(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL}, 00786 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ 00787 }; 00788 00789 00790 //-----------------------METHOD DEFINITIONS ---------------------- 00791 static struct PyMethodDef Color_methods[] = { 00792 {"__copy__", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc}, 00793 {"copy", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc}, 00794 {NULL, NULL, 0, NULL} 00795 }; 00796 00797 //------------------PY_OBECT DEFINITION-------------------------- 00798 PyDoc_STRVAR(color_doc, 00799 "This object gives access to Colors in Blender." 00800 ); 00801 PyTypeObject color_Type = { 00802 PyVarObject_HEAD_INIT(NULL, 0) 00803 "mathutils.Color", //tp_name 00804 sizeof(ColorObject), //tp_basicsize 00805 0, //tp_itemsize 00806 (destructor)BaseMathObject_dealloc, //tp_dealloc 00807 NULL, //tp_print 00808 NULL, //tp_getattr 00809 NULL, //tp_setattr 00810 NULL, //tp_compare 00811 (reprfunc) Color_repr, //tp_repr 00812 &Color_NumMethods, //tp_as_number 00813 &Color_SeqMethods, //tp_as_sequence 00814 &Color_AsMapping, //tp_as_mapping 00815 NULL, //tp_hash 00816 NULL, //tp_call 00817 (reprfunc) Color_str, //tp_str 00818 NULL, //tp_getattro 00819 NULL, //tp_setattro 00820 NULL, //tp_as_buffer 00821 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags 00822 color_doc, //tp_doc 00823 (traverseproc)BaseMathObject_traverse, //tp_traverse 00824 (inquiry)BaseMathObject_clear, //tp_clear 00825 (richcmpfunc)Color_richcmpr, //tp_richcompare 00826 0, //tp_weaklistoffset 00827 NULL, //tp_iter 00828 NULL, //tp_iternext 00829 Color_methods, //tp_methods 00830 NULL, //tp_members 00831 Color_getseters, //tp_getset 00832 NULL, //tp_base 00833 NULL, //tp_dict 00834 NULL, //tp_descr_get 00835 NULL, //tp_descr_set 00836 0, //tp_dictoffset 00837 NULL, //tp_init 00838 NULL, //tp_alloc 00839 Color_new, //tp_new 00840 NULL, //tp_free 00841 NULL, //tp_is_gc 00842 NULL, //tp_bases 00843 NULL, //tp_mro 00844 NULL, //tp_cache 00845 NULL, //tp_subclasses 00846 NULL, //tp_weaklist 00847 NULL //tp_del 00848 }; 00849 //------------------------Color_CreatePyObject (internal)------------- 00850 //creates a new color object 00851 /*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER 00852 (i.e. it was allocated elsewhere by MEM_mallocN()) 00853 pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON 00854 (i.e. it must be created here with PyMEM_malloc())*/ 00855 PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type) 00856 { 00857 ColorObject *self; 00858 00859 self = base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) : 00860 (ColorObject *)PyObject_GC_New(ColorObject, &color_Type); 00861 00862 if (self) { 00863 /* init callbacks as NULL */ 00864 self->cb_user = NULL; 00865 self->cb_type = self->cb_subtype = 0; 00866 00867 if (type == Py_WRAP) { 00868 self->col = col; 00869 self->wrapped = Py_WRAP; 00870 } 00871 else if (type == Py_NEW) { 00872 self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float)); 00873 if (col) 00874 copy_v3_v3(self->col, col); 00875 else 00876 zero_v3(self->col); 00877 00878 self->wrapped = Py_NEW; 00879 } 00880 else { 00881 Py_FatalError("Color(): invalid type!"); 00882 } 00883 } 00884 00885 return (PyObject *)self; 00886 } 00887 00888 PyObject *Color_CreatePyObject_cb(PyObject *cb_user, int cb_type, int cb_subtype) 00889 { 00890 ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL); 00891 if (self) { 00892 Py_INCREF(cb_user); 00893 self->cb_user = cb_user; 00894 self->cb_type = (unsigned char)cb_type; 00895 self->cb_subtype = (unsigned char)cb_subtype; 00896 PyObject_GC_Track(self); 00897 } 00898 00899 return (PyObject *)self; 00900 }