bool loadMeshSTL_ascii(Mesh* mesh, const char* filename, FMatrix3x3& matrix) { FILE* f = fopen(filename, "rt"); char buffer[1024]; FPoint3 vertex; int n = 0; Point3 v0(0,0,0), v1(0,0,0), v2(0,0,0); while(fgets_(buffer, sizeof(buffer), f)) { if (sscanf(buffer, " vertex %f %f %f", &vertex.x, &vertex.y, &vertex.z) == 3) { n++; switch(n) { case 1: v0 = matrix.apply(vertex); break; case 2: v1 = matrix.apply(vertex); break; case 3: v2 = matrix.apply(vertex); mesh->addFace(v0, v1, v2); n = 0; break; } } } fclose(f); mesh->finish(); return true; }
void ArcusCommunication::Private::readMeshGroupMessage(const proto::ObjectList& mesh_group_message) { if (mesh_group_message.objects_size() <= 0) { return; //Don't slice empty mesh groups. } Scene& scene = Application::getInstance().current_slice->scene; MeshGroup& mesh_group = scene.mesh_groups.at(object_count); //Load the settings in the mesh group. for (const cura::proto::Setting& setting : mesh_group_message.settings()) { mesh_group.settings.add(setting.name(), setting.value()); } FMatrix3x3 matrix; for (const cura::proto::Object& object : mesh_group_message.objects()) { const size_t bytes_per_face = sizeof(FPoint3) * 3; //3 vectors per face. const size_t face_count = object.vertices().size() / bytes_per_face; if (face_count <= 0) { logWarning("Got an empty mesh. Ignoring it!"); continue; } mesh_group.meshes.emplace_back(); Mesh& mesh = mesh_group.meshes.back(); //Load the settings for the mesh. for (const cura::proto::Setting& setting : object.settings()) { mesh.settings.add(setting.name(), setting.value()); } ExtruderTrain& extruder = mesh.settings.get<ExtruderTrain&>("extruder_nr"); //Set the parent setting to the correct extruder. mesh.settings.setParent(&extruder.settings); for (size_t face = 0; face < face_count; face++) { const std::string data = object.vertices().substr(face * bytes_per_face, bytes_per_face); const FPoint3* float_vertices = reinterpret_cast<const FPoint3*>(data.data()); Point3 verts[3]; verts[0] = matrix.apply(float_vertices[0]); verts[1] = matrix.apply(float_vertices[1]); verts[2] = matrix.apply(float_vertices[2]); mesh.addFace(verts[0], verts[1], verts[2]); } mesh.mesh_name = object.name(); mesh.finish(); } object_count++; mesh_group.finalize(); }
void CommandSocket::handleObjectList(cura::proto::ObjectList* list) { FMatrix3x3 matrix; //d->object_count = 0; //d->object_ids.clear(); d->objects_to_slice.push_back(std::make_shared<MeshGroup>(FffProcessor::getInstance())); MeshGroup* object_to_slice = d->objects_to_slice.back().get(); for(auto object : list->objects()) { DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("solid Cura_out\n"); object_to_slice->meshes.push_back(object_to_slice); //Construct a new mesh (with object_to_slice as settings parent object) and put it into MeshGroup's mesh list. Mesh& mesh = object_to_slice->meshes.back(); int bytes_per_face = BYTES_PER_FLOAT * FLOATS_PER_VECTOR * VECTORS_PER_FACE; int face_count = object.vertices().size() / bytes_per_face; for(int i = 0; i < face_count; ++i) { //TODO: Apply matrix std::string data = object.vertices().substr(i * bytes_per_face, bytes_per_face); const FPoint3* float_vertices = reinterpret_cast<const FPoint3*>(data.data()); Point3 verts[3]; verts[0] = matrix.apply(float_vertices[0]); verts[1] = matrix.apply(float_vertices[1]); verts[2] = matrix.apply(float_vertices[2]); mesh.addFace(verts[0], verts[1], verts[2]); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" facet normal -1 0 0\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" outer loop\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[0].x) <<" " << INT2MM(verts[0].y) <<" " << INT2MM(verts[0].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[1].x) <<" " << INT2MM(verts[1].y) <<" " << INT2MM(verts[1].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[2].x) <<" " << INT2MM(verts[2].y) <<" " << INT2MM(verts[2].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endloop\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endfacet\n"); } DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("endsolid Cura_out\n"); for(auto setting : object.settings()) { mesh.setSetting(setting.name(), setting.value()); } d->object_ids.push_back(object.id()); mesh.finish(); } for(auto setting : list->settings()) { object_to_slice->setSetting(setting.name(), setting.value()); } d->object_count++; object_to_slice->finalize(); }
bool loadMeshSTL_binary(Mesh* mesh, const char* filename, FMatrix3x3& matrix) { FILE* f = fopen(filename, "rb"); fseek(f, 0L, SEEK_END); long long file_size = ftell(f); //The file size is the position of the cursor after seeking to the end. rewind(f); //Seek back to start. size_t face_count = (file_size - 80 - sizeof(uint32_t)) / 50; //Subtract the size of the header. Every face uses exactly 50 bytes. char buffer[80]; //Skip the header if (fread(buffer, 80, 1, f) != 1) { fclose(f); return false; } uint32_t reported_face_count; //Read the face count. We'll use it as a sort of redundancy code to check for file corruption. if (fread(&reported_face_count, sizeof(uint32_t), 1, f) != 1) { fclose(f); return false; } if (reported_face_count != face_count) { logWarning("Face count reported by file (%s) is not equal to actual face count (%s). File could be corrupt!\n", std::to_string(reported_face_count).c_str(), std::to_string(face_count).c_str()); } //For each face read: //float(x,y,z) = normal, float(X,Y,Z)*3 = vertexes, uint16_t = flags // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer mesh->faces.reserve(face_count); mesh->vertices.reserve(face_count); for (unsigned int i = 0; i < face_count; i++) { if (fread(buffer, 50, 1, f) != 1) { fclose(f); return false; } float *v= ((float*)buffer)+3; Point3 v0 = matrix.apply(FPoint3(v[0], v[1], v[2])); Point3 v1 = matrix.apply(FPoint3(v[3], v[4], v[5])); Point3 v2 = matrix.apply(FPoint3(v[6], v[7], v[8])); mesh->addFace(v0, v1, v2); } fclose(f); mesh->finish(); return true; }
bool loadMeshSTL_binary(Mesh* mesh, const char* filename, FMatrix3x3& matrix) { FILE* f = fopen(filename, "rb"); char buffer[80]; uint32_t faceCount; //Skip the header if (fread(buffer, 80, 1, f) != 1) { fclose(f); return false; } //Read the face count if (fread(&faceCount, sizeof(uint32_t), 1, f) != 1) { fclose(f); return false; } //For each face read: //float(x,y,z) = normal, float(X,Y,Z)*3 = vertexes, uint16_t = flags // Every Face is 50 Bytes: Normal(3*float), Vertices(9*float), 2 Bytes Spacer mesh->faces.reserve(faceCount); mesh->vertices.reserve(faceCount); for(unsigned int i=0;i<faceCount;i++) { if (fread(buffer, 50, 1, f) != 1) { fclose(f); return false; } float *v= ((float*)buffer)+3; Point3 v0 = matrix.apply(FPoint3(v[0], v[1], v[2])); Point3 v1 = matrix.apply(FPoint3(v[3], v[4], v[5])); Point3 v2 = matrix.apply(FPoint3(v[6], v[7], v[8])); mesh->addFace(v0, v1, v2); } fclose(f); mesh->finish(); return true; }
void CommandSocket::handleObjectList(cura::proto::ObjectList* list) { if (list->objects_size() <= 0) { return; } FMatrix3x3 matrix; //private_data->object_count = 0; //private_data->object_ids.clear(); private_data->objects_to_slice.push_back(std::make_shared<MeshGroup>(FffProcessor::getInstance())); MeshGroup* meshgroup = private_data->objects_to_slice.back().get(); for (auto setting : list->settings()) { meshgroup->setSetting(setting.name(), setting.value()); } for (int extruder_nr = 0; extruder_nr < FffProcessor::getInstance()->getSettingAsCount("machine_extruder_count"); extruder_nr++) { // initialize remaining extruder trains and load the defaults ExtruderTrain* train = meshgroup->createExtruderTrain(extruder_nr); // create new extruder train objects or use already existing ones SettingRegistry::getInstance()->loadExtruderJSONsettings(extruder_nr, train); } for (auto object : list->objects()) { int bytes_per_face = BYTES_PER_FLOAT * FLOATS_PER_VECTOR * VECTORS_PER_FACE; int face_count = object.vertices().size() / bytes_per_face; if (face_count <= 0) { logWarning("Got an empty mesh, ignoring it!"); continue; } DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("solid Cura_out\n"); int extruder_train_nr = 0; // TODO: make primary extruder configurable! for (auto setting : object.settings()) { if (setting.name() == "extruder_nr") { extruder_train_nr = std::stoi(setting.value()); break; } } SettingsBase* extruder_train = meshgroup->getExtruderTrain(extruder_train_nr); meshgroup->meshes.push_back(extruder_train); //Construct a new mesh (with the corresponding extruder train as settings parent object) and put it into MeshGroup's mesh list. Mesh& mesh = meshgroup->meshes.back(); for (int i = 0; i < face_count; ++i) { //TODO: Apply matrix std::string data = object.vertices().substr(i * bytes_per_face, bytes_per_face); const FPoint3* float_vertices = reinterpret_cast<const FPoint3*>(data.data()); Point3 verts[3]; verts[0] = matrix.apply(float_vertices[0]); verts[1] = matrix.apply(float_vertices[1]); verts[2] = matrix.apply(float_vertices[2]); mesh.addFace(verts[0], verts[1], verts[2]); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" facet normal -1 0 0\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" outer loop\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[0].x) <<" " << INT2MM(verts[0].y) <<" " << INT2MM(verts[0].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[1].x) <<" " << INT2MM(verts[1].y) <<" " << INT2MM(verts[1].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" vertex "<<INT2MM(verts[2].x) <<" " << INT2MM(verts[2].y) <<" " << INT2MM(verts[2].z) << "\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endloop\n"); DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR(" endfacet\n"); } DEBUG_OUTPUT_OBJECT_STL_THROUGH_CERR("endsolid Cura_out\n"); for (auto setting : object.settings()) { mesh.setSetting(setting.name(), setting.value()); } mesh.finish(); } private_data->object_count++; meshgroup->finalize(); }