"git@code.it4i.cz:blender/blender-addons.git" did not exist on "d52ad87af7632d84fd5f96aa1392ece1e703974a"
Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
uniqueNormals[verts_normals[fv[i2]]][0],\
uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
else:
idx = uniqueNormals[faces_normals[fi]][0]
file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count
file.write('\n }\n')
if uv_layer:
file.write('\tuv_indices {\n')
file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
for fi, fv in enumerate(faces_verts):
if len(fv) == 4:
indicies = (0, 1, 2), (0, 2, 3)
else:
indicies = ((0, 1, 2),)
uv = uv_layer[fi]
if len(faces_verts[fi]) == 4:
uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4)
else:
uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3)
for i1, i2, i3 in indicies:
file.write(',\n\t\t<%d,%d,%d>' %\
(uniqueUVs[uvs[i1]][0],\
uniqueUVs[uvs[i2]][0],\
try:
material = me.materials[0] # dodgy
writeObjectMaterial(material)
except IndexError:
print(me)
file.write('%s\n' % ob.name) # Use named declaration to allow reference e.g. for baking. MR
bpy.data.meshes.remove(me)
def exportWorld(world):
render = scene.render
camera = scene.camera
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:
#Non fully transparent background could premultiply alpha and avoid anti-aliasing display issue:
if render.alpha_mode == 'PREMUL' or render.alpha_mode == 'PREMUL' :
file.write('background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n' % (tuple(world.horizon_color)))
#Currently using no alpha with Sky option:
elif render.alpha_mode == 'SKY':
file.write('background {rgbt<%.3g, %.3g, %.3g, 0>}\n' % (tuple(world.horizon_color)))
#StraightAlpha:
else:
file.write('background {rgbt<%.3g, %.3g, %.3g, 1>}\n' % (tuple(world.horizon_color)))
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
#For Background image textures
for t in world.texture_slots: #risk to write several sky_spheres but maybe ok.
if t and t.texture.type == 'IMAGE': #and t.use: #No enable checkbox for world textures yet (report it?)
image_filename = path_image(t.texture.image.filepath)
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
#commented below was an idea to make the Background image oriented as camera taken here: http://news.povray.org/povray.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.povray.org%3E/
#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))#replace 4/3 by the ratio of each image found by some custom or existing function
#using camera rotation valuesdirectly from blender seems much easier
mappingBlend = (" translate <%.4g-0.5,%.4g-0.5,%.4g-0.5> rotate<%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (t_blend.offset.x / 10 ,t_blend.offset.y / 10 ,t_blend.offset.z / 10, degrees(camera.rotation_euler[0]), degrees(camera.rotation_euler[1]), degrees(camera.rotation_euler[2]), t_blend.scale.x*0.85 , t_blend.scale.y*0.85 , t_blend.scale.z*0.85 ))
#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.
file.write('sky_sphere {\n')
file.write('\tpigment {\n')
file.write("\t\timage_map{%s \"%s\" %s}\n\t}\n\t%s\n" % (imageFormat(texturesBlend),texturesBlend,imgMapBG(t_blend),mappingBlend))
file.write('}\n')
#file.write('\t\tscale 2\n')
#file.write('\t\ttranslate -1\n')
#For only Background gradient
if not t:
if world.use_sky_blend:
file.write('sky_sphere {\n')
file.write('\tpigment {\n')
file.write('\t\tgradient z\n')#maybe Should follow the advice of POV doc about replacing gradient for skysphere..5.5
file.write('\t\tcolor_map {\n')
if render.alpha_mode == 'STRAIGHT':
file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n' % (tuple(world.horizon_color)))
file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n' % (tuple(world.zenith_color)))
elif render.alpha_mode == 'PREMUL':
file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n' % (tuple(world.horizon_color)))
file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n' % (tuple(world.zenith_color))) #aa premult not solved with transmit 1
file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n' % (tuple(world.horizon_color)))
file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n' % (tuple(world.zenith_color)))
file.write('\t\t}\n')
file.write('\t}\n')
file.write('}\n')
#sky_sphere alpha (transmit) is not translating into image alpha the same way as "background"
scene.pov_radio_enable=1
#Maybe change the above to scene.pov_radio_enable = world.light_settings.use_indirect_light ?
###############################################################
if mist.use_mist:
file.write('fog {\n')
file.write('\tdistance %.6f\n' % mist.depth)
file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1 - mist.intensity,)))
#file.write('\tfog_offset %.6f\n' % mist.start)
#file.write('\tfog_alt 5\n')
#file.write('\tturbulence 0.2\n')
#file.write('\tturb_depth 0.3\n')
file.write('\tfog_type 1\n')
file.write('}\n')
def exportGlobalSettings(scene):
file.write('global_settings {\n')
if scene.pov_radio_enable:
file.write('\tradiosity {\n')
file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout)
file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample)
file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness)
file.write("\t\tcount %d\n" % scene.pov_radio_count)
file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound)
file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold)
file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor)
file.write("\t\tmedia %d\n" % scene.pov_radio_media)
file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse)
file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count)
file.write("\t\tnormal %d\n" % scene.pov_radio_normal)
file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
file.write('\t}\n')
once=1
for material in bpy.data.materials:
if material.subsurface_scattering.use and once:
file.write("\tmm_per_unit %.6f\n" % (material.subsurface_scattering.scale * (-100) + 15))#In pov, the scale has reversed influence compared to blender. these number should correct that
once=0 #In povray, the scale factor for all subsurface shaders needs to be the same
file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color))
if material.pov_photons_refraction or material.pov_photons_reflection:
file.write("\tphotons {\n")
file.write("\t\tspacing 0.003\n")
file.write("\t\tmax_trace_level 4\n")
file.write("\t\tadc_bailout 0.1\n")
file.write("\t\tgather 30, 150\n")
file.write("\t}\n")
file.write('}\n')
# Convert all materials to strings we can access directly per vertex.
writeMaterial(None) # default material
for material in bpy.data.materials:
writeMaterial(material)
exportLamps([l for l in sel if l.type == 'LAMP'])
exportMeta([l for l in sel if l.type == 'META'])
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
exportWorld(scene.world)
exportGlobalSettings(scene)
file.close()
def write_pov_ini(filename_ini, filename_pov, filename_image):
scene = bpy.data.scenes[0]
render = scene.render
x = int(render.resolution_x * render.resolution_percentage * 0.01)
y = int(render.resolution_y * render.resolution_percentage * 0.01)
file = open(filename_ini, 'w')
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)
# Needed for border render.
'''
file.write('Start_Column=%d\n' % part.x)
file.write('End_Column=%d\n' % (part.x+part.w))
file.write('Start_Row=%d\n' % (part.y))
file.write('End_Row=%d\n' % (part.y+part.h))
'''
file.write('Bounding_method=2\n')#The new automatic BSP is faster in most scenes
file.write('Display=1\n')#Activated (turn this back off when better live exchange is done between the two programs (see next comment)
file.write('Output_File_Type=N\n') # PNG, with POV 3.7, can show background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#file.write('Output_File_Type=T\n') # TGA, best progressive loading
aa_mapping = {'5': 2, '8': 3, '11': 4, '16': 5} # method 2 (recursive) with higher max subdiv forced because no mipmapping in povray needs higher sampling.
file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples])
file.write('Antialias_Threshold=0.1\n')#rather high settings but necessary.
file.write('Jitter=off\n')#prevent animation flicker
else:
file.write('Antialias=0\n')
file.close()
class PovrayRender(bpy.types.RenderEngine):
DELAY = 0.02
def _export(self, scene):
import tempfile
self._temp_file_in = tempfile.mktemp(suffix='.pov')
self._temp_file_out = tempfile.mktemp(suffix='.png')#PNG with POV 3.7, can show the background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#self._temp_file_out = tempfile.mktemp(suffix='.tga')
self._temp_file_ini = tempfile.mktemp(suffix='.ini')
'''
self._temp_file_in = '/test.pov'
self._temp_file_out = '/test.png'#PNG with POV 3.7, can show the background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#self._temp_file_out = '/test.tga'
self._temp_file_ini = '/test.ini'
'''
def info_callback(txt):
write_pov(self._temp_file_in, scene, info_callback)
def _render(self):
try:
os.remove(self._temp_file_out) # so as not to load the old file
except: #OSError: #was that the proper error type?
pass
write_pov_ini(self._temp_file_ini, self._temp_file_in, self._temp_file_out)
print ("***-STARTING-***")
pov_binary = "povray"
if sys.platform == 'win32':
import winreg
regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.7\\Windows')
if bitness == 64:
pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64'
else:
pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine'
if 1:
# TODO, when povray isnt found this gives a cryptic error, would be nice to be able to detect if it exists
try:
self._process = subprocess.Popen([pov_binary, self._temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
except OSError:
# TODO, report api
print("POVRAY 3.7: could not execute '%s', possibly povray isn't installed" % pov_binary)
import traceback
traceback.print_exc()
print ("***-DONE-***")
return False
else:
# This works too but means we have to wait until its done
os.system('%s %s' % (pov_binary, self._temp_file_ini))
print ("***-DONE-***")
return True
def _cleanup(self):
for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
try:
os.remove(f)
except OSError: #was that the proper error type?
pass
self.update_stats("", "")
def render(self, scene):
self.update_stats("", "POVRAY 3.7: Exporting data from Blender")
##WIP output format
## if r.file_format == 'OPENEXR':
## fformat = 'EXR'
## render.color_mode = 'RGBA'
## else:
## fformat = 'TGA'
## r.file_format = 'TARGA'
## r.color_mode = 'RGBA'
# compute resolution
x = int(r.resolution_x * r.resolution_percentage * 0.01)
y = int(r.resolution_y * r.resolution_percentage * 0.01)
# Wait for the file to be created
while not os.path.exists(self._temp_file_out):
if self.test_break():
try:
self._process.terminate()
except: #OSError: #was that the proper error type?
pass
break
if self._process.poll() != None:
break
time.sleep(self.DELAY)
if os.path.exists(self._temp_file_out):
prev_size = -1
def update_image():
result = self.begin_result(0, 0, x, y)
lay = result.layers[0]
# possible the image wont load early on.
try:
lay.load_from_file(self._temp_file_out)
except: #OSError: #was that the proper error type?
pass
self.end_result(result)
# Update while povray renders
while True:
# test if povray exists
if self._process.poll() is not None:
update_image()
break
# user exit
if self.test_break():
try:
self._process.terminate()
except: #OSError: #was that the proper error type?
pass
break
# Would be nice to redirect the output
# stdout_value, stderr_value = self._process.communicate() # locks
# check if the file updated
new_size = os.path.getsize(self._temp_file_out)
if new_size != prev_size:
update_image()
prev_size = new_size
time.sleep(self.DELAY)
self._cleanup()