def evaluate_graph(self, internalTime, order):
inputSocketsData = {}
for nodeName in order:
inputSocketsData[nodeName] = {}
for nodeName in order:
node = self.nodes.get(nodeName)
if node == None: # Safeguard, may be unnecessary
# Node has dissappeared since last reconstruct
# Reconstruct & retry
print("Unexpected change in structure; retrying")
self.reconstruct(order)
self.evaluate_graph(internalTime, order, outputNode)
return
outputSocketsData = node.callback(inputSocketsData[nodeName], internalTime, self.sample_rate, self.chunk_size/self.sample_rate)
for i in range(len(node.outputs)):
socket = node.outputs[i]
data = outputSocketsData[i]
for link in socket.links:
if link.to_node.name in inputSocketsData:
inputSocketsData[link.to_node.name][link.to_socket.identifier] = data
python类Node()的实例源码
def register():
global _object_node_categories
bpy.utils.register_module(__name__)
register_object_components()
node_categories = []
for name, items in _object_node_categories.items():
cat = ObjectNodeCategory(name.upper(), name, items=items)
node_categories.append(cat)
nodeitems_utils.register_node_categories("OBJECT_NODES", node_categories)
# create keymap
wm = bpy.context.window_manager
km = wm.keyconfigs.default.keymaps.new(name="Node Generic", space_type='NODE_EDITOR')
kmi = km.keymap_items.new(bpy.types.OBJECT_NODES_OT_node_edit.bl_idname, 'TAB', 'PRESS')
kmi.properties.exit = False
kmi = km.keymap_items.new(bpy.types.OBJECT_NODES_OT_node_edit.bl_idname, 'TAB', 'PRESS', ctrl=True)
kmi.properties.exit = True
keymaps.append(km)
def poll(cls, ntree):
return ntree.bl_idname == 'CustomTreeType'
# Derived from the Node base type.
def draw_buttons(self, context, layout):
layout.label("Node settings")
layout.prop(self, "myFloatProperty")
# Detail buttons in the sidebar.
# If this function is not defined, the draw_buttons function is used instead
def draw_label(self):
return "I am a custom node"
### Node Categories ###
# Node categories are a python system for automatically
# extending the Add menu, toolbar panels and search operator.
# For more examples see release/scripts/startup/nodeitems_builtins.py
def poll(cls, ntree):
b = False
if ntree.bl_idname == 'ShaderNodeTree':
b = True
return b
# Derived from the Node base type.
def draw_buttons(self, context, layout):
intensity_ui(self, context, layout, self.name)
global node_name
node_name = self.name
#Node Label
def draw_buttons(self, context, layout):
SpectrumPaletteUI(self, context, layout)
#Node Label
def poll(cls, ntree):
b = False
if ntree.bl_idname == 'ShaderNodeTree':
b = True
return b
# Derived from the Node base type
def draw_buttons(self, context, layout):
layout.label("Node settings")
layout.operator("audionodes.piano").caller_id = self.path_from_id()
def poll(cls, ntree):
b = False
if ntree.bl_idname == 'ShaderNodeTree':
b = True
return b
# Derived from the Node base type.
def draw_buttons(self, context, layout):
IntensityUI(self, context, layout, self.name)
global node_name
node_name = self.name
#Node Label
def draw_buttons(self, context, layout):
SpectrumPaletteUI(self, context, layout)
#Node Label
def poll(cls, ntree):
b = False
if ntree.bl_idname == 'ShaderNodeTree':
b = True
return b
# Derived from the Node base type
def draw(self, context):
layout = self.layout
layout.operator("update_data_node.btn", icon="FILE_REFRESH")
### Node Categories ###
def poll(self, context):
return True
# < !Select parent Cutaway Shader Node Button >
# < Jump To parent Cutaway Shader Node Button >
def poll(self, context):
return True
# < !Jump To parent Cutaway Shader Node Button >
# < Select all Objects using this Child Shader Button >
def poll(self, context):
return True
# < !Select all Objects using this Child Shader Button >
# < Unlink child Node from parent Node >
def clean_node_tree(self, node_tree):
nodes = node_tree.nodes
for node in nodes:
if not node.type == 'OUTPUT_MATERIAL':
nodes.remove(node)
return node_tree.nodes[0]
# < !Node layout helper functions >
def remove_child_node_from_parent(self):
self.carry_out_action_on_this_parents_child_nodes_b('CLEAN_CHILD_LIST')
# Called by button: When the user presses the Unlink child Node button
# We must be a child node if this routine is called
# Tell the parent node that we are no longer a child. Set ourselves to a parent node.
# This will allow the user access to all the full settings of the cutaway py node.
# We are a child node if this routine is being run.
def set_color_ramp(self):
"""Set the Colors from the Palette to a ColorRamp node"""
kaleidoscope_spectrum_props=bpy.context.scene.kaleidoscope_spectrum_props
ramp = None
ramp_world = None
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
try:
ramp_world = bpy.context.scene.world.node_tree.nodes[kaleidoscope_spectrum_props.colorramp_world_name].color_ramp
except:
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
self.report({'WARNING'}, "There is Not a Valid ColorRamp Node in the World Material")
except AttributeError:
pass
if kaleidoscope_spectrum_props.colorramp_world_name != "" and kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
for i in range(0, len(ramp_world.elements)):
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
exec("ramp_world.elements["+str(i)+"].color[0] = kaleidoscope_spectrum_props.color"+str(i+1)+"[0]")
exec("ramp_world.elements["+str(i)+"].color[1] = kaleidoscope_spectrum_props.color"+str(i+1)+"[1]")
exec("ramp_world.elements["+str(i)+"].color[2] = kaleidoscope_spectrum_props.color"+str(i+1)+"[2]")
ramp_world.elements[0].color[3] = 1.0
except:
pass
except:
pass
for mat in bpy.data.materials:
spectrum_active = mat.kaleidoscope_spectrum_props
if spectrum_active.assign_colorramp == True and spectrum_active.colorramp_name != "":
try:
if spectrum_active is not None:
ramp = mat.node_tree.nodes[spectrum_active.colorramp_name].color_ramp
except:
if spectrum_active.assign_colorramp == True:
try:
self.report({'WARNING'}, "There is Not a Valid ColorRamp Node in '"+mat.name+"'")
except AttributeError:
pass
if spectrum_active.colorramp_name != "" and spectrum_active.assign_colorramp == True:
try:
for i in range(0, len(ramp.elements)):
if spectrum_active.assign_colorramp == True:
exec("ramp.elements["+str(i)+"].color[0] = kaleidoscope_spectrum_props.color"+str(i+1)+"[0]")
exec("ramp.elements["+str(i)+"].color[1] = kaleidoscope_spectrum_props.color"+str(i+1)+"[1]")
exec("ramp.elements["+str(i)+"].color[2] = kaleidoscope_spectrum_props.color"+str(i+1)+"[2]")
ramp.elements[0].color[3] = 1.0
except:
pass
def set_color_ramp(self):
"""Set the Colors from the Palette to a ColorRamp node"""
kaleidoscope_spectrum_props=bpy.context.scene.kaleidoscope_spectrum_props
ramp = None
ramp_world = None
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
try:
ramp_world = bpy.context.scene.world.node_tree.nodes[kaleidoscope_spectrum_props.colorramp_world_name].color_ramp
except:
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
self.report({'WARNING'}, "There is Not a Valid ColorRamp Node in the World Material")
except AttributeError:
pass
if kaleidoscope_spectrum_props.colorramp_world_name != "" and kaleidoscope_spectrum_props.assign_colorramp_world == True:
try:
for i in range(0, len(ramp_world.elements)):
if kaleidoscope_spectrum_props.assign_colorramp_world == True:
exec("ramp_world.elements["+str(i)+"].color[0] = kaleidoscope_spectrum_props.color"+str(i+1)+"[0]")
exec("ramp_world.elements["+str(i)+"].color[1] = kaleidoscope_spectrum_props.color"+str(i+1)+"[1]")
exec("ramp_world.elements["+str(i)+"].color[2] = kaleidoscope_spectrum_props.color"+str(i+1)+"[2]")
ramp_world.elements[0].color[3] = 1.0
except:
pass
except:
pass
for mat in bpy.data.materials:
spectrum_active = mat.kaleidoscope_spectrum_props
if spectrum_active.assign_colorramp == True and spectrum_active.colorramp_name != "":
try:
if spectrum_active is not None:
ramp = mat.node_tree.nodes[spectrum_active.colorramp_name].color_ramp
except:
if spectrum_active.assign_colorramp == True:
try:
self.report({'WARNING'}, "There is Not a Valid ColorRamp Node in '"+mat.name+"'")
except AttributeError:
pass
if spectrum_active.colorramp_name != "" and spectrum_active.assign_colorramp == True:
try:
for i in range(0, len(ramp.elements)):
if spectrum_active.assign_colorramp == True:
exec("ramp.elements["+str(i)+"].color[0] = kaleidoscope_spectrum_props.color"+str(i+1)+"[0]")
exec("ramp.elements["+str(i)+"].color[1] = kaleidoscope_spectrum_props.color"+str(i+1)+"[1]")
exec("ramp.elements["+str(i)+"].color[2] = kaleidoscope_spectrum_props.color"+str(i+1)+"[2]")
ramp.elements[0].color[3] = 1.0
except:
pass
def make_attribute_nodes(attribute_set, attr_default, data_name, data_type):
def attribute_items(self, context):
return [(attr[0], attr[0], "", 'NONE', 2**i) for i, attr in enumerate(attribute_set)]
def update_attributes(self, context):
for socket in self.outputs:
socket.enabled = (socket.name in self.attributes)
@object_node_item('Mockups')
class get_node(ObjectNodeBase, Node):
__doc__ = "Get attribute from %s" % data_name
bl_idname = "Get%sAttributeNode" % data_name
bl_label = "Get %s Attribute" % data_name
attributes = EnumProperty(name="Attribute",
items=attribute_items,
update=update_attributes,
options={'ENUM_FLAG'})
def draw_buttons(self, context, layout):
layout.prop_menu_enum(self, "attributes")
def init(self, context):
self.inputs.new(data_type, data_name).is_readonly = True
for attr in attribute_set:
self.outputs.new(attr[1], attr[0])
# set default
self.attributes = { attr_default }
@object_node_item('Mockups')
class set_node(ObjectNodeBase, Node):
__doc__ = "Set attribute of %s" % data_name
bl_idname = "Set%sAttributeNode" % data_name
bl_label = "Set %s Attribute" % data_name
def update_attributes(self, context):
for socket in self.inputs[1:]:
socket.enabled = (socket.name in self.attributes)
attributes = EnumProperty(name="Attribute",
items=attribute_items,
update=update_attributes,
options={'ENUM_FLAG'})
def draw_buttons(self, context, layout):
layout.prop_menu_enum(self, "attributes")
def init(self, context):
self.inputs.new(data_type, data_name)
for attr in attribute_set:
self.inputs.new(attr[1], attr[0])
self.outputs.new(data_type, data_name)
# set default
self.attributes = { attr_default }
return get_node, set_node
def poll(self, context):
return True
# < !Warning Dialog: Delete all CutawayShaders -- can't be undone! >
# *************************************************************************************
# *************************************************************************************
#
# CutAwaySetupNode py_node class code
# This is the entry point for the code when the user selects "Shader Effects-> Cutaway Shader"
#
# *************************************************************************************
# *************************************************************************************
# ***************************** Define the Custom Node(s) *****************************
# We can create more than one new node if desired
#
# A custom node that allows the OSL cut away shader node to be easily set up
# Specifically, it:
# - Allows the cut away plane object to be selected from a drop down enumeration box,
# - Allows various shader mode selection options to be selected with check boxes
# - Connects all the required user inputs and outputs to the parent shader
# - Creates drivers to link the selected cutaway plane LOC,ROT,SCALE attributes to the OSL cut away shader
# - Creates the OSL shader node an pre-wires the node links for the user (these are really just for show - the drivers do the work)
# - Allows multiple slected objects in the scene to have the same cut away shader added to their existing materials
# (there is 1 parent shader and possibly many child shaders that follow the parent's node settings.)
# The general gist from here on is to:
# Define class props
# Do init:
# Define the node's input sockets.
# Define the node's output sockets.
# Get access to this nodes nodetree and nodetree.nodes functions/properties.
# Create the OSL cutaway Shader node.
# Link the outputs of this setup helper node to the inputes of the OSL cut away shader node.
# Set some user defaults on the OSL shader node.
# Group the this helper setup node and the OSL shader node together.
# Get access to the group node's nodetree and nodetree.nodes functions/properties.
# Create the group node's GROUP Input and Group Output nodes .
# Define the input and output socket types for the Group Input and OutPuts.
# Associate the input and output sockets to the input and ouput nodes.
# Make node links between the Group Input and Output Nodes and the setup helper + OSL shader node.
# Note: The links to this custom setup help node are for show only
# OSL node divers are set when a new cutaway plane is selected. Other OSL input values are written to directly by the py node code.
# The links to the OSL shader node are required and do work as normal.
def select_all_objects_using_this_unique_pynode_id(self, unique_pynode_id_str, jump_node_editor_to_active_material_bool):
# Get a list of the objects in the scene that use this pynode.
obj_list, matslot_list = self.get_all_objs_using_pynode(unique_pynode_id_str)
# No objects with using a material with the pynode of the given unique id was found.
# exit with a False (This is probably an orphaned child node)
if (len(obj_list) == 0):
return False
if (jump_node_editor_to_active_material_bool):
bpy.context.space_data.pin = False
# we need to be in object mode to do this work
# save the area type -- should be node editor since a pynode button was pressed.
# the cursor bpy ops only work from the 3d view context. So, switch to this.
bpy.ops.object.mode_set(mode='OBJECT')
original_areatype = bpy.context.area.type
bpy.context.area.type = "VIEW_3D"
if (jump_node_editor_to_active_material_bool):
saved_3d_layers_setting_list = self.save_3d_view_layer_settings(bpy.context.space_data.layers)
bpy.context.space_data.layers = [True] * 20
#bpy.ops.object.select_all(action='DESELECT')
# Select all objects in the scene that use this pynode.
# Enable layers the object is on if they are disabled
for obj in obj_list:
for i in range (len(bpy.context.scene.layers)):
if obj.layers[i] == True:
bpy.context.scene.layers[i] = True
break
obj.select = True
# make the node editor jump to the objects active material. (Used for child node button "Jump to Parent Node"
if(jump_node_editor_to_active_material_bool):
bpy.context.scene.objects.active = obj
self.restore_3d_view_layer_settings(bpy.context.space_data.layers, saved_3d_layers_setting_list)
# switch back to the users original context
bpy.context.area.type = original_areatype
# We found object(s) using a material with the pynode of the given unique id - so return true
return True
# The user has clicked the "Jump to Parent Node" button on a child pynode.
# Change the node view to show the parent pynode
# If this is called we are a child node