From e67b758566633fdf80916db471d4344c7a347154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=82=E4=B9=8B=E9=92=B3?= Date: Fri, 24 Jul 2026 11:42:13 +0000 Subject: [PATCH] =?UTF-8?q?fix:=203MF=20multi-object=20parsing=20=E2=80=94?= =?UTF-8?q?=20flush=20per=20object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/foundation/io_3mf.cpp | 86 ++++++++++++++------------------------- 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/src/foundation/io_3mf.cpp b/src/foundation/io_3mf.cpp index 2b14850..51e7905 100644 --- a/src/foundation/io_3mf.cpp +++ b/src/foundation/io_3mf.cpp @@ -328,14 +328,33 @@ static std::vector parse_model_xml(const std::string& xml) { std::istringstream iss(xml); std::string line; - // Parse all blocks in the XML + // Per-object state std::vector> verts; std::vector> tris; bool in_vertices = false, in_triangles = false; std::string object_name; + auto add_current_object = [&]() { + if (verts.empty()) return; + std::vector pts; + pts.reserve(verts.size()); + for (const auto& v : verts) pts.emplace_back(v[0], v[1], v[2]); + std::vector> faces; + for (const auto& t : tris) { + if (t[0]>=0 && (size_t)t[0]=0 && (size_t)t[1]=0 && (size_t)t[2] parse_model_xml(const std::string& xml) { if (!line.empty() && line.back() == '\r') line.pop_back(); } + // New object: flush previous if (line.find("") != std::string::npos) { - in_vertices = true; - continue; - } - if (line.find("") != std::string::npos) { - in_vertices = false; - continue; - } - if (line.find("") != std::string::npos) { - in_triangles = true; - continue; - } - if (line.find("") != std::string::npos) { - in_triangles = false; - continue; - } + if (line.find("") != std::string::npos) { in_vertices = true; continue; } + if (line.find("") != std::string::npos) { in_vertices = false; continue; } + if (line.find("") != std::string::npos) { in_triangles = true; continue; } + if (line.find("") != std::string::npos) { in_triangles = false; continue; } if (in_vertices && line.find(" pts; - pts.reserve(verts.size()); - for (const auto& v : verts) { - pts.emplace_back(v[0], v[1], v[2]); - } - - std::vector> faces; - faces.reserve(tris.size()); - for (const auto& t : tris) { - // Validate indices - if (t[0] >= 0 && static_cast(t[0]) < verts.size() && - t[1] >= 0 && static_cast(t[1]) < verts.size() && - t[2] >= 0 && static_cast(t[2]) < verts.size()) { - faces.push_back(t); - } - } - - ThreeMFMesh m; - m.mesh.build_from_triangles(pts, faces); - m.name = object_name; - results.push_back(m); - - // Reset for next object - verts.clear(); - tris.clear(); - object_name.clear(); - pts.clear(); - faces.clear(); - - // Re-parse for next objects? No, the function ends here. - // Actually this only works for the first object. - // For multi-object, need to detect boundaries + // Flush final object + add_current_object(); return results; }