Files
Bioxel/bioxelnodes/menus.py
2024-08-14 14:16:40 +08:00

298 lines
11 KiB
Python

from pathlib import Path
import bpy
from .operators.utils import get_layer_item_label
from .bioxelutils.utils import (get_container_obj,
get_container_objs_from_selection,
get_container_layer_objs,
get_layer_prop_value)
from .operators.layer import (FetchLayerMenu, FetchLayer,
RemoveLayer, RemoveMissingLayers, RenameLayer, ResampleScalar, SaveLayerCache,
SignScalar, CombineLabels,
FillByLabel, FillByThreshold, FillByRange, get_selected_objs_in_node_tree)
from .operators.container import (SaveAllLayerCaches, SaveContainer, LoadContainer,
AddPieCutter, AddPlaneCutter,
AddCylinderCutter, AddCubeCutter, AddSphereCutter,
PickBboxWire, PickMesh, PickVolume)
from .operators.io import (ImportAsLabel, ImportAsScalar, ImportAsColor)
from .operators.misc import (CleanAllCaches,
ReLinkNodes, RenderSettingPreset, SaveStagedData)
class PickFromContainerMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_PICK"
bl_label = "Pick from Container"
def draw(self, context):
layout = self.layout
layout.operator(PickMesh.bl_idname)
layout.operator(PickVolume.bl_idname)
layout.operator(PickBboxWire.bl_idname)
class AddCutterMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_CUTTERS"
bl_label = "Add a Object Cutter"
def draw(self, context):
layout = self.layout
layout.operator(AddPlaneCutter.bl_idname, text="Plane Cutter")
layout.operator(AddCylinderCutter.bl_idname, text="Cylinder Cutter")
layout.operator(AddCubeCutter.bl_idname, text="Cube Cutter")
layout.operator(AddSphereCutter.bl_idname, text="Sphere Cutter")
layout.operator(AddPieCutter.bl_idname, text="Pie Cutter")
class ImportLayerMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_IMPORTLAYER"
bl_label = "Import Volumetric Data (Init)"
bl_icon = "FILE_NEW"
def draw(self, context):
layout = self.layout
layout.operator(ImportAsScalar.bl_idname,
text="as Scalar")
layout.operator(ImportAsLabel.bl_idname,
text="as Label")
layout.operator(ImportAsColor.bl_idname,
text="as Color")
class AddLayerMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_ADDLAYER"
bl_label = "Import Volumetric Data (Add to)"
bl_icon = "FILE_NEW"
def draw(self, context):
layout = self.layout
layout.operator(ImportAsScalar.bl_idname,
text="as Scalar")
layout.operator(ImportAsLabel.bl_idname,
text="as Label")
layout.operator(ImportAsColor.bl_idname,
text="as Color")
class ModifyLayerMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_MODIFYLAYER"
bl_label = "Modify Layer"
bl_icon = "FILE_NEW"
def draw(self, context):
layer_objs = get_selected_objs_in_node_tree(context)
if len(layer_objs) > 0:
active_obj_name = layer_objs[0].name
else:
active_obj_name = ""
layout = self.layout
op = layout.operator(ResampleScalar.bl_idname,
icon=ResampleScalar.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(SignScalar.bl_idname,
icon=SignScalar.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(FillByThreshold.bl_idname,
icon=FillByThreshold.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(FillByRange.bl_idname,
icon=FillByRange.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(FillByLabel.bl_idname,
icon=FillByLabel.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(CombineLabels.bl_idname,
icon=CombineLabels.bl_icon)
op.layer_obj_name = active_obj_name
class RenderSettingMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_RENDER"
bl_label = "Render Setting Presets"
def draw(self, context):
layout = self.layout
for k, v in RenderSettingPreset.PRESETS.items():
op = layout.operator(RenderSettingPreset.bl_idname,
text=v)
op.preset = k
class BioxelNodesTopbarMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_TOPBAR"
bl_label = "Bioxel Nodes"
def draw(self, context):
layout = self.layout
layout.menu(ImportLayerMenu.bl_idname,
icon=ImportLayerMenu.bl_icon)
layout.operator(LoadContainer.bl_idname)
layout.separator()
layout.operator(SaveStagedData.bl_idname)
layout.operator(ReLinkNodes.bl_idname)
layout.operator(CleanAllCaches.bl_idname)
layout.separator()
layout.menu(RenderSettingMenu.bl_idname)
def TOPBAR(self, context):
layout = self.layout
layout.menu(BioxelNodesTopbarMenu.bl_idname)
class BioxelNodesNodeMenu(bpy.types.Menu):
bl_idname = "BIOXELNODES_MT_NODE"
bl_label = "Bioxel Nodes"
bl_icon = "FILE_VOLUME"
def draw(self, context):
layer_objs = get_selected_objs_in_node_tree(context)
if len(layer_objs) > 0:
active_obj_name = layer_objs[0].name
else:
active_obj_name = ""
layout = self.layout
layout.menu(AddLayerMenu.bl_idname,
icon=AddLayerMenu.bl_icon)
layout.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.bl_icon)
layout.separator()
layout.operator(SaveContainer.bl_idname)
layout.menu(AddCutterMenu.bl_idname)
layout.menu(PickFromContainerMenu.bl_idname)
layout.operator(SaveAllLayerCaches.bl_idname,
icon=SaveAllLayerCaches.bl_icon)
layout.separator()
layout.menu(FetchLayerMenu.bl_idname)
op = layout.operator(SaveLayerCache.bl_idname,
icon=SaveLayerCache.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(RenameLayer.bl_idname,
icon=RenameLayer.bl_icon)
op.layer_obj_name = active_obj_name
op = layout.operator(RemoveLayer.bl_idname,
icon=RemoveLayer.bl_icon)
op.layer_obj_name = active_obj_name
layout.separator()
layout.menu(ModifyLayerMenu.bl_idname)
def NODE(self, context):
container_obj = context.object
is_geo_nodes = context.area.ui_type == "GeometryNodeTree"
is_container = get_container_obj(container_obj)
if not is_geo_nodes or not is_container:
return
layout = self.layout
layout.separator()
layout.menu(BioxelNodesNodeMenu.bl_idname)
def NODE_PT(self, context):
container_obj = context.object
is_geo_nodes = context.area.ui_type == "GeometryNodeTree"
is_container = get_container_obj(container_obj)
self.bl_label = "Group"
if not is_geo_nodes or not is_container:
return
if container_obj.modifiers[0].node_group != context.space_data.edit_tree:
return
self.bl_label = "Bioxel Nodes"
layer_list_UL = bpy.context.window_manager.bioxelnodes_layer_list_UL
layer_list = layer_list_UL.layer_list
layer_list_active = layer_list_UL.layer_list_active
layer_list.clear()
for layer_obj in get_container_layer_objs(container_obj):
layer_item = layer_list.add()
layer_item.label = get_layer_item_label(context, layer_obj)
layer_item.obj_name = layer_obj.name
layer_item.info_text = "\n".join([f"{prop}: {get_layer_prop_value(layer_obj, prop)}"
for prop in ["kind", "bioxel_size", "shape", "min", "max", ]])
if len(layer_list) > 0 and layer_list_active != -1 and layer_list_active < len(layer_list):
active_obj_name = layer_list[layer_list_active].obj_name
else:
active_obj_name = ""
layout = self.layout
layout.label(text="Layer List")
split = layout.row()
split.template_list(listtype_name="BIOXELNODES_UL_layer_list",
list_id="layer_list",
dataptr=layer_list_UL,
propname="layer_list",
active_dataptr=layer_list_UL,
active_propname="layer_list_active",
item_dyntip_propname="info_text",
rows=20)
sidebar = split.column(align=True)
sidebar.menu(AddLayerMenu.bl_idname,
icon=AddLayerMenu.bl_icon, text="")
sidebar.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.bl_icon, text="")
sidebar.separator()
op = sidebar.operator(FetchLayer.bl_idname,
icon=FetchLayer.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(SaveLayerCache.bl_idname,
icon=SaveLayerCache.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(RenameLayer.bl_idname,
icon=RenameLayer.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(RemoveLayer.bl_idname,
icon=RemoveLayer.bl_icon, text="")
op.layer_obj_name = active_obj_name
sidebar.separator()
op = sidebar.operator(ResampleScalar.bl_idname,
icon=ResampleScalar.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(SignScalar.bl_idname,
icon=SignScalar.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(FillByThreshold.bl_idname,
icon=FillByThreshold.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(FillByRange.bl_idname,
icon=FillByRange.bl_icon, text="")
op.layer_obj_name = active_obj_name
op = sidebar.operator(FillByLabel.bl_idname,
icon=FillByLabel.bl_icon, text="")
op.layer_obj_name = active_obj_name
sidebar.separator()
layout.separator()
def add():
bpy.types.NODE_PT_node_tree_properties.prepend(NODE_PT)
bpy.types.TOPBAR_MT_editor_menus.append(TOPBAR)
bpy.types.NODE_MT_editor_menus.append(NODE)
def remove():
bpy.types.NODE_PT_node_tree_properties.remove(NODE_PT)
bpy.types.TOPBAR_MT_editor_menus.remove(TOPBAR)
bpy.types.NODE_MT_editor_menus.remove(NODE)