mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	Merge branch 'dev_native' of https://github.com/prusa3d/Slic3r into dev_native
This commit is contained in:
		
						commit
						fab4f55e63
					
				
					 16 changed files with 167 additions and 43 deletions
				
			
		|  | @ -119,28 +119,28 @@ if (MSVC) | |||
|         foreach (CONF ${CMAKE_CONFIGURATION_TYPES}) | ||||
|             file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}" WIN_CONF_OUTPUT_DIR) | ||||
|             file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}/resources" WIN_RESOURCES_SYMLINK) | ||||
|             add_custom_target("resources_symlink_${CONF}" ALL | ||||
|                 DEPENDS slic3r | ||||
|             add_custom_command(TARGET slic3r POST_BUILD | ||||
|                 COMMAND if exist "${WIN_CONF_OUTPUT_DIR}" "(" | ||||
|                         if not exist "${WIN_RESOURCES_SYMLINK}" "(" | ||||
|                             mklink /J "${WIN_RESOURCES_SYMLINK}" "${SLIC3R_RESOURCES_DIR_WIN}" | ||||
|                         ")" | ||||
|                     ")" | ||||
|                 COMMENT "Symlinking the resources directory into the build tree" | ||||
|                 VERBATIM | ||||
|             ) | ||||
|         endforeach () | ||||
|     else () | ||||
|         file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/resources" WIN_RESOURCES_SYMLINK) | ||||
|         add_custom_target(resources_symlink ALL | ||||
|             DEPENDS slic3r | ||||
|         add_custom_command(TARGET slic3r POST_BUILD | ||||
|             COMMAND if not exist "${WIN_RESOURCES_SYMLINK}" "(" mklink /J "${WIN_RESOURCES_SYMLINK}" "${SLIC3R_RESOURCES_DIR_WIN}" ")" | ||||
|             COMMENT "Symlinking the resources directory into the build tree" | ||||
|             VERBATIM | ||||
|         ) | ||||
|     endif () | ||||
| else () | ||||
|     add_custom_target(resources_symlink ALL | ||||
|         DEPENDS slic3r | ||||
|     add_custom_command(TARGET slic3r POST_BUILD | ||||
|         COMMAND ln -sf "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources" | ||||
|         COMMENT "Symlinking the resources directory into the build tree" | ||||
|         VERBATIM | ||||
|     ) | ||||
| endif() | ||||
|  |  | |||
|  | @ -1249,14 +1249,25 @@ namespace Slic3r { | |||
| 
 | ||||
|     void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform) | ||||
|     { | ||||
|         // slic3r ModelInstance cannot be transformed using a matrix
 | ||||
|         // we extract from the given matrix only the values currently used
 | ||||
| 
 | ||||
|         // translation
 | ||||
|         Vec3d offset = transform.matrix().block(0, 3, 3, 1); | ||||
| 
 | ||||
|         // scale
 | ||||
|         Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m3x3 = transform.matrix().block(0, 0, 3, 3); | ||||
| #if ENABLE_MIRROR | ||||
|         // mirror
 | ||||
|         // it is impossible to reconstruct the original mirroring factors from a matrix,
 | ||||
|         // we can only detect if the matrix contains a left handed reference system
 | ||||
|         // in which case we reorient it back to right handed by mirroring the x axis
 | ||||
|         Vec3d mirror = Vec3d::Ones(); | ||||
|         if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0) | ||||
|         { | ||||
|             mirror(0) = -1.0; | ||||
|             // remove mirror
 | ||||
|             m3x3.col(0) *= -1.0; | ||||
|         } | ||||
| 
 | ||||
|         // scale
 | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         Vec3d scale(m3x3.col(0).norm(), m3x3.col(1).norm(), m3x3.col(2).norm()); | ||||
| 
 | ||||
|         // invalid scale value, return
 | ||||
|  | @ -1273,6 +1284,9 @@ namespace Slic3r { | |||
|         instance.set_offset(offset); | ||||
|         instance.set_scaling_factor(scale); | ||||
|         instance.set_rotation(rotation); | ||||
| #if ENABLE_MIRROR | ||||
|         instance.set_mirror(mirror); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     } | ||||
| 
 | ||||
|     bool _3MF_Importer::_handle_start_config(const char** attributes, unsigned int num_attributes) | ||||
|  |  | |||
|  | @ -32,6 +32,9 @@ | |||
| // 2 : Added z component of offset
 | ||||
| //     Added x and y components of rotation
 | ||||
| //     Added x, y and z components of scale
 | ||||
| #if ENABLE_MIRROR | ||||
| //     Added x, y and z components of mirror
 | ||||
| #endif // ENABLE_MIRROR
 | ||||
| const unsigned int VERSION_AMF = 2; | ||||
| const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version"; | ||||
| 
 | ||||
|  | @ -126,14 +129,27 @@ struct AMFParserContext | |||
|         NODE_TYPE_RY,                   // amf/constellation/instance/ry
 | ||||
|         NODE_TYPE_RZ,                   // amf/constellation/instance/rz
 | ||||
|         NODE_TYPE_SCALE,                // amf/constellation/instance/scale
 | ||||
|         NODE_TYPE_SCALEX,                // amf/constellation/instance/scalex
 | ||||
|         NODE_TYPE_SCALEY,                // amf/constellation/instance/scaley
 | ||||
|         NODE_TYPE_SCALEZ,                // amf/constellation/instance/scalez
 | ||||
|         NODE_TYPE_SCALEX,               // amf/constellation/instance/scalex
 | ||||
|         NODE_TYPE_SCALEY,               // amf/constellation/instance/scaley
 | ||||
|         NODE_TYPE_SCALEZ,               // amf/constellation/instance/scalez
 | ||||
| #if ENABLE_MIRROR | ||||
|         NODE_TYPE_MIRRORX,              // amf/constellation/instance/mirrorx
 | ||||
|         NODE_TYPE_MIRRORY,              // amf/constellation/instance/mirrory
 | ||||
|         NODE_TYPE_MIRRORZ,              // amf/constellation/instance/mirrorz
 | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         NODE_TYPE_METADATA,             // anywhere under amf/*/metadata
 | ||||
|     }; | ||||
| 
 | ||||
|     struct Instance { | ||||
| #if ENABLE_MIRROR | ||||
|         Instance() | ||||
|             : deltax_set(false), deltay_set(false), deltaz_set(false) | ||||
|             , rx_set(false), ry_set(false), rz_set(false) | ||||
|             , scalex_set(false), scaley_set(false), scalez_set(false) | ||||
|             , mirrorx_set(false), mirrory_set(false), mirrorz_set(false) {} | ||||
| #else | ||||
|         Instance() : deltax_set(false), deltay_set(false), deltaz_set(false), rx_set(false), ry_set(false), rz_set(false), scalex_set(false), scaley_set(false), scalez_set(false)  {} | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         // Shift in the X axis.
 | ||||
|         float deltax; | ||||
|         bool  deltax_set; | ||||
|  | @ -159,6 +175,15 @@ struct AMFParserContext | |||
|         bool  scaley_set; | ||||
|         float scalez; | ||||
|         bool  scalez_set; | ||||
| #if ENABLE_MIRROR | ||||
|         // Mirroring factors
 | ||||
|         float mirrorx; | ||||
|         bool  mirrorx_set; | ||||
|         float mirrory; | ||||
|         bool  mirrory_set; | ||||
|         float mirrorz; | ||||
|         bool  mirrorz_set; | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     }; | ||||
| 
 | ||||
|     struct Object { | ||||
|  | @ -289,6 +314,14 @@ void AMFParserContext::startElement(const char *name, const char **atts) | |||
|                 node_type_new = NODE_TYPE_SCALEZ; | ||||
|             else if (strcmp(name, "scale") == 0) | ||||
|                 node_type_new = NODE_TYPE_SCALE; | ||||
| #if ENABLE_MIRROR | ||||
|             else if (strcmp(name, "mirrorx") == 0) | ||||
|                 node_type_new = NODE_TYPE_MIRRORX; | ||||
|             else if (strcmp(name, "mirrory") == 0) | ||||
|                 node_type_new = NODE_TYPE_MIRRORY; | ||||
|             else if (strcmp(name, "mirrorz") == 0) | ||||
|                 node_type_new = NODE_TYPE_MIRRORZ; | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         } | ||||
|         break; | ||||
|     case 4: | ||||
|  | @ -345,16 +378,23 @@ void AMFParserContext::characters(const XML_Char *s, int len) | |||
|     { | ||||
|         switch (m_path.size()) { | ||||
|         case 4: | ||||
|             if (m_path.back() == NODE_TYPE_DELTAX ||  | ||||
|                 m_path.back() == NODE_TYPE_DELTAY ||  | ||||
|                 m_path.back() == NODE_TYPE_DELTAZ ||  | ||||
|             if (m_path.back() == NODE_TYPE_DELTAX || | ||||
|                 m_path.back() == NODE_TYPE_DELTAY || | ||||
|                 m_path.back() == NODE_TYPE_DELTAZ || | ||||
|                 m_path.back() == NODE_TYPE_RX || | ||||
|                 m_path.back() == NODE_TYPE_RY || | ||||
|                 m_path.back() == NODE_TYPE_RZ || | ||||
|                 m_path.back() == NODE_TYPE_SCALEX || | ||||
|                 m_path.back() == NODE_TYPE_SCALEY || | ||||
|                 m_path.back() == NODE_TYPE_SCALEZ || | ||||
| #if ENABLE_MIRROR | ||||
|                 m_path.back() == NODE_TYPE_SCALE || | ||||
|                 m_path.back() == NODE_TYPE_MIRRORX || | ||||
|                 m_path.back() == NODE_TYPE_MIRRORY || | ||||
|                 m_path.back() == NODE_TYPE_MIRRORZ) | ||||
| #else | ||||
|                 m_path.back() == NODE_TYPE_SCALE) | ||||
| #endif // ENABLE_MIRROR
 | ||||
|                 m_value[0].append(s, len); | ||||
|             break; | ||||
|         case 6: | ||||
|  | @ -446,6 +486,26 @@ void AMFParserContext::endElement(const char * /* name */) | |||
|         m_instance->scalez_set = true; | ||||
|         m_value[0].clear(); | ||||
|         break; | ||||
| #if ENABLE_MIRROR | ||||
|     case NODE_TYPE_MIRRORX: | ||||
|         assert(m_instance); | ||||
|         m_instance->mirrorx = float(atof(m_value[0].c_str())); | ||||
|         m_instance->mirrorx_set = true; | ||||
|         m_value[0].clear(); | ||||
|         break; | ||||
|     case NODE_TYPE_MIRRORY: | ||||
|         assert(m_instance); | ||||
|         m_instance->mirrory = float(atof(m_value[0].c_str())); | ||||
|         m_instance->mirrory_set = true; | ||||
|         m_value[0].clear(); | ||||
|         break; | ||||
|     case NODE_TYPE_MIRRORZ: | ||||
|         assert(m_instance); | ||||
|         m_instance->mirrorz = float(atof(m_value[0].c_str())); | ||||
|         m_instance->mirrorz_set = true; | ||||
|         m_value[0].clear(); | ||||
|         break; | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
|     // Object vertices:
 | ||||
|     case NODE_TYPE_VERTEX: | ||||
|  | @ -585,6 +645,9 @@ void AMFParserContext::endDocument() | |||
|                 mi->set_offset(Vec3d(instance.deltax_set ? (double)instance.deltax : 0.0, instance.deltay_set ? (double)instance.deltay : 0.0, instance.deltaz_set ? (double)instance.deltaz : 0.0)); | ||||
|                 mi->set_rotation(Vec3d(instance.rx_set ? (double)instance.rx : 0.0, instance.ry_set ? (double)instance.ry : 0.0, instance.rz_set ? (double)instance.rz : 0.0)); | ||||
|                 mi->set_scaling_factor(Vec3d(instance.scalex_set ? (double)instance.scalex : 1.0, instance.scaley_set ? (double)instance.scaley : 1.0, instance.scalez_set ? (double)instance.scalez : 1.0)); | ||||
| #if ENABLE_MIRROR | ||||
|                 mi->set_mirror(Vec3d(instance.mirrorx_set ? (double)instance.mirrorx : 1.0, instance.mirrory_set ? (double)instance.mirrory : 1.0, instance.mirrorz_set ? (double)instance.mirrorz : 1.0)); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|             } | ||||
|     } | ||||
| } | ||||
|  | @ -891,6 +954,11 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c | |||
|                     "      <scalex>%lf</scalex>\n" | ||||
|                     "      <scaley>%lf</scaley>\n" | ||||
|                     "      <scalez>%lf</scalez>\n" | ||||
| #if ENABLE_MIRROR | ||||
|                     "      <mirrorx>%lf</mirrorx>\n" | ||||
|                     "      <mirrory>%lf</mirrory>\n" | ||||
|                     "      <mirrorz>%lf</mirrorz>\n" | ||||
| #endif // ENABLE_MIRROR
 | ||||
|                     "    </instance>\n", | ||||
|                     object_id, | ||||
|                     instance->get_offset(X), | ||||
|  | @ -901,7 +969,14 @@ bool store_amf(const char *path, Model *model, Print* print, bool export_print_c | |||
|                     instance->get_rotation(Z), | ||||
|                     instance->get_scaling_factor(X), | ||||
|                     instance->get_scaling_factor(Y), | ||||
| #if ENABLE_MIRROR | ||||
|                     instance->get_scaling_factor(Z), | ||||
|                     instance->get_mirror(X), | ||||
|                     instance->get_mirror(Y), | ||||
|                     instance->get_mirror(Z)); | ||||
| #else | ||||
|                     instance->get_scaling_factor(Z)); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
|                 //FIXME missing instance->scaling_factor
 | ||||
