This commit is contained in:
enricoturri1966 2020-10-12 08:39:51 +02:00
commit d0c5ed4130
17 changed files with 158 additions and 79 deletions

View file

@ -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

View file

@ -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.

View file

@ -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 << "\" ";

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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,6 +516,7 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in
unsigned int new_first = first;
unsigned int new_last = last;
if (m_sequential_view.skip_invisible_moves) {
while (!is_visible(new_first)) {
if (first_diff > 0)
++new_first;
@ -528,6 +530,7 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in
else
--new_last;
}
}
m_sequential_view.current.first = new_first;
m_sequential_view.current.last = new_last;

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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());
}
}

View file

@ -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);