Merge pull request #16 from OmooLab/feature/dev
fix: label join scalar cannot get scalar offset
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -163,16 +163,18 @@ class CustomNodes():
|
||||
|
||||
def add_node(self, node_tree, node_type: str):
|
||||
item = self.find_item(node_type)
|
||||
op = AddCustomNode()
|
||||
op.nodes_file = self.nodes_file
|
||||
op.node_type = node_type
|
||||
if item:
|
||||
op = AddCustomNode()
|
||||
op.nodes_file = self.nodes_file
|
||||
op.node_type = item['node_type']
|
||||
op.node_label = item.get('label') or ""
|
||||
op.node_link = item.get('link') or True
|
||||
op.node_callback = item.get('node_callback') or ""
|
||||
return op.add_node(node_tree)
|
||||
else:
|
||||
raise RuntimeError("Not found in menu.")
|
||||
op.node_label = ""
|
||||
op.node_link = True
|
||||
op.node_callback = ""
|
||||
return op.add_node(node_tree)
|
||||
|
||||
def register(self):
|
||||
for cls in self.menu_classes:
|
||||
|
||||
@@ -236,14 +236,14 @@ class ImportVolumeDataDialog(bpy.types.Operator):
|
||||
|
||||
if self.read_as == "labels":
|
||||
if "vector" in image.GetPixelIDTypeAsString():
|
||||
print("Convet to Grayscale...")
|
||||
print("Conveting to Grayscale...")
|
||||
image = x2gray(image)
|
||||
else:
|
||||
image = sitk.Cast(image, sitk.sitkUInt16)
|
||||
default_value = 0
|
||||
elif self.read_as == "scalar":
|
||||
if "vector" in image.GetPixelIDTypeAsString():
|
||||
print("Convet to Grayscale...")
|
||||
print("Conveting to Grayscale...")
|
||||
image = rgb2gray(image)
|
||||
else:
|
||||
image = sitk.Cast(image, sitk.sitkFloat32)
|
||||
@@ -258,6 +258,9 @@ class ImportVolumeDataDialog(bpy.types.Operator):
|
||||
interpolator = sitk.sitkNearestNeighbor
|
||||
elif self.resample_method == "gaussian":
|
||||
interpolator = sitk.sitkGaussian
|
||||
|
||||
if self.read_as == "labels":
|
||||
interpolator = sitk.sitkNearestNeighbor
|
||||
|
||||
print(f"Resampling...")
|
||||
image = sitk.Resample(
|
||||
@@ -448,16 +451,15 @@ class ImportVolumeDataDialog(bpy.types.Operator):
|
||||
input_node = get_node_by_type(nodes, 'NodeGroupInput')[0]
|
||||
output_node = get_node_by_type(nodes, 'NodeGroupOutput')[0]
|
||||
|
||||
node_type = 'BioxelNodes_AsLabel' if layer_type == "label" else 'BioxelNodes_AsScalar'
|
||||
source_node = custom_nodes.add_node(nodes, node_type)
|
||||
to_layer_node = custom_nodes.add_node(nodes, "BioxelNodes__ConvertToLayer")
|
||||
|
||||
links.new(input_node.outputs[0], source_node.inputs[0])
|
||||
links.new(source_node.outputs[0], output_node.inputs[0])
|
||||
links.new(input_node.outputs[0], to_layer_node.inputs[0])
|
||||
links.new(to_layer_node.outputs[0], output_node.inputs[0])
|
||||
|
||||
source_node.inputs['Bioxel Size'].default_value = bioxel_size
|
||||
source_node.inputs['Shape'].default_value = layer_shape
|
||||
source_node.inputs['Origin'].default_value = layer_origin
|
||||
source_node.inputs['Rotation'].default_value = layer_rotation
|
||||
to_layer_node.inputs['Bioxel Size'].default_value = bioxel_size
|
||||
to_layer_node.inputs['Shape'].default_value = layer_shape
|
||||
to_layer_node.inputs['Origin'].default_value = layer_origin
|
||||
to_layer_node.inputs['Rotation'].default_value = layer_rotation
|
||||
|
||||
return layer
|
||||
|
||||
@@ -511,10 +513,10 @@ class ImportVolumeDataDialog(bpy.types.Operator):
|
||||
layer_type="scalar")
|
||||
|
||||
layer_node_tree = layer.modifiers[0].node_group
|
||||
source_node = layer_node_tree.nodes['BioxelNodes_AsScalar']
|
||||
source_node.inputs['Offset'].default_value = scalar_offset
|
||||
source_node.inputs['Max'].default_value = orig_max
|
||||
source_node.inputs['Min'].default_value = orig_min
|
||||
to_layer_node = layer_node_tree.nodes['BioxelNodes__ConvertToLayer']
|
||||
to_layer_node.inputs['Scalar Offset'].default_value = scalar_offset
|
||||
to_layer_node.inputs['Scalar Max'].default_value = orig_max
|
||||
to_layer_node.inputs['Scalar Min'].default_value = orig_min
|
||||
|
||||
output_node = get_node_by_type(container_node_tree.nodes,
|
||||
'NodeGroupOutput')[0]
|
||||
|
||||
@@ -166,29 +166,6 @@ if bpy.app.version >= (4, 1, 0):
|
||||
'icon': 'CONSTRAINT_BONE',
|
||||
'node_type': 'BioxelNodes_JoinComponent',
|
||||
'node_description': ''
|
||||
},
|
||||
{
|
||||
'label': 'Separate Component',
|
||||
'node_type': 'BioxelNodes_SeparateComponent',
|
||||
'node_description': ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'label': 'Others',
|
||||
'icon': 'PACKAGE',
|
||||
'items': [
|
||||
{
|
||||
'label': 'Source As Label',
|
||||
'icon': 'GP_SELECT_POINTS',
|
||||
'node_type': 'BioxelNodes_AsLabel',
|
||||
'node_description': ''
|
||||
},
|
||||
{
|
||||
'label': 'Source As Scalar',
|
||||
'icon': 'GP_SELECT_STROKES',
|
||||
'node_type': 'BioxelNodes_AsScalar',
|
||||
'node_description': ''
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -286,9 +263,9 @@ else:
|
||||
'icon': 'MOD_BEVEL',
|
||||
'items': [
|
||||
{
|
||||
'label': 'Apply Cutters',
|
||||
'label': 'Cut',
|
||||
'icon': 'MOD_BEVEL',
|
||||
'node_type': 'BioxelNodes_ApplyCutters',
|
||||
'node_type': 'BioxelNodes_Cut',
|
||||
'node_description': ''
|
||||
},
|
||||
"separator",
|
||||
@@ -315,29 +292,6 @@ else:
|
||||
'icon': 'CONSTRAINT_BONE',
|
||||
'node_type': 'BioxelNodes_JoinComponent',
|
||||
'node_description': ''
|
||||
},
|
||||
{
|
||||
'label': 'Separate Component',
|
||||
'node_type': 'BioxelNodes_SeparateComponent',
|
||||
'node_description': ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'label': 'Others',
|
||||
'icon': 'PACKAGE',
|
||||
'items': [
|
||||
{
|
||||
'label': 'Source As Label',
|
||||
'icon': 'GP_SELECT_POINTS',
|
||||
'node_type': 'BioxelNodes_AsLabel',
|
||||
'node_description': ''
|
||||
},
|
||||
{
|
||||
'label': 'Source As Scalar',
|
||||
'icon': 'GP_SELECT_STROKES',
|
||||
'node_type': 'BioxelNodes_AsScalar',
|
||||
'node_description': ''
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -79,13 +79,14 @@ class JoinLayers(bpy.types.Operator):
|
||||
|
||||
layers = []
|
||||
if self.scalar_layer != "None":
|
||||
layers.append(bpy.data.objects[self.scalar_layer])
|
||||
scalar_layer = bpy.data.objects[self.scalar_layer]
|
||||
layers.append(scalar_layer)
|
||||
|
||||
if self.label_layer != "None":
|
||||
layers.append(bpy.data.objects[self.label_layer])
|
||||
label_layer = bpy.data.objects[self.label_layer]
|
||||
layers.append(label_layer)
|
||||
|
||||
# if self.color_layer:
|
||||
# layers.append(bpy.data.objects[self.color_layer])
|
||||
# TODO: add color and vector
|
||||
|
||||
if len(layers) == 0:
|
||||
self.report({"WARNING"}, "No additinal layers setted.")
|
||||
@@ -106,8 +107,45 @@ class JoinLayers(bpy.types.Operator):
|
||||
filepath=str(vdb_path), align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
|
||||
|
||||
joined_layer = bpy.context.active_object
|
||||
bpy.ops.object.modifier_add(type='NODES')
|
||||
joined_layer.modifiers[0].node_group = base_layer.modifiers[0].node_group
|
||||
|
||||
base_layer_node = base_layer.modifiers[0].node_group.nodes['BioxelNodes__ConvertToLayer']
|
||||
bioxel_size = base_layer_node.inputs['Bioxel Size'].default_value
|
||||
layer_shape = base_layer_node.inputs['Shape'].default_value
|
||||
layer_origin = base_layer_node.inputs['Origin'].default_value
|
||||
layer_rotation = base_layer_node.inputs['Rotation'].default_value
|
||||
scalar_offset = base_layer_node.inputs['Scalar Offset'].default_value
|
||||
scalar_min = base_layer_node.inputs['Scalar Min'].default_value
|
||||
scalar_max = base_layer_node.inputs['Scalar Max'].default_value
|
||||
|
||||
if self.scalar_layer != "None":
|
||||
scalar_layer_node = scalar_layer.modifiers[0].node_group.nodes['BioxelNodes__ConvertToLayer']
|
||||
scalar_offset = scalar_layer_node.inputs['Scalar Offset'].default_value
|
||||
scalar_min = scalar_layer_node.inputs['Scalar Min'].default_value
|
||||
scalar_max = scalar_layer_node.inputs['Scalar Max'].default_value
|
||||
|
||||
bpy.ops.node.new_geometry_nodes_modifier()
|
||||
node_tree = joined_layer.modifiers[0].node_group
|
||||
nodes = node_tree.nodes
|
||||
links = node_tree.links
|
||||
|
||||
input_node = get_node_by_type(nodes, 'NodeGroupInput')[0]
|
||||
output_node = get_node_by_type(nodes, 'NodeGroupOutput')[0]
|
||||
|
||||
|
||||
joined_layer_node = custom_nodes.add_node(
|
||||
nodes, "BioxelNodes__ConvertToLayer")
|
||||
|
||||
|
||||
links.new(input_node.outputs[0], joined_layer_node.inputs[0])
|
||||
links.new(joined_layer_node.outputs[0], output_node.inputs[0])
|
||||
|
||||
joined_layer_node.inputs['Bioxel Size'].default_value = bioxel_size
|
||||
joined_layer_node.inputs['Shape'].default_value = layer_shape
|
||||
joined_layer_node.inputs['Origin'].default_value = layer_origin
|
||||
joined_layer_node.inputs['Rotation'].default_value = layer_rotation
|
||||
joined_layer_node.inputs['Scalar Offset'].default_value = scalar_offset
|
||||
joined_layer_node.inputs['Scalar Min'].default_value = scalar_min
|
||||
joined_layer_node.inputs['Scalar Max'].default_value = scalar_max
|
||||
|
||||
# Set props to VDB object
|
||||
joined_layer.name = f"{base_layer.name}_Joined"
|
||||
@@ -169,7 +207,7 @@ class ConvertToMesh(bpy.types.Operator):
|
||||
object_node = nodes.new("GeometryNodeObjectInfo")
|
||||
realize_nodes = nodes.new("GeometryNodeRealizeInstances")
|
||||
separate_node = custom_nodes.add_node(
|
||||
nodes, "BioxelNodes_SeparateComponent")
|
||||
nodes, "BioxelNodes__SeparateComponent")
|
||||
|
||||
object_node.inputs[0].default_value = container
|
||||
separate_node.inputs[1].default_value = 1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Bioxel Design Concept
|
||||
|
||||
According to Bioxel design concept, Bioxel Nodes imports volume data and put it into a **Container** as a **Layer**. One container may has more than one layer, and each layer stores the information of different fields under the same location, which is similar to the view layer of map app, except that here it is in 3D space. In order to render the volume the way we want it to, we need to build a renderable object from layers. We call this object **Component**. The following diagram shows the relationship of **Container**, **Layer**, and **Component**:
|
||||
According to Bioxel design concept, Bioxel Nodes imports volume data and put it into a **Container** as a **Layer**. One container may has more than one layer, and each layer stores the information of different fields under the same location, which is similar to the view layers in map app, except that here it is in 3D space. In order to render the volume the way we want it to, we need to build renderable objects from layers. We call those objects **Component**. The following diagram shows the relationship of **Container**, **Layer**, and **Component**:
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -251,41 +251,6 @@ This type of node is responsible for cutting components to present cross-section
|
||||
|
||||
</div>
|
||||
|
||||
## Utils
|
||||
|
||||
### 📦 Join Component
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- 
|
||||
|
||||
- Components' combination should not be done by "Join Geometry" node because Blender Cycles can't render volumes in the same position, so the node will slightly offset all components randomly to avoid this problem.
|
||||
|
||||
***
|
||||
|
||||
Node Parameter:
|
||||
|
||||
- **Component 0~4**, _the components_
|
||||
|
||||
</div>
|
||||
|
||||
### 🗂️ Separate Component
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- 
|
||||
|
||||
- Volumes, previews, and guides are included within a component. This node can split them by type.
|
||||
|
||||
***
|
||||
|
||||
Node Parameter:
|
||||
|
||||
- **Component**, _the upstream component_
|
||||
- **Type**, _the sub-object type, 0 is volume, 1 is preview, 2 is guide_
|
||||
|
||||
</div>
|
||||
|
||||
## Colors
|
||||
|
||||
This type of node is responsible for setting the color properties of the shader
|
||||
@@ -406,3 +371,21 @@ This type of node is responsible for setting the color properties of the shader
|
||||
- **Contrast**, _the larger the contrast, the harder color ramp will be_
|
||||
|
||||
</div>
|
||||
|
||||
## Utils
|
||||
|
||||
### 📦 Join Component
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- 
|
||||
|
||||
- Components' combination should not be done by "Join Geometry" node because Blender Cycles can't render volumes in the same position, so the node will slightly offset all components randomly to avoid this problem.
|
||||
|
||||
***
|
||||
|
||||
Node Parameter:
|
||||
|
||||
- **Component 0~4**, _the components_
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user