|                 instances.append(buf); | ||||
|  |  | |||
|  | @ -711,9 +711,13 @@ void ModelObject::center_around_origin() | |||
| 
 | ||||
|     if (!this->instances.empty()) { | ||||
|         for (ModelInstance *i : this->instances) { | ||||
| #if ENABLE_MIRROR | ||||
|             i->set_offset(i->get_offset() - shift); | ||||
| #else | ||||
|             // apply rotation and scaling to vector as well before translating instance,
 | ||||
|             // in order to leave final position unaltered
 | ||||
|             i->set_offset(i->get_offset() + i->transform_vector(-shift, true)); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         } | ||||
|         this->invalidate_bounding_box(); | ||||
|     } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
| // New selections
 | ||||
| #define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0) | ||||
| // Add mirror components along the three axes in ModelInstance and GLVolume
 | ||||
| #define ENABLE_MIRROR (0 && ENABLE_1_42_0) | ||||
| #define ENABLE_MIRROR (1 && ENABLE_1_42_0) | ||||
| 
 | ||||
| #endif // _technologies_h_
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3432,7 +3432,6 @@ int GLCanvas3D::get_in_object_volume_id(int scene_vol_idx) const | |||
| #if ENABLE_EXTENDED_SELECTION | ||||
| void GLCanvas3D::mirror_selection(Axis axis) | ||||
| { | ||||
|     m_regenerate_volumes = false; | ||||
|     m_selection.mirror(axis); | ||||
|     _on_mirror(); | ||||
|     wxGetApp().obj_manipul()->update_settings_value(m_selection); | ||||
|  | @ -3457,7 +3456,12 @@ void GLCanvas3D::reload_scene(bool force) | |||
| 
 | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|     if (m_regenerate_volumes) | ||||
|     { | ||||
|         reset_volumes(); | ||||
| 
 | ||||
|         // to update the toolbar
 | ||||
|         post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); | ||||
|     } | ||||
| #endif // ENABLE_EXTENDED_SELECTION
 | ||||
