mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 05:05:57 +08:00
Create text on second Part(volume) of object
This commit is contained in:
parent
936ba6c28c
commit
1078fe55ec
@ -103,6 +103,15 @@ struct FontItem
|
|||||||
wx_mac_font_descr // path is font descriptor generated by wxWidgets on windows
|
wx_mac_font_descr // path is font descriptor generated by wxWidgets on windows
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool operator==(const FontItem &other) const {
|
||||||
|
return
|
||||||
|
type == other.type &&
|
||||||
|
prop == other.prop &&
|
||||||
|
name == other.name &&
|
||||||
|
path == other.path
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
// undo / redo stack recovery
|
// undo / redo stack recovery
|
||||||
template<class Archive> void serialize(Archive &ar)
|
template<class Archive> void serialize(Archive &ar)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "libslic3r/AppConfig.hpp" // store/load font list
|
#include "libslic3r/AppConfig.hpp" // store/load font list
|
||||||
#include "libslic3r/MapUtils.hpp"
|
#include "libslic3r/MapUtils.hpp"
|
||||||
#include "libslic3r/Format/OBJ.hpp" // load obj file for default object
|
#include "libslic3r/Format/OBJ.hpp" // load obj file for default object
|
||||||
|
#include "libslic3r/BuildVolume.hpp"
|
||||||
|
|
||||||
#include "imgui/imgui_stdlib.h" // using std::string for inputs
|
#include "imgui/imgui_stdlib.h" // using std::string for inputs
|
||||||
#include "nanosvg/nanosvg.h" // load SVG file
|
#include "nanosvg/nanosvg.h" // load SVG file
|
||||||
@ -133,15 +134,28 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mous
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> object_idx;
|
std::optional<int> object_idx;
|
||||||
|
|
||||||
|
std::optional<Transform3d> hit_vol_tr;
|
||||||
const Selection &selection = m_parent.get_selection();
|
const Selection &selection = m_parent.get_selection();
|
||||||
if (!selection.is_empty()) object_idx = selection.get_object_idx();
|
if (!selection.is_empty()) {
|
||||||
auto data =
|
object_idx = selection.get_object_idx();
|
||||||
std::make_unique<EmbossDataCreate>(m_font_manager.get_font_file(),
|
int hovered_id = m_parent.get_first_hover_volume_idx();
|
||||||
create_configuration(),
|
if (hovered_id >= 0) {
|
||||||
create_volume_name(), volume_type,
|
GLVolume *gl_volume = m_parent.get_volumes().volumes[hovered_id];
|
||||||
screen_coor, object_idx,
|
hit_vol_tr = gl_volume->get_instance_transformation().get_matrix();
|
||||||
&m_raycast_manager);
|
}
|
||||||
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
}
|
||||||
|
Plater* plater = wxGetApp().plater();
|
||||||
|
const Camera &camera = plater->get_camera();
|
||||||
|
auto data = std::make_unique<EmbossDataCreate>(
|
||||||
|
m_font_manager.get_font_file(),
|
||||||
|
create_configuration(),
|
||||||
|
create_volume_name(), volume_type, screen_coor, object_idx,
|
||||||
|
hit_vol_tr, camera,
|
||||||
|
plater->build_volume().bed_shape(),
|
||||||
|
&m_raycast_manager);
|
||||||
|
|
||||||
|
auto &worker = plater->get_ui_job_worker();
|
||||||
queue_job(worker, std::make_unique<EmbossCreateJob>(std::move(data)));
|
queue_job(worker, std::make_unique<EmbossCreateJob>(std::move(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,14 +220,15 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
|||||||
// initialize raycasters
|
// initialize raycasters
|
||||||
// IMPROVE: move to job, for big scene it slows down
|
// IMPROVE: move to job, for big scene it slows down
|
||||||
ModelObject *act_model_object = act_model_volume->get_object();
|
ModelObject *act_model_object = act_model_volume->get_object();
|
||||||
m_raycast_manager.actualize({act_model_object}, &skip);
|
m_raycast_manager.actualize(act_model_object, &skip);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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());
|
||||||
Vec2d mouse_pos = mouse_coord.cast<double>();
|
Vec2d mouse_pos = mouse_coord.cast<double>();
|
||||||
auto hit = m_raycast_manager.unproject(mouse_pos, &skip);
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
|
auto hit = m_raycast_manager.unproject(mouse_pos, camera, &skip);
|
||||||
if (!hit.has_value()) {
|
if (!hit.has_value()) {
|
||||||
// there is no hit
|
// there is no hit
|
||||||
// show common translation of object
|
// show common translation of object
|
||||||
@ -325,7 +340,7 @@ void GLGizmoEmboss::on_render_for_picking() {
|
|||||||
void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
||||||
{
|
{
|
||||||
initialize();
|
initialize();
|
||||||
check_selection();
|
check_selection();
|
||||||
|
|
||||||
// TODO: fix width - showing scroll in first draw of advanced.
|
// TODO: fix width - showing scroll in first draw of advanced.
|
||||||
const ImVec2 &min_window_size = get_minimal_window_size();
|
const ImVec2 &min_window_size = get_minimal_window_size();
|
||||||
@ -480,6 +495,12 @@ void GLGizmoEmboss::initialize()
|
|||||||
cfg.max_style_image_width = cfg.max_font_name_width -
|
cfg.max_style_image_width = cfg.max_font_name_width -
|
||||||
2 * style.FramePadding.x;
|
2 * style.FramePadding.x;
|
||||||
|
|
||||||
|
// initialize default font
|
||||||
|
FontList default_font_list = create_default_font_list();
|
||||||
|
for (const FontItem &fi : default_font_list) {
|
||||||
|
assert(cfg.default_styles.find(fi.name) == cfg.default_styles.end());
|
||||||
|
cfg.default_styles[fi.name] = fi; // copy
|
||||||
|
}
|
||||||
m_gui_cfg.emplace(cfg);
|
m_gui_cfg.emplace(cfg);
|
||||||
|
|
||||||
// TODO: What to do when icon was NOT loaded? Generate them?
|
// TODO: What to do when icon was NOT loaded? Generate them?
|
||||||
@ -489,39 +510,28 @@ void GLGizmoEmboss::initialize()
|
|||||||
const AppConfig *app_cfg = wxGetApp().app_config;
|
const AppConfig *app_cfg = wxGetApp().app_config;
|
||||||
FontList font_list = load_font_list_from_app_config(app_cfg);
|
FontList font_list = load_font_list_from_app_config(app_cfg);
|
||||||
m_font_manager.add_fonts(font_list);
|
m_font_manager.add_fonts(font_list);
|
||||||
|
// TODO: select last session sellected font index
|
||||||
|
|
||||||
if (!m_font_manager.load_first_valid_font()) {
|
if (!m_font_manager.load_first_valid_font()) {
|
||||||
FontList font_list = create_default_font_list();
|
m_font_manager.add_fonts(default_font_list);
|
||||||
m_font_manager.add_fonts(font_list);
|
|
||||||
// TODO: What to do when default fonts are not loadable?
|
// TODO: What to do when default fonts are not loadable?
|
||||||
bool success = m_font_manager.load_first_valid_font();
|
bool success = m_font_manager.load_first_valid_font();
|
||||||
assert(success);
|
assert(success);
|
||||||
}
|
}
|
||||||
set_default_text();
|
set_default_text();
|
||||||
|
select_stored_font_item();
|
||||||
}
|
}
|
||||||
|
|
||||||
FontList GLGizmoEmboss::create_default_font_list()
|
FontList GLGizmoEmboss::create_default_font_list()
|
||||||
{
|
{
|
||||||
// https://docs.wxwidgets.org/3.0/classwx_font.html
|
// https://docs.wxwidgets.org/3.0/classwx_font.html
|
||||||
// Predefined objects/pointers: wxNullFont, wxNORMAL_FONT, wxSMALL_FONT, wxITALIC_FONT, wxSWISS_FONT
|
// Predefined objects/pointers: wxNullFont, wxNORMAL_FONT, wxSMALL_FONT, wxITALIC_FONT, wxSWISS_FONT
|
||||||
|
|
||||||
FontItem par_fi = WxFontUtils::get_font_item(*wxNORMAL_FONT, _u8L("Parallel to bed"));
|
|
||||||
|
|
||||||
FontItem perp_fi = WxFontUtils::get_font_item(*wxNORMAL_FONT, _u8L("Perpendicular to bed"));
|
|
||||||
|
|
||||||
FontItem fix_fi = WxFontUtils::get_font_item(*wxNORMAL_FONT, _u8L("Fixed size"));
|
|
||||||
|
|
||||||
FontItem negative_fi = WxFontUtils::get_font_item(*wxNORMAL_FONT, _u8L("Negative"));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
par_fi,
|
WxFontUtils::get_font_item(*wxNORMAL_FONT, _u8L("NORMAL")), // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
|
||||||
perp_fi,
|
WxFontUtils::get_font_item(*wxSMALL_FONT, _u8L("SMALL")), // A font using the wxFONTFAMILY_SWISS family and 2 points smaller than wxNORMAL_FONT.
|
||||||
fix_fi,
|
WxFontUtils::get_font_item(*wxITALIC_FONT, _u8L("ITALIC")), // A font using the wxFONTFAMILY_ROMAN family and wxFONTSTYLE_ITALIC style and of the same size of wxNORMAL_FONT.
|
||||||
negative_fi,
|
WxFontUtils::get_font_item(*wxSWISS_FONT, _u8L("SWISS")), // A font identic to wxNORMAL_FONT except for the family used which is wxFONTFAMILY_SWISS.
|
||||||
WxFontUtils::get_font_item(*wxNORMAL_FONT), // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
|
WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD), _u8L("MODERN"))
|
||||||
WxFontUtils::get_font_item(*wxSMALL_FONT), // A font using the wxFONTFAMILY_SWISS family and 2 points smaller than wxNORMAL_FONT.
|
|
||||||
WxFontUtils::get_font_item(*wxITALIC_FONT), // A font using the wxFONTFAMILY_ROMAN family and wxFONTSTYLE_ITALIC style and of the same size of wxNORMAL_FONT.
|
|
||||||
WxFontUtils::get_font_item(*wxSWISS_FONT), // A font identic to wxNORMAL_FONT except for the family used which is wxFONTFAMILY_SWISS.
|
|
||||||
WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD))
|
|
||||||
//, WxFontUtils::get_os_font() == wxNORMAL_FONT
|
//, WxFontUtils::get_os_font() == wxNORMAL_FONT
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -617,6 +627,18 @@ void GLGizmoEmboss::close()
|
|||||||
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoEmboss::select_stored_font_item()
|
||||||
|
{
|
||||||
|
const std::string &name = m_font_manager.get_font_item().name;
|
||||||
|
const auto &styles = m_gui_cfg->default_styles;
|
||||||
|
const auto &it = styles.find(name);
|
||||||
|
if (it == styles.end()) {
|
||||||
|
m_stored_font_item.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_stored_font_item = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_window()
|
void GLGizmoEmboss::draw_window()
|
||||||
{
|
{
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
@ -899,6 +921,7 @@ void GLGizmoEmboss::draw_rename_style(bool start_rename)
|
|||||||
m_font_manager.get_truncated_name() = "";
|
m_font_manager.get_truncated_name() = "";
|
||||||
m_font_manager.free_style_images();
|
m_font_manager.free_style_images();
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
|
select_stored_font_item();
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
@ -936,7 +959,10 @@ void GLGizmoEmboss::draw_style_list() {
|
|||||||
const FontManager::StyleImage &img = *item.image;
|
const FontManager::StyleImage &img = *item.image;
|
||||||
ImVec2 select_size(0.f, std::max(img.tex_size.y, m_gui_cfg->min_style_image_height));
|
ImVec2 select_size(0.f, std::max(img.tex_size.y, m_gui_cfg->min_style_image_height));
|
||||||
if (ImGui::Selectable("##style_select", is_selected, flags, select_size)) {
|
if (ImGui::Selectable("##style_select", is_selected, flags, select_size)) {
|
||||||
if (m_font_manager.load_font(index)) process();
|
if (m_font_manager.load_font(index)) {
|
||||||
|
process();
|
||||||
|
select_stored_font_item();
|
||||||
|
}
|
||||||
} else if (ImGui::IsItemHovered())
|
} else if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("%s", actual_style_name.c_str());
|
ImGui::SetTooltip("%s", actual_style_name.c_str());
|
||||||
|
|
||||||
@ -991,9 +1017,10 @@ void GLGizmoEmboss::draw_style_list() {
|
|||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("%s", _u8L("Duplicate style.").c_str());
|
ImGui::SetTooltip("%s", _u8L("Duplicate style.").c_str());
|
||||||
|
|
||||||
|
|
||||||
// TODO: Is style changed against stored one
|
// TODO: Is style changed against stored one
|
||||||
bool is_changed = false;
|
bool is_stored = m_stored_font_item.has_value();
|
||||||
|
bool is_changed = (is_stored) ?
|
||||||
|
!(*m_stored_font_item == m_font_manager.get_font_item()) : true;
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (draw_button(IconType::save, !is_changed)) {
|
if (draw_button(IconType::save, !is_changed)) {
|
||||||
@ -1025,7 +1052,10 @@ void GLGizmoEmboss::draw_style_list() {
|
|||||||
m_font_manager.add_fonts(font_list);
|
m_font_manager.add_fonts(font_list);
|
||||||
// TODO: What to do when default fonts are not loadable?
|
// TODO: What to do when default fonts are not loadable?
|
||||||
bool success = m_font_manager.load_first_valid_font();
|
bool success = m_font_manager.load_first_valid_font();
|
||||||
|
select_stored_font_item();
|
||||||
}
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip("%s", _u8L("Revert all styles").c_str());
|
||||||
#endif // ALLOW_REVERT_ALL_STYLES
|
#endif // ALLOW_REVERT_ALL_STYLES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "libslic3r/Emboss.hpp"
|
#include "libslic3r/Emboss.hpp"
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
|
#include "libslic3r/TextConfiguration.hpp"
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
@ -148,6 +149,9 @@ private:
|
|||||||
std::string depth;
|
std::string depth;
|
||||||
};
|
};
|
||||||
Translations translations;
|
Translations translations;
|
||||||
|
|
||||||
|
std::map<std::string, FontItem> default_styles;
|
||||||
|
|
||||||
GuiCfg() = default;
|
GuiCfg() = default;
|
||||||
};
|
};
|
||||||
std::optional<const GuiCfg> m_gui_cfg;
|
std::optional<const GuiCfg> m_gui_cfg;
|
||||||
@ -157,7 +161,8 @@ private:
|
|||||||
bool m_is_advanced_edit_style = false;
|
bool m_is_advanced_edit_style = false;
|
||||||
|
|
||||||
FontManager m_font_manager;
|
FontManager m_font_manager;
|
||||||
|
std::optional<FontItem> m_stored_font_item;
|
||||||
|
void select_stored_font_item();
|
||||||
//FontList m_font_list;
|
//FontList m_font_list;
|
||||||
//size_t m_font_selected;// index to m_font_list
|
//size_t m_font_selected;// index to m_font_list
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <libslic3r/Model.hpp>
|
#include <libslic3r/Model.hpp>
|
||||||
#include <libslic3r/Format/OBJ.hpp> // load_obj for default mesh
|
#include <libslic3r/Format/OBJ.hpp> // load_obj for default mesh
|
||||||
#include <libslic3r/BuildVolume.hpp>
|
|
||||||
|
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
#include "slic3r/GUI/NotificationManager.hpp"
|
#include "slic3r/GUI/NotificationManager.hpp"
|
||||||
@ -102,15 +101,13 @@ void EmbossCreateJob::process(Ctl &ctl) {
|
|||||||
if (m_result.its.empty()) m_result = create_default_mesh();
|
if (m_result.its.empty()) m_result = create_default_mesh();
|
||||||
if (ctl.was_canceled()) return;
|
if (ctl.was_canceled()) return;
|
||||||
|
|
||||||
Plater * plater = wxGetApp().plater(); // may be move to input
|
|
||||||
|
|
||||||
std::optional<RaycastManager::Hit> hit;
|
std::optional<RaycastManager::Hit> hit;
|
||||||
if (m_input->object_idx.has_value()) {
|
if (m_input->object_idx.has_value()) {
|
||||||
// By position of cursor create transformation to put text on surface of model
|
// By position of cursor create transformation to put text on surface of model
|
||||||
const ModelObjectPtrs &objects = wxGetApp().plater()->model().objects;
|
ModelObject *obj = wxGetApp().plater()->model().objects[*m_input->object_idx];
|
||||||
m_input->raycast_manager->actualize(objects);
|
m_input->raycast_manager->actualize(obj);
|
||||||
if (ctl.was_canceled()) return;
|
if (ctl.was_canceled()) return;
|
||||||
hit = m_input->raycast_manager->unproject(m_input->screen_coor);
|
hit = m_input->raycast_manager->unproject(m_input->screen_coor, m_input->camera);
|
||||||
|
|
||||||
// context menu for add text could be open only by right click on an
|
// context menu for add text could be open only by right click on an
|
||||||
// object. After right click, object is selected and object_idx is set
|
// object. After right click, object is selected and object_idx is set
|
||||||
@ -123,14 +120,12 @@ void EmbossCreateJob::process(Ctl &ctl) {
|
|||||||
// create new object
|
// create new object
|
||||||
// calculate X,Y offset position for lay on platter in place of
|
// calculate X,Y offset position for lay on platter in place of
|
||||||
// mouse click
|
// mouse click
|
||||||
const Camera &camera = plater->get_camera();
|
Vec2d bed_coor = CameraUtils::get_z0_position(m_input->camera, m_input->screen_coor);
|
||||||
Vec2d bed_coor = CameraUtils::get_z0_position(camera, m_input->screen_coor);
|
|
||||||
|
|
||||||
// check point is on build plate:
|
// check point is on build plate:
|
||||||
Pointfs bed_shape = plater->build_volume().bed_shape();
|
|
||||||
Points bed_shape_;
|
Points bed_shape_;
|
||||||
bed_shape_.reserve(bed_shape.size());
|
bed_shape_.reserve(m_input->bed_shape.size());
|
||||||
for (const Vec2d &p : bed_shape)
|
for (const Vec2d &p : m_input->bed_shape)
|
||||||
bed_shape_.emplace_back(p.cast<int>());
|
bed_shape_.emplace_back(p.cast<int>());
|
||||||
Polygon bed(bed_shape_);
|
Polygon bed(bed_shape_);
|
||||||
if (!bed.contains(bed_coor.cast<int>()))
|
if (!bed.contains(bed_coor.cast<int>()))
|
||||||
@ -143,8 +138,13 @@ void EmbossCreateJob::process(Ctl &ctl) {
|
|||||||
Transform3d::TranslationType tt(offset.x(), offset.y(), offset.z());
|
Transform3d::TranslationType tt(offset.x(), offset.y(), offset.z());
|
||||||
m_transformation = Transform3d(tt);
|
m_transformation = Transform3d(tt);
|
||||||
} else {
|
} else {
|
||||||
m_transformation = Emboss::create_transformation_onto_surface(
|
// TODO: Disable apply common transformation after draggig
|
||||||
hit->position, hit->normal);
|
// Call after is used for apply transformation after common dragging to rewrite it
|
||||||
|
m_transformation = Emboss::create_transformation_onto_surface(hit->position, hit->normal);
|
||||||
|
if (m_input->hit_vol_tr.has_value()) {
|
||||||
|
Transform3d object_trmat = m_input->raycast_manager->get_transformation(hit->tr_key);
|
||||||
|
m_transformation = m_input->hit_vol_tr->inverse() * object_trmat * m_transformation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <libslic3r/Emboss.hpp>
|
#include <libslic3r/Emboss.hpp>
|
||||||
#include <libslic3r/ModelVolumeType.hpp>
|
#include <libslic3r/ModelVolumeType.hpp>
|
||||||
#include "slic3r/Utils/RaycastManager.hpp"
|
#include "slic3r/Utils/RaycastManager.hpp"
|
||||||
|
#include "slic3r/GUI/Camera.hpp"
|
||||||
#include "Job.hpp"
|
#include "Job.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
@ -110,6 +111,15 @@ struct EmbossDataCreate: public EmbossDataBase
|
|||||||
// when exist ModelObject where to create volume
|
// when exist ModelObject where to create volume
|
||||||
std::optional<int> object_idx;
|
std::optional<int> object_idx;
|
||||||
|
|
||||||
|
// hitted instance transformation
|
||||||
|
std::optional<Transform3d> hit_vol_tr;
|
||||||
|
|
||||||
|
// projection property
|
||||||
|
Camera camera;
|
||||||
|
|
||||||
|
// shape of bed in case of create volume on bed
|
||||||
|
std::vector<Vec2d> bed_shape;
|
||||||
|
|
||||||
// used to find point on surface where to create new object
|
// used to find point on surface where to create new object
|
||||||
RaycastManager *raycast_manager;
|
RaycastManager *raycast_manager;
|
||||||
// It is inside of GLGizmoEmboss object,
|
// It is inside of GLGizmoEmboss object,
|
||||||
@ -121,11 +131,17 @@ struct EmbossDataCreate: public EmbossDataBase
|
|||||||
ModelVolumeType volume_type,
|
ModelVolumeType volume_type,
|
||||||
Vec2d screen_coor,
|
Vec2d screen_coor,
|
||||||
std::optional<int> object_idx,
|
std::optional<int> object_idx,
|
||||||
|
const std::optional<Transform3d>& hit_vol_tr,
|
||||||
|
const Camera& camera,
|
||||||
|
const std::vector<Vec2d> & bed_shape,
|
||||||
RaycastManager * raycast_manager)
|
RaycastManager * raycast_manager)
|
||||||
: EmbossDataBase(std::move(font_file), text_configuration, volume_name)
|
: EmbossDataBase(std::move(font_file), text_configuration, volume_name)
|
||||||
, volume_type(volume_type)
|
, volume_type(volume_type)
|
||||||
, screen_coor(screen_coor)
|
, screen_coor(screen_coor)
|
||||||
, object_idx(object_idx)
|
, object_idx(object_idx)
|
||||||
|
, hit_vol_tr(hit_vol_tr)
|
||||||
|
, camera(camera)
|
||||||
|
, bed_shape(bed_shape)
|
||||||
, raycast_manager(raycast_manager)
|
, raycast_manager(raycast_manager)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -73,8 +73,45 @@ void RaycastManager::actualize(const ModelObjectPtrs &objects,
|
|||||||
transformations.erase(transformation_key);
|
transformations.erase(transformation_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RaycastManager::actualize(const ModelObject *object, const ISkip *skip)
|
||||||
|
{
|
||||||
|
// actualize MeshRaycaster
|
||||||
|
for (const ModelVolume *volume : object->volumes) {
|
||||||
|
size_t oid = volume->id().id;
|
||||||
|
if (skip != nullptr && skip->skip(oid))
|
||||||
|
continue;
|
||||||
|
auto item = raycasters.find(oid);
|
||||||
|
if (item == raycasters.end()) {
|
||||||
|
// add new raycaster
|
||||||
|
auto raycaster = std::make_unique<MeshRaycaster>(volume->mesh());
|
||||||
|
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 = transformations.find(tr_key);
|
||||||
|
if (item != transformations.end()) {
|
||||||
|
// actualize transformation all the time
|
||||||
|
item->second = transformation;
|
||||||
|
} else {
|
||||||
|
// add new transformation
|
||||||
|
transformations.insert(std::make_pair(tr_key, transformation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<RaycastManager::Hit> RaycastManager::unproject(
|
std::optional<RaycastManager::Hit> RaycastManager::unproject(
|
||||||
const Vec2d &mouse_pos, const ISkip *skip) const
|
const Vec2d &mouse_pos, const Camera &camera, const ISkip *skip) const
|
||||||
{
|
{
|
||||||
struct HitWithDistance: public Hit
|
struct HitWithDistance: public Hit
|
||||||
{
|
{
|
||||||
@ -87,8 +124,6 @@ std::optional<RaycastManager::Hit> RaycastManager::unproject(
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
std::optional<HitWithDistance> closest;
|
std::optional<HitWithDistance> closest;
|
||||||
|
|
||||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
|
||||||
for (const auto &item : transformations) {
|
for (const auto &item : transformations) {
|
||||||
const TrKey &key = item.first;
|
const TrKey &key = item.first;
|
||||||
size_t volume_id = key.second;
|
size_t volume_id = key.second;
|
||||||
|
@ -53,6 +53,8 @@ public:
|
|||||||
void actualize(const ModelObjectPtrs &objects,
|
void actualize(const ModelObjectPtrs &objects,
|
||||||
const ISkip * skip = nullptr);
|
const ISkip * skip = nullptr);
|
||||||
|
|
||||||
|
void actualize(const ModelObject *object, 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
|
||||||
{
|
{
|
||||||
@ -85,9 +87,11 @@ public:
|
|||||||
/// Note: Function use current camera position from wxGetApp()
|
/// Note: Function use current camera position from wxGetApp()
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mouse_pos">Position of mouse on screen</param>
|
/// <param name="mouse_pos">Position of mouse on screen</param>
|
||||||
|
/// <param name="camera">Projection params</param>
|
||||||
/// <param name="skip">Define which caster will be skipped, null mean no skip</param>
|
/// <param name="skip">Define which caster will be skipped, null mean no skip</param>
|
||||||
/// <returns>Position on surface, normal direction and transformation key, which define hitted object instance</returns>
|
/// <returns>Position on surface, normal direction and transformation key, which define hitted object instance</returns>
|
||||||
std::optional<Hit> unproject(const Vec2d &mouse_pos,
|
std::optional<Hit> unproject(const Vec2d &mouse_pos,
|
||||||
|
const Camera &camera,
|
||||||
const ISkip *skip = nullptr) const;
|
const ISkip *skip = nullptr) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user