Merge branch 'dev_native' of https://github.com/prusa3d/Slic3r into dev_native

This commit is contained in:
bubnikv 2018-10-22 19:55:19 +02:00
commit fab4f55e63
16 changed files with 167 additions and 43 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -119,28 +119,28 @@ if (MSVC)
foreach (CONF ${CMAKE_CONFIGURATION_TYPES}) 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}" WIN_CONF_OUTPUT_DIR)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}/resources" WIN_RESOURCES_SYMLINK) file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}/resources" WIN_RESOURCES_SYMLINK)
add_custom_target("resources_symlink_${CONF}" ALL add_custom_command(TARGET slic3r POST_BUILD
DEPENDS slic3r
COMMAND if exist "${WIN_CONF_OUTPUT_DIR}" "(" COMMAND if exist "${WIN_CONF_OUTPUT_DIR}" "("
if not exist "${WIN_RESOURCES_SYMLINK}" "(" if not exist "${WIN_RESOURCES_SYMLINK}" "("
mklink /J "${WIN_RESOURCES_SYMLINK}" "${SLIC3R_RESOURCES_DIR_WIN}" mklink /J "${WIN_RESOURCES_SYMLINK}" "${SLIC3R_RESOURCES_DIR_WIN}"
")" ")"
")" ")"
COMMENT "Symlinking the resources directory into the build tree"
VERBATIM VERBATIM
) )
endforeach () endforeach ()
else () else ()
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/resources" WIN_RESOURCES_SYMLINK) file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/resources" WIN_RESOURCES_SYMLINK)
add_custom_target(resources_symlink ALL add_custom_command(TARGET slic3r POST_BUILD
DEPENDS slic3r
COMMAND if not exist "${WIN_RESOURCES_SYMLINK}" "(" mklink /J "${WIN_RESOURCES_SYMLINK}" "${SLIC3R_RESOURCES_DIR_WIN}" ")" 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 VERBATIM
) )
endif () endif ()
else () else ()
add_custom_target(resources_symlink ALL add_custom_command(TARGET slic3r POST_BUILD
DEPENDS slic3r
COMMAND ln -sf "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources" COMMAND ln -sf "${SLIC3R_RESOURCES_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/../resources"
COMMENT "Symlinking the resources directory into the build tree"
VERBATIM VERBATIM
) )
endif() endif()

View File

@ -1249,14 +1249,25 @@ namespace Slic3r {
void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform) 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 // translation
Vec3d offset = transform.matrix().block(0, 3, 3, 1); 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); 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()); Vec3d scale(m3x3.col(0).norm(), m3x3.col(1).norm(), m3x3.col(2).norm());
// invalid scale value, return // invalid scale value, return
@ -1273,6 +1284,9 @@ namespace Slic3r {
instance.set_offset(offset); instance.set_offset(offset);
instance.set_scaling_factor(scale); instance.set_scaling_factor(scale);
instance.set_rotation(rotation); 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) bool _3MF_Importer::_handle_start_config(const char** attributes, unsigned int num_attributes)

View File

