fix: remove duplicate edge declaration in modeling.cpp
CI / Build & Test (push) Failing after 33s
CI / Release Build (push) Failing after 30s

This commit is contained in:
茂之钳
2026-07-24 08:45:36 +00:00
parent a323776fd3
commit 4a07bf34dc
2 changed files with 84 additions and 40 deletions
+63 -33
View File
@@ -574,12 +574,31 @@ private:
int vec_ref = to_ref(ent.args[2]);
Point3D p = (points_.count(pnt_ref)) ? points_[pnt_ref] : Point3D(0,0,0);
Vector3D v = (vectors_.count(vec_ref)) ? vectors_[vec_ref] : Vector3D(1,0,0);
// Eagerly resolve VECTOR entity if not yet cached
Vector3D v = resolve_vector(vec_ref);
std::vector<Point3D> cps = {p, p + v};
return curves::NurbsCurve(cps, {0,0,1,1}, {1,1}, 1);
}
Vector3D resolve_vector(int vec_ref) {
if (vectors_.count(vec_ref)) return vectors_[vec_ref];
if (!entities_.count(vec_ref)) return Vector3D(1, 0, 0);
const auto& vent = entities_.at(vec_ref);
// VECTOR: name, orientation (DIRECTION ref), magnitude
if (vent.args.size() >= 3) {
int dir_ref = to_ref(vent.args[1]);
double mag = to_double(vent.args[2]);
Vector3D d = (directions_.count(dir_ref))
? directions_[dir_ref].normalized()
: Vector3D(1, 0, 0);
Vector3D v = d * mag;
vectors_[vec_ref] = v;
return v;
}
return Vector3D(1, 0, 0);
}
curves::NurbsCurve build_circle_curve(int id) {
const auto& ent = entities_.at(id);
// CIRCLE args: name, placement (AXIS2_PLACEMENT_3D ref), radius
@@ -933,33 +952,23 @@ private:
// P0=(0,0,R) w=1, P1=(R,0,R)*w(?) -- wait let me use the right construction
// Sphere as surface of revolution of half-circle profile about Z:
// Profile points (half circle in XZ plane, going from +Z to -Z):
Point3D top = C + R * Z; // (0,0,R) pole
Point3D mid = C + R * (X + Z); // (R,0,R), weight=w
Point3D bot = C - R * Z; // (0,0,-R) pole
// Control grid: 3 rows in v × 9 columns in u
// Row 0 (top half-circle): revolve the half across u
// Row 1 (mid circle): revolve at equator
// Row 2 (bot half-circle): revolve the half across u
// We construct 3 rows of control points with the equator as the middle row
// and degenerate poles at top/bottom.
std::vector<std::vector<Point3D>> grid(3);
double a0 = 0, a1 = M_PI_2, a2 = M_PI, a3 = 3*M_PI_2;
for (int u = 0; u < 9; ++u) {
double theta = u * M_PI_4; // 0, π/4, π/2, ..., 2π
double theta = u * (M_PI / 4.0); // 0, π/4, π/2, ..., 2π
double cx = std::cos(theta), sy = std::sin(theta);
Vector3D rad_dir = cx * X + sy * Y;
// Top row (v=0): pole + offset towards equator
grid[0].push_back(C + R * Z); // degenerate at pole
// Top row (v=0): degenerate at north pole
grid[0].push_back(C + R * Z);
// Middle row (v=1): equator ring
grid[1].push_back(C + R * rad_dir);
// Bottom row (v=2): degenerate at south pole
grid[2].push_back(C - R * Z);
}
// Weights: row 0 (top): all 1 except corner poles need special handling
// For proper sphere, use weights [1, w, 1] in v and [1, w, 1, w, 1, w, 1, w, 1] in u
std::vector<double> u_wg = {1, w, 1, w, 1, w, 1, w, 1};
// Weights: for proper sphere, each row uses circle arc weights in u
std::vector<std::vector<double>> wg = {
{1, w, 1, w, 1, w, 1, w, 1},
{1, w, 1, w, 1, w, 1, w, 1},
@@ -987,24 +996,19 @@ private:
// Sweep minor circle around major circle
for (int u = 0; u < 9; ++u) {
double theta = u * M_PI_4; // 0 to 2π
grid[u].resize(9);
wg[u].resize(9);
double theta = u * (M_PI / 4.0); // 0 to 2π
double ct = std::cos(theta), st = std::sin(theta);
Point3D mc = C + R * (ct * X + st * Y); // major circle center
for (int v = 0; v < 9; ++v) {
double phi = v * M_PI_4;
double phi = v * (M_PI / 4.0);
double cp = std::cos(phi), sp = std::sin(phi);
// Minor circle in plane spanned by radial dir and Z
Vector3D rad = ct * X + st * Y;
Point3D pt = mc + r * (cp * rad + sp * Z);
grid[u].push_back(pt);
wg[u].push_back(w * w); // simplified weight
}
}
grid[u][v] = mc + r * (cp * rad + sp * Z);
// Fix corner weights
for (int u = 0; u < 9; ++u) {
for (int v = 0; v < 9; ++v) {
// Weight = product of circle arc weights for u and v directions
double wu = (u % 2 == 0) ? 1.0 : w;
double wv = (v % 2 == 0) ? 1.0 : w;
wg[u][v] = wu * wv;
@@ -1024,18 +1028,44 @@ private:
const auto& solid_ent = entities_.at(solid_id);
// MANIFOLD_SOLID_BREP args: name, outer (CLOSED_SHELL ref)
// SHELL_BASED_SURFACE_MODEL args: name, sbsm_boundary (SET of SHELL refs)
if (solid_ent.args.size() < 2) return model;
std::string solid_name;
if (!is_omitted(solid_ent.args[0]))
solid_name = to_string(solid_ent.args[0]);
// find CLOSED_SHELL
int shell_ref = to_ref(solid_ent.args[1]);
std::vector<int> face_ids = convert_shell(shell_ref, model);
// Look for shell refs — might be a single ref or a list of refs
std::vector<int> shell_refs;
if (solid_ent.args[1].type == StepValue::Type::Ref) {
shell_refs.push_back(to_ref(solid_ent.args[1]));
} else if (solid_ent.args[1].type == StepValue::Type::List) {
for (const auto& sv : solid_ent.args[1].list) {
int r = to_ref(sv);
if (r > 0) shell_refs.push_back(r);
}
}
if (!face_ids.empty()) {
int shell_id = model.add_shell(face_ids, true);
// Also scan all args for Ref-type shells as fallback
if (shell_refs.empty()) {
for (const auto& arg : solid_ent.args) {
int r = to_ref(arg);
if (r > 0 && entities_.count(r)) {
const auto& e = entities_.at(r);
if (e.type == "CLOSED_SHELL" || e.type == "OPEN_SHELL")
shell_refs.push_back(r);
}
}
}
std::vector<int> all_face_ids;
for (int sh_ref : shell_refs) {
auto face_ids = convert_shell(sh_ref, model);
all_face_ids.insert(all_face_ids.end(), face_ids.begin(), face_ids.end());
}
if (!all_face_ids.empty()) {
int shell_id = model.add_shell(all_face_ids, true);
model.add_body({shell_id}, solid_name);
}