QUESTION: Editing Node Attributes, Emission Color Problem?

Another question about nodes and Python. I have this code and I’m trying to edit the attributes to change the color.

Here is the code thread:

56

bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeEmission')

57

bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs[0].default_value = (1, 0.17, 0.075, 1)

Why am I getting an error from the second (57th) line of code? I have typed everything out exactly as I read it, even triple checked every character.

Thank you to all who reply!

-Blake

can you show more from your script
might help

also do you have only one emission node or more then one?

here is example for another way of doing it

emission1 = m1.makeNode(‘ShaderNodeEmission’,‘Emission1’)
emission1.inputs[“Color”].default_value = [0.8,0.0,0.7,1.0] # Mauve
emission1.inputs[“Strength”].default_value =4.4
emission1.location =xl1,-100

let me see if i can find one like yours

are you using the

for cmat in mats:

print (’ cmat =’,cmat)

cmat.use_nodes=True
TreeNodes=cmat.node_tree
links = TreeNodes.links

method here ?

happy bl

Thanks for the reply Ricky,

Here is the portion of the shader script:

matName = “GlowRock_1”
bpy.data.materials.new(matName)
bpy.data.materials[matName].use_nodes = True
bpy.data.materials[matName].node_tree.nodes.new(type=‘ShaderNodeMixShader’)
bpy.data.materials[matName].node_tree.nodes.new(type=‘ShaderNodeEmission’)
bpy.data.node_groups[“Shader Nodetree”].nodes[“Emission”].inputs[0].default_value = (1, 0.17, 0.075, 1)
bpy.data.materials[matName].node_tree.nodes.new(type=‘ShaderNodeAddShader’)

in_1 = bpy.data.materials[matName].node_tree.nodes[“Material Output”].inputs[“Surface”]
out_1 = bpy.data.materials[matName].node_tree.nodes[“Mix Shader”].outputs[“Shader”]

in_2 = bpy.data.materials[matName].node_tree.nodes[“Mix Shader”].inputs[“Shader”]
out_2 = bpy.data.materials[matName].node_tree.nodes[“Emission”].outputs[“Emission”]

#in_3 = bpy.data.materials[matName].node_tree.nodes[“Material Output”].inputs[“Surface”]
#out_3 = bpy.data.materials[matName].node_tree.nodes[“Mix Shader”].outputs[“Shader”]

bpy.data.materials[matName].node_tree.links.new(in_1,out_1)
bpy.data.materials[matName].node_tree.links.new(in_2,out_2)
#bpy.data.materials[matName].node_tree.links.new(in_3,out_3)

bpy.data.objects[“Cube”].active_material = bpy.data.materials[matName]

bpy.context.scene.render.engine = ‘CYCLES’

I have the ‘#’ to separate the non-working/ disconnected parts.

There is only to be one Emission node.

Also I have on I am converting to fit mine from: http://blenderscripting.blogspot.com/2012/10/scripting-cycles-shaders-return-of-time.html

Here is what I’ve got, if you can help me with this instead:

import bpy
from mathutils import Vector

rock_mat = bpy.data.materials.new(“GlowRock_1”)
rock_mat.use_nodes = True

nodes = {
‘Texture Coordinate’: [‘TEX_COORD’, (115.0, 341.0)],
‘Emission’: [‘EMISSION’, (210.0, 193.0)],
‘Diffuse BSDF’: [‘BSDF_DIFFUSE’, (114.0, 245.0)],
‘Mix Shader’: [‘MIX_SHADER’, (319.0, 310.0)],
‘Material Output’: [‘OUTPUT_MATERIAL’, (436.0, 309.0)],
‘Image Texture’: [‘TEX_IMAGE’, (377.0, 299.0)],
‘Add Shader’: [‘ADD_SHADER’, (212.0, 255.0)],
‘Translucent BSDF’: [‘BSDF_TRANSLUCENT’, (113.0, 184.0)]
}

for k, v in nodes.items():
location = Vector(v[1])
if not k in rock_mat.node_tree.nodes:
cur_node = rock_mat.node_tree.nodes.new(v[0])
cur_node.location = location
else:
rock_mat.node_tree.nodes[k].location = location

from_node, from_socket, to_node, to_socket

unfortunately Mix Shader has two input nodes called ‘Shader’

this means you have to assign to input index instead.

