diff --git a/honeybee_grasshopper_radiance/icon/HB Extract HDR.png b/honeybee_grasshopper_radiance/icon/HB Extract HDR.png index 6a8b3bb..63bb63d 100644 Binary files a/honeybee_grasshopper_radiance/icon/HB Extract HDR.png and b/honeybee_grasshopper_radiance/icon/HB Extract HDR.png differ diff --git a/honeybee_grasshopper_radiance/json/HB_Extract_HDR.json b/honeybee_grasshopper_radiance/json/HB_Extract_HDR.json index 8ce062f..895d96d 100644 --- a/honeybee_grasshopper_radiance/json/HB_Extract_HDR.json +++ b/honeybee_grasshopper_radiance/json/HB_Extract_HDR.json @@ -1,5 +1,5 @@ { - "version": "1.6.0", + "version": "1.6.1", "nickname": "ExtractHDR", "outputs": [ [ @@ -36,7 +36,7 @@ } ], "subcategory": "4 :: Results", - "code": "\nimport os\nimport subprocess\n\ntry: # import honeybee_radiance_command dependencies\n from honeybee_radiance_command.pinterp import Pinterp\n from honeybee_radiance_command.ra_xyze import Ra_xyze\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_radiance_command:\\n\\t{}'.format(e))\n\ntry: # import honeybee_radiance dependencies\n from honeybee_radiance.config import folders as rad_folders\n from honeybee_radiance.view import View\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_radiance:\\n\\t{}'.format(e))\n\ntry: # import ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n# check the Radiance date of the installed radiance\ntry: # import lbt_recipes dependencies\n from lbt_recipes.version import check_radiance_date\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\ncheck_radiance_date()\n\n\ndef check_view_hdr(hdr_path):\n \"\"\"Check if the header of the HDR image contains a view (VIEW=).\n \n A ValueError is raised if the image does not contain a valid view.\n A ValueError is raised if the view type is not -vta or -vth.\n \n Args:\n hdr_path: The path to an HDR image file.\n \"\"\"\n # set hdr_view to None\n hdr_view = None\n \n # read hdr image and search for a valid view\n with open(hdr_path, 'r') as hdr_file:\n for lineCount, line in enumerate(hdr_file):\n if lineCount < 200:\n low_line = line.lower()\n if not low_line.startswith('\\t'):\n if low_line.startswith('view='):\n hdr_view = View.from_string('hdr_view', line)\n else: # no need to check the rest of the document\n break\n if not hdr_view:\n raise ValueError(\n 'Connected _hdr image does not contain a valid view in the header.\\n'\n 'Note that indented views in the header will be ignored by pinterp.')\n if not hdr_view.type in ('a', 'h'):\n msg = 'Expected view type -vta or -vth in _hdr. Got view type -vt{}.'\n raise ValueError(msg.format(hdr_view.type))\n return hdr_view\n\n\ndef check_view_points(view, hdr_view):\n \"\"\"Check if view points of output view and input HDR are matching.\n \n A ValueError is raised if the view points are not matching.\n \n Args:\n view: A Honeybee Radiance View to extract.\n hdr_view: A Honeybee Radiance View from the input HDR.\n \"\"\"\n if not view.position == hdr_view.position:\n msg = 'View points of _view and _hdr are not matching.\\n' \\\n 'Got _view = {} and _hdr = {}.'\n raise ValueError(msg.format(view.position, hdr_view.position))\n\n\ndef check_resolution(hdr_path, resolution, view, hdr_view):\n \"\"\"Check the resolution of the output HDR as well as the input HDR.\n \n A warning is raised if the HDR image dimensions are not square. A warning is\n raised if the resolution is larger than one third of the HDR image\n resolution if converting a 360 FOV HDR to 180 FOV HDR. A warning is raised \n if the output resolution is larger than the input resolution.\n \n Args:\n hdr_path: The path to an HDR image file.\n resolution: The resolution of the extracted view from hdr_path.\n view: A Honeybee Radiance View to extract.\n hdr_view: A Honeybee Radiance View from the input HDR.\n \"\"\"\n # get the path the the getinfo command\n getinfo_exe = os.path.join(rad_folders.radbin_path, 'getinfo.exe') if \\\n os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'getinfo')\n \n # run the getinfo command in a manner that lets us obtain the result\n cmds = [getinfo_exe, '-d', hdr_path]\n use_shell = True if os.name == 'nt' else False\n process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)\n stdout = process.communicate()\n img_dim = stdout[0]\n \n # check the X and Y dimensions of the image\n hdr_x = int(img_dim.split(' ')[-1].strip())\n hdr_y = int(img_dim.split(' ')[-3].strip())\n if hdr_x == hdr_y: \n hdr_resolution = hdr_x = hdr_y\n else:\n msg = 'It is recommended that image dimensions of _hdr are square.\\n' \\\n 'Got {} x {}.'\n give_warning(ghenv.Component, msg.format(hdr_x, hdr_y))\n \n # check resolution ratio of output image / input image\n if hdr_view.h_size == 360 and hdr_view.v_size == 360:\n if resolution is None: \n resolution = hdr_resolution / 3\n if resolution > hdr_resolution / 3:\n msg = 'Recommended _resolution_ is one third or less of the _hdr resolution. \\n' \\\n 'Got {} for _resolution_ and {} for _hdr. Recommended _resolution_ \\n' \\\n 'is {} or lower.'\n give_warning(ghenv.Component, msg.format(resolution, hdr_resolution, \n int(hdr_resolution / 3)))\n else:\n if resolution is None: \n resolution = hdr_resolution\n if resolution > hdr_resolution:\n msg = 'Output image resolution ({}) is larger than input image \\n' \\\n 'resolution ({}). It is recommended that _resolution_ is equal \\n' \\\n 'to or less than input image resolution.'\n give_warning(ghenv.Component, msg.format(resolution, hdr_resolution))\n return resolution\n\n\nif all_required_inputs(ghenv.Component):\n # check if _view is Honeybee Radiance View\n assert isinstance(_view, View), \\\n 'Expected Honeybee Radiance View in _view. Got {}.'.format(type(_view))\n \n # check if header contains a view\n hdr_view = check_view_hdr(_hdr)\n \n # check view points\n check_view_points(_view, hdr_view)\n \n # check resolution\n resolution = check_resolution(_hdr, _resolution_, _view, hdr_view)\n \n # set up the paths for the various files used in translation\n img_dir = os.path.dirname(_hdr)\n input_image = os.path.basename(_hdr)\n commands = []\n \n # add the command to include exposure in the pixels\n expos_image = input_image.lower().replace('.hdr', '_e.hdr')\n ra_xyze = Ra_xyze(input=input_image, output=expos_image)\n ra_xyze.options.r = True\n ra_xyze.options.o = True\n commands.append(ra_xyze)\n \n # add the command to extract a view (HDR)\n view_identifier = _view.identifier\n view = os.path.basename(_view.to_file(img_dir))\n pinterp_image = input_image.lower().replace('.hdr', '_{}.hdr'.format(view_identifier))\n pinterp = Pinterp(output=pinterp_image, view=view, image=expos_image,\n zspec=1)\n pinterp.options.x = resolution\n pinterp.options.y = resolution\n commands.append(pinterp)\n hdr = os.path.join(img_dir, pinterp_image)\n \n # run the commands in series\n env = None\n if rad_folders.env != {}:\n env = rad_folders.env\n env = dict(os.environ, **env) if env else None\n for r_cmd in commands:\n r_cmd.run(env, cwd=img_dir)\n", + "code": "\nimport os\nimport subprocess\nimport re\n\ntry: # import honeybee_radiance_command dependencies\n from honeybee_radiance_command.pinterp import Pinterp\n from honeybee_radiance_command.ra_xyze import Ra_xyze\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_radiance_command:\\n\\t{}'.format(e))\n\ntry: # import honeybee_radiance dependencies\n from honeybee_radiance.config import folders as rad_folders\n from honeybee_radiance.view import View\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_radiance:\\n\\t{}'.format(e))\n\ntry: # import ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n# check the Radiance date of the installed radiance\ntry: # import lbt_recipes dependencies\n from lbt_recipes.version import check_radiance_date\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\ncheck_radiance_date()\n\n\ndef check_view_hdr(hdr_path):\n \"\"\"Check if the header of the HDR image contains a view (VIEW=).\n \n A ValueError is raised if the image does not contain a valid view.\n A ValueError is raised if the view type is not -vta or -vth.\n \n Args:\n hdr_path: The path to an HDR image file.\n \"\"\"\n # set hdr_view to None\n hdr_view = None\n \n # read hdr image and search for a valid view\n with open(hdr_path, 'r') as hdr_file:\n for lineCount, line in enumerate(hdr_file):\n if lineCount < 200:\n low_line = line.lower()\n if not low_line.startswith('\\t'):\n if low_line.startswith('view='):\n hdr_view = View.from_string('hdr_view', line)\n else: # no need to check the rest of the document\n break\n if not hdr_view:\n raise ValueError(\n 'Connected _hdr image does not contain a valid view in the header.\\n'\n 'Note that indented views in the header will be ignored by pinterp.')\n if not hdr_view.type in ('a', 'h'):\n msg = 'Expected view type -vta or -vth in _hdr. Got view type -vt{}.'\n raise ValueError(msg.format(hdr_view.type))\n return hdr_view\n\n\ndef check_view_points(view, hdr_view):\n \"\"\"Check if view points of output view and input HDR are matching.\n \n A ValueError is raised if the view points are not matching.\n \n Args:\n view: A Honeybee Radiance View to extract.\n hdr_view: A Honeybee Radiance View from the input HDR.\n \"\"\"\n if not view.position == hdr_view.position:\n msg = 'View points of _view and _hdr are not matching.\\n' \\\n 'Got _view = {} and _hdr = {}.'\n raise ValueError(msg.format(view.position, hdr_view.position))\n\n\ndef check_resolution(hdr_path, resolution, view, hdr_view):\n \"\"\"Check the resolution of the output HDR as well as the input HDR.\n \n A warning is raised if the HDR image dimensions are not square. A warning is\n raised if the resolution is larger than one third of the HDR image\n resolution if converting a 360 FOV HDR to 180 FOV HDR. A warning is raised \n if the output resolution is larger than the input resolution.\n \n Args:\n hdr_path: The path to an HDR image file.\n resolution: The resolution of the extracted view from hdr_path.\n view: A Honeybee Radiance View to extract.\n hdr_view: A Honeybee Radiance View from the input HDR.\n \"\"\"\n # get the path the the getinfo command\n getinfo_exe = os.path.join(rad_folders.radbin_path, 'getinfo.exe') if \\\n os.name == 'nt' else os.path.join(rad_folders.radbin_path, 'getinfo')\n \n # run the getinfo command in a manner that lets us obtain the result\n cmds = [getinfo_exe, '-d', hdr_path]\n use_shell = True if os.name == 'nt' else False\n process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell)\n stdout = process.communicate()\n img_dim = stdout[0]\n\n def get_dimensions(img_dim):\n dimensions = []\n for d in ['+X', '-Y']:\n regex = r'\\%s\\s+(\\d+)' % d\n matches = re.finditer(regex, img_dim, re.MULTILINE)\n dim = next(matches).groups()[0]\n dimensions.append(int(dim))\n return dimensions\n # check the X and Y dimensions of the image\n hdr_x, hdr_y = get_dimensions(img_dim)\n \n if hdr_x == hdr_y: \n hdr_resolution = hdr_x = hdr_y\n else:\n msg = 'It is recommended that image dimensions of _hdr are square.\\n' \\\n 'Got {} x {}.'\n give_warning(ghenv.Component, msg.format(hdr_x, hdr_y))\n \n # check resolution ratio of output image / input image\n if hdr_view.h_size == 360 and hdr_view.v_size == 360:\n if resolution is None: \n resolution = hdr_resolution / 3\n if resolution > hdr_resolution / 3:\n msg = 'Recommended _resolution_ is one third or less of the _hdr resolution. \\n' \\\n 'Got {} for _resolution_ and {} for _hdr. Recommended _resolution_ \\n' \\\n 'is {} or lower.'\n give_warning(ghenv.Component, msg.format(resolution, hdr_resolution, \n int(hdr_resolution / 3)))\n else:\n if resolution is None: \n resolution = hdr_resolution\n if resolution > hdr_resolution:\n msg = 'Output image resolution ({}) is larger than input image \\n' \\\n 'resolution ({}). It is recommended that _resolution_ is equal \\n' \\\n 'to or less than input image resolution.'\n give_warning(ghenv.Component, msg.format(resolution, hdr_resolution))\n return resolution\n\n\nif all_required_inputs(ghenv.Component):\n # check if _view is Honeybee Radiance View\n assert isinstance(_view, View), \\\n 'Expected Honeybee Radiance View in _view. Got {}.'.format(type(_view))\n \n # check if header contains a view\n hdr_view = check_view_hdr(_hdr)\n \n # check view points\n check_view_points(_view, hdr_view)\n \n # check resolution\n resolution = check_resolution(_hdr, _resolution_, _view, hdr_view)\n \n # set up the paths for the various files used in translation\n img_dir = os.path.dirname(_hdr)\n input_image = os.path.basename(_hdr)\n commands = []\n \n # add the command to include exposure in the pixels\n expos_image = input_image.lower().replace('.hdr', '_e.hdr')\n ra_xyze = Ra_xyze(input=input_image, output=expos_image)\n ra_xyze.options.r = True\n ra_xyze.options.o = True\n commands.append(ra_xyze)\n \n # add the command to extract a view (HDR)\n view_identifier = _view.identifier\n view = os.path.basename(_view.to_file(img_dir))\n pinterp_image = input_image.lower().replace('.hdr', '_{}.hdr'.format(view_identifier))\n pinterp = Pinterp(output=pinterp_image, view=view, image=expos_image,\n zspec=1)\n pinterp.options.x = resolution\n pinterp.options.y = resolution\n commands.append(pinterp)\n hdr = os.path.join(img_dir, pinterp_image)\n \n # run the commands in series\n env = None\n if rad_folders.env != {}:\n env = rad_folders.env\n env = dict(os.environ, **env) if env else None\n for r_cmd in commands:\n r_cmd.run(env, cwd=img_dir)\n", "category": "HB-Radiance", "name": "HB Extract HDR", "description": "Interpolate or extrapolate a High Dynamic Range (HDR) image file from another\nHDR image file.\n_\nRecommended use is to extract 180 FOV (-vh 180 -vv 180) angular or hemispherical\nHDR images from a 360 FOV (-vh 360 -vv 360) angular HDR image. Alternatively,\nconversions between 180 FOV angular and hemispherical HDR images can be made.\n-" diff --git a/honeybee_grasshopper_radiance/src/HB Extract HDR.py b/honeybee_grasshopper_radiance/src/HB Extract HDR.py index 2ad92d2..0f7f098 100644 --- a/honeybee_grasshopper_radiance/src/HB Extract HDR.py +++ b/honeybee_grasshopper_radiance/src/HB Extract HDR.py @@ -34,13 +34,14 @@ ghenv.Component.Name = 'HB Extract HDR' ghenv.Component.NickName = 'ExtractHDR' -ghenv.Component.Message = '1.6.0' +ghenv.Component.Message = '1.6.1' ghenv.Component.Category = 'HB-Radiance' ghenv.Component.SubCategory = '4 :: Results' ghenv.Component.AdditionalHelpFromDocStrings = '0' import os import subprocess +import re try: # import honeybee_radiance_command dependencies from honeybee_radiance_command.pinterp import Pinterp @@ -138,10 +139,18 @@ def check_resolution(hdr_path, resolution, view, hdr_view): process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell) stdout = process.communicate() img_dim = stdout[0] - + + def get_dimensions(img_dim): + dimensions = [] + for d in ['+X', '-Y']: + regex = r'\%s\s+(\d+)' % d + matches = re.finditer(regex, img_dim, re.MULTILINE) + dim = next(matches).groups()[0] + dimensions.append(int(dim)) + return dimensions # check the X and Y dimensions of the image - hdr_x = int(img_dim.split(' ')[-1].strip()) - hdr_y = int(img_dim.split(' ')[-3].strip()) + hdr_x, hdr_y = get_dimensions(img_dim) + if hdr_x == hdr_y: hdr_resolution = hdr_x = hdr_y else: diff --git a/honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser b/honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser index 1f35345..1d84af7 100644 Binary files a/honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser and b/honeybee_grasshopper_radiance/user_objects/HB Extract HDR.ghuser differ