diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py index b4ff2d30e05..570a437c213 100644 --- a/release/scripts/startup/bl_ui/properties_constraint.py +++ b/release/scripts/startup/bl_ui/properties_constraint.py @@ -1146,6 +1146,30 @@ class ConstraintButtonsSubPanel: col.prop(con, "frame_start", text="Frame Start") col.prop(con, "frame_end", text="End") + def draw_transform_cache_velocity(self, context): + self.draw_transform_cache_subpanel( + context, self.layout.template_cache_file_velocity + ) + + def draw_transform_cache_procedural(self, context): + self.draw_transform_cache_subpanel( + context, self.layout.template_cache_file_procedural + ) + + def draw_transform_cache_time(self, context): + self.draw_transform_cache_subpanel( + context, self.layout.template_cache_file_time_settings + ) + + def draw_transform_cache_subpanel(self, context, template_func): + con = self.get_constraint(context) + if con.cache_file is None: + return + + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = True + template_func(con, "cache_file") # Child Of Constraint @@ -1534,6 +1558,54 @@ class BONE_PT_bTransformCacheConstraint(BoneConstraintPanel, ConstraintButtonsPa self.draw_transform_cache(context) +class OBJECT_PT_bTransformCacheConstraint_velocity(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "OBJECT_PT_bTransformCacheConstraint" + bl_label = "Velocity" + + def draw(self, context): + self.draw_transform_cache_velocity(context) + + +class BONE_PT_bTransformCacheConstraint_velocity(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "BONE_PT_bTransformCacheConstraint" + bl_label = "Velocity" + + def draw(self, context): + self.draw_transform_cache_velocity(context) + + +class OBJECT_PT_bTransformCacheConstraint_procedural(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "OBJECT_PT_bTransformCacheConstraint" + bl_label = "Render Procedural" + + def draw(self, context): + self.draw_transform_cache_procedural(context) + + +class BONE_PT_bTransformCacheConstraint_procedural(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "BONE_PT_bTransformCacheConstraint" + bl_label = "Render Procedural" + + def draw(self, context): + self.draw_transform_cache_procedural(context) + + +class OBJECT_PT_bTransformCacheConstraint_time(ObjectConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "OBJECT_PT_bTransformCacheConstraint" + bl_label = "Time" + + def draw(self, context): + self.draw_transform_cache_time(context) + + +class BONE_PT_bTransformCacheConstraint_time(BoneConstraintPanel, ConstraintButtonsSubPanel, Panel): + bl_parent_id = "BONE_PT_bTransformCacheConstraint" + bl_label = "Time" + + def draw(self, context): + self.draw_transform_cache_time(context) + + # Python Constraint class OBJECT_PT_bPythonConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel): @@ -1620,6 +1692,9 @@ classes = ( OBJECT_PT_bCameraSolverConstraint, OBJECT_PT_bObjectSolverConstraint, OBJECT_PT_bTransformCacheConstraint, + OBJECT_PT_bTransformCacheConstraint_time, + OBJECT_PT_bTransformCacheConstraint_procedural, + OBJECT_PT_bTransformCacheConstraint_velocity, OBJECT_PT_bPythonConstraint, OBJECT_PT_bArmatureConstraint, OBJECT_PT_bArmatureConstraint_bones, @@ -1657,6 +1732,9 @@ classes = ( BONE_PT_bCameraSolverConstraint, BONE_PT_bObjectSolverConstraint, BONE_PT_bTransformCacheConstraint, + BONE_PT_bTransformCacheConstraint_time, + BONE_PT_bTransformCacheConstraint_procedural, + BONE_PT_bTransformCacheConstraint_velocity, BONE_PT_bPythonConstraint, BONE_PT_bArmatureConstraint, BONE_PT_bArmatureConstraint_bones, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 9df5b17975a..ba9e56256af 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2544,11 +2544,42 @@ void uiTemplateComponentMenu(uiLayout *layout, const char *propname, const char *name); void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float color[4]); + +/** + * Draw the main CacheFile properties and operators (file path, scale, etc.), that is those which + * do not have their own dedicated template functions. + */ void uiTemplateCacheFile(uiLayout *layout, const struct bContext *C, struct PointerRNA *ptr, const char *propname); +/** + * Lookup the CacheFile PointerRNA of the given pointer and return it in the output parameter. + * Returns true if `ptr` has a RNACacheFile, false otherwise. If false, the output parameter is not + * initialized. + */ +bool uiTemplateCacheFilePointer(struct PointerRNA *ptr, + const char *propname, + struct PointerRNA *r_file_ptr); + +/** + * Draw the velocity related properties of the CacheFile. + */ +void uiTemplateCacheFileVelocity(uiLayout *layout, struct PointerRNA *fileptr); + +/** + * Draw the render procedural related properties of the CacheFile. + */ +void uiTemplateCacheFileProcedural(uiLayout *layout, + const struct bContext *C, + struct PointerRNA *fileptr); + +/** + * Draw the time related properties of the CacheFile. + */ +void uiTemplateCacheFileTimeSettings(uiLayout *layout, struct PointerRNA *fileptr); + /* Default UIList class name, keep in sync with its declaration in bl_ui/__init__.py */ #define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list" enum uiTemplateListFlags { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 6bf0e36a3cc..00e9a75848a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -6395,64 +6395,21 @@ void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float color[4]) /** \name Cache File Template * \{ */ -void uiTemplateCacheFile(uiLayout *layout, - const bContext *C, - PointerRNA *ptr, - const char *propname) +void uiTemplateCacheFileVelocity(uiLayout *layout, PointerRNA *fileptr) { - if (!ptr->data) { - return; - } + /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */ + uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr); - PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + uiItemR(layout, fileptr, "velocity_name", 0, NULL, ICON_NONE); + uiItemR(layout, fileptr, "velocity_unit", 0, NULL, ICON_NONE); +} - if (!prop) { - printf( - "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); - return; - } +void uiTemplateCacheFileProcedural(uiLayout *layout, const bContext *C, PointerRNA *fileptr) +{ + /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */ + uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr); - if (RNA_property_type(prop) != PROP_POINTER) { - printf("%s: expected pointer property for %s.%s\n", - __func__, - RNA_struct_identifier(ptr->type), - propname); - return; - } - - PointerRNA fileptr = RNA_property_pointer_get(ptr, prop); - CacheFile *file = fileptr.data; - - uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr); - - uiTemplateID(layout, - C, - ptr, - propname, - NULL, - "CACHEFILE_OT_open", - NULL, - UI_TEMPLATE_ID_FILTER_ALL, - false, - NULL); - - if (!file) { - return; - } - - SpaceProperties *sbuts = CTX_wm_space_properties(C); - - uiLayout *row, *sub, *subsub; - - uiLayoutSetPropSep(layout, true); - - row = uiLayoutRow(layout, true); - uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE); - sub = uiLayoutRow(row, true); - uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload"); - - row = uiLayoutRow(layout, false); - uiItemR(row, &fileptr, "is_sequence", 0, NULL, ICON_NONE); + uiLayout *row, *sub; /* Only enable render procedural option if the active engine supports it. */ const struct RenderEngineType *engine_type = CTX_data_engine_type(C); @@ -6479,40 +6436,115 @@ void uiTemplateCacheFile(uiLayout *layout, row = uiLayoutRow(layout, false); uiLayoutSetActive(row, engine_supports_procedural); - uiItemR(row, &fileptr, "use_render_procedural", 0, NULL, ICON_NONE); + uiItemR(row, fileptr, "use_render_procedural", 0, NULL, ICON_NONE); - const bool use_render_procedural = RNA_boolean_get(&fileptr, "use_render_procedural"); - const bool use_prefetch = RNA_boolean_get(&fileptr, "use_prefetch"); + const bool use_render_procedural = RNA_boolean_get(fileptr, "use_render_procedural"); + const bool use_prefetch = RNA_boolean_get(fileptr, "use_prefetch"); row = uiLayoutRow(layout, false); uiLayoutSetEnabled(row, use_render_procedural); - uiItemR(row, &fileptr, "use_prefetch", 0, NULL, ICON_NONE); + uiItemR(row, fileptr, "use_prefetch", 0, NULL, ICON_NONE); sub = uiLayoutRow(layout, false); uiLayoutSetEnabled(sub, use_prefetch && use_render_procedural); - uiItemR(sub, &fileptr, "prefetch_cache_size", 0, NULL, ICON_NONE); + uiItemR(sub, fileptr, "prefetch_cache_size", 0, NULL, ICON_NONE); +} + +void uiTemplateCacheFileTimeSettings(uiLayout *layout, PointerRNA *fileptr) +{ + /* Ensure that the context has a CacheFile as this may not be set inside of modifiers panels. */ + uiLayoutSetContextPointer(layout, "edit_cachefile", fileptr); + + uiLayout *row, *sub, *subsub; + + row = uiLayoutRow(layout, false); + uiItemR(row, fileptr, "is_sequence", 0, NULL, ICON_NONE); row = uiLayoutRowWithHeading(layout, true, IFACE_("Override Frame")); sub = uiLayoutRow(row, true); uiLayoutSetPropDecorate(sub, false); - uiItemR(sub, &fileptr, "override_frame", 0, "", ICON_NONE); + uiItemR(sub, fileptr, "override_frame", 0, "", ICON_NONE); subsub = uiLayoutRow(sub, true); - uiLayoutSetActive(subsub, RNA_boolean_get(&fileptr, "override_frame")); - uiItemR(subsub, &fileptr, "frame", 0, "", ICON_NONE); - uiItemDecoratorR(row, &fileptr, "frame", 0); + uiLayoutSetActive(subsub, RNA_boolean_get(fileptr, "override_frame")); + uiItemR(subsub, fileptr, "frame", 0, "", ICON_NONE); + uiItemDecoratorR(row, fileptr, "frame", 0); row = uiLayoutRow(layout, false); - uiItemR(row, &fileptr, "frame_offset", 0, NULL, ICON_NONE); - uiLayoutSetActive(row, !RNA_boolean_get(&fileptr, "is_sequence")); + uiItemR(row, fileptr, "frame_offset", 0, NULL, ICON_NONE); + uiLayoutSetActive(row, !RNA_boolean_get(fileptr, "is_sequence")); +} + +bool uiTemplateCacheFilePointer(PointerRNA *ptr, const char *propname, PointerRNA *r_file_ptr) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + + if (!prop) { + printf( + "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname); + return false; + } + + if (RNA_property_type(prop) != PROP_POINTER) { + printf("%s: expected pointer property for %s.%s\n", + __func__, + RNA_struct_identifier(ptr->type), + propname); + return false; + } + + *r_file_ptr = RNA_property_pointer_get(ptr, prop); + return true; +} + +void uiTemplateCacheFile(uiLayout *layout, + const bContext *C, + PointerRNA *ptr, + const char *propname) +{ + if (!ptr->data) { + return; + } + + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, propname, &fileptr)) { + return; + } + + CacheFile *file = fileptr.data; + + uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr); + + uiTemplateID(layout, + C, + ptr, + propname, + NULL, + "CACHEFILE_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); + + if (!file) { + return; + } + + SpaceProperties *sbuts = CTX_wm_space_properties(C); + + uiLayout *row, *sub; + + uiLayoutSetPropSep(layout, true); + + row = uiLayoutRow(layout, true); + uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE); + sub = uiLayoutRow(row, true); + uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload"); if (sbuts->mainb == BCONTEXT_CONSTRAINT) { row = uiLayoutRow(layout, false); uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE); } - uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE); - uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE); - /* TODO: unused for now, so no need to expose. */ #if 0 row = uiLayoutRow(layout, false); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index f96b3fc5eee..a406e867d6c 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -582,6 +582,43 @@ static void rna_uiTemplateCacheFile(uiLayout *layout, uiTemplateCacheFile(layout, C, ptr, propname); } +static void rna_uiTemplateCacheFileVelocity(uiLayout *layout, + PointerRNA *ptr, + const char *propname) +{ + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, propname, &fileptr)) { + return; + } + + uiTemplateCacheFileVelocity(layout, &fileptr); +} + +static void rna_uiTemplateCacheFileProcedural(uiLayout *layout, + bContext *C, + PointerRNA *ptr, + const char *propname) +{ + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, propname, &fileptr)) { + return; + } + + uiTemplateCacheFileProcedural(layout, C, &fileptr); +} + +static void rna_uiTemplateCacheFileTimeSettings(uiLayout *layout, + PointerRNA *ptr, + const char *propname) +{ + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, propname, &fileptr)) { + return; + } + + uiTemplateCacheFileTimeSettings(layout, &fileptr); +} + static void rna_uiTemplatePathBuilder(uiLayout *layout, PointerRNA *ptr, const char *propname, @@ -1795,6 +1832,21 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_CONTEXT); api_ui_item_rna_common(func); + func = RNA_def_function(srna, "template_cache_file_velocity", "rna_uiTemplateCacheFileVelocity"); + RNA_def_function_ui_description(func, "Show cache files velocity properties"); + api_ui_item_rna_common(func); + + func = RNA_def_function( + srna, "template_cache_file_procedural", "rna_uiTemplateCacheFileProcedural"); + RNA_def_function_ui_description(func, "Show cache files render procedural properties"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + api_ui_item_rna_common(func); + + func = RNA_def_function( + srna, "template_cache_file_time_settings", "rna_uiTemplateCacheFileTimeSettings"); + RNA_def_function_ui_description(func, "Show cache files time settings"); + api_ui_item_rna_common(func); + func = RNA_def_function(srna, "template_recent_files", "uiTemplateRecentFiles"); RNA_def_function_ui_description(func, "Show list of recently saved .blend files"); RNA_def_int(func, "rows", 5, 1, INT_MAX, "", "Maximum number of items to show", 1, INT_MAX); diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index bcaf294ec8b..6982f95ef8d 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -328,14 +328,71 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemR(layout, ptr, "use_vertex_interpolation", 0, NULL, ICON_NONE); } - uiItemR(layout, ptr, "velocity_scale", 0, NULL, ICON_NONE); - modifier_panel_end(layout, ptr); } +static void velocity_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ob_ptr; + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); + + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) { + return; + } + + uiLayoutSetPropSep(layout, true); + uiTemplateCacheFileVelocity(layout, &fileptr); + uiItemR(layout, ptr, "velocity_scale", 0, NULL, ICON_NONE); +} + +static void time_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ob_ptr; + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); + + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) { + return; + } + + uiLayoutSetPropSep(layout, true); + uiTemplateCacheFileTimeSettings(layout, &fileptr); +} + +static void render_procedural_panel_draw(const bContext *C, Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA ob_ptr; + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); + + PointerRNA fileptr; + if (!uiTemplateCacheFilePointer(ptr, "cache_file", &fileptr)) { + return; + } + + uiLayoutSetPropSep(layout, true); + uiTemplateCacheFileProcedural(layout, C, &fileptr); +} + static void panelRegister(ARegionType *region_type) { - modifier_panel_register(region_type, eModifierType_MeshSequenceCache, panel_draw); + PanelType *panel_type = modifier_panel_register( + region_type, eModifierType_MeshSequenceCache, panel_draw); + modifier_subpanel_register(region_type, "time", "Time", NULL, time_panel_draw, panel_type); + modifier_subpanel_register(region_type, + "render_procedural", + "Render Procedural", + NULL, + render_procedural_panel_draw, + panel_type); + modifier_subpanel_register( + region_type, "velocity", "Velocity", NULL, velocity_panel_draw, panel_type); } static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)