topologicpy 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Cell.py +129 -127
- topologicpy/CellComplex.py +21 -23
- topologicpy/Cluster.py +7 -11
- topologicpy/DGL.py +10 -5
- topologicpy/Face.py +124 -38
- topologicpy/Honeybee.py +158 -334
- topologicpy/Plotly.py +51 -33
- topologicpy/Shell.py +30 -50
- topologicpy/Topology.py +231 -79
- topologicpy/UnitTest.py +2 -2
- topologicpy/Vector.py +242 -17
- topologicpy/Wire.py +38 -66
- topologicpy/__init__.py +1 -1
- {topologicpy-0.2.1.dist-info → topologicpy-0.2.3.dist-info}/METADATA +3 -1
- {topologicpy-0.2.1.dist-info → topologicpy-0.2.3.dist-info}/RECORD +18 -18
- {topologicpy-0.2.1.dist-info → topologicpy-0.2.3.dist-info}/LICENSE +0 -0
- {topologicpy-0.2.1.dist-info → topologicpy-0.2.3.dist-info}/WHEEL +0 -0
- {topologicpy-0.2.1.dist-info → topologicpy-0.2.3.dist-info}/top_level.txt +0 -0
topologicpy/Honeybee.py
CHANGED
|
@@ -1,49 +1,54 @@
|
|
|
1
|
-
import topologic
|
|
2
|
-
import math
|
|
3
1
|
import honeybee_energy.lib.constructionsets as constr_set_lib
|
|
4
2
|
import honeybee.facetype
|
|
5
|
-
from honeybee.face import Face
|
|
3
|
+
from honeybee.face import Face as HBFace
|
|
6
4
|
from ladybug_geometry.geometry3d.face import Face3D
|
|
7
|
-
from honeybee.model import Model
|
|
8
|
-
from honeybee.room import Room
|
|
9
|
-
from honeybee.shade import Shade
|
|
10
|
-
from honeybee.aperture import Aperture
|
|
11
|
-
from honeybee.door import Door
|
|
5
|
+
from honeybee.model import Model as HBModel
|
|
6
|
+
from honeybee.room import Room as HBRoom
|
|
7
|
+
from honeybee.shade import Shade as HBShade
|
|
8
|
+
from honeybee.aperture import Aperture as HBAperture
|
|
9
|
+
from honeybee.door import Door as HBDoor
|
|
12
10
|
from honeybee_energy.schedule.ruleset import ScheduleRuleset
|
|
13
11
|
from honeybee_energy.schedule.day import ScheduleDay
|
|
14
12
|
from honeybee_energy.load.setpoint import Setpoint
|
|
15
13
|
from honeybee_energy.load.hotwater import ServiceHotWater
|
|
16
14
|
import honeybee_energy.lib.programtypes as prog_type_lib
|
|
17
15
|
import honeybee_energy.lib.scheduletypelimits as schedule_types
|
|
16
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
17
|
+
|
|
18
18
|
from ladybug.dt import Time
|
|
19
19
|
from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D
|
|
20
20
|
import json
|
|
21
|
-
import Dictionary
|
|
21
|
+
from topologicpy.Dictionary import Dictionary
|
|
22
|
+
import topologic
|
|
22
23
|
|
|
23
|
-
class
|
|
24
|
+
class Honeybee:
|
|
24
25
|
@staticmethod
|
|
25
|
-
def
|
|
26
|
+
def ConstructionSetByIdentifier(id):
|
|
26
27
|
"""
|
|
28
|
+
Returns the built-in construction set by the input identifying string.
|
|
29
|
+
|
|
27
30
|
Parameters
|
|
28
31
|
----------
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
id : str
|
|
33
|
+
The construction set identifier.
|
|
31
34
|
|
|
32
35
|
Returns
|
|
33
36
|
-------
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
HBConstructionSet
|
|
38
|
+
The found built-in construction set.
|
|
36
39
|
|
|
37
40
|
"""
|
|
38
|
-
return constr_set_lib.construction_set_by_identifier(
|
|
41
|
+
return constr_set_lib.construction_set_by_identifier(id)
|
|
39
42
|
|
|
40
43
|
@staticmethod
|
|
41
|
-
def
|
|
44
|
+
def ConstructionSets():
|
|
42
45
|
"""
|
|
46
|
+
Returns the list of built-in construction sets
|
|
47
|
+
|
|
43
48
|
Returns
|
|
44
49
|
-------
|
|
45
50
|
list
|
|
46
|
-
|
|
51
|
+
The list of built-in construction sets.
|
|
47
52
|
|
|
48
53
|
"""
|
|
49
54
|
constrSets = []
|
|
@@ -53,222 +58,73 @@ class HB:
|
|
|
53
58
|
return [constrSets, constrIdentifiers]
|
|
54
59
|
|
|
55
60
|
@staticmethod
|
|
56
|
-
def
|
|
57
|
-
tpShadingSurfacesCluster, floorLevels, buildingName,
|
|
58
|
-
buildingType, defaultSpaceType, northAxis, glazingRatio, coolingTemp, heatingTemp):
|
|
61
|
+
def ExportToHBJSON(model, path, overwrite=True):
|
|
59
62
|
"""
|
|
63
|
+
Exports the input HB Model to a file.
|
|
64
|
+
|
|
60
65
|
Parameters
|
|
61
66
|
----------
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
tpBuilding : TYPE
|
|
69
|
-
DESCRIPTION.
|
|
70
|
-
tpShadingSurfacesCluster : TYPE
|
|
71
|
-
DESCRIPTION.
|
|
72
|
-
floorLevels : TYPE
|
|
73
|
-
DESCRIPTION.
|
|
74
|
-
buildingName : TYPE
|
|
75
|
-
DESCRIPTION.
|
|
76
|
-
buildingType : TYPE
|
|
77
|
-
DESCRIPTION.
|
|
78
|
-
defaultSpaceType : TYPE
|
|
79
|
-
DESCRIPTION.
|
|
80
|
-
northAxis : TYPE
|
|
81
|
-
DESCRIPTION.
|
|
82
|
-
glazingRatio : TYPE
|
|
83
|
-
DESCRIPTION.
|
|
84
|
-
coolingTemp : TYPE
|
|
85
|
-
DESCRIPTION.
|
|
86
|
-
heatingTemp : TYPE
|
|
87
|
-
DESCRIPTION.
|
|
67
|
+
model : HBModel
|
|
68
|
+
The input HB Model.
|
|
69
|
+
path : str
|
|
70
|
+
The location of the output file.
|
|
71
|
+
overwrite : bool , optional
|
|
72
|
+
If set to True this method overwrites any existing file. Otherwise, it won't. The default is True.
|
|
88
73
|
|
|
89
74
|
Returns
|
|
90
75
|
-------
|
|
91
|
-
|
|
92
|
-
|
|
76
|
+
bool
|
|
77
|
+
Returns True if the operation is successful. Returns False otherwise.
|
|
93
78
|
|
|
94
79
|
"""
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# northAxis = item[9]
|
|
105
|
-
# glazingRatio = item[10]
|
|
106
|
-
# coolingTemp = item[11]
|
|
107
|
-
# heatingTemp = item[12]
|
|
108
|
-
|
|
109
|
-
def listAttributeValues(listAttribute):
|
|
110
|
-
listAttributes = listAttribute.ListValue()
|
|
111
|
-
returnList = []
|
|
112
|
-
for attr in listAttributes:
|
|
113
|
-
if isinstance(attr, topologic.IntAttribute):
|
|
114
|
-
returnList.append(attr.IntValue())
|
|
115
|
-
elif isinstance(attr, topologic.DoubleAttribute):
|
|
116
|
-
returnList.append(attr.DoubleValue())
|
|
117
|
-
elif isinstance(attr, topologic.StringAttribute):
|
|
118
|
-
returnList.append(attr.StringValue())
|
|
119
|
-
return returnList
|
|
120
|
-
|
|
121
|
-
def valueAtKey(item, key):
|
|
122
|
-
try:
|
|
123
|
-
attr = item.ValueAtKey(key)
|
|
124
|
-
except:
|
|
125
|
-
raise Exception("Dictionary.ValueAtKey - Error: Could not retrieve a Value at the specified key ("+key+")")
|
|
126
|
-
if isinstance(attr, topologic.IntAttribute):
|
|
127
|
-
return (attr.IntValue())
|
|
128
|
-
elif isinstance(attr, topologic.DoubleAttribute):
|
|
129
|
-
return (attr.DoubleValue())
|
|
130
|
-
elif isinstance(attr, topologic.StringAttribute):
|
|
131
|
-
return (attr.StringValue())
|
|
132
|
-
elif isinstance(attr, topologic.ListAttribute):
|
|
133
|
-
return (listAttributeValues(attr))
|
|
80
|
+
# hbModel, path = item
|
|
81
|
+
# Make sure the file extension is .hbjson
|
|
82
|
+
ext = path[len(path)-7:len(path)]
|
|
83
|
+
if ext.lower() != ".hbjson":
|
|
84
|
+
path = path+".hbjson"
|
|
85
|
+
f = None
|
|
86
|
+
try:
|
|
87
|
+
if overwrite == True:
|
|
88
|
+
f = open(path, "w")
|
|
134
89
|
else:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
tpDictionary = tpCell.GetDictionary()
|
|
144
|
-
tpCellName = None
|
|
145
|
-
tpCellStory = None
|
|
146
|
-
if tpDictionary:
|
|
147
|
-
tpCellName = valueAtKey(tpDictionary,'name')
|
|
148
|
-
tpCellStory = valueAtKey(tpDictionary,'story')
|
|
149
|
-
tpCellFaces = []
|
|
150
|
-
_ = tpCell.Faces(None, tpCellFaces)
|
|
151
|
-
if tpCellFaces:
|
|
152
|
-
hbRoomFaces = []
|
|
153
|
-
for tpFaceNumber, tpCellFace in enumerate(tpCellFaces):
|
|
154
|
-
hbRoomFacePoints = []
|
|
155
|
-
tpFaceVertices = []
|
|
156
|
-
_ = tpCellFace.ExternalBoundary().Vertices(None, tpFaceVertices)
|
|
157
|
-
for tpVertex in tpFaceVertices:
|
|
158
|
-
hbRoomFacePoints.append(Point3D(tpVertex.X(), tpVertex.Y(), tpVertex.Z()))
|
|
159
|
-
hbRoomFace = Face(tpCellName+'_Face_'+str(tpFaceNumber+1), Face3D(hbRoomFacePoints))
|
|
160
|
-
faceNormal = topologic.FaceUtility.NormalAtParameters(tpFace, 0.5, 0.5)
|
|
161
|
-
ang = math.degrees(math.acos(faceNormal.dot([0, 0, 1])))
|
|
162
|
-
print("HBJSONByTopology: Angle between face normal and UP",ang)
|
|
163
|
-
if ang > 175:
|
|
164
|
-
hbRoomFace.type = "floor"
|
|
165
|
-
tpFaceApertures = []
|
|
166
|
-
_ = tpCellFace.Apertures(tpFaceApertures)
|
|
167
|
-
if tpFaceApertures:
|
|
168
|
-
for tpFaceApertureNumber, tpFaceAperture in enumerate(tpFaceApertures):
|
|
169
|
-
apertureTopology = topologic.Aperture.Topology(tpFaceAperture)
|
|
170
|
-
tpFaceApertureDictionary = apertureTopology.GetDictionary()
|
|
171
|
-
if tpFaceApertureDictionary:
|
|
172
|
-
tpFaceApertureType = valueAtKey(tpFaceApertureDictionary,'type')
|
|
173
|
-
hbFaceAperturePoints = []
|
|
174
|
-
tpFaceApertureVertices = []
|
|
175
|
-
_ = apertureTopology.ExternalBoundary().Vertices(None, tpFaceApertureVertices)
|
|
176
|
-
for tpFaceApertureVertex in tpFaceApertureVertices:
|
|
177
|
-
hbFaceAperturePoints.append(Point3D(tpFaceApertureVertex.X(), tpFaceApertureVertex.Y(), tpFaceApertureVertex.Z()))
|
|
178
|
-
if(tpFaceApertureType):
|
|
179
|
-
if ("door" in tpFaceApertureType.lower()):
|
|
180
|
-
hbFaceAperture = Door(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Door_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
181
|
-
else:
|
|
182
|
-
hbFaceAperture = Aperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
183
|
-
else:
|
|
184
|
-
hbFaceAperture = Aperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
185
|
-
hbRoomFace.add_aperture(hbFaceAperture)
|
|
186
|
-
hbRoomFaces.append(hbRoomFace)
|
|
187
|
-
if tpCellName == None:
|
|
188
|
-
tpCellName = "GENERICROOM_"+(str(spaceNumber+1))
|
|
189
|
-
room = Room(tpCellName, hbRoomFaces, 0.01, 1) #ToDo: Figure out how to add Story number
|
|
190
|
-
heat_setpt = ScheduleRuleset.from_constant_value('Room Heating', heatingTemp, schedule_types.temperature)
|
|
191
|
-
cool_setpt = ScheduleRuleset.from_constant_value('Room Cooling', coolingTemp, schedule_types.temperature)
|
|
192
|
-
humidify_setpt = ScheduleRuleset.from_constant_value('Room Humidifying', 30, schedule_types.humidity) #Todo: Remove hardwired number
|
|
193
|
-
dehumidify_setpt = ScheduleRuleset.from_constant_value('Room Dehumidifying', 55, schedule_types.humidity) #Todo: Remove hardwired number
|
|
194
|
-
setpoint = Setpoint('Room Setpoint', heat_setpt, cool_setpt, humidify_setpt, dehumidify_setpt)
|
|
195
|
-
simple_office = ScheduleDay('Simple Weekday', [0, 1, 0], [Time(0, 0), Time(9, 0), Time(17, 0)])
|
|
196
|
-
schedule = ScheduleRuleset('Office Water Use', simple_office, None, schedule_types.fractional)
|
|
197
|
-
shw = ServiceHotWater('Office Hot Water', 0.1, schedule)
|
|
198
|
-
room.properties.energy.program_type = prog_type_lib.office_program #Default Office Program
|
|
199
|
-
room.properties.energy.add_default_ideal_air() #Ideal Air Exchange
|
|
200
|
-
room.properties.energy.setpoint = setpoint #Heating/Cooling/Humidifying/Dehumidifying
|
|
201
|
-
room.properties.energy.service_hot_water = shw #Service Hot Water
|
|
202
|
-
if tpCellStory:
|
|
203
|
-
room.story = tpCellStory
|
|
204
|
-
rooms.append(room)
|
|
205
|
-
Room.solve_adjacency(rooms, 0.01)
|
|
206
|
-
Room.stories_by_floor_height(rooms, min_difference=2.0)
|
|
207
|
-
|
|
208
|
-
hbShades = []
|
|
209
|
-
shadingFaces = []
|
|
210
|
-
_ = tpShadingSurfacesCluster.Faces(None, shadingFaces)
|
|
211
|
-
for faceIndex, shadingFace in enumerate(shadingFaces):
|
|
212
|
-
faceVertices = []
|
|
213
|
-
_ = shadingFace.ExternalBoundary().Vertices(None, faceVertices)
|
|
214
|
-
facePoints = []
|
|
215
|
-
for aVertex in faceVertices:
|
|
216
|
-
facePoints.append(Point3D(aVertex.X(), aVertex.Y(), aVertex.Z()))
|
|
217
|
-
hbShadingFace = Face3D(facePoints, None, [])
|
|
218
|
-
hbShade = Shade("SHADINGSURFACE_" + str(faceIndex), hbShadingFace)
|
|
219
|
-
hbShades.append(hbShade)
|
|
220
|
-
model = Model('TopologicModel', rooms, orphaned_shades=hbShades)
|
|
221
|
-
return model.to_dict()
|
|
90
|
+
f = open(path, "x") # Try to create a new File
|
|
91
|
+
except:
|
|
92
|
+
raise Exception("Error: Could not create a new file at the following location: "+path)
|
|
93
|
+
if (f):
|
|
94
|
+
json.dump(model.to_dict(), f, indent=4)
|
|
95
|
+
f.close()
|
|
96
|
+
return True
|
|
97
|
+
return False
|
|
222
98
|
|
|
223
99
|
@staticmethod
|
|
224
|
-
def
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
100
|
+
def ModelByTopology(tpBuilding,
|
|
101
|
+
tpShadingFacesCluster=None,
|
|
102
|
+
buildingName = "Generic_Building",
|
|
103
|
+
defaultProgramIdentifier = "Generic Office Program",
|
|
104
|
+
defaultConstructionSetIdentifier = "Default Generic Construction Set",
|
|
105
|
+
coolingSetpoint = 25.0,
|
|
106
|
+
heatingSetpoint = 20.0,
|
|
107
|
+
humidifyingSetpoint = 30.0,
|
|
108
|
+
dehumidifyingSetpoint = 55.0,
|
|
109
|
+
roomNameKey = "name",
|
|
110
|
+
roomTypeKey = "type",
|
|
111
|
+
apertureTypeKey = "type",
|
|
112
|
+
addSensorGrid = False):
|
|
228
113
|
"""
|
|
229
|
-
|
|
230
|
-
----------
|
|
231
|
-
tpBuilding : TYPE
|
|
232
|
-
DESCRIPTION.
|
|
233
|
-
tpShadingFacesCluster : TYPE
|
|
234
|
-
DESCRIPTION.
|
|
235
|
-
buildingName : TYPE
|
|
236
|
-
DESCRIPTION.
|
|
237
|
-
defaultProgramIdentifier : TYPE
|
|
238
|
-
DESCRIPTION.
|
|
239
|
-
defaultConstructionSetIdentifier : TYPE
|
|
240
|
-
DESCRIPTION.
|
|
241
|
-
coolingSetpoint : TYPE
|
|
242
|
-
DESCRIPTION.
|
|
243
|
-
heatingSetpoint : TYPE
|
|
244
|
-
DESCRIPTION.
|
|
245
|
-
humidifyingSetpoint : TYPE
|
|
246
|
-
DESCRIPTION.
|
|
247
|
-
dehumidifyingSetpoint : TYPE
|
|
248
|
-
DESCRIPTION.
|
|
249
|
-
roomNameKey : TYPE
|
|
250
|
-
DESCRIPTION.
|
|
251
|
-
roomTypeKey : TYPE
|
|
252
|
-
DESCRIPTION.
|
|
253
|
-
|
|
254
|
-
Returns
|
|
114
|
+
Creates an HB Model from the input Topology
|
|
255
115
|
-------
|
|
256
|
-
|
|
257
|
-
|
|
116
|
+
HBModel
|
|
117
|
+
The created HB Model
|
|
258
118
|
|
|
259
119
|
"""
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
# dehumidifyingSetpoint = item[8]
|
|
269
|
-
# roomNameKey = item[9]
|
|
270
|
-
# roomTypeKey = item[10]
|
|
271
|
-
|
|
120
|
+
from topologicpy.Vertex import Vertex
|
|
121
|
+
from topologicpy.Wire import Wire
|
|
122
|
+
from topologicpy.Face import Face
|
|
123
|
+
from topologicpy.Cell import Cell
|
|
124
|
+
from topologicpy.Aperture import Aperture
|
|
125
|
+
from topologicpy.Topology import Topology
|
|
126
|
+
from topologicpy.Dictionary import Dictionary
|
|
127
|
+
|
|
272
128
|
def cellFloor(cell):
|
|
273
129
|
faces = []
|
|
274
130
|
_ = cell.Faces(None, faces)
|
|
@@ -287,14 +143,14 @@ class HB:
|
|
|
287
143
|
returnList.append("Floor"+str(floorNumber).zfill(2))
|
|
288
144
|
break
|
|
289
145
|
return returnList
|
|
290
|
-
|
|
146
|
+
|
|
291
147
|
def getKeyName(d, keyName):
|
|
292
|
-
keys =
|
|
148
|
+
keys = Dictionary.Keys(d)
|
|
293
149
|
for key in keys:
|
|
294
150
|
if key.lower() == keyName.lower():
|
|
295
151
|
return key
|
|
296
152
|
return None
|
|
297
|
-
|
|
153
|
+
|
|
298
154
|
def createUniqueName(name, nameList, number):
|
|
299
155
|
if not (name in nameList):
|
|
300
156
|
return name
|
|
@@ -303,10 +159,8 @@ class HB:
|
|
|
303
159
|
else:
|
|
304
160
|
return createUniqueName(name,nameList, number+1)
|
|
305
161
|
|
|
306
|
-
if
|
|
307
|
-
|
|
308
|
-
else:
|
|
309
|
-
buildingName = "GENERICBUILDING"
|
|
162
|
+
if not isinstance(tpBuilding, topologic.Topology):
|
|
163
|
+
return None
|
|
310
164
|
rooms = []
|
|
311
165
|
tpCells = []
|
|
312
166
|
_ = tpBuilding.Cells(None, tpCells)
|
|
@@ -314,8 +168,9 @@ class HB:
|
|
|
314
168
|
tpCells.sort(key=lambda c: cellFloor(c), reverse=False)
|
|
315
169
|
fl = floorLevels(tpCells, 2)
|
|
316
170
|
spaceNames = []
|
|
171
|
+
sensorGrids = []
|
|
317
172
|
for spaceNumber, tpCell in enumerate(tpCells):
|
|
318
|
-
tpDictionary =
|
|
173
|
+
tpDictionary = Topology.Dictionary(tpCell)
|
|
319
174
|
tpCellName = None
|
|
320
175
|
tpCellStory = None
|
|
321
176
|
tpCellProgramIdentifier = None
|
|
@@ -323,38 +178,40 @@ class HB:
|
|
|
323
178
|
tpCellConditioned = True
|
|
324
179
|
if tpDictionary:
|
|
325
180
|
keyName = getKeyName(tpDictionary, 'Story')
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
181
|
+
try:
|
|
182
|
+
tpCellStory = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
183
|
+
if tpCellStory:
|
|
184
|
+
tpCellStory = tpCellStory.replace(" ","_")
|
|
185
|
+
except:
|
|
330
186
|
tpCellStory = fl[spaceNumber]
|
|
331
187
|
if roomNameKey:
|
|
332
188
|
keyName = getKeyName(tpDictionary, roomNameKey)
|
|
333
189
|
else:
|
|
334
190
|
keyName = getKeyName(tpDictionary, 'Name')
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
191
|
+
try:
|
|
192
|
+
tpCellName = Dictionary.ValueAtKey(tpDictionary,keyName)
|
|
193
|
+
if tpCellName:
|
|
194
|
+
tpCellName = createUniqueName(tpCellName.replace(" ","_"), spaceNames, 1)
|
|
195
|
+
except:
|
|
339
196
|
tpCellName = tpCellStory+"_SPACE_"+(str(spaceNumber+1))
|
|
340
197
|
if roomTypeKey:
|
|
341
198
|
keyName = getKeyName(tpDictionary, roomTypeKey)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
else:
|
|
199
|
+
try:
|
|
200
|
+
tpCellProgramIdentifier = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
201
|
+
if tpCellProgramIdentifier:
|
|
202
|
+
program = prog_type_lib.program_type_by_identifier(tpCellProgramIdentifier)
|
|
203
|
+
elif defaultProgramIdentifier:
|
|
204
|
+
program = prog_type_lib.program_type_by_identifier(defaultProgramIdentifier)
|
|
205
|
+
except:
|
|
350
206
|
program = prog_type_lib.office_program #Default Office Program as a last resort
|
|
351
207
|
keyName = getKeyName(tpDictionary, 'construction_set')
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
208
|
+
try:
|
|
209
|
+
tpCellConstructionSetIdentifier = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
210
|
+
if tpCellConstructionSetIdentifier:
|
|
211
|
+
constr_set = constr_set_lib.construction_set_by_identifier(tpCellConstructionSetIdentifier)
|
|
212
|
+
elif defaultConstructionSetIdentifier:
|
|
213
|
+
constr_set = constr_set_lib.construction_set_by_identifier(defaultConstructionSetIdentifier)
|
|
214
|
+
except:
|
|
358
215
|
constr_set = constr_set_lib.construction_set_by_identifier("Default Generic Construction Set")
|
|
359
216
|
else:
|
|
360
217
|
tpCellStory = fl[spaceNumber]
|
|
@@ -368,44 +225,47 @@ class HB:
|
|
|
368
225
|
if tpCellFaces:
|
|
369
226
|
hbRoomFaces = []
|
|
370
227
|
for tpFaceNumber, tpCellFace in enumerate(tpCellFaces):
|
|
371
|
-
tpCellFaceNormal =
|
|
228
|
+
tpCellFaceNormal = Face.NormalAtParameters(tpCellFace, 0.5, 0.5)
|
|
372
229
|
hbRoomFacePoints = []
|
|
373
|
-
tpFaceVertices =
|
|
374
|
-
_ = tpCellFace.ExternalBoundary().Vertices(None, tpFaceVertices)
|
|
230
|
+
tpFaceVertices = Wire.Vertices(Face.ExternalBoundary(tpCellFace))
|
|
375
231
|
for tpVertex in tpFaceVertices:
|
|
376
232
|
hbRoomFacePoints.append(Point3D(tpVertex.X(), tpVertex.Y(), tpVertex.Z()))
|
|
377
|
-
hbRoomFace =
|
|
233
|
+
hbRoomFace = HBFace(tpCellName+'_Face_'+str(tpFaceNumber+1), Face3D(hbRoomFacePoints))
|
|
378
234
|
tpFaceApertures = []
|
|
379
235
|
_ = tpCellFace.Apertures(tpFaceApertures)
|
|
380
236
|
if tpFaceApertures:
|
|
381
237
|
for tpFaceApertureNumber, tpFaceAperture in enumerate(tpFaceApertures):
|
|
382
|
-
apertureTopology =
|
|
383
|
-
tpFaceApertureDictionary =
|
|
238
|
+
apertureTopology = Aperture.Topology(tpFaceAperture)
|
|
239
|
+
tpFaceApertureDictionary = Topology.Dictionary(apertureTopology)
|
|
384
240
|
if tpFaceApertureDictionary:
|
|
385
|
-
|
|
241
|
+
apertureKeyName = getKeyName(tpFaceApertureDictionary, apertureTypeKey)
|
|
242
|
+
tpFaceApertureType = Dictionary.ValueAtKey(tpFaceApertureDictionary,apertureKeyName)
|
|
386
243
|
hbFaceAperturePoints = []
|
|
387
244
|
tpFaceApertureVertices = []
|
|
388
|
-
|
|
245
|
+
tpFaceApertureVertices = Wire.Vertices(Face.ExternalBoundary(apertureTopology))
|
|
389
246
|
for tpFaceApertureVertex in tpFaceApertureVertices:
|
|
390
247
|
hbFaceAperturePoints.append(Point3D(tpFaceApertureVertex.X(), tpFaceApertureVertex.Y(), tpFaceApertureVertex.Z()))
|
|
391
248
|
if(tpFaceApertureType):
|
|
392
249
|
if ("door" in tpFaceApertureType.lower()):
|
|
393
|
-
hbFaceAperture =
|
|
250
|
+
hbFaceAperture = HBDoor(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Door_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
394
251
|
else:
|
|
395
|
-
hbFaceAperture =
|
|
252
|
+
hbFaceAperture = HBAperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
396
253
|
else:
|
|
397
|
-
hbFaceAperture =
|
|
254
|
+
hbFaceAperture = HBAperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
398
255
|
hbRoomFace.add_aperture(hbFaceAperture)
|
|
399
256
|
else:
|
|
400
|
-
tpFaceDictionary =
|
|
257
|
+
tpFaceDictionary = Topology.Dictionary(tpCellFace)
|
|
401
258
|
if (abs(tpCellFaceNormal[2]) < 1e-6) and tpFaceDictionary: #It is a mostly vertical wall and has a dictionary
|
|
402
|
-
apertureRatio = Dictionary.
|
|
259
|
+
apertureRatio = Dictionary.ValueAtKey(tpFaceDictionary,'apertureRatio')
|
|
403
260
|
if apertureRatio:
|
|
404
261
|
hbRoomFace.apertures_by_ratio(apertureRatio, tolerance=0.01)
|
|
405
262
|
fType = honeybee.facetype.get_type_from_normal(Vector3D(tpCellFaceNormal[0],tpCellFaceNormal[1],tpCellFaceNormal[2]), roof_angle=30, floor_angle=150)
|
|
406
263
|
hbRoomFace.type = fType
|
|
407
264
|
hbRoomFaces.append(hbRoomFace)
|
|
408
|
-
room =
|
|
265
|
+
room = HBRoom(tpCellName, hbRoomFaces, 0.01, 1)
|
|
266
|
+
if addSensorGrid:
|
|
267
|
+
floor_mesh = room.generate_grid(0.5, 0.5, 1)
|
|
268
|
+
sensorGrids.append(SensorGrid.from_mesh3d(tpCellName+"_SG", floor_mesh))
|
|
409
269
|
heat_setpt = ScheduleRuleset.from_constant_value('Room Heating', heatingSetpoint, schedule_types.temperature)
|
|
410
270
|
cool_setpt = ScheduleRuleset.from_constant_value('Room Cooling', coolingSetpoint, schedule_types.temperature)
|
|
411
271
|
humidify_setpt = ScheduleRuleset.from_constant_value('Room Humidifying', humidifyingSetpoint, schedule_types.humidity)
|
|
@@ -422,112 +282,76 @@ class HB:
|
|
|
422
282
|
if tpCellStory:
|
|
423
283
|
room.story = tpCellStory
|
|
424
284
|
rooms.append(room)
|
|
425
|
-
|
|
426
|
-
#for room in rooms:
|
|
427
|
-
#room.properties.energy.construction_set = constr_set
|
|
428
|
-
#Room.stories_by_floor_height(rooms, min_difference=2.0)
|
|
285
|
+
HBRoom.solve_adjacency(rooms, 0.01)
|
|
429
286
|
|
|
287
|
+
hbShades = []
|
|
430
288
|
if(tpShadingFacesCluster):
|
|
431
289
|
hbShades = []
|
|
432
|
-
tpShadingFaces =
|
|
433
|
-
_ = tpShadingFacesCluster.Faces(None, tpShadingFaces)
|
|
290
|
+
tpShadingFaces = Topology.SubTopologies(tpShadingFacesCluster, subTopologyType="face")
|
|
434
291
|
for faceIndex, tpShadingFace in enumerate(tpShadingFaces):
|
|
435
292
|
faceVertices = []
|
|
436
|
-
|
|
293
|
+
faceVertices = Wire.Vertices(Face.ExternalBoundary(tpShadingFace))
|
|
437
294
|
facePoints = []
|
|
438
295
|
for aVertex in faceVertices:
|
|
439
296
|
facePoints.append(Point3D(aVertex.X(), aVertex.Y(), aVertex.Z()))
|
|
440
297
|
hbShadingFace = Face3D(facePoints, None, [])
|
|
441
|
-
hbShade =
|
|
298
|
+
hbShade = HBShade("SHADINGSURFACE_" + str(faceIndex+1), hbShadingFace)
|
|
442
299
|
hbShades.append(hbShade)
|
|
443
|
-
model =
|
|
300
|
+
model = HBModel(buildingName, rooms, orphaned_shades=hbShades)
|
|
301
|
+
if addSensorGrid:
|
|
302
|
+
model.properties.radiance.sensor_grids = []
|
|
303
|
+
model.properties.radiance.add_sensor_grids(sensorGrids)
|
|
444
304
|
return model
|
|
445
|
-
|
|
305
|
+
|
|
446
306
|
@staticmethod
|
|
447
|
-
def
|
|
307
|
+
def ProgramTypeByIdentifier(id):
|
|
448
308
|
"""
|
|
309
|
+
Returns the program type by the input identifying string.
|
|
310
|
+
|
|
449
311
|
Parameters
|
|
450
312
|
----------
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
filepath : TYPE
|
|
454
|
-
DESCRIPTION.
|
|
455
|
-
overwrite : TYPE
|
|
456
|
-
DESCRIPTION.
|
|
457
|
-
|
|
458
|
-
Raises
|
|
459
|
-
------
|
|
460
|
-
Exception
|
|
461
|
-
DESCRIPTION.
|
|
313
|
+
id : str
|
|
314
|
+
The identifiying string.
|
|
462
315
|
|
|
463
316
|
Returns
|
|
464
317
|
-------
|
|
465
|
-
|
|
466
|
-
|
|
318
|
+
HBProgram
|
|
319
|
+
The found built-in program.
|
|
467
320
|
|
|
468
321
|
"""
|
|
469
|
-
|
|
470
|
-
# Make sure the file extension is .hbjson
|
|
471
|
-
ext = filepath[len(filepath)-7:len(filepath)]
|
|
472
|
-
if ext.lower() != ".hbjson":
|
|
473
|
-
filepath = filepath+".hbjson"
|
|
474
|
-
f = None
|
|
475
|
-
try:
|
|
476
|
-
if overwrite == True:
|
|
477
|
-
f = open(filepath, "w")
|
|
478
|
-
else:
|
|
479
|
-
f = open(filepath, "x") # Try to create a new File
|
|
480
|
-
except:
|
|
481
|
-
raise Exception("Error: Could not create a new file at the following location: "+filepath)
|
|
482
|
-
if (f):
|
|
483
|
-
json.dump(hbModel.to_dict(), f, indent=4)
|
|
484
|
-
f.close()
|
|
485
|
-
return True
|
|
486
|
-
return False
|
|
322
|
+
return prog_type_lib.program_type_by_identifier(id)
|
|
487
323
|
|
|
488
324
|
@staticmethod
|
|
489
|
-
def
|
|
325
|
+
def ProgramTypes():
|
|
490
326
|
"""
|
|
491
|
-
|
|
492
|
-
----------
|
|
493
|
-
item : TYPE
|
|
494
|
-
DESCRIPTION.
|
|
327
|
+
Returns the list of available built-in program types.
|
|
495
328
|
|
|
496
329
|
Returns
|
|
497
330
|
-------
|
|
498
|
-
|
|
499
|
-
|
|
331
|
+
list
|
|
332
|
+
The list of available built-in program types.
|
|
500
333
|
|
|
501
334
|
"""
|
|
502
|
-
|
|
335
|
+
progTypes = []
|
|
336
|
+
progIdentifiers = list(prog_type_lib.PROGRAM_TYPES)
|
|
337
|
+
for progIdentifier in progIdentifiers:
|
|
338
|
+
progTypes.append(prog_type_lib.program_type_by_identifier(progIdentifier))
|
|
339
|
+
return [progTypes, progIdentifiers]
|
|
503
340
|
|
|
504
341
|
@staticmethod
|
|
505
|
-
def
|
|
342
|
+
def String(model):
|
|
506
343
|
"""
|
|
344
|
+
Returns the string representation of the input model.
|
|
345
|
+
|
|
507
346
|
Parameters
|
|
508
347
|
----------
|
|
509
|
-
|
|
510
|
-
|
|
348
|
+
model : HBModel
|
|
349
|
+
The input HB Model.
|
|
511
350
|
|
|
512
351
|
Returns
|
|
513
352
|
-------
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
"""
|
|
518
|
-
return prog_type_lib.program_type_by_identifier(item)
|
|
519
|
-
|
|
520
|
-
@staticmethod
|
|
521
|
-
def HBProgramTypes():
|
|
522
|
-
"""
|
|
523
|
-
Returns
|
|
524
|
-
-------
|
|
525
|
-
list
|
|
526
|
-
DESCRIPTION.
|
|
353
|
+
dict
|
|
354
|
+
A dictionary representing the input HB Model.
|
|
527
355
|
|
|
528
356
|
"""
|
|
529
|
-
|
|
530
|
-
progIdentifiers = list(prog_type_lib.PROGRAM_TYPES)
|
|
531
|
-
for progIdentifier in progIdentifiers:
|
|
532
|
-
progTypes.append(prog_type_lib.program_type_by_identifier(progIdentifier))
|
|
533
|
-
return [progTypes, progIdentifiers]
|
|
357
|
+
return model.to_dict()
|