Move text only above selected instance.

This commit is contained in:
Filip Sykala - NTB T15p 2023-02-02 14:42:29 +01:00
parent df79841f93
commit 66be5faedd
3 changed files with 83 additions and 23 deletions

View File

@ -490,6 +490,10 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
// detect start text dragging
if (mouse_event.LeftDown()) {
// exist selected volume?
if (m_volume == nullptr)
return false;
// must exist hover object
int hovered_id = m_parent.get_first_hover_volume_idx();
if (hovered_id < 0)
@ -502,6 +506,12 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
if (m_volume != priv::get_model_volume(gl_volume, objects))
return false;
const ModelInstancePtrs instances = m_volume->get_object()->instances;
int instance_id = gl_volume->instance_idx();
if (instance_id < 0 || static_cast<size_t>(instance_id) >= instances.size())
return false; // should not happen
const ModelInstance *instance = instances[instance_id];
const ModelVolumePtrs &volumes = m_volume->get_object()->volumes;
std::vector<size_t> allowed_volumes_id;
if (volumes.size() > 1) {
@ -519,7 +529,7 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
// initialize raycasters
// INFO: It could slows down for big objects
// (may be move to thread and do not show drag until it finish)
m_raycast_manager.actualize(m_volume->get_object(), &condition);
m_raycast_manager.actualize(instance, &condition);
// wxCoord == int --> wx/types.h
Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY());

View File

@ -6,34 +6,53 @@
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/Camera.hpp"
using namespace Slic3r::GUI;
using namespace Slic3r::GUI;
void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
namespace priv {
using namespace Slic3r;
// copied from private part of RaycastManager.hpp
using Raycaster = std::pair<size_t, std::unique_ptr<MeshRaycaster> >;
// ModelVolume.id
using Raycasters = std::vector<Raycaster>;
static void actualize(Raycasters &casters, const ModelVolumePtrs &volumes, const RaycastManager::ISkip *skip)
{
// check if volume was removed
std::vector<bool> removed_casters(m_raycasters.size(), {true});
// check if inscance was removed
std::vector<bool> removed_transf(m_transformations.size(), {true});
std::vector<bool> removed_casters(casters.size(), {true});
// actualize MeshRaycaster
for (const ModelVolume *volume : object->volumes) {
for (const ModelVolume *volume : volumes) {
size_t oid = volume->id().id;
if (skip != nullptr && skip->skip(oid))
if (skip != nullptr && skip->skip(oid))
continue;
auto item = std::find_if(m_raycasters.begin(), m_raycasters.end(),
[oid](const RaycastManager::Raycaster &it)->bool {
return oid == it.first;
});
if (item == m_raycasters.end()) {
auto item = std::find_if(casters.begin(), casters.end(),
[oid](const Raycaster &it) -> bool { return oid == it.first; });
if (item == casters.end()) {
// add new raycaster
auto raycaster = std::make_unique<MeshRaycaster>(volume->get_mesh_shared_ptr());
m_raycasters.emplace_back(std::make_pair(oid, std::move(raycaster)));
casters.emplace_back(std::make_pair(oid, std::move(raycaster)));
} else {
size_t index = item - m_raycasters.begin();
size_t index = item - casters.begin();
removed_casters[index] = false;
}
}
// clean other raycasters
for (int i = removed_casters.size() - 1; i >= 0; --i)
if (removed_casters[i])
casters.erase(casters.begin() + i);
}
}
void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
{
// actualize MeshRaycaster
priv::actualize(m_raycasters, object->volumes, skip);
// check if inscance was removed
std::vector<bool> removed_transf(m_transformations.size(), {true});
// actualize transformation matrices
for (const ModelVolume *volume : object->volumes) {
if (skip != nullptr && skip->skip(volume->id().id)) continue;
@ -41,8 +60,6 @@ void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
for (const ModelInstance *instance : object->instances) {
const Transform3d &instrance_tr = instance->get_matrix();
Transform3d transformation = instrance_tr * volume_tr;
// TODO: add SLA shift Z
// transformation.translation()(2) += m_sla_shift_z;
TrKey tr_key = std::make_pair(instance->id().id, volume->id().id);
auto item = std::find_if(m_transformations.begin(),
m_transformations.end(),
@ -62,17 +79,49 @@ void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
}
}
// clean other raycasters
for (int i = removed_casters.size() - 1; i >= 0; --i)
if (removed_casters[i])
m_raycasters.erase(m_raycasters.begin() + i);
// clean other transformation
for (int i = removed_transf.size() - 1; i >= 0; --i)
if (removed_transf[i])
m_transformations.erase(m_transformations.begin() + i);
}
void RaycastManager::actualize(const ModelInstance *instance, const ISkip *skip) {
const ModelVolumePtrs &volumes = instance->get_object()->volumes;
// actualize MeshRaycaster
priv::actualize(m_raycasters, volumes, skip);
// check if inscance was removed
std::vector<bool> removed_transf(m_transformations.size(), {true});
// actualize transformation matrices
for (const ModelVolume *volume : volumes) {
if (skip != nullptr && skip->skip(volume->id().id))
continue;
const Transform3d &volume_tr = volume->get_matrix();
const Transform3d &instrance_tr = instance->get_matrix();
Transform3d transformation = instrance_tr * volume_tr;
TrKey tr_key = std::make_pair(instance->id().id, volume->id().id);
auto item = std::find_if(m_transformations.begin(), m_transformations.end(),
[&tr_key](const TrItem &it) -> bool { return it.first == tr_key; });
if (item != m_transformations.end()) {
// actualize transformation all the time
item->second = transformation;
size_t index = item - m_transformations.begin();
removed_transf[index] = false;
} else {
// add new transformation
m_transformations.emplace_back(std::make_pair(tr_key, transformation));
}
}
// clean other transformation
for (int i = removed_transf.size() - 1; i >= 0; --i)
if (removed_transf[i])
m_transformations.erase(m_transformations.begin() + i);
}
std::optional<RaycastManager::Hit> RaycastManager::unproject(
const Vec2d &mouse_pos, const Camera &camera, const ISkip *skip) const
{

View File

@ -51,6 +51,7 @@ public:
/// <param name="object">Model representation</param>
/// <param name="skip">Condifiton for skip actualization</param>
void actualize(const ModelObject *object, const ISkip *skip = nullptr);
void actualize(const ModelInstance *instance, const ISkip *skip = nullptr);
// TODO: it is more general object move outside of this class
struct SurfacePoint