Source code for honeybee.radiance.command.pyRad.objview

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
    objview - view RADIANCE object(s)

    This script is essentially a re-write of Axel Jacobs' objview.pl from
    http://radiance-online.org/cgi-bin/viewcvs.cgi/ray/src/util/objview.pl

    Axel's script inturn is a re-write of Greg Ward's original c-shell script.

    Sarith Subramaniam <sarith@sarith.in>,2016.
"""

from __future__ import division, print_function, unicode_literals
import os
import sys
import argparse
import tempfile
import shutil

__all__ = ('main')

# if __name__ == '__main__' and not getattr(sys, 'frozen', False):
#     _rp = os.environ.get('RAYPATH')
#     if not _rp:
#         print('No RAYPATH, unable to find support library');
#         sys.exit(-1)
#     for _p in _rp.split(os.path.pathsep):
#         if os.path.isdir(os.path.join(_p, 'pyradlib')):
#             if _p not in sys.path: sys.path.insert(0, _p)
#             break
#     else:
#         print('Support library not found on RAYPATH');
#         sys.exit(-1)

from pyRadLib.pyrad_proc import Error, ProcMixin


SHORTPROGN = os.path.splitext(os.path.basename(sys.argv[0]))[0]


lights = """
void glow dim 0 0 4 .1 .1 .15 0
dim source background 0 0 4 0 0 1 360
void light bright 0 0 3 1000 1000 1000
bright source sun1 0 0 4 1 .2 1 5
bright source sun2 0 0 4 .3 1 1 5
bright source sun3 0 0 4 -1 -.7 1 5"""


[docs]class Objview(ProcMixin): def __init__(self, args): self.useGl = args.useGl self.upDirection = args.upDirection self.backFaceVisible = args.backFaceVisible self.viewDetials = args.view_details self.numProc = args.numProc self.output_device = args.output_device self.verbose_display = args.verbose_display self.disable_warnings = args.disable_warnings self.gl_rad_full_screen = args.gl_rad_full_screen self.view_file = args.view_file self.scene_exposure = args.scene_exposure # Wrap all radfiles in quotes. self.rad_files = ['"%s"' % rad_file for rad_file in args.Radfiles[0]] self.no_lights = args.no_lights self.run_silently = args.run_silently self.print_viewsStdin = args.print_viewsStdin self.tempDir = None try: self.run() finally: if self.tempDir: shutil.rmtree(self.tempDir)
[docs] def run(self): output_device = 'x11' if self.useGl and os.name == 'nt': self.raise_on_error("set glRad variables.", "Glrad is only available in an X11 environment") self.create_temp() if not self.no_lights: self.rad_files.append(self.lightsFile) self.rad_options, self.render_options = self.create_rad_render_options() # If the OS is Windows then make the path Rad friendly by switching # slashes and set the output device to qt. if os.name == 'nt': self.rad_files = [s.replace('\\', '/') for s in self.rad_files] self.octree_file, self.lightsFile, self.rifFile, self.ambFile\ = [ s.replace('\\', '/') for s in (self.octree_file, self.lightsFile, self.rifFile, self.ambFile)] if self.view_file: self.view_file = [s.replace('\\', '/') for s in self.view_file] output_device = 'qt' self.rifLines = self.create_rif_list() self.write_files() if self.useGl: cmd_string = ['glrad'] + self.rad_options + [self.rifFile] else: if output_device: cmd_string = ['rad'] + ['-o', output_device] + \ self.rad_options + [self.rifFile] else: cmd_string = ['rad'] + self.rad_options + [self.rifFile] self.call_one(cmd_string, 'start rad')
[docs] def create_temp(self): """Create temporary files and directories needed for objview""" # Try creating a temp folder. Exit if not possible. try: self.tempDir = tempfile.mkdtemp('RAD') except IOError as e: self.raise_on_error("Create a temp folder", e) # create strings for files that are to be written to. def create_in_temp(file_name): return os.path.join(self.tempDir, file_name) self.octree_file = create_in_temp('scene.oct') self.lightsFile = create_in_temp('lights.rad') self.rifFile = create_in_temp('scene.rif') self.ambFile = create_in_temp('scene.amb')
[docs] def create_rad_render_options(self): """Based on the inputs provided, create options for running Rad/Glrad and also set rendering options.""" # If the output device is specified by the user, use that. # TODO(sarith): I'm not sure what is happening here. What is the deal with # output_device. It doesn't get used after the assignement # if self.output_device: # output_device = self.output_device render_options = '' if self.backFaceVisible: render_options += '-bv ' rad_options = [] rad_options_set = False gl_rad_options_set = False if self.disable_warnings: rad_options.append("-w") if self.numProc: rad_options.extend(['-N', str(self.numProc)]) rad_options_set = True if self.verbose_display: rad_options.append('-e') rad_options_set = True if self.gl_rad_full_screen: rad_options.append('-S') gl_rad_options_set = True if self.run_silently: rad_options.append('-s') if self.print_viewsStdin: rad_options.append('-V') rad_options_set = True if rad_options_set and self.useGl: self.raise_on_error("setting rad options", 'One among the following options :() are not ' 'compatible with Open GL'.format(",".join(rad_options))) elif gl_rad_options_set and not self.useGl: self.raise_on_error('set glRad options.', "Although glRad options have been set the " "rendering is being run through RAD.") return rad_options, render_options
[docs] def create_rif_list(self): """Create a list of RifFile variables based on user input and defaults.""" rif_list = ['scene= %s' % s for s in self.rad_files] rif_list.append('EXPOSURE= %s' % (self.scene_exposure or 0.5)) rif_list.append('UP= %s' % (self.upDirection or 'Z')) rif_list.append('OCTREE= %s' % self.octree_file) rif_list.append('AMBF= %s' % self.ambFile) rif_list.append('render=%s' % self.render_options) if self.view_file: self.view_file = '-vf %s' % "".join(self.view_file) rif_list.append('view= %s' % (self.view_file or '')) else: rif_list.append('view= %s' % (self.viewDetials or 'XYZ')) return rif_list
[docs] def write_files(self): # Write lights and join to the input rad files. with open(self.lightsFile, 'w')as lightRad: lightRad.write(lights) with open(self.rifFile, 'w') as rifData: rifData.write('\n'.join(self.rifLines) + '\n')
[docs]def main(): parser = argparse.ArgumentParser(add_help=False, description='Render a RADIANCE object ' 'interactively') parser.add_argument('-g', action='store_true', dest='useGl', help='Use OpenGL to render the scene') parser.add_argument('-u', action='store', dest='upDirection', help='Up direction. The default ' 'up direction vector is +Z', type=str, metavar='upDirection') parser.add_argument('-bv', action='store_true', dest='backFaceVisible', help='Enable back-face visibility in the scene.') parser.add_argument('-v', action='store', dest='view_details', help='Specify view details.', type=str, metavar='view_details') parser.add_argument('-N', action='store', dest='numProc', help='Number of parallel processes to render the scene.', type=int, metavar='numProc') parser.add_argument('-o', action='store', dest='output_device', help='Specify an output device for rendering', type=str, metavar='output_device') parser.add_argument('-w', action='store_true', dest='disable_warnings', help='Disable warnings about multiply and misassigned' ' variables.') parser.add_argument('-s', action='store_true', dest='run_silently', help='Process the radiance scene silently') parser.add_argument('-S', action='store_true', dest='gl_rad_full_screen', help='Enable full-screen stereo options with OpenGL') parser.add_argument('-exp', action='store', dest='scene_exposure', help='Set the exposure value') parser.add_argument('-e', action='store_true', dest='verbose_display', help='Display Radiance variables and error messages in' ' standard output') parser.add_argument('-V', action='store_true', dest='print_viewsStdin', help='Print each view on the standard output before being' ' applied') parser.add_argument('Radfiles', action='append', nargs='+', help='File(s) containing radiance scene objects that' ' are to be rendered interactively.') parser.add_argument('-H', action='help', help='Help: print this text to ' 'stderr and exit.') parser.add_argument('-vf', action='store', help='Specify a view file.', dest='view_file') parser.add_argument('-nL', action='store_true', dest='no_lights', help="Use lights in the scene only. Don't add additional lights") Objview(parser.parse_args())
if __name__ == "__main__": try: main() except KeyboardInterrupt: sys.stderr.write('*cancelled*\n') sys.exit(1) except (Error) as e: sys.stderr.write('%s: %s\n' % (SHORTPROGN, str(e))) sys.exit(-1)