0
$\begingroup$

I have lots of objects consisting of many different meshes. Some of these meshes come with transparent materials applied to them. My goal is to modify the nodes list, add new nodes and change the links for the transparent materials. Based on this answer, I can detect the transparent materials (thanks to gandalf3) using the following Python script:

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        for slot in obj.material_slots:
            if slot.material:
                mat = slot.material
                for node in mat.node_tree.nodes:
                    if node.label == "Mix Color/Alpha":
                        if node.inputs[1].default_value[0] < 1:
                            print("Material '%s' on object '%s' seems transparent" % (mat.name, obj.name))

Also, based on this answer (again, thanks to gandalf3) I can manually add shader nodes to get depth maps or surface Normals while ignoring those materials as shown below:

enter image description here

I need to do this process for thousands of objects. I am pretty new to the concepts of nodes in Blender and do not know how modify the nodes and remove/add links to do what is being shown in the GIF image above. So I wonder, how can I add the math and mix shader nodes and add/remove the corresponding links using Python?

You can download this .obj file and load it in Blender to be able and make sure your code works. Just make sure you have selected Cycles before importing the obj file into Blender so that Blender creates the materials' nodes list automatically.

NOTE: I'm not sure how this helps but some of the meshes share the same materials. For instance, in the car example, the headlamps and the glasses (windshield, side windows) share the same material.

NOTE: Just loading the object and doing rendering will not get you the same Normal maps as shown here. The surface Normals of the object I provide here are incorrect. If you want to get the same surface Normals you need to do the following: join all the meshes. Then go edit mode and recalculate outside surface Normals of the downloaded object. Then turn off Auto Smooth.

$\endgroup$
  • $\begingroup$ Could taking out the faces with that material be an option? $\endgroup$ – batFINGER Feb 26 '18 at 15:57
  • $\begingroup$ @batFINGER What do you mean by taking out the faces? Sorry I'm a bit new to Blender stuff and am still becoming familiar with terminologies. $\endgroup$ – Amir Feb 26 '18 at 16:12
  • $\begingroup$ remove the transparent faces to other objects, and don't render those objects $\endgroup$ – batFINGER Feb 26 '18 at 16:14
  • $\begingroup$ @batFINGER I see. In that case, I think I do not want to take out the faces. $\endgroup$ – Amir Feb 26 '18 at 16:15
2
$\begingroup$

Since the name/labels of the nodes are all the same for all my objects I can simply use the same code for all other objects and it works. Here's how to do this automatically:

for mat in bpy.context.scene.objects.active.data.materials:
    for node in mat.node_tree.nodes:
        if node.label == "Mix Color/Alpha":
            if node.inputs[1].default_value[0] < 1:
                mixColorAlphaNode = node
                for n in mat.node_tree.nodes:
                    if n.label == "Alpha BSDF":
                        alphaBSDFNode = n
                    elif n.label == "Shader Add Refl":
                        shaderAddReflNode = n
                    elif n.label == "Material Out":
                        materialOutNode = n

                # Math node
                mat.node_tree.nodes.new('ShaderNodeMath')
                mathNode = mat.node_tree.nodes[len(mat.node_tree.nodes)-1]
                mathNode.operation = 'LESS_THAN'
                mathNode.inputs[1].default_value = 1.0

                # Mix shader node
                mat.node_tree.nodes.new('ShaderNodeMixShader')
                mixShaderNode = mat.node_tree.nodes[len(mat.node_tree.nodes)-1]

                # Add links
                mat.node_tree.links.new(mathNode.outputs['Value'], mixShaderNode.inputs[0])
                mat.node_tree.links.new(mixColorAlphaNode.outputs[0], mathNode.inputs[0])
                mat.node_tree.links.new(mixColorAlphaNode.outputs[0], mathNode.inputs[0])
                mat.node_tree.links.new(shaderAddReflNode.outputs[0], mixShaderNode.inputs[1])
                mat.node_tree.links.new(alphaBSDFNode.outputs[0], mixShaderNode.inputs[2])
                mat.node_tree.links.new(mixShaderNode.outputs[0], materialOutNode.inputs[0])
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.