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 // detect start text dragging
if (mouse_event.LeftDown()) { if (mouse_event.LeftDown()) {
// exist selected volume?
if (m_volume == nullptr)
return false;
// must exist hover object // must exist hover object
int hovered_id = m_parent.get_first_hover_volume_idx(); int hovered_id = m_parent.get_first_hover_volume_idx();
if (hovered_id < 0) 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)) if (m_volume != priv::get_model_volume(gl_volume, objects))
return false; 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; const ModelVolumePtrs &volumes = m_volume->get_object()->volumes;
std::vector<size_t> allowed_volumes_id; std::vector<size_t> allowed_volumes_id;
if (volumes.size() > 1) { if (volumes.size() > 1) {
@ -519,7 +529,7 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
// initialize raycasters // initialize raycasters
// INFO: It could slows down for big objects // INFO: It could slows down for big objects
// (may be move to thread and do not show drag until it finish) // (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 // wxCoord == int --> wx/types.h
Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY()); Vec2i mouse_coord(mouse_event.GetX(), mouse_event.GetY());

View File

@ -6,34 +6,53 @@
#include "slic3r/GUI/Plater.hpp" #include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/Camera.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 // check if volume was removed
std::vector<bool> removed_casters(m_raycasters.size(), {true}); std::vector<bool> removed_casters(casters.size(), {true});
// check if inscance was removed
std::vector<bool> removed_transf(m_transformations.size(), {true});
// actualize MeshRaycaster // actualize MeshRaycaster
for (const ModelVolume *volume : object->volumes) { for (const ModelVolume *volume : volumes) {
size_t oid = volume->id().id; size_t oid = volume->id().id;
if (skip != nullptr && skip->skip(oid)) if (skip != nullptr && skip->skip(oid))
continue; continue;
auto item = std::find_if(m_raycasters.begin(), m_raycasters.end(), auto item = std::find_if(casters.begin(), casters.end(),
[oid](const RaycastManager::Raycaster &it)->bool { [oid](const Raycaster &it) -> bool { return oid == it.first; });
return oid == it.first; if (item == casters.end()) {
});
if (item == m_raycasters.end()) {
// add new raycaster // add new raycaster
auto raycaster = std::make_unique<MeshRaycaster>(volume->get_mesh_shared_ptr()); 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 { } else {
size_t index = item - m_raycasters.begin(); size_t index = item - casters.begin();
removed_casters[index] = false; 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 // actualize transformation matrices
for (const ModelVolume *volume : object->volumes) { for (const ModelVolume *volume : object->volumes) {
if (skip != nullptr && skip->skip(volume->id().id)) continue; 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) { for (const ModelInstance *instance : object->instances) {
const Transform3d &instrance_tr = instance->get_matrix(); const Transform3d &instrance_tr = instance->get_matrix();
Transform3d transformation = instrance_tr * volume_tr; 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); TrKey tr_key = std::make_pair(instance->id().id, volume->id().id);
auto item = std::find_if(m_transformations.begin(), auto item = std::find_if(m_transformations.begin(),
m_transformations.end(), 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 // clean other transformation
for (int i = removed_transf.size() - 1; i >= 0; --i) for (int i = removed_transf.size() - 1; i >= 0; --i)
if (removed_transf[i]) if (removed_transf[i])
m_transformations.erase(m_transformations.begin() + 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( std::optional<RaycastManager::Hit> RaycastManager::unproject(
const Vec2d &mouse_pos, const Camera &camera, const ISkip *skip) const 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="object">Model representation</param>
/// <param name="skip">Condifiton for skip actualization</param> /// <param name="skip">Condifiton for skip actualization</param>
void actualize(const ModelObject *object, const ISkip *skip = nullptr); 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 // TODO: it is more general object move outside of this class
struct SurfacePoint struct SurfacePoint