NEW:tracking stl model files

jira:[STUDIO-5372]

Change-Id: Idb1275b07441f0cd06c24588d5f7c20f81f1556c
This commit is contained in:
tao wang 2023-11-23 20:00:34 +08:00 committed by Lane.Wei
parent b96f1b333e
commit 54eed41661
8 changed files with 131 additions and 19 deletions

View File

@ -45,7 +45,7 @@ typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> stl_triangle_vertex_indices
static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect");
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
typedef std::function<void(int current, int total, bool& cancel)> ImportstlProgressFn;
typedef std::function<void(int current, int total, bool& cancel, std::string& model_id)> ImportstlProgressFn;
typedef enum {
eNormal, // normal face
@ -157,6 +157,7 @@ struct stl_file {
return sizeof(*this) + sizeof(stl_facet) * facet_start.size() + sizeof(stl_neighbors) * neighbors_start.size();
}
char mw_data[256];
std::vector<stl_facet> facet_start;
std::vector<stl_neighbors> neighbors_start;
// Statistics
@ -275,7 +276,6 @@ extern void stl_mirror_yz(stl_file *stl);
extern void stl_mirror_xz(stl_file *stl);
extern float get_area(stl_facet* facet);
extern void stl_get_size(stl_file *stl);
// the following function is not used

View File

@ -44,6 +44,7 @@ extern void stl_internal_reverse_quads(char *buf, size_t cnt);
#endif /* BOOST_ENDIAN_BIG_BYTE */
const int LOAD_STL_UNIT_NUM = 5;
static std::string model_id = "";
static FILE* stl_open_count_facets(stl_file *stl, const char *file)
{
@ -150,31 +151,66 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file)
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)
{
if (stl->stats.type == binary)
fseek(fp, HEADER_SIZE, SEEK_SET);
else
rewind(fp);
if (stl->stats.type == binary) {
fseek(fp, HEADER_SIZE, SEEK_SET);
}
else {
rewind(fp);
try{
char solid_name[256];
int res_solid = fscanf(fp, " solid %[^\n]", solid_name);
if (res_solid == 1) {
char* mw_position = strstr(solid_name, "MW");
if (mw_position != NULL) {
// Extract the value after "MW"
char version_str[16];
char model_id_str[128];
int num_values = sscanf(mw_position + 3, "%s %s", version_str, model_id_str);
if (num_values == 2) {
if (strcmp(version_str, "1.0") == 0) {
model_id = model_id_str;
}
}
else {
model_id = "";
}
}
else {
model_id = ""; // No MW format found
}
}
}
catch (...){
}
rewind(fp);
}
char normal_buf[3][32];
uint32_t facets_num = stl->stats.number_of_facets;
uint32_t unit = facets_num / LOAD_STL_UNIT_NUM + 1;
for (uint32_t i = first_facet; i < facets_num; ++ i) {
if ((i % unit) == 0) {
bool cb_cancel = false;
if (stlFn) {
stlFn(i, facets_num, cb_cancel);
if (cb_cancel)
return false;
}
}
if ((i % unit) == 0) {
bool cb_cancel = false;
if (stlFn) {
stlFn(i, facets_num, cb_cancel, model_id);
if (cb_cancel)
return false;
}
}
stl_facet facet;
if (stl->stats.type == binary) {
// Read a single facet from a binary .STL file. We assume little-endian architecture!
if (fread(&facet, 1, SIZEOF_STL_FACET, fp) != SIZEOF_STL_FACET)
return false;
#if BOOST_ENDIAN_BIG_BYTE
// Convert the loaded little endian data to big endian.
stl_internal_reverse_quads((char*)&facet, 48);
@ -251,7 +287,7 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, Impor
stl->facet_start[i] = facet;
stl_facet_stats(stl, facet, first);
}
stl->stats.size = stl->stats.max - stl->stats.min;
stl->stats.bounding_diameter = stl->stats.size.norm();
return true;

View File

@ -17,6 +17,8 @@ namespace Slic3r {
bool load_stl(const char *path, Model *model, const char *object_name_in, ImportstlProgressFn stlFn)
{
TriangleMesh mesh;
std::string design_id;
if (! mesh.ReadSTLFile(path, true, stlFn)) {
// die "Failed to open $file\n" if !-e $path;
return false;
@ -59,4 +61,4 @@ bool store_stl(const char *path, Model *model, bool binary)
return store_stl(path, &mesh, binary);
}
}; // namespace Slic3r
}; // namespace Slic3r

View File

@ -84,6 +84,7 @@ Model& Model::assign_copy(const Model &rhs)
// BBS: for design info
this->design_info = rhs.design_info;
this->model_info = rhs.model_info;
this->stl_design_id = rhs.stl_design_id;
this->profile_info = rhs.profile_info;
return *this;
@ -113,6 +114,7 @@ Model& Model::assign_copy(Model &&rhs)
//BBS: add auxiliary path logic
// BBS: backup, all in one temp dir
this->stl_design_id = rhs.stl_design_id;
this->backup_path = std::move(rhs.backup_path);
this->object_backup_id_map = std::move(rhs.object_backup_id_map);
this->next_object_backup_id = rhs.next_object_backup_id;
@ -910,6 +912,7 @@ void Model::load_from(Model& model)
object_backup_id_map = model.object_backup_id_map;
next_object_backup_id = model.next_object_backup_id;
design_info = model.design_info;
stl_design_id = model.stl_design_id;
model_info = model.model_info;
profile_info = model.profile_info;
model.design_info.reset();

View File

@ -1508,6 +1508,7 @@ public:
static GlobalSpeedMap printSpeedMap;
// DesignInfo of Model
std::string stl_design_id;
std::shared_ptr<ModelDesignInfo> design_info = nullptr;
std::shared_ptr<ModelInfo> model_info = nullptr;
std::shared_ptr<ModelProfileInfo> profile_info = nullptr;

View File

@ -245,7 +245,6 @@ void PrintJob::process()
params.dst_file = m_dst_path;
}
if (wxGetApp().model().model_info && wxGetApp().model().model_info.get()) {
ModelInfo* model_info = wxGetApp().model().model_info.get();
auto origin_profile_id = model_info->metadata_items.find(BBL_DESIGNER_PROFILE_ID_TAG);
@ -279,7 +278,17 @@ void PrintJob::process()
catch (...) {}
}
}
if (!wxGetApp().model().stl_design_id.empty()) {
int stl_design_id = 0;
try {
stl_design_id = std::stoi(wxGetApp().model().stl_design_id);
}
catch (const std::exception& e) {
stl_design_id = 0;
}
params.stl_design_id = stl_design_id;
}
if (params.preset_name.empty() && m_print_type == "from_normal") { params.preset_name = wxString::Format("%s_plate_%d", m_project_name, curr_plate_idx).ToStdString(); }
if (params.project_name.empty()) {params.project_name = m_project_name;}

