2
$\begingroup$

Blender and python newbee here.

I would be very happy if one of you could help me with the following problem i am running into: i have imported a scale model into blender, which i want to render in real life scale. When i scale the model, the materials do not scale with it and look bad. The materials however all have a Value node named "Scale", which, if i edit it with the same scale i am scaling the model, fixes everything and it looks right then. Example of Value Node It would be so much easier to have a script to do that semi-automatically, as the model uses way over 100 objects with different materials...

What i could find was this kind of similar problem solved, but i have not been able to adapt it to solve my problem, as i have no prior experience with scripting.

What i would like to do:

  • Select the objects i want to change
  • Go into scripting
  • copy a script into it
  • edit a number that should be put into the value node labeled "scale" of all selected objects
  • run script
  • be happy to get way better rendering results.

I am using Blender 2.83.4, in scripting the console says PYTHON INTERACTIVE CONSOLE 3.7.4 (default, Feb 17 2020, 16:23:28) [MSC v.1916 64 bit (AMD64)]

Every help is much appreciated!

$\endgroup$
2
  • $\begingroup$ Hi. Please use the built-in uploader when adding images. See: meta.stackexchange.com/questions/75491/… . Thanks. $\endgroup$ Commented Aug 16, 2020 at 11:29
  • $\begingroup$ edited the post, sorry for the inconvenience $\endgroup$
    – Neteye
    Commented Aug 16, 2020 at 11:38

1 Answer 1

1
$\begingroup$

The script below iterates over all selected objects and adjusts the value nodes in the assigned materials if their label is set to "Scale".

import bpy
      
       
def set_scale_nodes_selected_objects(scale_val):
    for obj in bpy.context.selected_objects:
        for mat_slot in obj.material_slots:
            set_scale_nodes_material(mat_slot.material, scale_val)
    

def set_scale_nodes_material(mat, scale_val):
    if mat is not None and mat.use_nodes and mat.node_tree is not None:
        for node in mat.node_tree.nodes:
            if node.label == "Scale" and node.type == "VALUE":
                node.outputs["Value"].default_value = scale_val  


if __name__ == "__main__":
    scale_val = 1.0
    set_scale_nodes_selected_objects(scale_val)
$\endgroup$
5
  • $\begingroup$ I wonder, instead, if a script could replace the node with an instanced 1-element node group, so it doesn't have to be run again? :) $\endgroup$
    – Robin Betts
    Commented Aug 16, 2020 at 11:17
  • 1
    $\begingroup$ @RobinBetts As far as I'm aware the instancing of node groups doesn't link the input value. Hence you would still need to set it for each node group. What could be optimized though, is that every material is only edited once. Currently the script will inspect a material multiple times if it is assigned to more than one selected object. $\endgroup$ Commented Aug 16, 2020 at 11:57
  • $\begingroup$ @RobertGützkow Thank you very much, your script is working, and a quick test render showed promising results. Again, thank you very much! $\endgroup$
    – Neteye
    Commented Aug 16, 2020 at 12:18
  • $\begingroup$ @RobertGützkow... Slightly clumsy, I know, but I wasn't thinking the group would have a group input.. just an internal Value node. Sure, You have to edit the group to change the value, but that's reflected in all instances. $\endgroup$
    – Robin Betts
    Commented Aug 16, 2020 at 15:28
  • $\begingroup$ @RobinBetts I see, that would be an alternative. $\endgroup$ Commented Aug 16, 2020 at 16:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .