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 {
stl_stats() { memset(&header, 0, 81); }
char header[81];
stl_stats() {}
void reset_header(int size) {
header.clear();
header.resize(size +1);
}
std::vector<char> 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);

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");
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));

View File

@ -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);

View File

@ -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()) {

View File

@ -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);

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);
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"))

View File

@ -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);
}

View File

@ -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();

View File

@ -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 } },

View File

@ -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<fs::path> normal_paths;