armory/blender/arm/logicnode/arm_nodes.py

253 lines
9.3 KiB
Python
Raw Normal View History

2017-04-08 00:34:45 +02:00
import bpy.types
from bpy.props import *
2017-03-06 02:29:03 +01:00
from nodeitems_utils import NodeItem
2017-12-04 13:22:09 +01:00
import arm.utils
2017-03-06 02:29:03 +01:00
nodes = []
category_items = {}
2017-04-08 00:34:45 +02:00
object_sockets = dict()
array_nodes = dict()
2017-03-06 02:29:03 +01:00
class ArmLogicTreeNode:
@classmethod
def poll(cls, ntree):
return ntree.bl_idname == 'ArmLogicTreeType'
2017-04-08 20:05:35 +02:00
class ArmActionSocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketAction'
bl_label = 'Action Socket'
2017-04-08 00:34:45 +02:00
def draw(self, context, layout, node, text):
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2017-04-08 00:34:45 +02:00
def draw_color(self, context, node):
return (0.8, 0.3, 0.3, 1)
2018-06-12 23:16:28 +02:00
class ArmArraySocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketArray'
bl_label = 'Array Socket'
def draw(self, context, layout, node, text):
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2018-06-12 23:16:28 +02:00
def draw_color(self, context, node):
return (0.8, 0.4, 0.0, 1)
2018-06-12 23:16:28 +02:00
2017-04-08 00:34:45 +02:00
class ArmObjectSocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketObject'
bl_label = 'Object Socket'
default_value_get: PointerProperty(name='Object', type=bpy.types.Object)
2017-04-08 00:34:45 +02:00
2017-12-04 13:22:09 +01:00
def get_default_value(self):
if self.default_value_get == None:
2017-12-04 13:22:09 +01:00
return ''
if self.default_value_get.name not in bpy.data.objects:
return self.default_value_get.name
return arm.utils.asset_name(bpy.data.objects[self.default_value_get.name])
2017-12-04 13:22:09 +01:00
2017-04-08 00:34:45 +02:00
def __init__(self):
global object_sockets
# Buckle up..
# Match id strings to socket dict to retrieve socket in eyedropper operator
object_sockets[str(id(self))] = self
def draw(self, context, layout, node, text):
if self.is_output:
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2017-04-16 14:46:35 +02:00
elif self.is_linked:
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2017-04-08 00:34:45 +02:00
else:
2017-04-16 14:46:35 +02:00
row = layout.row(align=True)
row.prop_search(self, 'default_value_get', bpy.context.scene, 'objects', icon='NONE', text=self.name)
2017-04-08 00:34:45 +02:00
op = row.operator('arm.node_eyedrop', text='', icon='EYEDROPPER', emboss=True)
op.socket_index = str(id(self))
def draw_color(self, context, node):
return (0.15, 0.55, 0.75, 1)
class ArmNodeEyedropButton(bpy.types.Operator):
'''Pick selected object'''
bl_idname = 'arm.node_eyedrop'
bl_label = 'Eyedrop'
2018-12-18 23:48:38 +01:00
socket_index: StringProperty(name='Socket Index', default='')
2017-04-08 00:34:45 +02:00
def execute(self, context):
global object_sockets
obj = bpy.context.active_object
if obj != None:
object_sockets[self.socket_index].default_value_get = obj
2017-04-08 00:34:45 +02:00
return{'FINISHED'}
2017-09-08 13:57:34 +02:00
class ArmAnimActionSocket(bpy.types.NodeSocket):
bl_idname = 'ArmNodeSocketAnimAction'
bl_label = 'Action Socket'
default_value_get: PointerProperty(name='Action', type=bpy.types.Action)
2017-09-08 13:57:34 +02:00
2017-12-04 13:22:09 +01:00
def get_default_value(self):
if self.default_value_get == None:
2017-12-06 12:36:39 +01:00
return ''
if self.default_value_get.name not in bpy.data.actions:
return self.default_value_get.name
name = arm.utils.asset_name(bpy.data.actions[self.default_value_get.name])
2017-12-04 13:22:09 +01:00
return arm.utils.safestr(name)
2017-09-08 13:57:34 +02:00
def draw(self, context, layout, node, text):
if self.is_output:
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2017-09-08 13:57:34 +02:00
elif self.is_linked:
2018-09-05 10:20:02 +02:00
layout.label(text=self.name)
2017-09-08 13:57:34 +02:00
else:
layout.prop_search(self, 'default_value_get', bpy.data, 'actions', icon='NONE', text='')
2017-09-08 13:57:34 +02:00
def draw_color(self, context, node):
return (0.8, 0.8, 0.8, 1)
2017-04-08 00:34:45 +02:00
class ArmNodeAddInputButton(bpy.types.Operator):
'''Add new input'''
bl_idname = 'arm.node_add_input'
bl_label = 'Add Input'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
name_format: StringProperty(name='Name Format', default='Input {0}')
index_name_offset: IntProperty(name='Index Name Offset', default=0)
2017-04-08 00:34:45 +02:00
def execute(self, context):
global array_nodes
2017-04-11 11:28:22 +02:00
inps = array_nodes[self.node_index].inputs
inps.new(self.socket_type, self.name_format.format(str(len(inps) + self.index_name_offset)))
2017-04-08 00:34:45 +02:00
return{'FINISHED'}
2018-06-12 23:48:01 +02:00
class ArmNodeAddInputValueButton(bpy.types.Operator):
'''Add new input'''
bl_idname = 'arm.node_add_input_value'
bl_label = 'Add Input'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
2018-06-12 23:48:01 +02:00
def execute(self, context):
global array_nodes
inps = array_nodes[self.node_index].inputs
inps.new(self.socket_type, 'Value')
return{'FINISHED'}
2017-04-08 00:34:45 +02:00
class ArmNodeRemoveInputButton(bpy.types.Operator):
'''Remove last input'''
bl_idname = 'arm.node_remove_input'
bl_label = 'Remove Input'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
2017-04-08 00:34:45 +02:00
def execute(self, context):
global array_nodes
node = array_nodes[self.node_index]
inps = node.inputs
min_inps = 0 if not hasattr(node, 'min_inputs') else node.min_inputs
if len(inps) > min_inps:
2017-04-08 00:34:45 +02:00
inps.remove(inps.values()[-1])
return{'FINISHED'}
2018-06-12 23:48:01 +02:00
class ArmNodeRemoveInputValueButton(bpy.types.Operator):
'''Remove last input'''
bl_idname = 'arm.node_remove_input_value'
bl_label = 'Remove Input'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
2018-06-12 23:48:01 +02:00
def execute(self, context):
global array_nodes
node = array_nodes[self.node_index]
inps = node.inputs
min_inps = 0 if not hasattr(node, 'min_inputs') else node.min_inputs
if len(inps) > min_inps and inps[-1].name == 'Value':
inps.remove(inps.values()[-1])
return{'FINISHED'}
2017-04-11 11:28:22 +02:00
class ArmNodeAddOutputButton(bpy.types.Operator):
'''Add new output'''
bl_idname = 'arm.node_add_output'
bl_label = 'Add Output'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
socket_type: StringProperty(name='Socket Type', default='NodeSocketShader')
name_format: StringProperty(name='Name Format', default='Output {0}')
index_name_offset: IntProperty(name='Index Name Offset', default=0)
2017-04-11 11:28:22 +02:00
def execute(self, context):
global array_nodes
outs = array_nodes[self.node_index].outputs
outs.new(self.socket_type, self.name_format.format(str(len(outs) + self.index_name_offset)))
2017-04-11 11:28:22 +02:00
return{'FINISHED'}
class ArmNodeRemoveOutputButton(bpy.types.Operator):
'''Remove last output'''
bl_idname = 'arm.node_remove_output'
bl_label = 'Remove Output'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
2017-04-11 11:28:22 +02:00
def execute(self, context):
global array_nodes
2018-08-12 08:42:39 +02:00
node = array_nodes[self.node_index]
outs = node.outputs
min_outs = 0 if not hasattr(node, 'min_outputs') else node.min_outputs
if len(outs) > min_outs:
outs.remove(outs.values()[-1])
return{'FINISHED'}
class ArmNodeAddInputOutputButton(bpy.types.Operator):
'''Add new input and output'''
bl_idname = 'arm.node_add_input_output'
bl_label = 'Add Input Output'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
in_socket_type: StringProperty(name='In Socket Type', default='NodeSocketShader')
out_socket_type: StringProperty(name='Out Socket Type', default='NodeSocketShader')
in_name_format: StringProperty(name='In Name Format', default='Input {0}')
out_name_format: StringProperty(name='Out Name Format', default='Output {0}')
in_index_name_offset: IntProperty(name='Index Name Offset', default=0)
2018-08-12 08:42:39 +02:00
def execute(self, context):
global array_nodes
node = array_nodes[self.node_index]
inps = node.inputs
outs = node.outputs
inps.new(self.in_socket_type, self.in_name_format.format(str(len(inps) + self.in_index_name_offset)))
outs.new(self.out_socket_type, self.out_name_format.format(str(len(outs))))
return{'FINISHED'}
class ArmNodeRemoveInputOutputButton(bpy.types.Operator):
'''Remove last input and output'''
bl_idname = 'arm.node_remove_input_output'
bl_label = 'Remove Input Output'
2018-12-18 23:48:38 +01:00
node_index: StringProperty(name='Node Index', default='')
2018-08-12 08:42:39 +02:00
def execute(self, context):
global array_nodes
node = array_nodes[self.node_index]
inps = node.inputs
outs = node.outputs
min_inps = 0 if not hasattr(node, 'min_inputs') else node.min_inputs
min_outs = 0 if not hasattr(node, 'min_outputs') else node.min_outputs
if len(inps) > min_inps:
inps.remove(inps.values()[-1])
if len(outs) > min_outs:
2017-04-11 11:28:22 +02:00
outs.remove(outs.values()[-1])
return{'FINISHED'}
2017-03-06 02:29:03 +01:00
def add_node(node_class, category):
2017-04-08 00:34:45 +02:00
global nodes
nodes.append(node_class)
if category_items.get(category) == None:
category_items[category] = []
2017-04-08 00:34:45 +02:00
category_items[category].append(NodeItem(node_class.bl_idname))
2017-04-08 20:05:35 +02:00
bpy.utils.register_class(ArmActionSocket)
2018-06-12 23:16:28 +02:00
bpy.utils.register_class(ArmArraySocket)
2017-04-08 00:34:45 +02:00
bpy.utils.register_class(ArmObjectSocket)
bpy.utils.register_class(ArmNodeEyedropButton)
2017-09-08 13:57:34 +02:00
bpy.utils.register_class(ArmAnimActionSocket)
2017-04-08 00:34:45 +02:00
bpy.utils.register_class(ArmNodeAddInputButton)
2018-06-12 23:48:01 +02:00
bpy.utils.register_class(ArmNodeAddInputValueButton)
2017-04-08 00:34:45 +02:00
bpy.utils.register_class(ArmNodeRemoveInputButton)
2018-06-12 23:48:01 +02:00
bpy.utils.register_class(ArmNodeRemoveInputValueButton)
2017-04-11 11:28:22 +02:00
bpy.utils.register_class(ArmNodeAddOutputButton)
bpy.utils.register_class(ArmNodeRemoveOutputButton)
2018-08-12 08:42:39 +02:00
bpy.utils.register_class(ArmNodeAddInputOutputButton)
bpy.utils.register_class(ArmNodeRemoveInputOutputButton)