Special case of mirror when emboss gizmo is opend

This commit is contained in:
Filip Sykala - NTB T15p 2023-08-14 08:14:07 +02:00
parent d8c7513668
commit 7f647c49f5
4 changed files with 121 additions and 24 deletions

View File

@ -15,11 +15,44 @@
#include "MainFrame.hpp"
#include "MsgDialog.hpp"
#include <GL/glew.h> // Fix for fatal error C1189: #error: gl.h included before glew.h (compiling source file C:\git\slicer2\src\slic3r\GUI\GUI_ObjectManipulation.cpp)
#include <wx/glcanvas.h>
#include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp"
// For special mirroring in manipulation gizmo
#include "Gizmos/GLGizmosManager.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"
namespace {
using namespace Slic3r::GUI;
bool is_emboss_mirror(size_t axis_idx)
{
Plater* plater = wxGetApp().plater();
if (!plater)
return false;
GLCanvas3D *canvas = plater->canvas3D();
if (!canvas)
return false;
GLGizmosManager &manager = canvas->get_gizmos_manager();
// is embossing
if (manager.get_current_type() != GLGizmosManager::Emboss)
return false;
GLGizmoBase *gizmo = manager.get_current();
if (!gizmo)
return false;
GLGizmoEmboss *emboss = dynamic_cast<GLGizmoEmboss *>(gizmo);
if (!emboss)
return false;
return emboss->do_mirror(axis_idx);
}
} // namespace
namespace Slic3r
{
namespace GUI
@ -253,10 +286,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
sizer->AddStretchSpacer(2);
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) {
if (::is_emboss_mirror(axis_idx))
return;
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
Selection& selection = canvas->get_selection();
TransformationType transformation_type;
if (is_local_coordinates())
transformation_type.set_local();
@ -265,6 +300,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
transformation_type.set_relative();
Selection& selection = canvas->get_selection();
selection.setup_cache();
selection.mirror((Axis)axis_idx, transformation_type);

View File

@ -360,6 +360,67 @@ void GLGizmoEmboss::on_shortcut_key() {
}
}
namespace{
ModelVolumePtrs prepare_volumes_to_slice(const ModelVolume &mv)
{
const ModelVolumePtrs &volumes = mv.get_object()->volumes;
ModelVolumePtrs result;
result.reserve(volumes.size());
for (ModelVolume *volume : volumes) {
// only part could be surface for volumes
if (!volume->is_model_part())
continue;
// is selected volume
if (mv.id() == volume->id())
continue;
result.push_back(volume);
}
return result;
}
}
bool GLGizmoEmboss::do_mirror(size_t axis)
{
// is valid input
assert(axis < 3);
if (axis >= 3)
return false;
// is gizmo opened and initialized?
assert(m_parent.get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss);
if (m_parent.get_gizmos_manager().get_current_type() != GLGizmosManager::Emboss)
return false;
const TextConfiguration &tc= *m_volume->text_configuration;
if(tc.style.prop.per_glyph){
// init textlines before mirroring on mirrored text volume transformation
Transform3d tr = m_volume->get_matrix();
const std::optional<Transform3d> &fix_tr = tc.fix_3mf_tr;
if (fix_tr.has_value())
tr = tr * (fix_tr->inverse());
// mirror
Vec3d scale = Vec3d::Ones();
scale[axis] = -1.;
tr = tr * Eigen::Scaling(scale);
// collect volumes in object
ModelVolumePtrs volumes = prepare_volumes_to_slice(*m_volume);
m_text_lines.init(tr, volumes, m_style_manager, m_text_lines.get_lines().size());
}
// mirror
Transform3d tr = m_volume->get_matrix();
Vec3d scale = Vec3d::Ones();
scale[axis] = -1.;
tr = tr * Eigen::Scaling(scale);
m_volume->set_transformation(tr);
// NOTE: Staff around volume transformation change is done in job finish
return process();
}
namespace{
// verify correct volume type for creation of text
bool check(ModelVolumeType volume_type) {
@ -1101,11 +1162,6 @@ void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /*
return;
const GLVolume &gl_volume = *gl_volume_ptr;
const ModelObjectPtrs &objects = selection.get_model()->objects;
const ModelObject *mo_ptr = get_model_object(gl_volume, objects);
if (mo_ptr == nullptr)
return;
const ModelObject &mo = *mo_ptr;
const ModelVolume *mv_ptr = get_model_volume(gl_volume, objects);
if (mv_ptr == nullptr)
return;
@ -1126,19 +1182,7 @@ void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /*
}
// prepare volumes to slice
ModelVolumePtrs volumes;
volumes.reserve(mo.volumes.size());
for (ModelVolume *volume : mo.volumes) {
// only part could be surface for volumes
if (!volume->is_model_part())
continue;
// is selected volume
if (mv.id() == volume->id())
continue;
volumes.push_back(volume);
}
ModelVolumePtrs volumes = prepare_volumes_to_slice(mv);
// For interactivity during drag over surface it must be from gl_volume not volume.
Transform3d mv_trafo = gl_volume.get_volume_transformation().get_matrix();

View File

@ -52,6 +52,15 @@ public:
/// Handle pressing of shortcut
/// </summary>
void on_shortcut_key();
/// <summary>
/// Mirroring from object manipulation panel
/// !! Emboss gizmo must be active
/// </summary>
/// <param name="axis">Axis for mirroring must be one of {0,1,2}</param>
/// <returns>True on success start job otherwise False</returns>
bool do_mirror(size_t axis);
protected:
bool on_init() override;
std::string on_get_name() const override;

View File

@ -218,7 +218,7 @@ indexed_triangle_set create_its(const TextLines &lines, float radius)
return its;
}
GLModel::Geometry create_geometry(const TextLines &lines, float radius)
GLModel::Geometry create_geometry(const TextLines &lines, float radius, bool is_mirrored)
{
indexed_triangle_set its = create_its(lines, radius);
@ -232,8 +232,15 @@ GLModel::Geometry create_geometry(const TextLines &lines, float radius)
geometry.add_vertex(vertex);
geometry.reserve_indices(its.indices.size() * 3);
for (Vec3i t : its.indices)
geometry.add_triangle(t[0], t[1], t[2]);
if (is_mirrored) {
// change order of indices
for (Vec3i t : its.indices)
geometry.add_triangle(t[0], t[2], t[1]);
} else {
for (Vec3i t : its.indices)
geometry.add_triangle(t[0], t[1], t[2]);
}
return geometry;
}
@ -333,9 +340,10 @@ void TextLinesModel::init(const Transform3d &text_tr,
for (size_t i = 0; i < count_lines; ++i)
m_lines[i].y = line_centers[i];
bool is_mirrored = has_reflection(text_tr);
float radius = static_cast<float>(line_height_mm / 20.);
//*
GLModel::Geometry geometry = create_geometry(m_lines, radius);
GLModel::Geometry geometry = create_geometry(m_lines, radius, is_mirrored);
if (geometry.vertices_count() == 0 || geometry.indices_count() == 0)
return;
m_model.init_from(std::move(geometry));