1 # SPDX-License-Identifier: GPL-2.0-or-later
3 """Translate Blender meta balls to POV blobs."""
6 from .shading
import write_object_material_interior
8 def export_meta(file, metas
, tab_write
, DEF_MAT_NAME
):
9 """write all POV blob primitives and Blender Metas to exported file """
10 # TODO - blenders 'motherball' naming is not supported.
18 if comments
and len(metas
) >= 1:
19 file.write("//--Blob objects--\n\n")
20 # Get groups of metaballs by blender name prefix.
24 prefix
= meta_ob
.name
.split(".")[0]
25 if prefix
not in meta_group
:
26 meta_group
[prefix
] = meta_ob
# .data.threshold
29 for elem
in meta_ob
.data
.elements
30 if elem
.type in {'BALL', 'ELLIPSOID', 'CAPSULE', 'CUBE', 'PLANE'}
32 if prefix
in meta_elems
:
33 meta_elems
[prefix
].extend(elems
)
35 meta_elems
[prefix
] = elems
39 tab_write(file, "\n//dummy sphere to represent empty meta location\n")
41 "sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} "
42 "no_image no_reflection no_radiosity "
43 "photons{pass_through collect off} hollow}\n\n"
44 % (meta_ob
.location
.x
, meta_ob
.location
.y
, meta_ob
.location
.z
)
45 ) # meta_ob.name > povdataname)
50 for mg
, mob
in meta_group
.items():
51 if len(meta_elems
[mg
]) != 0:
52 tab_write(file, "blob{threshold %.4g // %s \n" % (mob
.data
.threshold
, mg
))
53 for elems
in meta_elems
[mg
]:
56 stiffness
= elem
.stiffness
58 stiffness
= -stiffness
59 if elem
.type == 'BALL':
61 "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g "
62 % (loc
.x
, loc
.y
, loc
.z
, elem
.radius
, stiffness
)
64 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
65 tab_write(file, "}\n")
66 elif elem
.type == 'ELLIPSOID':
68 "sphere{ <%.6g, %.6g, %.6g>,%.4g,%.4g "
78 "scale <%.6g, %.6g, %.6g>"
79 % (elem
.size_x
, elem
.size_y
, elem
.size_z
)
81 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
82 tab_write(file, "}\n")
83 elif elem
.type == 'CAPSULE':
85 "cylinder{ <%.6g, %.6g, %.6g>,<%.6g, %.6g, %.6g>,%.4g,%.4g "
87 (loc
.x
- elem
.size_x
),
90 (loc
.x
+ elem
.size_x
),
97 # tab_write(file, "scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z))
98 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
99 tab_write(file, "}\n")
101 elif elem
.type == 'CUBE':
103 "cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n"
115 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
116 tab_write(file, "}\n")
118 "cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n"
130 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
131 tab_write(file, "}\n")
133 "cylinder { -z*8, +z*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1,1/4> scale <%.6g, %.6g, %.6g>\n"
145 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
146 tab_write(file, "}\n")
148 elif elem
.type == 'PLANE':
150 "cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n"
162 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
163 tab_write(file, "}\n")
165 "cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n"
177 write_matrix(file, global_matrix
@ elems
[1].matrix_world
)
178 tab_write(file, "}\n")
181 one_material
= elems
[1].data
.materials
[
183 ] # lame! - blender can't do enything else.
184 except BaseException
as e
:
186 print('An exception occurred: {}'.format(e
))
189 diffuse_color
= one_material
.diffuse_color
190 trans
= 1.0 - one_material
.pov
.alpha
192 one_material
.pov
.use_transparency
193 and one_material
.pov
.transparency_method
== 'RAYTRACE'
195 pov_filter
= one_material
.pov_raytrace_transparency
.filter * (
196 1.0 - one_material
.pov
.alpha
198 trans
= (1.0 - one_material
.pov
.alpha
) - pov_filter
201 material_finish
= material_names_dictionary
[one_material
.name
]
203 "pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n"
212 tab_write(file, "finish{%s} " % safety(material_finish
, ref_level_bound
=2))
214 material_finish
= DEF_MAT_NAME
217 "pigment{srgbt<1,1,1,%.3g>} finish{%s} "
218 % (trans
, safety(material_finish
, ref_level_bound
=2))
221 write_object_material_interior(file, one_material
, mob
, tab_write
)
222 # write_object_material_interior(file, one_material, elems[1])
223 tab_write(file, "radiosity{importance %3g}\n" % mob
.pov
.importance_value
)
224 tab_write(file, "}\n\n") # End of Metaball block
230 # important because no elements will break parsing.
231 elements = [elem for elem in meta.elements if elem.type in {'BALL', 'ELLIPSOID'}]
234 tab_write(file, "blob {\n")
235 tab_write(file, "threshold %.4g\n" % meta.threshold)
236 importance = ob.pov.importance_value
239 material = meta.materials[0] # lame! - blender can't do anything else.
243 for elem in elements:
246 stiffness = elem.stiffness
247 if elem.use_negative:
248 stiffness = - stiffness
250 if elem.type == 'BALL':
252 tab_write(file, "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" %
253 (loc.x, loc.y, loc.z, elem.radius, stiffness))
255 # After this wecould do something simple like...
257 # except we'll write the color
259 elif elem.type == 'ELLIPSOID':
260 # location is modified by scale
261 tab_write(file, "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" %
262 (loc.x / elem.size_x,
265 elem.radius, stiffness))
266 tab_write(file, "scale <%.6g, %.6g, %.6g> \n" %
267 (elem.size_x, elem.size_y, elem.size_z))
270 diffuse_color = material.diffuse_color
271 trans = 1.0 - material.pov.alpha
272 if material.pov.use_transparency and material.pov.transparency_method == 'RAYTRACE':
273 pov_filter = material.pov_raytrace_transparency.filter * (1.0 -
275 trans = (1.0 - material.pov.alpha) - pov_filter
279 material_finish = material_names_dictionary[material.name]
281 tab_write(file, "pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n" %
282 (diffuse_color[0], diffuse_color[1], diffuse_color[2],
284 tab_write(file, "finish {%s}\n" % safety(material_finish, ref_level_bound=2))
287 tab_write(file, "pigment {srgb 1} \n")
288 # Write the finish last.
289 tab_write(file, "finish {%s}\n" % (safety(DEF_MAT_NAME, ref_level_bound=2)))
291 write_object_material_interior(file, material, elems[1], tab_write)
293 write_matrix(file, global_matrix @ ob.matrix_world)
294 # Importance for radiosity sampling added here
295 tab_write(file, "radiosity { \n")
296 # importance > ob.pov.importance_value
297 tab_write(file, "importance %3g \n" % importance)
298 tab_write(file, "}\n")
300 tab_write(file, "}\n") # End of Metaball block
302 if comments and len(metas) >= 1: