diff options
Diffstat (limited to 'render_povray/nodes_gui.py')
-rw-r--r-- | render_povray/nodes_gui.py | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/render_povray/nodes_gui.py b/render_povray/nodes_gui.py new file mode 100644 index 00000000..64fcc130 --- /dev/null +++ b/render_povray/nodes_gui.py @@ -0,0 +1,278 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# <pep8 compliant> +""""Nodes based User interface for shaders exported to POV textures.""" +import bpy + +from bpy.utils import register_class, unregister_class +from bpy.types import Menu, Operator +from bpy.props import ( + StringProperty, +) + +# def find_node_input(node, name): +# for input in node.inputs: +# if input.name == name: +# return input + +# def panel_node_draw(layout, id_data, output_type, input_name): +# if not id_data.use_nodes: +# #layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') +# #layout.operator("pov.use_shading_nodes", icon='NODETREE') +# layout.operator("WM_OT_context_toggle", icon='NODETREE').data_path = \ +# "material.pov.material_use_nodes" +# return False + +# ntree = id_data.node_tree + +# node = find_node(id_data, output_type) +# if not node: +# layout.label(text="No output node") +# else: +# input = find_node_input(node, input_name) +# layout.template_node_view(ntree, node, input) + +# return True + + +class NODE_MT_POV_map_create(Menu): + """Create maps""" + + bl_idname = "POVRAY_MT_node_map_create" + bl_label = "Create map" + + def draw(self, context): + layout = self.layout + layout.operator("node.map_create") + + +def menu_func_nodes(self, context): + ob = context.object + if hasattr(ob, "active_material"): + mat = context.object.active_material + if mat and context.space_data.tree_type == "ObjectNodeTree": + self.layout.prop(mat.pov, "material_use_nodes") + self.layout.menu(NODE_MT_POV_map_create.bl_idname) + self.layout.operator("wm.updatepreviewkey") + if hasattr(mat, "active_texture") and context.scene.render.engine == "POVRAY_RENDER": + tex = mat.active_texture + if tex and context.space_data.tree_type == "TextureNodeTree": + self.layout.prop(tex.pov, "texture_use_nodes") + + +# ------------------------------------------------------------------------------ # +# --------------------------------- Operators ---------------------------------- # +# ------------------------------------------------------------------------------ # + + +class NODE_OT_iso_add(Operator): + bl_idname = "pov.nodeisoadd" + bl_label = "Create iso props" + + def execute(self, context): + ob = bpy.context.object + if not bpy.context.scene.use_nodes: + bpy.context.scene.use_nodes = True + tree = bpy.context.scene.node_tree + for node in tree.nodes: + if node.bl_idname == "IsoPropsNode" and node.label == ob.name: + tree.nodes.remove(node) + isonode = tree.nodes.new("IsoPropsNode") + isonode.location = (0, 0) + isonode.label = ob.name + return {"FINISHED"} + + +class NODE_OT_map_create(Operator): + bl_idname = "node.map_create" + bl_label = "Create map" + + def execute(self, context): + x = y = 0 + space = context.space_data + tree = space.edit_tree + for node in tree.nodes: + if node.select: + x, y = node.location + node.select = False + tmap = tree.nodes.new("ShaderTextureMapNode") + tmap.location = (x - 200, y) + return {"FINISHED"} + + def invoke(self, context, event): + wm = context.window_manager + return wm.invoke_props_dialog(self) + + def draw(self, context): + layout = self.layout + mat = context.object.active_material + layout.prop(mat.pov, "inputs_number") + + +class NODE_OT_povray_node_texture_map_add(Operator): + bl_idname = "pov.nodetexmapadd" + bl_label = "Texture map" + + def execute(self, context): + tree = bpy.context.object.active_material.node_tree + tmap = tree.nodes.active + mtl = context.object.active_material + mtl.node_tree.nodes.active = tmap + el = tmap.color_ramp.elements.new(0.5) + for el in tmap.color_ramp.elements: + el.color = (0, 0, 0, 1) + for inp in tmap.inputs: + tmap.inputs.remove(inp) + for outp in tmap.outputs: + tmap.outputs.remove(outp) + pattern = tmap.inputs.new("NodeSocketVector", "Pattern") + pattern.hide_value = True + for i in range(3): + tmap.inputs.new("NodeSocketColor", "Shader") + tmap.outputs.new("NodeSocketShader", "BSDF") + tmap.label = "Texture Map" + return {"FINISHED"} + + +class NODE_OT_povray_node_output_add(Operator): + bl_idname = "pov.nodeoutputadd" + bl_label = "Output" + + def execute(self, context): + tree = bpy.context.object.active_material.node_tree + tmap = tree.nodes.new("ShaderNodeOutputMaterial") + mtl = context.object.active_material + mtl.node_tree.nodes.active = tmap + for inp in tmap.inputs: + tmap.inputs.remove(inp) + tmap.inputs.new("NodeSocketShader", "Surface") + tmap.label = "Output" + return {"FINISHED"} + + +class NODE_OT_povray_node_layered_add(Operator): + bl_idname = "pov.nodelayeredadd" + bl_label = "Layered material" + + def execute(self, context): + tree = bpy.context.object.active_material.node_tree + tmap = tree.nodes.new("ShaderNodeAddShader") + mtl = context.object.active_material + mtl.node_tree.nodes.active = tmap + tmap.label = "Layered material" + return {"FINISHED"} + + +class NODE_OT_povray_input_add(Operator): + bl_idname = "pov.nodeinputadd" + bl_label = "Add entry" + + def execute(self, context): + mtl = context.object.active_material + node = mtl.node_tree.nodes.active + if node.type == "VALTORGB": + number = 1 + for inp in node.inputs: + if inp.type == "SHADER": + number += 1 + node.inputs.new("NodeSocketShader", "%s" % number) + els = node.color_ramp.elements + pos1 = els[len(els) - 1].position + pos2 = els[len(els) - 2].position + pos = (pos1 - pos2) / 2 + pos2 + el = els.new(pos) + + if node.bl_idname == "PovraySlopeNode": + number = len(node.inputs) + node.inputs.new("PovraySocketSlope", "%s" % number) + + return {"FINISHED"} + + +class NODE_OT_povray_input_remove(Operator): + bl_idname = "pov.nodeinputremove" + bl_label = "Remove input" + + def execute(self, context): + mtl = context.object.active_material + node = mtl.node_tree.nodes.active + if node.type in {"VALTORGB", "ADD_SHADER"}: + number = len(node.inputs) - 1 + if number > 5: + inp = node.inputs[number] + node.inputs.remove(inp) + if node.type == "VALTORGB": + els = node.color_ramp.elements + number = len(els) - 2 + el = els[number] + els.remove(el) + return {"FINISHED"} + + +class NODE_OT_povray_image_open(Operator): + bl_idname = "pov.imageopen" + bl_label = "Open" + + filepath: StringProperty( + name="File Path", description="Open image", maxlen=1024, subtype="FILE_PATH" + ) + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} + + def execute(self, context): + im = bpy.data.images.load(self.filepath) + mtl = context.object.active_material + node = mtl.node_tree.nodes.active + node.image = im.name + return {"FINISHED"} + + +# class TEXTURE_OT_povray_open_image(Operator): +# bl_idname = "pov.openimage" +# bl_label = "Open Image" + +# filepath = StringProperty( +# name="File Path", +# description="Open image", +# maxlen=1024, +# subtype='FILE_PATH', +# ) + +# def invoke(self, context, event): +# context.window_manager.fileselect_add(self) +# return {'RUNNING_MODAL'} + +# def execute(self, context): +# im=bpy.data.images.load(self.filepath) +# tex = context.texture +# tex.pov.image = im.name +# view_layer = context.view_layer +# view_layer.update() +# return {'FINISHED'} + + +classes = ( + NODE_MT_POV_map_create, + NODE_OT_iso_add, + NODE_OT_map_create, + NODE_OT_povray_node_texture_map_add, + NODE_OT_povray_node_output_add, + NODE_OT_povray_node_layered_add, + NODE_OT_povray_input_add, + NODE_OT_povray_input_remove, + NODE_OT_povray_image_open, +) + + +def register(): + bpy.types.NODE_HT_header.append(menu_func_nodes) + for cls in classes: + register_class(cls) + + +def unregister(): + for cls in reversed(classes): + unregister_class(cls) + bpy.types.NODE_HT_header.remove(menu_func_nodes) |