fix: 3MF reader support multiple objects in single model file
CI / Build & Test (push) Failing after 30s
CI / Release Build (push) Failing after 35s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled

This commit is contained in:
茂之钳
2026-07-24 11:39:36 +00:00
parent f4e34d36cc
commit d05dc3f7f3
2 changed files with 24 additions and 11 deletions
+21 -8
View File
@@ -323,13 +323,12 @@ static std::string xml_get_attr(const std::string& line, const std::string& attr
return line.substr(pos, end - pos);
}
static ThreeMFMesh parse_model_xml(const std::string& xml) {
ThreeMFMesh result;
static std::vector<ThreeMFMesh> parse_model_xml(const std::string& xml) {
std::vector<ThreeMFMesh> results;
std::istringstream iss(xml);
std::string line;
// We parse vertices and triangles from a single <object><mesh>
// Collect vertex coordinates as triplets of strings
// Parse all <object> blocks in the XML
std::vector<std::array<double, 3>> verts;
std::vector<std::array<int, 3>> tris;
bool in_vertices = false, in_triangles = false;
@@ -403,9 +402,22 @@ static ThreeMFMesh parse_model_xml(const std::string& xml) {
}
}
result.mesh.build_from_triangles(pts, faces);
result.name = object_name;
return result;
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 <object> boundaries
return results;
}
} // anonymous namespace
@@ -449,7 +461,8 @@ std::vector<ThreeMFMesh> read_3mf(const std::string& filepath) {
for (const auto& mp : model_paths) {
auto it = zip_files.find(mp);
if (it != zip_files.end()) {
result.push_back(parse_model_xml(it->second));
auto models = parse_model_xml(it->second);
for (auto& m : models) result.push_back(std::move(m));
}
}
+3 -3
View File
@@ -182,9 +182,9 @@ TEST(Io3mfTest, VertexPositionsRoundTrip) {
auto& v0 = loaded[0].mesh.vertex(0);
auto& v1 = loaded[0].mesh.vertex(1);
auto& v2 = loaded[0].mesh.vertex(2);
EXPECT_NEAR(v0.x(), 1.23456789, 1e-6);
EXPECT_NEAR(v0.y(), 9.87654321, 1e-6);
EXPECT_NEAR(v0.z(), -5.5, 1e-6);
EXPECT_NEAR(v0.x(), 1.23456789, 1e-5);
EXPECT_NEAR(v0.y(), 9.87654321, 1e-5);
EXPECT_NEAR(v0.z(), -5.5, 1e-5);
EXPECT_NEAR(v1.x(), 0.0, 1e-12);
EXPECT_NEAR(v2.x(), 100.0, 1e-12);