Left: | ||
Right: |
OLD | NEW |
---|---|
1 # ##### BEGIN GPL LICENSE BLOCK ##### | 1 # ##### BEGIN GPL LICENSE BLOCK ##### |
2 # | 2 # |
3 # This program is free software; you can redistribute it and/or | 3 # This program is free software; you can redistribute it and/or |
4 # modify it under the terms of the GNU General Public License | 4 # modify it under the terms of the GNU General Public License |
5 # as published by the Free Software Foundation; either version 2 | 5 # as published by the Free Software Foundation; either version 2 |
6 # of the License, or (at your option) any later version. | 6 # of the License, or (at your option) any later version. |
7 # | 7 # |
8 # This program is distributed in the hope that it will be useful, | 8 # This program is distributed in the hope that it will be useful, |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 ('ShaderNodeEmission', 'EMISSION', 'Emission'), | 93 ('ShaderNodeEmission', 'EMISSION', 'Emission'), |
94 ('ShaderNodeBsdfVelvet', 'BSDF_VELVET', 'Velvet BSDF'), | 94 ('ShaderNodeBsdfVelvet', 'BSDF_VELVET', 'Velvet BSDF'), |
95 ('ShaderNodeBsdfTranslucent', 'BSDF_TRANSLUCENT', 'Translucent BSDF'), | 95 ('ShaderNodeBsdfTranslucent', 'BSDF_TRANSLUCENT', 'Translucent BSDF'), |
96 ('ShaderNodeAmbientOcclusion', 'AMBIENT_OCCLUSION', 'Ambient Occlusion'), | 96 ('ShaderNodeAmbientOcclusion', 'AMBIENT_OCCLUSION', 'Ambient Occlusion'), |
97 ('ShaderNodeBackground', 'BACKGROUND', 'Background'), | 97 ('ShaderNodeBackground', 'BACKGROUND', 'Background'), |
98 ('ShaderNodeBsdfRefraction', 'BSDF_REFRACTION', 'Refraction BSDF'), | 98 ('ShaderNodeBsdfRefraction', 'BSDF_REFRACTION', 'Refraction BSDF'), |
99 ('ShaderNodeBsdfAnisotropic', 'BSDF_ANISOTROPIC', 'Anisotropic BSDF'), | 99 ('ShaderNodeBsdfAnisotropic', 'BSDF_ANISOTROPIC', 'Anisotropic BSDF'), |
100 ('ShaderNodeHoldout', 'HOLDOUT', 'Holdout'), | 100 ('ShaderNodeHoldout', 'HOLDOUT', 'Holdout'), |
101 ) | 101 ) |
102 | 102 |
103 def set_convenience_variables(context): | 103 def set_convenience_variables(context): |
ideasman42
2013/03/27 00:16:46
suggest to not use globals here and just:
return n
| |
104 global nodes | 104 global nodes |
105 global links | 105 global links |
106 | 106 |
107 space = context.space_data | 107 space = context.space_data |
108 tree = space.node_tree | 108 tree = space.node_tree |
109 nodes = tree.nodes | 109 nodes = tree.nodes |
110 links = tree.links | 110 links = tree.links |
111 active = nodes.active | 111 active = nodes.active |
112 context_active = context.active_node | 112 context_active = context.active_node |
113 # check if we are working on regular node tree or node group is currently ed ited. | 113 # check if we are working on regular node tree or node group is currently ed ited. |
(...skipping 14 matching lines...) Expand all Loading... | |
128 | 128 |
129 class MergeNodes(bpy.types.Operator): | 129 class MergeNodes(bpy.types.Operator): |
130 bl_idname = "node.merge_nodes" | 130 bl_idname = "node.merge_nodes" |
131 bl_label = "Merge Selected Nodes" | 131 bl_label = "Merge Selected Nodes" |
132 bl_options = {'REGISTER', 'UNDO'} | 132 bl_options = {'REGISTER', 'UNDO'} |
133 ···· | 133 ···· |
134 # option: "BlendType/ShaderKind/MathOperation and Node Kind" separated with space | 134 # option: "BlendType/ShaderKind/MathOperation and Node Kind" separated with space |
135 option = StringProperty() | 135 option = StringProperty() |
136 ···· | 136 ···· |
137 @classmethod | 137 @classmethod |
138 def poll(cls, context): | 138 def poll(cls, context): |
ideasman42
2013/03/27 00:16:46
All both functions are the same, use use a mix-in
| |
139 space = context.space_data | 139 space = context.space_data |
140 return space.type == 'NODE_EDITOR' and space.node_tree is not None | 140 return space.type == 'NODE_EDITOR' and space.node_tree is not None |
141 ···· | 141 ···· |
142 def execute(self, context): | 142 def execute(self, context): |
143 tree_type = context.space_data.node_tree.type | 143 tree_type = context.space_data.node_tree.type |
144 if tree_type == 'COMPOSITING': | 144 if tree_type == 'COMPOSITING': |
145 node_type = 'CompositorNode' | 145 node_type = 'CompositorNode' |
146 elif tree_type == 'SHADER': | 146 elif tree_type == 'SHADER': |
147 node_type = 'ShaderNode' | 147 node_type = 'ShaderNode' |
148 set_convenience_variables(context) | 148 set_convenience_variables(context) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 ): | 181 ): |
182 if node_kind == kind and mode in the_list: | 182 if node_kind == kind and mode in the_list: |
183 dst.append([i, node.location.x, node.location.y]) | 183 dst.append([i, node.location.x, node.location.y]) |
184 # When nodes with output kinds 'RGBA' and 'VALUE' are selected at the sa me time | 184 # When nodes with output kinds 'RGBA' and 'VALUE' are selected at the sa me time |
185 # use only 'Mix' nodes for merging. | 185 # use only 'Mix' nodes for merging. |
186 # For that we add selected_math list to selected_mix list and clear sele cted_math. | 186 # For that we add selected_math list to selected_mix list and clear sele cted_math. |
187 if selected_mix and selected_math and node_kind == 'AUTO': | 187 if selected_mix and selected_math and node_kind == 'AUTO': |
188 selected_mix += selected_math | 188 selected_mix += selected_math |
189 selected_math = [] | 189 selected_math = [] |
190 ········ | 190 ········ |
191 for the_list in [selected_mix, selected_shader, selected_math]: | 191 for the_list in [selected_mix, selected_shader, selected_math]: |
ideasman42
2013/03/27 00:16:46
'the_list' is used for different purposes, would p
| |
192 if the_list: | 192 if the_list: |
193 count_before = len(nodes) | 193 count_before = len(nodes) |
194 # sort list by loc_x - reversed | 194 # sort list by loc_x - reversed |
195 the_list.sort(key = lambda k: k[1], reverse = True) | 195 the_list.sort(key = lambda k: k[1], reverse = True) |
196 # get maximum loc_x | 196 # get maximum loc_x |
197 loc_x = the_list[0][1] + 350.0 | 197 loc_x = the_list[0][1] + 350.0 |
ideasman42
2013/03/27 00:16:46
*picky* - personal preference to use 2d vectors fo
| |
198 the_list.sort(key = lambda k: k[2], reverse = True) | 198 the_list.sort(key = lambda k: k[2], reverse = True) |
199 loc_y = the_list[len(the_list) - 1][2] | 199 loc_y = the_list[len(the_list) - 1][2] |
200 offset_y = 40.0 | 200 offset_y = 40.0 |
201 if the_list == selected_shader: | 201 if the_list == selected_shader: |
202 offset_y = 150.0 | 202 offset_y = 150.0 |
203 the_range = len(the_list)-1 | 203 the_range = len(the_list)-1 |
204 do_hide = True | 204 do_hide = True |
205 if len(the_list) == 1: | 205 if len(the_list) == 1: |
206 the_range = 1 | 206 the_range = 1 |
207 do_hide = False | 207 do_hide = False |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 # Hack needed to calculate real width | 593 # Hack needed to calculate real width |
594 if node.hide: | 594 if node.hide: |
595 bpy.ops.node.select_all(action = 'DESELECT') | 595 bpy.ops.node.select_all(action = 'DESELECT') |
596 helper = nodes.new('NodeReroute') | 596 helper = nodes.new('NodeReroute') |
597 helper.select = True | 597 helper.select = True |
598 node.select = True | 598 node.select = True |
599 # resize node and helper to zero. Then check locations to ca lculate width | 599 # resize node and helper to zero. Then check locations to ca lculate width |
600 bpy.ops.transform.resize(value = (0.0, 0.0, 0.0)) | 600 bpy.ops.transform.resize(value = (0.0, 0.0, 0.0)) |
601 width = 2.0 * (helper.location.x - node.location.x) | 601 width = 2.0 * (helper.location.x - node.location.x) |
602 # restore node location | 602 # restore node location |
603 node.location = [x,y] | 603 node.location = [x,y] |
ideasman42
2013/03/27 00:16:46
*picky*, you can just do this.
node.location = x,
| |
604 # delete helper | 604 # delete helper |
605 node.select = False | 605 node.select = False |
606 # only helper is selected now | 606 # only helper is selected now |
607 bpy.ops.node.delete() | 607 bpy.ops.node.delete() |
608 x = node.location.x + width + 20.0 | 608 x = node.location.x + width + 20.0 |
609 if node.type != 'REROUTE': | 609 if node.type != 'REROUTE': |
610 y -= 35.0 | 610 y -= 35.0 |
611 y_offset = -22.0 | 611 y_offset = -22.0 |
612 loc = [x, y] | 612 loc = [x, y] |
613 reroutes_count = 0 # will be used when aligning reroutes added to h idden nodes | 613 reroutes_count = 0 # will be used when aligning reroutes added to h idden nodes |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
789 if space.type == 'NODE_EDITOR': | 789 if space.type == 'NODE_EDITOR': |
790 if space.node_tree is not None and context.active_node is not None: | 790 if space.node_tree is not None and context.active_node is not None: |
791 if context.active_node.select: | 791 if context.active_node.select: |
792 valid = True | 792 valid = True |
793 return valid | 793 return valid |
794 ···· | 794 ···· |
795 def execute(self, context): | 795 def execute(self, context): |
796 set_convenience_variables(context) | 796 set_convenience_variables(context) |
797 option_split = self.option.split( ) | 797 option_split = self.option.split( ) |
798 replace = eval(option_split[0]) | 798 replace = eval(option_split[0]) |
799 use_node_name = eval(option_split[1]) | 799 use_node_name = eval(option_split[1]) |
ideasman42
2013/03/27 00:16:46
Using eval() just to pass 3 bools is not really go
| |
800 use_outputs_names = eval(option_split[2]) | 800 use_outputs_names = eval(option_split[2]) |
801 active = nodes.active | 801 active = nodes.active |
802 selected = [node for node in nodes if node.select and node != active] | 802 selected = [node for node in nodes if node.select and node != active] |
803 outputs = [] # Only usable outputs of active nodes will be stored here. | 803 outputs = [] # Only usable outputs of active nodes will be stored here. |
804 for out in active.outputs: | 804 for out in active.outputs: |
805 if active.type != 'R_LAYERS': | 805 if active.type != 'R_LAYERS': |
806 outputs.append(out) | 806 outputs.append(out) |
807 else: | 807 else: |
808 # 'R_LAYERS' node type needs special handling. | 808 # 'R_LAYERS' node type needs special handling. |
809 # outputs of 'R_LAYERS' are callable even if not seen in UI. | 809 # outputs of 'R_LAYERS' are callable even if not seen in UI. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
848 if input.type == out.type or node.type == 'REROUTE': | 848 if input.type == out.type or node.type == 'REROUTE': |
849 if replace or not input.is_linked: | 849 if replace or not input.is_linked: |
850 links.new(out, input) | 850 links.new(out, input) |
851 if not use_node_name and not use_outputs_nam es: | 851 if not use_node_name and not use_outputs_nam es: |
852 doit = False | 852 doit = False |
853 break | 853 break |
854 ········ | 854 ········ |
855 return {'FINISHED'} | 855 return {'FINISHED'} |
856 | 856 |
857 | 857 |
858 class AlignNodes(bpy.types.Operator): | 858 class AlignNodes(bpy.types.Operator): |
ideasman42
2013/03/27 00:16:46
*picky* - again, this would benefit from using 2d
| |
859 bl_idname = "node.align_nodes" | 859 bl_idname = "node.align_nodes" |
860 bl_label = "Align nodes" | 860 bl_label = "Align nodes" |
861 bl_options = {'REGISTER', 'UNDO'} | 861 bl_options = {'REGISTER', 'UNDO'} |
862 ···· | 862 ···· |
863 # option: 'Vertically', 'Horizontally' | 863 # option: 'Vertically', 'Horizontally' |
864 option = StringProperty() | 864 option = StringProperty() |
865 ···· | 865 ···· |
866 @classmethod | 866 @classmethod |
867 def poll(cls, context): | 867 def poll(cls, context): |
868 space = context.space_data | 868 space = context.space_data |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
966 ···· | 966 ···· |
967 # reselect selected frames | 967 # reselect selected frames |
968 for i in frames_reselect: | 968 for i in frames_reselect: |
969 nodes[i].select = True | 969 nodes[i].select = True |
970 # restore active node | 970 # restore active node |
971 nodes.active = active | 971 nodes.active = active |
972 ········ | 972 ········ |
973 return {'FINISHED'} | 973 return {'FINISHED'} |
974 | 974 |
975 | 975 |
976 class SelectParentChildren(bpy.types.Operator): | 976 class SelectParentChildren(bpy.types.Operator): |
ideasman42
2013/03/27 00:16:46
This could be added into blenders C code, seems ge
| |
977 bl_idname = "node.select_parent_child" | 977 bl_idname = "node.select_parent_child" |
978 bl_label = "Select Parent or Children" | 978 bl_label = "Select Parent or Children" |
979 bl_options = {'REGISTER', 'UNDO'} | 979 bl_options = {'REGISTER', 'UNDO'} |
980 ···· | 980 ···· |
981 # option: 'Parent', 'Children' | 981 # option: 'Parent', 'Children' |
982 option = StringProperty() | 982 option = StringProperty() |
983 ···· | 983 ···· |
984 @classmethod | 984 @classmethod |
985 def poll(cls, context): | 985 def poll(cls, context): |
986 space = context.space_data | 986 space = context.space_data |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1486 | 1486 |
1487 def unregister(): | 1487 def unregister(): |
1488 bpy.utils.unregister_module(__name__) | 1488 bpy.utils.unregister_module(__name__) |
1489 bpy.types.NODE_MT_select.remove(select_parent_children_buttons) | 1489 bpy.types.NODE_MT_select.remove(select_parent_children_buttons) |
1490 for km, kmi in addon_keymaps: | 1490 for km, kmi in addon_keymaps: |
1491 km.keymap_items.remove(kmi) | 1491 km.keymap_items.remove(kmi) |
1492 addon_keymaps.clear() | 1492 addon_keymaps.clear() |
1493 | 1493 |
1494 if __name__ == "__main__": | 1494 if __name__ == "__main__": |
1495 register() | 1495 register() |
1496 | |
OLD | NEW |