mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-04 09:40:35 +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 "MainFrame.hpp"
|
||||||
#include "MsgDialog.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 <wx/glcanvas.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "slic3r/Utils/FixModelByWin10.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 Slic3r
|
||||||
{
|
{
|
||||||
namespace GUI
|
namespace GUI
|
||||||
@ -255,8 +288,10 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||||||
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
|
sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||||
|
|
||||||
btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) {
|
btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) {
|
||||||
|
if (::is_emboss_mirror(axis_idx))
|
||||||
|
return;
|
||||||
|
|
||||||
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
|
||||||
Selection& selection = canvas->get_selection();
|
|
||||||
TransformationType transformation_type;
|
TransformationType transformation_type;
|
||||||
if (is_local_coordinates())
|
if (is_local_coordinates())
|
||||||
transformation_type.set_local();
|
transformation_type.set_local();
|
||||||
@ -265,6 +300,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||||||
|
|
||||||
transformation_type.set_relative();
|
transformation_type.set_relative();
|
||||||
|
|
||||||
|
Selection& selection = canvas->get_selection();
|
||||||
selection.setup_cache();
|
selection.setup_cache();
|
||||||
selection.mirror((Axis)axis_idx, transformation_type);
|
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{
|
namespace{
|
||||||
// verify correct volume type for creation of text
|
// verify correct volume type for creation of text
|
||||||
bool check(ModelVolumeType volume_type) {
|
bool check(ModelVolumeType volume_type) {
|
||||||
@ -1101,11 +1162,6 @@ void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /*
|
|||||||
return;
|
return;
|
||||||
const GLVolume &gl_volume = *gl_volume_ptr;
|
const GLVolume &gl_volume = *gl_volume_ptr;
|
||||||
const ModelObjectPtrs &objects = selection.get_model()->objects;
|
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);
|
const ModelVolume *mv_ptr = get_model_volume(gl_volume, objects);
|
||||||
if (mv_ptr == nullptr)
|
if (mv_ptr == nullptr)
|
||||||
return;
|
return;
|
||||||
@ -1126,19 +1182,7 @@ void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare volumes to slice
|
// prepare volumes to slice
|
||||||
ModelVolumePtrs volumes;
|
ModelVolumePtrs volumes = prepare_volumes_to_slice(mv);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For interactivity during drag over surface it must be from gl_volume not volume.
|
// For interactivity during drag over surface it must be from gl_volume not volume.
|
||||||
Transform3d mv_trafo = gl_volume.get_volume_transformation().get_matrix();
|
Transform3d mv_trafo = gl_volume.get_volume_transformation().get_matrix();
|
||||||
|
@ -52,6 +52,15 @@ public:
|
|||||||
/// Handle pressing of shortcut
|
/// Handle pressing of shortcut
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void on_shortcut_key();
|
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:
|
protected:
|
||||||
bool on_init() override;
|
bool on_init() override;
|
||||||
std::string on_get_name() const override;
|
std::string on_get_name() const override;
|
||||||
|
@ -218,7 +218,7 @@ indexed_triangle_set create_its(const TextLines &lines, float radius)
|
|||||||
return its;
|
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);
|
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.add_vertex(vertex);
|
||||||
|
|
||||||
geometry.reserve_indices(its.indices.size() * 3);
|
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;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,9 +340,10 @@ void TextLinesModel::init(const Transform3d &text_tr,
|
|||||||
for (size_t i = 0; i < count_lines; ++i)
|
for (size_t i = 0; i < count_lines; ++i)
|
||||||
m_lines[i].y = line_centers[i];
|
m_lines[i].y = line_centers[i];
|
||||||
|
|
||||||
|
bool is_mirrored = has_reflection(text_tr);
|
||||||
float radius = static_cast<float>(line_height_mm / 20.);
|
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)
|
if (geometry.vertices_count() == 0 || geometry.indices_count() == 0)
|
||||||
return;
|
return;
|
||||||
m_model.init_from(std::move(geometry));
|
m_model.init_from(std::move(geometry));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user