From 28b787638cd33b2b806899d41cc843f2812b55f1 Mon Sep 17 00:00:00 2001 From: Ma Nan Date: Tue, 16 Apr 2024 14:33:18 +0800 Subject: [PATCH] fix: bug fix --- .gitignore | 4 +- bioxelnodes/assets/Nodes.blend | 4 +- bioxelnodes/convert.py | 1 + bioxelnodes/external_package/package.py | 25 ++++++------ bioxelnodes/external_package/preferences.py | 5 ++- bioxelnodes/io.py | 45 ++++++++++++--------- bioxelnodes/nodes.py | 5 ++- bioxelnodes/utils.py | 30 ++++++++++++-- 8 files changed, 77 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index c41ab26..84a2267 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,6 @@ pythonlib* blendcache_* -*.ipynb \ No newline at end of file +*.ipynb + +.secrets \ No newline at end of file diff --git a/bioxelnodes/assets/Nodes.blend b/bioxelnodes/assets/Nodes.blend index 1e1f82b..f23fc9e 100644 --- a/bioxelnodes/assets/Nodes.blend +++ b/bioxelnodes/assets/Nodes.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:930786ba62844df527a9c7b7ee02920a117e80d7f4f899b91d807379e5e9a780 -size 1665260 +oid sha256:ae5e166bf8adfc1d5387b7ec1365adcb7a3d65d68e74b84232d90791ba9a0c6f +size 1705390 diff --git a/bioxelnodes/convert.py b/bioxelnodes/convert.py index 8046fad..bfbc12c 100644 --- a/bioxelnodes/convert.py +++ b/bioxelnodes/convert.py @@ -10,6 +10,7 @@ class ConvertToMesh(bpy.types.Operator): def execute(self, context): bioxels_objs = [] + for obj in bpy.context.selected_objects: bioxels_obj = get_bioxels_obj(obj) if bioxels_obj: diff --git a/bioxelnodes/external_package/package.py b/bioxelnodes/external_package/package.py index 36bb68a..4c7c396 100644 --- a/bioxelnodes/external_package/package.py +++ b/bioxelnodes/external_package/package.py @@ -42,15 +42,13 @@ class InstallationError(Exception): class PackageInstaller(): def __init__( self, + log_dir: str, + requirements_dir: str, pypi_mirror_provider='Default', - log_dir: str = None, - requirements_dir: str = None ) -> None: self.pypi_mirror_provider = pypi_mirror_provider - self.log_path: Path = Path(log_dir) if log_dir else \ - Path(Path.home(), '.externalpackage', 'logs') - self.requirements_path: Path = Path(requirements_dir) if requirements_dir else \ - Path(__file__).parent + self.log_path: Path = Path(log_dir) + self.requirements_path: Path = Path(requirements_dir) def start_logging(self, logfile_name: str = 'side-packages-install') -> logging.Logger: """ @@ -233,7 +231,7 @@ class PackageInstaller(): """ # path to python.exe - python_exe = Path(sys.executable).resolve() + python_exe = Path(sys.executable).resolve().as_posix() # build the command list cmd_list = [python_exe] + cmd_list @@ -293,12 +291,11 @@ class PackageInstaller(): raise ValueError("Package name must be provided.") print(f"Installing {package}...") - print(f"Using PyPI mirror:\ - {self.pypi_mirror_provider} {self.pypi_mirror_url}") + print(f"Using PyPI mirror: {self.pypi_mirror_provider}") self.run_python(["-m", "ensurepip"]), self.run_python(["-m", "pip", "install", "--upgrade", "pip"]) - result = self.run_python(["-m", "pip", "install", package]) + result = self.run_python(["-m", "pip", "install", package, "--user"]) return result @@ -348,7 +345,7 @@ class EXTERNALPACKAGE_OT_Install_Package(bpy.types.Operator): bl_idname = 'externalpackage.install_package' bl_label = 'Install Given Python Package' bl_options = {'REGISTER', 'INTERNAL'} - + package: bpy.props.StringProperty( name='Python Package', description='Python Package to Install' @@ -384,7 +381,9 @@ class EXTERNALPACKAGE_OT_Install_Package(bpy.types.Operator): else: self.report( {'ERROR'}, - f"Error installing package. Please check the log files in \ - '{preferences.log_dir}'." + f""" +Error installing package. Please check the log files +in {preferences.log_dir}. + """ ) return {'FINISHED'} diff --git a/bioxelnodes/external_package/preferences.py b/bioxelnodes/external_package/preferences.py index 357e2a2..092f258 100644 --- a/bioxelnodes/external_package/preferences.py +++ b/bioxelnodes/external_package/preferences.py @@ -14,13 +14,13 @@ class ExternalPackagePreferences(): requirements_dir: bpy.props.StringProperty( name="requirements.txt Directory", subtype='DIR_PATH', - default='' + default=Path(__file__).parent.as_posix() ) # type: ignore log_dir: bpy.props.StringProperty( name="Python Log Directory", subtype='DIR_PATH', - default='' + default=Path(Path.home(), '.externalpackage', 'logs').as_posix() ) # type: ignore pypi_mirror_provider: bpy.props.StringProperty( @@ -40,6 +40,7 @@ class ExternalPackagePreferences(): row_import = col_main.row() row_import.prop(self, 'pypi_mirror_provider', text='Set PyPI Mirror') + installer = PackageInstaller( pypi_mirror_provider=self.pypi_mirror_provider, log_dir=self.log_dir, diff --git a/bioxelnodes/io.py b/bioxelnodes/io.py index dca0600..a376184 100644 --- a/bioxelnodes/io.py +++ b/bioxelnodes/io.py @@ -6,12 +6,27 @@ import numpy as np from pathlib import Path from uuid import uuid4 import mathutils -from .utils import calc_bbox_verts, get_bioxels_obj, show_message +from .utils import calc_bbox_verts, extract_last_number, get_bioxels_obj, show_message from .nodes import custom_nodes SUPPORT_EXTS = ['.dcm', '.tif', '.tiff', '.png', '.bmp'] +def get_data_files(filepath: str): + file_path = Path(filepath).resolve() + suffix = file_path.suffix + + files = list(file_path.parent.iterdir()) + files = [f for f in files if f.is_file() and f.suffix == suffix] + + def last_number(file: Path): + return extract_last_number(file.stem) + + files.sort(key=last_number) + files = [f.as_posix() for f in files] + return files + + def on_orig_spacing_changed(self, context): if self.auto: self.auto = False @@ -122,12 +137,8 @@ class ImportDICOMDialog(bpy.types.Operator): return {'CANCELLED'} file_path = Path(self.filepath).resolve() - name = file_path.parent.stem - suffix = file_path.suffix - - files = list(file_path.parent.iterdir()) - files = [f.as_posix() - for f in files if f.is_file() and f.suffix == suffix] + name = file_path.parent.name + files = get_data_files(self.filepath) import SimpleITK as sitk image = sitk.ReadImage(files) @@ -174,7 +185,7 @@ class ImportDICOMDialog(bpy.types.Operator): image_origin = image.GetOrigin() bioxels_scale = float(self.bioxels_scale) bioxel_size *= bioxels_scale - bioxel_origin = ( + bioxels_origin = ( image_origin[0] * bioxels_scale, image_origin[1] * bioxels_scale, image_origin[2] * bioxels_scale, @@ -248,7 +259,7 @@ class ImportDICOMDialog(bpy.types.Operator): ).to_4x4() mat_loc = mathutils.Matrix.Translation( - mathutils.Vector(bioxel_origin)) + mathutils.Vector(bioxels_origin)) mat_sca = mathutils.Matrix.Scale(bioxel_size, 4) mat_rot = mathutils.Matrix( np.array(direction).reshape((3, 3)) @@ -269,10 +280,12 @@ class ImportDICOMDialog(bpy.types.Operator): bioxels_obj['value_max'] = value_max bioxels_obj['value_min'] = value_min bioxels_obj['value_offset'] = value_offset + bioxels_obj['image_origin'] = mathutils.Vector( + bioxels_origin) / bioxel_size + bioxels_obj['bioxel_size'] = bioxel_size bioxels_obj['bioxels_shape'] = bioxels_shape bioxels_obj['bioxels_size'] = bioxels_size - bioxels_obj['bioxel_size'] = bioxel_size - bioxels_obj['bioxel_origin'] = bioxel_origin + bioxels_obj['bioxels_origin'] = bioxels_origin bioxels_obj['bioxels_values'] = True bpy.ops.node.new_geometry_nodes_modifier() @@ -284,7 +297,7 @@ class ImportDICOMDialog(bpy.types.Operator): ) container_obj = bpy.context.active_object - bbox_verts = calc_bbox_verts(bioxel_origin, bioxels_size) + bbox_verts = calc_bbox_verts(bioxels_origin, bioxels_size) for index, vert in enumerate(container_obj.data.vertices): vert.co = bbox_verts[index] @@ -353,13 +366,7 @@ class ReadDICOM(bpy.types.Operator): ) # type: ignore def execute(self, context): - - file_path = Path(self.filepath).resolve() - suffix = file_path.suffix - - files = list(file_path.parent.iterdir()) - files = [f.as_posix() - for f in files if f.is_file() and f.suffix == suffix] + files = get_data_files(self.filepath) import SimpleITK as sitk image = sitk.ReadImage(files) diff --git a/bioxelnodes/nodes.py b/bioxelnodes/nodes.py index 9a8ed9e..bae71f8 100644 --- a/bioxelnodes/nodes.py +++ b/bioxelnodes/nodes.py @@ -1,4 +1,5 @@ +from pathlib import Path from .custom_nodes import CustomNodes import bpy @@ -83,7 +84,7 @@ MENU_ITEMS = [ 'icon': 'EMPTY_DATA', 'node_type': 'BioxelNodes_LPS-Slicer', 'node_description': '', - 'node_callback': add_driver_to_node_factory("origin", "Origin") + 'node_callback': add_driver_to_node_factory("image_origin", "Origin") }, { 'label': 'Axis Slicer', @@ -103,7 +104,7 @@ MENU_ITEMS = [ custom_nodes = CustomNodes( menu_items=MENU_ITEMS, - nodes_file="assets/Nodes.blend", + nodes_file=Path(__file__).parent/"assets/Nodes.blend", root_label='BioxelNodes', root_icon="FILE_VOLUME", ) diff --git a/bioxelnodes/utils.py b/bioxelnodes/utils.py index c12d4c7..5710fad 100644 --- a/bioxelnodes/utils.py +++ b/bioxelnodes/utils.py @@ -1,13 +1,15 @@ import bpy import mathutils -def show_message(message = "", title = "Message Box", icon = 'INFO'): + +def show_message(message="", title="Message Box", icon='INFO'): def draw(self, context): self.layout.label(text=message) - bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) - + bpy.context.window_manager.popup_menu(draw, title=title, icon=icon) + + def calc_bbox_verts(origin, size): bbox_origin = mathutils.Vector( (-origin[0], -origin[2], -origin[1])) @@ -76,6 +78,28 @@ def get_bioxels_obj(current_obj): return bioxels_obj +def extract_last_number(text): + # Initialize an empty string to store the digits + digits = "" + + # Iterate through the characters in reverse order + started = False + for char in text[::-1]: + if char.isdigit(): + started = True + # If the character is a digit, add it to the digits string + digits += char + else: + if started: + # If a non-digit character is encountered, stop the loop + break + + # Reverse the digits string to get the correct order + last_number = digits[::-1] + + return int(last_number) + + def add_driver(target_prop, var_sources, expression): driver = target_prop.driver_add("default_value")