Tool System: use categories for tool identifiers
[blender.git] / release / scripts / startup / nodeitems_builtins.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 import nodeitems_utils
22 from nodeitems_utils import (
23     NodeCategory,
24     NodeItem,
25     NodeItemCustom,
26 )
27
28
29 # Subclasses for standard node types
30
31 class SortedNodeCategory(NodeCategory):
32     def __init__(self, identifier, name, description="", items=None):
33         # for builtin nodes the convention is to sort by name
34         if isinstance(items, list):
35             items = sorted(items, key=lambda item: item.label.lower())
36
37         super().__init__(identifier, name, description, items)
38
39
40 class CompositorNodeCategory(SortedNodeCategory):
41     @classmethod
42     def poll(cls, context):
43         return (context.space_data.tree_type == 'CompositorNodeTree')
44
45
46 class ShaderNodeCategory(SortedNodeCategory):
47     @classmethod
48     def poll(cls, context):
49         return (context.space_data.tree_type == 'ShaderNodeTree')
50
51
52 class TextureNodeCategory(SortedNodeCategory):
53     @classmethod
54     def poll(cls, context):
55         return context.space_data.tree_type == 'TextureNodeTree'
56
57
58 # menu entry for node group tools
59 def group_tools_draw(self, layout, context):
60     layout.operator("node.group_make")
61     layout.operator("node.group_ungroup")
62     layout.separator()
63
64
65 # maps node tree type to group node type
66 node_tree_group_type = {
67     'CompositorNodeTree': 'CompositorNodeGroup',
68     'ShaderNodeTree': 'ShaderNodeGroup',
69     'TextureNodeTree': 'TextureNodeGroup',
70 }
71
72
73 # generic node group items generator for shader, compositor and texture node groups
74 def node_group_items(context):
75     if context is None:
76         return
77     space = context.space_data
78     if not space:
79         return
80     ntree = space.edit_tree
81     if not ntree:
82         return
83
84     yield NodeItemCustom(draw=group_tools_draw)
85
86     def contains_group(nodetree, group):
87         if nodetree == group:
88             return True
89         else:
90             for node in nodetree.nodes:
91                 if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
92                     if contains_group(node.node_tree, group):
93                         return True
94         return False
95
96     for group in context.blend_data.node_groups:
97         if group.bl_idname != ntree.bl_idname:
98             continue
99         # filter out recursive groups
100         if contains_group(group, ntree):
101             continue
102
103         yield NodeItem(node_tree_group_type[group.bl_idname],
104                        group.name,
105                        {"node_tree": "bpy.data.node_groups[%r]" % group.name})
106
107
108 # only show input/output nodes inside node groups
109 def group_input_output_item_poll(context):
110     space = context.space_data
111     if space.edit_tree in bpy.data.node_groups.values():
112         return True
113     return False
114
115
116 # only show input/output nodes when editing line style node trees
117 def line_style_shader_nodes_poll(context):
118     snode = context.space_data
119     return (snode.tree_type == 'ShaderNodeTree' and
120             snode.shader_type == 'LINESTYLE')
121
122
123 # only show nodes working in world node trees
124 def world_shader_nodes_poll(context):
125     snode = context.space_data
126     return (snode.tree_type == 'ShaderNodeTree' and
127             snode.shader_type == 'WORLD')
128
129
130 # only show nodes working in object node trees
131 def object_shader_nodes_poll(context):
132     snode = context.space_data
133     return (snode.tree_type == 'ShaderNodeTree' and
134             snode.shader_type == 'OBJECT')
135
136
137 def cycles_shader_nodes_poll(context):
138     return context.engine == 'CYCLES'
139
140
141 def eevee_shader_nodes_poll(context):
142     return context.engine == 'BLENDER_EEVEE'
143
144
145 def eevee_cycles_shader_nodes_poll(context):
146     return (cycles_shader_nodes_poll(context) or
147             eevee_shader_nodes_poll(context))
148
149
150 def object_cycles_shader_nodes_poll(context):
151     return (object_shader_nodes_poll(context) and
152             cycles_shader_nodes_poll(context))
153
154
155 def object_eevee_shader_nodes_poll(context):
156     return (object_shader_nodes_poll(context) and
157             eevee_shader_nodes_poll(context))
158
159
160 def object_eevee_cycles_shader_nodes_poll(context):
161     return (object_shader_nodes_poll(context) and
162             eevee_cycles_shader_nodes_poll(context))
163
164
165 # All standard node categories currently used in nodes.
166
167 shader_node_categories = [
168     # Shader Nodes (Cycles and Eevee)
169     ShaderNodeCategory("SH_NEW_INPUT", "Input", items=[
170         NodeItem("ShaderNodeTexCoord"),
171         NodeItem("ShaderNodeAttribute"),
172         NodeItem("ShaderNodeLightPath"),
173         NodeItem("ShaderNodeFresnel"),
174         NodeItem("ShaderNodeLayerWeight"),
175         NodeItem("ShaderNodeRGB"),
176         NodeItem("ShaderNodeValue"),
177         NodeItem("ShaderNodeTangent"),
178         NodeItem("ShaderNodeNewGeometry"),
179         NodeItem("ShaderNodeWireframe"),
180         NodeItem("ShaderNodeBevel"),
181         NodeItem("ShaderNodeAmbientOcclusion"),
182         NodeItem("ShaderNodeObjectInfo"),
183         NodeItem("ShaderNodeHairInfo"),
184         NodeItem("ShaderNodeParticleInfo"),
185         NodeItem("ShaderNodeCameraData"),
186         NodeItem("ShaderNodeUVMap"),
187         NodeItem("ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll),
188         NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
189     ]),
190     ShaderNodeCategory("SH_NEW_OUTPUT", "Output", items=[
191         NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll),
192         NodeItem("ShaderNodeOutputLight", poll=object_cycles_shader_nodes_poll),
193         NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
194         NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
195         NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
196     ]),
197     ShaderNodeCategory("SH_NEW_SHADER", "Shader", items=[
198         NodeItem("ShaderNodeMixShader", poll=eevee_cycles_shader_nodes_poll),
199         NodeItem("ShaderNodeAddShader", poll=eevee_cycles_shader_nodes_poll),
200         NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll),
201         NodeItem("ShaderNodeBsdfPrincipled", poll=object_eevee_cycles_shader_nodes_poll),
202         NodeItem("ShaderNodeBsdfGlossy", poll=object_eevee_cycles_shader_nodes_poll),
203         NodeItem("ShaderNodeBsdfTransparent", poll=object_eevee_cycles_shader_nodes_poll),
204         NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll),
205         NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll),
206         NodeItem("ShaderNodeBsdfTranslucent", poll=object_eevee_cycles_shader_nodes_poll),
207         NodeItem("ShaderNodeBsdfAnisotropic", poll=object_cycles_shader_nodes_poll),
208         NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll),
209         NodeItem("ShaderNodeBsdfToon", poll=object_cycles_shader_nodes_poll),
210         NodeItem("ShaderNodeSubsurfaceScattering", poll=object_eevee_cycles_shader_nodes_poll),
211         NodeItem("ShaderNodeEmission", poll=object_eevee_cycles_shader_nodes_poll),
212         NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll),
213         NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll),
214         NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll),
215         NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll),
216         NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll),
217         NodeItem("ShaderNodeVolumePrincipled"),
218         NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll),
219         NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll)
220     ]),
221     ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[
222         NodeItem("ShaderNodeTexImage"),
223         NodeItem("ShaderNodeTexEnvironment"),
224         NodeItem("ShaderNodeTexSky"),
225         NodeItem("ShaderNodeTexNoise"),
226         NodeItem("ShaderNodeTexWave"),
227         NodeItem("ShaderNodeTexVoronoi"),
228         NodeItem("ShaderNodeTexMusgrave"),
229         NodeItem("ShaderNodeTexGradient"),
230         NodeItem("ShaderNodeTexMagic"),
231         NodeItem("ShaderNodeTexChecker"),
232         NodeItem("ShaderNodeTexBrick"),
233         NodeItem("ShaderNodeTexPointDensity"),
234         NodeItem("ShaderNodeTexIES"),
235     ]),
236     ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[
237         NodeItem("ShaderNodeMixRGB"),
238         NodeItem("ShaderNodeRGBCurve"),
239         NodeItem("ShaderNodeInvert"),
240         NodeItem("ShaderNodeLightFalloff"),
241         NodeItem("ShaderNodeHueSaturation"),
242         NodeItem("ShaderNodeGamma"),
243         NodeItem("ShaderNodeBrightContrast"),
244     ]),
245     ShaderNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[
246         NodeItem("ShaderNodeMapping"),
247         NodeItem("ShaderNodeBump"),
248         NodeItem("ShaderNodeDisplacement"),
249         NodeItem("ShaderNodeVectorDisplacement"),
250         NodeItem("ShaderNodeNormalMap"),
251         NodeItem("ShaderNodeNormal"),
252         NodeItem("ShaderNodeVectorCurve"),
253         NodeItem("ShaderNodeVectorTransform"),
254     ]),
255     ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[
256         NodeItem("ShaderNodeMath"),
257         NodeItem("ShaderNodeValToRGB"),
258         NodeItem("ShaderNodeRGBToBW"),
259         NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll),
260         NodeItem("ShaderNodeVectorMath"),
261         NodeItem("ShaderNodeSeparateRGB"),
262         NodeItem("ShaderNodeCombineRGB"),
263         NodeItem("ShaderNodeSeparateXYZ"),
264         NodeItem("ShaderNodeCombineXYZ"),
265         NodeItem("ShaderNodeSeparateHSV"),
266         NodeItem("ShaderNodeCombineHSV"),
267         NodeItem("ShaderNodeWavelength"),
268         NodeItem("ShaderNodeBlackbody"),
269     ]),
270     ShaderNodeCategory("SH_NEW_SCRIPT", "Script", items=[
271         NodeItem("ShaderNodeScript"),
272     ]),
273     ShaderNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items),
274     ShaderNodeCategory("SH_NEW_LAYOUT", "Layout", items=[
275         NodeItem("NodeFrame"),
276         NodeItem("NodeReroute"),
277     ]),
278 ]
279
280 compositor_node_categories = [
281     # Compositor Nodes
282     CompositorNodeCategory("CMP_INPUT", "Input", items=[
283         NodeItem("CompositorNodeRLayers"),
284         NodeItem("CompositorNodeImage"),
285         NodeItem("CompositorNodeMovieClip"),
286         NodeItem("CompositorNodeMask"),
287         NodeItem("CompositorNodeRGB"),
288         NodeItem("CompositorNodeValue"),
289         NodeItem("CompositorNodeTexture"),
290         NodeItem("CompositorNodeBokehImage"),
291         NodeItem("CompositorNodeTime"),
292         NodeItem("CompositorNodeTrackPos"),
293         NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
294     ]),
295     CompositorNodeCategory("CMP_OUTPUT", "Output", items=[
296         NodeItem("CompositorNodeComposite"),
297         NodeItem("CompositorNodeViewer"),
298         NodeItem("CompositorNodeSplitViewer"),
299         NodeItem("CompositorNodeOutputFile"),
300         NodeItem("CompositorNodeLevels"),
301         NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
302     ]),
303     CompositorNodeCategory("CMP_OP_COLOR", "Color", items=[
304         NodeItem("CompositorNodeMixRGB"),
305         NodeItem("CompositorNodeAlphaOver"),
306         NodeItem("CompositorNodeInvert"),
307         NodeItem("CompositorNodeCurveRGB"),
308         NodeItem("CompositorNodeHueSat"),
309         NodeItem("CompositorNodeColorBalance"),
310         NodeItem("CompositorNodeHueCorrect"),
311         NodeItem("CompositorNodeBrightContrast"),
312         NodeItem("CompositorNodeGamma"),
313         NodeItem("CompositorNodeColorCorrection"),
314         NodeItem("CompositorNodeTonemap"),
315         NodeItem("CompositorNodeZcombine"),
316     ]),
317     CompositorNodeCategory("CMP_CONVERTOR", "Converter", items=[
318         NodeItem("CompositorNodeMath"),
319         NodeItem("CompositorNodeValToRGB"),
320         NodeItem("CompositorNodeSetAlpha"),
321         NodeItem("CompositorNodePremulKey"),
322         NodeItem("CompositorNodeIDMask"),
323         NodeItem("CompositorNodeRGBToBW"),
324         NodeItem("CompositorNodeSepRGBA"),
325         NodeItem("CompositorNodeCombRGBA"),
326         NodeItem("CompositorNodeSepHSVA"),
327         NodeItem("CompositorNodeCombHSVA"),
328         NodeItem("CompositorNodeSepYUVA"),
329         NodeItem("CompositorNodeCombYUVA"),
330         NodeItem("CompositorNodeSepYCCA"),
331         NodeItem("CompositorNodeCombYCCA"),
332         NodeItem("CompositorNodeSwitchView"),
333     ]),
334     CompositorNodeCategory("CMP_OP_FILTER", "Filter", items=[
335         NodeItem("CompositorNodeBlur"),
336         NodeItem("CompositorNodeBilateralblur"),
337         NodeItem("CompositorNodeDilateErode"),
338         NodeItem("CompositorNodeDespeckle"),
339         NodeItem("CompositorNodeFilter"),
340         NodeItem("CompositorNodeBokehBlur"),
341         NodeItem("CompositorNodeVecBlur"),
342         NodeItem("CompositorNodeDefocus"),
343         NodeItem("CompositorNodeGlare"),
344         NodeItem("CompositorNodeInpaint"),
345         NodeItem("CompositorNodeDBlur"),
346         NodeItem("CompositorNodePixelate"),
347         NodeItem("CompositorNodeSunBeams"),
348     ]),
349     CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[
350         NodeItem("CompositorNodeNormal"),
351         NodeItem("CompositorNodeMapValue"),
352         NodeItem("CompositorNodeMapRange"),
353         NodeItem("CompositorNodeNormalize"),
354         NodeItem("CompositorNodeCurveVec"),
355     ]),
356     CompositorNodeCategory("CMP_MATTE", "Matte", items=[
357         NodeItem("CompositorNodeKeying"),
358         NodeItem("CompositorNodeKeyingScreen"),
359         NodeItem("CompositorNodeChannelMatte"),
360         NodeItem("CompositorNodeColorSpill"),
361         NodeItem("CompositorNodeBoxMask"),
362         NodeItem("CompositorNodeEllipseMask"),
363         NodeItem("CompositorNodeLumaMatte"),
364         NodeItem("CompositorNodeDiffMatte"),
365         NodeItem("CompositorNodeDistanceMatte"),
366         NodeItem("CompositorNodeChromaMatte"),
367         NodeItem("CompositorNodeColorMatte"),
368         NodeItem("CompositorNodeDoubleEdgeMask"),
369         NodeItem("CompositorNodeCryptomatte"),
370     ]),
371     CompositorNodeCategory("CMP_DISTORT", "Distort", items=[
372         NodeItem("CompositorNodeScale"),
373         NodeItem("CompositorNodeLensdist"),
374         NodeItem("CompositorNodeMovieDistortion"),
375         NodeItem("CompositorNodeTranslate"),
376         NodeItem("CompositorNodeRotate"),
377         NodeItem("CompositorNodeFlip"),
378         NodeItem("CompositorNodeCrop"),
379         NodeItem("CompositorNodeDisplace"),
380         NodeItem("CompositorNodeMapUV"),
381         NodeItem("CompositorNodeTransform"),
382         NodeItem("CompositorNodeStabilize"),
383         NodeItem("CompositorNodePlaneTrackDeform"),
384         NodeItem("CompositorNodeCornerPin"),
385     ]),
386     CompositorNodeCategory("CMP_GROUP", "Group", items=node_group_items),
387     CompositorNodeCategory("CMP_LAYOUT", "Layout", items=[
388         NodeItem("NodeFrame"),
389         NodeItem("NodeReroute"),
390         NodeItem("CompositorNodeSwitch"),
391     ]),
392 ]
393
394 texture_node_categories = [
395     # Texture Nodes
396     TextureNodeCategory("TEX_INPUT", "Input", items=[
397         NodeItem("TextureNodeCurveTime"),
398         NodeItem("TextureNodeCoordinates"),
399         NodeItem("TextureNodeTexture"),
400         NodeItem("TextureNodeImage"),
401         NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
402     ]),
403     TextureNodeCategory("TEX_OUTPUT", "Output", items=[
404         NodeItem("TextureNodeOutput"),
405         NodeItem("TextureNodeViewer"),
406         NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
407     ]),
408     TextureNodeCategory("TEX_OP_COLOR", "Color", items=[
409         NodeItem("TextureNodeMixRGB"),
410         NodeItem("TextureNodeCurveRGB"),
411         NodeItem("TextureNodeInvert"),
412         NodeItem("TextureNodeHueSaturation"),
413         NodeItem("TextureNodeCompose"),
414         NodeItem("TextureNodeDecompose"),
415     ]),
416     TextureNodeCategory("TEX_PATTERN", "Pattern", items=[
417         NodeItem("TextureNodeChecker"),
418         NodeItem("TextureNodeBricks"),
419     ]),
420     TextureNodeCategory("TEX_TEXTURE", "Textures", items=[
421         NodeItem("TextureNodeTexNoise"),
422         NodeItem("TextureNodeTexDistNoise"),
423         NodeItem("TextureNodeTexClouds"),
424         NodeItem("TextureNodeTexBlend"),
425         NodeItem("TextureNodeTexVoronoi"),
426         NodeItem("TextureNodeTexMagic"),
427         NodeItem("TextureNodeTexMarble"),
428         NodeItem("TextureNodeTexWood"),
429         NodeItem("TextureNodeTexMusgrave"),
430         NodeItem("TextureNodeTexStucci"),
431     ]),
432     TextureNodeCategory("TEX_CONVERTOR", "Converter", items=[
433         NodeItem("TextureNodeMath"),
434         NodeItem("TextureNodeValToRGB"),
435         NodeItem("TextureNodeRGBToBW"),
436         NodeItem("TextureNodeValToNor"),
437         NodeItem("TextureNodeDistance"),
438     ]),
439     TextureNodeCategory("TEX_DISTORT", "Distort", items=[
440         NodeItem("TextureNodeScale"),
441         NodeItem("TextureNodeTranslate"),
442         NodeItem("TextureNodeRotate"),
443         NodeItem("TextureNodeAt"),
444     ]),
445     TextureNodeCategory("TEX_GROUP", "Group", items=node_group_items),
446     TextureNodeCategory("TEX_LAYOUT", "Layout", items=[
447         NodeItem("NodeFrame"),
448         NodeItem("NodeReroute"),
449     ]),
450 ]
451
452
453 def register():
454     nodeitems_utils.register_node_categories('SHADER', shader_node_categories)
455     nodeitems_utils.register_node_categories('COMPOSITING', compositor_node_categories)
456     nodeitems_utils.register_node_categories('TEXTURE', texture_node_categories)
457
458
459 def unregister():
460     nodeitems_utils.unregister_node_categories('SHADER')
461     nodeitems_utils.unregister_node_categories('COMPOSITING')
462     nodeitems_utils.unregister_node_categories('TEXTURE')
463
464
465 if __name__ == "__main__":
466     register()