"...resource-allocation-and-job-execution.md" did not exist on "576c448775b1ac2ab8d407cfe147ea866e5c8ef5"
Newer
Older
(ob.pov.inside_vector[0],
ob.pov.inside_vector[1],
ob.pov.inside_vector[2]))
onceCSG = 1
if me.materials:
try:
material = me.materials[0] # dodgy
writeObjectMaterial(material, ob)
except IndexError:
print(me)
# POV object modifiers such as
# hollow / sturm / double_illuminate etc.
write_object_modifiers(scene,ob,file)
Maurice Raybaud
committed
#Importance for radiosity sampling added here:
tabWrite("radiosity { \n")
tabWrite("importance %3g \n" % importance)
tabWrite("}\n")
tabWrite("}\n") # End of mesh block
else:
facesMaterials = [] # WARNING!!!!!!!!!!!!!!!!!!!!!!
if me_materials:
for f in me_faces:
if f.material_index not in facesMaterials:
facesMaterials.append(f.material_index)
# No vertex colors, so write material colors as vertex colors
for i, material in enumerate(me_materials):
if material and material.pov.material_use_nodes == False: # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Multiply diffuse with SSS Color
if material.subsurface_scattering.use:
diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat
vertCols[key] = [-1]
else:
diffuse_color = material.diffuse_color[:]
key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i # i == f.mat
vertCols[key] = [-1]
idx = 0
for col, index in vertCols.items():
#if me_materials:
mater = me_materials[col[3]]
if me_materials is None: #XXX working?
material_finish = DEF_MAT_NAME # not working properly,
trans = 0.0
Maurice Raybaud
committed
shading.writeTextureInfluence(mater, materialNames,
path_image, lampCount,
imageFormat, imgMap,
imgMapTransforms,
tabWrite, comments,
Maurice Raybaud
committed
safety, col, os, preview_dir, unpacked_images)
###################################################################
index[0] = idx
# Vert Colors
tabWrite("texture_list {\n")
# In case there's is no material slot, give at least one texture
#(an empty one so it uses pov default)
if len(vertCols)==0:
file.write(tabStr + "1")
file.write(tabStr + "%s" % (len(vertCols))) # vert count
# below "material" alias, added check ob.active_material
# to avoid variable referenced before assignment error
try:
material = ob.active_material
except IndexError:
material=None
# WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if material and ob.active_material is not None and material.pov.material_use_nodes == False:
if material.pov.replacement_text != "":
file.write("\n")
file.write(" texture{%s}\n" % material.pov.replacement_text)
Maurice Raybaud
committed
else:
# Loop through declared materials list
for cMN in LocalMaterialNames:
if material != "Default":
file.write("\n texture{MAT_%s}\n" % cMN)
#use string_strip_hyphen(materialNames[material]))
#or Something like that to clean up the above?
elif material and material.pov.material_use_nodes:
for index in facesMaterials:
faceMaterial = string_strip_hyphen(bpy.path.clean_name(me_materials[index].name))
file.write("\n texture{%s}\n" % faceMaterial)
# END!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Face indices
tabWrite("face_indices {\n")
tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
tabStr = tab * tabLevel
for fi, f in enumerate(me_faces):
fv = faces_verts[fi]
material_index = f.material_index
indices = (0, 1, 2), (0, 2, 3)
Maurice Raybaud
committed
else:
indices = ((0, 1, 2),)
if vcol_layer:
col = vcol_layer[fi]
if len(fv) == 4:
cols = col.color1, col.color2, col.color3, col.color4
cols = col.color1, col.color2, col.color3
if not me_materials or me_materials[material_index] is None: # No materials
for i1, i2, i3 in indices:
if linebreaksinlists:
file.write(",\n")
# vert count
file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))
file.write(", ")
file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3])) # vert count
Maurice Raybaud
committed
else:
material = me_materials[material_index]
for i1, i2, i3 in indices:
ci1 = ci2 = ci3 = f.material_index
if me.vertex_colors: #and material.use_vertex_color_paint:
# Color per vertex - vertex color
col1 = cols[i1]
col2 = cols[i2]
col3 = cols[i3]
ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
elif material.pov.material_use_nodes:
ci1 = ci2 = ci3 = 0
else:
# Color per material - flat material color
if material.subsurface_scattering.use:
diffuse_color = [i * j for i, j in
zip(material.subsurface_scattering.color[:],
material.diffuse_color[:])]
else:
diffuse_color = material.diffuse_color[:]
ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
diffuse_color[2], f.material_index][0]
if linebreaksinlists:
file.write(",\n")
file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
(fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
else:
file.write(", ")
file.write("<%d,%d,%d>, %d,%d,%d" % \
(fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
Maurice Raybaud
committed
file.write("\n")
tabWrite("}\n")
Maurice Raybaud
committed
# normal_indices indices
tabWrite("normal_indices {\n")
tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
tabStr = tab * tabLevel
for fi, fv in enumerate(faces_verts):
Maurice Raybaud
committed
if len(fv) == 4:
indices = (0, 1, 2), (0, 2, 3)
else:
indices = ((0, 1, 2),)
for i1, i2, i3 in indices:
if me_faces[fi].use_smooth:
if linebreaksinlists:
file.write(",\n")
file.write(tabStr + "<%d,%d,%d>" %\
(uniqueNormals[verts_normals[fv[i1]]][0],\
uniqueNormals[verts_normals[fv[i2]]][0],\
uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
else:
file.write(", ")
file.write("<%d,%d,%d>" %\
(uniqueNormals[verts_normals[fv[i1]]][0],\
uniqueNormals[verts_normals[fv[i2]]][0],\
uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
idx = uniqueNormals[faces_normals[fi]][0]
if linebreaksinlists:
file.write(",\n")
file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vertcount
else:
file.write(", ")
file.write("<%d,%d,%d>" % (idx, idx, idx)) # vert count
file.write("\n")
tabWrite("}\n")
if uv_layer:
tabWrite("uv_indices {\n")
tabWrite("%d" % (len(me_faces) + quadCount)) # faces count
tabStr = tab * tabLevel
for fi, fv in enumerate(faces_verts):
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
if len(fv) == 4:
indices = (0, 1, 2), (0, 2, 3)
else:
indices = ((0, 1, 2),)
uv = uv_layer[fi]
if len(faces_verts[fi]) == 4:
uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:], uv.uv[3][:]
else:
uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:]
for i1, i2, i3 in indices:
if linebreaksinlists:
file.write(",\n")
file.write(tabStr + "<%d,%d,%d>" % (
uniqueUVs[uvs[i1]][0],\
uniqueUVs[uvs[i2]][0],\
uniqueUVs[uvs[i3]][0]))
else:
file.write(", ")
file.write("<%d,%d,%d>" % (
uniqueUVs[uvs[i1]][0],\
uniqueUVs[uvs[i2]][0],\
uniqueUVs[uvs[i3]][0]))
file.write("\n")
tabWrite("}\n")
#XXX BOOLEAN
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
Maurice Raybaud
committed
if me.materials:
try:
material = me.materials[0] # dodgy
writeObjectMaterial(material, ob)
except IndexError:
print(me)
# POV object modifiers such as
# hollow / sturm / double_illuminate etc.
write_object_modifiers(scene,ob,file)
#Importance for radiosity sampling added here:
tabWrite("radiosity { \n")
tabWrite("importance %3g \n" % importance)
tabWrite("}\n")
tabWrite("}\n") # End of mesh block
bpy.data.meshes.remove(me)
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
if csg:
duplidata_ref = []
for ob in sel:
#matrix = global_matrix * ob.matrix_world
if ob.is_duplicator:
tabWrite("\n//--DupliObjects in %s--\n\n"% ob.name)
ob.dupli_list_create(scene)
dup = ""
if ob.is_modified(scene, 'RENDER'):
#modified object always unique so using object name rather than data name
dup = "#declare OB%s = union{\n" %(string_strip_hyphen(bpy.path.clean_name(ob.name)))
else:
dup = "#declare DATA%s = union{\n" %(string_strip_hyphen(bpy.path.clean_name(ob.name)))
for eachduplicate in ob.dupli_list:
duplidataname = "OB"+string_strip_hyphen(bpy.path.clean_name(bpy.data.objects[eachduplicate.object.name].data.name))
dup += ("\tobject {\n\t\tDATA%s\n\t\t%s\t}\n" %(string_strip_hyphen(bpy.path.clean_name(bpy.data.objects[eachduplicate.object.name].data.name)), MatrixAsPovString(ob.matrix_world.inverted() * eachduplicate.matrix)))
#add object to a list so that it is not rendered for some dupli_types
if ob.dupli_type not in {'GROUP'} and duplidataname not in duplidata_ref:
duplidata_ref.append(duplidataname) #older key [string_strip_hyphen(bpy.path.clean_name("OB"+ob.name))]
dup += "}\n"
ob.dupli_list_clear()
tabWrite(dup)
Maurice Raybaud
committed
else:
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
continue
print(duplidata_ref)
for data_name, inst in data_ref.items():
for ob_name, matrix_str in inst:
if ob_name not in duplidata_ref: #.items() for a dictionary
tabWrite("\n//----Blender Object Name:%s----\n" % ob_name)
if ob.pov.object_as == '':
tabWrite("object { \n")
tabWrite("%s\n" % data_name)
tabWrite("%s\n" % matrix_str)
tabWrite("}\n")
else:
no_boolean = True
for mod in ob.modifiers:
if mod.type == 'BOOLEAN':
operation = None
no_boolean = False
if mod.operation == 'INTERSECT':
operation = 'intersection'
else:
operation = mod.operation.lower()
mod_ob_name = string_strip_hyphen(bpy.path.clean_name(mod.object.name))
mod_matrix = global_matrix * mod.object.matrix_world
mod_ob_matrix = MatrixAsPovString(mod_matrix)
tabWrite("%s { \n"%operation)
tabWrite("object { \n")
tabWrite("%s\n" % data_name)
tabWrite("%s\n" % matrix_str)
tabWrite("}\n")
tabWrite("object { \n")
tabWrite("%s\n" % ('DATA'+ mod_ob_name))
tabWrite("%s\n" % mod_ob_matrix)
tabWrite("}\n")
tabWrite("}\n")
break
if no_boolean:
tabWrite("object { \n")
tabWrite("%s\n" % data_name)
tabWrite("%s\n" % matrix_str)
tabWrite("}\n")
Maurice Raybaud
committed
render = scene.render
matrix = global_matrix * camera.matrix_world
#############Maurice####################################
#These lines added to get sky gradient (visible with PNG output)
if world:
#For simple flat background:
if not world.use_sky_blend:
Bastien Montagne
committed
# Non fully transparent background could premultiply alpha and avoid anti-aliasing
# display issue:
if render.alpha_mode == 'TRANSPARENT':
Bastien Montagne
committed
tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" % \
(world.horizon_color[:]))
#Currently using no alpha with Sky option:
elif render.alpha_mode == 'SKY':
tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0>}\n" % (world.horizon_color[:]))
# XXX Does not exists anymore
#else:
#tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.horizon_color[:]))
for t in world.texture_slots: # risk to write several sky_spheres but maybe ok.
if t and t.texture.type is not None:
Bastien Montagne
committed
# XXX No enable checkbox for world textures yet (report it?)
#if t and t.texture.type == 'IMAGE' and t.use:
if t and t.texture.type == 'IMAGE':
if t.texture.image.filepath != image_filename:
t.texture.image.filepath = image_filename
if image_filename != "" and t.use_map_blend:
texturesBlend = image_filename
#colvalue = t.default_value
t_blend = t
Bastien Montagne
committed
Bastien Montagne
committed
# Commented below was an idea to make the Background image oriented as camera
# taken here:
#http://news.pov.org/pov.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.pov.org%3E/
Bastien Montagne
committed
# Replace 4/3 by the ratio of each image found by some custom or existing
# function
#mappingBlend = (" translate <%.4g,%.4g,%.4g> rotate z*degrees" \
# "(atan((camLocation - camLookAt).x/(camLocation - " \
# "camLookAt).y)) rotate x*degrees(atan((camLocation - " \
# "camLookAt).y/(camLocation - camLookAt).z)) rotate y*" \
# "degrees(atan((camLocation - camLookAt).z/(camLocation - " \
# "camLookAt).x)) scale <%.4g,%.4g,%.4g>b" % \
# (t_blend.offset.x / 10 , t_blend.offset.y / 10 ,
# t_blend.offset.z / 10, t_blend.scale.x ,
# t_blend.scale.y , t_blend.scale.z))
#using camera rotation valuesdirectly from blender seems much easier
if t_blend.texture_coords == 'ANGMAP':
mappingBlend = ""
Maurice Raybaud
committed
else:
# 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
# UV scale is 0.5,0.5 in blender and 0,0 in POV
# required for the sky_sphere not to repeat
mappingBlend = "scale 2 scale <%.4g,%.4g,%.4g> translate -1 " \
"translate <%.4g,%.4g,%.4g> rotate<0,0,0> " % \
(1.0 / t_blend.scale.y),
0.5-(0.5/t_blend.scale.x)- t_blend.offset.x,
0.5-(0.5/t_blend.scale.y)- t_blend.offset.y,
t_blend.offset.z)
Bastien Montagne
committed
# The initial position and rotation of the pov camera is probably creating
# the rotation offset should look into it someday but at least background
# won't rotate with the camera now.
# Putting the map on a plane would not introduce the skysphere distortion and
# allow for better image scale matching but also some waay to chose depth and
# size of the plane relative to camera.
tabWrite("sky_sphere {\n")
tabWrite("pigment {\n")
Bastien Montagne
committed
tabWrite("image_map{%s \"%s\" %s}\n" % \
(imageFormat(texturesBlend), texturesBlend, imgMapBG(t_blend)))
tabWrite("}\n")
tabWrite("%s\n" % (mappingBlend))
Bastien Montagne
committed
# The following layered pigment opacifies to black over the texture for
# transmit below 1 or otherwise adds to itself
Maurice Raybaud
committed
tabWrite("pigment {rgb 0 transmit %s}\n" % (t.texture.intensity))
tabWrite("}\n")
#tabWrite("scale 2\n")
#tabWrite("translate -1\n")
#For only Background gradient
if worldTexCount == 0:
tabWrite("sky_sphere {\n")
tabWrite("pigment {\n")
Bastien Montagne
committed
# maybe Should follow the advice of POV doc about replacing gradient
# for skysphere..5.5
tabWrite("gradient y\n")
tabWrite("color_map {\n")
# XXX Does not exists anymore
#if render.alpha_mode == 'STRAIGHT':
#tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.horizon_color[:]))
#tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.zenith_color[:]))
if render.alpha_mode == 'TRANSPARENT':
tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.horizon_color[:]))
Bastien Montagne
committed
# aa premult not solved with transmit 1
tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.zenith_color[:]))
tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.horizon_color[:]))
tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.zenith_color[:]))
tabWrite("}\n")
tabWrite("}\n")
tabWrite("}\n")
Bastien Montagne
committed
# Sky_sphere alpha (transmit) is not translating into image alpha the same
# way as 'background'
Maurice Raybaud
committed
#if world.light_settings.use_indirect_light:
Bastien Montagne
committed
# scene.pov.radio_enable=1
Bastien Montagne
committed
# Maybe change the above to a funtion copyInternalRenderer settings when
# user pushes a button, then:
#scene.pov.radio_enable = world.light_settings.use_indirect_light
# and other such translations but maybe this would not be allowed either?
###############################################################
tabWrite("fog {\n")
if mist.falloff=='LINEAR':
tabWrite("distance %.6f\n" % ((mist.start+mist.depth)*0.368))
elif mist.falloff=='QUADRATIC': # n**2 or squrt(n)?
tabWrite("distance %.6f\n" % ((mist.start+mist.depth)**2*0.368))
elif mist.falloff=='INVERSE_QUADRATIC': # n**2 or squrt(n)?
tabWrite("distance %.6f\n" % ((mist.start+mist.depth)**2*0.368))
Bastien Montagne
committed
tabWrite("color rgbt<%.3g, %.3g, %.3g, %.3g>\n" % \
(*world.horizon_color, 1.0 - mist.intensity))
#tabWrite("fog_offset %.6f\n" % mist.start) #create a pov property to prepend
#tabWrite("fog_alt %.6f\n" % mist.height) #XXX right?
#tabWrite("turbulence 0.2\n")
#tabWrite("turb_depth 0.3\n")
tabWrite("fog_type 1\n") #type2 for height
tabWrite("}\n")
Bastien Montagne
committed
if scene.pov.media_enable:
tabWrite("media {\n")
tabWrite("scattering { %d, rgb %.12f*<%.4g, %.4g, %.4g>\n" % \
(int(scene.pov.media_scattering_type),
(scene.pov.media_diffusion_scale),
*(scene.pov.media_diffusion_color[:])))
if scene.pov.media_scattering_type == '5':
tabWrite("eccentricity %.3g\n" % scene.pov.media_eccentricity)
tabWrite("}\n")
tabWrite("absorption %.12f*<%.4g, %.4g, %.4g>\n" % \
(scene.pov.media_absorption_scale,
*(scene.pov.media_absorption_color[:])))
tabWrite("\n")
Bastien Montagne
committed
tabWrite("samples %.d\n" % scene.pov.media_samples)
tabWrite("}\n")
tabWrite("global_settings {\n")
tabWrite("assumed_gamma 1.0\n")
Bastien Montagne
committed
tabWrite("max_trace_level %d\n" % scene.pov.max_trace_level)
Maurice Raybaud
committed
if scene.pov.charset != 'ascii':
file.write(" charset %s\n"%scene.pov.charset)
if scene.pov.global_settings_advanced:
if scene.pov.radio_enable == False:
Maurice Raybaud
committed
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(" 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)
Bastien Montagne
committed
if scene.pov.radio_enable:
tabWrite("radiosity {\n")
Bastien Montagne
committed
tabWrite("adc_bailout %.4g\n" % scene.pov.radio_adc_bailout)
tabWrite("brightness %.4g\n" % scene.pov.radio_brightness)
tabWrite("count %d\n" % scene.pov.radio_count)
tabWrite("error_bound %.4g\n" % scene.pov.radio_error_bound)
tabWrite("gray_threshold %.4g\n" % scene.pov.radio_gray_threshold)
tabWrite("low_error_factor %.4g\n" % scene.pov.radio_low_error_factor)
tabWrite("maximum_reuse %.4g\n" % scene.pov.radio_maximum_reuse)
Bastien Montagne
committed
tabWrite("minimum_reuse %.4g\n" % scene.pov.radio_minimum_reuse)
tabWrite("nearest_count %d\n" % scene.pov.radio_nearest_count)
tabWrite("pretrace_start %.3g\n" % scene.pov.radio_pretrace_start)
tabWrite("pretrace_end %.3g\n" % scene.pov.radio_pretrace_end)
tabWrite("recursion_limit %d\n" % scene.pov.radio_recursion_limit)
Maurice Raybaud
committed
tabWrite("always_sample %d\n" % scene.pov.radio_always_sample)
tabWrite("normal %d\n" % scene.pov.radio_normal)
tabWrite("media %d\n" % scene.pov.radio_media)
tabWrite("subsurface %d\n" % scene.pov.radio_subsurface)
tabWrite("}\n")
Bastien Montagne
committed
onceSss = 1
onceAmbient = 1
oncePhotons = 1
if material.subsurface_scattering.use and onceSss:
Bastien Montagne
committed
# In pov, the scale has reversed influence compared to blender. these number
# should correct that
tabWrite("mm_per_unit %.6f\n" % \
(material.subsurface_scattering.scale * 1000.0))
# 1000 rather than scale * (-100.0) + 15.0))
Bastien Montagne
committed
# In POV-Ray, the scale factor for all subsurface shaders needs to be the same
# formerly sslt_samples were multiplied by 100 instead of 10
sslt_samples = (11 - material.subsurface_scattering.error_threshold) * 10
tabWrite("subsurface { samples %d, %d }\n" % (sslt_samples, sslt_samples / 10))
Bastien Montagne
committed
onceSss = 0
Bastien Montagne
committed
if world and onceAmbient:
tabWrite("ambient_light rgb<%.3g, %.3g, %.3g>\n" % world.ambient_color[:])
Bastien Montagne
committed
onceAmbient = 0
Maurice Raybaud
committed
Maurice Raybaud
committed
if scene.pov.photon_enable:
if (oncePhotons and
(material.pov.refraction_type == "2" or
material.pov.photons_reflection == True)):
tabWrite("photons {\n")
tabWrite("spacing %.6f\n" % scene.pov.photon_spacing)
tabWrite("max_trace_level %d\n" % scene.pov.photon_max_trace_level)
tabWrite("adc_bailout %.3g\n" % scene.pov.photon_adc_bailout)
tabWrite("gather %d, %d\n" % (scene.pov.photon_gather_min,
scene.pov.photon_gather_max))
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)
tabWrite('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):
tabWrite('load_file "%s"\n'%fullFileName)
Maurice Raybaud
committed
tabWrite("}\n")
oncePhotons = 0
tabWrite("}\n")
Maurice Raybaud
committed
def exportCustomCode():
# Write CurrentAnimation Frame for use in Custom POV Code
file.write("#declare CURFRAMENUM = %d;\n" % bpy.context.scene.frame_current)
#Change path and uncomment to add an animated include file by hand:
file.write("//#include \"/home/user/directory/animation_include_file.inc\"\n")
Campbell Barton
committed
for txt in bpy.data.texts:
Maurice Raybaud
committed
if txt.pov.custom_code == 'both':
Campbell Barton
committed
# Why are the newlines needed?
file.write("\n")
file.write(txt.as_string())
file.write("\n")
Maurice Raybaud
committed
#sel = renderable_objects(scene) #removed for booleans
Bastien Montagne
committed
file.write("//----------------------------------------------\n" \
"//--Exported with POV-Ray exporter for Blender--\n" \
"//----------------------------------------------\n\n")
file.write("#version 3.7;\n")
file.write("\n//--Global settings--\n\n")
file.write("\n//--Custom Code--\n\n")
exportCustomCode()
if comments:
file.write("\n//--Patterns Definitions--\n\n")
LocalPatternNames = []
for texture in bpy.data.textures: #ok?
if texture.users > 0:
currentPatName = string_strip_hyphen(bpy.path.clean_name(texture.name))
#string_strip_hyphen(patternNames[texture.name]) #maybe instead of the above
#use above list to prevent writing texture instances several times and assign in mats?
Maurice Raybaud
committed
if (texture.type not in {'NONE', 'IMAGE'} and texture.pov.tex_pattern_type == 'emulator')or(texture.type in {'NONE', 'IMAGE'} and texture.pov.tex_pattern_type != 'emulator'):
Maurice Raybaud
committed
file.write("\n#declare PAT_%s = \n" % currentPatName)
file.write(shading.exportPattern(texture, string_strip_hyphen))
file.write("\n//--Background--\n\n")
file.write("\n//--Cameras--\n\n")
file.write("\n//--Lamps--\n\n")
for ob in bpy.data.objects:
if ob.type == 'MESH':
for mod in ob.modifiers:
if mod.type == 'BOOLEAN':
if mod.object not in csg_list:
csg_list.append(mod.object)
if csg_list != []:
csg = False
sel = no_renderable_objects(scene)
exportMeshes(scene, sel, csg)
csg = True
sel = renderable_objects(scene)
exportLamps([L for L in sel if (L.type == 'LAMP' and L.pov.object_as != 'RAINBOW')])
if comments:
file.write("\n//--Rainbows--\n\n")
exportRainbows([L for L in sel if (L.type == 'LAMP' and L.pov.object_as == 'RAINBOW')])
if comments:
file.write("\n//--Special Curves--\n\n")
for c in sel:
if c.is_modified(scene, 'RENDER'):
continue #don't export as pov curves objects with modifiers, but as mesh
elif c.type == 'CURVE' and (c.pov.curveshape in {'lathe','sphere_sweep','loft','birail'}):
file.write("\n//--Material Definitions--\n\n")
# write a default pigment for objects with no material (comment out to show black)
Maurice Raybaud
committed
file.write("#default{ pigment{ color srgb 0.8 }}\n")
# Convert all materials to strings we can access directly per vertex.
shading.writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, None) # default material
if material.pov.material_use_nodes:
ntree = material.node_tree
povMatName=string_strip_hyphen(bpy.path.clean_name(material.name))
if len(ntree.nodes)==0:
file.write('#declare %s = texture {%s}\n'%(povMatName,color))
else:
shading.write_nodes(scene,povMatName,ntree,file)
for node in ntree.nodes:
if node:
if node.bl_idname == "PovrayOutputNode":
if node.inputs["Texture"].is_linked:
for link in ntree.links:
if link.to_node.bl_idname == "PovrayOutputNode":
povMatName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
else:
file.write('#declare %s = texture {%s}\n'%(povMatName,color))
else:
shading.writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, material)
# attributes are all the variables needed by the other python file...
file.write("\n")
exportMeta([m for m in sel if m.type == 'META'])
file.write("//--Mesh objects--\n")
exportMeshes(scene, sel, csg)
#What follow used to happen here:
#exportCamera()
#exportWorld(scene.world)
#exportGlobalSettings(scene)
# MR:..and the order was important for implementing pov 3.7 baking
Bastien Montagne
committed
# (mesh camera) comment for the record
Constantin Rahn
committed
# CR: Baking should be a special case than. If "baking", than we could change the order.
#print("pov file closed %s" % file.closed)
#print("pov file closed %s" % file.closed)
def write_pov_ini(scene, filename_ini, filename_log, filename_pov, filename_image):
feature_set = bpy.context.user_preferences.addons[__package__].preferences.branch_feature_set_povray
using_uberpov = (feature_set=='uberpov')
#scene = bpy.data.scenes[0]
x = int(render.resolution_x * render.resolution_percentage * 0.01)
y = int(render.resolution_y * render.resolution_percentage * 0.01)
file.write("Version=3.7\n")
#write povray text stream to temporary file of same name with _log suffix
#file.write("All_File='%s'\n" % filename_log)
# DEBUG.OUT log if none specified:
file.write("All_File=1\n")
file.write("Input_File_Name='%s'\n" % filename_pov)
file.write("Output_File_Name='%s'\n" % filename_image)
file.write("Width=%d\n" % x)
file.write("Height=%d\n" % y)
# Border render.
if render.use_border:
file.write("Start_Column=%4g\n" % render.border_min_x)
file.write("End_Column=%4g\n" % (render.border_max_x))
file.write("Start_Row=%4g\n" % (1.0 - render.border_max_y))
file.write("End_Row=%4g\n" % (1.0 - render.border_min_y))
file.write("Bounding_Method=2\n") # The new automatic BSP is faster in most scenes
Bastien Montagne
committed
# Activated (turn this back off when better live exchange is done between the two programs
# (see next comment)
file.write("Display=1\n")
file.write("Pause_When_Done=0\n")
Bastien Montagne
committed
# PNG, with POV-Ray 3.7, can show background color with alpha. In the long run using the
# POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
file.write("Output_File_Type=N\n")
#file.write("Output_File_Type=T\n") # TGA, best progressive loading
file.write("Output_Alpha=1\n")
Bastien Montagne
committed
if scene.pov.antialias_enable:
# method 2 (recursive) with higher max subdiv forced because no mipmapping in POV-Ray
# needs higher sampling.
# aa_mapping = {"5": 2, "8": 3, "11": 4, "16": 5}
if using_uberpov:
method = {"0": 1, "1": 2, "2": 3}
else:
method = {"0": 1, "1": 2, "2": 2}
file.write("Antialias=on\n")
Bastien Montagne
committed
file.write("Antialias_Depth=%d\n" % scene.pov.antialias_depth)
file.write("Antialias_Threshold=%.3g\n" % scene.pov.antialias_threshold)
if using_uberpov and scene.pov.antialias_method == '2':
file.write("Sampling_Method=%s\n" % method[scene.pov.antialias_method])
file.write("Antialias_Confidence=%.3g\n" % scene.pov.antialias_confidence)
else:
file.write("Sampling_Method=%s\n" % method[scene.pov.antialias_method])
Bastien Montagne
committed
file.write("Antialias_Gamma=%.3g\n" % scene.pov.antialias_gamma)
if scene.pov.jitter_enable:
file.write("Jitter=on\n")
Bastien Montagne
committed
file.write("Jitter_Amount=%3g\n" % scene.pov.jitter_amount)
file.write("Jitter=off\n") # prevent animation flicker
file.write("Antialias=off\n")
#print("ini file closed %s" % file.closed)
#print("ini file closed %s" % file.closed)
bl_label = "Persitence Of Vision"
Campbell Barton
committed
@staticmethod
def _locate_binary():
addon_prefs = bpy.context.user_preferences.addons[__package__].preferences
# Use the system preference if its set.
pov_binary = addon_prefs.filepath_povray
if pov_binary:
if os.path.exists(pov_binary):
return pov_binary
else:
print("User Preferences path to povray %r NOT FOUND, checking $PATH" % pov_binary)
Campbell Barton
committed
# Windows Only
# assume if there is a 64bit binary that the user has a 64bit capable OS
if sys.platform[:3] == "win":
import winreg
win_reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
"Software\\POV-Ray\\v3.7\\Windows")
Campbell Barton
committed
win_home = winreg.QueryValueEx(win_reg_key, "Home")[0]
# First try 64bits UberPOV
pov_binary = os.path.join(win_home, "bin", "uberpov64.exe")
if os.path.exists(pov_binary):
return pov_binary
# Then try 64bits POV
Campbell Barton
committed
pov_binary = os.path.join(win_home, "bin", "pvengine64.exe")
if os.path.exists(pov_binary):
return pov_binary
# Then try 32bits UberPOV
pov_binary = os.path.join(win_home, "bin", "uberpov32.exe")
if os.path.exists(pov_binary):
# Then try 32bits POV
Campbell Barton
committed
pov_binary = os.path.join(win_home, "bin", "pvengine.exe")
if os.path.exists(pov_binary):
return pov_binary
# search the path all os's
pov_binary_default = "povray"
os_path_ls = os.getenv("PATH").split(':') + [""]
for dir_name in os_path_ls:
pov_binary = os.path.join(dir_name, pov_binary_default)
if os.path.exists(pov_binary):
return pov_binary
return ""
def _export(self, scene, povPath, renderImagePath):
Bastien Montagne
committed
if scene.pov.tempfiles_enable:
self._temp_file_in = tempfile.NamedTemporaryFile(suffix=".pov", delete=False).name
Bastien Montagne
committed
# PNG with POV 3.7, can show the background color with alpha. In the long run using the
# POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name
#self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name
self._temp_file_ini = tempfile.NamedTemporaryFile(suffix=".ini", delete=False).name
self._temp_file_log = os.path.join(tempfile.gettempdir(), "alltext.out")
else:
self._temp_file_in = povPath + ".pov"
Bastien Montagne
committed
# PNG with POV 3.7, can show the background color with alpha. In the long run using the
# POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
self._temp_file_out = renderImagePath + ".png"
#self._temp_file_out = renderImagePath + ".tga"
self._temp_file_ini = povPath + ".ini"
logPath = bpy.path.abspath(scene.pov.scene_path).replace('\\', '/')
self._temp_file_log = os.path.join(logPath, "alltext.out")
'''
self._temp_file_in = "/test.pov"
Bastien Montagne
committed
# PNG with POV 3.7, can show the background color with alpha. In the long run using the
# POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
self._temp_file_out = "/test.png"
#self._temp_file_out = "/test.tga"
self._temp_file_ini = "/test.ini"
'''
Maurice Raybaud
committed
if scene.pov.text_block == "":
def info_callback(txt):
self.update_stats("", "POV-Ray 3.7: " + txt)
Maurice Raybaud
committed
# os.makedirs(user_dir, exist_ok=True) # handled with previews
os.makedirs(preview_dir, exist_ok=True)
Maurice Raybaud
committed
write_pov(self._temp_file_in, scene, info_callback)
else:
pass
Constantin Rahn
committed
def _render(self, scene):
os.remove(self._temp_file_out) # so as not to load the old file
Campbell Barton
committed
pov_binary = PovrayRender._locate_binary()
if not pov_binary:
print("POV-Ray 3.7: could not execute povray, possibly POV-Ray isn't installed")
return False
write_pov_ini(scene, self._temp_file_ini, self._temp_file_log, self._temp_file_in, self._temp_file_out)
print ("***-STARTING-***")
Doug Hammond
committed
extra_args = []
Bastien Montagne
committed
if scene.pov.command_line_switches != "":
for newArg in scene.pov.command_line_switches.split(" "):
Constantin Rahn
committed
extra_args.append(newArg)
self._is_windows = False
self._is_windows = True
if"/EXIT" not in extra_args and not scene.pov.pov_editor:
extra_args.append("/EXIT")
Doug Hammond
committed
else:
Campbell Barton
committed
# added -d option to prevent render window popup which leads to segfault on linux
extra_args.append("-d")
Campbell Barton
committed
# Start Rendering!
try:
self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except OSError:
# TODO, report api
print("POV-Ray 3.7: could not execute '%s'" % pov_binary)
import traceback
traceback.print_exc()
print ("***-DONE-***")
return False
Campbell Barton
committed
else:
print("Engine ready!...")
Campbell Barton
committed
print("Command line arguments passed: " + str(extra_args))
return True
# Now that we have a valid process
def _cleanup(self):
for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
for i in range(5):
try:
os.unlink(f)
break
except OSError:
# Wait a bit before retrying file might be still in use by Blender,
# and Windows does not know how to delete a file in use!
time.sleep(self.DELAY)
for i in unpacked_images:
for c in range(5):
try:
os.unlink(i)
break
except OSError:
# Wait a bit before retrying file might be still in use by Blender,
# and Windows does not know how to delete a file in use!
time.sleep(self.DELAY)
x = int(r.resolution_x * r.resolution_percentage * 0.01)
y = int(r.resolution_y * r.resolution_percentage * 0.01)
Maurice Raybaud
committed
print("***INITIALIZING***")
# This makes some tests on the render, returning True if all goes good, and False if
# it was finished one way or the other.
# It also pauses the script (time.sleep())
def _test_wait():
time.sleep(self.DELAY)
# User interrupts the rendering
print("***POV INTERRUPTED***")
return False
Doug Hammond
committed
poll_result = self._process.poll()
# POV process is finisehd, one way or the other
if poll_result < 0:
print("***POV PROCESS FAILED : %s ***" % poll_result)
self.update_stats("", "POV-Ray 3.7: Failed")
return False