Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/osut/osut.py
Original file line number Diff line number Diff line change
Expand Up @@ -2737,7 +2737,10 @@ def p3Dv(pts=None) -> openstudio.Point3dVector:
elif isinstance(pts, openstudio.Point3dVector):
return pts
elif isinstance(pts, openstudio.model.PlanarSurface):
pts = list(pts.vertices())
for vt in pts.vertices():
pt = openstudio.Point3d(vt.x(), vt.y(), vt.z())
v.append(pt)
return v
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No point in validating planar surface .vertices() individually.


try:
pts = list(pts)
Expand Down Expand Up @@ -3056,7 +3059,7 @@ def nextUp(pts=None, pt=None):
None: If invalid inputs (see logs).

"""
mth = "osut.nextUP"
mth = "osut.nextUp"
pts = p3Dv(pts)
cl = openstudio.Point3d

Expand Down Expand Up @@ -3341,7 +3344,7 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool:

Returns:
bool: Whether a 3D point lies ~along a 3D point segment.
False: If invalid inputs.
False: If invalid inputs (see logs).

"""
mth = "osut.isPointAlongSegment"
Expand All @@ -3350,12 +3353,10 @@ def isPointAlongSegment(p0=None, sg=[]) -> bool:

if not isinstance(p0, cl1):
return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False)
if not isSegment(sg):
return oslg.mismatch("segment", sg, cl2, mth, CN.DBG, False)

if not isSegment(sg): return False
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowering the log volume: isPointAlongSegment calls isSegment, which in turn calls p3Dv. The latter will log an inadmissible object.

if holds(sg, p0): return True

a = sg[0]
a = sg[ 0]
b = sg[-1]
ab = b - a
abn = b - a
Expand Down Expand Up @@ -3397,7 +3398,7 @@ def isPointAlongSegments(p0=None, sgs=[]) -> bool:
if not sgs:
return oslg.empty("segments", mth, CN.DBG, False)
if not isinstance(p0, cl1):
return oslg.mismatch("point", p0, cl, mth, CN.DBG, False)
return oslg.mismatch("point", p0, cl1, mth, CN.DBG, False)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. No cl variable.


for sg in sgs:
if isPointAlongSegment(p0, sg): return True
Expand Down
99 changes: 97 additions & 2 deletions tests/test_osut.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test03_dictionaries(self):
self.assertTrue("skylight" in osut.film())
self.assertTrue("skylight" in osut.uo())
self.assertEqual(osut.film().keys(), osut.uo().keys())

def test04_materials(self):
material = osut.mats()["material"]
sand = osut.mats()["sand"]
Expand Down Expand Up @@ -3308,6 +3308,84 @@ def test25_segments_triads_orientation(self):
p7 = openstudio.Point3d(14, 20, -5)
p8 = openstudio.Point3d(-9, -9, -5)

# Stress test 'to_p3Dv'. 4 valid input cases.
# Valid case #1: a single Point3d.
vtx = osut.p3Dv(p0)
self.assertTrue(isinstance(vtx, openstudio.Point3dVector))
self.assertEqual(vtx[0], p0) # same object ID
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 4 valid p3Dv use cases systematically return an openstudio.Point3dVector (and not occasionally a list).


# Valid case #2: a Point3dVector.
vtxx = openstudio.Point3dVector()
vtxx.append(p0)
vtxx.append(p1)
vtxx.append(p2)
vtxx.append(p3)
vtx = osut.p3Dv(vtxx)
self.assertTrue(isinstance(vtx, openstudio.Point3dVector))
self.assertEqual(vtx[ 0], p0) # same object ID
self.assertEqual(vtx[ 1], p1) # same object ID
self.assertEqual(vtx[ 2], p2) # same object ID
self.assertEqual(vtx[-1], p3) # same object ID

# Valid case #3: Surface vertices.
model = openstudio.model.Model()
surface = openstudio.model.Surface(vtxx, model)
self.assertTrue(isinstance(surface.vertices(), tuple)) # ! Point3dVector
self.assertEqual(len(surface.vertices()), 4)
vtx = osut.p3Dv(vtxx)
self.assertTrue(isinstance(vtx, openstudio.Point3dVector))
self.assertEqual(len(vtx), 4)
self.assertEqual(vtx[0], p0)
self.assertEqual(vtx[1], p1)
self.assertEqual(vtx[2], p2)
self.assertEqual(vtx[3], p3)

# Valid case #4: Array.
vtx = osut.p3Dv([p0, p1, p2, p3])
self.assertTrue(isinstance(vtx, openstudio.Point3dVector))
self.assertEqual(len(vtx), 4)
self.assertEqual(vtx[0], p0)
self.assertEqual(vtx[1], p1)
self.assertEqual(vtx[2], p2)
self.assertEqual(vtx[3], p3)

# Stress test 'nextUp'.
m0 = "Invalid 'points (2+)' arg #1 (osut.nextUp)"

# Invalid case.
pt = osut.nextUp([], p0)
self.assertFalse(pt)
self.assertTrue(o.is_warn())
self.assertEqual(len(o.logs()), 1)
self.assertEqual(o.logs()[0]["message"], m0)
self.assertEqual(o.clean(), DBG)

# Valid case.
pt = osut.nextUp([p0, p1, p2, p3], p0)
self.assertTrue(isinstance(pt, openstudio.Point3d))
self.assertEqual(pt, p1)

pt = osut.nextUp([p0, p0, p0], p0)
self.assertTrue(isinstance(pt, openstudio.Point3d))
self.assertEqual(pt, p0)

# Stress test 'segments'. Invalid case.
sgs = osut.segments(p3)
self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector))
self.assertFalse(sgs)
self.assertEqual(o.status(), 0) # nothing logged

sgs = osut.segments([p3, p3])
self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector))
self.assertFalse(sgs)
self.assertEqual(o.status(), 0) # nothing logged

# Valid case.
sgs = osut.segments([p0, p1, p2, p3])
self.assertTrue(isinstance(sgs, openstudio.Point3dVectorVector))
self.assertEqual(len(sgs), 4)
self.assertTrue(isinstance(sgs[-1], tuple)) # ! Point3dVector

# Stress test 'uniques'.
m0 = "'n points' str? expecting int (osut.uniques)"

Expand Down Expand Up @@ -3375,6 +3453,7 @@ def test25_segments_triads_orientation(self):
self.assertEqual(len(collinears), 2)
self.assertTrue(osut.areSame(collinears[0], p0))
self.assertTrue(osut.areSame(collinears[1], p1))
self.assertTrue(osut.isPointAlongSegment(p0, sgs[0]))

# Only 2 collinears, so request for first 3 is ignored.
collinears = osut.collinears([p0, p1, p2, p3, p8], 3)
Expand Down Expand Up @@ -3409,6 +3488,22 @@ def test25_segments_triads_orientation(self):
self.assertTrue(osut.areSame(collinears[0], p0))
self.assertTrue(osut.areSame(collinears[1], p1))

# Stress test isPointAlongSegment.
m0 = "'point' str? expecting Point3d (osut.p3Dv)"

# Invalid case.
self.assertFalse(osut.isPointAlongSegment(p3, "osut"))
self.assertTrue(o.is_debug())
self.assertEqual(len(o.logs()), 1)
self.assertEqual(o.logs()[0]["message"], m0)
self.assertEqual(o.clean(), DBG)

# Valid case.
pts = openstudio.Point3dVector()
pts.append(p0)
pts.append(p1)
self.assertFalse(osut.isPointAlongSegment(p3, pts))

# CASE a1: 2x end-to-end line segments (returns matching endpoints).
self.assertTrue(osut.doesLineIntersect([p0, p1], [p1, p2]))
pt = osut.lineIntersection([p0, p1], [p1, p2])
Expand Down Expand Up @@ -4999,7 +5094,7 @@ def test33_leader_line_anchors_inserts(self):
# [ 4, 14, 0] ... vs [16, 2, 20]
# [ 0, 14, 0] ... vs [20, 2, 20]
# [ 0, 0, 0] ... vs [20, 16, 20]

def test34_generated_skylight_wells(self):
o = osut.oslg
self.assertEqual(o.status(), 0)
Expand Down