mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-04 03:40:38 +08:00
Special case of mirror when emboss gizmo is opend
This commit is contained in:
parent
d8c7513668
commit
7f647c49f5
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user