forked from strike-digital/NGviewer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNGviewer beta 1_4.py
284 lines (230 loc) · 11.6 KB
/
NGviewer beta 1_4.py
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
bl_info = {
"name": "NGviewer在 3D 视口中显示节点组的输入",
"author": "Andrew Stevenson,cp",
"version": (1, 4),
"blender": (2, 80, 0),
"location": "View3D > N-Panel > tools >NGviewer",
"doc_url":"https://github.com/strike-digital",
"description": "easily edit node group perameters from the 3D view",
"category": "Node",
}
import bpy
import nodeitems_utils
from bpy.types import Panel
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
EnumProperty,
PointerProperty,
)
#Feel free to change this but it would be great for me if you would consider buying the addon first ;)
is_trial = False
def draw_trial(col):
row = col.row(align=True)
row.operator('wm.url_open',
text="",
icon='FUND',
emboss=False).url = "https://gumroad.com/l/qWuvv"
row.alert = True
row.label(text="Trial Version")
# 保存字符串引用的全局变量
enum_strings = []
def get_node_group_names(self, context):
node_group_names = []
#nodes = bpy.data.materials[ng_tool.material].node_tree.nodes
nodes = bpy.context.active_object.active_material.node_tree.nodes
for node in nodes:
if node.type == 'GROUP'or node.bl_idname == 'ShaderNodeOutputMaterial': #node.name == 'Material Output':
if node.type == 'GROUP':
if node.node_tree:
node_group_name = node.node_tree.name # 获取节点组的名字
else:
node_group_name = "节点树丢失了"
else:
node_group_name = "整个材质"
full_name = f"{node.name} ({node_group_name})"
node_group_names.append((full_name, full_name, ""))
# 将字符串保存到全局变量中,不然无法显示中文
enum_strings.append(full_name)
return node_group_names
def draw_sockets(self, context):#绘制节点输入框,显示节点组的输入端口信息
layout = self.layout
ng_tool = bpy.context.scene.ng_tool
node_tree = bpy.context.active_object.active_material.node_tree
selected_option = ng_tool.selected_node_group
if selected_option:
node_name, group_name = selected_option.split(' (')
node = bpy.context.active_object.active_material.node_tree.nodes.get(node_name)
if node:
group_node = node_tree.nodes[node_name]
layout.label(text="Inputs:")
if ng_tool.edit_node_links:#如果编辑节点链接被启用用bl默认的方式显示节点组,名字会自动翻译
for socket in group_node.inputs:
if socket.is_linked:
col = layout.column(align = True)
boxcol = col.box().column(align = True)# 在列中创建一个框,并在框内创建一个列
row = boxcol.column()# 在框列中创建一行
#row.label(text = socket.name)
row.template_node_view(node_tree, group_node, socket)
else:
boxcol = layout.column(align = True)# 在布局中创建一个新列
boxcol.template_node_view(node_tree, group_node, socket) # 使用节点视图模板绘制节点输入
else:# 如果编辑节点链接未启用
for input in group_node.inputs:
if input.is_linked:
linked_nodes = []
for link in input.links:
linked_nodes.append(link.from_node.name)
if linked_nodes:
connected_nodes_text = ", ".join(linked_nodes)
col = layout.column(align = True)
col.label(text =input.name+ f"【Link:{connected_nodes_text}】") # 在行中添加标签,显示输入名称
elif input.hide_value :
col.label(text =input.name+ "【Hide】")
else:
if input.type == "RGBA":
layout.prop(input, 'default_value', text=input.name)
col = layout.column(align = True)
else:
col.prop(input, 'default_value', text=input.name)
class NodeGroupSettings(bpy.types.PropertyGroup):
selected_node_group: bpy.props.EnumProperty(
items=get_node_group_names,
)
edit_node_links: BoolProperty(
name="切换显示方式(以BL默认方式显示)",
description="取消勾选后以自定义方式排布!",
default=True,
)
class PANEL_PT_ng_node_panel1(Panel):
"""Creates a Panel in the Tool panel"""
bl_space_type = "VIEW_3D"
bl_idname = "PANEL_PT_ng_node_panel1"
bl_region_type = "UI"
bl_label = "NGviewer"
bl_category = "材质"
# ng_tool = bpy.context.scene.ng_tool
# if ng_tool.category is "Tool":
# bl_category = "Tool"
# else:
# bl_category = "NGviewer"
def draw(self, context):
ng_tool = bpy.context.scene.ng_tool
layout = self.layout
if is_trial:
draw_trial(layout)
try:
#check for active object
if bpy.context.active_object is not None:
material_slots = bpy.context.active_object.material_slots
#check for material slots
if len(material_slots) != 0:
#check for materials
#if bpy.data.materials[ng_tool.material] is not None and bpy.context.active_object.active_material is not None:
if bpy.context.active_object.active_material is not None:
col = layout.column(align = True)
row = col.split(factor=0.3, align=True)
row.scale_y = 1.2
row.scale_x = 1.13
#row.prop(ng_tool, "material")
row.popover(panel="NODE_PT_material_slots")
row.label(text=bpy.context.active_object.active_material.name)
# row.prop(ng_tool, "show_material_settings", text="", icon='PREFERENCES')
# #material settings panel
# if ng_tool.show_material_settings:
# box = col.box()
# boxcol = box.column(align = True)
# boxcol.prop(ng_tool, "show_non_group_materials")
# boxcol.prop(ng_tool, "grumpy")
col.separator()
#check for node tree
#if bpy.data.materials[ng_tool.material].node_tree is not None:
if bpy.context.active_object.active_material.node_tree is not None:
node_groups = []
#nodes = bpy.data.materials[ng_tool.material].node_tree.nodes
nodes = bpy.context.active_object.active_material.node_tree.nodes
#check for node groups
for node in nodes:
if node.type == 'GROUP':
node_groups.append(node.name)
if len(node_groups) != 0:
#node_tree = bpy.data.materials[ng_tool.material].node_tree
#group_node = node_tree.nodes[ng_tool.node_group]
#def_input_boxes(group_node)
row = col.row(align = True)
row.scale_y = 1.2
row.scale_x = 1.13
#row.prop(ng_tool, "node_group", icon = "NODETREE")
row.prop(ng_tool, "selected_node_group", text="", icon = "NODETREE")
# #row.prop(ng_tool, "show_group_settings", text="", icon='PREFERENCES')
# #group settings panel
# if ng_tool.show_group_settings:
box = col.box()
boxcol = box.column(align = True)
#boxcol.prop(ng_tool, "show_non_input_groups")
boxcol.prop(ng_tool, "edit_node_links")
draw_sockets(self,context)
else:
layout.label(text = "No node groups in this material " )
else:
layout.label(text = "No active node tree " )
# else:
# layout.label(text = "No active material " + face)
else:
layout.label(text = "No material slots " )
else:
layout.label(text = "No object selected " )
except KeyError:
layout.label(text = "Please select a material ")
class NG_OT_add_box_separator(bpy.types.Operator):
"""add a new box including the active group node input"""
bl_label = "New box group"
bl_idname = "object.new_box"
bl_description = "add a new box including the active group node input"
bl_options = {"REGISTER", "UNDO"}
name : StringProperty(
name = "Box title",
default = "",
description = "Box title",)
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, "name")
def execute(self, context):
bpy.ops.node.tree_socket_add(in_out='IN')
bpy.ops.node.tree_socket_move(direction='UP')
node = bpy.context.active_object.active_material.node_tree.nodes.active
if node.type == 'GROUP':
#stupid hack becuase I can't figure out how to get active node group name
for group in bpy.data.node_groups:
if len(group.inputs) == len(node.inputs) and group.inputs[0].name == node.inputs[0].name:
name = group.name
index = bpy.data.node_groups[name].active_input.numerator
break
node.inputs[index].hide_value = True
if self.name != "":
node.inputs[index].name = self.name
bpy.data.node_groups[name].inputs[index].name = self.name
return{'FINISHED'}
classes = (
NodeGroupSettings,
PANEL_PT_ng_node_panel1,
#NGPreferences,
#PANEL_PT_ng_node_panel,
NG_OT_add_box_separator,
#MySettings
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.ng_tool = bpy.props.PointerProperty(type=NodeGroupSettings)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.ng_tool
if __name__ == "__main__":
register()