Fix cleaning during actualization of raycast manager

This commit is contained in:
Filip Sykala 2022-05-31 20:09:51 +02:00
parent e0d5505413
commit ff604785f6
3 changed files with 48 additions and 86 deletions

View file

@ -497,7 +497,7 @@ std::unique_ptr<Emboss::IProject3f> priv::create_emboss_projection(
const float surface_offset = 1e-3f; // [in mm]
float
front_move = (is_outside) ? emboss : surface_offset,
back_move = -(is_outside) ? surface_offset : emboss;
back_move = -((is_outside) ? surface_offset : emboss);
its_transform(cut, tr.pretranslate(Vec3d(0., 0., front_move)));
Vec3f from_front_to_back(0.f, 0.f, back_move - front_move);
return std::make_unique<Emboss::OrthoProject3f>(from_front_to_back);

View file

@ -1,4 +1,5 @@
#include "RaycastManager.hpp"
#include <utility>
// include for earn camera
#include "slic3r/GUI/GUI_App.hpp"
@ -7,84 +8,29 @@
using namespace Slic3r::GUI;
void RaycastManager::actualize(const ModelObjectPtrs &objects,
const ISkip * skip)
{
// check if volume was removed
std::set<size_t> removed_casters;
for (const auto &raycaster_item : m_raycasters)
removed_casters.insert(raycaster_item.first);
// check if inscance was removed
std::set<TrKey> removed_transformation;
for (const auto &item : m_transformations)
removed_transformation.insert(item.first);
for (const ModelObject *object : objects) {
// actualize MeshRaycaster
for (const ModelVolume *volume : object->volumes) {
size_t oid = volume->id().id;
if (skip != nullptr && skip->skip(oid)) {
removed_casters.erase(oid);
continue;
}
auto item = m_raycasters.find(oid);
if (item != m_raycasters.end()) {
removed_casters.erase(oid);
// alredy in list only actualize
// TODO: check triangles when change than actualize MeshRaycaster
} else {
// add new raycaster
auto raycaster = std::make_unique<MeshRaycaster>(
volume->mesh());
m_raycasters.insert(std::make_pair(oid, std::move(raycaster)));
}
}
// actualize transformation matrices
for (const ModelVolume *volume : object->volumes) {
if (skip != nullptr && skip->skip(volume->id().id)) continue;
const Transform3d &volume_tr = volume->get_matrix();
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 = m_transformations.find(tr_key);
if (item != m_transformations.end()) {
// actualize transformation all the time
item->second = transformation;
removed_transformation.erase(tr_key);
} else {
// add new transformation
m_transformations.insert(
std::make_pair(tr_key, transformation));
}
}
}
}
// remove non existing volumes
for (size_t volume_oid : removed_casters) m_raycasters.erase(volume_oid);
// remove non existing transformations
for (const TrKey& transformation_key : removed_transformation)
m_transformations.erase(transformation_key);
}
void RaycastManager::actualize(const ModelObject *object, const 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});
// actualize MeshRaycaster
for (const ModelVolume *volume : object->volumes) {
size_t oid = volume->id().id;
if (skip != nullptr && skip->skip(oid))
continue;
auto item = m_raycasters.find(oid);
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()) {
// add new raycaster
auto raycaster = std::make_unique<MeshRaycaster>(volume->mesh());
m_raycasters.insert(std::make_pair(oid, std::move(raycaster)));
m_raycasters.emplace_back(std::make_pair(oid, std::move(raycaster)));
} else {
size_t index = item - m_raycasters.begin();
removed_casters[index] = false;
}
}
@ -98,17 +44,33 @@ void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
// 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 = m_transformations.find(tr_key);
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.insert(
m_transformations.emplace_back(
std::make_pair(tr_key, transformation));
}
}
}
// 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);
}
std::optional<RaycastManager::Hit> RaycastManager::unproject(
@ -130,7 +92,10 @@ std::optional<RaycastManager::Hit> RaycastManager::unproject(
size_t volume_id = key.second;
if (skip != nullptr && skip->skip(volume_id)) continue;
const Transform3d &transformation = item.second;
auto raycaster_it = m_raycasters.find(volume_id);
auto raycaster_it =
std::find_if(m_raycasters.begin(), m_raycasters.end(),
[volume_id](const RaycastManager::Raycaster &it)
-> bool { return volume_id == it.first; });
if (raycaster_it == m_raycasters.end()) continue;
const MeshRaycaster &raycaster = *(raycaster_it->second);
SurfacePoint surface_point;
@ -152,7 +117,11 @@ std::optional<RaycastManager::Hit> RaycastManager::unproject(
}
Slic3r::Transform3d RaycastManager::get_transformation(const TrKey &tr_key) const {
auto item = m_transformations.find(tr_key);
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()) return Transform3d::Identity();
return item->second;
}

View file

@ -17,13 +17,15 @@ namespace Slic3r::GUI{
/// </summary>
class RaycastManager
{
// ModelVolume
std::map<size_t, std::unique_ptr<MeshRaycaster>> m_raycasters;
// ModelVolume.id
using Raycaster = std::pair<size_t, std::unique_ptr<MeshRaycaster> >;
std::vector<Raycaster> m_raycasters;
// Key for transformation consist of unique volume and instance
// ModelInstance, ModelVolume
using TrKey = std::pair<size_t, size_t>;
std::map<TrKey, Transform3d> m_transformations;
using TrItem = std::pair<TrKey, Transform3d>;
std::vector<TrItem> m_transformations;
// should contain shared pointer to camera but it is not shared pointer so it need it every time when casts rays
@ -31,12 +33,6 @@ public:
class ISkip{
public:
virtual ~ISkip() = default;
/// <summary>
/// Condition to not process specific transformation
/// </summary>
/// <param name="key">Transformation key</param>
/// <returns>True on skip otherwise false</returns>
//virtual bool skip(const TrKey &key) const { return false; }
/// <summary>
/// Condition to not process model volume
@ -52,11 +48,8 @@ public:
/// Detection of removed instance
/// Detection of removed volume
/// </summary>
/// <param name="object">Model representation</param>
/// <param name="skip">Condifiton for skip actualization</param>
/// <param name="objects">Model representation</param>
void actualize(const ModelObjectPtrs &objects,
const ISkip * skip = nullptr);
void actualize(const ModelObject *object, const ISkip *skip = nullptr);
// TODO: it is more general object move outside of this class