Merge branch 'master' of https://github.com/Prusa3d/Slic3r
This commit is contained in:
commit
9722bcdd75
@ -661,6 +661,23 @@ void ModelObject::delete_volume(size_t idx)
|
||||
ModelVolumePtrs::iterator i = this->volumes.begin() + idx;
|
||||
delete *i;
|
||||
this->volumes.erase(i);
|
||||
|
||||
if (this->volumes.size() == 1)
|
||||
{
|
||||
// only one volume left
|
||||
// center it and update the instances accordingly
|
||||
// rationale: the volume may be shifted with respect to the object center and this may lead to wrong rotation and scaling
|
||||
// when modifying the instance matrix of the derived GLVolume
|
||||
ModelVolume* v = this->volumes.front();
|
||||
v->center_geometry();
|
||||
const Vec3d& vol_offset = v->get_offset();
|
||||
for (ModelInstance* inst : this->instances)
|
||||
{
|
||||
inst->set_offset(inst->get_offset() + inst->get_matrix(true) * vol_offset);
|
||||
}
|
||||
v->set_offset(Vec3d::Zero());
|
||||
}
|
||||
|
||||
this->invalidate_bounding_box();
|
||||
}
|
||||
|
||||
|
@ -2471,15 +2471,6 @@ void PrintConfigDef::init_sla_params()
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(0.2);
|
||||
|
||||
def = this->add("support_head_back_radius", coFloat);
|
||||
def->label = L("Support head back radius");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("Radius of the back side of the 3d arrow");
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(0.5);
|
||||
|
||||
def = this->add("support_head_width", coFloat);
|
||||
def->label = L("Support head width");
|
||||
def->category = L("Supports");
|
||||
@ -2496,7 +2487,19 @@ void PrintConfigDef::init_sla_params()
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(0.8);
|
||||
def->default_value = new ConfigOptionFloat(0.5);
|
||||
|
||||
def = this->add("support_pillar_widening_factor", coFloat);
|
||||
def->label = L("Pillar widening factor");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("Merging bridges or pillars into another pillars can "
|
||||
"increase the radius. Zero means no increase, one means "
|
||||
"full increase.");
|
||||
def->sidetext = L("");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
def->max = 1.0;
|
||||
def->default_value = new ConfigOptionFloat(0.0);
|
||||
|
||||
def = this->add("support_base_radius", coFloat);
|
||||
def->label = L("Support base radius");
|
||||
|
@ -913,20 +913,18 @@ public:
|
||||
// How much the pinhead has to penetrate the model surface
|
||||
ConfigOptionFloat support_head_penetration /*= 0.2*/;
|
||||
|
||||
// Radius of the back side of the 3d arrow. TODO: consider renaming this
|
||||
// to actual pillar radius, because that's what it boils down to.
|
||||
ConfigOptionFloat support_head_back_radius /*= 0.5*/;
|
||||
|
||||
// Width in mm from the back sphere center to the front sphere center.
|
||||
ConfigOptionFloat support_head_width /*= 1.0*/;
|
||||
|
||||
// Radius in mm of the support pillars.
|
||||
// TODO: This parameter is questionable. The pillar radius will be dynamic in
|
||||
// nature. Merged pillars will have an increased thickness. This parameter
|
||||
// may serve as the maximum radius, or maybe an increase when two are merged
|
||||
// The default radius will be derived from head_back_radius_mm
|
||||
ConfigOptionFloat support_pillar_radius /*= 0.8*/;
|
||||
|
||||
// TODO: unimplemented at the moment. This coefficient will have an impact
|
||||
// when bridges and pillars are merged. The resulting pillar should be a bit
|
||||
// thicker than the ones merging into it. How much thicker? I don't know
|
||||
// but it will be derived from this value.
|
||||
ConfigOptionFloat support_pillar_widening_factor;
|
||||
|
||||
// Radius in mm of the pillar base.
|
||||
ConfigOptionFloat support_base_radius /*= 2.0*/;
|
||||
|
||||
@ -968,9 +966,9 @@ protected:
|
||||
OPT_PTR(supports_enable);
|
||||
OPT_PTR(support_head_front_radius);
|
||||
OPT_PTR(support_head_penetration);
|
||||
OPT_PTR(support_head_back_radius);
|
||||
OPT_PTR(support_head_width);
|
||||
OPT_PTR(support_pillar_radius);
|
||||
OPT_PTR(support_pillar_widening_factor);
|
||||
OPT_PTR(support_base_radius);
|
||||
OPT_PTR(support_base_height);
|
||||
OPT_PTR(support_critical_angle);
|
||||
|
@ -309,7 +309,7 @@ struct Head {
|
||||
}
|
||||
|
||||
double request_pillar_radius(double radius) const {
|
||||
const double rmax = r_back_mm /* * 0.65*/ ;
|
||||
const double rmax = r_back_mm;
|
||||
return radius > 0 && radius < rmax ? radius : rmax;
|
||||
}
|
||||
};
|
||||
@ -929,6 +929,9 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
const SupportConfig &cfg,
|
||||
const Controller &ctl)
|
||||
{
|
||||
// If there are no input points there is no point in doing anything
|
||||
if(points.rows() == 0) return false;
|
||||
|
||||
PointSet filtered_points; // all valid support points
|
||||
PointSet head_positions; // support points with pinhead
|
||||
PointSet head_normals; // head normals
|
||||
@ -1183,7 +1186,7 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
|
||||
// If the pillars are so close that they touch each other,
|
||||
// there is no need to bridge them together.
|
||||
if(pillar_dist > 2*cfg.pillar_radius_mm &&
|
||||
if(pillar_dist > 2*cfg.head_back_radius_mm &&
|
||||
bridge_distance < cfg.max_bridge_length_mm)
|
||||
while(sj(Z) > pillar.endpoint(Z) &&
|
||||
ej(Z) > nextpillar.endpoint(Z))
|
||||
@ -1222,7 +1225,7 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
Result& result)
|
||||
{
|
||||
const double hbr = cfg.head_back_radius_mm;
|
||||
const double pradius = cfg.pillar_radius_mm;
|
||||
const double pradius = cfg.head_back_radius_mm;
|
||||
const double maxbridgelen = cfg.max_bridge_length_mm;
|
||||
const double gndlvl = result.ground_level;
|
||||
|
||||
@ -1475,7 +1478,7 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
|
||||
result.add_pillar(idx,
|
||||
Vec3d{headend(X), headend(Y), headend(Z) - gh + hl},
|
||||
cfg.pillar_radius_mm
|
||||
cfg.head_back_radius_mm
|
||||
).base = base_head.mesh;
|
||||
}
|
||||
};
|
||||
@ -1490,7 +1493,7 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
// For now we will just generate smaller headless sticks with a sharp
|
||||
// ending point that connects to the mesh surface.
|
||||
|
||||
const double R = 0.5*cfg.pillar_radius_mm;
|
||||
const double R = cfg.headless_pillar_radius_mm;
|
||||
const double HWIDTH_MM = R/3;
|
||||
|
||||
// We will sink the pins into the model surface for a distance of 1/3 of
|
||||
@ -1619,10 +1622,7 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||
return pc == ABORT;
|
||||
}
|
||||
|
||||
SLASupportTree::SLASupportTree(): m_impl(new Impl())
|
||||
{
|
||||
|
||||
}
|
||||
SLASupportTree::SLASupportTree(): m_impl(new Impl()) {}
|
||||
|
||||
const TriangleMesh &SLASupportTree::merged_mesh() const
|
||||
{
|
||||
|
@ -41,13 +41,16 @@ struct SupportConfig {
|
||||
// Width in mm from the back sphere center to the front sphere center.
|
||||
double head_width_mm = 1.0;
|
||||
|
||||
// Radius in mm of the support pillars.
|
||||
// Warning: this value will be at most 65% of head_back_radius_mm
|
||||
// TODO: This parameter is invalid. The pillar radius will be dynamic in
|
||||
// nature. Merged pillars will have an increased thickness. This parameter
|
||||
// may serve as the maximum radius, or maybe an increase when two are merged
|
||||
// The default radius will be derived from head_back_radius_mm
|
||||
double pillar_radius_mm = 0.8;
|
||||
// Radius in mm of the support pillars. The actual radius of the pillars
|
||||
// beginning with a head will not be higher than head_back_radius but the
|
||||
// headless pillars will have half of this value.
|
||||
double headless_pillar_radius_mm = 0.4;
|
||||
|
||||
// TODO: unimplemented at the moment. This coefficient will have an impact
|
||||
// when bridges and pillars are merged. The resulting pillar should be a bit
|
||||
// thicker than the ones merging into it. How much thicker? I don't know
|
||||
// but it will be derived from this value.
|
||||
double pillar_widening_factor = 0.5;
|
||||
|
||||
// Radius in mm of the pillar base.
|
||||
double base_radius_mm = 2.0;
|
||||
|
@ -84,6 +84,7 @@ size_t SpatIndex::size() const
|
||||
}
|
||||
|
||||
PointSet normals(const PointSet& points, const EigenMesh3D& mesh) {
|
||||
if(points.rows() == 0 || mesh.V.rows() == 0 || mesh.F.rows() == 0) return {};
|
||||
#ifdef IGL_COMPATIBLE
|
||||
Eigen::VectorXd dists;
|
||||
Eigen::VectorXi I;
|
||||
@ -108,7 +109,7 @@ PointSet normals(const PointSet& points, const EigenMesh3D& mesh) {
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
#else // TODO: do something on 32 bit windows
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
@ -458,13 +458,16 @@ void SLAPrint::process()
|
||||
SLAPrintObjectConfig& c = po.m_config;
|
||||
|
||||
scfg.head_front_radius_mm = c.support_head_front_radius.getFloat();
|
||||
scfg.head_back_radius_mm = c.support_head_back_radius.getFloat();
|
||||
scfg.head_back_radius_mm = c.support_pillar_radius.getFloat();
|
||||
scfg.head_penetration_mm = c.support_head_penetration.getFloat();
|
||||
scfg.head_width_mm = c.support_head_width.getFloat();
|
||||
scfg.object_elevation_mm = c.support_object_elevation.getFloat();
|
||||
scfg.tilt = c.support_critical_angle.getFloat() * PI / 180.0 ;
|
||||
scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat();
|
||||
scfg.pillar_radius_mm = c.support_pillar_radius.getFloat();
|
||||
scfg.headless_pillar_radius_mm = 0.75*c.support_pillar_radius.getFloat();
|
||||
scfg.pillar_widening_factor = c.support_pillar_widening_factor.getFloat();
|
||||
scfg.base_radius_mm = c.support_base_radius.getFloat();
|
||||
scfg.base_height_mm = c.support_base_height.getFloat();
|
||||
|
||||
sla::Controller ctl;
|
||||
|
||||
@ -521,11 +524,6 @@ void SLAPrint::process()
|
||||
if(elevation < pad_h) sla::base_plate(trmesh, bp,
|
||||
float(pad_h), float(lh));
|
||||
|
||||
std::cout << "Mesh is empty: " << trmesh.empty() << std::endl;
|
||||
std::cout << "Pad height: " << pad_h << std::endl;
|
||||
std::cout << "Elevation " << elevation << std::endl;
|
||||
std::cout << "Pad plate vertices: " << bp.size() << std::endl;
|
||||
|
||||
po.m_supportdata->support_tree_ptr->add_pad(bp, wt, h, md, er);
|
||||
}
|
||||
};
|
||||
|
@ -1320,10 +1320,12 @@ void GLCanvas3D::Selection::add_all()
|
||||
return;
|
||||
|
||||
m_mode = Instance;
|
||||
clear();
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
||||
{
|
||||
_add_volume(i);
|
||||
if (!(*m_volumes)[i]->is_wipe_tower)
|
||||
_add_volume(i);
|
||||
}
|
||||
|
||||
_update_type();
|
||||
@ -1399,6 +1401,12 @@ bool GLCanvas3D::Selection::is_single_full_instance() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::Selection::is_from_single_object() const
|
||||
{
|
||||
int idx = get_object_idx();
|
||||
return (0 <= idx) && (idx < 1000);
|
||||
}
|
||||
|
||||
int GLCanvas3D::Selection::get_object_idx() const
|
||||
{
|
||||
return (m_cache.content.size() == 1) ? m_cache.content.begin()->first : -1;
|
||||
@ -1455,7 +1463,7 @@ void GLCanvas3D::Selection::translate(const Vec3d& displacement)
|
||||
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
|
||||
else if (m_mode == Volume)
|
||||
{
|
||||
Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_volume_rotation_matrix()).inverse() * displacement;
|
||||
Vec3d local_displacement = m_cache.volumes_data[i].get_instance_rotation_matrix().inverse() * displacement;
|
||||
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
|
||||
}
|
||||
#else
|
||||
@ -1924,9 +1932,17 @@ void GLCanvas3D::Selection::_update_type()
|
||||
unsigned int volumes_count = (unsigned int)model_object->volumes.size();
|
||||
unsigned int instances_count = (unsigned int)model_object->instances.size();
|
||||
if (volumes_count * instances_count == 1)
|
||||
{
|
||||
m_type = SingleFullObject;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
else if (volumes_count == 1) // instances_count > 1
|
||||
{
|
||||
m_type = SingleFullInstance;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = SingleVolume;
|
||||
@ -1950,11 +1966,19 @@ void GLCanvas3D::Selection::_update_type()
|
||||
unsigned int instances_count = (unsigned int)model_object->instances.size();
|
||||
unsigned int selected_instances_count = (unsigned int)m_cache.content.begin()->second.size();
|
||||
if (volumes_count * instances_count == (unsigned int)m_list.size())
|
||||
{
|
||||
m_type = SingleFullObject;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
else if (selected_instances_count == 1)
|
||||
{
|
||||
if (volumes_count == (unsigned int)m_list.size())
|
||||
{
|
||||
m_type = SingleFullInstance;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int modifiers_count = 0;
|
||||
@ -1977,7 +2001,11 @@ void GLCanvas3D::Selection::_update_type()
|
||||
}
|
||||
}
|
||||
else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size()))
|
||||
{
|
||||
m_type = MultipleFullInstance;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1990,7 +2018,11 @@ void GLCanvas3D::Selection::_update_type()
|
||||
sels_cntr += volumes_count * instances_count;
|
||||
}
|
||||
if (sels_cntr == (unsigned int)m_list.size())
|
||||
{
|
||||
m_type = MultipleFullObject;
|
||||
// ensures the correct mode is selected
|
||||
m_mode = Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2002,66 +2034,84 @@ void GLCanvas3D::Selection::_update_type()
|
||||
v->disabled = requires_disable ? (v->object_idx() != object_idx) || (v->instance_idx() != instance_idx) : false;
|
||||
}
|
||||
|
||||
std::cout << "Selection: ";
|
||||
std::cout << "mode: ";
|
||||
switch (m_mode)
|
||||
{
|
||||
case Volume:
|
||||
{
|
||||
std::cout << "Volume";
|
||||
break;
|
||||
}
|
||||
case Instance:
|
||||
{
|
||||
std::cout << "Instance";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << " - type: ";
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case Invalid:
|
||||
{
|
||||
std::cout << "selection type: Invalid" << std::endl;
|
||||
std::cout << "Invalid" << std::endl;
|
||||
break;
|
||||
}
|
||||
case Empty:
|
||||
{
|
||||
std::cout << "selection type: Empty" << std::endl;
|
||||
std::cout << "Empty" << std::endl;
|
||||
break;
|
||||
}
|
||||
case WipeTower:
|
||||
{
|
||||
std::cout << "selection type: WipeTower" << std::endl;
|
||||
std::cout << "WipeTower" << std::endl;
|
||||
break;
|
||||
}
|
||||
case SingleModifier:
|
||||
{
|
||||
std::cout << "selection type: SingleModifier" << std::endl;
|
||||
std::cout << "SingleModifier" << std::endl;
|
||||
break;
|
||||
}
|
||||
case MultipleModifier:
|
||||
{
|
||||
std::cout << "selection type: MultipleModifier" << std::endl;
|
||||
std::cout << "MultipleModifier" << std::endl;
|
||||
break;
|
||||
}
|
||||
case SingleVolume:
|
||||
{
|
||||
std::cout << "selection type: SingleVolume" << std::endl;
|
||||
std::cout << "SingleVolume" << std::endl;
|
||||
break;
|
||||
}
|
||||
case MultipleVolume:
|
||||
{
|
||||
std::cout << "selection type: MultipleVolume" << std::endl;
|
||||
std::cout << "MultipleVolume" << std::endl;
|
||||
break;
|
||||
}
|
||||
case SingleFullObject:
|
||||
{
|
||||
std::cout << "selection type: SingleFullObject" << std::endl;
|
||||
std::cout << "SingleFullObject" << std::endl;
|
||||
break;
|
||||
}
|
||||
case MultipleFullObject:
|
||||
{
|
||||
std::cout << "selection type: MultipleFullObject" << std::endl;
|
||||
std::cout << "MultipleFullObject" << std::endl;
|
||||
break;
|
||||
}
|
||||
case SingleFullInstance:
|
||||
{
|
||||
std::cout << "selection type: SingleFullInstance" << std::endl;
|
||||
std::cout << "SingleFullInstance" << std::endl;
|
||||
break;
|
||||
}
|
||||
case MultipleFullInstance:
|
||||
{
|
||||
std::cout << "selection type: MultipleFullInstance" << std::endl;
|
||||
std::cout << "MultipleFullInstance" << std::endl;
|
||||
break;
|
||||
}
|
||||
case Mixed:
|
||||
{
|
||||
std::cout << "selection type: Mixed" << std::endl;
|
||||
std::cout << "Mixed" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3943,7 +3993,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
int extruder_id = mvs->model_volume->extruder_id();
|
||||
if (extruder_id != -1)
|
||||
volume->extruder_id = extruder_id;
|
||||
}
|
||||
|
||||
// updates volumes transformations
|
||||
volume->set_instance_transformation(mvs->model_volume->get_object()->instances[volume->instance_idx()]->get_transformation());
|
||||
volume->set_volume_transformation(mvs->model_volume->get_transformation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4016,6 +4070,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
size_t idx = 0;
|
||||
const SLAPrint *sla_print = this->sla_print();
|
||||
for (const SLAPrintObject *print_object : sla_print->objects()) {
|
||||
std::cout << "Current elevation: "<< print_object->get_current_elevation() << std::endl;
|
||||
SLASupportState &state = sla_support_state[idx ++];
|
||||
const ModelObject *model_object = print_object->model_object();
|
||||
// Find an index of the ModelObject
|
||||
|
@ -502,7 +502,7 @@ public:
|
||||
bool is_multiple_volume() const { return m_type == MultipleVolume; }
|
||||
bool is_mixed() const { return m_type == Mixed; }
|
||||
bool is_from_single_instance() const { return get_instance_idx() != -1; }
|
||||
bool is_from_single_object() const { return get_object_idx() != -1; }
|
||||
bool is_from_single_object() const;
|
||||
|
||||
bool contains_volume(unsigned int volume_idx) const { return std::find(m_list.begin(), m_list.end(), volume_idx) != m_list.end(); }
|
||||
|
||||
|
@ -333,7 +333,7 @@ void ObjectList::key_event(wxKeyEvent& event)
|
||||
printf("WXK_BACK\n");
|
||||
remove();
|
||||
}
|
||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL))
|
||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
|
||||
select_item_all_children();
|
||||
else
|
||||
event.Skip();
|
||||
@ -1230,7 +1230,8 @@ void ObjectList::delete_from_model_and_list(const std::vector<ItemForDelete>& it
|
||||
m_objects_model->Delete(m_objects_model->GetItemById(item->obj_idx));
|
||||
}
|
||||
else {
|
||||
del_subobject_from_object(item->obj_idx, item->sub_obj_idx, item->type);
|
||||
if (!del_subobject_from_object(item->obj_idx, item->sub_obj_idx, item->type))
|
||||
continue;
|
||||
if (item->type&itVolume)
|
||||
{
|
||||
m_objects_model->Delete(m_objects_model->GetItemByVolumeId(item->obj_idx, item->sub_obj_idx));
|
||||
@ -1305,7 +1306,7 @@ void ObjectList::remove()
|
||||
for (auto& item : sels)
|
||||
{
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0))
|
||||
wxGetApp().plater()->remove(m_objects_model->GetIdByItem(item));
|
||||
delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1);
|
||||
else
|
||||
del_subobject_item(item);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "GUI_ObjectSettings.hpp"
|
||||
#include "GLCanvas3D.hpp"
|
||||
|
||||
class wxStaticText;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
@ -2200,7 +2200,7 @@ bool Plater::priv::init_object_menu()
|
||||
wxMenuItem* item_split = append_submenu(&object_menu, split_menu, wxID_ANY, _(L("Split")), _(L("Split the selected object")), "shape_ungroup.png");
|
||||
|
||||
// Add the automatic rotation sub-menu
|
||||
item_sla_autorot = append_menu_item(&object_menu, wxID_ANY, _(L("Optimize orientation\t+")), _(L("Optimize the rotation of the object for better print results.")),
|
||||
item_sla_autorot = append_menu_item(&object_menu, wxID_ANY, _(L("Optimize orientation")), _(L("Optimize the rotation of the object for better print results.")),
|
||||
[this](wxCommandEvent&) { sla_optimize_rotation(); });
|
||||
|
||||
if(printer_technology == ptFFF) item_sla_autorot = object_menu.Remove(item_sla_autorot);
|
||||
|
@ -405,9 +405,9 @@ const std::vector<std::string>& Preset::sla_print_options()
|
||||
"supports_enable",
|
||||
"support_head_front_radius",
|
||||
"support_head_penetration",
|
||||
"support_head_back_radius",
|
||||
"support_head_width",
|
||||
"support_pillar_radius",
|
||||
"support_pillar_widening_factor",
|
||||
"support_base_radius",
|
||||
"support_base_height",
|
||||
"support_critical_angle",
|
||||
|
@ -3002,12 +3002,12 @@ void TabSLAPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Support head")));
|
||||
optgroup->append_single_option_line("support_head_front_radius");
|
||||
optgroup->append_single_option_line("support_head_back_radius");
|
||||
optgroup->append_single_option_line("support_head_penetration");
|
||||
optgroup->append_single_option_line("support_head_width");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Support pillar")));
|
||||
optgroup->append_single_option_line("support_pillar_radius");
|
||||
optgroup->append_single_option_line("support_pillar_widening_factor");
|
||||
optgroup->append_single_option_line("support_base_radius");
|
||||
optgroup->append_single_option_line("support_base_height");
|
||||
optgroup->append_single_option_line("support_object_elevation");
|
||||
|
@ -410,6 +410,8 @@ bool PrusaObjectDataViewModelNode::update_settings_digest(const std::vector<std:
|
||||
|
||||
for (auto& cat : m_opt_categories)
|
||||
m_name += cat + "; ";
|
||||
if (!m_name.IsEmpty())
|
||||
m_name.erase(m_name.Length()-2, 2); // Delete last "; "
|
||||
|
||||
wxBitmap *bmp = m_bitmap_cache->find(m_name.ToStdString());
|
||||
if (bmp == nullptr) {
|
||||
|
Loading…
Reference in New Issue
Block a user