Import images: add file handler
[blender-addons.git] / render_povray / nodes.py
blob4d7d0ed55b914ead747399e53d61d8a270f9ea5c
1 # SPDX-FileCopyrightText: 2017-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 Node, CompositorNodeTree, TextureNodeTree
10 from bpy.props import (
11 StringProperty,
12 BoolProperty,
13 IntProperty,
14 FloatProperty,
15 EnumProperty,
17 from . import nodes_properties
20 # -------- Output
21 class PovrayOutputNode(Node, nodes_properties.ObjectNodeTree):
22 """Output"""
24 bl_idname = "PovrayOutputNode"
25 bl_label = "Output"
26 bl_icon = "SHADING_TEXTURE"
28 def init(self, context):
30 self.inputs.new("PovraySocketTexture", "Texture")
32 def draw_buttons(self, context, layout):
34 ob = context.object
35 layout.prop(ob.pov, "object_ior", slider=True)
37 def draw_buttons_ext(self, context, layout):
39 ob = context.object
40 layout.prop(ob.pov, "object_ior", slider=True)
42 def draw_label(self):
43 return "Output"
46 # -------- Material
47 class PovrayTextureNode(Node, nodes_properties.ObjectNodeTree):
48 """Texture"""
50 bl_idname = "PovrayTextureNode"
51 bl_label = "Simple texture"
52 bl_icon = "SHADING_TEXTURE"
54 def init(self, context):
56 color = self.inputs.new("PovraySocketColor", "Pigment")
57 color.default_value = (1, 1, 1)
58 normal = self.inputs.new("NodeSocketFloat", "Normal")
59 normal.hide_value = True
60 finish = self.inputs.new("NodeSocketVector", "Finish")
61 finish.hide_value = True
63 self.outputs.new("PovraySocketTexture", "Texture")
65 def draw_label(self):
66 return "Simple texture"
69 class PovrayFinishNode(Node, nodes_properties.ObjectNodeTree):
70 """Finish"""
72 bl_idname = "PovrayFinishNode"
73 bl_label = "Finish"
74 bl_icon = "SHADING_TEXTURE"
76 def init(self, context):
78 self.inputs.new("PovraySocketFloat_0_1", "Emission")
79 ambient = self.inputs.new("NodeSocketVector", "Ambient")
80 ambient.hide_value = True
81 diffuse = self.inputs.new("NodeSocketVector", "Diffuse")
82 diffuse.hide_value = True
83 specular = self.inputs.new("NodeSocketVector", "Highlight")
84 specular.hide_value = True
85 mirror = self.inputs.new("NodeSocketVector", "Mirror")
86 mirror.hide_value = True
87 iridescence = self.inputs.new("NodeSocketVector", "Iridescence")
88 iridescence.hide_value = True
89 subsurface = self.inputs.new("NodeSocketVector", "Translucency")
90 subsurface.hide_value = True
91 self.outputs.new("NodeSocketVector", "Finish")
93 def draw_label(self):
94 return "Finish"
97 class PovrayDiffuseNode(Node, nodes_properties.ObjectNodeTree):
98 """Diffuse"""
100 bl_idname = "PovrayDiffuseNode"
101 bl_label = "Diffuse"
102 bl_icon = "MATSPHERE"
104 def init(self, context):
106 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
107 intensity.default_value = 0.8
108 albedo = self.inputs.new("NodeSocketBool", "Albedo")
109 albedo.default_value = False
110 brilliance = self.inputs.new("PovraySocketFloat_0_10", "Brilliance")
111 brilliance.default_value = 1.8
112 self.inputs.new("PovraySocketFloat_0_1", "Crand")
113 self.outputs.new("NodeSocketVector", "Diffuse")
115 def draw_label(self):
116 return "Diffuse"
119 class PovrayPhongNode(Node, nodes_properties.ObjectNodeTree):
120 """Phong"""
122 bl_idname = "PovrayPhongNode"
123 bl_label = "Phong"
124 bl_icon = "MESH_UVSPHERE"
126 def init(self, context):
128 albedo = self.inputs.new("NodeSocketBool", "Albedo")
129 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
130 intensity.default_value = 0.8
131 phong_size = self.inputs.new("PovraySocketInt_0_256", "Size")
132 phong_size.default_value = 60
133 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
135 self.outputs.new("NodeSocketVector", "Phong")
137 def draw_label(self):
138 return "Phong"
141 class PovraySpecularNode(Node, nodes_properties.ObjectNodeTree):
142 """Specular"""
144 bl_idname = "PovraySpecularNode"
145 bl_label = "Specular"
146 bl_icon = "MESH_UVSPHERE"
148 def init(self, context):
150 albedo = self.inputs.new("NodeSocketBool", "Albedo")
151 intensity = self.inputs.new("PovraySocketFloat_0_1", "Intensity")
152 intensity.default_value = 0.8
153 roughness = self.inputs.new("PovraySocketFloat_0_1", "Roughness")
154 roughness.default_value = 0.02
155 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
157 self.outputs.new("NodeSocketVector", "Specular")
159 def draw_label(self):
160 return "Specular"
163 class PovrayMirrorNode(Node, nodes_properties.ObjectNodeTree):
164 """Mirror"""
166 bl_idname = "PovrayMirrorNode"
167 bl_label = "Mirror"
168 bl_icon = "SHADING_TEXTURE"
170 def init(self, context):
172 color = self.inputs.new("PovraySocketColor", "Color")
173 color.default_value = (1, 1, 1)
174 metallic = self.inputs.new("PovraySocketFloat_0_1", "Metallic")
175 metallic.default_value = 1.0
176 exponent = self.inputs.new("PovraySocketFloat_0_1", "Exponent")
177 exponent.default_value = 1.0
178 self.inputs.new("PovraySocketFloat_0_1", "Falloff")
179 self.inputs.new("NodeSocketBool", "Fresnel")
180 self.inputs.new("NodeSocketBool", "Conserve energy")
181 self.outputs.new("NodeSocketVector", "Mirror")
183 def draw_label(self):
184 return "Mirror"
187 class PovrayAmbientNode(Node, nodes_properties.ObjectNodeTree):
188 """Ambient"""
190 bl_idname = "PovrayAmbientNode"
191 bl_label = "Ambient"
192 bl_icon = "SHADING_SOLID"
194 def init(self, context):
196 self.inputs.new("PovraySocketColor", "Ambient")
198 self.outputs.new("NodeSocketVector", "Ambient")
200 def draw_label(self):
201 return "Ambient"
204 class PovrayIridescenceNode(Node, nodes_properties.ObjectNodeTree):
205 """Iridescence"""
207 bl_idname = "PovrayIridescenceNode"
208 bl_label = "Iridescence"
209 bl_icon = "MESH_UVSPHERE"
211 def init(self, context):
213 amount = self.inputs.new("NodeSocketFloat", "Amount")
214 amount.default_value = 0.25
215 thickness = self.inputs.new("NodeSocketFloat", "Thickness")
216 thickness.default_value = 1
217 self.inputs.new("NodeSocketFloat", "Turbulence")
219 self.outputs.new("NodeSocketVector", "Iridescence")
221 def draw_label(self):
222 return "Iridescence"
225 class PovraySubsurfaceNode(Node, nodes_properties.ObjectNodeTree):
226 """Subsurface"""
228 bl_idname = "PovraySubsurfaceNode"
229 bl_label = "Subsurface"
230 bl_icon = "MESH_UVSPHERE"
232 def init(self, context):
234 translucency = self.inputs.new("NodeSocketColor", "Translucency")
235 translucency.default_value = (0, 0, 0, 1)
236 energy = self.inputs.new("PovraySocketInt_0_256", "Energy")
237 energy.default_value = 20
238 self.outputs.new("NodeSocketVector", "Translucency")
240 def draw_buttons(self, context, layout):
241 scene = context.scene
242 layout.prop(scene.pov, "sslt_enable", text="SSLT")
244 def draw_buttons_ext(self, context, layout):
245 scene = context.scene
246 layout.prop(scene.pov, "sslt_enable", text="SSLT")
248 def draw_label(self):
249 return "Subsurface"
252 # ---------------------------------------------------------------- #
255 class PovrayMappingNode(Node, nodes_properties.ObjectNodeTree):
256 """Mapping"""
258 bl_idname = "PovrayMappingNode"
259 bl_label = "Mapping"
260 bl_icon = "NODE_TEXTURE"
262 warp_type: EnumProperty(
263 name="Warp Types",
264 description="Select the type of warp",
265 items=(
266 ("cubic", "Cubic", ""),
267 ("cylindrical", "Cylindrical", ""),
268 ("planar", "Planar", ""),
269 ("spherical", "Spherical", ""),
270 ("toroidal", "Toroidal", ""),
271 ("uv_mapping", "UV", ""),
272 ("NONE", "None", "No indentation"),
274 default="NONE",
277 warp_orientation: EnumProperty(
278 name="Warp Orientation",
279 description="Select the orientation of warp",
280 items=(("x", "X", ""), ("y", "Y", ""), ("z", "Z", "")),
281 default="y",
284 warp_dist_exp: FloatProperty(
285 name="Distance exponent", description="Distance exponent", min=0.0, max=100.0, default=1.0
288 warp_tor_major_radius: FloatProperty(
289 name="Major radius",
290 description="Torus is distance from major radius",
291 min=0.0,
292 max=5.0,
293 default=1.0,
296 def init(self, context):
297 self.outputs.new("NodeSocketVector", "Mapping")
299 def draw_buttons(self, context, layout):
301 column = layout.column()
302 column.prop(self, "warp_type", text="Warp type")
303 if self.warp_type in {"toroidal", "spherical", "cylindrical", "planar"}:
304 column.prop(self, "warp_orientation", text="Orientation")
305 column.prop(self, "warp_dist_exp", text="Exponent")
306 if self.warp_type == "toroidal":
307 column.prop(self, "warp_tor_major_radius", text="Major R")
309 def draw_buttons_ext(self, context, layout):
311 column = layout.column()
312 column.prop(self, "warp_type", text="Warp type")
313 if self.warp_type in {"toroidal", "spherical", "cylindrical", "planar"}:
314 column.prop(self, "warp_orientation", text="Orientation")
315 column.prop(self, "warp_dist_exp", text="Exponent")
316 if self.warp_type == "toroidal":
317 column.prop(self, "warp_tor_major_radius", text="Major R")
319 def draw_label(self):
320 return "Mapping"
323 class PovrayMultiplyNode(Node, nodes_properties.ObjectNodeTree):
324 """Multiply"""
326 bl_idname = "PovrayMultiplyNode"
327 bl_label = "Multiply"
328 bl_icon = "SHADING_SOLID"
330 amount_x: FloatProperty(
331 name="X", description="Number of repeats", min=1.0, max=10000.0, default=1.0
334 amount_y: FloatProperty(
335 name="Y", description="Number of repeats", min=1.0, max=10000.0, default=1.0
338 amount_z: FloatProperty(
339 name="Z", description="Number of repeats", min=1.0, max=10000.0, default=1.0
342 def init(self, context):
343 self.outputs.new("NodeSocketVector", "Amount")
345 def draw_buttons(self, context, layout):
347 column = layout.column()
348 column.label(text="Amount")
349 row = column.row(align=True)
350 row.prop(self, "amount_x")
351 row.prop(self, "amount_y")
352 row.prop(self, "amount_z")
354 def draw_buttons_ext(self, context, layout):
356 column = layout.column()
357 column.label(text="Amount")
358 row = column.row(align=True)
359 row.prop(self, "amount_x")
360 row.prop(self, "amount_y")
361 row.prop(self, "amount_z")
363 def draw_label(self):
364 return "Multiply"
367 class PovrayTransformNode(Node, nodes_properties.ObjectNodeTree):
368 """Transform"""
370 bl_idname = "PovrayTransformNode"
371 bl_label = "Transform"
372 bl_icon = "NODE_TEXTURE"
374 def init(self, context):
376 self.inputs.new("PovraySocketFloatUnlimited", "Translate x")
377 self.inputs.new("PovraySocketFloatUnlimited", "Translate y")
378 self.inputs.new("PovraySocketFloatUnlimited", "Translate z")
379 self.inputs.new("PovraySocketFloatUnlimited", "Rotate x")
380 self.inputs.new("PovraySocketFloatUnlimited", "Rotate y")
381 self.inputs.new("PovraySocketFloatUnlimited", "Rotate z")
382 sX = self.inputs.new("PovraySocketFloatUnlimited", "Scale x")
383 sX.default_value = 1.0
384 sY = self.inputs.new("PovraySocketFloatUnlimited", "Scale y")
385 sY.default_value = 1.0
386 sZ = self.inputs.new("PovraySocketFloatUnlimited", "Scale z")
387 sZ.default_value = 1.0
389 self.outputs.new("NodeSocketVector", "Transform")
391 def draw_label(self):
392 return "Transform"
395 class PovrayValueNode(Node, nodes_properties.ObjectNodeTree):
396 """Value"""
398 bl_idname = "PovrayValueNode"
399 bl_label = "Value"
400 bl_icon = "SHADING_SOLID"
402 def init(self, context):
404 self.outputs.new("PovraySocketUniversal", "Value")
406 def draw_label(self):
407 return "Value"
410 class PovrayModifierNode(Node, nodes_properties.ObjectNodeTree):
411 """Modifier"""
413 bl_idname = "PovrayModifierNode"
414 bl_label = "Modifier"
415 bl_icon = "NODE_TEXTURE"
417 def init(self, context):
419 turb_x = self.inputs.new("PovraySocketFloat_0_10", "Turb X")
420 turb_x.default_value = 0.1
421 turb_y = self.inputs.new("PovraySocketFloat_0_10", "Turb Y")
422 turb_y.default_value = 0.1
423 turb_z = self.inputs.new("PovraySocketFloat_0_10", "Turb Z")
424 turb_z.default_value = 0.1
425 octaves = self.inputs.new("PovraySocketInt_1_9", "Octaves")
426 octaves.default_value = 1
427 lambat = self.inputs.new("PovraySocketFloat_0_10", "Lambda")
428 lambat.default_value = 2.0
429 omega = self.inputs.new("PovraySocketFloat_0_10", "Omega")
430 omega.default_value = 0.5
431 freq = self.inputs.new("PovraySocketFloat_0_10", "Frequency")
432 freq.default_value = 2.0
433 self.inputs.new("PovraySocketFloat_0_10", "Phase")
435 self.outputs.new("NodeSocketVector", "Modifier")
437 def draw_label(self):
438 return "Modifier"
441 class PovrayPigmentNode(Node, nodes_properties.ObjectNodeTree):
442 """Pigment"""
444 bl_idname = "PovrayPigmentNode"
445 bl_label = "Color"
446 bl_icon = "SHADING_SOLID"
448 def init(self, context):
450 color = self.inputs.new("PovraySocketColor", "Color")
451 color.default_value = (1, 1, 1)
452 pov_filter = self.inputs.new("PovraySocketFloat_0_1", "Filter")
453 transmit = self.inputs.new("PovraySocketFloat_0_1", "Transmit")
454 self.outputs.new("NodeSocketColor", "Pigment")
456 def draw_label(self):
457 return "Color"
460 class PovrayColorImageNode(Node, nodes_properties.ObjectNodeTree):
461 """ColorImage"""
463 bl_idname = "PovrayColorImageNode"
464 bl_label = "Image map"
466 map_type: bpy.props.EnumProperty(
467 name="Map type",
468 description="",
469 items=(
470 ("uv_mapping", "UV", ""),
471 ("0", "Planar", "Default planar mapping"),
472 ("1", "Spherical", "Spherical mapping"),
473 ("2", "Cylindrical", "Cylindrical mapping"),
474 ("5", "Toroidal", "Torus or donut shaped mapping"),
476 default="0",
478 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
479 interpolate: EnumProperty(
480 name="Interpolate",
481 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
482 items=(
483 ("2", "Bilinear", "Gives bilinear interpolation"),
484 ("4", "Normalized", "Gives normalized distance"),
486 default="2",
488 premultiplied: BoolProperty(default=False)
489 once: BoolProperty(description="Not to repeat", default=False)
491 def init(self, context):
493 gamma = self.inputs.new("PovraySocketFloat_000001_10", "Gamma")
494 gamma.default_value = 2.0
495 transmit = self.inputs.new("PovraySocketFloat_0_1", "Transmit")
496 pov_filter = self.inputs.new("PovraySocketFloat_0_1", "Filter")
497 mapping = self.inputs.new("NodeSocketVector", "Mapping")
498 mapping.hide_value = True
499 transform = self.inputs.new("NodeSocketVector", "Transform")
500 transform.hide_value = True
501 modifier = self.inputs.new("NodeSocketVector", "Modifier")
502 modifier.hide_value = True
504 self.outputs.new("NodeSocketColor", "Pigment")
506 def draw_buttons(self, context, layout):
508 column = layout.column()
509 im = None
510 for image in bpy.data.images:
511 if image.name == self.image:
512 im = image
513 split = column.split(factor=0.8, align=True)
514 split.prop_search(self, "image", context.blend_data, "images", text="")
515 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
516 if im is not None:
517 column.prop(im, "source", text="")
518 column.prop(self, "map_type", text="")
519 column.prop(self, "interpolate", text="")
520 row = column.row()
521 row.prop(self, "premultiplied", text="Premul")
522 row.prop(self, "once", text="Once")
524 def draw_buttons_ext(self, context, layout):
526 column = layout.column()
527 im = None
528 for image in bpy.data.images:
529 if image.name == self.image:
530 im = image
531 split = column.split(factor=0.8, align=True)
532 split.prop_search(self, "image", context.blend_data, "images", text="")
533 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
534 if im is not None:
535 column.prop(im, "source", text="")
536 column.prop(self, "map_type", text="")
537 column.prop(self, "interpolate", text="")
538 row = column.row()
539 row.prop(self, "premultiplied", text="Premul")
540 row.prop(self, "once", text="Once")
542 def draw_label(self):
543 return "Image map"
546 class PovrayBumpMapNode(Node, nodes_properties.ObjectNodeTree):
547 """BumpMap"""
549 bl_idname = "PovrayBumpMapNode"
550 bl_label = "Bump map"
551 bl_icon = "TEXTURE"
553 map_type: bpy.props.EnumProperty(
554 name="Map type",
555 description="",
556 items=(
557 ("uv_mapping", "UV", ""),
558 ("0", "Planar", "Default planar mapping"),
559 ("1", "Spherical", "Spherical mapping"),
560 ("2", "Cylindrical", "Cylindrical mapping"),
561 ("5", "Toroidal", "Torus or donut shaped mapping"),
563 default="0",
565 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
566 interpolate: EnumProperty(
567 name="Interpolate",
568 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
569 items=(
570 ("2", "Bilinear", "Gives bilinear interpolation"),
571 ("4", "Normalized", "Gives normalized distance"),
573 default="2",
575 once: BoolProperty(description="Not to repeat", default=False)
577 def init(self, context):
579 self.inputs.new("PovraySocketFloat_0_10", "Normal")
580 mapping = self.inputs.new("NodeSocketVector", "Mapping")
581 mapping.hide_value = True
582 transform = self.inputs.new("NodeSocketVector", "Transform")
583 transform.hide_value = True
584 modifier = self.inputs.new("NodeSocketVector", "Modifier")
585 modifier.hide_value = True
587 normal = self.outputs.new("NodeSocketFloat", "Normal")
588 normal.hide_value = True
590 def draw_buttons(self, context, layout):
592 column = layout.column()
593 im = None
594 for image in bpy.data.images:
595 if image.name == self.image:
596 im = image
597 split = column.split(factor=0.8, align=True)
598 split.prop_search(self, "image", context.blend_data, "images", text="")
599 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
600 if im is not None:
601 column.prop(im, "source", text="")
602 column.prop(self, "map_type", text="")
603 column.prop(self, "interpolate", text="")
604 column.prop(self, "once", text="Once")
606 def draw_buttons_ext(self, context, layout):
608 column = layout.column()
609 im = None
610 for image in bpy.data.images:
611 if image.name == self.image:
612 im = image
613 split = column.split(factor=0.8, align=True)
614 split.prop_search(self, "image", context.blend_data, "images", text="")
615 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
616 if im is not None:
617 column.prop(im, "source", text="")
618 column.prop(self, "map_type", text="")
619 column.prop(self, "interpolate", text="")
620 column.prop(self, "once", text="Once")
622 def draw_label(self):
623 return "Bump Map"
626 class PovrayImagePatternNode(Node, nodes_properties.ObjectNodeTree):
627 """ImagePattern"""
629 bl_idname = "PovrayImagePatternNode"
630 bl_label = "Image pattern"
631 bl_icon = "NODE_TEXTURE"
633 map_type: bpy.props.EnumProperty(
634 name="Map type",
635 description="",
636 items=(
637 ("uv_mapping", "UV", ""),
638 ("0", "Planar", "Default planar mapping"),
639 ("1", "Spherical", "Spherical mapping"),
640 ("2", "Cylindrical", "Cylindrical mapping"),
641 ("5", "Toroidal", "Torus or donut shaped mapping"),
643 default="0",
645 image: StringProperty(maxlen=1024) # , subtype="FILE_PATH"
646 interpolate: EnumProperty(
647 name="Interpolate",
648 description="Adding the interpolate keyword can smooth the jagged look of a bitmap",
649 items=(
650 ("2", "Bilinear", "Gives bilinear interpolation"),
651 ("4", "Normalized", "Gives normalized distance"),
653 default="2",
655 premultiplied: BoolProperty(default=False)
656 once: BoolProperty(description="Not to repeat", default=False)
657 use_alpha: BoolProperty(default=True)
659 def init(self, context):
661 gamma = self.inputs.new("PovraySocketFloat_000001_10", "Gamma")
662 gamma.default_value = 2.0
664 self.outputs.new("PovraySocketPattern", "Pattern")
666 def draw_buttons(self, context, layout):
668 column = layout.column()
669 im = None
670 for image in bpy.data.images:
671 if image.name == self.image:
672 im = image
673 split = column.split(factor=0.8, align=True)
674 split.prop_search(self, "image", context.blend_data, "images", text="")
675 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
676 if im is not None:
677 column.prop(im, "source", text="")
678 column.prop(self, "map_type", text="")
679 column.prop(self, "interpolate", text="")
680 row = column.row()
681 row.prop(self, "premultiplied", text="Premul")
682 row.prop(self, "once", text="Once")
683 column.prop(self, "use_alpha", text="Use alpha")
685 def draw_buttons_ext(self, context, layout):
687 column = layout.column()
688 im = None
689 for image in bpy.data.images:
690 if image.name == self.image:
691 im = image
692 split = column.split(factor=0.8, align=True)
693 split.prop_search(self, "image", context.blend_data, "images", text="")
694 split.operator("pov.imageopen", text="", icon="FILEBROWSER")
695 if im is not None:
696 column.prop(im, "source", text="")
697 column.prop(self, "map_type", text="")
698 column.prop(self, "interpolate", text="")
699 row = column.row()
700 row.prop(self, "premultiplied", text="Premul")
701 row.prop(self, "once", text="Once")
703 def draw_label(self):
704 return "Image pattern"
707 class ShaderPatternNode(Node, nodes_properties.ObjectNodeTree):
708 """Pattern"""
710 bl_idname = "ShaderPatternNode"
711 bl_label = "Other patterns"
713 pattern: EnumProperty(
714 name="Pattern",
715 description="Agate, Crackle, Gradient, Pavement, Spiral, Tiling",
716 items=(
717 ("agate", "Agate", ""),
718 ("crackle", "Crackle", ""),
719 ("gradient", "Gradient", ""),
720 ("pavement", "Pavement", ""),
721 ("spiral1", "Spiral 1", ""),
722 ("spiral2", "Spiral 2", ""),
723 ("tiling", "Tiling", ""),
725 default="agate",
728 agate_turb: FloatProperty(
729 name="Agate turb", description="Agate turbulence", min=0.0, max=100.0, default=0.5
732 crackle_form_x: FloatProperty(
733 name="X", description="Form vector X", min=-150.0, max=150.0, default=-1
736 crackle_form_y: FloatProperty(
737 name="Y", description="Form vector Y", min=-150.0, max=150.0, default=1
740 crackle_form_z: FloatProperty(
741 name="Z", description="Form vector Z", min=-150.0, max=150.0, default=0
744 crackle_metric: FloatProperty(
745 name="Metric", description="Crackle metric", min=0.0, max=150.0, default=1
748 crackle_solid: BoolProperty(name="Solid", description="Crackle solid", default=False)
750 spiral_arms: FloatProperty(name="Number", description="", min=0.0, max=256.0, default=2.0)
752 tiling_number: IntProperty(name="Number", description="", min=1, max=27, default=1)
754 gradient_orient: EnumProperty(
755 name="Orient",
756 description="",
757 items=(("x", "X", ""), ("y", "Y", ""), ("z", "Z", "")),
758 default="x",
761 def init(self, context):
763 pat = self.outputs.new("PovraySocketPattern", "Pattern")
765 def draw_buttons(self, context, layout):
767 layout.prop(self, "pattern", text="")
768 if self.pattern == "agate":
769 layout.prop(self, "agate_turb")
770 if self.pattern == "crackle":
771 layout.prop(self, "crackle_metric")
772 layout.prop(self, "crackle_solid")
773 layout.label(text="Form:")
774 layout.prop(self, "crackle_form_x")
775 layout.prop(self, "crackle_form_y")
776 layout.prop(self, "crackle_form_z")
777 if self.pattern in {"spiral1", "spiral2"}:
778 layout.prop(self, "spiral_arms")
779 if self.pattern in {"tiling"}:
780 layout.prop(self, "tiling_number")
781 if self.pattern in {"gradient"}:
782 layout.prop(self, "gradient_orient")
784 def draw_buttons_ext(self, context, layout):
785 pass
787 def draw_label(self):
788 return "Other patterns"
791 class ShaderTextureMapNode(Node, nodes_properties.ObjectNodeTree):
792 """Texture Map"""
794 bl_idname = "ShaderTextureMapNode"
795 bl_label = "Texture map"
797 brick_size_x: FloatProperty(name="X", description="", min=0.0000, max=1.0000, default=0.2500)
799 brick_size_y: FloatProperty(name="Y", description="", min=0.0000, max=1.0000, default=0.0525)
801 brick_size_z: FloatProperty(name="Z", description="", min=0.0000, max=1.0000, default=0.1250)
803 brick_mortar: FloatProperty(
804 name="Mortar", description="Mortar", min=0.000, max=1.500, default=0.01
807 def init(self, context):
808 mat = bpy.context.object.active_material
809 self.inputs.new("PovraySocketPattern", "")
810 color = self.inputs.new("NodeSocketColor", "Color ramp")
811 color.hide_value = True
812 for i in range(4):
813 transform = self.inputs.new("PovraySocketTransform", "Transform")
814 transform.hide_value = True
815 number = mat.pov.inputs_number
816 for i in range(number):
817 self.inputs.new("PovraySocketTexture", "%s" % i)
819 self.outputs.new("PovraySocketTexture", "Texture")
821 def draw_buttons(self, context, layout):
823 if self.inputs[0].default_value == "brick":
824 layout.prop(self, "brick_mortar")
825 layout.label(text="Brick size:")
826 layout.prop(self, "brick_size_x")
827 layout.prop(self, "brick_size_y")
828 layout.prop(self, "brick_size_z")
830 def draw_buttons_ext(self, context, layout):
832 if self.inputs[0].default_value == "brick":
833 layout.prop(self, "brick_mortar")
834 layout.label(text="Brick size:")
835 layout.prop(self, "brick_size_x")
836 layout.prop(self, "brick_size_y")
837 layout.prop(self, "brick_size_z")
839 def draw_label(self):
840 return "Texture map"
843 class ShaderNormalMapNode(Node, nodes_properties.ObjectNodeTree):
844 """Normal Map"""
846 bl_idname = "ShaderNormalMapNode"
847 bl_label = "Normal map"
849 brick_size_x: FloatProperty(name="X", description="", min=0.0000, max=1.0000, default=0.2500)
851 brick_size_y: FloatProperty(name="Y", description="", min=0.0000, max=1.0000, default=0.0525)
853 brick_size_z: FloatProperty(name="Z", description="", min=0.0000, max=1.0000, default=0.1250)
855 brick_mortar: FloatProperty(
856 name="Mortar", description="Mortar", min=0.000, max=1.500, default=0.01
859 def init(self, context):
860 self.inputs.new("PovraySocketPattern", "")
861 normal = self.inputs.new("PovraySocketFloat_10", "Normal")
862 slope = self.inputs.new("PovraySocketMap", "Slope map")
863 for i in range(4):
864 transform = self.inputs.new("PovraySocketTransform", "Transform")
865 transform.hide_value = True
866 self.outputs.new("PovraySocketNormal", "Normal")
868 def draw_buttons(self, context, layout):
869 # for i, inp in enumerate(self.inputs):
871 if self.inputs[0].default_value == "brick":
872 layout.prop(self, "brick_mortar")
873 layout.label(text="Brick size:")
874 layout.prop(self, "brick_size_x")
875 layout.prop(self, "brick_size_y")
876 layout.prop(self, "brick_size_z")
878 def draw_buttons_ext(self, context, layout):
880 if self.inputs[0].default_value == "brick":
881 layout.prop(self, "brick_mortar")
882 layout.label(text="Brick size:")
883 layout.prop(self, "brick_size_x")
884 layout.prop(self, "brick_size_y")
885 layout.prop(self, "brick_size_z")
887 def draw_label(self):
888 return "Normal map"
891 class ShaderNormalMapEntryNode(Node, nodes_properties.ObjectNodeTree):
892 """Normal Map Entry"""
894 bl_idname = "ShaderNormalMapEntryNode"
895 bl_label = "Normal map entry"
897 def init(self, context):
898 self.inputs.new("PovraySocketFloat_0_1", "Stop")
899 self.inputs.new("PovraySocketFloat_0_1", "Gray")
901 def draw_label(self):
902 return "Normal map entry"
905 class IsoPropsNode(Node, CompositorNodeTree):
906 """ISO Props"""
908 bl_idname = "IsoPropsNode"
909 bl_label = "Iso"
910 node_label: StringProperty(maxlen=1024)
912 def init(self, context):
913 ob = bpy.context.object
914 self.node_label = ob.name
915 text_name = ob.pov.function_text
916 if text_name:
917 text = bpy.data.texts[text_name]
918 for line in text.lines:
919 split = line.body.split()
920 if split[0] == "#declare":
921 socket = self.inputs.new("NodeSocketFloat", "%s" % split[1])
922 value = split[3].split(";")
923 value = value[0]
924 socket.default_value = float(value)
926 def draw_label(self):
927 return self.node_label
930 class PovrayFogNode(Node, CompositorNodeTree):
931 """Fog settings"""
933 bl_idname = "PovrayFogNode"
934 bl_label = "Fog"
936 def init(self, context):
937 color = self.inputs.new("NodeSocketColor", "Color")
938 color.default_value = (0.7, 0.7, 0.7, 0.25)
939 self.inputs.new("PovraySocketFloat_0_1", "Filter")
940 distance = self.inputs.new("NodeSocketInt", "Distance")
941 distance.default_value = 150
942 self.inputs.new("NodeSocketBool", "Ground")
943 fog_offset = self.inputs.new("NodeSocketFloat", "Offset")
944 fog_alt = self.inputs.new("NodeSocketFloat", "Altitude")
945 turb = self.inputs.new("NodeSocketVector", "Turbulence")
946 turb_depth = self.inputs.new("PovraySocketFloat_0_10", "Depth")
947 turb_depth.default_value = 0.5
948 octaves = self.inputs.new("PovraySocketInt_1_9", "Octaves")
949 octaves.default_value = 5
950 lambdat = self.inputs.new("PovraySocketFloat_0_10", "Lambda")
951 lambdat.default_value = 1.25
952 omega = self.inputs.new("PovraySocketFloat_0_10", "Omega")
953 omega.default_value = 0.35
954 translate = self.inputs.new("NodeSocketVector", "Translate")
955 rotate = self.inputs.new("NodeSocketVector", "Rotate")
956 scale = self.inputs.new("NodeSocketVector", "Scale")
957 scale.default_value = (1, 1, 1)
959 def draw_label(self):
960 return "Fog"
963 class PovraySlopeNode(Node, TextureNodeTree):
964 """Output"""
966 bl_idname = "PovraySlopeNode"
967 bl_label = "Slope Map"
969 def init(self, context):
970 self.use_custom_color = True
971 self.color = (0, 0.2, 0)
972 slope = self.inputs.new("PovraySocketSlope", "0")
973 slope = self.inputs.new("PovraySocketSlope", "1")
974 slopemap = self.outputs.new("PovraySocketMap", "Slope map")
975 slopemap.hide_value = True
977 def draw_buttons(self, context, layout):
979 layout.operator("pov.nodeinputadd")
980 row = layout.row()
981 row.label(text="Value")
982 row.label(text="Height")
983 row.label(text="Slope")
985 def draw_buttons_ext(self, context, layout):
987 layout.operator("pov.nodeinputadd")
988 row = layout.row()
989 row.label(text="Value")
990 row.label(text="Height")
991 row.label(text="Slope")
993 def draw_label(self):
994 return "Slope Map"
997 # -------- Texture nodes
998 class TextureOutputNode(Node, TextureNodeTree):
999 """Output"""
1001 bl_idname = "TextureOutputNode"
1002 bl_label = "Color Map"
1004 def init(self, context):
1005 tex = bpy.context.object.active_material.active_texture
1006 num_sockets = int(tex.pov.density_lines / 32)
1007 for i in range(num_sockets):
1008 color = self.inputs.new("NodeSocketColor", "%s" % i)
1009 color.hide_value = True
1011 def draw_buttons(self, context, layout):
1013 layout.label(text="Color Ramps:")
1015 def draw_label(self):
1016 return "Color Map"
1019 classes = (
1020 PovrayOutputNode,
1021 PovrayTextureNode,
1022 PovrayFinishNode,
1023 PovrayDiffuseNode,
1024 PovrayPhongNode,
1025 PovraySpecularNode,
1026 PovrayMirrorNode,
1027 PovrayAmbientNode,
1028 PovrayIridescenceNode,
1029 PovraySubsurfaceNode,
1030 PovrayMappingNode,
1031 PovrayMultiplyNode,
1032 PovrayTransformNode,
1033 PovrayValueNode,
1034 PovrayModifierNode,
1035 PovrayPigmentNode,
1036 PovrayColorImageNode,
1037 PovrayBumpMapNode,
1038 PovrayImagePatternNode,
1039 ShaderPatternNode,
1040 ShaderTextureMapNode,
1041 ShaderNormalMapNode,
1042 ShaderNormalMapEntryNode,
1043 IsoPropsNode,
1044 PovrayFogNode,
1045 PovraySlopeNode,
1046 TextureOutputNode,
1050 def register():
1051 for cls in classes:
1052 register_class(cls)
1055 def unregister():
1056 for cls in reversed(classes):
1057 unregister_class(cls)