Skip to content

Commit

Permalink
Add early fail for get_normal_newell when the provided polygon is t…
Browse files Browse the repository at this point in the history
…oo small (< 3)
  • Loading branch information
mdjong1 committed Nov 21, 2023
1 parent 836ed00 commit 9f13738
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 9 deletions.
20 changes: 11 additions & 9 deletions cjio/geom_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
try:
import mapbox_earcut
except ImportError as e:
MODULE_EARCUT_AVAILABLE = False
MODULE_EARCUT_AVAILABLE = False

def to_2d(p, n):
#-- n must be normalised
Expand All @@ -24,7 +24,7 @@ def to_2d(p, n):
x3 += np.array([1,2,3])
x3 = x3 - np.dot(x3, n) * n
# print(n, x3)
x3 /= math.sqrt((x3**2).sum()) # make x a unit vector
x3 /= math.sqrt((x3**2).sum()) # make x a unit vector
y3 = np.cross(n, x3)
return (np.dot(p, x3), np.dot(p, y3))

Expand All @@ -39,14 +39,16 @@ def get_normal_newell(poly):
ne = i + 1
if (ne == len(poly)):
ne = 0
if len(poly[i]) < 3 or len(poly[ne]) < 3:
return n, False
n[0] += ( (poly[i][1] - poly[ne][1]) * (poly[i][2] + poly[ne][2]) )
n[1] += ( (poly[i][2] - poly[ne][2]) * (poly[i][0] + poly[ne][0]) )
n[2] += ( (poly[i][0] - poly[ne][0]) * (poly[i][1] + poly[ne][1]) )

if (n==np.array([0.0, 0.0, 0.0])).all():
# print("one wrong")
return (n, False)
n = n / math.sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2])
n = n / math.sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2])
return (n, True)


Expand Down Expand Up @@ -86,7 +88,7 @@ def triangulate_face_shewchuk(face, vnp):
for ring in face:
sf = np.hstack( (sf, np.array(ring)) )
sfv = vnp[sf]

rings = np.zeros(len(face), dtype=np.int64)
total = 0
for i in range(len(face)):
Expand Down Expand Up @@ -133,14 +135,14 @@ def triangulate_face_shewchuk(face, vnp):
A = dict(vertices=sfv2d, segments=sg, holes=holes)
else:
A = dict(vertices=sfv2d, segments=sg)

try:
re = triangle.triangulate(A, 'p')
except:
print("Houston we have a problem...")
# re = {}
return(np.array(face), False)
#-- check the output
#-- check the output
if 'triangles' not in re:
return([], False)
re = re['triangles']
Expand Down Expand Up @@ -187,9 +189,9 @@ def triangulate_face_mapbox_earcut(face, vnp):
# print (result.reshape(-1, 3))

for i,each in enumerate(result):
# print (sf[i])
# print (sf[i])
result[i] = sf[each]

# print (result.reshape(-1, 3))
return (result.reshape(-1, 3), True)

Expand Down
57 changes: 57 additions & 0 deletions tests/test_geom_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import typing as t

import numpy as np
import numpy.typing as npt
import pytest

from cjio.geom_help import get_normal_newell


@pytest.mark.parametrize(
["poly", "expected_normal"],
[
(
[
[2195013, 353200, 12283],
[2195013, 353200, 8680],
[2182302, 347931, 8680],
[2182302, 347931, 12159],
[2182302, 347931, 12178],
],
np.array([-0.38292729, 0.92377848, 0.0]),
),
(
[
[2203406, 332904, 12622],
[2203406, 332904, 8680],
[2204954, 333543, 8680],
[2204954, 333543, 12223],
[2204954, 333543, 12584],
],
np.array([0.38156054, -0.92434385, 0.0]),
),
],
)
def test_get_normal_valid_poly(poly: t.List[t.List[int]], expected_normal: npt.NDArray[t.Any]) -> None:
normal, success = get_normal_newell(poly=poly)
assert success
np.testing.assert_almost_equal(actual=normal, desired=expected_normal)


@pytest.mark.parametrize(
["poly", "expected_normal"],
[
(
[[1041, 1009, 1025, 1054, 1087]],
np.array([0.0, 0.0, 0.0]),
),
(
[[[1099, 1098]]],
np.array([0.0, 0.0, 0.0]),
),
],
)
def test_get_normal_invalid_poly(poly: t.List[t.List[int]], expected_normal: npt.NDArray[t.Any]) -> None:
normal, success = get_normal_newell(poly=poly)
assert not success
np.testing.assert_almost_equal(actual=normal, desired=expected_normal)

0 comments on commit 9f13738

Please sign in to comment.