diff --git a/xs/src/libslic3r/IO/AMF.cpp b/xs/src/libslic3r/IO/AMF.cpp index ce49640d0..f0bb7a60a 100644 --- a/xs/src/libslic3r/IO/AMF.cpp +++ b/xs/src/libslic3r/IO/AMF.cpp @@ -1,4 +1,6 @@ #include "../IO.hpp" +#include +#include #include #include #include @@ -495,109 +497,121 @@ AMF::read(std::string input_file, Model* model) bool AMF::write(Model& model, std::string output_file) { - FILE *file = ::fopen(output_file.c_str(), "wb"); - if (file == NULL) - return false; - - fprintf(file, "\n"); - fprintf(file, "\n"); - fprintf(file, "Slic3r %s\n", SLIC3R_VERSION); + using namespace std; + + ofstream file; + file.open(output_file, ios::out | ios::trunc); + + file << "" << endl + << "" << endl + << "Slic3r " << SLIC3R_VERSION << "" << endl; + for (const auto &material : model.materials) { if (material.first.empty()) continue; // note that material-id must never be 0 since it's reserved by the AMF spec - fprintf(file, " \n", material.first.c_str()); + file << " " << endl; for (const auto &attr : material.second->attributes) - fprintf(file, " %s\n", attr.first.c_str(), attr.second.c_str()); + file << " " << attr.second << "" << endl; for (const std::string &key : material.second->config.keys()) - fprintf(file, " %s\n", key.c_str(), material.second->config.serialize(key).c_str()); - fprintf(file, " \n"); + file << " " + << material.second->config.serialize(key) << "" << endl; + file << " " << endl; } - std::string instances; - for (size_t object_id = 0; object_id < model.objects.size(); ++ object_id) { + + ostringstream instances; + for (size_t object_id = 0; object_id < model.objects.size(); ++object_id) { ModelObject *object = model.objects[object_id]; - fprintf(file, " \n", object_id); + file << " " << endl; + for (const std::string &key : object->config.keys()) - fprintf(file, " %s\n", key.c_str(), object->config.serialize(key).c_str()); - if (! object->name.empty()) - fprintf(file, " %s\n", object->name.c_str()); + file << " " + << object->config.serialize(key) << "" << endl; + + if (!object->name.empty()) + file << " " << object->name << "" << endl; - //FIXME Store the layer height ranges (ModelObject::layer_height_ranges) - fprintf(file, " \n"); - fprintf(file, " \n"); - std::vector vertices_offsets; - int num_vertices = 0; + //FIXME: Store the layer height ranges (ModelObject::layer_height_ranges) + file << " " << endl; + file << " " << endl; + + std::vector vertices_offsets; + size_t num_vertices = 0; + for (ModelVolume *volume : object->volumes) { - volume->mesh.check_topology(); + volume->mesh.require_shared_vertices(); vertices_offsets.push_back(num_vertices); - auto &stl = volume->mesh.stl; - if (stl.v_shared == NULL) - stl_generate_shared_vertices(&stl); - for (size_t i = 0; i < stl.stats.shared_vertices; ++ i) { + const auto &stl = volume->mesh.stl; + for (size_t i = 0; i < stl.stats.shared_vertices; ++i) // Subtract origin_translation in order to restore the coordinates of the parts // before they were imported. Otherwise, when this AMF file is reimported parts // will be placed in the plater correctly, but we will have lost origin_translation // thus any additional part added will not align with the others. // In order to do this we compensate for this translation in the instance placement // below. - fprintf(file, " \n"); - fprintf(file, " \n"); - fprintf(file, " %f\n", stl.v_shared[i].x - object->origin_translation.x); - fprintf(file, " %f\n", stl.v_shared[i].y - object->origin_translation.y); - fprintf(file, " %f\n", stl.v_shared[i].z - object->origin_translation.z); - fprintf(file, " \n"); - fprintf(file, " \n"); - } + file << " " << endl + << " " << endl + << " " << (stl.v_shared[i].x - object->origin_translation.x) << "" << endl + << " " << (stl.v_shared[i].y - object->origin_translation.y) << "" << endl + << " " << (stl.v_shared[i].z - object->origin_translation.z) << "" << endl + << " " << endl + << " " << endl; + num_vertices += stl.stats.shared_vertices; } - fprintf(file, " \n"); - for (size_t i_volume = 0; i_volume < object->volumes.size(); ++ i_volume) { + file << " " << endl; + + for (size_t i_volume = 0; i_volume < object->volumes.size(); ++i_volume) { ModelVolume *volume = object->volumes[i_volume]; int vertices_offset = vertices_offsets[i_volume]; + if (volume->material_id().empty()) - fprintf(file, " \n"); + file << " " << endl; else - fprintf(file, " \n", volume->material_id().c_str()); + file << " material_id() << "\">" << endl; + for (const std::string &key : volume->config.keys()) - fprintf(file, " %s\n", key.c_str(), volume->config.serialize(key).c_str()); - if (! volume->name.empty()) - fprintf(file, " %s\n", volume->name.c_str()); + file << " " + << volume->config.serialize(key) << "" << endl; + + if (!volume->name.empty()) + file << " " << volume->name << "" << endl; + if (volume->modifier) - fprintf(file, " 1\n"); - for (int i = 0; i < volume->mesh.stl.stats.number_of_facets; ++ i) { - fprintf(file, " \n"); + file << " 1" << endl; + + for (int i = 0; i < volume->mesh.stl.stats.number_of_facets; ++i) { + file << " " << endl; for (int j = 0; j < 3; ++ j) - fprintf(file, " %d\n", j+1, volume->mesh.stl.v_indices[i].vertex[j] + vertices_offset, j+1); - fprintf(file, " \n"); + file << " " + << (volume->mesh.stl.v_indices[i].vertex[j] + vertices_offset) + << "" << endl; + file << " " << endl; } - fprintf(file, " \n"); - } - fprintf(file, " \n"); - fprintf(file, " \n"); - for (const ModelInstance* instance : object->instances) { - char buf[512]; - sprintf(buf, - " \n" - " %lf\n" - " %lf\n" - " %lf\n" - " %lf\n" - " \n", - object_id, - instance->offset.x + object->origin_translation.x, - instance->offset.y + object->origin_translation.y, - instance->rotation, - instance->scaling_factor); - instances.append(buf); + file << " " << endl; } + file << " " << endl; + file << " " << endl; + + for (const ModelInstance* instance : object->instances) + instances + << " " << endl + << " " << instance->offset.x + object->origin_translation.x << "" << endl + << " " << instance->offset.y + object->origin_translation.y << "" << endl + << " %" << instance->rotation << "" << endl + << " " << instance->scaling_factor << "" << endl + << " " << endl; } - if (! instances.empty()) { - fprintf(file, " \n"); - fwrite(instances.data(), instances.size(), 1, file); - fprintf(file, " \n"); - } - fprintf(file, "\n"); - fclose(file); + + std::string instances_str = instances.str(); + if (!instances_str.empty()) + file << " " << endl + << instances_str + << " " << endl; + + file << "" << endl; + + file.close(); return true; } diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index cba8ba43e..51a4e9df4 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -58,6 +58,7 @@ class TriangleMesh bool needed_repair() const; size_t facets_count() const; void extrude_tin(float offset); + void require_shared_vertices(); static TriangleMesh make_cube(double x, double y, double z); static TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360)); @@ -67,7 +68,6 @@ class TriangleMesh bool repaired; private: - void require_shared_vertices(); friend class TriangleMeshSlicer; friend class TriangleMeshSlicer; friend class TriangleMeshSlicer;