| 
 | ||||
|     set_bed_shape(dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"))->values); | ||||
|  | @ -3477,9 +3481,6 @@ void GLCanvas3D::reload_scene(bool force) | |||
|         { | ||||
|             load_object(*m_model, obj_idx); | ||||
|         } | ||||
| 
 | ||||
|         // to update the toolbar
 | ||||
|         post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT)); | ||||
|     } | ||||
| 
 | ||||
|     update_gizmos_data(); | ||||
|  | @ -3858,7 +3859,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|         case Gizmos::Scale: | ||||
|         { | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|             m_regenerate_volumes = false; | ||||
|             m_selection.scale(m_gizmos.get_scale()); | ||||
|             _on_scale(); | ||||
| #else | ||||
|  | @ -3875,7 +3875,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|         case Gizmos::Rotate: | ||||
|         { | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|             m_regenerate_volumes = false; | ||||
|             m_selection.rotate(m_gizmos.get_rotation()); | ||||
|             _on_rotate(); | ||||
| #else | ||||
|  | @ -3958,7 +3957,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             if (m_gizmos.get_current_type() == Gizmos::Flatten) { | ||||
|                 // Rotate the object so the normal points downward:
 | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|                 m_regenerate_volumes = false; | ||||
|                 m_selection.rotate(m_gizmos.get_flattening_rotation()); | ||||
|                 _on_flatten(); | ||||
|                 wxGetApp().obj_manipul()->update_settings_value(m_selection); | ||||
|  | @ -4397,7 +4395,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             case Gizmos::Scale: | ||||
|             { | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|                 m_regenerate_volumes = false; | ||||
|                 _on_scale(); | ||||
| #endif // ENABLE_EXTENDED_SELECTION
 | ||||
|                 break; | ||||
|  | @ -4405,7 +4402,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) | |||
|             case Gizmos::Rotate: | ||||
|             { | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|                 m_regenerate_volumes = false; | ||||
|                 _on_rotate(); | ||||
| #else | ||||
|                 post_event(Vec3dEvent(EVT_GIZMO_ROTATE, m_gizmos.get_rotation())); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <wx/bitmap.h> | ||||
| #include <wx/dataview.h> | ||||
| #include <map> | ||||
| #include <vector> | ||||
| 
 | ||||
| class wxBoxSizer; | ||||
| class PrusaObjectDataViewModel; | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent) | |||
| 
 | ||||
|     auto* sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|     cbox = new wxCheckBox(this, wxID_ANY, checkbox_label); | ||||
|     cbox->SetValue(true); | ||||
|     sizer->AddSpacer(5); | ||||
|     sizer->Add(this->cbox, 0, wxEXPAND | wxALL, 5); | ||||
|     SetSizer(sizer); | ||||
|  |  | |||
|  | @ -296,11 +296,11 @@ void MainFrame::init_menubar() | |||
|     if (m_plater) { | ||||
|         m_plater_menu = new wxMenu(); | ||||
|         append_menu_item(m_plater_menu, wxID_ANY, _(L("Export G-code...")), _(L("Export current plate as G-code")), | ||||
|             [this](wxCommandEvent&){ /*m_plater->export_gcode(); */}, "cog_go.png"); | ||||
|             [this](wxCommandEvent&){ m_plater->export_gcode(); }, "cog_go.png"); | ||||
|         append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as STL...")), _(L("Export current plate as STL")), | ||||
|             [this](wxCommandEvent&){ /*m_plater->export_stl(); */}, "brick_go.png"); | ||||
|             [this](wxCommandEvent&){ m_plater->export_stl(); }, "brick_go.png"); | ||||
|         append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as AMF...")), _(L("Export current plate as AMF")), | ||||
|             [this](wxCommandEvent&){ /*m_plater->export_amf();*/ }, "brick_go.png"); | ||||
|             [this](wxCommandEvent&){ m_plater->export_amf(); }, "brick_go.png"); | ||||
|         append_menu_item(m_plater_menu, wxID_ANY, _(L("Export plate as 3MF...")), _(L("Export current plate as 3MF")), | ||||
|             [this](wxCommandEvent&){ m_plater->export_3mf(); }, "brick_go.png"); | ||||
|     } | ||||
|  |  | |||
|  | @ -388,24 +388,32 @@ void ConfigOptionsGroup::reload_config(){ | |||
| } | ||||
| 
 | ||||
| bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { | ||||
|     if (m_options_mode.empty()) | ||||
|         return true; | ||||
|     if (m_grid_sizer->GetEffectiveRowsCount() != m_options_mode.size() && | ||||
|         m_options_mode.size() == 1) | ||||
|         return m_options_mode[0] <= mode; | ||||
| 
 | ||||
|     sizer->ShowItems(true); | ||||
| #ifdef __WXGTK__ | ||||
|     m_panel->Show(true); | ||||
|     m_grid_sizer->Show(true); | ||||
| #endif /* __WXGTK__ */ | ||||
| 
 | ||||
|     int coef = 0; | ||||
|     int hidden_row_cnt = 0; | ||||
|     const int cols = m_grid_sizer->GetCols(); | ||||
|     for (auto opt_mode : m_options_mode) { | ||||
| 		const bool show = opt_mode <= mode; | ||||
|         if (!show) { | ||||
|             hidden_row_cnt++; | ||||
|             for (int i = 0; i < cols; ++i) | ||||
|                 m_grid_sizer->Show(coef + i, show); | ||||
|         } | ||||
|         coef+= cols; | ||||
| 	} | ||||
| 
 | ||||
|     if (!sizer->IsShown(m_grid_sizer)) { | ||||
|     if (hidden_row_cnt == m_options_mode.size()) { | ||||
|         sizer->ShowItems(false); | ||||
|         return false; | ||||
|     } | ||||
|  |  | |||
|  | @ -700,7 +700,7 @@ private: | |||
|     static const std::regex pattern_drop; | ||||
| }; | ||||
| 
 | ||||
| const std::regex PlaterDropTarget::pattern_drop("[.](stl|obj|amf|3mf|prusa)$", std::regex::icase); | ||||
| const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", std::regex::icase); | ||||
| 
 | ||||
| bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) | ||||
| { | ||||
|  | @ -850,13 +850,15 @@ private: | |||
|     bool layers_height_allowed() const; | ||||
|     bool can_delete_all() const; | ||||
|     bool can_arrange() const; | ||||
| #if ENABLE_MIRROR | ||||
|     bool can_mirror() const; | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_EXTENDED_SELECTION
 | ||||
| }; | ||||
| 
 | ||||
| const std::regex Plater::priv::pattern_bundle("[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)$", std::regex::icase); | ||||
| const std::regex Plater::priv::pattern_3mf("[.]3mf$", std::regex::icase); | ||||
| const std::regex Plater::priv::pattern_zip_amf("[.]zip[.]amf$", std::regex::icase); | ||||
| const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase); | ||||
| const std::regex Plater::priv::pattern_3mf(".*3mf", std::regex::icase); | ||||
| const std::regex Plater::priv::pattern_zip_amf(".*[.]zip[.]amf", std::regex::icase); | ||||
| 
 | ||||
| Plater::priv::priv(Plater *q, MainFrame *main_frame) : | ||||
|     q(q), | ||||
|  | @ -1258,7 +1260,8 @@ std::unique_ptr<CheckboxFileDialog> Plater::priv::get_export_file(GUI::FileType | |||
|         case FT_STL: | ||||
|         case FT_AMF: | ||||
|         case FT_3MF: | ||||
|             wildcard = file_wildcards[FT_STL]; | ||||
|         case FT_GCODE: | ||||
|             wildcard = file_wildcards[file_type]; | ||||
|         break; | ||||
| 
 | ||||
|         default: | ||||
|  | @ -1362,7 +1365,7 @@ void Plater::priv::selection_changed() | |||
|     _3DScene::enable_toolbar_item(canvas3D, "split", have_sel); | ||||
|     _3DScene::enable_toolbar_item(canvas3D, "cut", have_sel); | ||||
|     _3DScene::enable_toolbar_item(canvas3D, "settings", have_sel); | ||||
|     _3DScene::enable_toolbar_item(canvas3D, "layersediting", layers_height_allowed); | ||||
|     _3DScene::enable_toolbar_item(canvas3D, "layersediting", have_sel && config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D)); | ||||
| #endif // ENABLE_EXTENDED_SELECTION
 | ||||
| 
 | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|  | @ -1474,6 +1477,9 @@ void Plater::priv::remove(size_t obj_idx) | |||
|     // Prevent toolpaths preview from rendering while we modify the Print object
 | ||||
|     preview->set_enabled(false); | ||||
| 
 | ||||
|     if (_3DScene::is_layers_editing_enabled(canvas3D)) | ||||
|         _3DScene::enable_layers_editing(canvas3D, false); | ||||
| 
 | ||||
| #if !ENABLE_EXTENDED_SELECTION | ||||
|     objects.erase(objects.begin() + obj_idx); | ||||
| #endif // !ENABLE_EXTENDED_SELECTION
 | ||||
|  | @ -1497,6 +1503,9 @@ void Plater::priv::reset() | |||
|     // Prevent toolpaths preview from rendering while we modify the Print object
 | ||||
|     preview->set_enabled(false); | ||||
| 
 | ||||
|     if (_3DScene::is_layers_editing_enabled(canvas3D)) | ||||
|         _3DScene::enable_layers_editing(canvas3D, false); | ||||
| 
 | ||||
| #if !ENABLE_EXTENDED_SELECTION | ||||
|     objects.clear(); | ||||
| #endif // !ENABLE_EXTENDED_SELECTION
 | ||||
|  | @ -1774,7 +1783,10 @@ void Plater::priv::on_action_settings(SimpleEvent&) | |||
| 
 | ||||