@ -32,6 +32,9 @@
// 2 : Added z component of offset // 2 : Added z component of offset
// Added x and y components of rotation // Added x and y components of rotation
// Added x, y and z components of scale // 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 unsigned int VERSION_AMF = 2;
const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version"; const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version";
@ -129,11 +132,24 @@ struct AMFParserContext
NODE_TYPE_SCALEX, // amf/constellation/instance/scalex NODE_TYPE_SCALEX, // amf/constellation/instance/scalex
NODE_TYPE_SCALEY, // amf/constellation/instance/scaley NODE_TYPE_SCALEY, // amf/constellation/instance/scaley
NODE_TYPE_SCALEZ, // amf/constellation/instance/scalez 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 NODE_TYPE_METADATA, // anywhere under amf/*/metadata
}; };
struct Instance { 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) {} 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. // Shift in the X axis.
float deltax; float deltax;
bool deltax_set; bool deltax_set;
@ -159,6 +175,15 @@ struct AMFParserContext
bool scaley_set; bool scaley_set;
float scalez; float scalez;
bool scalez_set; 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 { struct Object {
@ -289,6 +314,14 @@ void AMFParserContext::startElement(const char *name, const char **atts)
node_type_new = NODE_TYPE_SCALEZ; node_type_new = NODE_TYPE_SCALEZ;
else if (strcmp(name, "scale") == 0) else if (strcmp(name, "scale") == 0)
node_type_new = NODE_TYPE_SCALE; 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; break;
case 4: case 4:
@ -354,7 +387,14 @@ void AMFParserContext::characters(const XML_Char *s, int len)
m_path.back() == NODE_TYPE_SCALEX || m_path.back() == NODE_TYPE_SCALEX ||
m_path.back() == NODE_TYPE_SCALEY || m_path.back() == NODE_TYPE_SCALEY ||
m_path.back() == NODE_TYPE_SCALEZ || 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) m_path.back() == NODE_TYPE_SCALE)
#endif // ENABLE_MIRROR
m_value[0].append(s, len); m_value[0].append(s, len);
break; break;
case 6: case 6:
@ -446,6 +486,26 @@ void AMFParserContext::endElement(const char * /* name */)
m_instance->scalez_set = true; m_instance->scalez_set = true;
m_value[0].clear(); m_value[0].clear();
break; 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: // Object vertices:
case NODE_TYPE_VERTEX: 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_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_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)); 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" " <scalex>%lf</scalex>\n"
" <scaley>%lf</scaley>\n" " <scaley>%lf</scaley>\n"
" <scalez>%lf</scalez>\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", " </instance>\n",
object_id, object_id,
instance->get_offset(X), 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_rotation(Z),
instance->get_scaling_factor(X), instance->get_scaling_factor(X),
instance->get_scaling_factor(Y), 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)); instance->get_scaling_factor(Z));
#endif // ENABLE_MIRROR
//FIXME missing instance->scaling_factor //FIXME missing instance->scaling_factor
instances.append(buf); instances.append(buf);

View File

@ -711,9 +711,13 @@ void ModelObject::center_around_origin()
if (!this->instances.empty()) { if (!this->instances.empty()) {
for (ModelInstance *i : this->instances) { 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, // apply rotation and scaling to vector as well before translating instance,
// in order to leave final position unaltered // in order to leave final position unaltered
i->set_offset(i->get_offset() + i->transform_vector(-shift, true)); i->set_offset(i->get_offset() + i->transform_vector(-shift, true));
#endif // ENABLE_MIRROR
} }
this->invalidate_bounding_box(); this->invalidate_bounding_box();
} }

View File

@ -11,7 +11,7 @@
// New selections // New selections
#define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0) #define ENABLE_EXTENDED_SELECTION (1 && ENABLE_1_42_0)
// Add mirror components along the three axes in ModelInstance and GLVolume // 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_ #endif // _technologies_h_

View File

