From 5a8b1d413e98abd10b8ca6b1eb5eb91987f39ebf Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 29 Jul 2011 00:38:18 -0600 Subject: Support rendering image subregions. This is the first step to supporting distributed renders. --- dimension/dimension.in | 92 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 31 deletions(-) (limited to 'dimension') diff --git a/dimension/dimension.in b/dimension/dimension.in index f8cb114..b81f44b 100644 --- a/dimension/dimension.in +++ b/dimension/dimension.in @@ -19,36 +19,19 @@ # along with this program. If not, see . # ######################################################################### -import argparse -import os.path -import sys - -# Display a progress bar -def progress_bar(str, progress): - if not _args.quiet: - print(str, end = ' ') - sys.stdout.flush() - - term_width = terminal_width() - width = term_width - (len(str) + 1)%term_width - for i in range(width): - progress.wait(i/width) - print('.', end = '') - sys.stdout.flush() - - print() - sys.stdout.flush() - - progress.finish() +import argparse as _argparse +import re as _re +import os.path as _path +import sys as _sys # Specialized parser to print --version output to stdout rather than stderr, # to pass distcheck -class _DimensionArgumentParser(argparse.ArgumentParser): +class _DimensionArgumentParser(_argparse.ArgumentParser): def exit(self, status = 0, message = None): if message: - file = sys.stdout if status == 0 else sys.stderr + file = _sys.stdout if status == 0 else _sys.stderr file.write(message) - sys.exit(status) + _sys.exit(status) # Parse the command line _parser = _DimensionArgumentParser( @@ -56,7 +39,7 @@ _parser = _DimensionArgumentParser( "@PACKAGE_URL@\n" "Copyright (C) 2009-2011 Tavian Barnes <@PACKAGE_BUGREPORT@>\n" "Licensed under the GNU General Public License", - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class = _argparse.RawDescriptionHelpFormatter, conflict_handler = "resolve", # For -h as height instead of help ) @@ -67,6 +50,9 @@ _parser.add_argument("-w", "--width", action = "store", type = int, default = 768, help = "image width") _parser.add_argument("-h", "--height", action = "store", type = int, default = 480, help = "image height") +_parser.add_argument("--region", action = "store", type = str, + default = None, + help = "subregion to render, as \"((x1, y1), (x2, y2))\"") _parser.add_argument("-v", "--verbose", action = "store_true", help = "print more information") @@ -85,23 +71,63 @@ _parser.add_argument("input", action = "store", type = str, # Debugging/testing options _parser.add_argument("--strict", action = "store_true", - help = argparse.SUPPRESS) + help = _argparse.SUPPRESS) _args = _parser.parse_args() +# Calculate subregion +if _args.region is None: + _args.region_x = 0 + _args.region_y = 0 + _args.region_width = _args.width + _args.region_height = _args.height +else: + _pattern = r"^\s*\(\s*\(\s*(\d*)\s*,\s*(\d*)\s*\)\s*,\s*\(\s*(\d*)\s*,\s*(\d*)\s*\)\s*\)\s*$" + _match = _re.match(_pattern, _args.region) + if _match is None: + raise RuntimeError("range specified in invalid format.") + _args.region_x = int(_match.group(1)) + _args.region_y = int(_match.group(2)) + _args.region_width = int(_match.group(3)) - _args.region_x + _args.region_height = int(_match.group(4)) - _args.region_y + if _args.region_x + _args.region_width >= _args.width: + raise RuntimeError("region exceeds width of image.") + if _args.region_y + _args.region_height >= _args.height: + raise RuntimeError("region exceeds height of image.") + # Default output is basename(input).png if _args.output is None: - _noext = os.path.splitext(os.path.basename(_args.input))[0] + _noext = _path.splitext(_path.basename(_args.input))[0] _args.output = _noext + ".png" # Imports available to scripts from math import * from dimension import * +# Display a progress bar +def _progress_bar(str, progress): + if not _args.quiet: + print(str, end = ' ') + _sys.stdout.flush() + + term_width = terminal_width() + width = term_width - (len(str) + 1)%term_width + for i in range(width): + progress.wait(i/width) + print('.', end = '') + _sys.stdout.flush() + + print() + _sys.stdout.flush() + + progress.finish() + # --strict option die_on_warnings(_args.strict) -# Defaults +# Defaults/available variables +image_width = _args.width +image_height = _args.height objects = [] lights = [] camera = PerspectiveCamera() @@ -121,7 +147,7 @@ with open(_args.input) as _fh: parse_timer.complete() # Make the canvas -canvas = Canvas(width = _args.width, height = _args.height) +canvas = Canvas(width = _args.region_width, height = _args.region_height) canvas.optimize_PNG() # Make the scene object @@ -129,6 +155,10 @@ scene = Scene(canvas = canvas, objects = objects, lights = lights, camera = camera) +scene.region_x = _args.region_x +scene.region_y = _args.region_y +scene.outer_width = _args.width +scene.outer_height = _args.height scene.default_texture = default_texture scene.background = background if sky_sphere is not None: @@ -145,11 +175,11 @@ if scene.nthreads == 1: render_message = "Rendering scene" else: render_message = "Rendering scene (using %d threads)" % scene.nthreads -progress_bar(render_message, scene.raytrace_async()) +_progress_bar(render_message, scene.raytrace_async()) # Write the output file export_timer = Timer() -progress_bar("Writing %s" % _args.output, canvas.write_PNG_async(_args.output)) +_progress_bar("Writing %s" % _args.output, canvas.write_PNG_async(_args.output)) export_timer.complete() # Print execution times -- cgit v1.2.3