NEW:Support OLTP file

Jira: STUDIO-6421
Change-Id: I58bc94e978e6d2dd136ea370fb01f6ec80e14b23
This commit is contained in:
zhou.xu 2024-03-06 17:08:04 +08:00 committed by Lane.Wei
parent 983aca7669
commit 2243747e75
10 changed files with 46 additions and 32 deletions

View File

@ -98,8 +98,12 @@ struct stl_neighbors {
}; };
struct stl_stats { struct stl_stats {
stl_stats() { memset(&header, 0, 81); } stl_stats() {}
char header[81]; void reset_header(int size) {
header.clear();
header.resize(size +1);
}
std::vector<char> header;
stl_type type = (stl_type)0; stl_type type = (stl_type)0;
// Should always match the number of facets stored inside stl_file::facet_start. // Should always match the number of facets stored inside stl_file::facet_start.
uint32_t number_of_facets = 0; 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 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_print_neighbors(stl_file *stl, char *file);
extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label); extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label);

View File

@ -41,7 +41,7 @@ void stl_stats_out(stl_file *stl, FILE *file, char *input_file)
fprintf(file, "File type : Binary STL file\n"); fprintf(file, "File type : Binary STL file\n");
else else
fprintf(file, "File type : ASCII STL file\n"); 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, "============== Size ==============\n");
fprintf(file, "Min X = % f, Max X = % f\n", stl->stats.min(0), stl->stats.max(0)); 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)); fprintf(file, "Min Y = % f, Max Y = % f\n", stl->stats.min(1), stl->stats.max(1));

View File

