NEW:Support OLTP file
Jira: STUDIO-6421 Change-Id: I58bc94e978e6d2dd136ea370fb01f6ec80e14b23
This commit is contained in:
parent
983aca7669
commit
2243747e75
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 } },
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue