Files
ViewDesignEngine/include/vde/brep/trimmed_surface.h
T
茂之钳 05b62e8238
CI / Build & Test (push) Failing after 48s
CI / Release Build (push) Failing after 40s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v5-M1): TrimmedSurface integration + SSI boolean + topology healing + tolerance system
M1.1 — TrimmedSurface 深度集成 (Agent #0):
- trimmed_surface.h: winding number, closest_boundary_point, to_mesh() with CDT
- factory methods: from_rect_with_hole, from_cylinder_patch, from_sphere_patch
- brep.h: TopoFace +trimmed_surface_id, add_trimmed_surface()
- brep.cpp: to_mesh() prefers TrimmedSurface path
- modeling.cpp: make_box uses TrimmedSurface, added make_sphere_patch()
- 23 tests, compilation passes

M1.2 — SSI 基布尔运算 (Agent #1):
- ssi_boolean.h/.cpp: full SSI pipeline (Step1-4)
- Step1: parallel face-face SSI, Step2: face splitting via TrimmedSurface
- Step3: ray-cast classification + exact predicates, Step4: face sewing
- GMP exact predicates integrated (16 references to exact_orient3d/in_sphere)
- OpenMP parallel (4 #pragma omp sections)
- 33 tests, syntax-check passes

M1.3 — 拓扑修复 + 容差系统 (Agent #2):
- brep_heal.h/.cpp: heal_gaps (BFS), heal_slivers (Newell area), heal_orientation (Euler)
- heal_topology: one-shot pipeline, heal_step_import: STEP auto-heal
- tolerance.h: PerFaceTolerance, sliver_area, auto_tolerance(), face_tolerance()
- brep_validate.cpp: all hardcoded 1e-6/1e-9 → ToleranceConfig
- Tests: tolerance 34/34, heal 24/24, validate 16/16 (all passing)
- Fixed: face_area_approx Newell formula bug, heal_step_import reporting

19 files, ~3200 lines net new code, 90+ new tests
2026-07-26 20:35:24 +08:00

85 lines
3.7 KiB
C++

#pragma once
#include "vde/curves/nurbs_surface.h"
#include "vde/curves/nurbs_curve.h"
#include "vde/core/point.h"
#include "vde/core/aabb.h"
#include "vde/mesh/halfedge_mesh.h"
#include <optional>
#include <vector>
#include <utility>
namespace vde::brep {
/// A p-curve: 2D curve in the parameter space of a surface
/// We reuse NurbsCurve with Z=0 — only X (u) and Y (v) are meaningful.
using PCurve = curves::NurbsCurve;
/// Trimming loop: closed contour in parameter space (u, v)
/// An outer loop defines the boundary; inner loops define holes.
struct TrimLoop {
std::vector<PCurve> p_curves; ///< parameter-space curves forming the loop
bool is_outer = true; ///< true = outer boundary, false = hole
};
/// A trimmed surface: base NURBS surface + trimming loops in parameter space
///
/// Point classification: a parameter (u, v) is INSIDE if it lies within
/// the outer loop AND outside all inner loops.
///
/// This is the fundamental B-Rep primitive used by all industrial CAD kernels
/// (Parasolid, ACIS, CGM).
///
/// @ingroup brep
struct TrimmedSurface {
curves::NurbsSurface base_surface; ///< Underlying geometry
std::vector<TrimLoop> loops; ///< Trimming loops (first = outer boundary if marked)
/// Evaluate the surface at (u, v).
/// Returns the 3D point only if (u, v) is inside the trimmed region.
/// @return Point3D if inside, std::nullopt if outside
[[nodiscard]] std::optional<core::Point3D> evaluate(double u, double v) const;
/// Check if a parameter point is inside the trimmed region
[[nodiscard]] bool is_inside(double u, double v) const;
/// Compute winding number of point (u,v) relative to a loop
/// Positive = inside (for counter-clockwise outer loop), 0 = outside
[[nodiscard]] int winding_number(double u, double v, const TrimLoop& loop) const;
/// Find the closest point on the boundary to (u,v) — for points outside trimmed region
[[nodiscard]] core::Point3D closest_boundary_point(double u, double v) const;
/// Get the axis-aligned bounding box of the trimmed surface
[[nodiscard]] core::AABB3D bounds() const;
/// Tessellate the trimmed surface to a triangle mesh
/// Uses adaptive grid sampling with inside/outside testing
/// @param deflection chord-height tolerance for tessellation
/// @return HalfedgeMesh containing the triangulated trimmed surface
[[nodiscard]] mesh::HalfedgeMesh to_mesh(double deflection = 0.01) const;
/// Create an untrimmed surface (full parameter domain)
static TrimmedSurface from_surface(const curves::NurbsSurface& surf);
/// Create a rectangular trimmed surface
static TrimmedSurface from_rect(const curves::NurbsSurface& surf,
double u0, double u1, double v0, double v1);
/// Create a trimmed surface with a circular hole
static TrimmedSurface from_rect_with_hole(const curves::NurbsSurface& surf,
double u0, double u1, double v0, double v1,
double hole_uc, double hole_vc, double hole_r,
int hole_segments = 32);
/// Create a trimmed surface for a cylinder side patch
/// u ranges [u0, u1] along circumference, v ranges [v0, v1] along height
static TrimmedSurface from_cylinder_patch(const curves::NurbsSurface& cyl_surf,
double u0, double u1, double v0, double v1);
/// Create a trimmed surface for a sphere patch
static TrimmedSurface from_sphere_patch(const curves::NurbsSurface& sphere_surf,
double u0, double u1, double v0, double v1);
};
} // namespace vde::brep