Node Wrangler: Add more specific poll methods
[blender-addons.git] / render_povray / nodes_fn.py
blob6b134e8b57316f4f5ba7eac95f4619f514ebb92b
1 # SPDX-FileCopyrightText: 2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 """Translate complex shaders to exported POV textures."""
7 import bpy
9 # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10 def write_nodes(pov_mat_name, ntree, file):
11 """Translate Blender node trees to pov and write them to file."""
12 # such function local inlined import are official guidelines
13 # of Blender Foundation to lighten addons footprint at startup
14 from os import path
15 from .render import string_strip_hyphen
17 declare_nodes = []
18 scene = bpy.context.scene
19 for node in ntree.nodes:
20 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
21 if node.bl_idname == "PovrayFinishNode" and node.outputs["Finish"].is_linked:
22 file.write("#declare %s = finish {\n" % pov_node_name)
23 emission = node.inputs["Emission"].default_value
24 if node.inputs["Emission"].is_linked:
25 pass
26 file.write(" emission %.4g\n" % emission)
27 for link in ntree.links:
28 if link.to_node == node:
30 if link.from_node.bl_idname == "PovrayDiffuseNode":
31 intensity = 0
32 albedo = ""
33 brilliance = 0
34 crand = 0
35 if link.from_node.inputs["Intensity"].is_linked:
36 pass
37 else:
38 intensity = link.from_node.inputs["Intensity"].default_value
39 if link.from_node.inputs["Albedo"].is_linked:
40 pass
41 else:
42 if link.from_node.inputs["Albedo"].default_value:
43 albedo = "albedo"
44 file.write(" diffuse %s %.4g\n" % (albedo, intensity))
45 if link.from_node.inputs["Brilliance"].is_linked:
46 pass
47 else:
48 brilliance = link.from_node.inputs["Brilliance"].default_value
49 file.write(" brilliance %.4g\n" % brilliance)
50 if link.from_node.inputs["Crand"].is_linked:
51 pass
52 else:
53 crand = link.from_node.inputs["Crand"].default_value
54 if crand > 0:
55 file.write(" crand %.4g\n" % crand)
57 if link.from_node.bl_idname == "PovraySubsurfaceNode":
58 if scene.povray.sslt_enable:
59 energy = 0
60 r = g = b = 0
61 if link.from_node.inputs["Translucency"].is_linked:
62 pass
63 else:
64 r, g, b, a = link.from_node.inputs["Translucency"].default_value[:]
65 if link.from_node.inputs["Energy"].is_linked:
66 pass
67 else:
68 energy = link.from_node.inputs["Energy"].default_value
69 file.write(
70 " subsurface { translucency <%.4g,%.4g,%.4g>*%s }\n"
71 % (r, g, b, energy)
74 if link.from_node.bl_idname in {"PovraySpecularNode", "PovrayPhongNode"}:
75 intensity = 0
76 albedo = ""
77 roughness = 0
78 metallic = 0
79 phong_size = 0
80 highlight = "specular"
81 if link.from_node.inputs["Intensity"].is_linked:
82 pass
83 else:
84 intensity = link.from_node.inputs["Intensity"].default_value
86 if link.from_node.inputs["Albedo"].is_linked:
87 pass
88 else:
89 if link.from_node.inputs["Albedo"].default_value:
90 albedo = "albedo"
91 if link.from_node.bl_idname in {"PovrayPhongNode"}:
92 highlight = "phong"
93 file.write(" %s %s %.4g\n" % (highlight, albedo, intensity))
95 if link.from_node.bl_idname in {"PovraySpecularNode"}:
96 if link.from_node.inputs["Roughness"].is_linked:
97 pass
98 else:
99 roughness = link.from_node.inputs["Roughness"].default_value
100 file.write(" roughness %.6g\n" % roughness)
102 if link.from_node.bl_idname in {"PovrayPhongNode"}:
103 if link.from_node.inputs["Size"].is_linked:
104 pass
105 else:
106 phong_size = link.from_node.inputs["Size"].default_value
107 file.write(" phong_size %s\n" % phong_size)
109 if link.from_node.inputs["Metallic"].is_linked:
110 pass
111 else:
112 metallic = link.from_node.inputs["Metallic"].default_value
113 file.write(" metallic %.4g\n" % metallic)
115 if link.from_node.bl_idname in {"PovrayMirrorNode"}:
116 file.write(" reflection {\n")
117 color = None
118 exponent = 0
119 metallic = 0
120 falloff = 0
121 fresnel = ""
122 conserve = ""
123 if link.from_node.inputs["Color"].is_linked:
124 pass
125 else:
126 color = link.from_node.inputs["Color"].default_value[:]
127 file.write(" <%.4g,%.4g,%.4g>\n" % (color[0], color[1], color[2]))
129 if link.from_node.inputs["Exponent"].is_linked:
130 pass
131 else:
132 exponent = link.from_node.inputs["Exponent"].default_value
133 file.write(" exponent %.4g\n" % exponent)
135 if link.from_node.inputs["Falloff"].is_linked:
136 pass
137 else:
138 falloff = link.from_node.inputs["Falloff"].default_value
139 file.write(" falloff %.4g\n" % falloff)
141 if link.from_node.inputs["Metallic"].is_linked:
142 pass
143 else:
144 metallic = link.from_node.inputs["Metallic"].default_value
145 file.write(" metallic %.4g" % metallic)
147 if link.from_node.inputs["Fresnel"].is_linked:
148 pass
149 else:
150 if link.from_node.inputs["Fresnel"].default_value:
151 fresnel = "fresnel"
153 if link.from_node.inputs["Conserve energy"].is_linked:
154 pass
155 else:
156 if link.from_node.inputs["Conserve energy"].default_value:
157 conserve = "conserve_energy"
159 file.write(" %s}\n %s\n" % (fresnel, conserve))
161 if link.from_node.bl_idname == "PovrayAmbientNode":
162 ambient = (0, 0, 0)
163 if link.from_node.inputs["Ambient"].is_linked:
164 pass
165 else:
166 ambient = link.from_node.inputs["Ambient"].default_value[:]
167 file.write(" ambient <%.4g,%.4g,%.4g>\n" % ambient)
169 if link.from_node.bl_idname in {"PovrayIridescenceNode"}:
170 file.write(" irid {\n")
171 amount = 0
172 thickness = 0
173 turbulence = 0
174 if link.from_node.inputs["Amount"].is_linked:
175 pass
176 else:
177 amount = link.from_node.inputs["Amount"].default_value
178 file.write(" %.4g\n" % amount)
180 if link.from_node.inputs["Thickness"].is_linked:
181 pass
182 else:
183 exponent = link.from_node.inputs["Thickness"].default_value
184 file.write(" thickness %.4g\n" % thickness)
186 if link.from_node.inputs["Turbulence"].is_linked:
187 pass
188 else:
189 falloff = link.from_node.inputs["Turbulence"].default_value
190 file.write(" turbulence %.4g}\n" % turbulence)
192 file.write("}\n")
194 for node in ntree.nodes:
195 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
196 if node.bl_idname == "PovrayTransformNode" and node.outputs["Transform"].is_linked:
197 tx = node.inputs["Translate x"].default_value
198 ty = node.inputs["Translate y"].default_value
199 tz = node.inputs["Translate z"].default_value
200 rx = node.inputs["Rotate x"].default_value
201 ry = node.inputs["Rotate y"].default_value
202 rz = node.inputs["Rotate z"].default_value
203 sx = node.inputs["Scale x"].default_value
204 sy = node.inputs["Scale y"].default_value
205 sz = node.inputs["Scale z"].default_value
206 file.write(
207 "#declare %s = transform {\n"
208 " translate<%.4g,%.4g,%.4g>\n"
209 " rotate<%.4g,%.4g,%.4g>\n"
210 " scale<%.4g,%.4g,%.4g>}\n" % (pov_node_name, tx, ty, tz, rx, ry, rz, sx, sy, sz)
213 for node in ntree.nodes:
214 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
215 if node.bl_idname == "PovrayColorImageNode" and node.outputs["Pigment"].is_linked:
216 declare_nodes.append(node.name)
217 if node.image == "":
218 file.write("#declare %s = pigment { color rgb 0.8}\n" % pov_node_name)
219 else:
220 im = bpy.data.images[node.image]
221 if im.filepath and path.exists(bpy.path.abspath(im.filepath)): # (os.path)
222 transform = ""
223 for link in ntree.links:
224 if (
225 link.from_node.bl_idname == "PovrayTransformNode"
226 and link.to_node == node
228 pov_trans_name = (
229 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
230 + "_%s" % pov_mat_name
232 transform = "transform {%s}" % pov_trans_name
233 uv = ""
234 if node.map_type == "uv_mapping":
235 uv = "uv_mapping"
236 filepath = bpy.path.abspath(im.filepath)
237 file.write("#declare %s = pigment {%s image_map {\n" % (pov_node_name, uv))
238 premul = "off"
239 if node.premultiplied:
240 premul = "on"
241 once = ""
242 if node.once:
243 once = "once"
244 file.write(
245 ' "%s"\n gamma %.6g\n premultiplied %s\n'
246 % (filepath, node.inputs["Gamma"].default_value, premul)
248 file.write(" %s\n" % once)
249 if node.map_type != "uv_mapping":
250 file.write(" map_type %s\n" % node.map_type)
251 file.write(
252 " interpolate %s\n filter all %.4g\n transmit all %.4g\n"
254 node.interpolate,
255 node.inputs["Filter"].default_value,
256 node.inputs["Transmit"].default_value,
259 file.write(" }\n")
260 file.write(" %s\n" % transform)
261 file.write(" }\n")
263 for node in ntree.nodes:
264 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
265 if node.bl_idname == "PovrayImagePatternNode" and node.outputs["Pattern"].is_linked:
266 declare_nodes.append(node.name)
267 if node.image != "":
268 im = bpy.data.images[node.image]
269 if im.filepath and path.exists(bpy.path.abspath(im.filepath)):
270 transform = ""
271 for link in ntree.links:
272 if (
273 link.from_node.bl_idname == "PovrayTransformNode"
274 and link.to_node == node
276 pov_trans_name = (
277 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
278 + "_%s" % pov_mat_name
280 transform = "transform {%s}" % pov_trans_name
281 uv = ""
282 if node.map_type == "uv_mapping":
283 uv = "uv_mapping"
284 filepath = bpy.path.abspath(im.filepath)
285 file.write("#macro %s() %s image_pattern {\n" % (pov_node_name, uv))
286 premul = "off"
287 if node.premultiplied:
288 premul = "on"
289 once = ""
290 if node.once:
291 once = "once"
292 file.write(
293 ' "%s"\n gamma %.6g\n premultiplied %s\n'
294 % (filepath, node.inputs["Gamma"].default_value, premul)
296 file.write(" %s\n" % once)
297 if node.map_type != "uv_mapping":
298 file.write(" map_type %s\n" % node.map_type)
299 file.write(" interpolate %s\n" % node.interpolate)
300 file.write(" }\n")
301 file.write(" %s\n" % transform)
302 file.write("#end\n")
304 for node in ntree.nodes:
305 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
306 if node.bl_idname == "PovrayBumpMapNode" and node.outputs["Normal"].is_linked:
307 if node.image != "":
308 im = bpy.data.images[node.image]
309 if im.filepath and path.exists(bpy.path.abspath(im.filepath)):
310 transform = ""
311 for link in ntree.links:
312 if (
313 link.from_node.bl_idname == "PovrayTransformNode"
314 and link.to_node == node
316 pov_trans_name = (
317 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
318 + "_%s" % pov_mat_name
320 transform = "transform {%s}" % pov_trans_name
321 uv = ""
322 if node.map_type == "uv_mapping":
323 uv = "uv_mapping"
324 filepath = bpy.path.abspath(im.filepath)
325 file.write("#declare %s = normal {%s bump_map {\n" % (pov_node_name, uv))
326 once = ""
327 if node.once:
328 once = "once"
329 file.write(' "%s"\n' % filepath)
330 file.write(" %s\n" % once)
331 if node.map_type != "uv_mapping":
332 file.write(" map_type %s\n" % node.map_type)
333 bump_size = node.inputs["Normal"].default_value
334 if node.inputs["Normal"].is_linked:
335 pass
336 file.write(
337 " interpolate %s\n bump_size %.4g\n" % (node.interpolate, bump_size)
339 file.write(" }\n")
340 file.write(" %s\n" % transform)
341 file.write(" }\n")
342 declare_nodes.append(node.name)
344 for node in ntree.nodes:
345 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
346 if node.bl_idname == "PovrayPigmentNode" and node.outputs["Pigment"].is_linked:
347 declare_nodes.append(node.name)
348 r, g, b = node.inputs["Color"].default_value[:]
349 f = node.inputs["Filter"].default_value
350 t = node.inputs["Transmit"].default_value
351 if node.inputs["Color"].is_linked:
352 pass
353 file.write(
354 "#declare %s = pigment{color srgbft <%.4g,%.4g,%.4g,%.4g,%.4g>}\n"
355 % (pov_node_name, r, g, b, f, t)
358 for node in ntree.nodes:
359 pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name
360 if node.bl_idname == "PovrayTextureNode" and node.outputs["Texture"].is_linked:
361 declare_nodes.append(node.name)
362 r, g, b = node.inputs["Pigment"].default_value[:]
363 pov_col_name = "color rgb <%.4g,%.4g,%.4g>" % (r, g, b)
364 if node.inputs["Pigment"].is_linked:
365 for link in ntree.links:
366 if link.to_node == node and link.to_socket.name == "Pigment":
367 pov_col_name = (
368 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
369 + "_%s" % pov_mat_name
371 file.write("#declare %s = texture{\n pigment{%s}\n" % (pov_node_name, pov_col_name))
372 if node.inputs["Normal"].is_linked:
373 for link in ntree.links:
374 if (
375 link.to_node == node
376 and link.to_socket.name == "Normal"
377 and link.from_node.name in declare_nodes
379 pov_nor_name = (
380 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
381 + "_%s" % pov_mat_name
383 file.write(" normal{%s}\n" % pov_nor_name)
384 if node.inputs["Finish"].is_linked:
385 for link in ntree.links:
386 if link.to_node == node and link.to_socket.name == "Finish":
387 pov_fin_name = (
388 string_strip_hyphen(bpy.path.clean_name(link.from_node.name))
389 + "_%s" % pov_mat_name
391 file.write(" finish{%s}\n" % pov_fin_name)
392 file.write("}\n")
393 declare_nodes.append(node.name)
395 for i in range(0, len(ntree.nodes)):
396 for node in ntree.nodes:
397 if node.bl_idname in {"ShaderNodeGroup", "ShaderTextureMapNode"}:
398 for output in node.outputs:
399 if (
400 output.name == "Texture"
401 and output.is_linked
402 and (node.name not in declare_nodes)
404 declare = True
405 for link in ntree.links:
406 if link.to_node == node and link.to_socket.name not in {
408 "Color ramp",
409 "Mapping",
410 "Transform",
411 "Modifier",
413 if link.from_node.name not in declare_nodes:
414 declare = False
415 if declare:
416 pov_node_name = (
417 string_strip_hyphen(bpy.path.clean_name(node.name))
418 + "_%s" % pov_mat_name
420 uv = ""
421 warp = ""
422 for link in ntree.links:
423 if (
424 link.to_node == node
425 and link.from_node.bl_idname == "PovrayMappingNode"
426 and link.from_node.warp_type != "NONE"
428 w_type = link.from_node.warp_type
429 if w_type == "uv_mapping":
430 uv = "uv_mapping"
431 else:
432 tor = ""
433 if w_type == "toroidal":
434 tor = (
435 "major_radius %.4g"
436 % link.from_node.warp_tor_major_radius
438 orient = link.from_node.warp_orientation
439 exp = link.from_node.warp_dist_exp
440 warp = "warp{%s orientation %s dist_exp %.4g %s}" % (
441 w_type,
442 orient,
443 exp,
444 tor,
446 if link.from_node.warp_type == "planar":
447 warp = "warp{%s %s %.4g}" % (w_type, orient, exp)
448 if link.from_node.warp_type == "cubic":
449 warp = "warp{%s}" % w_type
450 file.write("#declare %s = texture {%s\n" % (pov_node_name, uv))
451 pattern = node.inputs[0].default_value
452 advanced = ""
453 if node.inputs[0].is_linked:
454 for link in ntree.links:
455 if (
456 link.to_node == node
457 and link.from_node.bl_idname == "ShaderPatternNode"
459 # ------------ advanced ------------------------- #
460 lfn = link.from_node
461 pattern = lfn.pattern
462 if pattern == "agate":
463 advanced = "agate_turb %.4g" % lfn.agate_turb
464 if pattern == "crackle":
465 advanced = "form <%.4g,%.4g,%.4g>" % (
466 lfn.crackle_form_x,
467 lfn.crackle_form_y,
468 lfn.crackle_form_z,
470 advanced += " metric %.4g" % lfn.crackle_metric
471 if lfn.crackle_solid:
472 advanced += " solid"
473 if pattern in {"spiral1", "spiral2"}:
474 advanced = "%.4g" % lfn.spiral_arms
475 if pattern in {"tiling"}:
476 advanced = "%.4g" % lfn.tiling_number
477 if pattern in {"gradient"}:
478 advanced = "%s" % lfn.gradient_orient
479 if (
480 link.to_node == node
481 and link.from_node.bl_idname == "PovrayImagePatternNode"
483 pov_macro_name = (
484 string_strip_hyphen(
485 bpy.path.clean_name(link.from_node.name)
487 + "_%s" % pov_mat_name
489 pattern = "%s()" % pov_macro_name
490 file.write(" %s %s %s\n" % (pattern, advanced, warp))
492 repeat = ""
493 for link in ntree.links:
494 if (
495 link.to_node == node
496 and link.from_node.bl_idname == "PovrayMultiplyNode"
498 if link.from_node.amount_x > 1:
499 repeat += "warp{repeat %.4g * x}" % link.from_node.amount_x
500 if link.from_node.amount_y > 1:
501 repeat += " warp{repeat %.4g * y}" % link.from_node.amount_y
502 if link.from_node.amount_z > 1:
503 repeat += " warp{repeat %.4g * z}" % link.from_node.amount_z
505 transform = ""
506 for link in ntree.links:
507 if (
508 link.to_node == node
509 and link.from_node.bl_idname == "PovrayTransformNode"
511 pov_trans_name = (
512 string_strip_hyphen(
513 bpy.path.clean_name(link.from_node.name)
515 + "_%s" % pov_mat_name
517 transform = "transform {%s}" % pov_trans_name
518 x = 0
519 y = 0
520 z = 0
521 d = 0
522 e = 0
523 f = 0
524 g = 0
525 h = 0
526 modifier = False
527 for link in ntree.links:
528 if (
529 link.to_node == node
530 and link.from_node.bl_idname == "PovrayModifierNode"
532 modifier = True
533 if link.from_node.inputs["Turb X"].is_linked:
534 pass
535 else:
536 x = link.from_node.inputs["Turb X"].default_value
538 if link.from_node.inputs["Turb Y"].is_linked:
539 pass
540 else:
541 y = link.from_node.inputs["Turb Y"].default_value
543 if link.from_node.inputs["Turb Z"].is_linked:
544 pass
545 else:
546 z = link.from_node.inputs["Turb Z"].default_value
548 if link.from_node.inputs["Octaves"].is_linked:
549 pass
550 else:
551 d = link.from_node.inputs["Octaves"].default_value
553 if link.from_node.inputs["Lambda"].is_linked:
554 pass
555 else:
556 e = link.from_node.inputs["Lambda"].default_value
558 if link.from_node.inputs["Omega"].is_linked:
559 pass
560 else:
561 f = link.from_node.inputs["Omega"].default_value
563 if link.from_node.inputs["Frequency"].is_linked:
564 pass
565 else:
566 g = link.from_node.inputs["Frequency"].default_value
568 if link.from_node.inputs["Phase"].is_linked:
569 pass
570 else:
571 h = link.from_node.inputs["Phase"].default_value
573 turb = "turbulence <%.4g,%.4g,%.4g>" % (x, y, z)
574 octv = "octaves %s" % d
575 lmbd = "lambda %.4g" % e
576 omg = "omega %.4g" % f
577 freq = "frequency %.4g" % g
578 pha = "phase %.4g" % h
580 file.write("\n")
581 if pattern not in {
582 "checker",
583 "hexagon",
584 "square",
585 "triangular",
586 "brick",
588 file.write(" texture_map {\n")
589 if node.inputs["Color ramp"].is_linked:
590 for link in ntree.links:
591 if (
592 link.to_node == node
593 and link.from_node.bl_idname == "ShaderNodeValToRGB"
595 els = link.from_node.color_ramp.elements
596 n = -1
597 for el in els:
598 n += 1
599 pov_in_mat_name = string_strip_hyphen(
600 bpy.path.clean_name(link.from_node.name)
601 ) + "_%s_%s" % (n, pov_mat_name)
602 default = True
603 for ilink in ntree.links:
604 if (
605 ilink.to_node == node
606 and ilink.to_socket.name == str(n)
608 default = False
609 pov_in_mat_name = (
610 string_strip_hyphen(
611 bpy.path.clean_name(
612 ilink.from_node.name
615 + "_%s" % pov_mat_name
617 if default:
618 r, g, b, a = el.color[:]
619 file.write(
620 " #declare %s = texture{"
621 "pigment{"
622 "color srgbt <%.4g,%.4g,%.4g,%.4g>}};\n"
623 % (pov_in_mat_name, r, g, b, 1 - a)
625 file.write(
626 " [%s %s]\n" % (el.position, pov_in_mat_name)
628 else:
629 els = [[0, 0, 0, 0], [1, 1, 1, 1]]
630 for t in range(0, 2):
631 pov_in_mat_name = string_strip_hyphen(
632 bpy.path.clean_name(link.from_node.name)
633 ) + "_%s_%s" % (t, pov_mat_name)
634 default = True
635 for ilink in ntree.links:
636 if ilink.to_node == node and ilink.to_socket.name == str(t):
637 default = False
638 pov_in_mat_name = (
639 string_strip_hyphen(
640 bpy.path.clean_name(ilink.from_node.name)
642 + "_%s" % pov_mat_name
644 if default:
645 r, g, b = els[t][1], els[t][2], els[t][3]
646 if pattern not in {
647 "checker",
648 "hexagon",
649 "square",
650 "triangular",
651 "brick",
653 file.write(
654 " #declare %s = texture{pigment{color rgb <%.4g,%.4g,%.4g>}};\n"
655 % (pov_in_mat_name, r, g, b)
657 else:
658 file.write(
659 " texture{pigment{color rgb <%.4g,%.4g,%.4g>}}\n"
660 % (r, g, b)
662 if pattern not in {
663 "checker",
664 "hexagon",
665 "square",
666 "triangular",
667 "brick",
669 file.write(" [%s %s]\n" % (els[t][0], pov_in_mat_name))
670 else:
671 if not default:
672 file.write(" texture{%s}\n" % pov_in_mat_name)
673 if pattern not in {
674 "checker",
675 "hexagon",
676 "square",
677 "triangular",
678 "brick",
680 file.write("}\n")
681 if pattern == "brick":
682 file.write(
683 "brick_size <%.4g, %.4g, %.4g> mortar %.4g \n"
685 node.brick_size_x,
686 node.brick_size_y,
687 node.brick_size_z,
688 node.brick_mortar,
691 file.write(" %s %s" % (repeat, transform))
692 if modifier:
693 file.write(
694 " %s %s %s %s %s %s" % (turb, octv, lmbd, omg, freq, pha)
696 file.write("}\n")
697 declare_nodes.append(node.name)
699 for link in ntree.links:
700 if link.to_node.bl_idname == "PovrayOutputNode" and link.from_node.name in declare_nodes:
701 pov_mat_node_name = (
702 string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) + "_%s" % pov_mat_name
704 file.write("#declare %s = %s\n" % (pov_mat_name, pov_mat_node_name))