Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
d0c5ed4130
17 changed files with 158 additions and 79 deletions
|
@ -125,11 +125,11 @@ intermediate files, which are not handled correctly by either `b2.exe` or possib
|
|||
# Noob guide (step by step)
|
||||
|
||||
Install Visual Studio Community 2019 from
|
||||
visualstudio.microsoft.com/vs/
|
||||
[visualstudio.microsoft.com/vs/](https://visualstudio.microsoft.com/vs/)
|
||||
Select all workload options for C++
|
||||
|
||||
Install git for Windows from
|
||||
gitforwindows.org
|
||||
[gitforwindows.org](https://gitforwindows.org/)
|
||||
download and run the exe accepting all defaults
|
||||
|
||||
download PrusaSlicer-master.zip from github
|
||||
|
|
|
@ -1414,6 +1414,8 @@ public:
|
|||
bool multiline = false;
|
||||
// For text input: If true, the GUI text box spans the complete page width.
|
||||
bool full_width = false;
|
||||
// For text input: If true, the GUI formats text as code (fixed-width)
|
||||
bool is_code = false;
|
||||
// Not editable. Currently only used for the display of the number of threads.
|
||||
bool readonly = false;
|
||||
// Height of a multiline GUI text box.
|
||||
|
|
|
@ -1899,9 +1899,9 @@ namespace Slic3r {
|
|||
assert(index < geometry.custom_supports.size());
|
||||
assert(index < geometry.custom_seam.size());
|
||||
if (! geometry.custom_supports[index].empty())
|
||||
volume->m_supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]);
|
||||
volume->supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]);
|
||||
if (! geometry.custom_seam[index].empty())
|
||||
volume->m_seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]);
|
||||
volume->seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2417,11 +2417,11 @@ namespace Slic3r {
|
|||
stream << "v" << j + 1 << "=\"" << its.indices[i][j] + volume_it->second.first_vertex_id << "\" ";
|
||||
}
|
||||
|
||||
std::string custom_supports_data_string = volume->m_supported_facets.get_triangle_as_string(i);
|
||||
std::string custom_supports_data_string = volume->supported_facets.get_triangle_as_string(i);
|
||||
if (! custom_supports_data_string.empty())
|
||||
stream << CUSTOM_SUPPORTS_ATTR << "=\"" << custom_supports_data_string << "\" ";
|
||||
|
||||
std::string custom_seam_data_string = volume->m_seam_facets.get_triangle_as_string(i);
|
||||
std::string custom_seam_data_string = volume->seam_facets.get_triangle_as_string(i);
|
||||
if (! custom_seam_data_string.empty())
|
||||
stream << CUSTOM_SEAM_ATTR << "=\"" << custom_seam_data_string << "\" ";
|
||||
|
||||
|
|
|
@ -608,6 +608,7 @@ void ModelObject::assign_new_unique_ids_recursive()
|
|||
model_volume->assign_new_unique_ids_recursive();
|
||||
for (ModelInstance *model_instance : this->instances)
|
||||
model_instance->assign_new_unique_ids_recursive();
|
||||
this->layer_height_profile.set_new_unique_id();
|
||||
}
|
||||
|
||||
// Clone this ModelObject including its volumes and instances, keep the IDs of the copies equal to the original.
|
||||
|
@ -1041,8 +1042,8 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, bool from_imperial
|
|||
int vol_idx = 0;
|
||||
for (ModelVolume* volume : volumes)
|
||||
{
|
||||
volume->m_supported_facets.clear();
|
||||
volume->m_seam_facets.clear();
|
||||
volume->supported_facets.clear();
|
||||
volume->seam_facets.clear();
|
||||
if (!volume->mesh().empty()) {
|
||||
TriangleMesh mesh(volume->mesh());
|
||||
mesh.require_shared_vertices();
|
||||
|
@ -1147,8 +1148,8 @@ ModelObjectPtrs ModelObject::cut(size_t instance, coordf_t z, bool keep_upper, b
|
|||
for (ModelVolume *volume : volumes) {
|
||||
const auto volume_matrix = volume->get_matrix();
|
||||
|
||||
volume->m_supported_facets.clear();
|
||||
volume->m_seam_facets.clear();
|
||||
volume->supported_facets.clear();
|
||||
volume->seam_facets.clear();
|
||||
|
||||
if (! volume->is_model_part()) {
|
||||
// Modifiers are not cut, but we still need to add the instance transformation
|
||||
|
@ -1727,6 +1728,14 @@ void ModelObject::scale_to_fit(const Vec3d &size)
|
|||
*/
|
||||
}
|
||||
|
||||
void ModelVolume::assign_new_unique_ids_recursive()
|
||||
{
|
||||
ObjectBase::set_new_unique_id();
|
||||
config.set_new_unique_id();
|
||||
supported_facets.set_new_unique_id();
|
||||
seam_facets.set_new_unique_id();
|
||||
}
|
||||
|
||||
void ModelVolume::rotate(double angle, Axis axis)
|
||||
{
|
||||
switch (axis)
|
||||
|
@ -2011,7 +2020,7 @@ bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject
|
|||
assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART));
|
||||
assert(mo.volumes.size() == mo_new.volumes.size());
|
||||
for (size_t i=0; i<mo.volumes.size(); ++i) {
|
||||
if (! mo_new.volumes[i]->m_supported_facets.timestamp_matches(mo.volumes[i]->m_supported_facets))
|
||||
if (! mo_new.volumes[i]->supported_facets.timestamp_matches(mo.volumes[i]->supported_facets))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2021,7 +2030,7 @@ bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo
|
|||
assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART));
|
||||
assert(mo.volumes.size() == mo_new.volumes.size());
|
||||
for (size_t i=0; i<mo.volumes.size(); ++i) {
|
||||
if (! mo_new.volumes[i]->m_seam_facets.timestamp_matches(mo.volumes[i]->m_seam_facets))
|
||||
if (! mo_new.volumes[i]->seam_facets.timestamp_matches(mo.volumes[i]->seam_facets))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
|
||||
private:
|
||||
std::vector<coordf_t> m_data;
|
||||
|
||||
// to access set_new_unique_id() when copy / pasting an object
|
||||
friend class ModelObject;
|
||||
};
|
||||
|
||||
// A printable object, possibly having multiple print volumes (each with its own set of parameters and materials),
|
||||
|
@ -446,6 +449,9 @@ private:
|
|||
}
|
||||
|
||||
std::map<int, std::vector<bool>> m_data;
|
||||
|
||||
// To access set_new_unique_id() when copy / pasting a ModelVolume.
|
||||
friend class ModelVolume;
|
||||
};
|
||||
|
||||
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
|
||||
|
@ -483,10 +489,10 @@ public:
|
|||
ModelConfigObject config;
|
||||
|
||||
// List of mesh facets to be supported/unsupported.
|
||||
FacetsAnnotation m_supported_facets;
|
||||
FacetsAnnotation supported_facets;
|
||||
|
||||
// List of seam enforcers/blockers.
|
||||
FacetsAnnotation m_seam_facets;
|
||||
FacetsAnnotation seam_facets;
|
||||
|
||||
// A parent object owning this modifier volume.
|
||||
ModelObject* get_object() const { return this->object; }
|
||||
|
@ -579,7 +585,7 @@ protected:
|
|||
// Copies IDs of both the ModelVolume and its config.
|
||||
explicit ModelVolume(const ModelVolume &rhs) = default;
|
||||
void set_model_object(ModelObject *model_object) { object = model_object; }
|
||||
void assign_new_unique_ids_recursive() override { ObjectBase::set_new_unique_id(); config.set_new_unique_id(); }
|
||||
void assign_new_unique_ids_recursive() override;
|
||||
void transform_this_mesh(const Transform3d& t, bool fix_left_handed);
|
||||
void transform_this_mesh(const Matrix3d& m, bool fix_left_handed);
|
||||
|
||||
|
@ -617,7 +623,7 @@ private:
|
|||
ObjectBase(other),
|
||||
name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull),
|
||||
config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation),
|
||||
m_supported_facets(other.m_supported_facets), m_seam_facets(other.m_seam_facets)
|
||||
supported_facets(other.supported_facets), seam_facets(other.seam_facets)
|
||||
{
|
||||
assert(this->id().valid()); assert(this->config.id().valid()); assert(this->id() != this->config.id());
|
||||
assert(this->id() == other.id() && this->config.id() == other.config.id());
|
||||
|
@ -635,8 +641,8 @@ private:
|
|||
calculate_convex_hull();
|
||||
assert(this->config.id().valid()); assert(this->config.id() != other.config.id()); assert(this->id() != this->config.id());
|
||||
|
||||
m_supported_facets.clear();
|
||||
m_seam_facets.clear();
|
||||
supported_facets.clear();
|
||||
seam_facets.clear();
|
||||
}
|
||||
|
||||
ModelVolume& operator=(ModelVolume &rhs) = delete;
|
||||
|
@ -650,8 +656,8 @@ private:
|
|||
template<class Archive> void load(Archive &ar) {
|
||||
bool has_convex_hull;
|
||||
ar(name, source, m_mesh, m_type, m_material_id, m_transformation, m_is_splittable, has_convex_hull);
|
||||
cereal::load_by_value(ar, m_supported_facets);
|
||||
cereal::load_by_value(ar, m_seam_facets);
|
||||
cereal::load_by_value(ar, supported_facets);
|
||||
cereal::load_by_value(ar, seam_facets);
|
||||
cereal::load_by_value(ar, config);
|
||||
assert(m_mesh);
|
||||
if (has_convex_hull) {
|
||||
|
@ -665,8 +671,8 @@ private:
|
|||
template<class Archive> void save(Archive &ar) const {
|
||||
bool has_convex_hull = m_convex_hull.get() != nullptr;
|
||||
ar(name, source, m_mesh, m_type, m_material_id, m_transformation, m_is_splittable, has_convex_hull);
|
||||
cereal::save_by_value(ar, m_supported_facets);
|
||||
cereal::save_by_value(ar, m_seam_facets);
|
||||
cereal::save_by_value(ar, supported_facets);
|
||||
cereal::save_by_value(ar, seam_facets);
|
||||
cereal::save_by_value(ar, config);
|
||||
if (has_convex_hull)
|
||||
cereal::save_optional(ar, m_convex_hull);
|
||||
|
|
|
@ -404,10 +404,10 @@ static inline void model_volume_list_copy_configs(ModelObject &model_object_dst,
|
|||
// Copy the ModelVolume data.
|
||||
mv_dst.name = mv_src.name;
|
||||
mv_dst.config.assign_config(mv_src.config);
|
||||
if (! mv_dst.m_supported_facets.timestamp_matches(mv_src.m_supported_facets))
|
||||
mv_dst.m_supported_facets = mv_src.m_supported_facets;
|
||||
if (! mv_dst.m_seam_facets.timestamp_matches(mv_src.m_seam_facets))
|
||||
mv_dst.m_seam_facets = mv_src.m_seam_facets;
|
||||
if (! mv_dst.supported_facets.timestamp_matches(mv_src.supported_facets))
|
||||
mv_dst.supported_facets = mv_src.supported_facets;
|
||||
if (! mv_dst.seam_facets.timestamp_matches(mv_src.seam_facets))
|
||||
mv_dst.seam_facets = mv_src.seam_facets;
|
||||
//FIXME what to do with the materials?
|
||||
// mv_dst.m_material_id = mv_src.m_material_id;
|
||||
++ i_src;
|
||||
|
|
|
@ -2748,8 +2748,8 @@ void PrintObject::project_and_append_custom_facets(
|
|||
{
|
||||
for (const ModelVolume* mv : this->model_object()->volumes) {
|
||||
const indexed_triangle_set custom_facets = seam
|
||||
? mv->m_seam_facets.get_facets(*mv, type)
|
||||
: mv->m_supported_facets.get_facets(*mv, type);
|
||||
? mv->seam_facets.get_facets(*mv, type)
|
||||
: mv->supported_facets.get_facets(*mv, type);
|
||||
if (! mv->is_model_part() || custom_facets.indices.empty())
|
||||
continue;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define ENABLE_2_3_0_ALPHA1 1
|
||||
|
||||
// Enable rendering of objects using environment map
|
||||
#define ENABLE_ENVIRONMENT_MAP (1 && ENABLE_2_3_0_ALPHA1)
|
||||
#define ENABLE_ENVIRONMENT_MAP (0 && ENABLE_2_3_0_ALPHA1)
|
||||
|
||||
// Enable smoothing of objects normals
|
||||
#define ENABLE_SMOOTH_NORMALS (0 && ENABLE_2_3_0_ALPHA1)
|
||||
|
|
|
@ -387,7 +387,9 @@ void TextCtrl::BUILD() {
|
|||
|
||||
const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
|
||||
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);
|
||||
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
temp->SetFont(m_opt.is_code ?
|
||||
Slic3r::GUI::wxGetApp().code_font():
|
||||
Slic3r::GUI::wxGetApp().normal_font());
|
||||
|
||||
if (! m_opt.multiline && !wxOSX)
|
||||
// Only disable background refresh for single line input fields, as they are completely painted over by the edit control.
|
||||
|
|
|
@ -790,7 +790,7 @@ FirmwareDialog::FirmwareDialog(wxWindow *parent) :
|
|||
SetFont(font);
|
||||
wxFont status_font = font;//wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
status_font.MakeBold();
|
||||
wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
|
||||
wxFont mono_font = GUI::wxGetApp().code_font();
|
||||
mono_font.MakeSmaller();
|
||||
|
||||
// Create GUI components and layout
|
||||
|
|
|
@ -325,6 +325,7 @@ bool GCodeViewer::init()
|
|||
|
||||
set_toolpath_move_type_visible(EMoveType::Extrude, true);
|
||||
m_sequential_view.marker.init();
|
||||
m_sequential_view.skip_invisible_moves = true;
|
||||
|
||||
std::array<int, 2> point_sizes;
|
||||
::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data());
|
||||
|
@ -515,18 +516,20 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in
|
|||
unsigned int new_first = first;
|
||||
unsigned int new_last = last;
|
||||
|
||||
while (!is_visible(new_first)) {
|
||||
if (first_diff > 0)
|
||||
++new_first;
|
||||
else
|
||||
--new_first;
|
||||
}
|
||||
if (m_sequential_view.skip_invisible_moves) {
|
||||
while (!is_visible(new_first)) {
|
||||
if (first_diff > 0)
|
||||
++new_first;
|
||||
else
|
||||
--new_first;
|
||||
}
|
||||
|
||||
while (!is_visible(new_last)) {
|
||||
if (last_diff > 0)
|
||||
++new_last;
|
||||
else
|
||||
--new_last;
|
||||
while (!is_visible(new_last)) {
|
||||
if (last_diff > 0)
|
||||
++new_last;
|
||||
else
|
||||
--new_last;
|
||||
}
|
||||
}
|
||||
|
||||
m_sequential_view.current.first = new_first;
|
||||
|
|
|
@ -342,7 +342,7 @@ public:
|
|||
Vec3f m_world_position;
|
||||
Transform3f m_world_transform;
|
||||
float m_z_offset{ 0.5f };
|
||||
std::array<float, 4> m_color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
std::array<float, 4> m_color{ 1.0f, 1.0f, 1.0f, 0.5f };
|
||||
bool m_visible{ false };
|
||||
|
||||
public:
|
||||
|
@ -365,6 +365,7 @@ public:
|
|||
size_t last{ 0 };
|
||||
};
|
||||
|
||||
bool skip_invisible_moves{ false };
|
||||
Endpoints endpoints;
|
||||
Endpoints current;
|
||||
Endpoints last_current;
|
||||
|
|
|
@ -979,6 +979,11 @@ void GUI_App::init_fonts()
|
|||
m_small_font.SetPointSize(11);
|
||||
m_bold_font.SetPointSize(13);
|
||||
#endif /*__WXMAC__*/
|
||||
|
||||
// wxSYS_OEM_FIXED_FONT and wxSYS_ANSI_FIXED_FONT use the same as
|
||||
// DEFAULT in wxGtk. Use the TELETYPE family as a work-around
|
||||
m_code_font = wxFont(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
|
||||
m_code_font.SetPointSize(m_normal_font.GetPointSize());
|
||||
}
|
||||
|
||||
void GUI_App::update_fonts(const MainFrame *main_frame)
|
||||
|
@ -994,6 +999,7 @@ void GUI_App::update_fonts(const MainFrame *main_frame)
|
|||
m_small_font = m_normal_font;
|
||||
m_bold_font = main_frame->normal_font().Bold();
|
||||
m_em_unit = main_frame->em_unit();
|
||||
m_code_font.SetPointSize(m_normal_font.GetPointSize());
|
||||
}
|
||||
|
||||
void GUI_App::set_label_clr_modified(const wxColour& clr) {
|
||||
|
|
|
@ -121,6 +121,7 @@ private:
|
|||
wxFont m_small_font;
|
||||
wxFont m_bold_font;
|
||||
wxFont m_normal_font;
|
||||
wxFont m_code_font;
|
||||
|
||||
int m_em_unit; // width of a "m"-symbol in pixels for current system font
|
||||
// Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls
|
||||
|
@ -212,6 +213,7 @@ public:
|
|||
const wxFont& small_font() { return m_small_font; }
|
||||
const wxFont& bold_font() { return m_bold_font; }
|
||||
const wxFont& normal_font() { return m_normal_font; }
|
||||
const wxFont& code_font() { return m_code_font; }
|
||||
int em_unit() const { return m_em_unit; }
|
||||
wxSize get_min_size() const;
|
||||
float toolbar_icon_scale(const bool is_limited = false) const;
|
||||
|
|
|
@ -50,6 +50,8 @@ bool GLGizmoFdmSupports::on_init()
|
|||
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
|
||||
m_desc["remove"] = _L("Remove selection");
|
||||
m_desc["remove_all"] = _L("Remove all selection");
|
||||
m_desc["circle"] = _L("Circle");
|
||||
m_desc["sphere"] = _L("Sphere");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -86,18 +88,15 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
if (! m_setting_angle) {
|
||||
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
std::vector<std::string> cursor_types;
|
||||
cursor_types.push_back(_L("Circle").ToUTF8().data());
|
||||
cursor_types.push_back(_L("Sphere").ToUTF8().data());
|
||||
|
||||
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
|
||||
const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x,
|
||||
m_imgui->calc_text_size(m_desc.at("reset_direction")).x)
|
||||
+ m_imgui->scaled(1.5f);
|
||||
const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_combo_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_combo_width = std::max(m_imgui->calc_text_size(wxString::FromUTF8(cursor_types[0].c_str())).x,
|
||||
m_imgui->calc_text_size(wxString::FromUTF8(cursor_types[1].c_str())).x)
|
||||
const float cursor_type_radio_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_radio_width1 = m_imgui->calc_text_size(m_desc["circle"]).x
|
||||
+ m_imgui->scaled(2.5f);
|
||||
const float cursor_type_radio_width2 = m_imgui->calc_text_size(m_desc["sphere"]).x
|
||||
+ m_imgui->scaled(2.5f);
|
||||
const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f);
|
||||
const float minimal_slider_width = m_imgui->scaled(4.f);
|
||||
|
@ -114,7 +113,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left);
|
||||
window_width = std::max(window_width, total_text_max);
|
||||
window_width = std::max(window_width, button_width);
|
||||
window_width = std::max(window_width, cursor_type_combo_left + cursor_type_combo_width);
|
||||
window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_width1 + cursor_type_radio_width2);
|
||||
|
||||
auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) {
|
||||
m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, caption);
|
||||
|
@ -166,20 +165,41 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(m_desc.at("cursor_type"));
|
||||
ImGui::SameLine(window_width - cursor_type_combo_width - m_imgui->scaled(0.5f));
|
||||
ImGui::PushItemWidth(cursor_type_combo_width);
|
||||
int selection = int(m_cursor_type);
|
||||
m_imgui->combo("", cursor_types, selection);
|
||||
m_cursor_type = TriangleSelector::CursorType(selection);
|
||||
ImGui::SameLine(cursor_type_radio_left + m_imgui->scaled(0.f));
|
||||
ImGui::PushItemWidth(cursor_type_radio_width1);
|
||||
|
||||
bool sphere_sel = m_cursor_type == TriangleSelector::CursorType::SPHERE;
|
||||
if (m_imgui->radio_button(m_desc["sphere"], sphere_sel))
|
||||
sphere_sel = true;
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
ImGui::TextUnformatted(_L("Sphere paints all facets inside, regardless of their orientation.\n\n"
|
||||
"Circle ignores facets facing away from the camera.").ToUTF8().data());
|
||||
ImGui::TextUnformatted(_L("Paints all facets inside, regardless of their orientation.").ToUTF8().data());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine(cursor_type_radio_left + cursor_type_radio_width2 + m_imgui->scaled(0.f));
|
||||
ImGui::PushItemWidth(cursor_type_radio_width2);
|
||||
|
||||
if (m_imgui->radio_button(m_desc["circle"], ! sphere_sel))
|
||||
sphere_sel = false;
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
ImGui::TextUnformatted(_L("Ignores facets facing away from the camera.").ToUTF8().data());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
m_cursor_type = sphere_sel
|
||||
? TriangleSelector::CursorType::SPHERE
|
||||
: TriangleSelector::CursorType::CIRCLE;
|
||||
|
||||
|
||||
|
||||
|
||||
ImGui::Separator();
|
||||
if (m_c->object_clipper()->get_position() == 0.f) {
|
||||
|
@ -287,7 +307,7 @@ void GLGizmoFdmSupports::update_model_object() const
|
|||
if (! mv->is_model_part())
|
||||
continue;
|
||||
++idx;
|
||||
updated |= mv->m_supported_facets.set(*m_triangle_selectors[idx].get());
|
||||
updated |= mv->supported_facets.set(*m_triangle_selectors[idx].get());
|
||||
}
|
||||
|
||||
if (updated)
|
||||
|
@ -314,7 +334,7 @@ void GLGizmoFdmSupports::update_from_model_object()
|
|||
const TriangleMesh* mesh = &mv->mesh();
|
||||
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->m_supported_facets.get_data());
|
||||
m_triangle_selectors.back()->deserialize(mv->supported_facets.get_data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ bool GLGizmoSeam::on_init()
|
|||
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
|
||||
m_desc["remove"] = _L("Remove selection");
|
||||
m_desc["remove_all"] = _L("Remove all selection");
|
||||
m_desc["circle"] = _L("Circle");
|
||||
m_desc["sphere"] = _L("Sphere");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -71,12 +73,6 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
const float approx_height = m_imgui->scaled(14.0f);
|
||||
y = std::min(y, bottom_limit - approx_height);
|
||||
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
|
||||
|
||||
std::vector<std::string> cursor_types;
|
||||
cursor_types.push_back(_L("Circle").ToUTF8().data());
|
||||
cursor_types.push_back(_L("Sphere").ToUTF8().data());
|
||||
|
||||
|
||||
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
|
||||
|
@ -84,9 +80,10 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
m_imgui->calc_text_size(m_desc.at("reset_direction")).x)
|
||||
+ m_imgui->scaled(1.5f);
|
||||
const float cursor_size_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_combo_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_combo_width = std::max(m_imgui->calc_text_size(wxString::FromUTF8(cursor_types[0].c_str())).x,
|
||||
m_imgui->calc_text_size(wxString::FromUTF8(cursor_types[1].c_str())).x)
|
||||
const float cursor_type_radio_left = m_imgui->calc_text_size(m_desc.at("cursor_type")).x + m_imgui->scaled(1.f);
|
||||
const float cursor_type_radio_width1 = m_imgui->calc_text_size(m_desc["circle"]).x
|
||||
+ m_imgui->scaled(2.5f);
|
||||
const float cursor_type_radio_width2 = m_imgui->calc_text_size(m_desc["sphere"]).x
|
||||
+ m_imgui->scaled(2.5f);
|
||||
const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f);
|
||||
const float minimal_slider_width = m_imgui->scaled(4.f);
|
||||
|
@ -103,7 +100,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
float window_width = minimal_slider_width + std::max(cursor_size_slider_left, clipping_slider_left);
|
||||
window_width = std::max(window_width, total_text_max);
|
||||
window_width = std::max(window_width, button_width);
|
||||
window_width = std::max(window_width, cursor_type_combo_left + cursor_type_combo_width);
|
||||
window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_width1 + cursor_type_radio_width2);
|
||||
|
||||
auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) {
|
||||
static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f);
|
||||
|
@ -147,21 +144,41 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit)
|
|||
}
|
||||
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(m_desc.at("cursor_type"));
|
||||
ImGui::SameLine(window_width - cursor_type_combo_width - m_imgui->scaled(0.5f));
|
||||
ImGui::PushItemWidth(cursor_type_combo_width);
|
||||
int selection = int(m_cursor_type);
|
||||
m_imgui->combo("", cursor_types, selection);
|
||||
m_cursor_type = TriangleSelector::CursorType(selection);
|
||||
ImGui::SameLine(cursor_type_radio_left + m_imgui->scaled(0.f));
|
||||
ImGui::PushItemWidth(cursor_type_radio_width1);
|
||||
|
||||
bool sphere_sel = m_cursor_type == TriangleSelector::CursorType::SPHERE;
|
||||
if (m_imgui->radio_button(m_desc["sphere"], sphere_sel))
|
||||
sphere_sel = true;
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
ImGui::TextUnformatted(_L("Sphere paints all facets inside, regardless of their orientation.\n\n"
|
||||
"Circle ignores facets facing away from the camera.").ToUTF8().data());
|
||||
ImGui::TextUnformatted(_L("Paints all facets inside, regardless of their orientation.").ToUTF8().data());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine(cursor_type_radio_left + cursor_type_radio_width2 + m_imgui->scaled(0.f));
|
||||
ImGui::PushItemWidth(cursor_type_radio_width2);
|
||||
|
||||
if (m_imgui->radio_button(m_desc["circle"], ! sphere_sel))
|
||||
sphere_sel = false;
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(max_tooltip_width);
|
||||
ImGui::TextUnformatted(_L("Ignores facets facing away from the camera.").ToUTF8().data());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
m_cursor_type = sphere_sel
|
||||
? TriangleSelector::CursorType::SPHERE
|
||||
: TriangleSelector::CursorType::CIRCLE;
|
||||
|
||||
|
||||
|
||||
ImGui::Separator();
|
||||
|
@ -202,7 +219,7 @@ void GLGizmoSeam::update_model_object() const
|
|||
if (! mv->is_model_part())
|
||||
continue;
|
||||
++idx;
|
||||
updated |= mv->m_seam_facets.set(*m_triangle_selectors[idx].get());
|
||||
updated |= mv->seam_facets.set(*m_triangle_selectors[idx].get());
|
||||
}
|
||||
|
||||
if (updated)
|
||||
|
@ -229,7 +246,7 @@ void GLGizmoSeam::update_from_model_object()
|
|||
const TriangleMesh* mesh = &mv->mesh();
|
||||
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->m_seam_facets.get_data());
|
||||
m_triangle_selectors.back()->deserialize(mv->seam_facets.get_data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1872,12 +1872,14 @@ void TabFilament::build()
|
|||
optgroup = page->new_optgroup(L("Start G-code"), 0);
|
||||
option = optgroup->get_option("start_filament_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;// 150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("End G-code"), 0);
|
||||
option = optgroup->get_option("end_filament_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;// 150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
|
@ -2135,51 +2137,60 @@ void TabPrinter::build_fff()
|
|||
optgroup = page->new_optgroup(L("Start G-code"), 0);
|
||||
option = optgroup->get_option("start_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("End G-code"), 0);
|
||||
option = optgroup->get_option("end_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Before layer change G-code"), 0);
|
||||
option = optgroup->get_option("before_layer_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("After layer change G-code"), 0);
|
||||
option = optgroup->get_option("layer_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Tool change G-code"), 0);
|
||||
option = optgroup->get_option("toolchange_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Between objects G-code (for sequential printing)"), 0);
|
||||
option = optgroup->get_option("between_objects_gcode");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Color Change G-code"), 0);
|
||||
option = optgroup->get_option("color_change_gcode");
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Pause Print G-code"), 0);
|
||||
option = optgroup->get_option("pause_print_gcode");
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Template Custom G-code"), 0);
|
||||
option = optgroup->get_option("template_custom_gcode");
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = gcode_field_height;//150;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
|
|
Loading…
Reference in a new issue