Files
ConformalLabpp/code/include/mesh_builder.hpp
Tarik Moussa bf9c323d60 feat(phase3a): introduce CGAL Surface_mesh as ConformalMesh foundation
Replaces the Java CoHDS with CGAL::Surface_mesh<Point3> (Simple_cartesian
kernel). Adds domain-specific property maps for lambda/theta/idx/alpha and
face geometry type — the direct C++ equivalent of CoVertex/CoEdge adapters.

New files:
  include/conformal_mesh.hpp   — ConformalMesh type + property-map helpers
  include/mesh_builder.hpp     — mesh factories (triangle, tetrahedron,
                                 quad-strip, fan) for tests and examples
  tests/cgal/                  — second test executable (conformallab_cgal_tests)
                                 built only with -DWITH_CGAL=ON

Test results (local, -DWITH_CGAL=ON):
  conformallab_tests:      36 registered | 23 passed | 13 skipped | 0 failed
  conformallab_cgal_tests: 14 registered | 14 passed |  0 skipped | 0 failed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 18:36:21 +02:00

110 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
// mesh_builder.hpp
//
// Factory functions that build simple reference meshes for testing and examples.
// All functions return a ConformalMesh (CGAL::Surface_mesh<Point3>).
//
// Replaces Java mesh generators:
// CoHDS generators (convex hull, hyper-ideal generator) come later (Phase 3c/4).
// These builders cover the minimal meshes needed for functional unit tests.
#include "conformal_mesh.hpp"
#include <cmath>
#include <vector>
namespace conformallab {
// ── Single triangle ──────────────────────────────────────────────────────────
//
// v2
// | \
// | \
// v0 ─ v1
//
// Returns a mesh with 1 face, 3 vertices, 3 edges.
// The triangle lies in the xy-plane with a right angle at v0.
inline ConformalMesh make_triangle(
double x0=0, double y0=0,
double x1=1, double y1=0,
double x2=0, double y2=1)
{
ConformalMesh mesh;
auto v0 = mesh.add_vertex(Point3(x0, y0, 0));
auto v1 = mesh.add_vertex(Point3(x1, y1, 0));
auto v2 = mesh.add_vertex(Point3(x2, y2, 0));
mesh.add_face(v0, v1, v2);
return mesh;
}
// ── Regular tetrahedron ──────────────────────────────────────────────────────
//
// 4 vertices, 4 faces, 6 edges.
// Euler characteristic: V - E + F = 4 - 6 + 4 = 2 (sphere topology).
// Used to test closed-surface traversal.
inline ConformalMesh make_tetrahedron()
{
ConformalMesh mesh;
// Vertices of a regular tetrahedron centred at origin, edge length √2·2
auto v0 = mesh.add_vertex(Point3( 1, 1, 1));
auto v1 = mesh.add_vertex(Point3( 1, -1, -1));
auto v2 = mesh.add_vertex(Point3(-1, 1, -1));
auto v3 = mesh.add_vertex(Point3(-1, -1, 1));
// 4 outward-facing triangles (consistent winding)
mesh.add_face(v0, v2, v1); // bottom (z=-1 side)
mesh.add_face(v0, v1, v3); // front (y=-1 side)
mesh.add_face(v0, v3, v2); // left (x=-1 side)
mesh.add_face(v1, v2, v3); // back
return mesh;
}
// ── Two-triangle strip ───────────────────────────────────────────────────────
//
// v2 ─ v3
// | \ |
// v0 ─ v1
//
// 4 vertices, 2 faces, 5 edges (1 interior edge v1v2 shared by both faces).
// Useful for testing edge-interior vs edge-boundary distinction.
inline ConformalMesh make_quad_strip()
{
ConformalMesh mesh;
auto v0 = mesh.add_vertex(Point3(0, 0, 0));
auto v1 = mesh.add_vertex(Point3(1, 0, 0));
auto v2 = mesh.add_vertex(Point3(0, 1, 0));
auto v3 = mesh.add_vertex(Point3(1, 1, 0));
mesh.add_face(v0, v1, v2); // lower-left triangle
mesh.add_face(v1, v3, v2); // upper-right triangle (shares edge v1v2)
return mesh;
}
// ── Regular flat polygon fan ─────────────────────────────────────────────────
//
// n triangles sharing a central vertex; forms a disk topology (boundary).
// Used to verify valence-n vertex traversal.
inline ConformalMesh make_fan(int n)
{
CGAL_precondition(n >= 3);
ConformalMesh mesh;
auto center = mesh.add_vertex(Point3(0, 0, 0));
const double dtheta = 2.0 * M_PI / n;
std::vector<Vertex_index> rim(n);
for (int i = 0; i < n; ++i) {
double a = i * dtheta;
rim[i] = mesh.add_vertex(Point3(std::cos(a), std::sin(a), 0));
}
for (int i = 0; i < n; ++i)
mesh.add_face(center, rim[i], rim[(i+1) % n]);
return mesh;
}
} // namespace conformallab