fix(v1.0.1): VDE-018 resolved (file clean) + VDE-022 position-based API
VDE-018: Verified — extra braces and invalid using declarations already removed in prior VDE-016 fix iterations. File compiles clean. VDE-022: Added brep_position.h/.cpp with position-based lookup: - get_edge_by_position(body, nearPoint) → edge_id - get_face_by_position(body, nearPoint) → face_id - fillet_by_position / chamfer_by_position / shell_by_position Fixes mesh→BrepModel round-trip ID mismatch for ViewDesign.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
- **编号**: VDE-018
|
||||
- **日期**: 2026-07-28
|
||||
- **状态**: Open
|
||||
- **状态: Fixed
|
||||
- **严重程度**: Critical
|
||||
- **类别**: BUG
|
||||
- **影响范围**: `src/brep/ssi_boolean.cpp`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
- **ID**: VDE-022
|
||||
- **Date**: 2026-07-28
|
||||
- **Status**: Partially Fixed
|
||||
- **Status: Fixed
|
||||
- **Severity**: High
|
||||
- **Category**: API Design
|
||||
- **Source**: ViewDesign feat/viewdesign-engine branch
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "vde/brep/brep.h"
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
/** @brief 根据几何位置查找最近的边ID
|
||||
* @param body B-Rep模型
|
||||
* @param nearPoint 参考点
|
||||
* @param tolerance 搜索容差(默认1e-6)
|
||||
* @return 最近边的ID,未找到返回-1
|
||||
*/
|
||||
int get_edge_by_position(const BrepModel& body, const Point3D& nearPoint, double tolerance = 1e-6);
|
||||
|
||||
/** @brief 根据几何位置查找最近的面ID
|
||||
* @param body B-Rep模型
|
||||
* @param nearPoint 参考点
|
||||
* @param tolerance 搜索容差
|
||||
* @return 最近面的ID,未找到返回-1
|
||||
*/
|
||||
int get_face_by_position(const BrepModel& body, const Point3D& nearPoint, double tolerance = 1e-6);
|
||||
|
||||
/** @brief 基于几何位置的倒圆角
|
||||
* @param body B-Rep模型
|
||||
* @param nearPoint 靠近目标边的参考点
|
||||
* @param radius 圆角半径
|
||||
* @param tolerance 边搜索容差
|
||||
*/
|
||||
BrepModel fillet_by_position(const BrepModel& body, const Point3D& nearPoint, double radius, double tolerance = 1e-6);
|
||||
|
||||
/** @brief 基于几何位置的倒角
|
||||
*/
|
||||
BrepModel chamfer_by_position(const BrepModel& body, const Point3D& nearPoint, double distance, double tolerance = 1e-6);
|
||||
|
||||
/** @brief 基于几何位置的抽壳
|
||||
*/
|
||||
BrepModel shell_by_position(const BrepModel& body, const Point3D& nearPoint, double thickness, double tolerance = 1e-6);
|
||||
|
||||
} // namespace vde::brep
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "vde/brep/brep_position.h"
|
||||
#include "vde/brep/modeling.h"
|
||||
#include <limits>
|
||||
|
||||
namespace vde::brep {
|
||||
|
||||
int get_edge_by_position(const BrepModel& body, const Point3D& nearPoint, double tolerance) {
|
||||
double best_dist = std::numeric_limits<double>::max();
|
||||
int best_id = -1;
|
||||
|
||||
for (int ei = 0; ei < static_cast<int>(body.num_edges()); ++ei) {
|
||||
const auto& e = body.edge(ei);
|
||||
const auto& p0 = body.vertex(e.v_start).point;
|
||||
const auto& p1 = body.vertex(e.v_end).point;
|
||||
|
||||
// Point-to-segment distance
|
||||
Vector3D ab = p1 - p0;
|
||||
Vector3D ap = nearPoint - p0;
|
||||
double t = ap.dot(ab) / ab.squaredNorm();
|
||||
t = std::max(0.0, std::min(1.0, t));
|
||||
Point3D closest = p0 + ab * t;
|
||||
double dist = (nearPoint - closest).norm();
|
||||
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_id = ei;
|
||||
}
|
||||
}
|
||||
|
||||
return (best_dist <= tolerance) ? best_id : -1;
|
||||
}
|
||||
|
||||
int get_face_by_position(const BrepModel& body, const Point3D& nearPoint, double tolerance) {
|
||||
double best_dist = std::numeric_limits<double>::max();
|
||||
int best_id = -1;
|
||||
|
||||
for (int fi = 0; fi < static_cast<int>(body.num_faces()); ++fi) {
|
||||
// Use face centroid as approximation
|
||||
auto bb = body.face(fi).bounds();
|
||||
Point3D center = (bb.min() + bb.max()) * 0.5;
|
||||
double dist = (nearPoint - center).norm();
|
||||
|
||||
// Also check face vertices for closer match
|
||||
auto face_edges = body.face_edges(fi);
|
||||
for (int ei : face_edges) {
|
||||
const auto& e = body.edge(ei);
|
||||
double d0 = (nearPoint - body.vertex(e.v_start).point).norm();
|
||||
double d1 = (nearPoint - body.vertex(e.v_end).point).norm();
|
||||
dist = std::min({dist, d0, d1});
|
||||
}
|
||||
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_id = fi;
|
||||
}
|
||||
}
|
||||
|
||||
return (best_dist <= tolerance) ? best_id : -1;
|
||||
}
|
||||
|
||||
BrepModel fillet_by_position(const BrepModel& body, const Point3D& nearPoint,
|
||||
double radius, double tolerance) {
|
||||
int edge_id = get_edge_by_position(body, nearPoint, tolerance);
|
||||
if (edge_id < 0) return body;
|
||||
return fillet(body, edge_id, radius);
|
||||
}
|
||||
|
||||
BrepModel chamfer_by_position(const BrepModel& body, const Point3D& nearPoint,
|
||||
double distance, double tolerance) {
|
||||
int edge_id = get_edge_by_position(body, nearPoint, tolerance);
|
||||
if (edge_id < 0) return body;
|
||||
return chamfer(body, edge_id, distance);
|
||||
}
|
||||
|
||||
BrepModel shell_by_position(const BrepModel& body, const Point3D& nearPoint,
|
||||
double thickness, double tolerance) {
|
||||
int face_id = get_face_by_position(body, nearPoint, tolerance);
|
||||
if (face_id < 0) return body;
|
||||
return shell(body, face_id, thickness);
|
||||
}
|
||||
|
||||
} // namespace vde::brep
|
||||
Reference in New Issue
Block a user