Newer
Older
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?
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?
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 == 'LIGHT' and L.pov.object_as != 'RAINBOW')]
)
if comments:
file.write("\n//--Rainbows--\n\n")
exportRainbows(
[L for L in sel if (L.type == 'LIGHT' 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'}
):
exportCurves(scene, c)
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.
# exportMaterials()
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)
)
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
)
file.write(
'#declare %s = texture {%s}\n'
% (povMatName, color)
)
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")
#tbefore = time.time()
exportMeshes(scene, sel, csg)
#totime = time.time() - tbefore
#print("exportMeshes took" + str(totime))
# 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.preferences.addons[
__package__
].preferences.branch_feature_set_povray
using_uberpov = feature_set == 'uberpov'
# scene = bpy.data.scenes[0]
scene = bpy.context.scene
x = int(render.resolution_x * render.resolution_percentage * 0.01)
y = int(render.resolution_y * render.resolution_percentage * 0.01)
file.write("Version=3.8\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
)
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"
bl_use_shading_nodes_custom = False
Campbell Barton
committed
@staticmethod
def _locate_binary():
addon_prefs = bpy.context.preferences.addons[__package__].preferences
Campbell Barton
committed
# 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, depsgraph, povPath, renderImagePath):
"""gather all necessary output files paths user defined and auto generated and export there"""
scene = bpy.context.scene
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"
'''
if scene.pov.text_block == "":
Maurice Raybaud
committed
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
def _render(self, depsgraph):
"""Export necessary files and render image."""
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"
)
Campbell Barton
committed
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,
)
Campbell Barton
committed
except OSError:
# TODO, report api
print("POV-Ray 3.7: could not execute '%s'" % pov_binary)
import traceback
Campbell Barton
committed
traceback.print_exc()
print("***-DONE-***")
Campbell Barton
committed
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
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)
def render(self, depsgraph):
"""Export necessary files from text editor and render image."""
scene = bpy.context.scene
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
return True
if bpy.context.scene.pov.text_block != "":
Maurice Raybaud
committed
if scene.pov.tempfiles_enable:
self._temp_file_in = tempfile.NamedTemporaryFile(
suffix=".pov", delete=False
).name
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"
)
Maurice Raybaud
committed
else:
povPath = scene.pov.text_block
renderImagePath = os.path.splitext(povPath)[0]
self._temp_file_out = os.path.join(preview_dir, renderImagePath)
Maurice Raybaud
committed
self._temp_file_in = os.path.join(preview_dir, povPath)
self._temp_file_ini = os.path.join(
preview_dir,
(os.path.splitext(self._temp_file_in)[0] + ".INI"),
)
Maurice Raybaud
committed
self._temp_file_log = os.path.join(preview_dir, "alltext.out")
Maurice Raybaud
committed
Maurice Raybaud
committed
'''
try:
os.remove(self._temp_file_in) # so as not to load the old file
except OSError:
pass
Maurice Raybaud
committed
print(scene.pov.text_block)
text = bpy.data.texts[scene.pov.text_block]
file = open("%s" % self._temp_file_in, "w")
Maurice Raybaud
committed
# Why are the newlines needed?
file.write("\n")
file.write(text.as_string())
Maurice Raybaud
committed
file.close()
# has to be called to update the frame on exporting animations
scene.frame_set(scene.frame_current)
Maurice Raybaud
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"
)
Maurice Raybaud
committed
return False
Maurice Raybaud
committed
# start ini UI options export
self.update_stats(
"", "POV-Ray 3.7: Exporting ini options from Blender"
)
Maurice Raybaud
committed
write_pov_ini(
scene,
self._temp_file_ini,
self._temp_file_log,
self._temp_file_in,
self._temp_file_out,
)
Maurice Raybaud
committed
print("***-STARTING-***")
Maurice Raybaud
committed
extra_args = []
Maurice Raybaud
committed
if scene.pov.command_line_switches != "":
for newArg in scene.pov.command_line_switches.split(" "):
extra_args.append(newArg)
if sys.platform[:3] == "win":
if "/EXIT" not in extra_args and not scene.pov.pov_editor:
Maurice Raybaud
committed
extra_args.append("/EXIT")
else:
Maurice Raybaud
committed
# added -d option to prevent render window popup which leads to segfault on linux
extra_args.append("-d")
# Start Rendering!
try:
if (
sys.platform[:3] != "win" and scene.pov.sdl_window_enable
): # segfault on linux == False !!!
env = {'POV_DISPLAY_SCALED': 'off'}
env.update(os.environ)
self._process = subprocess.Popen(
[pov_binary, self._temp_file_ini],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env,
)
self._process = subprocess.Popen(
[pov_binary, self._temp_file_ini] + extra_args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
Maurice Raybaud
committed
except OSError:
# TODO, report api
print("POV-Ray 3.7: could not execute '%s'" % pov_binary)
import traceback
Maurice Raybaud
committed
traceback.print_exc()
print("***-DONE-***")
Maurice Raybaud
committed
return False
else:
print("Engine ready!...")
print("Command line arguments passed: " + str(extra_args))
self.update_stats("", "POV-Ray 3.7: Parsing File")
Maurice Raybaud
committed
# Indented in main function now so repeated here but still not working
Maurice Raybaud
committed
# to bring back render result to its buffer
Maurice Raybaud
committed
if os.path.exists(self._temp_file_out):
xmin = int(r.border_min_x * x)
ymin = int(r.border_min_y * y)
xmax = int(r.border_max_x * x)
ymax = int(r.border_max_y * y)
Maurice Raybaud
committed
lay = result.layers[0]
Maurice Raybaud
committed
time.sleep(self.DELAY)
try:
lay.load_from_file(self._temp_file_out)
except RuntimeError:
print("***POV ERROR WHILE READING OUTPUT FILE***")
self.end_result(result)
# print(self._temp_file_log) #bring the pov log to blender console with proper path?
with open(
self._temp_file_log
) as f: # The with keyword automatically closes the file when you are done
Maurice Raybaud
committed
self.update_stats("", "")
Maurice Raybaud
committed
Maurice Raybaud
committed
if scene.pov.tempfiles_enable or scene.pov.deletefiles_enable:
Maurice Raybaud
committed
else:
##WIP output format
## if r.image_settings.file_format == 'OPENEXR':
## fformat = 'EXR'
## render.image_settings.color_mode = 'RGBA'
## else:
## fformat = 'TGA'
## r.image_settings.file_format = 'TARGA'
## r.image_settings.color_mode = 'RGBA'
blendSceneName = bpy.data.filepath.split(os.path.sep)[-1].split(
"."
)[0]
Maurice Raybaud
committed
povSceneName = ""
povPath = ""
renderImagePath = ""
# has to be called to update the frame on exporting animations
scene.frame_set(scene.frame_current)
if not scene.pov.tempfiles_enable:
# check paths
povPath = bpy.path.abspath(scene.pov.scene_path).replace(
'\\', '/'
)
Maurice Raybaud
committed
if povPath == "":
if bpy.data.is_saved:
povPath = bpy.path.abspath("//")
else:
Maurice Raybaud
committed
povPath = tempfile.gettempdir()
elif povPath.endswith("/"):
if povPath == "/":
povPath = bpy.path.abspath("//")
else:
povPath = bpy.path.abspath(scene.pov.scene_path)
if not os.path.exists(povPath):
try:
os.makedirs(povPath)
except:
import traceback
Maurice Raybaud
committed
traceback.print_exc()
print(
"POV-Ray 3.7: Cannot create scenes directory: %r"
% povPath
)
self.update_stats(
"",
"POV-Ray 3.7: Cannot create scenes directory %r"
% povPath,
)
Maurice Raybaud
committed
time.sleep(2.0)
Maurice Raybaud
committed
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
'''
# Bug in POV-Ray RC3
renderImagePath = bpy.path.abspath(scene.pov.renderimage_path).replace('\\','/')
if renderImagePath == "":
if bpy.data.is_saved:
renderImagePath = bpy.path.abspath("//")
else:
renderImagePath = tempfile.gettempdir()
#print("Path: " + renderImagePath)
elif path.endswith("/"):
if renderImagePath == "/":
renderImagePath = bpy.path.abspath("//")
else:
renderImagePath = bpy.path.abspath(scene.pov.renderimage_path)
if not os.path.exists(path):
print("POV-Ray 3.7: Cannot find render image directory")
self.update_stats("", "POV-Ray 3.7: Cannot find render image directory")
time.sleep(2.0)
return
'''
# check name
if scene.pov.scene_name == "":
if blendSceneName != "":
povSceneName = blendSceneName
else:
povSceneName = "untitled"
else:
povSceneName = scene.pov.scene_name
if os.path.isfile(povSceneName):
povSceneName = os.path.basename(povSceneName)
povSceneName = povSceneName.split('/')[-1].split('\\')[-1]
if not povSceneName:
print("POV-Ray 3.7: Invalid scene name")
self.update_stats("", "POV-Ray 3.7: Invalid scene name")
time.sleep(2.0)
Maurice Raybaud
committed
povSceneName = os.path.splitext(povSceneName)[0]
print("Scene name: " + povSceneName)
print("Export path: " + povPath)
povPath = os.path.join(povPath, povSceneName)
povPath = os.path.realpath(povPath)
# for now this has to be the same like the pov output. Bug in POV-Ray RC3.
# renderImagePath = renderImagePath + "\\" + povSceneName
renderImagePath = povPath # Bugfix for POV-Ray RC3 bug
# renderImagePath = os.path.realpath(renderImagePath) # Bugfix for POV-Ray RC3 bug
# print("Export path: %s" % povPath)
# print("Render Image path: %s" % renderImagePath)
Maurice Raybaud
committed
# start export
self.update_stats("", "POV-Ray 3.7: Exporting data from Blender")
self._export(depsgraph, povPath, renderImagePath)
Maurice Raybaud
committed
self.update_stats("", "POV-Ray 3.7: Parsing File")
if not self._render(depsgraph):
Maurice Raybaud
committed
self.update_stats("", "POV-Ray 3.7: Not found")
Maurice Raybaud
committed
Maurice Raybaud
committed
# compute resolution
# x = int(r.resolution_x * r.resolution_percentage * 0.01)
# y = int(r.resolution_y * r.resolution_percentage * 0.01)
Maurice Raybaud
committed
# Wait for the file to be created
# XXX This is no more valid, as 3.7 always creates output file once render is finished!
parsing = re.compile(br"= \[Parsing\.\.\.\] =")
rendering = re.compile(br"= \[Rendering\.\.\.\] =")
percent = re.compile(r"\(([0-9]{1,3})%\)")
# print("***POV WAITING FOR FILE***")
data = b""
last_line = ""
while _test_wait():
Maurice Raybaud
committed
# POV in Windows did not output its stdout/stderr, it displayed them in its GUI
# But now writes file
Maurice Raybaud
committed
if self._is_windows:
self.update_stats("", "POV-Ray 3.7: Rendering File")
else:
t_data = self._process.stdout.read(10000)
if not t_data:
continue
Maurice Raybaud
committed
data += t_data
# XXX This is working for UNIX, not sure whether it might need adjustments for
# other OSs
# First replace is for windows
t_data = (
str(t_data)
.replace('\\r\\n', '\\n')
.replace('\\r', '\r')
)
Maurice Raybaud
committed
lines = t_data.split('\\n')
last_line += lines[0]
lines[0] = last_line
print('\n'.join(lines), end="")
last_line = lines[-1]
if rendering.search(data):
_pov_rendering = True
match = percent.findall(str(data))
if match:
self.update_stats(
"",
"POV-Ray 3.7: Rendering File (%s%%)"
% match[-1],
)
Maurice Raybaud
committed
else:
self.update_stats("", "POV-Ray 3.7: Rendering File")
Maurice Raybaud
committed
elif parsing.search(data):
self.update_stats("", "POV-Ray 3.7: Parsing File")
Maurice Raybaud
committed
if os.path.exists(self._temp_file_out):
# print("***POV FILE OK***")
# self.update_stats("", "POV-Ray 3.7: Rendering")
Maurice Raybaud
committed
# prev_size = -1
Maurice Raybaud
committed
xmin = int(r.border_min_x * x)
ymin = int(r.border_min_y * y)
xmax = int(r.border_max_x * x)
ymax = int(r.border_max_y * y)
Maurice Raybaud
committed
# print("***POV UPDATING IMAGE***")
result = self.begin_result(0, 0, x, y)
Bastien Montagne
committed
# XXX, tests for border render.
# result = self.begin_result(xmin, ymin, xmax - xmin, ymax - ymin)
# result = self.begin_result(0, 0, xmax - xmin, ymax - ymin)
Maurice Raybaud
committed
lay = result.layers[0]
Maurice Raybaud
committed
# This assumes the file has been fully written We wait a bit, just in case!
time.sleep(self.DELAY)
Campbell Barton
committed
try:
lay.load_from_file(self._temp_file_out)
# XXX, tests for border render.
# lay.load_from_file(self._temp_file_out, xmin, ymin)
Campbell Barton
committed
except RuntimeError:
Maurice Raybaud
committed
print("***POV ERROR WHILE READING OUTPUT FILE***")
Campbell Barton
committed
Maurice Raybaud
committed
# Not needed right now, might only be useful if we find a way to use temp raw output of
# pov 3.7 (in which case it might go under _test_wait()).
'''
def update_image():
# possible the image wont load early on.
Campbell Barton
committed
try:
Maurice Raybaud
committed
lay.load_from_file(self._temp_file_out)
# XXX, tests for border render.
#lay.load_from_file(self._temp_file_out, xmin, ymin)
#lay.load_from_file(self._temp_file_out, xmin, ymin)
except RuntimeError:
Campbell Barton
committed
pass
Maurice Raybaud
committed
# Update while POV-Ray renders
while True:
# print("***POV RENDER LOOP***")
Campbell Barton
committed
Maurice Raybaud
committed
# test if POV-Ray exists
if self._process.poll() is not None:
print("***POV PROCESS FINISHED***")
update_image()
break
Campbell Barton
committed
Maurice Raybaud
committed
# user exit
if self.test_break():
try:
self._process.terminate()
print("***POV PROCESS INTERRUPTED***")
except OSError:
pass
Campbell Barton
committed
Maurice Raybaud
committed
break
Campbell Barton
committed
Maurice Raybaud
committed
# Would be nice to redirect the output
# stdout_value, stderr_value = self._process.communicate() # locks
Maurice Raybaud
committed
# check if the file updated
new_size = os.path.getsize(self._temp_file_out)
Maurice Raybaud
committed
if new_size != prev_size:
update_image()
prev_size = new_size
Maurice Raybaud
committed
time.sleep(self.DELAY)
'''
Maurice Raybaud
committed
self.end_result(result)
Maurice Raybaud
committed
else:
print("***POV FILE NOT FOUND***")
print("***POV FILE FINISHED***")
# print(filename_log) #bring the pov log to blender console with proper path?
with open(
self._temp_file_log,
encoding='utf-8'
) as f: # The with keyword automatically closes the file when you are done
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
msg = f.read()
#if isinstance(msg, str):
#stdmsg = msg
#decoded = False
#else:
#if type(msg) == bytes:
#stdmsg = msg.split('\n')
#stdmsg = msg.encode('utf-8', "replace")
#stdmsg = msg.encode("utf-8", "replace")
#stdmsg = msg.decode(encoding)
#decoded = True
#msg.encode('utf-8').decode('utf-8')
print(msg)
# Also print to the interactive console used in POV centric workspace
# To do: get a grip on new line encoding
# and make this a function to be used elsewhere
for win in bpy.context.window_manager.windows:
if win.screen != None:
scr = win.screen
for area in scr.areas:
if area.type == 'CONSOLE':
#context override
#ctx = {'window': win, 'screen': scr, 'area':area}#bpy.context.copy()
ctx = {}
ctx['area'] = area
ctx['region'] = area.regions[-1]
ctx['space_data'] = area.spaces.active
ctx['screen'] = scr#C.screen
ctx['window'] = win
#bpy.ops.console.banner(ctx, text = "Hello world")
bpy.ops.console.clear_line(ctx)
stdmsg = msg.split('\n') #XXX todo , test and see
for i in stdmsg:
bpy.ops.console.insert(ctx, text = i)
Maurice Raybaud
committed
self.update_stats("", "")
if scene.pov.tempfiles_enable or scene.pov.deletefiles_enable:
self._cleanup()
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
sound_on = bpy.context.preferences.addons[
__package__
].preferences.use_sounds
if sys.platform[:3] == "win" and sound_on:
# Could not find tts Windows command so playing beeps instead :-)
# "Korobeiniki"(Коробе́йники)
# aka "A-Type" Tetris theme
import winsound
winsound.Beep(494,250) #B
winsound.Beep(370,125) #F
winsound.Beep(392,125) #G
winsound.Beep(440,250) #A
winsound.Beep(392,125) #G
winsound.Beep(370,125) #F#
winsound.Beep(330,275) #E
winsound.Beep(330,125) #E
winsound.Beep(392,125) #G
winsound.Beep(494,275) #B
winsound.Beep(440,125) #A
winsound.Beep(392,125) #G
winsound.Beep(370,275) #F
winsound.Beep(370,125) #F
winsound.Beep(392,125) #G
winsound.Beep(440,250) #A
winsound.Beep(494,250) #B
winsound.Beep(392,250) #G
winsound.Beep(330,350) #E
time.sleep(0.5)
winsound.Beep(440,250) #A
winsound.Beep(440,150) #A
winsound.Beep(523,125) #D8
winsound.Beep(659,250) #E8
winsound.Beep(587,125) #D8
winsound.Beep(523,125) #C8
winsound.Beep(494,250) #B
winsound.Beep(494,125) #B
winsound.Beep(392,125) #G
winsound.Beep(494,250) #B
winsound.Beep(440,150) #A
winsound.Beep(392,125) #G
winsound.Beep(370,250) #F#
winsound.Beep(370,125) #F#
winsound.Beep(392,125) #G
winsound.Beep(440,250) #A
winsound.Beep(494,250) #B
winsound.Beep(392,250) #G
winsound.Beep(330,300) #E
#Does Linux support say command?
elif sys.platform[:3] != "win" :
finished_render_message = "\'Render completed\'"
# We don't want the say command to block Python,
# so we add an ampersand after the message
os.system("say %s &" % (finished_render_message))
##################################################################################
#################################Operators########################################
##################################################################################
class RenderPovTexturePreview(Operator):
"""Export only files necessary to texture preview and render image."""
bl_idname = "tex.preview_update"
bl_label = "Update preview"
def execute(self, context):
tex = (
bpy.context.object.active_material.active_texture
) # context.texture
texPrevName = (
string_strip_hyphen(bpy.path.clean_name(tex.name)) + "_prev"