@ -47,7 +47,7 @@ const int LOAD_STL_UNIT_NUM = 5;
static std::string model_id = ""; static std::string model_id = "";
static std::string country_code = ""; 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. // Open the file in binary mode first.
FILE *fp = boost::nowide::fopen(file, "rb"); 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); long file_size = ftell(fp);
// Check for binary or ASCII file. // 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]; unsigned char chtest[128];
if (! fread(chtest, sizeof(chtest), 1, fp)) { if (! fread(chtest, sizeof(chtest), 1, fp)) {
BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The input is an empty file: " << file; 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 the .STL file is binary, then do the following:
if (stl->stats.type == binary) { if (stl->stats.type == binary) {
// Test if the STL file has the right size. // 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."; BOOST_LOG_TRIVIAL(error) << "stl_open_count_facets: The file " << file << " has the wrong size.";
fclose(fp); fclose(fp);
return nullptr; return nullptr;
} }
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET; num_facets = (file_size - header_size) / SIZEOF_STL_FACET;
// Read the header. // Read the header.
if (fread(stl->stats.header, LABEL_SIZE, 1, fp) > 79) if (fread(stl->stats.header.data(), custom_header_length, 1, fp) > custom_header_length -1)
stl->stats.header[80] = '\0'; stl->stats.header[custom_header_length] = '\0';
// Read the int following the header. This should contain # of facets. // Read the int following the header. This should contain # of facets.
uint32_t header_num_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. // Get the header.
int i = 0; 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[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; 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, /* 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 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. */ 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) { 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 = ""; model_id = "";
country_code = ""; country_code = "";
} }
@ -300,20 +302,24 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, Impor
return true; 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; Slic3r::CNumericLocalesSetter locales_setter;
stl->clear(); 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) if (fp == nullptr)
return false; return false;
stl_allocate(stl); 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); fclose(fp);
return result; return result;
} }
void stl_allocate(stl_file *stl) void stl_allocate(stl_file *stl)
{ {
// Allocate memory for the entire .STL file. // Allocate memory for the entire .STL file.
stl->facet_start.assign(stl->stats.number_of_facets, stl_facet()); 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()); 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->facet_start.resize(stl->stats.number_of_facets);
stl->neighbors_start.resize(stl->stats.number_of_facets); stl->neighbors_start.resize(stl->stats.number_of_facets);

View File

@ -14,13 +14,13 @@
namespace Slic3r { 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; TriangleMesh mesh;
std::string design_id; std::string design_id;
if (! mesh.ReadSTLFile(path, true, stlFn)) { if (!mesh.ReadSTLFile(path, true, stlFn, custom_header_length)) {
// die "Failed to open $file\n" if !-e $path; // die "Failed to open $file\n" if !-e $path;
return false; return false;
} }
if (mesh.empty()) { if (mesh.empty()) {

View File

@ -10,7 +10,7 @@ class TriangleMesh;
class ModelObject; class ModelObject;
// Load an STL file into a provided model. // 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, TriangleMesh *mesh, bool binary);
extern bool store_stl(const char *path, ModelObject *model_object, bool binary); extern bool store_stl(const char *path, ModelObject *model_object, bool binary);

View File

@ -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); result = load_step(input_file.c_str(), &model, is_cb_cancel, stepFn, stepIsUtf8Fn);
else if (boost::algorithm::iends_with(input_file, ".stl")) else if (boost::algorithm::iends_with(input_file, ".stl"))
result = load_stl(input_file.c_str(), &model, nullptr, stlFn); 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")) else if (boost::algorithm::iends_with(input_file, ".obj"))
result = load_obj(input_file.c_str(), &model, message); result = load_obj(input_file.c_str(), &model, message);
else if (boost::algorithm::iends_with(input_file, ".svg")) else if (boost::algorithm::iends_with(input_file, ".svg"))

View File

@ -209,21 +209,21 @@ bool TriangleMesh::from_stl(stl_file& stl, bool repair)
return true; 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; stl_file stl;
if (! stl_open(&stl, input_file, stlFn)) if (!stl_open(&stl, input_file, stlFn, custom_header_length))
return false; return false;
return from_stl(stl, repair); return from_stl(stl, repair);
} }
bool TriangleMesh::write_ascii(const char* output_file) bool TriangleMesh::write_ascii(const char* output_file)
{ {
return its_write_stl_ascii(output_file, "", this->its); return its_write_stl_ascii(output_file, "", this->its);
} }
bool TriangleMesh::write_binary(const char* output_file) bool TriangleMesh::write_binary(const char* output_file)
{ {
return its_write_stl_binary(output_file, "", this->its); return its_write_stl_binary(output_file, "", this->its);
} }

View File

@ -94,7 +94,7 @@ public:
explicit TriangleMesh(indexed_triangle_set &&M, const RepairedMeshErrors& repaired_errors = RepairedMeshErrors()); explicit TriangleMesh(indexed_triangle_set &&M, const RepairedMeshErrors& repaired_errors = RepairedMeshErrors());
void clear() { this->its.clear(); this->m_stats.clear(); } void clear() { this->its.clear(); this->m_stats.clear(); }
bool from_stl(stl_file& stl, bool repair = true); 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_ascii(const char* output_file);
bool write_binary(const char* output_file); bool write_binary(const char* output_file);
float volume(); float volume();

View File

@ -778,9 +778,11 @@ static const FileWildcards file_wildcards_by_type[FT_SIZE] = {
/* FT_3MF */ { "3MF files"sv, { ".3mf"sv } }, /* FT_3MF */ { "3MF files"sv, { ".3mf"sv } },
/* FT_GCODE */ { "G-code files"sv, { ".gcode"sv } }, /* FT_GCODE */ { "G-code files"sv, { ".gcode"sv } },
#ifdef __APPLE__ #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 #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 #endif
/* FT_PROJECT */ { "Project files"sv, { ".3mf"sv} }, /* FT_PROJECT */ { "Project files"sv, { ".3mf"sv} },
/* FT_GALLERY */ { "Known files"sv, { ".stl"sv, ".obj"sv } }, /* FT_GALLERY */ { "Known files"sv, { ".stl"sv, ".obj"sv } },

View File

@ -10098,7 +10098,7 @@ void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect)
//BBS: remove GCodeViewer as seperate APP logic //BBS: remove GCodeViewer as seperate APP logic
bool Plater::load_files(const wxArrayString& filenames) 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); const std::regex pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase);
std::vector<fs::path> normal_paths; std::vector<fs::path> normal_paths;