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