osut 0.6.0__py3-none-any.whl → 0.7.0__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.
- osut/osut.py +106 -102
- {osut-0.6.0.dist-info → osut-0.7.0.dist-info}/METADATA +25 -2
- osut-0.7.0.dist-info/RECORD +7 -0
- osut-0.6.0.dist-info/RECORD +0 -7
- {osut-0.6.0.dist-info → osut-0.7.0.dist-info}/WHEEL +0 -0
- {osut-0.6.0.dist-info → osut-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {osut-0.6.0.dist-info → osut-0.7.0.dist-info}/top_level.txt +0 -0
osut/osut.py
CHANGED
|
@@ -107,8 +107,8 @@ _film = dict(
|
|
|
107
107
|
|
|
108
108
|
# Default (~1980s) envelope Uo (W/m2•K), based on surface type.
|
|
109
109
|
_uo = dict(
|
|
110
|
-
shading = None,
|
|
111
|
-
partition = None,
|
|
110
|
+
shading = None, # N/A
|
|
111
|
+
partition = None, # N/A
|
|
112
112
|
wall = 0.384, # rated R14.8 hr•ft2F/Btu
|
|
113
113
|
roof = 0.327, # rated R17.6 hr•ft2F/Btu
|
|
114
114
|
floor = 0.317, # rated R17.9 hr•ft2F/Btu (exposed floor)
|
|
@@ -335,9 +335,8 @@ def genConstruction(model=None, specs=dict()):
|
|
|
335
335
|
ide = "OSut.CON." + specs["type"]
|
|
336
336
|
if specs["type"] not in uo():
|
|
337
337
|
return oslg.invalid("surface type", mth, 2, CN.ERR)
|
|
338
|
-
if "uo" not in specs:
|
|
339
|
-
specs["uo"] = uo()[ specs["type"] ]
|
|
340
338
|
|
|
339
|
+
if "uo" not in specs: specs["uo"] = uo()[ specs["type"] ] # can be None
|
|
341
340
|
u = specs["uo"]
|
|
342
341
|
|
|
343
342
|
if u:
|
|
@@ -348,6 +347,8 @@ def genConstruction(model=None, specs=dict()):
|
|
|
348
347
|
|
|
349
348
|
if u < 0:
|
|
350
349
|
return oslg.negative(id + " Uo", mth, CN.ERR)
|
|
350
|
+
if round(u, 2) == 0:
|
|
351
|
+
return oslg.zero(id + " Uo", mth, CN.ERR)
|
|
351
352
|
if u > 5.678:
|
|
352
353
|
return oslg.invalid(id + " Uo (> 5.678)", mth, 2, CN.ERR)
|
|
353
354
|
|
|
@@ -581,7 +582,7 @@ def genConstruction(model=None, specs=dict()):
|
|
|
581
582
|
a["compo" ]["id" ] = "OSut." + mt + ".%03d" % int(d * 1000)
|
|
582
583
|
|
|
583
584
|
elif specs["type"] == "window":
|
|
584
|
-
a["glazing"]["u" ] =
|
|
585
|
+
a["glazing"]["u" ] = u if u else uo()["window"]
|
|
585
586
|
a["glazing"]["shgc"] = 0.450
|
|
586
587
|
if "shgc" in specs: a["glazing"]["shgc"] = specs["shgc"]
|
|
587
588
|
a["glazing"]["id" ] = "OSut.window"
|
|
@@ -589,7 +590,7 @@ def genConstruction(model=None, specs=dict()):
|
|
|
589
590
|
a["glazing"]["id" ] += ".SHGC%d" % (a["glazing"]["shgc"]*100)
|
|
590
591
|
|
|
591
592
|
elif specs["type"] == "skylight":
|
|
592
|
-
a["glazing"]["u" ] =
|
|
593
|
+
a["glazing"]["u" ] = u if u else uo()["skylight"]
|
|
593
594
|
a["glazing"]["shgc"] = 0.450
|
|
594
595
|
if "shgc" in specs: a["glazing"]["shgc"] = specs["shgc"]
|
|
595
596
|
a["glazing"]["id" ] = "OSut.skylight"
|
|
@@ -599,14 +600,14 @@ def genConstruction(model=None, specs=dict()):
|
|
|
599
600
|
if a["glazing"]:
|
|
600
601
|
layers = openstudio.model.FenestrationMaterialVector()
|
|
601
602
|
|
|
602
|
-
|
|
603
|
+
u0 = a["glazing"]["u" ]
|
|
603
604
|
shgc = a["glazing"]["shgc"]
|
|
604
605
|
lyr = model.getSimpleGlazingByName(a["glazing"]["id"])
|
|
605
606
|
|
|
606
607
|
if lyr:
|
|
607
608
|
lyr = lyr.get()
|
|
608
609
|
else:
|
|
609
|
-
lyr = openstudio.model.SimpleGlazing(model,
|
|
610
|
+
lyr = openstudio.model.SimpleGlazing(model, u0, shgc)
|
|
610
611
|
lyr.setName(a["glazing"]["id"])
|
|
611
612
|
|
|
612
613
|
layers.append(lyr)
|
|
@@ -635,49 +636,54 @@ def genConstruction(model=None, specs=dict()):
|
|
|
635
636
|
|
|
636
637
|
layers.append(lyr)
|
|
637
638
|
|
|
638
|
-
c
|
|
639
|
+
c = openstudio.model.Construction(layers)
|
|
639
640
|
c.setName(ide)
|
|
640
641
|
|
|
641
642
|
# Adjust insulating layer thickness or conductivity to match requested Uo.
|
|
642
|
-
if not a["glazing"]:
|
|
643
|
-
ro = 1 /
|
|
643
|
+
if u and not a["glazing"]:
|
|
644
|
+
ro = 1 / u - flm
|
|
644
645
|
|
|
645
|
-
if
|
|
646
|
-
layer
|
|
646
|
+
if ro > 0:
|
|
647
|
+
if specs["type"] == "door": # 1x layer, adjust conductivity
|
|
648
|
+
layer = c.getLayer(0).to_StandardOpaqueMaterial()
|
|
647
649
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
+
if not layer:
|
|
651
|
+
return oslg.invalid(id + " standard material?", mth, 0)
|
|
650
652
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
653
|
+
layer = layer.get()
|
|
654
|
+
k = layer.thickness() / ro
|
|
655
|
+
layer.setConductivity(k)
|
|
654
656
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
+
else: # multiple layers, adjust insulating layer thickness
|
|
658
|
+
lyr = insulatingLayer(c)
|
|
657
659
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
+
if not lyr["index"] or not lyr["type"] or not lyr["r"]:
|
|
661
|
+
return oslg.invalid(id + " construction", mth, 0)
|
|
660
662
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
+
index = lyr["index"]
|
|
664
|
+
layer = c.getLayer(index).to_StandardOpaqueMaterial()
|
|
663
665
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
+
if not layer:
|
|
667
|
+
return oslg.invalid(id + " material %d" % index, mth, 0)
|
|
666
668
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
669
|
+
layer = layer.get()
|
|
670
|
+
k = layer.conductivity()
|
|
671
|
+
d = (ro - rsi(c) + lyr["r"]) * k
|
|
670
672
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
+
if d < 0.03:
|
|
674
|
+
m = id + " adjusted material thickness"
|
|
675
|
+
return oslg.invalid(m, mth, 0)
|
|
673
676
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
+
nom = re.sub(r'[^a-zA-Z]', '', layer.nameString())
|
|
678
|
+
nom = re.sub(r'OSut', '', nom)
|
|
679
|
+
nom = "OSut." + nom + ".%03d" % int(d * 1000)
|
|
677
680
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
+
if model.getStandardOpaqueMaterialByName(nom):
|
|
682
|
+
omat = model.getStandardOpaqueMaterialByName(nom).get()
|
|
683
|
+
c.setLayer(index, omat)
|
|
684
|
+
else:
|
|
685
|
+
layer.setName(nom)
|
|
686
|
+
layer.setThickness(d)
|
|
681
687
|
|
|
682
688
|
return c
|
|
683
689
|
|
|
@@ -1650,7 +1656,7 @@ def scheduleIntervalMinMax(sched=None) -> dict:
|
|
|
1650
1656
|
- "min" (float): min temperature. (None if invalid inputs - see logs).
|
|
1651
1657
|
- "max" (float): max temperature. (None if invalid inputs - see logs).
|
|
1652
1658
|
"""
|
|
1653
|
-
mth = "osut.
|
|
1659
|
+
mth = "osut.scheduleIntervalMinMax"
|
|
1654
1660
|
cl = openstudio.model.ScheduleInterval
|
|
1655
1661
|
vals = []
|
|
1656
1662
|
res = dict(min=None, max=None)
|
|
@@ -1658,10 +1664,19 @@ def scheduleIntervalMinMax(sched=None) -> dict:
|
|
|
1658
1664
|
if not isinstance(sched, cl):
|
|
1659
1665
|
return oslg.mismatch("sched", sched, cl, mth, CN.DBG, res)
|
|
1660
1666
|
|
|
1661
|
-
|
|
1667
|
+
values = sched.timeSeries().values()
|
|
1662
1668
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1669
|
+
for i in range(len(values)):
|
|
1670
|
+
try:
|
|
1671
|
+
value = float(values[i])
|
|
1672
|
+
vals.append(value)
|
|
1673
|
+
except:
|
|
1674
|
+
oslg.invalid("numerical at %d" % i, mth, 1, CN.ERR)
|
|
1675
|
+
|
|
1676
|
+
if not vals: return res
|
|
1677
|
+
|
|
1678
|
+
res["min"] = min(vals)
|
|
1679
|
+
res["max"] = max(vals)
|
|
1665
1680
|
|
|
1666
1681
|
try:
|
|
1667
1682
|
res["min"] = float(res["min"])
|
|
@@ -2595,6 +2610,17 @@ def availabilitySchedule(model=None, avl=""):
|
|
|
2595
2610
|
|
|
2596
2611
|
return schedule
|
|
2597
2612
|
|
|
2613
|
+
# ---- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---- #
|
|
2614
|
+
# This final set of utilities targets OpenStudio geometry. Many of the
|
|
2615
|
+
# following geometry methods rely on Boost as an OpenStudio dependency.
|
|
2616
|
+
# As per Boost requirements, points (e.g. vertical polygon) must be 'aligned':
|
|
2617
|
+
# - first rotated/tilted as to lay flat along XY plane (Z-axis ~= 0)
|
|
2618
|
+
# - initial Z-axis values now become Y-axis values
|
|
2619
|
+
# - points with the lowest X-axis values are 'aligned' along X-axis (0)
|
|
2620
|
+
# - points with the lowest Z-axis values are 'aligned' along Y-axis (0)
|
|
2621
|
+
# - for several Boost methods, points must be clockwise in sequence
|
|
2622
|
+
#
|
|
2623
|
+
# Check OSut's poly() method, which offers such Boost-related options.
|
|
2598
2624
|
|
|
2599
2625
|
def transforms(group=None) -> dict:
|
|
2600
2626
|
""""Returns OpenStudio site/space transformation & rotation angle.
|
|
@@ -2698,7 +2724,7 @@ def p3Dv(pts=None) -> openstudio.Point3dVector:
|
|
|
2698
2724
|
pts (list): OpenStudio 3D points.
|
|
2699
2725
|
|
|
2700
2726
|
Returns:
|
|
2701
|
-
openstudio.Point3dVector: Vector of 3D points (see logs if empty).
|
|
2727
|
+
openstudio.Point3dVector: Vector of 3D points (see 'p3Dv' logs if empty).
|
|
2702
2728
|
|
|
2703
2729
|
"""
|
|
2704
2730
|
mth = "osut.p3Dv"
|
|
@@ -2711,7 +2737,10 @@ def p3Dv(pts=None) -> openstudio.Point3dVector:
|
|
|
2711
2737
|
elif isinstance(pts, openstudio.Point3dVector):
|
|
2712
2738
|
return pts
|
|
2713
2739
|
elif isinstance(pts, openstudio.model.PlanarSurface):
|
|
2714
|
-
|
|
2740
|
+
for vt in pts.vertices():
|
|
2741
|
+
pt = openstudio.Point3d(vt.x(), vt.y(), vt.z())
|
|
2742
|
+
v.append(pt)
|
|
2743
|
+
return v
|
|
2715
2744
|
|
|
2716
2745
|
try:
|
|
2717
2746
|
pts = list(pts)
|
|
@@ -3030,7 +3059,7 @@ def nextUp(pts=None, pt=None):
|
|
|
3030
3059
|
None: If invalid inputs (see logs).
|
|
3031
3060
|
|
|
3032
3061
|
"""
|
|
3033
|
-
mth = "osut.
|
|
3062
|
+
mth = "osut.nextUp"
|
|
3034
3063
|
pts = p3Dv(pts)
|
|
3035
3064
|
cl = openstudio.Point3d
|
|
3036
3065
|
|
|
@@ -3168,7 +3197,7 @@ def uniques(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3168
3197
|
Requested number of unique points (0 returns all).
|
|
3169
3198
|
|
|
3170
3199
|
Returns:
|
|
3171
|
-
openstudio.Point3dVector: Unique points (see logs
|
|
3200
|
+
openstudio.Point3dVector: Unique points (see logs).
|
|
3172
3201
|
|
|
3173
3202
|
"""
|
|
3174
3203
|
mth = "osut.uniques"
|
|
@@ -3179,7 +3208,8 @@ def uniques(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3179
3208
|
try:
|
|
3180
3209
|
n = int(n)
|
|
3181
3210
|
except:
|
|
3182
|
-
|
|
3211
|
+
oslg.mismatch("n points", n, int, mth, CN.DBG)
|
|
3212
|
+
n = 0
|
|
3183
3213
|
|
|
3184
3214
|
for pt in pts:
|
|
3185
3215
|
if not holds(v, pt): v.append(pt)
|
|
@@ -3314,7 +3344,7 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool:
|
|
|
3314
3344
|
|
|
3315
3345
|
Returns:
|
|
3316
3346
|
bool: Whether a 3D point lies ~along a 3D point segment.
|
|
3317
|
-
False: If invalid inputs.
|
|
3347
|
+
False: If invalid inputs (see logs).
|
|
3318
3348
|
|
|
3319
3349
|
"""
|
|
3320
3350
|
mth = "osut.isPointAlongSegment"
|
|
@@ -3323,12 +3353,10 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool:
|
|
|
3323
3353
|
|
|
3324
3354
|
if not isinstance(p0, cl1):
|
|
3325
3355
|
return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False)
|
|
3326
|
-
if not isSegment(sg):
|
|
3327
|
-
return oslg.mismatch("segment", sg, cl2, mth, CN.DBG, False)
|
|
3328
|
-
|
|
3356
|
+
if not isSegment(sg): return False
|
|
3329
3357
|
if holds(sg, p0): return True
|
|
3330
3358
|
|
|
3331
|
-
a = sg[0]
|
|
3359
|
+
a = sg[ 0]
|
|
3332
3360
|
b = sg[-1]
|
|
3333
3361
|
ab = b - a
|
|
3334
3362
|
abn = b - a
|
|
@@ -3370,7 +3398,7 @@ def isPointAlongSegments(p0=None, sgs=[]) -> bool:
|
|
|
3370
3398
|
if not sgs:
|
|
3371
3399
|
return oslg.empty("segments", mth, CN.DBG, False)
|
|
3372
3400
|
if not isinstance(p0, cl1):
|
|
3373
|
-
return oslg.mismatch("point", p0,
|
|
3401
|
+
return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False)
|
|
3374
3402
|
|
|
3375
3403
|
for sg in sgs:
|
|
3376
3404
|
if isPointAlongSegment(p0, sg): return True
|
|
@@ -3444,14 +3472,6 @@ def lineIntersection(s1=[], s2=[]):
|
|
|
3444
3472
|
xa1b1 = a.cross(a1b1)
|
|
3445
3473
|
xa1b2 = a.cross(a1b2)
|
|
3446
3474
|
|
|
3447
|
-
if xa1b1.length() < CN.TOL2:
|
|
3448
|
-
if isPointAlongSegment(a1, [a2, b1]): return None
|
|
3449
|
-
if isPointAlongSegment(a2, [a1, b1]): return None
|
|
3450
|
-
|
|
3451
|
-
if xa1b2.length() < CN.TOL2:
|
|
3452
|
-
if isPointAlongSegment(a1, [a2, b2]): return None
|
|
3453
|
-
if isPointAlongSegment(a2, [a1, b2]): return None
|
|
3454
|
-
|
|
3455
3475
|
# Both segment endpoints can't be 'behind' point.
|
|
3456
3476
|
if a.dot(a1b1) < 0 and a.dot(a1b2) < 0: return None
|
|
3457
3477
|
|
|
@@ -3632,7 +3652,7 @@ def blc(pts=None) -> openstudio.Point3dVector:
|
|
|
3632
3652
|
|
|
3633
3653
|
|
|
3634
3654
|
def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
3635
|
-
"""Returns
|
|
3655
|
+
"""Returns non-collinear points in an OpenStudio 3D point vector.
|
|
3636
3656
|
|
|
3637
3657
|
Args:
|
|
3638
3658
|
pts (openstudio.Point3dVector):
|
|
@@ -3641,11 +3661,10 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3641
3661
|
Requested number of non-collinears (0 returns all).
|
|
3642
3662
|
|
|
3643
3663
|
Returns:
|
|
3644
|
-
openstudio.Point3dVector: non-collinears (see logs
|
|
3664
|
+
openstudio.Point3dVector: non-collinears (see logs).
|
|
3645
3665
|
|
|
3646
3666
|
"""
|
|
3647
3667
|
mth = "osut.nonCollinears"
|
|
3648
|
-
v = openstudio.Point3dVector()
|
|
3649
3668
|
a = []
|
|
3650
3669
|
pts = uniques(pts)
|
|
3651
3670
|
if len(pts) < 3: return pts
|
|
@@ -3653,12 +3672,8 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3653
3672
|
try:
|
|
3654
3673
|
n = int(n)
|
|
3655
3674
|
except:
|
|
3656
|
-
oslg.mismatch("n
|
|
3657
|
-
|
|
3658
|
-
if n > len(pts):
|
|
3659
|
-
return oslg.invalid("+n non-collinears", mth, 0, CN.ERR, v)
|
|
3660
|
-
elif n < 0 and abs(n) > len(pts):
|
|
3661
|
-
return oslg.invalid("-n non-collinears", mth, 0, CN.ERR, v)
|
|
3675
|
+
oslg.mismatch("n points", n, int, mth, CN.DBG)
|
|
3676
|
+
n = 0
|
|
3662
3677
|
|
|
3663
3678
|
# Evaluate cross product of vectors of 3x sequential points.
|
|
3664
3679
|
for i2, p2 in enumerate(pts):
|
|
@@ -3680,9 +3695,7 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3680
3695
|
a.rotate(1)
|
|
3681
3696
|
a = list(a)
|
|
3682
3697
|
|
|
3683
|
-
if n > len(a):
|
|
3684
|
-
if n < 0 and abs(n) > len(a): return p3Dv(a)
|
|
3685
|
-
|
|
3698
|
+
if abs(n) > len(a): n = 0
|
|
3686
3699
|
if n > 0: a = a[0:n]
|
|
3687
3700
|
if n < 0: a = a[n:]
|
|
3688
3701
|
|
|
@@ -3691,7 +3704,7 @@ def nonCollinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3691
3704
|
|
|
3692
3705
|
def collinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
3693
3706
|
"""
|
|
3694
|
-
Returns
|
|
3707
|
+
Returns collinear points in an OpenStudio 3D point vector.
|
|
3695
3708
|
|
|
3696
3709
|
Args:
|
|
3697
3710
|
pts (openstudio.Point3dVector):
|
|
@@ -3700,38 +3713,31 @@ def collinears(pts=None, n=0) -> openstudio.Point3dVector:
|
|
|
3700
3713
|
Requested number of collinears (0 returns all).
|
|
3701
3714
|
|
|
3702
3715
|
Returns:
|
|
3703
|
-
openstudio.Point3dVector: collinears (see logs
|
|
3716
|
+
openstudio.Point3dVector: collinears (see logs).
|
|
3704
3717
|
|
|
3705
3718
|
"""
|
|
3706
3719
|
mth = "osut.collinears"
|
|
3707
|
-
|
|
3708
|
-
a = []
|
|
3720
|
+
a = openstudio.Point3dVector()
|
|
3709
3721
|
pts = uniques(pts)
|
|
3710
3722
|
if len(pts) < 3: return pts
|
|
3711
3723
|
|
|
3712
3724
|
try:
|
|
3713
3725
|
n = int(n)
|
|
3714
3726
|
except:
|
|
3715
|
-
oslg.mismatch("n
|
|
3716
|
-
|
|
3717
|
-
if n > len(pts):
|
|
3718
|
-
return oslg.invalid("+n collinears", mth, 0, CN.ERR, v)
|
|
3719
|
-
elif n < 0 and abs(n) > len(pts):
|
|
3720
|
-
return oslg.invalid("-n collinears", mth, 0, CN.ERR, v)
|
|
3727
|
+
oslg.mismatch("n points", n, int, mth, CN.DBG)
|
|
3728
|
+
n = 0
|
|
3721
3729
|
|
|
3722
3730
|
ncolls = nonCollinears(pts)
|
|
3723
|
-
if not ncolls: return
|
|
3731
|
+
if not ncolls: return a
|
|
3724
3732
|
|
|
3725
3733
|
for pt in pts:
|
|
3726
3734
|
if pt not in ncolls: a.append(pt)
|
|
3727
3735
|
|
|
3728
|
-
if n > len(a):
|
|
3729
|
-
if n < 0 and abs(n) > len(a): return p3Dv(a)
|
|
3730
|
-
|
|
3736
|
+
if abs(n) > len(a): n = 0
|
|
3731
3737
|
if n > 0: a = a[0:n]
|
|
3732
3738
|
if n < 0: a = a[n:]
|
|
3733
3739
|
|
|
3734
|
-
return
|
|
3740
|
+
return a
|
|
3735
3741
|
|
|
3736
3742
|
|
|
3737
3743
|
def poly(pts=None, vx=False, uq=False, co=False, tt=False, sq="no") -> openstudio.Point3dVector:
|
|
@@ -5237,15 +5243,12 @@ def spaceHeight(space=None) -> float:
|
|
|
5237
5243
|
(float): Full height of space (0.0 if invalid input).
|
|
5238
5244
|
|
|
5239
5245
|
"""
|
|
5240
|
-
|
|
5241
|
-
|
|
5246
|
+
hght = 0
|
|
5247
|
+
if not isinstance(space, openstudio.model.Space): return 0
|
|
5242
5248
|
|
|
5243
|
-
hght = 0
|
|
5244
5249
|
minZ = 10000
|
|
5245
5250
|
maxZ = -10000
|
|
5246
5251
|
|
|
5247
|
-
# The solution considers all surface types: "Floor", "Wall", "RoofCeiling".
|
|
5248
|
-
# No presumption that floor are necessarily at ground level.
|
|
5249
5252
|
for surface in space.surfaces():
|
|
5250
5253
|
zs = [pt.z() for pt in surface.vertices()]
|
|
5251
5254
|
minZ = min(minZ, min(zs))
|
|
@@ -5288,21 +5291,18 @@ def spaceWidth(space=None) -> float:
|
|
|
5288
5291
|
# - retain only other floor surfaces sharing same 3D plane
|
|
5289
5292
|
# - recover potential union between floor surfaces
|
|
5290
5293
|
# - fall back to largest floor surface if invalid union
|
|
5294
|
+
# - return width of largest bounded box
|
|
5291
5295
|
floors = sorted(floors, key=lambda fl: fl.grossArea(), reverse=True)
|
|
5292
5296
|
floor = floors[0]
|
|
5293
5297
|
plane = floor.plane()
|
|
5294
5298
|
t = openstudio.Transformation.alignFace(floor.vertices())
|
|
5295
5299
|
polyg = list(poly(floor, False, True, True, t, "ulc"))
|
|
5296
|
-
|
|
5297
|
-
if not polyg:
|
|
5298
|
-
oslg.clean()
|
|
5299
|
-
return 0
|
|
5300
|
+
if not polyg: return 0
|
|
5300
5301
|
|
|
5301
5302
|
polyg.reverse()
|
|
5302
|
-
polyg = p3Dv(polyg)
|
|
5303
5303
|
|
|
5304
5304
|
if len(floors) > 1:
|
|
5305
|
-
floors = [flr for flr in floors if plane.equal(
|
|
5305
|
+
floors = [flr for flr in floors if plane.equal(flr.plane(), 0.001)]
|
|
5306
5306
|
|
|
5307
5307
|
if len(floors) > 1:
|
|
5308
5308
|
polygs = [poly(flr, False, True, True, t, "ulc") for flr in floors]
|
|
@@ -5315,12 +5315,16 @@ def spaceWidth(space=None) -> float:
|
|
|
5315
5315
|
|
|
5316
5316
|
union = openstudio.joinAll(polygs, 0.01)[0]
|
|
5317
5317
|
polyg = poly(union, False, True, True)
|
|
5318
|
+
if not polyg: return 0
|
|
5319
|
+
|
|
5320
|
+
polyg = list(polyg)
|
|
5321
|
+
polyg.reverse()
|
|
5318
5322
|
|
|
5319
|
-
|
|
5320
|
-
|
|
5323
|
+
res = realignedFace(polyg)
|
|
5324
|
+
if not res["box"]: return 0
|
|
5321
5325
|
|
|
5322
5326
|
# A bounded box's 'height', at its narrowest, is its 'width'.
|
|
5323
|
-
return height(box)
|
|
5327
|
+
return height(res["box"])
|
|
5324
5328
|
|
|
5325
5329
|
|
|
5326
5330
|
def genAnchors(s=None, sset=[], tag="box") -> int:
|
|
@@ -6079,7 +6083,7 @@ def genSlab(pltz=[], z=0) -> openstudio.Point3dVector:
|
|
|
6079
6083
|
slb = vtx
|
|
6080
6084
|
|
|
6081
6085
|
# Once joined, re-adjust Z-axis coordinates.
|
|
6082
|
-
if
|
|
6086
|
+
if round(z, 2) != 0.00:
|
|
6083
6087
|
vtx = openstudio.Point3dVector()
|
|
6084
6088
|
|
|
6085
6089
|
for pt in slb: vtx.append(openstudio.Point3d(pt.x(), pt.y(), z))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: osut
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: OpenStudio SDK utilities for Python
|
|
5
5
|
Author-email: Denis Bourgeois <denis@rd2.ca>
|
|
6
6
|
Maintainer-email: Denis Bourgeois <denis@rd2.ca>
|
|
@@ -16,7 +16,6 @@ Requires-Python: >=3.2
|
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: oslg
|
|
19
|
-
Requires-Dist: openstudio>=3.6.1
|
|
20
19
|
Dynamic: license-file
|
|
21
20
|
|
|
22
21
|
# pyOSut
|
|
@@ -25,3 +24,27 @@ Python implementation of the _OSut_ Ruby gem for the OpenStudio SDK.
|
|
|
25
24
|
- PyPi [package](https://pypi.org/project/osut/)
|
|
26
25
|
- Ruby [gem](https://rubygems.org/gems/osut)
|
|
27
26
|
- Ruby GitHub [repository](https://github.com/rd2/osut)
|
|
27
|
+
|
|
28
|
+
----
|
|
29
|
+
|
|
30
|
+
_OSut_ interacts with _OpenStudio_:
|
|
31
|
+
|
|
32
|
+
`pip install openstudio`
|
|
33
|
+
|
|
34
|
+
----
|
|
35
|
+
|
|
36
|
+
To download the _OSut_ Python package:
|
|
37
|
+
|
|
38
|
+
`pip install --upgrade osut`
|
|
39
|
+
|
|
40
|
+
----
|
|
41
|
+
|
|
42
|
+
To import the _OSut_ module in a Python project:
|
|
43
|
+
|
|
44
|
+
`from osut import osut`
|
|
45
|
+
|
|
46
|
+
____
|
|
47
|
+
|
|
48
|
+
To run the _OSut_ unit tests on a `git clone` of the repo:
|
|
49
|
+
|
|
50
|
+
`python -m unittest`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
osut/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
osut/osut.py,sha256=YyaK3ft1WRnPrAGkNGeTCA48ya_TapHccQkAmLm20M4,302755
|
|
3
|
+
osut-0.7.0.dist-info/licenses/LICENSE,sha256=Ag_zDZp4XtiEQWfCwuPk25nVa9gsNhJ3SIx2Ahh1I6c,1495
|
|
4
|
+
osut-0.7.0.dist-info/METADATA,sha256=6l48aPzuzXNVJXckxyvtEuq5Sl7g2M5GSAT2CSm8kzA,1254
|
|
5
|
+
osut-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
osut-0.7.0.dist-info/top_level.txt,sha256=elxZoPwvGd11mNFvZvnG07mjsDiiiiU2VwmzXjnSWT4,5
|
|
7
|
+
osut-0.7.0.dist-info/RECORD,,
|
osut-0.6.0.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
osut/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
osut/osut.py,sha256=wFIU7ZhAVK5b7i0pYFBxmwwDskGIdNrdRMY2RYrPyM8,302342
|
|
3
|
-
osut-0.6.0.dist-info/licenses/LICENSE,sha256=Ag_zDZp4XtiEQWfCwuPk25nVa9gsNhJ3SIx2Ahh1I6c,1495
|
|
4
|
-
osut-0.6.0.dist-info/METADATA,sha256=iQJMXVJfPi_yDD_kx-Uo4RPfSm-U0TkPeAOdQR9umxc,972
|
|
5
|
-
osut-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
osut-0.6.0.dist-info/top_level.txt,sha256=elxZoPwvGd11mNFvZvnG07mjsDiiiiU2VwmzXjnSWT4,5
|
|
7
|
-
osut-0.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|