diff options
Diffstat (limited to 'source/blender/makesrna')
36 files changed, 742 insertions, 348 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index a1af3f98274..f83608fa24b 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -783,6 +783,9 @@ const struct ListBase *RNA_struct_type_functions(StructRNA *srna); char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len); +bool RNA_struct_available_or_report(struct ReportList *reports, const char *identifier); +bool RNA_struct_bl_idname_ok_or_report(struct ReportList *reports, const char *identifier, const char *sep); + /* Properties * * Access to struct properties. All this works with RNA pointers rather than diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 6e62313b00a..42ffe774720 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -62,7 +62,8 @@ void RNA_def_struct_refine_func(StructRNA *srna, const char *refine); void RNA_def_struct_idprops_func(StructRNA *srna, const char *refine); void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance); void RNA_def_struct_path_func(StructRNA *srna, const char *path); -void RNA_def_struct_identifier(StructRNA *srna, const char *identifier); +void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier); +void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier); void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description); void RNA_def_struct_ui_icon(StructRNA *srna, int icon); void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext); @@ -216,8 +217,8 @@ void RNA_enum_item_end(EnumPropertyItem **items, int *totitem); /* Memory management */ -void RNA_def_struct_duplicate_pointers(StructRNA *srna); -void RNA_def_struct_free_pointers(StructRNA *srna); +void RNA_def_struct_duplicate_pointers(BlenderRNA *brna, StructRNA *srna); +void RNA_def_struct_free_pointers(BlenderRNA *brna, StructRNA *srna); void RNA_def_func_duplicate_pointers(FunctionRNA *func); void RNA_def_func_free_pointers(FunctionRNA *func); void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop); diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 1c9b3593d17..f8e240d57bf 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -114,6 +114,8 @@ extern EnumPropertyItem rna_enum_brush_image_tool_items[]; extern EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[]; +extern EnumPropertyItem rna_enum_uv_sculpt_tool_items[]; + extern EnumPropertyItem rna_enum_axis_xy_items[]; extern EnumPropertyItem rna_enum_axis_xyz_items[]; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index cd04f9e8a6d..e119c49401e 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -178,7 +178,7 @@ typedef enum PropertyFlag { * after every typed char, instead of waiting final validation. Used e.g. for text searchbox. * It will also cause UI_BUT_VALUE_CLEAR to be set for text buttons. We could add an own flag * for search/filter properties, but this works just fine for now. */ - PROP_TEXTEDIT_UPDATE = (1 << 31), + PROP_TEXTEDIT_UPDATE = (1u << 31), /* icon */ PROP_ICONS_CONSECUTIVE = (1 << 12), @@ -436,6 +436,8 @@ typedef enum StructFlag { STRUCT_NO_IDPROPERTIES = (1 << 6), /* Menus and Panels don't need properties */ STRUCT_NO_DATABLOCK_IDPROPERTIES = (1 << 7), /* e.g. for Operator */ STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES = (1 << 8), /* for PropertyGroup which contains pointers to datablocks */ + STRUCT_PUBLIC_NAMESPACE = (1 << 9), /* Added to type-map #BlenderRNA.structs_map */ + STRUCT_PUBLIC_NAMESPACE_INHERIT = (1 << 10), /* All subtypes are added too. */ } StructFlag; typedef int (*StructValidateFunc)(struct PointerRNA *ptr, void *data, int *have_function); diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 6a08d762920..9d0ba5586af 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -140,6 +140,9 @@ set(GENSRC_CFLAGS) if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) set(GENSRC_CFLAGS "-Wno-missing-prototypes") endif() +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(GENSRC_CFLAGS "${GENSRC_CFLAGS} -Wno-missing-variable-declarations") +endif() if(GENSRC_CFLAGS) set_source_files_properties(${GENSRC} PROPERTIES COMPILE_FLAGS "${GENSRC_CFLAGS}") diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index de436172bfd..9471d0e3fcf 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2583,17 +2583,23 @@ static void rna_generate_blender(BlenderRNA *brna, FILE *f) { StructRNA *srna; - fprintf(f, "BlenderRNA BLENDER_RNA = {"); - + fprintf(f, + "BlenderRNA BLENDER_RNA = {\n" + "\t.structs = {" + ); srna = brna->structs.first; - if (srna) fprintf(f, "{&RNA_%s, ", srna->identifier); - else fprintf(f, "{NULL, "); + if (srna) fprintf(f, "&RNA_%s, ", srna->identifier); + else fprintf(f, "NULL, "); srna = brna->structs.last; - if (srna) fprintf(f, "&RNA_%s}", srna->identifier); - else fprintf(f, "NULL}"); + if (srna) fprintf(f, "&RNA_%s},\n", srna->identifier); + else fprintf(f, "NULL},\n"); - fprintf(f, "};\n\n"); + fprintf(f, + "\t.structs_map = NULL,\n" + "\t.structs_len = 0,\n" + "};\n\n" + ); } static void rna_generate_property_prototypes(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE *f) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index a299302f04f..bfa1e7cef93 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -76,6 +76,9 @@ void RNA_init(void) StructRNA *srna; PropertyRNA *prop; + BLENDER_RNA.structs_map = BLI_ghash_str_new_ex(__func__, 2048); + BLENDER_RNA.structs_len = 0; + for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) { if (!srna->cont.prophash) { srna->cont.prophash = BLI_ghash_str_new("RNA_init gh"); @@ -86,6 +89,9 @@ void RNA_init(void) } } } + BLI_assert(srna->flag & STRUCT_PUBLIC_NAMESPACE); + BLI_ghash_insert(BLENDER_RNA.structs_map, (void *)srna->identifier, srna); + BLENDER_RNA.structs_len += 1; } } @@ -513,13 +519,7 @@ static const char *rna_ensure_property_name(const PropertyRNA *prop) StructRNA *RNA_struct_find(const char *identifier) { - StructRNA *type; - if (identifier) { - for (type = BLENDER_RNA.structs.first; type; type = type->cont.next) - if (STREQ(type->identifier, identifier)) - return type; - } - return NULL; + return BLI_ghash_lookup(BLENDER_RNA.structs_map, identifier); } const char *RNA_struct_identifier(const StructRNA *type) @@ -815,6 +815,89 @@ char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, i return NULL; } +/** + * Use when registering structs with the #STRUCT_PUBLIC_NAMESPACE flag. + */ +bool RNA_struct_available_or_report(ReportList *reports, const char *identifier) +{ + const StructRNA *srna_exists = RNA_struct_find(identifier); + if (UNLIKELY(srna_exists != NULL)) { + /* Use comprehensive string construction since this is such a rare occurrence + * and information here may cut down time troubleshooting. */ + DynStr *dynstr = BLI_dynstr_new(); + BLI_dynstr_appendf(dynstr, "Type identifier '%s' is already in use: '", identifier); + BLI_dynstr_append(dynstr, srna_exists->identifier); + int i = 0; + if (srna_exists->base) { + for (const StructRNA *base = srna_exists->base; base; base = base->base) { + BLI_dynstr_append(dynstr, "("); + BLI_dynstr_append(dynstr, base->identifier); + i += 1; + } + while (i--) { + BLI_dynstr_append(dynstr, ")"); + } + } + BLI_dynstr_append(dynstr, "'."); + char *result = BLI_dynstr_get_cstring(dynstr); + BLI_dynstr_free(dynstr); + BKE_report(reports, RPT_ERROR, result); + MEM_freeN(result); + return false; + } + else { + return true; + } +} + +bool RNA_struct_bl_idname_ok_or_report(ReportList *reports, const char *identifier, const char *sep) +{ + const int len_sep = strlen(sep); + const int len_id = strlen(identifier); + const char *p = strstr(identifier, sep); + /* TODO: make error, for now warning until add-ons update. */ +#if 1 + const int report_level = RPT_WARNING; + const bool failure = true; +#else + const int report_level = RPT_ERROR; + const bool failure = false; +#endif + if (p == NULL || p == identifier || p + len_sep >= identifier + len_id) { + BKE_reportf(reports, report_level, "'%s' doesn't contain '%s' with prefix & suffix", identifier, sep); + return failure; + } + + const char *c, *start, *end, *last; + start = identifier; + end = p; + last = end - 1; + for (c = start; c != end; c++) { + if (((*c >= 'A' && *c <= 'Z') || + ((c != start) && (*c >= '0' && *c <= '9')) || + ((c != start) && (c != last) && (*c == '_'))) == 0) + { + BKE_reportf(reports, report_level, "'%s' doesn't have upper case alpha-numeric prefix", identifier); + return failure; + } + } + + start = p + len_sep; + end = identifier + len_id; + last = end - 1; + for (c = start; c != end; c++) { + if (((*c >= 'A' && *c <= 'Z') || + (*c >= 'a' && *c <= 'z') || + (*c >= '0' && *c <= '9') || + ((c != start) && (c != last) && (*c == '_'))) == 0) + { + BKE_reportf(reports, report_level, "'%s' doesn't have an alpha-numeric suffix", identifier); + return failure; + } + } + return true; +} + /* Property Information */ const char *RNA_property_identifier(PropertyRNA *prop) @@ -6446,7 +6529,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna)); return -1; } - + *((void **)dest) = *((void **)src); break; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index f271bccd326..d9f673acf89 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -270,9 +270,10 @@ static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, v /* check if we have registered this info before, and remove it */ ksi = ANIM_keyingset_info_find_name(dummyksi.idname); - if (ksi && ksi->ext.srna) + if (ksi && ksi->ext.srna) { rna_KeyingSetInfo_unregister(bmain, ksi->ext.srna); - + } + /* create a new KeyingSetInfo type */ ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info"); memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 891f5c43ca6..ec700eb00de 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -480,7 +480,7 @@ static int rna_Armature_is_editmode_get(PointerRNA *ptr) static void rna_Armature_transform(struct bArmature *arm, float *mat) { - ED_armature_transform(arm, (float (*)[4])mat); + ED_armature_transform(arm, (float (*)[4])mat, true); } #else diff --git a/source/blender/makesrna/intern/rna_curve_api.c b/source/blender/makesrna/intern/rna_curve_api.c index b4b3aa84ec5..be6808567bb 100644 --- a/source/blender/makesrna/intern/rna_curve_api.c +++ b/source/blender/makesrna/intern/rna_curve_api.c @@ -45,7 +45,7 @@ #ifdef RNA_RUNTIME static void rna_Curve_transform(Curve *cu, float *mat, int shape_keys) { - BKE_curve_transform(cu, (float (*)[4])mat, shape_keys); + BKE_curve_transform(cu, (float (*)[4])mat, shape_keys, true); DAG_id_tag_update(&cu->id, 0); } diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 42c0344f46e..0e91c158669 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -135,6 +135,38 @@ void rna_freelistN(ListBase *listbase) listbase->first = listbase->last = NULL; } +static void rna_brna_structs_add(BlenderRNA *brna, StructRNA *srna) +{ + rna_addtail(&brna->structs, srna); + brna->structs_len += 1; + + /* This exception is only needed for pre-processing. + * otherwise we don't allow empty names. */ + if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && + (srna->identifier[0] != '\0')) + { + BLI_ghash_insert(brna->structs_map, (void *)srna->identifier, srna); + } +} + +#ifdef RNA_RUNTIME +static void rna_brna_structs_remove_and_free(BlenderRNA *brna, StructRNA *srna) +{ + if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && brna->structs_map) { + if (srna->identifier[0] != '\0') { + BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL); + } + } + + RNA_def_struct_free_pointers(NULL, srna); + + if (srna->flag & STRUCT_RUNTIME) { + rna_freelinkN(&brna->structs, srna); + } + brna->structs_len -= 1; +} +#endif + StructDefRNA *rna_find_struct_def(StructRNA *srna) { StructDefRNA *dsrna; @@ -534,6 +566,8 @@ BlenderRNA *RNA_create(void) const char *error_message = NULL; BLI_listbase_clear(&DefRNA.structs); + brna->structs_map = BLI_ghash_str_new_ex(__func__, 2048); + DefRNA.error = 0; DefRNA.preprocess = 1; @@ -640,10 +674,8 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna) rna_freelinkN(&srna->functions, func); } - RNA_def_struct_free_pointers(srna); - if (srna->flag & STRUCT_RUNTIME) - rna_freelinkN(&brna->structs, srna); + rna_brna_structs_remove_and_free(brna, srna); #else UNUSED_VARS(brna, srna); #endif @@ -654,6 +686,9 @@ void RNA_free(BlenderRNA *brna) StructRNA *srna, *nextsrna; FunctionRNA *func; + BLI_ghash_free(brna->structs_map, NULL, NULL); + brna->structs_map = NULL; + if (DefRNA.preprocess) { RNA_define_free(brna); @@ -730,12 +765,19 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN BLI_listbase_clear(&srna->functions); srna->py_type = NULL; + srna->base = srnafrom; + if (DefRNA.preprocess) { - srna->base = srnafrom; dsfrom = rna_find_def_struct(srnafrom); } - else - srna->base = srnafrom; + else { + if (srnafrom->flag & STRUCT_PUBLIC_NAMESPACE_INHERIT) { + srna->flag |= STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT; + } + else { + srna->flag &= ~(STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT); + } + } } srna->identifier = identifier; @@ -747,7 +789,11 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN if (!srnafrom) srna->icon = ICON_DOT; - rna_addtail(&brna->structs, srna); + if (DefRNA.preprocess) { + srna->flag |= STRUCT_PUBLIC_NAMESPACE; + } + + rna_brna_structs_add(brna, srna); if (DefRNA.preprocess) { ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA"); @@ -819,10 +865,8 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char * if (from) { /* find struct to derive from */ - for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) - if (STREQ(srnafrom->identifier, from)) - break; - + /* Inline RNA_struct_find(...) because it wont link from here. */ + srnafrom = BLI_ghash_lookup(brna->structs_map, from); if (!srnafrom) { fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier); DefRNA.error = 1; @@ -901,10 +945,7 @@ void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *struct StructRNA *srnafrom; /* find struct to derive from */ - for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next) - if (STREQ(srnafrom->identifier, structname)) - break; - + srnafrom = BLI_ghash_lookup(brna->structs_map, structname); if (!srnafrom) { fprintf(stderr, "%s: struct %s not found for %s.\n", __func__, structname, srna->identifier); DefRNA.error = 1; @@ -965,7 +1006,32 @@ void RNA_def_struct_path_func(StructRNA *srna, const char *path) if (path) srna->path = (StructPathFunc)path; } -void RNA_def_struct_identifier(StructRNA *srna, const char *identifier) +void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier) +{ + if (DefRNA.preprocess) { + fprintf(stderr, "%s: only at runtime.\n", __func__); + return; + } + + /* Operator registration may set twice, see: operator_properties_init */ + if (srna->flag & STRUCT_PUBLIC_NAMESPACE) { + if (identifier != srna->identifier) { + if (srna->identifier[0] != '\0') { + BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL); + } + if (identifier[0] != '\0') { + BLI_ghash_insert(brna->structs_map, (void *)identifier, srna); + } + } + } + + srna->identifier = identifier; +} + +/** + * Only used in one case when we name the struct for the purpose of useful error messages. + */ +void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier) { if (DefRNA.preprocess) { fprintf(stderr, "%s: only at runtime.\n", __func__); @@ -3262,21 +3328,41 @@ void RNA_enum_item_end(EnumPropertyItem **items, int *totitem) /* Memory management */ #ifdef RNA_RUNTIME -void RNA_def_struct_duplicate_pointers(StructRNA *srna) +void RNA_def_struct_duplicate_pointers(BlenderRNA *brna, StructRNA *srna) { - if (srna->identifier) srna->identifier = BLI_strdup(srna->identifier); - if (srna->name) srna->name = BLI_strdup(srna->name); - if (srna->description) srna->description = BLI_strdup(srna->description); + if (srna->identifier) { + srna->identifier = BLI_strdup(srna->identifier); + if (srna->flag & STRUCT_PUBLIC_NAMESPACE) { + BLI_ghash_replace_key(brna->structs_map, (void *)srna->identifier); + } + } + if (srna->name) { + srna->name = BLI_strdup(srna->name); + } + if (srna->description) { + srna->description = BLI_strdup(srna->description); + } srna->flag |= STRUCT_FREE_POINTERS; } -void RNA_def_struct_free_pointers(StructRNA *srna) +void RNA_def_struct_free_pointers(BlenderRNA *brna, StructRNA *srna) { if (srna->flag & STRUCT_FREE_POINTERS) { - if (srna->identifier) MEM_freeN((void *)srna->identifier); - if (srna->name) MEM_freeN((void *)srna->name); - if (srna->description) MEM_freeN((void *)srna->description); + if (srna->identifier) { + if (srna->flag & STRUCT_PUBLIC_NAMESPACE) { + if (brna != NULL) { + BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL); + } + } + MEM_freeN((void *)srna->identifier); + } + if (srna->name) { + MEM_freeN((void *)srna->name); + } + if (srna->description) { + MEM_freeN((void *)srna->description); + } } } diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index bccc47aa95d..ad63a652b12 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -765,6 +765,38 @@ static void rna_FModifierStepped_end_frame_range(PointerRNA *ptr, float *min, fl *max = MAXFRAMEF; } +static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value) +{ + FModifier *fcm = (FModifier *)ptr->data; + FMod_Stepped *data = fcm->data; + + float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max; + rna_FModifierStepped_start_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max); + value = CLAMPIS(value, prop_clamp_min, prop_clamp_max); + + /* Need to set both step-data's start/end and the start/end on the base-data, + * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009) + */ + data->start_frame = value; + fcm->sfra = value; +} + +static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value) +{ + FModifier *fcm = (FModifier *)ptr->data; + FMod_Stepped *data = fcm->data; + + float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max; + rna_FModifierStepped_end_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max); + value = CLAMPIS(value, prop_clamp_min, prop_clamp_max); + + /* Need to set both step-data's start/end and the start/end on the base-data, + * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009) + */ + data->end_frame = value; + fcm->efra = value; +} + static BezTriple *rna_FKeyframe_points_insert(FCurve *fcu, float frame, float value, int keyframe_type, int flag) { int index = insert_vert_fcurve(fcu, frame, value, (char)keyframe_type, flag | INSERTKEY_NO_USERPREF); @@ -1284,13 +1316,13 @@ static void rna_def_fmodifier_stepped(BlenderRNA *brna) prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "start_frame"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_start_frame_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_start_set", "rna_FModifierStepped_start_frame_range"); RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if applicable)"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update"); prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "end_frame"); - RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_end_frame_range"); + RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_end_set", "rna_FModifierStepped_end_frame_range"); RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if applicable)"); RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update"); } diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 6e0d6ad2bcd..79e1e95b27a 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -74,7 +74,7 @@ static void rna_GPencil_editmode_update(Main *UNUSED(bmain), Scene *UNUSED(scene { /* Notify all places where GPencil data lives that the editing state is different */ WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); - WM_main_add_notifier(NC_SCENE | ND_MODE, NULL); + WM_main_add_notifier(NC_SCENE | ND_MODE | NC_MOVIECLIP, NULL); } static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index b6e84cf8ac3..5ca7e624d88 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -192,6 +192,8 @@ static char *rna_ImageUser_path(PointerRNA *ptr) { return rna_Node_ImageUser_path(ptr); } + default: + break; } } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 344c1781b46..5c706d9d8db 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -291,7 +291,7 @@ static void rna_Image_filepath_from_user(Image *image, ImageUser *image_user, ch static void rna_Image_buffers_free(Image *image) { - BKE_image_free_buffers(image); + BKE_image_free_buffers_ex(image, true); } #else diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index df591659fdb..a470c807091 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -413,6 +413,11 @@ struct StructRNA { struct BlenderRNA { ListBase structs; + /* A map of structs: {StructRNA.identifier -> StructRNA} + * These are ensured to have unique names (with STRUCT_PUBLIC_NAMESPACE enabled). */ + struct GHash *structs_map; + /* Needed because types with an empty identifier aren't included in 'structs_map'. */ + unsigned int structs_len; }; #define CONTAINER_RNA_ID(cont) (*(const char **)(((ContainerRNA *)(cont))+1)) diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index a5abc8a3be2..b960890457b 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -178,6 +178,8 @@ static Mesh *rna_KeyBlock_normals_get_mesh(PointerRNA *ptr, ID *id) return ob->data; } } + default: + break; } } diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c index 1199cccc4e6..a163d9764c1 100644 --- a/source/blender/makesrna/intern/rna_linestyle.c +++ b/source/blender/makesrna/intern/rna_linestyle.c @@ -1620,6 +1620,7 @@ static void rna_def_linestyle(BlenderRNA *brna) prop = RNA_def_property(srna, "panel", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "panel"); RNA_def_property_enum_items(prop, panel_items); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Panel", "Select the property panel to be shown"); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index cb133aa683c..766ed5432af 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -46,6 +46,7 @@ #include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" diff --git a/source/blender/makesrna/intern/rna_meta_api.c b/source/blender/makesrna/intern/rna_meta_api.c index 3d8f375fd88..4c3fa787b94 100644 --- a/source/blender/makesrna/intern/rna_meta_api.c +++ b/source/blender/makesrna/intern/rna_meta_api.c @@ -45,7 +45,7 @@ #ifdef RNA_RUNTIME static void rna_Meta_transform(struct MetaBall *mb, float *mat) { - BKE_mball_transform(mb, (float (*)[4])mat); + BKE_mball_transform(mb, (float (*)[4])mat, true); DAG_id_tag_update(&mb->id, 0); } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1a8dd05a7b5..e53237ae2c1 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3413,6 +3413,13 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Screw", "Offset the revolution along its axis"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "merge_threshold", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "merge_dist"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 1, 4); + RNA_def_property_ui_text(prop, "Merge Distance", "Limit below which to merge vertices"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_normal_flip", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_NORMAL_FLIP); RNA_def_property_ui_text(prop, "Flip", "Flip normals of lathed faces"); @@ -3428,6 +3435,12 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Object Screw", "Use the distance between the objects to make a screw"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + /* Vertex merging parameters */ + prop = RNA_def_property(srna, "use_merge_vertices", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_MERGE); + RNA_def_property_ui_text(prop, "Merge Vertices", "Merge adjacent vertices (screw offset must be zero)"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_smooth_shade", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_SMOOTH_SHADING); RNA_def_property_ui_text(prop, "Smooth Shading", "Output faces with smooth shading rather than flat shaded"); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index e44a6420045..d72c858a5d5 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -659,7 +659,10 @@ static void rna_def_nlastrip(BlenderRNA *brna) prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + /* XXX: Update temporarily disabled so that the property can be edited at all! + * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost + */ + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL); prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME); RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate"); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 22d07d739cd..ee4608b550f 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -73,6 +73,13 @@ EnumPropertyItem rna_enum_node_socket_in_out_items[] = { }; #ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_node_socket_draw_shape_items[] = { + {SOCK_DRAW_SHAPE_CIRCLE, "CIRCLE", 0, "Circle", ""}, + {SOCK_DRAW_SHAPE_SQUARE, "SQUARE", 0, "Square", ""}, + {SOCK_DRAW_SHAPE_DIAMOND, "DIAMOND", 0, "Diamond", ""}, + {0, NULL, 0, NULL, NULL } +}; + static EnumPropertyItem node_socket_type_items[] = { {SOCK_CUSTOM, "CUSTOM", 0, "Custom", ""}, {SOCK_FLOAT, "VALUE", 0, "Value", ""}, @@ -238,10 +245,10 @@ bNodeTreeType *rna_node_tree_type_from_enum(int value) EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, bNodeTreeType *), bool *r_free) { - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; EnumPropertyItem *item = NULL; int totitem = 0, i = 0; - + NODE_TREE_TYPES_BEGIN (nt) { if (poll && !poll(data, nt)) { @@ -261,9 +268,14 @@ EnumPropertyItem *rna_node_tree_type_itemf(void *data, int (*poll)(void *data, b } NODE_TREE_TYPES_END; + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -310,9 +322,9 @@ bNodeType *rna_node_type_from_enum(int value) EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, bNodeType *), bool *r_free) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0, i = 0; - + NODE_TYPES_BEGIN(ntype) if (poll && !poll(data, ntype)) { ++i; @@ -329,9 +341,15 @@ EnumPropertyItem *rna_node_type_itemf(void *data, int (*poll)(void *data, bNodeT ++i; NODE_TYPES_END + + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -378,10 +396,10 @@ bNodeSocketType *rna_node_socket_type_from_enum(int value) EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, bNodeSocketType *), bool *r_free) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0, i = 0; StructRNA *srna; - + NODE_SOCKET_TYPES_BEGIN(stype) if (poll && !poll(data, stype)) { ++i; @@ -399,9 +417,15 @@ EnumPropertyItem *rna_node_socket_type_itemf(void *data, int (*poll)(void *data, ++i; NODE_SOCKET_TYPES_END + + if (totitem == 0) { + *r_free = false; + return DummyRNA_NULL_items; + } + RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -410,25 +434,25 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer EnumPropertyItem *item = NULL; EnumPropertyItem tmp; int totitem = 0; - + /* hack, don't want to add include path to RNA just for this, since in the future RNA types * for nodes should be defined locally at runtime anyway ... */ - + tmp.value = NODE_CUSTOM; tmp.identifier = "CUSTOM"; tmp.name = "Custom"; tmp.description = "Custom Node"; tmp.icon = ICON_NONE; RNA_enum_item_add(&item, &totitem, &tmp); - + tmp.value = NODE_UNDEFINED; tmp.identifier = "UNDEFINED"; tmp.name = "UNDEFINED"; tmp.description = ""; tmp.icon = ICON_NONE; RNA_enum_item_add(&item, &totitem, &tmp); - + #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "Node")) { \ tmp.value = ID; \ @@ -440,7 +464,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer } #include "../../nodes/NOD_static_types.h" #undef DefNode - + if (RNA_struct_is_a(ptr->type, &RNA_ShaderNode)) { #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "ShaderNode")) { \ @@ -468,7 +492,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer #include "../../nodes/NOD_static_types.h" #undef DefNode } - + if (RNA_struct_is_a(ptr->type, &RNA_TextureNode)) { #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ if (STREQ(#Category, "TextureNode")) { \ @@ -485,7 +509,7 @@ static EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C), Pointer RNA_enum_item_end(&item, &totitem); *r_free = true; - + return item; } @@ -578,11 +602,10 @@ static void rna_NodeTree_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &nt->ext); + RNA_struct_free(&BLENDER_RNA, type); ntreeTypeFreeLink(nt); - RNA_struct_free(&BLENDER_RNA, type); - /* update while blender is running */ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); } @@ -614,9 +637,10 @@ static StructRNA *rna_NodeTree_register( /* check if we have registered this tree type before, and remove it */ nt = ntreeTypeFind(dummynt.idname); - if (nt) + if (nt) { rna_NodeTree_unregister(bmain, nt->ext.srna); - + } + /* create a new node tree type */ nt = MEM_callocN(sizeof(bNodeTreeType), "node tree type"); memcpy(nt, &dummynt, sizeof(dummynt)); @@ -1331,11 +1355,11 @@ static void rna_Node_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &nt->ext); + RNA_struct_free(&BLENDER_RNA, type); /* this also frees the allocated nt pointer, no MEM_free call needed! */ nodeUnregisterType(nt); - RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); @@ -1376,8 +1400,9 @@ static bNodeType *rna_Node_register_base(Main *bmain, ReportList *reports, Struc /* check if we have registered this node type before, and remove it */ nt = nodeTypeFind(dummynt.idname); - if (nt) + if (nt) { rna_Node_unregister(bmain, nt->ext.srna); + } /* create a new node type */ nt = MEM_callocN(sizeof(bNodeType), "node type"); @@ -1793,10 +1818,10 @@ static void rna_NodeSocket_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &st->ext_socket); + RNA_struct_free(&BLENDER_RNA, type); nodeUnregisterSocketType(st); - RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); @@ -2617,9 +2642,9 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl) { EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int i = 0, totitem = 0; - + while (rl) { tmp.identifier = rl->name; /* little trick: using space char instead empty string makes the item selectable in the dropdown */ @@ -2631,7 +2656,7 @@ static EnumPropertyItem *renderresult_layers_add_enum(RenderLayer *rl) RNA_enum_item_add(&item, &totitem, &tmp); rl = rl->next; } - + RNA_enum_item_end(&item, &totitem); return item; @@ -2644,18 +2669,17 @@ static EnumPropertyItem *rna_Node_image_layer_itemf(bContext *UNUSED(C), Pointer Image *ima = (Image *)node->id; EnumPropertyItem *item = NULL; RenderLayer *rl; - - if (ima && ima->rr) { - rl = ima->rr->layers.first; - item = renderresult_layers_add_enum(rl); - } - else { - int totitem = 0; - RNA_enum_item_end(&item, &totitem); + + if (ima == NULL || ima->rr == NULL) { + *r_free = false; + return DummyRNA_NULL_items; } - + + rl = ima->rr->layers.first; + item = renderresult_layers_add_enum(rl); + *r_free = true; - + return item; } @@ -2706,19 +2730,22 @@ static EnumPropertyItem *renderresult_views_add_enum(RenderView *rv) } static EnumPropertyItem *rna_Node_image_view_itemf(bContext *UNUSED(C), PointerRNA *ptr, - PropertyRNA *UNUSED(prop), bool *free) + PropertyRNA *UNUSED(prop), bool *r_free) { bNode *node = (bNode *)ptr->data; Image *ima = (Image *)node->id; EnumPropertyItem *item = NULL; RenderView *rv; - if (!ima || !(ima->rr)) return NULL; + if (ima == NULL || ima->rr == NULL) { + *r_free = false; + return DummyRNA_NULL_items; + } rv = ima->rr->views.first; item = renderresult_views_add_enum(rv); - *free = true; + *r_free = true; return item; } @@ -2730,18 +2757,17 @@ static EnumPropertyItem *rna_Node_scene_layer_itemf(bContext *UNUSED(C), Pointer Scene *sce = (Scene *)node->id; EnumPropertyItem *item = NULL; RenderLayer *rl; - - if (sce) { - rl = sce->r.layers.first; - item = renderresult_layers_add_enum(rl); - } - else { - int totitem = 0; - RNA_enum_item_end(&item, &totitem); + + if (sce == NULL) { + *r_free = false; + return DummyRNA_NULL_items; } - + + rl = sce->r.layers.first; + item = renderresult_layers_add_enum(rl); + *r_free = true; - + return item; } @@ -2758,7 +2784,7 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA { bNode *node = (bNode *)ptr->data; EnumPropertyItem *item = NULL; - EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem tmp = {0}; int totitem = 0; switch (node->custom1) { @@ -2795,7 +2821,7 @@ static EnumPropertyItem *rna_Node_channel_itemf(bContext *UNUSED(C), PointerRNA RNA_enum_item_add(&item, &totitem, &tmp); break; default: - break; + return DummyRNA_NULL_items; } RNA_enum_item_end(&item, &totitem); @@ -3339,7 +3365,7 @@ static void def_frame(StructRNA *srna) prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Text"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Text", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -3609,7 +3635,7 @@ static void def_sh_lamp(StructRNA *srna) prop = RNA_def_property(srna, "lamp_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Lamp_object_poll"); RNA_def_property_ui_text(prop, "Lamp Object", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -3983,7 +4009,7 @@ static void def_sh_tex_coord(StructRNA *srna) prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Object", "Use coordinates from this object (for object texture coordinates output)"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -4099,7 +4125,7 @@ static void def_sh_tex_pointdensity(StructRNA *srna) prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Object", "Object to take point data from"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -4796,7 +4822,7 @@ static void def_cmp_render_layers(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL); RNA_def_property_struct_type(prop, "Scene"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Scene", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_scene_layer_update"); @@ -5453,7 +5479,7 @@ static void def_cmp_defocus(StructRNA *srna) RNA_def_property_pointer_sdna(prop, NULL, "id"); RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL); RNA_def_property_struct_type(prop, "Scene"); - RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Scene", "Scene from which to select the active camera (render scene if undefined)"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); @@ -6320,14 +6346,8 @@ static void def_cmp_switch(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } -static void def_cmp_switch_view(StructRNA *srna) +static void def_cmp_switch_view(StructRNA *UNUSED(srna)) { - PropertyRNA *prop; - - prop = RNA_def_property(srna, "check", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0); - RNA_def_property_ui_text(prop, "Switch", "Off: first socket, On: second socket"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_cmp_colorcorrection(StructRNA *srna) @@ -6974,6 +6994,13 @@ static void rna_def_node_socket(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Type", "Data type"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); + prop = RNA_def_property(srna, "draw_shape", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "draw_shape"); + RNA_def_property_enum_items(prop, rna_enum_node_socket_draw_shape_items); + RNA_def_property_enum_default(prop, SOCK_DRAW_SHAPE_CIRCLE); + RNA_def_property_ui_text(prop, "Shape", "Socket shape"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update"); + /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname"); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 3c3d88c858f..00104b8667d 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -446,10 +446,12 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totpart; int totchild = 0; int totface; + int totvert; int num = -1; DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ totface = modifier->dm_final->getNumTessFaces(modifier->dm_final); + totvert = modifier->dm_final->getNumVerts(modifier->dm_final); /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -484,13 +486,29 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys return num; } } + else if (part->from == PART_FROM_VERT) { + if (num != DMCACHE_NOTFOUND && num < totvert) { + MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + + *r_fuv = &particle->fuv; + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int i = 0; i < totface; i++, mface++) { + if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { + return i; + } + } + } + } } else { ChildParticle *cpa = particlesystem->child + particle_no - totpart; num = cpa->num; if (part->childtype == PART_CHILD_FACES) { - if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) { + if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME, PART_FROM_VERT)) { if (num != DMCACHE_NOTFOUND && num < totface) { *r_fuv = &cpa->fuv; return num; @@ -510,6 +528,22 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys return num; } } + else if (part->from == PART_FROM_VERT) { + if (num != DMCACHE_NOTFOUND && num < totvert) { + MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE); + + *r_fuv = &parent->fuv; + + /* This finds the first face to contain the emitting vertex, + * this is not ideal, but is mostly fine as UV seams generally + * map to equal-colored parts of a texture */ + for (int i = 0; i < totface; i++, mface++) { + if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) { + return i; + } + } + } + } } } @@ -2095,7 +2129,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); - + prop = RNA_def_property(srna, "use_die_on_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 44dcb72264a..a66c160ed1a 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -33,6 +33,8 @@ #include "BLI_utildefines.h" #include "BLI_path_util.h" +#include "BKE_scene.h" + #include "RNA_define.h" #include "RNA_enum_types.h" @@ -123,6 +125,11 @@ static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Sce return IMB_colormanagement_support_glsl_draw(&scene->view_settings); } +static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *scene) +{ + return BKE_render_preview_pixel_size(&scene->r); +} + static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene) { IMB_colormanagement_setup_glsl_draw(&scene->view_settings, @@ -279,8 +286,8 @@ static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &et->ext); - BLI_freelinkN(&R_engines, et); RNA_struct_free(&BLENDER_RNA, type); + BLI_freelinkN(&R_engines, et); } static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -647,6 +654,13 @@ static void rna_def_render_engine(BlenderRNA *brna) parm = RNA_def_boolean(func, "supported", 0, "Supported", ""); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "get_preview_pixel_size", "engine_get_preview_pixel_size"); + RNA_def_function_ui_description(func, "Get the pixel size that should be used for preview rendering"); + parm = RNA_def_pointer(func, "scene", "Scene", "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_int(func, "pixel_size", 0, 1, 8, "Pixel Size", "", 1, 8); + RNA_def_function_return(func, parm); + RNA_define_verify_sdna(0); prop = RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index abded187b33..b50ac7a61ef 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -983,21 +983,32 @@ static int rna_Function_use_self_type_get(PointerRNA *ptr) /* Blender RNA */ +static int rna_struct_is_publc(CollectionPropertyIterator *UNUSED(iter), void *data) +{ + StructRNA *srna = data; + + return !(srna->flag & STRUCT_PUBLIC_NAMESPACE); +} + + static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - rna_iterator_listbase_begin(iter, &((BlenderRNA *)ptr->data)->structs, NULL); + BlenderRNA *brna = ptr->data; + rna_iterator_listbase_begin(iter, &brna->structs, rna_struct_is_publc); } /* optional, for faster lookups */ static int rna_BlenderRNA_structs_length(PointerRNA *ptr) { - return BLI_listbase_count(&((BlenderRNA *)ptr->data)->structs); + BlenderRNA *brna = ptr->data; + BLI_assert(brna->structs_len == BLI_listbase_count(&brna->structs)); + return brna->structs_len; } static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) { - StructRNA *srna = BLI_findlink(&((BlenderRNA *)ptr->data)->structs, index); - - if (srna) { + BlenderRNA *brna = ptr->data; + StructRNA *srna = index < brna->structs_len ? BLI_findlink(&brna->structs, index) : NULL; + if (srna != NULL) { RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr); return true; } @@ -1007,12 +1018,11 @@ static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, Pointer } static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) { - StructRNA *srna = ((BlenderRNA *)ptr->data)->structs.first; - for (; srna; srna = srna->cont.next) { - if (key[0] == srna->identifier[0] && STREQ(key, srna->identifier)) { - RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr); - return true; - } + BlenderRNA *brna = ptr->data; + StructRNA *srna = BLI_ghash_lookup(brna->structs_map, (void *)key); + if (srna != NULL) { + RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr); + return true; } return false; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 20c3ab89b8e..71350edeb94 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -94,13 +94,15 @@ EnumPropertyItem rna_enum_exr_codec_items[] = { }; #endif -EnumPropertyItem uv_sculpt_relaxation_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem uv_sculpt_relaxation_items[] = { {UV_SCULPT_TOOL_RELAX_LAPLACIAN, "LAPLACIAN", 0, "Laplacian", "Use Laplacian method for relaxation"}, {UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"}, {0, NULL, 0, NULL, NULL} }; +#endif -EnumPropertyItem uv_sculpt_tool_items[] = { +EnumPropertyItem rna_enum_uv_sculpt_tool_items[] = { {UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"}, {UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"}, {UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"}, @@ -175,11 +177,13 @@ EnumPropertyItem rna_enum_snap_node_element_items[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem snap_uv_element_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem snap_uv_element_items[] = { {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"}, {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, {0, NULL, 0, NULL, NULL} }; +#endif EnumPropertyItem rna_enum_curve_fit_method_items[] = { {CURVE_PAINT_FIT_METHOD_REFIT, "REFIT", 0, "Refit", "Incrementally re-fit the curve (high quality)"}, @@ -265,12 +269,14 @@ EnumPropertyItem rna_enum_curve_fit_method_items[] = { R_IMF_ENUM_TIFF \ -EnumPropertyItem image_only_type_items[] = { +#ifdef RNA_RUNTIME +static EnumPropertyItem image_only_type_items[] = { IMAGE_TYPE_ITEMS_IMAGE_ONLY {0, NULL, 0, NULL, NULL} }; +#endif EnumPropertyItem rna_enum_image_type_items[] = { {0, "", 0, N_("Image"), NULL}, @@ -408,7 +414,8 @@ EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { /* interpolation */ {0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"}, {GP_IPO_LINEAR, "LINEAR", ICON_IPO_LINEAR, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, @@ -431,6 +438,7 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +#endif #ifdef RNA_RUNTIME @@ -1838,6 +1846,13 @@ static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), Pointer rna_Scene_use_simplify_update(bmain, sce, ptr); } +static void rna_SceneRenderData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Scene *sce = ptr->id.data; + + DAG_id_tag_update(&sce->id, 0); +} + static void rna_Scene_use_persistent_data_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *sce = ptr->id.data; @@ -2665,7 +2680,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "uv_sculpt_tool"); - RNA_def_property_enum_items(prop, uv_sculpt_tool_items); + RNA_def_property_enum_items(prop, rna_enum_uv_sculpt_tool_items); RNA_def_property_ui_text(prop, "UV Sculpt Tools", "Select Tools for the UV sculpt brushes"); prop = RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE); @@ -5887,6 +5902,15 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem pixel_size_items[] = { + {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"}, + {1, "1", 0, "1x", "Render at full resolution"}, + {2, "2", 0, "2x", "Render at 50% resolution"}, + {4, "4", 0, "4x", "Render at 25% resolution"}, + {8, "8", 0, "8x", "Render at 12.5% resolution"}, + {0, NULL, 0, NULL, NULL} + }; + static EnumPropertyItem octree_resolution_items[] = { {64, "64", 0, "64", ""}, {128, "128", 0, "128", ""}, @@ -6010,6 +6034,12 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "progressively increasing it to the full viewport size"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "preview_pixel_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "preview_pixel_size"); + RNA_def_property_enum_items(prop, pixel_size_items); + RNA_def_property_ui_text(prop, "Pixel Size", "Pixel size for viewport rendering"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderData_update"); + prop = RNA_def_property(srna, "pixel_aspect_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xasp"); RNA_def_property_flag(prop, PROP_PROPORTIONAL); @@ -6242,8 +6272,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "blurfac"); RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2); - RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close " + "(NOTE: Blender Internal does not support animated shutter)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_shutter_curve", PROP_POINTER, PROP_NONE); @@ -6605,11 +6635,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna) /* sequencer draw options */ - prop = RNA_def_property(srna, "use_sequencer_gl_preview", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_GL_PREV); - RNA_def_property_ui_text(prop, "Sequencer OpenGL", ""); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update"); - #if 0 /* see R_SEQ_GL_REND comment */ prop = RNA_def_property(srna, "use_sequencer_gl_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_GL_REND); @@ -6622,10 +6647,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update"); +#if 0 /* UNUSED, see R_SEQ_GL_REND comment */ prop = RNA_def_property(srna, "sequencer_gl_render", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "seq_rend_type"); RNA_def_property_enum_items(prop, rna_enum_viewport_shade_items); + /* XXX Label and tooltips are obviously wrong! */ RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view"); +#endif prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX); @@ -6988,7 +7016,7 @@ static void rna_def_display_safe_areas(BlenderRNA *brna) RNA_def_property_array(prop, 2); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_float_array_default(prop, default_title); - RNA_def_property_ui_text(prop, "Title Safe margins", "Safe area for text and graphics"); + RNA_def_property_ui_text(prop, "Title Safe Margins", "Safe area for text and graphics"); RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL); prop = RNA_def_property(srna, "action", PROP_FLOAT, PROP_XYZ); @@ -6999,7 +7027,6 @@ static void rna_def_display_safe_areas(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Action Safe Margins", "Safe area for general elements"); RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL); - prop = RNA_def_property(srna, "title_center", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "title_center"); RNA_def_property_array(prop, 2); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index a80e4c60127..16d91a4964b 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -164,7 +164,6 @@ static void rna_Scene_ray_cast( bool ret = ED_transform_snap_object_project_ray_ex( sctx, - SCE_SNAP_MODE_FACE, &(const struct SnapObjectParams){ .snap_select = SNAP_ALL, }, @@ -280,8 +279,7 @@ static void rna_Scene_collada_export( int include_shapekeys, int deform_bones_only, int active_uv_only, - int include_uv_textures, - int include_material_textures, + int export_texture_type, int use_texture_copies, int triangulate, int use_object_instantiation, @@ -305,8 +303,7 @@ static void rna_Scene_collada_export( deform_bones_only, active_uv_only, - include_uv_textures, - include_material_textures, + export_texture_type, use_texture_copies, triangulate, @@ -403,11 +400,8 @@ void RNA_api_scene(StructRNA *srna) RNA_def_boolean(func, "active_uv_only", false, "Only Selected UV Map", "Export only the selected UV Map"); - RNA_def_boolean(func, "include_uv_textures", false, - "Include UV Textures", "Export textures assigned to the object UV Maps"); - - RNA_def_boolean(func, "include_material_textures", false, - "Include Material Textures", "Export textures assigned to the object Materials"); + RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX, + "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX); RNA_def_boolean(func, "use_texture_copies", true, "Copy", "Copy textures to same folder where the .dae file is exported"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 207ef182346..f775997b947 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -75,13 +76,15 @@ EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = { { 0, NULL, 0, NULL, NULL } }; -EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { { GP_LOCKAXIS_NONE, "GP_LOCKAXIS_NONE", 0, "None", "" }, { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", 0, "X", "Project strokes to plane locked to X" }, { GP_LOCKAXIS_Y, "GP_LOCKAXIS_Y", 0, "Y", "Project strokes to plane locked to Y" }, { GP_LOCKAXIS_Z, "GP_LOCKAXIS_Z", 0, "Z", "Project strokes to plane locked to Z" }, { 0, NULL, 0, NULL, NULL } }; +#endif EnumPropertyItem rna_enum_symmetrize_direction_items[] = { {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 84b62721999..f628c5f14d9 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -341,7 +341,7 @@ static void rna_Sequence_use_translation_set(PointerRNA *ptr, int value) } } else { - seq->flag ^= SEQ_USE_TRANSFORM; + seq->flag &= ~SEQ_USE_TRANSFORM; } } @@ -355,7 +355,7 @@ static void rna_Sequence_use_crop_set(PointerRNA *ptr, int value) } } else { - seq->flag ^= SEQ_USE_CROP; + seq->flag &= ~SEQ_USE_CROP; } } @@ -1126,7 +1126,7 @@ static void rna_def_strip_crop(BlenderRNA *brna) prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "bottom"); - RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the buttom"); + RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the bottom"); RNA_def_property_ui_range(prop, 0, 4096, 1, -1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update"); @@ -2338,7 +2338,7 @@ static void rna_def_text(StructRNA *srna) prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shadow_color"); - RNA_def_property_ui_text(prop, "Shadow Color", "Shadow color"); + RNA_def_property_ui_text(prop, "Shadow Color", ""); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index f2e856bf1ba..2fd471a66ef 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1045,6 +1045,8 @@ static void rna_SpaceProperties_pin_id_update(Main *UNUSED(bmain), Scene *UNUSED case ID_LA: WM_main_add_notifier(NC_LAMP, NULL); break; + default: + break; } } @@ -4605,7 +4607,7 @@ static void rna_def_space_clip(BlenderRNA *brna) /* path length */ prop = RNA_def_property(srna, "path_length", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "path_length"); - RNA_def_property_range(prop, 0, 50); + RNA_def_property_range(prop, 0, INT_MAX); RNA_def_property_ui_text(prop, "Path Length", "Length of displaying path, in frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 1e88585a286..4ad2832b953 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -267,6 +267,8 @@ void rna_TextureSlot_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL); break; } + default: + break; } } diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 54b82fc89d6..12af5dc8287 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -177,9 +177,9 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &pt->ext); + RNA_struct_free(&BLENDER_RNA, type); BLI_freelinkN(&art->paneltypes, pt); - RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -229,6 +229,12 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat break; } } + if (!RNA_struct_available_or_report(reports, dummypt.idname)) { + return NULL; + } + if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) { + return NULL; + } /* create a new panel type */ pt = MEM_callocN(sizeof(PanelType), "python buttons panel"); @@ -455,11 +461,10 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &ult->ext); + RNA_struct_free(&BLENDER_RNA, type); WM_uilisttype_freelink(ult); - RNA_struct_free(&BLENDER_RNA, type); - /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); } @@ -489,8 +494,15 @@ static StructRNA *rna_UIList_register(Main *bmain, ReportList *reports, void *da /* check if we have registered this uilist type before, and remove it */ ult = WM_uilisttype_find(dummyult.idname, true); - if (ult && ult->ext.srna) + if (ult && ult->ext.srna) { rna_UIList_unregister(bmain, ult->ext.srna); + } + if (!RNA_struct_available_or_report(reports, dummyult.idname)) { + return NULL; + } + if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) { + return NULL; + } /* create a new menu type */ ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist"); @@ -551,9 +563,9 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &ht->ext); + RNA_struct_free(&BLENDER_RNA, type); BLI_freelinkN(&art->headertypes, ht); - RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -593,6 +605,12 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da break; } } + if (!RNA_struct_available_or_report(reports, dummyht.idname)) { + return NULL; + } + if (!RNA_struct_bl_idname_ok_or_report(reports, dummyht.idname, "_HT_")) { + return NULL; + } /* create a new header type */ ht = MEM_callocN(sizeof(HeaderType), "python buttons header"); @@ -673,11 +691,10 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &mt->ext); + RNA_struct_free(&BLENDER_RNA, type); WM_menutype_freelink(mt); - RNA_struct_free(&BLENDER_RNA, type); - /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); } @@ -714,8 +731,15 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data /* check if we have registered this menu type before, and remove it */ mt = WM_menutype_find(dummymt.idname, true); - if (mt && mt->ext.srna) + if (mt && mt->ext.srna) { rna_Menu_unregister(bmain, mt->ext.srna); + } + if (!RNA_struct_available_or_report(reports, dummymt.idname)) { + return NULL; + } + if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) { + return NULL; + } /* create a new menu type */ if (_menu_descr[0]) { @@ -937,6 +961,7 @@ static void rna_def_panel(BlenderRNA *brna) RNA_def_struct_refine_func(srna, "rna_Panel_refine"); RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL); RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* poll */ func = RNA_def_function(srna, "poll", NULL); @@ -1039,7 +1064,7 @@ static void rna_def_uilist(BlenderRNA *brna) RNA_def_struct_refine_func(srna, "rna_UIList_refine"); RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL); RNA_def_struct_idprops_func(srna, "rna_UIList_idprops"); - RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES); + RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_PUBLIC_NAMESPACE_INHERIT); /* Registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); @@ -1161,6 +1186,7 @@ static void rna_def_header(BlenderRNA *brna) RNA_def_struct_sdna(srna, "Header"); RNA_def_struct_refine_func(srna, "rna_Header_refine"); RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL); + RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* draw */ func = RNA_def_function(srna, "draw", NULL); @@ -1208,6 +1234,7 @@ static void rna_def_menu(BlenderRNA *brna) RNA_def_struct_refine_func(srna, "rna_Menu_refine"); RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL); RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); /* poll */ func = RNA_def_function(srna, "poll", NULL); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 46775af21db..7d8d24670a7 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -557,8 +557,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text"); parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED); RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item"); - parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", - "Operator properties to fill in, return when 'properties' is set to true"); + parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR); RNA_def_function_return(func, parm); RNA_def_function_ui_description(func, "Item. Places a button into the layout to call an Operator"); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d1e89ea18d0..358d790e555 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -606,9 +606,9 @@ static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type) return; RNA_struct_free_extension(type, &apt->ext); + RNA_struct_free(&BLENDER_RNA, type); BKE_addon_pref_type_remove(apt); - RNA_struct_free(&BLENDER_RNA, type); /* update while blender is running */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -638,10 +638,8 @@ static StructRNA *rna_AddonPref_register(Main *bmain, ReportList *reports, void /* check if we have registered this header type before, and remove it */ apt = BKE_addon_pref_type_find(dummyaddon.module, true); - if (apt) { - if (apt->ext.srna) { - rna_AddonPref_unregister(bmain, apt->ext.srna); - } + if (apt && apt->ext.srna) { + rna_AddonPref_unregister(bmain, apt->ext.srna); } /* create a new header type */ @@ -3304,6 +3302,13 @@ static void rna_def_userdef_view(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem line_width[] = { + {-1, "THIN", 0, "Thin", "Thinner lines than the default"}, + { 0, "AUTO", 0, "Auto", "Automatic line width based on UI scale"}, + { 1, "THICK", 0, "Thick", "Thicker lines than the default"}, + {0, NULL, 0, NULL, NULL} + }; + PropertyRNA *prop; StructRNA *srna; @@ -3317,10 +3322,16 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop = RNA_def_property(srna, "ui_scale", PROP_FLOAT, PROP_FACTOR); RNA_def_property_ui_text(prop, "UI Scale", "Changes the size of the fonts and buttons in the interface"); RNA_def_property_range(prop, 0.25f, 4.0f); - RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 1); + RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 2); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + prop = RNA_def_property(srna, "ui_line_width", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, line_width); + RNA_def_property_ui_text(prop, "UI Line Width", + "Changes the thickness of lines and points in the interface"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + /* display */ prop = RNA_def_property(srna, "show_tooltips", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_TOOLTIPS); @@ -3445,6 +3456,11 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Cursor Depth", "Use the depth under the mouse when placing the cursor"); + prop = RNA_def_property(srna, "use_cursor_lock_adjust", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_LOCK_CURSOR_ADJUST); + RNA_def_property_ui_text(prop, "Cursor Lock Adjust", + "Place the cursor without 'jumping' to the new location (when lock-to-cursor is used)"); + prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_CAM_LOCK_NO_PARENT); RNA_def_property_ui_text(prop, "Camera Parent Lock", @@ -3926,12 +3942,18 @@ static void rna_def_userdef_system(BlenderRNA *brna) prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display"); + RNA_def_property_ui_text(prop, "DPI", + "DPI for add-ons to use when drawing custom user interface elements, controlled by " + "operating system settings and Blender UI scale, with a reference value of 72 DPI " + "(note that since this value includes a user defined scale, it is not always the " + "actual monitor DPI)"); prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_sdna(prop, NULL, "pixelsize"); - RNA_def_property_ui_text(prop, "Pixel Size", ""); + RNA_def_property_ui_text(prop, "Pixel Size", + "Suggested line thickness and point size in pixels, for add-ons drawing custom user " + "interface elements, controlled by operating system settings and Blender UI scale"); prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "font_path_ui"); @@ -3979,11 +4001,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Translate New Names", "Translate new data names (when adding/creating some)"); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "use_textured_fonts", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transopts", USER_USETEXTUREFONT); - RNA_def_property_ui_text(prop, "Textured Fonts", "Use textures for drawing international fonts"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - /* System & OpenGL */ prop = RNA_def_property(srna, "solid_lights", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index b458b2e69d5..df3eae4f221 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -32,6 +32,7 @@ #include "DNA_windowmanager_types.h" #include "BLI_utildefines.h" +#include "BLI_string_utils.h" #include "BLT_translation.h" @@ -939,35 +940,8 @@ static void rna_wmClipboard_set(PointerRNA *UNUSED(ptr), const char *value) } #ifdef WITH_PYTHON -static void rna_Operator_unregister(struct Main *bmain, StructRNA *type) -{ - const char *idname; - wmOperatorType *ot = RNA_struct_blender_type_get(type); - wmWindowManager *wm; - - if (!ot) - return; - - /* update while blender is running */ - wm = bmain->wm.first; - if (wm) { - WM_operator_stack_clear(wm); - - WM_operator_handlers_clear(wm, ot); - } - WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); - - RNA_struct_free_extension(type, &ot->ext); - - idname = ot->idname; - WM_operatortype_remove_ptr(ot); - MEM_freeN((void *)idname); - /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */ - RNA_struct_free(&BLENDER_RNA, type); -} - -static int operator_poll(bContext *C, wmOperatorType *ot) +static int rna_operator_poll_cb(bContext *C, wmOperatorType *ot) { extern FunctionRNA rna_Operator_poll_func; @@ -992,7 +966,7 @@ static int operator_poll(bContext *C, wmOperatorType *ot) return visible; } -static int operator_execute(bContext *C, wmOperator *op) +static int rna_operator_execute_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_execute_func; @@ -1018,7 +992,7 @@ static int operator_execute(bContext *C, wmOperator *op) } /* same as execute() but no return value */ -static bool operator_check(bContext *C, wmOperator *op) +static bool rna_operator_check_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_check_func; @@ -1043,7 +1017,7 @@ static bool operator_check(bContext *C, wmOperator *op) return result; } -static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int rna_operator_invoke_cb(bContext *C, wmOperator *op, const wmEvent *event) { extern FunctionRNA rna_Operator_invoke_func; @@ -1070,7 +1044,7 @@ static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event) } /* same as invoke */ -static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event) +static int rna_operator_modal_cb(bContext *C, wmOperator *op, const wmEvent *event) { extern FunctionRNA rna_Operator_modal_func; @@ -1096,7 +1070,7 @@ static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event) return result; } -static void operator_draw(bContext *C, wmOperator *op) +static void rna_operator_draw_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_draw_func; @@ -1115,7 +1089,7 @@ static void operator_draw(bContext *C, wmOperator *op) } /* same as exec(), but call cancel */ -static void operator_cancel(bContext *C, wmOperator *op) +static void rna_operator_cancel_cb(bContext *C, wmOperator *op) { extern FunctionRNA rna_Operator_cancel_func; @@ -1133,112 +1107,84 @@ static void operator_cancel(bContext *C, wmOperator *op) RNA_parameter_list_free(&list); } -void operator_wrapper(wmOperatorType *ot, void *userdata); -void macro_wrapper(wmOperatorType *ot, void *userdata); +static void rna_Operator_unregister(struct Main *bmain, StructRNA *type); + +/* bpy_operator_wrap.c */ +extern void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata); +extern void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata); -static char _operator_idname[OP_MAX_TYPENAME]; -static char _operator_name[OP_MAX_TYPENAME]; -static char _operator_descr[RNA_DYN_DESCR_MAX]; -static char _operator_ctxt[RNA_DYN_DESCR_MAX]; -static char _operator_undo_group[OP_MAX_TYPENAME]; -static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier, - StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +static StructRNA *rna_Operator_register( + Main *bmain, ReportList *reports, void *data, const char *identifier, + StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { wmOperatorType dummyot = {NULL}; wmOperator dummyop = {NULL}; PointerRNA dummyotr; int have_function[7]; + struct { + char idname[OP_MAX_TYPENAME]; + char name[OP_MAX_TYPENAME]; + char description[RNA_DYN_DESCR_MAX]; + char translation_context[RNA_DYN_DESCR_MAX]; + char undo_group[OP_MAX_TYPENAME]; + } temp_buffers; + /* setup dummy operator & operator type to store static properties in */ dummyop.type = &dummyot; - dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */ - dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */ - dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */ - dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */ - dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */ + dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */ + dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */ + dummyot.description = temp_buffers.description; /* only assigne the pointer, string is NULL'd */ + dummyot.translation_context = temp_buffers.translation_context; /* only assigne the pointer, string is NULL'd */ + dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */ RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr); /* clear in case they are left unset */ - _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0'; + temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.description[0] = temp_buffers.undo_group[0] = '\0'; /* We have to set default op context! */ - strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + strcpy(temp_buffers.translation_context, BLT_I18NCONTEXT_OPERATOR_DEFAULT); /* validate the python class */ if (validate(&dummyotr, data, have_function) != 0) return NULL; - { /* convert foo.bar to FOO_OT_bar - * allocate the description and the idname in 1 go */ - - /* inconveniently long name sanity check */ - { - char *ch = _operator_idname; - int i; - int dot = 0; - for (i = 0; *ch; i++) { - if ((*ch >= 'a' && *ch <= 'z') || (*ch >= '0' && *ch <= '9') || *ch == '_') { - /* pass */ - } - else if (*ch == '.') { - dot++; - } - else { - BKE_reportf(reports, RPT_ERROR, - "Registering operator class: '%s', invalid bl_idname '%s', at position %d", - identifier, _operator_idname, i); - return NULL; - } + /* check if we have registered this operator type before, and remove it */ + { + wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true); + if (ot && ot->ext.srna) + rna_Operator_unregister(bmain, ot->ext.srna); + } - ch++; - } + if (!WM_operator_py_idname_ok_or_report(reports, identifier, dummyot.idname)) { + return NULL; + } - if (i > ((int)sizeof(dummyop.idname)) - 3) { - BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " - "is too long, maximum length is %d", identifier, _operator_idname, - (int)sizeof(dummyop.idname) - 3); - return NULL; - } + char idname_conv[sizeof(dummyop.idname)]; + WM_operator_bl_idname(idname_conv, dummyot.idname); /* convert the idname from python */ - if (dot != 1) { - BKE_reportf(reports, RPT_ERROR, - "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", - identifier, _operator_idname); - return NULL; - } - } - /* end sanity check */ - - { - int idlen = strlen(_operator_idname) + 4; - int namelen = strlen(_operator_name) + 1; - int desclen = strlen(_operator_descr) + 1; - int ctxtlen = strlen(_operator_ctxt) + 1; - int ugrouplen = strlen(_operator_undo_group) + 1; - char *ch; - /* 2 terminators and 3 to convert a.b -> A_OT_b */ - ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname"); - WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */ - dummyot.idname = ch; - ch += idlen; - strcpy(ch, _operator_name); - dummyot.name = ch; - ch += namelen; - strcpy(ch, _operator_descr); - dummyot.description = ch; - ch += desclen; - strcpy(ch, _operator_ctxt); - dummyot.translation_context = ch; - ch += ctxtlen; - strcpy(ch, _operator_undo_group); - dummyot.undo_group = ch; - } + if (!RNA_struct_available_or_report(reports, idname_conv)) { + return NULL; } - /* check if we have registered this operator type before, and remove it */ + /* Convert foo.bar to FOO_OT_bar + * allocate all strings at once. */ { - wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true); - if (ot && ot->ext.srna) - rna_Operator_unregister(bmain, ot->ext.srna); + const char *strings[] = { + idname_conv, + temp_buffers.name, + temp_buffers.description, + temp_buffers.translation_context, + temp_buffers.undo_group, + }; + char *strings_table[ARRAY_SIZE(strings)]; + BLI_string_join_array_by_sep_char_with_tableN('\0', strings_table, strings, ARRAY_SIZE(strings)); + + dummyot.idname = strings_table[0]; /* allocated string stored here */ + dummyot.name = strings_table[1]; + dummyot.description = strings_table[2]; + dummyot.translation_context = strings_table[3]; + dummyot.undo_group = strings_table[4]; + BLI_assert(ARRAY_SIZE(strings) == 5); } /* XXX, this doubles up with the operator name [#29666] @@ -1252,14 +1198,14 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * dummyot.ext.call = call; dummyot.ext.free = free; - dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL; - dummyot.exec = (have_function[1]) ? operator_execute : NULL; - dummyot.check = (have_function[2]) ? operator_check : NULL; - dummyot.invoke = (have_function[3]) ? operator_invoke : NULL; - dummyot.modal = (have_function[4]) ? operator_modal : NULL; - dummyot.ui = (have_function[5]) ? operator_draw : NULL; - dummyot.cancel = (have_function[6]) ? operator_cancel : NULL; - WM_operatortype_append_ptr(operator_wrapper, (void *)&dummyot); + dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL; + dummyot.exec = (have_function[1]) ? rna_operator_execute_cb : NULL; + dummyot.check = (have_function[2]) ? rna_operator_check_cb : NULL; + dummyot.invoke = (have_function[3]) ? rna_operator_invoke_cb : NULL; + dummyot.modal = (have_function[4]) ? rna_operator_modal_cb : NULL; + dummyot.ui = (have_function[5]) ? rna_operator_draw_cb : NULL; + dummyot.cancel = (have_function[6]) ? rna_operator_cancel_cb : NULL; + WM_operatortype_append_ptr(BPY_RNA_operator_wrapper, (void *)&dummyot); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); @@ -1267,64 +1213,76 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * return dummyot.ext.srna; } +static void rna_Operator_unregister(struct Main *bmain, StructRNA *type) +{ + const char *idname; + wmOperatorType *ot = RNA_struct_blender_type_get(type); + wmWindowManager *wm; + + if (!ot) + return; + + /* update while blender is running */ + wm = bmain->wm.first; + if (wm) { + WM_operator_stack_clear(wm); + + WM_operator_handlers_clear(wm, ot); + } + WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); + + RNA_struct_free_extension(type, &ot->ext); + + idname = ot->idname; + WM_operatortype_remove_ptr(ot); + + /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */ + RNA_struct_free(&BLENDER_RNA, type); + + MEM_freeN((void *)idname); +} + static void **rna_Operator_instance(PointerRNA *ptr) { wmOperator *op = ptr->data; return &op->py_instance; } -static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, void *data, const char *identifier, - StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +static StructRNA *rna_MacroOperator_register( + Main *bmain, ReportList *reports, void *data, const char *identifier, + StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { wmOperatorType dummyot = {NULL}; wmOperator dummyop = {NULL}; PointerRNA dummyotr; int have_function[4]; + struct { + char idname[OP_MAX_TYPENAME]; + char name[OP_MAX_TYPENAME]; + char description[RNA_DYN_DESCR_MAX]; + char translation_context[RNA_DYN_DESCR_MAX]; + char undo_group[OP_MAX_TYPENAME]; + } temp_buffers; + /* setup dummy operator & operator type to store static properties in */ dummyop.type = &dummyot; - dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */ - dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */ - dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */ - dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */ - dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */ + dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */ + dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */ + dummyot.description = temp_buffers.description; /* only assigne the pointer, string is NULL'd */ + dummyot.translation_context = temp_buffers.translation_context; /* only assigne the pointer, string is NULL'd */ + dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */ RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr); /* clear in case they are left unset */ - _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0'; + temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.description[0] = temp_buffers.undo_group[0] = '\0'; /* We have to set default op context! */ - strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + strcpy(temp_buffers.translation_context, BLT_I18NCONTEXT_OPERATOR_DEFAULT); /* validate the python class */ if (validate(&dummyotr, data, have_function) != 0) return NULL; - { /* convert foo.bar to FOO_OT_bar - * allocate the description and the idname in 1 go */ - int idlen = strlen(_operator_idname) + 4; - int namelen = strlen(_operator_name) + 1; - int desclen = strlen(_operator_descr) + 1; - int ctxtlen = strlen(_operator_ctxt) + 1; - int ugrouplen = strlen(_operator_undo_group) + 1; - char *ch; - /* 2 terminators and 3 to convert a.b -> A_OT_b */ - ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname"); - WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */ - dummyot.idname = ch; - ch += idlen; - strcpy(ch, _operator_name); - dummyot.name = ch; - ch += namelen; - strcpy(ch, _operator_descr); - dummyot.description = ch; - ch += desclen; - strcpy(ch, _operator_ctxt); - dummyot.translation_context = ch; - ch += ctxtlen; - strcpy(ch, _operator_undo_group); - dummyot.undo_group = ch; - } - if (strlen(identifier) >= sizeof(dummyop.idname)) { BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyop.idname)); @@ -1338,6 +1296,38 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v rna_Operator_unregister(bmain, ot->ext.srna); } + if (!WM_operator_py_idname_ok_or_report(reports, identifier, dummyot.idname)) { + return NULL; + } + + char idname_conv[sizeof(dummyop.idname)]; + WM_operator_bl_idname(idname_conv, dummyot.idname); /* convert the idname from python */ + + if (!RNA_struct_available_or_report(reports, idname_conv)) { + return NULL; + } + + /* Convert foo.bar to FOO_OT_bar + * allocate all strings at once. */ + { + const char *strings[] = { + idname_conv, + temp_buffers.name, + temp_buffers.description, + temp_buffers.translation_context, + temp_buffers.undo_group, + }; + char *strings_table[ARRAY_SIZE(strings)]; + BLI_string_join_array_by_sep_char_with_tableN('\0', strings_table, strings, ARRAY_SIZE(strings)); + + dummyot.idname = strings_table[0]; /* allocated string stored here */ + dummyot.name = strings_table[1]; + dummyot.description = strings_table[2]; + dummyot.translation_context = strings_table[3]; + dummyot.undo_group = strings_table[4]; + BLI_assert(ARRAY_SIZE(strings) == 5); + } + /* XXX, this doubles up with the operator name [#29666] * for now just remove from dir(bpy.types) */ @@ -1348,10 +1338,10 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v dummyot.ext.call = call; dummyot.ext.free = free; - dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL; - dummyot.ui = (have_function[3]) ? operator_draw : NULL; + dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL; + dummyot.ui = (have_function[3]) ? rna_operator_draw_cb : NULL; - WM_operatortype_append_macro_ptr(macro_wrapper, (void *)&dummyot); + WM_operatortype_append_macro_ptr(BPY_RNA_operator_macro_wrapper, (void *)&dummyot); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); @@ -1471,6 +1461,7 @@ static void rna_def_operator(BlenderRNA *brna) RNA_def_struct_register_funcs(srna, "rna_Operator_register", "rna_Operator_unregister", "rna_Operator_instance"); #endif RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1574,6 +1565,7 @@ static void rna_def_macro_operator(BlenderRNA *brna) "rna_Operator_instance"); #endif RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); |