Files
blender-addons/render_povray/model_meta_topology.py
Campbell Barton e8da6131fd License headers: use SPDX-FileCopyrightText for all addons
Move copyright text to SPDX-FileCopyrightText or set to the
Blender Foundation so "make check_licenses" now runs without warnings.
2023-06-15 16:54:05 +10:00

308 lines
14 KiB
Python

# SPDX-FileCopyrightText: 2022-2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""Translate Blender meta balls to POV blobs."""
import bpy
from .shading import write_object_material_interior
def export_meta(file, metas, material_names_dictionary, tab_write, DEF_MAT_NAME):
"""write all POV blob primitives and Blender Metas to exported file """
# TODO - blenders 'motherball' naming is not supported.
from .render import (
safety,
global_matrix,
write_matrix,
comments,
)
if comments and len(metas) >= 1:
file.write("//--Blob objects--\n\n")
# Get groups of metaballs by blender name prefix.
meta_group = {}
meta_elems = {}
for meta_ob in metas:
prefix = meta_ob.name.split(".")[0]
if prefix not in meta_group:
meta_group[prefix] = meta_ob # .data.threshold
elems = [
(elem, meta_ob)
for elem in meta_ob.data.elements
if elem.type in {'BALL', 'ELLIPSOID', 'CAPSULE', 'CUBE', 'PLANE'}
]
if prefix in meta_elems:
meta_elems[prefix].extend(elems)
else:
meta_elems[prefix] = elems
# empty metaball
if not elems:
tab_write(file, "\n//dummy sphere to represent empty meta location\n")
tab_write(file,
"sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} "
"no_image no_reflection no_radiosity "
"photons{pass_through collect off} hollow}\n\n"
% (meta_ob.location.x, meta_ob.location.y, meta_ob.location.z)
) # meta_ob.name > povdataname)
return
# other metaballs
for mg, mob in meta_group.items():
if len(meta_elems[mg]) != 0:
tab_write(file, "blob{threshold %.4g // %s \n" % (mob.data.threshold, mg))
for elems in meta_elems[mg]:
elem = elems[0]
loc = elem.co
stiffness = elem.stiffness
if elem.use_negative:
stiffness = -stiffness
if elem.type == 'BALL':
tab_write(file,
"sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g "
% (loc.x, loc.y, loc.z, elem.radius, stiffness)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
elif elem.type == 'ELLIPSOID':
tab_write(file,
"sphere{ <%.6g, %.6g, %.6g>,%.4g,%.4g "
% (
loc.x / elem.size_x,
loc.y / elem.size_y,
loc.z / elem.size_z,
elem.radius,
stiffness,
)
)
tab_write(file,
"scale <%.6g, %.6g, %.6g>"
% (elem.size_x, elem.size_y, elem.size_z)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
elif elem.type == 'CAPSULE':
tab_write(file,
"cylinder{ <%.6g, %.6g, %.6g>,<%.6g, %.6g, %.6g>,%.4g,%.4g "
% (
(loc.x - elem.size_x),
loc.y,
loc.z,
(loc.x + elem.size_x),
loc.y,
loc.z,
elem.radius,
stiffness,
)
)
# tab_write(file, "scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z))
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
elif elem.type == 'CUBE':
tab_write(file,
"cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n"
% (
elem.radius * 2.0,
stiffness / 4.0,
loc.x,
loc.y,
loc.z,
elem.size_x,
elem.size_y,
elem.size_z,
)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
tab_write(file,
"cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n"
% (
elem.radius * 2.0,
stiffness / 4.0,
loc.x,
loc.y,
loc.z,
elem.size_x,
elem.size_y,
elem.size_z,
)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
tab_write(file,
"cylinder { -z*8, +z*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1,1/4> scale <%.6g, %.6g, %.6g>\n"
% (
elem.radius * 2.0,
stiffness / 4.0,
loc.x,
loc.y,
loc.z,
elem.size_x,
elem.size_y,
elem.size_z,
)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
elif elem.type == 'PLANE':
tab_write(file,
"cylinder { -x*8, +x*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1/4,1,1> scale <%.6g, %.6g, %.6g>\n"
% (
elem.radius * 2.0,
stiffness / 4.0,
loc.x,
loc.y,
loc.z,
elem.size_x,
elem.size_y,
elem.size_z,
)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
tab_write(file,
"cylinder { -y*8, +y*8,%.4g,%.4g translate<%.6g,%.6g,%.6g> scale <1,1/4,1> scale <%.6g, %.6g, %.6g>\n"
% (
elem.radius * 2.0,
stiffness / 4.0,
loc.x,
loc.y,
loc.z,
elem.size_x,
elem.size_y,
elem.size_z,
)
)
write_matrix(file, global_matrix @ elems[1].matrix_world)
tab_write(file, "}\n")
try:
one_material = elems[1].data.materials[
0
] # lame! - blender can't do anything else.
except BaseException as e:
print(e.__doc__)
print('An exception occurred: {}'.format(e))
one_material = None
if one_material:
diffuse_color = one_material.diffuse_color
trans = 1.0 - one_material.pov.alpha
if (
one_material.pov.use_transparency
and one_material.pov.transparency_method == 'RAYTRACE'
):
pov_filter = one_material.pov_raytrace_transparency.filter * (
1.0 - one_material.pov.alpha
)
trans = (1.0 - one_material.pov.alpha) - pov_filter
else:
pov_filter = 0.0
material_finish = material_names_dictionary[one_material.name]
tab_write(file,
"pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n"
% (
diffuse_color[0],
diffuse_color[1],
diffuse_color[2],
pov_filter,
trans,
)
)
tab_write(file, "finish{%s} " % safety(material_finish, ref_level_bound=2))
else:
material_finish = DEF_MAT_NAME
trans = 0.0
tab_write(file,
"pigment{srgbt<1,1,1,%.3g>} finish{%s} "
% (trans, safety(material_finish, ref_level_bound=2))
)
write_object_material_interior(file, one_material, mob, tab_write)
# write_object_material_interior(file, one_material, elems[1])
tab_write(file, "radiosity{importance %3g}\n" % mob.pov.importance_value)
tab_write(file, "}\n\n") # End of Metaball block
'''
meta = ob.data
# important because no elements will break parsing.
elements = [elem for elem in meta.elements if elem.type in {'BALL', 'ELLIPSOID'}]
if elements:
tab_write(file, "blob {\n")
tab_write(file, "threshold %.4g\n" % meta.threshold)
importance = ob.pov.importance_value
try:
material = meta.materials[0] # lame! - blender can't do anything else.
except:
material = None
for elem in elements:
loc = elem.co
stiffness = elem.stiffness
if elem.use_negative:
stiffness = - stiffness
if elem.type == 'BALL':
tab_write(file, "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" %
(loc.x, loc.y, loc.z, elem.radius, stiffness))
# After this wecould do something simple like...
# "pigment {Blue} }"
# except we'll write the color
elif elem.type == 'ELLIPSOID':
# location is modified by scale
tab_write(file, "sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" %
(loc.x / elem.size_x,
loc.y / elem.size_y,
loc.z / elem.size_z,
elem.radius, stiffness))
tab_write(file, "scale <%.6g, %.6g, %.6g> \n" %
(elem.size_x, elem.size_y, elem.size_z))
if material:
diffuse_color = material.diffuse_color
trans = 1.0 - material.pov.alpha
if material.pov.use_transparency and material.pov.transparency_method == 'RAYTRACE':
pov_filter = material.pov_raytrace_transparency.filter * (1.0 -
material.pov.alpha)
trans = (1.0 - material.pov.alpha) - pov_filter
else:
pov_filter = 0.0
material_finish = material_names_dictionary[material.name]
tab_write(file, "pigment {srgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n" %
(diffuse_color[0], diffuse_color[1], diffuse_color[2],
pov_filter, trans))
tab_write(file, "finish {%s}\n" % safety(material_finish, ref_level_bound=2))
else:
tab_write(file, "pigment {srgb 1} \n")
# Write the finish last.
tab_write(file, "finish {%s}\n" % (safety(DEF_MAT_NAME, ref_level_bound=2)))
write_object_material_interior(file, material, elems[1], tab_write)
write_matrix(file, global_matrix @ ob.matrix_world)
# Importance for radiosity sampling added here
tab_write(file, "radiosity { \n")
# importance > ob.pov.importance_value
tab_write(file, "importance %3g \n" % importance)
tab_write(file, "}\n")
tab_write(file, "}\n") # End of Metaball block
if comments and len(metas) >= 1:
file.write("\n")
'''