[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55239] trunk/lib/tests: Cycles test rendering script:
Brecht Van Lommel
brechtvanlommel at pandora.be
Wed Mar 13 15:29:20 CET 2013
Revision: 55239
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55239
Author: blendix
Date: 2013-03-13 14:29:20 +0000 (Wed, 13 Mar 2013)
Log Message:
-----------
Cycles test rendering script:
* Make it work for non-cycles files too. I haven't committed the reference
renders for those since the files could use some work to render with a
proper camera viewpoint and actually testing the functionality, but it's
easy to copy the .png files to compare between two versions (already found
some regressions since 2.66).
* Modify some .blend files to add a camera, avoiding errors when rendering.
* The test scripts and reference renders are now in auto/ rather than
rendering/cycles, and the cycles .blend files have been moved to a cycles/
folder in the top directory.
Modified Paths:
--------------
trunk/lib/tests/animation/CtrlObject.blend
trunk/lib/tests/animation/IK_pole_target.blend
trunk/lib/tests/animation/chinchilla_mdef.blend
trunk/lib/tests/animation/pydrivers_flap.blend
trunk/lib/tests/particles_and_hair/particle_children_hair.blend
trunk/lib/tests/particles_and_hair/particle_extras_effector.blend
trunk/lib/tests/physics/continue_physics.blend
trunk/lib/tests/physics/softbody_basics.blend
Added Paths:
-----------
trunk/lib/tests/auto/
trunk/lib/tests/auto/readme.txt
trunk/lib/tests/auto/reference_renders/
trunk/lib/tests/auto/render_test_files.py
trunk/lib/tests/auto/test_config.py
trunk/lib/tests/auto/test_run.py
trunk/lib/tests/auto/test_utils.py
trunk/lib/tests/cycles/
Removed Paths:
-------------
trunk/lib/tests/rendering/cycles/
Modified: trunk/lib/tests/animation/CtrlObject.blend
===================================================================
(Binary files differ)
Modified: trunk/lib/tests/animation/IK_pole_target.blend
===================================================================
(Binary files differ)
Modified: trunk/lib/tests/animation/chinchilla_mdef.blend
===================================================================
(Binary files differ)
Modified: trunk/lib/tests/animation/pydrivers_flap.blend
===================================================================
(Binary files differ)
Copied: trunk/lib/tests/auto/readme.txt (from rev 55220, trunk/lib/tests/rendering/cycles/readme.txt)
===================================================================
--- trunk/lib/tests/auto/readme.txt (rev 0)
+++ trunk/lib/tests/auto/readme.txt 2013-03-13 14:29:20 UTC (rev 55239)
@@ -0,0 +1,36 @@
+Auto Render Regression suite
+==================================
+
+Running
+==================================
+
+./blender -b -P /path/to/tests/auto/render_test_files.py
+
+If desired the blender executable path can be set in test_config.py to
+run the script outside of Blender with:
+
+python render_test_files.py
+
+Results
+==================================
+
+It saves all renders and additional info into tests/auto/test_renders
+The reference renders are in tests/auto/reference_renders
+
+Comparisons
+==================================
+
+Manual comparison is possible, easier is to use automatic comparsion with
+OpenImageIO installed. If it's in PATH then it will be found automatically,
+otherwise the path can be set in test_config.py.
+
+For comparing two Blender versions, you can run the tests with old version,
+copy the .png files from test_renders to reference_renders and then run the
+tests with the newer version.
+
+Notes
+==================================
+
+* test_run.py is executed for each .blend file.
+* The script renders every cycles file twice on the CPU (SVM and OSL).
+
Copied: trunk/lib/tests/auto/render_test_files.py (from rev 55220, trunk/lib/tests/rendering/cycles/render_test_files.py)
===================================================================
--- trunk/lib/tests/auto/render_test_files.py (rev 0)
+++ trunk/lib/tests/auto/render_test_files.py 2013-03-13 14:29:20 UTC (rev 55239)
@@ -0,0 +1,175 @@
+# Run auto regression files
+import os
+import select
+import shutil
+import subprocess
+import sys
+
+# Find executables and files
+def find_test_directory():
+ test_directory = ""
+
+ if "__file__" in globals():
+ test_directory = os.path.dirname(__file__)
+ sys.path.append(test_directory)
+
+ return test_directory
+
+def find_idiff(idiff_path):
+ if not idiff_path:
+ if shutil.which("idiff"):
+ idiff_path = "idiff"
+
+ return idiff_path
+
+def find_blender(blender_executable):
+ if not blender_executable:
+ if os.path.split(sys.executable)[1] == "blender":
+ blender_executable = sys.executable
+ print("")
+
+ return blender_executable
+
+def find_test_files(directory, search_items, extension):
+ files = []
+
+ for item in search_items:
+ item_path = os.path.join(directory, item)
+
+ if os.path.isdir(item_path):
+ # find all .blend files in directory
+ for filename in os.listdir(item_path):
+ name, ext = os.path.splitext(filename)
+ if ext == extension:
+ files += [(name, os.path.join(item, filename))]
+ else:
+ # single .blend
+ name = os.path.splitext(os.path.basename(item))[0]
+ files += [(name, item)]
+
+ return files
+
+def render_variations(blend_file):
+ if blend_file.find("cycles") == -1:
+ return ("",)
+ else:
+ return ("_svm", "_osl")
+
+# Execute command while printing and logging it
+def execute_command(command, logfile):
+ logdir = os.path.dirname(logfile)
+ if not os.path.exists(logdir):
+ os.makedirs(logdir)
+
+ log = open(str(logfile), "w")
+ log.write(command + "\n\n")
+
+ p = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ maxlen = 10
+ columns = shutil.get_terminal_size().columns
+
+ while True:
+ reads = [p.stdout.fileno(), p.stderr.fileno()]
+ ret = select.select(reads, [], [])
+
+ for fd in ret[0]:
+ for std in (p.stdout, p.stderr):
+ if fd == std.fileno():
+ read = std.readline().decode('utf8').rstrip()
+ log.write(read + "\n")
+
+ # get last part, and no multiline because it breaks \r
+ read = read.split('|')[-1].strip()
+ if len(read) > columns:
+ read = read[:columns]
+
+ maxlen = max(len(read), maxlen)
+ sys.stdout.write("\r" + read + (maxlen - len(read))*" " + "\r")
+
+ if p.poll() != None:
+ break
+
+ log.close()
+ sys.stdout.write("\r" + maxlen*" \r")
+
+ return p.returncode
+
+def failure_color(message):
+ return '\033[91m' + message + '\033[0m'
+
+def ok_color(message):
+ return '\033[92m' + message + '\033[0m'
+
+def bold_color(message):
+ return '\033[1m' + message + '\033[0m'
+
+# Setup paths
+test_directory = find_test_directory()
+
+import test_config
+
+idiff_path = find_idiff(test_config.idiff_path)
+blender_executable = find_blender(test_config.blender_executable)
+blend_files = find_test_files(test_directory, test_config.files, ".blend")
+
+# Run tests
+for blend_name, blend_file in blend_files:
+ # Remove previous output
+ def clear_file(blend_name, blend_file):
+ for variation in render_variations(blend_file):
+ extension = variation + ".png"
+ diff_log = os.path.join(test_directory, "test_renders", blend_name + ".diff")
+ test_image = os.path.join(test_directory, "test_renders", blend_name + extension)
+
+ if os.path.exists(diff_log):
+ os.remove(diff_log)
+ if os.path.exists(test_image):
+ os.remove(test_image)
+
+ # Render
+ def render_file(blend_name, blend_file):
+ test_script = os.path.join(test_directory, "test_run.py")
+ blend_path = os.path.join(test_directory, blend_file)
+ blend_log = os.path.join(test_directory, "test_renders", blend_name + ".log")
+
+ command = '%s -b %s -P %s' % (blender_executable, blend_path, test_script)
+ print("Rendering " + bold_color(blend_file))
+ if execute_command(command, blend_log) != 0:
+ print(failure_color("Render Failed"))
+ return False
+
+ return True
+
+ # Compare
+ def compare_file(blend_name, blend_file):
+ for variation in render_variations(blend_file):
+ extension = variation + ".png"
+ diff_log = os.path.join(test_directory, "test_renders", blend_name + ".diff")
+ reference_image = os.path.join(test_directory, "reference_renders", blend_name + extension)
+ test_image = os.path.join(test_directory, "test_renders", blend_name + extension)
+
+ if not os.path.isfile(test_image):
+ print(failure_color("Output image missing"))
+ return False
+ if idiff_path and not os.path.isfile(reference_image):
+ print(ok_color("Render OK"))
+ return True
+
+ if idiff_path:
+ command = '%s -fail %f -failpercent %f %s %s' % (idiff_path, 0.02, 2, reference_image, test_image)
+ if execute_command(command, diff_log) not in (0, 1):
+ print(failure_color("Image does not match reference"))
+ return False
+ else:
+ print(ok_color("Render OK"))
+ return True
+
+ print(ok_color("Render + Compare OK"))
+ return True
+
+ clear_file(blend_name, blend_file)
+
+ if render_file(blend_name, blend_file):
+ compare_file(blend_name, blend_file)
+
Copied: trunk/lib/tests/auto/test_config.py (from rev 55220, trunk/lib/tests/rendering/cycles/test_config.py)
===================================================================
--- trunk/lib/tests/auto/test_config.py (rev 0)
+++ trunk/lib/tests/auto/test_config.py 2013-03-13 14:29:20 UTC (rev 55239)
@@ -0,0 +1,26 @@
+
+# Full path to Blender executable, autodetected when running from Blender
+blender_executable = ""
+
+# Path to OpenImageIO idiff executable, empty if in PATH
+idiff_path = ""
+
+# list of .blend files and directories with .blend files to render
+files = [
+"animation",
+"gameengine_visual",
+"modifier_stack",
+"sequence_editing",
+"glsl",
+"compositing",
+"particles_and_hair",
+"libraries_and_linking",
+"physics",
+"materials",
+"rendering",
+"modeling",
+"sculpting",
+"cycles"]
+
+files = ["../" + f for f in files]
+
Copied: trunk/lib/tests/auto/test_run.py (from rev 55220, trunk/lib/tests/rendering/cycles/test_run.py)
===================================================================
--- trunk/lib/tests/auto/test_run.py (rev 0)
+++ trunk/lib/tests/auto/test_run.py 2013-03-13 14:29:20 UTC (rev 55239)
@@ -0,0 +1,15 @@
+# Main imports
+import bpy
+import os
+import sys
+
+# Get the cycles test directory
+filepath = bpy.data.filepath
+test_dir = os.path.dirname(__file__)
+
+# Append to sys.path
+sys.path.append(test_dir)
+
+# Import external script and execute
+import test_utils
+test_utils.main()
Copied: trunk/lib/tests/auto/test_utils.py (from rev 55220, trunk/lib/tests/rendering/cycles/test_utils.py)
===================================================================
--- trunk/lib/tests/auto/test_utils.py (rev 0)
+++ trunk/lib/tests/auto/test_utils.py 2013-03-13 14:29:20 UTC (rev 55239)
@@ -0,0 +1,68 @@
+import os
+import sys
+import bpy
+import time
+
+# Get the cycles test directory
+filepath = bpy.data.filepath
+blend_files_dir = os.path.dirname(filepath)
+test_dir = os.path.dirname(__file__)
+
+# Get the filename without ending
+basename = os.path.basename(filepath)
+filename = os.path.splitext(basename)[0]
+
+def write_log_file(seconds, dir, blend_file, shading):
+ rev = get_blender_revision()
+ seconds = round(seconds, 2)
+ path = "%s/test_renders/log.txt" % dir
+
+ try:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list