2025-12-01
This commit is contained in:
@@ -0,0 +1,402 @@
|
||||
# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
|
||||
from . import (
|
||||
propsdata,
|
||||
props,
|
||||
cache
|
||||
)
|
||||
from .ops import (
|
||||
CM_OT_cache_export,
|
||||
CM_OT_cacheconfig_export,
|
||||
CM_OT_import_cache,
|
||||
CM_OT_import_colls_from_config,
|
||||
CM_OT_update_cache_colls_list,
|
||||
CM_OT_cache_list_actions,
|
||||
CM_OT_assign_cachefile,
|
||||
CM_OT_cache_show,
|
||||
CM_OT_cache_hide,
|
||||
CM_OT_cache_remove,
|
||||
CM_OT_set_cache_version,
|
||||
CM_OT_add_cache_version_increment,
|
||||
)
|
||||
|
||||
|
||||
class CM_PT_vi3d_cache(bpy.types.Panel):
|
||||
bl_category = "CacheManager"
|
||||
bl_label = "Cache"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_order = 10
|
||||
|
||||
def draw(self, context: bpy.types.Context) -> None:
|
||||
layout = self.layout
|
||||
split_factor = 0.225
|
||||
split_factor_small = 0.95
|
||||
# Category to choose between export / import.
|
||||
row = layout.row(align=True)
|
||||
row.prop(context.scene.cm, "category", expand=True)
|
||||
|
||||
# Add some space.
|
||||
row = layout.row(align=True)
|
||||
row.separator()
|
||||
|
||||
# Box for cache version and cacheconfig.
|
||||
box = layout.box()
|
||||
|
||||
# Version.
|
||||
version_text = self._get_version_text(context)
|
||||
|
||||
split = box.split(factor=split_factor, align=True)
|
||||
|
||||
# Version label.
|
||||
split.label(text="Version:")
|
||||
|
||||
if context.scene.cm.category == "EXPORT":
|
||||
sub_split = split.split(factor=split_factor_small, align=True)
|
||||
sub_split.operator(
|
||||
CM_OT_set_cache_version.bl_idname,
|
||||
icon="DOWNARROW_HLT",
|
||||
text=version_text,
|
||||
)
|
||||
sub_split.operator(
|
||||
CM_OT_add_cache_version_increment.bl_idname,
|
||||
icon="ADD",
|
||||
text="",
|
||||
)
|
||||
|
||||
else:
|
||||
split.operator(
|
||||
CM_OT_set_cache_version.bl_idname,
|
||||
icon="DOWNARROW_HLT",
|
||||
text=version_text,
|
||||
)
|
||||
|
||||
# Cachedir.
|
||||
split = box.split(factor=split_factor, align=True)
|
||||
|
||||
# Cachedir label.
|
||||
split.label(text="Cache Directory:")
|
||||
|
||||
if not context.scene.cm.is_cachedir_valid:
|
||||
split.label(text=f"Invalid. Check Addon Preferences.")
|
||||
|
||||
else:
|
||||
if context.scene.cm.category == "EXPORT":
|
||||
if context.scene.cm.cachedir_path.exists():
|
||||
sub_split = split.split(factor=1 - split_factor_small)
|
||||
sub_split.label(icon="ERROR")
|
||||
sub_split.prop(context.scene.cm, "cachedir", text="")
|
||||
|
||||
else:
|
||||
split.prop(context.scene.cm, "cachedir", text="")
|
||||
|
||||
else:
|
||||
if not context.scene.cm.cachedir_path.exists():
|
||||
split.label(text=f"Not found")
|
||||
else:
|
||||
split.prop(context.scene.cm, "cachedir", text="")
|
||||
|
||||
# Cacheconfig.
|
||||
split = box.split(factor=split_factor, align=True)
|
||||
# Cachedir label.
|
||||
split.label(text="Cacheconfig:")
|
||||
|
||||
if not context.scene.cm.is_cacheconfig_valid:
|
||||
if (
|
||||
context.scene.cm.use_cacheconfig_custom
|
||||
and context.scene.cm.category == "IMPORT"
|
||||
):
|
||||
sub_split = split.split(factor=0.95, align=True)
|
||||
sub_split.prop(context.scene.cm, "cacheconfig_custom", text="")
|
||||
sub_split.operator(
|
||||
CM_OT_import_colls_from_config.bl_idname, icon="PLAY", text=""
|
||||
)
|
||||
else:
|
||||
split.label(text=f"Invalid. Check Addon Preferences.")
|
||||
|
||||
row = box.row(align=True)
|
||||
row.prop(context.scene.cm, "use_cacheconfig_custom")
|
||||
|
||||
else:
|
||||
if context.scene.cm.category == "EXPORT":
|
||||
|
||||
if context.scene.cm.cacheconfig_path.exists():
|
||||
sub_split = split.split(factor=1 - split_factor_small)
|
||||
sub_split.label(icon="ERROR")
|
||||
sub_split.prop(context.scene.cm, "cacheconfig", text="")
|
||||
|
||||
else:
|
||||
split.prop(context.scene.cm, "cacheconfig", text="")
|
||||
else:
|
||||
if context.scene.cm.use_cacheconfig_custom:
|
||||
sub_split = split.split(factor=0.95, align=True)
|
||||
sub_split.prop(context.scene.cm, "cacheconfig_custom", text="")
|
||||
sub_split.operator(
|
||||
CM_OT_import_colls_from_config.bl_idname, icon="PLAY", text=""
|
||||
)
|
||||
|
||||
else:
|
||||
if not context.scene.cm.cacheconfig_path.exists():
|
||||
split.label(text=f"Not found")
|
||||
|
||||
else:
|
||||
sub_split = split.split(factor=0.95, align=True)
|
||||
sub_split.prop(context.scene.cm, "cacheconfig", text="")
|
||||
sub_split.operator(
|
||||
CM_OT_import_colls_from_config.bl_idname,
|
||||
icon="PLAY",
|
||||
text="",
|
||||
)
|
||||
row = box.row(align=True)
|
||||
row.prop(context.scene.cm, "use_cacheconfig_custom")
|
||||
|
||||
# Add some space.
|
||||
row = layout.row(align=True)
|
||||
row.separator()
|
||||
|
||||
# Collection operations.
|
||||
box = layout.box()
|
||||
box.label(text="Cache Collections", icon="OUTLINER_COLLECTION")
|
||||
if context.scene.cm.category == "EXPORT":
|
||||
|
||||
# Get collections.
|
||||
collections = list(props.get_cache_collections_export(context))
|
||||
|
||||
# Ui-list.
|
||||
row = box.row()
|
||||
row.template_list(
|
||||
"CM_UL_collection_cache_list_export",
|
||||
"collection_cache_list_export",
|
||||
context.scene.cm,
|
||||
"colls_export",
|
||||
context.scene.cm,
|
||||
"colls_export_index",
|
||||
rows=5,
|
||||
type="DEFAULT",
|
||||
)
|
||||
col = row.column(align=True)
|
||||
col.operator(
|
||||
CM_OT_update_cache_colls_list.bl_idname, icon="FILE_REFRESH", text=""
|
||||
)
|
||||
col.operator(
|
||||
CM_OT_cache_list_actions.bl_idname, icon="ADD", text=""
|
||||
).action = "ADD"
|
||||
col.operator(
|
||||
CM_OT_cache_list_actions.bl_idname, icon="REMOVE", text=""
|
||||
).action = "REMOVE"
|
||||
|
||||
row = box.row(align=True)
|
||||
row.operator(
|
||||
CM_OT_cache_export.bl_idname,
|
||||
text=f"Cache {len(collections)} Collections",
|
||||
icon="EXPORT",
|
||||
).do_all = True
|
||||
|
||||
row.operator(
|
||||
CM_OT_cacheconfig_export.bl_idname,
|
||||
text="",
|
||||
icon="ALIGN_LEFT",
|
||||
).do_all = True
|
||||
|
||||
else:
|
||||
# Get collections.
|
||||
collections = list(props.get_cache_collections_import(context))
|
||||
|
||||
# Ui-list.
|
||||
row = box.row()
|
||||
row.template_list(
|
||||
"CM_UL_collection_cache_list_import",
|
||||
"collection_cache_list_import",
|
||||
context.scene.cm,
|
||||
"colls_import",
|
||||
context.scene.cm,
|
||||
"colls_import_index",
|
||||
rows=5,
|
||||
type="DEFAULT",
|
||||
)
|
||||
col = row.column(align=True)
|
||||
col.operator(
|
||||
CM_OT_update_cache_colls_list.bl_idname, icon="FILE_REFRESH", text=""
|
||||
)
|
||||
col.operator(
|
||||
CM_OT_cache_list_actions.bl_idname, icon="ADD", text=""
|
||||
).action = "ADD"
|
||||
col.operator(
|
||||
CM_OT_cache_list_actions.bl_idname, icon="REMOVE", text=""
|
||||
).action = "REMOVE"
|
||||
|
||||
row = box.row(align=True)
|
||||
row.operator(
|
||||
CM_OT_import_cache.bl_idname,
|
||||
text="Load",
|
||||
icon="IMPORT",
|
||||
).do_all = True
|
||||
row.operator(
|
||||
CM_OT_cache_show.bl_idname, text="Show", icon="HIDE_OFF"
|
||||
).do_all = True
|
||||
|
||||
row.operator(
|
||||
CM_OT_cache_hide.bl_idname, text="Hide", icon="HIDE_ON"
|
||||
).do_all = True
|
||||
|
||||
row.operator(
|
||||
CM_OT_cache_remove.bl_idname, text="Remove", icon="REMOVE"
|
||||
).do_all = True
|
||||
|
||||
def _get_version_text(self, context: bpy.types.Context) -> str:
|
||||
version_text = "Select Version"
|
||||
|
||||
if context.scene.cm.cache_version:
|
||||
version_text = context.scene.cm.cache_version
|
||||
|
||||
return version_text
|
||||
|
||||
|
||||
class CM_PT_vi3d_advanced(bpy.types.Panel):
|
||||
bl_parent_id = "CM_PT_vi3d_cache"
|
||||
bl_category = "CacheManager"
|
||||
bl_label = "Advanced"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_order = 10
|
||||
bl_options = {"DEFAULT_CLOSED"}
|
||||
|
||||
def draw(self, context: bpy.types.Context) -> None:
|
||||
layout = self.layout
|
||||
|
||||
# Alembic export settings.
|
||||
box = layout.box()
|
||||
box.label(text="Alembic Export Settings", icon="MODIFIER")
|
||||
|
||||
# Frame range.
|
||||
col = box.column(align=True)
|
||||
col.prop(context.scene.cm, "frame_handles_left")
|
||||
col.prop(context.scene.cm, "frame_handles_right")
|
||||
|
||||
# Shutter.
|
||||
col = box.column(align=True)
|
||||
col.prop(context.scene.cm, "sh_open")
|
||||
col.prop(context.scene.cm, "sh_close")
|
||||
|
||||
# Samples.
|
||||
col = box.column(align=True)
|
||||
col.prop(context.scene.cm, "xsamples")
|
||||
col.prop(context.scene.cm, "gsamples")
|
||||
|
||||
|
||||
class CM_UL_collection_cache_list_export(bpy.types.UIList):
|
||||
def draw_item(
|
||||
self, context, layout, data, item, icon, active_data, active_propname, index
|
||||
):
|
||||
coll = item.coll_ptr
|
||||
|
||||
if self.layout_type in {"DEFAULT", "COMPACT"}:
|
||||
# Item got deleted.
|
||||
if not coll:
|
||||
layout.label(text=f"{item.name} was deleted")
|
||||
return
|
||||
|
||||
split = layout.split(factor=0.5, align=True)
|
||||
split.prop(
|
||||
coll,
|
||||
"name",
|
||||
text="",
|
||||
emboss=False,
|
||||
icon="OUTLINER_COLLECTION",
|
||||
)
|
||||
split = split.split(factor=0.75, align=True)
|
||||
split.label(text=f"/{propsdata.gen_cache_coll_filename(coll)}")
|
||||
split.operator(
|
||||
CM_OT_cache_export.bl_idname,
|
||||
text="",
|
||||
icon="EXPORT",
|
||||
).index = index
|
||||
# Disable row if coll not valid.
|
||||
if not cache.is_valid_cache_coll(coll):
|
||||
split.enabled = False
|
||||
|
||||
elif self.layout_type in {"GRID"}:
|
||||
layout.alignment = "CENTER"
|
||||
layout.label(text="", icon_value=layout.icon(coll))
|
||||
|
||||
|
||||
class CM_UL_collection_cache_list_import(bpy.types.UIList):
|
||||
def draw_item(
|
||||
self, context, layout, data, item, icon, active_data, active_propname, index
|
||||
):
|
||||
coll = item.coll_ptr
|
||||
|
||||
if self.layout_type in {"DEFAULT", "COMPACT"}:
|
||||
# Item got deleted.
|
||||
if not coll:
|
||||
layout.label(text=f"{item.name} was deleted")
|
||||
return
|
||||
|
||||
split = layout.split(factor=0.4, align=True)
|
||||
split.prop(
|
||||
coll,
|
||||
"name",
|
||||
text="",
|
||||
emboss=False,
|
||||
icon="OUTLINER_COLLECTION",
|
||||
)
|
||||
split = split.split(factor=0.7, align=True)
|
||||
|
||||
cachefile = coll.cm.cachefile
|
||||
op_text = "Select Cachefile"
|
||||
if cachefile:
|
||||
op_text = Path(cachefile).name
|
||||
|
||||
split.operator(
|
||||
CM_OT_assign_cachefile.bl_idname, text=op_text, icon="DOWNARROW_HLT"
|
||||
).index = index
|
||||
|
||||
if not coll.cm.is_cache_loaded:
|
||||
split.operator(
|
||||
CM_OT_import_cache.bl_idname,
|
||||
text="",
|
||||
icon="IMPORT",
|
||||
).index = index
|
||||
else:
|
||||
split.operator(
|
||||
CM_OT_cache_remove.bl_idname, text="", icon="REMOVE"
|
||||
).index = index
|
||||
|
||||
if coll.cm.is_cache_hidden:
|
||||
split.operator(
|
||||
CM_OT_cache_show.bl_idname, text="", icon="HIDE_ON"
|
||||
).index = index
|
||||
else:
|
||||
split.operator(
|
||||
CM_OT_cache_hide.bl_idname, text="", icon="HIDE_OFF"
|
||||
).index = index
|
||||
|
||||
elif self.layout_type in {"GRID"}:
|
||||
layout.alignment = "CENTER"
|
||||
layout.label(text="", icon_value=layout.icon(item.coll_ptr))
|
||||
|
||||
|
||||
# ---------REGISTER ----------.
|
||||
|
||||
classes = [
|
||||
CM_UL_collection_cache_list_export,
|
||||
CM_UL_collection_cache_list_import,
|
||||
CM_PT_vi3d_cache,
|
||||
CM_PT_vi3d_advanced,
|
||||
]
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
Reference in New Issue
Block a user