Files
ViewDesignEngine/src/brep/brep_position.cpp
T
茂之钳 4a83780e62
CI / Build & Test (push) Failing after 34s
CI / Release Build (push) Failing after 32s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
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.
2026-07-28 17:27:18 +08:00

83 lines
2.8 KiB
C++

#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