Keep asset library cleanup on unregister (#64)
* feat: Add Bioxel asset catalog and layer management functionality - Introduced a new asset catalog definition file for Blender to manage Bioxel assets. - Implemented layer caching and snapshot functionality in `layer.py`, allowing for VDB file generation and low-resolution snapshots. - Created node management functions in `node.py` for handling Bioxel nodes within Blender's Geometry Node Editor. - Added an operator to extract mesh data from selected nodes in `structure.py`. - Developed UI panels in `panels.py` for layer management, including import options and layer library display. * Add unit tests for bioxel module and documentation - Created README.md for test instructions and categories. - Implemented comprehensive unit tests for the Data, Layer, and utility functions in the bioxel module. - Added tests for reading NRRD and DICOM formats, data properties, and edge cases. - Included tests for real data files to ensure functionality with actual datasets. * feat: Update .gitattributes and .gitignore for improved asset management and ignore patterns chore: Add app.json and omoolab.css for Obsidian integration refactor: Clean up AGENTS.md and remove outdated test files * feat: Update .gitignore to include scipy_ndimage directory * feat: Update release workflow and manifest for improved dependency management and layer handling * feat: Update .gitignore and add binary files for scipy_ndimage across multiple platforms * feat: Add OPSX commands for archiving, exploring, and proposing changes * feat: Refactor asset library management and update manifest for improved organization * feat: Downgrade h5py version to 3.14.0 in requirements and manifest * feat: Update Help operator and panel labels to use English terminology * Translate documentation to Chinese, add support format details, and enhance styling with new fonts. Update mkdocs configuration for multilingual support and improve package dependencies. * feat: Remove default version setting from extra configuration in mkdocs.yml * fix: Update documentation links to point to the correct URLs for Chinese and English versions * Add documentation for basic usage, supported formats, and performance tips - Created English and Chinese documentation for basic usage of the add-on, including data download, import, extraction, and rendering steps. - Added support format documentation listing compatible file types for the add-on. - Included links to open databases for volumetric data. - Provided performance improvement tips for voxel reconstruction and rendering, including settings for low-resolution previews and balanced rendering configurations. * Add OpenSpec skills for change management and exploration - Implement openspec-apply-change skill for applying tasks from OpenSpec changes. - Create openspec-archive-change skill for archiving completed changes. - Introduce openspec-explore skill for exploring ideas and clarifying requirements. - Add openspec-propose skill for proposing new changes with generated artifacts. - Migrate source command skills: source-command-opsx-apply, source-command-opsx-archive, source-command-opsx-explore, and source-command-opsx-propose for improved command handling. * feat: Update version to 2.0.1, refactor asset library handling, and enhance layer import process * fix: downgrade scipy version to 1.16.3 in build.py and pyproject.toml * Remove deprecated modules and functions from bioxel package - Deleted _ni_support.py, _utils.py, and dtype.py as they contained unused or redundant functions. - Removed the resize function and related utilities from _warps.py to streamline image processing. - Cleaned up the skimage module by removing unnecessary imports and functions. * feat: Add SKIP_MODULE_NAMES to exclude specific modules during import and refactor io_worker import logic * refactor: Remove known limitations section from documentation for EEVEE NEXT support * feat: Implement CLI command registration for bioxelnodes_import_worker and refactor io_worker for improved module handling * chore: Update version to 2.0.2 in project files and dependencies * feat: Enhance volumetric data parsing by adding progress updates and refactoring worker processes * feat: Enhance asset library management with status checks and error handling * feat: Update version to 2.0.3 and adjust dependencies in project files
This commit is contained in:
@@ -2,6 +2,7 @@ import bpy
|
||||
import bpy.utils.previews as previews
|
||||
|
||||
from .constants import PREVIEW_COLLECTIONS
|
||||
from .asset_library import remove_bioxel_asset_library_if_exists
|
||||
from .props import _bioxel_layer_items, _update_layer_gallery, _update_snapshot_z
|
||||
|
||||
from . import auto_load
|
||||
@@ -47,6 +48,7 @@ def register():
|
||||
|
||||
|
||||
def unregister():
|
||||
remove_bioxel_asset_library_if_exists()
|
||||
unregister_cli_commands()
|
||||
menus.remove()
|
||||
auto_load.unregister()
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
|
||||
from .constants import NODE_LIB_DIRPATH
|
||||
from .constants import LATEST_NODE_LIB_PATH, NODE_LIB_DIRPATH, NODE_LIB_FILENAME
|
||||
|
||||
|
||||
ASSET_LIBRARY_NAME = "O Bioxel"
|
||||
ASSET_LIBRARY_READY = "READY"
|
||||
ASSET_LIBRARY_OUTDATED = "OUTDATED"
|
||||
ASSET_LIBRARY_MISSING = "MISSING"
|
||||
|
||||
STATUS_MESSAGES = {
|
||||
"missing": "O Bioxel asset library is not installed.",
|
||||
"missing_blend": "O Bioxel node library file is missing.",
|
||||
"outdated": "O Bioxel node library needs update.",
|
||||
"ready": "O Bioxel asset library is ready.",
|
||||
}
|
||||
|
||||
|
||||
def _asset_library_path():
|
||||
@@ -19,6 +29,26 @@ def _asset_libraries():
|
||||
return bpy.context.preferences.filepaths.asset_libraries
|
||||
|
||||
|
||||
def _find_bioxel_asset_library():
|
||||
lib_path = _normalized_path(_asset_library_path())
|
||||
named_lib = None
|
||||
|
||||
for lib in _asset_libraries():
|
||||
try:
|
||||
if _normalized_path(lib.path) == lib_path:
|
||||
return lib
|
||||
if lib.name == ASSET_LIBRARY_NAME:
|
||||
named_lib = lib
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return named_lib
|
||||
|
||||
|
||||
def _node_lib_path_for_library(lib):
|
||||
return _normalized_path(lib.path) / NODE_LIB_FILENAME
|
||||
|
||||
|
||||
def get_bioxel_asset_library():
|
||||
lib_path = _normalized_path(_asset_library_path())
|
||||
|
||||
@@ -32,16 +62,47 @@ def get_bioxel_asset_library():
|
||||
return None
|
||||
|
||||
|
||||
def get_bioxel_asset_library_status():
|
||||
lib = _find_bioxel_asset_library()
|
||||
lib_path = _normalized_path(_asset_library_path())
|
||||
|
||||
if lib is None:
|
||||
return {"code": ASSET_LIBRARY_MISSING, "reason": "missing",
|
||||
"message": STATUS_MESSAGES["missing"]}
|
||||
|
||||
try:
|
||||
installed_lib_path = _normalized_path(lib.path)
|
||||
except Exception:
|
||||
return {"code": ASSET_LIBRARY_MISSING, "reason": "missing",
|
||||
"message": STATUS_MESSAGES["missing"]}
|
||||
|
||||
if not _node_lib_path_for_library(lib).is_file():
|
||||
return {"code": ASSET_LIBRARY_MISSING, "reason": "missing_blend",
|
||||
"message": STATUS_MESSAGES["missing_blend"]}
|
||||
|
||||
if installed_lib_path != lib_path:
|
||||
return {"code": ASSET_LIBRARY_OUTDATED, "reason": "outdated",
|
||||
"message": STATUS_MESSAGES["outdated"]}
|
||||
|
||||
return {"code": ASSET_LIBRARY_READY, "reason": "ready",
|
||||
"message": STATUS_MESSAGES["ready"]}
|
||||
|
||||
|
||||
def has_bioxel_asset_library():
|
||||
return get_bioxel_asset_library() is not None
|
||||
return get_bioxel_asset_library_status()["code"] in {
|
||||
ASSET_LIBRARY_READY,
|
||||
ASSET_LIBRARY_OUTDATED,
|
||||
}
|
||||
|
||||
|
||||
def add_bioxel_asset_library():
|
||||
if not NODE_LIB_DIRPATH.exists():
|
||||
raise FileNotFoundError(f"Node library path does not exist: {NODE_LIB_DIRPATH}")
|
||||
if not LATEST_NODE_LIB_PATH.is_file():
|
||||
raise FileNotFoundError(f"Node library file does not exist: {LATEST_NODE_LIB_PATH}")
|
||||
|
||||
prefs = _asset_libraries()
|
||||
lib = get_bioxel_asset_library()
|
||||
lib = _find_bioxel_asset_library()
|
||||
|
||||
if lib is None:
|
||||
for item in prefs:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
schema_version = "1.0.0"
|
||||
|
||||
id = "bioxelnodes"
|
||||
version = "2.0.2"
|
||||
version = "2.0.3"
|
||||
name = "Bioxel Nodes"
|
||||
tagline = "For scientific volumetric data visualization in Blender"
|
||||
maintainer = "Nan <icrdr2010@outlook.com>"
|
||||
|
||||
@@ -89,7 +89,7 @@ def start_worker_process(owner, command: str, payload: dict):
|
||||
write_worker_json(config_path, config)
|
||||
write_worker_json(
|
||||
progress_path,
|
||||
{"factor": 0.0, "text": "Starting background Blender..."},
|
||||
{"factor": 0.0, "text": "Starting..."},
|
||||
)
|
||||
|
||||
print(f"Starting Bioxel worker with addon module: {addon_name}")
|
||||
|
||||
@@ -3,6 +3,7 @@ import shutil
|
||||
|
||||
import bpy
|
||||
|
||||
from ..asset_library import ASSET_LIBRARY_MISSING, get_bioxel_asset_library_status
|
||||
from ..node import add_bioxel_node, get_layer_nodes, get_main_node_group
|
||||
from ..utils import refresh_bioxel_panels
|
||||
from ..layer import get_layer_caches, set_layer_caches
|
||||
@@ -91,6 +92,11 @@ class AddLayerNode(bpy.types.Operator):
|
||||
cache_id: bpy.props.StringProperty() # type: ignore # 图层ID
|
||||
|
||||
def execute(self, context):
|
||||
status = get_bioxel_asset_library_status()
|
||||
if status["code"] == ASSET_LIBRARY_MISSING:
|
||||
self.report({"ERROR"}, status["message"])
|
||||
return {"CANCELLED"}
|
||||
|
||||
# 获取图层数据
|
||||
caches = get_layer_caches()
|
||||
|
||||
|
||||
@@ -5,7 +5,12 @@ import bpy
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
from ..asset_library import add_bioxel_asset_library
|
||||
from ..asset_library import (
|
||||
ASSET_LIBRARY_OUTDATED,
|
||||
ASSET_LIBRARY_READY,
|
||||
add_bioxel_asset_library,
|
||||
get_bioxel_asset_library_status,
|
||||
)
|
||||
from ..constants import LATEST_NODE_LIB_PATH
|
||||
from ..utils import (
|
||||
get_all_layer_objs,
|
||||
@@ -138,8 +143,17 @@ class AddAssetLibrary(bpy.types.Operator):
|
||||
if area.type == "NODE_EDITOR":
|
||||
area.tag_redraw()
|
||||
|
||||
self.report({"INFO"}, "O Bioxel asset library is ready.")
|
||||
return {"FINISHED"}
|
||||
status = get_bioxel_asset_library_status()
|
||||
if status["code"] == ASSET_LIBRARY_READY:
|
||||
self.report({"INFO"}, status["message"])
|
||||
return {"FINISHED"}
|
||||
|
||||
if status["code"] == ASSET_LIBRARY_OUTDATED:
|
||||
self.report({"WARNING"}, status["message"])
|
||||
return {"FINISHED"}
|
||||
|
||||
self.report({"ERROR"}, status["message"])
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
# 定义虚无化切换操作
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
from pathlib import Path
|
||||
import bpy
|
||||
|
||||
from .asset_library import has_bioxel_asset_library
|
||||
from .asset_library import (
|
||||
ASSET_LIBRARY_OUTDATED,
|
||||
ASSET_LIBRARY_READY,
|
||||
get_bioxel_asset_library_status,
|
||||
has_bioxel_asset_library,
|
||||
)
|
||||
from .node import get_layer_nodes, get_main_node_group
|
||||
from .utils import load_icon
|
||||
from .layer import get_layer_caches
|
||||
@@ -78,13 +83,23 @@ class HeaderPanel(bpy.types.Panel, BioxelPanelBase):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
status = get_bioxel_asset_library_status()
|
||||
|
||||
if not has_bioxel_asset_library():
|
||||
if status["code"] == ASSET_LIBRARY_OUTDATED:
|
||||
layout.operator(
|
||||
AddAssetLibrary.bl_idname,
|
||||
text="Update Nodes Library",
|
||||
icon="ASSET_MANAGER",
|
||||
)
|
||||
layout.label(text=status["message"], icon="INFO")
|
||||
|
||||
elif status["code"] != ASSET_LIBRARY_READY:
|
||||
layout.operator(
|
||||
AddAssetLibrary.bl_idname,
|
||||
text="Add Nodes Library",
|
||||
icon="ASSET_MANAGER",
|
||||
)
|
||||
layout.label(text=status["message"], icon="INFO")
|
||||
return
|
||||
|
||||
layout.operator(
|
||||
|
||||
Reference in New Issue
Block a user