Export_3ds: Improved distance cue node search
[blender-addons.git] / render_povray / nodes_properties.py
blobace3cba88b423f6798606ed0ae2f528ca6aabd18
1 # SPDX-FileCopyrightText: 2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 """"Nodes based User interface for shaders exported to POV textures."""
6 import bpy
8 from bpy.utils import register_class, unregister_class
9 from bpy.types import NodeSocket, Operator
10 from bpy.props import (
11 StringProperty,
12 FloatVectorProperty,
14 import nodeitems_utils
15 from nodeitems_utils import NodeCategory, NodeItem
17 # ---------------------------------------------------------------- #
18 # Pov Nodes init
19 # ---------------------------------------------------------------- #
20 # -------- Parent node class
21 class ObjectNodeTree(bpy.types.NodeTree):
22 """Povray Material Nodes"""
24 bl_idname = "ObjectNodeTree"
25 bl_label = "Povray Object Nodes"
26 bl_icon = "PLUGIN"
28 @classmethod
29 def poll(cls, context):
30 return context.scene.render.engine == "POVRAY_RENDER"
32 @classmethod
33 def get_from_context(cls, context):
34 ob = context.active_object
35 if ob and ob.type != 'LIGHT':
36 ma = ob.active_material
37 if ma is not None:
38 nt_name = ma.node_tree
39 if nt_name != "":
40 return nt_name, ma, ma
41 return (None, None, None)
43 def update(self):
44 self.refresh = True
47 # -------- Sockets classes
48 class PovraySocketUniversal(NodeSocket):
49 bl_idname = "PovraySocketUniversal"
50 bl_label = "Povray Socket"
51 value_unlimited: bpy.props.FloatProperty(default=0.0)
52 value_0_1: bpy.props.FloatProperty(min=0.0, max=1.0, default=0.0)
53 value_0_10: bpy.props.FloatProperty(min=0.0, max=10.0, default=0.0)
54 value_000001_10: bpy.props.FloatProperty(min=0.000001, max=10.0, default=0.0)
55 value_1_9: bpy.props.IntProperty(min=1, max=9, default=1)
56 value_0_255: bpy.props.IntProperty(min=0, max=255, default=0)
57 percent: bpy.props.FloatProperty(min=0.0, max=100.0, default=0.0)
59 def draw(self, context, layout, node, text):
60 space = context.space_data
61 tree = space.edit_tree
62 links = tree.links
63 if self.is_linked:
64 value = []
65 for link in links:
66 # inps = link.to_node.inputs
67 linked_inps = (
68 inp for inp in link.to_node.inputs if link.from_node == node and inp.is_linked
70 for inp in linked_inps:
71 if inp.bl_idname == "PovraySocketFloat_0_1":
72 if (prop := "value_0_1") not in value:
73 value.append(prop)
74 if inp.bl_idname == "PovraySocketFloat_000001_10":
75 if (prop := "value_000001_10") not in value:
76 value.append(prop)
77 if inp.bl_idname == "PovraySocketFloat_0_10":
78 if (prop := "value_0_10") not in value:
79 value.append(prop)
80 if inp.bl_idname == "PovraySocketInt_1_9":
81 if (prop := "value_1_9") not in value:
82 value.append(prop)
83 if inp.bl_idname == "PovraySocketInt_0_255":
84 if (prop := "value_0_255") not in value:
85 value.append(prop)
86 if inp.bl_idname == "PovraySocketFloatUnlimited":
87 if (prop := "value_unlimited") not in value:
88 value.append(prop)
89 if len(value) == 1:
90 layout.prop(self, "%s" % value[0], text=text)
91 else:
92 layout.prop(self, "percent", text="Percent")
93 else:
94 layout.prop(self, "percent", text=text)
96 def draw_color(self, context, node):
97 return (1, 0, 0, 1)
100 class PovraySocketFloat_0_1(NodeSocket):
101 bl_idname = "PovraySocketFloat_0_1"
102 bl_label = "Povray Socket"
103 default_value: bpy.props.FloatProperty(
104 description="Input node Value_0_1", min=0, max=1, default=0
107 def draw(self, context, layout, node, text):
108 if self.is_linked:
109 layout.label(text=text)
110 else:
111 layout.prop(self, "default_value", text=text, slider=True)
113 def draw_color(self, context, node):
114 return (0.5, 0.7, 0.7, 1)
117 class PovraySocketFloat_0_10(NodeSocket):
118 bl_idname = "PovraySocketFloat_0_10"
119 bl_label = "Povray Socket"
120 default_value: bpy.props.FloatProperty(
121 description="Input node Value_0_10", min=0, max=10, default=0
124 def draw(self, context, layout, node, text):
125 if node.bl_idname == "ShaderNormalMapNode" and node.inputs[2].is_linked:
126 layout.label(text="")
127 self.hide_value = True
128 if self.is_linked:
129 layout.label(text=text)
130 else:
131 layout.prop(self, "default_value", text=text, slider=True)
133 def draw_color(self, context, node):
134 return (0.65, 0.65, 0.65, 1)
137 class PovraySocketFloat_10(NodeSocket):
138 bl_idname = "PovraySocketFloat_10"
139 bl_label = "Povray Socket"
140 default_value: bpy.props.FloatProperty(
141 description="Input node Value_10", min=-10, max=10, default=0
144 def draw(self, context, layout, node, text):
145 if node.bl_idname == "ShaderNormalMapNode" and node.inputs[2].is_linked:
146 layout.label(text="")
147 self.hide_value = True
148 if self.is_linked:
149 layout.label(text=text)
150 else:
151 layout.prop(self, "default_value", text=text, slider=True)
153 def draw_color(self, context, node):
154 return (0.65, 0.65, 0.65, 1)
157 class PovraySocketFloatPositive(NodeSocket):
158 bl_idname = "PovraySocketFloatPositive"
159 bl_label = "Povray Socket"
160 default_value: bpy.props.FloatProperty(
161 description="Input Node Value Positive", min=0.0, default=0
164 def draw(self, context, layout, node, text):
165 if self.is_linked:
166 layout.label(text=text)
167 else:
168 layout.prop(self, "default_value", text=text, slider=True)
170 def draw_color(self, context, node):
171 return (0.045, 0.005, 0.136, 1)
174 class PovraySocketFloat_000001_10(NodeSocket):
175 bl_idname = "PovraySocketFloat_000001_10"
176 bl_label = "Povray Socket"
177 default_value: bpy.props.FloatProperty(min=0.000001, max=10, default=0.000001)
179 def draw(self, context, layout, node, text):
180 if self.is_output or self.is_linked:
181 layout.label(text=text)
182 else:
183 layout.prop(self, "default_value", text=text, slider=True)
185 def draw_color(self, context, node):
186 return (1, 0, 0, 1)
189 class PovraySocketFloatUnlimited(NodeSocket):
190 bl_idname = "PovraySocketFloatUnlimited"
191 bl_label = "Povray Socket"
192 default_value: bpy.props.FloatProperty(default=0.0)
194 def draw(self, context, layout, node, text):
195 if self.is_linked:
196 layout.label(text=text)
197 else:
198 layout.prop(self, "default_value", text=text, slider=True)
200 def draw_color(self, context, node):
201 return (0.7, 0.7, 1, 1)
204 class PovraySocketInt_1_9(NodeSocket):
205 bl_idname = "PovraySocketInt_1_9"
206 bl_label = "Povray Socket"
207 default_value: bpy.props.IntProperty(
208 description="Input node Value_1_9", min=1, max=9, default=6
211 def draw(self, context, layout, node, text):
212 if self.is_linked:
213 layout.label(text=text)
214 else:
215 layout.prop(self, "default_value", text=text)
217 def draw_color(self, context, node):
218 return (1, 0.7, 0.7, 1)
221 class PovraySocketInt_0_256(NodeSocket):
222 bl_idname = "PovraySocketInt_0_256"
223 bl_label = "Povray Socket"
224 default_value: bpy.props.IntProperty(min=0, max=255, default=0)
226 def draw(self, context, layout, node, text):
227 if self.is_linked:
228 layout.label(text=text)
229 else:
230 layout.prop(self, "default_value", text=text)
232 def draw_color(self, context, node):
233 return (0.5, 0.5, 0.5, 1)
236 class PovraySocketPattern(NodeSocket):
237 bl_idname = "PovraySocketPattern"
238 bl_label = "Povray Socket"
240 default_value: bpy.props.EnumProperty(
241 name="Pattern",
242 description="Select the pattern",
243 items=(
244 ("boxed", "Boxed", ""),
245 ("brick", "Brick", ""),
246 ("cells", "Cells", ""),
247 ("checker", "Checker", ""),
248 ("granite", "Granite", ""),
249 ("leopard", "Leopard", ""),
250 ("marble", "Marble", ""),
251 ("onion", "Onion", ""),
252 ("planar", "Planar", ""),
253 ("quilted", "Quilted", ""),
254 ("ripples", "Ripples", ""),
255 ("radial", "Radial", ""),
256 ("spherical", "Spherical", ""),
257 ("spotted", "Spotted", ""),
258 ("waves", "Waves", ""),
259 ("wood", "Wood", ""),
260 ("wrinkles", "Wrinkles", ""),
262 default="granite",
265 def draw(self, context, layout, node, text):
266 if self.is_output or self.is_linked:
267 layout.label(text="Pattern")
268 else:
269 layout.prop(self, "default_value", text=text)
271 def draw_color(self, context, node):
272 return (1, 1, 1, 1)
275 class PovraySocketColor(NodeSocket):
276 bl_idname = "PovraySocketColor"
277 bl_label = "Povray Socket"
279 default_value: FloatVectorProperty(
280 precision=4,
281 step=0.01,
282 min=0,
283 soft_max=1,
284 default=(0.0, 0.0, 0.0),
285 options={"ANIMATABLE"},
286 subtype="COLOR",
289 def draw(self, context, layout, node, text):
290 if self.is_output or self.is_linked:
291 layout.label(text=text)
292 else:
293 layout.prop(self, "default_value", text=text)
295 def draw_color(self, context, node):
296 return (1, 1, 0, 1)
299 class PovraySocketColorRGBFT(NodeSocket):
300 bl_idname = "PovraySocketColorRGBFT"
301 bl_label = "Povray Socket"
303 default_value: FloatVectorProperty(
304 precision=4,
305 step=0.01,
306 min=0,
307 soft_max=1,
308 default=(0.0, 0.0, 0.0),
309 options={"ANIMATABLE"},
310 subtype="COLOR",
312 f: bpy.props.FloatProperty(default=0.0, min=0.0, max=1.0)
313 t: bpy.props.FloatProperty(default=0.0, min=0.0, max=1.0)
315 def draw(self, context, layout, node, text):
316 if self.is_output or self.is_linked:
317 layout.label(text=text)
318 else:
319 layout.prop(self, "default_value", text=text)
321 def draw_color(self, context, node):
322 return (1, 1, 0, 1)
325 class PovraySocketTexture(NodeSocket):
326 bl_idname = "PovraySocketTexture"
327 bl_label = "Povray Socket"
328 default_value: bpy.props.IntProperty()
330 def draw(self, context, layout, node, text):
331 layout.label(text=text)
333 def draw_color(self, context, node):
334 return (0, 1, 0, 1)
337 class PovraySocketTransform(NodeSocket):
338 bl_idname = "PovraySocketTransform"
339 bl_label = "Povray Socket"
340 default_value: bpy.props.IntProperty(min=0, max=255, default=0)
342 def draw(self, context, layout, node, text):
343 layout.label(text=text)
345 def draw_color(self, context, node):
346 return (99 / 255, 99 / 255, 199 / 255, 1)
349 class PovraySocketNormal(NodeSocket):
350 bl_idname = "PovraySocketNormal"
351 bl_label = "Povray Socket"
352 default_value: bpy.props.IntProperty(min=0, max=255, default=0)
354 def draw(self, context, layout, node, text):
355 layout.label(text=text)
357 def draw_color(self, context, node):
358 return (0.65, 0.65, 0.65, 1)
361 class PovraySocketSlope(NodeSocket):
362 bl_idname = "PovraySocketSlope"
363 bl_label = "Povray Socket"
364 default_value: bpy.props.FloatProperty(min=0.0, max=1.0)
365 height: bpy.props.FloatProperty(min=0.0, max=10.0)
366 slope: bpy.props.FloatProperty(min=-10.0, max=10.0)
368 def draw(self, context, layout, node, text):
369 if self.is_output or self.is_linked:
370 layout.label(text=text)
371 else:
372 layout.prop(self, "default_value", text="")
373 layout.prop(self, "height", text="")
374 layout.prop(self, "slope", text="")
376 def draw_color(self, context, node):
377 return (0, 0, 0, 1)
380 class PovraySocketMap(NodeSocket):
381 bl_idname = "PovraySocketMap"
382 bl_label = "Povray Socket"
383 default_value: bpy.props.StringProperty()
385 def draw(self, context, layout, node, text):
386 layout.label(text=text)
388 def draw_color(self, context, node):
389 return (0.2, 0, 0.2, 1)
392 class PovrayPatternNode(Operator):
393 bl_idname = "pov.patternnode"
394 bl_label = "Pattern"
396 add = True
398 def execute(self, context):
399 space = context.space_data
400 tree = space.edit_tree
401 for node in tree.nodes:
402 node.select = False
403 if self.add:
404 tmap = tree.nodes.new("ShaderNodeValToRGB")
405 tmap.label = "Pattern"
406 for inp in tmap.inputs:
407 tmap.inputs.remove(inp)
408 for outp in tmap.outputs:
409 tmap.outputs.remove(outp)
410 pattern = tmap.inputs.new("PovraySocketPattern", "Pattern")
411 pattern.hide_value = True
412 mapping = tmap.inputs.new("NodeSocketVector", "Mapping")
413 mapping.hide_value = True
414 transform = tmap.inputs.new("NodeSocketVector", "Transform")
415 transform.hide_value = True
416 modifier = tmap.inputs.new("NodeSocketVector", "Modifier")
417 modifier.hide_value = True
418 for i in range(0, 2):
419 tmap.inputs.new("NodeSocketShader", "%s" % (i + 1))
420 tmap.outputs.new("NodeSocketShader", "Material")
421 tmap.outputs.new("NodeSocketColor", "Color")
422 tree.nodes.active = tmap
423 self.add = False
424 aNode = tree.nodes.active
425 aNode.select = True
426 v2d = context.region.view2d
427 x, y = v2d.region_to_view(self.x, self.y)
428 aNode.location = (x, y)
430 def modal(self, context, event):
431 if event.type == "MOUSEMOVE":
432 self.x = event.mouse_region_x
433 self.y = event.mouse_region_y
434 self.execute(context)
435 return {"RUNNING_MODAL"}
436 if event.type == "LEFTMOUSE":
437 return {"FINISHED"}
438 if event.type in ("RIGHTMOUSE", "ESC"):
439 return {"CANCELLED"}
441 return {"RUNNING_MODAL"}
443 def invoke(self, context, event):
444 context.window_manager.modal_handler_add(self)
445 return {"RUNNING_MODAL"}
448 class UpdatePreviewMaterial(Operator):
449 """Operator update preview material"""
451 bl_idname = "node.updatepreview"
452 bl_label = "Update preview"
454 def execute(self, context):
455 scene = context.view_layer
456 ob = context.object
457 for obj in scene.objects:
458 if obj != ob:
459 scene.objects.active = ob
460 break
461 scene.objects.active = ob
463 def modal(self, context, event):
464 if event.type == "RIGHTMOUSE":
465 self.execute(context)
466 return {"FINISHED"}
467 return {"PASS_THROUGH"}
469 def invoke(self, context, event):
470 context.window_manager.modal_handler_add(self)
471 return {"RUNNING_MODAL"}
474 class UpdatePreviewKey(Operator):
475 """Operator update preview keymap"""
477 bl_idname = "wm.updatepreviewkey"
478 bl_label = "Activate RMB"
480 @classmethod
481 def poll(cls, context):
482 conf = context.window_manager.keyconfigs.active
483 mapstr = "Node Editor"
484 map = conf.keymaps[mapstr]
485 try:
486 map.keymap_items["node.updatepreview"]
487 return False
488 except BaseException as e:
489 print(e.__doc__)
490 print("An exception occurred: {}".format(e))
491 return True
493 def execute(self, context):
494 conf = context.window_manager.keyconfigs.active
495 mapstr = "Node Editor"
496 map = conf.keymaps[mapstr]
497 map.keymap_items.new("node.updatepreview", type="RIGHTMOUSE", value="PRESS")
498 return {"FINISHED"}
501 class PovrayShaderNodeCategory(NodeCategory):
502 @classmethod
503 def poll(cls, context):
504 return context.space_data.tree_type == "ObjectNodeTree"
507 class PovrayTextureNodeCategory(NodeCategory):
508 @classmethod
509 def poll(cls, context):
510 return context.space_data.tree_type == "TextureNodeTree"
513 class PovraySceneNodeCategory(NodeCategory):
514 @classmethod
515 def poll(cls, context):
516 return context.space_data.tree_type == "CompositorNodeTree"
519 node_categories = [
520 PovrayShaderNodeCategory("SHADEROUTPUT", "Output", items=[NodeItem("PovrayOutputNode")]),
521 PovrayShaderNodeCategory("SIMPLE", "Simple texture", items=[NodeItem("PovrayTextureNode")]),
522 PovrayShaderNodeCategory(
523 "MAPS",
524 "Maps",
525 items=[
526 NodeItem("PovrayBumpMapNode"),
527 NodeItem("PovrayColorImageNode"),
528 NodeItem("ShaderNormalMapNode"),
529 NodeItem("PovraySlopeNode"),
530 NodeItem("ShaderTextureMapNode"),
531 NodeItem("ShaderNodeValToRGB"),
534 PovrayShaderNodeCategory(
535 "OTHER",
536 "Other patterns",
537 items=[NodeItem("PovrayImagePatternNode"), NodeItem("ShaderPatternNode")],
539 PovrayShaderNodeCategory("COLOR", "Color", items=[NodeItem("PovrayPigmentNode")]),
540 PovrayShaderNodeCategory(
541 "TRANSFORM",
542 "Transform",
543 items=[
544 NodeItem("PovrayMappingNode"),
545 NodeItem("PovrayMultiplyNode"),
546 NodeItem("PovrayModifierNode"),
547 NodeItem("PovrayTransformNode"),
548 NodeItem("PovrayValueNode"),
551 PovrayShaderNodeCategory(
552 "FINISH",
553 "Finish",
554 items=[
555 NodeItem("PovrayFinishNode"),
556 NodeItem("PovrayDiffuseNode"),
557 NodeItem("PovraySpecularNode"),
558 NodeItem("PovrayPhongNode"),
559 NodeItem("PovrayAmbientNode"),
560 NodeItem("PovrayMirrorNode"),
561 NodeItem("PovrayIridescenceNode"),
562 NodeItem("PovraySubsurfaceNode"),
565 PovrayShaderNodeCategory(
566 "CYCLES",
567 "Cycles",
568 items=[
569 NodeItem("ShaderNodeAddShader"),
570 NodeItem("ShaderNodeAmbientOcclusion"),
571 NodeItem("ShaderNodeAttribute"),
572 NodeItem("ShaderNodeBackground"),
573 NodeItem("ShaderNodeBlackbody"),
574 NodeItem("ShaderNodeBrightContrast"),
575 NodeItem("ShaderNodeBsdfAnisotropic"),
576 NodeItem("ShaderNodeBsdfDiffuse"),
577 NodeItem("ShaderNodeBsdfGlass"),
578 NodeItem("ShaderNodeBsdfGlossy"),
579 NodeItem("ShaderNodeBsdfHair"),
580 NodeItem("ShaderNodeBsdfRefraction"),
581 NodeItem("ShaderNodeBsdfToon"),
582 NodeItem("ShaderNodeBsdfTranslucent"),
583 NodeItem("ShaderNodeBsdfTransparent"),
584 NodeItem("ShaderNodeBsdfVelvet"),
585 NodeItem("ShaderNodeBump"),
586 NodeItem("ShaderNodeCameraData"),
587 NodeItem("ShaderNodeCombineHSV"),
588 NodeItem("ShaderNodeCombineRGB"),
589 NodeItem("ShaderNodeCombineXYZ"),
590 NodeItem("ShaderNodeEmission"),
591 NodeItem("ShaderNodeExtendedMaterial"),
592 NodeItem("ShaderNodeFresnel"),
593 NodeItem("ShaderNodeGamma"),
594 NodeItem("ShaderNodeGeometry"),
595 NodeItem("ShaderNodeGroup"),
596 NodeItem("ShaderNodeHairInfo"),
597 NodeItem("ShaderNodeHoldout"),
598 NodeItem("ShaderNodeHueSaturation"),
599 NodeItem("ShaderNodeInvert"),
600 NodeItem("ShaderNodeLampData"),
601 NodeItem("ShaderNodeLayerWeight"),
602 NodeItem("ShaderNodeLightFalloff"),
603 NodeItem("ShaderNodeLightPath"),
604 NodeItem("ShaderNodeMapping"),
605 NodeItem("ShaderNodeMaterial"),
606 NodeItem("ShaderNodeMath"),
607 NodeItem("ShaderNodeMixRGB"),
608 NodeItem("ShaderNodeMixShader"),
609 NodeItem("ShaderNodeNewGeometry"),
610 NodeItem("ShaderNodeNormal"),
611 NodeItem("ShaderNodeNormalMap"),
612 NodeItem("ShaderNodeObjectInfo"),
613 NodeItem("ShaderNodeOutput"),
614 NodeItem("ShaderNodeOutputLamp"),
615 NodeItem("ShaderNodeOutputLineStyle"),
616 NodeItem("ShaderNodeOutputMaterial"),
617 NodeItem("ShaderNodeOutputWorld"),
618 NodeItem("ShaderNodeParticleInfo"),
619 NodeItem("ShaderNodeRGB"),
620 NodeItem("ShaderNodeRGBCurve"),
621 NodeItem("ShaderNodeRGBToBW"),
622 NodeItem("ShaderNodeScript"),
623 NodeItem("ShaderNodeSeparateHSV"),
624 NodeItem("ShaderNodeSeparateRGB"),
625 NodeItem("ShaderNodeSeparateXYZ"),
626 NodeItem("ShaderNodeSqueeze"),
627 NodeItem("ShaderNodeSubsurfaceScattering"),
628 NodeItem("ShaderNodeTangent"),
629 NodeItem("ShaderNodeTexBrick"),
630 NodeItem("ShaderNodeTexChecker"),
631 NodeItem("ShaderNodeTexCoord"),
632 NodeItem("ShaderNodeTexEnvironment"),
633 NodeItem("ShaderNodeTexGradient"),
634 NodeItem("ShaderNodeTexImage"),
635 NodeItem("ShaderNodeTexMagic"),
636 NodeItem("ShaderNodeTexMusgrave"),
637 NodeItem("ShaderNodeTexNoise"),
638 NodeItem("ShaderNodeTexPointDensity"),
639 NodeItem("ShaderNodeTexSky"),
640 NodeItem("ShaderNodeTexVoronoi"),
641 NodeItem("ShaderNodeTexWave"),
642 NodeItem("ShaderNodeTexture"),
643 NodeItem("ShaderNodeUVAlongStroke"),
644 NodeItem("ShaderNodeUVMap"),
645 NodeItem("ShaderNodeValToRGB"),
646 NodeItem("ShaderNodeValue"),
647 NodeItem("ShaderNodeVectorCurve"),
648 NodeItem("ShaderNodeVectorMath"),
649 NodeItem("ShaderNodeVectorTransform"),
650 NodeItem("ShaderNodeVolumeAbsorption"),
651 NodeItem("ShaderNodeVolumeScatter"),
652 NodeItem("ShaderNodeWavelength"),
653 NodeItem("ShaderNodeWireframe"),
656 PovrayTextureNodeCategory(
657 "TEXTUREOUTPUT",
658 "Output",
659 items=[NodeItem("TextureNodeValToRGB"), NodeItem("TextureOutputNode")],
661 PovraySceneNodeCategory("ISOSURFACE", "Isosurface", items=[NodeItem("IsoPropsNode")]),
662 PovraySceneNodeCategory("FOG", "Fog", items=[NodeItem("PovrayFogNode")]),
664 # -------- end nodes init
667 classes = (
668 ObjectNodeTree,
669 PovraySocketUniversal,
670 PovraySocketFloat_0_1,
671 PovraySocketFloat_0_10,
672 PovraySocketFloat_10,
673 PovraySocketFloatPositive,
674 PovraySocketFloat_000001_10,
675 PovraySocketFloatUnlimited,
676 PovraySocketInt_1_9,
677 PovraySocketInt_0_256,
678 PovraySocketPattern,
679 PovraySocketColor,
680 PovraySocketColorRGBFT,
681 PovraySocketTexture,
682 PovraySocketTransform,
683 PovraySocketNormal,
684 PovraySocketSlope,
685 PovraySocketMap,
686 # PovrayShaderNodeCategory, # XXX SOMETHING BROKEN from 2.8 ?
687 # PovrayTextureNodeCategory, # XXX SOMETHING BROKEN from 2.8 ?
688 # PovraySceneNodeCategory, # XXX SOMETHING BROKEN from 2.8 ?
689 PovrayPatternNode,
690 UpdatePreviewMaterial,
691 UpdatePreviewKey,
695 def register():
696 nodeitems_utils.register_node_categories("POVRAYNODES", node_categories)
697 for cls in classes:
698 register_class(cls)
701 def unregister():
702 for cls in reversed(classes):
703 unregister_class(cls)
704 nodeitems_utils.unregister_node_categories("POVRAYNODES")