This repository was archived by the owner on Dec 1, 2023. It is now read-only.
forked from williamchange/node_tabber
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
174 lines (130 loc) · 4.54 KB
/
utils.py
File metadata and controls
174 lines (130 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import json
from bpy import context
from pathlib import Path
ADDON_FOLDER = Path(__file__).parent
TALLY_FOLDER = ADDON_FOLDER / "tally_cache"
# Create Folder for caching node tallies
if not TALLY_FOLDER.exists():
TALLY_FOLDER.mkdir()
nodes_with_op_symbols = [
"ShaderNodeMath",
"CompositorNodeMath",
"TextureNodeMath",
"ShaderNodeVectorMath",
"FunctionNodeBooleanMath",
"FunctionNodeCompare",
]
op_symbol_dict = {
"Add" : "+",
"Subtract" : "-",
"Multiply" : "*",
"Divide" : "/",
"Multiply Add" : "*+",
"Power" : "^",
"Exponent" : "e^",
"Less Than" : "<",
"Less Than or Equal" : "<=",
"Greater Than" : ">",
"Greater Than or Equal" : ">=",
"Scale" : "*",
"Cross Product" : "x",
"And" : "^",
"Or" : "v",
"Not" : "!",
"Not And" : "!^",
"Nor" : "!v",
"Equal" : "=",
"Not Equal" : "!=",
"Imply" : "->",
}
def add_op_symbols(operation):
op_symbol = op_symbol_dict.get(operation)
if op_symbol is not None:
return f"{operation} ({op_symbol})"
return operation
def fetch_tally_path(tree_type):
return Path(TALLY_FOLDER, f'{tree_type}.json')
def fetch_user_prefs(attr_id=None):
prefs = context.preferences.addons[__package__].preferences
if attr_id is None:
return prefs
else:
return getattr(prefs, attr_id)
def sort_enum_items(tree_type, items):
path = fetch_tally_path(tree_type)
if path.exists():
with open(path, "r") as f:
tally_dict = json.load(f)
items.sort(key=lambda x : tally_dict.get(x[0], 0), reverse=True)
def update_tally(context, entry):
prefs = fetch_user_prefs()
tree_type = context.space_data.tree_type
path = fetch_tally_path(tree_type)
if path.exists():
with open(path, "r") as f:
tally_dict = json.load(f)
else:
tally_dict = {}
tally_dict[entry] = min(tally_dict.get(entry, 0) + 1, prefs.tally_max)
with open(path, "w") as f:
json.dump(tally_dict, f, indent=4)
def in_nodegroup(context):
current_tree = context.space_data.edit_tree
node_groups = context.blend_data.node_groups
return current_tree in node_groups.values()
def fetch_active_nodetree(context):
edit_tree = context.space_data.edit_tree
node_tree = context.space_data.node_tree
if edit_tree is not None:
return edit_tree
else:
return node_tree
def create_node(context, node_type=None, *_, node_tree=None, **settings):
tree = fetch_active_nodetree(context)
node = tree.nodes.new(type=node_type)
prefs = fetch_user_prefs()
try:
if settings is not None:
for key, value in settings.items():
setattr(node, key, value)
if node_tree is not None:
node.node_tree = context.blend_data.node_groups.get(node_tree)
node.show_options = not prefs.hide_group_selector
node.location = context.space_data.cursor_location
return make_selection(context, nodes=(node,))
except Exception as error:
tree.nodes.remove(node)
raise error
def create_zone(context, *_, input_type=None, output_type=None, offset=(150, 0), **settings,):
tree = fetch_active_nodetree(context)
input_node = tree.nodes.new(type=input_type)
output_node = tree.nodes.new(type=output_type)
try:
# Simulation input must be paired with the output.
input_node.pair_with_output(output_node)
for node in (input_node, output_node):
node.location = context.space_data.cursor_location
x_offset, y_offset = offset
input_node.location.x -= x_offset
input_node.location.y -= y_offset
output_node.location.x += x_offset
output_node.location.y += y_offset
# Connect geometry sockets by default.
# Get the sockets by their types, because the name is not guaranteed due to i18n.
from_socket = next(s for s in input_node.outputs if s.type == 'GEOMETRY')
to_socket = next(s for s in output_node.inputs if s.type == 'GEOMETRY')
tree.links.new(to_socket, from_socket)
return make_selection(context, nodes=(input_node, output_node))
except Exception as error:
tree.nodes.remove(input_node)
tree.nodes.remove(output_node)
raise error
def make_selection(context, nodes):
tree = fetch_active_nodetree(context)
# select only the new node
for n in tree.nodes:
n.select = False
for n in nodes:
n.select = True
tree.nodes.active = nodes[-1]
return nodes