feat(v4.6): memory pool + parallel boolean/MC/intersection + GMP exact predicates
M1 — Memory Pool (内存池): - ObjectPool<T>: O(1) acquire/release with free-list, chunk-based expansion - ThreadSafeObjectPool<T>: per-thread local pools with global fallback - CowPtr<T>: copy-on-write smart pointer with shallow/deep copy - 10 tests: single/multi-thread, CoW detach, reuse rate M2 — Parallel Boolean (并行布尔): - parallel_face_face_intersection(): OpenMP face-pair dispatch with AABB culling - parallel_classify_faces(): thread-safe ray casting classification - parallel_mesh_union/intersection/difference + B-Rep variants - Thread count management API - 12 tests: coverage, empty cases, identity operations M3 — Parallel Marching Cubes (并行MC): - parallel_marching_cubes(): Z-slice parallel voxel processing - parallel_adaptive_mc(): octree-based adaptive resolution - Complete 256-entry edge table + Möller-Trumbore interpolation - 5 tests: sphere basic/high-res/empty/adaptive/threaded M4 — Parallel Surface Intersection (并行求交): - parallel_curve_intersections(): per-pair parallel dispatch - parallel_surface_intersection(): recursive subdivision + Newton refinement - AABB broad-phase culling before narrow-phase - 4 tests: curve pairs, surface batch M5 — GMP Exact Predicates (精确谓词): - exact_orient2d/3d: adaptive precision (double → GMP fallback) - exact_in_sphere: circumsphere test with degenerate handling - exact_point_in_polygon/polyhedron: robust ray casting - PrecisionMode: Fast/Adaptive/Exact with global toggle - 12 tests: all orientations, boundary cases, mode switching 21 files, +2263 lines
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file parallel_boolean.h
|
||||
* @brief 并行布尔运算
|
||||
*
|
||||
* OpenMP 并行化:面-面求交、射线分类、网格构建。
|
||||
* 串行兼容(OpenMP 不可用时退化到串行)。
|
||||
*
|
||||
* @ingroup brep
|
||||
*/
|
||||
|
||||
#include "vde/brep/brep.h"
|
||||
#include "vde/mesh/halfedge_mesh.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Face-Face Intersection
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 并行计算两实体所有面对的交线
|
||||
*
|
||||
* 外层循环用 OpenMP parallel for 分发面对,内层为单对求交。
|
||||
* 结果线程安全合并。
|
||||
*
|
||||
* @param a 实体 A
|
||||
* @param b 实体 B
|
||||
* @return 所有交线段的集合(每条交线段为 {起点, 终点})
|
||||
*/
|
||||
[[nodiscard]] std::vector<std::pair<core::Point3D, core::Point3D>>
|
||||
parallel_face_face_intersection(const BrepModel& a, const BrepModel& b);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Classification
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 面分类结果
|
||||
enum class FaceClassification {
|
||||
Inside, ///< 面在另一实体内部
|
||||
Outside, ///< 面在另一实体外部
|
||||
OnBoundary, ///< 面在边界上
|
||||
Unknown, ///< 无法确定
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 并行对面进行分类(IN/OUT/ON 判定)
|
||||
*
|
||||
* 每个面独立射线投射测试,线程安全。
|
||||
*
|
||||
* @param faces 待分类的面ID列表
|
||||
* @param body 目标实体
|
||||
* @return face_id → 分类结果
|
||||
*/
|
||||
[[nodiscard]] std::vector<FaceClassification>
|
||||
parallel_classify_faces(const BrepModel& body,
|
||||
const std::vector<int>& face_ids);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Boolean Operations
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 并行网格布尔并集
|
||||
*
|
||||
* @param a 实体 A 的网格
|
||||
* @param b 实体 B 的网格
|
||||
* @return 并集网格
|
||||
*/
|
||||
[[nodiscard]] mesh::HalfedgeMesh parallel_mesh_union(
|
||||
const mesh::HalfedgeMesh& a, const mesh::HalfedgeMesh& b);
|
||||
|
||||
/**
|
||||
* @brief 并行网格布尔交集
|
||||
*/
|
||||
[[nodiscard]] mesh::HalfedgeMesh parallel_mesh_intersection(
|
||||
const mesh::HalfedgeMesh& a, const mesh::HalfedgeMesh& b);
|
||||
|
||||
/**
|
||||
* @brief 并行网格布尔差集 (A - B)
|
||||
*/
|
||||
[[nodiscard]] mesh::HalfedgeMesh parallel_mesh_difference(
|
||||
const mesh::HalfedgeMesh& a, const mesh::HalfedgeMesh& b);
|
||||
|
||||
/**
|
||||
* @brief 并行 B-Rep 布尔并集
|
||||
*
|
||||
* 完整管线:平行面-面求交 → 平行分类 → 缝合
|
||||
*/
|
||||
[[nodiscard]] BrepModel parallel_brep_union(
|
||||
const BrepModel& a, const BrepModel& b);
|
||||
|
||||
/**
|
||||
* @brief 并行 B-Rep 布尔交集
|
||||
*/
|
||||
[[nodiscard]] BrepModel parallel_brep_intersection(
|
||||
const BrepModel& a, const BrepModel& b);
|
||||
|
||||
/**
|
||||
* @brief 并行 B-Rep 布尔差集 (A - B)
|
||||
*/
|
||||
[[nodiscard]] BrepModel parallel_brep_difference(
|
||||
const BrepModel& a, const BrepModel& b);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Performance helpers
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 获取可用线程数
|
||||
[[nodiscard]] int parallel_thread_count();
|
||||
|
||||
/// 设置并行线程数(0 = 自动)
|
||||
void set_parallel_threads(int n);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file exact_predicates.h
|
||||
* @brief 精确几何谓词
|
||||
*
|
||||
* 使用 GMP/MPFR 进行精确算术运算,消除浮点误差。
|
||||
* 关键路径:布尔运算分类、Delaunay 三角剖分、凸包计算。
|
||||
*
|
||||
* 支持混合精度:先用 double,检测到不确定时自动升级到 GMP。
|
||||
*
|
||||
* @ingroup foundation
|
||||
*/
|
||||
|
||||
#include "vde/core/point.h"
|
||||
#include <vector>
|
||||
|
||||
namespace vde::core {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Exact Predicates (double → GMP fallback)
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 精确三点定向 (orient2d)
|
||||
*
|
||||
* 计算 (ax,ay), (bx,by), (cx,cy) 的有向面积 × 2。
|
||||
* > 0 → 逆时针, < 0 → 顺时针, = 0 → 共线。
|
||||
*
|
||||
* 先使用浮点运算,若结果接近 0 则升级到 GMP。
|
||||
*
|
||||
* @return 精确的 orient 值
|
||||
*/
|
||||
[[nodiscard]] double exact_orient2d(
|
||||
double ax, double ay, double bx, double by, double cx, double cy);
|
||||
|
||||
/**
|
||||
* @brief 精确四点定向 (orient3d)
|
||||
*
|
||||
* 计算四面体 (a,b,c,d) 的有向体积 × 6。
|
||||
* > 0 → d 在平面 abc 上方, < 0 → 下方, = 0 → 共面。
|
||||
*/
|
||||
[[nodiscard]] double exact_orient3d(
|
||||
double ax, double ay, double az,
|
||||
double bx, double by, double bz,
|
||||
double cx, double cy, double cz,
|
||||
double dx, double dy, double dz);
|
||||
|
||||
/**
|
||||
* @brief 精确球内测试 (in_sphere)
|
||||
*
|
||||
* 判断点 d 是否在四面体 abc 的外接球内。
|
||||
* > 0 → 内部, < 0 → 外部, = 0 → 在球面上。
|
||||
*/
|
||||
[[nodiscard]] double exact_in_sphere(
|
||||
double ax, double ay, double az,
|
||||
double bx, double by, double bz,
|
||||
double cx, double cy, double cz,
|
||||
double dx, double dy, double dz,
|
||||
double ex, double ey, double ez);
|
||||
|
||||
/**
|
||||
* @brief 精确点在多边形内测试
|
||||
*
|
||||
* 射线投射法 + 精确算术处理边界情况。
|
||||
*
|
||||
* @param point 测试点
|
||||
* @param polygon 多边形顶点(逆时针)
|
||||
* @return true 如果点在多边形内或边界上
|
||||
*/
|
||||
[[nodiscard]] bool exact_point_in_polygon(
|
||||
const Point3D& point, const std::vector<Point3D>& polygon);
|
||||
|
||||
/**
|
||||
* @brief 精确点在多面体内测试
|
||||
*
|
||||
* 射线投射法,使用精确算术处理共面/共线退化情况。
|
||||
*
|
||||
* @param point 测试点
|
||||
* @param vertices 多面体顶点
|
||||
* @param faces 面索引(每面 3+ 个顶点索引)
|
||||
* @return true 如果点在体内
|
||||
*/
|
||||
[[nodiscard]] bool exact_point_in_polyhedron(
|
||||
const Point3D& point,
|
||||
const std::vector<Point3D>& vertices,
|
||||
const std::vector<std::vector<int>>& faces);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Adaptive precision wrapper
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 精度模式
|
||||
enum class PrecisionMode {
|
||||
Fast, ///< 仅使用 double(默认)
|
||||
Adaptive, ///< 先 double,不确定时升级到 GMP
|
||||
Exact, ///< 始终使用 GMP
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 设置全局精度模式
|
||||
*/
|
||||
void set_precision_mode(PrecisionMode mode);
|
||||
|
||||
/**
|
||||
* @brief 获取当前精度模式
|
||||
*/
|
||||
[[nodiscard]] PrecisionMode precision_mode();
|
||||
|
||||
/**
|
||||
* @brief 检查和报告两浮点数是否在误差范围内"不确定"
|
||||
*
|
||||
* 用于自适应精度升级判断。
|
||||
*/
|
||||
[[nodiscard]] bool is_uncertain(double value, double threshold = 1e-10);
|
||||
|
||||
} // namespace vde::core
|
||||
@@ -0,0 +1,277 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file object_pool.h
|
||||
* @brief 高性能对象池 + 写时复制
|
||||
*
|
||||
* 对象池:预分配 chunk,free-list 回收,O(1) acquire/release。
|
||||
* 写时复制:引用计数共享,修改时深拷贝,避免不必要的大对象拷贝。
|
||||
*
|
||||
* @ingroup foundation
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::core {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// ObjectPool — 单线程对象池
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 高性能对象池(单线程)
|
||||
*
|
||||
* 预分配 chunk 减少 malloc 调用,free-list 实现 O(1) 回收。
|
||||
*
|
||||
* @tparam T 池化对象类型(需有默认构造函数)
|
||||
* @tparam ChunkSize 每次扩容时分配的 chunk 大小
|
||||
*
|
||||
* @ingroup foundation
|
||||
*/
|
||||
template <typename T, size_t ChunkSize = 256>
|
||||
class ObjectPool {
|
||||
static_assert(std::is_default_constructible_v<T>,
|
||||
"T must be default constructible");
|
||||
|
||||
public:
|
||||
ObjectPool() { expand(); }
|
||||
~ObjectPool() {
|
||||
for (auto* chunk : chunks_) {
|
||||
::operator delete(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/// 禁止拷贝
|
||||
ObjectPool(const ObjectPool&) = delete;
|
||||
ObjectPool& operator=(const ObjectPool&) = delete;
|
||||
|
||||
/**
|
||||
* @brief 获取一个对象(复用或新建)
|
||||
* @return 对象指针
|
||||
*/
|
||||
[[nodiscard]] T* acquire();
|
||||
|
||||
/**
|
||||
* @brief 归还对象到池中
|
||||
* @param ptr 之前由 acquire() 返回的指针
|
||||
*/
|
||||
void release(T* ptr);
|
||||
|
||||
/// 统计
|
||||
[[nodiscard]] size_t total_allocated() const { return total_allocated_; }
|
||||
[[nodiscard]] size_t total_reused() const { return total_reused_; }
|
||||
[[nodiscard]] size_t pool_size() const { return chunks_.size() * ChunkSize; }
|
||||
[[nodiscard]] size_t free_count() const { return free_count_; }
|
||||
[[nodiscard]] double reuse_rate() const;
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Node* next = nullptr;
|
||||
T data;
|
||||
};
|
||||
|
||||
std::vector<Node*> chunks_; ///< 分配的 chunk
|
||||
Node* free_list_ = nullptr; ///< 空闲列表头
|
||||
size_t free_count_ = 0;
|
||||
size_t total_allocated_ = 0;
|
||||
size_t total_reused_ = 0;
|
||||
|
||||
void expand();
|
||||
};
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
T* ObjectPool<T, ChunkSize>::acquire() {
|
||||
if (free_list_ == nullptr) {
|
||||
expand();
|
||||
}
|
||||
|
||||
total_allocated_++;
|
||||
if (free_list_ != chunks_.back()) {
|
||||
total_reused_++;
|
||||
}
|
||||
|
||||
Node* node = free_list_;
|
||||
free_list_ = node->next;
|
||||
free_count_--;
|
||||
|
||||
// Reset the object to default state
|
||||
node->data = T{};
|
||||
return &node->data;
|
||||
}
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
void ObjectPool<T, ChunkSize>::release(T* ptr) {
|
||||
if (!ptr) return;
|
||||
|
||||
// Recover the Node pointer from the data pointer
|
||||
Node* node = reinterpret_cast<Node*>(
|
||||
reinterpret_cast<char*>(ptr) - offsetof(Node, data));
|
||||
|
||||
node->next = free_list_;
|
||||
free_list_ = node;
|
||||
free_count_++;
|
||||
}
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
void ObjectPool<T, ChunkSize>::expand() {
|
||||
auto* chunk = static_cast<Node*>(::operator new(ChunkSize * sizeof(Node)));
|
||||
chunks_.push_back(chunk);
|
||||
|
||||
// Build free list from the new chunk
|
||||
for (size_t i = 0; i < ChunkSize; ++i) {
|
||||
chunk[i].next = free_list_;
|
||||
free_list_ = &chunk[i];
|
||||
}
|
||||
free_count_ += ChunkSize;
|
||||
}
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
double ObjectPool<T, ChunkSize>::reuse_rate() const {
|
||||
if (total_allocated_ == 0) return 0.0;
|
||||
return static_cast<double>(total_reused_) / total_allocated_;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// ThreadSafeObjectPool — 线程安全对象池
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 线程安全对象池
|
||||
*
|
||||
* 每线程独立 pool + global fallback,无锁竞争。
|
||||
*
|
||||
* @tparam T 池化对象类型
|
||||
* @tparam ChunkSize 每个线程 local pool 的 chunk 大小
|
||||
*/
|
||||
template <typename T, size_t ChunkSize = 256>
|
||||
class ThreadSafeObjectPool {
|
||||
public:
|
||||
[[nodiscard]] T* acquire();
|
||||
void release(T* ptr);
|
||||
|
||||
[[nodiscard]] size_t total_allocated() const { return global_allocated_.load(); }
|
||||
|
||||
private:
|
||||
// Per-thread pool (thread_local)
|
||||
static thread_local ObjectPool<T, ChunkSize> local_pool_;
|
||||
|
||||
// Fallback when local pool is empty
|
||||
ObjectPool<T, ChunkSize> global_pool_;
|
||||
std::mutex global_mutex_;
|
||||
std::atomic<size_t> global_allocated_{0};
|
||||
};
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
thread_local ObjectPool<T, ChunkSize> ThreadSafeObjectPool<T, ChunkSize>::local_pool_{};
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
T* ThreadSafeObjectPool<T, ChunkSize>::acquire() {
|
||||
// Try local pool first (no lock)
|
||||
if (local_pool_.free_count() > 0) {
|
||||
return local_pool_.acquire();
|
||||
}
|
||||
|
||||
// Fall back to global pool
|
||||
std::lock_guard<std::mutex> lock(global_mutex_);
|
||||
if (global_pool_.free_count() > 0) {
|
||||
global_allocated_++;
|
||||
return global_pool_.acquire();
|
||||
}
|
||||
|
||||
// Both empty — expand global
|
||||
global_allocated_++;
|
||||
return global_pool_.acquire();
|
||||
}
|
||||
|
||||
template <typename T, size_t ChunkSize>
|
||||
void ThreadSafeObjectPool<T, ChunkSize>::release(T* ptr) {
|
||||
// Return to local pool
|
||||
local_pool_.release(ptr);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// CowPtr — Copy-on-Write 智能指针
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 写时复制 (Copy-on-Write) 智能指针
|
||||
*
|
||||
* 类似 shared_ptr,但修改时自动深拷贝(detach)。
|
||||
* 用于大对象如 NurbsSurface、HalfedgeMesh 的共享。
|
||||
*
|
||||
* @tparam T 被包装类型
|
||||
*/
|
||||
template <typename T>
|
||||
class CowPtr {
|
||||
public:
|
||||
CowPtr() = default;
|
||||
|
||||
explicit CowPtr(T value)
|
||||
: data_(std::make_shared<T>(std::move(value))) {}
|
||||
|
||||
CowPtr(const CowPtr& other) = default;
|
||||
CowPtr& operator=(const CowPtr& other) = default;
|
||||
CowPtr(CowPtr&&) = default;
|
||||
CowPtr& operator=(CowPtr&&) = default;
|
||||
|
||||
/// 只读访问
|
||||
[[nodiscard]] const T& read() const {
|
||||
ensure_valid();
|
||||
return *data_;
|
||||
}
|
||||
|
||||
/// 可写访问(如有共享则深拷贝)
|
||||
[[nodiscard]] T& write() {
|
||||
ensure_valid();
|
||||
detach();
|
||||
return *data_;
|
||||
}
|
||||
|
||||
/// 只读解引用
|
||||
[[nodiscard]] const T& operator*() const { return read(); }
|
||||
[[nodiscard]] const T* operator->() const { return &read(); }
|
||||
|
||||
/// 引用计数
|
||||
[[nodiscard]] long use_count() const {
|
||||
return data_ ? data_.use_count() : 0;
|
||||
}
|
||||
|
||||
/// 是否唯一持有
|
||||
[[nodiscard]] bool unique() const {
|
||||
return data_ && data_.use_count() == 1;
|
||||
}
|
||||
|
||||
/// 浅拷贝(共享数据)
|
||||
[[nodiscard]] CowPtr shallow_copy() const {
|
||||
return CowPtr(*this);
|
||||
}
|
||||
|
||||
/// 深拷贝(显式复制数据)
|
||||
[[nodiscard]] CowPtr deep_copy() const {
|
||||
if (!data_) return CowPtr();
|
||||
return CowPtr(T(*data_));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<T> data_;
|
||||
|
||||
void ensure_valid() const {
|
||||
if (!data_) {
|
||||
const_cast<CowPtr*>(this)->data_ = std::make_shared<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/// 如果数据被共享,则深拷贝
|
||||
void detach() {
|
||||
if (data_ && data_.use_count() > 1) {
|
||||
data_ = std::make_shared<T>(*data_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace vde::core
|
||||
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file parallel_intersection.h
|
||||
* @brief 并行曲面/曲线求交
|
||||
*
|
||||
* OpenMP 并行化曲面-曲面求交和曲线-曲线求交。
|
||||
*
|
||||
* @ingroup curves
|
||||
*/
|
||||
|
||||
#include "vde/core/point.h"
|
||||
#include "vde/curves/nurbs_curve.h"
|
||||
#include "vde/curves/nurbs_surface.h"
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace vde::curves {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Curve Intersection
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* @brief 并行计算一组曲线对的交点
|
||||
*
|
||||
* 每对曲线独立求交,结果线程安全合并。
|
||||
*
|
||||
* @param curve_pairs 曲线对列表 ((curve_a_idx, curve_b_idx), ...)
|
||||
* @param curves_a 曲线集合 A
|
||||
* @param curves_b 曲线集合 B
|
||||
* @return 每条曲线对的交点参数列表
|
||||
*/
|
||||
[[nodiscard]] std::vector<std::vector<std::pair<double, double>>>
|
||||
parallel_curve_intersections(
|
||||
const std::vector<std::pair<int, int>>& curve_pairs,
|
||||
const std::vector<NurbsCurve>& curves_a,
|
||||
const std::vector<NurbsCurve>& curves_b);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Surface Intersection
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 曲面交线段
|
||||
struct SurfaceIntersectionSegment {
|
||||
core::Point3D start;
|
||||
core::Point3D end;
|
||||
double u_a_start, v_a_start;
|
||||
double u_a_end, v_a_end;
|
||||
double u_b_start, v_b_start;
|
||||
double u_b_end, v_b_end;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 并行计算两曲面的交线
|
||||
*
|
||||
* 递归细分 + 牛顿精化,边界盒预筛选,并行分发。
|
||||
*
|
||||
* @param surf_a 曲面 A
|
||||
* @param surf_b 曲面 B
|
||||
* @param tolerance 精度要求
|
||||
* @param max_refinements 最大细分次数
|
||||
* @return 交线段列表
|
||||
*/
|
||||
[[nodiscard]] std::vector<SurfaceIntersectionSegment>
|
||||
parallel_surface_intersection(
|
||||
const NurbsSurface& surf_a, const NurbsSurface& surf_b,
|
||||
double tolerance = 1e-6, int max_refinements = 10);
|
||||
|
||||
/**
|
||||
* @brief 并行批量曲面-曲面对求交
|
||||
*
|
||||
* @param pairs 曲面对索引
|
||||
* @param surfaces_a 曲面集合 A
|
||||
* @param surfaces_b 曲面集合 B
|
||||
* @return 每对曲面的交线段列表
|
||||
*/
|
||||
[[nodiscard]] std::vector<std::vector<SurfaceIntersectionSegment>>
|
||||
parallel_surface_intersections(
|
||||
const std::vector<std::pair<int, int>>& pairs,
|
||||
const std::vector<NurbsSurface>& surfaces_a,
|
||||
const std::vector<NurbsSurface>& surfaces_b,
|
||||
double tolerance = 1e-6);
|
||||
|
||||
} // namespace vde::curves
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file parallel_mc.h
|
||||
* @brief 并行 Marching Cubes
|
||||
*
|
||||
* 体素网格分块并行处理,每线程独立三角形缓冲区,最终合并。
|
||||
* 支持自适应八叉树分辨率。
|
||||
*
|
||||
* @ingroup mesh
|
||||
*/
|
||||
|
||||
#include "vde/mesh/halfedge_mesh.h"
|
||||
#include "vde/sdf/sdf_tree.h"
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace vde::mesh {
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// Parallel Marching Cubes
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
|
||||
/// 并行 MC 配置
|
||||
struct ParallelMCConfig {
|
||||
int resolution = 64; ///< 基础分辨率(每轴体素数)
|
||||
int num_threads = 0; ///< 线程数(0 = 自动)
|
||||
bool adaptive = false; ///< 是否启用自适应分辨率
|
||||
double min_voxel_size = 0.01; ///< 自适应最小体素
|
||||
int max_depth = 4; ///< 自适应最大细分深度
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 并行 Marching Cubes
|
||||
*
|
||||
* 将体素网格沿 Z 轴分块,每线程处理一块。
|
||||
* SDF 求值需要线程安全(只读操作)。
|
||||
*
|
||||
* @param sdf SDF 求值函数 f(x,y,z) → signed distance
|
||||
* @param bounds 体素空间包围盒
|
||||
* @param config 配置参数
|
||||
* @return 生成的三角网格
|
||||
*/
|
||||
[[nodiscard]] HalfedgeMesh parallel_marching_cubes(
|
||||
const std::function<double(double, double, double)>& sdf,
|
||||
const core::AABB3D& bounds,
|
||||
const ParallelMCConfig& config = {});
|
||||
|
||||
/**
|
||||
* @brief 并行自适应 Marching Cubes
|
||||
*
|
||||
* 平坦区域用大格子,曲面附近细分。
|
||||
*
|
||||
* @param sdf SDF 求值函数
|
||||
* @param bounds 包围盒
|
||||
* @param config 配置参数
|
||||
* @return 生成的三角网格
|
||||
*/
|
||||
[[nodiscard]] HalfedgeMesh parallel_adaptive_mc(
|
||||
const std::function<double(double, double, double)>& sdf,
|
||||
const core::AABB3D& bounds,
|
||||
const ParallelMCConfig& config = {});
|
||||
|
||||
} // namespace vde::mesh
|
||||
Reference in New Issue
Block a user