@ -3432,7 +3432,6 @@ int GLCanvas3D::get_in_object_volume_id(int scene_vol_idx) const
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
void GLCanvas3D::mirror_selection(Axis axis) void GLCanvas3D::mirror_selection(Axis axis)
{ {
m_regenerate_volumes = false;
m_selection.mirror(axis); m_selection.mirror(axis);
_on_mirror(); _on_mirror();
wxGetApp().obj_manipul()->update_settings_value(m_selection); wxGetApp().obj_manipul()->update_settings_value(m_selection);
@ -3457,7 +3456,12 @@ void GLCanvas3D::reload_scene(bool force)
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
if (m_regenerate_volumes) if (m_regenerate_volumes)
{
reset_volumes(); reset_volumes();
// to update the toolbar
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
}
#endif // ENABLE_EXTENDED_SELECTION #endif // ENABLE_EXTENDED_SELECTION
set_bed_shape(dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"))->values); 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); load_object(*m_model, obj_idx);
} }
// to update the toolbar
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
} }
update_gizmos_data(); update_gizmos_data();
@ -3858,7 +3859,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
case Gizmos::Scale: case Gizmos::Scale:
{ {
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
m_regenerate_volumes = false;
m_selection.scale(m_gizmos.get_scale()); m_selection.scale(m_gizmos.get_scale());
_on_scale(); _on_scale();
#else #else
@ -3875,7 +3875,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
case Gizmos::Rotate: case Gizmos::Rotate:
{ {
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
m_regenerate_volumes = false;
m_selection.rotate(m_gizmos.get_rotation()); m_selection.rotate(m_gizmos.get_rotation());
_on_rotate(); _on_rotate();
#else #else
@ -3958,7 +3957,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (m_gizmos.get_current_type() == Gizmos::Flatten) { if (m_gizmos.get_current_type() == Gizmos::Flatten) {
// Rotate the object so the normal points downward: // Rotate the object so the normal points downward:
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
m_regenerate_volumes = false;
m_selection.rotate(m_gizmos.get_flattening_rotation()); m_selection.rotate(m_gizmos.get_flattening_rotation());
_on_flatten(); _on_flatten();
wxGetApp().obj_manipul()->update_settings_value(m_selection); wxGetApp().obj_manipul()->update_settings_value(m_selection);
@ -4397,7 +4395,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
case Gizmos::Scale: case Gizmos::Scale:
{ {
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
m_regenerate_volumes = false;
_on_scale(); _on_scale();
#endif // ENABLE_EXTENDED_SELECTION #endif // ENABLE_EXTENDED_SELECTION
break; break;
@ -4405,7 +4402,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
case Gizmos::Rotate: case Gizmos::Rotate:
{ {
#if ENABLE_EXTENDED_SELECTION #if ENABLE_EXTENDED_SELECTION
m_regenerate_volumes = false;
_on_rotate(); _on_rotate();
#else #else
post_event(Vec3dEvent(EVT_GIZMO_ROTATE, m_gizmos.get_rotation())); post_event(Vec3dEvent(EVT_GIZMO_ROTATE, m_gizmos.get_rotation()));

View File

@ -4,6 +4,7 @@
#include <wx/bitmap.h> #include <wx/bitmap.h>
#include <wx/dataview.h> #include <wx/dataview.h>
#include <map> #include <map>
#include <vector>
class wxBoxSizer; class wxBoxSizer;
class PrusaObjectDataViewModel; class PrusaObjectDataViewModel;

View File

@ -28,6 +28,7 @@ CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
auto* sizer = new wxBoxSizer(wxHORIZONTAL); auto* sizer = new wxBoxSizer(wxHORIZONTAL);
cbox = new wxCheckBox(this, wxID_ANY, checkbox_label); cbox = new wxCheckBox(this, wxID_ANY, checkbox_label);
cbox->SetValue(true);
sizer->AddSpacer(5); sizer->AddSpacer(5);
sizer->Add(this->cbox, 0, wxEXPAND | wxALL, 5); sizer->Add(this->cbox, 0, wxEXPAND | wxALL, 5);
SetSizer(sizer); SetSizer(sizer);

View File

@ -296,11 +296,11 @@ void MainFrame::init_menubar()
if (m_plater) { if (m_plater) {
m_plater_menu = new wxMenu(); m_plater_menu = new wxMenu();
append_menu_item(m_plater_menu, wxID_ANY, _(L("Export G-code...")), _(L("Export current plate as G-code")), 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")), 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")), 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")), 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"); [this](wxCommandEvent&){ m_plater->export_3mf(); }, "brick_go.png");
} }

View File

@ -388,24 +388,32 @@ void ConfigOptionsGroup::reload_config(){
} }
bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) { bool ConfigOptionsGroup::update_visibility(ConfigOptionMode mode) {
if (m_options_mode.empty())
return true;
if (m_grid_sizer->GetEffectiveRowsCount() != m_options_mode.size() && if (m_grid_sizer->GetEffectiveRowsCount() != m_options_mode.size() &&
m_options_mode.size() == 1) m_options_mode.size() == 1)
return m_options_mode[0] <= mode; return m_options_mode[0] <= mode;
sizer->ShowItems(true); sizer->ShowItems(true);
#ifdef __WXGTK__
m_panel->Show(true);
m_grid_sizer->Show(true);
#endif /* __WXGTK__ */
int coef = 0; int coef = 0;
int hidden_row_cnt = 0;
const int cols = m_grid_sizer->GetCols(); const int cols = m_grid_sizer->GetCols();
for (auto opt_mode : m_options_mode) { for (auto opt_mode : m_options_mode) {
const bool show = opt_mode <= mode; const bool show = opt_mode <= mode;
if (!show) { if (!show) {
hidden_row_cnt++;
for (int i = 0; i < cols; ++i) for (int i = 0; i < cols; ++i)
m_grid_sizer->Show(coef + i, show); m_grid_sizer->Show(coef + i, show);
} }
coef+= cols; coef+= cols;
} }
if (!sizer->IsShown(m_grid_sizer)) { if (hidden_row_cnt == m_options_mode.size()) {
sizer->ShowItems(false); sizer->ShowItems(false);
return false; return false;
} }

View File

@ -700,7 +700,7 @@ private:
static const std::regex pattern_drop; 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) bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames)
{ {
@ -850,13 +850,15 @@ private:
bool layers_height_allowed() const; bool layers_height_allowed() const;
bool can_delete_all() const; bool can_delete_all() const;
bool can_arrange() const; bool can_arrange() const;
#if ENABLE_MIRROR
bool can_mirror() const; bool can_mirror() const;
#endif // ENABLE_MIRROR
#endif // ENABLE_EXTENDED_SELECTION #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_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_3mf(".*3mf", std::regex::icase);
const std::regex Plater::priv::pattern_zip_amf("[.]zip[.]amf$", std::regex::icase); const std::regex Plater::priv::pattern_zip_amf(".*[.]zip[.]amf", std::regex::icase);
Plater::priv::priv(Plater *q, MainFrame *main_frame) : Plater::priv::priv(Plater *q, MainFrame *main_frame) :
q(q), q(q),
@ -1258,7 +1260,8 @@ std::unique_ptr<CheckboxFileDialog> Plater::priv::get_export_file(GUI::FileType
case FT_STL: case FT_STL:
case FT_AMF: case FT_AMF:
case FT_3MF: case FT_3MF:
wildcard = file_wildcards[FT_STL]; case FT_GCODE:
wildcard = file_wildcards[file_type];
break; break;
default: default:
@ -1362,7 +1365,7 @@ void Plater::priv::selection_changed()
_3DScene::enable_toolbar_item(canvas3D, "split", have_sel); _3DScene::enable_toolbar_item(canvas3D, "split", have_sel);
_3DScene::enable_toolbar_item(canvas3D, "cut", have_sel); _3DScene::enable_toolbar_item(canvas3D, "cut", have_sel);
_3DScene::enable_toolbar_item(canvas3D, "settings", 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 #endif // ENABLE_EXTENDED_SELECTION
#if 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 // Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false); preview->set_enabled(false);
if (_3DScene::is_layers_editing_enabled(canvas3D))
_3DScene::enable_layers_editing(canvas3D, false);
#if !ENABLE_EXTENDED_SELECTION #if !ENABLE_EXTENDED_SELECTION
objects.erase(objects.begin() + obj_idx); objects.erase(objects.begin() + obj_idx);
#endif // !ENABLE_EXTENDED_SELECTION #endif // !ENABLE_EXTENDED_SELECTION
@ -1497,6 +1503,9 @@ void Plater::priv::reset()
// Prevent toolpaths preview from rendering while we modify the Print object // Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false); preview->set_enabled(false);
if (_3DScene::is_layers_editing_enabled(canvas3D))
_3DScene::enable_layers_editing(canvas3D, false);
#if !ENABLE_EXTENDED_SELECTION #if !ENABLE_EXTENDED_SELECTION
objects.clear(); objects.clear();
#endif // !ENABLE_EXTENDED_SELECTION #endif // !ENABLE_EXTENDED_SELECTION
@ -1774,7 +1783,10 @@ void Plater::priv::on_action_settings(SimpleEvent&)
void Plater::priv::on_action_layersediting(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 #if !ENABLE_EXTENDED_SELECTION
@ -1899,6 +1911,7 @@ bool Plater::priv::init_object_menu()
object_menu.AppendSeparator(); object_menu.AppendSeparator();
#if ENABLE_MIRROR
wxMenu* mirror_menu = new wxMenu(); wxMenu* mirror_menu = new wxMenu();
if (mirror_menu == nullptr) if (mirror_menu == nullptr)
return false; return false;
@ -1911,6 +1924,7 @@ bool Plater::priv::init_object_menu()
[this](wxCommandEvent&){ mirror(Z); }, "bullet_blue.png", &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"))); 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")), 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"); [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 // ui updates needs to be binded to the parent panel
if (q != nullptr) if (q != nullptr)
{ {
#if ENABLE_MIRROR
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_mirror()); }, item_mirror->GetId()); 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_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_increase_instances()); }, item_increase->GetId());
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_decrease_instances()); }, item_decrease->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 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 bool Plater::priv::can_delete_all() const
@ -1976,10 +1993,12 @@ bool Plater::priv::can_arrange() const
return !model.objects.empty(); return !model.objects.empty();
} }
#if ENABLE_MIRROR
bool Plater::priv::can_mirror() const bool Plater::priv::can_mirror() const
{ {
return get_selection().is_from_single_instance(); return get_selection().is_from_single_instance();
} }
#endif // ENABLE_MIRROR
#endif // ENABLE_EXTENDED_SELECTION #endif // ENABLE_EXTENDED_SELECTION
// Plater / Public // Plater / Public

