Fixed conflicts after merge with master

This commit is contained in:
Enrico Turri 2019-05-24 15:29:22 +02:00
commit efe29b3c2d
13 changed files with 1581 additions and 1934 deletions

File diff suppressed because it is too large Load diff

View file

@ -247,7 +247,10 @@ namespace Slic3r {
struct CurrentObject
{
// ID of the object inside the 3MF file, 1 based.
int id;
// Index of the ModelObject in its respective Model, zero based.
int model_object_idx;
Geometry geometry;
ModelObject* object;
ComponentsList components;
@ -260,6 +263,7 @@ namespace Slic3r {
void reset()
{
id = -1;
model_object_idx = -1;
geometry.reset();
object = nullptr;
components.clear();
@ -319,7 +323,8 @@ namespace Slic3r {
VolumeMetadataList volumes;
};
typedef std::map<int, ModelObject*> IdToModelObjectMap;
// Map from a 1 based 3MF object ID to a 0 based ModelObject index inside m_model->objects.
typedef std::map<int, int> IdToModelObjectMap;
typedef std::map<int, ComponentsList> IdToAliasesMap;
typedef std::vector<Instance> InstancesList;
typedef std::map<int, ObjectMetadata> IdToMetadataMap;
@ -572,6 +577,7 @@ namespace Slic3r {
for (const IdToModelObjectMap::value_type& object : m_objects)
{
ModelObject *model_object = m_model->objects[object.second];
ObjectMetadata::VolumeMetadataList volumes;
ObjectMetadata::VolumeMetadataList* volumes_ptr = nullptr;
@ -582,14 +588,16 @@ namespace Slic3r {
return false;
}
IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.first);
// m_layer_heights_profiles are indexed by a 1 based model object index.
IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.second + 1);
if (obj_layer_heights_profile != m_layer_heights_profiles.end())
object.second->layer_height_profile = obj_layer_heights_profile->second;
model_object->layer_height_profile = obj_layer_heights_profile->second;
IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.first);
// m_sla_support_points are indexed by a 1 based model object index.
IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.second + 1);
if (obj_sla_support_points != m_sla_support_points.end() && !obj_sla_support_points->second.empty()) {
object.second->sla_support_points = obj_sla_support_points->second;
object.second->sla_points_status = sla::PointsStatus::UserModified;
model_object->sla_support_points = obj_sla_support_points->second;
model_object->sla_points_status = sla::PointsStatus::UserModified;
}
IdToMetadataMap::iterator obj_metadata = m_objects_metadata.find(object.first);
@ -601,9 +609,9 @@ namespace Slic3r {
for (const Metadata& metadata : obj_metadata->second.metadata)
{
if (metadata.key == "name")
object.second->name = metadata.value;
model_object->name = metadata.value;
else
object.second->config.set_deserialize(metadata.key, metadata.value);
model_object->config.set_deserialize(metadata.key, metadata.value);
}
// select object's detected volumes
@ -620,7 +628,7 @@ namespace Slic3r {
volumes_ptr = &volumes;
}
if (!_generate_volumes(*object.second, obj_geometry->second, *volumes_ptr))
if (!_generate_volumes(*model_object, obj_geometry->second, *volumes_ptr))
return false;
}
@ -828,19 +836,20 @@ namespace Slic3r {
if (version == 0) {
for (unsigned int i=0; i<object_data_points.size(); i+=3)
sla_support_points.emplace_back(std::atof(object_data_points[i+0].c_str()),
std::atof(object_data_points[i+1].c_str()),
std::atof(object_data_points[i+2].c_str()),
sla_support_points.emplace_back(float(std::atof(object_data_points[i+0].c_str())),
float(std::atof(object_data_points[i+1].c_str())),
float(std::atof(object_data_points[i+2].c_str())),
0.4f,
false);
}
if (version == 1) {
for (unsigned int i=0; i<object_data_points.size(); i+=5)
sla_support_points.emplace_back(std::atof(object_data_points[i+0].c_str()),
std::atof(object_data_points[i+1].c_str()),
std::atof(object_data_points[i+2].c_str()),
std::atof(object_data_points[i+3].c_str()),
std::atof(object_data_points[i+4].c_str()));
sla_support_points.emplace_back(float(std::atof(object_data_points[i+0].c_str())),
float(std::atof(object_data_points[i+1].c_str())),
float(std::atof(object_data_points[i+2].c_str())),
float(std::atof(object_data_points[i+3].c_str())),
//FIXME storing boolean as 0 / 1 and importing it as float.
std::abs(std::atof(object_data_points[i+4].c_str()) - 1.) < EPSILON);
}
if (!sla_support_points.empty())
@ -1029,8 +1038,9 @@ namespace Slic3r {
// deletes all non-built or non-instanced objects
for (const IdToModelObjectMap::value_type& object : m_objects)
{
if ((object.second != nullptr) && (object.second->instances.size() == 0))
m_model->delete_object(object.second);
ModelObject *model_object = m_model->objects[object.second];
if ((model_object != nullptr) && (model_object->instances.size() == 0))
m_model->delete_object(model_object);
}
// applies instances' matrices
@ -1070,6 +1080,7 @@ namespace Slic3r {
if (is_valid_object_type(get_attribute_value_string(attributes, num_attributes, TYPE_ATTR)))
{
// create new object (it may be removed later if no instances are generated from it)
m_curr_object.model_object_idx = (int)m_model->objects.size();
m_curr_object.object = m_model->add_object();
if (m_curr_object.object == nullptr)
{
@ -1121,7 +1132,7 @@ namespace Slic3r {
// stores the object for later use
if (m_objects.find(m_curr_object.id) == m_objects.end())
{
m_objects.insert(IdToModelObjectMap::value_type(m_curr_object.id, m_curr_object.object));
m_objects.insert(IdToModelObjectMap::value_type(m_curr_object.id, m_curr_object.model_object_idx));
m_objects_aliases.insert(IdToAliasesMap::value_type(m_curr_object.id, ComponentsList(1, Component(m_curr_object.id)))); // aliases itself
}
else
@ -1328,14 +1339,14 @@ namespace Slic3r {
// aliasing to itself
IdToModelObjectMap::iterator object_item = m_objects.find(object_id);
if ((object_item == m_objects.end()) || (object_item->second == nullptr))
if ((object_item == m_objects.end()) || (object_item->second == -1))
{
add_error("Found invalid object");
return false;
}
else
{
ModelInstance* instance = object_item->second->add_instance();
ModelInstance* instance = m_model->objects[object_item->second]->add_instance();
if (instance == nullptr)
{
add_error("Unable to add object instance");
@ -1600,8 +1611,6 @@ namespace Slic3r {
typedef std::vector<BuildItem> BuildItemsList;
typedef std::map<int, ObjectData> IdToObjectDataMap;
IdToObjectDataMap m_objects_data;
public:
bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config);
@ -1609,14 +1618,14 @@ namespace Slic3r {
bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config);
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
bool _add_model_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data);
bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets);
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items);
bool _add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_sla_support_points_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config);
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model);
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data);
};
bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config)
@ -1630,8 +1639,6 @@ namespace Slic3r {
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
m_objects_data.clear();
mz_bool res = mz_zip_writer_init_file(&archive, filename.c_str(), 0);
if (res == 0)
{
@ -1639,7 +1646,8 @@ namespace Slic3r {
return false;
}
// adds content types file
// Adds content types file ("[Content_Types].xml";).
// The content of this file is the same for each PrusaSlicer 3mf.
if (!_add_content_types_file_to_archive(archive))
{
mz_zip_writer_end(&archive);
@ -1647,7 +1655,9 @@ namespace Slic3r {
return false;
}
// adds relationships file
// 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))
{
mz_zip_writer_end(&archive);
@ -1655,15 +1665,19 @@ namespace Slic3r {
return false;
}
// adds model file
if (!_add_model_file_to_archive(archive, model))
// Adds model file ("3D/3dmodel.model").
// This is the one and only file that contains all the geometry (vertices and triangles) of all ModelVolumes.
IdToObjectDataMap objects_data;
if (!_add_model_file_to_archive(archive, model, objects_data))
{
mz_zip_writer_end(&archive);
boost::filesystem::remove(filename);
return false;
}
// adds layer height profile file
// Adds layer height profile file ("Metadata/Slic3r_PE_layer_heights_profile.txt").
// All layer height profiles of all ModelObjects are stored here, indexed by 1 based index of the ModelObject in Model.
// The index differes from the index of an object ID of an object instance of a 3MF file!
if (!_add_layer_height_profile_file_to_archive(archive, model))
{
mz_zip_writer_end(&archive);
@ -1671,7 +1685,9 @@ namespace Slic3r {
return false;
}
// adds sla support points file
// Adds sla support points file ("Metadata/Slic3r_PE_sla_support_points.txt").
// All sla support points of all ModelObjects are stored here, indexed by 1 based index of the ModelObject in Model.
// The index differes from the index of an object ID of an object instance of a 3MF file!
if (!_add_sla_support_points_file_to_archive(archive, model))
{
mz_zip_writer_end(&archive);
@ -1679,7 +1695,8 @@ namespace Slic3r {
return false;
}
// adds slic3r print config file
// Adds slic3r print config file ("Metadata/Slic3r_PE.config").
// This file contains the content of FullPrintConfing / SLAFullPrintConfig.
if (config != nullptr)
{
if (!_add_print_config_file_to_archive(archive, *config))
@ -1690,8 +1707,11 @@ namespace Slic3r {
}
}
// adds slic3r model config file
if (!_add_model_config_file_to_archive(archive, model))
// Adds slic3r model config file ("Metadata/Slic3r_PE_model.config").
// This file contains all the attributes of all ModelObjects and their ModelVolumes (names, parameter overrides).
// As there is just a single Indexed Triangle Set data stored per ModelObject, offsets of volumes into their respective Indexed Triangle Set data
// is stored here as well.
if (!_add_model_config_file_to_archive(archive, model, objects_data))
{
mz_zip_writer_end(&archive);
boost::filesystem::remove(filename);
@ -1750,7 +1770,7 @@ namespace Slic3r {
return true;
}
bool _3MF_Exporter::_add_model_file_to_archive(mz_zip_archive& archive, Model& model)
bool _3MF_Exporter::_add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data)
{
std::stringstream stream;
// https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
@ -1763,17 +1783,24 @@ namespace Slic3r {
stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "</" << METADATA_TAG << ">\n";
stream << " <" << RESOURCES_TAG << ">\n";
// Instance transformations, indexed by the 3MF object ID (which is a linear serialization of all instances of all ModelObjects).
BuildItemsList build_items;
// The object_id here is a one based identifier of the first instance of a ModelObject in the 3MF file, where
// all the object instances of all ModelObjects are stored and indexed in a 1 based linear fashion.
// Therefore the list of object_ids here may not be continuous.
unsigned int object_id = 1;
for (ModelObject* obj : model.objects)
{
if (obj == nullptr)
continue;
// Index of an object in the 3MF file corresponding to the 1st instance of a ModelObject.
unsigned int curr_id = object_id;
IdToObjectDataMap::iterator object_it = m_objects_data.insert(IdToObjectDataMap::value_type(curr_id, ObjectData(obj))).first;
IdToObjectDataMap::iterator object_it = objects_data.insert(IdToObjectDataMap::value_type(curr_id, ObjectData(obj))).first;
// Store geometry of all ModelVolumes contained in a single ModelObject into a single 3MF indexed triangle set object.
// object_it->second.volumes_offsets will contain the offsets of the ModelVolumes in that single indexed triangle set.
// object_id will be increased to point to the 1st instance of the next ModelObject.
if (!_add_object_to_model_stream(stream, object_id, *obj, build_items, object_it->second.volumes_offsets))
{
add_error("Unable to add object to archive");
@ -1783,6 +1810,7 @@ namespace Slic3r {
stream << " </" << RESOURCES_TAG << ">\n";
// Store the transformations of all the ModelInstances of all ModelObjects, indexed in a linear fashion.
if (!_add_build_to_model_stream(stream, build_items))
{
add_error("Unable to add build to archive");
@ -1807,6 +1835,7 @@ namespace Slic3r {
unsigned int id = 0;
for (const ModelInstance* instance : object.instances)
{
assert(instance != nullptr);
if (instance == nullptr)
continue;
@ -1829,6 +1858,8 @@ namespace Slic3r {
}
Transform3d t = instance->get_matrix();
// instance_id is just a 1 indexed index in build_items.
assert(instance_id == build_items.size() + 1);
build_items.emplace_back(instance_id, t);
stream << " </" << OBJECT_TAG << ">\n";
@ -2045,13 +2076,13 @@ namespace Slic3r {
return true;
}
bool _3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model)
bool _3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data)
{
std::stringstream stream;
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
stream << "<" << CONFIG_TAG << ">\n";
for (const IdToObjectDataMap::value_type& obj_metadata : m_objects_data)
for (const IdToObjectDataMap::value_type& obj_metadata : objects_data)
{
const ModelObject* obj = obj_metadata.second.object;
if (obj != nullptr)

View file

@ -52,7 +52,4 @@
// Enable texture max size to be dependent on detected OpenGL version
#define ENABLE_TEXTURES_MAXSIZE_DEPENDENT_ON_OPENGL_VERSION 1
// Enable scale object to fit print volume
#define ENABLE_SCALE_TO_FIT_PRINT_VOLUME 1
#endif // _technologies_h_

View file

@ -2047,7 +2047,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if (it->new_geometry())
instances[istep].emplace_back(std::pair<size_t, size_t>(instance_idx, print_instance_idx));
else
// Recycling an old GLVolume. Update the Object/Instance indices into the current Model.
// Recycling an old GLVolume. Update the Object/Instance indices into the current Model.
m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx);
}
}
@ -5523,6 +5523,7 @@ void GLCanvas3D::_load_sla_shells()
v.set_instance_offset(unscale(instance.shift(0), instance.shift(1), 0));
v.set_instance_rotation(Vec3d(0.0, 0.0, (double)instance.rotation));
v.set_instance_mirror(X, object.is_left_handed() ? -1. : 1.);
v.set_convex_hull(new TriangleMesh(std::move(mesh.convex_hull_3d())), true);
};
// adds objects' volumes
@ -5537,7 +5538,7 @@ void GLCanvas3D::_load_sla_shells()
if (obj->is_step_done(slaposSupportTree) && obj->has_mesh(slaposSupportTree))
add_volume(*obj, -int(slaposSupportTree), instance, obj->support_mesh(), GLVolume::SLA_SUPPORT_COLOR, true);
if (obj->is_step_done(slaposBasePool) && obj->has_mesh(slaposBasePool))
add_volume(*obj, -int(slaposBasePool), instance, obj->pad_mesh(), GLVolume::SLA_PAD_COLOR, true);
add_volume(*obj, -int(slaposBasePool), instance, obj->pad_mesh(), GLVolume::SLA_PAD_COLOR, false);
}
double shift_z = obj->get_current_elevation();
for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++ i) {
@ -5660,7 +5661,7 @@ void GLCanvas3D::_update_sla_shells_outside_state()
for (GLVolume* volume : m_volumes.volumes)
{
volume->is_outside = ((print_volume.radius() > 0.0) && volume->is_sla_support()) ? !print_volume.contains(volume->transformed_convex_hull_bounding_box()) : false;
volume->is_outside = ((print_volume.radius() > 0.0) && volume->shader_outside_printer_detection_enabled) ? !print_volume.contains(volume->transformed_convex_hull_bounding_box()) : false;
}
}

View file

@ -1284,13 +1284,11 @@ void ObjectList::append_menu_item_delete(wxMenu* menu)
[this](wxCommandEvent&) { remove(); }, "", menu);
}
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void ObjectList::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu)
{
append_menu_item(menu, wxID_ANY, _(L("Scale to print volume")), _(L("Scale the selected object to fit the print volume")),
[this](wxCommandEvent&) { wxGetApp().plater()->scale_selection_to_fit_print_volume(); }, "", menu);
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void ObjectList::create_object_popupmenu(wxMenu *menu)
{
@ -1300,9 +1298,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
append_menu_item_export_stl(menu);
append_menu_item_fix_through_netfabb(menu);
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
append_menu_item_scale_selection_to_fit_print_volume(menu);
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
// Split object to parts
m_menu_item_split = append_menu_item_split(menu);

View file

@ -207,9 +207,7 @@ public:
void append_menu_item_export_stl(wxMenu* menu) const ;
void append_menu_item_change_extruder(wxMenu* menu) const;
void append_menu_item_delete(wxMenu* menu);
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu);
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void create_object_popupmenu(wxMenu *menu);
void create_sla_object_popupmenu(wxMenu*menu);
void create_part_popupmenu(wxMenu*menu);

View file

@ -847,7 +847,6 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas)
break;
}
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
case 'F':
case 'f':
{
@ -861,7 +860,6 @@ bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas)
break;
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
}
}

View file

@ -1302,9 +1302,7 @@ struct Plater::priv
void sla_optimize_rotation();
void split_object();
void split_volume();
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void scale_selection_to_fit_print_volume();
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
bool background_processing_enabled() const { return this->get_config("background_processing") == "1"; }
void update_print_volume_state();
void schedule_background_process();
@ -2367,12 +2365,10 @@ void Plater::priv::split_volume()
wxGetApp().obj_list()->split();
}
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Plater::priv::scale_selection_to_fit_print_volume()
{
this->view3D->get_canvas3d()->get_selection().scale_to_fit_print_volume(*config);
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Plater::priv::schedule_background_process()
{
@ -3036,9 +3032,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu);
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
sidebar->obj_list()->append_menu_item_scale_selection_to_fit_print_volume(menu);
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
wxMenu* mirror_menu = new wxMenu();
if (mirror_menu == nullptr)
@ -3479,12 +3473,10 @@ bool Plater::is_selection_empty() const
return p->get_selection().is_empty() || p->get_selection().is_wipe_tower();
}
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Plater::scale_selection_to_fit_print_volume()
{
p->scale_selection_to_fit_print_volume();
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper, bool keep_lower, bool rotate_lower)
{

View file

@ -162,9 +162,7 @@ public:
void decrease_instances(size_t num = 1);
void set_number_of_copies(/*size_t num*/);
bool is_selection_empty() const;
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void scale_selection_to_fit_print_volume();
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_upper = true, bool keep_lower = true, bool rotate_lower = false);

View file

@ -662,7 +662,6 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
{
GLVolume &volume = *(*m_volumes)[i];
if (is_single_full_instance()) {
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
if (transformation_type.relative())
{
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
@ -676,9 +675,6 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
}
else
{
#else
assert(transformation_type.absolute());
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
// This is only possible, if the instance rotation is mulitples of ninety degrees.
@ -687,9 +683,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
}
else
volume.set_instance_scaling_factor(scale);
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
}
else if (is_single_volume() || is_single_modifier())
volume.set_volume_scaling_factor(scale);
@ -733,7 +727,6 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
this->set_bounding_boxes_dirty();
}
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config)
{
if (is_empty() || (m_mode == Volume))
@ -776,7 +769,6 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config)
}
}
}
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void Selection::mirror(Axis axis)
{

View file

@ -287,9 +287,7 @@ public:
void rotate(const Vec3d& rotation, TransformationType transformation_type);
void flattening_rotate(const Vec3d& normal);
void scale(const Vec3d& scale, TransformationType transformation_type);
#if ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void scale_to_fit_print_volume(const DynamicPrintConfig& config);
#endif // ENABLE_SCALE_TO_FIT_PRINT_VOLUME
void mirror(Axis axis);
void translate(unsigned int object_idx, const Vec3d& displacement);

View file

@ -2234,6 +2234,18 @@ void TabPrinter::build_unregular_pages()
* */
Freeze();
#ifdef __WXMSW__
/* Workaround for correct layout of controls inside the created page:
* In some _strange_ way we should we should imitate page resizing.
*/
auto layout_page = [this](PageShp page)
{
const wxSize& sz = page->GetSize();
page->SetSize(sz.x + 1, sz.y + 1);
page->SetSize(sz);
};
#endif //__WXMSW__
// Add/delete Kinematics page according to is_marlin_flavor
size_t existed_page = 0;
for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
@ -2247,6 +2259,9 @@ void TabPrinter::build_unregular_pages()
if (existed_page < n_before_extruders && is_marlin_flavor) {
auto page = build_kinematics_page();
#ifdef __WXMSW__
layout_page(page);
#endif
m_pages.insert(m_pages.begin() + n_before_extruders, page);
}
@ -2318,6 +2333,10 @@ void TabPrinter::build_unregular_pages()
optgroup = page->new_optgroup(_(L("Preview")));
optgroup->append_single_option_line("extruder_colour", extruder_idx);
#ifdef __WXMSW__
layout_page(page);
#endif
}
// # remove extra pages