| void Plater::priv::on_action_layersediting(SimpleEvent&) | ||||
| { | ||||
|     // TODO
 | ||||
|     bool enable = !_3DScene::is_layers_editing_enabled(canvas3D); | ||||
|     _3DScene::enable_layers_editing(canvas3D, enable); | ||||
|     if (enable && !_3DScene::is_layers_editing_enabled(canvas3D)) | ||||
|         _3DScene::enable_toolbar_item(canvas3D, "layersediting", false); | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_EXTENDED_SELECTION | ||||
|  | @ -1899,6 +1911,7 @@ bool Plater::priv::init_object_menu() | |||
| 
 | ||||
|     object_menu.AppendSeparator(); | ||||
|      | ||||
| #if ENABLE_MIRROR | ||||
|     wxMenu* mirror_menu = new wxMenu(); | ||||
|     if (mirror_menu == nullptr) | ||||
|         return false; | ||||
|  | @ -1911,6 +1924,7 @@ bool Plater::priv::init_object_menu() | |||
|         [this](wxCommandEvent&){ mirror(Z); }, "bullet_blue.png", &object_menu); | ||||
| 
 | ||||
|     wxMenuItem* item_mirror = append_submenu(&object_menu, mirror_menu, wxID_ANY, _(L("Mirror")), _(L("Mirror the selected object"))); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
|     wxMenuItem* item_split = append_menu_item(&object_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object into individual parts")), | ||||
|         [this](wxCommandEvent&){ split_object(); }, "shape_ungroup.png"); | ||||
|  | @ -1919,7 +1933,9 @@ bool Plater::priv::init_object_menu() | |||
|     // ui updates needs to be binded to the parent panel
 | ||||
