2
$\begingroup$

In Blender/Python 2.8, I can't get my code to create the surface node I want (it creates a shader node along with a surface node that I don't want). The objective is to assign an image texture to an object as seen in three related posts (1, 2 and 3):

The manual process produces the desired result by setting up the node as follows: Surface node Diffuse BSDF

In Python I am attempting to do the same (code below), but the results aren't working out. First I'll show the output, then the code:

Here's the objectionable output:

enter image description here

And here's the node tree as created by my code; when I make the manual adjustments I note in the picture I get the final result that I want:

enter image description here

My flawed code is below. Before you criticize the obvious problem (that I am creating shaders), I have tried other approaches (replacing "Shader" with "Surface" and various other words) without success. I am also baffled as to why the "Principled BSDF" node appears out of nowhere.

Here's my code. Your suggestions would be highly appreciated. Thanks in advance!

matP_name='CCmat' matP = bpy.data.materials.get(matP_name) if matP is None: matP = bpy.data.materials.new(matP_name) matP.use_nodes=True nodes = matP.node_tree.nodes nodeID='ShaderNodeBsdfDiffuse' diffuse_BSDF = matP.node_tree.nodes.new(nodeID) path=TextureFolder+TextureFilenamePost imgTex = bpy.data.images.load(path) node_texture = nodes.new(type='ShaderNodeTexImage') node_texture.image = imgTex node_texture.location = 0,200 links = matP.node_tree.links link = links.new(node_texture.outputs[0], nodes.get('Diffuse BSDF').inputs[0]) obj=bpy.data.objects['CubeCopy1'] obj.active_material=matP 
$\endgroup$
4
  • 2
    $\begingroup$ If I read correctly this code does not link the diffuse to the output. Also creating a new material will create principled and output by default. So you need to clear them. material.node_tree.links.clear() material.node_tree.nodes.clear() $\endgroup$ Commented Jul 29, 2019 at 16:02
  • $\begingroup$ @lemon Doesn't this create the link? link = links.new(node_texture.outputs[0], nodes.get('Diffuse BSDF').inputs[0]) $\endgroup$ Commented Jul 29, 2019 at 16:11
  • 1
    $\begingroup$ Yes but between texture and diffuse, not between diffuse and output $\endgroup$ Commented Jul 29, 2019 at 16:11
  • $\begingroup$ @lemon What python code would link diffuse and output? $\endgroup$ Commented Jul 29, 2019 at 16:13

1 Answer 1

8
$\begingroup$

Small code that can bring the indication you need.

import bpy # Clear all nodes in a mat def clear_material( material ): if material.node_tree: material.node_tree.links.clear() material.node_tree.nodes.clear() # Create a node corresponding to a defined group def instanciate_group( nodes, group_name ): group = nodes.new( type = 'ShaderNodeGroup' ) group.node_tree = bpy.data.node_groups[group_name] materials = bpy.data.materials mat_name = 'test' material = materials.get( mat_name ) if not material: material = materials.new( mat_name ) # We clear it as we'll define it completely clear_material( material ) material.use_nodes = True nodes = material.node_tree.nodes links = material.node_tree.links output = nodes.new( type = 'ShaderNodeOutputMaterial' ) diffuse = nodes.new( type = 'ShaderNodeBsdfDiffuse' ) #With names link = links.new( diffuse.outputs['BSDF'], output.inputs['Surface'] ) #Or with indices #link = links.new( diffuse.outputs[0], output.inputs[0] ) 

Note: when you create a new material (materials.new(...)), it creates two nodes by default (principled linked to ouput).

$\endgroup$
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.