Skip to content

Add Triangulate_Contours for planar polygon triangulation#8

Open
Copilot wants to merge 6 commits intomasterfrom
copilot/implement-polygon-triangulation
Open

Add Triangulate_Contours for planar polygon triangulation#8
Copilot wants to merge 6 commits intomasterfrom
copilot/implement-polygon-triangulation

Conversation

Copy link

Copilot AI commented Jan 31, 2026

Implements polygon triangulation for contour_collection vertices projected onto a best-fit plane, returning an fv_surface_mesh with triangles as faces.

Changes

  • Triangulate_Contours<T,I>(const contour_collection<T>&) — new free function in YgorMath.h/.cc

    • Projects all contour vertices onto best-fit plane via Plane_Orthogonal_Regression
    • Triangulates using ear-clipping algorithm (handles non-convex, non-monotone polygons)
    • Uses is_ccw flag to distinguish outer contours (CCW) from holes (CW) in bridging logic
    • Bridges multiple contours via nearest-point connections with visibility checks to avoid self-intersections
    • Template instantiations for float/double × uint32_t/uint64_t
  • Unit tests in tests2/YgorMath/triangulate_contours.cc

    • Covers: convex/concave shapes, tilted planes, multi-contour bridging, degenerate cases, area preservation
    • Includes test for collinear points causing plane regression failure (returns empty mesh)

Usage

contour_collection<double> cc;
// ... populate contours ...

auto mesh = Triangulate_Contours<double, uint32_t>(cc);
// mesh.vertices: projected 3D points on best-fit plane
// mesh.faces: triangle indices (n-2 triangles for n-gon)

Resulting mesh is a non-watertight surface patch as specified.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits January 31, 2026 07:17
…nd add unit tests

Co-authored-by: hdclark <934858+hdclark@users.noreply.github.com>
Co-authored-by: hdclark <934858+hdclark@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement polygon triangulation algorithm for vertices Add Triangulate_Contours for planar polygon triangulation Jan 31, 2026
Copilot AI requested a review from hdclark January 31, 2026 07:22
@hdclark hdclark marked this pull request as ready for review January 31, 2026 07:49
Copilot AI review requested due to automatic review settings January 31, 2026 07:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a Triangulate_Contours<T,I> utility that projects a contour_collection onto a best-fit plane and triangulates it into an fv_surface_mesh, along with a focused unit test suite validating the new behavior.

Changes:

  • Declare and implement Triangulate_Contours<T,I>(const contour_collection<T>&) in YgorMath.h/.cc, including explicit template instantiations for {float,double} × {uint32_t,uint64_t}.
  • Implement an ear-clipping based triangulation on a best-fit plane with support for multiple contours via a bridging heuristic.
  • Add tests2/YgorMath/triangulate_contours.cc covering basic polygons, concave shapes, tilted planes, multiple contours, degeneracies, and different scalar/index types.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/YgorMath.h Declares the Triangulate_Contours template and documents its intended behavior and assumptions.
src/YgorMath.cc Implements Triangulate_Contours, including plane fitting, 2D projection, multi-contour bridging, ear-clipping, and explicit template instantiations.
tests2/YgorMath/triangulate_contours.cc Adds doctest-based unit tests for Triangulate_Contours across a variety of geometric configurations and type combinations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8092 to +8096
struct ContourInfo {
size_t start_idx;
size_t end_idx; // One past the last index.
bool is_ccw; // Counter-clockwise orientation (outer contour) or clockwise (hole).
};
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

ContourInfo::is_ccw is computed but never used in the rest of the function, which adds noise and suggests orientation‑dependent logic that is not actually implemented. Either remove this field and the associated area computation, or use it to distinguish outer contours from holes in the bridging logic so the stored flag has a purpose.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

Use it to distinguish outer contours from holes in the bridging logic so the stored flag has a purpose.

Copy link
Author

Choose a reason for hiding this comment

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

Updated the bridging logic to use is_ccw to distinguish outer contours from holes. The sorting now prioritizes outer contours (CCW) first before processing holes (CW), ensuring outer boundaries are established before holes are merged in. See commit d25f924.

Comment on lines +8057 to +8061
try {
best_fit_plane = Plane_Orthogonal_Regression(all_points);
} catch(const std::exception &) {
// Points are likely collinear; cannot triangulate.
return mesh;
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

This catch block returns an empty mesh when Plane_Orthogonal_Regression throws (e.g., for collinear input), but there is no unit test exercising this failure path. Given the rest of the function is well covered by tests, consider adding a test case with collinear contour points to confirm the intended "empty mesh on regression failure" behaviour and guard against regressions.

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

Implement this suggestion.

Copy link
Author

Choose a reason for hiding this comment

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

Added a test case "collinear points cause plane regression failure and return empty mesh" that verifies the empty mesh behavior when Plane_Orthogonal_Regression throws due to collinear input. See commit d25f924.

hdclark and others added 2 commits February 26, 2026 21:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@hdclark
Copy link
Owner

hdclark commented Feb 27, 2026

@copilot apply changes based on the comments in this thread

…ollinear points test

Co-authored-by: hdclark <934858+hdclark@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 27, 2026

@copilot apply changes based on the comments in this thread

Applied all changes from the review thread in commit d25f924:

  1. Updated the bridging logic to use is_ccw to distinguish outer contours (CCW) from holes (CW), sorting outer contours first
  2. Added a unit test for collinear points that verifies the empty mesh behavior when plane regression fails

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants