FIX:move text should update text info

jira: STUDIO-7038
Change-Id: Ibd760c3655e6ff3f7c0a5604ef66e001f7cdc1fb
(cherry picked from commit aef92cd8eb9bae95939fdc1e8dfadec4ca529a3e)
This commit is contained in:
zhou.xu 2024-05-11 10:51:16 +08:00 committed by Lane.Wei
parent 795ec50eb4
commit 2822ac102b
7 changed files with 165 additions and 31 deletions

View File

@ -823,7 +823,7 @@ struct TextInfo
std::string m_text;
RaycastResult m_rr;
Vec3d m_hit_in_text; // for load use
template<typename Archive> void serialize(Archive &ar) {
ar(m_font_name, m_font_size, m_curr_font_idx, m_bold, m_italic, m_thickness, m_embeded_depth, m_rotate_angle, m_text_gap, m_is_surface_text, m_keep_horizontal, m_text, m_rr);
}

View File

@ -4599,7 +4599,31 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip)
m_tooltip.set_text(tooltip);
}
void GLCanvas3D::do_move(const std::string& snapshot_type)
void GLCanvas3D::generate_new_hit_in_text_info(ModelVolume * cur_mv,
ModelObject * model_object,
ModelInstance * mi,
const Transform3d &old_text_world_tran,
const Transform3d &cur_text_world_tran,
TextInfo * text_info,
int type)
{
Geometry::Transformation old_text_tran_(old_text_world_tran);
Geometry::Transformation cur_text_tran_(cur_text_world_tran);
bool is_changed = (type == 0 && old_text_tran_.get_offset() != cur_text_tran_.get_offset()) ||//move
(type == 1 && old_text_tran_.get_rotation() != cur_text_tran_.get_rotation()) ||// rotate
(type == 2 && old_text_tran_.get_scaling_factor() != cur_text_tran_.get_scaling_factor());
if (is_changed) {
std::vector<Transform3d> trafo_matrices;
for (const ModelVolume *mv : model_object->volumes) {
if (mv->is_model_part()) { trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix()); }
}
if (text_info->m_rr.mesh_id < trafo_matrices.size()) {
text_info->m_rr.hit = (trafo_matrices[text_info->m_rr.mesh_id].inverse() * (cur_text_world_tran * text_info->m_hit_in_text)).cast<float>();
}
}
}
void GLCanvas3D::do_move(const std::string &snapshot_type)
{
if (m_model == nullptr)
return;
@ -4639,8 +4663,20 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
}
}
else if (selection_mode == Selection::Volume) {
if (model_object->volumes[volume_idx]->get_offset() != v->get_volume_offset()) {
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
auto cur_mv = model_object->volumes[volume_idx];
if (cur_mv->get_offset() != v->get_volume_offset()) {
auto text_info = const_cast<TextInfo *>(&cur_mv->get_text_info());
auto mi = model_object->instances[instance_idx];
Transform3d old_text_world_tran;
bool is_text_mv = text_info && !text_info->m_text.empty() && text_info->m_rr.mesh_id >= 0;
if (is_text_mv) { // deal text_info
old_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
}
cur_mv->set_offset(v->get_volume_offset());
if (is_text_mv) { // deal text_info
auto cur_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
generate_new_hit_in_text_info(cur_mv, model_object, mi, old_text_world_tran, cur_text_world_tran, text_info, 0);
}
// BBS: backup
Slic3r::save_object_mesh(*model_object);
}
@ -4753,9 +4789,22 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
}
}
else if (selection_mode == Selection::Volume) {
if (model_object->volumes[volume_idx]->get_rotation() != v->get_volume_rotation()) {
model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation());
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
auto cur_mv = model_object->volumes[volume_idx];
if (cur_mv->get_rotation() != v->get_volume_rotation()) {
auto text_info = const_cast<TextInfo *>(&cur_mv->get_text_info());
auto mi = model_object->instances[instance_idx];
Transform3d old_text_world_tran;
bool is_text_mv = text_info && !text_info->m_text.empty() && text_info->m_rr.mesh_id >= 0;
if (is_text_mv) { // deal text_info
old_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
}
cur_mv->set_rotation(v->get_volume_rotation());
cur_mv->set_offset(v->get_volume_offset());
if (is_text_mv) { // deal text_info
auto cur_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
generate_new_hit_in_text_info(cur_mv, model_object, mi, old_text_world_tran, cur_text_world_tran, text_info, 1);
}
// BBS: backup
Slic3r::save_object_mesh(*model_object);
}
@ -4835,10 +4884,24 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
}
else if (selection_mode == Selection::Volume) {
if (model_object->volumes[volume_idx]->get_scaling_factor() != v->get_volume_scaling_factor()) {
auto cur_mv = model_object->volumes[volume_idx];
if (cur_mv->get_scaling_factor() != v->get_volume_scaling_factor()) {
auto text_info = const_cast<TextInfo *>(&cur_mv->get_text_info());
auto mi = model_object->instances[instance_idx];
Transform3d old_text_world_tran;
bool is_text_mv = text_info && !text_info->m_text.empty() && text_info->m_rr.mesh_id >= 0;
if (is_text_mv) { // deal text_info
old_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
}
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor());
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
cur_mv->set_scaling_factor(v->get_volume_scaling_factor());
cur_mv->set_offset(v->get_volume_offset());
if (is_text_mv) { // deal text_info
auto cur_text_world_tran = mi->get_transformation().get_matrix() * cur_mv->get_matrix();
generate_new_hit_in_text_info(cur_mv, model_object, mi, old_text_world_tran, cur_text_world_tran, text_info, 2);
}
// BBS: backup
Slic3r::save_object_mesh(*model_object);
}

View File

@ -45,6 +45,7 @@ struct ThumbnailData;
struct ThumbnailsParams;
class ModelObject;
class ModelInstance;
class TextInfo;
class PrintObject;
class Print;
class SLAPrint;
@ -949,6 +950,8 @@ public:
void set_tooltip(const std::string& tooltip);
// the following methods add a snapshot to the undo/redo stack, unless the given string is empty
void generate_new_hit_in_text_info(ModelVolume *cur_mv, ModelObject *model_object,ModelInstance *mi,
const Transform3d &old_text_world_tran, const Transform3d &cur_text_world_tran, TextInfo *text_info,int type);
void do_move(const std::string& snapshot_type);
void do_rotate(const std::string& snapshot_type);
void do_scale(const std::string& snapshot_type);

View File

@ -390,7 +390,7 @@ void GLGizmoText::on_set_state()
{
if (m_state == EState::On) {
if (m_parent.get_selection().is_single_volume() || m_parent.get_selection().is_single_modifier()) {
ModelVolume *model_volume = get_selected_single_volume(m_object_idx, m_volume_idx);
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(m_object_idx, m_volume_idx);
if (model_volume) {
TextInfo text_info = model_volume->get_text_info();
if (!text_info.m_text.empty()) {
@ -434,7 +434,7 @@ bool GLGizmoText::on_is_activable() const
return true;
int obejct_idx, volume_idx;
ModelVolume *model_volume = get_selected_single_volume(obejct_idx, volume_idx);
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(obejct_idx, volume_idx);
if (model_volume)
return !model_volume->get_text_info().m_text.empty();
@ -535,7 +535,7 @@ void GLGizmoText::on_render_for_picking()
glsafe(::glDisable(GL_DEPTH_TEST));
int obejct_idx, volume_idx;
ModelVolume *model_volume = get_selected_single_volume(obejct_idx, volume_idx);
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(obejct_idx, volume_idx);
if (model_volume && !model_volume->get_text_info().m_text.empty()) {
if (m_grabbers.size() == 1) {
ModelObject *mo = m_c->selection_info()->model_object();
@ -721,9 +721,10 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
}
} else if (selection.is_single_volume() || selection.is_single_modifier()) {
int object_idx, volume_idx;
ModelVolume *model_volume = get_selected_single_volume(object_idx, volume_idx);
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(object_idx, volume_idx);
if ((object_idx != m_object_idx || (object_idx == m_object_idx && volume_idx != m_volume_idx))
&& model_volume) {
m_hit_in_text = Vec3d::Zero();
TextInfo text_info = model_volume->get_text_info();
load_from_text_info(text_info);
m_is_modify = true;
@ -972,20 +973,6 @@ void GLGizmoText::show_tooltip_information(float x, float y)
ImGui::PopStyleVar(2);
}
ModelVolume *GLGizmoText::get_selected_single_volume(int &out_object_idx, int &out_volume_idx) const
{
if (m_parent.get_selection().is_single_volume() || m_parent.get_selection().is_single_modifier()) {
const Selection &selection = m_parent.get_selection();
const GLVolume * gl_volume = selection.get_volume(*selection.get_volume_idxs().begin());
out_object_idx = gl_volume->object_idx();
ModelObject *model_object = selection.get_model()->objects[out_object_idx];
out_volume_idx = gl_volume->volume_idx();
if (out_volume_idx < model_object->volumes.size())
return model_object->volumes[out_volume_idx];
}
return nullptr;
}
void GLGizmoText::reset_text_info()
{
m_font_name = "";
@ -1569,15 +1556,14 @@ void GLGizmoText::generate_text_volume(bool is_temp)
return;
TextInfo text_info = get_text_info();
const Selection &selection = m_parent.get_selection();
ModelObject * model_object = selection.get_model()->objects[m_object_idx];
if (m_is_modify && m_need_update_text) {
if (m_object_idx == -1 || m_volume_idx == -1) {
BOOST_LOG_TRIVIAL(error) << boost::format("Text: selected object_idx = %1%, volume_idx = %2%") % m_object_idx % m_volume_idx;
return;
}
plater->take_snapshot("Modify Text");
const Selection &selection = m_parent.get_selection();
ModelObject * model_object = selection.get_model()->objects[m_object_idx];
ModelVolume * model_volume = model_object->volumes[m_volume_idx];
ModelVolume * new_model_volume = model_object->add_volume(std::move(mesh));
new_model_volume->set_text_info(text_info);
@ -1587,12 +1573,21 @@ void GLGizmoText::generate_text_volume(bool is_temp)
std::swap(model_object->volumes[m_volume_idx], model_object->volumes.back());
model_object->delete_volume(model_object->volumes.size() - 1);
plater->update();
auto cur_text_info = const_cast<TextInfo*> (&new_model_volume->get_text_info());
m_text_volume_tran = new_model_volume->get_matrix();
update_hit_in_text();
cur_text_info->m_hit_in_text = m_hit_in_text;
} else {
if (m_need_update_text)
plater->take_snapshot("Add Text");
ObjectList *obj_list = wxGetApp().obj_list();
int volume_id = obj_list->load_mesh_part(mesh, "text_shape", text_info, is_temp);
m_preview_text_volume_id = is_temp ? volume_id : -1;
ModelVolume *text_model_volume = model_object->volumes[volume_id];
m_text_volume_tran = text_model_volume->get_matrix();
auto cur_text_info = const_cast<TextInfo *>(&text_model_volume->get_text_info());
update_hit_in_text();
cur_text_info->m_hit_in_text = m_hit_in_text;
}
m_need_update_text = false;
}
@ -1626,6 +1621,7 @@ TextInfo GLGizmoText::get_text_info()
text_info.m_thickness = m_thickness;
text_info.m_text = m_text;
text_info.m_rr = m_rr;
text_info.m_hit_in_text = m_hit_in_text;
text_info.m_embeded_depth = m_embeded_depth;
text_info.m_rotate_angle = m_rotate_angle;
text_info.m_text_gap = m_text_gap;
@ -1634,6 +1630,16 @@ TextInfo GLGizmoText::get_text_info()
return text_info;
}
void GLGizmoText::update_hit_in_text() {
{
const std::vector<Transform3d> &trafo_matrices = m_parent.get_selection().get_all_tran_of_selected_volumes();
auto mi = m_parent.get_selection().get_selected_single_intance();
if (mi && trafo_matrices.size() > 0) {
auto text_world_tran = mi->get_transformation().get_matrix() * m_text_volume_tran;
m_hit_in_text = text_world_tran.inverse() * (trafo_matrices[m_rr.mesh_id] * m_rr.hit.cast<double>());
}
}
}
void GLGizmoText::load_from_text_info(const TextInfo &text_info)
{
m_font_name = text_info.m_font_name;

View File

@ -34,6 +34,7 @@ private:
bool m_is_surface_text = false;
bool m_keep_horizontal = false;
mutable RaycastResult m_rr;
mutable Vec3d m_hit_in_text;
float m_combo_height = 0.0f;
float m_combo_width = 0.0f;
@ -81,6 +82,7 @@ private:
// This map holds all translated description texts, so they can be easily referenced during layout calculations
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.
std::map<std::string, wxString> m_desc;
Transform3d m_text_volume_tran;
public:
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
@ -112,8 +114,11 @@ protected:
void show_tooltip_information(float x, float y);
private:
<<<<<<< HEAD (ac285d FIX:return bar pos only been modified in 3d view)
ModelVolume *get_selected_single_volume(int& out_object_idx, int& out_volume_idx) const;
void update_font_status();
=======
>>>>>>> CHANGE (aef92c FIX:move text should update text info)
void reset_text_info();
bool update_text_positions(const std::vector<std::string>& texts);
TriangleMesh get_text_mesh(const char* text_str, const Vec3d &position, const Vec3d &normal, const Vec3d &text_up_dir);
@ -123,6 +128,7 @@ private:
void delete_temp_preview_text_volume();
TextInfo get_text_info();
void update_hit_in_text();
void load_from_text_info(const TextInfo &text_info);
};

View File

@ -407,6 +407,55 @@ void Selection::remove_volumes(EMode mode, const std::vector<unsigned int>& volu
this->set_bounding_boxes_dirty();
}
ModelVolume *Selection::get_selected_single_volume(int &out_object_idx, int &out_volume_idx)
{
if (is_single_volume() || is_single_modifier()) {
const GLVolume *gl_volume = get_volume(*get_volume_idxs().begin());
out_object_idx = gl_volume->object_idx();
ModelObject *model_object = get_model()->objects[out_object_idx];
out_volume_idx = gl_volume->volume_idx();
if (out_volume_idx < model_object->volumes.size())
return model_object->volumes[out_volume_idx];
}
return nullptr;
}
ModelObject *Selection::get_selected_single_object(int &out_object_idx)
{
if (is_single_volume() || is_single_modifier()) {
const GLVolume *gl_volume = get_volume(*get_volume_idxs().begin());
out_object_idx = gl_volume->object_idx();
return get_model()->objects[out_object_idx];
}
return nullptr;
}
const std::vector<Transform3d> &Selection::get_all_tran_of_selected_volumes()
{
m_trafo_matrices.clear();
int object_idx;
auto mo = get_selected_single_object(object_idx);
if (mo) {
const ModelInstance *mi = mo->instances[get_instance_idx()];
for (const ModelVolume *mv : mo->volumes) {
if (mv->is_model_part()) {
m_trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix());
}
}
}
return m_trafo_matrices;
}
const ModelInstance *Selection::get_selected_single_intance()
{
int object_idx;
auto mo = get_selected_single_object(object_idx);
if (mo) {
return mo->instances[get_instance_idx()];
}
return nullptr;
}
void Selection::add_curr_plate()
{
if (!m_valid)

View File

@ -12,6 +12,8 @@ namespace Slic3r {
class Shader;
class Model;
class ModelObject;
class ModelVolume;
class ModelInstance;
class GLVolume;
class GLArrow;
class GLCurvedArrow;
@ -266,6 +268,7 @@ private:
// BBS
EMode m_volume_selection_mode{ Instance };
bool m_volume_selection_locked { false };
std::vector<Transform3d> m_trafo_matrices;
public:
Selection();
@ -299,6 +302,10 @@ public:
void remove_volumes(EMode mode, const std::vector<unsigned int>& volume_idxs);
//BBS
ModelVolume * get_selected_single_volume(int &out_object_idx, int &out_volume_idx);
ModelObject * get_selected_single_object(int &out_object_idx);
const ModelInstance * get_selected_single_intance();
const std::vector<Transform3d> &get_all_tran_of_selected_volumes();
void add_curr_plate();
void add_object_from_idx(std::vector<int>& object_idxs);
void remove_curr_plate();