diff --git a/README.md b/README.md index 286fff6..f2b83c1 100644 --- a/README.md +++ b/README.md @@ -10,5 +10,27 @@ This saves a lot of time when working with large node trees. Head over to [releases](https://github.com/jiggymoon69/node_tabber/releases) and download the zip file, but do not unzip it, just save it somewhere local.In blender preferences, go to the addon section and select "install ...", locate the downloaded zip and it will appear under the addons. Just enable it and change any preferences you wish. + +## Note (November 17 2021) +This repo is probably temporary as the original author, and all credits should go for him JiggyMoon69 owns the original repository of this project. +the file is there since it works and people may need the recent changes, but this repo's changes will perhaps end up merged into original Master, which would be for the best. + +https://twitter.com/jiggymoon +Thank you again, JiggyMoon for such a pleasant Addon +https://github.com/jiggymoon69/node_tabber/releases + +In the meantime there is a .zip file in the pre-releases of this repo that you can install in the exact same way. +https://github.com/sazaam/node_tabber/releases + + +[Edit] Also in the rush of committing, I almost forgot to give a huge shout out to Olimoth +https://github.com/olimoth/node_tabber +who has a fork which fixed some very annoying bugs such as instancing the wrong node (Vector Math Add would call ToDegrees instead, for those of you that remember) +and who managed to fix the exact issue he had previously reported here : +https://github.com/jiggymoon69/node_tabber/issues/3 +Thanks so much Olimoth! + + + [![IMAGE ALT TEXT](https://user-images.githubusercontent.com/48856925/95994231-54459f00-0e30-11eb-95b2-0fbbf1770121.png)](https://www.youtube.com/watch?v=Dd6lQCX4x3U "Preview 0.1.3") diff --git a/node_tabber/nt_extras.py b/node_tabber/nt_extras.py index 07add24..37e3154 100644 --- a/node_tabber/nt_extras.py +++ b/node_tabber/nt_extras.py @@ -6,7 +6,7 @@ [" M MAXIMUM", "Maximum (M) MATH"], [" M LESS_THAN", "Less Than (LT) MATH"], [" M GREATER_THAN", "Greater Than (GT) MATH"], [" M SIGN", "Sign (S) MATH"], [" M COMPARE", "Compare (C) MATH"], [" M SMOOTH_MIN", "Smooth Minimum (SM) MATH"], [" M SMOOTH_MAX", "Smooth Maximum (SM) MATH"], [" M ROUND", "Round (R) MATH"], [" M FLOOR", "Floor (F) MATH"], [" M CEIL", "Ceiling (C) MATH"], [" M TRUNC", "Truncate (T) MATH"], [" M FRACT", "Fraction (F) MATH"], -[" M MODULO", "Modulo (M) MATH"], [" M WRAP", "Wrap (W) MATH"], [" M SNAP", "Snap (S) MATH"], [" M PINGPONG", "Ping-Pong (PP) MATH"], +[" M MODULO", "Modulo (M) MATH"], [" M WRAP", "Wrap (W) MATH"], [" M SNAP", "Snap (S) MATH"], [" M PINGPONG", "Ping Pong (PP) MATH"], [" M SINE", "Sine (S) MATH"], [" M COSINE", "Cosine (C) MATH"], [" M TANGENT", "Tangent (T) MATH"], [" M ARCSINE", "ArcSine (AS) MATH"], [" M ARCCOSINE", "Arccosine (AC) MATH"], [" M ARCTANGENT", "Arctangent (AT) MATH"], [" M ARCTAN2", "Arctan2 (AT) MATH"], [" M SINH", "Hyperbolic Sine (HS) MATH"], [" M COSH", "Hyperbolic Cosine (HC) MATH"], [" M TANH", "Hyperbolic Tangent (HT) MATH"], [" M RADIANS", "To Radians (TR) MATH"], [" M DEGREES", "To Degrees (TD) MATH"], @@ -22,10 +22,11 @@ [" VM SINE", "Sine (S) VEC MATH"], [" VM COSINE", "Cosine (C) VEC MATH"], [" VM TANGENT", "Tangent (T) VEC MATH"], ] -extra_color = [[" C VALUE", "Value (V) COLOR"], [" C COLOR", "Color (C) COLOR"], [" C SATURATION", "Saturation (S) COLOR"], [" C HUE", "Hue (H) COLOR"], -[" C DIVIDE", "Divide (D) COLOR"], [" C SUBTRACT", "Subtract (S) COLOR"], [" C DIFFERENCE", "Difference (D) COLOR"], -[" C LINEAR_LIGHT", "Linear Light (LL) COLOR"], [" C SOFT_LIGHT", "Soft Light (SL) COLOR"], [" C OVERLAY", "Overlay (O) COLOR"], -[" C ADD", "Add (A) COLOR"], [" C DODGE", "Dodge (D) COLOR"], [" C SCREEN", "Screen (S) COLOR"], [" C LIGHTEN", "Lighten (L) COLOR"], -[" C BURN", "Burn (B) COLOR"], [" C MULTIPLY", "Multiply (M) COLOR"], [" C DARKEN", "Darken (D) COLOR"], [" C MIX", "Mix (M) COLOR"], +extra_color = [[" CM VALUE", "Value (V) COLOR"], [" CM COLOR", "Color (C) COLOR"], [" CM SATURATION", "Saturation (S) COLOR"], [" CM HUE", "Hue (H) COLOR"], +[" CM DIVIDE", "Divide (D) COLOR"], [" CM SUBTRACT", "Subtract (S) COLOR"], [" CM DIFFERENCE", "Difference (D) COLOR"], +[" CM LINEAR_LIGHT", "Linear Light (LL) COLOR"], [" CM SOFT_LIGHT", "Soft Light (SL) COLOR"], [" CM OVERLAY", "Overlay (O) COLOR"], +[" CM ADD", "Add (A) COLOR"], [" CM DODGE", "Dodge (D) COLOR"], [" CM SCREEN", "Screen (S) COLOR"], [" CM LIGHTEN", "Lighten (L) COLOR"], +[" CM BURN", "Burn (B) COLOR"], [" CM MULTIPLY", "Multiply (M) COLOR"], [" CM DARKEN", "Darken (D) COLOR"], [" CM MIX", "Mix (M) COLOR"], +[" CM VECTORUNIFORM", "Mix (M) Vector"], [" CM VECTORNON_UNIFORM", "Mix (M) Vector Non Uniform"] ] diff --git a/node_tabber/operators.py b/node_tabber/operators.py index acb00f4..c255ad6 100644 --- a/node_tabber/operators.py +++ b/node_tabber/operators.py @@ -85,14 +85,34 @@ class NODE_OT_add_tabber_search(bpy.types.Operator): bl_property = "node_item" _enum_item_hack = [] - + + def node_enum_items2(self, context): for index, item in enumerate(nodeitems_utils.node_items_iter(context)): if isinstance(item, nodeitems_utils.NodeItem): print(str(index) + " : " + str(item.label)) return None - + + def retrieve_geo_nodes(self, context): + geonodes_extras = [ "ShaderNodeMapRange", "ShaderNodeMath", "ShaderNodeVectorMath", + "ShaderNodeValToRGB", "ShaderNodeMix", "ShaderNodeVectorCurve", + "ShaderNodeRGBCurve", "ShaderNodeFloatCurve", + "ShaderNodeVectorRotate", "ShaderNodeCombineXYZ", "ShaderNodeSeparateXYZ", + "ShaderNodeClamp", "ShaderNodeValue"] + + NI = nodeitems_utils.NodeItem + geonodelist = (lambda data: [NI(i) for i in dir(data) if ((i.startswith("GeometryNode") or i.startswith("FunctionNode") or i.startswith("ShaderNodeTex")) and i!= "GeometryNode")])(bpy.types) + geonodelist += [NI(i) for i in geonodes_extras] + groups = [NI(nodetype = "GeometryNodeGroup", label=g.name, settings={"node_tree": g}) for g in list(bpy.data.node_groups) if g.type == "GEOMETRY" and g.name != bpy.context.space_data.edit_tree.name] + + geonodelist += groups + #geonodelist += [NI(nodetype = "GeometryNodeGroup", label="TestNodeGroup", settings={tuple(["node_tree", "TestNodeGroup"])})] #settings={} + return (y for y in geonodelist) + + def ensure_nodes(self, context): + return nodeitems_utils.node_items_iter(context) if context.space_data.edit_tree.type != "GEOMETRY" else NODE_OT_add_tabber_search.retrieve_geo_nodes(self, context) + # Create an enum list from node items def node_enum_items(self, context): nt_debug("DEF: node_enum_items") @@ -124,12 +144,14 @@ def node_enum_items(self, context): math_index = -1 vector_math_index = -1 mix_rgb_index = -1 - - for index, item in enumerate(nodeitems_utils.node_items_iter(context)): + + + node_items = NODE_OT_add_tabber_search.ensure_nodes(self, context) + + for index, item in enumerate(node_items): #nt_debug("DEF: node_enum_items") if isinstance(item, nodeitems_utils.NodeItem): - - #nt_debug(str(item.label)) + short = '' tally = 0 words = item.label.split() @@ -138,7 +160,7 @@ def node_enum_items(self, context): match = item.label+" ("+short+")" if match in content: tally = content[match]['tally'] - + enum_items.append( (str(index) + " 0 0", item.label+" ("+short+")", @@ -146,14 +168,16 @@ def node_enum_items(self, context): index, )) index_offset = index - + + + if item.label == "Math": math_index = index if item.label == "Vector Math": vector_math_index = index - if item.label == "MixRGB": + if item.label == "Mix": mix_rgb_index = index - + #Add sub node searching if enabled if prefs.sub_search: if math_index > -1: @@ -168,10 +192,9 @@ def node_enum_items(self, context): str(tally), index_offset+1+index2, )) - index_offset += index2 + index_offset += index2 + 1 if vector_math_index > -1: - nt_debug("Adding vector math nodes") for index2, subname in enumerate(nt_extras.extra_vector_math): tally = 0 if subname[1] in content: @@ -182,10 +205,10 @@ def node_enum_items(self, context): str(tally), index_offset+1+index2, )) - index_offset += index2 + index_offset += index2 + 1 if mix_rgb_index > -1: - nt_debug("Adding mix rgb nodes") + for index2, subname in enumerate(nt_extras.extra_color): tally = 0 if subname[1] in content: @@ -196,7 +219,7 @@ def node_enum_items(self, context): str(tally), index_offset+1+index2, )) - index_offset += index2 + index_offset += index2 + 1 @@ -216,15 +239,17 @@ def find_node_item(self, context): nt_debug("DEF: find_node_item") tmp = int(self.node_item.split()[0]) nt_debug("FIND_NODE_ITEM: Tmp : " + str(self.node_item.split())) - + node_item = tmp extra = [self.node_item.split()[1], self.node_item.split()[2]] #nt_debug ("First extra :" + str(extra)) #nt_debug ("Third ? :" + str(self.node_item.split()[3:])) nice_name = ' '.join(self.node_item.split()[3:]) - - for index, item in enumerate(nodeitems_utils.node_items_iter(context)): + + node_items = NODE_OT_add_tabber_search.ensure_nodes(self, context) + + for index, item in enumerate(node_items): #nt_debug("DEF: find_node_item") if index == node_item: return [item, extra, nice_name] @@ -237,7 +262,8 @@ def execute(self, context): startTime = time.perf_counter() addon = bpy.context.preferences.addons['node_tabber'] prefs = addon.preferences - + + item = self.find_node_item(context)[0] extra = self.find_node_item(context)[1] nice_name = self.find_node_item(context)[2] @@ -269,15 +295,25 @@ def execute(self, context): # no need to keep self._enum_item_hack.clear() - + + if item: + node_tree_type = None + + if "node_tree" in item.settings : + node_tree_type = item.settings["node_tree"] if item.nodetype == 'GeometryNodeGroup' else eval(item.settings["node_tree"]) # apply settings from the node item - for setting in item.settings.items(): - ops = self.settings.add() - ops.name = setting[0] - ops.value = setting[1] - - self.create_node(context, item.nodetype) + # !!! this was breaking on custom node groups and not sure what it does + try: + for setting in item.settings.items(): + if setting[0] != "node_tree": + ops = self.settings.add() + ops.name = setting[0] + ops.value = setting[1] + except AttributeError as e: + print("NodeTabber:: An AttributeError exception occurred: " + e) + + self.create_node(context, item.nodetype, node_tree_type) #print("Added node in node tabber") nt_debug(str(item.nodetype)) @@ -297,8 +333,13 @@ def execute(self, context): if (extra[0] == "VM"): node_active.operation = extra[1] - if (extra[0] == "C"): - node_active.blend_type = extra[1] + if (extra[0] == "CM"): + if(extra[1].startswith("VECTOR")) : + node_active.data_type = "VECTOR" + node_active.factor_mode = str(extra[1]).replace("VECTOR", "") + else: + node_active.data_type = "RGBA" + node_active.blend_type = extra[1] if not prefs.quick_place: bpy.ops.node.translate_attach_remove_on_cancel('INVOKE_DEFAULT') @@ -308,7 +349,7 @@ def execute(self, context): else: return {'CANCELLED'} - def create_node(self, context, node_type=None): + def create_node(self, context, node_type=None, node_tree_type=None): nt_debug("DEF: create_node") space = context.space_data tree = space.edit_tree @@ -322,7 +363,10 @@ def create_node(self, context, node_type=None): n.select = False node = tree.nodes.new(type=node_type) - + + if node_tree_type != None: + node.node_tree = node_tree_type + node.select = True tree.nodes.active = node node.location = space.cursor_location