[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30387] branches/soc-2010-leifandersen/ tests/render/run.py: Added documentation into the code, and the code looks much nicer now.
Leif Andersen
leif.a.andersen at gmail.com
Thu Jul 15 20:13:15 CEST 2010
Revision: 30387
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30387
Author: leifandersen
Date: 2010-07-15 20:13:15 +0200 (Thu, 15 Jul 2010)
Log Message:
-----------
Added documentation into the code, and the code looks much nicer now.
Modified Paths:
--------------
branches/soc-2010-leifandersen/tests/render/run.py
Modified: branches/soc-2010-leifandersen/tests/render/run.py
===================================================================
--- branches/soc-2010-leifandersen/tests/render/run.py 2010-07-15 17:54:53 UTC (rev 30386)
+++ branches/soc-2010-leifandersen/tests/render/run.py 2010-07-15 18:13:15 UTC (rev 30387)
@@ -1,3 +1,26 @@
+# ##### 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.
+#
+# Contributor(s): Leif Andersen
+#
+# The Original Code is Copyright (C) 2010 by Leif Andersen.
+# All rights reserved.
+#
+# ##### END GPL LICENSE BLOCK #####
+
import Image
import ImageChops
@@ -15,12 +38,8 @@
VERBOSE = False
class ImageTestCase:
- '''A Render Test Case. Steps must be run in order:
- 1. Constructer
- 2. Render Image (if it doesn't already exist)
- 3. Setup Tests
- 4. Save Diff'''
-
+ '''A Render Test Case only for use with images. It can either be used to directly
+ compare images, or if there is no good image, but a stored hashcode, it can compare the hashcode.'''
name = ''
passed = None
good_path = ''
@@ -40,12 +59,17 @@
mode = ''
def __init__(self):
+ '''Simply initializes the case, but no data is created'''
self.name = 'Uninitialized'
self.good_hash = -1
self.test_hash = -1
self.diff_hash = -1
def setup_hash(self, blend_path, good_hash, test_path):
+ '''Used for setting up the case for the purpose of a hash test
+ blend_path: the path to the blend file for the case
+ good_hash: An int containing the good hash of the case
+ test_path: the path for the output of the test when it's rendered'''
self.name = os.path.split(blend_path)[1]
self.good_hash = good_hash
self.blend_path = blend_path
@@ -53,9 +77,10 @@
self.mode = 'Hash'
def setup_image(self, blend_path, good_path, test_path):
- '''Sets up a test case, with the blend_path, the known good path, and the test path
- For images, the known good path is a file,
- for animations, it's a folder containing all of the frames'''
+ '''Used for setting up the case for the purpose of a image comparison test
+ blend_path: the path to the blend file for the case
+ good_path: The path for the good image that the case will be compared too.
+ test_path: the path for the output of the test when it's rendered'''
self.name = os.path.split(blend_path)[1]
self.blend_path = blend_path
self.good_path = good_path
@@ -63,6 +88,10 @@
self.mode = 'Image'
def generate_hash(self, image):
+ '''Designed mainly for internal use, but can be used for external purposes if needed
+ Generates a hash out of a given image
+ image: The image that the hash will be made from
+ returns: The calculated hash'''
hash = 0
for i in range(0,image.size[0]):
for j in range(0, image.size[1]):
@@ -71,25 +100,35 @@
return hash
def get_images(self):
+ '''Gets the good image, and test image (which assumes it's rendered), based on their
+ paths. Then creates a diff image out of the two other images. If the images
+ cannot be found, null is returned
+ returns: A tuplet (good_image, test_image, diff_image), or (null, null, null) if the images can't be found'''
try:
good_image = Image.open(self.good_path)
test_image = Image.open(self.test_path)
diff_image = ImageChops.difference(good_image, test_image)
+ return (good_image, test_image, diff_image)
except (IOError, OSError):
good_image = test_image = diff_image = None
- finally:
return (good_image, test_image, diff_image)
def format_frame(self, num):
+ '''Designed mainly for internal use: Will return the frame number given in the four didget format blender uses.
+ num: The num to be converted
+ returns: The num in four didget format, e.g. 3 becomes 0003, 29 becomes 0029'''
frame_num = str(num)
while len(frame_num) < 4:
frame_num = '0' + frame_num
return frame_num
def render_test(self):
- '''Renders a single image of the first frame of the blend file.
- Also changes output_path slightly'''
+ '''Renders the test image based on the given image path in the setup methods.
+ Assumes there is a global VERBOSE and BLENDER_BIN variable to be used.
+ Will only render the first frame of the image using the default settings (saving as a PNG though)
+ Changes the animation paths to the actual paths (from the given path)'''
+ # Render Based on whether or not it's verbose
if VERBOSE:
command = BLENDER_BIN + ' -b ' + self.blend_path + ' -o ' + self.test_path + '_#### -F PNG -x 1 -f 1'
os.system(command)
@@ -97,16 +136,25 @@
p = Popen([BLENDER_BIN, '-b', self.blend_path, '-o', self.test_path + '_####', '-F', 'PNG', '-x', '1', '-f', '1'], stdout=PIPE, stderr=PIPE, stdin=PIPE)
p.wait()
+ # Modify the test path as needed
self.test_path += '_0001.png'
def image_test(self):
- '''Runs the test, filling in all of the usefull fields'''
+ '''Performs the image comparison test, assuming that the images have already been generated.
+ if they have not been generated, than the testcase will be set to a fail. After the completion
+ of the test, the status of if the test passed or failed can be found in the passed field <testCaseName>.passed
+ returns: Whether or not the test passed'''
try:
+
+ # Setup Variables
(good_image, test_image, diff_image) = self.get_images()
self.diff_sum = 0
self.bad_pixels = 0
self.pixel_range = len(diff_image.histogram())
self.pixel_count = diff_image.size[0] * diff_image.size[1]
+
+ # Determine the total diff,
+ # as well as the bad pixels
for i in range(0,diff_image.size[0]):
for j in range(0, diff_image.size[1]):
p = diff_image.getpixel((i,j))
@@ -114,11 +162,14 @@
if p[0] + p[1] + p[2] > 10:
self.bad_pixels+=1
self.difference = float(self.diff_sum)/float(self.pixel_range*self.pixel_count)
+
+ # Set pass/fail
if self.bad_pixels < self.pixel_count/5 and self.difference < 0.01:
self.passed = True
else:
self.passed = False
except (TypeError, AttributeError):
+ # In case the Image wasn't rendered or something else goes wrong
self.passed = False
self.diff_sum = -1
self.bad_pixels = -1
@@ -129,6 +180,14 @@
return self.passed
def hash_test(self):
+ '''Performs the hash test on the image in case that the testcase is being used as a hashtest.
+ If the setup_image method was used rather than the setup_hash method, the test attempts to generate
+ a hash based on that image. It assumes that the test image has been rendered
+ The status of the test passing can be found in the passed field.
+ This method changes the value of the diff paths to the actual diff paths.
+ returns: Whether or not the test passed'''
+
+ ### TODO, rewrite...bad code ###
if test_image == None:
try:
test_image = Image.open(self.test_path)
@@ -153,17 +212,16 @@
self.passed = False
def save_diff(self, output_path):
- '''Saves the diff image to output_path'''
+ '''Saves the diff image of the testcase to output_path
+ output_path: The path to save the diff image'''
(good_image, test_image, diff_image) = self.get_images()
if diff_image != None:
self.diff_path = output_path
diff_image.save(output_path)
- else:
- self.diff_path = 0
class AnimationTestCase(ImageTestCase):
- ''''''
-
+ '''A Render Test Case only for use with animations. It can either be used to directly
+ compare images, or if there is no good image, but a stored hashcode, it can compare the hashcode.'''
passed_arr = []
good_path_arr = []
test_path_arr = []
@@ -175,6 +233,7 @@
diffference_arr = []
def __init__(self):
+ '''Simply initializes the case, but no data is created'''
self.name = 'Uninitialized'
self.passed_arr = []
self.good_path = ''
@@ -195,7 +254,10 @@
self.diff_hash = -1
def setup_hash(self, blend_path, good_hash, test_path):
- ''''''
+ '''Used for setting up the case for the purpose of a hash test
+ blend_path: the path to the blend file for the case
+ good_hash: An int containing the good hash of the case
+ test_path: the path for the output folder of the test when it's rendered'''
self.name = os.path.split(blend_path)[1]
self.good_hash = good_hash
self.blend_path = blend_path
@@ -209,7 +271,10 @@
self.mode = 'Hash'
def setup_image(self, blend_path, good_path, test_path):
- ''''''
+ '''Used for setting up the case for the purpose of a image comparison test
+ blend_path: the path to the blend file for the case
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list