forked from ladybug-tools/honeybee-grasshopper-core
/
HB Dump gbXML.py
123 lines (106 loc) · 5.5 KB
/
HB Dump gbXML.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# Honeybee: A Plugin for Environmental Analysis (GPL)
# This file is part of Honeybee.
#
# Copyright (c) 2022, Ladybug Tools.
# You should have received a copy of the GNU Affero General Public License
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>.
#
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later>
"""
Dump a Honyebee Model to a gbXML file.
_
The gbXML format is a common open standard used to transfer energy model geometry
and (some) energy simulation properties from one simulation environment to another.
_
The forward translators within the OpenStudio SDK are used to export all Honeybee
model geometry and properties.
-
Args:
_model: A Honeybee Model object to be written to a gbXML file.
_name_: A name for the file to which the honeybee objects will be written.
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
will increase file size without adding much new infomration that
doesn't already exist in the file. However, some gbXML interfaces
need this geometry in order to properly represent and display
room volumes. (Default: False).
_dump: Set to "True" to save the honeybee model to a gbXML file.
Returns:
report: Errors, warnings, etc.
hb_file: The location of the file where the honeybee JSON is saved.
"""
ghenv.Component.Name = 'HB Dump gbXML'
ghenv.Component.NickName = 'DumpGBXML'
ghenv.Component.Message = '1.4.1'
ghenv.Component.Category = 'Honeybee'
ghenv.Component.SubCategory = '3 :: Serialize'
ghenv.Component.AdditionalHelpFromDocStrings = '4'
import os
import json
try: # import the core honeybee dependencies
from honeybee.model import Model
from honeybee.config import folders
except ImportError as e:
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
try: # import the honeybee_energy dependencies
from honeybee_energy.run import to_gbxml_osw, run_osw, add_gbxml_space_boundaries
except ImportError as e:
raise ImportError('\nFailed to import honeybee_energy:\n\t{}'.format(e))
try:
from lbt_recipes.version import check_openstudio_version
except ImportError as e:
raise ImportError('\nFailed to import lbt_recipes:\n\t{}'.format(e))
try: # import the core ladybug_rhino dependencies
from ladybug_rhino.grasshopper import all_required_inputs
except ImportError as e:
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
if all_required_inputs(ghenv.Component) and _dump:
# check the presence of openstudio and check that the version is compatible
check_openstudio_version()
# check the input and set the component defaults
assert isinstance(_model, Model), \
'Excpected Honeybee Model object. Got {}.'.format(type(_model))
name = _name_ if _name_ is not None else _model.identifier
lower_name = name.lower()
gbxml_file = name if lower_name.endswith('.xml') or lower_name.endswith('.gbxml') \
else '{}.xml'.format(name)
folder = _folder_ if _folder_ is not None else folders.default_simulation_folder
gbxml = os.path.join(folder, gbxml_file)
# duplicate model to avoid mutating it as we edit it for energy simulation
_model = _model.duplicate()
# remove colinear vertices using the Model tolerance to avoid E+ tolerance issues
for room in _model.rooms:
room.remove_colinear_vertices_envelope(_model.tolerance)
# scale the model if the units are not meters
if _model.units != 'Meters':
_model.convert_to_units('Meters')
# write out the HBJSON and OpenStudio Workflow (OSW) that translates models to gbXML
out_directory = os.path.join(folders.default_simulation_folder, 'temp_translate')
if not os.path.isdir(out_directory):
os.makedirs(out_directory)
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))
with open(hb_file, 'w') as fp:
json.dump(model_dict, fp)
osw = to_gbxml_osw(hb_file, gbxml, out_directory)
# run the measure to translate the model JSON to an openstudio measure
osm, idf = run_osw(osw, silent=True)
if idf is None:
raise Exception('Running OpenStudio CLI failed.')
# add in the space boundary geometry if the user has requested it
if full_geo_:
add_gbxml_space_boundaries(gbxml, _model)