From cf0e6464322bbdf6ae8b41f1dffc3e3704fad541 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 5 Jan 2013 13:51:07 +0000 Subject: [PATCH 001/132] Remove usage of deprecated TEX_USEALPHA from GE code --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index a4c4253754e..9267b2b9fed 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -650,11 +650,10 @@ static bool ConvertMaterial( material->texname[i] = material->img[i]->id.name; material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0; // ----------------------- - if ( mttmp->tex->imaflag &TEX_USEALPHA ) { + if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0) material->flag[i] |= USEALPHA; - } // ----------------------- - else if ( mttmp->tex->imaflag &TEX_CALCALPHA ) { + if ( mttmp->tex->imaflag &TEX_CALCALPHA ) { material->flag[i] |= CALCALPHA; } else if (mttmp->tex->flag &TEX_NEGALPHA) { From 5ee3cd6c86391e78a6905d1aa9c5241f623dcfc1 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 5 Jan 2013 13:52:41 +0000 Subject: [PATCH 002/132] Remove some uneeded/irrelevant "PROP_TRANSLATE". This sub-type is actually *only* needed for the "text" property of UI rna api (maybe we should rename it to "PROP_PY_TRANSLATE", as it is anyway only 'active' during conversion from py string to RNA string property...). In fact, I think it should only be used in RNA func properties anyway, as it stores the translated string into the property, it should only be used with "one time" RNA stuff... --- source/blender/makesrna/intern/rna_animation.c | 4 ++-- source/blender/makesrna/intern/rna_render.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 2 +- source/blender/makesrna/intern/rna_wm.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 402d05a20b6..cedb741b994 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -577,7 +577,7 @@ static void rna_def_keyingset_info(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); @@ -777,7 +777,7 @@ static void rna_def_keyingset(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_SCENE | ND_KEYINGSET | NA_RENAME, NULL); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 93c5b45e642..91b25bbc40a 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -415,7 +415,7 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER | PROP_NEVER_CLAMP); - prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->name"); RNA_def_property_flag(prop, PROP_REGISTER); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 14789a437b7..0d8acb207a8 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -1000,7 +1000,7 @@ static void rna_def_menu(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The menu label"); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f123b564f8d..f46d24bc01c 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1340,7 +1340,7 @@ static void rna_def_operator(BlenderRNA *brna) /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */ RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); @@ -1407,7 +1407,7 @@ static void rna_def_macro_operator(BlenderRNA *brna) /* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */ RNA_def_property_flag(prop, PROP_REGISTER); - prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->description"); RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); From e8b415bdb4ba282e3574cad1463bf2512fe5eb8f Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sat, 5 Jan 2013 14:56:37 +0000 Subject: [PATCH 003/132] This patch adds support in bpy.props for getter/setter callback functions. We already have update callbacks, but generic get/set functions can come in handy in some cases where the functionality is too complex to use a single value. The current C callback functions are too simple allow a straightforward implementation, in particular they don't receive the PropertyRNA pointer itself as an argument, which means the callback cannot directly access the PropertyRNA's py_data pointers which store the python function objects. For this reason a second runtime variant of these callbacks has been added. It is only used for runtime callbacks and not in makesrna, but otherwise works the same way. --- source/blender/makesrna/RNA_define.h | 12 +- source/blender/makesrna/RNA_types.h | 22 +- source/blender/makesrna/intern/makesrna.c | 35 +- source/blender/makesrna/intern/rna_access.c | 78 +- source/blender/makesrna/intern/rna_define.c | 144 +- .../makesrna/intern/rna_internal_types.h | 52 +- source/blender/python/generic/py_capi_utils.c | 48 + source/blender/python/generic/py_capi_utils.h | 2 + source/blender/python/intern/bpy_props.c | 2570 ++++++++++++----- 9 files changed, 2195 insertions(+), 768 deletions(-) diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 9939d0839e6..a435f9b0206 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -91,7 +91,6 @@ PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont, const char *ide PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description); void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc); -void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data); PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax); @@ -177,6 +176,17 @@ void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, con void RNA_def_property_srna(PropertyRNA *prop, const char *type); void RNA_def_py_data(PropertyRNA *prop, void *py_data); +void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc); +void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc); +void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc); +void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc); +void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc); +void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc); +void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc); +void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc); + +void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data); + void RNA_def_property_translation_context(PropertyRNA *prop, const char *context); /* Function */ diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index dacb2fee212..c76f9824c73 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -269,7 +269,27 @@ typedef struct EnumPropertyItem { const char *description; } EnumPropertyItem; -/* this is a copy of 'PropEnumItemFunc' defined in rna_internal_types.h */ +/* extended versions with PropertyRNA argument */ +typedef int (*BooleanPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*BooleanPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*BooleanArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*BooleanArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef int (*IntPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*IntPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*IntArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*IntArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef void (*IntPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax); +typedef float (*FloatPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*FloatPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value); +typedef void (*FloatArrayPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values); +typedef void (*FloatArrayPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values); +typedef void (*FloatPropertyRangeFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax); +typedef void (*StringPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value); +typedef int (*StringPropertyLengthFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*StringPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value); +typedef int (*EnumPropertyGetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*EnumPropertySetFunc)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +/* same as PropEnumItemFunc */ typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, struct PropertyRNA *prop, int *free); typedef struct PropertyRNA PropertyRNA; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 6b1f496b593..1ba50657751 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2947,11 +2947,15 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_BOOLEAN: { BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %d, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %d, ", rna_function_string(bprop->get), rna_function_string(bprop->set), rna_function_string(bprop->getarray), rna_function_string(bprop->setarray), + rna_function_string(bprop->get_ex), + rna_function_string(bprop->set_ex), + rna_function_string(bprop->getarray_ex), + rna_function_string(bprop->setarray_ex), bprop->defaultvalue); if (prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier); @@ -2961,12 +2965,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_INT: { IntPropertyRNA *iprop = (IntPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %s,\n\t", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,\n\t", rna_function_string(iprop->get), rna_function_string(iprop->set), rna_function_string(iprop->getarray), rna_function_string(iprop->setarray), - rna_function_string(iprop->range)); + rna_function_string(iprop->range), + rna_function_string(iprop->get_ex), + rna_function_string(iprop->set_ex), + rna_function_string(iprop->getarray_ex), + rna_function_string(iprop->setarray_ex), + rna_function_string(iprop->range_ex)); rna_int_print(f, iprop->softmin); fprintf(f, ", "); rna_int_print(f, iprop->softmax); fprintf(f, ", "); rna_int_print(f, iprop->hardmin); fprintf(f, ", "); @@ -2981,12 +2990,17 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_FLOAT: { FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %s, %s, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), - rna_function_string(fprop->range)); + rna_function_string(fprop->range), + rna_function_string(fprop->get_ex), + rna_function_string(fprop->set_ex), + rna_function_string(fprop->getarray_ex), + rna_function_string(fprop->setarray_ex), + rna_function_string(fprop->range_ex)); rna_float_print(f, fprop->softmin); fprintf(f, ", "); rna_float_print(f, fprop->softmax); fprintf(f, ", "); rna_float_print(f, fprop->hardmin); fprintf(f, ", "); @@ -3002,10 +3016,13 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_STRING: { StringPropertyRNA *sprop = (StringPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, %d, ", + fprintf(f, "\t%s, %s, %s, %s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), + rna_function_string(sprop->get_ex), + rna_function_string(sprop->length_ex), + rna_function_string(sprop->set_ex), sprop->maxlength); rna_print_c_string(f, sprop->defaultvalue); fprintf(f, "\n"); break; @@ -3013,10 +3030,12 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr case PROP_ENUM: { EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; - fprintf(f, "\t%s, %s, %s, NULL, ", + fprintf(f, "\t%s, %s, %s, %s, %s, NULL, ", rna_function_string(eprop->get), rna_function_string(eprop->set), - rna_function_string(eprop->itemf)); + rna_function_string(eprop->itemf), + rna_function_string(eprop->get_ex), + rna_function_string(eprop->set_ex)); if (eprop->item) fprintf(f, "rna_%s%s_%s_items, ", srna->identifier, strnest, prop->identifier); else diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 0048e1c60c2..012575616a1 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_dynstr.h" #include "BLI_ghash.h" +#include "BLI_math.h" #include "BLF_api.h" #include "BLF_translation.h" @@ -937,6 +938,12 @@ void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, in iprop->range(ptr, hardmin, hardmax, &softmin, &softmax); } + else if (iprop->range_ex) { + *hardmin = INT_MIN; + *hardmax = INT_MAX; + + iprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax); + } else { *hardmin = iprop->hardmin; *hardmax = iprop->hardmax; @@ -977,8 +984,17 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, iprop->range(ptr, &hardmin, &hardmax, softmin, softmax); - *softmin = MAX2(*softmin, hardmin); - *softmax = MIN2(*softmax, hardmax); + *softmin = max_ii(*softmin, hardmin); + *softmax = min_ii(*softmax, hardmax); + } + else if (iprop->range_ex) { + hardmin = INT_MIN; + hardmax = INT_MAX; + + iprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax); + + *softmin = max_ii(*softmin, hardmin); + *softmax = min_ii(*softmax, hardmax); } *step = iprop->step; @@ -1012,6 +1028,12 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin fprop->range(ptr, hardmin, hardmax, &softmin, &softmax); } + else if (fprop->range_ex) { + *hardmin = -FLT_MAX; + *hardmax = FLT_MAX; + + fprop->range_ex(ptr, prop, hardmin, hardmax, &softmin, &softmax); + } else { *hardmin = fprop->hardmin; *hardmax = fprop->hardmax; @@ -1056,8 +1078,17 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft fprop->range(ptr, &hardmin, &hardmax, softmin, softmax); - *softmin = MAX2(*softmin, hardmin); - *softmax = MIN2(*softmax, hardmax); + *softmin = max_ff(*softmin, hardmin); + *softmax = min_ff(*softmax, hardmax); + } + else if (fprop->range_ex) { + hardmin = -FLT_MAX; + hardmax = FLT_MAX; + + fprop->range_ex(ptr, prop, &hardmin, &hardmax, softmin, softmax); + + *softmin = max_ff(*softmin, hardmin); + *softmax = min_ff(*softmax, hardmax); } *step = fprop->step; @@ -1645,6 +1676,8 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (bprop->get) return bprop->get(ptr); + else if (bprop->get_ex) + return bprop->get_ex(ptr, prop); else return bprop->defaultvalue; } @@ -1667,6 +1700,9 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value) else if (bprop->set) { bprop->set(ptr, value); } + else if (bprop->set_ex) { + bprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1697,6 +1733,8 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val values[0] = RNA_property_boolean_get(ptr, prop); else if (bprop->getarray) bprop->getarray(ptr, values); + else if (bprop->getarray_ex) + bprop->getarray_ex(ptr, prop, values); else if (bprop->defaultarray) memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength); else @@ -1747,6 +1785,8 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in RNA_property_boolean_set(ptr, prop, values[0]); else if (bprop->setarray) bprop->setarray(ptr, values); + else if (bprop->setarray_ex) + bprop->setarray_ex(ptr, prop, values); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1848,6 +1888,8 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (iprop->get) return iprop->get(ptr); + else if (iprop->get_ex) + return iprop->get_ex(ptr, prop); else return iprop->defaultvalue; } @@ -1868,6 +1910,8 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value) } else if (iprop->set) iprop->set(ptr, value); + else if (iprop->set_ex) + iprop->set_ex(ptr, prop, value); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -1900,6 +1944,8 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values) values[0] = RNA_property_int_get(ptr, prop); else if (iprop->getarray) iprop->getarray(ptr, values); + else if (iprop->getarray_ex) + iprop->getarray_ex(ptr, prop, values); else if (iprop->defaultarray) memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength); else @@ -1987,6 +2033,8 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v RNA_property_int_set(ptr, prop, values[0]); else if (iprop->setarray) iprop->setarray(ptr, values); + else if (iprop->setarray_ex) + iprop->setarray_ex(ptr, prop, values); else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2087,6 +2135,8 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop) } else if (fprop->get) return fprop->get(ptr); + else if (fprop->get_ex) + return fprop->get_ex(ptr, prop); else return fprop->defaultvalue; } @@ -2112,6 +2162,9 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value) else if (fprop->set) { fprop->set(ptr, value); } + else if (fprop->set_ex) { + fprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2150,6 +2203,8 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val values[0] = RNA_property_float_get(ptr, prop); else if (fprop->getarray) fprop->getarray(ptr, values); + else if (fprop->getarray_ex) + fprop->getarray_ex(ptr, prop, values); else if (fprop->defaultarray) memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength); else @@ -2249,6 +2304,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa else if (fprop->setarray) { fprop->setarray(ptr, values); } + else if (fprop->setarray_ex) { + fprop->setarray_ex(ptr, prop, values); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; @@ -2361,6 +2419,9 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value) else if (sprop->get) { sprop->get(ptr, value); } + else if (sprop->get_ex) { + sprop->get_ex(ptr, prop, value); + } else { strcpy(value, sprop->defaultvalue); } @@ -2421,6 +2482,8 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop) } else if (sprop->length) return sprop->length(ptr); + else if (sprop->length_ex) + return sprop->length_ex(ptr, prop); else return strlen(sprop->defaultvalue); } @@ -2439,6 +2502,8 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val } else if (sprop->set) sprop->set(ptr, value); /* set function needs to clamp its self */ + else if (sprop->set_ex) + sprop->set_ex(ptr, prop, value); /* set function needs to clamp its self */ else if (prop->flag & PROP_EDITABLE) { IDProperty *group; @@ -2497,6 +2562,8 @@ int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop) return IDP_Int(idprop); else if (eprop->get) return eprop->get(ptr); + else if (eprop->get_ex) + return eprop->get_ex(ptr, prop); else return eprop->defaultvalue; } @@ -2515,6 +2582,9 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value) else if (eprop->set) { eprop->set(ptr, value); } + else if (eprop->set_ex) { + eprop->set_ex(ptr, prop, value); + } else if (prop->flag & PROP_EDITABLE) { IDPropertyTemplate val = {0}; IDProperty *group; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 727b1e44931..0a8254cb9c1 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2017,6 +2017,38 @@ void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const ch } } +void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop, BooleanPropertyGetFunc getfunc, BooleanPropertySetFunc setfunc) +{ + BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; + + if (getfunc) bprop->get_ex = getfunc; + if (setfunc) bprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop, BooleanArrayPropertyGetFunc getfunc, BooleanArrayPropertySetFunc setfunc) +{ + BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop; + + if (getfunc) bprop->getarray_ex = getfunc; + if (setfunc) bprop->setarray_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range) { StructRNA *srna = DefRNA.laststruct; @@ -2049,6 +2081,38 @@ void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char * } } +void RNA_def_property_int_funcs_runtime(PropertyRNA *prop, IntPropertyGetFunc getfunc, IntPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc) +{ + IntPropertyRNA *iprop = (IntPropertyRNA *)prop; + + if (getfunc) iprop->get_ex = getfunc; + if (setfunc) iprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc) +{ + IntPropertyRNA *iprop = (IntPropertyRNA *)prop; + + if (getfunc) iprop->getarray_ex = getfunc; + if (setfunc) iprop->setarray_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range) { StructRNA *srna = DefRNA.laststruct; @@ -2081,6 +2145,40 @@ void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char } } +void RNA_def_property_float_funcs_runtime(PropertyRNA *prop, FloatPropertyGetFunc getfunc, FloatPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc) +{ + FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; + + if (getfunc) fprop->get_ex = getfunc; + if (setfunc) fprop->set_ex = setfunc; + if (rangefunc) fprop->range_ex = rangefunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc) +{ + FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; + + if (getfunc) fprop->getarray_ex = getfunc; + if (setfunc) fprop->setarray_ex = setfunc; + if (rangefunc) fprop->range_ex = rangefunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item) { StructRNA *srna = DefRNA.laststruct; @@ -2107,6 +2205,29 @@ void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char } } +void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc) +{ + EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; + + if (getfunc) eprop->get_ex = getfunc; + if (setfunc) eprop->set_ex = setfunc; + if (itemfunc) eprop->itemf = itemfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + +void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data) +{ + EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; + eprop->py_data = py_data; +} + void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set) { StructRNA *srna = DefRNA.laststruct; @@ -2133,6 +2254,23 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha } } +void RNA_def_property_string_funcs_runtime(PropertyRNA *prop, StringPropertyGetFunc getfunc, StringPropertyLengthFunc lengthfunc, StringPropertySetFunc setfunc) +{ + StringPropertyRNA *sprop = (StringPropertyRNA *)prop; + + if (getfunc) sprop->get_ex = getfunc; + if (lengthfunc) sprop->length_ex = lengthfunc; + if (setfunc) sprop->set_ex = setfunc; + + if (getfunc || setfunc) { + /* don't save in id properties */ + prop->flag &= ~PROP_IDPROPERTY; + + if (!setfunc) + prop->flag &= ~PROP_EDITABLE; + } +} + void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll) { @@ -2447,12 +2585,6 @@ void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc) eprop->itemf = itemfunc; } -void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data) -{ - EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop; - eprop->py_data = py_data; -} - PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax) diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index ccfb83b61e3..b16f0d69fba 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -30,6 +30,8 @@ #include "DNA_listBase.h" +#include "RNA_types.h" + struct BlenderRNA; struct ContainerRNA; struct StructRNA; @@ -103,6 +105,27 @@ typedef int (*PropCollectionLookupIntFunc)(struct PointerRNA *ptr, int key, stru typedef int (*PropCollectionLookupStringFunc)(struct PointerRNA *ptr, const char *key, struct PointerRNA *r_ptr); typedef int (*PropCollectionAssignIntFunc)(struct PointerRNA *ptr, int key, const struct PointerRNA *assign_ptr); +/* extended versions with PropertyRNA argument */ +typedef int (*PropBooleanGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropBooleanSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*PropBooleanArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*PropBooleanArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef int (*PropIntGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropIntSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); +typedef void (*PropIntArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values); +typedef void (*PropIntArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values); +typedef void (*PropIntRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int *min, int *max, int *softmin, int *softmax); +typedef float (*PropFloatGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropFloatSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float value); +typedef void (*PropFloatArrayGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values); +typedef void (*PropFloatArraySetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values); +typedef void (*PropFloatRangeFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, float *min, float *max, float *softmin, float *softmax); +typedef void (*PropStringGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value); +typedef int (*PropStringLengthFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropStringSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value); +typedef int (*PropEnumGetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop); +typedef void (*PropEnumSetFuncEx)(struct PointerRNA *ptr, struct PropertyRNA *prop, int value); + /* Container - generic abstracted container of RNA properties */ typedef struct ContainerRNA { void *next, *prev; @@ -193,10 +216,14 @@ typedef struct BoolPropertyRNA { PropBooleanGetFunc get; PropBooleanSetFunc set; - PropBooleanArrayGetFunc getarray; PropBooleanArraySetFunc setarray; + PropBooleanGetFuncEx get_ex; + PropBooleanSetFuncEx set_ex; + PropBooleanArrayGetFuncEx getarray_ex; + PropBooleanArraySetFuncEx setarray_ex; + int defaultvalue; const int *defaultarray; } BoolPropertyRNA; @@ -206,12 +233,16 @@ typedef struct IntPropertyRNA { PropIntGetFunc get; PropIntSetFunc set; - PropIntArrayGetFunc getarray; PropIntArraySetFunc setarray; - PropIntRangeFunc range; + PropIntGetFuncEx get_ex; + PropIntSetFuncEx set_ex; + PropIntArrayGetFuncEx getarray_ex; + PropIntArraySetFuncEx setarray_ex; + PropIntRangeFuncEx range_ex; + int softmin, softmax; int hardmin, hardmax; int step; @@ -225,12 +256,16 @@ typedef struct FloatPropertyRNA { PropFloatGetFunc get; PropFloatSetFunc set; - PropFloatArrayGetFunc getarray; PropFloatArraySetFunc setarray; - PropFloatRangeFunc range; + PropFloatGetFuncEx get_ex; + PropFloatSetFuncEx set_ex; + PropFloatArrayGetFuncEx getarray_ex; + PropFloatArraySetFuncEx setarray_ex; + PropFloatRangeFuncEx range_ex; + float softmin, softmax; float hardmin, hardmax; float step; @@ -247,6 +282,10 @@ typedef struct StringPropertyRNA { PropStringLengthFunc length; PropStringSetFunc set; + PropStringGetFuncEx get_ex; + PropStringLengthFuncEx length_ex; + PropStringSetFuncEx set_ex; + int maxlength; /* includes string terminator! */ const char *defaultvalue; @@ -258,6 +297,9 @@ typedef struct EnumPropertyRNA { PropEnumGetFunc get; PropEnumSetFunc set; PropEnumItemFunc itemf; + + PropEnumGetFuncEx get_ex; + PropEnumSetFuncEx set_ex; void *py_data; /* store py callback here */ EnumPropertyItem *item; diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 9a064923736..86230318896 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -112,6 +112,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, return 0; } +/* array utility function */ +PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const short is_double, const char *error_prefix) +{ + PyObject *tuple; + int i; + + tuple = PyTuple_New(length); + + /* for each type */ + if (type == &PyFloat_Type) { + if (is_double) { + const double *array_double = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i])); + } + } + else { + const float *array_float = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i])); + } + } + } + else if (type == &PyLong_Type) { + /* could use is_double for 'long int' but no use now */ + const int *array_int = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i])); + } + } + else if (type == &PyBool_Type) { + const int *array_bool = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i])); + } + } + else { + Py_DECREF(tuple); + PyErr_Format(PyExc_TypeError, + "%s: internal error %s is invalid", + error_prefix, type->tp_name); + return NULL; + } + + return tuple; +} + /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index db582bd7086..b4eea6ac90c 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -39,6 +39,8 @@ void PyC_FileAndNum(const char **filename, int *lineno); void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const short is_double, const char *error_prefix); +PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const short is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 57ddee0c8c0..d3ce25b4f04 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -50,9 +50,11 @@ #include "../generic/py_capi_utils.h" /* initial definition of callback slots we'll probably have more then 1 */ -#define BPY_DATA_CB_SLOT_SIZE 1 +#define BPY_DATA_CB_SLOT_SIZE 3 #define BPY_DATA_CB_SLOT_UPDATE 0 +#define BPY_DATA_CB_SLOT_GET 1 +#define BPY_DATA_CB_SLOT_SET 2 extern BPy_StructRNA *bpy_context_module; @@ -234,43 +236,810 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc } } -static int bpy_prop_callback_check(PyObject *py_func, int argcount) +static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) { - if (py_func && py_func != Py_None) { - if (!PyFunction_Check(py_func)) { - PyErr_Format(PyExc_TypeError, - "update keyword: expected a function type, not a %.200s", - Py_TYPE(py_func)->tp_name); - return -1; - } - else { - PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); - if (f_code->co_argcount != argcount) { - PyErr_Format(PyExc_TypeError, - "update keyword: expected a function taking %d arguments, not %d", - argcount, f_code->co_argcount); - return -1; - } - } + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); } - return 0; + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = FALSE; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = FALSE; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } + + return value; } - -static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb) +static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) { - /* assume this is already checked for type and arg length */ - if (update_cb && update_cb != Py_None) { - PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); - RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); - py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; - RNA_def_py_data(prop, py_data); + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); - RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); } - return 0; + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = FALSE; + } + else { + if (ret && PyC_AsArray(values, ret, len, &PyBool_Type, FALSE, "BoolVectorProperty get") < 0) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = FALSE; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyBool_Type, FALSE, "BoolVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } + + return value; +} + +static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + } + else { + if (ret && PyC_AsArray(values, ret, len, &PyLong_Type, FALSE, "IntVectorProperty get") < 0) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyLong_Type, FALSE, "IntVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + float value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyFloat_AsDouble(ret); + + if (value == -1.0f && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0.0f; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } + + return value; +} + +static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + } + else { + if (ret && PyC_AsArray(values, ret, len, &PyFloat_Type, FALSE, "FloatVectorProperty get") < 0) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyFloat_Type, FALSE, "FloatVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value[0] = '\0'; + } + else { + Py_ssize_t length; + char *buffer = _PyUnicode_AsStringAndSize(ret, &length); + + if (!buffer && PyErr_Occurred()) { + printf_func_error(py_func); + value[0] = '\0'; + } + else { + memcpy(value, buffer, length+1); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int length; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + length = PyUnicode_GetLength(ret); + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } + + return length; +} + +static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + PyObject *py_value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_value = PyUnicode_FromString(value); + if (!py_value) { + PyErr_SetString(PyExc_ValueError, "the return value must be a string"); + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_value); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } +} + +static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } + + return value; +} + +static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(TRUE); + } + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (!is_write_ok) { + pyrna_write_set(FALSE); + } } /* utility function we need for parsing int's in an if statement */ @@ -285,702 +1054,6 @@ static int py_long_as_int(PyObject *py_long, int *r_int) } } -/* this define runs at the start of each function and deals with - * returning a deferred property (to be registered later) */ -#define BPY_PROPDEF_HEAD(_func) \ - if (PyTuple_GET_SIZE(args) == 1) { \ - PyObject *ret; \ - self = PyTuple_GET_ITEM(args, 0); \ - args = PyTuple_New(0); \ - ret = BPy_##_func(self, args, kw); \ - Py_DECREF(args); \ - return ret; \ - } \ - else if (PyTuple_GET_SIZE(args) > 1) { \ - PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ - return NULL; \ - } \ - srna = srna_from_self(self, #_func"(...):"); \ - if (srna == NULL) { \ - if (PyErr_Occurred()) \ - return NULL; \ - return bpy_prop_deferred_return(pymeth_##_func, kw); \ - } (void)0 - -/* terse macros for error checks shared between all funcs cant use function - * calls because of static strings passed to pyrna_set_to_enum_bitfield */ -#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ - if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \ - PyErr_Format(PyExc_TypeError, \ - #_func"(): '%.200s' too long, max length is %d", \ - id, MAX_IDPROP_NAME - 1); \ - return NULL; \ - } \ - if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \ - PyErr_Format(PyExc_TypeError, \ - #_func"(): '%s' is defined as a non-dynamic type", \ - id); \ - return NULL; \ - } \ - if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ - pyopts, \ - &opts, \ - #_func"(options={ ...}):"))) \ - { \ - return NULL; \ - } (void)0 - -#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ - BPY_PROPDEF_CHECK(_func, _property_flag_items); \ - if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \ - pysubtype, \ - &subtype) == 0)) \ - { \ - const char *enum_str = BPy_enum_as_string(_subtype); \ - PyErr_Format(PyExc_TypeError, \ - #_func"(subtype='%s'): " \ - "subtype not found in (%s)", \ - pysubtype, enum_str); \ - MEM_freeN((void *)enum_str); \ - return NULL; \ - } (void)0 - - -#define BPY_PROPDEF_NAME_DOC \ -" :arg name: Name used in the user interface.\n" \ -" :type name: string\n" \ - - -#define BPY_PROPDEF_DESC_DOC \ -" :arg description: Text used for the tooltip and api documentation.\n" \ -" :type description: string\n" \ - - -#define BPY_PROPDEF_UNIT_DOC \ -" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \ -" :type unit: string\n" \ - - -#define BPY_PROPDEF_UPDATE_DOC \ -" :arg update: function to be called when this value is modified,\n" \ -" This function must take 2 values (self, context) and return None.\n" \ -" *Warning* there are no safety checks to avoid infinite recursion.\n" \ -" :type update: function\n" \ - -#if 0 -static int bpy_struct_id_used(StructRNA *srna, char *identifier) -{ - PointerRNA ptr; - RNA_pointer_create(NULL, srna, NULL, &ptr); - return (RNA_struct_find_property(&ptr, identifier) != NULL); -} -#endif - - -/* Function that sets RNA, NOTE - self is NULL when called from python, - * but being abused from C so we can pass the srna along. - * This isn't incorrect since its a python object - but be careful */ -PyDoc_STRVAR(BPy_BoolProperty_doc, -".. function:: BoolProperty(name=\"\", " - "description=\"\", " - "default=False, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "update=None)\n" -"\n" -" Returns a new boolean property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" -" :type subtype: string\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(BoolProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - int def = 0; - PropertyRNA *prop; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiO!sO:BoolProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &PySet_Type, &pyopts, &pysubtype, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items); - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); - RNA_def_property_boolean_default(prop, def); - RNA_def_property_ui_text(prop, name ? name : id, description); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(BPy_BoolVectorProperty_doc, -".. function:: BoolVectorProperty(name=\"\", " - "description=\"\", " - "default=(False, False, False), " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "size=3, " - "update=None)\n" -"\n" -" Returns a new vector boolean property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg default: sequence of booleans the length of *size*.\n" -" :type default: sequence\n" -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " - "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " - "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" -" :type subtype: string\n" -" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" -" :type size: int\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(BoolVectorProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "size", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - int def[PYRNA_STACK_ARRAY] = {0}; - int size = 3; - PropertyRNA *prop; - PyObject *pydef = NULL; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOO!siO:BoolVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items); - - if (size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, - "BoolVectorProperty(size=%d): size must be between 0 and " - STRINGIFY(PYRNA_STACK_ARRAY), size); - return NULL; - } - - if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) - return NULL; - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - // prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description); - prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); - RNA_def_property_array(prop, size); - if (pydef) RNA_def_property_boolean_array_default(prop, def); - RNA_def_property_ui_text(prop, name ? name : id, description); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(BPy_IntProperty_doc, -".. function:: IntProperty(name=\"\", " - "description=\"\", " - "default=0, " - "min=-sys.maxint, max=sys.maxint, " - "soft_min=-sys.maxint, soft_max=sys.maxint, " - "step=1, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "update=None)\n" -"\n" -" Returns a new int property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" -" :type subtype: string\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(IntProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; - PropertyRNA *prop; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiiiiiiO!sO:IntProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &min, &max, &soft_min, &soft_max, - &step, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items); - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_INT, subtype); - RNA_def_property_int_default(prop, def); - RNA_def_property_ui_text(prop, name ? name : id, description); - RNA_def_property_range(prop, min, max); - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(BPy_IntVectorProperty_doc, -".. function:: IntVectorProperty(name=\"\", " - "description=\"\", " - "default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, " - "soft_min=-sys.maxint, " - "soft_max=sys.maxint, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "size=3, " - "update=None)\n" -"\n" -" Returns a new vector int property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg default: sequence of ints the length of *size*.\n" -" :type default: sequence\n" -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " - "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " - "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" -" :type subtype: string\n" -" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" -" :type size: int\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(IntVectorProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "size", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; - int def[PYRNA_STACK_ARRAY] = {0}; - int size = 3; - PropertyRNA *prop; - PyObject *pydef = NULL; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOiiiiiO!siO:IntVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &min, &max, &soft_min, &soft_max, - &step, &PySet_Type, &pyopts, - &pysubtype, &size, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items); - - if (size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, - "IntVectorProperty(size=%d): size must be between 0 and " - STRINGIFY(PYRNA_STACK_ARRAY), size); - return NULL; - } - - if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) - return NULL; - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_INT, subtype); - RNA_def_property_array(prop, size); - if (pydef) RNA_def_property_int_array_default(prop, def); - RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name ? name : id, description); - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - Py_RETURN_NONE; -} - - -PyDoc_STRVAR(BPy_FloatProperty_doc, -".. function:: FloatProperty(name=\"\", " - "description=\"\", " - "default=0.0, " - "min=sys.float_info.min, max=sys.float_info.max, " - "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " - "step=3, " - "precision=2, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "unit='NONE', " - "update=None)\n" -"\n" -" Returns a new float property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" -" :type subtype: string\n" -BPY_PROPDEF_UNIT_DOC -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(FloatProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; - int precision = 2; - PropertyRNA *prop; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - char *pyunit = NULL; - int unit = PROP_UNIT_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssffffffiO!ssO:FloatProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &min, &max, &soft_min, &soft_max, - &step, &precision, &PySet_Type, - &pyopts, &pysubtype, &pyunit, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items); - - if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { - PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit); - return NULL; - } - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); - RNA_def_property_float_default(prop, def); - RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name ? name : id, description); - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(BPy_FloatVectorProperty_doc, -".. function:: FloatVectorProperty(name=\"\", " - "description=\"\", " - "default=(0.0, 0.0, 0.0), " - "min=sys.float_info.min, max=sys.float_info.max, " - "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " - "step=3, " - "precision=2, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "size=3, " - "update=None)\n" -"\n" -" Returns a new vector float property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg default: sequence of floats the length of *size*.\n" -" :type default: sequence\n" -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " - "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', " - "'COLOR_GAMMA', 'LAYER', 'NONE'].\n" -" :type subtype: string\n" -BPY_PROPDEF_UNIT_DOC -" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" -" :type size: int\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(FloatVectorProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "size", "update", NULL}; - const char *id = NULL, *name = NULL, *description = ""; - int id_len; - float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; - float def[PYRNA_STACK_ARRAY] = {0.0f}; - int precision = 2, size = 3; - PropertyRNA *prop; - PyObject *pydef = NULL; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - char *pyunit = NULL; - int unit = PROP_UNIT_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOfffffiO!ssiO:FloatVectorProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &pydef, - &min, &max, &soft_min, &soft_max, - &step, &precision, &PySet_Type, - &pyopts, &pysubtype, &pyunit, &size, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items); - - if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { - PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit); - return NULL; - } - - if (size < 1 || size > PYRNA_STACK_ARRAY) { - PyErr_Format(PyExc_TypeError, - "FloatVectorProperty(size=%d): size must be between 0 and " - STRINGIFY(PYRNA_STACK_ARRAY), size); - return NULL; - } - - if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) - return NULL; - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); - RNA_def_property_array(prop, size); - if (pydef) RNA_def_property_float_array_default(prop, def); - RNA_def_property_range(prop, min, max); - RNA_def_property_ui_text(prop, name ? name : id, description); - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(BPy_StringProperty_doc, -".. function:: StringProperty(name=\"\", " - "description=\"\", " - "default=\"\", " - "maxlen=0, " - "options={'ANIMATABLE'}, " - "subtype='NONE', " - "update=None)\n" -"\n" -" Returns a new string property definition.\n" -"\n" -BPY_PROPDEF_NAME_DOC -BPY_PROPDEF_DESC_DOC -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" -" :type options: set\n" -" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n" -" :type subtype: string\n" -BPY_PROPDEF_UPDATE_DOC -); -static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) -{ - StructRNA *srna; - - BPY_PROPDEF_HEAD(StringProperty); - - if (srna) { - static const char *kwlist[] = {"attr", "name", "description", "default", - "maxlen", "options", "subtype", "update", NULL}; - const char *id = NULL, *name = NULL, *description = "", *def = ""; - int id_len; - int maxlen = 0; - PropertyRNA *prop; - PyObject *pyopts = NULL; - int opts = 0; - char *pysubtype = NULL; - int subtype = PROP_NONE; - PyObject *update_cb = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|sssiO!sO:StringProperty", - (char **)kwlist, &id, &id_len, - &name, &description, &def, - &maxlen, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) - { - return NULL; - } - - BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items); - - if (bpy_prop_callback_check(update_cb, 2) == -1) { - return NULL; - } - - prop = RNA_def_property(srna, id, PROP_STRING, subtype); - if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */ - if (def) RNA_def_property_string_default(prop, def); - RNA_def_property_ui_text(prop, name ? name : id, description); - - if (pyopts) { - if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); - if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); - if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); - } - bpy_prop_callback_assign(prop, update_cb); - RNA_def_property_duplicate_pointers(srna, prop); - } - Py_RETURN_NONE; -} - #if 0 /* copies orig to buf, then sets orig to buf, returns copy length */ static size_t strswapbufcpy(char *buf, const char **orig) @@ -1142,7 +1215,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i return items; } -static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) +static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) { PyGILState_STATE gilstate; @@ -1208,13 +1281,1024 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt return eitems; } +static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount) +{ + if (py_func && py_func != Py_None) { + if (!PyFunction_Check(py_func)) { + PyErr_Format(PyExc_TypeError, + "%s keyword: expected a function type, not a %.200s", + keyword, Py_TYPE(py_func)->tp_name); + return -1; + } + else { + PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); + if (f_code->co_argcount != argcount) { + PyErr_Format(PyExc_TypeError, + "%s keyword: expected a function taking %d arguments, not %d", + keyword, argcount, f_code->co_argcount); + return -1; + } + } + } + + return 0; +} + +static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop) +{ + PyObject **py_data = RNA_property_py_data_get(prop); + if (!py_data) { + py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + RNA_def_py_data(prop, py_data); + } + return py_data; +} + +static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb) +{ + /* assume this is already checked for type and arg length */ + if (update_cb && update_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); + py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; + + RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); + } +} + +static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + BooleanPropertyGetFunc rna_get_cb = NULL; + BooleanPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + BooleanArrayPropertyGetFunc rna_get_cb = NULL; + BooleanArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntPropertyGetFunc rna_get_cb = NULL; + IntPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntArrayPropertyGetFunc rna_get_cb = NULL; + IntArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatPropertyGetFunc rna_get_cb = NULL; + FloatPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatArrayPropertyGetFunc rna_get_cb = NULL; + FloatArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + StringPropertyGetFunc rna_get_cb = NULL; + StringPropertyLengthFunc rna_length_cb = NULL; + StringPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_string_get_cb; + rna_length_cb = bpy_prop_string_length_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_string_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb) +{ + EnumPropertyGetFunc rna_get_cb = NULL; + EnumPropertyItemFunc rna_itemf_cb = NULL; + EnumPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_enum_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_enum_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + if (itemf_cb && itemf_cb != Py_None) { + rna_itemf_cb = bpy_prop_enum_itemf_cb; + RNA_def_property_enum_py_data(prop, (void *)itemf_cb); + + /* watch out!, if a user is tricky they can probably crash blender + * if they manage to free the callback, take care! */ + /* Py_INCREF(itemf_cb); */ + } + + RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb); +} + +/* this define runs at the start of each function and deals with + * returning a deferred property (to be registered later) */ +#define BPY_PROPDEF_HEAD(_func) \ + if (PyTuple_GET_SIZE(args) == 1) { \ + PyObject *ret; \ + self = PyTuple_GET_ITEM(args, 0); \ + args = PyTuple_New(0); \ + ret = BPy_##_func(self, args, kw); \ + Py_DECREF(args); \ + return ret; \ + } \ + else if (PyTuple_GET_SIZE(args) > 1) { \ + PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ + return NULL; \ + } \ + srna = srna_from_self(self, #_func"(...):"); \ + if (srna == NULL) { \ + if (PyErr_Occurred()) \ + return NULL; \ + return bpy_prop_deferred_return(pymeth_##_func, kw); \ + } (void)0 + +/* terse macros for error checks shared between all funcs cant use function + * calls because of static strings passed to pyrna_set_to_enum_bitfield */ +#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ + if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(): '%.200s' too long, max length is %d", \ + id, MAX_IDPROP_NAME - 1); \ + return NULL; \ + } \ + if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(): '%s' is defined as a non-dynamic type", \ + id); \ + return NULL; \ + } \ + if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ + pyopts, \ + &opts, \ + #_func"(options={ ...}):"))) \ + { \ + return NULL; \ + } (void)0 + +#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ + BPY_PROPDEF_CHECK(_func, _property_flag_items); \ + if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \ + pysubtype, \ + &subtype) == 0)) \ + { \ + const char *enum_str = BPy_enum_as_string(_subtype); \ + PyErr_Format(PyExc_TypeError, \ + #_func"(subtype='%s'): " \ + "subtype not found in (%s)", \ + pysubtype, enum_str); \ + MEM_freeN((void *)enum_str); \ + return NULL; \ + } (void)0 + + +#define BPY_PROPDEF_NAME_DOC \ +" :arg name: Name used in the user interface.\n" \ +" :type name: string\n" \ + + +#define BPY_PROPDEF_DESC_DOC \ +" :arg description: Text used for the tooltip and api documentation.\n" \ +" :type description: string\n" \ + + +#define BPY_PROPDEF_UNIT_DOC \ +" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \ +" :type unit: string\n" \ + + +#define BPY_PROPDEF_UPDATE_DOC \ +" :arg update: function to be called when this value is modified,\n" \ +" This function must take 2 values (self, context) and return None.\n" \ +" *Warning* there are no safety checks to avoid infinite recursion.\n" \ +" :type update: function\n" \ + +#if 0 +static int bpy_struct_id_used(StructRNA *srna, char *identifier) +{ + PointerRNA ptr; + RNA_pointer_create(NULL, srna, NULL, &ptr); + return (RNA_struct_find_property(&ptr, identifier) != NULL); +} +#endif + + +/* Function that sets RNA, NOTE - self is NULL when called from python, + * but being abused from C so we can pass the srna along. + * This isn't incorrect since its a python object - but be careful */ +PyDoc_STRVAR(BPy_BoolProperty_doc, +".. function:: BoolProperty(name=\"\", " + "description=\"\", " + "default=False, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new boolean property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" +" :type subtype: string\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(BoolProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "options", "subtype", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + int def = 0; + PropertyRNA *prop; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssiO!sOOO:BoolProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &def, + &PySet_Type, &pyopts, &pysubtype, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items); + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); + RNA_def_property_boolean_default(prop, def); + RNA_def_property_ui_text(prop, name ? name : id, description); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(BPy_BoolVectorProperty_doc, +".. function:: BoolVectorProperty(name=\"\", " + "description=\"\", " + "default=(False, False, False), " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new vector boolean property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg default: sequence of booleans the length of *size*.\n" +" :type default: sequence\n" +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " + "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :type subtype: string\n" +" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" +" :type size: int\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(BoolVectorProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "options", "subtype", "size", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + int def[PYRNA_STACK_ARRAY] = {0}; + int size = 3; + PropertyRNA *prop; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssOO!siOOO:BoolVectorProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &pydef, + &PySet_Type, &pyopts, &pysubtype, &size, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items); + + if (size < 1 || size > PYRNA_STACK_ARRAY) { + PyErr_Format(PyExc_TypeError, + "BoolVectorProperty(size=%d): size must be between 0 and " + STRINGIFY(PYRNA_STACK_ARRAY), size); + return NULL; + } + + if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) + return NULL; + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + // prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description); + prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); + RNA_def_property_array(prop, size); + if (pydef) RNA_def_property_boolean_array_default(prop, def); + RNA_def_property_ui_text(prop, name ? name : id, description); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(BPy_IntProperty_doc, +".. function:: IntProperty(name=\"\", " + "description=\"\", " + "default=0, " + "min=-sys.maxint, max=sys.maxint, " + "soft_min=-sys.maxint, soft_max=sys.maxint, " + "step=1, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new int property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" +" :type subtype: string\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(IntProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "options", "subtype", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; + PropertyRNA *prop; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssiiiiiiO!sOOO:IntProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &def, + &min, &max, &soft_min, &soft_max, + &step, &PySet_Type, &pyopts, &pysubtype, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items); + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_INT, subtype); + RNA_def_property_int_default(prop, def); + RNA_def_property_ui_text(prop, name ? name : id, description); + RNA_def_property_range(prop, min, max); + RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(BPy_IntVectorProperty_doc, +".. function:: IntVectorProperty(name=\"\", " + "description=\"\", " + "default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, " + "soft_min=-sys.maxint, " + "soft_max=sys.maxint, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new vector int property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg default: sequence of ints the length of *size*.\n" +" :type default: sequence\n" +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', " + "'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :type subtype: string\n" +" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" +" :type size: int\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(IntVectorProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "options", "subtype", "size", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; + int def[PYRNA_STACK_ARRAY] = {0}; + int size = 3; + PropertyRNA *prop; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssOiiiiiO!siOOO:IntVectorProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &pydef, + &min, &max, &soft_min, &soft_max, + &step, &PySet_Type, &pyopts, + &pysubtype, &size, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items); + + if (size < 1 || size > PYRNA_STACK_ARRAY) { + PyErr_Format(PyExc_TypeError, + "IntVectorProperty(size=%d): size must be between 0 and " + STRINGIFY(PYRNA_STACK_ARRAY), size); + return NULL; + } + + if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) + return NULL; + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_INT, subtype); + RNA_def_property_array(prop, size); + if (pydef) RNA_def_property_int_array_default(prop, def); + RNA_def_property_range(prop, min, max); + RNA_def_property_ui_text(prop, name ? name : id, description); + RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int_array(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + Py_RETURN_NONE; +} + + +PyDoc_STRVAR(BPy_FloatProperty_doc, +".. function:: FloatProperty(name=\"\", " + "description=\"\", " + "default=0.0, " + "min=sys.float_info.min, max=sys.float_info.max, " + "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " + "step=3, " + "precision=2, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "unit='NONE', " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new float property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" +" :type subtype: string\n" +BPY_PROPDEF_UNIT_DOC +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(FloatProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "precision", "options", "subtype", + "unit", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; + int precision = 2; + PropertyRNA *prop; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + char *pyunit = NULL; + int unit = PROP_UNIT_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssffffffiO!ssOOO:FloatProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &def, + &min, &max, &soft_min, &soft_max, + &step, &precision, &PySet_Type, + &pyopts, &pysubtype, &pyunit, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items); + + if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { + PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit); + return NULL; + } + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); + RNA_def_property_float_default(prop, def); + RNA_def_property_range(prop, min, max); + RNA_def_property_ui_text(prop, name ? name : id, description); + RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(BPy_FloatVectorProperty_doc, +".. function:: FloatVectorProperty(name=\"\", " + "description=\"\", " + "default=(0.0, 0.0, 0.0), " + "min=sys.float_info.min, max=sys.float_info.max, " + "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " + "step=3, " + "precision=2, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "size=3, " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new vector float property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg default: sequence of floats the length of *size*.\n" +" :type default: sequence\n" +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', " + "'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', " + "'COLOR_GAMMA', 'LAYER', 'NONE'].\n" +" :type subtype: string\n" +BPY_PROPDEF_UNIT_DOC +" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" +" :type size: int\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(FloatVectorProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "min", "max", "soft_min", "soft_max", + "step", "precision", "options", "subtype", + "unit", "size", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = ""; + int id_len; + float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; + float def[PYRNA_STACK_ARRAY] = {0.0f}; + int precision = 2, size = 3; + PropertyRNA *prop; + PyObject *pydef = NULL; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + char *pyunit = NULL; + int unit = PROP_UNIT_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|ssOfffffiO!ssiOOO:FloatVectorProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &pydef, + &min, &max, &soft_min, &soft_max, + &step, &precision, &PySet_Type, + &pyopts, &pysubtype, &pyunit, &size, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items); + + if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { + PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit); + return NULL; + } + + if (size < 1 || size > PYRNA_STACK_ARRAY) { + PyErr_Format(PyExc_TypeError, + "FloatVectorProperty(size=%d): size must be between 0 and " + STRINGIFY(PYRNA_STACK_ARRAY), size); + return NULL; + } + + if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) + return NULL; + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); + RNA_def_property_array(prop, size); + if (pydef) RNA_def_property_float_array_default(prop, def); + RNA_def_property_range(prop, min, max); + RNA_def_property_ui_text(prop, name ? name : id, description); + RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float_array(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(BPy_StringProperty_doc, +".. function:: StringProperty(name=\"\", " + "description=\"\", " + "default=\"\", " + "maxlen=0, " + "options={'ANIMATABLE'}, " + "subtype='NONE', " + "update=None, " + "get=None, " + "set=None)\n" +"\n" +" Returns a new string property definition.\n" +"\n" +BPY_PROPDEF_NAME_DOC +BPY_PROPDEF_DESC_DOC +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" +" :type options: set\n" +" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n" +" :type subtype: string\n" +BPY_PROPDEF_UPDATE_DOC +); +static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) +{ + StructRNA *srna; + + BPY_PROPDEF_HEAD(StringProperty); + + if (srna) { + static const char *kwlist[] = {"attr", "name", "description", "default", + "maxlen", "options", "subtype", "update", "get", "set", NULL}; + const char *id = NULL, *name = NULL, *description = "", *def = ""; + int id_len; + int maxlen = 0; + PropertyRNA *prop; + PyObject *pyopts = NULL; + int opts = 0; + char *pysubtype = NULL; + int subtype = PROP_NONE; + PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kw, + "s#|sssiO!sOOO:StringProperty", + (char **)kwlist, &id, &id_len, + &name, &description, &def, + &maxlen, &PySet_Type, &pyopts, &pysubtype, + &update_cb, &get_cb, &set_cb)) + { + return NULL; + } + + BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items); + + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { + return NULL; + } + + prop = RNA_def_property(srna, id, PROP_STRING, subtype); + if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */ + if (def) RNA_def_property_string_default(prop, def); + RNA_def_property_ui_text(prop, name ? name : id, description); + + if (pyopts) { + if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); + if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); + if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + } + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_string(prop, get_cb, set_cb); + RNA_def_property_duplicate_pointers(srna, prop); + } + Py_RETURN_NONE; +} + PyDoc_STRVAR(BPy_EnumProperty_doc, ".. function:: EnumProperty(items, " "name=\"\", " "description=\"\", " "default=\"\", " "options={'ANIMATABLE'}, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new enumerator property definition.\n" "\n" @@ -1246,7 +2330,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "items", "name", "description", "default", - "options", "update", NULL}; + "options", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; PyObject *def = NULL; int id_len; @@ -1258,20 +2342,28 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) int opts = 0; short is_itemf = FALSE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssOO!O:EnumProperty", + "s#O|ssOO!OOO:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -1314,22 +2406,14 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); - if (is_itemf) { - RNA_def_enum_funcs(prop, bpy_props_enum_itemf); - RNA_def_enum_py_data(prop, (void *)items); - - /* watch out!, if a user is tricky they can probably crash blender - * if they manage to free the callback, take care! */ - /* Py_INCREF(items); */ - } - if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL)); RNA_def_property_duplicate_pointers(srna, prop); if (is_itemf == FALSE) { @@ -1424,7 +2508,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (!ptype) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { return NULL; } @@ -1435,7 +2519,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; From fa0805e287e762df3638df1982297c794c4cf4b7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 5 Jan 2013 15:33:18 +0000 Subject: [PATCH 004/132] Changes for opengl render to reflect new alpha premul pipeline without hurting quick texture painting - ED_view3d_draw_offscreen will now output buffer with transparent alpha, if sky needed it should be alpha-undered later. - ED_view3d_draw_offscreen_imbuf now accepts alpha mode as an argument which could be either R_ADDSKY or R_PREMULALPHA - OpenGL render and sequencer's opengl preview will now reflect scene's Alpha Mode - Quick Edit will use OpenGL with transparent alpha mode --- source/blender/blenkernel/intern/sequencer.c | 2 +- source/blender/editors/include/ED_view3d.h | 8 +- source/blender/editors/render/render_opengl.c | 18 +++-- .../editors/sculpt_paint/paint_image.c | 2 +- .../editors/space_view3d/view3d_draw.c | 77 +++++++++---------- source/blender/imbuf/IMB_imbuf.h | 3 + source/blender/imbuf/intern/imageprocess.c | 50 ++++++++++++ .../blender/windowmanager/intern/wm_files.c | 4 +- 8 files changed, 109 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 8d010de408a..2c1fd092fbb 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2391,7 +2391,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX, - TRUE, FALSE, err_out); + TRUE, scene->r.alphamode, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 3d13938c204..ac2c47216a6 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -270,13 +270,13 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background); + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, - int draw_background, int colormanage_background, char err_out[256]); + int draw_background, int alpha_mode, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, - int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]); - + int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]); +void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]); struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index cbc076b3342..7ba6a92e4be 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -43,6 +43,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_world_types.h" #include "BKE_context.h" #include "BKE_global.h" @@ -192,7 +193,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } if ((scene->r.mode & R_OSA) == 0) { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf); } else { @@ -206,7 +207,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) BLI_jitter_init(jit_ofs[0], scene->r.osa); /* first sample buffer, also initializes 'rv3d->persmat' */ - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer); /* skip the first sample */ @@ -216,7 +217,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) (jit_ofs[j][0] * 2.0f) / sizex, (jit_ofs[j][1] * 2.0f) / sizey); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp); add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float)); } @@ -232,7 +233,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender) else { /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; - ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out); + ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, + IB_rectfloat, OB_SOLID, FALSE, TRUE, R_ALPHAPREMUL, err_out); camera = scene->camera; if (ibuf_view) { @@ -243,7 +245,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender) fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out); } } - + + if (scene->r.alphamode == R_ADDSKY) { + float sky_color[3]; + ED_view3d_offscreen_sky_color_get(scene, sky_color); + IMB_alpha_under_color_float(rr->rectf, sizex, sizey, sky_color); + } + /* note on color management: * * OpenGL renders into sRGB colors, but render buffers are expected to be diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index fa8252c824d..d0f8e36e17d 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -6038,7 +6038,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (w > maxsize) w = maxsize; if (h > maxsize) h = maxsize; - ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, FALSE, err_out); + ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out); if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4ccf26e12b1..76f62db3c5b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2393,7 +2393,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) invert_m4_m4(rv3d.persinv, rv3d.viewinv); /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE); GPU_lamp_shadow_buffer_unbind(shadow->lamp); v3d->drawtype = drawtype; @@ -2540,13 +2540,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) /* ED_view3d_draw_offscreen_init should be called before this to initialize * stuff like shadow buffers */ -void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], - int do_bgpic, int colormanage_background) +void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, + float viewmat[4][4], float winmat[4][4], int do_bgpic) { RegionView3D *rv3d = ar->regiondata; Base *base; - float backcol[3]; int bwinx, bwiny; rcti brect; @@ -2574,34 +2572,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); - /* set background color, fallback on the view background color - * (if active clip is set but frame is failed to load fallback to horizon color as background) */ - if (scene->world) { - /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not - * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc) - * but due to compatibility issues background is being affected display transform, so we can - * emulate behavior of disabled color management - * but this function is also used for sequencer's scene strips which shouldn't be affected by - * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background - * we can drop this flag in cost of some compatibility loss -- background wouldn't be - * color managed in 3d viewport - * same goes to opengl rendering, where color profile should be applied as very final step - */ - - if (colormanage_background) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - } - else { - linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); - } - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0f); - } - else { - UI_ThemeClearColor(TH_BACK); - } - + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -2703,10 +2674,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, G.f &= ~G_RENDER_OGL; } +/* get a color used for offscreen sky, returns color in sRGB space */ +void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3]) +{ + if (scene->world) + linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr); + else + UI_GetThemeColor3fv(TH_BACK, sky_color); +} + +static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene) +{ + float sky_color[3]; + + ED_view3d_offscreen_sky_color_get(scene, sky_color); + + if (ibuf->rect_float) + IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color); + else + IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color); +} + /* utility func for ED_view3d_draw_offscreen */ -ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, - int sizex, int sizey, unsigned int flag, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, + int draw_background, int alpha_mode, char err_out[256]) { RegionView3D *rv3d = ar->regiondata; ImBuf *ibuf; @@ -2733,10 +2724,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background); } else { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background); } /* read in pixels & stamp */ @@ -2747,6 +2738,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, else if (ibuf->rect) GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); + if (alpha_mode == R_ADDSKY) + offscreen_imbuf_add_sky(ibuf, scene); + /* unbind */ GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); @@ -2760,9 +2754,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, } /* creates own 3d views, used by the sequencer */ -ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, - unsigned int flag, int drawtype, int use_solid_tex, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype, + int use_solid_tex, int draw_background, int alpha_mode, char err_out[256]) { View3D v3d = {NULL}; ARegion ar = {NULL}; @@ -2805,7 +2798,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag, - draw_background, colormanage_background, err_out); + draw_background, alpha_mode, err_out); // seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty); } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 850060ef4d5..8d60227377b 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -416,6 +416,9 @@ void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float c void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]); +void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]); + /** * * \attention defined in readimage.c diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 1eac6236829..59282c9d207 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -327,3 +327,53 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_ MEM_freeN(handles); } + +/* Alpha-under */ + +void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]) +{ + int a = x * y; + float *fp = rect_float; + + while (a--) { + if (fp[3] == 0.0f) { + copy_v3_v3(fp, backcol); + } + else { + float mul = 1.0f - fp[3]; + + fp[0] += mul * backcol[0]; + fp[1] += mul * backcol[1]; + fp[2] += mul * backcol[2]; + } + + fp[3] = 1.0f; + + fp += 4; + } +} + +void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3]) +{ + int a = x * y; + unsigned char *cp = rect; + + while (a--) { + if (cp[3] == 0) { + cp[0] = backcol[0] * 255; + cp[1] = backcol[1] * 255; + cp[2] = backcol[2] * 255; + } + else { + int mul = 255 - cp[3]; + + cp[0] += mul * backcol[0] / 255; + cp[1] += mul * backcol[1] / 255; + cp[2] += mul * backcol[2] / 255; + } + + cp[3] = 255; + + cp += 4; + } +} diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index f31aff3d3f8..a9b3e4272ce 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -733,11 +733,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out); + IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, FALSE, FALSE, err_out); + IB_rect, FALSE, R_ADDSKY, err_out); } if (ibuf) { From aecfe6d148be2c3716e910de856da4ede2059129 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Jan 2013 15:36:03 +0000 Subject: [PATCH 005/132] style cleanup: also add checker for function brace placement. --- source/blender/editors/sculpt_paint/paint_ops.c | 3 +-- source/blender/makesrna/intern/rna_particle.c | 6 +++--- source/blender/makesrna/intern/rna_sculpt_paint.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 9e702c16e2f..e5d6a1820a2 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -657,8 +657,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) * grid rather than brush alpha */ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0); set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0); - RNA_string_set(kmi->ptr, "data_path_primary", - "tool_settings.sculpt.detail_size"); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); /* multires switch */ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index be3cbfaece3..6dc6d8809f0 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -492,7 +492,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { if (num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, vcol_no); mc += num * 4; psys_interpolate_mcol(mc, mface->v4, particle->fuv, &mcol); @@ -517,7 +517,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(PART_FROM_FACE, PART_FROM_FACE, PART_FROM_VOLUME)) { if (cpa->num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, cpa->num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); mc += cpa->num * 4; psys_interpolate_mcol(mc, mface->v4, cpa->fuv, &mcol); @@ -543,7 +543,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, P if (n_mcol && ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { if (num != DMCACHE_NOTFOUND) { MFace *mface = modifier->dm->getTessFaceData(modifier->dm, num, CD_MFACE); - MCol *mc = (MCol*)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); + MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->dm->faceData, CD_MCOL, 0); mc += num * 4; psys_interpolate_mcol(mc, mface->v4, parent->fuv, &mcol); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 17edf2944aa..cc1895541df 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -222,7 +222,7 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU if (ob->sculpt) { ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags & - SCULPT_DYNTOPO_SMOOTH_SHADING); + SCULPT_DYNTOPO_SMOOTH_SHADING); } } } From 123191881b02a12f90a402650d043c2ac66e7f99 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sat, 5 Jan 2013 15:50:51 +0000 Subject: [PATCH 006/132] Added some python API examples for the new get/set callbacks in bpy.props. --- doc/python_api/examples/bpy.props.5.py | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 doc/python_api/examples/bpy.props.5.py diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py new file mode 100644 index 00000000000..e49d0f2a0a0 --- /dev/null +++ b/doc/python_api/examples/bpy.props.5.py @@ -0,0 +1,85 @@ +""" +Get/Set Example +++++++++++++++ + +Get/Set functions can be used for boolean, int, float, string and enum properties. +If these callbacks are defined the property will not be stored in the ID properties +automatically, instead the get/set functions will be called when the property is +read or written from the API. +""" + +import bpy + + +# Simple property reading/writing from ID properties. +# This is what the RNA would do internally. +def get_float(self): + return self["testprop"] + +def set_float(self, value): + self["testprop"] = value + +bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float) + + +# Read-only string property, returns the current date +def get_date(self): + import datetime + return str(datetime.datetime.now()) + +bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date) + + +# Boolean array. Set function stores a single boolean value, returned as the second component. +# Array getters must return a list or tuple +# Array size must match the property vector size exactly +def get_array(self): + return (True, self["somebool"]) + +def set_array(self, values): + self["somebool"] = values[0] and values[1] + +bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array) + + +# Enum property. +# Note: the getter/setter callback must use integer identifiers! +test_items = [ + ("RED", "Red", "", 1), + ("GREEN", "Red", "", 2), + ("BLUE", "Red", "", 3), + ("YELLOW", "Red", "", 4), + ] + +def get_enum(self): + import random + return random.randint(1, 4) + +def set_enum(self, value): + print("setting value", value) + +bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum) + + +# Testing + +scene = bpy.context.scene + +scene.test_float = 12.34 +print (scene.test_float) + +scene.test_array = (True, False) +print ([x for x in scene.test_array]) + +#scene.test_date = "blah" # this would fail, property is read-only +print (scene.test_date) + +scene.test_enum = 'BLUE' +print (scene.test_enum) + + +# >>> 12.34000015258789 +# >>> [True, False] +# >>> 2013-01-05 16:33:52.135340 +# >>> setting value 3 +# >>> GREEN From 8dfe7620fb7df5bc4adb6bc4b42bd3343dce3f74 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 5 Jan 2013 17:13:07 +0000 Subject: [PATCH 007/132] New version of code to detect whether a wheel is involved, or a trackpad. It was compiled with "deploy target 10.6" tested on macbook with 10.8. More tests follow quick. --- intern/ghost/intern/GHOST_SystemCocoa.mm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 2d9d89d9ad0..d219679f1f9 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1576,14 +1576,17 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } } break; + case NSEventTypeBeginGesture: + m_hasMultiTouchTrackpad = 1; + break; + case NSEventTypeEndGesture: + m_hasMultiTouchTrackpad = 0; + break; case NSScrollWheel: { - int momentum = 0; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - m_hasMultiTouchTrackpad = 0; - momentum = [event momentumPhase] || [event phase]; -#endif + int momentum = [event momentumPhase]; + /* standard scrollwheel case */ if (!m_hasMultiTouchTrackpad && momentum == 0) { GHOST_TInt32 delta; From 1005cdc72a3f54554fcb9d8f1172e66492d4f627 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 5 Jan 2013 17:57:17 +0000 Subject: [PATCH 008/132] Trackpad pans for UV/Image and MovieClip editors were inverse compared to all other editors. --- .../blender/editors/render/render_preview.c | 29 +++++++++++++++++-- source/blender/editors/space_clip/clip_ops.c | 4 +-- .../blender/editors/space_image/image_ops.c | 4 +-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 8d748d3ea20..cb3d92fbc67 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -84,6 +84,8 @@ #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" +#include "GPU_extensions.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -885,6 +887,8 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat ID *id = sp->id; short idtype = GS(id->name); + printf("icon start job %s\n", id->name); + if (idtype == ID_IM) { Image *ima = (Image *)id; ImBuf *ibuf = NULL; @@ -1007,8 +1011,27 @@ static void icon_preview_endjob(void *customdata) { IconPreview *ip = customdata; - if (ip->id && GS(ip->id->name) == ID_BR) - WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); + if (ip->id) { + printf("icon end job %s\n", ip->id->name); + + if (GS(ip->id->name) == ID_BR) + WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); + + if (GS(ip->id->name) == ID_MA) { + Material *ma = (Material *)ip->id; + PreviewImage *prv_img = ma->preview; + int i; + + /* signal to gpu texture */ + for (i = 0; i < NUM_ICON_SIZES; ++i) { + if (prv_img->gputexture[i]) { + GPU_texture_free(prv_img->gputexture[i]); + prv_img->gputexture[i] = NULL; + WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ip->id); + } + } + } + } } static void icon_preview_free(void *customdata) @@ -1044,7 +1067,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* setup job */ WM_jobs_customdata_set(wm_job, ip, icon_preview_free); - WM_jobs_timer(wm_job, 0.25, NC_MATERIAL, NC_MATERIAL); + WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL); WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 4e53f34359e..caf28e1c551 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -382,8 +382,8 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceClip *sc = CTX_wm_space_clip(C); float offset[2]; - offset[0] = (event->x - event->prevx) / sc->zoom; - offset[1] = (event->y - event->prevy) / sc->zoom; + offset[0] = (event->prevx - event->x) / sc->zoom; + offset[1] = (event->prevy - event->y) / sc->zoom; RNA_float_set_array(op->ptr, "offset", offset); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index f1662bc254d..57c00a52231 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -299,8 +299,8 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima = CTX_wm_space_image(C); float offset[2]; - offset[0] = (event->x - event->prevx) / sima->zoom; - offset[1] = (event->y - event->prevy) / sima->zoom; + offset[0] = (event->prevx - event->x) / sima->zoom; + offset[1] = (event->prevy - event->y) / sima->zoom; RNA_float_set_array(op->ptr, "offset", offset); image_view_pan_exec(C, op); From c6a0818642ed57b8529e4e21f549367fe42cf68f Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 5 Jan 2013 18:23:05 +0000 Subject: [PATCH 009/132] Removal of old code trying to detect trackpads. This was causing error in previous commit "wheel only worked after using trackpad once". --- intern/ghost/intern/GHOST_SystemCocoa.mm | 12 ++++-------- source/blender/editors/render/render_preview.c | 5 +++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index d219679f1f9..ef87a498587 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -574,13 +574,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() rstring = (char*)malloc( len ); sysctl( mib, 2, rstring, &len, NULL, 0 ); - //Hack on MacBook revision, as multitouch avail. function missing - //MacbookAir or MacBook version >= 5 (retina is MacBookPro10,1) - if (strstr(rstring,"MacBookAir") || - (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')) || - (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-4]>='1') && (rstring[strlen(rstring)-4]<='9'))) - m_hasMultiTouchTrackpad = true; - else m_hasMultiTouchTrackpad = false; + m_hasMultiTouchTrackpad = false; free( rstring ); rstring = NULL; @@ -1576,6 +1570,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } } break; + + /* these events only happen on swiping trackpads */ case NSEventTypeBeginGesture: m_hasMultiTouchTrackpad = 1; break; @@ -1587,7 +1583,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { int momentum = [event momentumPhase]; - /* standard scrollwheel case */ + /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ if (!m_hasMultiTouchTrackpad && momentum == 0) { GHOST_TInt32 delta; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index cb3d92fbc67..10cb5620808 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1016,12 +1016,12 @@ static void icon_preview_endjob(void *customdata) if (GS(ip->id->name) == ID_BR) WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); - +#if 0 if (GS(ip->id->name) == ID_MA) { Material *ma = (Material *)ip->id; PreviewImage *prv_img = ma->preview; int i; - + /* signal to gpu texture */ for (i = 0; i < NUM_ICON_SIZES; ++i) { if (prv_img->gputexture[i]) { @@ -1031,6 +1031,7 @@ static void icon_preview_endjob(void *customdata) } } } +#endif } } From 0ea3c285ea769bcb692b6fbe7ad072c514b5f4d2 Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Sun, 6 Jan 2013 07:10:22 +0000 Subject: [PATCH 010/132] device_network.cpp is completely elided when WITH_NETWORK is not defined, so do not include it in the build in that case --- intern/cycles/device/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 0071bbe5cdc..661d43ab036 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -18,11 +18,14 @@ set(SRC device_cpu.cpp device_cuda.cpp device_multi.cpp - device_network.cpp device_opencl.cpp device_task.cpp ) +if(WITH_NETWORK) + list(APPEND SRC device_network.cpp) +endif() + set(SRC_HEADERS device.h device_memory.h From 252d0c6c5bbb8de66e10249892abb16f891b9ac7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 6 Jan 2013 08:28:45 +0000 Subject: [PATCH 011/132] Workaround for textured display with dynamic topology enabled This will only make object display with proper shape in textured view, but all materials and textures will be replaced with default gray color. There's currently no better way to deal with textured display when dynamic topology enabled because of all UV/tfaces are clearing when enabling dynamic topology sculpt. Anyway, better to display gray object with proper lighting in this case rather than not update object's shape during sculpt. Proper solution will be possible once CD layer will be preserved by BMesh log. --- .../blender/blenkernel/intern/cdderivedmesh.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 51890851ebc..517a5d6f6c6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -647,6 +647,23 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, index_mp_to_orig = NULL; } + /* TODO: not entirely correct, but currently dynamic topology will + * destroy UVs anyway, so textured display wouldn't work anyway + * + * this will do more like solid view with lights set up for + * textured view, but object itself will be displayed gray + * (the same as it'll display without UV maps in textured view) + */ + if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { + if (dm->numTessFaceData) { + glDisable(GL_TEXTURE_2D); + BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, FALSE); + glEnable(GL_TEXTURE_2D); + } + + return; + } + colType = CD_TEXTURE_MCOL; mcol = dm->getTessFaceDataArray(dm, colType); if (!mcol) { From 92481161d6d04374107cbc0fde4819a1bf086b6d Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Sun, 6 Jan 2013 09:24:45 +0000 Subject: [PATCH 012/132] BLI_assert uses printf so stdio.h should be included instead of relying on it to be included by other headers accidentally --- source/blender/blenlib/BLI_utildefines.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index cb30138c4f9..43b1e7871cd 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -32,6 +32,10 @@ * \ingroup bli */ +#ifndef NDEBUG /* for BLI_assert */ +#include +#endif + /* note: use of (int, TRUE / FALSE) is deprecated, * use (bool, true / false) instead */ #ifdef HAVE_STDBOOL_H From 563e38b010449009aaaaa851a47bafc2aefa7d67 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Jan 2013 10:17:38 +0000 Subject: [PATCH 013/132] remove frame limits for sequence strip creation. was causing errors importing some EDL's --- source/blender/makesrna/intern/rna_sequencer_api.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 69d35a3c2f0..2a5197b67f5 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -590,12 +590,13 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); + /* don't use MAXFRAME since it makes importer scripts fail */ RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", - "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + parm = RNA_def_int(func, "start_frame", 0, INT_MIN, INT_MAX, "", + "The start frame for the new sequence", INT_MIN, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "", - "The end frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_int(func, "end_frame", 0, INT_MIN, INT_MAX, "", + "The end frame for the new sequence", INT_MIN, INT_MAX); RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect"); From 27170d3e381adf514b01b4810665b870b030f882 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 6 Jan 2013 10:30:05 +0000 Subject: [PATCH 014/132] Rename dilate/erode rna property "type" to "mode" to avoid naming conflicts --- source/blender/editors/space_node/drawnode.c | 4 ++-- source/blender/makesrna/intern/rna_nodetree.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 8797cb4a459..ef69358c24f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1932,9 +1932,9 @@ static void node_composit_buts_hue_sat(uiLayout *layout, bContext *UNUSED(C), Po static void node_composit_buts_dilateerode(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiItemR(layout, ptr, "type", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "distance", 0, NULL, ICON_NONE); - switch (RNA_enum_get(ptr, "type")) { + switch (RNA_enum_get(ptr, "mode")) { case CMP_NODE_DILATEERODE_DISTANCE_THRESH: uiItemR(layout, ptr, "edge", 0, NULL, ICON_NONE); break; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 18dfd8aa6f9..456a6ff83c2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2480,7 +2480,7 @@ static void def_cmp_dilate_erode(StructRNA *srna) { PropertyRNA *prop; - static EnumPropertyItem type_items[] = { + static EnumPropertyItem mode_items[] = { {CMP_NODE_DILATEERODE_STEP, "STEP", 0, "Step", ""}, {CMP_NODE_DILATEERODE_DISTANCE_THRESH, "THRESHOLD", 0, "Threshold", ""}, {CMP_NODE_DILATEERODE_DISTANCE, "DISTANCE", 0, "Distance", ""}, @@ -2488,10 +2488,10 @@ static void def_cmp_dilate_erode(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, type_items); - RNA_def_property_ui_text(prop, "Distance", "Distance to grow/shrink (number of iterations)"); + RNA_def_property_enum_items(prop, mode_items); + RNA_def_property_ui_text(prop, "Mode", "Growing/shrinking mode"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "distance", PROP_INT, PROP_NONE); From 16ca65e4a91bf49b77dc27d79779a35ed749bbf8 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 6 Jan 2013 11:16:49 +0000 Subject: [PATCH 015/132] Solving nasty annoyance: Trackpad zoom (swipe + CTRL) direction was inverted compared to MMB-drag or scrollwheel usage. In the 3D viewport it was OK, in all others not. Now the same physical gesture maps identical to zooming everywhere. Or to recap (with blender factory settings) Zooming in: - MMB-drag, move mouse towards screen - Scroll wheel, move finger towards screen - Magic Mouse, move finger towards screen - Trackpad 2-finger swipe: move fingers toward screen. To make this extra confusing: this is only consistent if you set your system to inperpret trackpad swipes as "inverted" (pan view left = swipe to right). This is a typical default, although Apple wants you to call this "Unnatural" :) Next commit will be testing on laptop if all pinch gestures zoom consistent. And following to that, a sensible user preference to map trackpad use for Blender yourself, to invert system defaults again. :) Blame and thanks goes to Sebastian Koenig, for his perseverance on getting this solved :) --- source/blender/editors/interface/view2d_ops.c | 4 ++-- source/blender/editors/space_clip/clip_editor.c | 2 +- source/blender/editors/space_clip/clip_ops.c | 4 ++-- source/blender/editors/space_clip/space_clip.c | 1 + source/blender/editors/space_image/image_ops.c | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 5 ++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index cc473998340..9236800c16b 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -946,10 +946,10 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) /* As we have only 1D information (magnify value), feed both axes * with magnify information that is stored in x axis */ - fac = 0.01f * (event->x - event->prevx); + fac = 0.01f * (event->prevx - event->x); dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; if (event->type == MOUSEPAN) - fac = 0.01f * (event->y - event->prevy); + fac = 0.01f * (event->prevy - event->y); dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; RNA_float_set(op->ptr, "deltax", dx); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 3088243d266..04154a27b74 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -82,7 +82,7 @@ int ED_space_clip_view_clip_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); - if (sc && sc->clip) { + if (sc) { return sc->view == SC_VIEW_CLIP; } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index caf28e1c551..26bae6e3978 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -515,10 +515,10 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { - if (event->type == MOUSEZOOM) { + if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { float delta, factor; - delta = event->x - event->prevx + event->y - event->prevy; + delta = event->prevx - event->x + event->prevy - event->y; if (U.uiflag & USER_ZOOM_INVERT) delta *= -1; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index dc7b6d77c9e..9d0421349d7 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -587,6 +587,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEPAN, 0, KM_CTRL, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 57c00a52231..eed15425441 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -464,7 +464,7 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); - delta = event->x - event->prevx + event->y - event->prevy; + delta = event->prevx - event->x + event->prevy - event->y; if (U.uiflag & USER_ZOOM_INVERT) delta *= -1; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e984a3f5cfd..a1e132c6601 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2101,16 +2101,15 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) } else { if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { - /* Bypass Zoom invert flag for track pads (pass FALSE always) */ if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0); } ED_view3d_depth_tag_update(vod->rv3d); From 927b2645d4f84a56d9c8b434415edf1eb279c43e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Jan 2013 12:42:47 +0000 Subject: [PATCH 016/132] sequencer api args - rename start/end_frame to frame_start/end to match the rest of the RNA api. --- .../makesrna/intern/rna_sequencer_api.c | 58 +++++++++---------- source/blender/python/intern/bpy_app_ffmpeg.c | 12 ++-- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 2a5197b67f5..9df8662263c 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -82,14 +82,14 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, BKE_report(reports, RPT_ERROR, error_msg); } -static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame, +static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int frame_start, int channel, int type, const char *file) { Sequence *seq; Strip *strip; StripElem *se; - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel); + seq = BKE_sequence_alloc(ed->seqbasep, frame_start, channel); seq->type = type; BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2); @@ -113,12 +113,12 @@ static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, const char *name, MovieClip *clip, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIECLIP, clip->name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIECLIP, clip->name); seq->clip = clip; seq->len = BKE_movieclip_get_duration(clip); id_us_plus((ID *)clip); @@ -132,12 +132,12 @@ static Sequence *rna_Sequences_new_clip(ID *id, Editing *ed, static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, const char *name, Mask *mask, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MASK, mask->id.name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MASK, mask->id.name); seq->mask = mask; seq->len = BKE_mask_get_duration(mask); id_us_plus((ID *)mask); @@ -151,15 +151,15 @@ static Sequence *rna_Sequences_new_mask(ID *id, Editing *ed, static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, const char *name, Scene *sce_seq, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SCENE, NULL); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SCENE, NULL); seq->scene = sce_seq; seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; - seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + seq->scene_sound = sound_scene_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0); id_us_plus((ID *)sce_seq); BKE_sequence_calc_disp(scene, seq); @@ -171,12 +171,12 @@ static Sequence *rna_Sequences_new_scene(ID *id, Editing *ed, static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *reports, const char *name, const char *file, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_IMAGE, file); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_IMAGE, file); seq->len = 1; if (seq->strip->stripdata->name[0] == '\0') { @@ -195,7 +195,7 @@ static Sequence *rna_Sequences_new_image(ID *id, Editing *ed, ReportList *report static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *reports, const char *name, const char *file, int channel, - int start_frame) + int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; @@ -208,7 +208,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_MOVIE, file); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_MOVIE, file); seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN); @@ -222,7 +222,7 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report #ifdef WITH_AUDASPACE static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, ReportList *reports, - const char *name, const char *file, int channel, int start_frame) + const char *name, const char *file, int channel, int frame_start) { Scene *scene = (Scene *)id; Sequence *seq; @@ -234,11 +234,11 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_TYPE_SOUND_RAM, sound->name); + seq = alloc_generic_sequence(ed, name, frame_start, channel, SEQ_TYPE_SOUND_RAM, sound->name); seq->sound = sound; seq->len = ceil((double)sound_get_length(sound) * FPS); - seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + seq->scene_sound = sound_add_scene_sound(scene, seq, frame_start, frame_start + seq->len, 0); BKE_sequence_calc_disp(scene, seq); @@ -249,7 +249,7 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor #else /* WITH_AUDASPACE */ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), - int UNUSED(start_frame)) + int UNUSED(frame_start)) { BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support"); return NULL; @@ -258,7 +258,7 @@ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Ma static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports, const char *name, int type, int channel, - int start_frame, int end_frame, + int frame_start, int frame_end, Sequence *seq1, Sequence *seq2, Sequence *seq3) { Scene *scene = (Scene *)id; @@ -268,7 +268,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor switch (num_inputs) { case 0: - if (end_frame <= start_frame) { + if (frame_end <= frame_start) { BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set"); return NULL; } @@ -298,7 +298,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor return NULL; } - seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL); + seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL); sh = BKE_sequence_get_effect(seq); @@ -310,7 +310,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor if (!seq1) { /* effect has no deps */ seq->len = 1; - BKE_sequence_tx_set_final_right(seq, end_frame); + BKE_sequence_tx_set_final_right(seq, frame_end); } seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; @@ -488,7 +488,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -505,7 +505,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -522,7 +522,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -539,7 +539,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -556,7 +556,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -573,7 +573,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", "The channel for the new sequence", 0, MAXSEQ - 1); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); /* return type */ @@ -592,10 +592,10 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) "The channel for the new sequence", 0, MAXSEQ - 1); /* don't use MAXFRAME since it makes importer scripts fail */ RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "start_frame", 0, INT_MIN, INT_MAX, "", + parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "", "The start frame for the new sequence", INT_MIN, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - RNA_def_int(func, "end_frame", 0, INT_MIN, INT_MAX, "", + RNA_def_int(func, "frame_end", 0, INT_MIN, INT_MAX, "", "The end frame for the new sequence", INT_MIN, INT_MAX); RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c index 5ae2a11710a..3bf3dec3872 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.c +++ b/source/blender/python/intern/bpy_app_ffmpeg.c @@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType; #define DEF_FFMPEG_LIB_VERSION(lib) \ {(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \ - {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}, + {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")} static PyStructSequence_Field app_ffmpeg_info_fields[] = { {(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")}, - DEF_FFMPEG_LIB_VERSION(avcodec) - DEF_FFMPEG_LIB_VERSION(avdevice) - DEF_FFMPEG_LIB_VERSION(avformat) - DEF_FFMPEG_LIB_VERSION(avutil) - DEF_FFMPEG_LIB_VERSION(swscale) + DEF_FFMPEG_LIB_VERSION(avcodec), + DEF_FFMPEG_LIB_VERSION(avdevice), + DEF_FFMPEG_LIB_VERSION(avformat), + DEF_FFMPEG_LIB_VERSION(avutil), + DEF_FFMPEG_LIB_VERSION(swscale), {NULL} }; From 0fd4a102e0f312daf8c56fd22e611feeeaf7a992 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 6 Jan 2013 12:49:32 +0000 Subject: [PATCH 017/132] With some help in irc (thanks erwin, markus!) and some googling, here's code that compiles for OSX 10.6 for new momentumPhase usage. Jens Verwiebe can give final blessings, I'm just copypasting stuff and test it :) --- intern/ghost/intern/GHOST_SystemCocoa.mm | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index ef87a498587..ac3e22368bc 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1439,6 +1439,27 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) } +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 +enum { + NSEventPhaseNone = 0, + NSEventPhaseBegan = 0x1 << 0, + NSEventPhaseStationary = 0x1 << 1, + NSEventPhaseChanged = 0x1 << 2, + NSEventPhaseEnded = 0x1 << 3, + NSEventPhaseCancelled = 0x1 << 4, +}; +typedef NSUInteger NSEventPhase; + +@interface NSEvent (AvailableOn1070AndLater) +- (BOOL)hasPreciseScrollingDeltas; +- (CGFloat)scrollingDeltaX; +- (CGFloat)scrollingDeltaY; +- (NSEventPhase)momentumPhase; +- (BOOL)isDirectionInvertedFromDevice; +- (NSEventPhase)phase; +@end +#endif + GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; @@ -1581,10 +1602,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSScrollWheel: { - int momentum = [event momentumPhase]; + int *momentum = NULL; + + if ([event respondsToSelector:@selector(momentumPhase)]) + momentum = (int *)[event momentumPhase]; /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ - if (!m_hasMultiTouchTrackpad && momentum == 0) { + if (!m_hasMultiTouchTrackpad && momentum == NULL) { GHOST_TInt32 delta; double deltaF = [event deltaY]; From 8ee99cc39cdcc07611795c16ee57b5936d5b924e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Jan 2013 15:02:23 +0000 Subject: [PATCH 018/132] add ability to use world gradient rendering when 'Only Render' option is enabled. supports paper/blend/real. --- .../editors/space_view3d/view3d_draw.c | 120 ++++++++++++++++-- source/blender/makesrna/intern/rna_world.c | 8 +- source/blender/python/intern/bpy_props.c | 2 +- 3 files changed, 113 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 76f62db3c5b..43022e2a5d2 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2987,21 +2987,117 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const GPU_default_lights(); } - /* clear background */ - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else - UI_ThemeClearColor(TH_BACK); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); + /* clear background */ + if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */ + if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ + int x, y; + float col_hor[3]; + float col_zen[3]; + +#define XTOT 16 +#define YTOT 16 + + GLubyte grid_col[XTOT][YTOT][3]; + float grid_pos[XTOT][YTOT][2]; + + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, + &scene->display_settings); + + glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + + for (x = 0; x < XTOT; x++) { + for (y = 0; y < YTOT; y++) { + const float xf = (float)x / (float)(XTOT - 1); + const float yf = (float)y / (float)(YTOT - 1); + const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; + float out[3]; + const float up[3] = {0.0f, 0.0f, 1.0f}; + GLubyte *col_ub = grid_col[x][y]; + + float col_fac; + float col_fl[3]; + + /* -1..1 range */ + grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; + grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + + ED_view3d_win_to_vector(ar, mval, out); + + if (scene->world->skytype & WO_SKYPAPER) { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf(((float)y / (float)YTOT) - 0.5f) * 2.0f; + } + else { + col_fac = (float)y / (float)YTOT; + } + } + else { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf((angle_v3v3(up, out) / (float)M_PI) - 0.5f) * 2.0f; + } + else { + col_fac = 1.0f - (angle_v3v3(up, out) / (float)M_PI); + } + } + + interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); + + rgb_float_to_uchar(col_ub, col_fl); + } + } + + glBegin(GL_QUADS); + for (x = 0; x < XTOT - 1; x++) { + for (y = 0; y < YTOT - 1; y++) { + glColor3ubv(grid_col[x][y]); + glVertex2fv(grid_pos[x][y]); + glColor3ubv(grid_col[x][y + 1]); + glVertex2fv(grid_pos[x][y + 1]); + glColor3ubv(grid_col[x + 1][y + 1]); + glVertex2fv(grid_pos[x + 1][y + 1]); + glColor3ubv(grid_col[x + 1][y]); + glVertex2fv(grid_pos[x + 1][y]); + } + } + glEnd(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glShadeModel(GL_FLAT); +#undef XTOT +#undef YTOT + } + else { /* solid sky */ + IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + + glClearColor(backcol[0], backcol[1], backcol[2], 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + else { + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); if (rv3d->rflag & RV3D_CLIPPING) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index a84b1124d44..7a94566c6ee 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -529,7 +529,7 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "zenr"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Zenith Color", "Color at the zenith"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "ambient_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "ambr"); @@ -554,17 +554,17 @@ void RNA_def_world(BlenderRNA *brna) prop = RNA_def_property(srna, "use_sky_blend", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYBLEND); RNA_def_property_ui_text(prop, "Blend Sky", "Render background with natural progression from horizon to zenith"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "use_sky_paper", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYPAPER); RNA_def_property_ui_text(prop, "Paper Sky", "Flatten blend or texture coordinates"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); prop = RNA_def_property(srna, "use_sky_real", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "skytype", WO_SKYREAL); RNA_def_property_ui_text(prop, "Real Sky", "Render background with a real horizon, relative to the camera angle"); - RNA_def_property_update(prop, 0, "rna_World_update"); + RNA_def_property_update(prop, NC_WORLD | ND_WORLD_DRAW, "rna_World_update"); /* nested structs */ prop = RNA_def_property(srna, "light_settings", PROP_POINTER, PROP_NONE); diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index d3ce25b4f04..f3837203c9a 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -847,7 +847,7 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p value[0] = '\0'; } else { - memcpy(value, buffer, length+1); + memcpy(value, buffer, length + 1); } Py_DECREF(ret); From c87fed669b2c76e136e4587cd817dc9586809574 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Jan 2013 15:59:14 +0000 Subject: [PATCH 019/132] correct 2 issues with startup.blend - scroll bars were not in info space - bake bias was 0.0, changed to 0.001 as it is for new scenes --- release/datafiles/startup.blend | Bin 416736 -> 407724 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend index aa7a679c0b22d08cebf00cde27562bee9da12919..599bfb50d6eeca22e442b9ff25d88b0451efd633 100644 GIT binary patch literal 407724 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 z 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

jdp+bSn$hm?ZGjQn3oc2}Zn>k+-_D0Mb Date: Sun, 6 Jan 2013 16:28:44 +0000 Subject: [PATCH 020/132] Trackpad: "pinch/stretch" zooming is non-inversed in default now. Only tested on Mac trackpads... I'm on it. --- source/blender/windowmanager/intern/wm_event_system.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index a6b3efd30bf..edf5700673c 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2792,6 +2792,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U switch (pd->subtype) { case GHOST_kTrackpadEventMagnify: event.type = MOUSEZOOM; + pd->deltaX = -pd->deltaX; + pd->deltaY = -pd->deltaY; break; case GHOST_kTrackpadEventRotate: event.type = MOUSEROTATE; From d72a90349a84d80d585e36f4d8cdda1a2b66717f Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Sun, 6 Jan 2013 16:45:10 +0000 Subject: [PATCH 021/132] Eyecandy feature: background gradient for 3D viewport. Enable in user preferences under themes->3D view->Theme Gradient Color. This is only used when use render only is not ticked and for now it may interfere with grid lines. Will investigate how to adjust contrast. Tidying up of options after advisory session on irc: Move all RNA code in Themes. Changes after merging trunk's commit that renders sky --- .../scripts/startup/bl_ui/space_userpref.py | 2 +- source/blender/editors/include/UI_resources.h | 5 ++- source/blender/editors/interface/resources.c | 9 ++++- .../editors/space_view3d/view3d_draw.c | 33 +++++++++++++++++-- source/blender/makesdna/DNA_userdef_types.h | 12 ++++++- source/blender/makesrna/intern/rna_userdef.c | 28 +++++++++++++++- 6 files changed, 82 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 58c433d3772..a9712b1557e 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -200,7 +200,7 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_playback_fps", text="Playback FPS") col.prop(view, "use_global_scene") col.prop(view, "object_origin_size") - + col.separator() col.separator() col.separator() diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index e575d9ac924..0ddb8830c2a 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -223,7 +223,10 @@ enum { TH_AXIS_X, /* X/Y/Z Axis */ TH_AXIS_Y, - TH_AXIS_Z + TH_AXIS_Z, + + TH_BACK_GRAD, + TH_SHOW_BACK_GRAD }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 25e7a4b58ba..8d19171d591 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -170,6 +170,13 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo else cp = ts->button; break; + case TH_BACK_GRAD: + cp = ts->gradients.gradient; + break; + case TH_SHOW_BACK_GRAD: + cp = &setting; + setting = ts->gradients.show_grad; + break; case TH_TEXT: if (theme_regionid == RGN_TYPE_WINDOW) cp = ts->text; @@ -2099,7 +2106,7 @@ void init_userdef_do_versions(void) rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */ } } - + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 43022e2a5d2..f68b61004a7 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3094,8 +3094,37 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } else { - UI_ThemeClearColor(TH_BACK); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + /* only clear depth buffer here */ + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + UI_ThemeColor(TH_BACK_GRAD); + glVertex2f(-1.0, -1.0); + glVertex2f(1.0, -1.0); + UI_ThemeColor(TH_BACK); + glVertex2f(1.0, 1.0); + glVertex2f(-1.0, 1.0); + glEnd(); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } else { + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } } ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 38848e30bf6..d6da03040cc 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -149,6 +149,13 @@ typedef struct uiPanelColors { int pad; } uiPanelColors; +typedef struct uiGradientColors { + char gradient[4]; + char pad[4]; + int show_grad; + int pad2; +} uiGradientColors; + typedef struct ThemeUI { /* Interface Elements (buttons, menus, icons) */ uiWidgetColors wcol_regular, wcol_tool, wcol_text; @@ -210,7 +217,9 @@ typedef struct ThemeSpace { /* note, cannot use name 'panel' because of DNA mapping old files */ uiPanelColors panelcolors; - + + uiGradientColors gradients; + char shade1[4]; char shade2[4]; @@ -437,6 +446,7 @@ typedef struct UserDef { int ndof_flag; /* flags for 3D mouse */ short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */ + short pad4; float glalphaclip; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 21b81e3e16a..83162bec7f4 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -758,6 +758,26 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); } +static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThemeGradientColors", NULL); + RNA_def_struct_sdna(srna, "uiGradientColors"); + RNA_def_struct_clear_flag(srna, STRUCT_UNDO); + RNA_def_struct_ui_text(srna, "Theme Gradient Color", "Theme settings for gradient colors"); + + prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Gradient Color", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Use Gradient", + "Do a gradient for the background of the viewport working area"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +} + static void rna_def_userdef_theme_ui(BlenderRNA *brna) { StructRNA *srna; @@ -766,7 +786,8 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) rna_def_userdef_theme_ui_wcol(brna); rna_def_userdef_theme_ui_wcol_state(brna); rna_def_userdef_theme_ui_panel(brna); - + rna_def_userdef_theme_ui_gradient(brna); + srna = RNA_def_struct(brna, "ThemeUserInterface", NULL); RNA_def_struct_sdna(srna, "ThemeUI"); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); @@ -1360,6 +1381,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Skin Root", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Gradient", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } From 9f99c7b4e2215c28781751b5e34acd54ae875431 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Sun, 6 Jan 2013 17:06:13 +0000 Subject: [PATCH 022/132] Slight modification of viewport sky: Avoid clearing the colour buffer since we fill it later anyway. Usually OpenGL does color + depth buffer concurrently so this probably won't have any noticable effect. Still better be pedantic about it in case we do earn some performance out of it. Added alpha component in sky color to make sure it is set to zero in the framebuffer too. --- source/blender/editors/space_view3d/view3d_draw.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index f68b61004a7..5302f63ebcb 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3000,7 +3000,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const #define XTOT 16 #define YTOT 16 - GLubyte grid_col[XTOT][YTOT][3]; + GLubyte grid_col[XTOT][YTOT][4]; float grid_pos[XTOT][YTOT][2]; IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, @@ -3008,8 +3008,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, &scene->display_settings); - glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -3058,19 +3057,20 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); rgb_float_to_uchar(col_ub, col_fl); + col_ub[3] = 0; } } glBegin(GL_QUADS); for (x = 0; x < XTOT - 1; x++) { for (y = 0; y < YTOT - 1; y++) { - glColor3ubv(grid_col[x][y]); + glColor4ubv(grid_col[x][y]); glVertex2fv(grid_pos[x][y]); - glColor3ubv(grid_col[x][y + 1]); + glColor4ubv(grid_col[x][y + 1]); glVertex2fv(grid_pos[x][y + 1]); - glColor3ubv(grid_col[x + 1][y + 1]); + glColor4ubv(grid_col[x + 1][y + 1]); glVertex2fv(grid_pos[x + 1][y + 1]); - glColor3ubv(grid_col[x + 1][y]); + glColor4ubv(grid_col[x + 1][y]); glVertex2fv(grid_pos[x + 1][y]); } } From e8d599eefe91051c668c864e5a42db02126ea95b Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 6 Jan 2013 18:02:47 +0000 Subject: [PATCH 023/132] Disable multires in sculpt mode if dynamic-topology mode is enabled sculpt_multires_active() now returns NULL if dynamic topology is enabled. Fixes bug #33718: projects.blender.org/tracker/?func=detail&aid=33718&group_id=9&atid=498 --- source/blender/editors/sculpt_paint/sculpt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 54ae2ebf588..f9c874ea073 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -137,6 +137,11 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob) Mesh *me = (Mesh *)ob->data; ModifierData *md; + if (ob->sculpt->bm) { + /* can't combine multires and dynamic topology */ + return NULL; + } + if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) { /* multires can't work without displacement layer */ return NULL; From 69dd1b08195b53a141cc984947ee30256bbd8303 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Sun, 6 Jan 2013 18:26:29 +0000 Subject: [PATCH 024/132] OSX/scons: make 64bit Intel the default now --- build_files/scons/config/darwin-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 207ddd3579b..431c366986c 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -14,7 +14,7 @@ USE_SDK=True ################### Cocoa & architecture settings ################## ############################################################################# WITH_GHOST_COCOA=True -MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64 +MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64 cmd = 'uname -p' From bbd95fafefa88390a9bb3fef3664719cf8539d85 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 6 Jan 2013 18:28:39 +0000 Subject: [PATCH 025/132] Three fixes: - Old issue: on scrolling button views, tooltips could open or stayed open. - New fix: alt+swipe now changes button values again - Removed test print, from WIP code project. --- .../editors/interface/interface_handlers.c | 32 +++++++++++-------- .../blender/editors/render/render_preview.c | 3 -- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1c9cd92271c..e92cfae07b0 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -238,6 +238,7 @@ void ui_pan_to_scroll(wmEvent *event, int *type, int *val) *type = WHEELUPMOUSE; else *type = WHEELDOWNMOUSE; + lastdy = 0; } } @@ -2717,7 +2718,9 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_pan_to_scroll(event, &type, &val); /* XXX hardcoded keymap check.... */ - if (type == WHEELDOWNMOUSE && event->alt) { + if (type == MOUSEPAN && event->alt) + retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */ + else if (type == WHEELDOWNMOUSE && event->alt) { mx = but->rect.xmin; click = 1; } @@ -2945,7 +2948,9 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_pan_to_scroll(event, &type, &val); /* XXX hardcoded keymap check.... */ - if (type == WHEELDOWNMOUSE && event->alt) { + if (type == MOUSEPAN && event->alt) + retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */ + else if (type == WHEELDOWNMOUSE && event->alt) { mx = but->rect.xmin; click = 2; } @@ -6010,19 +6015,18 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) retval = WM_UI_HANDLER_CONTINUE; break; - case WHEELUPMOUSE: - case WHEELDOWNMOUSE: - case MIDDLEMOUSE: - /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ - if (data->tooltiptimer) { - WM_event_remove_timer(data->wm, data->window, data->tooltiptimer); - data->tooltiptimer = NULL; - } - /* pass on purposedly */ - default: - /* handle button type specific events */ - retval = ui_do_button(C, block, but, event); } + /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: + case MIDDLEMOUSE: + case MOUSEPAN: + button_timers_tooltip_remove(C, but); + + /* pass on purposedly */ + default: + /* handle button type specific events */ + retval = ui_do_button(C, block, but, event); } } else if (data->state == BUTTON_STATE_WAIT_RELEASE) { diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 10cb5620808..2b714daecf8 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -886,8 +886,6 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat ShaderPreview *sp = customdata; ID *id = sp->id; short idtype = GS(id->name); - - printf("icon start job %s\n", id->name); if (idtype == ID_IM) { Image *ima = (Image *)id; @@ -1012,7 +1010,6 @@ static void icon_preview_endjob(void *customdata) IconPreview *ip = customdata; if (ip->id) { - printf("icon end job %s\n", ip->id->name); if (GS(ip->id->name) == ID_BR) WM_main_add_notifier(NC_BRUSH | NA_EDITED, ip->id); From af143b73781a22a6c54ab65bc36a1ee3d06ffe2f Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Sun, 6 Jan 2013 18:38:16 +0000 Subject: [PATCH 026/132] Small draw optimization: Draw sky with glDrawElements. Calculate positions and indices once and update only colours each frame. --- .../editors/space_view3d/view3d_draw.c | 55 ++++++++++++------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 5302f63ebcb..b4b35c6b3ac 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3001,7 +3001,9 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const #define YTOT 16 GLubyte grid_col[XTOT][YTOT][4]; - float grid_pos[XTOT][YTOT][2]; + static float grid_pos[XTOT][YTOT][2]; + static GLushort indices[XTOT-1][XTOT-1][4]; + static char buf_calculated = FALSE; IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, &scene->display_settings); @@ -3019,6 +3021,31 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glShadeModel(GL_SMOOTH); + /* calculate buffers the first time only */ + if (!buf_calculated) { + for (x = 0; x < XTOT; x++) { + for (y = 0; y < YTOT; y++) { + const float xf = (float)x / (float)(XTOT - 1); + const float yf = (float)y / (float)(YTOT - 1); + + /* -1..1 range */ + grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; + grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + } + } + + for (x = 0; x < XTOT - 1; x++) { + for (y = 0; y < YTOT - 1; y++) { + indices[x][y][0] = x*XTOT + y; + indices[x][y][1] = x*XTOT + y + 1; + indices[x][y][2] = (x + 1)*XTOT + y + 1; + indices[x][y][3] = (x + 1)*XTOT + y; + } + } + + buf_calculated = TRUE; + } + for (x = 0; x < XTOT; x++) { for (y = 0; y < YTOT; y++) { const float xf = (float)x / (float)(XTOT - 1); @@ -3031,10 +3058,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const float col_fac; float col_fl[3]; - /* -1..1 range */ - grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; - grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; - ED_view3d_win_to_vector(ar, mval, out); if (scene->world->skytype & WO_SKYPAPER) { @@ -3061,20 +3084,14 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - glBegin(GL_QUADS); - for (x = 0; x < XTOT - 1; x++) { - for (y = 0; y < YTOT - 1; y++) { - glColor4ubv(grid_col[x][y]); - glVertex2fv(grid_pos[x][y]); - glColor4ubv(grid_col[x][y + 1]); - glVertex2fv(grid_pos[x][y + 1]); - glColor4ubv(grid_col[x + 1][y + 1]); - glVertex2fv(grid_pos[x + 1][y + 1]); - glColor4ubv(grid_col[x + 1][y]); - glVertex2fv(grid_pos[x + 1][y]); - } - } - glEnd(); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, grid_pos); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); + + glDrawElements(GL_QUADS, (XTOT - 1)*(YTOT - 1)*4, GL_UNSIGNED_SHORT, indices); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); glMatrixMode(GL_PROJECTION); glPopMatrix(); From 75f05ebe6278d48ca8503d604f7fc4c805d719a6 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Sun, 6 Jan 2013 19:26:30 +0000 Subject: [PATCH 027/132] Initialize gradient for default theme --- source/blender/editors/interface/resources.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 8d19171d591..088715218ef 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -779,7 +779,9 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255); rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); - + rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0); + btheme->tv3d.gradients.show_grad = FALSE; + /* space buttons */ /* to have something initialized */ btheme->tbuts = btheme->tv3d; From a4c6e36aac7b7e99786198ce8a7f9ece5239365e Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 6 Jan 2013 20:06:53 +0000 Subject: [PATCH 028/132] Fix for r53610, check that ob->sculpt is valid before using it --- source/blender/editors/sculpt_paint/sculpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index f9c874ea073..a9ceebc270a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -137,7 +137,7 @@ MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob) Mesh *me = (Mesh *)ob->data; ModifierData *md; - if (ob->sculpt->bm) { + if (ob->sculpt && ob->sculpt->bm) { /* can't combine multires and dynamic topology */ return NULL; } From 6a7a144f500b59334224f250c6a816ae5d7327bf Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 6 Jan 2013 23:11:12 +0000 Subject: [PATCH 029/132] BGE: Fix for [#33053] "2.6x Joystick Sensor Event: Axis fails to fire at full tilt" reported by Auuman Anubis (auuman_anubis). The problem was that SCA_Joystick::pAxisTest() was using shorts, and tried to store abs(MIN_SHRT) in a short. However, on most systems MIN_SHRT == -32768 and MAX_SHRT == 32767. This means that abs(MIN_SHRT) > MAX_SHRT, and thus the short would overflow. --- source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index b7fbe958c86..dce62ad189a 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -307,8 +307,11 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr) int SCA_Joystick::pAxisTest(int axisnum) { #ifdef WITH_SDL - short i1 = m_axis_array[(axisnum * 2)]; - short i2 = m_axis_array[(axisnum * 2) + 1]; + /* Use ints instead of shorts here to avoid problems when we get -32768. + * When we take the negative of that later, we should get 32768, which is greater + * than what a short can hold. In other words, abs(MIN_SHORT) > MAX_SHRT. */ + int i1 = m_axis_array[(axisnum * 2)]; + int i2 = m_axis_array[(axisnum * 2) + 1]; /* long winded way to do: * return max_ff(absf(i1), absf(i2)) From eca21a2532f56872c5b7b8de3ba271420ddfb22e Mon Sep 17 00:00:00 2001 From: Mike Erwin Date: Mon, 7 Jan 2013 01:23:09 +0000 Subject: [PATCH 030/132] fix for bugs 30300, 31107: pen pressure with multiple open windows on MS Windows --- intern/ghost/intern/GHOST_SystemWin32.cpp | 1 + intern/ghost/intern/GHOST_WindowWin32.cpp | 10 ++++++++++ intern/ghost/intern/GHOST_WindowWin32.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9f62ed76735..75d606a5d79 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -761,6 +761,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_ if (type == GHOST_kEventWindowActivate) { system->getWindowManager()->setActiveWindow(window); + ((GHOST_WindowWin32*)window)->bringTabletContextToFront(); } return new GHOST_Event(system->getMilliSeconds(), type, window); diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index fead1884f8a..bf429527199 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -1192,6 +1192,16 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) } } +void GHOST_WindowWin32::bringTabletContextToFront() +{ + if (m_wintab) { + GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap"); + if (fpWTOverlap) { + fpWTOverlap(m_tablet, TRUE); + } + } +} + /** Reverse the bits in a GHOST_TUns8 */ static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) { diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 9e4377b8225..7f50d58ce35 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -58,6 +58,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL); typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX); typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID); +typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL); /** * GHOST window on M$ Windows OSs. @@ -273,6 +274,7 @@ public: void processWin32TabletInitEvent(); void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); + void bringTabletContextToFront(); protected: GHOST_TSuccess initMultisample(PIXELFORMATDESCRIPTOR pfd); From 85b59bd89e3f220f8921d7a227f17534bb428145 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 02:32:57 +0000 Subject: [PATCH 031/132] style cleanup: '} else' and add this check to check_style_c.py --- source/blender/editors/sculpt_paint/sculpt.c | 3 ++- source/blender/editors/space_view3d/view3d_draw.c | 3 ++- source/blender/editors/uvedit/uvedit_smart_stitch.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a9ceebc270a..2dc4176dde3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4590,7 +4590,8 @@ void sculpt_dynamic_topology_disable(bContext *C, CD_DUPLICATE, unode->bm_enter_totpoly); mesh_update_customdata_pointers(me, FALSE); - } else { + } + else { sculptsession_bm_to_me(ob, TRUE); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index b4b35c6b3ac..d66236d1c51 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3138,7 +3138,8 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glMatrixMode(GL_MODELVIEW); glPopMatrix(); - } else { + } + else { UI_ThemeClearColor(TH_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 8c3eaa1192f..ba4ffefddca 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1273,7 +1273,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvElement *element = state->selection_stack[i]; stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene); - } else { + } + else { UvEdge *edge = state->selection_stack[i]; stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene); From 6747dec926ded010641cef37bd4384fff15dc961 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 03:24:22 +0000 Subject: [PATCH 032/132] style cleanup --- source/blender/blenkernel/intern/seqeffects.c | 2 +- source/blender/blenkernel/intern/subsurf_ccg.c | 2 +- source/blender/blenlib/BLI_scanfill.h | 2 +- source/blender/blenlib/intern/math_geom.c | 2 +- source/blender/bmesh/bmesh_class.h | 6 +++--- source/blender/bmesh/tools/bmesh_decimate_collapse.c | 2 +- source/blender/editors/physics/physics_fluid.c | 2 +- source/blender/editors/render/render_preview.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 12 ++++++------ .../render/intern/raytrace/rayobject_octree.cpp | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 3ca04f235b8..c64609c8e70 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1150,7 +1150,7 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned fac3 = (int)(256.0f * facf1); /* formula: - * fac * (a * b) + (1-fac)*a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx + * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + axaux = c * px + py * s; //+centx * yaux = -s * px + c * py; //+centy */ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 12a82ba38d7..d381a157fcc 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3320,7 +3320,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /*I think this is for interpolating the center vert?*/ - w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1); + w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1); DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum); if (vertOrigIndex) { diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 5204e0dd718..7830c0675b4 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -103,7 +103,7 @@ enum { BLI_SCANFILL_CALC_REMOVE_DOUBLES = (1 << 1), /* note: This flag removes checks for overlapping polygons. - * when this flag is set, we'll never get back more faces then (totvert - 2)*/ + * when this flag is set, we'll never get back more faces then (totvert - 2) */ BLI_SCANFILL_CALC_HOLES = (1 << 2) }; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 3527af365ec..b78b15de5a6 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1817,7 +1817,7 @@ static int point_in_slice_as(float p[3], float origin[3], float normal[3]) return 1; } -/*mama (knowing the squared length of the normal)*/ +/*mama (knowing the squared length of the normal) */ static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns) { float h, rp[3]; diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 922c6886c13..5d7ded2024d 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -184,10 +184,10 @@ typedef struct BMesh { * BM_LOOP isn't handled so far. */ char elem_index_dirty; - /*element pools*/ + /* element pools */ struct BLI_mempool *vpool, *epool, *lpool, *fpool; - /*operator api stuff (must be all NULL or all alloc'd)*/ + /* operator api stuff (must be all NULL or all alloc'd) */ struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; int stackdepth; @@ -205,7 +205,7 @@ typedef struct BMesh { * Only use when the edit mesh cant be accessed - campbell */ short selectmode; - /*ID of the shape key this bmesh came from*/ + /* ID of the shape key this bmesh came from */ int shapenr; int walkers, totflags; diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 7c054d84405..9d2d2b75d6e 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -172,7 +172,7 @@ static int bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_c #endif /* use a small value rather then zero so we don't flip a face in multiple steps - * (first making it zero area, then flipping again)*/ + * (first making it zero area, then flipping again) */ if (dot_v3v3(cross_exist, cross_optim) <= FLT_EPSILON) { //printf("no flip\n"); return TRUE; diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index c54ac485be6..fc55b2b5915 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -237,7 +237,7 @@ static void init_time(FluidsimSettings *domainSettings, FluidAnimChannels *chann { int i; - channels->timeAtFrame = MEM_callocN((channels->length+1)*sizeof(float), "timeAtFrame channel"); + channels->timeAtFrame = MEM_callocN((channels->length + 1) * sizeof(float), "timeAtFrame channel"); channels->timeAtFrame[0] = channels->timeAtFrame[1] = domainSettings->animStart; // start at index 1 diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 2b714daecf8..25ad1f61aaf 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -712,7 +712,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs else { /* validate owner */ //if (ri->rect == NULL) - // ri->rect= MEM_mallocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); + // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender"); //RE_ResultGet32(re, ri->rect); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index d66236d1c51..202b5befa01 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -937,7 +937,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) } /* color depends on whether there is a keyframe */ - if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) + if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) UI_ThemeColor(TH_VERTEX_SELECT); else UI_ThemeColor(TH_TEXT_HI); @@ -3036,10 +3036,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const for (x = 0; x < XTOT - 1; x++) { for (y = 0; y < YTOT - 1; y++) { - indices[x][y][0] = x*XTOT + y; - indices[x][y][1] = x*XTOT + y + 1; - indices[x][y][2] = (x + 1)*XTOT + y + 1; - indices[x][y][3] = (x + 1)*XTOT + y; + indices[x][y][0] = x * XTOT + y; + indices[x][y][1] = x * XTOT + y + 1; + indices[x][y][2] = (x + 1) * XTOT + y + 1; + indices[x][y][3] = (x + 1) * XTOT + y; } } @@ -3089,7 +3089,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glVertexPointer(2, GL_FLOAT, 0, grid_pos); glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); - glDrawElements(GL_QUADS, (XTOT - 1)*(YTOT - 1)*4, GL_UNSIGNED_SHORT, indices); + glDrawElements(GL_QUADS, (XTOT - 1) * (YTOT - 1) * 4, GL_UNSIGNED_SHORT, indices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 148e3417ea9..658ab9dc091 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -1015,7 +1015,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) vec2[2] = oz1 - dda_lambda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda; + //is->dist = (u1 + dda_lambda * (u2 - u1)) * o_lambda; if (testnode(oc, is, no, ocval) ) found = 1; From 2f23267797700ec001a7a447ee4b7d4344a2419a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 03:29:03 +0000 Subject: [PATCH 033/132] compare normalized vectors when calculating the view horizon --- source/blender/editors/space_view3d/view3d_draw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 202b5befa01..ec4b28f3fe5 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3051,8 +3051,8 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const const float xf = (float)x / (float)(XTOT - 1); const float yf = (float)y / (float)(YTOT - 1); const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; + const float z_up[3] = {0.0f, 0.0f, 1.0f}; float out[3]; - const float up[3] = {0.0f, 0.0f, 1.0f}; GLubyte *col_ub = grid_col[x][y]; float col_fac; @@ -3070,10 +3070,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } else { if (scene->world->skytype & WO_SKYREAL) { - col_fac = fabsf((angle_v3v3(up, out) / (float)M_PI) - 0.5f) * 2.0f; + col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f; } else { - col_fac = 1.0f - (angle_v3v3(up, out) / (float)M_PI); + col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI); } } From 1bf5832dfba17426e22fe6a2e7d9e4bf622b393f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 05:26:12 +0000 Subject: [PATCH 034/132] code cleanup: warnings and use stdbool for bpy* funcs. --- source/blender/python/BPY_extern.h | 2 +- source/blender/python/generic/py_capi_utils.c | 6 +- source/blender/python/generic/py_capi_utils.h | 6 +- source/blender/python/intern/bpy.c | 24 +-- source/blender/python/intern/bpy_driver.c | 6 +- source/blender/python/intern/bpy_interface.c | 38 ++--- .../python/intern/bpy_interface_atexit.c | 4 +- source/blender/python/intern/bpy_library.c | 2 +- source/blender/python/intern/bpy_operator.c | 26 ++-- .../blender/python/intern/bpy_operator_wrap.c | 4 +- source/blender/python/intern/bpy_path.c | 2 + source/blender/python/intern/bpy_props.c | 116 +++++++-------- source/blender/python/intern/bpy_rna.c | 138 +++++++++--------- source/blender/python/intern/bpy_rna.h | 10 +- source/blender/python/intern/bpy_rna_anim.c | 8 +- .../blender/python/intern/bpy_rna_callback.c | 8 +- source/blender/python/intern/bpy_util.c | 10 +- source/blender/python/intern/bpy_util.h | 2 +- .../render/intern/source/multires_bake.c | 4 +- 19 files changed, 215 insertions(+), 201 deletions(-) diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 9bd45d2b759..13cb11d1301 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -66,7 +66,7 @@ void BPY_python_end(void); /* 2.5 UI Scripts */ int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports); -int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump); +int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump); void BPY_text_free_code(struct Text *text); void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date void BPY_modules_load_user(struct bContext *C); diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 86230318896..56d9e2ac0dd 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -33,6 +33,8 @@ #include #include +#include "BLI_utildefines.h" /* for bool */ + #include "py_capi_utils.h" /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ @@ -44,7 +46,7 @@ /* array utility function */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix) + const PyTypeObject *type, const bool is_double, const char *error_prefix) { PyObject *value_fast; Py_ssize_t value_len; @@ -114,7 +116,7 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, /* array utility function */ PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type, - const short is_double, const char *error_prefix) + const bool is_double, const char *error_prefix) { PyObject *tuple; int i; diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index b4eea6ac90c..239858032de 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -38,9 +38,9 @@ PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *f void PyC_FileAndNum(const char **filename, int *lineno); void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix); -PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type, - const short is_double, const char *error_prefix); + const PyTypeObject *type, const bool is_double, const char *error_prefix); +PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const bool is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 082807c62db..c4d68290da3 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -35,19 +35,19 @@ #include "RNA_types.h" #include "RNA_access.h" -#include "bpy.h" -#include "bpy_util.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BKE_bpath.h" +#include "BLI_utildefines.h" + +#include "bpy.h" +#include "bpy_util.h" #include "bpy_rna.h" #include "bpy_app.h" #include "bpy_props.h" #include "bpy_library.h" #include "bpy_operator.h" -#include "BLI_path_util.h" -#include "BLI_string.h" -#include "BKE_bpath.h" -#include "BLI_utildefines.h" - #include "BKE_main.h" #include "BKE_global.h" /* XXX, G.main only */ #include "BKE_blender.h" @@ -94,7 +94,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons PyObject *item = PyUnicode_DecodeFSDefault(path_src); PyList_Append(list, item); Py_DECREF(item); - return FALSE; /* never edits the path */ + return false; /* never edits the path */ } PyDoc_STRVAR(bpy_blend_paths_doc, @@ -116,9 +116,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec int flag = 0; PyObject *list; - int absolute = FALSE; - int packed = FALSE; - int local = FALSE; + int absolute = false; + int packed = false; + int local = false; static const char *kwlist[] = {"absolute", "packed", "local", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths", @@ -205,7 +205,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; } - path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE); + path = BLI_get_folder_version(folder_id, (major * 100) + minor, false); return PyUnicode_DecodeFSDefault(path ? path : ""); } diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 9a79616c23b..c49794ad37a 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime) void BPY_driver_reset(void) { PyGILState_STATE gilstate; - int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); @@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */ PyObject *expr_code; PyGILState_STATE gilstate; - int use_gil; + bool use_gil; DriverVar *dvar; double result = 0.0; /* default return */ @@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) return 0.0f; } - use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 7bce8673943..e9fa00c7868 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -39,6 +39,15 @@ #include "MEM_guardedalloc.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_string.h" +#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" +#include "BLI_threads.h" + #include "RNA_types.h" #include "bpy.h" @@ -52,15 +61,6 @@ #include "DNA_space_types.h" #include "DNA_text_types.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "BLI_listbase.h" -#include "BLI_math_base.h" -#include "BLI_string.h" -#include "BLI_string_utf8.h" -#include "BLI_utildefines.h" -#include "BLI_threads.h" - #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" @@ -166,7 +166,7 @@ void BPY_text_free_code(Text *text) { if (text->compiled) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; if (use_gil) gilstate = PyGILState_Ensure(); @@ -378,8 +378,8 @@ static void python_script_error_jump_text(struct Text *text) python_script_error_jump(text->id.name + 2, &lineno, &offset); if (lineno != -1) { /* select the line with the error */ - txt_move_to(text, lineno - 1, INT_MAX, FALSE); - txt_move_to(text, lineno - 1, offset, TRUE); + txt_move_to(text, lineno - 1, INT_MAX, false); + txt_move_to(text, lineno - 1, offset, true); } } @@ -397,7 +397,7 @@ typedef struct { #endif static int python_script_exec(bContext *C, const char *fn, struct Text *text, - struct ReportList *reports, const short do_jump) + struct ReportList *reports, const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; @@ -514,11 +514,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, /* Can run a file or text block */ int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports) { - return python_script_exec(C, filepath, NULL, reports, FALSE); + return python_script_exec(C, filepath, NULL, reports, false); } -int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump) +int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump) { return python_script_exec(C, NULL, text, reports, do_jump); } @@ -719,12 +719,12 @@ void BPY_modules_load_user(bContext *C) int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; PyObject *pyctx; PyObject *item; PointerRNA *ptr = NULL; - int done = FALSE; + bool done = false; if (use_gil) gilstate = PyGILState_Ensure(); @@ -743,7 +743,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * //result->ptr = ((BPy_StructRNA *)item)->ptr; CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); - done = TRUE; + done = true; } else if (PySequence_Check(item)) { PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); @@ -774,7 +774,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * } Py_DECREF(seq_fast); - done = TRUE; + done = true; } } diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index 13d8cedf907..d1d33a01e55 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -31,13 +31,13 @@ #include +#include "BLI_utildefines.h" + #include "bpy_util.h" #include "bpy.h" /* own include */ #include "WM_api.h" -#include "BLI_utildefines.h" - static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw)) { /* close down enough of blender at least not to crash */ diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 7571fe0f75e..ec6322a1a11 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args)) self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports); if (self->blo_handle == NULL) { - if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) { + if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) { PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath); diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 55ef217e781..ee885684e03 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -35,6 +35,9 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" +#include "BLI_string.h" + #include "BPY_extern.h" #include "bpy_operator.h" #include "bpy_operator_wrap.h" @@ -42,9 +45,6 @@ #include "bpy_util.h" #include "../generic/bpy_internal_import.h" -#include "BLI_utildefines.h" -#include "BLI_string.h" - #include "RNA_access.h" #include "RNA_enum_types.h" @@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) /* note that context is an int, python does the conversion in this case */ int context = WM_OP_EXEC_DEFAULT; - int is_undo = FALSE; + int is_undo = false; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ @@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ - if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) { + if (WM_operator_poll_context((bContext *)C, ot, context) == false) { const char *msg = CTX_wm_operator_poll_msg_get(C); PyErr_Format(PyExc_RuntimeError, "Operator bpy.ops.%.200s.poll() %.200s", @@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) } #endif - error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); + error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false); /* operator output is nice to have in the terminal/console too */ if (reports->list.first) { @@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname); return NULL; @@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif return (PyObject *)pyrna; } @@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname); return NULL; @@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif op->ptr = &pyrna->ptr; diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 1caec294aa0..cb2e12ba996 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -112,7 +112,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) return NULL; - if (WM_operatortype_find(opname, TRUE) == NULL) { + if (WM_operatortype_find(opname, true) == NULL) { PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname); @@ -123,7 +123,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) srna = srna_from_self(macro, "Macro Define:"); macroname = RNA_struct_identifier(srna); - ot = WM_operatortype_find(macroname, TRUE); + ot = WM_operatortype_find(macroname, true); if (!ot) { PyErr_Format(PyExc_ValueError, diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c index 8df7ed2364f..1d554b60bbe 100644 --- a/source/blender/python/intern/bpy_path.c +++ b/source/blender/python/intern/bpy_path.c @@ -28,6 +28,8 @@ #include +#include "BLI_utildefines.h" + #include "bpy_path.h" #include "../generic/py_capi_utils.h" diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index f3837203c9a..b9bfaed54d5 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -33,12 +33,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_props.h" #include "bpy_rna.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "BKE_idprop.h" #include "RNA_access.h" @@ -199,7 +199,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } bpy_context_set(C, &gilstate); @@ -232,7 +232,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc bpy_context_clear(C, &gilstate); if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -249,7 +249,7 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -264,21 +264,21 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p if (ret == NULL) { printf_func_error(py_func); - value = FALSE; + value = false; } else { value = PyLong_AsLong(ret); if (value == -1 && PyErr_Occurred()) { printf_func_error(py_func); - value = FALSE; + value = false; } Py_DECREF(ret); } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } return value; @@ -296,7 +296,7 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -324,7 +324,7 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -341,7 +341,7 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -358,21 +358,21 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert printf_func_error(py_func); for (i = 0; i < len; ++i) - values[i] = FALSE; + values[i] = false; } else { - if (ret && PyC_AsArray(values, ret, len, &PyBool_Type, FALSE, "BoolVectorProperty get") < 0) { + if (ret && PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) - values[i] = FALSE; + values[i] = false; } Py_DECREF(ret); } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -390,7 +390,7 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -399,7 +399,7 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyBool_Type, FALSE, "BoolVectorProperty set"); + py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set"); if (!py_values) { printf_func_error(py_func); } @@ -423,7 +423,7 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -440,7 +440,7 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -469,7 +469,7 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } return value; @@ -487,7 +487,7 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -515,7 +515,7 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -532,7 +532,7 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -552,7 +552,7 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA values[i] = 0; } else { - if (ret && PyC_AsArray(values, ret, len, &PyLong_Type, FALSE, "IntVectorProperty get") < 0) { + if (ret && PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) @@ -563,7 +563,7 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -581,7 +581,7 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -590,7 +590,7 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyLong_Type, FALSE, "IntVectorProperty set"); + py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set"); if (!py_values) { printf_func_error(py_func); } @@ -614,7 +614,7 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -631,7 +631,7 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -660,7 +660,7 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } return value; @@ -678,7 +678,7 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -706,7 +706,7 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -723,7 +723,7 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -743,7 +743,7 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR values[i] = 0.0f; } else { - if (ret && PyC_AsArray(values, ret, len, &PyFloat_Type, FALSE, "FloatVectorProperty get") < 0) { + if (ret && PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) @@ -754,7 +754,7 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -772,7 +772,7 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -781,7 +781,7 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); - py_values = PyC_FromArray(values, len, &PyFloat_Type, FALSE, "FloatVectorProperty set"); + py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set"); if (!py_values) { printf_func_error(py_func); } @@ -805,7 +805,7 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -821,7 +821,7 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -840,10 +840,12 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p } else { Py_ssize_t length; - char *buffer = _PyUnicode_AsStringAndSize(ret, &length); + const char *buffer = _PyUnicode_AsStringAndSize(ret, &length); - if (!buffer && PyErr_Occurred()) { - printf_func_error(py_func); + if (!buffer) { + if (PyErr_Occurred()) { /* should always be true */ + printf_func_error(py_func); + } value[0] = '\0'; } else { @@ -854,7 +856,7 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -871,7 +873,7 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -893,7 +895,7 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } return length; @@ -912,7 +914,7 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -946,7 +948,7 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -963,7 +965,7 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_GET]; @@ -992,7 +994,7 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } return value; @@ -1010,7 +1012,7 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } py_func = py_data[BPY_DATA_CB_SLOT_SET]; @@ -1038,7 +1040,7 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro } if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); } } @@ -1760,7 +1762,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") < 0) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { @@ -1955,7 +1957,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") < 0) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { @@ -2175,7 +2177,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") < 0) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { @@ -2340,7 +2342,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; - short is_itemf = FALSE; + bool is_itemf = false; PyObject *update_cb = NULL; PyObject *get_cb = NULL; PyObject *set_cb = NULL; @@ -2384,7 +2386,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - is_itemf = TRUE; + is_itemf = true; eitems = DummyRNA_NULL_items; } else { @@ -2416,7 +2418,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL)); RNA_def_property_duplicate_pointers(srna, prop); - if (is_itemf == FALSE) { + if (is_itemf == false) { /* note: this must be postponed until after #RNA_def_property_duplicate_pointers * otherwise if this is a generator it may free the strings before we copy them */ Py_DECREF(items_fast); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index bc245ecda5c..5be6c33ec18 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -37,6 +37,12 @@ #include "RNA_types.h" +#include "BLI_dynstr.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math_rotation.h" +#include "BLI_utildefines.h" + #include "BPY_extern.h" #include "bpy_rna.h" @@ -50,12 +56,6 @@ # include "MEM_guardedalloc.h" #endif -#include "BLI_dynstr.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "BLI_math_rotation.h" -#include "BLI_utildefines.h" - #ifdef USE_PYRNA_INVALIDATE_WEAKREF # include "BLI_ghash.h" #endif @@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id) } #ifdef USE_PEDANTIC_WRITE -static short rna_disallow_writes = FALSE; +static bool rna_disallow_writes = false; -static int rna_id_write_error(PointerRNA *ptr, PyObject *key) +static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) { ID *id = ptr->id.data; if (id) { @@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key) "%.200s, %.200s datablock, error setting %.200s.%.200s", id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname); - return TRUE; + return true; } } - return FALSE; + return false; } #endif /* USE_PEDANTIC_WRITE */ #ifdef USE_PEDANTIC_WRITE -int pyrna_write_check(void) +bool pyrna_write_check(void) { return !rna_disallow_writes; } -void pyrna_write_set(int val) +void pyrna_write_set(bool val) { rna_disallow_writes = !val; } #else /* USE_PEDANTIC_WRITE */ -int pyrna_write_check(void) +bool pyrna_write_check(void) { - return TRUE; + return true; } -void pyrna_write_set(int UNUSED(val)) +void pyrna_write_set(bool UNUSED(val)) { /* nothing */ } @@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { EnumPropertyItem *item; const char *result; - int free = FALSE; + int free = false; RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if (item) { @@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj { EnumPropertyItem *item; int ret; - int free = FALSE; + int free = false; *r_value = 0; @@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) } else { EnumPropertyItem *enum_item; - int free = FALSE; + int free = false; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ @@ -1777,7 +1777,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb } else { BPy_StructRNA *param = (BPy_StructRNA *)value; - int raise_error = FALSE; + bool raise_error = false; if (data) { if (flag & PROP_RNAPTR) { @@ -1804,7 +1804,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb *((void **)data) = param->ptr.data; } else { - raise_error = TRUE; + raise_error = true; } } else { @@ -2195,7 +2195,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel else { PyObject *keylib = PyTuple_GET_ITEM(key, 1); Library *lib; - int found = FALSE; + bool found = false; if (keylib == Py_None) { lib = NULL; @@ -2232,7 +2232,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel { ID *id = itemptr.data; /* always an ID */ if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) { - found = TRUE; + found = true; if (r_ptr) { *r_ptr = itemptr; } @@ -2242,7 +2242,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel RNA_PROP_END; /* we may want to fail silently as with collection.get() */ - if ((found == FALSE) && err_not_found) { + if ((found == false) && err_not_found) { /* only runs for getitem access so use fixed string */ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); @@ -2255,7 +2255,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel } static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key, - const char *err_prefix, const short err_not_found) + const char *err_prefix, const bool err_not_found) { PointerRNA ptr; const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr); @@ -2448,7 +2448,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject else if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair(self, key, - "bpy_prop_collection[id, lib]", TRUE); + "bpy_prop_collection[id, lib]", true); } else { PyErr_Format(PyExc_TypeError, @@ -2865,7 +2865,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, - "(id, lib) in bpy_prop_collection", FALSE, NULL); + "(id, lib) in bpy_prop_collection", false, NULL); } else { @@ -4205,7 +4205,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args } else if (PyTuple_Check(key_ob)) { PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, - "bpy_prop_collection.get((id, lib))", FALSE); + "bpy_prop_collection.get((id, lib))", false); if (ret) { return ret; } @@ -4267,12 +4267,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, /* values to assign */ - RawPropertyType *raw_type, int *attr_tot, int *attr_signed) + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed) { PropertyRNA *prop; *raw_type = PROP_RAW_UNSET; *attr_tot = 0; - *attr_signed = FALSE; + *attr_signed = false; /* note: this is fail with zero length lists, so don't let this get caled in that case */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) @@ -4280,7 +4280,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, prop = RNA_struct_find_property(&itemptr, attr); *raw_type = RNA_property_raw_type(prop); *attr_tot = RNA_property_array_length(&itemptr, prop); - *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE; + *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true; break; } RNA_PROP_END; @@ -4291,7 +4291,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, /* values to assign */ const char **attr, PyObject **seq, int *tot, int *size, - RawPropertyType *raw_type, int *attr_tot, int *attr_signed + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed ) { #if 0 @@ -4299,7 +4299,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, int target_tot; #endif - *size = *attr_tot = *attr_signed = FALSE; + *size = *attr_tot = 0; + *attr_signed = false; *raw_type = PROP_RAW_UNSET; if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { @@ -4344,7 +4345,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, return 0; } -static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) +static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) { char f = format ? *format : 'B'; /* B is assumed when not set */ @@ -4372,13 +4373,15 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) { PyObject *item = NULL; - int i = 0, ok = 0, buffer_is_compat; + int i = 0, ok = 0; + bool buffer_is_compat; void *array = NULL; /* get/set both take the same args currently */ const char *attr; PyObject *seq; - int tot, size, attr_tot, attr_signed; + int tot, size, attr_tot; + bool attr_signed; RawPropertyType raw_type; if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) @@ -4390,7 +4393,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) if (set) { /* get the array from python */ - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4441,7 +4444,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) } } else { - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4945,7 +4948,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ParameterIterator iter; PropertyRNA *parm; PyObject *ret, *item; - int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg; + int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0; + bool kw_arg; PropertyRNA *pret_single = NULL; void *retdata_single = NULL; @@ -5026,7 +5030,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (i < pyargs_len) { item = PyTuple_GET_ITEM(args, i); - kw_arg = FALSE; + kw_arg = false; } else if (kw != NULL) { #if 0 @@ -5037,7 +5041,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (item) kw_tot++; /* make sure invalid keywords are not given */ - kw_arg = TRUE; + kw_arg = true; } i++; /* current argument */ @@ -5074,7 +5078,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject char error_prefix[512]; PyErr_Clear(); /* re-raise */ - if (kw_arg == TRUE) + if (kw_arg == true) BLI_snprintf(error_prefix, sizeof(error_prefix), "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", RNA_struct_identifier(self_ptr->type), @@ -5109,12 +5113,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject DynStr *good_args = BLI_dynstr_new(); const char *arg_name, *bad_args_str, *good_args_str; - int found = FALSE, first = TRUE; + bool found = false, first = true; while (PyDict_Next(kw, &pos, &key, &value)) { arg_name = _PyUnicode_AsString(key); - found = FALSE; + found = false; if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ PyErr_Clear(); @@ -5125,22 +5129,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) { - found = TRUE; + found = true; break; } } RNA_parameter_list_end(&iter); - if (found == FALSE) { + if (found == false) { BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); - first = FALSE; + first = false; } } } /* list good args */ - first = TRUE; + first = true; RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { @@ -5149,7 +5153,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject continue; BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); - first = FALSE; + first = false; } RNA_parameter_list_end(&iter); @@ -5179,7 +5183,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject BKE_reports_init(&reports, RPT_STORE); RNA_function_call(C, &reports, self_ptr, self_func, &parms); - err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE)); + err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); /* return value */ if (err != -1) { @@ -5242,7 +5246,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) PyObject *ret; char *args; - args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE); + args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true); ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s", RNA_struct_identifier(self->ptr.type), @@ -5974,7 +5978,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) { - if (self->iter.valid == FALSE) { + if (self->iter.valid == false) { PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop"); return NULL; } @@ -6052,7 +6056,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */ - (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ + (flag & FUNC_REGISTER) == false) /* is not for registration */ { /* we may want to set the type of this later */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); @@ -6262,7 +6266,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) pyrna->ptr = *ptr; #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = FALSE; + pyrna->freeptr = false; #endif #ifdef USE_PYRNA_STRUCT_REFERENCE @@ -6342,15 +6346,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id) } } -int pyrna_id_FromPyObject(PyObject *obj, ID **id) +bool pyrna_id_FromPyObject(PyObject *obj, ID **id) { if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) { *id = ((BPy_StructRNA *)obj)->ptr.id.data; - return TRUE; + return true; } else { *id = NULL; - return FALSE; + return false; } } @@ -6561,7 +6565,7 @@ PyObject *BPY_rna_types(void) return (PyObject *)self; } -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix) +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix) { BPy_StructRNA *py_srna = NULL; StructRNA *srna; @@ -6635,7 +6639,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Clear(); - srna = pyrna_struct_as_srna(self, 0, error_prefix); + srna = pyrna_struct_as_srna(self, false, error_prefix); if (!PyErr_Occurred()) { PyErr_Restore(error_type, error_value, error_traceback); @@ -7051,7 +7055,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (py_class->tp_init) { #ifdef USE_PEDANTIC_WRITE const int prev_write = rna_disallow_writes; - rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */ + rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */ #endif /* true in most cases even when the class its self doesn't define an __init__ function. */ @@ -7070,7 +7074,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #else const int prev_write = rna_disallow_writes; - rna_disallow_writes = TRUE; + rna_disallow_writes = true; /* 'almost' all the time calling the class isn't needed. * We could just do... */ @@ -7146,7 +7150,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = is_readonly ? TRUE : FALSE; + rna_disallow_writes = is_readonly ? true : false; #endif /* *** Main Caller *** */ @@ -7155,7 +7159,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param /* *** Done Calling *** */ #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = FALSE; + rna_disallow_writes = false; #endif RNA_parameter_list_end(&iter); @@ -7420,7 +7424,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } /* warning: gets parent classes srna, only for the register function */ - srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):"); + srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); if (srna == NULL) return NULL; @@ -7456,7 +7460,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class srna_new = reg(CTX_data_main(C), &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; /* python errors validating are not converted into reports so the check above will fail. @@ -7563,7 +7567,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla return NULL; } - srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):"); + srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):"); if (srna == NULL) return NULL; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index edd2ada0539..424452ef6fe 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -115,7 +115,7 @@ typedef struct { #endif /* !USE_PYRNA_STRUCT_REFERENCE */ #ifdef PYRNA_FREE_SUPPORT - int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ + bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ #endif /* PYRNA_FREE_SUPPORT */ } BPy_StructRNA; @@ -164,7 +164,7 @@ typedef struct { #define BPy_BaseTypeRNA BPy_PropertyRNA StructRNA *srna_from_self(PyObject *self, const char *error_prefix); -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix); +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix); void BPY_rna_init(void); PyObject *BPY_rna_module(void); @@ -178,7 +178,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop); /* extern'd by other modules which don't deal closely with RNA */ PyObject *pyrna_id_CreatePyObject(struct ID *id); -int pyrna_id_FromPyObject(PyObject *obj, struct ID **id); +bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id); /* operators also need this to set args */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix); @@ -205,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop); int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value); -int pyrna_write_check(void); -void pyrna_write_set(int val); +bool pyrna_write_check(void); +void pyrna_write_set(bool val); void pyrna_invalidate(BPy_DummyPointerRNA *self); int pyrna_struct_validity_check(BPy_StructRNA *pysrna); diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 0acfc36bb4e..234eeae8a4a 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -222,7 +222,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -271,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -313,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; if (result) { @@ -390,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL); diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index adb4ae6a2c6..c66b336a1da 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -32,12 +32,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_rna.h" #include "bpy_rna_callback.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "DNA_space_types.h" #include "DNA_screen_types.h" @@ -194,7 +194,7 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "handler_add"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) { return NULL; } cb_func = PyTuple_GET_ITEM(args, 1); @@ -257,7 +257,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "callback_remove"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) { return NULL; } py_handle = PyTuple_GET_ITEM(args, 1); diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index b7994eeccdc..b0b0f346944 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -29,9 +29,13 @@ #include -#include "bpy_util.h" +#include "BLI_utildefines.h" #include "BLI_dynstr.h" + +#include "bpy_util.h" + #include "MEM_guardedalloc.h" + #include "BKE_report.h" #include "BKE_context.h" @@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item) return cstring; } -short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear) +short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear) { char *report_str; report_str = BKE_reports_string(reports, RPT_ERROR); - if (clear) { + if (clear == true) { BKE_reports_clear(reports); } diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index b5f679b741f..b007e123cfc 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item); #define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL} /* error reporting */ -short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear); +short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear); short BPy_errors_to_report(struct ReportList *reports); /* TODO - find a better solution! */ diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index b8784685836..091ba9589d7 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -952,7 +952,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RayFace *face; CCGElem **grid_data; CCGKey key; - int num_grids, grid_size, face_side, num_faces; + int num_grids, grid_size /*, face_side */, num_faces; int i; num_grids = hidm->getNumGrids(hidm); @@ -960,7 +960,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) grid_data = hidm->getGridData(hidm); hidm->getGridKey(hidm, &key); - face_side = (grid_size << 1) - 1; + /* face_side = (grid_size << 1) - 1; */ /* UNUSED */ num_faces = num_grids * (grid_size - 1) * (grid_size - 1); raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution); From 2edf2943b0f52b9e3cc8cb6eb1f1649fa05cfdb3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 06:33:29 +0000 Subject: [PATCH 035/132] split viewport clearing into its own function: view3d_main_area_clear() --- .../editors/space_view3d/view3d_draw.c | 106 ++++++++++-------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ec4b28f3fe5..0f9739dc3b1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2967,29 +2967,11 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar) ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25); } -/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ -static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) +/* + * Function to clear the view + */ +static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) { - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - Base *base; - float backcol[3]; - unsigned int lay_used; - - /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows(scene, v3d); - - /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ - if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { - rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; - GPU_default_lights(); - } - - /* setup view matrices */ - view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); - /* clear background */ if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */ if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ @@ -2997,12 +2979,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const float col_hor[3]; float col_zen[3]; -#define XTOT 16 -#define YTOT 16 +#define VIEWGRAD_RES_X 16 +#define VIEWGRAD_RES_Y 16 - GLubyte grid_col[XTOT][YTOT][4]; - static float grid_pos[XTOT][YTOT][2]; - static GLushort indices[XTOT-1][XTOT-1][4]; + GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; + static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2]; + static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; static char buf_calculated = FALSE; IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, @@ -3023,10 +3005,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const /* calculate buffers the first time only */ if (!buf_calculated) { - for (x = 0; x < XTOT; x++) { - for (y = 0; y < YTOT; y++) { - const float xf = (float)x / (float)(XTOT - 1); - const float yf = (float)y / (float)(YTOT - 1); + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); /* -1..1 range */ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; @@ -3034,22 +3016,22 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - for (x = 0; x < XTOT - 1; x++) { - for (y = 0; y < YTOT - 1; y++) { - indices[x][y][0] = x * XTOT + y; - indices[x][y][1] = x * XTOT + y + 1; - indices[x][y][2] = (x + 1) * XTOT + y + 1; - indices[x][y][3] = (x + 1) * XTOT + y; + for (x = 0; x < VIEWGRAD_RES_X - 1; x++) { + for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) { + indices[x][y][0] = x * VIEWGRAD_RES_X + y; + indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1; + indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1; + indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y; } } buf_calculated = TRUE; } - for (x = 0; x < XTOT; x++) { - for (y = 0; y < YTOT; y++) { - const float xf = (float)x / (float)(XTOT - 1); - const float yf = (float)y / (float)(YTOT - 1); + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; const float z_up[3] = {0.0f, 0.0f, 1.0f}; float out[3]; @@ -3062,10 +3044,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const if (scene->world->skytype & WO_SKYPAPER) { if (scene->world->skytype & WO_SKYREAL) { - col_fac = fabsf(((float)y / (float)YTOT) - 0.5f) * 2.0f; + col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f; } else { - col_fac = (float)y / (float)YTOT; + col_fac = (float)y / (float)VIEWGRAD_RES_Y; } } else { @@ -3089,7 +3071,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glVertexPointer(2, GL_FLOAT, 0, grid_pos); glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); - glDrawElements(GL_QUADS, (XTOT - 1) * (YTOT - 1) * 4, GL_UNSIGNED_SHORT, indices); + glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -3099,14 +3081,16 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glPopMatrix(); glShadeModel(GL_FLAT); -#undef XTOT -#undef YTOT + +#undef VIEWGRAD_RES_X +#undef VIEWGRAD_RES_Y } else { /* solid sky */ - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, + float col_hor[3]; + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, &scene->display_settings); - glClearColor(backcol[0], backcol[1], backcol[2], 0.0f); + glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } @@ -3144,6 +3128,32 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } +} + +/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ +static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) +{ + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + Base *base; + unsigned int lay_used; + + /* shadow buffers, before we setup matrices */ + if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) + gpu_update_lamps_shadows(scene, v3d); + + /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ + if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { + rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; + GPU_default_lights(); + } + + /* setup view matrices */ + view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); + + /* clear the background */ + view3d_main_area_clear(scene, v3d, ar); ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); From 13c1478c5d6abb3cee87d4e4163958c58657c0b8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Jan 2013 11:28:20 +0000 Subject: [PATCH 036/132] Track.insert_frame used to create markers with zero pattern size In most cases it's harmles since this call was intended to be used for importers only where pattern size was overriding after creation anyway. But better don't allow things which will work unpredictable. --- source/blender/makesrna/intern/rna_tracking.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 7cc57947671..31c50fb6b05 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -475,6 +475,14 @@ static MovieTrackingMarker *rna_trackingMarkers_insert_frame(MovieTrackingTrack marker.framenr = framenr; copy_v2_v2(marker.pos, co); + /* a bit arbitrary, but better than creating markers with zero pattern + * which is forbidden actually + */ + copy_v2_v2(marker.pattern_corners[0], track->markers[0].pattern_corners[0]); + copy_v2_v2(marker.pattern_corners[1], track->markers[0].pattern_corners[1]); + copy_v2_v2(marker.pattern_corners[2], track->markers[0].pattern_corners[2]); + copy_v2_v2(marker.pattern_corners[3], track->markers[0].pattern_corners[3]); + new_marker = BKE_tracking_marker_insert(track, &marker); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); From d96d948f52b041c527d98c6d41fd8d6b1afab8b8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Jan 2013 11:28:27 +0000 Subject: [PATCH 037/132] Motion tracking API change Replace Tracks.add(count, frame) with Tracks.new(name, frame) which will return newly created track. Before there was no reliable way to get newly created tracks. --- source/blender/makesrna/intern/rna_tracking.c | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 31c50fb6b05..cd646f4849c 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -402,39 +402,52 @@ static void rna_trackingDopesheet_tagUpdate(Main *UNUSED(bmain), Scene *scene, P /* API */ -static void add_tracks_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, int frame, int number) +static MovieTrackingTrack *add_track_to_base(MovieClip *clip, MovieTracking *tracking, ListBase *tracksbase, const char *name, int frame) { - int a, width, height; + int width, height; MovieClipUser user = {0}; + MovieTrackingTrack *track; user.framenr = 1; BKE_movieclip_get_size(clip, &user, &width, &height); - for (a = 0; a < number; a++) - BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height); + track = BKE_tracking_track_add(tracking, tracksbase, 0, 0, frame, width, height); + + if (name && name[0]) { + BLI_strncpy(track->name, name, sizeof(track->name)); + BKE_tracking_track_unique_name(tracksbase, track); + } + + return track; } -static void rna_trackingTracks_add(ID *id, MovieTracking *tracking, int frame, int number) +static MovieTrackingTrack *rna_trackingTracks_new(ID *id, MovieTracking *tracking, const char *name, int frame) { MovieClip *clip = (MovieClip *) id; + MovieTrackingTrack *track; - add_tracks_to_base(clip, tracking, &tracking->tracks, frame, number); + track = add_track_to_base(clip, tracking, &tracking->tracks, name, frame); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, clip); + + return track; } -static void rna_trackingObject_tracks_add(ID *id, MovieTrackingObject *object, int frame, int number) +static MovieTrackingTrack *rna_trackingObject_tracks_new(ID *id, MovieTrackingObject *object, const char *name, int frame) { MovieClip *clip = (MovieClip *) id; ListBase *tracksbase = &object->tracks; + MovieTrackingTrack *track; if (object->flag & TRACKING_OBJECT_CAMERA) tracksbase = &clip->tracking.tracks; - add_tracks_to_base(clip, &clip->tracking, tracksbase, frame, number); + track = add_track_to_base(clip, &clip->tracking, tracksbase, name, frame); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); + + return track; } static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, const char *name) @@ -1326,16 +1339,19 @@ static void rna_def_trackingTracks(BlenderRNA *brna) StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; + PropertyRNA *parm; srna = RNA_def_struct(brna, "MovieTrackingTracks", NULL); RNA_def_struct_sdna(srna, "MovieTracking"); RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); - func = RNA_def_function(srna, "add", "rna_trackingTracks_add"); + func = RNA_def_function(srna, "new", "rna_trackingTracks_new"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); - RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + RNA_def_function_ui_description(func, "Create new motion track in this movie clip"); + RNA_def_string(func, "name", "", 0, "", "Name of new track"); + RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add track on", MINFRAME, MAXFRAME); + parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track"); + RNA_def_function_return(func, parm); /* active track */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); @@ -1350,16 +1366,19 @@ static void rna_def_trackingObjectTracks(BlenderRNA *brna) StructRNA *srna; FunctionRNA *func; PropertyRNA *prop; + PropertyRNA *parm; srna = RNA_def_struct(brna, "MovieTrackingObjectTracks", NULL); RNA_def_struct_sdna(srna, "MovieTrackingObject"); RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); - func = RNA_def_function(srna, "add", "rna_trackingObject_tracks_add"); + func = RNA_def_function(srna, "new", "rna_trackingObject_tracks_new"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); + RNA_def_function_ui_description(func, "create new motion track in this movie clip"); + RNA_def_string(func, "name", "", 0, "", "Name of new track"); RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); - RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + parm = RNA_def_pointer(func, "track", "MovieTrackingTrack", "", "Newly created track"); + RNA_def_function_return(func, parm); /* active track */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); From 0e26a67c855bed001cf54ec97dbb970b6086959f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 12:16:11 +0000 Subject: [PATCH 038/132] add area_poly_v3_max() for use with area_poly_v3 --- source/blender/blenlib/BLI_math_geom.h | 7 +++- source/blender/blenlib/intern/math_geom.c | 51 ++++++++++++----------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index b322d9d7aef..7cb91a45118 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -260,7 +260,12 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f); float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]); -void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]); +void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]); +float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; MINLINE int max_axis_v3(const float vec[3]); MINLINE int min_axis_v3(const float vec[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index b78b15de5a6..a643c893cdb 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -131,30 +131,19 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) float area_poly_v3(int nr, float verts[][3], const float normal[3]) { - float x, y, z, area, max; - float *cur, *prev; - int a, px = 0, py = 1; - - /* first: find dominant axis: 0==X, 1==Y, 2==Z - * don't use 'axis_dominant_v3()' because we need max axis too */ - x = fabsf(normal[0]); - y = fabsf(normal[1]); - z = fabsf(normal[2]); - max = max_fff(x, y, z); - if (max == y) py = 2; - else if (max == x) { - px = 1; - py = 2; - } + int a, px, py; + const float max = axis_dominant_v3_max(&px, &py, normal); + float area; + float *co_curr, *co_prev; /* The Trapezium Area Rule */ - prev = verts[nr - 1]; - cur = verts[0]; - area = 0; + co_prev = verts[nr - 1]; + co_curr = verts[0]; + area = 0.0f; for (a = 0; a < nr; a++) { - area += (cur[px] - prev[px]) * (cur[py] + prev[py]); - prev = verts[a]; - cur = verts[a + 1]; + area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]); + co_prev = verts[a]; + co_curr = verts[a + 1]; } return fabsf(0.5f * area / max); @@ -1952,15 +1941,27 @@ void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, /****************************** Interpolation ********************************/ /* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */ -void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]) +void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3]) { const float xn = fabsf(axis[0]); const float yn = fabsf(axis[1]); const float zn = fabsf(axis[2]); - if (zn >= xn && zn >= yn) { *axis_a = 0; *axis_b = 1; } - else if (yn >= xn && yn >= zn) { *axis_a = 0; *axis_b = 2; } - else { *axis_a = 1; *axis_b = 2; } + if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; } + else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; } + else { *r_axis_a = 1; *r_axis_b = 2; } +} + +/* same as axis_dominant_v3 but return the max value */ +float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3]) +{ + const float xn = fabsf(axis[0]); + const float yn = fabsf(axis[1]); + const float zn = fabsf(axis[2]); + + if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; } + else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; } + else { *r_axis_a = 1; *r_axis_b = 2; return xn; } } static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j) From c598a306c4422db483d122cbdcea54c1baf60d11 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Mon, 7 Jan 2013 12:19:00 +0000 Subject: [PATCH 039/132] Add normal_flip() member to Python BMesh's Face. --- source/blender/python/bmesh/bmesh_py_types.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 5db9962e690..ea6e1e29f0b 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1616,6 +1616,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self) } +PyDoc_STRVAR(bpy_bmface_normal_flip_doc, +".. method:: normal_flip()\n" +"\n" +" Reverses winding of a face, which flips its normal.\n" +); +static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self) +{ + BPY_BM_CHECK_OBJ(self); + + BM_face_normal_flip(self->bm, self->f); + + Py_RETURN_NONE; +} + + /* Loop * ---- */ @@ -2424,6 +2439,7 @@ static struct PyMethodDef bpy_bmface_methods[] = { {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc}, {"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc}, + {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc}, {NULL, NULL, 0, NULL} }; From d22c8cfca39d3f55447bc54870f6984edf1ae3c2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 14:25:26 +0000 Subject: [PATCH 040/132] add error check for qtcreator&netbeans project file generators to quit early if cmake fails. --- build_files/cmake/cmake_netbeans_project.py | 4 ++++ build_files/cmake/cmake_qtcreator_project.py | 3 +++ build_files/cmake/project_info.py | 10 ++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py index 2f36cad4d24..17490e36bb3 100755 --- a/build_files/cmake/cmake_netbeans_project.py +++ b/build_files/cmake/cmake_netbeans_project.py @@ -56,6 +56,10 @@ def create_nb_project_main(): pass else: includes, defines = cmake_advanced_info() + + if (includes, defines) == (None, None): + return + # for some reason it doesnt give all internal includes includes = list(set(includes) | set(dirname(f) for f in files if is_c_header(f))) includes.sort() diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 86201da23de..4cf854aad77 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -81,6 +81,9 @@ def create_qtc_project_main(): else: includes, defines = cmake_advanced_info() + if (includes, defines) == (None, None): + return + # for some reason it doesnt give all internal includes includes = list(set(includes) | set(os.path.dirname(f) for f in files_rel if is_c_header(f))) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 495ca71263e..e73b94a7051 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -149,14 +149,20 @@ def cmake_advanced_info(): raise Exception("Unknown make program %r" % make_exe) os.system(cmd) + return join(CMAKE_DIR, ".cproject") + includes = [] defines = [] - create_eclipse_project() + project_path = create_eclipse_project() + + if not exists(project_path): + print("Generating Eclipse Prokect File Failed: %r not found" % project_path) + return None, None from xml.dom.minidom import parse - tree = parse(join(CMAKE_DIR, ".cproject")) + tree = parse(project_path) # to check on nicer xml # f = open(".cproject_pretty", 'w') From 1f70a30bd74c3fd2616479b0e8aa4a1c0dda3019 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Jan 2013 14:25:29 +0000 Subject: [PATCH 041/132] Fix #33735: sequencer crash when using rendered preview Issue was caused by preview job starting just moment before sequencer starts rendering. This lead to threading conflicts since renderer itself is not thread-safe. Now all preview jobs would be killed before sequencer starts rendering stack when final render for preview is enabled. --- source/blender/editors/space_sequencer/sequencer_draw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index e3db9c23c41..9e55d95637d 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -929,6 +929,13 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq * needed to make so sequencer's rendering doesn't conflict with compositor */ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE); + + if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { + /* in case of final rendering used for preview, kill all previews, + * otherwise threading conflict will happen in rendering module + */ + WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW); + } } render_size = sseq->render_size; From 6f381db60e86ec17f4d84eb2b35d47dba3ed62e3 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 7 Jan 2013 15:29:15 +0000 Subject: [PATCH 042/132] Bug fix 33778 The user pref "Mini Axis Brightness" didn't work. Note it's only accissble via the outliner now. --- source/blender/editors/space_view3d/view3d_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0f9739dc3b1..34a9529d777 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -599,7 +599,7 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect) float startx = k + 1.0f; /* axis center in screen coordinates, x=y */ float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ - int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ + int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */ float vec[3]; float dx, dy; From 12d921eb5b438473cf1cbf287d3f7640cad32f40 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 15:35:20 +0000 Subject: [PATCH 043/132] minor improvement to CustomData_bmesh_merge(), allocate the correct size pool rather then always 512. --- source/blender/blenkernel/intern/customdata.c | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 0f352dede23..832c1979a51 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2298,34 +2298,45 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest, BMIter iter; CustomData destold; void *tmp; - int t; + int iter_type; + int totelem; /* copy old layer description so that old data can be copied into * the new allocation */ destold = *dest; - if (destold.layers) destold.layers = MEM_dupallocN(destold.layers); - - CustomData_merge(source, dest, mask, alloctype, 0); - dest->pool = NULL; - CustomData_bmesh_init_pool(dest, 512, htype); + if (destold.layers) { + destold.layers = MEM_dupallocN(destold.layers); + } switch (htype) { case BM_VERT: - t = BM_VERTS_OF_MESH; break; + iter_type = BM_VERTS_OF_MESH; + totelem = bm->totvert; + break; case BM_EDGE: - t = BM_EDGES_OF_MESH; break; + iter_type = BM_EDGES_OF_MESH; + totelem = bm->totedge; + break; case BM_LOOP: - t = BM_LOOPS_OF_FACE; break; + iter_type = BM_LOOPS_OF_FACE; + totelem = bm->totloop; + break; case BM_FACE: - t = BM_FACES_OF_MESH; break; + iter_type = BM_FACES_OF_MESH; + totelem = bm->totface; + break; default: /* should never happen */ BLI_assert(!"invalid type given"); - t = BM_VERTS_OF_MESH; + iter_type = BM_VERTS_OF_MESH; } - if (t != BM_LOOPS_OF_FACE) { + CustomData_merge(source, dest, mask, alloctype, 0); + dest->pool = NULL; + CustomData_bmesh_init_pool(dest, totelem, htype); + + if (iter_type != BM_LOOPS_OF_FACE) { /*ensure all current elements follow new customdata layout*/ - BM_ITER_MESH (h, &iter, bm, t) { + BM_ITER_MESH (h, &iter, bm, iter_type) { tmp = NULL; CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp); CustomData_bmesh_free_block(&destold, &h->data); From ff6339a9799b854e145608c4ed3673227b85d971 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 7 Jan 2013 15:42:42 +0000 Subject: [PATCH 044/132] Make options for background gradient more organized. This was difficult to do because we group theme colours and display them together in user preferences. To make the background options more presentable and keep them grouped and separate, I needed to group the two gradient colours somehow. I added a separate ThemeSpaceGradient RNA struct as opposed to ThemeSpaceGeneric. This struct is the same as ThemeSpaceGeneric but it lacks the window background option (which does nothing now) and includes the UiGradient struct which now has both gradient colours. I modified the clear functions to use a new high colour from the gradient. Now all options appear grouped and any other editor that may use a gradient for the window background may do so. Also corrected incorrect MAIN_VERSION_ATLEAST macro, it would not detect versions correctly --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/BKE_main.h | 2 +- source/blender/editors/include/UI_resources.h | 3 +- source/blender/editors/interface/resources.c | 15 ++- .../editors/space_view3d/view3d_draw.c | 6 +- source/blender/makesdna/DNA_userdef_types.h | 2 +- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_userdef.c | 117 ++++++++++++++++-- 8 files changed, 128 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 10528f1b270..dc3f8dfb964 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 5 +#define BLENDER_SUBVERSION 6 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index da0cba422c3..1b7b29432e2 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -93,7 +93,7 @@ typedef struct Main { } Main; #define MAIN_VERSION_ATLEAST(main, ver, subver) \ - ((main)->versionfile >= (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) + ((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) #ifdef __cplusplus } diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 0ddb8830c2a..7e7be17d7c6 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -225,7 +225,8 @@ enum { TH_AXIS_Y, TH_AXIS_Z, - TH_BACK_GRAD, + TH_LOW_GRAD, + TH_HIGH_GRAD, TH_SHOW_BACK_GRAD }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 088715218ef..0627fad7227 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -170,9 +170,12 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo else cp = ts->button; break; - case TH_BACK_GRAD: + case TH_LOW_GRAD: cp = ts->gradients.gradient; break; + case TH_HIGH_GRAD: + cp = ts->gradients.high_gradient; + break; case TH_SHOW_BACK_GRAD: cp = &setting; setting = ts->gradients.show_grad; @@ -780,6 +783,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0); + rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 0.225, 0.225, 0.225, 1.0); btheme->tv3d.gradients.show_grad = FALSE; /* space buttons */ @@ -2100,7 +2104,7 @@ void init_userdef_do_versions(void) } } - if (!MAIN_VERSION_ATLEAST(bmain, 266, 4)) { + if (!MAIN_VERSION_ATLEAST(bmain, 265, 4)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */ @@ -2109,6 +2113,13 @@ void init_userdef_do_versions(void) } } + if (!MAIN_VERSION_ATLEAST(bmain, 265, 6)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + copy_v4_v4_char(btheme->tv3d.gradients.high_gradient, btheme->tv3d.back); + } + } + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 34a9529d777..740bf797a6b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3108,10 +3108,10 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) glShadeModel(GL_SMOOTH); glBegin(GL_QUADS); - UI_ThemeColor(TH_BACK_GRAD); + UI_ThemeColor(TH_LOW_GRAD); glVertex2f(-1.0, -1.0); glVertex2f(1.0, -1.0); - UI_ThemeColor(TH_BACK); + UI_ThemeColor(TH_HIGH_GRAD); glVertex2f(1.0, 1.0); glVertex2f(-1.0, 1.0); glEnd(); @@ -3124,7 +3124,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) glPopMatrix(); } else { - UI_ThemeClearColor(TH_BACK); + UI_ThemeClearColor(TH_HIGH_GRAD); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index d6da03040cc..3027a3abd7d 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -151,7 +151,7 @@ typedef struct uiPanelColors { typedef struct uiGradientColors { char gradient[4]; - char pad[4]; + char high_gradient[4]; int show_grad; int pad2; } uiGradientColors; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index e2f72ca339d..29adb8ff599 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -571,6 +571,7 @@ extern StructRNA RNA_ThemeOutliner; extern StructRNA RNA_ThemeProperties; extern StructRNA RNA_ThemeSequenceEditor; extern StructRNA RNA_ThemeSpaceGeneric; +extern StructRNA RNA_ThemeSpaceGradient; extern StructRNA RNA_ThemeSpaceListGeneric; extern StructRNA RNA_ThemeStyle; extern StructRNA RNA_ThemeTextEditor; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 83162bec7f4..07390958bd9 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -345,6 +345,11 @@ static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr) return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data); } +static PointerRNA rna_Theme_space_gradient_get(PointerRNA *ptr) +{ + return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGradient, ptr->data); +} + static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceListGeneric, ptr->data); @@ -766,16 +771,22 @@ static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna) srna = RNA_def_struct(brna, "ThemeGradientColors", NULL); RNA_def_struct_sdna(srna, "uiGradientColors"); RNA_def_struct_clear_flag(srna, STRUCT_UNDO); - RNA_def_struct_ui_text(srna, "Theme Gradient Color", "Theme settings for gradient colors"); - - prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_ui_text(prop, "Gradient Color", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + RNA_def_struct_ui_text(srna, "Theme Background Color", "Theme settings for background colors and gradient"); prop = RNA_def_property(srna, "show_grad", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Use Gradient", "Do a gradient for the background of the viewport working area"); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "gradient", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Gradient Low", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "high_gradient", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Gradient High/Off", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui(BlenderRNA *brna) @@ -997,6 +1008,83 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) /* } */ } +static void rna_def_userdef_theme_space_gradient(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThemeSpaceGradient", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_ui_text(srna, "Theme Space Settings", ""); + + /* window */ + prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Title", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* header */ + prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "header_text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "header_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Header Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* panel settings */ + prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Panel Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* gradient/background settings */ + prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Gradient Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + /* buttons */ +/* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */ + prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Region Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_title", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text Titles", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_text", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "button_text_hi", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Region Text Highlight", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +/* } */ +} + /* list / channels */ static void rna_def_userdef_theme_space_list_generic(BlenderRNA *brna) { @@ -1039,6 +1127,17 @@ static void rna_def_userdef_theme_spaces_main(StructRNA *srna) RNA_def_property_ui_text(prop, "Theme Space", "Settings for space"); } +static void rna_def_userdef_theme_spaces_gradient(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_struct_type(prop, "ThemeSpaceGradient"); + RNA_def_property_pointer_funcs(prop, "rna_Theme_space_gradient_get", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Theme Space", "Settings for space"); +} + static void rna_def_userdef_theme_spaces_list_main(StructRNA *srna) { PropertyRNA *prop; @@ -1243,7 +1342,7 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Theme 3D View", "Theme settings for the 3D View"); - rna_def_userdef_theme_spaces_main(srna); + rna_def_userdef_theme_spaces_gradient(srna); prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1381,11 +1480,6 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Skin Root", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop = RNA_def_property(srna, "gradients", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_ui_text(prop, "Gradient", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); } @@ -2562,6 +2656,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna) rna_def_userdef_theme_ui(brna); rna_def_userdef_theme_space_generic(brna); + rna_def_userdef_theme_space_gradient(brna); rna_def_userdef_theme_space_list_generic(brna); rna_def_userdef_theme_space_view3d(brna); From f1cc922ccd1378a8e7206f4180dda7c8398aa9f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Jan 2013 15:43:28 +0000 Subject: [PATCH 045/132] dont copy the mvert array in DM_to_bmesh_ex() --- source/blender/blenkernel/intern/modifiers_bmesh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 7df7561a1a1..9b5cf443bcf 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -89,7 +89,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ - mv = mvert = dm->dupVertArray(dm); + mv = mvert = dm->getVertArray(dm); for (i = 0; i < totvert; i++, mv++) { v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); @@ -107,7 +107,6 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) *orig_index = ORIGINDEX_NONE; } } - MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ From 999aaa1a514caaed9137033b32f1936d7ccccde0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Jan 2013 18:10:03 +0000 Subject: [PATCH 046/132] ui_lists shall be NULLed in BKE_area_region_copy Otherwise it'll be nasty crashes when, say, adding and removing screens with lists visible on the screen. Thanks Ton for assisting looking into this issue :) --- source/blender/blenkernel/intern/screen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 81bcdc4b06e..95b72d0185c 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -167,6 +167,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar) newar->prev = newar->next = NULL; newar->handlers.first = newar->handlers.last = NULL; newar->uiblocks.first = newar->uiblocks.last = NULL; + newar->ui_lists.first = newar->ui_lists.last = NULL; newar->swinid = 0; /* use optional regiondata callback */ From 41c588256ba88703d172254ff1d7155f5d2c6b02 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Jan 2013 19:55:49 +0000 Subject: [PATCH 047/132] Cycles / Tile Rendering: * Added new option to chose the tile order. In addition to the "Center" method, 4 new methods are available now, like Top -> Bottom and Right -> Left. Thanks to Sergey for code review and some tweaks! --- intern/cycles/blender/addon/properties.py | 14 ++++++ intern/cycles/blender/addon/ui.py | 3 +- intern/cycles/blender/blender_sync.cpp | 2 + intern/cycles/render/session.cpp | 2 +- intern/cycles/render/session.h | 1 + intern/cycles/render/tile.cpp | 60 +++++++++++++++++++---- intern/cycles/render/tile.h | 19 +++++-- 7 files changed, 86 insertions(+), 15 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2bc4afe969e..8b90b0bd4ff 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -95,6 +95,14 @@ enum_curves_interpolation = ( ('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"), ('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"), ) + +enum_tile_order = ( + ('CENTER', "Center", "Render from center to the edges"), + ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"), + ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"), + ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"), + ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"), + ) class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod @@ -352,6 +360,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Cache last built BVH to disk for faster re-render if no geometry changed", default=False, ) + cls.tile_order = EnumProperty( + name="Tile Order", + description="Tile order for rendering", + items=enum_tile_order, + default='CENTER', + ) cls.use_progressive_refine = BoolProperty( name="Progressive Refine", description="Instead of rendering each tile until it is finished, " diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 81ee34b6b5e..a24da593b43 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -191,7 +191,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.prop(rd, "threads") sub = col.column(align=True) - sub.label(text="Tile Size:") + sub.label(text="Tiles:") + sub.prop(cscene, "tile_order", text="") sub.prop(rd, "tile_x", text="X") sub.prop(rd, "tile_y", text="Y") diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b9860ca90f2..a2a8c23404f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -396,6 +396,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use params.tile_size = make_int2(tile_x, tile_y); } + + params.tile_order = RNA_enum_get(&cscene, "tile_order"); params.start_resolution = get_int(cscene, "preview_start_resolution"); diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 36948adce17..e49a4a3ed34 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN Session::Session(const SessionParams& params_) : params(params_), tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution, - params.background == false || params.progressive_refine, params.background, + params.background == false || params.progressive_refine, params.background, params.tile_order, max(params.device.multi_devices.size(), 1)), stats() { diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index cfc1502287d..27073d2fd9c 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -51,6 +51,7 @@ public: bool experimental; int samples; int2 tile_size; + int tile_order; int start_resolution; int threads; diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index bbcdb47260e..d62ecd8a88c 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -24,10 +24,11 @@ CCL_NAMESPACE_BEGIN TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, - bool preserve_tile_device_, bool background_, int num_devices_) + bool preserve_tile_device_, bool background_, int tile_order_, int num_devices_) { progressive = progressive_; tile_size = tile_size_; + tile_order = tile_order_; start_resolution = start_resolution_; num_devices = num_devices_; preserve_tile_device = preserve_tile_device_; @@ -165,6 +166,20 @@ void TileManager::set_tiles() state.buffer.full_height = max(1, params.full_height/resolution); } +list::iterator TileManager::next_viewport_tile(int device) +{ + list::iterator iter; + + int logical_device = preserve_tile_device? device: 0; + + for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { + if(iter->device == logical_device && iter->rendering == false) + return iter; + } + + return state.tiles.end(); +} + list::iterator TileManager::next_center_tile(int device) { list::iterator iter, best = state.tiles.end(); @@ -210,28 +225,53 @@ list::iterator TileManager::next_center_tile(int device) return best; } -list::iterator TileManager::next_simple_tile(int device) +list::iterator TileManager::next_simple_tile(int device, int tile_order) { - list::iterator iter; + list::iterator iter, best = state.tiles.end(); + int resolution = state.resolution_divider; int logical_device = preserve_tile_device? device: 0; + int64_t cordx = max(1, params.width/resolution); + int64_t cordy = max(1, params.height/resolution); + int64_t mindist = cordx * cordy; + for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { - if(iter->device == logical_device && iter->rendering == false) - return iter; + if(iter->device == logical_device && iter->rendering == false) { + Tile &cur_tile = *iter; + + int64_t distx = cordx; + + if (tile_order == TileManager::RIGHT_TO_LEFT) + distx = cordx - cur_tile.x; + else if (tile_order == TileManager::LEFT_TO_RIGHT) + distx = cordx + cur_tile.x; + else if (tile_order == TileManager::TOP_TO_BOTTOM) + distx = cordx - cur_tile.y; + else /* TileManager::BOTTOM_TO_TOP */ + distx = cordx + cur_tile.y; + + if(distx < mindist) { + best = iter; + mindist = distx; + } + } } - return state.tiles.end(); + return best; } bool TileManager::next_tile(Tile& tile, int device) { list::iterator tile_it; - - if(background) - tile_it = next_center_tile(device); + if (background) { + if(tile_order == TileManager::CENTER) + tile_it = next_center_tile(device); + else + tile_it = next_simple_tile(device, tile_order); + } else - tile_it = next_simple_tile(device); + tile_it = next_viewport_tile(device); if(tile_it != state.tiles.end()) { tile_it->rendering = true; diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 6f7a8f20734..7d3df6c1524 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -59,7 +59,7 @@ public: } state; TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution, - bool preserve_tile_device, bool background, int num_devices = 1); + bool preserve_tile_device, bool background, int tile_order, int num_devices = 1); ~TileManager(); void reset(BufferParams& params, int num_samples); @@ -69,11 +69,21 @@ public: bool done(); protected: + /* Note: this should match enum_tile_order in properties.py */ + enum { + CENTER = 0, + RIGHT_TO_LEFT = 1, + LEFT_TO_RIGHT = 2, + TOP_TO_BOTTOM = 3, + BOTTOM_TO_TOP = 4 + } TileOrder; + void set_tiles(); bool progressive; int num_samples; int2 tile_size; + int tile_order; int start_resolution; int num_devices; @@ -106,9 +116,12 @@ protected: * mimics behavior of blender internal's tile order */ list::iterator next_center_tile(int device); + + /* returns simple tile order */ + list::iterator next_simple_tile(int device, int tile_order); - /* returns first unhandled tile starting from left bottom corner of the image */ - list::iterator next_simple_tile(int device); + /* returns first unhandled tile (for viewport) */ + list::iterator next_viewport_tile(int device); }; CCL_NAMESPACE_END From c3b5c726c7a76b17d3fa3a4bb1f9e9db2e61ee18 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 7 Jan 2013 21:42:40 +0000 Subject: [PATCH 048/132] * Fix for #31581. The issue was that we scaled the face prior to projecting it. The original paper suggests to simply interpolate between the two points of an edge if the distance of the point to that edge is smaller than a threshold. * Fixed both 3D and 2D code to utilize this. Possibly other places in blender where this scaling is done will have to be adjusted. * Changed vertex interpolation to use 2D interpolation, since it already did projection on plane and 2d calculations are faster. * Also added notifier on hard recalc when uvcalc_transfor_correction is used. Results in instant feedback on UV editor when edge sliding. --- source/blender/blenlib/intern/math_geom.c | 67 +++++++++++++++++--- source/blender/bmesh/intern/bmesh_interp.c | 34 ++-------- source/blender/editors/transform/transform.c | 7 +- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index a643c893cdb..91939b4d883 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2335,14 +2335,25 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i; + int i, inext, icur; + bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { + icur = i; + inext = (i == n - 1) ? 0 : i + 1; + vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = (i == n - 1) ? v[0] : v[i + 1]; + vnext = v[inext]; + + /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close + * to borders of face. In that case, do simple linear interpolation between the two edges */ + if (dist_to_line_segment_v3(co, vmid, vnext) < 10*FLT_EPSILON) { + edge_interp = true; + break; + } t1 = mean_value_half_tan_v3(co, vprev, vmid); t2 = mean_value_half_tan_v3(co, vmid, vnext); @@ -2352,25 +2363,49 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ totweight += w[i]; } - if (totweight != 0.0f) { - for (i = 0; i < n; i++) { - w[i] /= totweight; + if (edge_interp) { + float len_cur = len_v3v3(co, vmid); + float len_next = len_v3v3(co, vnext); + float edge_len = len_cur + len_next; + for (i = 0; i < n; i++) + w[i] = 0.0; + + w[icur] = len_next/edge_len; + w[inext] = len_cur/edge_len; + } + else { + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { + w[i] /= totweight; + } } } } + void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2]) { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i; + int i, inext, icur; + bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { + icur = i; + inext = (i == n - 1) ? 0 : i + 1; + vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = (i == n - 1) ? v[0] : v[i + 1]; + vnext = v[inext]; + + /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close + * to borders of face. In that case, do simple linear interpolation between the two edges */ + if (dist_to_line_segment_v2(co, vmid, vnext) < 10*FLT_EPSILON) { + edge_interp = true; + break; + } t1 = mean_value_half_tan_v2(co, vprev, vmid); t2 = mean_value_half_tan_v2(co, vmid, vnext); @@ -2380,9 +2415,21 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ totweight += w[i]; } - if (totweight != 0.0f) { - for (i = 0; i < n; i++) { - w[i] /= totweight; + if (edge_interp) { + float len_cur = len_v2v2(co, vmid); + float len_next = len_v2v2(co, vnext); + float edge_len = len_cur + len_next; + for (i = 0; i < n; i++) + w[i] = 0.0; + + w[icur] = len_next/edge_len; + w[inext] = len_cur/edge_len; + } + else { + if (totweight != 0.0f) { + for (i = 0; i < n; i++) { + w[i] /= totweight; + } } } } diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 4ec91b8d8d7..1afaf851e2a 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -606,9 +606,9 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL; void **blocks = BLI_array_alloca(blocks, source->len); float (*cos)[3] = BLI_array_alloca(cos, source->len); + float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len); float *w = BLI_array_alloca(w, source->len); - float co[3]; - float cent[3] = {0.0f, 0.0f, 0.0f}; + float co[2]; int i, ax, ay; BM_elem_attrs_copy(bm, bm, source, target->f); @@ -617,7 +617,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, l_iter = l_first = BM_FACE_FIRST_LOOP(source); do { copy_v3_v3(cos[i], l_iter->v->co); - add_v3_v3(cent, cos[i]); w[i] = 0.0f; blocks[i] = l_iter->head.data; @@ -634,28 +633,17 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, axis_dominant_v3(&ax, &ay, source->no); - /* scale source face coordinates a bit, so points sitting directly on an - * edge will work. */ - mul_v3_fl(cent, 1.0f / (float)source->len); for (i = 0; i < source->len; i++) { - float vec[3], tmp[3]; - sub_v3_v3v3(vec, cent, cos[i]); - mul_v3_fl(vec, 0.001f); - add_v3_v3(cos[i], vec); - - copy_v3_v3(tmp, cos[i]); - cos[i][0] = tmp[ax]; - cos[i][1] = tmp[ay]; - cos[i][2] = 0.0f; + cos_2d[i][0] = cos[i][ax]; + cos_2d[i][1] = cos[i][ay]; } /* interpolate */ co[0] = target->v->co[ax]; co[1] = target->v->co[ay]; - co[2] = 0.0f; - interp_weights_poly_v3(w, cos, source->len, co); + interp_weights_poly_v2(w, cos_2d, source->len, co); CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data); if (do_vertex) { CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data); @@ -676,30 +664,18 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) void **blocks = BLI_array_alloca(blocks, source->len); float (*cos)[3] = BLI_array_alloca(cos, source->len); float *w = BLI_array_alloca(w, source->len); - float cent[3] = {0.0f, 0.0f, 0.0f}; int i; i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(source); do { copy_v3_v3(cos[i], l_iter->v->co); - add_v3_v3(cent, cos[i]); w[i] = 0.0f; blocks[i] = l_iter->v->head.data; i++; } while ((l_iter = l_iter->next) != l_first); - /* scale source face coordinates a bit, so points sitting directly on an - * edge will work. */ - mul_v3_fl(cent, 1.0f / (float)source->len); - for (i = 0; i < source->len; i++) { - float vec[3]; - sub_v3_v3v3(vec, cent, cos[i]); - mul_v3_fl(vec, 0.01f); - add_v3_v3(cos[i], vec); - } - /* interpolate */ interp_weights_poly_v3(w, cos, source->len, v->co); CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 3b443e8bbac..78a8bd47668 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -462,7 +462,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); else WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - + + if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) + WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); + /* for realtime animation record - send notifiers recognised by animation editors */ // XXX: is this notifier a lame duck? if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) @@ -5424,7 +5427,7 @@ void projectSVData(TransInfo *t, int final) } } - + if (!affected) continue; From 44ab30caf6b7e412ce89bc0eb02a12dab1da3515 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 7 Jan 2013 21:56:13 +0000 Subject: [PATCH 049/132] comment fix. Looks like no scaling is done elsewhere on blender for this code. I hope this bug is squashed for good. --- source/blender/blenlib/intern/math_geom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 91939b4d883..771de0f1569 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2349,7 +2349,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ vnext = v[inext]; /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close - * to borders of face. In that case, do simple linear interpolation between the two edges */ + * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ if (dist_to_line_segment_v3(co, vmid, vnext) < 10*FLT_EPSILON) { edge_interp = true; break; @@ -2401,7 +2401,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ vnext = v[inext]; /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close - * to borders of face. In that case, do simple linear interpolation between the two edges */ + * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ if (dist_to_line_segment_v2(co, vmid, vnext) < 10*FLT_EPSILON) { edge_interp = true; break; From 35b187e2834f552e2e319c0ead03395d966d153b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 8 Jan 2013 01:00:59 +0000 Subject: [PATCH 050/132] Motion Path drawing tweaks and fixes * Green (current frame) color now extends to the segments on either side of the current frame point. This is so that the path is more visible (especially on the black/dark side), as those segments were prone to being interpolated such that they became invisible * Added padding for frame number strings so that they do not overlap the dots anymore * Fixed off-by-one error, which meant that the frame number for the first frame step (white dot) didn't get shown --- .../editors/space_view3d/drawanimviz.c | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c index 0649edc1ac4..57864854734 100644 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ b/source/blender/editors/space_view3d/drawanimviz.c @@ -139,35 +139,38 @@ void draw_motion_path_instance(Scene *scene, short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT); float intensity; /* how faint */ + int frame = sfra + i; + int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */ + /* set color * - more intense for active/selected bones, less intense for unselected bones * - black for before current frame, green for current frame, blue for after current frame * - intensity decreases as distance from current frame increases */ #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min) - if ((sfra + i) < CFRA) { + if (frame < CFRA) { /* black - before cfra */ if (sel) { - // intensity = 0.5f; + /* intensity = 0.5f; */ intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f); } else { - //intensity = 0.8f; + /* intensity = 0.8f; */ intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f); } - UI_ThemeColorBlend(TH_WIRE, TH_BACK, intensity); + UI_ThemeColorBlend(TH_WIRE, blend_base, intensity); } - else if ((sfra + i) > CFRA) { + else if (frame > CFRA) { /* blue - after cfra */ if (sel) { - //intensity = 0.5f; + /* intensity = 0.5f; */ intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f); } else { - //intensity = 0.8f; + /* intensity = 0.8f; */ intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f); } - UI_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity); + UI_ThemeColorBlend(TH_BONE_POSE, blend_base, intensity); } else { /* green - on cfra */ @@ -232,21 +235,22 @@ void draw_motion_path_instance(Scene *scene, col[3] = 255; for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { + int frame = sfra + i; char numstr[32]; float co[3]; /* only draw framenum if several consecutive highlighted points don't occur on same point */ if (i == 0) { - sprintf(numstr, "%d", (i + sfra)); + sprintf(numstr, " %d", frame); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } - else if ((i > stepsize) && (i < len - stepsize)) { + else if ((i >= stepsize) && (i < len - stepsize)) { bMotionPathVert *mpvP = (mpv - stepsize); bMotionPathVert *mpvN = (mpv + stepsize); if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) { - sprintf(numstr, "%d", (sfra + i)); + sprintf(numstr, " %d", frame); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } @@ -286,12 +290,13 @@ void draw_motion_path_instance(Scene *scene, UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); col[3] = 255; - glPointSize(4.0f); // XXX perhaps a bit too big + glPointSize(4.0f); glColor3ubv(col); glBegin(GL_POINTS); for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - float mframe = (float)(sfra + i); + int frame = sfra + i; + float mframe = (float)(frame); if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) glVertex3fv(mpv->co); @@ -309,7 +314,7 @@ void draw_motion_path_instance(Scene *scene, if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { char numstr[32]; - sprintf(numstr, "%d", (sfra + i)); + sprintf(numstr, " %d", (sfra + i)); mul_v3_m4v3(co, ob->imat, mpv->co); view3d_cached_text_draw_add(co, numstr, 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); } From 08358a60b072461f3632c08cfc3a7af55b290162 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 01:48:14 +0000 Subject: [PATCH 051/132] style cleanup --- intern/ghost/intern/GHOST_SystemX11.cpp | 4 +-- source/blender/blenkernel/intern/image.c | 2 +- source/blender/blenlib/intern/math_geom.c | 36 +++++++++---------- .../blender/editors/armature/meshlaplacian.c | 2 +- .../editors/space_view3d/view3d_draw.c | 4 +-- .../blender/editors/space_view3d/view3d_fly.c | 2 +- source/blender/imbuf/IMB_thumbs.h | 2 +- source/blender/modifiers/intern/MOD_screw.c | 2 +- source/blender/quicktime/apple/qtkit_export.m | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 2d3cc4f88dc..f5cb0d9323c 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -132,7 +132,7 @@ GHOST_SystemX11( GHOST_ASSERT(false, "Could not instantiate timer!"); } - /* Taking care not to overflow the tv.tv_sec*1000 */ + /* Taking care not to overflow the tv.tv_sec * 1000 */ m_start_time = GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000; @@ -190,7 +190,7 @@ getMilliSeconds() const GHOST_ASSERT(false, "Could not compute time!"); } - /* Taking care not to overflow the tv.tv_sec*1000 */ + /* Taking care not to overflow the tv.tv_sec * 1000 */ return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index dbc423f98b3..21417386d65 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -904,7 +904,7 @@ void BKE_image_free_all_textures(void) image_free_buffers(ima); } } - /* printf("freed total %d MB\n", totsize/(1024*1024)); */ + /* printf("freed total %d MB\n", totsize / (1024 * 1024)); */ } /* except_frame is weak, only works for seqs without offset... */ diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 771de0f1569..a54bef9d5d2 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2335,22 +2335,22 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i, inext, icur; + int i, i_next, i_curr; bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { - icur = i; - inext = (i == n - 1) ? 0 : i + 1; + i_curr = i; + i_next = (i == n - 1) ? 0 : i + 1; vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = v[inext]; + vnext = v[i_next]; /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ - if (dist_to_line_segment_v3(co, vmid, vnext) < 10*FLT_EPSILON) { + if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) { edge_interp = true; break; } @@ -2364,14 +2364,14 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ } if (edge_interp) { - float len_cur = len_v3v3(co, vmid); + float len_curr = len_v3v3(co, vmid); float len_next = len_v3v3(co, vnext); - float edge_len = len_cur + len_next; + float edge_len = len_curr + len_next; for (i = 0; i < n; i++) w[i] = 0.0; - w[icur] = len_next/edge_len; - w[inext] = len_cur/edge_len; + w[i_curr] = len_next / edge_len; + w[i_next] = len_curr / edge_len; } else { if (totweight != 0.0f) { @@ -2387,22 +2387,22 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ { /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */ float totweight, t1, t2, len, *vmid, *vprev, *vnext; - int i, inext, icur; + int i, i_next, i_curr; bool edge_interp = false; totweight = 0.0f; for (i = 0; i < n; i++) { - icur = i; - inext = (i == n - 1) ? 0 : i + 1; + i_curr = i; + i_next = (i == n - 1) ? 0 : i + 1; vmid = v[i]; vprev = (i == 0) ? v[n - 1] : v[i - 1]; - vnext = v[inext]; + vnext = v[i_next]; /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close * to borders of face. In that case, do simple linear interpolation between the two edge vertices */ - if (dist_to_line_segment_v2(co, vmid, vnext) < 10*FLT_EPSILON) { + if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) { edge_interp = true; break; } @@ -2416,14 +2416,14 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ } if (edge_interp) { - float len_cur = len_v2v2(co, vmid); + float len_curr = len_v2v2(co, vmid); float len_next = len_v2v2(co, vnext); - float edge_len = len_cur + len_next; + float edge_len = len_curr + len_next; for (i = 0; i < n; i++) w[i] = 0.0; - w[icur] = len_next/edge_len; - w[inext] = len_cur/edge_len; + w[i_curr] = len_next / edge_len; + w[i_next] = len_curr / edge_len; } else { if (totweight != 0.0f) { diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 19a97fa0810..a7e84d590b5 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1769,7 +1769,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi"); mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); - mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON*100, 4, 6); + mdb->bvhtree = bvhtree_from_mesh_faces(&mdb->bvhdata, mdb->cagedm, FLT_EPSILON * 100, 4, 6); mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside"); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 740bf797a6b..67344a9804b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -315,7 +315,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** UI_ThemeColor(TH_GRID); if (unit->system) { - /* Use GRID_MIN_PX*2 for units because very very small grid + /* Use GRID_MIN_PX * 2 for units because very very small grid * items are less useful when dealing with units */ void *usys; int len, i; @@ -381,7 +381,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** drawgrid_draw(ar, wx, wy, x, y, sublines * dx); } } - else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */ + else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */ UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index f8c9497a686..a749a815546 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -816,7 +816,7 @@ static int flyApply(bContext *C, FlyInfo *fly) /* scale the mouse movement by this value - scales mouse movement to the view size - * moffset[0]/(ar->winx-xmargin*2) - window size minus margin (same for y) + * moffset[0] / (ar->winx-xmargin * 2) - window size minus margin (same for y) * * the mouse moves isn't linear */ diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index a6f38516a14..9fc075e4e8b 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -58,7 +58,7 @@ typedef enum ThumbSource { } ThumbSource; /* don't generate thumbs for images bigger then this (100mb) */ -#define THUMB_SIZE_MAX (100 * 1024*1024) +#define THUMB_SIZE_MAX (100 * 1024 * 1024) // IB_metadata diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index ff88cd97197..1021620e04f 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -274,7 +274,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); /* will the screw be closed? - * Note! smaller then FLT_EPSILON*100 gives problems with float precision so its never closed. */ + * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) { diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index 6935c908ee4..ca9b5bb89e1 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -557,7 +557,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R [qtexport->movie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieEditableAttribute]; [qtexport->movie setAttribute:@"Made with Blender" forKey:QTMovieCopyrightAttribute]; - qtexport->frameDuration = QTMakeTime(rd->frs_sec_base*1000, rd->frs_sec*1000); + qtexport->frameDuration = QTMakeTime(rd->frs_sec_base * 1000, rd->frs_sec * 1000); /* specifying the codec attributes : try to retrieve them from render data first*/ if (rd->qtcodecsettings.codecType) { From 682df047a0005435fb8caad3dba974eb6eca2232 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 02:06:16 +0000 Subject: [PATCH 052/132] style cleanup --- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/fmodifier.c | 2 +- source/blender/blenkernel/intern/pointcache.c | 18 +++++++++--------- source/blender/blenkernel/intern/subsurf_ccg.c | 4 ++-- source/blender/blenlib/intern/math_geom.c | 6 +++--- source/blender/blenlib/intern/string.c | 2 +- source/blender/blenloader/intern/readfile.c | 4 ++-- source/blender/blenloader/intern/writefile.c | 6 +++--- .../editors/interface/interface_handlers.c | 4 ++-- source/blender/editors/screen/area.c | 4 ++-- .../editors/sculpt_paint/paint_image_2d.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 2 +- .../editors/uvedit/uvedit_smart_stitch.c | 4 ++-- .../windowmanager/intern/wm_operators.c | 2 +- 14 files changed, 31 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 1d199cdf1e2..fe8bd0cc5a4 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -875,7 +875,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv) -/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */ +/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */ { BPoint *bp; float *basisu, *basis, *basisv, *sum, *fp, *in; diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 2b393b4d90b..47397a60b20 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -167,7 +167,7 @@ static void fcm_generator_verify(FModifier *fcm) case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ { - /* arraysize needs to be 2*order, so resize if not */ + /* arraysize needs to be (2 * order), so resize if not */ if (data->arraysize != (data->poly_order * 2)) { float *nc; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 9c3c1b0e508..c94ffd3205f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -559,7 +559,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); //int mode = res >= 1000000 ? 2 : 1; int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy @@ -792,7 +792,7 @@ static int ptcache_dynamicpaint_write(PTCacheFile *pf, void *dp_v) int cache_compress = 1; /* version header */ - ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char)*4); + ptcache_file_write(pf, DPAINT_CACHE_VERSION, 1, sizeof(char) * 4); if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) { int total_points=surface->data->total_points; @@ -831,7 +831,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v) char version[4]; /* version header */ - ptcache_file_read(pf, version, 1, sizeof(char)*4); + ptcache_file_read(pf, version, 1, sizeof(char) * 4); if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;} if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) { @@ -1163,7 +1163,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup */ #define MAX_PTCACHE_PATH FILE_MAX -#define MAX_PTCACHE_FILE ((FILE_MAX)*2) +#define MAX_PTCACHE_FILE (FILE_MAX * 2) static int ptcache_path(PTCacheID *pid, char *filename) { @@ -1258,7 +1258,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) { PTCacheFile *pf; FILE *fp = NULL; - char filename[(FILE_MAX)*2]; + char filename[FILE_MAX * 2]; #ifndef DURIAN_POINTCACHE_LIB_OK /* don't allow writing for linked objects */ @@ -1311,7 +1311,7 @@ static int ptcache_file_compressed_read(PTCacheFile *pf, unsigned char *result, size_t out_len = len; #endif unsigned char *in; - unsigned char *props = MEM_callocN(16*sizeof(char), "tmp"); + unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp"); ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char)); if (compressed) { @@ -1354,7 +1354,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns int r = 0; unsigned char compressed = 0; size_t out_len= 0; - unsigned char *props = MEM_callocN(16*sizeof(char), "tmp"); + unsigned char *props = MEM_callocN(16 * sizeof(char), "tmp"); size_t sizeOfIt = 5; (void)mode; /* unused when building w/o compression */ @@ -1787,7 +1787,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) for (i=0; idata[i]) { unsigned int in_len = pm->totpoint*ptcache_data_size[i]; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression); MEM_freeN(out); } @@ -1820,7 +1820,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) if (pid->cache->compression) { unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type]; - unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); + unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len) * 4, "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression); MEM_freeN(out); } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index d381a157fcc..6d4313d1bc3 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1314,8 +1314,8 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop) for (index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */ - /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */ + /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */ + /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */ for (S = 0; S < numVerts; S++) { for (y = 0; y < gridSize - 1; y++) { diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index a54bef9d5d2..5f1047d054e 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -318,7 +318,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of AB, if so return projection of P onto AB */ - vc = d1*d4 - d3*d2; + vc = d1 * d4 - d3 * d2; if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) { float v = d1 / (d1 - d3); /* barycentric coordinates (1-v,v,0) */ @@ -335,7 +335,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of AC, if so return projection of P onto AC */ - vb = d5*d2 - d1*d6; + vb = d5 * d2 - d1 * d6; if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) { float w = d2 / (d2 - d6); /* barycentric coordinates (1-w,0,w) */ @@ -343,7 +343,7 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3], return; } /* Check if P in edge region of BC, if so return projection of P onto BC */ - va = d3*d6 - d5*d4; + va = d3 * d6 - d5 * d4; if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) { float w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); /* barycentric coordinates (0,1-w,w) */ diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index f23f75f69d9..28fdf7b61db 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -412,7 +412,7 @@ int BLI_natstrcmp(const char *s1, const char *s2) void BLI_timestr(double _time, char *str) { /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ - int hr = ( (int) _time) / (60*60); + int hr = ( (int) _time) / (60 * 60); int min = (((int) _time) / 60 ) % 60; int sec = ( (int) (_time)) % 60; int hun = ( (int) (_time * 100.0)) % 100; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9ca393a946b..279c8e6bc61 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6862,7 +6862,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree) /* Convert degrees to radians. */ NodeDefocus *nqd = node->storage; /* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */ - nqd->rotation = DEG2RADF(nqd->rotation*255.0f); + nqd->rotation = DEG2RADF(nqd->rotation * 255.0f); } else if (node->type == CMP_NODE_CHROMA_MATTE) { /* Convert degrees to radians. */ @@ -6874,7 +6874,7 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree) /* Convert degrees to radians. */ NodeGlare *ndg = node->storage; /* XXX DNA char to float conversion seems to map the char value into the [0.0f, 1.0f] range... */ - ndg->angle_ofs = DEG2RADF(ndg->angle_ofs*255.0f); + ndg->angle_ofs = DEG2RADF(ndg->angle_ofs * 255.0f); } /* XXX TexMapping struct is used by other nodes too (at least node_composite_mapValue), * but not the rot part... diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 680a02eed30..6f5b0e967e9 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1420,8 +1420,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) int size = mmd->dyngridsize; writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->bindinfluences); - writedata(wd, DATA, sizeof(int)*(mmd->totvert+1), mmd->bindoffsets); - writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert, + writedata(wd, DATA, sizeof(int) * (mmd->totvert + 1), mmd->bindoffsets); + writedata(wd, DATA, sizeof(float) * 3 * mmd->totcagevert, mmd->bindcagecos); writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid); writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences); @@ -1678,7 +1678,7 @@ static void write_mdisps(WriteData *wd, int count, MDisps *mdlist, int external) MDisps *md = &mdlist[i]; if (md->disps) { if (!external) - writedata(wd, DATA, sizeof(float)*3*md->totdisp, md->disps); + writedata(wd, DATA, sizeof(float) * 3 * md->totdisp, md->disps); } if (md->hidden) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index e92cfae07b0..07b8d8e23b2 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6387,7 +6387,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) for (bt = block->buttons.first; bt; bt = bt->next) ymax = max_ff(ymax, bt->rect.ymax); - if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) + if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD; } else { @@ -6397,7 +6397,7 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) for (bt = block->buttons.first; bt; bt = bt->next) ymin = min_ff(ymin, bt->rect.ymin); - if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) + if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 5af60726f14..cea7b12a27d 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1584,14 +1584,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) if (sa->flag & HEADER_NO_PULLDOWN) { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_RIGHT, - xco, yco, U.widget_unit, U.widget_unit*0.9, + xco, yco, U.widget_unit, U.widget_unit * 0.9f, &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); } else { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_DOWN, - xco, yco, U.widget_unit, U.widget_unit*0.9, + xco, yco, U.widget_unit, U.widget_unit * 0.9f, &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); } diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index c30996f03de..dd7412cf3d5 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -391,7 +391,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p double starttime, curtime = time; /* compute brush spacing adapted to brush size */ - spacing = brush->rate; //radius*brush->spacing*0.01f; + spacing = brush->rate; //radius*brush->spacing * 0.01f; /* setup starting time, direction vector and accumulated time */ starttime = painter->accumtime; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c72cb2c4d8c..76f73e1505c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3425,7 +3425,7 @@ static int drawDispListwire(ListBase *dlbase) #if 0 /* (ton) this code crashes for me when resolv is 86 or higher... no clue */ - glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3*nr); + glVertexPointer(3, GL_FLOAT, sizeof(float) * 3 * dl->nr, data + 3 * nr); if (dl->flag & DL_CYCL_V) glDrawArrays(GL_LINE_LOOP, 0, dl->parts); else diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index ba4ffefddca..f969e07384c 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1502,11 +1502,11 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar else { UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_stitchable); + glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable); UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_unstitchable); + glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable); } glPopClientAttrib(); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index bfcd4b1e955..81e469f8c5a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1558,7 +1558,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); /* XXX splash scales with pixelsize, should become widget-units */ - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); From d7e6d021615adcd0bf1d6f4d0c52f75ab34a6584 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 02:20:05 +0000 Subject: [PATCH 053/132] simplify fcm_generator_verify() using MEM_recallocN --- source/blender/blenkernel/intern/fmodifier.c | 53 ++++++-------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 47397a60b20..7b007af86d6 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -141,55 +141,34 @@ static void fcm_generator_verify(FModifier *fcm) switch (data->mode) { case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ { + const int arraysize_new = data->poly_order + 1; /* arraysize needs to be order+1, so resize if not */ - if (data->arraysize != (data->poly_order + 1)) { - float *nc; - - /* make new coefficients array, and copy over as much data as can fit */ - nc = MEM_callocN(sizeof(float) * (data->poly_order + 1), "FMod_Generator_Coefs"); - + if (data->arraysize != arraysize_new) { if (data->coefficients) { - if ((int)data->arraysize > (data->poly_order + 1)) - memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order + 1)); - else - memcpy(nc, data->coefficients, sizeof(float) * data->arraysize); - - /* free the old data */ - MEM_freeN(data->coefficients); + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); } - - /* set the new data */ - data->coefficients = nc; - data->arraysize = data->poly_order + 1; + else { + data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); + } + data->arraysize = arraysize_new; } + break; } - break; - case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ { + const int arraysize_new = data->poly_order * 2; /* arraysize needs to be (2 * order), so resize if not */ - if (data->arraysize != (data->poly_order * 2)) { - float *nc; - - /* make new coefficients array, and copy over as much data as can fit */ - nc = MEM_callocN(sizeof(float) * (data->poly_order * 2), "FMod_Generator_Coefs"); - + if (data->arraysize != arraysize_new) { if (data->coefficients) { - if (data->arraysize > (unsigned int)(data->poly_order * 2)) - memcpy(nc, data->coefficients, sizeof(float) * (data->poly_order * 2)); - else - memcpy(nc, data->coefficients, sizeof(float) * data->arraysize); - - /* free the old data */ - MEM_freeN(data->coefficients); + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); } - - /* set the new data */ - data->coefficients = nc; - data->arraysize = data->poly_order * 2; + else { + data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs"); + } + data->arraysize = arraysize_new; } + break; } - break; } } From 4d1d50ea8bc3e01387d8c052d797bec32c798a77 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Tue, 8 Jan 2013 03:30:31 +0000 Subject: [PATCH 054/132] Fix bevel crash #33801, when first edge of a vertex is wire. --- source/blender/bmesh/tools/bmesh_bevel.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 759246c38e0..a593e40d850 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1499,7 +1499,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) { BMEdge *bme; BevVert *bv; - BMEdge *bme2, *unflagged_bme; + BMEdge *bme2, *unflagged_bme, *first_bme; BMFace *f; BMIter iter, iter2; EdgeHalf *e; @@ -1511,10 +1511,16 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) * Only bevel selected edges that have exactly two incident faces. */ + if (bp->vertex_only) + first_bme = v->e; + else + first_bme = NULL; BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) { BLI_assert(BM_edge_is_manifold(bme)); nsel++; + if (!first_bme) + first_bme = bme; } ntot++; @@ -1543,7 +1549,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) /* add edges to bv->edges in order that keeps adjacent edges sharing * a face, if possible */ i = 0; - bme = v->e; + + bme = first_bme; BM_BEVEL_EDGE_TAG_ENABLE(bme); e = &bv->edges[0]; e->e = bme; @@ -1557,6 +1564,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) continue; if (!unflagged_bme) unflagged_bme = bme2; + if (!bme->l) + continue; BM_ITER_ELEM (f, &iter2, bme2, BM_FACES_OF_EDGE) { if (BM_face_edge_share_loop(f, bme)) { found_shared_face = 1; @@ -1591,7 +1600,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) } /* find wrap-around shared face */ BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) { - if (BM_face_edge_share_loop(f, bv->edges[0].e)) { + if (bv->edges[0].e->l && BM_face_edge_share_loop(f, bv->edges[0].e)) { if (bv->edges[0].fnext == f) continue; /* if two shared faces, want the other one now */ bv->edges[ntot - 1].fnext = f; From 59ef68cd9a2e8ccb5eaaa88e4602a491fcfffe7e Mon Sep 17 00:00:00 2001 From: Alex Fraser Date: Tue, 8 Jan 2013 04:28:44 +0000 Subject: [PATCH 055/132] Fix for [#33788] Particles - Fluid "exploding" behavior Particle mass was being used incorrectly by DDR solver (my fault). --- source/blender/blenkernel/intern/particle_system.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3b897e94241..eabfbf2e251 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2396,6 +2396,7 @@ typedef struct SPHRangeData { ParticleData *pa; float h; + float mass; float massfac; int use_size; } SPHRangeData; @@ -2408,7 +2409,7 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], for (i=0; i < 10 && psys[i]; i++) { pfr->npsys = psys[i]; - pfr->massfac = psys[i]->part->mass; + pfr->massfac = psys[i]->part->mass / pfr->mass; pfr->use_size = psys[i]->part->flag & PART_SIZEMASS; if (tree) { @@ -2491,7 +2492,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa ParticleSpring *spring = NULL; SPHRangeData pfr; SPHNeighbor *pfn; - float mass = sphdata->mass; float *gravity = sphdata->gravity; EdgeHash *springhash = sphdata->eh; @@ -2501,7 +2501,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float visc = fluid->viscosity_omega; float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f); - float inv_mass = 1.0f/mass; + float inv_mass = 1.0f / sphdata->mass; float spring_constant = fluid->spring_k; /* 4.0 seems to be a pretty good value */ @@ -2526,6 +2526,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa pfr.data = data; pfr.h = h; pfr.pa = pa; + pfr.mass = sphdata->mass; sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb); @@ -2644,7 +2645,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) * plot [0:2] q1(x) */ q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); - q *= pfr->massfac; + q *= pfr->npsys->part->mass; if (pfr->use_size) q *= pfr->pa->size; @@ -2792,6 +2793,7 @@ static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData pfr.data = data; pfr.h = interaction_radius * sphdata->hfac; pfr.pa = pa; + pfr.mass = sphdata->mass; sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb); pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); @@ -2851,7 +2853,8 @@ void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2 density[0] = density[1] = 0.0f; pfr.data = density; - pfr.h = interaction_radius*sphdata->hfac; + pfr.h = interaction_radius * sphdata->hfac; + pfr.mass = sphdata->mass; sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb); From 7dfcdbedb4dca91280b94cb967fedf7c63d9827e Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Tue, 8 Jan 2013 06:08:08 +0000 Subject: [PATCH 056/132] OSX: remove a unneccessary condition, QTKit can do 32bit too --- source/blender/quicktime/apple/qtkit_export.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index ca9b5bb89e1..4a8a06134c8 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -61,8 +61,8 @@ #import #include -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) || !__LP64__ -#error 64 bit build & OSX 10.5 minimum are needed for QTKit +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 +#error OSX 10.5 minimum is needed for QTKit #endif #include "quicktime_import.h" From 474b92c76ce813af8d5352426c5551e0af7a0abf Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Tue, 8 Jan 2013 07:36:22 +0000 Subject: [PATCH 057/132] OSX: take back 53611 for now, give trouble with the local variables in config, guess needs some cleanup --- build_files/scons/config/darwin-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 431c366986c..207ddd3579b 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -14,7 +14,7 @@ USE_SDK=True ################### Cocoa & architecture settings ################## ############################################################################# WITH_GHOST_COCOA=True -MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64 +MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64 cmd = 'uname -p' From 1dd8851244a3c88ba315c57549a2c3c46786aad0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 08:39:28 +0000 Subject: [PATCH 058/132] Fix #33804: Blender crash unlinking multilayer exr image in image node --- .../compositor/nodes/COM_ImageNode.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 4293e344c65..864d6f08311 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -28,6 +28,10 @@ #include "BKE_node.h" #include "BLI_utildefines.h" +#include "COM_SetValueOperation.h" +#include "COM_SetVectorOperation.h" +#include "COM_SetColorOperation.h" + ImageNode::ImageNode(bNode *editorNode) : Node(editorNode) { /* pass */ @@ -165,6 +169,46 @@ void ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c graph->addOperation(depthOperation); } } + if (numberOfOutputs > 3) { + /* happens when unlinking image datablock from multilayer node */ + for (int i = 3; i < numberOfOutputs; i++) { + OutputSocket *output = this->getOutputSocket(i); + NodeOperation *operation = NULL; + switch (output->getDataType()) { + case COM_DT_VALUE: + { + SetValueOperation *valueoperation = new SetValueOperation(); + valueoperation->setValue(0.0f); + operation = valueoperation; + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *vectoroperation = new SetVectorOperation(); + vectoroperation->setX(0.0f); + vectoroperation->setY(0.0f); + vectoroperation->setW(0.0f); + operation = vectoroperation; + break; + } + case COM_DT_COLOR: + { + SetColorOperation *coloroperation = new SetColorOperation(); + coloroperation->setChannel1(0.0f); + coloroperation->setChannel2(0.0f); + coloroperation->setChannel3(0.0f); + coloroperation->setChannel4(0.0f); + operation = coloroperation; + break; + } + } + + if (operation) { + output->relinkConnections(operation->getOutputSocket()); + graph->addOperation(operation); + } + } + } } } From 1524b1f11db98faf92441360a9a22a9d6a20babe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 12:10:53 +0000 Subject: [PATCH 059/132] fix own error in recent update to follow active quads [#33783] Unwrap with Follow Active Quad fails --- release/scripts/startup/bl_operators/uvcalc_follow_active.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index d870ef963ea..7b6013f3044 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -49,8 +49,13 @@ def extend(obj, operator, EXTEND_MODE): # our own local walker def walk_face_init(faces, f_act): + # first tag all faces True (so we dont uvmap them) + for f in bm.faces: + f.tag = True + # then tag faces arg False for f in faces: f.tag = False + # tag the active face True since we begin there f_act.tag = True def walk_face(f): From c69f57147882e75900aac77a89f2181bccc6e665 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 13:32:48 +0000 Subject: [PATCH 060/132] Remove unused IMB function which wasn't ported to new color management Also marked some TODOs as actually solved. --- source/blender/imbuf/IMB_imbuf.h | 2 - source/blender/imbuf/intern/divers.c | 47 ------------------- .../makesrna/intern/rna_sequencer_api.c | 1 - 3 files changed, 50 deletions(-) diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 8d60227377b..a19433dbd2f 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -373,8 +373,6 @@ void IMB_rect_from_float(struct ImBuf *ibuf); * Changed part will be stored in buffer. This is expected to be used for texture painting updates */ void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h, int is_data); void IMB_float_from_rect(struct ImBuf *ibuf); -/* note, check that the conversion exists, only some are supported */ -float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc); void IMB_color_to_bw(struct ImBuf *ibuf); void IMB_saturation(struct ImBuf *ibuf, float sat); diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index f0d8b7cac72..84339b51721 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -659,53 +659,6 @@ void IMB_float_from_rect(ImBuf *ibuf) BLI_unlock_thread(LOCK_COLORMANAGE); } -/* use when you need to get a buffer with a certain profile - * if the return */ - -/* OCIO_TODO: used only by Cineon/DPX exporter which is still broken, so can not guarantee - * this function is working properly - */ -float *IMB_float_profile_ensure(ImBuf *ibuf, int profile, int *alloc) -{ - int profile_from = IB_PROFILE_LINEAR_RGB; - int profile_to; - - /* determine profile */ - if (profile == IB_PROFILE_NONE) - profile_to = IB_PROFILE_LINEAR_RGB; - else - profile_to = IB_PROFILE_SRGB; - - if (profile_from == profile_to) { - /* simple case, just allocate the buffer and return */ - *alloc = 0; - - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - - return ibuf->rect_float; - } - else { - /* conversion is needed, first check */ - float *fbuf = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure"); - *alloc = 1; - - if (ibuf->rect_float == NULL) { - IMB_buffer_float_from_byte(fbuf, (uchar *)ibuf->rect, - profile_to, profile_from, FALSE, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - IMB_premultiply_rect_float(ibuf->rect_float, ibuf->planes, ibuf->x, ibuf->y); - } - else { - IMB_buffer_float_from_float(fbuf, ibuf->rect_float, - 4, profile_to, profile_from, TRUE, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - } - - return fbuf; - } -} - /**************************** Color to Grayscale *****************************/ /* no profile conversion */ diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 9df8662263c..386263c784e 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -200,7 +200,6 @@ static Sequence *rna_Sequences_new_movie(ID *id, Editing *ed, ReportList *report Scene *scene = (Scene *)id; Sequence *seq; - /* OCIO_TODO: support configurable color spaces for strips */ struct anim *an = openanim(file, IB_rect, 0, NULL); if (an == NULL) { From 4ed46b4043e5a84cf02a0a18ba1f8acb462e2762 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 13:58:01 +0000 Subject: [PATCH 061/132] Make "Clone" option in project paint options more clear name --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 0e1f5d8dff2..3c56ff82a77 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1120,11 +1120,11 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text) row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA') - row = layout.row() - row.active = (settings.brush.image_tool == 'CLONE') - row.prop(ipaint, "use_clone_layer", text="Clone") + col = layout.column() + col.active = (settings.brush.image_tool == 'CLONE') + col.prop(ipaint, "use_clone_layer", text="Clone from UV map") clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else "" - row.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text) + col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text) layout.prop(ipaint, "seam_bleed") From 5042a0a8ef8bb4a3247b924bd1f34710d0a9fa0f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 14:04:01 +0000 Subject: [PATCH 062/132] use guarded malloc for blf texture --- source/blender/blenfont/intern/blf_glyph.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 9c7623f3757..12c0088e93e 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -83,7 +83,7 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table)); memset(gc->bucket, 0, sizeof(gc->bucket)); - gc->textures = (GLuint *)malloc(sizeof(GLuint) * 256); + gc->textures = (GLuint *)MEM_mallocN(sizeof(GLuint) * 256, __func__); gc->ntex = 256; gc->cur_tex = -1; gc->x_offs = 0; @@ -150,7 +150,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc) if (gc->cur_tex + 1 > 0) glDeleteTextures(gc->cur_tex + 1, gc->textures); - free((void *)gc->textures); + MEM_freeN((void *)gc->textures); MEM_freeN(gc); } @@ -178,8 +178,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) gc->p2_height = font->max_tex_size; tot_mem = gc->p2_width * gc->p2_height; - buf = (unsigned char *)malloc(tot_mem); - memset((void *)buf, 0, tot_mem); + buf = (unsigned char *)MEM_callocN(tot_mem, __func__); glGenTextures(1, &gc->textures[gc->cur_tex]); glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state = gc->textures[gc->cur_tex])); @@ -189,7 +188,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gc->p2_width, gc->p2_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buf); - free((void *)buf); + MEM_freeN((void *)buf); } GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c) From e62bc29a9b5a4bb69547bb565e9793fca6df5b76 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 14:25:17 +0000 Subject: [PATCH 063/132] fix [#33792] Accessing a bmesh object created by from_object crashes blender Issue was customdata wasnt being initialized for layers in the destination BMesh but not in the source data. --- source/blender/blenkernel/BKE_customdata.h | 3 +- source/blender/blenkernel/intern/customdata.c | 43 ++++++++++++++----- .../blenkernel/intern/modifiers_bmesh.c | 8 ++-- source/blender/bmesh/intern/bmesh_mesh_conv.c | 8 ++-- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 4736e7b7312..70532384643 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -39,6 +39,7 @@ extern "C" { #endif #include "../blenloader/BLO_sys_types.h" /* XXX, should have a more generic include for this */ +#include "BLI_utildefines.h" struct BMesh; struct ID; @@ -304,7 +305,7 @@ void CustomData_bmesh_free_block(struct CustomData *data, void **block); /* copy custom data to/from layers as in mesh/derivedmesh, to editmesh * blocks of data. the CustomData's must not be compatible */ void CustomData_to_bmesh_block(const struct CustomData *source, - struct CustomData *dest, int src_index, void **dest_block); + struct CustomData *dest, int src_index, void **dest_block, bool use_default_init); void CustomData_from_bmesh_block(const struct CustomData *source, struct CustomData *dest, void *src_block, int dest_index); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 832c1979a51..19624e8a2b9 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2660,27 +2660,40 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w if (count > SOURCE_BUF_SIZE) MEM_freeN(sources); } -void CustomData_bmesh_set_default(CustomData *data, void **block) +static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n) { const LayerTypeInfo *typeInfo; + int offset = data->layers[n].offset; + + typeInfo = layerType_getInfo(data->layers[n].type); + + if (typeInfo->set_default) { + typeInfo->set_default((char *)*block + offset, 1); + } + else { + memset((char *)*block + offset, 0, typeInfo->size); + } +} + +void CustomData_bmesh_set_default(CustomData *data, void **block) +{ int i; if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { - int offset = data->layers[i].offset; - - typeInfo = layerType_getInfo(data->layers[i].type); - - if (typeInfo->set_default) - typeInfo->set_default((char *)*block + offset, 1); - else memset((char *)*block + offset, 0, typeInfo->size); + CustomData_bmesh_set_default_n(data, block, i); } } +/** + * \param use_default_init initializes data which can't be copied, + * typically you'll want to use this if the BM_xxx create function + * is called with BM_CREATE_SKIP_CD flag + */ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, - int src_index, void **dest_block) + int src_index, void **dest_block, bool use_default_init) { const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; @@ -2696,11 +2709,14 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, * (this should work because layers are ordered by type) */ while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { + if (use_default_init) { + CustomData_bmesh_set_default_n(dest, dest_block, dest_i); + } dest_i++; } /* if there are no more dest layers, we're done */ - if (dest_i >= dest->totlayer) return; + if (dest_i >= dest->totlayer) break; /* if we found a matching layer, copy the data */ if (dest->layers[dest_i].type == source->layers[src_i].type) { @@ -2723,6 +2739,13 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, dest_i++; } } + + if (use_default_init) { + while (dest_i < dest->totlayer) { + CustomData_bmesh_set_default_n(dest, dest_block, dest_i); + dest_i++; + } + } } void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest, diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 9b5cf443bcf..3939c45a436 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -96,7 +96,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) v->head.hflag = BM_vert_flag_from_mflag(mv->flag); BM_elem_index_set(v, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true); vtable[i] = v; /* add bevel weight */ @@ -118,7 +118,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) e->head.hflag = BM_edge_flag_from_mflag(me->flag); BM_elem_index_set(e, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true); etable[i] = e; /* add crease */ @@ -168,10 +168,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) { - CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data); + CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true); } - CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true); if (face_normals) { copy_v3_v3(f->no, face_normals[i]); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 388d148377a..53b29a4ce74 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -221,7 +221,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) normal_short_to_float_v3(v->no, mvert->no); /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); @@ -267,7 +267,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) } /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f); BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f); @@ -338,11 +338,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) j = 0; BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) { /* Save index of correspsonding MLoop */ - CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data); + CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true); } /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true); } bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */ From 472595f1d3533f143bdc84700b26f20a7b2ba1c1 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 8 Jan 2013 14:40:15 +0000 Subject: [PATCH 064/132] Bugfix #33803 (2.65a and older) Case: ALT+CTRL+U (user prefs) made mousewheel change button values in inactive window. On opening 2nd window, or de-activating a window, the modifier state was kept for that window. That meant that mouse-over in a window was using the old modifier - for example for scrollwheel it would change values in buttons. --- source/blender/windowmanager/intern/wm_window.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index ec94501c8be..9e0f8613a1a 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -701,6 +701,14 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr case GHOST_kEventWindowDeactivate: wm_event_add_ghostevent(wm, win, type, time, data); win->active = 0; /* XXX */ + + /* clear modifiers for inactive windows */ + win->eventstate->alt = 0; + win->eventstate->ctrl = 0; + win->eventstate->shift = 0; + win->eventstate->oskey = 0; + win->eventstate->keymodifier = 0; + break; case GHOST_kEventWindowActivate: { From 0c1d1e6c30e8f11834d401b46bdc2018a4e942d9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 15:34:33 +0000 Subject: [PATCH 065/132] Alpha-over images on a black background when in RGB display mode This is actually a bit arbitrary decision and mainly it preserves compatibility with how images were displaying in previous releases. In fact, we actually would need to think about configurable backdrop color and blending mode to be used for display in RGB mode. --- source/blender/editors/space_image/image_draw.c | 13 ++++++++----- source/blender/editors/space_node/drawnode.c | 10 +++++++++- .../editors/space_sequencer/sequencer_draw.c | 5 +++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 0534b9f4ffd..7b4814d1ab2 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -514,11 +514,15 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, unsigned char *display_buffer; void *cache_handle; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (sima->flag & SI_USE_ALPHA) { fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glRecti(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); } display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); @@ -532,8 +536,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, IMB_display_buffer_release(cache_handle); - if (sima->flag & SI_USE_ALPHA) - glDisable(GL_BLEND); + glDisable(GL_BLEND); } /* reset zoom */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index ef69358c24f..981a1775b51 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3271,10 +3271,18 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) } else { glPixelZoom(snode->zoom, snode->zoom); - + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glRecti(x, y, x + ibuf->x * snode->zoom, y + ibuf->y * snode->zoom); + glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); glPixelZoom(1.0f, 1.0f); + + glDisable(GL_BLEND); } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 9e55d95637d..9477b3197fa 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1058,6 +1058,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_QUADS); if (draw_overlay) { @@ -1089,6 +1093,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glEnd(); glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); glDeleteTextures(1, &texid); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { From b0c084c6cca1dd9703f580427d838ee9e6d9f849 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 16:39:36 +0000 Subject: [PATCH 066/132] fix [#33797] decimate modifier bug on uv-coordinates when mesh uses vertex color if vertex colors had no seams - it would interpolate the UV's too, now interpolate per-layer. --- source/blender/blenkernel/BKE_customdata.h | 2 ++ source/blender/blenkernel/intern/customdata.c | 17 +++++++++--- .../bmesh/tools/bmesh_decimate_collapse.c | 26 +++++++++++++------ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 70532384643..3a65c8d3b72 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -216,6 +216,8 @@ void CustomData_free_elem(struct CustomData *data, int index, int count); void CustomData_interp(const struct CustomData *source, struct CustomData *dest, int *src_indices, float *weights, float *sub_weights, int count, int dest_index); +void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights, + const float *sub_weights, int count, void *dest_block, int n); void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks, const float *weights, const float *sub_weights, int count, void *dest_block); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 19624e8a2b9..4c6b0c08158 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2629,6 +2629,19 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so memcpy(dest, source, typeInfo->size); } +/** + * \param src_blocks must be pointers to the data, offset by layer->offset already. + */ +void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights, + const float *sub_weights, int count, void *dest_block, int n) +{ + CustomDataLayer *layer = &data->layers[n]; + const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type); + + typeInfo->interp(src_blocks, weights, sub_weights, count, + (char *)dest_block + layer->offset); +} + void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights, const float *sub_weights, int count, void *dest_block) { @@ -2651,9 +2664,7 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w for (j = 0; j < count; ++j) { sources[j] = (char *)src_blocks[j] + layer->offset; } - - typeInfo->interp(sources, weights, sub_weights, count, - (char *)dest_block + layer->offset); + CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i); } } diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index 9d2d2b75d6e..794afb3e0d2 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -441,6 +441,8 @@ static void bm_decim_triangulate_end(BMesh *bm) static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_clear, BMVert *v_other, const float customdata_fac) { + /* disable seam check - the seam check would have to be done per layer, its not really that important */ +//#define USE_SEAM /* these don't need to be updated, since they will get removed when the edge collapses */ BMLoop *l_clear, *l_other; const int is_manifold = BM_edge_is_manifold(l->e); @@ -464,7 +466,9 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle /* now we have both corners of the face 'l->f' */ for (side = 0; side < 2; side++) { +#ifdef USE_SEAM int is_seam = FALSE; +#endif void *src[2]; BMFace *f_exit = is_manifold ? l->radial_next->f : NULL; BMEdge *e_prev = l->e; @@ -501,34 +505,40 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle break; } +#ifdef USE_SEAM /* break out unless we find a match */ is_seam = TRUE; +#endif /* ok. we have a loop. now be smart with it! */ for (i = 0; i < bm->ldata.totlayer; i++) { if (CustomData_layer_has_math(&bm->ldata, i)) { const int offset = bm->ldata.layers[i].offset; const int type = bm->ldata.layers[i].type; - void *cd_src, *cd_iter; - - /* todo, make nicer macros for this */ - cd_src = (char *)src[0] + offset; - // cd_dst = (char *)src[1] + offset; // UNUSED - cd_iter = (char *)l_iter->head.data + offset; + void *cd_src[2] = {(char *)src[0] + offset, + (char *)src[1] + offset}; + void *cd_iter = (char *)l_iter->head.data + offset;; /* detect seams */ - if (CustomData_data_equals(type, cd_src, cd_iter)) { - CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_iter->head.data); + if (CustomData_data_equals(type, cd_src[0], cd_iter)) { + CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i); +#ifdef USE_SEAM is_seam = FALSE; +#endif } } } +#ifdef USE_SEAM if (is_seam) { break; } +#endif } } + +//#undef USE_SEAM + } #endif /* USE_CUSTOMDATA */ From 4737e08cb9a59c1a598bc42e1eb2b2f20852b14c Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 8 Jan 2013 16:54:26 +0000 Subject: [PATCH 067/132] Added trackpad (and magic mouse) support to control speed in Fly Mode in 3d. --- .../blender/editors/space_view3d/view3d_fly.c | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index a749a815546..c2e75a1c5d9 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -76,7 +76,8 @@ enum { FLY_MODAL_PRECISION_ENABLE, FLY_MODAL_PRECISION_DISABLE, FLY_MODAL_FREELOOK_ENABLE, - FLY_MODAL_FREELOOK_DISABLE + FLY_MODAL_FREELOOK_DISABLE, + FLY_MODAL_SPEED, /* mousepan typically */ }; @@ -132,6 +133,8 @@ void fly_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_ACCELERATE); WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, FLY_MODAL_SPEED); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, FLY_MODAL_PAN_ENABLE); /* XXX - Bug in the event system, middle mouse release doesnt work */ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, FLY_MODAL_PAN_DISABLE); @@ -544,7 +547,22 @@ static void flyEvent(FlyInfo *fly, wmEvent *event) case FLY_MODAL_CONFIRM: fly->state = FLY_CONFIRM; break; - + + /* speed adjusting with mousepan (trackpad) */ + case FLY_MODAL_SPEED: + { + float fac = 0.02f * (event->prevy - event->y); + + /* allowing to brake immediate */ + if (fac > 0.0f && fly->speed < 0.0f) + fly->speed = 0.0f; + else if (fac < 0.0f && fly->speed > 0.0f) + fly->speed = 0.0f; + else + fly->speed += fly->grid * fac; + + break; + } case FLY_MODAL_ACCELERATE: { double time_currwheel; From fd35b0aa669155bfa503997f82151d822fff574b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 16:56:04 +0000 Subject: [PATCH 068/132] Fix for recent tile_order feature not working properly with persistent data --- intern/cycles/blender/blender_session.cpp | 2 ++ intern/cycles/render/tile.h | 1 + 2 files changed, 3 insertions(+) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 770b71afcdc..d0c7c06cbb3 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -139,6 +139,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_) session->progress.reset(); scene->reset(); + session->tile_manager.set_tile_order(session_params.tile_order); + /* peak memory usage should show current render peak, not peak for all renders * made by this render session */ diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 7d3df6c1524..99cffb49c08 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -68,6 +68,7 @@ public: bool next_tile(Tile& tile, int device = 0); bool done(); + void set_tile_order(int tile_order_) { tile_order = tile_order_; } protected: /* Note: this should match enum_tile_order in properties.py */ enum { From 74d85d28827207901aeec37ca6c93939e938c462 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 8 Jan 2013 17:27:11 +0000 Subject: [PATCH 069/132] Macbook HiDPI support: reshuffled code to make it compile for 10.6 and work in 10.7 and later. OS X Gurus might check though :) --- intern/ghost/intern/GHOST_WindowCocoa.mm | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 2d58f0612ce..40b9dcaf94e 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -428,6 +428,13 @@ extern "C" { #pragma mark initialization / finalization +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 +@interface NSView (NSOpenGLSurfaceResolution) +- (BOOL)wantsBestResolutionOpenGLSurface; +- (void)setWantsBestResolutionOpenGLSurface; +@end +#endif + NSOpenGLContext* GHOST_WindowCocoa::s_firstOpenGLcontext = nil; GHOST_WindowCocoa::GHOST_WindowCocoa( @@ -579,13 +586,15 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setDrawingContextType(type); updateDrawingContext(); activateDrawingContext(); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // retina support started with 10.7.4 afaik + if (m_systemCocoa->m_nativePixel) { - [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; - NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; - m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; + if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { + [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; + + NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; + m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; + } } -#endif m_tablet.Active = GHOST_kTabletModeNone; From 36f79eab204f5d3f031f3d3bb5a514cdae1fba69 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 17:30:06 +0000 Subject: [PATCH 070/132] fix [#33784] Select Linked All + Seams fails to select seam bounded area was incorrectly flushing vertex selection. --- source/blender/bmesh/intern/bmesh_walkers_impl.c | 5 +++++ source/blender/editors/mesh/editmesh_select.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index bb013e6428e..538a9058ed5 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -403,6 +403,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker) continue; } + /* saves checking BLI_ghash_haskey below (manifold edges theres a 50% chance) */ + if (f == iwalk->cur) { + continue; + } + if (BLI_ghash_haskey(walker->visithash, f)) { continue; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 44e38efdc67..0735b95588e 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2250,7 +2250,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent * BMW_FLAG_TEST_HIDDEN, BMW_NIL_LAY); - e = BMW_begin(&walker, efa); + efa = BMW_begin(&walker, efa); for (; efa; efa = BMW_step(&walker)) { BM_face_select_set(bm, efa, sel); } @@ -2344,7 +2344,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - e = BMW_begin(&walker, efa); + efa = BMW_begin(&walker, efa); for (; efa; efa = BMW_step(&walker)) { BM_face_select_set(bm, efa, TRUE); } @@ -2381,8 +2381,9 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op) } } BMW_end(&walker); + + EDBM_selectmode_flush(em); } - EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); From 67a6d4dd56f13cd548f1004491dab1b614393ec4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 17:40:36 +0000 Subject: [PATCH 071/132] fix for select flushing in face mode for mesh 'Select More' --- source/blender/editors/mesh/editmesh_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index e8132f5b82b..b95c8a05353 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -550,7 +550,7 @@ void EDBM_select_more(BMEditMesh *em) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE); BMO_op_finish(em->bm, &bmop); - EDBM_select_flush(em); + EDBM_selectmode_flush(em); } void EDBM_select_less(BMEditMesh *em) From 25cc959a9ceaa8f4cb2f9508efdb3621c4516246 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Jan 2013 17:53:38 +0000 Subject: [PATCH 072/132] fix [#33646] Deleting edge loops creates holes in uv map --- release/scripts/startup/bl_operators/wm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index c24e0920213..00cc763c4e1 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -44,7 +44,7 @@ class MESH_OT_delete_edgeloop(Operator): mesh = context.object.data use_mirror_x = mesh.use_mirror_x mesh.use_mirror_x = False - if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0): + if 'FINISHED' in bpy.ops.transform.edge_slide(value=1.0, correct_uv=True): bpy.ops.mesh.select_more() bpy.ops.mesh.remove_doubles() ret = {'FINISHED'} From bb0319022d822c7fb12296e48888fc1f25b56f53 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 20:50:26 +0000 Subject: [PATCH 073/132] Fix #33809: Wrong exposure affect after alpha premul changes Exposure shouldn't affect on alpha channel, only RGB shall be affected by exposure. Was a regression since recent alpha premul pipeline changes. --- source/blender/imbuf/intern/colormanagement.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index bcfddfe425a..d823e7c4882 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -698,7 +698,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie if (exposure != 0.0f) { OCIO_MatrixTransformRcPtr *mt; float gain = powf(2.0f, exposure); - const float scale4f[] = {gain, gain, gain, gain}; + const float scale4f[] = {gain, gain, gain, 1.0f}; float m44[16], offset4[4]; OCIO_matrixTransformScale(m44, offset4, scale4f); From f5317b5f0c553801362a371ad18739d1ff2820cc Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 8 Jan 2013 20:55:07 +0000 Subject: [PATCH 074/132] Style cleanup in OCIO area Also fixed typo in function name. --- intern/opencolorio/fallback_impl.cc | 2 +- intern/opencolorio/ocio_capi.cc | 4 ++-- intern/opencolorio/ocio_capi.h | 4 ++-- intern/opencolorio/ocio_impl.cc | 2 +- source/blender/imbuf/intern/colormanagement.c | 18 +++++++++--------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index 44c02d1442b..d01d8d4c8f4 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -331,7 +331,7 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *) } OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription"); diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 18fa4b7cb1b..4f839a61fad 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -238,12 +238,12 @@ void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) } OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { return impl->createOCIO_PackedImageDesc(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); } -void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) +void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id) { impl->OCIO_PackedImageDescRelease(id); } diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 0ce5f8a1456..19fd8fe643b 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -105,9 +105,9 @@ void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_Const void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt); OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes); + long chanStrideBytes, long xStrideBytes, long yStrideBytes); -void OCIO_OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); +void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p); OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void); void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent); diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index 2d73d2ff56b..b073a038f0d 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -479,7 +479,7 @@ void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) } OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels, - long chanStrideBytes, long xStrideBytes, long yStrideBytes) + long chanStrideBytes, long xStrideBytes, long yStrideBytes) { try { void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index d823e7c4882..2c6e46cb664 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -351,9 +351,9 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV if (cache_data->exposure != view_settings->exposure || cache_data->gamma != view_settings->gamma || - cache_data->flag != view_settings->flag || - cache_data->curve_mapping != curve_mapping || - cache_data->curve_mapping_timestamp != curve_mapping_timestamp) + cache_data->flag != view_settings->flag || + cache_data->curve_mapping != curve_mapping || + cache_data->curve_mapping_timestamp != curve_mapping_timestamp) { *cache_handle = NULL; @@ -681,7 +681,7 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin } static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display, - float exposure, float gamma) + float exposure, float gamma) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); OCIO_DisplayTransformRcPtr *dt; @@ -731,7 +731,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie } static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, - const char *to_colorspace) + const char *to_colorspace) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); OCIO_ConstProcessorRcPtr *processor; @@ -1591,14 +1591,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, int width, in OCIO_PackedImageDesc *img; img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), - channels * sizeof(float), channels * sizeof(float) * width); + channels * sizeof(float), channels * sizeof(float) * width); if (predivide) OCIO_processorApply_predivide(processor, img); else OCIO_processorApply(processor, img); - OCIO_OCIO_PackedImageDescRelease(img); + OCIO_PackedImageDescRelease(img); } } @@ -2538,14 +2538,14 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, flo /* apply OCIO processor */ img = OCIO_createOCIO_PackedImageDesc(buffer, width, height, channels, sizeof(float), - channels * sizeof(float), channels * sizeof(float) * width); + channels * sizeof(float), channels * sizeof(float) * width); if (predivide) OCIO_processorApply_predivide(cm_processor->processor, img); else OCIO_processorApply(cm_processor->processor, img); - OCIO_OCIO_PackedImageDescRelease(img); + OCIO_PackedImageDescRelease(img); } } From 73ead0b207ec5b34ada98230487e9b35852fb7d0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 03:26:39 +0000 Subject: [PATCH 075/132] drawing texture icon was multiplying the red channel by alpha, this is almost certainly a typo/accident. --- source/blender/editors/interface/interface_icons.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index ebc80d61af3..68780083b97 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -950,8 +950,8 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy { float x1, x2, y1, y2; - if (rgb) glColor4f(alpha*rgb[0], rgb[1], rgb[2], alpha); - else glColor4f(alpha, alpha, alpha, alpha); + if (rgb) glColor4f(rgb[0], rgb[1], rgb[2], alpha); + else glColor4f(alpha, alpha, alpha, alpha); x1 = ix * icongltex.invw; x2 = (ix + ih) * icongltex.invw; From e24443b79a23e3d274124f0f666f2632a7073267 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 03:30:15 +0000 Subject: [PATCH 076/132] style cleanup --- source/blender/blenkernel/intern/pointcache.c | 4 +-- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/bmesh/intern/bmesh_log.c | 4 +-- source/blender/compositor/intern/COM_Node.h | 6 ++-- .../compositor/nodes/COM_PixelateNode.cpp | 4 +-- source/blender/editors/interface/view2d.c | 2 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- source/blender/editors/transform/transform.c | 2 +- .../editors/transform/transform_conversions.c | 30 ++++++++----------- .../editors/uvedit/uvedit_smart_stitch.c | 6 ++-- source/blender/imbuf/intern/dds/ColorBlock.h | 2 +- .../imbuf/intern/dds/DirectDrawSurface.h | 2 +- source/blender/makesrna/intern/rna_color.c | 2 +- .../makesrna/intern/rna_internal_types.h | 4 +-- .../blender/python/bmesh/bmesh_py_ops_call.c | 2 +- .../python/generic/bpy_internal_import.h | 6 ++-- source/blender/quicktime/quicktime_export.h | 4 +-- source/blender/windowmanager/WM_api.h | 6 ++-- 18 files changed, 42 insertions(+), 48 deletions(-) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index c94ffd3205f..97948683e22 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -272,7 +272,7 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf ParticleSystem *psys= psys_v; ParticleData *pa; BoidParticle *boid; - float timestep = 0.04f*psys->part->timetweak; + float timestep = 0.04f * psys->part->timetweak; if (index >= psys->totpart) return; @@ -333,7 +333,7 @@ static void ptcache_particle_interpolate(int index, void *psys_v, void **data, f ParticleSystem *psys= psys_v; ParticleData *pa; ParticleKey keys[4]; - float dfra, timestep = 0.04f*psys->part->timetweak; + float dfra, timestep = 0.04f * psys->part->timetweak; if (index >= psys->totpart) return; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 279c8e6bc61..34c08a917b3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3340,7 +3340,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) tex->env = newdataadr(fd, tex->env); if (tex->env) { tex->env->ima = NULL; - memset(tex->env->cube, 0, 6*sizeof(void *)); + memset(tex->env->cube, 0, 6 * sizeof(void *)); tex->env->ok= 0; } tex->pd = newdataadr(fd, tex->pd); diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index b821c9875db..a2510129df6 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -523,14 +523,14 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) i = 0; varr = MEM_mallocN(sizeof(int) * bm->totvert, AT); BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) { - ((unsigned int*)varr)[i++] = bm_log_vert_id_get(log, v); + ((unsigned int *)varr)[i++] = bm_log_vert_id_get(log, v); } /* Put all face IDs into an array */ i = 0; farr = MEM_mallocN(sizeof(int) * bm->totface, AT); BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) { - ((unsigned int*)farr)[i++] = bm_log_face_id_get(log, f); + ((unsigned int *)farr)[i++] = bm_log_face_id_get(log, f); } /* Create BMVert index remap array */ diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index c098d6da32b..5b0381f6443 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -58,7 +58,7 @@ private: * @brief The group node this node belongs to. * @note: used to find the links in the current subtree for muting nodes */ - bNode* m_bNodeGroup; + bNode *m_bNodeGroup; public: Node(bNode *editorNode, bool create_sockets = true); @@ -145,8 +145,8 @@ public: */ OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket); - inline void setbNodeGroup(bNode* group) {this->m_bNodeGroup = group;} - inline bNode* getbNodeGroup() {return this->m_bNodeGroup;} + inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;} + inline bNode *getbNodeGroup() {return this->m_bNodeGroup;} protected: void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket); void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket); diff --git a/source/blender/compositor/nodes/COM_PixelateNode.cpp b/source/blender/compositor/nodes/COM_PixelateNode.cpp index f1c7c616a30..b751c9a6e9f 100644 --- a/source/blender/compositor/nodes/COM_PixelateNode.cpp +++ b/source/blender/compositor/nodes/COM_PixelateNode.cpp @@ -36,8 +36,8 @@ void PixelateNode::convertToOperations(ExecutionSystem *graph, CompositorContext OutputSocket *outputSocket = this->getOutputSocket(0); DataType datatype = inputSocket->getDataType(); if (inputSocket->isConnected()) { - SocketConnection * connection = inputSocket->getConnection(); - OutputSocket* otherOutputSocket = connection->getFromSocket(); + SocketConnection *connection = inputSocket->getConnection(); + OutputSocket *otherOutputSocket = connection->getFromSocket(); datatype = otherOutputSocket->getDataType(); } diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index d0d631e14a5..41bbed8eb19 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1694,7 +1694,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* draw numbers in the appropriate range */ if (dfac > 0.0f) { - float h = 0.1f*UI_UNIT_Y + (float)(hor.ymin); + float h = 0.1f * UI_UNIT_Y + (float)(hor.ymin); for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 590bcd5939e..5e1d954a2ea 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1320,7 +1320,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd) { BMIter iter; BMVert *v; - BMesh* bm = kcd->em->bm; + BMesh *bm = kcd->em->bm; float max_xyz = 0.0f; int i; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 78a8bd47668..5b5e5206e9c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -5265,7 +5265,7 @@ static int createSlideVerts(TransInfo *t) if (dot_v3v3(loop_dir[l_nr], dir) < 0.0f) { swap_v3_v3(sv_array->upvec, sv_array->downvec); SWAP(BMVert, sv_array->vup, sv_array->vdown); - SWAP(BMVert*, sv_array->up, sv_array->down); + SWAP(BMVert *, sv_array->up, sv_array->down); } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 12b0341d395..63eea8b8d4c 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -127,30 +127,24 @@ static short constraints_list_needinv(TransInfo *t, ListBase *list); /* ************************** Functions *************************** */ -static int trans_data_compare_dist(const void *A, const void *B) +static int trans_data_compare_dist(const void *a, const void *b) { - const TransData *td_A = (const TransData*)A; - const TransData *td_B = (const TransData*)B; + const TransData *td_a = (const TransData *)a; + const TransData *td_b = (const TransData *)b; - if (td_A->dist < td_B->dist) - return -1; - else if (td_A->dist > td_B->dist) - return 1; - - return 0; + if (td_a->dist < td_b->dist) return -1; + else if (td_a->dist > td_b->dist) return 1; + else return 0; } -static int trans_data_compare_rdist(const void *A, const void *B) +static int trans_data_compare_rdist(const void *a, const void *b) { - const TransData *td_A = (const TransData*)A; - const TransData *td_B = (const TransData*)B; + const TransData *td_a = (const TransData *)a; + const TransData *td_b = (const TransData *)b; - if (td_A->rdist < td_B->rdist) - return -1; - else if (td_A->rdist > td_B->rdist) - return 1; - - return 0; + if (td_a->rdist < td_b->rdist) return -1; + else if (td_a->rdist > td_b->rdist) return 1; + else return 0; } void sort_trans_data_dist(TransInfo *t) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index f969e07384c..b1bb5c85e50 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -799,7 +799,7 @@ static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, } -static void stitch_propagate_uv_final_position (UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene* scene) +static void stitch_propagate_uv_final_position(UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene *scene) { StitchPreviewer *preview = state->stitch_preview; @@ -1392,7 +1392,7 @@ static void stitch_switch_selection_mode(StitchState *state) if (state->mode == STITCH_VERT) { int i; - state->selection_stack = MEM_mallocN(state->total_separate_edges*sizeof(*state->selection_stack), + state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack), "stitch_new_edge_selection_stack"); /* check if both elements of an edge are selected */ @@ -1415,7 +1415,7 @@ static void stitch_switch_selection_mode(StitchState *state) } else { int i; - state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack), + state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack), "stitch_new_vert_selection_stack"); for (i = 0; i < old_selection_size; i++) { diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index f0864f06e6f..730a19d84fd 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -69,7 +69,7 @@ struct ColorBlock private: - Color32 m_color[4*4]; + Color32 m_color[4 * 4]; }; diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 72a524daba2..11e6d4a5708 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -172,7 +172,7 @@ public: void setUserVersion(int version); void mipmap(Image * img, uint f, uint m); - void* readData(uint &size); + void *readData(uint &size); // void mipmap(FloatImage * img, uint f, uint m); void printInfo() const; diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 21bd55e0137..9ce3b313c37 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -424,7 +424,7 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int } } -static EnumPropertyItem* rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) +static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) { Scene *scene = CTX_data_scene(C); EnumPropertyItem *items = NULL; diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index b16f0d69fba..43ec09de010 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -66,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr); typedef int (*EditableFunc)(struct PointerRNA *ptr); typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index); -typedef struct IDProperty* (*IDPropertiesFunc)(struct PointerRNA *ptr, int create); +typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create); typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr); typedef char *(*StructPathFunc)(struct PointerRNA *ptr); @@ -93,7 +93,7 @@ typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value); typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int *free); typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr); -typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr); +typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr); typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value); typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value); typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr); diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index ded35363287..32315195072 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -523,7 +523,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec * * \note Don't throw any exceptions and should always return a valid (PyObject *). */ -static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) +static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) { PyObject *item = NULL; diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 1592ec52b4c..56cdf677ccb 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -48,9 +48,9 @@ struct Text; void bpy_import_init(PyObject *builtins); -PyObject* bpy_text_import(struct Text *text); -PyObject* bpy_text_import_name(const char *name, int *found); -PyObject* bpy_text_reimport(PyObject *module, int *found); +PyObject *bpy_text_import(struct Text *text); +PyObject *bpy_text_import_name(const char *name, int *found); +PyObject *bpy_text_reimport(PyObject *module, int *found); /* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */ void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text); diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index d773cdc8f3a..55323c05278 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -65,14 +65,14 @@ void filepath_qt(char *string, struct RenderData *rd); void quicktime_verify_image_type(struct RenderData *rd, struct ImageFormatData *imf); //used by RNA for defaults values init, if needed /*Video codec type*/ int quicktime_get_num_videocodecs(void); -QuicktimeCodecTypeDesc* quicktime_get_videocodecType_desc(int indexValue); +QuicktimeCodecTypeDesc *quicktime_get_videocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_videocodectype(int codecType); int quicktime_videocodecType_from_rnatmpvalue(int rnatmpvalue); #ifdef USE_QTKIT /*Audio codec type*/ int quicktime_get_num_audiocodecs(void); -QuicktimeCodecTypeDesc* quicktime_get_audiocodecType_desc(int indexValue); +QuicktimeCodecTypeDesc *quicktime_get_audiocodecType_desc(int indexValue); int quicktime_rnatmpvalue_from_audiocodectype(int codecType); int quicktime_audiocodecType_from_rnatmpvalue(int rnatmpvalue); #endif diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index eee4b5a3a57..eb1aad75a88 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -204,9 +204,9 @@ void WM_operator_stack_clear(struct wmWindowManager *wm); struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet); struct GHashIterator *WM_operatortype_iter(void); -void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*)); -void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); -void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata); +void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *)); +void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); +void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata); int WM_operatortype_remove(const char *idname); struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag); From 02f6645bef3ebb3b802d03f6949f44d488e141bc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 04:17:53 +0000 Subject: [PATCH 077/132] fix [#33806] weight paint crash and computer freeze when painting clear weight paint runtime data on file-load. --- source/blender/blenloader/intern/readfile.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 34c08a917b3..43c1179dbba 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5124,6 +5124,16 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->imapaint.paintcursor = NULL; sce->toolsettings->particle.paintcursor = NULL; + + /* in rare cases this is needed, see [#33806] */ + if (sce->toolsettings->vpaint) { + sce->toolsettings->vpaint->vpaint_prev = NULL; + sce->toolsettings->vpaint->tot = 0; + } + if (sce->toolsettings->wpaint) { + sce->toolsettings->wpaint->wpaint_prev = NULL; + sce->toolsettings->wpaint->tot = 0; + } } if (sce->ed) { From cecbb3498b245fbf2226c967001c4ab40b1c7b87 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 05:32:15 +0000 Subject: [PATCH 078/132] add RNA_def_struct_ptr(...) to use for runtime struct registration, saves over 2000 string lookups on startup and gives overall ~10% speedup for starting blender on my system. --- source/blender/makesrna/RNA_define.h | 1 + source/blender/makesrna/intern/rna_ID.c | 2 +- .../blender/makesrna/intern/rna_animation.c | 2 +- source/blender/makesrna/intern/rna_define.c | 43 +++++++++++-------- source/blender/makesrna/intern/rna_render.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 8 ++-- source/blender/makesrna/intern/rna_userdef.c | 2 +- source/blender/makesrna/intern/rna_wm.c | 4 +- .../windowmanager/intern/wm_operators.c | 8 ++-- 9 files changed, 41 insertions(+), 31 deletions(-) diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index a435f9b0206..463e0e04679 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -49,6 +49,7 @@ void RNA_exit(void); /* Struct */ +StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom); StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from); void RNA_def_struct_sdna(StructRNA *srna, const char *structname); void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname); diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 11ce7345e41..184ee23b488 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -248,7 +248,7 @@ StructRNA *rna_PropertyGroup_register(Main *UNUSED(bmain), ReportList *reports, return NULL; } - return RNA_def_struct(&BLENDER_RNA, identifier, "PropertyGroup"); /* XXX */ + return RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_PropertyGroup); /* XXX */ } StructRNA *rna_PropertyGroup_refine(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index cedb741b994..020ad2c147a 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -234,7 +234,7 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); /* set RNA-extensions info */ - ksi->ext.srna = RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo"); + ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo); ksi->ext.data = data; ksi->ext.call = call; ksi->ext.free = free; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 0a8254cb9c1..b94d7eb691f 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -623,13 +623,12 @@ static StructDefRNA *rna_find_def_struct(StructRNA *srna) } /* Struct Definition */ - -StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from) +StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom) { - StructRNA *srna, *srnafrom = NULL; + StructRNA *srna; StructDefRNA *ds = NULL, *dsfrom = NULL; PropertyRNA *prop; - + if (DefRNA.preprocess) { char error[512]; @@ -638,18 +637,6 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * DefRNA.error = 1; } } - - if (from) { - /* find struct to derive from */ - for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) - if (strcmp(srnafrom->identifier, from) == 0) - break; - - if (!srnafrom) { - fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier); - DefRNA.error = 1; - } - } srna = MEM_callocN(sizeof(StructRNA), "StructRNA"); DefRNA.laststruct = srna; @@ -670,7 +657,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * else srna->base = srnafrom; } - + srna->identifier = identifier; srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */ srna->description = ""; @@ -741,6 +728,28 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * return srna; } +StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from) +{ + StructRNA *srnafrom = NULL; + + /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */ + BLI_assert(DefRNA.preprocess); + + if (from) { + /* find struct to derive from */ + for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) + if (strcmp(srnafrom->identifier, from) == 0) + break; + + if (!srnafrom) { + fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier); + DefRNA.error = 1; + } + } + + return RNA_def_struct_ptr(brna, identifier, srnafrom); +} + void RNA_def_struct_sdna(StructRNA *srna, const char *structname) { StructDefRNA *ds; diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 91b25bbc40a..5931440b422 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -196,7 +196,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo et = MEM_callocN(sizeof(RenderEngineType), "python render engine"); memcpy(et, &dummyet, sizeof(dummyet)); - et->ext.srna = RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine"); + et->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, et->idname, &RNA_RenderEngine); et->ext.data = data; et->ext.call = call; et->ext.free = free; diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 0d8acb207a8..137ffecac9a 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -225,7 +225,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat pt = MEM_callocN(sizeof(PanelType), "python buttons panel"); memcpy(pt, &dummypt, sizeof(dummypt)); - pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); + pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel); pt->ext.data = data; pt->ext.call = call; pt->ext.free = free; @@ -338,7 +338,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist"); memcpy(ult, &dummyult, sizeof(dummyult)); - ult->ext.srna = RNA_def_struct(&BLENDER_RNA, ult->idname, "UIList"); + ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList); ult->ext.data = data; ult->ext.call = call; ult->ext.free = free; @@ -439,7 +439,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da ht = MEM_callocN(sizeof(HeaderType), "python buttons header"); memcpy(ht, &dummyht, sizeof(dummyht)); - ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header"); + ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header); ht->ext.data = data; ht->ext.call = call; ht->ext.free = free; @@ -572,7 +572,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data mt->description = buf; } - mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); + mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu); mt->ext.data = data; mt->ext.call = call; mt->ext.free = free; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 07390958bd9..74fcd44fb38 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -514,7 +514,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void memcpy(apt, &dummyapt, sizeof(dummyapt)); BKE_addon_pref_type_add(apt); - apt->ext.srna = RNA_def_struct(&BLENDER_RNA, identifier, "AddonPreferences"); + apt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, identifier, &RNA_AddonPreferences); apt->ext.data = data; apt->ext.call = call; apt->ext.free = free; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f46d24bc01c..f416d3403ad 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1138,7 +1138,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * * for now just remove from dir(bpy.types) */ /* create a new operator type */ - dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); + dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator); RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */ dummyot.ext.data = data; dummyot.ext.call = call; @@ -1219,7 +1219,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v * for now just remove from dir(bpy.types) */ /* create a new operator type */ - dummyot.ext.srna = RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); + dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator); dummyot.ext.data = data; dummyot.ext.call = call; dummyot.ext.free = free; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 81e469f8c5a..b2c3c935553 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -151,7 +151,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *)) wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT); opfunc(ot); @@ -173,7 +173,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void * wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT); opfunc(ot, userdata); @@ -360,7 +360,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam } ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); ot->idname = idname; ot->name = name; @@ -390,7 +390,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *), wmOperatorType *ot; ot = MEM_callocN(sizeof(wmOperatorType), "operatortype"); - ot->srna = RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_OperatorProperties); ot->flag = OPTYPE_MACRO; ot->exec = wm_macro_exec; From 9b5a2084bc1ca8f330faeb601d2b3c65efa98f3d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 06:00:33 +0000 Subject: [PATCH 079/132] avoid having dangling panel pointers in the interface, unregistering addons could leave the interface pointing to freed memory. --- source/blender/editors/include/UI_interface.h | 2 ++ .../editors/interface/interface_panel.c | 25 +++++++++++++++++++ source/blender/makesrna/intern/rna_ui.c | 7 +++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 080367c4325..16b5526ca26 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -42,6 +42,7 @@ struct ID; struct Main; struct ListBase; struct ARegion; +struct ARegionType; struct ScrArea; struct wmWindow; struct wmWindowManager; @@ -660,6 +661,7 @@ void uiDrawPanels(const struct bContext *C, struct ARegion *ar); struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open); void uiEndPanel(uiBlock *block, int width, int height); void uiScalePanels(struct ARegion *ar, float new_width); +void uiPanelClearType(struct wmWindowManager *wm, const struct ARegionType *art, const struct PanelType *type); /* Handlers * diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 9fbf2fe8898..bcd49551784 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -306,6 +306,31 @@ void uiEndPanel(uiBlock *block, int width, int height) } } +void uiPanelClearType(wmWindowManager *wm, const ARegionType *art, const PanelType *type) +{ + wmWindow *win; + for (win = wm->windows.first; win; win = win->next) { + ScrArea *sa; + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->type == art) { + uiBlock *block, *nblock = ar->uiblocks.first; + while ((block = nblock)) { + nblock = block->next; + if (block->panel) { + if (block->panel->type == type) { + uiFreeBlock(block->evil_C, block); + BLI_remlink(&ar->uiblocks, block); + } + } + } + } + } + } + } +} + static void ui_offset_panel_block(uiBlock *block) { uiStyle *style = UI_GetStyleDraw(); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 137ffecac9a..cae9673906e 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -165,8 +165,9 @@ static void panel_draw_header(const bContext *C, Panel *pnl) RNA_parameter_list_free(&list); } -static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) +static void rna_Panel_unregister(Main *bmain, StructRNA *type) { + wmWindowManager *wm; ARegionType *art; PanelType *pt = RNA_struct_blender_type_get(type); @@ -174,6 +175,10 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) return; if (!(art = region_type_find(NULL, pt->space_type, pt->region_type))) return; + + for (wm = bmain->wm.first; wm; wm = wm->id.next) { + uiPanelClearType(wm, art, pt); + } RNA_struct_free_extension(type, &pt->ext); From 5fe82bc091ab0f0537209af6dfd807a82c6d1d6b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 9 Jan 2013 10:15:12 +0000 Subject: [PATCH 080/132] Fix #33796: Curve radius makes affect only in full fill mode --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/displist.c | 3 +- source/blender/blenloader/intern/readfile.c | 33 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index dc3f8dfb964..49301f47df6 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 6 +#define BLENDER_SUBVERSION 7 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 71e9daaee6b..daf0d571887 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1485,8 +1485,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba float *cur_data = data; if (cu->taperobj == NULL) { - if ( (cu->bevobj != NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ) - fac = bevp->radius; + fac = bevp->radius; } else { float len, taper_fac; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 43c1179dbba..c8bd02e2776 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8612,6 +8612,39 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { + Curve *cu; + + for (cu = main->curve.first; cu; cu = cu->id.next) { + if (cu->flag & (CU_FRONT | CU_BACK)) { + Nurb *nu; + + for (nu = cu->nurb.first; nu; nu = nu->next) { + int a; + + if (nu->bezt) { + BezTriple *bezt = nu->bezt; + a = nu->pntsu; + + while (a--) { + bezt->radius = 1.0f; + bezt++; + } + } + else if (nu->bp) { + BPoint *bp = nu->bp; + a = nu->pntsu * nu->pntsv; + + while (a--) { + bp->radius = 1.0f; + bp++; + } + } + } + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ From a2e17ff5ecb673c2133aaf145033b6f00f50e4cb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 10:18:05 +0000 Subject: [PATCH 081/132] reduce the alpha of console selection (text was too hard to read) --- source/blender/editors/include/BIF_glutil.h | 8 ++++---- source/blender/editors/screen/glutil.c | 8 ++++---- source/blender/editors/space_info/textview.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index 577113927d1..31f89063f05 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -51,10 +51,10 @@ void fdrawcheckerboard(float x1, float y1, float x2, float y2); /* OpenGL stipple defines */ /* OpenGL stipple defines */ -extern unsigned char stipple_halftone[128]; -extern unsigned char stipple_quarttone[128]; -extern unsigned char stipple_diag_stripes_pos[128]; -extern unsigned char stipple_diag_stripes_neg[128]; +extern const unsigned char stipple_halftone[128]; +extern const unsigned char stipple_quarttone[128]; +extern const unsigned char stipple_diag_stripes_pos[128]; +extern const unsigned char stipple_diag_stripes_neg[128]; /** * Draw a lined (non-looping) arc with the given diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index d3947432004..f073fdd5125 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -56,7 +56,7 @@ /* ******************************************** */ /* defined in BIF_gl.h */ -GLubyte stipple_halftone[128] = { +const GLubyte stipple_halftone[128] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, @@ -83,7 +83,7 @@ GLubyte stipple_halftone[128] = { * 00000000 */ -GLubyte stipple_quarttone[128] = { +const GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, @@ -94,7 +94,7 @@ GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0}; -GLubyte stipple_diag_stripes_pos[128] = { +const GLubyte stipple_diag_stripes_pos[128] = { 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe, 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8, 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, @@ -113,7 +113,7 @@ GLubyte stipple_diag_stripes_pos[128] = { 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f}; -GLubyte stipple_diag_stripes_neg[128] = { +const GLubyte stipple_diag_stripes_neg[128] = { 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f, diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index e5f8d6553ed..fc0a7b3b883 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -71,14 +71,14 @@ BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step) static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight) { if (sel[0] <= str_len_draw && sel[1] >= 0) { - int sta = max_ii(sel[0], 0); - int end = min_ii(sel[1], str_len_draw); + const int sta = max_ii(sel[0], 0); + const int end = min_ii(sel[1], str_len_draw); glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(stipple_halftone); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4ub(255, 255, 255, 96); + glColor4ub(255, 255, 255, 48); glRecti(xy[0] + (cwidth * sta), xy[1] - 2 + lheight, xy[0] + (cwidth * end), xy[1] - 2); From 96b44c622cad77eb05790c9da3ef316fe56159c0 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 9 Jan 2013 11:25:16 +0000 Subject: [PATCH 082/132] Mac HiDPI support: With the good help from googling, here's code that compiles for 10.6 natively. Will check on 10.7 and 10.8 right after commit. --- intern/ghost/intern/GHOST_WindowCocoa.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 40b9dcaf94e..e89dd1b41dc 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -431,7 +431,8 @@ extern "C" { #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 @interface NSView (NSOpenGLSurfaceResolution) - (BOOL)wantsBestResolutionOpenGLSurface; -- (void)setWantsBestResolutionOpenGLSurface; +- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; +- (NSRect)convertRectToBacking:(NSRect)bounds; @end #endif From cf2eeabf6dc84b7ac527df2e7a9358f1acaf79d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 12:26:36 +0000 Subject: [PATCH 083/132] fix [#33808] custom property write RNA_pointer_get: xxx.xxxx not found in the console message was harmless but annoying. --- source/blender/makesrna/intern/rna_access.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 012575616a1..59bcb1506af 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -4104,8 +4104,9 @@ static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *nee else { if (iter->type == IDP_GROUP) { /* ensure this is RNA */ - PointerRNA child_ptr = RNA_pointer_get(ptr, iter->name); - if (child_ptr.type) { + PropertyRNA *prop = RNA_struct_find_property(ptr, iter->name); + if (prop && prop->type == PROP_POINTER) { + PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop); link.name = iter->name; link.index = -1; if ((path = rna_idp_path(&child_ptr, iter, needle, &link))) { From 2d526c23dde460de6573bb8795d3490722498387 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 13:15:23 +0000 Subject: [PATCH 084/132] remove uiPanelClearType(), instead redraw all windows when registering/unregistering. --- source/blender/editors/include/UI_interface.h | 1 - .../editors/interface/interface_panel.c | 25 ------------------- .../blender/makesrna/intern/rna_animation.c | 4 +++ source/blender/makesrna/intern/rna_ui.c | 21 ++++++---------- source/blender/makesrna/intern/rna_userdef.c | 4 +-- 5 files changed, 14 insertions(+), 41 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 16b5526ca26..eff85ba4390 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -661,7 +661,6 @@ void uiDrawPanels(const struct bContext *C, struct ARegion *ar); struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open); void uiEndPanel(uiBlock *block, int width, int height); void uiScalePanels(struct ARegion *ar, float new_width); -void uiPanelClearType(struct wmWindowManager *wm, const struct ARegionType *art, const struct PanelType *type); /* Handlers * diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index bcd49551784..9fbf2fe8898 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -306,31 +306,6 @@ void uiEndPanel(uiBlock *block, int width, int height) } } -void uiPanelClearType(wmWindowManager *wm, const ARegionType *art, const PanelType *type) -{ - wmWindow *win; - for (win = wm->windows.first; win; win = win->next) { - ScrArea *sa; - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - ARegion *ar; - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->type == art) { - uiBlock *block, *nblock = ar->uiblocks.first; - while ((block = nblock)) { - nblock = block->next; - if (block->panel) { - if (block->panel->type == type) { - uiFreeBlock(block->evil_C, block); - BLI_remlink(&ar->uiblocks, block); - } - } - } - } - } - } - } -} - static void ui_offset_panel_block(uiBlock *block) { uiStyle *style = UI_GetStyleDraw(); diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 020ad2c147a..d6ea53f6ab3 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -198,6 +198,8 @@ static void rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type) RNA_struct_free_extension(type, &ksi->ext); RNA_struct_free(&BLENDER_RNA, type); + WM_main_add_notifier(NC_WINDOW, NULL); + /* unlink Blender-side data */ ANIM_keyingset_info_unregister(bmain, ksi); } @@ -249,6 +251,8 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v /* add and register with other info as needed */ ANIM_keyingset_info_register(ksi); + WM_main_add_notifier(NC_WINDOW, NULL); + /* return the struct-rna added */ return ksi->ext.srna; } diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index cae9673906e..00124a82dd1 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -167,7 +167,6 @@ static void panel_draw_header(const bContext *C, Panel *pnl) static void rna_Panel_unregister(Main *bmain, StructRNA *type) { - wmWindowManager *wm; ARegionType *art; PanelType *pt = RNA_struct_blender_type_get(type); @@ -175,10 +174,6 @@ static void rna_Panel_unregister(Main *bmain, StructRNA *type) return; if (!(art = region_type_find(NULL, pt->space_type, pt->region_type))) return; - - for (wm = bmain->wm.first; wm; wm = wm->id.next) { - uiPanelClearType(wm, art, pt); - } RNA_struct_free_extension(type, &pt->ext); @@ -186,7 +181,7 @@ static void rna_Panel_unregister(Main *bmain, StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -256,7 +251,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat BLI_addtail(&art->paneltypes, pt); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return pt->ext.srna; } @@ -308,7 +303,7 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -355,7 +350,7 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da WM_uilisttype_add(ult); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return ult->ext.srna; } @@ -402,7 +397,7 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -455,7 +450,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da BLI_addtail(&art->headertypes, ht); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return ht->ext.srna; } @@ -525,7 +520,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static char _menu_descr[RNA_DYN_DESCR_MAX]; @@ -590,7 +585,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data WM_menutype_add(mt); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return mt->ext.srna; } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 74fcd44fb38..28ba7d4f66a 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -476,7 +476,7 @@ static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type) RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); } static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -523,7 +523,7 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void // apt->draw = (have_function[0]) ? header_draw : NULL; /* update while blender is running */ - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + WM_main_add_notifier(NC_WINDOW, NULL); return apt->ext.srna; } From f9c87b86fc03e6239c7be53a20aeec1b735c293d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 13:25:46 +0000 Subject: [PATCH 085/132] partial fix for [#32581] Mesh properties API does not allow for zeros in byte array bmesh access allows zero bytes, support still needs adding via RNA. --- source/blender/makesdna/DNA_meshdata_types.h | 2 +- source/blender/makesrna/intern/rna_mesh.c | 21 +++++++++++++++++++ .../python/bmesh/bmesh_py_types_customdata.c | 12 +++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 0c193e9be21..ffa5e420fca 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -167,7 +167,7 @@ typedef struct MIntProperty { int i; } MIntProperty; typedef struct MStringProperty { - char s[256]; + char s[255], s_len; } MStringProperty; typedef struct OrigSpaceFace { diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index e471bf3dd3c..d6ded23ffed 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1233,6 +1233,26 @@ static char *rna_MeshStringProperty_path(PointerRNA *ptr) return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR); } +/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1) + * bmesh API exposes correct python/bytestring access */ +void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + BLI_strncpy(value, ms->s, (int)ms->s_len + 1); +} + +int rna_MeshStringProperty_s_length(PointerRNA *ptr) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + return (int)ms->s_len + 1; +} + +void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value) +{ + MStringProperty *ms = (MStringProperty *)ptr->data; + BLI_strncpy(ms->s, value, sizeof(ms->s)); +} + static int rna_Mesh_tot_vert_get(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); @@ -2161,6 +2181,7 @@ static void rna_def_mproperties(BlenderRNA *brna) /* low level mesh data access, treat as bytes */ prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING); RNA_def_property_string_sdna(prop, NULL, "s"); + RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set"); RNA_def_property_ui_text(prop, "Value", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index fd31f3c40cc..4a8f8d49f35 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) case CD_PROP_STR: { MStringProperty *mstring = value; - ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s))); + ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len); break; } case CD_MTEXPOLY: @@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj case CD_PROP_STR: { MStringProperty *mstring = value; - const char *tmp_val = PyBytes_AsString(py_value); - if (UNLIKELY(tmp_val == NULL)) { + char *tmp_val; + Py_ssize_t tmp_val_len; + if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) { PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name); ret = -1; } else { - BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s))); + if (tmp_val_len > sizeof(mstring->s)) + tmp_val_len = sizeof(mstring->s); + memcpy(mstring->s, tmp_val, tmp_val_len); + mstring->s_len = tmp_val_len; } break; } From a4ba448529924a69d2ef01d36c67e8cec7978f7f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 9 Jan 2013 13:46:59 +0000 Subject: [PATCH 086/132] Remove glibc27 from buildbot scripts --- .../config/user-config-glibc27-i686.py | 149 ------------------ .../config/user-config-glibc27-x86_64.py | 149 ------------------ .../config/user-config-player-glibc27-i686.py | 114 -------------- .../user-config-player-glibc27-x86_64.py | 114 -------------- build_files/buildbot/master.cfg | 4 +- build_files/buildbot/slave_compile.py | 6 - build_files/buildbot/slave_pack.py | 6 - 7 files changed, 2 insertions(+), 540 deletions(-) delete mode 100644 build_files/buildbot/config/user-config-glibc27-i686.py delete mode 100644 build_files/buildbot/config/user-config-glibc27-x86_64.py delete mode 100644 build_files/buildbot/config/user-config-player-glibc27-i686.py delete mode 100644 build_files/buildbot/config/user-config-player-glibc27-x86_64.py diff --git a/build_files/buildbot/config/user-config-glibc27-i686.py b/build_files/buildbot/config/user-config-glibc27-i686.py deleted file mode 100644 index 46f3ccb3df7..00000000000 --- a/build_files/buildbot/config/user-config-glibc27-i686.py +++ /dev/null @@ -1,149 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-i686' -BF_INSTALLDIR = '../blender-install/linux-glibc27-i686' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = True -BF_OPENCOLLADA = '/opt/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib32' -BF_PCRE_LIB = '' -BF_EXPAT_LIB = '' - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = True -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = True -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = True - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Blender player (would be enabled in it's own config) -WITH_BF_PLAYER = False - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32' - -# FFT -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True - -# JACK -WITH_BF_JACK = False - -# Cycles -WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] - -WITH_BF_OIIO = True -WITH_BF_STATICOIIO = True -BF_OIIO = '/opt/oiio' -BF_OIIO_INC = '${BF_OIIO}/include' -BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a' -BF_OIIO_LIBPATH = '${BF_OIIO}/lib' - -WITH_BF_CYCLES_OSL = True -WITH_BF_STATICOSL = False -BF_OSL = '/opt/osl' -BF_OSL_INC = '${BF_OSL}/include' -# note oslexec would passed via program linkflags, which is needed to -# make llvm happy with osl_allocate_closure_component -BF_OSL_LIB = 'oslcomp oslexec oslquery' -BF_OSL_LIBPATH = '${BF_OSL}/lib' -BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' - -WITH_BF_LLVM = True -WITH_BF_STATICLLVM = False -BF_LLVM = '/opt/llvm-3.1' -BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ - 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ - 'LLVMTarget LLVMMC LLVMCore LLVMSupport' -BF_LLVM_LIBPATH = '${BF_LLVM}/lib' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# Ocean Simulation -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-DNDEBUG', '-O2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] -BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-glibc27-x86_64.py b/build_files/buildbot/config/user-config-glibc27-x86_64.py deleted file mode 100644 index 23ddcf7a5b9..00000000000 --- a/build_files/buildbot/config/user-config-glibc27-x86_64.py +++ /dev/null @@ -1,149 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64' -BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = True -BF_OPENCOLLADA = '/opt/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver buffer ftoa libxml2-static libexpat-static libpcre-static' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib /home/sources/staticlibs/lib64' -BF_PCRE_LIB = '' -BF_EXPAT_LIB = '' - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = True -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = True -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = True - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Blender player (would be enabled in it's own config) -WITH_BF_PLAYER = False - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64' - -# FFT -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True - -# JACK -WITH_BF_JACK = False - -# Cycles -WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] - -WITH_BF_OIIO = True -WITH_BF_STATICOIIO = True -BF_OIIO = '/opt/oiio' -BF_OIIO_INC = '${BF_OIIO}/include' -BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a' -BF_OIIO_LIBPATH = '${BF_OIIO}/lib' - -WITH_BF_CYCLES_OSL = True -WITH_BF_STATICOSL = False -BF_OSL = '/opt/osl' -BF_OSL_INC = '${BF_OSL}/include' -# note oslexec would passed via program linkflags, which is needed to -# make llvm happy with osl_allocate_closure_component -BF_OSL_LIB = 'oslcomp oslexec oslquery' -BF_OSL_LIBPATH = '${BF_OSL}/lib' -BF_OSL_COMPILER = '${BF_OSL}/bin/oslc' - -WITH_BF_LLVM = True -WITH_BF_STATICLLVM = False -BF_LLVM = '/opt/llvm-3.1' -BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \ - 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \ - 'LLVMTarget LLVMMC LLVMCore LLVMSupport' -BF_LLVM_LIBPATH = '${BF_LLVM}/lib' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# Ocean Simulation -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] -BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map'] diff --git a/build_files/buildbot/config/user-config-player-glibc27-i686.py b/build_files/buildbot/config/user-config-player-glibc27-i686.py deleted file mode 100644 index 300af2295f0..00000000000 --- a/build_files/buildbot/config/user-config-player-glibc27-i686.py +++ /dev/null @@ -1,114 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-i686' -BF_INSTALLDIR = '../blender-install/linux-glibc27-i686' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = False - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = False -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = False -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = False - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Do not build blender when building blenderplayer -WITH_BF_NOBLENDER = True -WITH_BF_PLAYER = True - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# JACK -WITH_BF_JACK = False - -# Motion Tracking -WITH_BF_LIBMV = False - -# Ocean Simulation -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib32'] diff --git a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py b/build_files/buildbot/config/user-config-player-glibc27-x86_64.py deleted file mode 100644 index 722c3a00a66..00000000000 --- a/build_files/buildbot/config/user-config-player-glibc27-x86_64.py +++ /dev/null @@ -1,114 +0,0 @@ -BF_BUILDDIR = '../blender-build/linux-glibc27-x86_64' -BF_INSTALLDIR = '../blender-install/linux-glibc27-x86_64' -BF_NUMJOBS = 2 - -# Python configuration -BF_PYTHON_VERSION = '3.3' -BF_PYTHON_ABI_FLAGS = 'm' -BF_PYTHON = '/opt/python3' - -WITH_BF_STATICPYTHON = True - -# OpenCollada configuration -WITH_BF_COLLADA = False - -# FFMPEG configuration -WITH_BF_FFMPEG = True -WITH_BF_STATICFFMPEG = True - -BF_FFMPEG = '/home/sources/staticlibs/ffmpeg' -BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64' -BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' - -# Don't depend on system's libstdc++ -WITH_BF_STATICCXX = True -BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.3.4/libstdc++.a' - -WITH_BF_OPENAL = True -WITH_BF_STATICOPENAL = True -BF_OPENAL_LIB_STATIC = '/opt/openal/lib/libopenal.a' - -WITH_BF_GETTEXT_STATIC = True -BF_FREETYPE_LIB_STATIC = True - -WITH_BF_OPENEXR = False -WITH_BF_STATICOPENEXR = True - -WITH_BF_TIFF = False -WITH_BF_STATICTIFF = True -BF_TIFF_LIB_STATIC = '${BF_TIFF}/lib/libtiff.a' - -WITH_BF_JPEG = True -BF_JPEG_LIB = 'libjpeg' -BF_JPEG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_STATICLIBSAMPLERATE = True - -WITH_BF_PNG = True -BF_PNG_LIB = 'libpng' -BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64' - -WITH_BF_ZLIB = True -WITH_BF_STATICZLIB = True -BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a' - -WITH_BF_SDL = True -WITH_BF_OGG = False - -WITH_BF_OPENMP = True - -WITH_BF_GAMEENGINE = True -WITH_BF_BULLET = True - -# Do not build blender when building blenderplayer -WITH_BF_NOBLENDER = True -WITH_BF_PLAYER = True - -# Use jemalloc memory manager -WITH_BF_JEMALLOC = True -WITH_BF_STATICJEMALLOC = True -BF_JEMALLOC = '/home/sources/staticlibs/jemalloc' -BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64' - -# Use 3d mouse library -WITH_BF_3DMOUSE = True -WITH_BF_STATIC3DMOUSE = True -BF_3DMOUSE = '/home/sources/staticlibs/spnav' -BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64' - -# Color management -WITH_BF_OCIO = True -WITH_BF_STATICOCIO = True -BF_OCIO = '/opt/ocio' -BF_OCIO_INC = '${BF_OCIO}/include' -BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' -BF_OCIO_LIBPATH = '${BF_OCIO}/lib' - -WITH_BF_BOOST = True -WITH_BF_STATICBOOST = True -BF_BOOST = '/opt/boost' -BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a ${BF_BOOST_LIBPATH}/libboost_thread.a' -BF_BOOST_LIBPATH = '${BF_BOOST}/lib' - -# JACK -WITH_BF_JACK = False - -# Motion Tracking -WITH_BF_LIBMV = False - -# Ocean Simulation -WITH_BF_FFTW3 = True -WITH_BF_STATICFFTW3 = True -WITH_BF_OCEANSIM = True - -# Compilation and optimization -BF_DEBUG = False -REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++ -PLATFORM_LINKFLAGS = ['-L/home/sources/staticlibs/lib64'] diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 90f0c805f58..9d0839bd0d7 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -116,10 +116,10 @@ add_builder(c, 'mac_x86_64_10_5_scons', '', generic_builder, '', True) add_builder(c, 'mac_i386_scons', 'darwin-9.x.universal', generic_builder) add_builder(c, 'mac_ppc_scons', 'darwin-9.x.universal', generic_builder) #add_builder(c, 'linux_x86_64_cmake', '', generic_builder) -add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder) +#add_builder(c, 'linux_glibc27_i386_scons', '', generic_builder) add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder) #add_builder(c, 'salad_linux_i386_scons', '', generic_builder, 'soc-2011-salad') -add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder) +#add_builder(c, 'linux_glibc27_x86_64_scons', '', generic_builder) add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder) #add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad') add_builder(c, 'win32_scons', 'windows', generic_builder) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index bedada93a5a..fa933a84841 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -75,12 +75,6 @@ else: config_dir = os.path.join(buildbot_dir, 'config') configs = [] - if builder.endswith('linux_glibc27_x86_64_scons'): - configs = ['user-config-player-glibc27-x86_64.py', - 'user-config-glibc27-x86_64.py'] - elif builder.endswith('linux_glibc27_i386_scons'): - configs = ['user-config-player-glibc27-i686.py', - 'user-config-glibc27-i686.py'] if builder.endswith('linux_glibc211_x86_64_scons'): configs = ['user-config-player-glibc211-x86_64.py', 'user-config-glibc211-x86_64.py'] diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index b7775ef872f..285307a7af9 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -57,12 +57,6 @@ if builder.find('scons') != -1: config = None bits = None - if builder.endswith('linux_glibc27_x86_64_scons'): - config = 'user-config-glibc27-x86_64.py' - bits = 64 - elif builder.endswith('linux_glibc27_i386_scons'): - config = 'user-config-glibc27-i686.py' - bits = 32 if builder.endswith('linux_glibc211_x86_64_scons'): config = 'user-config-glibc211-x86_64.py' bits = 64 From b02dd1e7190a61a31d2a0335e5f2d4f91b7367e7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Jan 2013 15:39:26 +0000 Subject: [PATCH 087/132] Fix #33815: blender internal crash rendering material pass with strands. Patch from Sergey with modifications. --- source/blender/render/intern/source/zbuf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2e1b23435e5..a0267cd65b7 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -4148,8 +4148,17 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas } if (addpassflag & SCE_PASS_INDEXMA) { ObjectRen *obr = R.objectinstance[zrow[totface-1].obi].obr; - VlakRen *vr = obr->vlaknodes->vlak; - Material *mat = vr->mat; + Material *mat = NULL; + + if (zrow[totface-1].segment == -1) { + if (obr->vlaknodes) + mat = obr->vlaknodes->vlak->mat; + } + else { + if (obr->strandbuf) + mat = obr->strandbuf->ma; + } + if (mat) { for (a= 0; a Date: Wed, 9 Jan 2013 15:58:34 +0000 Subject: [PATCH 088/132] Usability fix: Blender's data link button (typically with menu and searching options) now has a X icon to clear its contents. Before you had to click, delete text, enter. For example: - Object Parent - Modifier objects or vertexgroups This fix saves each user 100 clicks per day, with 100k users that's 3 billion clicks per year! --- source/blender/editors/include/UI_interface.h | 3 +- source/blender/editors/interface/interface.c | 13 +++-- .../editors/interface/interface_handlers.c | 58 ++++++++++++++----- .../editors/interface/interface_layout.c | 2 +- .../editors/interface/interface_regions.c | 2 +- .../editors/interface/interface_widgets.c | 15 ++++- 6 files changed, 68 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index eff85ba4390..292cc4cdca0 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -254,7 +254,8 @@ typedef enum { HISTOGRAM = (48 << 9), WAVEFORM = (49 << 9), VECTORSCOPE = (50 << 9), - PROGRESSBAR = (51 << 9) + PROGRESSBAR = (51 << 9), + SEARCH_MENU_UNLINK = (52 << 9) } eButType; #define BUTTYPE (63 << 9) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 1d26cbd344b..1dee497ff11 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1605,7 +1605,7 @@ void ui_set_but_val(uiBut *but, double value) int ui_get_but_string_max_length(uiBut *but) { - if (ELEM(but->type, TEX, SEARCH_MENU)) + if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) return but->hardmax; else if (but->type == IDPOIN) return MAX_ID_NAME - 2; @@ -1688,7 +1688,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default) void ui_get_but_string(uiBut *but, char *str, size_t maxlen) { - if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { PropertyType type; const char *buf = NULL; int buf_len; @@ -1742,7 +1742,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen) BLI_strncpy(str, but->poin, maxlen); return; } - else if (but->type == SEARCH_MENU) { + else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(str, but->poin, maxlen); return; @@ -1833,7 +1833,7 @@ int ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double int ui_set_but_string(bContext *C, uiBut *but, const char *str) { - if (but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { PropertyType type; @@ -1890,7 +1890,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str) return 1; } - else if (but->type == SEARCH_MENU) { + else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* string */ BLI_strncpy(but->poin, str, but->hardmax); return 1; @@ -2360,6 +2360,7 @@ void ui_check_but(uiBut *but) case IDPOIN: case TEX: case SEARCH_MENU: + case SEARCH_MENU_UNLINK: if (!but->editstr) { char str[UI_MAX_DRAW_STR]; @@ -2741,7 +2742,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } if ((block->flag & UI_BLOCK_LOOP) || - ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR)) + ELEM9(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) { but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 07b8d8e23b2..c87bb2a97a1 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1062,6 +1062,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut ui_apply_but_BUT(C, but, data); break; case TEX: + case SEARCH_MENU_UNLINK: case SEARCH_MENU: ui_apply_but_TEX(C, but, data); break; @@ -1169,7 +1170,7 @@ static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonD for (wmd = drags->first; wmd; wmd = wmd->next) { if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { ID *id = (ID *)wmd->poin; if (but->poin == NULL && but->rnapoin.data == NULL) {} @@ -1270,7 +1271,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, } /* text/string and ID data */ - else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + else if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { uiHandleButtonData *active_data = but->active; if (but->poin == NULL && but->rnapoin.data == NULL) { @@ -1289,7 +1290,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, if (ui_is_but_utf8(but)) BLI_strncpy_utf8(active_data->str, buf, active_data->maxlen); else BLI_strncpy(active_data->str, buf, active_data->maxlen); - if (but->type == SEARCH_MENU) { + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* else uiSearchboxData.active member is not updated [#26856] */ ui_searchbox_update(C, data->searchbox, but, 1); } @@ -1436,7 +1437,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho /* XXX solve generic */ if (but->type == NUM || but->type == NUMSLI) startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect))); - else if (ELEM(but->type, TEX, SEARCH_MENU)) { + else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { startx += 5; if (but->flag & UI_HAS_ICON) startx += UI_DPI_ICON_SIZE; @@ -1816,7 +1817,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) but->selend = len; /* optional searchbox */ - if (but->type == SEARCH_MENU) { + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { data->searchbox = ui_searchbox_create(C, data->region, but); ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */ } @@ -1862,7 +1863,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; for (but = actbut->next; but; but = but->next) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1871,7 +1872,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.first; but != actbut; but = but->next) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1890,7 +1891,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; for (but = actbut->prev; but; but = but->prev) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -1899,7 +1900,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } for (but = block->buttons.last; but != actbut; but = but->prev) { - if (ELEM7(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU)) { + if (ELEM8(but->type, TEX, NUM, NUMABS, NUMSLI, HSVSLI, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; data->posttype = BUTTON_ACTIVATE_TEXT_EDITING; @@ -2430,6 +2431,34 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton return WM_UI_HANDLER_CONTINUE; } +static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + /* unlink icon is on right */ + if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + ARegion *ar = CTX_wm_region(C); + rcti rect; + int x = event->x, y = event->y; + + ui_window_to_block(ar, but->block, &x, &y); + + BLI_rcti_rctf_copy(&rect, &but->rect); + + rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect)); + if ( BLI_rcti_isect_pt(&rect, x, y) ) { + /* most likely NULL, but let's check, and give it temp zero string */ + if (data->str == NULL) + data->str = MEM_callocN(16, "temp str"); + data->str[0] = 0; + + ui_apply_but_TEX(C, but, data); + button_activate_state(C, but, BUTTON_STATE_EXIT); + + return WM_UI_HANDLER_BREAK; + } + } + return ui_do_but_TEX(C, block, but, data, event); +} + static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) { if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -5138,6 +5167,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case SEARCH_MENU: retval = ui_do_but_TEX(C, block, but, data, event); break; + case SEARCH_MENU_UNLINK: + retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event); + break; case MENU: case ICONROW: case ICONTEXTROW: @@ -5251,7 +5283,7 @@ int UI_but_active_drop_name(bContext *C) uiBut *but = ui_but_find_activated(ar); if (but) { - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) return 1; } @@ -5577,7 +5609,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA copy_v2_fl(data->ungrab_mval, FLT_MAX); #endif - if (ELEM(but->type, BUT_CURVE, SEARCH_MENU)) { + if (ELEM3(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* XXX curve is temp */ } else { @@ -6440,7 +6472,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle /* if there's an active modal button, don't check events or outside, except for search menu */ but = ui_but_find_activated(ar); - if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU) { + if (but && button_modal_state(but->active->state) && but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK) { /* if a button is activated modal, always reset the start mouse * position of the towards mechanism to avoid loosing focus, * and don't handle events */ @@ -6466,7 +6498,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle if (block->block_event_func && block->block_event_func(C, block, event)) { /* pass */ } /* events not for active search menu button */ - else if (but == NULL || but->type != SEARCH_MENU) { + else if (but == NULL || (but->type != SEARCH_MENU && but->type != SEARCH_MENU_UNLINK)) { switch (event->type) { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index f4af1f036a3..3b0a1cd3eb5 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1386,7 +1386,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN /* turn button into search button */ if (searchprop) { - but->type = SEARCH_MENU; + but->type = SEARCH_MENU_UNLINK; but->hardmax = MAX2(but->hardmax, 256.0f); but->rnasearchpoin = *searchptr; but->rnasearchprop = searchprop; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4a8ad5d24a6..ca5e2a1926c 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -466,7 +466,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->totline++; } - if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + if (ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* full string */ ui_get_but_string(but, buf, sizeof(buf)); if (buf[0]) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e4ad3a4f73b..6b44a82a52a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -897,7 +897,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti } } else if (but->block->flag & UI_BLOCK_LOOP) { - if (but->type == SEARCH_MENU) + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) xs = rect->xmin + 4.0f * ofs; else xs = rect->xmin + ofs; @@ -1283,7 +1283,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) { ui_text_clip_right_label(fstyle, but, rect); } - else if (ELEM(but->type, TEX, SEARCH_MENU)) { + else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { ui_text_clip_left(fstyle, but, rect); } else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) { @@ -1331,6 +1331,14 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB else if ((but->flag & UI_TEXT_LEFT)) { rect->xmin += (0.4f * U.widget_unit) / but->block->aspect; } + + /* unlink icon for this button type */ + if (but->type == SEARCH_MENU_UNLINK && but->drawstr[0]) { + rcti temp = *rect; + + temp.xmin = temp.xmax - BLI_rcti_size_y(rect); + widget_draw_icon(but, ICON_X, 1.0f, &temp); + } /* always draw text for textbutton cursor */ widget_draw_text(fstyle, wcol, but, rect); @@ -3215,7 +3223,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case TEX: wt = widget_type(UI_WTYPE_NAME); break; - + + case SEARCH_MENU_UNLINK: case SEARCH_MENU: wt = widget_type(UI_WTYPE_NAME); if (but->block->flag & UI_BLOCK_LOOP) From b29f7038814341639d91b815db3871801e9649ca Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 9 Jan 2013 16:07:42 +0000 Subject: [PATCH 089/132] Make the node.parent property editable in RNA, so frame hierarchy can be changed by scripts without resorting to operator hacks. Performs sanity checks internally to make sure that a) Only frames are used as parents. In future other nodes may be used for parenting, that will require more sophisticated poll functions. b) Avoid infinite recursion. If the supposed parent is already attached to a frame node the parent assignment will be ignored. --- source/blender/makesrna/intern/rna_nodetree.c | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 456a6ff83c2..276eba2033e 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -288,6 +288,43 @@ static const char *rna_Node_get_node_type(StructRNA *type) return ""; } +static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value) +{ + bNode *node = ptr->data; + bNode *parent = value.data; + + /* XXX only Frame node allowed for now, + * in the future should have a poll function or so to test possible attachment. + */ + if (parent->type != NODE_FRAME) + return; + + /* make sure parent is not attached to the node */ + if (nodeAttachNodeCheck(parent, node)) + return; + + nodeDetachNode(node); + nodeAttachNode(node, parent); +} + +static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value) +{ + bNode *node = ptr->data; + bNode *parent = value.data; + + /* XXX only Frame node allowed for now, + * in the future should have a poll function or so to test possible attachment. + */ + if (parent->type != NODE_FRAME) + return FALSE; + + /* make sure parent is not attached to the node */ + if (nodeAttachNodeCheck(parent, node)) + return FALSE; + + return TRUE; +} + static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) { bNodeSocket *sock = (bNodeSocket *)ptr->data; @@ -4689,8 +4726,9 @@ static void rna_def_node(BlenderRNA *brna) prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "parent"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_parent_set", NULL, "rna_Node_parent_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "Node"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to"); prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE); From e5113c51a75731d2b051ce2aeafadc55c947d414 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 9 Jan 2013 16:15:06 +0000 Subject: [PATCH 090/132] Small fix for r53685: Allow setting NULL/None as parent, i.e. detach a node from a frame. --- source/blender/makesrna/intern/rna_nodetree.c | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 276eba2033e..eecdf13813c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -293,18 +293,22 @@ static void rna_Node_parent_set(PointerRNA *ptr, PointerRNA value) bNode *node = ptr->data; bNode *parent = value.data; - /* XXX only Frame node allowed for now, - * in the future should have a poll function or so to test possible attachment. - */ - if (parent->type != NODE_FRAME) - return; - - /* make sure parent is not attached to the node */ - if (nodeAttachNodeCheck(parent, node)) - return; + if (parent) { + /* XXX only Frame node allowed for now, + * in the future should have a poll function or so to test possible attachment. + */ + if (parent->type != NODE_FRAME) + return; + + /* make sure parent is not attached to the node */ + if (nodeAttachNodeCheck(parent, node)) + return; + } nodeDetachNode(node); - nodeAttachNode(node, parent); + if (parent) { + nodeAttachNode(node, parent); + } } static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value) From 97d1abfe95281de3e42fb9a8d13226c621fdede5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Jan 2013 18:20:11 +0000 Subject: [PATCH 091/132] speedup for editmesh getVert and getEdge, were doing 2x customdata layer lookups for crease and bevel weight, also make use of the existing meshdata array for lookups. --- .../blenkernel/intern/editderivedmesh.c | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 1c43b418a1c..c3587f6b188 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1309,14 +1309,16 @@ static int emDM_getNumPolys(DerivedMesh *dm) static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r) { + float *f; + copy_v3_v3(vert_r->co, ev->co); normal_float_to_short_v3(vert_r->no, ev->no); vert_r->flag = BM_vert_flag_to_mflag(ev); - if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, ev, CD_BWEIGHT) * 255.0f); + if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) { + vert_r->bweight = (unsigned char)((*f) * 255.0f); } return 1; @@ -1332,8 +1334,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) return; } - // ev = EDBM_vert_at_index(bmdm->tc, index); - ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ + ev = bmdm->tc->vert_index[index]; /* should be EDBM_vert_at_index() */ + // ev = BM_vert_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ bmvert_to_mvert(bmdm->tc->bm, ev, vert_r); if (bmdm->vertexCos) @@ -1345,27 +1347,27 @@ static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r) EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->tc->bm; BMEdge *e; + float *f; if (index < 0 || index >= bmdm->te) { printf("error in emDM_getEdge.\n"); return; } - // e = EDBM_edge_at_index(bmdm->tc, index); - e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ - - if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) * 255.0f); - } - - if (CustomData_has_layer(&bm->edata, CD_CREASE)) { - edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, e, CD_CREASE) * 255.0f); - } + e = bmdm->tc->edge_index[index]; /* should be EDBM_edge_at_index() */ + // e = BM_edge_at_index(bmdm->tc->bm, index); /* warning, does list loop, _not_ ideal */ edge_r->flag = BM_edge_flag_to_mflag(e); edge_r->v1 = BM_elem_index_get(e->v1); edge_r->v2 = BM_elem_index_get(e->v2); + + if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) { + edge_r->bweight = (unsigned char)((*f) * 255.0f); + } + if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) { + edge_r->crease = (unsigned char)((*f) * 255.0f); + } } static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r) From ad10cbf04aed17c69ccd4e15921669d18ed987e1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Jan 2013 21:09:20 +0000 Subject: [PATCH 092/132] Cycles: multiple importance sampling for lamps, which helps reduce noise for big lamps and sharp glossy reflections. This was already supported for mesh lights and the background, so lamps should do it too. This is not for free and it's a bit slower than I hoped even though there is no extra BVH ray intersection. I'll try to optimize it more later. * Area lights look a bit different now, they had the wrong shape before. * Also fixes a sampling issue in the non-progressive integrator. * Only enabled for the CPU, will test on the GPU later. * An option to disable this will be added for situations where it does not help. Same time comparison before/after: http://www.pasteall.org/pic/show.php?id=43313 http://www.pasteall.org/pic/show.php?id=43314 --- intern/cycles/blender/blender_object.cpp | 8 +- intern/cycles/kernel/kernel_camera.h | 1 - intern/cycles/kernel/kernel_emission.h | 61 ++- intern/cycles/kernel/kernel_light.h | 467 ++++++++++++++-------- intern/cycles/kernel/kernel_path.h | 78 +++- intern/cycles/kernel/kernel_types.h | 6 +- intern/cycles/kernel/osl/osl_services.cpp | 8 + intern/cycles/kernel/osl/osl_shader.cpp | 6 +- intern/cycles/render/light.cpp | 27 +- intern/cycles/util/util_math.h | 124 ++++++ 10 files changed, 586 insertions(+), 200 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index ad701266c5b..e9bcea70ab6 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -127,8 +127,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI case BL::Lamp::type_AREA: { BL::AreaLamp b_area_lamp(b_lamp); light->size = 1.0f; - light->axisu = make_float3(tfm.x.x, tfm.y.x, tfm.z.x); - light->axisv = make_float3(tfm.x.y, tfm.y.y, tfm.z.y); + light->axisu = transform_get_column(&tfm, 0); + light->axisv = transform_get_column(&tfm, 1); light->sizeu = b_area_lamp.size(); if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE) light->sizev = b_area_lamp.size_y(); @@ -140,8 +140,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI } /* location and (inverted!) direction */ - light->co = make_float3(tfm.x.w, tfm.y.w, tfm.z.w); - light->dir = -make_float3(tfm.x.z, tfm.y.z, tfm.z.z); + light->co = transform_get_column(&tfm, 3); + light->dir = -transform_get_column(&tfm, 2); /* shader */ vector used_shaders; diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 97d37a8b3f4..cd896ffe133 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -199,7 +199,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f)); ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; - #endif } diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index d5506ad1dd0..54bc0717b60 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -66,6 +66,8 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, else eval = make_float3(0.0f, 0.0f, 0.0f); } + + eval *= ls->eval_fac; shader_release(kg, &sd); @@ -74,29 +76,29 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval, - bool *is_lamp) + int *lamp) { LightSample ls; - float pdf = -1.0f; - #ifdef __NON_PROGRESSIVE__ if(lindex != -1) { /* sample position on a specified light */ - light_select(kg, lindex, randu, randv, sd->P, &ls, &pdf); + light_select(kg, lindex, randu, randv, sd->P, &ls); } else #endif { /* sample a light and position on int */ - light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls, &pdf); + light_sample(kg, randt, randu, randv, sd->time, sd->P, &ls); } - /* compute pdf */ - if(pdf < 0.0f) - pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t); + /* return lamp index for MIS */ + if(ls.use_mis) + *lamp = ls.lamp; + else + *lamp= ~0; - if(pdf == 0.0f) + if(ls.pdf == 0.0f) return false; /* evaluate closure */ @@ -112,13 +114,13 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, shader_bsdf_eval(kg, sd, ls.D, eval, &bsdf_pdf); - if(ls.prim != ~0 || ls.type == LIGHT_BACKGROUND) { + if(ls.use_mis) { /* multiple importance sampling */ - float mis_weight = power_heuristic(pdf, bsdf_pdf); + float mis_weight = power_heuristic(ls.pdf, bsdf_pdf); light_eval *= mis_weight; } - bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf)); + bsdf_eval_mul(eval, light_eval/ls.pdf); if(bsdf_eval_is_zero(eval)) return false; @@ -144,14 +146,12 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex, ray->t = 0.0f; } - *is_lamp = (ls.prim == ~0); - return true; } -/* Indirect Emission */ +/* Indirect Primitive Emission */ -__device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) +__device float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf) { /* evaluate emissive closure */ float3 L = shader_emissive_eval(kg, sd); @@ -172,6 +172,35 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in return L; } +/* Indirect Lamp Emission */ + +__device bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf, float randt, float3 *emission) +{ + LightSample ls; + int lamp = lamp_light_eval_sample(kg, randt); + + if(lamp == ~0) + return false; + + if(!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls)) + return false; + + /* todo: missing texture coordinates */ + float u = 0.0f; + float v = 0.0f; + float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ls.t, ray->time); + + if(!(path_flag & PATH_RAY_MIS_SKIP)) { + /* multiple importance sampling, get regular light pdf, + * and compute weight with respect to BSDF pdf */ + float mis_weight = power_heuristic(bsdf_pdf, ls.pdf); + L *= mis_weight; + } + + *emission = L; + return true; +} + /* Indirect Background */ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, float bsdf_pdf) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index ea0e4d014fe..df5acca6e65 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -18,49 +18,27 @@ CCL_NAMESPACE_BEGIN +/* Light Sample result */ + typedef struct LightSample { - float3 P; - float3 D; - float3 Ng; - float t; - float eval_fac; - int object; - int prim; - int shader; - LightType type; + float3 P; /* position on light, or direction for distant light */ + float3 Ng; /* normal on light */ + float3 D; /* direction from shading point to light */ + float t; /* distance to light (FLT_MAX for distant light) */ + float pdf; /* light sampling probability density function */ + float eval_fac; /* intensity multiplier */ + int object; /* object id for triangle/curve lights */ + int prim; /* primitive id for triangle/curve ligths */ + int shader; /* shader id */ + int lamp; /* lamp id */ + int use_mis; /* for lamps with size zero */ + LightType type; /* type of light */ } LightSample; -/* Regular Light */ - -__device float3 disk_light_sample(float3 v, float randu, float randv) -{ - float3 ru, rv; - - make_orthonormals(v, &ru, &rv); - to_unit_disk(&randu, &randv); - - return ru*randu + rv*randv; -} - -__device float3 distant_light_sample(float3 D, float size, float randu, float randv) -{ - return normalize(D + disk_light_sample(D, randu, randv)*size); -} - -__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv) -{ - return disk_light_sample(normalize(P - center), randu, randv)*size; -} - -__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv) -{ - randu = randu - 0.5f; - randv = randv - 0.5f; - - return axisu*randu + axisv*randv; -} +/* Background Light */ #ifdef __BACKGROUND_MIS__ + __device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf) { /* for the following, the CDF values are actually a pair of floats, with the @@ -169,33 +147,108 @@ __device float background_light_pdf(KernelGlobals *kg, float3 direction) } #endif -__device void regular_light_sample(KernelGlobals *kg, int point, - float randu, float randv, float3 P, LightSample *ls, float *pdf) +/* Regular Light */ + +__device float3 disk_light_sample(float3 v, float randu, float randv) { - float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0); - float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1); + float3 ru, rv; + + make_orthonormals(v, &ru, &rv); + to_unit_disk(&randu, &randv); + + return ru*randu + rv*randv; +} + +__device float3 distant_light_sample(float3 D, float radius, float randu, float randv) +{ + return normalize(D + disk_light_sample(D, randu, randv)*radius); +} + +__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv) +{ + return disk_light_sample(normalize(P - center), randu, randv)*radius; +} + +__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv) +{ + randu = randu - 0.5f; + randv = randv - 0.5f; + + return axisu*randu + axisv*randv; +} + +__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls) +{ + float3 dir = make_float3(data2.y, data2.z, data2.w); + float3 I = ls->Ng; + + float spot_angle = data1.w; + float spot_smooth = data2.x; + + float attenuation = dot(dir, I); + + if(attenuation <= spot_angle) { + attenuation = 0.0f; + } + else { + float t = attenuation - spot_angle; + + if(t < spot_smooth && spot_smooth != 0.0f) + attenuation *= smoothstepf(t/spot_smooth); + } + + return attenuation; +} + +__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) +{ + float cos_pi = dot(Ng, I); + + if(cos_pi <= 0.0f) + return 0.0f; + + return t*t/cos_pi; +} + +__device void lamp_light_sample(KernelGlobals *kg, int lamp, + float randu, float randv, float3 P, LightSample *ls) +{ + float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0); + float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1); LightType type = (LightType)__float_as_int(data0.x); ls->type = type; +#ifdef __LAMP_MIS__ + ls->use_mis = true; +#else + ls->use_mis = false; +#endif if(type == LIGHT_DISTANT) { /* distant light */ - float3 D = make_float3(data0.y, data0.z, data0.w); - float size = data1.y; + float3 lightD = make_float3(data0.y, data0.z, data0.w); + float3 D = lightD; + float radius = data1.y; + float invarea = data1.w; - if(size > 0.0f) - D = distant_light_sample(D, size, randu, randv); + if(radius > 0.0f) + D = distant_light_sample(D, radius, randu, randv); + else + ls->use_mis = false; ls->P = D; ls->Ng = D; ls->D = -D; ls->t = FLT_MAX; - ls->eval_fac = 1.0f; + + float costheta = dot(lightD, D); + ls->pdf = invarea/(costheta*costheta*costheta); + ls->eval_fac = ls->pdf; } #ifdef __BACKGROUND_MIS__ else if(type == LIGHT_BACKGROUND) { /* infinite area light (e.g. light dome or env light) */ - float3 D = background_light_sample(kg, randu, randv, pdf); + float3 D = background_light_sample(kg, randu, randv, &ls->pdf); ls->P = D; ls->Ng = D; @@ -207,85 +260,208 @@ __device void regular_light_sample(KernelGlobals *kg, int point, else { ls->P = make_float3(data0.y, data0.z, data0.w); - if(type == LIGHT_POINT) { - float size = data1.y; + if(type == LIGHT_POINT || type == LIGHT_SPOT) { + float radius = data1.y; - /* sphere light */ - if(size > 0.0f) - ls->P += sphere_light_sample(P, ls->P, size, randu, randv); + if(radius > 0.0f) + /* sphere light */ + ls->P += sphere_light_sample(P, ls->P, radius, randu, randv); + else + ls->use_mis = false; - ls->Ng = normalize(P - ls->P); - ls->eval_fac = 0.25f*M_1_PI_F; - } - else if(type == LIGHT_SPOT) { - float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); - float size = data1.y; + ls->D = normalize_len(ls->P - P, &ls->t); + ls->Ng = -ls->D; - /* spot light */ - if(size > 0.0f) - ls->P += sphere_light_sample(P, ls->P, size, randu, randv); + float invarea = data1.z; + ls->eval_fac = (0.25f*M_1_PI_F)*invarea; + ls->pdf = invarea; - float3 dir = make_float3(data1.z, data1.w, data2.x); - float3 I = normalize(P - ls->P); - - float spot_angle = data2.y; - float spot_smooth = data2.z; - - float eval_fac = dot(dir, I); - - if(eval_fac <= spot_angle) { - eval_fac = 0.0f; + if(type == LIGHT_SPOT) { + /* spot light attentuation */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + ls->eval_fac *= spot_light_attenuation(data1, data2, ls); } - else { - float t = eval_fac - spot_angle; - - if(t < spot_smooth && spot_smooth != 0.0f) - eval_fac *= smoothstepf(t/spot_smooth); - } - - ls->Ng = I; - ls->eval_fac = eval_fac*0.25f*M_1_PI_F; } else { /* area light */ - float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2); - float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3); + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3); - float3 axisu = make_float3(data1.y, data1.z, data2.w); + float3 axisu = make_float3(data1.y, data1.z, data1.w); float3 axisv = make_float3(data2.y, data2.z, data2.w); float3 D = make_float3(data3.y, data3.z, data3.w); ls->P += area_light_sample(axisu, axisv, randu, randv); ls->Ng = D; - ls->eval_fac = 0.25f; - } + ls->D = normalize_len(ls->P - P, &ls->t); - ls->t = 0.0f; + float invarea = data2.x; + + if(invarea == 0.0f) { + ls->use_mis = false; + invarea = 1.0f; + } + + ls->pdf = invarea; + ls->eval_fac = 0.25f*ls->pdf; + } } ls->shader = __float_as_int(data1.x); ls->object = ~0; ls->prim = ~0; + ls->lamp = lamp; + + /* compute pdf */ + if(ls->t != FLT_MAX) + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); + + /* this is a bit weak, but we don't want this as part of the pdf for + * multiple importance sampling */ + ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; } -__device float regular_light_pdf(KernelGlobals *kg, - const float3 Ng, const float3 I, float t) +__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls) { - float pdf = kernel_data.integrator.pdf_lights; + float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0); + float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1); - if(t == FLT_MAX) - return pdf; + LightType type = (LightType)__float_as_int(data0.x); + ls->type = type; + ls->shader = __float_as_int(data1.x); + ls->object = ~0; + ls->prim = ~0; + ls->lamp = lamp; + ls->use_mis = false; /* flag not used for eval */ - float cos_pi = dot(Ng, I); + if(type == LIGHT_DISTANT) { + /* distant light */ + float radius = data1.y; - if(cos_pi <= 0.0f) - return 0.0f; + if(radius == 0.0f) + return false; + if(t != FLT_MAX) + return false; - return t*t*pdf/cos_pi; + /* a distant light is infinitely far away, but equivalent to a disk + * shaped light exactly 1 unit away from the current shading point. + * + * radius t^2/cos(theta) + * <----------> t = sqrt(1^2 + tan(theta)^2) + * tan(th) area = radius*radius*pi + * <-----> + * \ | (1 + tan(theta)^2)/cos(theta) + * \ | (1 + tan(acos(cos(theta)))^2)/cos(theta) + * t \th| 1 simplifies to + * \-| 1/(cos(theta)^3) + * \| magic! + * P + */ + + float3 lightD = make_float3(data0.y, data0.z, data0.w); + float costheta = dot(-lightD, D); + float cosangle = data1.z; + + if(costheta < cosangle) + return false; + + ls->P = -D; + ls->Ng = -D; + ls->D = D; + ls->t = FLT_MAX; + + float invarea = data1.w; + ls->pdf = invarea/(costheta*costheta*costheta); + ls->eval_fac = ls->pdf; + } + else if(type == LIGHT_POINT || type == LIGHT_SPOT) { + float3 lightP = make_float3(data0.y, data0.z, data0.w); + float radius = data1.y; + + /* sphere light */ + if(radius == 0.0f) + return false; + + if(!ray_aligned_disk_intersect(P, D, t, + lightP, radius, &ls->P, &ls->t)) + return false; + + ls->Ng = -D; + ls->D = D; + + float invarea = data1.z; + ls->eval_fac = (0.25f*M_1_PI_F)*invarea; + ls->pdf = invarea; + + if(type == LIGHT_SPOT) { + /* spot light attentuation */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + ls->eval_fac *= spot_light_attenuation(data1, data2, ls); + + if(ls->eval_fac == 0.0f) + return false; + } + } + else if(type == LIGHT_AREA) { + /* area light */ + float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); + float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3); + + float invarea = data2.x; + if(invarea == 0.0f) + return false; + + float3 axisu = make_float3(data1.y, data1.z, data1.w); + float3 axisv = make_float3(data2.y, data2.z, data2.w); + float3 Ng = make_float3(data3.y, data3.z, data3.w); + + /* one sided */ + if(dot(D, Ng) >= 0.0f) + return false; + + ls->P = make_float3(data0.y, data0.z, data0.w); + + if(!ray_quad_intersect(P, D, t, + ls->P, axisu, axisv, &ls->P, &ls->t)) + return false; + + ls->D = D; + ls->Ng = Ng; + ls->pdf = invarea; + ls->eval_fac = 0.25f*ls->pdf; + } + else + return false; + + /* compute pdf */ + if(ls->t != FLT_MAX) + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); + ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; + + return true; } /* Triangle Light */ +__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time) +{ +#ifdef __INSTANCING__ + /* instance transform */ + if(object >= 0) { +#ifdef __OBJECT_MOTION__ + Transform itfm; + Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); +#else + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); +#endif + + ls->P = transform_point(&tfm, ls->P); + ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); + } +#endif +} + __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, float randu, float randv, float time, LightSample *ls) { @@ -294,40 +470,30 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, ls->Ng = triangle_normal_MT(kg, prim, &ls->shader); ls->object = object; ls->prim = prim; + ls->lamp = ~0; + ls->use_mis = true; ls->t = 0.0f; ls->type = LIGHT_AREA; ls->eval_fac = 1.0f; -#ifdef __INSTANCING__ - /* instance transform */ - if(ls->object >= 0) { -#ifdef __OBJECT_MOTION__ - Transform itfm; - Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); -#else - Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); -#endif - - ls->P = transform_point(&tfm, ls->P); - ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng)); - } -#endif + object_transform_light_sample(kg, ls, object, time); } __device float triangle_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t) { + float pdf = kernel_data.integrator.pdf_triangles; float cos_pi = fabsf(dot(Ng, I)); if(cos_pi == 0.0f) return 0.0f; - return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi; + return t*t*pdf/cos_pi; } +/* Curve Light */ + #ifdef __HAIR__ -/* Strand Light */ __device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object, int segment, float randu, float randv, float time, LightSample *ls) @@ -358,27 +524,16 @@ __device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object ls->P = randu * l * tg + (gd * l + r1) * ls->Ng; ls->object = object; ls->prim = prim; + ls->lamp = ~0; + ls->use_mis = true; ls->t = 0.0f; ls->type = LIGHT_STRAND; ls->eval_fac = 1.0f; ls->shader = __float_as_int(v00.z); -#ifdef __INSTANCING__ - /* instance transform */ - if(ls->object >= 0) { -#ifdef __OBJECT_MOTION__ - Transform itfm; - Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); -#else - Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); -#endif - - ls->P = transform_point(&tfm, ls->P); - ls->Ng = normalize(transform_direction(&tfm, ls->Ng)); - } -#endif + object_transform_light_sample(kg, ls, object, time); } + #endif /* Light Distribution */ @@ -412,7 +567,7 @@ __device int light_distribution_sample(KernelGlobals *kg, float randt) /* Generic Light */ -__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls, float *pdf) +__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls) { /* sample index */ int index = light_distribution_sample(kg, randt); @@ -420,12 +575,12 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra /* fetch light data */ float4 l = kernel_tex_fetch(__light_distribution, index); int prim = __float_as_int(l.y); -#ifdef __HAIR__ - int segment = __float_as_int(l.z); -#endif if(prim >= 0) { int object = __float_as_int(l.w); +#ifdef __HAIR__ + int segment = __float_as_int(l.z); +#endif #ifdef __HAIR__ if (segment != ~0) @@ -433,27 +588,15 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra else #endif triangle_light_sample(kg, prim, object, randu, randv, time, ls); + + /* compute incoming direction, distance and pdf */ + ls->D = normalize_len(ls->P - P, &ls->t); + ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t); } else { - int point = -prim-1; - regular_light_sample(kg, point, randu, randv, P, ls, pdf); + int lamp = -prim-1; + lamp_light_sample(kg, lamp, randu, randv, P, ls); } - - /* compute incoming direction and distance */ - if(ls->t != FLT_MAX) - ls->D = normalize_len(ls->P - P, &ls->t); -} - -__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) -{ - float pdf; - - if(ls->prim != ~0) - pdf = triangle_light_pdf(kg, ls->Ng, I, t); - else - pdf = regular_light_pdf(kg, ls->Ng, I, t); - - return pdf; } __device int light_select_num_samples(KernelGlobals *kg, int index) @@ -462,18 +605,26 @@ __device int light_select_num_samples(KernelGlobals *kg, int index) return __float_as_int(data3.x); } -__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf) +__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls) { - regular_light_sample(kg, index, randu, randv, P, ls, pdf); - - /* compute incoming direction and distance */ - if(ls->t != FLT_MAX) - ls->D = normalize_len(ls->P - P, &ls->t); + lamp_light_sample(kg, index, randu, randv, P, ls); } -__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t) +__device int lamp_light_eval_sample(KernelGlobals *kg, float randt) { - return regular_light_pdf(kg, ls->Ng, I, t); + /* sample index */ + int index = light_distribution_sample(kg, randt); + + /* fetch light data */ + float4 l = kernel_tex_fetch(__light_distribution, index); + int prim = __float_as_int(l.y); + + if(prim < 0) { + int lamp = -prim-1; + return lamp; + } + else + return ~0; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 20feaf50a2e..87a10e8bba7 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -238,6 +238,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, float min_ray_pdf = FLT_MAX; float ray_pdf = 0.0f; + float ray_t = 0.0f; PathState state; int rng_offset = PRNG_BASE_NUM; @@ -248,8 +249,29 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* intersect scene */ Intersection isect; uint visibility = path_state_ray_visibility(kg, &state); + bool hit = scene_intersect(kg, &ray, visibility, &isect); - if(!scene_intersect(kg, &ray, visibility, &isect)) { +#ifdef __LAMP_MIS__ + if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) { + /* ray starting from previous non-transparent bounce */ + Ray light_ray; + + light_ray.P = ray.P - ray_t*ray.D; + ray_t += isect.t; + light_ray.D = ray.D; + light_ray.t = ray_t; + light_ray.time = ray.time; + + /* intersect with lamp */ + float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); + float3 emission; + + if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission)) + path_radiance_accum_emission(&L, throughput, emission, state.bounce); + } +#endif + + if(!hit) { /* eval background shader if nothing hit */ if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { L_transparent += average(throughput); @@ -313,7 +335,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + /* todo: is isect.t wrong here for transparent surfaces? */ + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -374,18 +397,19 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif - if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput, &L_light, shadow, state.bounce, is_lamp); } } @@ -422,6 +446,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; + ray_t = 0.0f; min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -459,13 +484,36 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) { + float ray_t = 0.0f; + /* path iteration */ for(;; rng_offset += PRNG_BOUNCE_NUM) { /* intersect scene */ Intersection isect; uint visibility = path_state_ray_visibility(kg, &state); + bool hit = scene_intersect(kg, &ray, visibility, &isect); - if(!scene_intersect(kg, &ray, visibility, &isect)) { +#ifdef __LAMP_MIS__ + if(kernel_data.integrator.pdf_lights > 0.0f && !(state.flag & PATH_RAY_CAMERA)) { + /* ray starting from previous non-transparent bounce */ + Ray light_ray; + + light_ray.P = ray.P - ray_t*ray.D; + ray_t += isect.t; + light_ray.D = ray.D; + light_ray.t = ray_t; + light_ray.time = ray.time; + + /* intersect with lamp */ + float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT); + float3 emission; + + if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission)) + path_radiance_accum_emission(L, throughput, emission, state.bounce); + } +#endif + + if(!hit) { #ifdef __BACKGROUND__ /* sample background shader */ float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf); @@ -496,7 +544,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(L, throughput, emission, state.bounce); } #endif @@ -557,19 +605,20 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif /* sample random light */ - if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(L, throughput, &L_light, shadow, state.bounce, is_lamp); } } @@ -606,6 +655,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; + ray_t = 0.0f; min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -697,7 +747,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam #ifdef __EMISSION__ /* emission */ if(sd.flag & SD_EMISSION) { - float3 emission = indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf); + float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); path_radiance_accum_emission(&L, throughput, emission, state.bounce); } #endif @@ -760,7 +810,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(sd.flag & SD_BSDF_HAS_EVAL) { Ray light_ray; BsdfEval L_light; - bool is_lamp; + int lamp; #ifdef __OBJECT_MOTION__ light_ray.time = sd.time; @@ -778,12 +828,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam float light_u = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_U); float light_v = path_rng(kg, rng, sample*num_samples + j, rng_offset + PRNG_LIGHT_V); - if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); } } @@ -807,12 +858,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam if(kernel_data.integrator.num_all_lights) light_t = 0.5f*light_t; - if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { + if(direct_emission(kg, &sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &lamp)) { /* trace shadow ray */ float3 shadow; if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { /* accumulate */ + bool is_lamp = (lamp != ~0); path_radiance_accum_light(&L, throughput*num_samples_inv, &L_light, shadow, state.bounce, is_lamp); } } @@ -885,7 +937,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam bsdf_ray.time = sd.time; #endif - kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer, + kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer, tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); } } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 2bd6b5859f3..102be440978 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -48,6 +48,7 @@ CCL_NAMESPACE_BEGIN #endif #define __NON_PROGRESSIVE__ #define __HAIR__ +#define __LAMP_MIS__ #endif #ifdef __KERNEL_CUDA__ @@ -384,7 +385,7 @@ typedef enum AttributeStandard { /* Closure data */ -#define MAX_CLOSURE 8 +#define MAX_CLOSURE 16 typedef struct ShaderClosure { ClosureType type; @@ -636,6 +637,7 @@ typedef struct KernelIntegrator { int num_all_lights; float pdf_triangles; float pdf_lights; + float inv_pdf_lights; int pdf_background_res; /* bounces */ @@ -671,7 +673,7 @@ typedef struct KernelIntegrator { int transmission_samples; int ao_samples; int mesh_light_samples; - int pad1, pad2; + int pad1; } KernelIntegrator; typedef struct KernelBVH { diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 28742d56e3b..92a023bd765 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -605,7 +605,11 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD return set_attribute_int(3, type, derivatives, val); } else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) +#ifdef __HAIR__ && sd->segment == ~0) { +#else + ) { +#endif float3 P[3]; triangle_vertices(kg, sd->prim, P); @@ -675,7 +679,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri else { object = sd->object; prim = sd->prim; +#ifdef __HAIR__ segment = sd->segment; +#else + segment = ~0; +#endif if (object == ~0) return get_background_attribute(kg, sd, name, type, derivatives, val); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 59e307bb408..a32c526a2be 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -457,7 +457,11 @@ float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem) { /* for OSL, a hash map is used to lookup the attribute by name. */ - int object = sd->object*ATTR_PRIM_TYPES + (sd->segment != ~0); + int object = sd->object*ATTR_PRIM_TYPES; +#ifdef __HAIR__ + if(sd->segment != ~0) object += ATTR_PRIM_CURVE; +#endif + OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object]; ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id))); OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname); diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index c8e3e94ec98..1b94d603a26 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -323,6 +323,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* precompute pdfs */ kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_lights = 0.0f; + kintegrator->inv_pdf_lights = 0.0f; /* sample one, with 0.5 probability of light or triangle */ kintegrator->num_all_lights = num_lights; @@ -337,6 +338,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen kintegrator->pdf_lights = 1.0f/num_lights; if(trianglearea > 0.0f) kintegrator->pdf_lights *= 0.5f; + + kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights; } /* CDF */ @@ -349,6 +352,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen kintegrator->num_all_lights = 0; kintegrator->pdf_triangles = 0.0f; kintegrator->pdf_lights = 0.0f; + kintegrator->inv_pdf_lights = 0.0f; } } @@ -475,16 +479,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce if(light->type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f; + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_DISTANT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float angle = atanf(radius); + float cosangle = cosf(angle); + float area = M_PI_F*radius*radius; + float invarea = (area > 0.0f)? 1.0f/area: 1.0f; + light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea); light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } @@ -499,21 +512,25 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce else if(light->type == LIGHT_AREA) { float3 axisu = light->axisu*(light->sizeu*light->size); float3 axisv = light->axisv*(light->sizev*light->size); + float area = len(axisu)*len(axisv); + float invarea = (area > 0.0f)? 1.0f/area: 0.0f; light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z); - light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z); + light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z); } else if(light->type == LIGHT_SPOT) { shader_id &= ~SHADER_AREA_LIGHT; + float radius = light->size; + float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f; float spot_angle = cosf(light->spot_angle*0.5f); float spot_smooth = (1.0f - spot_angle)*light->spot_smooth; light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z); - light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y); - light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f); + light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle); + light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z); light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); } } diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 8932c85db07..c37fa1a4dc6 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1161,6 +1161,130 @@ __device float safe_divide(float a, float b) return result; } +/* Ray Intersection */ + +__device bool ray_sphere_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 sphere_P, float sphere_radius, + float3 *isect_P, float *isect_t) +{ + float3 d = sphere_P - ray_P; + float radiussq = sphere_radius*sphere_radius; + float tsq = dot(d, d); + + if(tsq > radiussq) { /* ray origin outside sphere */ + float tp = dot(d, ray_D); + + if(tp < 0.0f) /* dir points away from sphere */ + return false; + + float dsq = tsq - tp*tp; /* pythagoras */ + + if(dsq > radiussq) /* closest point on ray outside sphere */ + return false; + + float t = tp - sqrtf(radiussq - dsq); /* pythagoras */ + + if(t < ray_t) { + *isect_t = t; + *isect_P = ray_P + ray_D*t; + return true; + } + } + + return false; +} + +__device bool ray_aligned_disk_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 disk_P, float disk_radius, + float3 *isect_P, float *isect_t) +{ + /* aligned disk normal */ + float disk_t; + float3 disk_N = normalize_len(ray_P - disk_P, &disk_t); + float div = dot(ray_D, disk_N); + + if(div == 0.0f) + return false; + + /* compute t to intersection point */ + float t = -disk_t/div; + if(t < 0.0f || t > ray_t) + return false; + + /* test if within radius */ + float3 P = ray_P + ray_D*t; + if(len_squared(P - disk_P) > disk_radius*disk_radius) + return false; + + *isect_P = P; + *isect_t = t; + + return true; +} + +__device bool ray_triangle_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 v0, float3 v1, float3 v2, + float3 *isect_P, float *isect_t) +{ + /* Calculate intersection */ + float3 e1 = v1 - v0; + float3 e2 = v2 - v0; + float3 s1 = cross(ray_D, e2); + + const float divisor = dot(s1, e1); + if(divisor == 0.0f) + return false; + + const float invdivisor = 1.0f/divisor; + + /* compute first barycentric coordinate */ + const float3 d = ray_P - v0; + const float u = dot(d, s1)*invdivisor; + if(u < 0.0f) + return false; + + /* Compute second barycentric coordinate */ + const float3 s2 = cross(d, e1); + const float v = dot(ray_D, s2)*invdivisor; + if(v < 0.0f) + return false; + + const float b0 = 1.0f - u - v; + if(b0 < 0.0f) + return false; + + /* compute t to intersection point */ + const float t = dot(e2, s2)*invdivisor; + if(t < 0.0f || t > ray_t) + return false; + + *isect_t = t; + *isect_P = ray_P + ray_D*t; + + return true; +} + +__device bool ray_quad_intersect( + float3 ray_P, float3 ray_D, float ray_t, + float3 quad_P, float3 quad_u, float3 quad_v, + float3 *isect_P, float *isect_t) +{ + float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; + float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; + float3 v2 = quad_P + quad_u*0.5f + quad_v*0.5f; + float3 v3 = quad_P - quad_u*0.5f + quad_v*0.5f; + + if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v1, v2, isect_P, isect_t)) + return true; + else if(ray_triangle_intersect(ray_P, ray_D, ray_t, v0, v2, v3, isect_P, isect_t)) + return true; + + return false; +} + CCL_NAMESPACE_END #endif /* __UTIL_MATH_H__ */ From 8cf374d4012e193a50a58f1e2abcdae306ae33cd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 9 Jan 2013 22:06:03 +0000 Subject: [PATCH 093/132] Cycles: different fix for perlin noise generating nan values, now check for the result to be finite afterwards which is a bit faster and works for OSL too without needing to slow down OSL itself. --- intern/cycles/kernel/kernel_path.h | 8 +++++++ .../kernel/shaders/node_musgrave_texture.osl | 24 +++++++++---------- intern/cycles/kernel/shaders/node_texture.h | 13 +++++++++- intern/cycles/kernel/svm/svm_noise.h | 15 ++++++++---- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 87a10e8bba7..6302031475a 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -238,7 +238,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, float min_ray_pdf = FLT_MAX; float ray_pdf = 0.0f; +#ifdef __LAMP_MIS__ float ray_t = 0.0f; +#endif PathState state; int rng_offset = PRNG_BASE_NUM; @@ -446,7 +448,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } @@ -484,7 +488,9 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) { +#ifdef __LAMP_MIS__ float ray_t = 0.0f; +#endif /* path iteration */ for(;; rng_offset += PRNG_BOUNCE_NUM) { @@ -655,7 +661,9 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* set labels */ if(!(label & LABEL_TRANSPARENT)) { ray_pdf = bsdf_pdf; +#ifdef __LAMP_MIS__ ray_t = 0.0f; +#endif min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); } diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index 541f26b4e56..38232ea0aeb 100644 --- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl @@ -37,14 +37,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float int i; for (i = 0; i < (int)octaves; i++) { - value += noise("perlin", p) * pwr; + value += safe_noise(p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value += rmd * noise("perlin", p) * pwr; + value += rmd * safe_noise(p) * pwr; return value; } @@ -65,14 +65,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar int i; for (i = 0; i < (int)octaves; i++) { - value *= (pwr * noise("perlin", p) + 1.0); + value *= (pwr * safe_noise(p) + 1.0); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); if (rmd != 0.0) - value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */ + value *= (rmd * pwr * safe_noise(p) + 1.0); /* correct? */ return value; } @@ -93,11 +93,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna int i; /* first unscaled octave of function; later octaves are scaled */ - value = offset + noise("perlin", p); + value = offset + safe_noise(p); p *= lacunarity; for (i = 1; i < (int)octaves; i++) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += increment; pwr *= pwHL; p *= lacunarity; @@ -105,7 +105,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna rmd = octaves - floor(octaves); if (rmd != 0.0) { - increment = (noise("perlin", p) + offset) * pwr * value; + increment = (safe_noise(p) + offset) * pwr * value; value += rmd * increment; } @@ -128,7 +128,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - result = noise("perlin", p) + offset; + result = safe_noise(p) + offset; weight = gain * result; p *= lacunarity; @@ -136,7 +136,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, if (weight > 1.0) weight = 1.0; - signal = (noise("perlin", p) + offset) * pwr; + signal = (safe_noise(p) + offset) * pwr; pwr *= pwHL; result += weight * signal; weight *= gain * signal; @@ -145,7 +145,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, rmd = octaves - floor(octaves); if (rmd != 0.0) - result += rmd * ((noise("perlin", p) + offset) * pwr); + result += rmd * ((safe_noise(p) + offset) * pwr); return result; } @@ -166,7 +166,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float pwr = pwHL; int i; - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; result = signal; weight = 1.0; @@ -174,7 +174,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, for (i = 1; i < (int)octaves; i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); - signal = offset - fabs(noise("perlin", p)); + signal = offset - fabs(safe_noise(p)); signal *= signal; signal *= weight; result += signal * pwr; diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h index 1b3ba8207ab..2de0fc0ea57 100644 --- a/intern/cycles/kernel/shaders/node_texture.h +++ b/intern/cycles/kernel/shaders/node_texture.h @@ -151,12 +151,23 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; } /* Noise Bases */ +float safe_noise(point p) +{ + float f = noise(p); + + /* can happen for big coordinates, things even out to 0.5 then anyway */ + if(!isfinite(f)) + return 0.5; + + return f; +} + float noise_basis(point p, string basis) { float result = 0.0; if (basis == "Perlin") - result = noise(p); /* returns perlin noise in range 0..1 */ + result = safe_noise(p); /* returns perlin noise in range 0..1 */ if (basis == "Voronoi F1") result = voronoi_F1S(p); if (basis == "Voronoi F2") diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h index 224a1d96543..5ead6486dd6 100644 --- a/intern/cycles/kernel/svm/svm_noise.h +++ b/intern/cycles/kernel/svm/svm_noise.h @@ -84,9 +84,8 @@ __device uint phash(int kx, int ky, int kz, int3 p) __device float floorfrac(float x, int* i) { - float f = floorf(x); - *i = (int)f; - return x - f; + *i = quick_floor(x); + return x - *i; } __device float fade(float t) @@ -133,7 +132,10 @@ __device_noinline float perlin(float x, float y, float z) grad (hash (X+1, Y , Z+1), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (hash (X , Y+1, Z+1), fx , fy-1.0f, fz-1.0f ), grad (hash (X+1, Y+1, Z+1), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } __device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod) @@ -162,7 +164,10 @@ __device_noinline float perlin_periodic(float x, float y, float z, float3 pperio grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )), nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ), grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f )))); - return scale3(result); + float r = scale3(result); + + /* can happen for big coordinates, things even out to 0.0 then anyway */ + return (isfinite(r))? r: 0.0f; } /* perlin noise in range 0..1 */ From ceb9701507848865434557af4ec89ce9b6560446 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 04:43:31 +0000 Subject: [PATCH 094/132] don't store bevel weights or edge crease customdata layers in editmode unless they are needed. configurable in 'Geometry Data' panel, will be added when running crease edges transform for example. --- .../startup/bl_ui/properties_data_mesh.py | 17 ++- source/blender/blenkernel/BKE_DerivedMesh.h | 3 + source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/BKE_customdata.h | 1 + source/blender/blenkernel/BKE_mesh.h | 2 + .../blender/blenkernel/intern/DerivedMesh.c | 3 + .../blender/blenkernel/intern/cdderivedmesh.c | 22 +-- source/blender/blenkernel/intern/customdata.c | 8 + .../blenkernel/intern/editderivedmesh.c | 33 ++-- source/blender/blenkernel/intern/mesh.c | 36 +++++ .../blenkernel/intern/modifiers_bmesh.c | 26 ++-- source/blender/blenloader/intern/readfile.c | 9 ++ source/blender/bmesh/bmesh_class.h | 12 ++ source/blender/bmesh/intern/bmesh_mesh_conv.c | 108 ++++++++++--- source/blender/bmesh/intern/bmesh_mesh_conv.h | 4 + source/blender/editors/mesh/editmesh_select.c | 12 ++ .../editors/space_view3d/view3d_buttons.c | 144 ++++++++++-------- .../editors/transform/transform_conversions.c | 30 ++-- source/blender/makesdna/DNA_mesh_types.h | 10 +- source/blender/makesrna/intern/rna_mesh.c | 16 ++ 20 files changed, 355 insertions(+), 143 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 538063cb038..373d727063e 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -372,17 +372,20 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): def draw(self, context): layout = self.layout - # me = context.mesh + obj = context.object + me = context.mesh col = layout.column() - # sticky has no UI access since 2.49 - we may remove - ''' - row = col.row(align=True) - row.operator("mesh.customdata_create_sticky") - row.operator("mesh.customdata_clear_sticky", icon='X') - ''' + col.operator("mesh.customdata_clear_mask", icon='X') col.operator("mesh.customdata_clear_skin", icon='X') + col = layout.column() + + col.enabled = (obj.mode != 'EDIT') + col.prop(me, "use_customdata_vertex_bevel") + col.prop(me, "use_customdata_edge_bevel") + col.prop(me, "use_customdata_edge_crease") + class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index ed90c63d949..f06547fe2e3 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -173,6 +173,9 @@ struct DerivedMesh { float auto_bump_scale; DMDirtyFlag dirty; + /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */ + char cd_flag; + /** Calculate vert and face normals */ void (*calcNormals)(DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 49301f47df6..9c6d26c08bc 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 7 +#define BLENDER_SUBVERSION 8 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 3a65c8d3b72..6f9e046f212 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -249,6 +249,7 @@ void *CustomData_get_layer(const struct CustomData *data, int type); void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); +int CustomData_get_offset(const struct CustomData *data, int type); int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index db9f1228f76..5f4cc65ae7e 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -334,6 +334,8 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop, struct MPoly *mp, float angles[]); +void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ec8d37e1ae3..4ffbc3e6de1 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH, CD_CALLOC, numPolys); + dm->cd_flag = source->cd_flag; + dm->type = type; dm->numVertData = numVerts; dm->numEdgeData = numEdges; @@ -488,6 +490,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop); CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly); + me->cd_flag = dm->cd_flag; if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { KeyBlock *kb; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 517a5d6f6c6..0321b963256 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1743,6 +1743,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) mesh->totloop, mesh->totpoly); dm->deformedOnly = 1; + dm->cd_flag = mesh->cd_flag; alloctype = CD_REFERENCE; @@ -1926,13 +1927,12 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); int *index, add_orig; - int has_crease, has_edge_bweight, has_vert_bweight; CustomDataMask mask; unsigned int i, j; - has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT); - has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT); - has_crease = CustomData_has_layer(&bm->edata, CD_CREASE); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); dm->deformedOnly = 1; @@ -1972,8 +1972,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, mv->flag = BM_vert_flag_to_mflag(eve); - if (has_vert_bweight) - mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); + if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); if (add_orig) *index = i; @@ -1991,11 +1990,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, med->v1 = BM_elem_index_get(eed->v1); med->v2 = BM_elem_index_get(eed->v2); - if (has_crease) - med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f); - if (has_edge_bweight) - med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f); - med->flag = BM_edge_flag_to_mflag(eed); /* handle this differently to editmode switching, @@ -2006,6 +2000,9 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, } } + if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); + CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i); if (add_orig) *index = i; } @@ -2068,6 +2065,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, } bm->elem_index_dirty &= ~BM_FACE; + dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); + return dm; } @@ -2105,6 +2104,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces) DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); dm->deformedOnly = source->deformedOnly; + dm->cd_flag = source->cd_flag; dm->dirty = source->dirty; CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 4c6b0c08158..82c0535254b 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2095,6 +2095,14 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, return data->layers[layer_index].data; } +int CustomData_get_offset(const CustomData *data, int type) +{ + /* get the layer index of the active layer of type */ + int layer_index = CustomData_get_layer_index(data, type); + if (layer_index < 0) return -1; + + return data->layers[layer_index].offset; +} int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) { diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index c3587f6b188..fd7c3f55bb0 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1402,7 +1402,7 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) BMesh *bm = bmdm->tc->bm; BMVert *eve; BMIter iter; - const int has_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); if (bmdm->vertexCos) { int i; @@ -1412,9 +1412,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) normal_float_to_short_v3(vert_r->no, eve->no); vert_r->flag = BM_vert_flag_to_mflag(eve); - if (has_bweight) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); - } + if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); + vert_r++; } } @@ -1424,9 +1423,8 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r) normal_float_to_short_v3(vert_r->no, eve->no); vert_r->flag = BM_vert_flag_to_mflag(eve); - if (has_bweight) { - vert_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f); - } + if (cd_vert_bweight_offset != -1) vert_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); + vert_r++; } } @@ -1437,24 +1435,20 @@ static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r) BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm; BMEdge *eed; BMIter iter; - const int has_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT); - const int has_crease = CustomData_has_layer(&bm->edata, CD_CREASE); + + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (has_bweight) { - edge_r->bweight = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f); - } - - if (has_crease) { - edge_r->crease = (unsigned char) (BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f); - } + edge_r->v1 = BM_elem_index_get(eed->v1); + edge_r->v2 = BM_elem_index_get(eed->v2); edge_r->flag = BM_edge_flag_to_mflag(eed); - edge_r->v1 = BM_elem_index_get(eed->v1); - edge_r->v2 = BM_elem_index_get(eed->v2); + if (cd_edge_crease_offset != -1) edge_r->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) edge_r->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); edge_r++; } @@ -1662,6 +1656,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, em->bm->totvert, em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface); + /* could also get from the objects mesh directly */ + bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm); + bmdm->dm.getVertCos = emDM_getVertCos; bmdm->dm.getMinMax = emDM_getMinMax; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 30e7cb3bb36..806df92a4cb 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -3337,3 +3337,39 @@ void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop, } } #endif + + +void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) +{ + if (UNLIKELY(mesh->cd_flag)) { + return; + } + else { + MVert *mv; + MEdge *med; + int i; + + for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) { + if (mv->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + break; + } + } + + for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) { + if (med->bweight != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { + break; + } + } + if (med->crease != 0) { + mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; + if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + break; + } + } + } + + } +} diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 3939c45a436..849471a083b 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -62,6 +62,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); char has_orig_hflag = 0; + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + if (is_init == FALSE) { /* check if we have an origflag */ has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0; @@ -75,16 +79,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP); CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE); + if (is_init) { + BM_mesh_cd_flag_apply(bm, dm->cd_flag); + } + + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + totvert = dm->getNumVerts(dm); totedge = dm->getNumEdges(dm); /* totface = dm->getNumPolys(dm); */ /* UNUSED */ - /* add crease layer */ - BM_data_layer_add(bm, &bm->edata, CD_CREASE); - /* add bevel weight layers */ - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - vtable = MEM_callocN(sizeof(void **) * totvert, __func__); etable = MEM_callocN(sizeof(void **) * totedge, __func__); @@ -100,7 +106,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) vtable[i] = v; /* add bevel weight */ - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f); + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f); if (UNLIKELY(has_orig_hflag & BM_VERT)) { int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX); @@ -121,10 +127,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true); etable[i] = e; - /* add crease */ - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f); - /* add bevel weight */ - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f); if (UNLIKELY(has_orig_hflag & BM_EDGE)) { int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index c8bd02e2776..2235906329d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8645,6 +8645,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (!MAIN_VERSION_ATLEAST(main, 265, 8)) { + Mesh *me; + for (me = main->mesh.first; me; me = me->id.next) { + BKE_mesh_do_versions_cd_flag_init(me); + } + } + + // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) { + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 5d7ded2024d..824884fb4e4 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -254,6 +254,18 @@ enum { /* defines */ +#define BM_ELEM_CD_GET_VOID_P(ele, offset) \ + ((void)0, (void *)((char *)(ele)->head.data + (offset))) + +#define BM_ELEM_CD_SET_FLOAT(ele, offset, f) \ + { *((float *)((char *)(ele)->head.data + (offset))) = (f); } (void)0 + +#define BM_ELEM_CD_GET_FLOAT(ele, offset) \ + ((void)0, *((float *)((char *)(ele)->head.data + (offset)))) + +#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \ + (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f) + /*forward declarations*/ #ifdef USE_BMESH_HOLES diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 53b29a4ce74..8198e30bac6 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -98,6 +98,70 @@ #include "bmesh.h" #include "intern/bmesh_private.h" /* for element checking */ +void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) +{ + const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; + BM_mesh_cd_flag_apply(bm, cd_flag_all); + if (mesh) { + mesh->cd_flag = cd_flag_all; + } +} + +void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) +{ + /* CustomData_bmesh_init_pool() must run first */ + BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); + BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL); + + if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) { + if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_CREASE) { + if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_add(bm, &bm->edata, CD_CREASE); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_free(bm, &bm->edata, CD_CREASE); + } + } +} + +char BM_mesh_cd_flag_from_bmesh(BMesh *bm) +{ + char cd_flag = 0; + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + cd_flag |= ME_CDFLAG_EDGE_CREASE; + } + return cd_flag; +} + /* Mesh -> BMesh */ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) { @@ -116,6 +180,10 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) int *keyi; int totuv, i, j; + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + /* free custom data */ /* this isnt needed in most cases but do just incase */ CustomData_free(&bm->vdata, bm->totvert); @@ -152,15 +220,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name); } - if (!CustomData_has_layer(&bm->edata, CD_CREASE)) - CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) - CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) - CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - if ((act_key_nr != 0) && (me->key != NULL)) { actkey = BLI_findlink(&me->key->block, act_key_nr - 1); } @@ -205,6 +264,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); + BM_mesh_cd_flag_apply(bm, me->cd_flag); + + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ @@ -223,7 +288,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) /* Copy Custom Data */ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f); /* set shapekey data */ if (me->key) { @@ -269,8 +334,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) /* Copy Custom Data */ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f); - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f); + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f); + } bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */ @@ -496,6 +562,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) BMIter iter, liter; int i, j, ototvert; + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + ototvert = me->totvert; /* new vertex block */ @@ -555,10 +625,6 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT); - - mvert->bweight = bweight ? (char)((*bweight) * 255) : 0; - copy_v3_v3(mvert->co, v->co); normal_float_to_short_v3(mvert->no, v->no); @@ -569,6 +635,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) /* copy over customdat */ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); + if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); + i++; mvert++; @@ -579,13 +647,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) med = medge; i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE); - float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT); - med->v1 = BM_elem_index_get(e->v1); med->v2 = BM_elem_index_get(e->v2); - med->crease = crease ? (char)((*crease) * 255) : 0; - med->bweight = bweight ? (char)((*bweight) * 255) : 0; med->flag = BM_edge_flag_to_mflag(e); @@ -596,6 +659,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) bmesh_quick_edgedraw_flag(med, e); + if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); + i++; med++; BM_CHECK_ELEMENT(e); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index f9c51584081..55ac39c6745 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -34,6 +34,10 @@ struct Mesh; +void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag); +void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag); +char BM_mesh_cd_flag_from_bmesh(BMesh *bm); + void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, int set_key, int act_key_nr); void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, int dotess); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 0735b95588e..0af2913dae0 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -42,6 +42,7 @@ #include "BKE_displist.h" #include "BKE_report.h" #include "BKE_paint.h" +#include "BKE_mesh.h" #include "BKE_tessmesh.h" #include "IMB_imbuf_types.h" @@ -1351,6 +1352,17 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge /* note, would pass BM_EDGE except we are looping over all edges anyway */ BM_mesh_elem_index_ensure(bm, BM_VERT /* | BM_EDGE */); + switch (scene->toolsettings->edge_mode) { + case EDGE_MODE_TAG_CREASE: + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_CREASE); + break; + case EDGE_MODE_TAG_BEVEL: + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(OBACT), ME_CDFLAG_EDGE_BWEIGHT); + break; + default: + break; + } + BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == FALSE) { BM_elem_flag_disable(e, BM_ELEM_TAG); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 6a095a8d2b1..cc3885b5327 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -179,6 +179,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BMEdge *eed; BMIter iter; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs; @@ -187,24 +192,32 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float tot++; add_v3_v3(&median[LOC_X], eve->co); - vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) { + /* TODO cd_vert_bweight_offset */ + (void)cd_vert_bweight_offset; + + if (cd_vert_skin_offset != -1) { + vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ totskinradius++; } } } - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *f; + if ((cd_edge_bweight_offset != -1) || + (cd_edge_crease_offset != -1)) + { + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (cd_edge_bweight_offset != -1) { + median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); + } - totedgedata++; - f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - median[M_CREASE] += f ? *f : 0.0f; + if (cd_edge_crease_offset != -1) { + median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset); + } - f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - median[M_WEIGHT] += f ? *f : 0.0f; + totedgedata++; + } } } @@ -412,14 +425,26 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float /* Meshes... */ if (meshdata) { if (totedgedata) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, - totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + Mesh *me = ob->data; + BMEditMesh *em = me->edit_btmesh; + BMesh *bm = em->bm; + + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + + if (cd_edge_crease_offset != -1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); + } + + if (cd_edge_bweight_offset != -1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + } } if (totskinradius) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, @@ -502,91 +527,85 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } if (median[M_CREASE] != 0.0f) { - BMEdge *eed; + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); + BMEdge *eed; if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease = sca; - } + BM_ELEM_CD_SET_FLOAT(eed, cd_edge_crease_offset, sca); } } } else if (sca > 0.0f) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease *= sca; - CLAMP(*crease, 0.0f, 1.0f); - } + float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); + *crease *= sca; + CLAMP(*crease, 0.0f, 1.0f); } } } else { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *crease = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - if (crease) { - *crease = 1.0f + ((1.0f - *crease) * sca); - CLAMP(*crease, 0.0f, 1.0f); - } + float *crease = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_crease_offset); + *crease = 1.0f + ((1.0f - *crease) * sca); + CLAMP(*crease, 0.0f, 1.0f); } } } } if (median[M_WEIGHT] != 0.0f) { - BMEdge *eed; + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); + BMEdge *eed; + + BLI_assert(cd_edge_bweight_offset != -1); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight = sca; - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight = sca; } } } else if (sca > 0.0f) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight *= sca; - CLAMP(*bweight, 0.0f, 1.0f); - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight *= sca; + CLAMP(*bweight, 0.0f, 1.0f); } } } else { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float *bweight = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - if (bweight) { - *bweight = 1.0f + ((1.0f - *bweight) * sca); - CLAMP(*bweight, 0.0f, 1.0f); - } + float *bweight = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_bweight_offset); + *bweight = 1.0f + ((1.0f - *bweight) * sca); + CLAMP(*bweight, 0.0f, 1.0f); } } } } if (median[M_SKIN_X] != 0.0f) { - BMVert *eve; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); /* That one is not clamped to [0.0, 1.0]. */ float sca = ve_median[M_SKIN_X]; + BMVert *eve; + + BLI_assert(cd_vert_skin_offset != -1); + if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[0] = sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[0] = sca; } } } @@ -594,23 +613,25 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[0] *= sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[0] *= sca; } } } } if (median[M_SKIN_Y] != 0.0f) { - BMVert *eve; + const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); /* That one is not clamped to [0.0, 1.0]. */ float sca = ve_median[M_SKIN_Y]; + BMVert *eve; + + BLI_assert(cd_vert_skin_offset != -1); + if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[1] = sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[1] = sca; } } } @@ -618,9 +639,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); - if (vs) - vs->radius[1] *= sca; + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + vs->radius[1] *= sca; } } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 63eea8b8d4c..cc5a56a34f8 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -289,6 +289,7 @@ static void createTransEdge(TransInfo *t) float mtx[3][3], smtx[3][3]; int count = 0, countsel = 0; int propmode = t->flag & T_PROP_EDIT; + int cd_edge_float_offset; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { @@ -312,8 +313,22 @@ static void createTransEdge(TransInfo *t) copy_m3_m4(mtx, t->obedit->obmat); pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); + /* create data we need */ + if (t->mode == TFM_BWEIGHT) { + BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT); + cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); + } + else { //if (t->mode == TFM_CREASE) { + BLI_assert(t->mode == TFM_CREASE); + BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE); + cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); + } + + BLI_assert(cd_edge_float_offset != -1); + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) { + float *fl_ptr; /* need to set center for center calculations */ mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co); @@ -327,17 +342,10 @@ static void createTransEdge(TransInfo *t) copy_m3_m3(td->mtx, mtx); td->ext = NULL; - if (t->mode == TFM_BWEIGHT) { - float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); - td->val = bweight; - td->ival = bweight ? *bweight : 1.0f; - } - else { - float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); - BLI_assert(t->mode == TFM_CREASE); - td->val = crease; - td->ival = crease ? *crease : 0.0f; - } + + fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset); + td->val = fl_ptr; + td->ival = *fl_ptr; td++; } diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 4c9f6014445..0c708ddcbef 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -119,7 +119,10 @@ typedef struct Mesh { short texflag, drawflag; short smoothresh, flag; - short subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED; + /* customdata flag, for bevel-weight and crease, which are now optional */ + char cd_flag, pad; + + char subdiv DNA_DEPRECATED, subdivr DNA_DEPRECATED; char subsurftype DNA_DEPRECATED; /* only kept for backwards compat, not used anymore */ char editflag; @@ -172,6 +175,11 @@ typedef struct TFace { #define ME_DS_EXPAND 512 #define ME_SCULPT_DYNAMIC_TOPOLOGY 1024 +/* me->cd_flag */ +#define ME_CDFLAG_VERT_BWEIGHT (1 << 0) +#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1) +#define ME_CDFLAG_EDGE_CREASE (1 << 2) + /* me->drawflag, short */ #define ME_DRAWEDGES (1 << 0) #define ME_DRAWFACES (1 << 1) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index d6ded23ffed..d5b8e4cddeb 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2998,6 +2998,22 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Mesh_update_vertmask"); + + + /* customdata flags */ + prop = RNA_def_property(srna, "use_customdata_vertex_bevel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_VERT_BWEIGHT); + RNA_def_property_ui_text(prop, "Store Vertex Bevel Weight", ""); + + prop = RNA_def_property(srna, "use_customdata_edge_bevel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_BWEIGHT); + RNA_def_property_ui_text(prop, "Store Edge Bevel Weight", ""); + + prop = RNA_def_property(srna, "use_customdata_edge_crease", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "cd_flag", ME_CDFLAG_EDGE_CREASE); + RNA_def_property_ui_text(prop, "Store Edge Crease", ""); + + /* readonly editmesh info - use for extrude menu */ prop = RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_funcs(prop, "rna_Mesh_tot_vert_get", NULL, NULL); From 70833509132b86198742ee1eec017e7869c328ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 04:46:51 +0000 Subject: [PATCH 095/132] fix for editmesh calculating normals twice when using the number-buttons. --- source/blender/editors/space_view3d/view3d_buttons.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index cc3885b5327..4ca0284d0e0 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -645,7 +645,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } } - EDBM_mesh_normals_update(em); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu = ob->data; From 0ce1be552e8d240f8fd17d9b21e045045c85cc5b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 05:35:10 +0000 Subject: [PATCH 096/132] transforming verts was getting the bevel weight for each vertex even if bevel-weight wasnt being transformed. --- .../editors/transform/transform_conversions.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index cc5a56a34f8..d38bdb178fb 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1915,8 +1915,8 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx td->val = NULL; td->extra = NULL; if (t->mode == TFM_BWEIGHT) { - td->val = bweight; - td->ival = bweight ? *(bweight) : 1.0f; + td->val = bweight; + td->ival = *bweight; } else if (t->mode == TFM_SKIN_RESIZE) { MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, @@ -1952,6 +1952,7 @@ static void createTransEditVerts(TransInfo *t) int mirror = 0; char *selstate = NULL; short selectmode = ts->selectmode; + int cd_vert_bweight_offset = -1; if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_begin(em, TRUE); @@ -2033,6 +2034,10 @@ static void createTransEditVerts(TransInfo *t) } } + if (t->mode == TFM_BWEIGHT) { + BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT); + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + } if (propmode) { t->total = count; @@ -2099,11 +2104,10 @@ static void createTransEditVerts(TransInfo *t) } } - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a = 0; eve; eve = BM_iter_step(&iter), a++) { + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (propmode || selstate[a]) { - float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT); + float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL; VertsToTransData(t, tob, tx, em, eve, bweight); if (tx) From ce4116c35c6d36bc147b8e96377bc895555dbf92 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 05:50:21 +0000 Subject: [PATCH 097/132] don't call BKE_mesh_tessface_ensure() from DM_to_mesh(), caller must do this instead. --- source/blender/blenkernel/intern/DerivedMesh.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4ffbc3e6de1..dde1d5870ca 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -485,6 +485,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) totedge = tmp.totedge = dm->getNumEdges(dm); totloop = tmp.totloop = dm->getNumLoops(dm); totpoly = tmp.totpoly = dm->getNumPolys(dm); + tmp.totface = 0; CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); @@ -541,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) } /* yes, must be before _and_ after tessellate */ - mesh_update_customdata_pointers(&tmp, TRUE); + mesh_update_customdata_pointers(&tmp, false); - BKE_mesh_tessface_calc(&tmp); + /* since 2.65 caller must do! */ + // BKE_mesh_tessface_calc(&tmp); CustomData_free(&me->vdata, me->totvert); CustomData_free(&me->edata, me->totedge); From 35d0e99299cc653c9064026ccbb2b2453483c515 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 08:01:07 +0000 Subject: [PATCH 098/132] Added new scons target: cudakernels It's intended to perform compilation of CUDA kernels only, without doing anything with other sources/resources and main purpose of this target is to be able to compile cuda kernels in completely different environment than the rest of blender was compiled. This is needed for linux build environment, where sm_13 compilation fails dramatically in 32bit chroot but could be compiled in 64bit environment. --- SConstruct | 24 +++++++++++++++++++++--- build_files/scons/tools/btools.py | 15 ++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 90c3c45b302..c50240b85e0 100644 --- a/SConstruct +++ b/SConstruct @@ -275,6 +275,9 @@ if 'blenderlite' in B.targets: if k not in B.arguments: env[k] = v +if 'cudakernels' in B.targets: + env['WITH_BF_CYCLES_CUDA_BINARIES'] = True + # Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX if env['OURPLATFORM']=='darwin': print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --" @@ -651,6 +654,7 @@ datafileslist = [] datafilestargetlist = [] dottargetlist = [] scriptinstall = [] +cubininstall = [] if env['OURPLATFORM']!='darwin': dotblenderinstall = [] @@ -746,7 +750,7 @@ if env['OURPLATFORM']!='darwin': for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']: kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel') cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) - scriptinstall.append(env.Install(dir=dir,source=cubin_file)) + cubininstall.append(env.Install(dir=dir,source=cubin_file)) # osl shaders if env['WITH_BF_CYCLES_OSL']: @@ -857,9 +861,9 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist) if env['OURPLATFORM']=='darwin': allinstall = [blenderinstall, textinstall] elif env['OURPLATFORM']=='linux': - allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall] + allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, iconinstall, cubininstall] else: - allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall] + allinstall = [blenderinstall, dotblenderinstall, scriptinstall, textinstall, cubininstall] if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'): dllsources = [] @@ -989,6 +993,20 @@ buildslave_alias = env.Alias('buildslave', buildslave_cmd) Depends(buildslave_cmd, allinstall) +cudakernels_action = env.Action(btools.cudakernels, btools.cudakernels_print) +cudakernels_cmd = env.Command('cudakernels_exec', None, cudakernels_action) +cudakernels_alias = env.Alias('cudakernels', cudakernels_cmd) + +cudakernel_dir = os.path.join(os.path.abspath(os.path.normpath(B.root_build_dir)), 'intern/cycles/kernel') +cuda_kernels = [] + +for x in env['BF_CYCLES_CUDA_BINARIES_ARCH']: + cubin = os.path.join(cudakernel_dir, 'kernel_' + x + '.cubin') + cuda_kernels.append(cubin) + +Depends(cudakernels_cmd, cuda_kernels) +Depends(cudakernels_cmd, cubininstall) + Default(B.program_list) if not env['WITHOUT_BF_INSTALL']: diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index f7673492013..22360447343 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -215,7 +215,8 @@ def print_targets(targs, bc): def validate_targets(targs, bc): valid_list = ['.', 'blender', 'blenderstatic', 'blenderplayer', 'webplugin', 'blendernogame', 'blenderstaticnogame', 'blenderlite', 'release', - 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave'] + 'everything', 'clean', 'install-bin', 'install', 'nsis','buildslave', + 'cudakernels'] oklist = [] for t in targs: if t in valid_list: @@ -826,6 +827,18 @@ def NSIS_Installer(target=None, source=None, env=None): print data.strip().split("\n")[-1] return rv +def cudakernels_print(target, source, env): + return "Running cudakernels target" + +def cudakernels(target=None, source=None, env=None): + """ + Builder for cuda kernels compilation. Used by release build environment only + """ + + # Currently nothing to do, everything is handled by a dependency resolver + + pass + def check_environ(): problematic_envvars = "" for i in os.environ: From 2a43380dedd2aec7d5cb0260448e894c22da04fb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 08:01:19 +0000 Subject: [PATCH 099/132] Switch linux buildbot to compile all cuda kernels in 64bit environment Solves memory limit issues when building sm_13 for 32bit platform. Some further refinement of patch could be needed. --- SConstruct | 2 + .../config/user-config-cuda-glibc211-i686.py | 6 +++ .../user-config-cuda-glibc211-x86_64.py | 6 +++ .../config/user-config-glibc211-i686.py | 5 +-- .../config/user-config-glibc211-x86_64.py | 5 +-- .../user-config-player-glibc211-i686.py | 2 +- .../user-config-player-glibc211-x86_64.py | 2 +- build_files/buildbot/slave_compile.py | 41 +++++++++++++------ 8 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 build_files/buildbot/config/user-config-cuda-glibc211-i686.py create mode 100644 build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py diff --git a/SConstruct b/SConstruct index c50240b85e0..49e899c3d20 100644 --- a/SConstruct +++ b/SConstruct @@ -276,7 +276,9 @@ if 'blenderlite' in B.targets: env[k] = v if 'cudakernels' in B.targets: + env['WITH_BF_CYCLES'] = True env['WITH_BF_CYCLES_CUDA_BINARIES'] = True + env['WITH_BF_PYTHON'] = False # Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX if env['OURPLATFORM']=='darwin': diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py new file mode 100644 index 00000000000..16733be5a48 --- /dev/null +++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py @@ -0,0 +1,6 @@ +BF_BUILDDIR = '../blender-build/linux-glibc211-i686' +BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' +BF_NUMJOBS = 1 +BF_BITNESS = 32 + +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py new file mode 100644 index 00000000000..60afeccae49 --- /dev/null +++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py @@ -0,0 +1,6 @@ +BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' +BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' +BF_NUMJOBS = 1 +BF_BITNESS = 64 + +BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index 149a01433a6..56eedc3203b 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' @@ -109,8 +109,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a' # Cycles WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] +WITH_BF_CYCLES_CUDA_BINARIES = False WITH_BF_OIIO = True WITH_BF_STATICOIIO = True diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py index 0fae7f0cdb3..ab3efedfb86 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' @@ -109,8 +109,7 @@ BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a' # Cycles WITH_BF_CYCLES = True -WITH_BF_CYCLES_CUDA_BINARIES = True -BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] +WITH_BF_CYCLES_CUDA_BINARIES = False WITH_BF_OIIO = True WITH_BF_STATICOIIO = True diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py index 37fe511fac8..a99337f03e6 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py index 8f51c5ad8be..c17cff2893d 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py @@ -1,6 +1,6 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' -BF_NUMJOBS = 2 +BF_NUMJOBS = 4 # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index fa933a84841..b66a09afe25 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -60,6 +60,26 @@ else: if builder.find('linux') != -1: import shutil + configs = [] + if builder.endswith('linux_glibc211_x86_64_scons'): + configs = ['user-config-player-glibc211-x86_64.py', + 'user-config-cuda-glibc211-x86_64.py', + 'user-config-glibc211-x86_64.py'] + chroot_name = 'buildbot_squeeze_x86_64' + cuda_chroot = 'buildbot_squeeze_x86_64' + elif builder.endswith('linux_glibc211_i386_scons'): + configs = ['user-config-player-glibc211-i686.py', + 'user-config-cuda-glibc211-i686.py', + 'user-config-glibc211-i686.py'] + chroot_name = 'buildbot_squeeze_i686' + + # use 64bit cuda toolkit, so there'll be no memory limit issues + cuda_chroot = 'buildbot_squeeze_x86_64' + + # Compilation will happen inside of chroot environment + prog_scons_cmd = ['schroot', '-c', chroot_name] + scons_cmd + cuda_scons_cmd = ['schroot', '-c', cuda_chroot] + scons_cmd + # We're using the same rules as release builder, so tweak # build and install dirs build_dir = os.path.join('..', 'build', builder) @@ -74,14 +94,6 @@ else: buildbot_dir = os.path.dirname(os.path.realpath(__file__)) config_dir = os.path.join(buildbot_dir, 'config') - configs = [] - if builder.endswith('linux_glibc211_x86_64_scons'): - configs = ['user-config-player-glibc211-x86_64.py', - 'user-config-glibc211-x86_64.py'] - elif builder.endswith('linux_glibc211_i386_scons'): - configs = ['user-config-player-glibc211-i686.py', - 'user-config-glibc211-i686.py'] - for config in configs: config_fpath = os.path.join(config_dir, config) @@ -94,14 +106,19 @@ else: scons_options += common_options - if config.find('player') == -1: - scons_options.append('blender') - else: + if config.find('player') != -1: scons_options.append('blenderplayer') + cur_scons_cmd = prog_scons_cmd + elif config.find('cuda') != -1: + scons_options.append('cudakernels') + cur_scons_cmd = cuda_scons_cmd + else: + scons_options.append('blender') + cur_scons_cmd = prog_scons_cmd scons_options.append('BF_CONFIG=' + config_fpath) - retcode = subprocess.call(scons_cmd + scons_options) + retcode = subprocess.call(cur_scons_cmd + scons_options) if retcode != 0: print('Error building rules wuth config ' + config) sys.exit(retcode) From 7c64109bce446b91f35e187f081f3244c5c92522 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 08:16:19 +0000 Subject: [PATCH 100/132] bmesh todo: uv stretch area draw mode wasn't calculating ngon area - added area_poly_v2(). --- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 19 +++++++++++++++++++ source/blender/bmesh/intern/bmesh_polygon.c | 2 +- source/blender/editors/uvedit/uvedit_draw.c | 6 ++---- source/blender/editors/uvedit/uvedit_intern.h | 1 - source/blender/editors/uvedit/uvedit_ops.c | 13 ------------- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 7cb91a45118..448396811d3 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -53,6 +53,7 @@ float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2] float area_tri_v3(const float a[3], const float b[3], const float c[3]); float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]); float area_poly_v3(int nr, float verts[][3], const float normal[3]); +float area_poly_v2(int nr, float verts[][2]); int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); int is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 5f1047d054e..fc1d0e99a30 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -149,6 +149,25 @@ float area_poly_v3(int nr, float verts[][3], const float normal[3]) return fabsf(0.5f * area / max); } +float area_poly_v2(int nr, float verts[][2]) +{ + int a; + float area; + float *co_curr, *co_prev; + + /* The Trapezium Area Rule */ + co_prev = verts[nr - 1]; + co_curr = verts[0]; + area = 0.0f; + for (a = 0; a < nr; a++) { + area += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]); + co_prev = verts[a]; + co_curr = verts[a + 1]; + } + + return fabsf(0.5f * area); +} + /********************************* Distance **********************************/ /* distance p to line v1-v2 diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 953e7f4d20c..4545c9bb564 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -158,7 +158,6 @@ float BM_face_calc_area(BMFace *f) BMLoop *l; BMIter iter; float (*verts)[3] = BLI_array_alloca(verts, f->len); - float normal[3]; float area; int i; @@ -173,6 +172,7 @@ float BM_face_calc_area(BMFace *f) area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]); } else { + float normal[3]; calc_poly_normal(normal, verts, f->len); area = area_poly_v3(f->len, verts, normal); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 607640090aa..023f281aea9 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -194,8 +194,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); totarea += BM_face_calc_area(efa); - //totuvarea += tf_area(tf, efa->v4!=0); - totuvarea += uv_poly_area(tf_uv, efa->len); + totuvarea += area_poly_v2(efa->len, tf_uv); if (uvedit_face_visible_test(scene, ima, efa, tf)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -238,8 +237,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); - //uvarea = tf_area(tf, efa->v4!=0) / totuvarea; - uvarea = uv_poly_area(tf_uv, efa->len) / totuvarea; + uvarea = area_poly_v2(efa->len, tf_uv) / totuvarea; if (area < FLT_EPSILON || uvarea < FLT_EPSILON) areadiff = 1.0f; diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 4d52282d540..b6d82451d2f 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -50,7 +50,6 @@ struct BMVert; int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); /* geometric utilities */ -float uv_poly_area(float uv[][2], int len); void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4336eb02752..2194ce28353 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -575,19 +575,6 @@ void uv_poly_center(BMEditMesh *em, BMFace *f, float r_cent[2]) mul_v2_fl(r_cent, 1.0f / (float)f->len); } -float uv_poly_area(float uv[][2], int len) -{ - //BMESH_TODO: make this not suck - //maybe use scanfill? I dunno. - - if (len >= 4) - return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]); - else - return area_tri_v2(uv[0], uv[1], uv[2]); - - return 1.0; -} - void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) { int i; From 93c82483c7bf27f2c067c1dd634940b28074244c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 08:55:44 +0000 Subject: [PATCH 101/132] Further tweaks to buildbot - BF_BITNESS should be passed as a command line argument - Made it so CUDA binaries and OSL compiled scripts would be installed regardless WITH_BF_PYTHON (which seems to be quite obvious) - Disable overwrite install, so CUDA kernels installed by it's build target will be preserved when building blender itself. --- SConstruct | 39 ++++++++++--------- .../config/user-config-cuda-glibc211-i686.py | 1 - .../user-config-cuda-glibc211-x86_64.py | 1 - .../config/user-config-glibc211-i686.py | 1 + .../config/user-config-glibc211-x86_64.py | 1 + build_files/buildbot/slave_compile.py | 12 ++++-- 6 files changed, 31 insertions(+), 24 deletions(-) diff --git a/SConstruct b/SConstruct index 49e899c3d20..3b1be71aebd 100644 --- a/SConstruct +++ b/SConstruct @@ -746,29 +746,30 @@ if env['OURPLATFORM']!='darwin': source=['intern/cycles/doc/license/'+s for s in source] scriptinstall.append(env.Install(dir=dir,source=source)) - # cuda binaries - if env['WITH_BF_CYCLES_CUDA_BINARIES']: - dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib') - for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']: - kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel') - cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) - cubininstall.append(env.Install(dir=dir,source=cubin_file)) + if env['WITH_BF_CYCLES']: + # cuda binaries + if env['WITH_BF_CYCLES_CUDA_BINARIES']: + dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'lib') + for arch in env['BF_CYCLES_CUDA_BINARIES_ARCH']: + kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel') + cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch) + cubininstall.append(env.Install(dir=dir,source=cubin_file)) - # osl shaders - if env['WITH_BF_CYCLES_OSL']: - dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader') + # osl shaders + if env['WITH_BF_CYCLES_OSL']: + dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'shader') - osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path - oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders') + osl_source_dir = Dir('./intern/cycles/kernel/shaders').srcnode().path + oso_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel/shaders') - headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split() - source=['intern/cycles/kernel/shaders/'+s for s in headers] - scriptinstall.append(env.Install(dir=dir,source=source)) + headers='node_color.h node_fresnel.h node_texture.h oslutil.h stdosl.h'.split() + source=['intern/cycles/kernel/shaders/'+s for s in headers] + scriptinstall.append(env.Install(dir=dir,source=source)) - for f in os.listdir(osl_source_dir): - if f.endswith('.osl'): - oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso')) - scriptinstall.append(env.Install(dir=dir,source=oso_file)) + for f in os.listdir(osl_source_dir): + if f.endswith('.osl'): + oso_file = os.path.join(oso_build_dir, f.replace('.osl', '.oso')) + scriptinstall.append(env.Install(dir=dir,source=oso_file)) if env['WITH_BF_OCIO']: colormanagement = os.path.join('release', 'datafiles', 'colormanagement') diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py index 16733be5a48..e72218e6615 100644 --- a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py @@ -1,6 +1,5 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' BF_NUMJOBS = 1 -BF_BITNESS = 32 BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py index 60afeccae49..10738a11eaa 100644 --- a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py @@ -1,6 +1,5 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' BF_NUMJOBS = 1 -BF_BITNESS = 64 BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30'] diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index 56eedc3203b..540416ee1fb 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -1,6 +1,7 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686' BF_INSTALLDIR = '../blender-install/linux-glibc211-i686' BF_NUMJOBS = 4 +WITHOUT_BF_OVERWRITE_INSTALL = True # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py index ab3efedfb86..c0ba8060712 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -1,6 +1,7 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64' BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64' BF_NUMJOBS = 4 +WITHOUT_BF_OVERWRITE_INSTALL = True # Python configuration BF_PYTHON_VERSION = '3.3' diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index b66a09afe25..dab8a8e6483 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -64,7 +64,8 @@ else: if builder.endswith('linux_glibc211_x86_64_scons'): configs = ['user-config-player-glibc211-x86_64.py', 'user-config-cuda-glibc211-x86_64.py', - 'user-config-glibc211-x86_64.py'] + 'user-config-glibc211-x86_64.py' + ] chroot_name = 'buildbot_squeeze_x86_64' cuda_chroot = 'buildbot_squeeze_x86_64' elif builder.endswith('linux_glibc211_i386_scons'): @@ -77,8 +78,8 @@ else: cuda_chroot = 'buildbot_squeeze_x86_64' # Compilation will happen inside of chroot environment - prog_scons_cmd = ['schroot', '-c', chroot_name] + scons_cmd - cuda_scons_cmd = ['schroot', '-c', cuda_chroot] + scons_cmd + prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd + cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd # We're using the same rules as release builder, so tweak # build and install dirs @@ -112,6 +113,11 @@ else: elif config.find('cuda') != -1: scons_options.append('cudakernels') cur_scons_cmd = cuda_scons_cmd + + if config.find('i686') != -1: + scons_options.append('BF_BITNESS=32') + elif config.find('x86_64') != -1: + scons_options.append('BF_BITNESS=64') else: scons_options.append('blender') cur_scons_cmd = prog_scons_cmd From 53ad8274b00698e8f13ef6c931f057e0afd34661 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 09:21:12 +0000 Subject: [PATCH 102/132] Stripping and packaging shall happen inside of chroot as well --- build_files/buildbot/slave_pack.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index 285307a7af9..3d4f423be9c 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -59,9 +59,11 @@ if builder.find('scons') != -1: if builder.endswith('linux_glibc211_x86_64_scons'): config = 'user-config-glibc211-x86_64.py' + chroot_name = 'buildbot_squeeze_x86_64' bits = 64 elif builder.endswith('linux_glibc211_i386_scons'): config = 'user-config-glibc211-i686.py' + chroot_name = 'buildbot_squeeze_i686' bits = 32 if config is not None: @@ -70,7 +72,7 @@ if builder.find('scons') != -1: blender = os.path.join(install_dir, 'blender') blenderplayer = os.path.join(install_dir, 'blenderplayer') - subprocess.call(['strip', '--strip-all', blender, blenderplayer]) + subprocess.call(['schroot', '-c', chroot_name, '--', 'strip', '--strip-all', blender, blenderplayer]) extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra') mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2') @@ -80,7 +82,7 @@ if builder.find('scons') != -1: os.system('cp %s %s' % (software_gl, install_dir)) os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl'))) - retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options) + retcode = subprocess.call(['schroot', '-c', chroot_name, '--', 'python', 'scons/scons.py'] + scons_options) sys.exit(retcode) else: From 860d42b9a33b2f348f962f3f41f6fa171cd1f1ce Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 10:10:34 +0000 Subject: [PATCH 103/132] Fix #33816: property not found: World.use_textures Issue was caused bu svn rev53355 and now logic seems to mimic behavior before that change. --- release/scripts/startup/bl_ui/properties_texture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index eddb542ccc3..6842b324b0e 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -64,7 +64,7 @@ class TEXTURE_UL_texslots(UIList): tex = slot.texture if slot else None if self.layout_type in {'DEFAULT', 'COMPACT'}: layout.label(tex.name if tex else "", icon_value=icon) - if tex: + if tex and isinstance(item, bpy.types.MaterialTextureSlot): layout.prop(ma, "use_textures", text="", index=index) elif self.layout_type in {'GRID'}: layout.alignment = 'CENTER' From bed36187802eaa1acc59516b338eb3ec2b8038bb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 10 Jan 2013 11:08:38 +0000 Subject: [PATCH 104/132] Bug fix 33732 Modal operators with hardcoded (in C) event handling now don't get double clicks anymore. For modal keymaps things work OK. This fixes number input typing for CTRL+B bevel, for example. --- source/blender/windowmanager/intern/wm_event_system.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index edf5700673c..48cad9e020b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1345,6 +1345,15 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve } } } + else { + /* modal keymap checking returns handled events fine, but all hardcoded modal + handling typically swallows all events (OPERATOR_RUNNING_MODAL). + This bypass just disables support for double clicks in hardcoded modal handlers */ + if (event->val == KM_DBL_CLICK) { + event->prevval = event->val; + event->val = KM_PRESS; + } + } } /* bad hacking event system... better restore event type for checking of KM_CLICK for example */ @@ -1357,6 +1366,8 @@ static void wm_event_modalmap_end(wmEvent *event) event->val = event->prevval; event->prevval = 0; } + else if (event->prevval == KM_DBL_CLICK) + event->val = KM_DBL_CLICK; } From c3c3df3aecf885946b52d5eff72c4134a1c9478e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 12:07:01 +0000 Subject: [PATCH 105/132] editmesh texface drawing, reuse customdata offset rather then looking up each UV and vertex color, gives overall ~9.5% drawing speedup in my tests. was also doing NULL checks on UV's which are never NULL in this case. --- source/blender/blenkernel/BKE_customdata.h | 2 + source/blender/blenkernel/intern/customdata.c | 18 ++++ .../blenkernel/intern/editderivedmesh.c | 94 +++++++++---------- 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 6f9e046f212..30b15a24a7e 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -250,6 +250,8 @@ void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); int CustomData_get_offset(const struct CustomData *data, int type); +int CustomData_get_n_offset(const struct CustomData *data, int type, int n); +int CustomData_get_active_offset(const struct CustomData *data, int type); int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 82c0535254b..aca16861a75 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2104,6 +2104,24 @@ int CustomData_get_offset(const CustomData *data, int type) return data->layers[layer_index].offset; } +int CustomData_get_n_offset(const CustomData *data, int type, int n) +{ + /* get the layer index of the active layer of type */ + int layer_index = CustomData_get_layer_index_n(data, type, n); + if (layer_index < 0) return -1; + + return data->layers[layer_index].offset; +} + +int CustomData_get_active_offset(const CustomData *data, int type) +{ + /* get the layer index of the active layer of type */ + int layer_index = CustomData_get_active_layer_index(data, type); + if (layer_index < 0) return -1; + + return data->layers[layer_index].offset; +} + int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) { /* get the layer index of the first layer of type */ diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index fd7c3f55bb0..5bf0f503a51 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -782,22 +782,18 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, if (poly_prev != GL_ZERO) glEnd(); } -static void bmdm_get_tri_tex(BMesh *bm, BMLoop **ls, MLoopUV *luv[3], MLoopCol *lcol[3], - int has_uv, int has_col) +static void bmdm_get_tri_uv(BMLoop *ls[3], MLoopUV *luv[3], const int cd_loop_uv_offset) { - if (has_uv) { - luv[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPUV); - luv[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPUV); - luv[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPUV); - } - - if (has_col) { - lcol[0] = CustomData_bmesh_get(&bm->ldata, ls[0]->head.data, CD_MLOOPCOL); - lcol[1] = CustomData_bmesh_get(&bm->ldata, ls[1]->head.data, CD_MLOOPCOL); - lcol[2] = CustomData_bmesh_get(&bm->ldata, ls[2]->head.data, CD_MLOOPCOL); - } - + luv[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_uv_offset); + luv[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_uv_offset); + luv[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_uv_offset); +} +static void bmdm_get_tri_col(BMLoop *ls[3], MLoopCol *lcol[3], const int cd_loop_color_offset) +{ + lcol[0] = BM_ELEM_CD_GET_VOID_P(ls[0], cd_loop_color_offset); + lcol[1] = BM_ELEM_CD_GET_VOID_P(ls[1], cd_loop_color_offset); + lcol[2] = BM_ELEM_CD_GET_VOID_P(ls[2], cd_loop_color_offset); } static void emDM_drawFacesTex_common(DerivedMesh *dm, @@ -813,15 +809,19 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, float (*vertexNos)[3] = bmdm->vertexNos; BMFace *efa; MLoopUV *luv[3], dummyluv = {{0}}; - MLoopCol *lcol[3] = {NULL}, dummylcol = {0}; - int i, has_vcol = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL); - int has_uv = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY); + MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; + const int cd_loop_uv_offset = CustomData_get_active_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_color_offset = CustomData_get_active_offset(&bm->ldata, CD_MLOOPCOL); + const int cd_poly_tex_offset = CustomData_get_active_offset(&bm->pdata, CD_MTEXPOLY); + bool has_uv = (cd_loop_uv_offset != -1); + bool has_vcol = (cd_loop_color_offset != -1); + int i; (void) compareDrawOptions; luv[0] = luv[1] = luv[2] = &dummyluv; - dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; + // dummylcol.r = dummylcol.g = dummylcol.b = dummylcol.a = 255; /* UNUSED */ /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); @@ -833,7 +833,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, for (i = 0; i < em->tottri; i++) { BMLoop **ls = em->looptris[i]; - MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL; + MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH); @@ -841,7 +841,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, efa = ls[0]->f; - if (has_uv) { + if (cd_poly_tex_offset != -1) { ME_MTEXFACE_CPY(&mtf, tp); } @@ -858,25 +858,27 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (!drawSmooth) { glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]); - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[0]->v)]); glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[1]->v)]); glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glVertex3fv(vertexCos[BM_elem_index_get(ls[2]->v)]); } else { - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); glTexCoord2fv(luv[0]->uv); if (lcol[0]) @@ -905,7 +907,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, for (i = 0; i < em->tottri; i++) { BMLoop **ls = em->looptris[i]; - MTexPoly *tp = has_uv ? CustomData_bmesh_get(&bm->pdata, ls[0]->f->head.data, CD_MTEXPOLY) : NULL; + MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ls[0]->f, cd_poly_tex_offset) : NULL; MTFace mtf = {{{0}}}; /*unsigned char *cp = NULL;*/ /*UNUSED*/ int drawSmooth = BM_elem_flag_test(ls[0]->f, BM_ELEM_SMOOTH); @@ -913,12 +915,12 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, efa = ls[0]->f; - if (has_uv) { + if (cd_poly_tex_offset != -1) { ME_MTEXFACE_CPY(&mtf, tp); } if (drawParams) - draw_option = drawParams(&mtf, has_vcol, efa->mat_nr); + draw_option = drawParams(&mtf, (has_vcol), efa->mat_nr); else if (drawParamsMapped) draw_option = drawParamsMapped(userData, BM_elem_index_get(efa)); else @@ -930,46 +932,42 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, if (!drawSmooth) { glNormal3fv(efa->no); - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); - if (luv[0]) - glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + glTexCoord2fv(luv[0]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glVertex3fv(ls[0]->v->co); - if (luv[1]) - glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + glTexCoord2fv(luv[1]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glVertex3fv(ls[1]->v->co); - if (luv[2]) - glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + glTexCoord2fv(luv[2]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glVertex3fv(ls[2]->v->co); } else { - bmdm_get_tri_tex(bm, ls, luv, lcol, has_uv, has_vcol); + if (has_uv) bmdm_get_tri_uv(ls, luv, cd_loop_uv_offset); + if (has_vcol) bmdm_get_tri_col(ls, lcol, cd_loop_color_offset); - if (luv[0]) - glTexCoord2fv(luv[0]->uv); - if (lcol[0]) + glTexCoord2fv(luv[0]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[0]->r)); glNormal3fv(ls[0]->v->no); glVertex3fv(ls[0]->v->co); - if (luv[1]) - glTexCoord2fv(luv[1]->uv); - if (lcol[1]) + glTexCoord2fv(luv[1]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[1]->r)); glNormal3fv(ls[1]->v->no); glVertex3fv(ls[1]->v->co); - if (luv[2]) - glTexCoord2fv(luv[2]->uv); - if (lcol[2]) + glTexCoord2fv(luv[2]->uv); + if (has_vcol) glColor3ubv((const GLubyte *)&(lcol[2]->r)); glNormal3fv(ls[2]->v->no); glVertex3fv(ls[2]->v->co); From 273cf512dd8915e5360e8dc33471c89ef2a5e836 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Thu, 10 Jan 2013 12:32:09 +0000 Subject: [PATCH 106/132] Fix for bpy.props getter/setter callbacks. These were missing a valid GIL state when being called outside the UI context. --- source/blender/python/intern/bpy_props.c | 170 +++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index b9bfaed54d5..026b59244d3 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -243,6 +243,8 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int value; @@ -252,6 +254,11 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -277,6 +284,9 @@ static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -291,6 +301,8 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -299,6 +311,11 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -322,6 +339,9 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA * Py_DECREF(ret); } + + if (use_gil) + PyGILState_Release(gilstate); if (!is_write_ok) { pyrna_write_set(false); @@ -335,6 +355,8 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int i, len = RNA_property_array_length(ptr, prop); @@ -344,6 +366,11 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -371,6 +398,9 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -384,6 +414,8 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert PyObject *self; PyObject *ret; PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int len = RNA_property_array_length(ptr, prop); @@ -393,6 +425,11 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -422,6 +459,9 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct Propert Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -434,6 +474,8 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int value; @@ -443,6 +485,11 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -468,6 +515,9 @@ static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -482,6 +532,8 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -490,6 +542,11 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -514,6 +571,9 @@ static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -526,6 +586,8 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int i, len = RNA_property_array_length(ptr, prop); @@ -535,6 +597,11 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -562,6 +629,9 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -575,6 +645,8 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA PyObject *self; PyObject *ret; PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int len = RNA_property_array_length(ptr, prop); @@ -584,6 +656,11 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -613,6 +690,9 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -625,6 +705,8 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); float value; @@ -634,6 +716,11 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -659,6 +746,9 @@ static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -673,6 +763,8 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -681,6 +773,11 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -705,6 +802,9 @@ static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pr Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -717,6 +817,8 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int i, len = RNA_property_array_length(ptr, prop); @@ -726,6 +828,11 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -753,6 +860,9 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -766,6 +876,8 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR PyObject *self; PyObject *ret; PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int len = RNA_property_array_length(ptr, prop); @@ -775,6 +887,11 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -804,6 +921,9 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyR Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -816,6 +936,8 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -824,6 +946,11 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -855,6 +982,9 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -867,6 +997,8 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int length; @@ -876,6 +1008,11 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -894,6 +1031,9 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -908,6 +1048,8 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); PyObject *py_value; @@ -917,6 +1059,11 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -947,6 +1094,9 @@ static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *p Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -959,6 +1109,8 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); int value; @@ -968,6 +1120,11 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_GET]; args = PyTuple_New(1); @@ -993,6 +1150,9 @@ static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } @@ -1007,6 +1167,8 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; const int is_write_ok = pyrna_write_check(); BLI_assert(py_data != NULL); @@ -1015,6 +1177,11 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro pyrna_write_set(true); } + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + py_func = py_data[BPY_DATA_CB_SLOT_SET]; args = PyTuple_New(2); @@ -1039,6 +1206,9 @@ static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *pro Py_DECREF(ret); } + if (use_gil) + PyGILState_Release(gilstate); + if (!is_write_ok) { pyrna_write_set(false); } From 04754cc1125fce8c6c9881e81a70e3e1b8748598 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jan 2013 12:35:09 +0000 Subject: [PATCH 107/132] Fix too bright result in background multiple importance after recent changes. --- intern/cycles/kernel/kernel_light.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index df5acca6e65..eafe1d3d96b 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -243,7 +243,7 @@ __device void lamp_light_sample(KernelGlobals *kg, int lamp, float costheta = dot(lightD, D); ls->pdf = invarea/(costheta*costheta*costheta); - ls->eval_fac = ls->pdf; + ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights; } #ifdef __BACKGROUND_MIS__ else if(type == LIGHT_BACKGROUND) { @@ -302,23 +302,18 @@ __device void lamp_light_sample(KernelGlobals *kg, int lamp, invarea = 1.0f; } - ls->pdf = invarea; ls->eval_fac = 0.25f*ls->pdf; + ls->pdf = invarea; } + + ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } ls->shader = __float_as_int(data1.x); ls->object = ~0; ls->prim = ~0; ls->lamp = lamp; - - /* compute pdf */ - if(ls->t != FLT_MAX) - ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); - - /* this is a bit weak, but we don't want this as part of the pdf for - * multiple importance sampling */ - ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; } __device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls) From 1df1f9fdd3d922d770984ed933374a131233e6c8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 13:59:52 +0000 Subject: [PATCH 108/132] adding vertex color layer in mesh editmode would overwrite UV's, strange nobody reported this since its been there since 2.63. --- source/blender/editors/mesh/mesh_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 641d1be7a2e..1d13aa36a6b 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -462,7 +462,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes /* copy data from active vertex color layer */ if (layernum) { const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL); - BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst); + BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum, layernum_dst); } if (active_set || layernum == 0) { CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum); From 983e5fe5f1431e268ad7dd0d0e8fbdb79bbf3a13 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 14:28:06 +0000 Subject: [PATCH 109/132] fix for own mistake in recent changes to scanfill, bmo_triangle_fill_exec() (alt+f), was missing BLI_SCANFILL_CALC_HOLES argument. reported as [#33819] --- source/blender/bmesh/operators/bmo_triangulate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index d20d01af114..663ee463a2c 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) /* sf_edge->tmp.p = e; */ /* UNUSED */ } - BLI_scanfill_calc(&sf_ctx, 0); + BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_HOLES); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { BMFace *f = BM_face_create_quad_tri(bm, From 127b5423d6203d521acb2b96b7de5534e8dbe79a Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Thu, 10 Jan 2013 14:36:08 +0000 Subject: [PATCH 110/132] Another fix for bpy.props getters/setters: PyC_AsArray does a refcount decrement internally on errors, need to skip Py_DECREF in that case to avoid negative refcounts. --- source/blender/python/intern/bpy_props.c | 27 ++++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 026b59244d3..bd3fc95cd7e 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -388,14 +388,17 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert values[i] = false; } else { - if (ret && PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) values[i] = false; - } - Py_DECREF(ret); + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } } if (use_gil) @@ -619,14 +622,17 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA values[i] = 0; } else { - if (ret && PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) values[i] = 0; - } - Py_DECREF(ret); + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } } if (use_gil) @@ -850,14 +856,17 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR values[i] = 0.0f; } else { - if (ret && PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") < 0) { printf_func_error(py_func); for (i = 0; i < len; ++i) values[i] = 0.0f; - } - Py_DECREF(ret); + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } } if (use_gil) From e56844e98b5ab2332de301c9f85efdf9c2478558 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 14:38:30 +0000 Subject: [PATCH 111/132] simple speedup for view3d numeric panel - dont loop on verts or edges if none are selected. --- .../editors/space_view3d/view3d_buttons.c | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 4ca0284d0e0..ec716284bf3 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -184,21 +184,21 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - MVertSkin *vs; + if (bm->totvertsel) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + evedef = eve; + tot++; + add_v3_v3(&median[LOC_X], eve->co); - evedef = eve; - tot++; - add_v3_v3(&median[LOC_X], eve->co); + /* TODO cd_vert_bweight_offset */ + (void)cd_vert_bweight_offset; - /* TODO cd_vert_bweight_offset */ - (void)cd_vert_bweight_offset; - - if (cd_vert_skin_offset != -1) { - vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); - add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ - totskinradius++; + if (cd_vert_skin_offset != -1) { + MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_vert_skin_offset); + add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ + totskinradius++; + } } } } @@ -206,17 +206,19 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if ((cd_edge_bweight_offset != -1) || (cd_edge_crease_offset != -1)) { - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - if (cd_edge_bweight_offset != -1) { - median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); - } + if (bm->totedgesel) { + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + if (cd_edge_bweight_offset != -1) { + median[M_WEIGHT] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_bweight_offset); + } - if (cd_edge_crease_offset != -1) { - median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset); - } + if (cd_edge_crease_offset != -1) { + median[M_CREASE] += BM_ELEM_CD_GET_FLOAT(eed, cd_edge_crease_offset); + } - totedgedata++; + totedgedata++; + } } } } From 1c99e6aa0b79403d83325eb831e2efab6ae4e255 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 15:22:19 +0000 Subject: [PATCH 112/132] pyapi internal api code: check for == -1 rather then < 0, for known error returns. --- source/blender/python/intern/bpy_app.c | 2 +- source/blender/python/intern/bpy_props.c | 12 ++++++------ source/blender/python/intern/bpy_rna.c | 8 ++++---- source/blender/python/intern/bpy_rna_anim.c | 8 ++++---- source/blender/python/intern/bpy_rna_callback.c | 8 ++++---- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index bea63d2b6e8..3e2353c3571 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -182,7 +182,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos const int flag = GET_INT_FROM_POINTER(closure); const int param = PyObject_IsTrue(value); - if (param < 0) { + if (param == -1) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False"); return -1; } diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index bd3fc95cd7e..8769700f32c 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -388,7 +388,7 @@ static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct Propert values[i] = false; } else { - if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) { printf_func_error(py_func); for (i = 0; i < len; ++i) @@ -622,7 +622,7 @@ static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA values[i] = 0; } else { - if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) { printf_func_error(py_func); for (i = 0; i < len; ++i) @@ -856,7 +856,7 @@ static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyR values[i] = 0.0f; } else { - if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") < 0) { + if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) { printf_func_error(py_func); for (i = 0; i < len; ++i) @@ -1941,7 +1941,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { @@ -2136,7 +2136,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { @@ -2356,7 +2356,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1) return NULL; if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 5be6c33ec18..94f262f57f5 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_ return -1; } - if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) { + if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { return -1; } @@ -1682,13 +1682,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb /* type checkins is done by each function */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { /* set of enum items, concatenate all values with OR */ - if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) { + if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { return -1; } } else { /* simple enum string */ - if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) { + if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { return -1; } } @@ -4384,7 +4384,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) bool attr_signed; RawPropertyType raw_type; - if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) + if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) return NULL; if (tot == 0) diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 234eeae8a4a..a19f8e2d8ed 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -160,14 +160,14 @@ static int pyrna_struct_keyframe_parse( return -1; } - if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0) + if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1) return -1; if (*cfra == FLT_MAX) *cfra = CTX_data_scene(BPy_GetContext())->r.cfra; /* flag may be null (no option currently for remove keyframes e.g.). */ - if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) < 0)) + if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1)) return -1; return 0; /* success */ @@ -301,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) { return NULL; } else { @@ -377,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) { return NULL; } else { diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index c66b336a1da..1043f68dbdb 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -101,7 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args) if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) { if (cb_event_str) { - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } } @@ -212,10 +212,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) return NULL; } - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } - else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") < 0) { + else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) { return NULL; } else { @@ -278,7 +278,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar customdata = ED_region_draw_cb_customdata(handle); Py_DECREF((PyObject *)customdata); - if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") < 0) { + if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) { return NULL; } else { From f6f33515ac62fb603ceba0eeaf79047b4451f754 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 16:11:12 +0000 Subject: [PATCH 113/132] Fix #33822: Compositor gets stuck if a sequencer window is also visible Issue was caused by a fix for rendered sequencer preview mode, which will likely conflict with compositor job. Made it so compositor job will be killed when sequencer uses rendered preview. --- source/blender/editors/space_sequencer/sequencer_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 9477b3197fa..249ba986fd3 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -924,7 +924,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq void *cache_handle = NULL; const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); - if (G.is_rendering == FALSE) { + if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* stop all running jobs, except screen one. currently previews frustrate Render * needed to make so sequencer's rendering doesn't conflict with compositor */ From 18536e201f26f20bde6379afa996153433404c65 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 16:37:48 +0000 Subject: [PATCH 114/132] add a segfault handler that writes out the info log into a crash file alongside the blend file. --- source/blender/blenkernel/BKE_report.h | 5 +- source/blender/blenkernel/intern/report.c | 43 +++++++++-- source/blender/blenloader/intern/runtime.c | 5 +- source/blender/editors/space_file/file_ops.c | 5 +- .../blender/render/intern/source/pipeline.c | 20 +++--- .../render/intern/source/render_result.c | 10 +-- source/creator/creator.c | 71 +++++++++++++++++++ 7 files changed, 134 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 4d69a013101..84cc4b6db83 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -72,7 +72,10 @@ void BKE_reports_print(ReportList *reports, ReportType level); Report *BKE_reports_last_displayable(ReportList *reports); int BKE_reports_contain(ReportList *reports, ReportType level); - + +// int BKE_report_write_file_fp(struct FILE *fp, ReportList *reports, const char *header); +bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 185aeac5452..3acb35260cb 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -27,6 +27,10 @@ * \ingroup bke */ +#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -39,10 +43,6 @@ #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ -#include -#include -#include - static const char *report_type_str(int type) { switch (type) { @@ -302,3 +302,38 @@ int BKE_reports_contain(ReportList *reports, ReportType level) return FALSE; } +static bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header) +{ + Report *report; + + if (header) { + fputs(header, fp); + } + + for (report = reports->list.first; report; report = report->next) { + fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr); + } + + return true; +} + +bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header) +{ + FILE *fp; + + /* first try create the file, if it exists call without 'O_CREAT', + * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ + errno = 0; + fp = BLI_fopen(filepath, "wb"); + if (fp == NULL) { + fprintf(stderr, "Unable to save '%s': %s\n", + filepath, errno ? strerror(errno) : "Unknown error opening file"); + return false; + } + + BKE_report_write_file_fp(fp, reports, header); + + fclose(fp); + + return true; +} diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index 5d8a865eea8..cbbaf713e84 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -48,11 +48,12 @@ #include "BLO_readfile.h" #include "BLO_runtime.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + #include "BKE_blender.h" #include "BKE_report.h" -#include "BLI_blenlib.h" - /* Runtime reading */ static int handle_read_msb_int(int handle) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 763b18788de..9349abb4d8b 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -28,6 +28,8 @@ * \ingroup spfile */ +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -35,9 +37,6 @@ #include "BKE_report.h" #include "BKE_main.h" -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - #ifdef WIN32 # include "BLI_winstuff.h" #endif diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 755c8f40ba1..dec11f0da91 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -45,6 +45,16 @@ #include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_rect.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_threads.h" +#include "BLI_rand.h" +#include "BLI_callbacks.h" + #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" #include "BKE_global.h" @@ -57,16 +67,6 @@ #include "BKE_sequencer.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ -#include "BLI_math.h" -#include "BLI_rect.h" -#include "BLI_listbase.h" -#include "BLI_string.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "BLI_threads.h" -#include "BLI_rand.h" -#include "BLI_callbacks.h" - #include "PIL_time.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 6de5830df27..35b06385ae6 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -35,11 +35,6 @@ #include "MEM_guardedalloc.h" -#include "BKE_image.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_report.h" - #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" @@ -48,6 +43,11 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_report.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" diff --git a/source/creator/creator.c b/source/creator/creator.c index 158ce8f2eeb..7dd43840c91 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -40,6 +40,12 @@ # include #endif +#ifdef WIN32 +# include /* getpid */ +#else +# include /* getpid */ +#endif + #ifdef WIN32 # include # include "utfconv.h" @@ -157,6 +163,8 @@ static int print_version(int argc, const char **argv, void *data); /* Initialize callbacks for the modules that need them */ static void setCallbacks(void); +static bool use_crash_handler = true; + #ifndef WITH_PYTHON_MODULE /* set breakpoints here when running in debug mode, useful to catch floating point errors */ @@ -246,6 +254,7 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data) printf("Misc Options:\n"); BLI_argsPrintArgDoc(ba, "--debug"); BLI_argsPrintArgDoc(ba, "--debug-fpe"); + BLI_argsPrintArgDoc(ba, "--disable-crash-handler"); #ifdef WITH_FFMPEG BLI_argsPrintArgDoc(ba, "--debug-ffmpeg"); @@ -350,6 +359,12 @@ static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNU return 0; } +static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + use_crash_handler = false; + return 0; +} + static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { G.background = 1; @@ -423,6 +438,56 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat return 0; } +static void blender_crash_handler(int signum) +{ + +#if 0 + { + char fname[FILE_MAX]; + + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend"); + } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); + } + + printf("Writing: %s\n", fname); + fflush(stdout); + + BKE_undo_save_file(fname); + } +#endif + + { + char header[512]; + wmWindowManager *wm = G.main->wm.first; + + char fname[FILE_MAX]; + + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt"); + } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); + } + + printf("Writing: %s\n", fname); + fflush(stdout); + + BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); + + BKE_report_write_file(fname, &wm->reports, header); + } + + /* really crash */ + signal(signum, SIG_DFL); + kill(getpid(), signum); +} + + static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { G.factory_startup = 1; @@ -1122,6 +1187,8 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL); BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL); + BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL); + #undef PY_ENABLE_AUTO #undef PY_DISABLE_AUTO @@ -1301,6 +1368,10 @@ int main(int argc, const char **argv) BLI_argsParse(ba, 1, NULL, NULL); #endif + if (use_crash_handler) { + /* after parsing args */ + signal(SIGSEGV, blender_crash_handler); + } /* after level 1 args, this is so playanim skips RNA init */ RNA_init(); From b39090bb5ab54a396128178923bf3caf543c3a33 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jan 2013 17:37:17 +0000 Subject: [PATCH 115/132] Fix #33752: UV Orco coordinates were wrong for Cycles (and other external render engines). Replaced generating orco_index by filling the UV loop data directly which is easier and all that needed to be done anyway. --- source/blender/blenkernel/BKE_cdderivedmesh.h | 4 +- source/blender/blenkernel/BKE_mesh.h | 8 +- .../blender/blenkernel/intern/cdderivedmesh.c | 46 +-------- source/blender/blenkernel/intern/displist.c | 4 +- source/blender/blenkernel/intern/mesh.c | 98 ++++++++++--------- .../blender/makesrna/intern/rna_object_api.c | 33 +------ 6 files changed, 62 insertions(+), 131 deletions(-) diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 2b2497f3f50..af5e925987d 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_ /* merge verts */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap); -DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob); - /* creates a CDDerivedMesh from the given curve object */ struct DerivedMesh *CDDM_from_curve(struct Object *ob); /* creates a CDDerivedMesh from the given curve object and specified dispbase */ /* useful for OrcoDM creation for curves with constructive modifiers */ -DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr); +DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 5f4cc65ae7e..3466a914bce 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -154,13 +154,9 @@ int BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot int *totloop, int *totpoly); int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly, - int *_totloop, int *_totpoly, int **orco_index_ptr); -void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly, - struct MLoop *mloops, struct MLoopUV *mloopuvs, - float (*orco)[3], int (*orco_index)[4]); + struct MLoopUV **alluv, int *_totloop, int *_totpoly); +void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv); void BKE_mesh_from_nurbs(struct Object *ob); -void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, - int **orco_index_ptr); void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob); void BKE_mesh_delete_material_index(struct Mesh *me, short index); void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 0321b963256..85dd4c67fdf 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1775,49 +1775,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *CDDM_from_curve(Object *ob) { - return CDDM_from_curve_displist(ob, &ob->disp, NULL); + return CDDM_from_curve_displist(ob, &ob->disp); } -DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob) -{ - int *orco_index_ptr = NULL; - int (*orco_index)[4] = NULL; - float (*orco)[3] = NULL; - DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr); - - if (orco_index_ptr) { - orco = (float (*)[3])BKE_curve_make_orco(scene, ob); - } - - if (orco && orco_index_ptr) { - const char *uvname = "Orco"; - - int totpoly = dm->getNumPolys(dm); - - MPoly *mpolys = dm->getPolyArray(dm); - MLoop *mloops = dm->getLoopArray(dm); - - MLoopUV *mloopuvs; - - CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname); - mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV, CD_DEFAULT, NULL, dm->numLoopData, uvname); - - BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly, - mloops, mloopuvs, - orco, orco_index); - } - - if (orco_index) { - MEM_freeN(orco_index); - } - if (orco) { - MEM_freeN(orco); - } - - return dm; -} - -DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) +DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase) { DerivedMesh *dm; CDDerivedMesh *cddm; @@ -1828,7 +1789,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco int totvert, totedge, totloop, totpoly; if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, - &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) + &totedge, &allloop, &allpoly, NULL, + &totloop, &totpoly) != 0) { /* Error initializing mdata. This often happens when curve is empty */ return CDDM_new(0, 0, 0, 0, 0); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index daf0d571887..643c7b1d972 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -975,7 +975,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba curve_to_filledpoly(cu, nurb, dispbase); } - dm = CDDM_from_curve_displist(ob, dispbase, NULL); + dm = CDDM_from_curve_displist(ob, dispbase); CDDM_calc_normals_mapping(dm); } @@ -1065,7 +1065,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) /* OrcoDM should be created from underformed disp lists */ BKE_displist_make_curveTypes_forOrco(scene, ob, &disp); - dm = CDDM_from_curve_displist(ob, &disp, NULL); + dm = CDDM_from_curve_displist(ob, &disp); BKE_displist_free(&disp); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 806df92a4cb..dec7556392f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1204,8 +1204,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp, allvert, totvert, alledge, totedge, - allloop, allpoly, - totloop, totpoly, NULL); + allloop, allpoly, NULL, + totloop, totpoly); } /* BMESH: this doesn't calculate all edges from polygons, @@ -1213,25 +1213,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert, /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */ /* use specified dispbase */ -/* TODO: orco values for non DL_SURF types */ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert, MEdge **alledge, int *_totedge, MLoop **allloop, MPoly **allpoly, - int *_totloop, int *_totpoly, - int **orco_index_ptr) + MLoopUV **alluv, + int *_totloop, int *_totpoly) { DispList *dl; Curve *cu; MVert *mvert; MPoly *mpoly; MLoop *mloop; + MLoopUV *mloopuv = NULL; MEdge *medge; float *data; int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0; int p1, p2, p3, p4, *index; int conv_polys = 0; - int (*orco_index)[4] = NULL; cu = ob->data; @@ -1278,15 +1277,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, *alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge"); *allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop *allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop"); + + if (alluv) + *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv"); /* verts and faces */ vertcount = 0; - if (orco_index_ptr) { - *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco"); - orco_index = (int (*)[4]) *orco_index_ptr; - } - dl = dispbase->first; while (dl) { int smooth = dl->rt & CU_SMOOTH ? 1 : 0; @@ -1359,6 +1356,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 3; mpoly->mat_nr = dl->col; + if (mloopuv) { + int i; + + for (i = 0; i < 3; i++, mloopuv++) { + mloopuv->uv[0] = (mloop[i].v - startvert)/(float)(dl->nr - 1); + mloopuv->uv[1] = 0.0f; + } + } + if (smooth) mpoly->flag |= ME_SMOOTH; mpoly++; mloop += 3; @@ -1408,13 +1414,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, mpoly->totloop = 4; mpoly->mat_nr = dl->col; - if (orco_index) { - const int poly_index = mpoly - *allpoly; - const int p_orco_base = startvert + ((dl->nr + 1) * a) + b; - orco_index[poly_index][0] = p_orco_base + 1; - orco_index[poly_index][1] = p_orco_base + dl->nr + 2; - orco_index[poly_index][2] = p_orco_base + dl->nr + 1; - orco_index[poly_index][3] = p_orco_base; + if (mloopuv) { + int orco_sizeu = dl->nr - 1; + int orco_sizev = dl->parts - 1; + int i; + + /* exception as handled in convertblender.c too */ + if (dl->flag & DL_CYCL_U) { + orco_sizeu++; + if (dl->flag & DL_CYCL_V) + orco_sizev++; + } + + for (i = 0; i < 4; i++, mloopuv++) { + /* find uv based on vertex index into grid array */ + int v = mloop[i].v - startvert; + + mloopuv->uv[0] = (v / dl->nr)/(float)orco_sizev; + mloopuv->uv[1] = (v % dl->nr)/(float)orco_sizeu; + + /* cyclic correction */ + if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) + mloopuv->uv[1] = 1.0f; + } } if (smooth) mpoly->flag |= ME_SMOOTH; @@ -1427,7 +1449,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, p1++; } } - } dl = dl->next; @@ -1448,33 +1469,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, } -MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2]) -{ - r[0] = 0.5f + a[0] * 0.5f; - r[1] = 0.5f + a[1] * 0.5f; -} - -/** - * orco is normally from #BKE_curve_make_orco - */ -void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly, - MLoop *mloops, MLoopUV *mloopuvs, - float (*orco)[3], int (*orco_index)[4]) -{ - MPoly *mp; - - int i, j; - for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { - MLoop *ml = mloops + mp->loopstart; - MLoopUV *mluv = mloopuvs + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++, mluv++) { - copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]); - } - } -} - /* this may fail replacing ob->data, be sure to check ob->type */ -void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr) +void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv) { Main *bmain = G.main; Object *ob1; @@ -1484,6 +1480,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind MVert *allvert = NULL; MEdge *alledge = NULL; MLoop *allloop = NULL; + MLoopUV *alluv = NULL; MPoly *allpoly = NULL; int totvert, totedge, totloop, totpoly; @@ -1492,7 +1489,8 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind if (dm == NULL) { if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge, &totedge, &allloop, - &allpoly, &totloop, &totpoly, orco_index_ptr) != 0) + &allpoly, (use_orco_uv)? &alluv: NULL, + &totloop, &totpoly) != 0) { /* Error initializing */ return; @@ -1510,6 +1508,12 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop); me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly); + if (alluv) { + const char *uvname = "Orco"; + me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname); + me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname); + } + BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL); BKE_mesh_calc_edges(me, TRUE); @@ -1548,7 +1552,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind void BKE_mesh_from_nurbs(Object *ob) { - BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL); + BKE_mesh_from_nurbs_displist(ob, &ob->disp, false); } typedef struct EdgeLink { diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index d7115256fe5..40b8d4cce66 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -129,9 +129,6 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int DerivedMesh *derivedFinal = NULL; int uv_from_orco; - int (*orco_index)[4] = NULL; - float (*orco)[3] = NULL; - /* copies object and modifiers (but not the data) */ tmpobj = BKE_object_copy_with_caches(ob); tmpcu = (Curve *)tmpobj->data; @@ -158,38 +155,12 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int tmpobj->derivedFinal = derivedFinal; - uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; - - if (uv_from_orco) { - /* before curve conversion */ - orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj); - } - /* convert object type to mesh */ - BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL); + uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0; + BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco); tmpmesh = tmpobj->data; - if (uv_from_orco && orco && orco_index) { - const char *uvname = "Orco"; - /* add UV's */ - MTexPoly *mtpoly = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname); - MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, tmpmesh->totloop, uvname); - - BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly, - tmpmesh->mloop, mloopuvs, - orco, orco_index); - - (void)mtpoly; - } - - if (orco_index) { - MEM_freeN(orco_index); - } - if (orco) { - MEM_freeN(orco); - } - BKE_displist_free(&dispbase); /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ From 057f0a63d456d6fcaee0811261d9b8240f2d0e09 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jan 2013 17:37:26 +0000 Subject: [PATCH 116/132] Fix #33821: cycles background intensity fix had uninitialized memory usage for area lights. --- intern/cycles/kernel/kernel_light.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index eafe1d3d96b..e0d0802ae84 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -302,7 +302,7 @@ __device void lamp_light_sample(KernelGlobals *kg, int lamp, invarea = 1.0f; } - ls->eval_fac = 0.25f*ls->pdf; + ls->eval_fac = 0.25f*invarea; ls->pdf = invarea; } From b3802d0041f4faca1f038da458957b48ad03f76a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jan 2013 17:46:23 +0000 Subject: [PATCH 117/132] Fix build error on Mac, bool needs an #include. --- source/blender/blenkernel/BKE_report.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 84cc4b6db83..72611de107e 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -35,6 +35,7 @@ extern "C" { #endif #include "DNA_windowmanager_types.h" +#include "BLI_utildefines.h" /* Reporting Information and Errors * From c92be1a9a5491621b42f791e5c596494e1937254 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 10 Jan 2013 18:11:56 +0000 Subject: [PATCH 118/132] Correction to do_versions() in 53676 Affect on curve radius only if offset/extrude was used, otherwise radius could have been used for other things (like controlling hair) which will likely break compatibility. Reported by Tube project guys. --- source/blender/blenloader/intern/readfile.c | 34 +++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2235906329d..44499f1ae77 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8617,27 +8617,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (cu = main->curve.first; cu; cu = cu->id.next) { if (cu->flag & (CU_FRONT | CU_BACK)) { - Nurb *nu; + if ( cu->ext1 != 0.0f || cu->ext2 != 0.0f) { + Nurb *nu; - for (nu = cu->nurb.first; nu; nu = nu->next) { - int a; + for (nu = cu->nurb.first; nu; nu = nu->next) { + int a; - if (nu->bezt) { - BezTriple *bezt = nu->bezt; - a = nu->pntsu; + if (nu->bezt) { + BezTriple *bezt = nu->bezt; + a = nu->pntsu; - while (a--) { - bezt->radius = 1.0f; - bezt++; + while (a--) { + bezt->radius = 1.0f; + bezt++; + } } - } - else if (nu->bp) { - BPoint *bp = nu->bp; - a = nu->pntsu * nu->pntsv; + else if (nu->bp) { + BPoint *bp = nu->bp; + a = nu->pntsu * nu->pntsv; - while (a--) { - bp->radius = 1.0f; - bp++; + while (a--) { + bp->radius = 1.0f; + bp++; + } } } } From 70a59a326228af75e7daed0689f62900aef81a88 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 10 Jan 2013 18:20:29 +0000 Subject: [PATCH 119/132] Depsgraph hack feature - experimental Many depsgraph failures are because some data in the graph is being recalculated too early (or not at all). Since we better support animators with working renders, here's a hack to allow manual additional updates on frame changes. In Property Editor, Object, Panel "Relations Extra" you now have two buttons: - Extra Object Update - Extra Data Update This will do an extra update of object and/or its data ONLY on frame changes. Update happens as last. Tested on files collected in Wiki todo, several cases now work OK, especially the lags on updates. --- .../startup/bl_ui/properties_object.py | 3 ++ source/blender/blenkernel/intern/scene.c | 44 +++++++++++++++++++ source/blender/makesdna/DNA_object_types.h | 6 ++- source/blender/makesrna/intern/rna_object.c | 9 ++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 8a668b5d95b..951807488e7 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -289,6 +289,9 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): row.active = ((ob.parent is not None) and (ob.use_slow_parent)) row.prop(ob, "slow_parent_offset", text="Offset") + layout.prop(ob, "extra_recalc_object") + layout.prop(ob, "extra_recalc_data") + from bl_ui.properties_animviz import (MotionPathButtonsPanel, OnionSkinButtonsPanel) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index bccbdc44584..9cf0724f82a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1031,6 +1031,47 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene) } } +/* deps hack - do extra recalcs at end */ +static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent) +{ + Base *base; + + scene->customdata_mask = scene_parent->customdata_mask; + + /* sets first, we allow per definition current scene to have + * dependencies on sets, but not the other way around. */ + if (scene->set) + scene_depsgraph_hack(scene->set, scene_parent); + + for (base = scene->base.first; base; base = base->next) { + Object *ob = base->object; + + if (ob->depsflag) { + int recalc = 0; + // printf("depshack %s\n", ob->id.name+2); + + if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC) + recalc |= OB_RECALC_OB; + if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC) + recalc |= OB_RECALC_DATA; + + ob->recalc |= recalc; + BKE_object_handle_update(scene_parent, ob); + + if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) { + GroupObject *go; + + for (go = ob->dup_group->gobject.first; go; go = go->next) { + if (go->ob) + go->ob->recalc |= recalc; + } + group_handle_recalc_and_update(scene_parent, ob, ob->dup_group); + } + } + } + +} + static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent) { Base *base; @@ -1066,6 +1107,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* update masking curves */ BKE_mask_update_scene(bmain, scene, FALSE); + } /* this is called in main loop, doing tagged updates before redraw */ @@ -1158,6 +1200,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) /* BKE_object_handle_update() on all objects, groups and sets */ scene_update_tagged_recursive(bmain, sce, sce); + scene_depsgraph_hack(sce, sce); + /* notify editors and python about recalc */ BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST); BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 89328c33674..559ba446740 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -178,7 +178,7 @@ typedef struct Object { short ipoflag; // xxx deprecated... old animation system short scaflag; /* ui state for game logic */ char scavisflag; /* more display settings for game logic */ - char pad5; + char depsflag; int dupon, dupoff, dupsta, dupend; @@ -530,6 +530,10 @@ typedef struct DupliObject { #define OB_BODY_TYPE_NAVMESH 7 #define OB_BODY_TYPE_CHARACTER 8 +/* ob->depsflag */ +#define OB_DEPS_EXTRA_OB_RECALC 1 +#define OB_DEPS_EXTRA_DATA_RECALC 2 + /* ob->scavisflag */ #define OB_VIS_SENS 1 #define OB_VIS_CONT 2 diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 80d74c3a9fe..a617c78019f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2469,6 +2469,15 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Slow Parent Offset", "Delay in the parent relationship"); RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); + /* depsgraph hack */ + prop = RNA_def_property(srna, "extra_recalc_object", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_OB_RECALC); + RNA_def_property_ui_text(prop, "Extra Object Update", "Refresh this object again on frame changes, dependency graph hack"); + + prop = RNA_def_property(srna, "extra_recalc_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "depsflag", OB_DEPS_EXTRA_DATA_RECALC); + RNA_def_property_ui_text(prop, "Extra Data Update", "Refresh this object's data again on frame changes, dependency graph hack"); + /* duplicates */ prop = RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag"); From de6fe1294c7bddf59997a0de241a1d500d32ee89 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 18:31:14 +0000 Subject: [PATCH 120/132] minor speedup for DM_to_bmesh_ex(), only duplicate the edge array when the derivedMesh type isn't a CDDM. --- source/blender/blenkernel/intern/modifiers_bmesh.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 849471a083b..d6676e5a8bf 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -59,7 +59,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; - int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */ char has_orig_hflag = 0; int cd_vert_bweight_offset; @@ -95,7 +96,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ - mv = mvert = dm->getVertArray(dm); + mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm); for (i = 0; i < totvert; i++, mv++) { v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); @@ -113,10 +114,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) *orig_index = ORIGINDEX_NONE; } } + if (!is_cddm) MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ - me = medge = dm->dupEdgeArray(dm); + me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD); @@ -135,7 +137,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) *orig_index = ORIGINDEX_NONE; } } - MEM_freeN(medge); + if (!is_cddm) MEM_freeN(medge); if (is_init) bm->elem_index_dirty &= ~BM_EDGE; /* do faces */ From 91d4fb5d6c1f8f3986d7885e56c8f5f99bacd2a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Jan 2013 18:34:09 +0000 Subject: [PATCH 121/132] speedup for DM_to_bmesh_ex(), no need to check vertex order when converting faces since the loops are already in order, will speedup modifiers that use bmesh. --- source/blender/blenkernel/intern/modifiers_bmesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index d6676e5a8bf..a6c2325c740 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -161,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) edges[j] = etable[ml->e]; } - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD); + f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { continue; From d2f9b8a2c08a07fcc1dad8a32166643a25217aba Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 10 Jan 2013 18:54:01 +0000 Subject: [PATCH 122/132] Fix [#33825] Menu list widget does not work on UV and Vertex Colors Own stupid mistake in recent UI list refactor - those two lists are a good example where a non-void 'id' is necessary, as they use the same class in the same window... Else, the same object is shared by the two, which can't work! :) --- release/scripts/startup/bl_ui/properties_data_mesh.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 373d727063e..5fdb71b855f 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -330,7 +330,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): row = layout.row() col = row.column() - col.template_list("MESH_UL_uvmaps_vcols", "", me, "uv_textures", me.uv_textures, "active_index", rows=2) + col.template_list("MESH_UL_uvmaps_vcols", "uvmaps", me, "uv_textures", me.uv_textures, "active_index", rows=2) col = row.column(align=True) col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="") @@ -353,7 +353,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): row = layout.row() col = row.column() - col.template_list("MESH_UL_uvmaps_vcols", "", me, "vertex_colors", me.vertex_colors, "active_index", rows=2) + col.template_list("MESH_UL_uvmaps_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2) col = row.column(align=True) col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="") From 0deb074f1c09d4e2bf74cd099bce565aea4527bb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Jan 2013 19:28:16 +0000 Subject: [PATCH 123/132] Fix #33824: cycles non-progressive render mode did not do correct path termination, leading to too much noise when the min bounce setting was lower than max bounce. --- intern/cycles/kernel/kernel_path.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 6302031475a..532c32896d9 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -486,7 +486,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #ifdef __NON_PROGRESSIVE__ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, - float3 throughput, float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) + float3 throughput, float throughput_normalize, + float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) { #ifdef __LAMP_MIS__ float ray_t = 0.0f; @@ -558,7 +559,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray /* path termination. this is a strange place to put the termination, it's * mainly due to the mixed in MIS that we use. gives too many unneeded * shader evaluations, only need emission if we are going to terminate */ - float probability = path_state_terminate_probability(kg, &state, throughput); + float probability = path_state_terminate_probability(kg, &state, throughput*throughput_normalize); float terminate = path_rng(kg, rng, sample, rng_offset + PRNG_TERMINATE); if(terminate >= probability) { @@ -946,7 +947,8 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam #endif kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer, - tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); + tp*num_samples_inv, num_samples, + min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L); } } From 3fc0d2691ddc1a0c8b1a808791924561b306cec1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 01:30:44 +0000 Subject: [PATCH 124/132] include a stacktrace in the crashlog text written by the segfault handler. --- source/blender/blenkernel/BKE_report.h | 2 +- source/blender/blenkernel/intern/report.c | 4 +- source/creator/creator.c | 81 ++++++++++++++++++----- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 72611de107e..e659954a3ac 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -74,7 +74,7 @@ Report *BKE_reports_last_displayable(ReportList *reports); int BKE_reports_contain(ReportList *reports, ReportType level); -// int BKE_report_write_file_fp(struct FILE *fp, ReportList *reports, const char *header); +bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header); bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header); #ifdef __cplusplus diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3acb35260cb..1fd7dc14c23 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -302,7 +302,7 @@ int BKE_reports_contain(ReportList *reports, ReportType level) return FALSE; } -static bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header) +bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header) { Report *report; @@ -321,8 +321,6 @@ bool BKE_report_write_file(const char *filepath, ReportList *reports, const char { FILE *fp; - /* first try create the file, if it exists call without 'O_CREAT', - * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ errno = 0; fp = BLI_fopen(filepath, "wb"); if (fp == NULL) { diff --git a/source/creator/creator.c b/source/creator/creator.c index 7dd43840c91..f564e8c8fbf 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -40,11 +40,16 @@ # include #endif +/* crash handler */ #ifdef WIN32 # include /* getpid */ #else # include /* getpid */ #endif +/* for backtrace */ +#ifndef WIN32 +# include +#endif #ifdef WIN32 # include @@ -54,6 +59,7 @@ #include #include #include +#include /* This little block needed for linking to Blender... */ @@ -438,6 +444,32 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat return 0; } +static void blender_crash_handler_backtrace(FILE *fp) +{ +#ifndef WIN32 +#define SIZE 100 + void *buffer[SIZE]; + int nptrs; + char **strings; + int i; + + fputs("\n# backtrace\n", fp); + + /* include a backtrace for good measure */ + nptrs = backtrace(buffer, SIZE); + strings = backtrace_symbols(buffer, nptrs); + for (i = 0; i < nptrs; i++) { + fputs(strings[i], fp); + fputc('\n', fp); + } + + free(strings); +#undef SIZE +#else /* WIN32 */ + /* TODO */ + (void)fp; +#endif +} static void blender_crash_handler(int signum) { @@ -460,27 +492,40 @@ static void blender_crash_handler(int signum) } #endif - { - char header[512]; - wmWindowManager *wm = G.main->wm.first; + FILE *fp; + char header[512]; + wmWindowManager *wm = G.main->wm.first; - char fname[FILE_MAX]; + char fname[FILE_MAX]; - if (!G.main->name[0]) { - BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt"); - } - else { - BLI_strncpy(fname, G.main->name, sizeof(fname)); - BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); - } - - printf("Writing: %s\n", fname); - fflush(stdout); - - BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); - - BKE_report_write_file(fname, &wm->reports, header); + if (!G.main->name[0]) { + BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt"); } + else { + BLI_strncpy(fname, G.main->name, sizeof(fname)); + BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); + } + + printf("Writing: %s\n", fname); + fflush(stdout); + + BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); + + /* open the crash log */ + errno = 0; + fp = BLI_fopen(fname, "wb"); + if (fp == NULL) { + fprintf(stderr, "Unable to save '%s': %s\n", + fname, errno ? strerror(errno) : "Unknown error opening file"); + } + else { + BKE_report_write_file_fp(fp, &wm->reports, header); + + blender_crash_handler_backtrace(fp); + + fclose(fp); + } + /* really crash */ signal(signum, SIG_DFL); From 0c3e570868b86c26905c7f731e61f47a9e99deca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 01:41:27 +0000 Subject: [PATCH 125/132] remove CustomData_get_active_offset(), use CustomData_get_offset to return the active layer, matching CustomData_get() --- source/blender/blenkernel/BKE_customdata.h | 1 - source/blender/blenkernel/intern/customdata.c | 11 +---------- source/blender/blenkernel/intern/editderivedmesh.c | 6 +++--- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 30b15a24a7e..36733d1ced0 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -251,7 +251,6 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); int CustomData_get_offset(const struct CustomData *data, int type); int CustomData_get_n_offset(const struct CustomData *data, int type, int n); -int CustomData_get_active_offset(const struct CustomData *data, int type); int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index aca16861a75..e31d7133daf 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2098,7 +2098,7 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type, int CustomData_get_offset(const CustomData *data, int type) { /* get the layer index of the active layer of type */ - int layer_index = CustomData_get_layer_index(data, type); + int layer_index = CustomData_get_active_layer_index(data, type); if (layer_index < 0) return -1; return data->layers[layer_index].offset; @@ -2113,15 +2113,6 @@ int CustomData_get_n_offset(const CustomData *data, int type, int n) return data->layers[layer_index].offset; } -int CustomData_get_active_offset(const CustomData *data, int type) -{ - /* get the layer index of the active layer of type */ - int layer_index = CustomData_get_active_layer_index(data, type); - if (layer_index < 0) return -1; - - return data->layers[layer_index].offset; -} - int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name) { /* get the layer index of the first layer of type */ diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 5bf0f503a51..91577320a9c 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -810,9 +810,9 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BMFace *efa; MLoopUV *luv[3], dummyluv = {{0}}; MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; - const int cd_loop_uv_offset = CustomData_get_active_offset(&bm->ldata, CD_MLOOPUV); - const int cd_loop_color_offset = CustomData_get_active_offset(&bm->ldata, CD_MLOOPCOL); - const int cd_poly_tex_offset = CustomData_get_active_offset(&bm->pdata, CD_MTEXPOLY); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_color_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL); + const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); bool has_uv = (cd_loop_uv_offset != -1); bool has_vcol = (cd_loop_color_offset != -1); int i; From 61833ddd5a9ddb0d43e8b7d64ddfd90ea7f4b529 Mon Sep 17 00:00:00 2001 From: Alex Fraser Date: Fri, 11 Jan 2013 02:03:22 +0000 Subject: [PATCH 126/132] Fix own mistake in SPH solver selection. Thanks Campbell for pointing it out. --- source/blender/blenkernel/intern/particle_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index eabfbf2e251..3d777e46442 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4223,7 +4223,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) ParticleSettings *part = sim->psys->part; psys_sph_init(sim, &sphdata); - if (part->fluid->flag & SPH_SOLVER_DDR) { + if (part->fluid->solver == SPH_SOLVER_DDR) { /* Apply SPH forces using double-density relaxation algorithm * (Clavat et. al.) */ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) From 17c428d4df91cab78f9f77c03e7973e0e806f045 Mon Sep 17 00:00:00 2001 From: Alex Fraser Date: Fri, 11 Jan 2013 03:06:10 +0000 Subject: [PATCH 127/132] Changing units of stiffness parameter in classical (new) SPH solver: used to be speed of sound squared; now just speed of sound. The classical SPH solver was not in 2.65, so this change is unlikely to affect many users. But beta users who have been trying it out will need to change the stiffness parameter to sqrt(old value). --- source/blender/blenkernel/intern/particle_system.c | 3 ++- source/blender/makesrna/intern/rna_particle.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3d777e46442..5eac86a7e77 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2697,7 +2697,8 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo /* 4.77 is an experimentally determined density factor */ float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); - float stiffness = fluid->stiffness_k; + // Use speed of sound squared + float stiffness = pow2(fluid->stiffness_k); ParticleData *npa; float vec[3]; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 6dc6d8809f0..4a520cdc729 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1545,9 +1545,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna) /* Double density relaxation */ prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness_k"); - RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); - RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is"); + RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is (speed of sound)"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE); From 65497a25ba4f9468b83b9e02b9fbf96d87042192 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 03:19:52 +0000 Subject: [PATCH 128/132] fix for error in gradient theme rgba_char_args_set() use, was setting char's to float values. --- source/blender/editors/interface/resources.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 0627fad7227..ac7d423bf00 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -783,7 +783,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); rgba_char_args_set(btheme->tv3d.gradients.gradient, 0, 0, 0, 0); - rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 0.225, 0.225, 0.225, 1.0); + rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255); btheme->tv3d.gradients.show_grad = FALSE; /* space buttons */ From 4d7583b66f083d2b7278653016365e20f22e6d57 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 03:21:24 +0000 Subject: [PATCH 129/132] code cleanup: warnings, also add check in crash handler that a wmWindowManager is present. --- intern/cycles/blender/blender_curves.cpp | 20 +++++++++++++------ source/blender/blenkernel/intern/customdata.c | 1 + source/blender/makesrna/intern/rna_scene.c | 2 ++ source/creator/creator.c | 4 +++- source/gameengine/Ketsji/KX_GameObject.cpp | 1 - source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 2 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 2 +- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 4fad7d45162..41e1249dae7 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -330,13 +330,17 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents) { +#if 0 int keyno = 0; +#endif if(!(mesh && b_mesh && b_ob && CData)) return false; +#if 0 Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); +#endif BL::Object::modifiers_iterator b_mod; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { @@ -348,12 +352,13 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { - +#if 0 int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); int shader = mesh->used_shaders[mi]; int draw_step = b_psys.settings().draw_step(); int ren_step = (int)pow((float)2.0f,(float)draw_step); - /*b_psys.settings().render_step(draw_step);*/ + b_psys.settings().render_step(draw_step); +#endif int totparts = b_psys.particles.length(); int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; @@ -397,13 +402,16 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, int vcol_num) { +#if 0 int keyno = 0; - +#endif if(!(mesh && b_mesh && b_ob && CData)) return false; +#if 0 Transform tfm = get_transform(b_ob->matrix_world()); Transform itfm = transform_quick_inverse(tfm); +#endif BL::Object::modifiers_iterator b_mod; for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) { @@ -415,13 +423,13 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); if((b_psys.settings().render_type()==BL::ParticleSettings::render_type_PATH)&&(b_psys.settings().type()==BL::ParticleSettings::type_HAIR)) { - +#if 0 int mi = clamp(b_psys.settings().material()-1, 0, mesh->used_shaders.size()-1); int shader = mesh->used_shaders[mi]; int draw_step = b_psys.settings().draw_step(); int ren_step = (int)pow((float)2.0f,(float)draw_step); - /*b_psys.settings().render_step(draw_step);*/ - + b_psys.settings().render_step(draw_step); +#endif int totparts = b_psys.particles.length(); int totchild = b_psys.child_particles.length() * b_psys.settings().draw_percentage() / 100; int totcurves = totchild; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index e31d7133daf..f3548f776f5 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2345,6 +2345,7 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest, default: /* should never happen */ BLI_assert(!"invalid type given"); iter_type = BM_VERTS_OF_MESH; + totelem = bm->totvert; } CustomData_merge(source, dest, mask, alloctype, 0); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ced72dbeb99..663e09e5688 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -275,9 +275,11 @@ EnumPropertyItem image_color_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifdef RNA_RUNTIME #define IMAGE_COLOR_MODE_BW image_color_mode_items[0] #define IMAGE_COLOR_MODE_RGB image_color_mode_items[1] #define IMAGE_COLOR_MODE_RGBA image_color_mode_items[2] +#endif EnumPropertyItem image_color_depth_items[] = { /* 1 (monochrome) not used */ diff --git a/source/creator/creator.c b/source/creator/creator.c index f564e8c8fbf..ac0508ac10d 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -519,7 +519,9 @@ static void blender_crash_handler(int signum) fname, errno ? strerror(errno) : "Unknown error opening file"); } else { - BKE_report_write_file_fp(fp, &wm->reports, header); + if (wm) { + BKE_report_write_file_fp(fp, &wm->reports, header); + } blender_crash_handler_backtrace(fp); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index c7f6954fd6c..eec45669e04 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -42,7 +42,6 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#define KX_INERTIA_INFINITE 10000 #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" #include "KX_GameObject.h" diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f0d5d5c6685..87683f8b57b 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -83,7 +83,7 @@ // not valid, skip rendering this frame. //#define NZC_GUARDED_OUTPUT #define DEFAULT_LOGIC_TIC_RATE 60.0 -#define DEFAULT_PHYSICS_TIC_RATE 60.0 +//#define DEFAULT_PHYSICS_TIC_RATE 60.0 #ifdef FREE_WINDOWS /* XXX mingw64 (gcc 4.7.0) defines a macro for DrawText that translates to DrawTextA. Not good */ #ifdef DrawText diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 02995a53954..6b3f745b899 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -198,7 +198,7 @@ static PyObject *gp_OrigPythonSysModules= NULL; /* Macro for building the keyboard translation */ //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyLong_FromLong(SCA_IInputDevice::KX_##name)) -#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item) +//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ #define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromLong(name2)); Py_DECREF(item) From d0569dd68ed116b6d1998c9712875c6abafa1875 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 03:26:49 +0000 Subject: [PATCH 130/132] win32 has no kill, force crash for now, perhaps windows devs can do this more correctly. --- source/creator/creator.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/creator/creator.c b/source/creator/creator.c index ac0508ac10d..4a2274180e7 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -531,7 +531,12 @@ static void blender_crash_handler(int signum) /* really crash */ signal(signum, SIG_DFL); +#ifndef WIN32 kill(getpid(), signum); +#else + /* force crash on windows for now */ + *((void **)NULL) = NULL; +#endif } From a4d5ef8c7d6b8d1e73126b124aad3b4580370fa3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 04:09:54 +0000 Subject: [PATCH 131/132] fix for bpy.props string get-length callback, PyUnicode_GetLength() isn't a measure of the buffer size. --- source/blender/python/intern/bpy_props.c | 33 +++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 8769700f32c..f3fa0c9a0a9 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -974,20 +974,18 @@ static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *p printf_func_error(py_func); value[0] = '\0'; } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + value[0] = '\0'; + Py_DECREF(ret); + } else { Py_ssize_t length; const char *buffer = _PyUnicode_AsStringAndSize(ret, &length); - - if (!buffer) { - if (PyErr_Occurred()) { /* should always be true */ - printf_func_error(py_func); - } - value[0] = '\0'; - } - else { - memcpy(value, buffer, length + 1); - } - + memcpy(value, buffer, length + 1); Py_DECREF(ret); } @@ -1034,9 +1032,20 @@ static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA if (ret == NULL) { printf_func_error(py_func); + length = 0; + } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + length = 0; + Py_DECREF(ret); } else { - length = PyUnicode_GetLength(ret); + Py_ssize_t length_ssize_t = 0; + _PyUnicode_AsStringAndSize(ret, &length_ssize_t); + length = length_ssize_t; Py_DECREF(ret); } From f68e9db583489d541d535791536ea20bc1ae1d76 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 04:34:15 +0000 Subject: [PATCH 132/132] add padding for node view-all, view-home operators. --- source/blender/blenlib/BLI_rect.h | 2 ++ source/blender/blenlib/intern/rct.c | 24 +++++++++++++++++++ .../blender/editors/space_graph/graph_edit.c | 9 +------ source/blender/editors/space_node/node_view.c | 3 +++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index f2e26093711..3c9363039b2 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -56,6 +56,8 @@ void BLI_rctf_translate(struct rctf *rect, float x, float y); void BLI_rcti_translate(struct rcti *rect, int x, int y); void BLI_rcti_resize(struct rcti *rect, int x, int y); void BLI_rctf_resize(struct rctf *rect, float x, float y); +void BLI_rcti_scale(rcti *rect, const float scale); +void BLI_rctf_scale(rctf *rect, const float scale); void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac); //void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac); int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index fb767f54e55..4bd7715ea7a 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -317,6 +317,30 @@ void BLI_rctf_resize(rctf *rect, float x, float y) rect->ymax = rect->ymin + y; } +void BLI_rcti_scale(rcti *rect, const float scale) +{ + const int cent_x = BLI_rcti_cent_x(rect); + const int cent_y = BLI_rcti_cent_y(rect); + const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f); + const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f); + rect->xmin = cent_x - size_x_half; + rect->ymin = cent_y - size_y_half; + rect->xmax = cent_x + size_x_half; + rect->ymax = cent_y + size_y_half; +} + +void BLI_rctf_scale(rctf *rect, const float scale) +{ + const float cent_x = BLI_rctf_cent_x(rect); + const float cent_y = BLI_rctf_cent_y(rect); + const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f); + const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f); + rect->xmin = cent_x - size_x_half; + rect->ymin = cent_y - size_y_half; + rect->xmax = cent_x + size_x_half; + rect->ymax = cent_y + size_y_half; +} + void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac) { const float ifac = 1.0f - fac; diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 21b0ed99f0b..b92430ce0e9 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -217,7 +217,6 @@ void GRAPH_OT_previewrange_set(wmOperatorType *ot) static int graphkeys_viewall(bContext *C, const short do_sel_only, const short include_handles) { bAnimContext ac; - float extra; rctf cur_new; /* get editor data */ @@ -230,13 +229,7 @@ static int graphkeys_viewall(bContext *C, const short do_sel_only, const short i &cur_new.ymin, &cur_new.ymax, do_sel_only, include_handles); - extra = 0.1f * BLI_rctf_size_x(&cur_new); - cur_new.xmin -= extra; - cur_new.xmax += extra; - - extra = 0.1f * BLI_rctf_size_y(&cur_new); - cur_new.ymin -= extra; - cur_new.ymax += extra; + BLI_rctf_scale(&cur_new, 1.1f); UI_view2d_smooth_view(C, ac.ar, &cur_new); diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index 492ff0dcbd4..a69e73c1489 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -118,6 +118,9 @@ static int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar, cons cur_new.xmin = cur_new.xmin - width_new / 2.0f; cur_new.xmax = cur_new.xmax + width_new / 2.0f; } + + /* add some padding */ + BLI_rctf_scale(&cur_new, 1.1f); } UI_view2d_smooth_view(C, ar, &cur_new);