link00 = [‘Diffuse BSDF’,‘BSDF’,‘Add Shader’,‘Shader’]
link01 = [‘Translucent BSDF’,‘BSDF’,‘Add Shader’,‘Shader’]
link02 = [‘Add Shader’,‘Shader’,‘Mix Shader’,‘Shader’]
link03 = [‘Emission’,‘Emission’,‘Mix Shader’,‘Shader’]
link04 = [‘Texture Coordinate’,‘UV’,‘Image Texture’,‘Vector’]
link05 = [‘Image Texture’,‘Color’,‘Mix Shader’,‘Fac’]
link06 = [‘Mix Shader’,‘Shader’,‘Material Output’,‘Surface’]

links = [link00, link01, link02, link03, link04, link05, link06]
node_target = 1
for link in links:
from_node = rock_mat.node_tree.nodes[link[0]]
output_socket = from_node.outputs[link[1]]
to_node = rock_mat.node_tree.nodes[link[2]]
if link[0] in [‘Emission’, ‘Diffuse BSDF’]:
input_socket = to_node.inputs[node_target]
node_target += 1
else:
input_socket = to_node.inputs[link[3]]
my_mat.node_tree.links.new(output_socket, input_socket)

nodes = my_mat.node_tree.nodes

node = nodes[‘Emission’]
node.inputs[‘Color’].default_value = (0.0, 1.0, 1.0, 1.0)
node.inputs[‘Strength’].default_value = 0.5

node = nodes[‘Diffuse BSDF’]
node.inputs[‘Color’].default_value = (1.0, 0.0, 0.0, 1.0)
node.inputs[‘Roughness’].default_value = 0.0

node = nodes[‘Noise Texture’]
node.inputs[‘Scale’].default_value = 5.0
node.inputs[‘Detail’].default_value = 2.0
node.inputs[‘Distortion’].default_value = 0.0

normaly for cycles nodes you should set cyclre render first i think!

let me see if i can find an exampel like yours

happy bl

I thought I had… I’ll change that.

EDIT: I did before, just forgot to remove the end after the copy-paste.

do you have a working version for this script on the site ?
seen there is a bug in the script

have you been able to make it work?

thanks

I don’t, I’ve only started working on it today. It’s just for automating a change in mesh shape and adding a material.

I was able to make it work until I attempted to add Cycles materials. I haven’t gotten it to work since.

Here is the full script:

# This script, when enabled and/or run, should create a random "Glowing Crystal/Rock" object with full, render ready materials.


bl_info = {
    "name": "Glowing Rock",
    "author": "Blake A Harris",
    "version": (0, 1),
    "blender": (2, 69, 0),
    "location": "View3D > Add > Mesh > New Object",
    "description": "Adds a new mesh object with material and texture",
    "warning": "BETA, WIP (Work In Progress)",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Add Mesh"}


    
import bpy
import random
from bpy.types import Operator
from bpy.props import FloatVectorProperty
from bpy_extras.object_utils import AddObjectHelper, object_data_add
from mathutils import Vector


bpy.ops.mesh.primitive_cube_add()


bpy.ops.object.editmode_toggle()


bpy.ops.transform.translate(value=(0, 0, 1))


bpy.ops.uv.reset()


bpy.ops.mesh.select_random()


bpy.context.scene.tool_settings.proportional_edit = 'ENABLED'
bpy.context.scene.tool_settings.proportional_edit_falloff = 'RANDOM'
bpy.ops.transform.resize(value=(random.uniform(0.01, 1.0), random.uniform(0.01, 1.0), random.uniform(0.01, 1.0)))
bpy.context.scene.tool_settings.proportional_edit_falloff = 'SMOOTH'
bpy.context.scene.tool_settings.proportional_edit = 'DISABLED'


bpy.ops.mesh.select_all(action='TOGGLE')
bpy.ops.mesh.select_all(action='TOGGLE')
bpy.ops.mesh.subdivide(number_cuts=3, smoothness=0)


bpy.ops.object.editmode_toggle()


bpy.ops.object.modifier_add(type='SUBSURF')
bpy.context.object.modifiers["Subsurf"].levels = 3
bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Subsurf")


bpy.ops.object.shade_smooth()
bpy.context.scene.render.engine = 'CYCLES'

###THIS IS WHERE IT STOPPED WORKING PROPERLY.###


matName = "GlowRock_1"
bpy.data.materials.new(matName)
bpy.data.materials[matName].use_nodes = True
bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeMixShader')
bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeEmission')
#bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs[0].default_value = (1, 0.169663, 0.0753487, 1)
bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeAddShader')


in_1 = bpy.data.materials[matName].node_tree.nodes["Material Output"].inputs["Surface"]
out_1 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].outputs["Shader"]


