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

308 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, ScaleContainer)
from .operators.io import (ImportAsLabel, ImportAsScalar, ImportAsColor)
from .operators.misc import (CleanAllCaches,
ReLinkNodes, RenderSettingPreset, SaveStagedData, SliceViewer)
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.separator()
layout.menu(AddLayerMenu.bl_idname,
icon=AddLayerMenu.bl_icon)
layout.separator()
layout.operator(SaveContainer.bl_idname)
layout.separator()
layout.operator(ScaleContainer.bl_idname)
layout.menu(AddCutterMenu.bl_idname)
layout.menu(PickFromContainerMenu.bl_idname)
layout.operator(SaveAllLayerCaches.bl_idname,
icon=SaveAllLayerCaches.bl_icon)
layout.operator(RemoveMissingLayers.bl_idname,
icon=RemoveMissingLayers.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(SaveAllLayerCaches.bl_idname,
icon=SaveAllLayerCaches.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 VIEW3D_TOPBAR(self, context):
layout = self.layout
layout.operator(SliceViewer.bl_idname,
icon=SliceViewer.bl_icon, text="")
def add():
bpy.types.VIEW3D_HT_header.append(VIEW3D_TOPBAR)
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.VIEW3D_HT_header.remove(VIEW3D_TOPBAR)
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)