topologicpy 0.4.8__py3-none-any.whl → 0.4.9__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/Aperture.py +46 -0
- topologicpy/Cell.py +1780 -0
- topologicpy/CellComplex.py +791 -0
- topologicpy/Cluster.py +591 -0
- topologicpy/Color.py +157 -0
- topologicpy/Context.py +56 -0
- topologicpy/DGL.py +2661 -0
- topologicpy/Dictionary.py +470 -0
- topologicpy/Edge.py +855 -0
- topologicpy/EnergyModel.py +1052 -0
- topologicpy/Face.py +1810 -0
- topologicpy/Graph.py +3526 -0
- topologicpy/Graph_Export.py +858 -0
- topologicpy/Grid.py +338 -0
- topologicpy/Helper.py +182 -0
- topologicpy/Honeybee.py +424 -0
- topologicpy/Matrix.py +255 -0
- topologicpy/Neo4jGraph.py +311 -0
- topologicpy/Plotly.py +1396 -0
- topologicpy/Polyskel.py +524 -0
- topologicpy/Process.py +1368 -0
- topologicpy/SQL.py +48 -0
- topologicpy/Shell.py +1418 -0
- topologicpy/Speckle.py +433 -0
- topologicpy/Topology.py +5854 -0
- topologicpy/UnitTest.py +29 -0
- topologicpy/Vector.py +555 -0
- topologicpy/Vertex.py +714 -0
- topologicpy/Wire.py +2346 -0
- topologicpy/__init__.py +20 -0
- topologicpy/bin/linux/topologic/__init__.py +2 -0
- topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/windows/topologic/TKBO-f6b191de.dll +0 -0
- topologicpy/bin/windows/topologic/TKBRep-e56a600e.dll +0 -0
- topologicpy/bin/windows/topologic/TKBool-7b8d47ae.dll +0 -0
- topologicpy/bin/windows/topologic/TKFillet-0ddbf0a8.dll +0 -0
- topologicpy/bin/windows/topologic/TKG2d-2e2dee3d.dll +0 -0
- topologicpy/bin/windows/topologic/TKG3d-6674513d.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomAlgo-d240e370.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomBase-df87aba5.dll +0 -0
- topologicpy/bin/windows/topologic/TKMath-45bd625a.dll +0 -0
- topologicpy/bin/windows/topologic/TKMesh-d6e826b1.dll +0 -0
- topologicpy/bin/windows/topologic/TKOffset-79b9cc94.dll +0 -0
- topologicpy/bin/windows/topologic/TKPrim-aa430a86.dll +0 -0
- topologicpy/bin/windows/topologic/TKShHealing-bb48be89.dll +0 -0
- topologicpy/bin/windows/topologic/TKTopAlgo-7d0d1e22.dll +0 -0
- topologicpy/bin/windows/topologic/TKernel-08c8cfbb.dll +0 -0
- topologicpy/bin/windows/topologic/__init__.py +2 -0
- topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
- {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/METADATA +1 -1
- topologicpy-0.4.9.dist-info/RECORD +77 -0
- topologicpy-0.4.9.dist-info/top_level.txt +1 -0
- topologicpy-0.4.8.dist-info/RECORD +0 -5
- topologicpy-0.4.8.dist-info/top_level.txt +0 -1
- {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/WHEEL +0 -0
topologicpy/Honeybee.py
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import subprocess
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
import honeybee.facetype
|
|
6
|
+
from honeybee.face import Face as HBFace
|
|
7
|
+
from honeybee.model import Model as HBModel
|
|
8
|
+
from honeybee.room import Room as HBRoom
|
|
9
|
+
from honeybee.shade import Shade as HBShade
|
|
10
|
+
from honeybee.aperture import Aperture as HBAperture
|
|
11
|
+
from honeybee.door import Door as HBDoor
|
|
12
|
+
except:
|
|
13
|
+
call = [sys.executable, '-m', 'pip', 'install', 'honeybee', '-t', sys.path[0]]
|
|
14
|
+
subprocess.run(call)
|
|
15
|
+
try:
|
|
16
|
+
import honeybee.facetype
|
|
17
|
+
from honeybee.face import Face as HBFace
|
|
18
|
+
from honeybee.model import Model as HBModel
|
|
19
|
+
from honeybee.room import Room as HBRoom
|
|
20
|
+
from honeybee.shade import Shade as HBShade
|
|
21
|
+
from honeybee.aperture import Aperture as HBAperture
|
|
22
|
+
from honeybee.door import Door as HBDoor
|
|
23
|
+
except:
|
|
24
|
+
print("Honeybee - ERROR: Could not import honeybee")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
import honeybee_energy.lib.constructionsets as constr_set_lib
|
|
29
|
+
import honeybee_energy.lib.programtypes as prog_type_lib
|
|
30
|
+
import honeybee_energy.lib.scheduletypelimits as schedule_types
|
|
31
|
+
from honeybee_energy.schedule.ruleset import ScheduleRuleset
|
|
32
|
+
from honeybee_energy.schedule.day import ScheduleDay
|
|
33
|
+
from honeybee_energy.load.setpoint import Setpoint
|
|
34
|
+
from honeybee_energy.load.hotwater import ServiceHotWater
|
|
35
|
+
except:
|
|
36
|
+
call = [sys.executable, '-m', 'pip', 'install', '-U', 'honeybee-energy[standards]', '-t', sys.path[0]]
|
|
37
|
+
subprocess.run(call)
|
|
38
|
+
try:
|
|
39
|
+
import honeybee_energy.lib.constructionsets as constr_set_lib
|
|
40
|
+
import honeybee_energy.lib.programtypes as prog_type_lib
|
|
41
|
+
import honeybee_energy.lib.scheduletypelimits as schedule_types
|
|
42
|
+
from honeybee_energy.schedule.ruleset import ScheduleRuleset
|
|
43
|
+
from honeybee_energy.schedule.day import ScheduleDay
|
|
44
|
+
from honeybee_energy.load.setpoint import Setpoint
|
|
45
|
+
from honeybee_energy.load.hotwater import ServiceHotWater
|
|
46
|
+
except:
|
|
47
|
+
print("Honeybee - ERROR: Could not import honeybee-energy")
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
51
|
+
except:
|
|
52
|
+
call = [sys.executable, '-m', 'pip', 'install', '-U', 'honeybee-radiance', '-t', sys.path[0]]
|
|
53
|
+
subprocess.run(call)
|
|
54
|
+
try:
|
|
55
|
+
from honeybee_radiance.sensorgrid import SensorGrid
|
|
56
|
+
except:
|
|
57
|
+
print("Honeybee - ERROR: Could not import honeybee-radiance")
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
from ladybug.dt import Time
|
|
61
|
+
except:
|
|
62
|
+
call = [sys.executable, '-m', 'pip', 'install', '-U', 'ladybug', '-t', sys.path[0]]
|
|
63
|
+
subprocess.run(call)
|
|
64
|
+
try:
|
|
65
|
+
from ladybug.dt import Time
|
|
66
|
+
except:
|
|
67
|
+
print("Honeybee - ERROR: Could not import ladybug")
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
from ladybug_geometry.geometry3d.face import Face3D
|
|
71
|
+
from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D
|
|
72
|
+
except:
|
|
73
|
+
call = [sys.executable, '-m', 'pip', 'install', '-U', 'ladybug-geometry', '-t', sys.path[0]]
|
|
74
|
+
subprocess.run(call)
|
|
75
|
+
try:
|
|
76
|
+
from ladybug_geometry.geometry3d.face import Face3D
|
|
77
|
+
from ladybug_geometry.geometry3d.pointvector import Point3D, Vector3D
|
|
78
|
+
except:
|
|
79
|
+
print("Honeybee - ERROR: Could not import ladybug-geometry")
|
|
80
|
+
|
|
81
|
+
import json
|
|
82
|
+
from topologicpy.Dictionary import Dictionary
|
|
83
|
+
import topologic
|
|
84
|
+
|
|
85
|
+
class Honeybee:
|
|
86
|
+
@staticmethod
|
|
87
|
+
def ConstructionSetByIdentifier(id):
|
|
88
|
+
"""
|
|
89
|
+
Returns the built-in construction set by the input identifying string.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
id : str
|
|
94
|
+
The construction set identifier.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
HBConstructionSet
|
|
99
|
+
The found built-in construction set.
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
return constr_set_lib.construction_set_by_identifier(id)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def ConstructionSets():
|
|
106
|
+
"""
|
|
107
|
+
Returns the list of built-in construction sets
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
list
|
|
112
|
+
The list of built-in construction sets.
|
|
113
|
+
|
|
114
|
+
"""
|
|
115
|
+
constrSets = []
|
|
116
|
+
constrIdentifiers = list(constr_set_lib.CONSTRUCTION_SETS)
|
|
117
|
+
for constrIdentifier in constrIdentifiers:
|
|
118
|
+
constrSets.append(constr_set_lib.construction_set_by_identifier(constrIdentifier))
|
|
119
|
+
return [constrSets, constrIdentifiers]
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def ExportToHBJSON(model, path, overwrite=True):
|
|
123
|
+
"""
|
|
124
|
+
Exports the input HB Model to a file.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
model : HBModel
|
|
129
|
+
The input HB Model.
|
|
130
|
+
path : str
|
|
131
|
+
The location of the output file.
|
|
132
|
+
overwrite : bool , optional
|
|
133
|
+
If set to True this method overwrites any existing file. Otherwise, it won't. The default is True.
|
|
134
|
+
|
|
135
|
+
Returns
|
|
136
|
+
-------
|
|
137
|
+
bool
|
|
138
|
+
Returns True if the operation is successful. Returns False otherwise.
|
|
139
|
+
|
|
140
|
+
"""
|
|
141
|
+
# hbModel, path = item
|
|
142
|
+
# Make sure the file extension is .hbjson
|
|
143
|
+
ext = path[len(path)-7:len(path)]
|
|
144
|
+
if ext.lower() != ".hbjson":
|
|
145
|
+
path = path+".hbjson"
|
|
146
|
+
f = None
|
|
147
|
+
try:
|
|
148
|
+
if overwrite == True:
|
|
149
|
+
f = open(path, "w")
|
|
150
|
+
else:
|
|
151
|
+
f = open(path, "x") # Try to create a new File
|
|
152
|
+
except:
|
|
153
|
+
raise Exception("Error: Could not create a new file at the following location: "+path)
|
|
154
|
+
if (f):
|
|
155
|
+
json.dump(model.to_dict(), f, indent=4)
|
|
156
|
+
f.close()
|
|
157
|
+
return True
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def ModelByTopology(tpBuilding,
|
|
162
|
+
tpShadingFacesCluster = None,
|
|
163
|
+
buildingName = "Generic_Building",
|
|
164
|
+
defaultProgramIdentifier = "Generic Office Program",
|
|
165
|
+
defaultConstructionSetIdentifier = "Default Generic Construction Set",
|
|
166
|
+
coolingSetpoint = 25.0,
|
|
167
|
+
heatingSetpoint = 20.0,
|
|
168
|
+
humidifyingSetpoint = 30.0,
|
|
169
|
+
dehumidifyingSetpoint = 55.0,
|
|
170
|
+
roomNameKey = "TOPOLOGIC_name",
|
|
171
|
+
roomTypeKey = "TOPOLOGIC_type",
|
|
172
|
+
apertureTypeKey = "TOPOLOGIC_type",
|
|
173
|
+
addSensorGrid = False):
|
|
174
|
+
"""
|
|
175
|
+
Creates an HB Model from the input Topology.
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
HBModel
|
|
184
|
+
The created HB Model
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
from topologicpy.Vertex import Vertex
|
|
188
|
+
from topologicpy.Wire import Wire
|
|
189
|
+
from topologicpy.Face import Face
|
|
190
|
+
from topologicpy.Cell import Cell
|
|
191
|
+
from topologicpy.Aperture import Aperture
|
|
192
|
+
from topologicpy.Topology import Topology
|
|
193
|
+
from topologicpy.Dictionary import Dictionary
|
|
194
|
+
|
|
195
|
+
def cellFloor(cell):
|
|
196
|
+
faces = []
|
|
197
|
+
_ = cell.Faces(None, faces)
|
|
198
|
+
c = [x.CenterOfMass().Z() for x in faces]
|
|
199
|
+
return round(min(c),2)
|
|
200
|
+
|
|
201
|
+
def floorLevels(cells, min_difference):
|
|
202
|
+
floors = [cellFloor(x) for x in cells]
|
|
203
|
+
floors = list(set(floors)) #create a unique list
|
|
204
|
+
floors.sort()
|
|
205
|
+
returnList = []
|
|
206
|
+
for aCell in cells:
|
|
207
|
+
for floorNumber, aFloor in enumerate(floors):
|
|
208
|
+
if abs(cellFloor(aCell) - aFloor) > min_difference:
|
|
209
|
+
continue
|
|
210
|
+
returnList.append("Floor"+str(floorNumber).zfill(2))
|
|
211
|
+
break
|
|
212
|
+
return returnList
|
|
213
|
+
|
|
214
|
+
def getKeyName(d, keyName):
|
|
215
|
+
keys = Dictionary.Keys(d)
|
|
216
|
+
for key in keys:
|
|
217
|
+
if key.lower() == keyName.lower():
|
|
218
|
+
return key
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
def createUniqueName(name, nameList, number):
|
|
222
|
+
if not (name in nameList):
|
|
223
|
+
return name
|
|
224
|
+
elif not ((name+"_"+str(number)) in nameList):
|
|
225
|
+
return name+"_"+str(number)
|
|
226
|
+
else:
|
|
227
|
+
return createUniqueName(name,nameList, number+1)
|
|
228
|
+
|
|
229
|
+
if not isinstance(tpBuilding, topologic.Topology):
|
|
230
|
+
return None
|
|
231
|
+
rooms = []
|
|
232
|
+
tpCells = []
|
|
233
|
+
_ = tpBuilding.Cells(None, tpCells)
|
|
234
|
+
# Sort cells by Z Levels
|
|
235
|
+
tpCells.sort(key=lambda c: cellFloor(c), reverse=False)
|
|
236
|
+
fl = floorLevels(tpCells, 2)
|
|
237
|
+
spaceNames = []
|
|
238
|
+
sensorGrids = []
|
|
239
|
+
for spaceNumber, tpCell in enumerate(tpCells):
|
|
240
|
+
tpDictionary = Topology.Dictionary(tpCell)
|
|
241
|
+
tpCellName = None
|
|
242
|
+
tpCellStory = None
|
|
243
|
+
tpCellProgramIdentifier = None
|
|
244
|
+
tpCellConstructionSetIdentifier = None
|
|
245
|
+
tpCellConditioned = True
|
|
246
|
+
if tpDictionary:
|
|
247
|
+
keyName = getKeyName(tpDictionary, 'Story')
|
|
248
|
+
try:
|
|
249
|
+
tpCellStory = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
250
|
+
if tpCellStory:
|
|
251
|
+
tpCellStory = tpCellStory.replace(" ","_")
|
|
252
|
+
except:
|
|
253
|
+
tpCellStory = fl[spaceNumber]
|
|
254
|
+
if roomNameKey:
|
|
255
|
+
keyName = getKeyName(tpDictionary, roomNameKey)
|
|
256
|
+
else:
|
|
257
|
+
keyName = getKeyName(tpDictionary, 'Name')
|
|
258
|
+
try:
|
|
259
|
+
tpCellName = Dictionary.ValueAtKey(tpDictionary,keyName)
|
|
260
|
+
if tpCellName:
|
|
261
|
+
tpCellName = createUniqueName(tpCellName.replace(" ","_"), spaceNames, 1)
|
|
262
|
+
except:
|
|
263
|
+
tpCellName = tpCellStory+"_SPACE_"+(str(spaceNumber+1))
|
|
264
|
+
if roomTypeKey:
|
|
265
|
+
keyName = getKeyName(tpDictionary, roomTypeKey)
|
|
266
|
+
try:
|
|
267
|
+
tpCellProgramIdentifier = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
268
|
+
if tpCellProgramIdentifier:
|
|
269
|
+
program = prog_type_lib.program_type_by_identifier(tpCellProgramIdentifier)
|
|
270
|
+
elif defaultProgramIdentifier:
|
|
271
|
+
program = prog_type_lib.program_type_by_identifier(defaultProgramIdentifier)
|
|
272
|
+
except:
|
|
273
|
+
program = prog_type_lib.office_program #Default Office Program as a last resort
|
|
274
|
+
keyName = getKeyName(tpDictionary, 'construction_set')
|
|
275
|
+
try:
|
|
276
|
+
tpCellConstructionSetIdentifier = Dictionary.ValueAtKey(tpDictionary, keyName)
|
|
277
|
+
if tpCellConstructionSetIdentifier:
|
|
278
|
+
constr_set = constr_set_lib.construction_set_by_identifier(tpCellConstructionSetIdentifier)
|
|
279
|
+
elif defaultConstructionSetIdentifier:
|
|
280
|
+
constr_set = constr_set_lib.construction_set_by_identifier(defaultConstructionSetIdentifier)
|
|
281
|
+
except:
|
|
282
|
+
constr_set = constr_set_lib.construction_set_by_identifier("Default Generic Construction Set")
|
|
283
|
+
else:
|
|
284
|
+
tpCellStory = fl[spaceNumber]
|
|
285
|
+
tpCellName = tpCellStory+"_SPACE_"+(str(spaceNumber+1))
|
|
286
|
+
program = prog_type_lib.office_program
|
|
287
|
+
constr_set = constr_set_lib.construction_set_by_identifier("Default Generic Construction Set")
|
|
288
|
+
spaceNames.append(tpCellName)
|
|
289
|
+
|
|
290
|
+
tpCellFaces = []
|
|
291
|
+
_ = tpCell.Faces(None, tpCellFaces)
|
|
292
|
+
if tpCellFaces:
|
|
293
|
+
hbRoomFaces = []
|
|
294
|
+
for tpFaceNumber, tpCellFace in enumerate(tpCellFaces):
|
|
295
|
+
tpCellFaceNormal = Face.NormalAtParameters(tpCellFace, 0.5, 0.5)
|
|
296
|
+
hbRoomFacePoints = []
|
|
297
|
+
tpFaceVertices = Wire.Vertices(Face.ExternalBoundary(tpCellFace))
|
|
298
|
+
for tpVertex in tpFaceVertices:
|
|
299
|
+
hbRoomFacePoints.append(Point3D(tpVertex.X(), tpVertex.Y(), tpVertex.Z()))
|
|
300
|
+
hbRoomFace = HBFace(tpCellName+'_Face_'+str(tpFaceNumber+1), Face3D(hbRoomFacePoints))
|
|
301
|
+
tpFaceApertures = []
|
|
302
|
+
_ = tpCellFace.Apertures(tpFaceApertures)
|
|
303
|
+
if tpFaceApertures:
|
|
304
|
+
for tpFaceApertureNumber, tpFaceAperture in enumerate(tpFaceApertures):
|
|
305
|
+
apertureTopology = Aperture.Topology(tpFaceAperture)
|
|
306
|
+
tpFaceApertureDictionary = Topology.Dictionary(apertureTopology)
|
|
307
|
+
if tpFaceApertureDictionary:
|
|
308
|
+
apertureKeyName = getKeyName(tpFaceApertureDictionary, apertureTypeKey)
|
|
309
|
+
tpFaceApertureType = Dictionary.ValueAtKey(tpFaceApertureDictionary,apertureKeyName)
|
|
310
|
+
hbFaceAperturePoints = []
|
|
311
|
+
tpFaceApertureVertices = []
|
|
312
|
+
tpFaceApertureVertices = Wire.Vertices(Face.ExternalBoundary(apertureTopology))
|
|
313
|
+
for tpFaceApertureVertex in tpFaceApertureVertices:
|
|
314
|
+
hbFaceAperturePoints.append(Point3D(tpFaceApertureVertex.X(), tpFaceApertureVertex.Y(), tpFaceApertureVertex.Z()))
|
|
315
|
+
if(tpFaceApertureType):
|
|
316
|
+
if ("door" in tpFaceApertureType.lower()):
|
|
317
|
+
hbFaceAperture = HBDoor(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Door_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
318
|
+
else:
|
|
319
|
+
hbFaceAperture = HBAperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
320
|
+
else:
|
|
321
|
+
hbFaceAperture = HBAperture(tpCellName+'_Face_'+str(tpFaceNumber+1)+'_Window_'+str(tpFaceApertureNumber), Face3D(hbFaceAperturePoints))
|
|
322
|
+
hbRoomFace.add_aperture(hbFaceAperture)
|
|
323
|
+
else:
|
|
324
|
+
tpFaceDictionary = Topology.Dictionary(tpCellFace)
|
|
325
|
+
if (abs(tpCellFaceNormal[2]) < 1e-6) and tpFaceDictionary: #It is a mostly vertical wall and has a dictionary
|
|
326
|
+
apertureRatio = Dictionary.ValueAtKey(tpFaceDictionary,'apertureRatio')
|
|
327
|
+
if apertureRatio:
|
|
328
|
+
hbRoomFace.apertures_by_ratio(apertureRatio, tolerance=0.01)
|
|
329
|
+
fType = honeybee.facetype.get_type_from_normal(Vector3D(tpCellFaceNormal[0],tpCellFaceNormal[1],tpCellFaceNormal[2]), roof_angle=30, floor_angle=150)
|
|
330
|
+
hbRoomFace.type = fType
|
|
331
|
+
hbRoomFaces.append(hbRoomFace)
|
|
332
|
+
room = HBRoom(tpCellName, hbRoomFaces, 0.01, 1)
|
|
333
|
+
if addSensorGrid:
|
|
334
|
+
floor_mesh = room.generate_grid(0.5, 0.5, 1)
|
|
335
|
+
sensorGrids.append(SensorGrid.from_mesh3d(tpCellName+"_SG", floor_mesh))
|
|
336
|
+
heat_setpt = ScheduleRuleset.from_constant_value('Room Heating', heatingSetpoint, schedule_types.temperature)
|
|
337
|
+
cool_setpt = ScheduleRuleset.from_constant_value('Room Cooling', coolingSetpoint, schedule_types.temperature)
|
|
338
|
+
humidify_setpt = ScheduleRuleset.from_constant_value('Room Humidifying', humidifyingSetpoint, schedule_types.humidity)
|
|
339
|
+
dehumidify_setpt = ScheduleRuleset.from_constant_value('Room Dehumidifying', dehumidifyingSetpoint, schedule_types.humidity)
|
|
340
|
+
setpoint = Setpoint('Room Setpoint', heat_setpt, cool_setpt, humidify_setpt, dehumidify_setpt)
|
|
341
|
+
simple_office = ScheduleDay('Simple Weekday', [0, 1, 0], [Time(0, 0), Time(9, 0), Time(17, 0)]) #Todo: Remove hardwired scheduleday
|
|
342
|
+
schedule = ScheduleRuleset('Office Water Use', simple_office, None, schedule_types.fractional) #Todo: Remove hardwired schedule
|
|
343
|
+
shw = ServiceHotWater('Office Hot Water', 0.1, schedule) #Todo: Remove hardwired schedule hot water
|
|
344
|
+
room.properties.energy.program_type = program
|
|
345
|
+
room.properties.energy.construction_set = constr_set
|
|
346
|
+
room.properties.energy.add_default_ideal_air() #Ideal Air Exchange
|
|
347
|
+
room.properties.energy.setpoint = setpoint #Heating/Cooling/Humidifying/Dehumidifying
|
|
348
|
+
room.properties.energy.service_hot_water = shw #Service Hot Water
|
|
349
|
+
if tpCellStory:
|
|
350
|
+
room.story = tpCellStory
|
|
351
|
+
rooms.append(room)
|
|
352
|
+
HBRoom.solve_adjacency(rooms, 0.01)
|
|
353
|
+
|
|
354
|
+
hbShades = []
|
|
355
|
+
if(tpShadingFacesCluster):
|
|
356
|
+
hbShades = []
|
|
357
|
+
tpShadingFaces = Topology.SubTopologies(tpShadingFacesCluster, subTopologyType="face")
|
|
358
|
+
for faceIndex, tpShadingFace in enumerate(tpShadingFaces):
|
|
359
|
+
faceVertices = []
|
|
360
|
+
faceVertices = Wire.Vertices(Face.ExternalBoundary(tpShadingFace))
|
|
361
|
+
facePoints = []
|
|
362
|
+
for aVertex in faceVertices:
|
|
363
|
+
facePoints.append(Point3D(aVertex.X(), aVertex.Y(), aVertex.Z()))
|
|
364
|
+
hbShadingFace = Face3D(facePoints, None, [])
|
|
365
|
+
hbShade = HBShade("SHADINGSURFACE_" + str(faceIndex+1), hbShadingFace)
|
|
366
|
+
hbShades.append(hbShade)
|
|
367
|
+
model = HBModel(buildingName, rooms, orphaned_shades=hbShades)
|
|
368
|
+
if addSensorGrid:
|
|
369
|
+
model.properties.radiance.sensor_grids = []
|
|
370
|
+
model.properties.radiance.add_sensor_grids(sensorGrids)
|
|
371
|
+
return model
|
|
372
|
+
|
|
373
|
+
@staticmethod
|
|
374
|
+
def ProgramTypeByIdentifier(id):
|
|
375
|
+
"""
|
|
376
|
+
Returns the program type by the input identifying string.
|
|
377
|
+
|
|
378
|
+
Parameters
|
|
379
|
+
----------
|
|
380
|
+
id : str
|
|
381
|
+
The identifiying string.
|
|
382
|
+
|
|
383
|
+
Returns
|
|
384
|
+
-------
|
|
385
|
+
HBProgram
|
|
386
|
+
The found built-in program.
|
|
387
|
+
|
|
388
|
+
"""
|
|
389
|
+
return prog_type_lib.program_type_by_identifier(id)
|
|
390
|
+
|
|
391
|
+
@staticmethod
|
|
392
|
+
def ProgramTypes():
|
|
393
|
+
"""
|
|
394
|
+
Returns the list of available built-in program types.
|
|
395
|
+
|
|
396
|
+
Returns
|
|
397
|
+
-------
|
|
398
|
+
list
|
|
399
|
+
The list of available built-in program types.
|
|
400
|
+
|
|
401
|
+
"""
|
|
402
|
+
progTypes = []
|
|
403
|
+
progIdentifiers = list(prog_type_lib.PROGRAM_TYPES)
|
|
404
|
+
for progIdentifier in progIdentifiers:
|
|
405
|
+
progTypes.append(prog_type_lib.program_type_by_identifier(progIdentifier))
|
|
406
|
+
return [progTypes, progIdentifiers]
|
|
407
|
+
|
|
408
|
+
@staticmethod
|
|
409
|
+
def String(model):
|
|
410
|
+
"""
|
|
411
|
+
Returns the string representation of the input model.
|
|
412
|
+
|
|
413
|
+
Parameters
|
|
414
|
+
----------
|
|
415
|
+
model : HBModel
|
|
416
|
+
The input HB Model.
|
|
417
|
+
|
|
418
|
+
Returns
|
|
419
|
+
-------
|
|
420
|
+
dict
|
|
421
|
+
A dictionary representing the input HB Model.
|
|
422
|
+
|
|
423
|
+
"""
|
|
424
|
+
return model.to_dict()
|
topologicpy/Matrix.py
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
class Matrix:
|
|
4
|
+
@staticmethod
|
|
5
|
+
def Add(matA, matB):
|
|
6
|
+
"""
|
|
7
|
+
Description
|
|
8
|
+
----------
|
|
9
|
+
Adds the two input matrices.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
matA : list
|
|
14
|
+
The first input matrix.
|
|
15
|
+
matB : list
|
|
16
|
+
The second input matrix.
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
list
|
|
21
|
+
The matrix resulting from the addition of the two input matrices.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
matC = []
|
|
25
|
+
if not isinstance(matA, list):
|
|
26
|
+
return None
|
|
27
|
+
if not isinstance(matB, list):
|
|
28
|
+
return None
|
|
29
|
+
for i in range(len(matA)):
|
|
30
|
+
tempRow = []
|
|
31
|
+
for j in range(len(matB)):
|
|
32
|
+
tempRow.append(matA[i][j] + matB[i][j])
|
|
33
|
+
matC.append(tempRow)
|
|
34
|
+
return matC
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def ByRotation(rx=0, ry=0, rz=0, order="xyz"):
|
|
38
|
+
"""
|
|
39
|
+
Description
|
|
40
|
+
----------
|
|
41
|
+
Creates a 4x4 rotation matrix.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
rx : float , optional
|
|
46
|
+
The desired rotation around the X axis. The default is 0.
|
|
47
|
+
ry : float , optional
|
|
48
|
+
The desired rotation around the Y axis. The default is 0.
|
|
49
|
+
rz : float , optional
|
|
50
|
+
The desired rotation around the Z axis. The default is 0.
|
|
51
|
+
order : string , optional
|
|
52
|
+
The order by which the roatations will be applied. The possible values are any permutation of "xyz". This input is case insensitive. The default is "xyz".
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
list
|
|
57
|
+
The created 4X4 rotation matrix.
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
def rotateXMatrix(radians):
|
|
61
|
+
""" Return matrix for rotating about the x-axis by 'radians' radians """
|
|
62
|
+
c = math.cos(radians)
|
|
63
|
+
s = math.sin(radians)
|
|
64
|
+
return [[1, 0, 0, 0],
|
|
65
|
+
[0, c,-s, 0],
|
|
66
|
+
[0, s, c, 0],
|
|
67
|
+
[0, 0, 0, 1]]
|
|
68
|
+
|
|
69
|
+
def rotateYMatrix(radians):
|
|
70
|
+
""" Return matrix for rotating about the y-axis by 'radians' radians """
|
|
71
|
+
|
|
72
|
+
c = math.cos(radians)
|
|
73
|
+
s = math.sin(radians)
|
|
74
|
+
return [[ c, 0, s, 0],
|
|
75
|
+
[ 0, 1, 0, 0],
|
|
76
|
+
[-s, 0, c, 0],
|
|
77
|
+
[ 0, 0, 0, 1]]
|
|
78
|
+
|
|
79
|
+
def rotateZMatrix(radians):
|
|
80
|
+
""" Return matrix for rotating about the z-axis by 'radians' radians """
|
|
81
|
+
|
|
82
|
+
c = math.cos(radians)
|
|
83
|
+
s = math.sin(radians)
|
|
84
|
+
return [[c,-s, 0, 0],
|
|
85
|
+
[s, c, 0, 0],
|
|
86
|
+
[0, 0, 1, 0],
|
|
87
|
+
[0, 0, 0, 1]]
|
|
88
|
+
|
|
89
|
+
xMat = rotateXMatrix(math.radians(rx))
|
|
90
|
+
yMat = rotateYMatrix(math.radians(ry))
|
|
91
|
+
zMat = rotateZMatrix(math.radians(rz))
|
|
92
|
+
if order.lower() == "xyz":
|
|
93
|
+
return Matrix.Multiply(Matrix.Multiply(zMat,yMat),xMat)
|
|
94
|
+
if order.lower() == "xzy":
|
|
95
|
+
return Matrix.Multiply(Matrix.Multiply(yMat,zMat),xMat)
|
|
96
|
+
if order.lower() == "yxz":
|
|
97
|
+
return Matrix.Multiply(Matrix.Multiply(zMat,xMat),yMat)
|
|
98
|
+
if order.lower == "yzx":
|
|
99
|
+
return Matrix.Multiply(Matrix.Multiply(xMat,zMat),yMat)
|
|
100
|
+
if order.lower() == "zxy":
|
|
101
|
+
return Matrix.Multiply(Matrix.Multiply(yMat,xMat),zMat)
|
|
102
|
+
if order.lower() == "zyx":
|
|
103
|
+
return Matrix.Multiply(Matrix.Multiply(xMat,yMat),zMat)
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def ByScaling(sx=1.0, sy=1.0, sz=1.0):
|
|
107
|
+
"""
|
|
108
|
+
Description
|
|
109
|
+
----------
|
|
110
|
+
Creates a 4x4 scaling matrix.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
sx : float , optional
|
|
115
|
+
The desired scaling factor along the X axis. The default is 1.
|
|
116
|
+
sy : float , optional
|
|
117
|
+
The desired scaling factor along the X axis. The default is 1.
|
|
118
|
+
sz : float , optional
|
|
119
|
+
The desired scaling factor along the X axis. The default is 1.
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
list
|
|
124
|
+
The created 4X4 scaling matrix.
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
return Matrix.Transpose([[sx,0,0,0],
|
|
128
|
+
[0,sy,0,0],
|
|
129
|
+
[0,0,sz,0],
|
|
130
|
+
[0,0,0,1]])
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def ByTranslation(tx=0, ty=0, tz=0):
|
|
134
|
+
"""
|
|
135
|
+
Description
|
|
136
|
+
----------
|
|
137
|
+
Creates a 4x4 translation matrix.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
tx : float , optional
|
|
142
|
+
The desired translation distance along the X axis. The default is 0.
|
|
143
|
+
ty : float , optional
|
|
144
|
+
The desired translation distance along the X axis. The default is 0.
|
|
145
|
+
tz : float , optional
|
|
146
|
+
The desired translation distance along the X axis. The default is 0.
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
list
|
|
151
|
+
The created 4X4 translation matrix.
|
|
152
|
+
|
|
153
|
+
"""
|
|
154
|
+
return Matrix.Transpose([[1,0,0,tx],
|
|
155
|
+
[0,1,0,ty],
|
|
156
|
+
[0,0,1,tz],
|
|
157
|
+
[0,0,0,1]])
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def Multiply(matA, matB):
|
|
161
|
+
"""
|
|
162
|
+
Description
|
|
163
|
+
----------
|
|
164
|
+
Multiplies the two input matrices.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
matA : list
|
|
169
|
+
The first input matrix.
|
|
170
|
+
matB : list
|
|
171
|
+
The second input matrix.
|
|
172
|
+
|
|
173
|
+
Returns
|
|
174
|
+
-------
|
|
175
|
+
list
|
|
176
|
+
The matrix resulting from the multiplication of the two input matrices.
|
|
177
|
+
|
|
178
|
+
"""
|
|
179
|
+
if not isinstance(matA, list):
|
|
180
|
+
return None
|
|
181
|
+
if not isinstance(matB, list):
|
|
182
|
+
return None
|
|
183
|
+
nr = len(matA)
|
|
184
|
+
nc = len(matA[0])
|
|
185
|
+
matC = []
|
|
186
|
+
for i in range(nr):
|
|
187
|
+
tempRow = []
|
|
188
|
+
for j in range(nc):
|
|
189
|
+
tempRow.append(0)
|
|
190
|
+
matC.append(tempRow)
|
|
191
|
+
if not isinstance(matA, list):
|
|
192
|
+
return None
|
|
193
|
+
if not isinstance(matB, list):
|
|
194
|
+
return None
|
|
195
|
+
# iterate through rows of X
|
|
196
|
+
for i in range(len(matA)):
|
|
197
|
+
# iterate through columns of Y
|
|
198
|
+
tempRow = []
|
|
199
|
+
for j in range(len(matB[0])):
|
|
200
|
+
# iterate through rows of Y
|
|
201
|
+
for k in range(len(matB)):
|
|
202
|
+
matC[i][j] += matA[i][k] * matB[k][j]
|
|
203
|
+
return matC
|
|
204
|
+
|
|
205
|
+
@staticmethod
|
|
206
|
+
def Subtract(matA, matB):
|
|
207
|
+
"""
|
|
208
|
+
Description
|
|
209
|
+
----------
|
|
210
|
+
Subtracts the two input matrices.
|
|
211
|
+
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
matA : list
|
|
215
|
+
The first input matrix.
|
|
216
|
+
matB : list
|
|
217
|
+
The second input matrix.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
list
|
|
222
|
+
The matrix resulting from the subtraction of the second input matrix from the first input matrix.
|
|
223
|
+
|
|
224
|
+
"""
|
|
225
|
+
if not isinstance(matA, list):
|
|
226
|
+
return None
|
|
227
|
+
if not isinstance(matB, list):
|
|
228
|
+
return None
|
|
229
|
+
matC = []
|
|
230
|
+
for i in range(len(matA)):
|
|
231
|
+
tempRow = []
|
|
232
|
+
for j in range(len(matB)):
|
|
233
|
+
tempRow.append(matA[i][j] - matB[i][j])
|
|
234
|
+
matC.append(tempRow)
|
|
235
|
+
return matC
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def Transpose(matrix):
|
|
239
|
+
"""
|
|
240
|
+
Description
|
|
241
|
+
----------
|
|
242
|
+
Transposes the input matrix.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
matrix : list
|
|
247
|
+
The input matrix.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
list
|
|
252
|
+
The transposed matrix.
|
|
253
|
+
|
|
254
|
+
"""
|
|
255
|
+
return [list(x) for x in zip(*matrix)]
|