Animall: move to own dir, to add translations later
[blender-addons.git] / render_povray / nodes.py
blob8f0303a0b036fa58df76aa6c34d9cdf5cd5e105a
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 """"Nodes based User interface for shaders exported to POV textures."""
4 import bpy
6 from bpy.utils import register_class, unregister_class
7 from bpy.types import Node, CompositorNodeTree, TextureNodeTree
8 from bpy.props import (
9 StringProperty,
10 BoolProperty,
11 IntProperty,
12 FloatProperty,
13 EnumProperty,
15 from . import nodes_properties
18 # -------- Output
19 class PovrayOutputNode(Node, nodes_properties.ObjectNodeTree):
20 """Output"""
22 bl_idname = "PovrayOutputNode"
23 bl_label = "Output"
24 bl_icon = "SHADING_TEXTURE"
26 def init(self, context):
28 self.inputs.new("PovraySocketTexture", "Texture")
30 def draw_buttons(self, context, layout):
32 ob = context.object
33 layout.prop(ob.pov, "object_ior", slider=True)
35 def draw_buttons_ext(self, context, layout):
37 ob = context.object
38 layout.prop(ob.pov, "object_ior", slider=True)
40 def draw_label(self):
41 return "Output"
44 # -------- Material
45 class PovrayTextureNode(Node, nodes_properties.ObjectNodeTree):
46 """Texture"""
48 bl_idname = "PovrayTextureNode"
49 bl_label = "Simple texture"
50 bl_icon = "SHADING_TEXTURE"
52 def init(self, context):
54 color = self.inputs.new("PovraySocketColor", "Pigment")
55 color.default_value = (1, 1, 1)
56 normal = self.inputs.new("NodeSocketFloat", "Normal")
57 normal.hide_value = True
58 finish = self.inputs.new("NodeSocketVector", "Finish")
59 finish.hide_value = True
61 self.outputs.new("PovraySocketTexture", "Texture")
63 def draw_label(self):
64 return "Simple texture"
67 class PovrayFinishNode(Node, nodes_properties.ObjectNodeTree):
68 """Finish"""
70 bl_idname = "PovrayFinishNode"
71 bl_label = "Finish"
72 bl_icon = "SHADING_TEXTURE"
74 def init(self, context):
76 self.inputs.new("PovraySocketFloat_0_1", "Emission")
77 ambient = self.inputs.new("NodeSocketVector", "Ambient")
78 ambient.hide_value = True
79 diffuse = self.inputs.new("NodeSocketVector", "Diffuse")
80 diffuse.hide_value = True
81 specular = self.inputs.new("NodeSocketVector", "Highlight")
82 specular.hide_value = True
83 mirror = self.inputs.new("NodeSocketVector", "Mirror")
84 mirror.hide_value = True
85 iridescence = self.inputs.new("NodeSocketVector", "Iridescence")
86 iridescence.hide_value = True
87 subsurface = self.inputs.new("NodeSocketVector", "Translucency")
88 subsurface.hide_value = True
89 self.outputs.new("NodeSocketVector", "Finish")
91 def draw_label(self):
92 return "Finish"
95 class PovrayDiffuseNode(Node, nodes_properties.ObjectNodeTree):
96 """Diffuse"""
98 bl_idname = "PovrayDiffuseNode"
99 bl_label = "Diffuse"
100 bl_icon = "MATSPHERE"
102 def init(self, context):
104 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
105 intensity.default_value = 0.8
106 albedo = self.inputs.new("NodeSocketBool", "Albedo")
107 albedo.default_value = False
108 brilliance = self.inputs.new("PovraySocketFloat_0_10", "Brilliance")
109 brilliance.default_value = 1.8
110 self.inputs.new("PovraySocketFloat_0_1", "Crand")
111 self.outputs.new("NodeSocketVector", "Diffuse")
113 def draw_label(self):
114 return "Diffuse"
117 class PovrayPhongNode(Node, nodes_properties.ObjectNodeTree):
118 """Phong"""
120 bl_idname = "PovrayPhongNode"
121 bl_label = "Phong"
122 bl_icon = "MESH_UVSPHERE"
124 def init(self, context):
126 albedo = self.inputs.new("NodeSocketBool", "Albedo")
127 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
128 intensity.default_value = 0.8
129 phong_size = self.inputs.new("PovraySocketInt_0_256", "Size")
130 phong_size.default_value = 60
131 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
133 self.outputs.new("NodeSocketVector", "Phong")
135 def draw_label(self):
136 return "Phong"
139 class PovraySpecularNode(Node, nodes_properties.ObjectNodeTree):
140 """Specular"""
142 bl_idname = "PovraySpecularNode"
143 bl_label = "Specular"
144 bl_icon = "MESH_UVSPHERE"
146 def init(self, context):
148 albedo = self.inputs.new("NodeSocketBool", "Albedo")
149 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
150 intensity.default_value = 0.8
151 roughness = self.inputs.new("PovraySocketFloat_0_1", "Roughness")
152 roughness.default_value = 0.02
153 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
155 self.outputs.new("NodeSocketVector", "Specular")
157 def draw_label(self):
158 return "Specular"
161 class PovrayMirrorNode(Node, nodes_properties.ObjectNodeTree):
162 """Mirror"""
164 bl_idname = "PovrayMirrorNode"
165 bl_label = "Mirror"
166 bl_icon = "SHADING_TEXTURE"
168 def init(self, context):
170 color = self.inputs.new("PovraySocketColor", "Color")
171 color.default_value = (1, 1, 1)
172 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
173 metallic.default_value = 1.0
174 exponent = self.inputs.new("PovraySocketFloat_0_1", "Exponent")
175 exponent.default_value = 1.0
176 self.inputs.new("PovraySocketFloat_0_1", "Falloff")
177 self.inputs.new("NodeSocketBool", "Fresnel")
178 self.inputs.new("NodeSocketBool", "Conserve energy")
179 self.outputs.new("NodeSocketVector", "Mirror")
181 def draw_label(self):
182 return "Mirror"
185 class PovrayAmbientNode(Node, nodes_properties.ObjectNodeTree):
186 """Ambient"""
188 bl_idname = "PovrayAmbientNode"
189 bl_label = "Ambient"
190 bl_icon = "SHADING_SOLID"
192 def init(self, context):
194 self.inputs.new("PovraySocketColor", "Ambient")
196 self.outputs.new("NodeSocketVector", "Ambient")
198 def draw_label(self):
199 return "Ambient"
202 class PovrayIridescenceNode(Node, nodes_properties.ObjectNodeTree):
203 """Iridescence"""
205 bl_idname = "PovrayIridescenceNode"
206 bl_label = "Iridescence"
207 bl_icon = "MESH_UVSPHERE"
209 def init(self, context):
211 amount = self.inputs.new("NodeSocketFloat", "Amount")
212 amount.default_value = 0.25
213 thickness = self.inputs.new("NodeSocketFloat", "Thickness")
214 thickness.default_value = 1
215 self.inputs.new("NodeSocketFloat", "Turbulence")
217 self.outputs.new("NodeSocketVector", "Iridescence")
219 def draw_label(self):
220 return "Iridescence"
223 class PovraySubsurfaceNode(Node, nodes_properties.ObjectNodeTree):
224 """Subsurface"""
226 bl_idname = "PovraySubsurfaceNode"
227 bl_label = "Subsurface"
228 bl_icon = "MESH_UVSPHERE"
230 def init(self, context):
232 translucency = self.inputs.new("NodeSocketColor", "Translucency")
233 translucency.default_value = (0, 0, 0, 1)
234 energy = self.inputs.new("PovraySocketInt_0_256", "Energy")
235 energy.default_value = 20
236 self.outputs.new("NodeSocketVector", "Translucency")
238 def draw_buttons(self, context, layout):
239 scene = context.scene
240 layout.prop(scene.pov, "sslt_enable", text="SSLT")
242 def draw_buttons_ext(self, context, layout):
243 scene = context.scene
244 layout.prop(scene.pov, "sslt_enable", text="SSLT")
246 def draw_label(self):
247 return "Subsurface"
250 # ---------------------------------------------------------------- #
253 class PovrayMappingNode(Node, nodes_properties.ObjectNodeTree):
254 """Mapping"""
256 bl_idname = "PovrayMappingNode"
257 bl_label = "Mapping"
258 bl_icon = "NODE_TEXTURE"
260 warp_type: EnumProperty(
261 name="Warp Types",
262 description="Select the type of warp",
263 items=(
264 ("cubic", "Cubic", ""),
265 ("cylindrical", "Cylindrical", ""),
266 ("planar", "Planar", ""),
267 ("spherical", "Spherical", ""),
268 ("toroidal", "Toroidal", ""),
269 ("uv_mapping", "UV", ""),
270 ("NONE", "None", "No indentation"),
272 default="NONE",
275 warp_orientation: EnumProperty(
276 name="Warp Orientation",
277 description="Select the orientation of warp",
278 items=(("x", "X", ""), ("y", "Y", ""), ("z", "Z", "")),
279 default="y",
282 warp_dist_exp: FloatProperty(
283 name="Distance exponent", description="Distance exponent", min=0.0, max=100.0, default=1.0
286 warp_tor_major_radius: FloatProperty(
287 name="Major radius",
288 description="Torus is distance from major radius",
289 min=0.0,
290 max=5.0,
291 default=1.0,
294 def init(self, context):
295 self.outputs.new("NodeSocketVector", "Mapping")
297 def draw_buttons(self, context, layout):
299 column = layout.column()
300 column.prop(self, "warp_type", text="Warp type")
301 if self.warp_type in {"toroidal", "spherical", "cylindrical", "planar"}:
302 column.prop(self, "warp_orientation", text="Orientation")
303 column.prop(self, "warp_dist_exp", text="Exponent")
304 if self.warp_type == "toroidal":
305 column.prop(self, "warp_tor_major_radius", text="Major R")
307 def draw_buttons_ext(self, context, layout):
309 column = layout.column()
310 column.prop(self, "warp_type", text="Warp type")
311 if self.warp_type in {"toroidal", "spherical", "cylindrical", "planar"}:
312 column.prop(self, "warp_orientation", text="Orientation")
313 column.prop(self, "warp_dist_exp", text="Exponent")
314 if self.warp_type == "toroidal":
315 column.prop(self, "warp_tor_major_radius", text="Major R")
317 def draw_label(self):
318 return "Mapping"
321 class PovrayMultiplyNode(Node, nodes_properties.ObjectNodeTree):
322 """Multiply"""
324 bl_idname = "PovrayMultiplyNode"
325 bl_label = "Multiply"
326 bl_icon = "SHADING_SOLID"
328 amount_x: FloatProperty(
329 name="X", description="Number of repeats", min=1.0, max=10000.0, default=1.0
332 amount_y: FloatProperty(
333 name="Y", description="Number of repeats", min=1.0, max=10000.0, default=1.0
336 amount_z: FloatProperty(
337 name="Z", description="Number of repeats", min=1.0, max=10000.0, default=1.0
340 def init(self, context):
341 self.outputs.new("NodeSocketVector", "Amount")
343 def draw_buttons(self, context, layout):
345 column = layout.column()
346 column.label(text="Amount")
347 row = column.row(align=True)
348 row.prop(self, "amount_x")
349 row.prop(self, "amount_y")
350 row.prop(self, "amount_z")
352 def draw_buttons_ext(self, context, layout):
354 column = layout.column()
355 column.label(text="Amount")
356 row = column.row(align=True)
357 row.prop(self, "amount_x")
358 row.prop(self, "amount_y")
359 row.prop(self, "amount_z")
361 def draw_label(self):
362 return "Multiply"
365 class PovrayTransformNode(Node, nodes_properties.ObjectNodeTree):
366 """Transform"""
368 bl_idname = "PovrayTransformNode"
369 bl_label = "Transform"
370 bl_icon = "NODE_TEXTURE"
372 def init(self, context):
374 self.inputs.new("PovraySocketFloatUnlimited", "Translate x")
375 self.inputs.new("PovraySocketFloatUnlimited", "Translate y")
376 self.inputs.new("PovraySocketFloatUnlimited", "Translate z")
377 self.inputs.new("PovraySocketFloatUnlimited", "Rotate x")
378 self.inputs.new("PovraySocketFloatUnlimited", "Rotate y")
379 self.inputs.new("PovraySocketFloatUnlimited", "Rotate z")
380 sX = self.inputs.new("PovraySocketFloatUnlimited", "Scale x")
381 sX.default_value = 1.0
382 sY = self.inputs.new("PovraySocketFloatUnlimited", "Scale y")
383 sY.default_value = 1.0
384 sZ = self.inputs.new("PovraySocketFloatUnlimited", "Scale z")
385 sZ.default_value = 1.0
387 self.outputs.new("NodeSocketVector", "Transform")
389 def draw_label(self):
390 return "Transform"
393 class PovrayValueNode(Node, nodes_properties.ObjectNodeTree):
394 """Value"""
396 bl_idname = "PovrayValueNode"
397 bl_label = "Value"
398 bl_icon = "SHADING_SOLID"
400 def init(self, context):
402 self.outputs.new("PovraySocketUniversal", "Value")
404 def draw_label(self):
405 return "Value"
408 class PovrayModifierNode(Node, nodes_properties.ObjectNodeTree):
409 """Modifier"""
411 bl_idname = "PovrayModifierNode"
412 bl_label = "Modifier"
413 bl_icon = "NODE_TEXTURE"
415 def init(self, context):
417 turb_x = self.inputs.new("PovraySocketFloat_0_10", "Turb X")
418 turb_x.default_value = 0.1
419 turb_y = self.inputs.new("PovraySocketFloat_0_10", "Turb Y")
420 turb_y.default_value = 0.1
421 turb_z = self.inputs.new("PovraySocketFloat_0_10", "Turb Z")
422 turb_z.default_value = 0.1
423 octaves = self.inputs.new("PovraySocketInt_1_9", "Octaves")
424 octaves.default_value = 1
425 lambat = self.inputs.new("PovraySocketFloat_0_10", "Lambda")
426 lambat.default_value = 2.0
427 omega = self.inputs.new("PovraySocketFloat_0_10", "Omega")
428 omega.default_value = 0.5
429 freq = self.inputs.new("PovraySocketFloat_0_10", "Frequency")
430 freq.default_value = 2.0
431 self.inputs.new("PovraySocketFloat_0_10", "Phase")
433 self.outputs.new("NodeSocketVector", "Modifier")
435 def draw_label(self):
436 return "Modifier"
439 class PovrayPigmentNode(Node, nodes_properties.ObjectNodeTree):
440 """Pigment"""
442 bl_idname = "PovrayPigmentNode"
443 bl_label = "Color"
444 bl_icon = "SHADING_SOLID"
446 def init(self, context):
448 color = self.inputs.new("PovraySocketColor", "Color")
449 color.default_value = (1, 1, 1)
450 pov_filter = self.inputs.new("PovraySocketFloat_0_1", "Filter")
451 transmit = self.inputs.new("PovraySocketFloat_0_1", "Transmit")
452 self.outputs.new("NodeSocketColor", "Pigment")
454 def draw_label(self):
455 return "Color"
458 class PovrayColorImageNode(Node, nodes_properties.ObjectNodeTree):
459 """ColorImage"""
461 bl_idname = "PovrayColorImageNode"
462 bl_label = "Image map"
464 map_type: bpy.props.EnumProperty(
465 name="Map type",
466 description="",
467 items=(
468 ("uv_mapping", "UV", ""),
469 ("0", "Planar", "Default planar mapping"),
470 ("1", "Spherical", "Spherical mapping"),
471 ("2", "Cylindrical", "Cylindrical mapping"),
472 ("5", "Torroidal", "Torus or donut shaped mapping"),
474 default="0",
476 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
477 interpolate: EnumProperty(
478 name="Interpolate",
479 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
480 items=(
481 ("2", "Bilinear", "Gives bilinear interpolation"),
482 ("4", "Normalized", "Gives normalized distance"),
484 default="2",
486 premultiplied: BoolProperty(default=False)
487 once: BoolProperty(description="Not to repeat", default=False)
489 def init(self, context):
491 gamma = self.inputs.new("PovraySocketFloat_000001_10", "Gamma")
492 gamma.default_value = 2.0
493 transmit = self.inputs.new("PovraySocketFloat_0_1", "Transmit")
494 pov_filter = self.inputs.new("PovraySocketFloat_0_1", "Filter")
495 mapping = self.inputs.new("NodeSocketVector", "Mapping")
496 mapping.hide_value = True
497 transform = self.inputs.new("NodeSocketVector", "Transform")
498 transform.hide_value = True
499 modifier = self.inputs.new("NodeSocketVector", "Modifier")
500 modifier.hide_value = True
502 self.outputs.new("NodeSocketColor", "Pigment")
504 def draw_buttons(self, context, layout):
506 column = layout.column()
507 im = None
508 for image in bpy.data.images:
509 if image.name == self.image:
510 im = image
511 split = column.split(factor=0.8, align=True)
512 split.prop_search(self, "image", context.blend_data, "images", text="")
513 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
514 if im is not None:
515 column.prop(im, "source", text="")
516 column.prop(self, "map_type", text="")
517 column.prop(self, "interpolate", text="")
518 row = column.row()
519 row.prop(self, "premultiplied", text="Premul")
520 row.prop(self, "once", text="Once")
522 def draw_buttons_ext(self, context, layout):
524 column = layout.column()
525 im = None
526 for image in bpy.data.images:
527 if image.name == self.image:
528 im = image
529 split = column.split(factor=0.8, align=True)
530 split.prop_search(self, "image", context.blend_data, "images", text="")
531 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
532 if im is not None:
533 column.prop(im, "source", text="")
534 column.prop(self, "map_type", text="")
535 column.prop(self, "interpolate", text="")
536 row = column.row()
537 row.prop(self, "premultiplied", text="Premul")
538 row.prop(self, "once", text="Once")
540 def draw_label(self):
541 return "Image map"
544 class PovrayBumpMapNode(Node, nodes_properties.ObjectNodeTree):
545 """BumpMap"""
547 bl_idname = "PovrayBumpMapNode"
548 bl_label = "Bump map"
549 bl_icon = "TEXTURE"
551 map_type: bpy.props.EnumProperty(
552 name="Map type",
553 description="",
554 items=(
555 ("uv_mapping", "UV", ""),
556 ("0", "Planar", "Default planar mapping"),
557 ("1", "Spherical", "Spherical mapping"),
558 ("2", "Cylindrical", "Cylindrical mapping"),
559 ("5", "Torroidal", "Torus or donut shaped mapping"),
561 default="0",
563 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
564 interpolate: EnumProperty(
565 name="Interpolate",
566 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
567 items=(
568 ("2", "Bilinear", "Gives bilinear interpolation"),
569 ("4", "Normalized", "Gives normalized distance"),
571 default="2",
573 once: BoolProperty(description="Not to repeat", default=False)
575 def init(self, context):
577 self.inputs.new("PovraySocketFloat_0_10", "Normal")
578 mapping = self.inputs.new("NodeSocketVector", "Mapping")
579 mapping.hide_value = True
580 transform = self.inputs.new("NodeSocketVector", "Transform")
581 transform.hide_value = True
582 modifier = self.inputs.new("NodeSocketVector", "Modifier")
583 modifier.hide_value = True
585 normal = self.outputs.new("NodeSocketFloat", "Normal")
586 normal.hide_value = True
588 def draw_buttons(self, context, layout):
590 column = layout.column()
591 im = None
592 for image in bpy.data.images:
593 if image.name == self.image:
594 im = image
595 split = column.split(factor=0.8, align=True)
596 split.prop_search(self, "image", context.blend_data, "images", text="")
597 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
598 if im is not None:
599 column.prop(im, "source", text="")
600 column.prop(self, "map_type", text="")
601 column.prop(self, "interpolate", text="")
602 column.prop(self, "once", text="Once")
604 def draw_buttons_ext(self, context, layout):
606 column = layout.column()
607 im = None
608 for image in bpy.data.images:
609 if image.name == self.image:
610 im = image
611 split = column.split(factor=0.8, align=True)
612 split.prop_search(self, "image", context.blend_data, "images", text="")
613 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
614 if im is not None:
615 column.prop(im, "source", text="")
616 column.prop(self, "map_type", text="")
617 column.prop(self, "interpolate", text="")
618 column.prop(self, "once", text="Once")
620 def draw_label(self):
621 return "Bump Map"
624 class PovrayImagePatternNode(Node, nodes_properties.ObjectNodeTree):
625 """ImagePattern"""
627 bl_idname = "PovrayImagePatternNode"
628 bl_label = "Image pattern"
629 bl_icon = "NODE_TEXTURE"
631 map_type: bpy.props.EnumProperty(
632 name="Map type",
633 description="",
634 items=(
635 ("uv_mapping", "UV", ""),
636 ("0", "Planar", "Default planar mapping"),
637 ("1", "Spherical", "Spherical mapping"),
638 ("2", "Cylindrical", "Cylindrical mapping"),
639 ("5", "Torroidal", "Torus or donut shaped mapping"),
641 default="0",
643 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
644 interpolate: EnumProperty(
645 name="Interpolate",
646 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
647 items=(
648 ("2", "Bilinear", "Gives bilinear interpolation"),
649 ("4", "Normalized", "Gives normalized distance"),
651 default="2",
653 premultiplied: BoolProperty(default=False)
654 once: BoolProperty(description="Not to repeat", default=False)
655 use_alpha: BoolProperty(default=True)
657 def init(self, context):
659 gamma = self.inputs.new("PovraySocketFloat_000001_10", "Gamma")
660 gamma.default_value = 2.0
662 self.outputs.new("PovraySocketPattern", "Pattern")
664 def draw_buttons(self, context, layout):
666 column = layout.column()
667 im = None
668 for image in bpy.data.images:
669 if image.name == self.image:
670 im = image
671 split = column.split(factor=0.8, align=True)
672 split.prop_search(self, "image", context.blend_data, "images", text="")
673 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
674 if im is not None:
675 column.prop(im, "source", text="")
676 column.prop(self, "map_type", text="")
677 column.prop(self, "interpolate", text="")
678 row = column.row()
679 row.prop(self, "premultiplied", text="Premul")
680 row.prop(self, "once", text="Once")
681 column.prop(self, "use_alpha", text="Use alpha")
683 def draw_buttons_ext(self, context, layout):
685 column = layout.column()
686 im = None
687 for image in bpy.data.images:
688 if image.name == self.image:
689 im = image
690 split = column.split(factor=0.8, align=True)
691 split.prop_search(self, "image", context.blend_data, "images", text="")
692 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
693 if im is not None:
694 column.prop(im, "source", text="")
695 column.prop(self, "map_type", text="")
696 column.prop(self, "interpolate", text="")
697 row = column.row()
698 row.prop(self, "premultiplied", text="Premul")
699 row.prop(self, "once", text="Once")
701 def draw_label(self):
702 return "Image pattern"
705 class ShaderPatternNode(Node, nodes_properties.ObjectNodeTree):
706 """Pattern"""
708 bl_idname = "ShaderPatternNode"
709 bl_label = "Other patterns"
711 pattern: EnumProperty(
712 name="Pattern",
713 description="Agate, Crackle, Gradient, Pavement, Spiral, Tiling",
714 items=(
715 ("agate", "Agate", ""),
716 ("crackle", "Crackle", ""),
717 ("gradient", "Gradient", ""),
718 ("pavement", "Pavement", ""),
719 ("spiral1", "Spiral 1", ""),
720 ("spiral2", "Spiral 2", ""),
721 ("tiling", "Tiling", ""),
723 default="agate",
726 agate_turb: FloatProperty(
727 name="Agate turb", description="Agate turbulence", min=0.0, max=100.0, default=0.5
730 crackle_form_x: FloatProperty(
731 name="X", description="Form vector X", min=-150.0, max=150.0, default=-1
734 crackle_form_y: FloatProperty(
735 name="Y", description="Form vector Y", min=-150.0, max=150.0, default=1
738 crackle_form_z: FloatProperty(
739 name="Z", description="Form vector Z", min=-150.0, max=150.0, default=0
742 crackle_metric: FloatProperty(
743 name="Metric", description="Crackle metric", min=0.0, max=150.0, default=1
746 crackle_solid: BoolProperty(name="Solid", description="Crackle solid", default=False)
748 spiral_arms: FloatProperty(name="Number", description="", min=0.0, max=256.0, default=2.0)
750 tiling_number: IntProperty(name="Number", description="", min=1, max=27, default=1)
752 gradient_orient: EnumProperty(
753 name="Orient",
754 description="",
755 items=(("x", "X", ""), ("y", "Y", ""), ("z", "Z", "")),
756 default="x",
759 def init(self, context):
761 pat = self.outputs.new("PovraySocketPattern", "Pattern")
763 def draw_buttons(self, context, layout):
765 layout.prop(self, "pattern", text="")
766 if self.pattern == "agate":
767 layout.prop(self, "agate_turb")
768 if self.pattern == "crackle":
769 layout.prop(self, "crackle_metric")
770 layout.prop(self, "crackle_solid")
771 layout.label(text="Form:")
772 layout.prop(self, "crackle_form_x")
773 layout.prop(self, "crackle_form_y")
774 layout.prop(self, "crackle_form_z")
775 if self.pattern in {"spiral1", "spiral2"}:
776 layout.prop(self, "spiral_arms")
777 if self.pattern in {"tiling"}:
778 layout.prop(self, "tiling_number")
779 if self.pattern in {"gradient"}:
780 layout.prop(self, "gradient_orient")
782 def draw_buttons_ext(self, context, layout):
783 pass
785 def draw_label(self):
786 return "Other patterns"
789 class ShaderTextureMapNode(Node, nodes_properties.ObjectNodeTree):
790 """Texture Map"""
792 bl_idname = "ShaderTextureMapNode"
793 bl_label = "Texture map"
795 brick_size_x: FloatProperty(name="X", description="", min=0.0000, max=1.0000, default=0.2500)
797 brick_size_y: FloatProperty(name="Y", description="", min=0.0000, max=1.0000, default=0.0525)
799 brick_size_z: FloatProperty(name="Z", description="", min=0.0000, max=1.0000, default=0.1250)
801 brick_mortar: FloatProperty(
802 name="Mortar", description="Mortar", min=0.000, max=1.500, default=0.01
805 def init(self, context):
806 mat = bpy.context.object.active_material
807 self.inputs.new("PovraySocketPattern", "")
808 color = self.inputs.new("NodeSocketColor", "Color ramp")
809 color.hide_value = True
810 for i in range(4):
811 transform = self.inputs.new("PovraySocketTransform", "Transform")
812 transform.hide_value = True
813 number = mat.pov.inputs_number
814 for i in range(number):
815 self.inputs.new("PovraySocketTexture", "%s" % i)
817 self.outputs.new("PovraySocketTexture", "Texture")
819 def draw_buttons(self, context, layout):
821 if self.inputs[0].default_value == "brick":
822 layout.prop(self, "brick_mortar")
823 layout.label(text="Brick size:")
824 layout.prop(self, "brick_size_x")
825 layout.prop(self, "brick_size_y")
826 layout.prop(self, "brick_size_z")
828 def draw_buttons_ext(self, context, layout):
830 if self.inputs[0].default_value == "brick":
831 layout.prop(self, "brick_mortar")
832 layout.label(text="Brick size:")
833 layout.prop(self, "brick_size_x")
834 layout.prop(self, "brick_size_y")
835 layout.prop(self, "brick_size_z")
837 def draw_label(self):
838 return "Texture map"
841 class ShaderNormalMapNode(Node, nodes_properties.ObjectNodeTree):
842 """Normal Map"""
844 bl_idname = "ShaderNormalMapNode"
845 bl_label = "Normal map"
847 brick_size_x: FloatProperty(name="X", description="", min=0.0000, max=1.0000, default=0.2500)
849 brick_size_y: FloatProperty(name="Y", description="", min=0.0000, max=1.0000, default=0.0525)
851 brick_size_z: FloatProperty(name="Z", description="", min=0.0000, max=1.0000, default=0.1250)
853 brick_mortar: FloatProperty(
854 name="Mortar", description="Mortar", min=0.000, max=1.500, default=0.01
857 def init(self, context):
858 self.inputs.new("PovraySocketPattern", "")
859 normal = self.inputs.new("PovraySocketFloat_10", "Normal")
860 slope = self.inputs.new("PovraySocketMap", "Slope map")
861 for i in range(4):
862 transform = self.inputs.new("PovraySocketTransform", "Transform")
863 transform.hide_value = True
864 self.outputs.new("PovraySocketNormal", "Normal")
866 def draw_buttons(self, context, layout):
867 # for i, inp in enumerate(self.inputs):
869 if self.inputs[0].default_value == "brick":
870 layout.prop(self, "brick_mortar")
871 layout.label(text="Brick size:")
872 layout.prop(self, "brick_size_x")
873 layout.prop(self, "brick_size_y")
874 layout.prop(self, "brick_size_z")
876 def draw_buttons_ext(self, context, layout):
878 if self.inputs[0].default_value == "brick":
879 layout.prop(self, "brick_mortar")
880 layout.label(text="Brick size:")
881 layout.prop(self, "brick_size_x")
882 layout.prop(self, "brick_size_y")
883 layout.prop(self, "brick_size_z")
885 def draw_label(self):
886 return "Normal map"
889 class ShaderNormalMapEntryNode(Node, nodes_properties.ObjectNodeTree):
890 """Normal Map Entry"""
892 bl_idname = "ShaderNormalMapEntryNode"
893 bl_label = "Normal map entry"
895 def init(self, context):
896 self.inputs.new("PovraySocketFloat_0_1", "Stop")
897 self.inputs.new("PovraySocketFloat_0_1", "Gray")
899 def draw_label(self):
900 return "Normal map entry"
903 class IsoPropsNode(Node, CompositorNodeTree):
904 """ISO Props"""
906 bl_idname = "IsoPropsNode"
907 bl_label = "Iso"
908 node_label: StringProperty(maxlen=1024)
910 def init(self, context):
911 ob = bpy.context.object
912 self.node_label = ob.name
913 text_name = ob.pov.function_text
914 if text_name:
915 text = bpy.data.texts[text_name]
916 for line in text.lines:
917 split = line.body.split()
918 if split[0] == "#declare":
919 socket = self.inputs.new("NodeSocketFloat", "%s" % split[1])
920 value = split[3].split(";")
921 value = value[0]
922 socket.default_value = float(value)
924 def draw_label(self):
925 return self.node_label
928 class PovrayFogNode(Node, CompositorNodeTree):
929 """Fog settings"""
931 bl_idname = "PovrayFogNode"
932 bl_label = "Fog"
934 def init(self, context):
935 color = self.inputs.new("NodeSocketColor", "Color")
936 color.default_value = (0.7, 0.7, 0.7, 0.25)
937 self.inputs.new("PovraySocketFloat_0_1", "Filter")
938 distance = self.inputs.new("NodeSocketInt", "Distance")
939 distance.default_value = 150
940 self.inputs.new("NodeSocketBool", "Ground")
941 fog_offset = self.inputs.new("NodeSocketFloat", "Offset")
942 fog_alt = self.inputs.new("NodeSocketFloat", "Altitude")
943 turb = self.inputs.new("NodeSocketVector", "Turbulence")
944 turb_depth = self.inputs.new("PovraySocketFloat_0_10", "Depth")
945 turb_depth.default_value = 0.5
946 octaves = self.inputs.new("PovraySocketInt_1_9", "Octaves")
947 octaves.default_value = 5
948 lambdat = self.inputs.new("PovraySocketFloat_0_10", "Lambda")
949 lambdat.default_value = 1.25
950 omega = self.inputs.new("PovraySocketFloat_0_10", "Omega")
951 omega.default_value = 0.35
952 translate = self.inputs.new("NodeSocketVector", "Translate")
953 rotate = self.inputs.new("NodeSocketVector", "Rotate")
954 scale = self.inputs.new("NodeSocketVector", "Scale")
955 scale.default_value = (1, 1, 1)
957 def draw_label(self):
958 return "Fog"
961 class PovraySlopeNode(Node, TextureNodeTree):
962 """Output"""
964 bl_idname = "PovraySlopeNode"
965 bl_label = "Slope Map"
967 def init(self, context):
968 self.use_custom_color = True
969 self.color = (0, 0.2, 0)
970 slope = self.inputs.new("PovraySocketSlope", "0")
971 slope = self.inputs.new("PovraySocketSlope", "1")
972 slopemap = self.outputs.new("PovraySocketMap", "Slope map")
973 slopemap.hide_value = True
975 def draw_buttons(self, context, layout):
977 layout.operator("pov.nodeinputadd")
978 row = layout.row()
979 row.label(text="Value")
980 row.label(text="Height")
981 row.label(text="Slope")
983 def draw_buttons_ext(self, context, layout):
985 layout.operator("pov.nodeinputadd")
986 row = layout.row()
987 row.label(text="Value")
988 row.label(text="Height")
989 row.label(text="Slope")
991 def draw_label(self):
992 return "Slope Map"
995 # -------- Texture nodes
996 class TextureOutputNode(Node, TextureNodeTree):
997 """Output"""
999 bl_idname = "TextureOutputNode"
1000 bl_label = "Color Map"
1002 def init(self, context):
1003 tex = bpy.context.object.active_material.active_texture
1004 num_sockets = int(tex.pov.density_lines / 32)
1005 for i in range(num_sockets):
1006 color = self.inputs.new("NodeSocketColor", "%s" % i)
1007 color.hide_value = True
1009 def draw_buttons(self, context, layout):
1011 layout.label(text="Color Ramps:")
1013 def draw_label(self):
1014 return "Color Map"
1017 classes = (
1018 PovrayOutputNode,
1019 PovrayTextureNode,
1020 PovrayFinishNode,
1021 PovrayDiffuseNode,
1022 PovrayPhongNode,
1023 PovraySpecularNode,
1024 PovrayMirrorNode,
1025 PovrayAmbientNode,
1026 PovrayIridescenceNode,
1027 PovraySubsurfaceNode,
1028 PovrayMappingNode,
1029 PovrayMultiplyNode,
1030 PovrayTransformNode,
1031 PovrayValueNode,
1032 PovrayModifierNode,
1033 PovrayPigmentNode,
1034 PovrayColorImageNode,
1035 PovrayBumpMapNode,
1036 PovrayImagePatternNode,
1037 ShaderPatternNode,
1038 ShaderTextureMapNode,
1039 ShaderNormalMapNode,
1040 ShaderNormalMapEntryNode,
1041 IsoPropsNode,
1042 PovrayFogNode,
1043 PovraySlopeNode,
1044 TextureOutputNode,
1048 def register():
1049 for cls in classes:
1050 register_class(cls)
1053 def unregister():
1054 for cls in reversed(classes):
1055 unregister_class(cls)