fix: SDF nan/edge cases + B-Rep vertex index → ID fix + IGES 1-based DE + STEP cleanup
This commit is contained in:
+49
-18
@@ -14,13 +14,19 @@ curves::NurbsSurface make_plane_surface(const Point3D& p0, const Point3D& p1,
|
||||
}
|
||||
|
||||
// Offset a vertex along its normal (average of adjacent face normals)
|
||||
Point3D offset_vertex(const BrepModel& body, int vertex_id, double dist) {
|
||||
Point3D p = body.vertex(vertex_id).point;
|
||||
auto edges = body.vertex_edges(vertex_id);
|
||||
// vertex_idx = vertex array index (0..num_vertices-1)
|
||||
Point3D offset_vertex(const BrepModel& body, int vertex_idx, double dist) {
|
||||
const auto& v = body.vertex(vertex_idx);
|
||||
Point3D p = v.point;
|
||||
int vid = v.id; // Actual vertex ID (for matching edge v_start/v_end)
|
||||
|
||||
Vector3D avg_normal(0,0,0);
|
||||
int count = 0;
|
||||
for (int ei : edges) {
|
||||
auto efs = body.edge_faces(ei);
|
||||
// Iterate all edges by INDEX and check v_start/v_end against vertex ID
|
||||
for (size_t ei = 0; ei < body.num_edges(); ++ei) {
|
||||
const auto& e = body.edge(static_cast<int>(ei));
|
||||
if (e.v_start != vid && e.v_end != vid) continue;
|
||||
auto efs = body.edge_faces(static_cast<int>(ei));
|
||||
for (int fi : efs) {
|
||||
const auto& face = body.face(fi);
|
||||
const auto& surf = body.surface(face.surface_id);
|
||||
@@ -43,9 +49,10 @@ Vector3D compute_face_normal(const BrepModel& body, int face_id) {
|
||||
if (es.size() < 3) return Vector3D::UnitZ();
|
||||
const auto& e0 = body.edge(es[0]);
|
||||
const auto& e1 = body.edge(es[1]);
|
||||
Point3D p0 = body.vertex(e0.v_start).point;
|
||||
Point3D p1 = body.vertex(e0.v_end).point;
|
||||
Point3D p2 = body.vertex(e1.v_end).point;
|
||||
// v_start/v_end store vertex IDs — use vertex_by_id for proper lookup
|
||||
Point3D p0 = body.vertex_by_id(e0.v_start).point;
|
||||
Point3D p1 = body.vertex_by_id(e0.v_end).point;
|
||||
Point3D p2 = body.vertex_by_id(e1.v_end).point;
|
||||
Vector3D n = (p1 - p0).cross(p2 - p0);
|
||||
if (n.norm() > 1e-12) return n.normalized();
|
||||
return Vector3D::UnitZ();
|
||||
@@ -301,10 +308,33 @@ BrepModel fillet(const BrepModel& body, int edge_id, double radius) {
|
||||
if (edge_id < 0 || edge_id >= num_edges) return body;
|
||||
if (radius <= 0.0) return body;
|
||||
|
||||
// Find adjacent faces — in this implementation edges are not shared,
|
||||
// so edge_faces only returns 1 face. Find the other face geometrically.
|
||||
auto efs = body.edge_faces(edge_id);
|
||||
if (efs.size() != 2) return body; // Only handle manifold edges with 2 adjacent faces
|
||||
if (efs.empty()) return body;
|
||||
int face_a = efs[0];
|
||||
|
||||
int face_a = efs[0], face_b = efs[1];
|
||||
// Find face_b: searches for a face with an edge at the same geometric position
|
||||
const auto& edge = body.edge(edge_id);
|
||||
Point3D ep0 = body.vertex_by_id(edge.v_start).point;
|
||||
Point3D ep1 = body.vertex_by_id(edge.v_end).point;
|
||||
int face_b = -1;
|
||||
for (size_t fi = 0; fi < body.num_faces(); ++fi) {
|
||||
if (static_cast<int>(fi) == face_a) continue;
|
||||
auto f_edges = body.face_edges(static_cast<int>(fi));
|
||||
for (int ei : f_edges) {
|
||||
const auto& e2 = body.edge(ei);
|
||||
Point3D q0 = body.vertex_by_id(e2.v_start).point;
|
||||
Point3D q1 = body.vertex_by_id(e2.v_end).point;
|
||||
bool same_edge = ((ep0-q0).norm() < 1e-7 && (ep1-q1).norm() < 1e-7) ||
|
||||
((ep0-q1).norm() < 1e-7 && (ep1-q0).norm() < 1e-7);
|
||||
if (same_edge) { face_b = static_cast<int>(fi); break; }
|
||||
}
|
||||
if (face_b >= 0) break;
|
||||
}
|
||||
if (face_b < 0) return body; // No adjacent face found
|
||||
|
||||
int face_a_id = face_a, face_b_id = face_b;
|
||||
const auto& edge = body.edge(edge_id);
|
||||
const auto& curve = *edge.curve;
|
||||
|
||||
@@ -370,8 +400,8 @@ BrepModel fillet(const BrepModel& body, int edge_id, double radius) {
|
||||
std::vector<int> new_es;
|
||||
for (int ei : lop.edges) {
|
||||
const auto& e_src = body.edge(ei);
|
||||
Point3D p0 = body.vertex(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex(e_src.v_end).point;
|
||||
Point3D p0 = body.vertex_by_id(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex_by_id(e_src.v_end).point;
|
||||
int nv0 = result.add_vertex(p0);
|
||||
int nv1 = result.add_vertex(p1);
|
||||
new_es.push_back(result.add_edge(nv0, nv1));
|
||||
@@ -444,8 +474,8 @@ BrepModel fillet(const BrepModel& body, int edge_id, double radius) {
|
||||
for (size_t j = 1; j < sorted_edges.size(); ++j) {
|
||||
int old_ei = sorted_edges[j];
|
||||
const auto& e_src = body.edge(old_ei);
|
||||
Point3D p0 = body.vertex(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex(e_src.v_end).point;
|
||||
Point3D p0 = body.vertex_by_id(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex_by_id(e_src.v_end).point;
|
||||
|
||||
// If either endpoint is on the filleted edge, offset it
|
||||
bool v0_on_edge = (e_src.v_start == edge_src.v_start ||
|
||||
@@ -594,8 +624,8 @@ BrepModel chamfer(const BrepModel& body, int edge_id, double dist) {
|
||||
std::vector<int> new_es;
|
||||
for (int ei : lop.edges) {
|
||||
const auto& e_src = body.edge(ei);
|
||||
Point3D p0 = body.vertex(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex(e_src.v_end).point;
|
||||
Point3D p0 = body.vertex_by_id(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex_by_id(e_src.v_end).point;
|
||||
new_es.push_back(result.add_edge(
|
||||
result.add_vertex(p0), result.add_vertex(p1)));
|
||||
}
|
||||
@@ -633,8 +663,8 @@ BrepModel chamfer(const BrepModel& body, int edge_id, double dist) {
|
||||
int oe_idx = static_cast<int>((ei + j) % lop.edges.size());
|
||||
int old_ei = lop.edges[oe_idx];
|
||||
const auto& e_src = body.edge(old_ei);
|
||||
Point3D p0 = body.vertex(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex(e_src.v_end).point;
|
||||
Point3D p0 = body.vertex_by_id(e_src.v_start).point;
|
||||
Point3D p1 = body.vertex_by_id(e_src.v_end).point;
|
||||
|
||||
bool v0_on = (e_src.v_start == edge_src.v_start ||
|
||||
e_src.v_start == edge_src.v_end);
|
||||
@@ -698,6 +728,7 @@ BrepModel chamfer(const BrepModel& body, int edge_id, double dist) {
|
||||
// ── Shell ──
|
||||
BrepModel shell(const BrepModel& body, int open_face, double thickness) {
|
||||
BrepModel result;
|
||||
body.num_vertices(), body.num_faces(), open_face, thickness);
|
||||
|
||||
// ── 1. Offset all vertices inward ──
|
||||
std::vector<int> outer_vid(body.num_vertices()); // map old id → new outer id
|
||||
|
||||
Reference in New Issue
Block a user