Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Schittek <lone_noel>2022-07-25 21:31:14 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-07-25 21:42:04 +0300
commitad1966474ed28580aac6f43f000043596bdf37b1 (patch)
tree485186ddf30858c7d212e7d5eb47f688ee81c07e
parentb00712001075abd383af7d88252ee199b5991231 (diff)
Fix T97724: Node Wrangler: better align nodes on texture setup
* The added nodes are now top aligned with the nodes they belong to. This looks nicer and works independent of screen DPI. * There is a vertical offset based on the socket the added nodes are connected to. This prevents nodes from overlapping too much, when executing the texture setup several times in a row. * Ignore disabled sockets, which would create nodes seemingly connected to nothing. Differential Revision: https://developer.blender.org/D15031
-rw-r--r--node_wrangler.py118
1 files changed, 60 insertions, 58 deletions
diff --git a/node_wrangler.py b/node_wrangler.py
index 6d586e80..02aa62c4 100644
--- a/node_wrangler.py
+++ b/node_wrangler.py
@@ -1228,13 +1228,12 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
def nw_check(context):
space = context.space_data
- valid_trees = ["ShaderNodeTree", "CompositorNodeTree", "TextureNodeTree", "GeometryNodeTree"]
+ editor_is_valid = space.type == 'NODE_EDITOR'
- valid = False
- if space.type == 'NODE_EDITOR' and space.node_tree is not None and space.tree_type in valid_trees:
- valid = True
+ valid_trees = ["ShaderNodeTree", "CompositorNodeTree", "TextureNodeTree", "GeometryNodeTree"]
+ tree_is_valid = space.node_tree is not None and space.tree_type in valid_trees
- return valid
+ return editor_is_valid and tree_is_valid
class NWBase:
@classmethod
@@ -3014,71 +3013,74 @@ class NWAddTextureSetup(Operator, NWBase):
@classmethod
def poll(cls, context):
- valid = False
if nw_check(context):
space = context.space_data
if space.tree_type == 'ShaderNodeTree':
- valid = True
- return valid
+ return True
+ return False
def execute(self, context):
nodes, links = get_nodes_links(context)
+
shader_types = [x[1] for x in shaders_shader_nodes_props if x[1] not in {'MIX_SHADER', 'ADD_SHADER'}]
texture_types = [x[1] for x in shaders_texture_nodes_props]
selected_nodes = [n for n in nodes if n.select]
- for t_node in selected_nodes:
- valid = False
+
+ for node in selected_nodes:
+ if not node.inputs:
+ continue
+
input_index = 0
- if t_node.inputs:
- for index, i in enumerate(t_node.inputs):
- if not i.is_linked:
- valid = True
- input_index = index
+ target_input = node.inputs[0]
+ for input in node.inputs:
+ if input.enabled:
+ input_index += 1
+ if not input.is_linked:
+ target_input = input
break
- if valid:
- locx = t_node.location.x
- locy = t_node.location.y - t_node.dimensions.y/2
-
- xoffset = [500, 700]
- is_texture = False
- if t_node.type in texture_types + ['MAPPING']:
- xoffset = [290, 500]
- is_texture = True
-
- coordout = 2
- image_type = 'ShaderNodeTexImage'
-
- if (t_node.type in texture_types and t_node.type != 'TEX_IMAGE') or (t_node.type == 'BACKGROUND'):
- coordout = 0 # image texture uses UVs, procedural textures and Background shader use Generated
- if t_node.type == 'BACKGROUND':
- image_type = 'ShaderNodeTexEnvironment'
-
- if not is_texture:
- tex = nodes.new(image_type)
- tex.location = [locx - 200, locy + 112]
- nodes.active = tex
- links.new(tex.outputs[0], t_node.inputs[input_index])
-
- t_node.select = False
- if self.add_mapping or is_texture:
- if t_node.type != 'MAPPING':
- m = nodes.new('ShaderNodeMapping')
- m.location = [locx - xoffset[0], locy + 141]
- m.width = 240
- else:
- m = t_node
- coord = nodes.new('ShaderNodeTexCoord')
- coord.location = [locx - (200 if t_node.type == 'MAPPING' else xoffset[1]), locy + 124]
-
- if not is_texture:
- links.new(m.outputs[0], tex.inputs[0])
- links.new(coord.outputs[coordout], m.inputs[0])
- else:
- nodes.active = m
- links.new(m.outputs[0], t_node.inputs[input_index])
- links.new(coord.outputs[coordout], m.inputs[0])
else:
- self.report({'WARNING'}, "No free inputs for node: "+t_node.name)
+ self.report({'WARNING'}, "No free inputs for node: " + node.name)
+ continue
+
+ x_offset = 0
+ padding = 40.0
+ locx = node.location.x
+ locy = node.location.y - (input_index * padding)
+
+ is_texture_node = node.type in texture_types
+ use_environment_texture = node.type == 'BACKGROUND'
+
+ # Add an image texture before normal shader nodes.
+ if not is_texture_node:
+ image_texture_type = 'ShaderNodeTexEnvironment' if use_environment_texture else 'ShaderNodeTexImage'
+ image_texture_node = nodes.new(image_texture_type)
+ x_offset = x_offset + image_texture_node.width + padding
+ image_texture_node.location = [locx - x_offset, locy]
+ nodes.active = image_texture_node
+ links.new(image_texture_node.outputs[0], target_input)
+
+ # The mapping setup following this will connect to the firrst input of this image texture.
+ target_input = image_texture_node.inputs[0]
+
+ node.select = False
+
+ if is_texture_node or self.add_mapping:
+ # Add Mapping node.
+ mapping_node = nodes.new('ShaderNodeMapping')
+ x_offset = x_offset + mapping_node.width + padding
+ mapping_node.location = [locx - x_offset, locy]
+ links.new(mapping_node.outputs[0], target_input)
+
+ # Add Texture Coordinates node.
+ tex_coord_node = nodes.new('ShaderNodeTexCoord')
+ x_offset = x_offset + tex_coord_node.width + padding
+ tex_coord_node.location = [locx - x_offset, locy]
+
+ is_procedural_texture = is_texture_node and node.type != 'TEX_IMAGE'
+ use_generated_coordinates = is_procedural_texture or use_environment_texture
+ tex_coord_output = tex_coord_node.outputs[0 if use_generated_coordinates else 2]
+ links.new(tex_coord_output, mapping_node.inputs[0])
+
return {'FINISHED'}