|     if (q != nullptr) | ||||
|     { | ||||
| #if ENABLE_MIRROR | ||||
|         q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_mirror()); }, item_mirror->GetId()); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_object()); }, item_delete->GetId()); | ||||
|         q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_increase_instances()); }, item_increase->GetId()); | ||||
|         q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_decrease_instances()); }, item_decrease->GetId()); | ||||
|  | @ -1963,7 +1979,8 @@ bool Plater::priv::can_cut_object() const | |||
| 
 | ||||
| bool Plater::priv::layers_height_allowed() const | ||||
| { | ||||
|     return config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D); | ||||
|     int obj_idx = get_selected_object_idx(); | ||||
|     return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D); | ||||
| } | ||||
| 
 | ||||
| bool Plater::priv::can_delete_all() const | ||||
|  | @ -1976,10 +1993,12 @@ bool Plater::priv::can_arrange() const | |||
|     return !model.objects.empty(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
| bool Plater::priv::can_mirror() const | ||||
| { | ||||
|     return get_selection().is_from_single_instance(); | ||||
| } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_EXTENDED_SELECTION
 | ||||
| 
 | ||||
| // Plater / Public
 | ||||
|  |  | |||
|  | @ -476,14 +476,14 @@ void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool | |||
| void Tab::update_changed_tree_ui() | ||||
| { | ||||
| 	auto cur_item = m_treectrl->GetFirstVisibleItem(); | ||||
|     if (!m_treectrl->IsVisible(cur_item)) | ||||
|     if (!cur_item || !m_treectrl->IsVisible(cur_item)) | ||||
|         return; | ||||
| 	auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); | ||||
| 	while (cur_item){ | ||||
| 		auto title = m_treectrl->GetItemText(cur_item); | ||||
| 		for (auto page : m_pages) | ||||
| 		{ | ||||
| 			if (page->title() != title) | ||||
| 			if (page->title() != title)  | ||||
| 				continue; | ||||
| 			bool sys_page = true; | ||||
| 			bool modified_page = false; | ||||
|  | @ -644,6 +644,11 @@ void Tab::update_visibility(ConfigOptionMode mode) | |||
|     Refresh(); | ||||
| 
 | ||||
| 	Thaw(); | ||||
| 
 | ||||
|     // to update tree items color
 | ||||
|     wxTheApp->CallAfter([this]() { | ||||
|         update_changed_tree_ui(); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const | ||||
|  | @ -1782,7 +1787,7 @@ void TabPrinter::build_sla() | |||
|     auto page = add_options_page(_(L("General")), "printer_empty.png"); | ||||
|     auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); | ||||
| 
 | ||||
|     Line line{ _(L("Bed shape")), "" }; | ||||
|     Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
 | ||||
|     line.widget = [this](wxWindow* parent){ | ||||
|         auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); | ||||
|         //			btn->SetFont(Slic3r::GUI::small_font);
 | ||||
|  | @ -2762,8 +2767,8 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la | |||
|             bmp_name = "error.png"; | ||||
|         else { | ||||
|             auto mode = line.get_options()[0].opt.mode;  //we assume that we have one option per line
 | ||||
|             bmp_name = mode == comExpert ? "mode_expert.png" : | ||||
|                        mode == comMiddle ? "mode_middle.png" : "mode_simple.png"; | ||||
|             bmp_name = mode == comExpert ? "mode_expert_.png" : | ||||
|                        mode == comMiddle ? "mode_middle_.png" : "mode_simple_.png"; | ||||
|         }                                | ||||
|         auto bmp = new wxStaticBitmap(parent, wxID_ANY, wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG)); | ||||
|         return bmp; | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| 
 | ||||
| #include <vector> | ||||
| #include <set> | ||||
| #include <functional> | ||||
| 
 | ||||
| wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, | ||||
|     std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv