diff --git a/src/admesh/stl.h b/src/admesh/stl.h index 94bca3c96..0f1a0cec8 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -98,8 +98,12 @@ struct stl_neighbors { }; struct stl_stats { - stl_stats() { memset(&header, 0, 81); } - char header[81]; + stl_stats() {} + void reset_header(int size) { + header.clear(); + header.resize(size +1); + } + std::vector header; stl_type type = (stl_type)0; // Should always match the number of facets stored inside stl_file::facet_start. uint32_t number_of_facets = 0; @@ -247,7 +251,7 @@ struct indexed_triangle_set } }; -extern bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn = nullptr); +extern bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn = nullptr,int custom_header_length = 80); extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file); extern bool stl_print_neighbors(stl_file *stl, char *file); extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label); diff --git a/src/admesh/stl_io.cpp b/src/admesh/stl_io.cpp index 26f5dc321..221572bca 100644 --- a/src/admesh/stl_io.cpp +++ b/src/admesh/stl_io.cpp @@ -41,7 +41,7 @@ void stl_stats_out(stl_file *stl, FILE *file, char *input_file) fprintf(file, "File type : Binary STL file\n"); else fprintf(file, "File type : ASCII STL file\n"); - fprintf(file, "Header : %s\n", stl->stats.header); + fprintf(file, "Header : %s\n", stl->stats.header.data()); fprintf(file, "============== Size ==============\n"); fprintf(file, "Min X = % f, Max X = % f\n", stl->stats.min(0), stl->stats.max(0)); fprintf(file, "Min Y = % f, Max Y = % f\n", stl->stats.min(1), stl->stats.max(1)); diff --git a/src/admesh/stlinit.cpp b/src/admesh/stlinit.cpp index 6037be9f9..8196bf10c 100644 --- a/src/admesh/stlinit.cpp +++ b/src/admesh/stlinit.cpp @@ -47,7 +47,7 @@ const int LOAD_STL_UNIT_NUM = 5; static std::string model_id = ""; static std::string country_code = ""; -static FILE* stl_open_count_facets(stl_file *stl, const char *file) +static FILE *stl_open_count_facets(stl_file *stl, const char *file, unsigned int custom_header_length) { // Open the file in binary mode first. FILE *fp = boost::nowide::fopen(file, "rb"); @@ -60,7 +60,8 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file) long file_size = ftell(fp); // Check for binary or ASCII file. - fseek(fp, HEADER_SIZE, SEEK_SET); + int header_size = custom_header_length + NUM_FACET_SIZE; + fseek(fp, header_size, SEEK_SET); unsigned char chtest[128]; if (! fread(chtest, sizeof(chtest), 1, fp)) { BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file; @@ -82,16 +83,16 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file) // If the .STL file is binary, then do the following: if (stl->stats.type == binary) { // Test if the STL file has the right size. - if (((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0) || (file_size < STL_MIN_FILE_SIZE)) { + if (((file_size - header_size) % SIZEOF_STL_FACET != 0) || (file_size < STL_MIN_FILE_SIZE)) { BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The file " << file << " has the wrong size."; fclose(fp); return nullptr; } - num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET; + num_facets = (file_size - header_size) / SIZEOF_STL_FACET; // Read the header. - if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79) - stl->stats.header[80] = '\0'; + if (fread(stl->stats.header.data(), custom_header_length, 1, fp) > custom_header_length -1) + stl->stats.header[custom_header_length] = '\0'; // Read the int following the header. This should contain # of facets. uint32_t header_num_facets; @@ -135,9 +136,9 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file) // Get the header. int i = 0; - for (; i < 80 && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ; + for (; i < custom_header_length && (stl->stats.header[i] = getc(fp)) != '\n'; ++ i) ; stl->stats.header[i] = '\0'; // Lose the '\n' - stl->stats.header[80] = '\0'; + stl->stats.header[custom_header_length] = '\0'; num_facets = num_lines / ASCII_LINES_PER_FACET; } @@ -150,10 +151,11 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file) /* Reads the contents of the file pointed to by fp into the stl structure, starting at facet first_facet. The second argument says if it's our first time running this for the stl and therefore we should reset our max and min stats. */ -static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, ImportstlProgressFn stlFn) +static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, ImportstlProgressFn stlFn, int custom_header_length) { if (stl->stats.type == binary) { - fseek(fp, HEADER_SIZE, SEEK_SET); + int header_size = custom_header_length + NUM_FACET_SIZE; + fseek(fp, header_size, SEEK_SET); model_id = ""; country_code = ""; } @@ -300,20 +302,24 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, Impor return true; } -bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn) +bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn, int custom_header_length) { + if (custom_header_length < LABEL_SIZE) { + custom_header_length = LABEL_SIZE; + } Slic3r::CNumericLocalesSetter locales_setter; stl->clear(); - FILE *fp = stl_open_count_facets(stl, file); + stl->stats.reset_header(custom_header_length); + FILE *fp = stl_open_count_facets(stl, file, custom_header_length); if (fp == nullptr) return false; stl_allocate(stl); - bool result = stl_read(stl, fp, 0, true, stlFn); + bool result = stl_read(stl, fp, 0, true, stlFn, custom_header_length); fclose(fp); return result; } -void stl_allocate(stl_file *stl) +void stl_allocate(stl_file *stl) { // Allocate memory for the entire .STL file. stl->facet_start.assign(stl->stats.number_of_facets, stl_facet()); @@ -321,7 +327,7 @@ void stl_allocate(stl_file *stl) stl->neighbors_start.assign(stl->stats.number_of_facets, stl_neighbors()); } -void stl_reallocate(stl_file *stl) +void stl_reallocate(stl_file *stl) { stl->facet_start.resize(stl->stats.number_of_facets); stl->neighbors_start.resize(stl->stats.number_of_facets); diff --git a/src/libslic3r/Format/STL.cpp b/src/libslic3r/Format/STL.cpp index 133a7a505..1888f5cd1 100644 --- a/src/libslic3r/Format/STL.cpp +++ b/src/libslic3r/Format/STL.cpp @@ -14,13 +14,13 @@ namespace Slic3r { -bool load_stl(const char *path, Model *model, const char *object_name_in, ImportstlProgressFn stlFn) +bool load_stl(const char *path, Model *model, const char *object_name_in, ImportstlProgressFn stlFn, int custom_header_length) { TriangleMesh mesh; std::string design_id; - if (! mesh.ReadSTLFile(path, true, stlFn)) { -// die "Failed to open $file\n" if !-e $path; + if (!mesh.ReadSTLFile(path, true, stlFn, custom_header_length)) { + // die "Failed to open $file\n" if !-e $path; return false; } if (mesh.empty()) { diff --git a/src/libslic3r/Format/STL.hpp b/src/libslic3r/Format/STL.hpp index 5f2f838bf..e545e1c6d 100644 --- a/src/libslic3r/Format/STL.hpp +++ b/src/libslic3r/Format/STL.hpp @@ -10,7 +10,7 @@ class TriangleMesh; class ModelObject; // Load an STL file into a provided model. -extern bool load_stl(const char *path, Model *model, const char *object_name = nullptr, ImportstlProgressFn stlFn = nullptr); +extern bool load_stl(const char *path, Model *model, const char *object_name = nullptr, ImportstlProgressFn stlFn = nullptr, int custom_header_length = 80); extern bool store_stl(const char *path, TriangleMesh *mesh, bool binary); extern bool store_stl(const char *path, ModelObject *model_object, bool binary); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index ca1b8abe3..0837ced1e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -201,6 +201,8 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c result = load_step(input_file.c_str(), &model, is_cb_cancel, stepFn, stepIsUtf8Fn); else if (boost::algorithm::iends_with(input_file, ".stl")) result = load_stl(input_file.c_str(), &model, nullptr, stlFn); + else if (boost::algorithm::iends_with(input_file, ".oltp")) + result = load_stl(input_file.c_str(), &model, nullptr, stlFn,256); else if (boost::algorithm::iends_with(input_file, ".obj")) result = load_obj(input_file.c_str(), &model, message); else if (boost::algorithm::iends_with(input_file, ".svg")) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index f93d16325..bd8f4b1b3 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -209,21 +209,21 @@ bool TriangleMesh::from_stl(stl_file& stl, bool repair) return true; } -bool TriangleMesh::ReadSTLFile(const char* input_file, bool repair, ImportstlProgressFn stlFn) -{ +bool TriangleMesh::ReadSTLFile(const char *input_file, bool repair, ImportstlProgressFn stlFn, int custom_header_length) +{ stl_file stl; - if (! stl_open(&stl, input_file, stlFn)) + if (!stl_open(&stl, input_file, stlFn, custom_header_length)) return false; return from_stl(stl, repair); } bool TriangleMesh::write_ascii(const char* output_file) -{ +{ return its_write_stl_ascii(output_file, "", this->its); } bool TriangleMesh::write_binary(const char* output_file) -{ +{ return its_write_stl_binary(output_file, "", this->its); } diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index ebb1d57be..c3815af0a 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -94,7 +94,7 @@ public: explicit TriangleMesh(indexed_triangle_set &&M, const RepairedMeshErrors& repaired_errors = RepairedMeshErrors()); void clear() { this->its.clear(); this->m_stats.clear(); } bool from_stl(stl_file& stl, bool repair = true); - bool ReadSTLFile(const char* input_file, bool repair = true, ImportstlProgressFn stlFn = nullptr); + bool ReadSTLFile(const char *input_file, bool repair = true, ImportstlProgressFn stlFn = nullptr, int custom_header_length = 80); bool write_ascii(const char* output_file); bool write_binary(const char* output_file); float volume(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 30b4550dc..09f8670a1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -778,9 +778,11 @@ static const FileWildcards file_wildcards_by_type[FT_SIZE] = { /* FT_3MF */ { "3MF files"sv, { ".3mf"sv } }, /* FT_GCODE */ { "G-code files"sv, { ".gcode"sv } }, #ifdef __APPLE__ - /* FT_MODEL */ { "Supported files"sv, { ".3mf"sv, ".stl"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv , ".usd"sv, ".usda"sv, ".usdc"sv, ".usdz"sv, ".abc"sv, ".ply"sv} }, + /* FT_MODEL */ + {"Supported files"sv, {".3mf"sv, ".stl"sv, ".oltp"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv, ".usd"sv, ".usda"sv, ".usdc"sv, ".usdz"sv, ".abc"sv, ".ply"sv}}, #else - /* FT_MODEL */ {"Supported files"sv, {".3mf"sv, ".stl"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv }}, + /* FT_MODEL */ + {"Supported files"sv, {".3mf"sv, ".stl"sv, ".oltp"sv, ".stp"sv, ".step"sv, ".svg"sv, ".amf"sv, ".obj"sv}}, #endif /* FT_PROJECT */ { "Project files"sv, { ".3mf"sv} }, /* FT_GALLERY */ { "Known files"sv, { ".stl"sv, ".obj"sv } }, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a7115fb15..b9776eca0 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -10098,7 +10098,7 @@ void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect) //BBS: remove GCodeViewer as seperate APP logic bool Plater::load_files(const wxArrayString& filenames) { - const std::regex pattern_drop(".*[.](stp|step|stl|obj|amf|3mf|svg)", std::regex::icase); + const std::regex pattern_drop(".*[.](stp|step|stl|oltp|obj|amf|3mf|svg)", std::regex::icase); const std::regex pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase); std::vector normal_paths;