From 018cd12a3ac9dce17aa3f32eb097db38cfeaa792 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Sun, 26 Apr 2026 21:49:11 -0700 Subject: [PATCH] clean up two long-dead files --- .../geometrycentral/surface/detect_symmetry.h | 36 -- .../geometrycentral/surface/mesh_ray_tracer.h | 45 -- src/CMakeLists.txt | 4 - src/surface/detect_symmetry.cpp | 384 ------------------ src/surface/mesh_ray_tracer.cpp | 99 ----- 5 files changed, 568 deletions(-) delete mode 100644 include/geometrycentral/surface/detect_symmetry.h delete mode 100644 include/geometrycentral/surface/mesh_ray_tracer.h delete mode 100644 src/surface/detect_symmetry.cpp delete mode 100644 src/surface/mesh_ray_tracer.cpp diff --git a/include/geometrycentral/surface/detect_symmetry.h b/include/geometrycentral/surface/detect_symmetry.h deleted file mode 100644 index 189883f6..00000000 --- a/include/geometrycentral/surface/detect_symmetry.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "geometrycentral/surface/geometry.h" - -#include - -namespace geometrycentral { -namespace surface { - -struct SymmetryResult { - bool symmetryFound = false; // was a symmetry found? is this data valid? - std::vector canonicalVertices; // a representative entry from each - // set of symmetry pairs - VertexData> symmetrySet; // for each unique vertex, - // all others vertices that - // are symmetry pairs -}; - -// Look for a symmetry about a mirror plane -SymmetryResult detectSymmetryMirror(Geometry* geom, Vector3 planeNormal, Vector3 planePoint); - -// Look for a rotational symmetry -SymmetryResult detectSymmetryRotation(Geometry* geom, Vector3 rotAxis, Vector3 rotPoint, int nSym); - -// Automatically search for the typical mirror and rotation symmetries about the -// shape center -// Returns any symmetry which is found. -SymmetryResult detectSymmetryAuto(Geometry* geom); -SymmetryResult detectSymmetryAutoRotation(Geometry* geom); -SymmetryResult detectSymmetryAutoMirror(Geometry* geom); // Look for a symmetry about a mirror plane - -// Look for symmetry which is mirrored over the y and z planes -SymmetryResult detectSymmetryDoubleMirror(Geometry* geom); - -} // namespace surface -} // namespace geometrycentral diff --git a/include/geometrycentral/surface/mesh_ray_tracer.h b/include/geometrycentral/surface/mesh_ray_tracer.h deleted file mode 100644 index 30d24ec3..00000000 --- a/include/geometrycentral/surface/mesh_ray_tracer.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "geometrycentral/surface/geometry.h" - - -#include "nanort/nanort.h" - -namespace geometrycentral { -namespace surface { - -struct RayHitResult { - bool hit; - double tHit; - Face face; - Vector3 baryCoords; -}; - -class MeshRayTracer { -public: - // Creates a new tracer and builds the acceleration structure - MeshRayTracer(Geometry* geometry); - - // Build the BVH for the current geometry. Called automatically after - // construction, re-call if mesh changes. - void buildBVH(); - - // Trace a ray. Note: geometry should be identical to when BVH was constructed - RayHitResult trace(Vector3 start, Vector3 dir); - -private: - HalfedgeMesh* mesh; - Geometry* geometry; - - // Data for the BVH - std::vector rawPositions; - std::vector rawFaces; - nanort::BVHAccel, nanort::TriangleSAHPred, - nanort::TriangleIntersector> - accel; - - double tFar; -}; - -} // namespace surface -}; // namespace geometrycentral diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1869cde..804e37aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,8 +61,6 @@ SET(SRCS surface/quadric_error_simplification.cpp surface/subdivide.cpp surface/poisson_disk_sampler.cpp - #surface/detect_symmetry.cpp - #surface/mesh_ray_tracer.cpp pointcloud/point_cloud.cpp pointcloud/neighborhoods.cpp @@ -101,7 +99,6 @@ SET(HEADERS ${INCLUDE_ROOT}/surface/barycentric_coordinate_helpers.ipp ${INCLUDE_ROOT}/surface/base_geometry_interface.h ${INCLUDE_ROOT}/surface/boundary_first_flattening.h - ${INCLUDE_ROOT}/surface/detect_symmetry.h ${INCLUDE_ROOT}/surface/direction_fields.h ${INCLUDE_ROOT}/surface/edge_length_geometry.h ${INCLUDE_ROOT}/surface/edge_length_geometry.ipp @@ -124,7 +121,6 @@ SET(HEADERS ${INCLUDE_ROOT}/surface/manifold_surface_mesh.h ${INCLUDE_ROOT}/surface/meshio.h ${INCLUDE_ROOT}/surface/mesh_graph_algorithms.h - ${INCLUDE_ROOT}/surface/mesh_ray_tracer.h ${INCLUDE_ROOT}/surface/parameterize.h ${INCLUDE_ROOT}/surface/poisson_disk_sampler.h ${INCLUDE_ROOT}/surface/polygon_mesh_heat_solver.h diff --git a/src/surface/detect_symmetry.cpp b/src/surface/detect_symmetry.cpp deleted file mode 100644 index 33fb0c94..00000000 --- a/src/surface/detect_symmetry.cpp +++ /dev/null @@ -1,384 +0,0 @@ -#include "geometrycentral/surface/detect_symmetry.h" - -#include "nanoflann/KDTreeVectorOfVectorsAdaptor.h" -#include "nanoflann/nanoflann.hpp" - -#include -#include - -// Interal implementations that hide the NN lookup while allowing it to be -// shared - -using std::cout; -using std::endl; - -namespace geometrycentral { -namespace surface { - -namespace { - -// Stupid nanoflann wrapper -typedef KDTreeVectorOfVectorsAdaptor>, double> KdTree; -KdTree* buildKDTree(Geometry* geom) { - HalfedgeMesh* mesh = geom->getMesh(); - - // Pack data in a vector of vectors - std::vector>* pts = new std::vector>(mesh->nVertices()); - for (size_t i = 0; i < mesh->nVertices(); i++) { - Vector3 p = geom->position(mesh->vertex(i)); - (*pts)[i] = {p.x, p.y, p.z}; - } - - KdTree* tree = new KdTree(3, *pts); - tree->index->buildIndex(); - - return tree; -} - -bool findPoint(KdTree* tree, Vector3 target, double toleranceRadius, size_t& result) { - std::vector ret_indexes(1); - std::vector out_dists_sqr(1); - nanoflann::KNNResultSet resultSet(1); - resultSet.init(&ret_indexes[0], &out_dists_sqr[0]); - - std::vector query = {target.x, target.y, target.z}; - - bool success = tree->index->findNeighbors(resultSet, &query[0], nanoflann::SearchParams()); - - // Nothing found - if (!success) return false; - - double dist = std::sqrt(out_dists_sqr[0]); - if (dist > toleranceRadius) return false; // too far - - // Point found - result = ret_indexes[0]; - return true; -} - -SymmetryResult detectSymmetryMirror(Geometry* geom, Vector3 planeNormal, Vector3 planePoint, KdTree* tree) { - HalfedgeMesh* mesh = geom->getMesh(); - planeNormal = unit(planeNormal); - double toleranceRadius = geom->lengthScale() * 1e-5; - - SymmetryResult result; - result.symmetryFound = false; - result.symmetrySet = VertexData>(*mesh, std::vector()); - - for (Vertex v : mesh->vertices()) { - // Compute the symmetric point - Vector3 pos = geom->position(v); - Vector3 vecToPlane = dot(planeNormal, planePoint - pos) * planeNormal; - Vector3 mirrorPos = pos + 2 * vecToPlane; - - // If this point is on the positive side of the plane, it's canonical - bool isCanonical = dot(planeNormal, pos - planePoint) > -toleranceRadius; // small tolerance for points on plane - if (isCanonical) { - result.canonicalVertices.push_back(v); - } - - // If this point is its own pair, there's no mirror to look for (assumes no - // duplicate verts) - if (norm(pos - mirrorPos) < toleranceRadius) continue; - - // Search for the point - size_t mirrorInd; - bool success = findPoint(tree, mirrorPos, toleranceRadius, mirrorInd); - if (!success) { - return result; - } - - // If found, add to lists - if (isCanonical) { - result.symmetrySet[v].push_back(mesh->vertex(mirrorInd)); - } - } - - result.symmetryFound = true; - return result; -} - -SymmetryResult detectSymmetryRotation(Geometry* geom, Vector3 rotAxis, Vector3 rotPoint, int nSym, - KdTree* tree) { - HalfedgeMesh* mesh = geom->getMesh(); - rotAxis = unit(rotAxis); - double toleranceRadius = geom->lengthScale() * 1e-5; - double deltaTheta = 2 * PI / nSym; - - // Any axis orthogonal to the rotation axis - Vector3 castAxis = Vector3{0.12345623, -.883034723, 0.54457119}; // provably random - Vector3 orthAxis = unit(cross(rotAxis, castAxis)); - - SymmetryResult result; - result.symmetryFound = false; - result.symmetrySet = VertexData>(*mesh, std::vector()); - - for (Vertex v : mesh->vertices()) { - // Compute the symmetric point - Vector3 pos = geom->position(v); - - // Test if canonical - Vector3 vPlane = (pos - rotPoint) - dot(rotAxis, pos - rotPoint) * rotAxis; - double canonicalAngle = angleInPlane(orthAxis, vPlane, rotAxis); - bool isCanonical = norm(vPlane) < toleranceRadius || (canonicalAngle >= 0 && canonicalAngle < deltaTheta); - if (isCanonical) { - result.canonicalVertices.push_back(v); - } - - for (int iRot = 1; iRot < nSym; iRot++) { - double theta = iRot * deltaTheta; - Vector3 rotPos = (pos - rotPoint).rotate_around(rotAxis, theta) + rotPoint; - - // If this point is its own pair, there's no mirror to look for (assumes - // no duplicate verts) - if (norm(pos - rotPos) < toleranceRadius) continue; - - // Search for the point - size_t rotInd; - bool success = findPoint(tree, rotPos, toleranceRadius, rotInd); - if (!success) { - return result; - } - - // If found, add to lists - if (isCanonical) { - result.symmetrySet[v].push_back(mesh->vertex(rotInd)); - } - } - } - - result.symmetryFound = true; - return result; -} - -SymmetryResult detectSymmetryDoubleMirror(Geometry* geom, KdTree* tree) { - HalfedgeMesh* mesh = geom->getMesh(); - double toleranceRadius = geom->lengthScale() * 1e-5; - - SymmetryResult result; - result.symmetryFound = false; - result.symmetrySet = VertexData>(*mesh, std::vector()); - - for (Vertex v : mesh->vertices()) { - // Compute the symmetric point - Vector3 pos = geom->position(v); - - // Test if canonical - bool isCanonical = pos.y >= 0 && pos.z >= 0; - if (isCanonical) { - result.canonicalVertices.push_back(v); - } - - for (int iS = 1; iS < 4; iS++) { - // Compute positions flipped across axes - Vector3 mirrorPos = pos; - if (iS % 2 == 1) { - mirrorPos.y *= -1; - } - if (iS >= 2) { - mirrorPos.z *= -1; - } - - // If this point is its own pair, there's no mirror to look for (assumes - // no duplicate verts) - if (norm(pos - mirrorPos) < toleranceRadius) continue; - - // Search for the point - size_t symInd; - bool success = findPoint(tree, mirrorPos, toleranceRadius, symInd); - if (!success) { - return result; - } - - // If found, add to lists - if (isCanonical) { - result.symmetrySet[v].push_back(mesh->vertex(symInd)); - } - } - } - - result.symmetryFound = true; - return result; -} - -} // namespace - -SymmetryResult detectSymmetryMirror(Geometry* geom, Vector3 planeNormal, Vector3 planePoint) { - KdTree* tree = buildKDTree(geom); - SymmetryResult r = detectSymmetryMirror(geom, planeNormal, planePoint, tree); - delete tree; - return r; -} - -SymmetryResult detectSymmetryRotation(Geometry* geom, Vector3 rotAxis, Vector3 rotPoint, int nSym) { - KdTree* tree = buildKDTree(geom); - SymmetryResult r = detectSymmetryRotation(geom, rotAxis, rotPoint, nSym, tree); - delete tree; - return r; -} - -SymmetryResult detectSymmetryAuto(Geometry* geom) { - std::cout << "Attempting to automatically detect symmetry..." << std::endl; - - KdTree* tree = buildKDTree(geom); - - Vector3 center = geom->center(); - - // == Mirror symmetry across coordinate axes, about center - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{1.0, 0.0, 0.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across x-axis!" << endl; - delete tree; - return res; - } - } - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{0.0, 1.0, 0.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across y-axis!" << endl; - delete tree; - return res; - } - } - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{0.0, 0.0, 1.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across z-axis!" << endl; - delete tree; - return res; - } - } - - // == Rotational symmetry about coordinate axes at center - // (higher order symmetries are cooler) - for (int nSym = 8; nSym >= 2; nSym--) { - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{1.0, 0.0, 0.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about x-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{0.0, 1.0, 0.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about y-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{0.0, 0.0, 1.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about z-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - } - - cout << " ...no symmetry found." << endl; - delete tree; - SymmetryResult r; - r.symmetryFound = false; - return r; -} - -SymmetryResult detectSymmetryAutoMirror(Geometry* geom) { - cout << "Attempting to automatically detect mirror symmetry..." << endl; - - KdTree* tree = buildKDTree(geom); - - Vector3 center = geom->center(); - - // == Mirror symmetry across coordinate axes, about center - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{1.0, 0.0, 0.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across x-axis!" << endl; - delete tree; - return res; - } - } - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{0.0, 1.0, 0.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across y-axis!" << endl; - delete tree; - return res; - } - } - { - SymmetryResult res = detectSymmetryMirror(geom, Vector3{0.0, 0.0, 1.0}, center, tree); - if (res.symmetryFound) { - cout << " ... symmetry found across z-axis!" << endl; - delete tree; - return res; - } - } - - cout << " ...no symmetry found." << endl; - delete tree; - SymmetryResult r; - r.symmetryFound = false; - return r; -} - -SymmetryResult detectSymmetryAutoRotation(Geometry* geom) { - cout << "Attempting to automatically detect rotational symmetry..." << endl; - - KdTree* tree = buildKDTree(geom); - - Vector3 center = geom->center(); - - // == Rotational symmetry about coordinate axes at center - // (higher order symmetries are cooler) - for (int nSym = 8; nSym >= 2; nSym--) { - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{1.0, 0.0, 0.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about x-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{0.0, 1.0, 0.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about y-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - - { - SymmetryResult res = detectSymmetryRotation(geom, Vector3{0.0, 0.0, 1.0}, center, nSym, tree); - if (res.symmetryFound) { - cout << " ... rotational symmetry found about z-axis with index " << nSym << "!" << endl; - delete tree; - return res; - } - } - } - - cout << " ...no symmetry found." << endl; - delete tree; - SymmetryResult r; - r.symmetryFound = false; - return r; -} - -SymmetryResult detectSymmetryDoubleMirror(Geometry* geom) { - KdTree* tree = buildKDTree(geom); - SymmetryResult r = detectSymmetryDoubleMirror(geom, tree); - delete tree; - return r; -} - -} // namespace surface -} // namespace geometrycentral diff --git a/src/surface/mesh_ray_tracer.cpp b/src/surface/mesh_ray_tracer.cpp deleted file mode 100644 index f7c4a99a..00000000 --- a/src/surface/mesh_ray_tracer.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "geometrycentral/surface/mesh_ray_tracer.h" - -#include - -using std::cout; -using std::endl; - -namespace geometrycentral { -namespace surface { - -MeshRayTracer::MeshRayTracer(Geometry* geometry_) { - mesh = geometry_->getMesh(); - geometry = geometry_; - - buildBVH(); -} - -void MeshRayTracer::buildBVH() { - cout << "Building BVH for mesh..." << endl; - - nanort::BVHBuildOptions options; // Use default options - - if (!mesh->isTriangular()) { - throw std::runtime_error("Can only trace rays on triangle meshes."); - } - - // Build face and vertex arrays - rawPositions.resize(mesh->nVertices() * 3); - rawFaces.resize(mesh->nFaces() * 3); - VertexData vInd = mesh->getVertexIndices(); - for (Vertex v : mesh->vertices()) { - unsigned int i = 3 * vInd[v]; - Vector3 p = geometry->position(v); - for (unsigned int j = 0; j < 3; j++) rawPositions[i + j] = p[j]; - } - FaceData fInd = mesh->getFaceIndices(); - for (Face f : mesh->faces()) { - unsigned int i = 3 * fInd[f]; - unsigned int j = 0; - for (Vertex v : f.adjacentVertices()) { - rawFaces[i + j] = vInd[v]; - j++; - } - } - - // Construct nanort mesh objects - nanort::TriangleMesh triangle_mesh(rawPositions.data(), rawFaces.data(), sizeof(double) * 3); - nanort::TriangleSAHPred triangle_pred(rawPositions.data(), rawFaces.data(), - sizeof(double) * 3); // still have no idea what this does - bool ret = accel.Build(mesh->nFaces(), options, triangle_mesh, triangle_pred); - if (!ret) { - throw std::runtime_error("BVH construction failed"); - } - - nanort::BVHBuildStatistics stats = accel.GetStatistics(); - - cout << "BVH statistics:" << endl; - cout << " # of leaf nodes: " << stats.num_leaf_nodes << endl; - cout << " # of branch nodes: " << stats.num_branch_nodes << endl; - cout << " Max tree depth : " << stats.max_tree_depth << endl; - - double lengthScale = geometry->lengthScale(); - tFar = lengthScale * 1e3; -} - -RayHitResult MeshRayTracer::trace(Vector3 start, Vector3 dir) { - // Create the ray - nanort::Ray ray; - ray.min_t = 0.0; - ray.max_t = tFar; - for (int i = 0; i < 3; i++) ray.org[i] = start[i]; - dir = unit(dir); - for (int i = 0; i < 3; i++) ray.dir[i] = dir[i]; - - // Compute the intersection - nanort::BVHTraceOptions trace_options; - nanort::TriangleIntersector triangle_intersector(rawPositions.data(), rawFaces.data(), sizeof(double) * 3); - bool hit = accel.Traverse(ray, trace_options, triangle_intersector); - - // Return the result - if (hit) { - RayHitResult result; - result.hit = true; - result.tHit = triangle_intersector.intersection.t; - result.face = mesh->face(triangle_intersector.intersection.prim_id); - - // Convert barycentric formats - double U = triangle_intersector.intersection.u; - double V = triangle_intersector.intersection.v; - result.baryCoords = Vector3{1.0 - U - V, U, V}; - - return result; - } else { - return RayHitResult{false, std::numeric_limits::quiet_NaN(), Face(), Vector3{-1.0, -1.0, -1.0}}; - } -} - -} // namespace surface -}; // namespace geometrycentral