diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index f31bef0bf..5ec83a1f1 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -178,6 +178,8 @@ void AppConfig::set_defaults() set_bool("enable_lod", true); if (get("enable_opengl_multi_instance").empty()) set_bool("enable_opengl_multi_instance", true); + if (get("import_single_svg_and_split").empty()) + set_bool("import_single_svg_and_split", true); if (get("user_bed_type").empty()) set_bool("user_bed_type", true); if (get("grabber_size_factor").empty()) diff --git a/src/slic3r/GUI/Jobs/EmbossJob.cpp b/src/slic3r/GUI/Jobs/EmbossJob.cpp index 614ba6a06..4234dc4da 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.cpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.cpp @@ -374,7 +374,11 @@ void CreateObjectJob::process(Ctl &ctl) if (m_input.base->shape.projection.use_surface) m_input.base->shape.projection.use_surface = false; // auto was_canceled = ::was_canceled(ctl, *m_input.base); - m_result = create_mesh(*m_input.base); + if (m_input.base->merge_shape || !m_input.base->text_lines.empty()) { // || m_input.base->shape.shapes_with_ids.size() > 20 + m_result = create_mesh(*m_input.base); + } else { + m_results = create_meshs(*m_input.base); + } // Create new object // calculate X,Y offset position for lay on platter in place of @@ -407,7 +411,7 @@ void CreateObjectJob::finalize(bool canceled, std::exception_ptr &eptr) { if (!_finalize(canceled, eptr, *m_input.base)) return; // only for sure - if (m_result.empty()) { + if (m_result.empty() && m_results.empty()) { create_message("Can't create empty object."); return; } @@ -425,13 +429,28 @@ void CreateObjectJob::finalize(bool canceled, std::exception_ptr &eptr) new_object->name = m_input.base->volume_name; new_object->add_instance(); // each object should have at list one instance - ModelVolume *new_volume = new_object->add_volume(std::move(m_result)); - // set a default extruder value, since user can't add it manually - new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); - - // write emboss data into volume - m_input.base->write(*new_volume); + if (!m_result.empty()) { + ModelVolume *new_volume = new_object->add_volume(std::move(m_result)); + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + // write emboss data into volume + m_input.base->write(*new_volume); + } else if (!m_results.empty()) { + int index = 0; + for (auto shape : m_input.base->shape.shapes_with_ids) { + if (shape.expoly.empty()) + continue; + ModelVolume *new_volume = new_object->add_volume(std::move(m_results[index])); + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + //donot write emboss data into volume + new_volume->name = new_object->name + "_" + std::to_string(index); + index++; + } + } else { + create_message("CreateObjectJob:unknown error."); + } // set transformation Slic3r::Geometry::Transformation tr(m_transformation); new_object->instances.front()->set_transformation(tr); @@ -632,6 +651,26 @@ TriangleMesh create_mesh(DataBase &input) return result; } +std::vector create_meshs(DataBase &input) +{ + std::vector meshs; + + // NOTE: SHAPE_SCALE is applied in ProjectZ + double scale = input.shape.scale; + double depth = input.shape.projection.depth / scale; + auto projectZ = std::make_unique(depth); + float offset = input.is_outside ? -SAFE_SURFACE_OFFSET : (SAFE_SURFACE_OFFSET - input.shape.projection.depth); + if (input.from_surface.has_value()) offset += *input.from_surface; + Transform3d tr = Eigen::Translation(0., 0., static_cast(offset)) * Eigen::Scaling(scale); + ProjectTransform project(std::move(projectZ), tr); + + for (auto shape : input.shape.shapes_with_ids) { + if (shape.expoly.empty()) continue; + meshs.emplace_back(TriangleMesh(polygons2model(shape.expoly, project))); + } + return meshs; +} + void create_volume( TriangleMesh &&mesh, const ObjectID &object_id, const ModelVolumeType type, const std::optional &trmat, const DataBase &data, unsigned char gizmo_type) { @@ -967,9 +1006,13 @@ bool start_update_volume(DataUpdate &&data, const ModelVolume &volume, const Sel return execute_job(std::move(job)); #endif // EXECUTE_UPDATE_ON_MAIN_THREAD } +bool is_merge_shape_before_create_object() { + return GUI::wxGetApp().app_config->get_bool("import_single_svg_and_split") ? false : true; +} bool start_create_object_job(const CreateVolumeParams &input, DataBasePtr emboss_data, const Vec2d &coor) { + emboss_data->merge_shape = input.merge_shape; const Pointfs & bed_shape = input.build_volume.printable_area(); DataCreateObject m_input{std::move(emboss_data), coor, input.camera, bed_shape, input.gizmo_type, input.angle}; @@ -1025,17 +1068,20 @@ bool start_create_volume_without_position(CreateVolumeParams &input, DataBasePtr const ModelObjectPtrs &objects = selection.get_model()->objects; // No selected object so create new object - if (selection.is_empty() || object_idx < 0 || static_cast(object_idx) >= objects.size()) + if (selection.is_empty() || object_idx < 0 || static_cast(object_idx) >= objects.size()){ // create Object on center of screen // when ray throw center of screen not hit bed it create object on center of bed + input.merge_shape = is_merge_shape_before_create_object(); return start_create_object_job(input, std::move(data), screen_center); - + } // create volume inside of selected object Vec2d coor; const Camera &camera = wxGetApp().plater()->get_camera(); input.gl_volume = find_closest(selection, screen_center, camera, objects, &coor); - if (input.gl_volume == nullptr) + if (input.gl_volume == nullptr) { + input.merge_shape = is_merge_shape_before_create_object(); return start_create_object_job(input, std::move(data), screen_center); + } else { return start_create_volume_on_surface_job(input, std::move(data), coor); } @@ -1097,6 +1143,7 @@ bool start_create_volume_on_surface_job(CreateVolumeParams &input, DataBasePtr d // object. After right click, object is selected and object_idx is set // also hit must exist. But there is options to add text by object list if (!hit.has_value()) { // modify by bbs + input.merge_shape = is_merge_shape_before_create_object(); return start_create_object_job(input, std::move(data), mouse_pos); // return on_bad_state(std::move(data), object); } @@ -1114,9 +1161,11 @@ bool start_create_volume(CreateVolumeParams &input, DataBasePtr data, const Vec2 if (data == nullptr) return false; if (!check(input)) return false; - if (input.gl_volume == nullptr || !input.gl_volume->selected) + if (input.gl_volume == nullptr || !input.gl_volume->selected) { + input.merge_shape = is_merge_shape_before_create_object(); // object is not under mouse position soo create object on plater return start_create_object_job(input, std::move(data), mouse_pos); + } else { // modify by bbs return start_create_volume_on_surface_job(input, std::move(data), mouse_pos); } diff --git a/src/slic3r/GUI/Jobs/EmbossJob.hpp b/src/slic3r/GUI/Jobs/EmbossJob.hpp index 990b13228..7392a386a 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.hpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.hpp @@ -69,6 +69,7 @@ public: std::shared_ptr> cancel; // shape to emboss EmbossShape shape; + bool merge_shape{true}; }; struct DataCreateVolumeUtil : public DataBase // modfiy bu bbs //struct DataCreateVolume : public DataBase @@ -124,6 +125,7 @@ struct DataUpdate std::optional distance = {}; // Wanted additionl rotation around Z of new created volume std::optional angle = {}; + bool merge_shape{true}; }; struct DataCreateObject { @@ -251,6 +253,7 @@ class CreateObjectJob : public JobNew { DataCreateObject m_input; TriangleMesh m_result; + std::vector m_results; Transform3d m_transformation; public: @@ -318,6 +321,7 @@ static ExPolygons create_shape(DataBase &input); static TriangleMesh create_mesh_per_glyph(DataBase &input); static TriangleMesh try_create_mesh(DataBase &input); static TriangleMesh create_mesh(DataBase &input); +static std::vector create_meshs(DataBase &input); static indexed_triangle_set cut_surface_to_its(const ExPolygons &shapes, const Transform3d &tr, const SurfaceVolumeData::ModelSources &sources, DataBase &input); static TriangleMesh cut_per_glyph_surface(DataBase &input1, const SurfaceVolumeData &input2); static TriangleMesh cut_surface(DataBase &input1, const SurfaceVolumeData &input2); diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 451b52c41..c53fe9c57 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1174,6 +1174,9 @@ wxWindow* PreferencesDialog::create_general_page() auto item_show_shells_in_preview_settings = create_item_checkbox(_L("Always show shells in preview"), page, _L("Always show shells or not in preview view tab.If change value,you should reslice."), 50, "show_shells_in_preview"); + auto item_import_single_svg_and_split = create_item_checkbox(_L("Import a single SVG and split it"), page, + _L("Import a single SVG and then split it to several parts."), 50, + "import_single_svg_and_split"); auto enable_lod_settings = create_item_checkbox(_L("Improve rendering performance by lod"), page, _L("Improved rendering performance under the scene of multiple plates and many models."), 50, "enable_lod"); @@ -1264,6 +1267,7 @@ wxWindow* PreferencesDialog::create_general_page() sizer_page->Add(_3d_settings, 0, wxTOP | wxEXPAND, FromDIP(20)); sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3)); + sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3)); sizer_page->Add(enable_opengl_multi_instance_rendering, 0, wxTOP, FromDIP(3)); sizer_page->Add(enable_lod_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_grabber_size_settings, 0, wxTOP, FromDIP(3));