mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
ENH: some improvements to 3mf loading
1. convert instance to object when loading previous 3mf 2. fix an exception issue caused by previous commit caused by nil value of import_project_action Change-Id: Ieed853f0e8d458aab1716acf52307c5d672ebe22
This commit is contained in:
parent
1637981be5
commit
c0ccb733dd
2 changed files with 59 additions and 42 deletions
|
@ -661,7 +661,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
: m_version(0)
|
||||
, m_check_version(false)
|
||||
, m_xml_parser(nullptr)
|
||||
, m_model(nullptr)
|
||||
, m_model(nullptr)
|
||||
, m_unit_factor(1.0f)
|
||||
, m_curr_metadata_name("")
|
||||
, m_curr_characters("")
|
||||
|
@ -934,6 +934,18 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
++object_idx;
|
||||
}
|
||||
|
||||
//BBS: copy object isteadof instance
|
||||
int object_size = model.objects.size();
|
||||
for (int obj_index = 0; obj_index < object_size; obj_index ++) {
|
||||
ModelObject* object = model.objects[obj_index];
|
||||
while (object->instances.size() > 1) {
|
||||
ModelObject* new_model_object = model.add_object(*object);
|
||||
new_model_object->clear_instances();
|
||||
new_model_object->add_instance(*object->instances.back());
|
||||
object->delete_last_instance();
|
||||
}
|
||||
}
|
||||
|
||||
// // fixes the min z of the model if negative
|
||||
// model.adjust_min_z();
|
||||
|
||||
|
@ -1005,8 +1017,8 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
}
|
||||
|
||||
void _3MF_Importer::_extract_print_config_from_archive(
|
||||
mz_zip_archive& archive, const mz_zip_archive_file_stat& stat,
|
||||
DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions,
|
||||
mz_zip_archive& archive, const mz_zip_archive_file_stat& stat,
|
||||
DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions,
|
||||
const std::string& archive_filename)
|
||||
{
|
||||
if (stat.m_uncomp_size > 0) {
|
||||
|
@ -1227,7 +1239,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _3MF_Importer::_extract_sla_drain_holes_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
|
||||
{
|
||||
if (stat.m_uncomp_size > 0) {
|
||||
|
@ -1237,13 +1249,13 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
add_error("Error while reading sla support points data to buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (buffer.back() == '\n')
|
||||
buffer.pop_back();
|
||||
|
||||
|
||||
std::vector<std::string> objects;
|
||||
boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
|
||||
|
||||
|
||||
// Info on format versioning - see 3mf.hpp
|
||||
int version = 0;
|
||||
std::string key("drain_holes_format_version=");
|
||||
|
@ -1252,38 +1264,38 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
version = std::stoi(objects[0]);
|
||||
objects.erase(objects.begin()); // pop the header
|
||||
}
|
||||
|
||||
|
||||
for (const std::string& object : objects) {
|
||||
std::vector<std::string> object_data;
|
||||
boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
|
||||
|
||||
|
||||
if (object_data.size() != 2) {
|
||||
add_error("Error while reading object data");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> object_data_id;
|
||||
boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
|
||||
if (object_data_id.size() != 2) {
|
||||
add_error("Error while reading object id");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int object_id = std::atoi(object_data_id[1].c_str());
|
||||
if (object_id == 0) {
|
||||
add_error("Found invalid object id");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
IdToSlaDrainHolesMap::iterator object_item = m_sla_drain_holes.find(object_id);
|
||||
if (object_item != m_sla_drain_holes.end()) {
|
||||
add_error("Found duplicated SLA drain holes");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> object_data_points;
|
||||
boost::split(object_data_points, object_data[1], boost::is_any_of(" "), boost::token_compress_off);
|
||||
|
||||
|
||||
sla::DrainHoles sla_drain_holes;
|
||||
|
||||
if (version == 1) {
|
||||
|
@ -1306,7 +1318,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
hole.pos += hole.normal.normalized();
|
||||
hole.height -= 1.f;
|
||||
}
|
||||
|
||||
|
||||
if (!sla_drain_holes.empty())
|
||||
m_sla_drain_holes.insert({ object_id, sla_drain_holes });
|
||||
}
|
||||
|
@ -1394,11 +1406,11 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
pt::ptree attr_tree = tree.find("<xmlattr>")->second;
|
||||
if (attr_tree.find("type") == attr_tree.not_found()) {
|
||||
// It means that data was saved in old version (2.2.0 and older) of PrusaSlicer
|
||||
// read old data ...
|
||||
// read old data ...
|
||||
std::string gcode = tree.get<std::string> ("<xmlattr>.gcode");
|
||||
// ... and interpret them to the new data
|
||||
type = gcode == "M600" ? CustomGCode::ColorChange :
|
||||
gcode == "M601" ? CustomGCode::PausePrint :
|
||||
type = gcode == "M600" ? CustomGCode::ColorChange :
|
||||
gcode == "M601" ? CustomGCode::PausePrint :
|
||||
gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom;
|
||||
extra = type == CustomGCode::PausePrint ? color :
|
||||
type == CustomGCode::Custom ? gcode : "";
|
||||
|
@ -2113,7 +2125,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
tri_id -= min_id;
|
||||
}
|
||||
|
||||
if (m_prusaslicer_generator_version &&
|
||||
if (m_prusaslicer_generator_version &&
|
||||
*m_prusaslicer_generator_version >= *Semver::parse("2.4.0-alpha1") &&
|
||||
*m_prusaslicer_generator_version < *Semver::parse("2.4.0-alpha3"))
|
||||
// PrusaSlicer 2.4.0-alpha2 contained a bug, where all vertices of a single object were saved for each volume the object contained.
|
||||
|
@ -2227,7 +2239,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
if (importer != nullptr)
|
||||
importer->_handle_start_config_xml_element(name, attributes);
|
||||
}
|
||||
|
||||
|
||||
void XMLCALL _3MF_Importer::_handle_end_config_xml_element(void* userData, const char* name)
|
||||
{
|
||||
_3MF_Importer* importer = (_3MF_Importer*)userData;
|
||||
|
@ -2340,7 +2352,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
}
|
||||
}
|
||||
|
||||
// Adds relationships file ("_rels/.rels").
|
||||
// Adds relationships file ("_rels/.rels").
|
||||
// The content of this file is the same for each PrusaSlicer 3mf.
|
||||
// The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA.
|
||||
if (!_add_relationships_file_to_archive(archive)) {
|
||||
|
@ -2384,13 +2396,13 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
boost::filesystem::remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!_add_sla_drain_holes_file_to_archive(archive, model)) {
|
||||
close_zip_writer(&archive);
|
||||
boost::filesystem::remove(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml").
|
||||
// All custom gcode per height of whole Model are stored here
|
||||
|
@ -2502,11 +2514,11 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
bool _3MF_Exporter::_add_model_file_to_archive(const std::string& filename, mz_zip_archive& archive, const Model& model, IdToObjectDataMap& objects_data)
|
||||
{
|
||||
mz_zip_writer_staged_context context;
|
||||
if (!mz_zip_writer_add_staged_open(&archive, &context, MODEL_FILE.c_str(),
|
||||
m_zip64 ?
|
||||
if (!mz_zip_writer_add_staged_open(&archive, &context, MODEL_FILE.c_str(),
|
||||
m_zip64 ?
|
||||
// Maximum expected and allowed 3MF file size is 16GiB.
|
||||
// This switches the ZIP file to a 64bit mode, which adds a tiny bit of overhead to file records.
|
||||
(uint64_t(1) << 30) * 16 :
|
||||
(uint64_t(1) << 30) * 16 :
|
||||
// Maximum expected 3MF file size is 4GB-1. This is a workaround for interoperability with Windows 10 3D model fixing API, see
|
||||
// GH issue #6193.
|
||||
(uint64_t(1) << 32) - 1,
|
||||
|
@ -2589,7 +2601,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
}
|
||||
|
||||
stream << "</" << MODEL_TAG << ">\n";
|
||||
|
||||
|
||||
std::string buf = stream.str();
|
||||
|
||||
if ((! buf.empty() && ! mz_zip_writer_add_staged_data(&context, buf.data(), buf.size())) ||
|
||||
|
@ -2877,7 +2889,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
sprintf(buffer, (i == 0) ? "%f" : ";%f", layer_height_profile[i]);
|
||||
out += buffer;
|
||||
}
|
||||
|
||||
|
||||
out += "\n";
|
||||
}
|
||||
}
|
||||
|
@ -2936,8 +2948,8 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
boost::replace_all(out, "><option", ">\n <option");
|
||||
boost::replace_all(out, "></range>", ">\n </range>");
|
||||
boost::replace_all(out, "></object>", ">\n </object>");
|
||||
// OR just
|
||||
boost::replace_all(out, "><", ">\n<");
|
||||
// OR just
|
||||
boost::replace_all(out, "><", ">\n<");
|
||||
}
|
||||
|
||||
if (!out.empty()) {
|
||||
|
@ -2984,13 +2996,13 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _3MF_Exporter::_add_sla_drain_holes_file_to_archive(mz_zip_archive& archive, Model& model)
|
||||
{
|
||||
assert(is_decimal_separator_point());
|
||||
const char *const fmt = "object_id=%d|";
|
||||
std::string out;
|
||||
|
||||
|
||||
unsigned int count = 0;
|
||||
for (const ModelObject* object : model.objects) {
|
||||
++count;
|
||||
|
@ -3007,7 +3019,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
|
||||
if (!drain_holes.empty()) {
|
||||
out += string_printf(fmt, count);
|
||||
|
||||
|
||||
// Store the layer height profile as a single space separated list.
|
||||
for (size_t i = 0; i < drain_holes.size(); ++i)
|
||||
out += string_printf((i == 0 ? "%f %f %f %f %f %f %f %f" : " %f %f %f %f %f %f %f %f"),
|
||||
|
@ -3019,15 +3031,15 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
drain_holes[i].normal(2),
|
||||
drain_holes[i].radius,
|
||||
drain_holes[i].height);
|
||||
|
||||
|
||||
out += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!out.empty()) {
|
||||
// Adds version header at the beginning:
|
||||
out = std::string("drain_holes_format_version=") + std::to_string(drain_holes_format_version) + std::string("\n") + out;
|
||||
|
||||
|
||||
if (!mz_zip_writer_add_mem(&archive, SLA_DRAIN_HOLES_FILE.c_str(), static_cast<const void*>(out.data()), out.length(), mz_uint(MZ_DEFAULT_COMPRESSION))) {
|
||||
add_error("Unable to add sla support points file to archive");
|
||||
return false;
|
||||
|
@ -3099,7 +3111,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
if (volume->is_modifier())
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n";
|
||||
// stores volume's type (overrides the modifier field above)
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " <<
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " <<
|
||||
VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n";
|
||||
|
||||
// stores volume's local matrix
|
||||
|
@ -3137,7 +3149,7 @@ ModelVolumeType type_from_string(const std::string &s)
|
|||
for (const std::string& key : volume->config.keys()) {
|
||||
stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n";
|
||||
}
|
||||
|
||||
|
||||
// stores mesh's statistics
|
||||
const RepairedMeshErrors& stats = volume->mesh().stats().repaired_errors;
|
||||
stream << " <" << MESH_TAG << " ";
|
||||
|
@ -3190,12 +3202,12 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv
|
|||
std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") :
|
||||
code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") :
|
||||
code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") :
|
||||
code.type == CustomGCode::ToolChange ? "tool_change" : code.extra;
|
||||
code.type == CustomGCode::ToolChange ? "tool_change" : code.extra;
|
||||
code_tree.put("<xmlattr>.gcode" , gcode );
|
||||
}
|
||||
|
||||
pt::ptree& mode_tree = main_tree.add("mode", "");
|
||||
// store mode of a custom_gcode_per_print_z
|
||||
// store mode of a custom_gcode_per_print_z
|
||||
mode_tree.put("<xmlattr>.value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode :
|
||||
model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode :
|
||||
CustomGCode::MultiExtruderMode);
|
||||
|
@ -3208,7 +3220,7 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv
|
|||
// Post processing("beautification") of the output string
|
||||
boost::replace_all(out, "><", ">\n<");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!out.empty()) {
|
||||
if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) {
|
||||
|
|
|
@ -2948,7 +2948,12 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
wxGetApp().get_tab(Preset::TYPE_PRINT)->update();
|
||||
}
|
||||
|
||||
LoadType load_type = static_cast<LoadType>(std::stoi(wxGetApp().app_config->get("import_project_action")));
|
||||
std::string import_project_action = wxGetApp().app_config->get("import_project_action");
|
||||
LoadType load_type;
|
||||
if (import_project_action.empty())
|
||||
load_type = LoadType::Unknown;
|
||||
else
|
||||
load_type = static_cast<LoadType>(std::stoi(import_project_action));
|
||||
|
||||
// BBS: version check
|
||||
Semver app_version = *(Semver::parse(SLIC3R_VERSION));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue