Files
2026-03-17 14:58:51 -06:00

257 lines
7.1 KiB
Python

# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from typing import List, Any, Generator, Optional
from pathlib import Path
import bpy
from . import prefs, propsdata
class CM_collection_property(bpy.types.PropertyGroup):
coll_ptr: bpy.props.PointerProperty(name="Collection", type=bpy.types.Collection)
class CM_property_group_collection(bpy.types.PropertyGroup):
is_cache_coll: bpy.props.BoolProperty(
name="Cache Collection",
default=False,
options={"LIBRARY_EDITABLE"},
override={"LIBRARY_OVERRIDABLE"},
)
cachefile: bpy.props.StringProperty(
name="Cachefile",
default="",
subtype="FILE_PATH",
options={"LIBRARY_EDITABLE"},
override={"LIBRARY_OVERRIDABLE"},
)
is_cache_loaded: bpy.props.BoolProperty(
name="Cache Loaded",
default=False,
options={"LIBRARY_EDITABLE"},
override={"LIBRARY_OVERRIDABLE"},
)
is_cache_hidden: bpy.props.BoolProperty(
name="Cache Hidden",
default=False,
options={"LIBRARY_EDITABLE"},
override={"LIBRARY_OVERRIDABLE"},
)
def reset_properties(self):
self.is_cache_coll = False
self.cachefile = ""
self.is_cache_loaded = False
self.is_cache_hidden = False
class CM_property_group_scene(bpy.types.PropertyGroup):
category: bpy.props.EnumProperty( # type: ignore
items=(
("EXPORT", "Export", "Import Cache Collections", "EXPORT", 0),
("IMPORT", "Import", "Export Cache Collections", "IMPORT", 1),
),
default="EXPORT",
update=prefs.category_update_version_model,
)
colls_export_index: bpy.props.IntProperty(name="Index", default=0)
colls_import_index: bpy.props.IntProperty(name="Index", default=0)
cache_version: bpy.props.StringProperty(name="Version", default="v001")
colls_export: bpy.props.CollectionProperty(type=CM_collection_property)
colls_import: bpy.props.CollectionProperty(type=CM_collection_property)
cacheconfig: bpy.props.StringProperty(
name="Cacheconfig File", get=propsdata.gen_cacheconfig_path_str
)
cachedir: bpy.props.StringProperty(
name="Cachedir", get=propsdata.gen_cachedir_path_str,
description="Directory in which the cachefiles are located"
)
cache_version_dir: bpy.props.StringProperty(
name="Cache version dir", get=propsdata.get_cache_version_dir_path_str
)
use_cacheconfig_custom: bpy.props.BoolProperty(
name="Custom Cacheconfig", default=False
)
cacheconfig_custom: bpy.props.StringProperty(
name="Cacheconfig File",
default="",
subtype="FILE_PATH",
)
xsamples: bpy.props.IntProperty(
name="Transform Samples",
description="Sets the xsamples argument of bpy.ops.wm.alembic_export to the specified value",
default=1,
min=1,
max=128,
step=1,
)
gsamples: bpy.props.IntProperty(
name="Geometry Samples",
description="Sets the gsamples argument of bpy.ops.wm.alembic_export to the specified value",
default=1,
min=1,
max=128,
step=1,
)
sh_open: bpy.props.FloatProperty(
name="Shutter Open",
description="Sets the sh_open argument of bpy.ops.wm.alembic_export to the specified value",
default=0,
min=-1.0,
max=1.0,
step=0.1,
)
sh_close: bpy.props.FloatProperty(
name="Shutter Close",
description="Sets the sh_close argument of bpy.ops.wm.alembic_export to the specified value",
default=1,
min=-1.0,
max=1.0,
step=0.1,
)
frame_handles_left: bpy.props.IntProperty(
name="Frame Handles Start",
description="Caching starts at the frame in of the scene minus the specified amount of frame handles",
default=10,
min=0,
step=1,
)
frame_handles_right: bpy.props.IntProperty(
name="Frame Handles End",
description="Caching stops at the frame out of the scene plus the specified amount of frame handles",
default=10,
min=0,
step=1,
)
@property
def cachedir_path(self) -> Optional[Path]:
if not self.is_cachedir_valid:
return None
return Path(os.path.abspath(bpy.path.abspath(self.cachedir)))
@property
def is_cachedir_valid(self) -> bool:
if not self.cachedir:
return False
if not bpy.data.filepath and self.cachedir.startswith("//"):
return False
return True
@property
def cache_version_dir_path(self) -> Optional[Path]:
if not self.is_cache_version_dir_valid:
return None
return Path(os.path.abspath(bpy.path.abspath(self.cache_version_dir)))
@property
def is_cache_version_dir_valid(self) -> bool:
if not self.cache_version_dir:
return False
if not bpy.data.filepath and self.cache_version_dir.startswith("//"):
return False
return True
@property
def is_cacheconfig_valid(self) -> bool:
if not self.cacheconfig:
return False
if not bpy.data.filepath and self.cacheconfig.startswith("//"):
return False
return True
@property
def is_cacheconfig_custom_valid(self) -> bool:
if not self.cacheconfig_custom:
return False
if not bpy.data.filepath and self.cacheconfig_custom.startswith("//"):
return False
return True
@property
def cacheconfig_path(self) -> Optional[Path]:
if not self.is_cacheconfig_valid:
return None
return Path(os.path.abspath(bpy.path.abspath(self.cacheconfig)))
@property
def cacheconfig_custom_path(self) -> Optional[Path]:
if not self.is_cacheconfig_custom_valid:
return None
return Path(os.path.abspath(bpy.path.abspath(self.cacheconfig_custom)))
def get_cache_collections_import(
context: bpy.types.Context,
) -> Generator[bpy.types.Collection, None, None]:
for item in context.scene.cm.colls_import:
if item.coll_ptr:
yield item.coll_ptr
def get_cache_collections_export(
context: bpy.types.Context,
) -> Generator[bpy.types.Collection, None, None]:
for item in context.scene.cm.colls_export:
if item.coll_ptr:
yield item.coll_ptr
# ---------REGISTER ----------.
classes: List[Any] = [
CM_collection_property,
CM_property_group_collection,
CM_property_group_scene,
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
# Scene Properties.
bpy.types.Scene.cm = bpy.props.PointerProperty(type=CM_property_group_scene)
# Collection Properties.
bpy.types.Collection.cm = bpy.props.PointerProperty(
name="Cache Manager",
type=CM_property_group_collection,
description="Metadata that is required for the cache manager",
override={"LIBRARY_OVERRIDABLE"},
)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)