Skip to content

Commit

Permalink
fix: relocate cannot work on missing layer
Browse files Browse the repository at this point in the history
fix: import fail if label are all zero
fix: add cutter name to node
fix: cannot append node lib file on NAS (UNC path)
fix: join component cause disappear
feat: smooth label
feat: better topo on cutout by range
  • Loading branch information
icrdr committed Sep 19, 2024
1 parent 0ebc6da commit 63c593f
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 50 deletions.
4 changes: 2 additions & 2 deletions bioxelnodes/assets/Nodes/BioxelNodes_latest.blend
Git LFS file not shown
8 changes: 2 additions & 6 deletions bioxelnodes/bioxel/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def fill(self, value: float, mask: np.ndarray, smooth: int = 0):
for f in range(self.frame_count):
mask_frame = mask[f, :, :, :]
if smooth > 0:
mask_frame = scipy.minimum_filter(mask_frame.astype(np.float32),
mask_frame = scipy.median_filter(mask_frame.astype(np.float32),
mode="nearest",
size=smooth)
# mask_frame = scipy.median_filter(
Expand All @@ -87,7 +87,7 @@ def fill(self, value: float, mask: np.ndarray, smooth: int = 0):
for f in range(self.frame_count):
mask_frame = mask[:, :, :]
if smooth > 0:
mask_frame = scipy.minimum_filter(mask_frame.astype(np.float32),
mask_frame = scipy.median_filter(mask_frame.astype(np.float32),
mode="nearest",
size=smooth)
# mask_frame = scipy.median_filter(
Expand Down Expand Up @@ -119,10 +119,6 @@ def resize(self, shape: tuple, smooth: int = 0, progress_callback=None):
if progress_callback:
progress_callback(f, self.frame_count)

# frame = ski.resize(data[f, :, :, :],
# shape,
# preserve_range=True,
# anti_aliasing=data.dtype.kind != "b")
frame = data[f, :, :, :, :]
if smooth > 0:
frame = scipy.median_filter(frame.astype(np.float32),
Expand Down
5 changes: 3 additions & 2 deletions bioxelnodes/bioxelutils/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,12 @@ def local_lib_not_updated():
not_update = get_node_version() != addon_version
return use_local and not_update


def get_output_node(node_group):
try:
output_node = get_nodes_by_type(node_group,
'NodeGroupOutput')[0]
except:
output_node = node_group.nodes.new("NodeGroupOutput")
return output_node

return output_node
43 changes: 22 additions & 21 deletions bioxelnodes/bioxelutils/node.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from pathlib import Path
import bpy

from .common import get_file_prop, get_node_lib_path, set_file_prop
from ..exceptions import Incompatible, NoFound
from .common import get_file_prop, set_file_prop
from ..exceptions import NoFound

from ..constants import LATEST_NODE_LIB_PATH, VERSIONS


def get_node_group(node_type: str, use_link=True):
def get_node_tree(node_type: str, use_link=True):
# unannotate below for local debug in node lib file.
# node_group = bpy.data.node_groups[node_type]
# return node_group
Expand All @@ -19,36 +19,37 @@ def get_node_group(node_type: str, use_link=True):
if get_file_prop("node_version") is None:
set_file_prop("node_version", addon_version)

local_lib_path = None
local_lib = None
for node_group in bpy.data.node_groups:
if node_group.name.startswith("BioxelNodes"):
lib = node_group.library
if lib:
lib_path = Path(bpy.path.abspath(lib.filepath)).resolve()
if lib_path != addon_lib_path:
local_lib_path = lib_path
local_lib = lib.filepath
break

# local lib first
lib_path = local_lib_path or addon_lib_path
bpy.ops.wm.append('EXEC_DEFAULT',
directory=f"{lib_path.as_posix()}/NodeTree",
filename=node_type,
link=use_link,
use_recursive=True,
do_reuse_local_id=True)
node_group = bpy.data.node_groups.get(node_type)

if node_group is None:
lib_path_str = local_lib or str(addon_lib_path)

with bpy.data.libraries.load(lib_path_str,
link=use_link,
relative=True) as (data_from, data_to):
data_to.node_groups = [n for n in data_from.node_groups
if n == node_type]

node_tree = data_to.node_groups[0]

if node_tree is None:
raise NoFound('No custom node found')

return node_group
return node_tree


def assign_node_group(node, node_type: str):
node.node_tree = bpy.data.node_groups[node_type]
def assign_node_tree(node, node_tree):
node.node_tree = node_tree
node.width = 200.0
node.name = node_type
node.name = node_tree.name
return node


Expand All @@ -61,9 +62,9 @@ def add_node_to_graph(node_name: str, node_group, node_label=None, use_link=True
if node.select:
node.select = False

get_node_group(node_type, use_link)
node_tree = get_node_tree(node_type, use_link)
node = node_group.nodes.new("GeometryNodeGroup")
assign_node_group(node, node_type)
assign_node_tree(node, node_tree)

node.label = node_label
node.show_options = False
Expand Down
2 changes: 1 addition & 1 deletion bioxelnodes/blender_manifest.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
schema_version = "1.0.0"

id = "bioxelnodes"
version = "1.0.1"
version = "1.0.2"
name = "Bioxel Nodes"
tagline = "For scientific volumetric data visualization in Blender"
maintainer = "Ma Nan <[email protected]>"
Expand Down
2 changes: 1 addition & 1 deletion bioxelnodes/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pathlib import Path

VERSIONS = [{"label": "Latest", "node_version": (1, 0, 1)},
VERSIONS = [{"label": "Latest", "node_version": (1, 0, 2)},
{"label": "v0.3.x", "node_version": (0, 3, 3)},
{"label": "v0.2.x", "node_version": (0, 2, 9)}]

Expand Down
2 changes: 1 addition & 1 deletion bioxelnodes/operators/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ def execute(self, context):
if len(cut_nodes) == 0:
cutter_node = add_node_to_graph("ObjectCutter",
node_group,
node_label=name,
node_label=f"{self.cutter_type.capitalize()} Cutter",
use_link=get_use_link())
cutter_node.inputs[0].default_value = self.cutter_type.capitalize()
cutter_node.inputs[1].default_value = cutter_obj
Expand Down
22 changes: 17 additions & 5 deletions bioxelnodes/operators/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class ParseVolumetricData(bpy.types.Operator):
read_as: bpy.props.EnumProperty(name="Read as",
default="SCALAR",
items=[("SCALAR", "Scalar", ""),
("LABEL", "Labels", ""),
("LABEL", "Label", ""),
("COLOR", "Color", "")]) # type: ignore

series_id: bpy.props.EnumProperty(name="Select Series",
Expand Down Expand Up @@ -284,6 +284,10 @@ def modal(self, context, event):
self.report({"ERROR"}, "Invaild label data.")
return {'CANCELLED'}

if self.label_count == 0:
self.report({"ERROR"}, "Get no label.")
return {'CANCELLED'}

orig_shape = self.meta['xyz_shape']
orig_spacing = self.meta['spacing']

Expand Down Expand Up @@ -418,8 +422,8 @@ def get_meta(key):
series_id = "empty"

label = "{:<20} {:>1}".format(f"{study_description}>{series_description}({series_modality})",
f"({size_x}x{size_y})x{count}")
f"({size_x}x{size_y})x{count}")

series_items[series_id] = label

for series_id, label in series_items.items():
Expand Down Expand Up @@ -500,10 +504,13 @@ class ImportVolumetricDataDialog(bpy.types.Operator):

label_count: bpy.props.IntProperty() # type: ignore

smooth: bpy.props.IntProperty(name="Smooth Size (Larger takes longer time)",
default=3) # type: ignore

read_as: bpy.props.EnumProperty(name="Read as",
default="SCALAR",
items=[("SCALAR", "Scalar", ""),
("LABEL", "Labels", ""),
("LABEL", "Label", ""),
("COLOR", "Color", "")]) # type: ignore

bioxel_size: bpy.props.FloatProperty(name="Bioxel Size (Larger size means small resolution)",
Expand Down Expand Up @@ -616,12 +623,15 @@ def progress_callback(frame, total):
progress_callback = progress_callback_factory(name_i,
progress,
progress_step)
label_data = data == np.full_like(data, i+1)
label_data = label_data.astype(np.float32)
try:
layer = Layer(data=data == np.full_like(data, i+1),
layer = Layer(data=label_data,
name=name_i,
kind=kind)

layer.resize(shape=shape,
smooth=self.smooth,
progress_callback=progress_callback)

layer.affine = affine
Expand Down Expand Up @@ -924,6 +934,8 @@ def draw(self, context):
if self.read_as == "SCALAR":
panel.prop(self, "split_channel",
text=f"Split Channel as Multi Layer")
elif self.read_as == "LABEL":
panel.prop(self, "smooth")

panel.label(
text="Dimension Order: [Frame, (X-axis,Y-axis,Z-axis), Channel]")
Expand Down
23 changes: 16 additions & 7 deletions bioxelnodes/operators/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import numpy as np



from ..exceptions import NoContent
from ..bioxel.layer import Layer
from ..bioxelutils.node import add_node_to_graph
Expand Down Expand Up @@ -199,14 +198,24 @@ def invoke(self, context, event):
return self.execute(context)


class RelocateLayer(bpy.types.Operator, LayerOperator):
class RelocateLayer(bpy.types.Operator):
bl_idname = "bioxelnodes.relocate_layer"
bl_label = "Relocate Layer Cache"
bl_description = "Relocate layer cache"
bl_icon = "FILE"

filepath: bpy.props.StringProperty(subtype="FILE_PATH") # type: ignore

def execute(self, context):
layer_obj = get_selected_layer(context)
if layer_obj == None:
self.report({"WARNING"}, "Get no layer.")
return {'FINISHED'}

self.operate(layer_obj, context)

return {'FINISHED'}

def operate(self, layer_obj, context):
layer_obj.data.filepath = self.filepath

Expand Down Expand Up @@ -259,7 +268,7 @@ class ResampleLayer(bpy.types.Operator, OutputLayerOperator):
bl_description = "Resample value"
bl_icon = "ALIASED"

smooth: bpy.props.IntProperty(name="Smooth Iteration",
smooth: bpy.props.IntProperty(name="Smooth Size",
default=0,
soft_min=0, soft_max=5,
options={"SKIP_SAVE"}) # type: ignore
Expand Down Expand Up @@ -389,7 +398,7 @@ def operate(self, orig_layer: Layer, context):
if self.invert else data > self.threshold

new_layer = orig_layer.copy()
new_layer.fill(self.fill_value, mask, 3)
new_layer.fill(self.fill_value, mask, 0)
new_layer.name = self.new_layer_name \
or f"{orig_layer.name}_F-{self.threshold:.2f}"
return new_layer
Expand Down Expand Up @@ -419,7 +428,7 @@ def operate(self, orig_layer: Layer, context):
(data > self.from_min) & (data < self.from_max)

new_layer = orig_layer.copy()
new_layer.fill(self.fill_value, mask, 3)
new_layer.fill(self.fill_value, mask, 0)
new_layer.name = self.new_layer_name \
or f"{orig_layer.name}_F-{self.from_min:.2f}-{self.from_max:.2f}"
return new_layer
Expand All @@ -431,7 +440,7 @@ class FillByLabel(bpy.types.Operator, FillOperator):
bl_description = "Fill value by label"
bl_icon = "MESH_CAPSULE"

smooth: bpy.props.IntProperty(name="Smooth Iteration",
smooth: bpy.props.IntProperty(name="Smooth Size",
default=0,
soft_min=0, soft_max=5,
options={"SKIP_SAVE"}) # type: ignore
Expand All @@ -451,7 +460,7 @@ def operate(self, orig_layer: Layer, context):
mask = 1 - mask

new_layer = orig_layer.copy()
new_layer.fill(self.fill_value, mask, 3)
new_layer.fill(self.fill_value, mask, 0)
new_layer.name = self.new_layer_name \
or f"{orig_layer.name}_F-{label_layer.name}"
return new_layer
Expand Down
6 changes: 3 additions & 3 deletions bioxelnodes/operators/node.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import bpy

from ..bioxelutils.common import is_incompatible, local_lib_not_updated
from ..bioxelutils.node import assign_node_group, get_node_group
from ..bioxelutils.node import assign_node_tree, get_node_tree
from ..utils import get_use_link


Expand Down Expand Up @@ -41,14 +41,14 @@ def execute(self, context):
"Current addon verison is not compatible to this file. If you insist on editing this file please keep the same addon version.")
return {'CANCELLED'}

get_node_group(self.node_type, get_use_link())
node_tree = get_node_tree(self.node_type, get_use_link())
bpy.ops.node.add_node(
'INVOKE_DEFAULT',
type='GeometryNodeGroup',
use_transform=True
)
node = bpy.context.active_node
assign_node_group(node, self.node_type)
assign_node_tree(node, node_tree)
node.label = self.node_label

node.show_options = False
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "bioxelnodes"
version = "1.0.1"
version = "1.0.2"
description = ""
authors = ["Ma Nan <[email protected]>"]
license = "MIT"
Expand Down

0 comments on commit 63c593f

Please sign in to comment.