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:
authorCampbell Barton <ideasman42@gmail.com>2019-12-09 15:21:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-12-09 15:29:43 +0300
commit395ca8a4be7a66c72a5556c51f958644601a846b (patch)
treeecc5e68e499a40c6c5ea4ac152a44138312ceeb6 /node_presets.py
parentefbc5e5db7c73ae43ddc11abf8db8bc8f98c9945 (diff)
node_presets: add back from addons_contrib
Improve error handling: - Show exception if the path can't be listed. - Reload node cache if the preferences directory changes.
Diffstat (limited to 'node_presets.py')
-rw-r--r--node_presets.py247
1 files changed, 247 insertions, 0 deletions
diff --git a/node_presets.py b/node_presets.py
new file mode 100644
index 00000000..7bb73b67
--- /dev/null
+++ b/node_presets.py
@@ -0,0 +1,247 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Node Presets",
+ "description": "Useful and time-saving tools for rendering workflow",
+ "author": "Campbell Barton",
+ "version": (1, 1),
+ "blender": (2, 80, 0),
+ "location": "Node > Add Template",
+ "description": "Adds node presets",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+ "category": "Render",
+}
+
+import os
+import bpy
+from bpy.types import (
+ Operator,
+ Menu,
+ AddonPreferences,
+)
+
+from bpy.props import (
+ StringProperty,
+)
+
+
+# -----------------------------------------------------------------------------
+# Node Adding Operator
+
+
+def node_center(context):
+ from mathutils import Vector
+ loc = Vector((0.0, 0.0))
+ node_selected = context.selected_nodes
+ if node_selected:
+ for node in node_selected:
+ loc += node.location
+ loc /= len(node_selected)
+ return loc
+
+
+def node_template_add(context, filepath, node_group, ungroup, report):
+ """ Main function
+ """
+
+ space = context.space_data
+ node_tree = space.node_tree
+ node_active = context.active_node
+ node_selected = context.selected_nodes
+
+ if node_tree is None:
+ report({'ERROR'}, "No node tree available")
+ return
+
+ with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
+ assert(node_group in data_from.node_groups)
+ data_to.node_groups = [node_group]
+ node_group = data_to.node_groups[0]
+
+ # add node!
+ center = node_center(context)
+
+ for node in node_tree.nodes:
+ node.select = False
+
+ node_type_string = {
+ "ShaderNodeTree": "ShaderNodeGroup",
+ "CompositorNodeTree": "CompositorNodeGroup",
+ "TextureNodeTree": "TextureNodeGroup",
+ }[type(node_tree).__name__]
+
+ node = node_tree.nodes.new(type=node_type_string)
+ node.node_tree = node_group
+
+ is_fail = (node.node_tree is None)
+ if is_fail:
+ report({'WARNING'}, "Incompatible node type")
+
+ node.select = True
+ node_tree.nodes.active = node
+ node.location = center
+
+ if is_fail:
+ node_tree.nodes.remove(node)
+ else:
+ if ungroup:
+ bpy.ops.node.group_ungroup()
+
+ # node_group.user_clear()
+ # bpy.data.node_groups.remove(node_group)
+
+
+# -----------------------------------------------------------------------------
+# Node Template Prefs
+
+def node_search_path(context):
+ preferences = context.preferences
+ addon_prefs = preferences.addons[__name__].preferences
+ dirpath = addon_prefs.search_path
+ return dirpath
+
+
+class NodeTemplatePrefs(AddonPreferences):
+ bl_idname = __name__
+
+ search_path: StringProperty(
+ name="Directory of blend files with node-groups",
+ subtype='DIR_PATH',
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "search_path")
+
+
+class NODE_OT_template_add(Operator):
+ """Add a node template"""
+ bl_idname = "node.template_add"
+ bl_label = "Add node group template"
+ bl_description = "Add node group template"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ filepath: StringProperty(
+ subtype='FILE_PATH',
+ )
+ group_name: StringProperty()
+
+ def execute(self, context):
+ node_template_add(context, self.filepath, self.group_name, True, self.report)
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ node_template_add(context, self.filepath, self.group_name, event.shift, self.report)
+
+ return {'FINISHED'}
+
+
+# -----------------------------------------------------------------------------
+# Node menu list
+
+def node_template_cache(context, *, reload=False):
+ dirpath = node_search_path(context)
+
+ if node_template_cache._node_cache_path != dirpath:
+ reload = True
+
+ node_cache = node_template_cache._node_cache
+ if reload:
+ node_cache = []
+ if node_cache:
+ return node_cache
+
+ for fn in os.listdir(dirpath):
+ if fn.endswith(".blend"):
+ filepath = os.path.join(dirpath, fn)
+ with bpy.data.libraries.load(filepath) as (data_from, data_to):
+ for group_name in data_from.node_groups:
+ if not group_name.startswith("_"):
+ node_cache.append((filepath, group_name))
+
+ node_template_cache._node_cache = node_cache
+ node_template_cache._node_cache_path = dirpath
+
+ return node_cache
+
+
+node_template_cache._node_cache = []
+node_template_cache._node_cache_path = ""
+
+
+class NODE_MT_template_add(Menu):
+ bl_label = "Node Template"
+
+ def draw(self, context):
+ layout = self.layout
+
+ dirpath = node_search_path(context)
+ if dirpath == "":
+ layout.label(text="Set search dir in the addon-prefs")
+ return
+
+ try:
+ node_items = node_template_cache(context)
+ except Exception as ex:
+ node_items = ()
+ layout.label(text=repr(ex), icon='ERROR')
+
+ for filepath, group_name in node_items:
+ props = layout.operator(
+ NODE_OT_template_add.bl_idname,
+ text=group_name,
+ )
+ props.filepath = filepath
+ props.group_name = group_name
+
+
+def add_node_button(self, context):
+ self.layout.menu(
+ NODE_MT_template_add.__name__,
+ text="Template",
+ icon='PLUGIN',
+ )
+
+
+classes = (
+ NODE_OT_template_add,
+ NODE_MT_template_add,
+ NodeTemplatePrefs
+)
+
+
+def register():
+ for cls in classes:
+ bpy.utils.register_class(cls)
+
+ bpy.types.NODE_MT_add.append(add_node_button)
+
+
+def unregister():
+ for cls in classes:
+ bpy.utils.unregister_class(cls)
+
+ bpy.types.NODE_MT_add.remove(add_node_button)
+
+
+if __name__ == "__main__":
+ register()