Newer
Older
Bastien Montagne
committed
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# #**** END GPL LICENSE BLOCK #****
import subprocess
import os
import sys
import time
from math import atan, pi, degrees, sqrt, cos, sin
####################
## Faster mesh export
import numpy as np
####################
import re
import platform #
import subprocess #
import tempfile # generate temporary files with random names
from bpy.types import Operator
from imghdr import what # imghdr is a python lib to identify image file types
from bpy.utils import register_class
from . import df3 # for smoke rendering
from . import shading # for BI POV shaders emulation
from . import primitives # for import and export of POV specific primitives
from . import nodes # for POV specific nodes
##############################SF###########################
##############find image texture
"""Identify input image filetypes to transmit to POV."""
# First use the below explicit extensions to identify image file prospects
ext = {
'JPG': "jpeg",
'JPEG': "jpeg",
'GIF': "gif",
'TGA': "tga",
'IFF': "iff",
'PPM': "ppm",
'PNG': "png",
'SYS': "sys",
'TIFF': "tiff",
'TIF': "tiff",
'EXR': "exr",
'HDR': "hdr",
}.get(os.path.splitext(imgF)[-1].upper(), "")
# Then, use imghdr to really identify the filetype as it can be different
# maybe add a check for if path exists here?
print(" WARNING: texture image has no extension") # too verbose
ext = what(imgF) # imghdr is a python lib to identify image file types
"""Translate mapping type from Blender UI to POV syntax and return that string."""
texdata = bpy.data.textures[ts.texture]
if ts.mapping == 'FLAT':
image_map = "map_type 0 "
elif ts.mapping == 'SPHERE':
elif ts.mapping == 'TUBE':
image_map = "map_type 2 "
## map_type 3 and 4 in development (?) (ENV in pov 3.8)
## for POV-Ray, currently they just seem to default back to Flat (type 0)
# elif ts.mapping=="?":
# elif ts.mapping=="?":
if ts.use_interpolation: # Available if image sampling class reactivated?
image_map += " interpolate 2 "
if texdata.extension == 'CLIP':
# image_map += "}"
# if ts.mapping=='CUBE':
# image_map+= "warp { cubic } rotate <-90,0,180>"
# no direct cube type mapping. Though this should work in POV 3.7
# it doesn't give that good results(best suited to environment maps?)
# print(" No texture image found ")
def imgMapTransforms(ts):
"""Translate mapping transformations from Blender UI to POV syntax and return that string."""
# XXX TODO: unchecked textures give error of variable referenced before assignment XXX
# POV-Ray "scale" is not a number of repetitions factor, but ,its
# inverse, a standard scale factor.
# 0.5 Offset is needed relatively to scale because center of the
# scale is 0.5,0.5 in blender and 0,0 in POV
# Strange that the translation factor for scale is not the same as for
# translate.
# TODO: verify both matches with blender internal.
image_map_transforms = ""
image_map_transforms = (
"scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>"
% (
ts.scale[0],
ts.scale[1],
ts.scale[2],
ts.offset[0],
ts.offset[1],
ts.offset[2],
# image_map_transforms = (" translate <-0.5,-0.5,0.0> scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" % \
# ( 1.0 / ts.scale.x,
# 1.0 / ts.scale.y,
# 1.0 / ts.scale.z,
# (0.5 / ts.scale.x) + ts.offset.x,
# (0.5 / ts.scale.y) + ts.offset.y,
# ts.offset.z))
# image_map_transforms = ("translate <-0.5,-0.5,0> scale <-1,-1,1> * <%.4g,%.4g,%.4g> translate <0.5,0.5,0> + <%.4g,%.4g,%.4g>" % \
# (1.0 / ts.scale.x,
# 1.0 / ts.scale.y,
# 1.0 / ts.scale.z,
# ts.offset.x,
# ts.offset.y,
# ts.offset.z))
return image_map_transforms
"""Translate world mapping from Blender UI to POV syntax and return that string."""
tex = bpy.data.textures[wts.texture]
# texture_coords refers to the mapping of world textures:
if wts.texture_coords == 'VIEW' or wts.texture_coords == 'GLOBAL':
elif wts.texture_coords == 'ANGMAP':
image_mapBG = " map_type 1 "
elif wts.texture_coords == 'TUBE':
image_mapBG = " map_type 2 "
image_mapBG += " interpolate 2 "
if tex.extension == 'CLIP':
# image_mapBG += "}"
# if wts.mapping == 'CUBE':
# image_mapBG += "warp { cubic } rotate <-90,0,180>"
# no direct cube type mapping. Though this should work in POV 3.7
# it doesn't give that good results(best suited to environment maps?)
# if image_mapBG == "":
# print(" No background texture image found ")
"""Conform a path string to POV syntax to avoid POV errors."""
return bpy.path.abspath(image.filepath, library=image.library).replace(
"\\", "/"
)
# .replace("\\","/") to get only forward slashes as it's what POV prefers,
Maurice Raybaud
committed
# even on windows
# end find image texture
# -----------------------------------------------------------------------------
"""Remove hyphen characters from a string to avoid POV errors."""
def safety(name, Level):
"""append suffix characters to names of various material declinations.
Material declinations are necessary to POV syntax and used in shading.py
by the povHasnoSpecularMaps function to create the finish map trick and
the suffixes avoid name collisions.
Keyword arguments:
name -- the initial material name as a string
Level -- the enum number of the Level being written:
Level=1 is for texture with No specular nor Mirror reflection
Level=2 is for texture with translation of spec and mir levels
for when no map influences them
Level=3 is for texture with Maximum Spec and Mirror
Maurice Raybaud
committed
prefix = ""
return prefix + name + "0" # used for 0 of specular map
return prefix + name + "1" # used for 1 of specular map
Maurice Raybaud
committed
##############end safety string name material
##############################EndSF###########################
def is_renderable(scene, ob):
return not ob.hide_render and ob not in csg_list
def renderable_objects(scene):
return [ob for ob in bpy.data.objects if is_renderable(scene, ob)]
def no_renderable_objects(scene):
return [ob for ob in csg_list]
Maurice Raybaud
committed
tabLevel = 0
user_dir = bpy.utils.resource_path('USER')
preview_dir = os.path.join(user_dir, "preview")
## Make sure Preview directory exists and is empty
smokePath = os.path.join(preview_dir, "smoke.df3")
def write_global_setting(scene,file):
file.write("global_settings {\n")
file.write(" assumed_gamma %.6f\n"%scene.pov.assumed_gamma)
if scene.pov.global_settings_advanced:
if scene.pov.radio_enable == False:
file.write(" adc_bailout %.6f\n"%scene.pov.adc_bailout)
file.write(" ambient_light <%.6f,%.6f,%.6f>\n"%scene.pov.ambient_light[:])
file.write(" irid_wavelength <%.6f,%.6f,%.6f>\n"%scene.pov.irid_wavelength[:])
file.write(" charset %s\n"%scene.pov.charset)
file.write(" max_trace_level %s\n"%scene.pov.max_trace_level)
file.write(" max_intersections %s\n"%scene.pov.max_intersections)
file.write(" number_of_waves %s\n"%scene.pov.number_of_waves)
file.write(" noise_generator %s\n"%scene.pov.noise_generator)
# below properties not added to __init__ yet to avoid conflicts with material sss scale
# unless it would override then should be interfaced also in scene units property tab
# if scene.pov.sslt_enable:
# file.write(" mm_per_unit %s\n"%scene.pov.mm_per_unit)
# file.write(" subsurface {\n")
# file.write(" samples %s, %s\n"%(scene.pov.sslt_samples_max,scene.pov.sslt_samples_min))
# if scene.pov.sslt_radiosity:
# file.write(" radiosity on\n")
# file.write("}\n")
if scene.pov.radio_enable:
file.write(" radiosity {\n")
file.write(" pretrace_start %.6f\n"%scene.pov.radio_pretrace_start)
file.write(" pretrace_end %.6f\n"%scene.pov.radio_pretrace_end)
file.write(" count %s\n"%scene.pov.radio_count)
file.write(" nearest_count %s\n"%scene.pov.radio_nearest_count)
file.write(" error_bound %.6f\n"%scene.pov.radio_error_bound)
file.write(" recursion_limit %s\n"%scene.pov.radio_recursion_limit)
file.write(" low_error_factor %.6f\n"%scene.pov.radio_low_error_factor)
file.write(" gray_threshold %.6f\n"%scene.pov.radio_gray_threshold)
file.write(" maximum_reuse %.6f\n"%scene.pov.radio_maximum_reuse)
file.write(" minimum_reuse %.6f\n"%scene.pov.radio_minimum_reuse)
file.write(" brightness %.6f\n"%scene.pov.radio_brightness)
file.write(" adc_bailout %.6f\n"%scene.pov.radio_adc_bailout)
if scene.pov.radio_normal:
if scene.pov.radio_always_sample:
if scene.pov.radio_media:
if scene.pov.radio_subsurface:
file.write(" subsurface on\n")
file.write(" }\n")
if scene.pov.photon_enable:
file.write(" photons {\n")
if scene.pov.photon_enable_count:
file.write(" count %s\n"%scene.pov.photon_count)
else:
file.write(" spacing %.6g\n"%scene.pov.photon_spacing)
if scene.pov.photon_gather:
file.write(" gather %s, %s\n"%(scene.pov.photon_gather_min,scene.pov.photon_gather_max))
if scene.pov.photon_autostop:
file.write(" autostop %.4g\n"%scene.pov.photon_autostop_value)
if scene.pov.photon_jitter_enable:
file.write(" jitter %.4g\n"%scene.pov.photon_jitter)
file.write(" max_trace_level %s\n"%scene.pov.photon_max_trace_level)
if scene.pov.photon_adc:
file.write(" adc_bailout %.6f\n"%scene.pov.photon_adc_bailout)
if scene.pov.photon_media_enable:
file.write(" media %s, %s\n"%(scene.pov.photon_media_steps,scene.pov.photon_media_factor))
if scene.pov.photon_map_file_save_load in {'save'}:
filePhName = 'Photon_map_file.ph'
if scene.pov.photon_map_file != '':
filePhName = scene.pov.photon_map_file+'.ph'
filePhDir = tempfile.gettempdir()
path = bpy.path.abspath(scene.pov.photon_map_dir)
if os.path.exists(path):
filePhDir = path
fullFileName = os.path.join(filePhDir,filePhName)
file.write(' save_file "%s"\n'%fullFileName)
scene.pov.photon_map_file = fullFileName
if scene.pov.photon_map_file_save_load in {'load'}:
fullFileName = bpy.path.abspath(scene.pov.photon_map_file)
if os.path.exists(fullFileName):
file.write(' load_file "%s"\n'%fullFileName)
file.write("}\n")
file.write("}\n")
def write_object_modifiers(scene, ob, File):
"""Translate some object level POV statements from Blender UI
to POV syntax and write to exported file """
# Maybe return that string to be added instead of directly written.
'''XXX WIP
onceCSG = 0
for mod in ob.modifiers:
if onceCSG == 0:
if mod :
if mod.type == 'BOOLEAN':
if ob.pov.boolean_mod == "POV":
File.write("\tinside_vector <%.6g, %.6g, %.6g>\n" %
(ob.pov.inside_vector[0],
ob.pov.inside_vector[1],
ob.pov.inside_vector[2]))
onceCSG = 1
'''
File.write("\thollow\n")
if ob.pov.double_illuminate:
File.write("\tdouble_illuminate\n")
File.write("\tsturm\n")
File.write("\tno_shadow\n")
File.write("\tno_image\n")
if ob.pov.no_reflection:
File.write("\tno_reflection\n")
if ob.pov.no_radiosity:
File.write("\tno_radiosity\n")
File.write("\tinverse\n")
File.write("\thierarchy\n")
# XXX, Commented definitions
'''
if scene.pov.photon_enable:
File.write("photons {\n")
if ob.pov.target:
File.write("target %.4g\n"%ob.pov.target_value)
if ob.pov.refraction:
File.write("refraction on\n")
if ob.pov.reflection:
File.write("reflection on\n")
if ob.pov.pass_through:
File.write("pass_through\n")
File.write("}\n")
if ob.pov.object_ior > 1:
File.write("interior {\n")
File.write("ior %.4g\n"%ob.pov.object_ior)
if scene.pov.photon_enable and ob.pov.target and ob.pov.refraction and ob.pov.dispersion:
File.write("ior %.4g\n"%ob.pov.dispersion_value)
File.write("ior %s\n"%ob.pov.dispersion_samples)
if scene.pov.photon_enable == False:
File.write("caustics %.4g\n"%ob.pov.fake_caustics_power)
'''
"""Main export process from Blender UI to POV syntax and write to exported file """
import mathutils
# file = filename
# Only for testing
if not scene:
scene = bpy.data.scenes[0]
render = scene.render
world = scene.world
global_matrix = mathutils.Matrix.Rotation(-pi / 2.0, 4, 'X')
comments = scene.pov.comments_enable and not scene.pov.tempfiles_enable
linebreaksinlists = (
scene.pov.list_lf_enable and not scene.pov.tempfiles_enable
)
feature_set = bpy.context.preferences.addons[
__package__
].preferences.branch_feature_set_povray
using_uberpov = feature_set == 'uberpov'
pov_binary = PovrayRender._locate_binary()
if using_uberpov:
print("Unofficial UberPOV feature set chosen in preferences")
else:
print("Official POV-Ray 3.7 feature set chosen in preferences")
print(
"The name of the binary suggests you are probably rendering with Uber POV engine"
)
print(
"The name of the binary suggests you are probably rendering with standard POV engine"
)
Constantin Rahn
committed
def setTab(tabtype, spaces):
TabStr = ""
Campbell Barton
committed
if tabtype == 'NONE':
TabStr = ""
Campbell Barton
committed
elif tabtype == 'TAB':
TabStr = "\t"
Campbell Barton
committed
elif tabtype == 'SPACE':
TabStr = spaces * " "
Constantin Rahn
committed
return TabStr
Bastien Montagne
committed
tab = setTab(scene.pov.indentation_character, scene.pov.indentation_spaces)
if not scene.pov.tempfiles_enable:
"""Indent POV syntax from brackets levels and write to exported file """
brackets = (
str_o.count("{")
- str_o.count("}")
+ str_o.count("[")
- str_o.count("]")
)
if brackets < 0:
tabLevel = tabLevel + brackets
if tabLevel < 0:
print("Indentation Warning: tabLevel = %s" % tabLevel)
tabLevel = 0
if tabLevel >= 1:
file.write("%s" % tab * tabLevel)
file.write(str_o)
if brackets > 0:
tabLevel = tabLevel + brackets
"""write directly to exported file if user checked autonamed temp files (faster)."""
Constantin Rahn
committed
"""Increment any generated POV name that could get identical to avoid collisions"""
return name
name_orig = name
i = 1
while name in nameSeq:
name = "%s_%.3d" % (name_orig, i)
"""Translate some tranform matrix from Blender UI
to POV syntax and write to exported file """
tabWrite(
"matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n"
% (
matrix[0][0],
matrix[1][0],
matrix[2][0],
matrix[0][1],
matrix[1][1],
matrix[2][1],
matrix[0][2],
matrix[1][2],
matrix[2][2],
matrix[0][3],
matrix[1][3],
matrix[2][3],
)
)
Bastien Montagne
committed
def MatrixAsPovString(matrix):
"""Translate some tranform matrix from Blender UI
to POV syntax and return that string """
sMatrix = (
"matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f>\n"
% (
matrix[0][0],
matrix[1][0],
matrix[2][0],
matrix[0][1],
matrix[1][1],
matrix[2][1],
matrix[0][2],
matrix[1][2],
matrix[2][2],
matrix[0][3],
matrix[1][3],
matrix[2][3],
)
)
Bastien Montagne
committed
return sMatrix
def writeObjectMaterial(material, ob):
"""Translate some object level material from Blender UI (VS data level)
to POV interior{} syntax and write it to exported file """
Doug Hammond
committed
# DH - modified some variables to be function local, avoiding RNA write
# this should be checked to see if it is functionally correct
Bastien Montagne
committed
# Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
# if material and material.transparency_method == 'RAYTRACE':
Bastien Montagne
committed
if material:
# But there can be only one!
if (
material.pov_subsurface_scattering.use
): # SSS IOR get highest priority
tabWrite("interior {\n")
tabWrite("ior %.6f\n" % material.pov_subsurface_scattering.ior)
Bastien Montagne
committed
# Then the raytrace IOR taken from raytrace transparency properties and used for
# reflections if IOR Mirror option is checked.
elif material.pov.mirror_use_IOR:
tabWrite("interior {\n")
tabWrite("ior %.6f\n" % material.pov_raytrace_transparency.ior)
elif material.pov.transparency_method == 'Z_TRANSPARENCY':
tabWrite("interior {\n")
tabWrite("ior %.6f\n" % material.pov_raytrace_transparency.ior)
Doug Hammond
committed
pov_fake_caustics = False
pov_photons_refraction = False
pov_photons_reflection = False
Bastien Montagne
committed
if material.pov.photons_reflection:
Maurice Raybaud
committed
if not material.pov.refraction_caustics:
Doug Hammond
committed
pov_fake_caustics = False
pov_photons_refraction = False
Bastien Montagne
committed
elif material.pov.refraction_type == "1":
Doug Hammond
committed
pov_fake_caustics = True
pov_photons_refraction = False
Bastien Montagne
committed
elif material.pov.refraction_type == "2":
Doug Hammond
committed
pov_fake_caustics = False
pov_photons_refraction = True
Bastien Montagne
committed
# If only Raytrace transparency is set, its IOR will be used for refraction, but user
# can set up 'un-physical' fresnel reflections in raytrace mirror parameters.
# Last, if none of the above is specified, user can set up 'un-physical' fresnel
# reflections in raytrace mirror parameters. And pov IOR defaults to 1.
if material.pov.caustics_enable:
Doug Hammond
committed
if pov_fake_caustics:
tabWrite(
"caustics %.3g\n" % material.pov.fake_caustics_power
)
Maurice Raybaud
committed
if pov_photons_refraction:
Bastien Montagne
committed
# Default of 1 means no dispersion
tabWrite(
"dispersion %.6f\n" % material.pov.photons_dispersion
)
tabWrite(
"dispersion_samples %.d\n"
% material.pov.photons_dispersion_samples
)
# TODO
if (
material.pov.use_transparency
and material.pov.transparency_method == 'RAYTRACE'
):
Bastien Montagne
committed
# In Blender this value has always been reversed compared to what tooltip says.
# 100.001 rather than 100 so that it does not get to 0
# which deactivates the feature in POV
tabWrite(
"fade_distance %.3g\n"
% (100.001 - material.pov_raytrace_transparency.depth_max)
)
tabWrite(
"fade_power %.3g\n"
% material.pov_raytrace_transparency.falloff
)
tabWrite(
"fade_color <%.3g, %.3g, %.3g>\n"
% material.pov.interior_fade_color[:]
)
# (variable) dispersion_samples (constant count for now)
tabWrite("}\n")
if (
material.pov.photons_reflection
or material.pov.refraction_type == "2"
):
tabWrite("photons{")
Maurice Raybaud
committed
tabWrite("target %.3g\n" % ob.pov.spacing_multiplier)
if not ob.pov.collect_photons:
tabWrite("collect off\n")
if pov_photons_refraction:
tabWrite("refraction on\n")
if pov_photons_reflection:
tabWrite("reflection on\n")
tabWrite("}\n")
DEF_MAT_NAME = "" # or "Default"?
"""Translate camera from Blender UI to POV syntax and write to exported file."""
Doug Hammond
committed
# DH disabled for now, this isn't the correct context
active_object = (
None
) # bpy.context.active_object # does not always work MR
matrix = global_matrix @ camera.matrix_world
focal_point = camera.data.dof.focus_distance
Qsize = render.resolution_x / render.resolution_y
tabWrite(
"#declare camLocation = <%.6f, %.6f, %.6f>;\n"
% matrix.translation[:]
)
tabWrite(
"#declare camLookAt = <%.6f, %.6f, %.6f>;\n"
% tuple([degrees(e) for e in matrix.to_3x3().to_euler()])
)
tabWrite("camera {\n")
if (
scene.pov.baking_enable
and active_object
and active_object.type == 'MESH'
):
tabWrite(
"mesh_camera{ 1 3\n"
) # distribution 3 is what we want here
tabWrite("mesh{%s}\n" % active_object.name)
tabWrite("}\n")
tabWrite("location <0,0,.01>")
tabWrite("direction <0,0,-1>")
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
if camera.data.type == 'ORTHO':
SensorHeightRatio = render.resolution_x * camera.data.ortho_scale / render.resolution_y
tabWrite("orthographic\n")
# Blender angle is radian so should be converted to degrees:
# % (camera.data.angle * (180.0 / pi) )
# but actually argument is not compulsory after angle in pov ortho mode
tabWrite("angle\n")
tabWrite("right <%6f, 0, 0>\n" % -camera.data.ortho_scale)
tabWrite("location <0, 0, 0>\n")
tabWrite("look_at <0, 0, -1>\n")
tabWrite("up <0, %6f, 0>\n" % (camera.data.ortho_scale / Qsize))
elif camera.data.type == 'PANO':
tabWrite("panoramic\n")
tabWrite("location <0, 0, 0>\n")
tabWrite("look_at <0, 0, -1>\n")
tabWrite("right <%s, 0, 0>\n" % -Qsize)
tabWrite("up <0, 1, 0>\n")
tabWrite(
"angle %f\n" % (360.0 * atan(16.0 / camera.data.lens) / pi)
)
elif camera.data.type == 'PERSP':
# Standard camera otherwise would be default in pov
tabWrite("location <0, 0, 0>\n")
tabWrite("look_at <0, 0, -1>\n")
tabWrite("right <%s, 0, 0>\n" % -Qsize)
tabWrite("up <0, 1, 0>\n")
tabWrite(
"angle %f\n" % ( 2 * atan(camera.data.sensor_width / 2 / camera.data.lens) * 180.0 / pi )
tabWrite(
"rotate <%.6f, %.6f, %.6f>\n"
% tuple([degrees(e) for e in matrix.to_3x3().to_euler()])
)
tabWrite("translate <%.6f, %.6f, %.6f>\n" % matrix.translation[:])
if camera.data.dof.use_dof and (
focal_point != 0 or camera.data.dof.focus_object
):
tabWrite(
"aperture %.3g\n"
% (1 / camera.data.dof.aperture_fstop * 1000)
)
tabWrite(
"blur_samples %d %d\n"
% (
camera.data.pov.dof_samples_min,
camera.data.pov.dof_samples_max,
)
)
Bastien Montagne
committed
tabWrite("variance 1/%d\n" % camera.data.pov.dof_variance)
tabWrite("confidence %.3g\n" % camera.data.pov.dof_confidence)
Maurice Raybaud
committed
if camera.data.dof.focus_object:
focalOb = scene.objects[camera.data.dof.focus_object.name]
matrixBlur = global_matrix @ focalOb.matrix_world
tabWrite(
"focal_point <%.4f,%.4f,%.4f>\n"
% matrixBlur.translation[:]
)
else:
tabWrite("focal_point <0, 0, %f>\n" % focal_point)
if camera.data.pov.normal_enable:
tabWrite(
"normal {%s %.4f turbulence %.4f scale %.4f}\n"
% (
camera.data.pov.normal_patterns,
camera.data.pov.cam_normal,
camera.data.pov.turbulence,
camera.data.pov.scale,
)
)
tabWrite("}\n")
"""Translate lights from Blender UI to POV syntax and write to exported file."""
# Incremented after each lamp export to declare its target
# currently used for Fresnel diffuse shader as their slope vector:
global lampCount
lampCount = 0
# Get all lamps
for ob in lamps:
lamp = ob.data
matrix = global_matrix @ ob.matrix_world
# Color is no longer modified by energy
Maurice Raybaud
committed
color = tuple([c for c in lamp.color])
tabWrite("light_source {\n")
tabWrite("< 0,0,0 >\n")
Maurice Raybaud
committed
tabWrite("color srgb<%.3g, %.3g, %.3g>\n" % color)
tabWrite("spotlight\n")
tabWrite(
"falloff %.2f\n" % (degrees(lamp.spot_size) / 2.0)
) # 1 TO 179 FOR BOTH
tabWrite(
"radius %.6f\n"
% (
(degrees(lamp.spot_size) / 2.0)
* (1.0 - lamp.spot_blend)
)
)
# Blender does not have a tightness equivalent, 0 is most like blender default.
tabWrite("tightness 0\n") # 0:10f
tabWrite("point_at <0, 0, -1>\n")
Maurice Raybaud
committed
tabWrite("looks_like{\n")
tabWrite("sphere{<0,0,0>,%.6f\n" % lamp.distance)
Maurice Raybaud
committed
tabWrite("hollow\n")
tabWrite("material{\n")
tabWrite("texture{\n")
tabWrite(
"pigment{rgbf<1,1,1,%.4f>}\n"
% (lamp.pov.halo_intensity * 5.0)
)
Maurice Raybaud
committed
tabWrite("}\n")
tabWrite("interior{\n")
tabWrite("media{\n")
tabWrite("emission 1\n")
tabWrite("scattering {1, 0.5}\n")
tabWrite("density{\n")
tabWrite("spherical\n")
tabWrite("color_map{\n")
tabWrite("[0.0 rgb <0,0,0>]\n")
tabWrite("[0.5 rgb <1,1,1>]\n")
tabWrite("[1.0 rgb <1,1,1>]\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
tabWrite("parallel\n")
tabWrite("point_at <0, 0, -1>\n") # *must* be after 'parallel'
tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0))
Bastien Montagne
committed
# Area lights have no falloff type, so always use blenders lamp quad equivalent
# for those?
tabWrite("fade_power %d\n" % 2)
if lamp.shape == 'SQUARE':
size_y = size_x
samples_y = samples_x
else:
size_y = lamp.size_y
tabWrite(
"area_light <%.6f,0,0>,<0,%.6f,0> %d, %d\n"
% (size_x, size_y, samples_x, samples_y)
)
tabWrite("area_illumination\n")
if lamp.pov.shadow_ray_sample_method == 'CONSTANT_JITTERED':
if lamp.pov.use_jitter:
tabWrite("jitter\n")
tabWrite("adaptive 1\n")
tabWrite("jitter\n")
# No shadow checked either at global or light level:
if not scene.pov.use_shadows or (
lamp.pov.shadow_method == 'NOSHADOW'
):
tabWrite("shadowless\n")
# Sun shouldn't be attenuated. Area lights have no falloff attribute so they
Bastien Montagne
committed
# are put to type 2 attenuation a little higher above.
if lamp.type not in {'SUN', 'AREA'}:
tabWrite(
"fade_distance %.6f\n" % (sqrt(lamp.distance / 2.0))
)
tabWrite(
"fade_power %d\n" % 2
) # Use blenders lamp quad equivalent
tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0))
tabWrite("fade_power %d\n" % 1) # Use blenders lamp linear
Bastien Montagne
committed
elif lamp.falloff_type == 'CONSTANT':
tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0))
# Use blenders lamp constant equivalent no attenuation.
Bastien Montagne
committed
# Using Custom curve for fade power 3 for now.
elif lamp.falloff_type == 'CUSTOM_CURVE':
tabWrite("fade_power %d\n" % 4)
tabWrite("}\n")
lampCount += 1
# v(A,B) rotates vector A about origin by vector B.
file.write(
"#declare lampTarget%s= vrotate(<%.4g,%.4g,%.4g>,<%.4g,%.4g,%.4g>);\n"
% (
lampCount,
-(ob.location.x),
-(ob.location.y),
-(ob.location.z),
ob.rotation_euler.x,
ob.rotation_euler.y,
ob.rotation_euler.z,
)
)
####################################################################################################
def exportRainbows(rainbows):
"""write all POV rainbows primitives to exported file """
povdataname = ob.data.name # enough?
angle = degrees(ob.data.spot_size / 2.5) # radians in blender (2
width = ob.data.spot_blend * 10
# eps=0.0000001
# angle = br/(cr+eps) * 10 #eps is small epsilon variable to avoid dividing by zero
# width = ob.dimensions[2] #now let's say width of rainbow is the actual proxy height
# cz-bz # let's say width of the rainbow is height of the cone (interfacing choice
# v(A,B) rotates vector A about origin by vector B.
# and avoid a 0 length vector by adding 1
# file.write("#declare %s_Target= vrotate(<%.6g,%.6g,%.6g>,<%.4g,%.4g,%.4g>);\n" % \
# (povdataname, -(ob.location.x+0.1), -(ob.location.y+0.1), -(ob.location.z+0.1),
# ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z))
direction = (
ob.location.x,
ob.location.y,
ob.location.z,
) # not taking matrix into account
rmatrix = global_matrix @ ob.matrix_world
# ob.rotation_euler.to_matrix().to_4x4() * mathutils.Vector((0,0,1))
# XXX Is result of the below offset by 90 degrees?
up = ob.matrix_world.to_3x3()[1].xyz # * global_matrix
# formerly:
# tabWrite("#declare %s = rainbow {\n"%povdataname)
# clumsy for now but remove the rainbow from instancing
# system because not an object. use lamps later instead of meshes
# del data_ref[dataname]
tabWrite("rainbow {\n")
tabWrite("angle %.4f\n" % angle)
tabWrite("width %.4f\n" % width)
tabWrite("distance %.4f\n" % distance)
tabWrite("arc_angle %.4f\n" % ob.pov.arc_angle)
tabWrite("falloff_angle %.4f\n" % ob.pov.falloff_angle)
tabWrite("direction <%.4f,%.4f,%.4f>\n" % rmatrix.translation[:])
tabWrite("up <%.4f,%.4f,%.4f>\n" % (up[0], up[1], up[2]))
tabWrite("color_map {\n")
Maurice Raybaud
committed
tabWrite("[0.000 color srgbt<1.0, 0.5, 1.0, 1.0>]\n")
tabWrite("[0.130 color srgbt<0.5, 0.5, 1.0, 0.9>]\n")
tabWrite("[0.298 color srgbt<0.2, 0.2, 1.0, 0.7>]\n")
tabWrite("[0.412 color srgbt<0.2, 1.0, 1.0, 0.4>]\n")
tabWrite("[0.526 color srgbt<0.2, 1.0, 0.2, 0.4>]\n")
tabWrite("[0.640 color srgbt<1.0, 1.0, 0.2, 0.4>]\n")
tabWrite("[0.754 color srgbt<1.0, 0.5, 0.2, 0.6>]\n")
tabWrite("[0.900 color srgbt<1.0, 0.2, 0.2, 0.7>]\n")
tabWrite("[1.000 color srgbt<1.0, 0.2, 0.2, 1.0>]\n")
povMatName = "Default_texture"
# tabWrite("texture {%s}\n"%povMatName)
write_object_modifiers(scene, ob, file)
# tabWrite("rotate x*90\n")
# matrix = global_matrix @ ob.matrix_world
# writeMatrix(matrix)
# continue #Don't render proxy mesh, skip to next object
################################XXX LOFT, ETC.
def exportCurves(scene, ob):
"""write all curves based POV primitives to exported file """
name_orig = "OB" + ob.name
dataname_orig = "DATA" + ob.data.name
name = string_strip_hyphen(bpy.path.clean_name(name_orig))
dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))
global_matrix = mathutils.Matrix.Rotation(-pi / 2.0, 4, 'X')
matrix = global_matrix @ ob.matrix_world
bezier_sweep = False
if ob.pov.curveshape == 'sphere_sweep':
# inlined spheresweep macro, which itself calls Shapes.inc:
file.write(' #include "shapes.inc"\n')
file.write(
' #macro Shape_Bezierpoints_Sphere_Sweep(_merge_shape, _resolution, _points_array, _radius_array)\n'
)
file.write(' //input adjusting and inspection\n')
file.write(' #if(_resolution <= 1)\n')
file.write(' #local res = 1;\n')
file.write(' #else\n')
file.write(' #local res = int(_resolution);\n')
file.write(' #end\n')
file.write(
' #if(dimensions(_points_array) != 1 | dimensions(_radius_array) != 1)\n'
)
file.write(' #error ""\n')
file.write(
' #elseif(div(dimension_size(_points_array,1),4) - dimension_size(_points_array,1)/4 != 0)\n'
)
file.write(' #error ""\n')
file.write(
' #elseif(dimension_size(_points_array,1) != dimension_size(_radius_array,1))\n'
)
file.write(' #error ""\n')
file.write(' #else\n')
file.write(
' #local n_of_seg = div(dimension_size(_points_array,1), 4);\n'
)
file.write(' #local ctrl_pts_array = array[n_of_seg]\n')
file.write(' #local ctrl_rs_array = array[n_of_seg]\n')
file.write(' #for(i, 0, n_of_seg-1)\n')
file.write(
' #local ctrl_pts_array[i] = array[4] {_points_array[4*i], _points_array[4*i+1], _points_array[4*i+2], _points_array[4*i+3]}\n'
)
file.write(
' #local ctrl_rs_array[i] = array[4] {abs(_radius_array[4*i]), abs(_radius_array[4*i+1]), abs(_radius_array[4*i+2]), abs(_radius_array[4*i+3])}\n'
)
file.write(' #end\n')
file.write(' #end\n')
file.write(' //drawing\n')
file.write(' #local mockup1 =\n')
file.write(' #if(_merge_shape) merge{ #else union{ #end\n')
file.write(' #for(i, 0, n_of_seg-1)\n')
file.write(' #local has_head = true;\n')
file.write(' #if(i = 0)\n')
file.write(
' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[n_of_seg-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[n_of_seg-1][3] <= 0)\n'
)
file.write(' #local has_head = false;\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(
' #if(vlength(ctrl_pts_array[i][0]-ctrl_pts_array[i-1][3]) = 0 & ctrl_rs_array[i][0]-ctrl_rs_array[i-1][3] <= 0)\n'
)
file.write(' #local has_head = false;\n')
file.write(' #end\n')
file.write(' #end\n')
file.write(' #if(has_head = true)\n')
file.write(' sphere{\n')
file.write(
' ctrl_pts_array[i][0], ctrl_rs_array[i][0]\n'
)
file.write(' }\n')
file.write(' #end\n')
file.write(' #local para_t = (1/2)/res;\n')
file.write(
' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n'
)
file.write(
' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n'
)
file.write(
' #if(vlength(this_point-ctrl_pts_array[i][0]) > abs(this_radius-ctrl_rs_array[i][0]))\n'
)
file.write(' object{\n')
file.write(
' Connect_Spheres(ctrl_pts_array[i][0], ctrl_rs_array[i][0], this_point, this_radius)\n'
)
file.write(' }\n')
file.write(' #end\n')
file.write(' sphere{\n')
file.write(' this_point, this_radius\n')
file.write(' }\n')
file.write(' #for(j, 1, res-1)\n')
file.write(' #local last_point = this_point;\n')
file.write(
' #local last_radius = this_radius;\n'
)
file.write(' #local para_t = (1/2+j)/res;\n')
file.write(
' #local this_point = ctrl_pts_array[i][0]*pow(1-para_t,3) + ctrl_pts_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_pts_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_pts_array[i][3]*pow(para_t,3);\n'
)
file.write(
' #local this_radius = ctrl_rs_array[i][0]*pow(1-para_t,3) + ctrl_rs_array[i][1]*3*pow(1-para_t,2)*para_t + ctrl_rs_array[i][2]*3*(1-para_t)*pow(para_t,2) + ctrl_rs_array[i][3]*pow(para_t,3);\n'
)
file.write(
' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n'
)
file.write(' object{\n')
file.write(
' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n'
)
file.write(' }\n')
file.write(' #end\n')
file.write(' sphere{\n')
file.write(' this_point, this_radius\n')
file.write(' }\n')
file.write(' #end\n')
file.write(' #local last_point = this_point;\n')
file.write(' #local last_radius = this_radius;\n')
file.write(
' #local this_point = ctrl_pts_array[i][3];\n'
)
file.write(
' #local this_radius = ctrl_rs_array[i][3];\n'
)
file.write(
' #if(vlength(this_point-last_point) > abs(this_radius-last_radius))\n'
)
file.write(' object{\n')
file.write(
' Connect_Spheres(last_point, last_radius, this_point, this_radius)\n'
)
file.write(' }\n')
file.write(' #end\n')
file.write(' sphere{\n')
file.write(' this_point, this_radius\n')
file.write(' }\n')
file.write(' #end\n')
file.write(' }\n')
file.write(' mockup1\n')
file.write(' #end\n')
for spl in ob.data.splines:
if spl.type == "BEZIER":
bezier_sweep = True
if ob.pov.curveshape in {'loft', 'birail'}:
n = 0
for spline in ob.data.splines:
n += 1
tabWrite('#declare %s%s=spline {\n' % (dataname, n))
tabWrite('cubic_spline\n')
lp = len(spline.points)
delta = 1 / (lp)
d = -delta
point = spline.points[lp - 1]
x, y, z, w = point.co[:]
tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z))
d += delta
for point in spline.points:
x, y, z, w = point.co[:]
tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z))
d += delta
for i in range(2):
point = spline.points[i]
x, y, z, w = point.co[:]
tabWrite('%.6f, <%.6f,%.6f,%.6f>\n' % (d, x, y, z))
d += delta
tabWrite('}\n')
if ob.pov.curveshape in {'loft'}:
n = len(ob.data.splines)
tabWrite('#declare %s = array[%s]{\n' % (dataname, (n + 3)))
tabWrite('spline{%s%s},\n' % (dataname, n))
tabWrite('spline{%s%s},\n' % (dataname, (i + 1)))
tabWrite('spline{%s1},\n' % (dataname))
tabWrite('spline{%s2}\n' % (dataname))
tabWrite('}\n')
# Use some of the Meshmaker.inc macro, here inlined
file.write('#macro CheckFileName(FileName)\n')
file.write(' #local Len=strlen(FileName);\n')
file.write(' #if(Len>0)\n')
file.write(' #if(file_exists(FileName))\n')
file.write(' #if(Len>=4)\n')
file.write(
' #local Ext=strlwr(substr(FileName,Len-3,4))\n'
)
file.write(
' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n'
)
file.write(' #local Return=99;\n')
file.write(' #else\n')
file.write(' #local Return=0;\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(' #local Return=0;\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(' #if(Len>=4)\n')
file.write(
' #local Ext=strlwr(substr(FileName,Len-3,4))\n'
)
file.write(
' #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n'
)
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
file.write(' #if (strcmp(Ext,".obj")=0)\n')
file.write(' #local Return=2;\n')
file.write(' #end\n')
file.write(' #if (strcmp(Ext,".pcm")=0)\n')
file.write(' #local Return=3;\n')
file.write(' #end\n')
file.write(' #if (strcmp(Ext,".arr")=0)\n')
file.write(' #local Return=4;\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(' #local Return=1;\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(' #local Return=1;\n')
file.write(' #end\n')
file.write(' #end\n')
file.write(' #else\n')
file.write(' #local Return=1;\n')
file.write(' #end\n')
file.write(' (Return)\n')
file.write('#end\n')
file.write('#macro BuildSpline(Arr, SplType)\n')
file.write(' #local Ds=dimension_size(Arr,1);\n')
file.write(' #local Asc=asc(strupr(SplType));\n')
file.write(' #if(Asc!=67 & Asc!=76 & Asc!=81) \n')
file.write(' #local Asc=76;\n')
file.write(
' #debug "\nWrong spline type defined (C/c/L/l/N/n/Q/q), using default linear_spline\\n"\n'
)
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
file.write(' #end\n')
file.write(' spline {\n')
file.write(' #switch (Asc)\n')
file.write(' #case (67) //C cubic_spline\n')
file.write(' cubic_spline\n')
file.write(' #break\n')
file.write(' #case (76) //L linear_spline\n')
file.write(' linear_spline\n')
file.write(' #break\n')
file.write(' #case (78) //N linear_spline\n')
file.write(' natural_spline\n')
file.write(' #break\n')
file.write(' #case (81) //Q Quadratic_spline\n')
file.write(' quadratic_spline\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' #local Add=1/((Ds-2)-1);\n')
file.write(' #local J=0-Add;\n')
file.write(' #local I=0;\n')
file.write(' #while (I<Ds)\n')
file.write(' J\n')
file.write(' Arr[I]\n')
file.write(' #local I=I+1;\n')
file.write(' #local J=J+Add;\n')
file.write(' #end\n')
file.write(' }\n')
file.write('#end\n')
file.write(
'#macro BuildWriteMesh2(VecArr, NormArr, UVArr, U, V, FileName)\n'
)
# suppressed some file checking from original macro because no more separate files
file.write(' #local Write=0;\n')
file.write(
' #debug concat("\\n\\n Building mesh2: \\n - vertex_vectors\\n")\n'
)
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
file.write(' #local NumVertices=dimension_size(VecArr,1);\n')
file.write(' #switch (Write)\n')
file.write(' #case(1)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(' " vertex_vectors {\\n",\n')
file.write(' " ", str(NumVertices,0,0),"\\n "\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(' "# Vertices: ",str(NumVertices,0,0),"\\n"\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(' str(2*NumVertices,0,0),",\\n"\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "#declare VertexVectors= array[",str(NumVertices,0,0),"] {\\n "\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' mesh2 {\n')
file.write(' vertex_vectors {\n')
file.write(' NumVertices\n')
file.write(' #local I=0;\n')
file.write(' #while (I<NumVertices)\n')
file.write(' VecArr[I]\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile, VecArr[I])\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "v ", VecArr[I].x," ", VecArr[I].y," ", VecArr[I].z,"\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' VecArr[I].x,",", VecArr[I].y,",", VecArr[I].z,",\\n"\n'
)
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile, VecArr[I])\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' #local I=I+1;\n')
file.write(' #if(Write=1 | Write=4)\n')
file.write(' #if(mod(I,3)=0)\n')
file.write(' #write(MeshFile,"\\n ")\n')
file.write(' #end\n')
file.write(' #end \n')
file.write(' #end\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile,"\\n }\\n")\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(MeshFile,"\\n")\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' // do nothing\n')
file.write(' #break\n')
file.write(' #case(4) \n')
file.write(' #write(MeshFile,"\\n}\\n")\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' }\n')
file.write(' #debug concat(" - normal_vectors\\n") \n')
file.write(' #local NumVertices=dimension_size(NormArr,1);\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(' " normal_vectors {\\n",\n')
file.write(' " ", str(NumVertices,0,0),"\\n "\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "# Normals: ",str(NumVertices,0,0),"\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' // do nothing\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "#declare NormalVectors= array[",str(NumVertices,0,0),"] {\\n "\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' normal_vectors {\n')
file.write(' NumVertices\n')
file.write(' #local I=0;\n')
file.write(' #while (I<NumVertices)\n')
file.write(' NormArr[I]\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile NormArr[I])\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "vn ", NormArr[I].x," ", NormArr[I].y," ", NormArr[I].z,"\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' NormArr[I].x,",", NormArr[I].y,",", NormArr[I].z,",\\n"\n'
)
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile NormArr[I])\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' #local I=I+1;\n')
file.write(' #if(Write=1 | Write=4) \n')
file.write(' #if(mod(I,3)=0)\n')
file.write(' #write(MeshFile,"\\n ")\n')
file.write(' #end\n')
file.write(' #end\n')
file.write(' #end\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile,"\\n }\\n")\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(MeshFile,"\\n")\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' //do nothing\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile,"\\n}\\n")\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' }\n')
file.write(' #debug concat(" - uv_vectors\\n") \n')
file.write(' #local NumVertices=dimension_size(UVArr,1);\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(\n')
file.write(' MeshFile, \n')
file.write(' " uv_vectors {\\n",\n')
file.write(' " ", str(NumVertices,0,0),"\\n "\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "# UV-vectors: ",str(NumVertices,0,0),"\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(
' // do nothing, *.pcm does not support uv-vectors\n'
)
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "#declare UVVectors= array[",str(NumVertices,0,0),"] {\\n "\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' uv_vectors {\n')
file.write(' NumVertices\n')
file.write(' #local I=0;\n')
file.write(' #while (I<NumVertices)\n')
file.write(' UVArr[I]\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile UVArr[I])\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "vt ", UVArr[I].u," ", UVArr[I].v,"\\n"\n'
)
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' //do nothing\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile UVArr[I])\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' #local I=I+1; \n')
file.write(' #if(Write=1 | Write=4)\n')
file.write(' #if(mod(I,3)=0)\n')
file.write(' #write(MeshFile,"\\n ")\n')
file.write(' #end \n')
file.write(' #end\n')
file.write(' #end \n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile,"\\n }\\n")\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(MeshFile,"\\n")\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' //do nothing\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile,"\\n}\\n")\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' }\n')
file.write('\n')
file.write(' #debug concat(" - face_indices\\n") \n')
file.write(' #declare NumFaces=U*V*2;\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(' " face_indices {\\n"\n')
file.write(' " ", str(NumFaces,0,0),"\\n "\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write (\n')
file.write(' MeshFile,\n')
file.write(' "# faces: ",str(NumFaces,0,0),"\\n"\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #write (\n')
file.write(' MeshFile,\n')
file.write(' "0,",str(NumFaces,0,0),",\\n"\n')
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "#declare FaceIndices= array[",str(NumFaces,0,0),"] {\\n "\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' face_indices {\n')
file.write(' NumFaces\n')
file.write(' #local I=0;\n')
file.write(' #local H=0;\n')
file.write(' #local NumVertices=dimension_size(VecArr,1);\n')
file.write(' #while (I<V)\n')
file.write(' #local J=0;\n')
file.write(' #while (J<U)\n')
file.write(' #local Ind=(I*U)+I+J;\n')
file.write(
' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n'
)
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' "f ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+1+1,"/",Ind+1+1,"/",Ind+1+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n",\n'
)
file.write(
' "f ",Ind+U+1+1,"/",Ind+U+1+1,"/",Ind+U+1+1," ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' Ind,",",Ind+NumVertices,",",Ind+1,",",Ind+1+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n'
)
file.write(
' Ind+U+1,",",Ind+U+1+NumVertices,",",Ind,",",Ind+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n'
)
file.write(' )\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(\n')
file.write(' MeshFile,\n')
file.write(
' <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n'
)
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
file.write(' )\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' #local J=J+1;\n')
file.write(' #local H=H+1;\n')
file.write(' #if(Write=1 | Write=4)\n')
file.write(' #if(mod(H,3)=0)\n')
file.write(' #write(MeshFile,"\\n ")\n')
file.write(' #end \n')
file.write(' #end\n')
file.write(' #end\n')
file.write(' #local I=I+1;\n')
file.write(' #end\n')
file.write(' }\n')
file.write(' #switch(Write)\n')
file.write(' #case(1)\n')
file.write(' #write(MeshFile, "\\n }\\n}")\n')
file.write(' #fclose MeshFile\n')
file.write(' #debug concat(" Done writing\\n")\n')
file.write(' #break\n')
file.write(' #case(2)\n')
file.write(' #fclose MeshFile\n')
file.write(' #debug concat(" Done writing\\n")\n')
file.write(' #break\n')
file.write(' #case(3)\n')
file.write(' #fclose MeshFile\n')
file.write(' #debug concat(" Done writing\\n")\n')
file.write(' #break\n')
file.write(' #case(4)\n')
file.write(' #write(MeshFile, "\\n}\\n}")\n')
file.write(' #fclose MeshFile\n')
file.write(' #debug concat(" Done writing\\n")\n')
file.write(' #break\n')
file.write(' #end\n')
file.write(' }\n')
file.write('#end\n')
file.write(
'#macro MSM(SplineArray, SplRes, Interp_type, InterpRes, FileName)\n'
)
file.write(' #declare Build=CheckFileName(FileName);\n')
file.write(' #if(Build=0)\n')
file.write(
' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n'
)
file.write(' #include FileName\n')
file.write(' object{Surface}\n')
file.write(' #else\n')
file.write(' #local NumVertices=(SplRes+1)*(InterpRes+1);\n')
file.write(' #local NumFaces=SplRes*InterpRes*2;\n')
file.write(
' #debug concat("\\n Calculating ",str(NumVertices,0,0)," vertices for ", str(NumFaces,0,0)," triangles\\n\\n")\n'
)
file.write(' #local VecArr=array[NumVertices]\n')
file.write(' #local NormArr=array[NumVertices]\n')
file.write(' #local UVArr=array[NumVertices]\n')
file.write(' #local N=dimension_size(SplineArray,1);\n')
file.write(' #local TempSplArr0=array[N];\n')
file.write(' #local TempSplArr1=array[N];\n')
file.write(' #local TempSplArr2=array[N];\n')
file.write(' #local PosStep=1/SplRes;\n')
file.write(' #local InterpStep=1/InterpRes;\n')
file.write(' #local Count=0;\n')
file.write(' #local Pos=0;\n')
file.write(' #while(Pos<=1)\n')
file.write(' #local I=0;\n')
file.write(' #if (Pos=0)\n')
file.write(' #while (I<N)\n')
file.write(
' #local Spl=spline{SplineArray[I]}\n'
)
file.write(
' #local TempSplArr0[I]=<0,0,0>+Spl(Pos);\n'
)
file.write(
' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n'
)
file.write(
' #local TempSplArr2[I]=<0,0,0>+Spl(Pos-PosStep);\n'
)
file.write(' #local I=I+1;\n')
file.write(' #end\n')
file.write(
' #local S0=BuildSpline(TempSplArr0, Interp_type)\n'
)
file.write(
' #local S1=BuildSpline(TempSplArr1, Interp_type)\n'
)
file.write(
' #local S2=BuildSpline(TempSplArr2, Interp_type)\n'
)
file.write(' #else\n')
file.write(' #while (I<N)\n')
file.write(
' #local Spl=spline{SplineArray[I]}\n'
)
file.write(
' #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n'
)
file.write(' #local I=I+1;\n')
file.write(' #end\n')
file.write(
' #local S1=BuildSpline(TempSplArr1, Interp_type)\n'
)
file.write(' #end\n')
file.write(' #local J=0;\n')
file.write(' #while (J<=1)\n')
file.write(' #local P0=<0,0,0>+S0(J);\n')
file.write(' #local P1=<0,0,0>+S1(J);\n')
file.write(' #local P2=<0,0,0>+S2(J);\n')
file.write(' #local P3=<0,0,0>+S0(J+InterpStep);\n')
file.write(' #local P4=<0,0,0>+S0(J-InterpStep);\n')
file.write(' #local B1=P4-P0;\n')
file.write(' #local B2=P2-P0;\n')
file.write(' #local B3=P3-P0;\n')
file.write(' #local B4=P1-P0;\n')
file.write(' #local N1=vcross(B1,B2);\n')
file.write(' #local N2=vcross(B2,B3);\n')
file.write(' #local N3=vcross(B3,B4);\n')
file.write(' #local N4=vcross(B4,B1);\n')
file.write(
' #local Norm=vnormalize((N1+N2+N3+N4));\n'
)
file.write(' #local VecArr[Count]=P0;\n')
file.write(' #local NormArr[Count]=Norm;\n')
file.write(' #local UVArr[Count]=<J,Pos>;\n')
file.write(' #local J=J+InterpStep;\n')
file.write(' #local Count=Count+1;\n')
file.write(' #end\n')
file.write(' #local S2=spline{S0}\n')
file.write(' #local S0=spline{S1}\n')
file.write(
' #debug concat("\\r Done ", str(Count,0,0)," vertices : ", str(100*Count/NumVertices,0,2)," %")\n'
)
file.write(' #local Pos=Pos+PosStep;\n')
file.write(' #end\n')
file.write(
' BuildWriteMesh2(VecArr, NormArr, UVArr, InterpRes, SplRes, "")\n'
)
file.write(' #end\n')
file.write('#end\n\n')
file.write(
'#macro Coons(Spl1, Spl2, Spl3, Spl4, Iter_U, Iter_V, FileName)\n'
)
file.write(' #declare Build=CheckFileName(FileName);\n')
file.write(' #if(Build=0)\n')
file.write(
' #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n'
)
file.write(' #include FileName\n')
file.write(' object{Surface}\n')
file.write(' #else\n')
file.write(' #local NumVertices=(Iter_U+1)*(Iter_V+1);\n')
file.write(' #local NumFaces=Iter_U*Iter_V*2;\n')
file.write(
' #debug concat("\\n Calculating ", str(NumVertices,0,0), " vertices for ",str(NumFaces,0,0), " triangles\\n\\n")\n'
)
file.write(' #declare VecArr=array[NumVertices] \n')
file.write(' #declare NormArr=array[NumVertices] \n')
file.write(' #local UVArr=array[NumVertices] \n')
file.write(' #local Spl1_0=Spl1(0);\n')
file.write(' #local Spl2_0=Spl2(0);\n')
file.write(' #local Spl3_0=Spl3(0);\n')
file.write(' #local Spl4_0=Spl4(0);\n')
file.write(' #local UStep=1/Iter_U;\n')
file.write(' #local VStep=1/Iter_V;\n')
file.write(' #local Count=0;\n')
file.write(' #local I=0;\n')
file.write(' #while (I<=1)\n')
file.write(' #local Im=1-I;\n')
file.write(' #local J=0;\n')
file.write(' #while (J<=1)\n')
file.write(' #local Jm=1-J;\n')
file.write(
' #local C0=Im*Jm*(Spl1_0)+Im*J*(Spl2_0)+I*J*(Spl3_0)+I*Jm*(Spl4_0);\n'
)
file.write(
' #local P0=LInterpolate(I, Spl1(J), Spl3(Jm)) + \n'
)
file.write(
' LInterpolate(Jm, Spl2(I), Spl4(Im))-C0;\n'
)
file.write(' #declare VecArr[Count]=P0;\n')
file.write(' #local UVArr[Count]=<J,I>;\n')
file.write(' #local J=J+UStep;\n')
file.write(' #local Count=Count+1;\n')
file.write(' #end\n')
file.write(' #debug concat(\n')
file.write(
' "\r Done ", str(Count,0,0)," vertices : ",\n'
)
file.write(' str(100*Count/NumVertices,0,2)," %"\n')
file.write(' )\n')
file.write(' #local I=I+VStep;\n')
file.write(' #end\n')
file.write(
' #debug "\r Normals "\n'
)
file.write(' #local Count=0;\n')
file.write(' #local I=0;\n')
file.write(' #while (I<=Iter_V)\n')
file.write(' #local J=0;\n')
file.write(' #while (J<=Iter_U)\n')
file.write(' #local Ind=(I*Iter_U)+I+J;\n')
file.write(' #local P0=VecArr[Ind];\n')
file.write(' #if(J=0)\n')
file.write(' #local P1=P0+(P0-VecArr[Ind+1]);\n')
file.write(' #else\n')
file.write(' #local P1=VecArr[Ind-1];\n')
file.write(' #end\n')
file.write(' #if (J=Iter_U)\n')
file.write(' #local P2=P0+(P0-VecArr[Ind-1]);\n')
file.write(' #else\n')
file.write(' #local P2=VecArr[Ind+1];\n')
file.write(' #end\n')
file.write(' #if (I=0)\n')
file.write(
' #local P3=P0+(P0-VecArr[Ind+Iter_U+1]);\n'
)
file.write(' #else\n')
file.write(' #local P3=VecArr[Ind-Iter_U-1];\n')
file.write(' #end\n')
file.write(' #if (I=Iter_V)\n')
file.write(
' #local P4=P0+(P0-VecArr[Ind-Iter_U-1]);\n'
)
file.write(' #else\n')
file.write(' #local P4=VecArr[Ind+Iter_U+1];\n')
file.write(' #end\n')
file.write(' #local B1=P4-P0;\n')
file.write(' #local B2=P2-P0;\n')
file.write(' #local B3=P3-P0;\n')
file.write(' #local B4=P1-P0;\n')
file.write(' #local N1=vcross(B1,B2);\n')
file.write(' #local N2=vcross(B2,B3);\n')
file.write(' #local N3=vcross(B3,B4);\n')
file.write(' #local N4=vcross(B4,B1);\n')
file.write(' #local Norm=vnormalize((N1+N2+N3+N4));\n')
file.write(' #declare NormArr[Count]=Norm;\n')
file.write(' #local J=J+1;\n')
file.write(' #local Count=Count+1;\n')
file.write(' #end\n')
file.write(
' #debug concat("\r Done ", str(Count,0,0)," normals : ",str(100*Count/NumVertices,0,2), " %")\n'
)
file.write(' #local I=I+1;\n')
file.write(' #end\n')
file.write(
' BuildWriteMesh2(VecArr, NormArr, UVArr, Iter_U, Iter_V, FileName)\n'
)
file.write(' #end\n')
file.write('#end\n\n')
Maurice Raybaud
committed
# Empty curves
if len(ob.data.splines) == 0:
tabWrite("\n//dummy sphere to represent empty curve location\n")
tabWrite("#declare %s =\n" % dataname)
tabWrite(
"sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n"
% (ob.location.x, ob.location.y, ob.location.z)
) # ob.name > povdataname)
Maurice Raybaud
committed
else:
if bezier_sweep == False:
tabWrite("#declare %s =\n" % dataname)
Maurice Raybaud
committed
if ob.pov.curveshape == 'sphere_sweep' and bezier_sweep == False:
tabWrite("union {\n")
for spl in ob.data.splines:
if spl.type != "BEZIER":
spl_type = "linear"
if spl.type == "NURBS":
spl_type = "cubic"
points = spl.points
numPoints = len(points)
Maurice Raybaud
committed
if spl.use_cyclic_u:
Maurice Raybaud
committed
tabWrite(
"sphere_sweep { %s_spline %s,\n"
% (spl_type, numPoints)
)
Maurice Raybaud
committed
if spl.use_cyclic_u:
pt1 = points[len(points) - 1]
Maurice Raybaud
committed
wpt1 = pt1.co
tabWrite(
"<%.4g,%.4g,%.4g>,%.4g\n"
% (
wpt1[0],
wpt1[1],
wpt1[2],
pt1.radius * ob.data.bevel_depth,
)
)
Maurice Raybaud
committed
for pt in points:
wpt = pt.co
tabWrite(
"<%.4g,%.4g,%.4g>,%.4g\n"
% (
wpt[0],
wpt[1],
wpt[2],
pt.radius * ob.data.bevel_depth,
)
)
Maurice Raybaud
committed
if spl.use_cyclic_u:
for i in range(0, 2):
endPt = points[i]
Maurice Raybaud
committed
wpt = endPt.co
tabWrite(
"<%.4g,%.4g,%.4g>,%.4g\n"
% (
wpt[0],
wpt[1],
wpt[2],
endPt.radius * ob.data.bevel_depth,
)
)
Maurice Raybaud
committed
tabWrite("}\n")
# below not used yet?
Maurice Raybaud
committed
if ob.pov.curveshape == 'sor':
for spl in ob.data.splines:
if spl.type in {'POLY', 'NURBS'}:
points = spl.points
numPoints = len(points)
tabWrite("sor { %s,\n" % numPoints)
Maurice Raybaud
committed
for pt in points:
wpt = pt.co
tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
Maurice Raybaud
committed
else:
tabWrite("box { 0,0\n")
if ob.pov.curveshape in {'lathe', 'prism'}:
Maurice Raybaud
committed
spl = ob.data.splines[0]
if spl.type == "BEZIER":
points = spl.bezier_points
lenCur = len(points) - 1
lenPts = lenCur * 4
Maurice Raybaud
committed
ifprism = ''
if ob.pov.curveshape in {'prism'}:
height = ob.data.extrude
ifprism = '-%s, %s,' % (height, height)
lenCur += 1
lenPts += 4
tabWrite(
"%s { bezier_spline %s %s,\n"
% (ob.pov.curveshape, ifprism, lenPts)
)
for i in range(0, lenCur):
p1 = points[i].co
pR = points[i].handle_right
end = i + 1
if i == lenCur - 1 and ob.pov.curveshape in {'prism'}:
Maurice Raybaud
committed
end = 0
pL = points[end].handle_left
p2 = points[end].co
line = "<%.4g,%.4g>" % (p1[0], p1[1])
line += "<%.4g,%.4g>" % (pR[0], pR[1])
line += "<%.4g,%.4g>" % (pL[0], pL[1])
line += "<%.4g,%.4g>" % (p2[0], p2[1])
tabWrite("%s\n" % line)
Maurice Raybaud
committed
else:
points = spl.points
lenCur = len(points)
lenPts = lenCur
Maurice Raybaud
committed
ifprism = ''
if ob.pov.curveshape in {'prism'}:
height = ob.data.extrude
ifprism = '-%s, %s,' % (height, height)
lenPts += 3
Maurice Raybaud
committed
spl_type = 'quadratic'
if spl.type == 'POLY':
spl_type = 'linear'
tabWrite(
"%s { %s_spline %s %s,\n"
% (ob.pov.curveshape, spl_type, ifprism, lenPts)
)
Maurice Raybaud
committed
if ob.pov.curveshape in {'prism'}:
pt = points[len(points) - 1]
tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
Maurice Raybaud
committed
for pt in points:
tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
Maurice Raybaud
committed
if ob.pov.curveshape in {'prism'}:
for i in range(2):
pt = points[i]
wpt = pt.co
tabWrite("<%.4g,%.4g>\n" % (wpt[0], wpt[1]))
Maurice Raybaud
committed
if bezier_sweep:
for p in range(len(ob.data.splines)):
Maurice Raybaud
committed
br = []
depth = ob.data.bevel_depth
spl = ob.data.splines[p]
points = spl.bezier_points
lenCur = len(points) - 1
numPoints = lenCur * 4
Maurice Raybaud
committed
if spl.use_cyclic_u:
lenCur += 1
numPoints += 4
tabWrite(
"#declare %s_points_%s = array[%s]{\n"
% (dataname, p, numPoints)
)
Maurice Raybaud
committed
for i in range(lenCur):
p1 = points[i].co
pR = points[i].handle_right
end = i + 1
Maurice Raybaud
committed
if spl.use_cyclic_u and i == (lenCur - 1):
end = 0
pL = points[end].handle_left
p2 = points[end].co
Maurice Raybaud
committed
r3 = points[end].radius * depth
r0 = points[i].radius * depth
r1 = 2 / 3 * r0 + 1 / 3 * r3
r2 = 1 / 3 * r0 + 2 / 3 * r3
br.append((r0, r1, r2, r3))
line = "<%.4g,%.4g,%.4f>" % (p1[0], p1[1], p1[2])
line += "<%.4g,%.4g,%.4f>" % (pR[0], pR[1], pR[2])
line += "<%.4g,%.4g,%.4f>" % (pL[0], pL[1], pL[2])
line += "<%.4g,%.4g,%.4f>" % (p2[0], p2[1], p2[2])
tabWrite("%s\n" % line)
Maurice Raybaud
committed
tabWrite("}\n")
tabWrite(
"#declare %s_radii_%s = array[%s]{\n"
% (dataname, p, len(br) * 4)
)
Maurice Raybaud
committed
for Tuple in br:
tabWrite(
'%.4f,%.4f,%.4f,%.4f\n'
% (Tuple[0], Tuple[1], Tuple[2], Tuple[3])
)
Maurice Raybaud
committed
tabWrite("}\n")
if len(ob.data.splines) == 1:
tabWrite('#declare %s = object{\n' % dataname)
tabWrite(
' Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s) \n'
% (ob.data.resolution_u, dataname, p, dataname, p)
)
Maurice Raybaud
committed
else:
tabWrite('#declare %s = union{\n' % dataname)
Maurice Raybaud
committed
for p in range(len(ob.data.splines)):
tabWrite(
' object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_points_%s, %s_radii_%s)} \n'
% (ob.data.resolution_u, dataname, p, dataname, p)
)
# tabWrite('#include "bezier_spheresweep.inc"\n') #now inlined
# tabWrite('#declare %s = object{Shape_Bezierpoints_Sphere_Sweep(yes,%s, %s_bezier_points, %.4f) \n'%(dataname,ob.data.resolution_u,dataname,ob.data.bevel_depth))
Maurice Raybaud
committed
if ob.pov.curveshape in {'loft'}:
tabWrite(
'object {MSM(%s,%s,"c",%s,"")\n'
% (dataname, ob.pov.res_u, ob.pov.res_v)
)
Maurice Raybaud
committed
if ob.pov.curveshape in {'birail'}:
splines = '%s1,%s2,%s3,%s4' % (
dataname,
dataname,
dataname,
dataname,
)
tabWrite(
'object {Coons(%s, %s, %s, "")\n'
% (splines, ob.pov.res_u, ob.pov.res_v)
)
Maurice Raybaud
committed
povMatName = "Default_texture"
if ob.active_material:
# povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
Maurice Raybaud
committed
try:
material = ob.active_material
writeObjectMaterial(material, ob)
except IndexError:
print(me)
# tabWrite("texture {%s}\n"%povMatName)
Maurice Raybaud
committed
if ob.pov.curveshape in {'prism'}:
tabWrite("rotate <90,0,0>\n")
tabWrite("scale y*-1\n")
Maurice Raybaud
committed
tabWrite("}\n")
#################################################################
"""write all POV blob primitives and Blender Metas to exported file """
if comments and len(metas) >= 1:
file.write("//--Blob objects--\n\n")
# Get groups of metaballs by blender name prefix.
meta_group = {}
meta_elems = {}
Maurice Raybaud
committed
prefix = ob.name.split(".")[0]
if not prefix in meta_group:
meta_group[prefix] = ob # .data.threshold
elems = [
(elem, ob)
for elem in ob.data.elements
if elem.type
in {'BALL', 'ELLIPSOID', 'CAPSULE', 'CUBE', 'PLANE'}
]
if prefix in meta_elems:
meta_elems[prefix].extend(elems)
Maurice Raybaud
committed
else:
Maurice Raybaud
committed
# empty metaball
Maurice Raybaud
committed
tabWrite("\n//dummy sphere to represent empty meta location\n")
tabWrite(
"sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n"
% (ob.location.x, ob.location.y, ob.location.z)
) # ob.name > povdataname)
Maurice Raybaud
committed
for mg, ob in meta_group.items():
if len(meta_elems[mg]) != 0:
tabWrite(
"blob{threshold %.4g // %s \n"
% (ob.data.threshold, mg)
)
Maurice Raybaud
committed
for elems in meta_elems[mg]:
elem = elems[0]
loc = elem.co
stiffness = elem.stiffness
if elem.use_negative:
stiffness = -stiffness
Maurice Raybaud
committed
if elem.type == 'BALL':
tabWrite(
"sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g "
% (
loc.x,
loc.y,
loc.z,
elem.radius,
stiffness,
)
)
writeMatrix(
global_matrix @ elems[1].matrix_world
)
Maurice Raybaud
committed
elif elem.type == 'ELLIPSOID':
tabWrite(
"sphere{ <%.6g, %.6g, %.6g>,%.4g,%.4g "
% (
loc.x / elem.size_x,
loc.y / elem.size_y,
loc.z / elem.size_z,
elem.radius,
stiffness,
)
)
tabWrite(
"scale <%.6g, %.6g, %.6g>"
% (elem.size_x, elem.size_y, elem.size_z)
)
writeMatrix(
global_matrix @ elems[1].matrix_world
)
elif elem.type == 'CAPSULE':
tabWrite(
"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,
)
)
# tabWrite("scale <%.6g, %.6g, %.6g>" % (elem.size_x, elem.size_y, elem.size_z))
writeMatrix(
global_matrix @ elems[1].matrix_world
)
Maurice Raybaud
committed
tabWrite("}\n")
elif elem.type == 'CUBE':
tabWrite(
"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,
)
)
writeMatrix(
global_matrix @ elems[1].matrix_world
)
Maurice Raybaud
committed
tabWrite("}\n")
tabWrite(
"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,
)
)
writeMatrix(
global_matrix @ elems[1].matrix_world
)
tabWrite(
"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,
)
)
writeMatrix(
global_matrix @ elems[1].matrix_world
)
Maurice Raybaud
committed
tabWrite("}\n")
Maurice Raybaud
committed
elif elem.type == 'PLANE':
tabWrite(
"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,
Loading
Loading full blame…