#pragma once #include "vde/brep/brep.h" #include "vde/core/transform.h" #include "vde/mesh/halfedge_mesh.h" #include #include #include #include namespace vde::brep { using core::Point3D; using core::Vector3D; using core::Transform3D; /** * @brief 装配体节点 * * 表示装配体树中的一个节点,可以是零件(含 B-Rep 模型)或子装配体。 * 每个节点有局部变换矩阵和名称。 * * @ingroup brep */ struct AssemblyNode { /// 节点名称 std::string name; /// 局部(相对父节点)变换矩阵 Transform3D local_transform = Transform3D::Identity(); /// 此节点的 B-Rep 模型(零件),可选 std::optional model; /// 子节点列表 std::vector> children; /// 是否是零件节点(有 model)还是子装配体(有 children) [[nodiscard]] bool is_part() const { return model.has_value() && children.empty(); } /// 添加子节点 AssemblyNode* add_child(std::unique_ptr child) { auto* ptr = child.get(); children.push_back(std::move(child)); return ptr; } /// 添加 B-Rep 零件 AssemblyNode* add_part(const std::string& part_name, BrepModel part_model, const Transform3D& transform = Transform3D::Identity()) { auto node = std::make_unique(); node->name = part_name; node->model = std::move(part_model); node->local_transform = transform; return add_child(std::move(node)); } /// 添加子装配体 AssemblyNode* add_subassembly(const std::string& sub_name, const Transform3D& transform = Transform3D::Identity()) { auto node = std::make_unique(); node->name = sub_name; node->local_transform = transform; return add_child(std::move(node)); } }; /** * @brief 装配体 * * 装配体树的根节点。管理零件和子装配体的层级结构。 * * @code{.cpp} * Assembly assembly("robot_arm"); * auto* base = assembly.root().add_part("base", make_box(10,10,2)); * auto* arm = assembly.root().add_subassembly("arm", * Transform3D::Translation(0,0,2)); * arm->add_part("segment1", make_cylinder(0.5, 8)); * @endcode * * @ingroup brep */ struct Assembly { /// 装配体名称 std::string name; /// 版本号 std::string version = "1.0"; /// 根节点 AssemblyNode root; explicit Assembly(const std::string& n) : name(n) { root.name = n; } /// 遍历所有零件节点 template void visit_parts(Visitor&& visitor) const { visit_parts_impl(&root, Transform3D::Identity(), std::forward(visitor)); } /// 统计零件总数 [[nodiscard]] size_t part_count() const { size_t count = 0; visit_parts([&count](const std::string&, const BrepModel&, const Transform3D&) { ++count; }); return count; } /// 统计节点总数(含子装配体) [[nodiscard]] size_t node_count() const { return node_count_impl(&root); } private: template void visit_parts_impl(const AssemblyNode* node, const Transform3D& parent_xform, Visitor&& visitor) const { Transform3D world = parent_xform * node->local_transform; if (node->model.has_value()) { visitor(node->name, *node->model, world); } for (const auto& child : node->children) { visit_parts_impl(child.get(), world, std::forward(visitor)); } } size_t node_count_impl(const AssemblyNode* node) const { size_t n = 1; // count this node for (const auto& child : node->children) n += node_count_impl(child.get()); return n; } }; // ═══════════════════════════════════════════════ // VDE-025: MeshData→Assembly 批量构建 API // ═══════════════════════════════════════════════ /** * @brief 零件输入描述(VDE-025) * * 包含零件名称、三角网格和变换矩阵, * 用于 build_assembly_from_meshes() 批量构建装配体。 * * @ingroup brep */ struct PartInput { /// 零件名称 std::string name; /// 三角网格数据 mesh::HalfedgeMesh mesh; /// 局部变换矩阵(相对父节点) Transform3D transform = Transform3D::Identity(); }; /** * @brief 将三角网格转换为 B-Rep 模型(VDE-025) * * 每个三角面转换为一个平面 B-Rep 面, * 所有面聚合成单个封闭壳和体。 * * @param mesh 输入三角网格 * @return 对应的 BrepModel * * @ingroup brep */ [[nodiscard]] BrepModel mesh_to_brep_model(const mesh::HalfedgeMesh& mesh); /** * @brief 从网格零件批量构建装配体(VDE-025) * * 并行将每个 PartInput 的网格转换为 BrepModel, * 统一管理内存,通过根节点构建层级装配体。 * * @param parts 零件输入列表 * @return 构建完成的 Assembly * * @code{.cpp} * HalfedgeMesh mesh1 = ..., mesh2 = ...; * std::vector inputs = { * {"base", mesh1, Transform3D::Identity()}, * {"arm", mesh2, translate(0, 0, 5)} * }; * auto assembly = build_assembly_from_meshes(inputs); * @endcode * * @ingroup brep */ [[nodiscard]] Assembly build_assembly_from_meshes( const std::vector& parts); } // namespace vde::brep