View File

@ -3140,6 +3140,53 @@ BoundingBox Plater::priv::scaled_bed_shape_bb() const
return printable_area.bounding_box();
}
std::string read_binary_stl(const std::string& filename) {
std::string model_id;
std::ifstream file(filename, std::ios::binary);
if (!file) {
return model_id;
}
try{
// Read the first 80 bytes
char data[80];
file.read(data, 80);
if (!file) {
file.close();
return model_id;
}
if (data[0] == '\0' || data[0] == ' ') {
file.close();
return model_id;
}
char magic[2] = { data[0], data[1] };
if (magic[0] != 'M' || magic[1] != 'W') {
file.close();
return model_id;
}
if (data[2] != ' ') {
file.close();
return model_id;
}
char protocol_version[3] = { data[3], data[4], data[5] };
//version
if (protocol_version[0] == '1' && protocol_version[1] == '.' && protocol_version[2] == '0') {
model_id = std::string(&data[7], &data[80]);
}
file.close();
}
catch (...){
}
return model_id;
}
// BBS: backup & restore
std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi)
{
@ -3177,6 +3224,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
std::vector<size_t> obj_idxs;
std::string designer_model_id;
int answer_convert_from_meters = wxOK_DEFAULT;
int answer_convert_from_imperial_units = wxOK_DEFAULT;
int tolal_model_count = 0;
@ -3626,10 +3675,12 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
std::vector<Preset *> project_presets;
bool is_xxx;
Semver file_version;
model = Slic3r::Model::read_from_file(
path.string(), nullptr, nullptr, strategy, &plate_data, &project_presets, &is_xxx, &file_version, nullptr,
[this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i](int current, int total, bool &cancel)
[this, &dlg, real_filename, &progress_percent, &file_percent, INPUT_FILES_RATIO, total_files, i, &designer_model_id](int current, int total, bool &cancel, std::string &mode_id)
{
designer_model_id = mode_id;
bool cont = true;
float percent_float = (100.0f * (float)i / (float)total_files) + INPUT_FILES_RATIO * 100.0f * ((float)current / (float)total) / (float)total_files;
BOOST_LOG_TRIVIAL(trace) << "load_stl_file: percent(float)=" << percent_float << ", curr = " << current << ", total = " << total;
@ -3654,6 +3705,11 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
_L("Attention!"));
});
if (designer_model_id.empty() && boost::algorithm::iends_with(path.string(), ".stl")) {
designer_model_id = read_binary_stl(path.string());
}
if (type_any_amf && is_xxx) imperial_units = true;
for (auto obj : model.objects)
@ -3947,6 +4003,10 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
GLGizmoSimplify::add_simplify_suggestion_notification(
obj_idxs, model.objects, *notification_manager);
//set designer_model_id
if (!designer_model_id.empty() && q->model().stl_design_id.empty()) {
q->model().stl_design_id = designer_model_id;
}
if (tolal_model_count <= 0 && !q->m_exported_file) {
dlg.Hide();

View File

@ -202,6 +202,7 @@ struct PrintParams {
std::string connection_type;
std::string comments;
int origin_profile_id = 0;
int stl_design_id = 0;
std::string origin_model_id;
std::string print_type;
std::string dst_file;