Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(serialize): Do not triangulate sub-faces by default in gbXML export #284

Merged
merged 1 commit into from Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file modified honeybee_grasshopper_core/icon/HB Dump gbXML.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions honeybee_grasshopper_core/json/HB_Dump_gbXML.json
@@ -1,5 +1,5 @@
{
"version": "1.4.0",
"version": "1.4.1",
"nickname": "DumpGBXML",
"outputs": [
[
Expand Down Expand Up @@ -34,6 +34,13 @@
"type": "string",
"default": null
},
{
"access": "item",
"name": "triangulate_",
"description": "Boolean to note whether sub-faces (including Apertures and Doors)\nshould be triangulated if they have more than 4 sides (True) or\nwhether they should be left as they are (False). This triangulation\nis necessary when exporting directly to EnergyPlus since it cannot\naccept sub-faces with more than 4 vertices. However, it is not a\ngeneral requirement of gbXML or all of the simulation engines that\ngbXML can import to/from. (Default: False).",
"type": "bool",
"default": null
},
{
"access": "item",
"name": "full_geo_",
Expand All @@ -50,7 +57,7 @@
}
],
"subcategory": "3 :: Serialize",
"code": "\nimport os\nimport json\n\ntry: # import the core honeybee dependencies\n from honeybee.model import Model\n from honeybee.config import folders\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\n\\t{}'.format(e))\n\ntry: # import the honeybee_energy dependencies\n from honeybee_energy.run import to_gbxml_osw, run_osw, add_gbxml_space_boundaries\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_energy:\\n\\t{}'.format(e))\n\ntry:\n from lbt_recipes.version import check_openstudio_version\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\n\ntry: # import the core ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component) and _dump:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # check the input and set the component defaults\n assert isinstance(_model, Model), \\\n 'Excpected Honeybee Model object. Got {}.'.format(type(_model))\n name = _name_ if _name_ is not None else _model.identifier\n lower_name = name.lower()\n gbxml_file = name if lower_name.endswith('.xml') or lower_name.endswith('.gbxml') \\\n else '{}.xml'.format(name)\n folder = _folder_ if _folder_ is not None else folders.default_simulation_folder\n gbxml = os.path.join(folder, gbxml_file)\n\n # duplicate model to avoid mutating it as we edit it for energy simulation\n _model = _model.duplicate()\n # remove colinear vertices using the Model tolerance to avoid E+ tolerance issues\n for room in _model.rooms:\n room.remove_colinear_vertices_envelope(_model.tolerance)\n # scale the model if the units are not meters\n if _model.units != 'Meters':\n _model.convert_to_units('Meters')\n\n # write out the HBJSON and OpenStudio Workflow (OSW) that translates models to gbXML\n out_directory = os.path.join(folders.default_simulation_folder, 'temp_translate')\n if not os.path.isdir(out_directory):\n os.makedirs(out_directory)\n model_dict = _model.to_dict(included_prop=['energy'], triangulate_sub_faces=True)\n _model.properties.energy.add_autocal_properties_to_dict(model_dict)\n _model.properties.energy.simplify_window_constructions_in_dict(model_dict)\n hb_file = os.path.join(out_directory, '{}.hbjson'.format(_model.identifier))\n with open(hb_file, 'w') as fp:\n json.dump(model_dict, fp)\n osw = to_gbxml_osw(hb_file, gbxml, out_directory)\n\n # run the measure to translate the model JSON to an openstudio measure\n osm, idf = run_osw(osw, silent=True)\n if idf is None:\n raise Exception('Running OpenStudio CLI failed.')\n\n # add in the space boundary geometry if the user has requested it\n if full_geo_:\n add_gbxml_space_boundaries(gbxml, _model)\n",
"code": "\nimport os\nimport json\n\ntry: # import the core honeybee dependencies\n from honeybee.model import Model\n from honeybee.config import folders\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\n\\t{}'.format(e))\n\ntry: # import the honeybee_energy dependencies\n from honeybee_energy.run import to_gbxml_osw, run_osw, add_gbxml_space_boundaries\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_energy:\\n\\t{}'.format(e))\n\ntry:\n from lbt_recipes.version import check_openstudio_version\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\n\ntry: # import the core ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component) and _dump:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # check the input and set the component defaults\n assert isinstance(_model, Model), \\\n 'Excpected Honeybee Model object. Got {}.'.format(type(_model))\n name = _name_ if _name_ is not None else _model.identifier\n lower_name = name.lower()\n gbxml_file = name if lower_name.endswith('.xml') or lower_name.endswith('.gbxml') \\\n else '{}.xml'.format(name)\n folder = _folder_ if _folder_ is not None else folders.default_simulation_folder\n gbxml = os.path.join(folder, gbxml_file)\n\n # duplicate model to avoid mutating it as we edit it for energy simulation\n _model = _model.duplicate()\n # remove colinear vertices using the Model tolerance to avoid E+ tolerance issues\n for room in _model.rooms:\n room.remove_colinear_vertices_envelope(_model.tolerance)\n # scale the model if the units are not meters\n if _model.units != 'Meters':\n _model.convert_to_units('Meters')\n\n # write out the HBJSON and OpenStudio Workflow (OSW) that translates models to gbXML\n out_directory = os.path.join(folders.default_simulation_folder, 'temp_translate')\n if not os.path.isdir(out_directory):\n os.makedirs(out_directory)\n triangulate_ = False if triangulate_ is None else triangulate_\n model_dict = _model.to_dict(included_prop=['energy'], triangulate_sub_faces=triangulate_)\n _model.properties.energy.add_autocal_properties_to_dict(model_dict)\n _model.properties.energy.simplify_window_constructions_in_dict(model_dict)\n hb_file = os.path.join(out_directory, '{}.hbjson'.format(_model.identifier))\n with open(hb_file, 'w') as fp:\n json.dump(model_dict, fp)\n osw = to_gbxml_osw(hb_file, gbxml, out_directory)\n\n # run the measure to translate the model JSON to an openstudio measure\n osm, idf = run_osw(osw, silent=True)\n if idf is None:\n raise Exception('Running OpenStudio CLI failed.')\n\n # add in the space boundary geometry if the user has requested it\n if full_geo_:\n add_gbxml_space_boundaries(gbxml, _model)\n",
"category": "Honeybee",
"name": "HB Dump gbXML",
"description": "Dump a Honyebee Model to a gbXML file.\n_\nThe gbXML format is a common open standard used to transfer energy model geometry\nand (some) energy simulation properties from one simulation environment to another.\n_\nThe forward translators within the OpenStudio SDK are used to export all Honeybee\nmodel geometry and properties.\n-"
Expand Down
12 changes: 10 additions & 2 deletions honeybee_grasshopper_core/src/HB Dump gbXML.py
Expand Up @@ -24,6 +24,13 @@
If unspecified, it will be derived from the model identifier.
_folder_: An optional directory into which the honeybee objects will be
written. The default is set to the default simulation folder.
triangulate_: Boolean to note whether sub-faces (including Apertures and Doors)
should be triangulated if they have more than 4 sides (True) or
whether they should be left as they are (False). This triangulation
is necessary when exporting directly to EnergyPlus since it cannot
accept sub-faces with more than 4 vertices. However, it is not a
general requirement of gbXML or all of the simulation engines that
gbXML can import to/from. (Default: False).
full_geo_: Boolean to note whether space boundaries and shell geometry should
be included in the exported gbXML vs. just the minimal required
non-manifold geometry. Setting to True to include the full geometry
Expand All @@ -40,7 +47,7 @@

ghenv.Component.Name = 'HB Dump gbXML'
ghenv.Component.NickName = 'DumpGBXML'
ghenv.Component.Message = '1.4.0'
ghenv.Component.Message = '1.4.1'
ghenv.Component.Category = 'Honeybee'
ghenv.Component.SubCategory = '3 :: Serialize'
ghenv.Component.AdditionalHelpFromDocStrings = '4'
Expand Down Expand Up @@ -97,7 +104,8 @@
out_directory = os.path.join(folders.default_simulation_folder, 'temp_translate')
if not os.path.isdir(out_directory):
os.makedirs(out_directory)
model_dict = _model.to_dict(included_prop=['energy'], triangulate_sub_faces=True)
triangulate_ = False if triangulate_ is None else triangulate_
model_dict = _model.to_dict(included_prop=['energy'], triangulate_sub_faces=triangulate_)
_model.properties.energy.add_autocal_properties_to_dict(model_dict)
_model.properties.energy.simplify_window_constructions_in_dict(model_dict)
hb_file = os.path.join(out_directory, '{}.hbjson'.format(_model.identifier))
Expand Down
Binary file modified honeybee_grasshopper_core/user_objects/HB Dump gbXML.ghuser
Binary file not shown.