in_2 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].inputs["Shader"]
out_2 = bpy.data.materials[matName].node_tree.nodes["Emission"].outputs["Emission"]


#in_3 = bpy.data.materials[matName].node_tree.nodes["Material Output"].inputs["Surface"]
#out_3 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].outputs["Shader"]


bpy.data.materials[matName].node_tree.links.new(in_1,out_1)
bpy.data.materials[matName].node_tree.links.new(in_2,out_2)
#bpy.data.materials[matName].node_tree.links.new(in_3,out_3)


bpy.data.objects["Cube"].active_material = bpy.data.materials[matName]

Here is a visual of what I’m trying to accomplish:


not certain
never use this method
but this seems to work here



    
import bpy
    
bpy.context.scene.render.engine = 'CYCLES' 
    
    
    
bpy.ops.object.select_pattern(extend=False, pattern="Cube", case_sensitive=True)
obj_act = bpy.context.active_object
obj_act.name="smallboxe1"
    
    
#bpy.context.scene.objects.active = ob
    
    
#bpy.ops.object.editmode_toggle()
    
    
    
    
matName = "GlowRock_1"
bpy.data.materials.new(matName)
bpy.data.materials[matName].use_nodes = True

bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeMixShader')
aa1=bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeEmission')

aa1.inputs['Color'].default_value =(1, 0.17, 0.075, 1)

#bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs[0].default_value = (1, 0.17, 0.075, 1)
#bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs.default_value = (1, 0.17, 0.075, 1)
    
bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeAddShader')


in_1 = bpy.data.materials[matName].node_tree.nodes["Material Output"].inputs["Surface"]
out_1 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].outputs["Shader"]


in_2 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].inputs["Shader"]
out_2 = bpy.data.materials[matName].node_tree.nodes["Emission"].outputs["Emission"]


#in_3 = bpy.data.materials[matName].node_tree.nodes["Material Output"].inputs["Surface"]
#out_3 = bpy.data.materials[matName].node_tree.nodes["Mix Shader"].outputs["Shader"]


bpy.data.materials[matName].node_tree.links.new(in_1,out_1)
bpy.data.materials[matName].node_tree.links.new(in_2,out_2)



this is ad to the mat list not to the cycles mat
so don’t really need to be in cycles mode!

there are links missing
and nodes location are not good !

show us the final set up
would be a nice example fo other peoples too!

happy cycles

Thank you for all of your help!

Have you taken a look at the image above?

do you want to add it to an object too in cycles

not certain how to use this method?

but i have another way to do it

salut

try this script
this add a new mat to an object in cycles

addonemat1.blend (130 KB)

happy cycles

Basically, it’s supposed to create an object and create a material and assign it to the created object. I’ll try out the script, thank you!

Why am I getting an error from the second (57th) line of code?

You have made a lot of assumptions in that line of code. Let’s assume the tree exists and the node as well. You assume that default value is a color without checking it’s type. default_value can be many types of values. It can be a float, an int, a RGB color, A RGBA color etc.

Try a series of print(dir()) to discover what valid operations you can execute upon the node.


print(dir(bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs[0]))
print(type(bpy.data.node_groups["Shader Nodetree"].nodes["Emission"].inputs[0].default_value))

What is the exact error message you get?

I just checked bpy.data.node_groups and it has no elements unless a node group has been created explicitly by the user (via GUI or Script). There is no node group with the name ‘Shader Nodetree’ in version 2.69.

You can access the created node directly like this


node=bpy.data.materials[matName].node_tree.nodes.new(type='ShaderNodeEmission')
node.default_value=(1,0.17,0.075,1)

#BTW: you might consider abreviating your code by using local variables, i.e.
mat=bpy.data.materials[matName]
#do sth with nodes
nodes=mat.node_tree.nodes
nodes.new(...)
nodes.new(...)
nodes.new(...)
links=mat.node_tree.links
#do sth with links
links.new(...,...)
links.new(...,...)
links.new(...,...)