View File

@ -476,7 +476,7 @@ void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool
void Tab::update_changed_tree_ui() void Tab::update_changed_tree_ui()
{ {
auto cur_item = m_treectrl->GetFirstVisibleItem(); auto cur_item = m_treectrl->GetFirstVisibleItem();
if (!m_treectrl->IsVisible(cur_item)) if (!cur_item || !m_treectrl->IsVisible(cur_item))
return; return;
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
while (cur_item){ while (cur_item){
@ -644,6 +644,11 @@ void Tab::update_visibility(ConfigOptionMode mode)
Refresh(); Refresh();
Thaw(); 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 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 page = add_options_page(_(L("General")), "printer_empty.png");
auto optgroup = page->new_optgroup(_(L("Size and coordinates"))); 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){ line.widget = [this](wxWindow* parent){
auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
// btn->SetFont(Slic3r::GUI::small_font); // btn->SetFont(Slic3r::GUI::small_font);
@ -2762,8 +2767,8 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la
bmp_name = "error.png"; bmp_name = "error.png";
else { else {
auto mode = line.get_options()[0].opt.mode; //we assume that we have one option per line auto mode = line.get_options()[0].opt.mode; //we assume that we have one option per line
bmp_name = mode == comExpert ? "mode_expert.png" : bmp_name = mode == comExpert ? "mode_expert_.png" :
mode == comMiddle ? "mode_middle.png" : "mode_simple.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)); auto bmp = new wxStaticBitmap(parent, wxID_ANY, wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG));
return bmp; return bmp;

View File

@ -12,6 +12,7 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <functional>
wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, 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); std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr);