4a83780e62
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.
83 lines
2.8 KiB
C++
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
|