mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 13:55:58 +08:00
Move text only above selected instance.
This commit is contained in:
parent
df79841f93
commit
66be5faedd
@ -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());
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user