feat: add Gordon surface implementation and test

modified:   pyproject.toml
	modified:   src/build123d/topology/two_d.py
	modified:   tests/test_direct_api/test_face.py
This commit is contained in:
Fan Gong 2025-10-01 22:10:19 -04:00
parent 0166408f60
commit 64267ab3f7
3 changed files with 106 additions and 0 deletions

View file

@ -502,6 +502,78 @@ class TestFace(unittest.TestCase):
]
)
def test_gordon_surface(self):
def create_test_curves(
num_profiles: int = 3,
num_guides: int = 4,
u_range: float = 1.0,
v_range: float = 1.0,
):
profiles: list[Edge] = []
guides: list[Edge] = []
intersection_points = [
[(0.0, 0.0, 0.0) for _ in range(num_guides)]
for _ in range(num_profiles)
]
for i in range(num_profiles):
for j in range(num_guides):
u = i * u_range / (num_profiles - 1)
v = j * v_range / (num_guides - 1)
z = 0.2 * math.sin(u * math.pi) * math.cos(v * math.pi)
intersection_points[i][j] = (u, v, z)
for i in range(num_profiles):
points = [intersection_points[i][j] for j in range(num_guides)]
profiles.append(Spline(points))
for j in range(num_guides):
points = [intersection_points[i][j] for i in range(num_profiles)]
guides.append(Spline(points))
return profiles, guides
profiles, guides = create_test_curves()
tolerance = 3e-4
gordon_surface = Face.gordon_surface(profiles, guides, tolerance=tolerance)
self.assertIsInstance(
gordon_surface, Face, "The returned object should be a Face."
)
def point_at_uv_against_expected(u: float, v: float, expected_point: Vector):
point_at_uv = gordon_surface.position_at(u, v)
self.assertAlmostEqual(
point_at_uv.X,
expected_point.X,
delta=tolerance,
msg=f"X coordinate mismatch at ({u},{v})",
)
self.assertAlmostEqual(
point_at_uv.Y,
expected_point.Y,
delta=tolerance,
msg=f"Y coordinate mismatch at ({u},{v})",
)
self.assertAlmostEqual(
point_at_uv.Z,
expected_point.Z,
delta=tolerance,
msg=f"Z coordinate mismatch at ({u},{v})",
)
point_at_uv_against_expected(
u=1.0, v=0.0, expected_point=profiles[0].position_at(1.0)
)
point_at_uv_against_expected(
u=0.0, v=1.0, expected_point=guides[0].position_at(1.0)
)
point_at_uv_against_expected(
u=1.0, v=1.0, expected_point=profiles[-1].position_at(1.0)
)
# def test_to_arcs(self):
# with BuildSketch() as bs:
# with BuildLine() as bl: