mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 04:05:52 +08:00
Create emboss object on cursor position
This commit is contained in:
parent
ed818f9177
commit
53ee0092b0
@ -72,3 +72,29 @@ Slic3r::Polygon CameraUtils::create_hull2d(const Camera & camera,
|
|||||||
Points vertices_2d = project(camera, vertices);
|
Points vertices_2d = project(camera, vertices);
|
||||||
return Geometry::convex_hull(vertices_2d);
|
return Geometry::convex_hull(vertices_2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <igl/unproject.h>
|
||||||
|
Vec3d CameraUtils::create_ray(const Camera &camera, const Vec2d &coor) {
|
||||||
|
Matrix4d modelview = camera.get_view_matrix().matrix();
|
||||||
|
Matrix4d projection = camera.get_projection_matrix().matrix();
|
||||||
|
Vec4i viewport(camera.get_viewport().data());
|
||||||
|
|
||||||
|
Vec3d scene_point(coor.x(), viewport[3] - coor.y(), 0.);
|
||||||
|
Vec3d unprojected_point;
|
||||||
|
igl::unproject(scene_point, modelview, projection, viewport, unprojected_point);
|
||||||
|
|
||||||
|
Vec3d p0 = camera.get_position();
|
||||||
|
Vec3d dir = unprojected_point - p0;
|
||||||
|
dir.normalize();
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2d CameraUtils::get_z0_position(const Camera &camera, const Vec2d & coor)
|
||||||
|
{
|
||||||
|
Vec3d dir = CameraUtils::create_ray(camera, coor);
|
||||||
|
Vec3d p0 = camera.get_position();
|
||||||
|
// find position of ray cross plane(z = 0)
|
||||||
|
double t = p0.z() / dir.z();
|
||||||
|
Vec3d p = p0 - t * dir;
|
||||||
|
return Vec2d(p.x(), p.y());
|
||||||
|
}
|
||||||
|
@ -33,6 +33,23 @@ public:
|
|||||||
/// <param name="volume">Outline by 3d object</param>
|
/// <param name="volume">Outline by 3d object</param>
|
||||||
/// <returns>Polygon around object</returns>
|
/// <returns>Polygon around object</returns>
|
||||||
static Polygon create_hull2d(const Camera &camera, const GLVolume &volume);
|
static Polygon create_hull2d(const Camera &camera, const GLVolume &volume);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unproject screen coordinate to scene direction start from camera position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="camera">Projection params</param>
|
||||||
|
/// <param name="coor">Coordinate on screen</param>
|
||||||
|
/// <returns>Scene direction</returns>
|
||||||
|
static Vec3d create_ray(const Camera &camera, const Vec2d &coor);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unproject mouse coordinate to get position in space where z coor is zero
|
||||||
|
/// Platter surface should be in z == 0
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="camera">Projection params</param>
|
||||||
|
/// <param name="coor">Mouse position</param>
|
||||||
|
/// <returns>Position on platter under mouse</returns>
|
||||||
|
static Vec2d get_z0_position(const Camera &camera, const Vec2d &coor);
|
||||||
|
|
||||||
};
|
};
|
||||||
} // Slic3r::GUI
|
} // Slic3r::GUI
|
||||||
|
@ -488,13 +488,18 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
|
|||||||
GLCanvas3D * canvas = plater()->canvas3D();
|
GLCanvas3D * canvas = plater()->canvas3D();
|
||||||
GLGizmosManager &mng = canvas->get_gizmos_manager();
|
GLGizmosManager &mng = canvas->get_gizmos_manager();
|
||||||
if ((mng.get_current_type() == GLGizmosManager::Emboss ||
|
if ((mng.get_current_type() == GLGizmosManager::Emboss ||
|
||||||
mng.open_gizmo(GLGizmosManager::Emboss)) &&
|
mng.open_gizmo(GLGizmosManager::Emboss))) {
|
||||||
type != ModelVolumeType::INVALID) {
|
|
||||||
GLGizmoEmboss *emboss = dynamic_cast<GLGizmoEmboss *>(mng.get_current());
|
GLGizmoEmboss *emboss = dynamic_cast<GLGizmoEmboss *>(mng.get_current());
|
||||||
|
assert(emboss != nullptr);
|
||||||
if (emboss == nullptr) return;
|
if (emboss == nullptr) return;
|
||||||
auto screen_position = canvas->get_popup_menu_position();
|
auto screen_position = canvas->get_popup_menu_position();
|
||||||
assert(screen_position.has_value());
|
assert(screen_position.has_value());
|
||||||
emboss->create_volume(type, *screen_position);
|
if(!screen_position.has_value()) return;
|
||||||
|
ModelVolumeType volume_type = type;
|
||||||
|
// no selected object means create new object
|
||||||
|
if (volume_type == ModelVolumeType::INVALID)
|
||||||
|
volume_type = ModelVolumeType::MODEL_PART;
|
||||||
|
emboss->create_volume(volume_type, *screen_position);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1750,7 +1750,12 @@ void ObjectList::load_shape_object_from_gallery(const wxArrayString& input_files
|
|||||||
wxGetApp().mainframe->update_title();
|
wxGetApp().mainframe->update_title();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center, const TextConfiguration* text_config/* = nullptr*/)
|
void ObjectList::load_mesh_object(
|
||||||
|
const TriangleMesh & mesh,
|
||||||
|
const wxString & name,
|
||||||
|
bool center,
|
||||||
|
const TextConfiguration *text_config /* = nullptr*/,
|
||||||
|
const Transform3d * transformation /* = nullptr*/)
|
||||||
{
|
{
|
||||||
// Add mesh to model as a new object
|
// Add mesh to model as a new object
|
||||||
Model& model = wxGetApp().plater()->model();
|
Model& model = wxGetApp().plater()->model();
|
||||||
@ -1760,7 +1765,6 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
|
|||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
std::vector<size_t> object_idxs;
|
std::vector<size_t> object_idxs;
|
||||||
auto bb = mesh.bounding_box();
|
|
||||||
ModelObject* new_object = model.add_object();
|
ModelObject* new_object = model.add_object();
|
||||||
new_object->name = into_u8(name);
|
new_object->name = into_u8(name);
|
||||||
new_object->add_instance(); // each object should have at list one instance
|
new_object->add_instance(); // each object should have at list one instance
|
||||||
@ -1773,11 +1777,17 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name
|
|||||||
// set a default extruder value, since user can't add it manually
|
// set a default extruder value, since user can't add it manually
|
||||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
new_object->invalidate_bounding_box();
|
new_object->invalidate_bounding_box();
|
||||||
new_object->translate(-bb.center());
|
if (transformation) {
|
||||||
|
assert(!center);
|
||||||
new_object->instances[0]->set_offset(center ?
|
Slic3r::Geometry::Transformation tr(*transformation);
|
||||||
to_3d(wxGetApp().plater()->build_volume().bounding_volume2d().center(), -new_object->origin_translation.z()) :
|
new_object->instances[0]->set_transformation(tr);
|
||||||
|
} else {
|
||||||
|
auto bb = mesh.bounding_box();
|
||||||
|
new_object->translate(-bb.center());
|
||||||
|
new_object->instances[0]->set_offset(
|
||||||
|
center ? to_3d(wxGetApp().plater()->build_volume().bounding_volume2d().center(), -new_object->origin_translation.z()) :
|
||||||
bb.center());
|
bb.center());
|
||||||
|
}
|
||||||
|
|
||||||
new_object->ensure_on_bed();
|
new_object->ensure_on_bed();
|
||||||
|
|
||||||
|
@ -257,7 +257,8 @@ public:
|
|||||||
void load_shape_object(const std::string &type_name);
|
void load_shape_object(const std::string &type_name);
|
||||||
void load_shape_object_from_gallery();
|
void load_shape_object_from_gallery();
|
||||||
void load_shape_object_from_gallery(const wxArrayString& input_files);
|
void load_shape_object_from_gallery(const wxArrayString& input_files);
|
||||||
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true, const TextConfiguration* text_config = nullptr);
|
void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true,
|
||||||
|
const TextConfiguration* text_config = nullptr, const Transform3d* transformation = nullptr);
|
||||||
void del_object(const int obj_idx);
|
void del_object(const int obj_idx);
|
||||||
void del_subobject_item(wxDataViewItem& item);
|
void del_subobject_item(wxDataViewItem& item);
|
||||||
void del_settings_from_config(const wxDataViewItem& parent_item);
|
void del_settings_from_config(const wxDataViewItem& parent_item);
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#define ALLOW_ADD_FONT_BY_OS_SELECTOR
|
#define ALLOW_ADD_FONT_BY_OS_SELECTOR
|
||||||
#define SHOW_IMGUI_ATLAS
|
#define SHOW_IMGUI_ATLAS
|
||||||
#define SHOW_FINE_POSITION
|
#define SHOW_FINE_POSITION
|
||||||
|
#define DRAW_PLACE_TO_ADD_TEXT
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // ALLOW_DEBUG_MODE
|
||||||
|
|
||||||
#define ALLOW_ADD_FONT_BY_FILE
|
#define ALLOW_ADD_FONT_BY_FILE
|
||||||
@ -89,7 +90,7 @@ void GLGizmoEmboss::set_fine_position()
|
|||||||
ImGuiWrapper::draw(rect);
|
ImGuiWrapper::draw(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef SHOW_FINE_POSITION
|
||||||
static void draw_fine_position(const Selection &selection)
|
static void draw_fine_position(const Selection &selection)
|
||||||
{
|
{
|
||||||
const Selection::IndicesList indices = selection.get_volume_idxs();
|
const Selection::IndicesList indices = selection.get_volume_idxs();
|
||||||
@ -111,38 +112,110 @@ static void draw_fine_position(const Selection &selection)
|
|||||||
ImGuiWrapper::draw(hull);
|
ImGuiWrapper::draw(hull);
|
||||||
ImGuiWrapper::draw(rect);
|
ImGuiWrapper::draw(rect);
|
||||||
}
|
}
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // SHOW_FINE_POSITION
|
||||||
|
|
||||||
|
#include "libslic3r/BuildVolume.hpp"
|
||||||
void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos)
|
void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos)
|
||||||
{
|
{
|
||||||
assert(volume_type == ModelVolumeType::MODEL_PART ||
|
assert(volume_type == ModelVolumeType::MODEL_PART ||
|
||||||
volume_type == ModelVolumeType::NEGATIVE_VOLUME ||
|
volume_type == ModelVolumeType::NEGATIVE_VOLUME ||
|
||||||
volume_type == ModelVolumeType::PARAMETER_MODIFIER);
|
volume_type == ModelVolumeType::PARAMETER_MODIFIER);
|
||||||
|
|
||||||
if (!m_is_initialized) initialize();
|
if (!m_is_initialized) initialize();
|
||||||
const Selection &selection = m_parent.get_selection();
|
std::shared_ptr<Emboss::FontFile> &font_file = m_font_manager.get_font_file();
|
||||||
if(selection.is_empty()) return;
|
|
||||||
|
|
||||||
set_default_text();
|
set_default_text();
|
||||||
|
|
||||||
// By position of cursor create transformation to put text on surface of model
|
Vec2d screen_coor = mouse_pos;
|
||||||
Transform3d transformation;
|
if (mouse_pos.x() < 0 || mouse_pos.y() < 0) {
|
||||||
const ModelObjectPtrs &objects = wxGetApp().plater()->model().objects;
|
// use center of screen
|
||||||
m_raycast_manager.actualize(objects);
|
auto screen_size = m_parent.get_canvas_size();
|
||||||
auto hit = m_raycast_manager.unproject(mouse_pos);
|
screen_coor.x() = screen_size.get_width() / 2.;
|
||||||
if (hit.has_value()) {
|
screen_coor.y() = screen_size.get_height() / 2.;
|
||||||
transformation = Emboss::create_transformation_onto_surface(hit->position, hit->normal);
|
|
||||||
} else {
|
|
||||||
// there is no hit with object
|
|
||||||
// TODO: calculate X,Y offset position for lay on platter by mouse position
|
|
||||||
transformation = Transform3d::Identity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_emboss_volume(create_mesh(), transformation, create_volume_name(),
|
std::optional<int> object_idx;
|
||||||
create_configuration(), volume_type,
|
const Selection &selection = m_parent.get_selection();
|
||||||
selection.get_object_idx());
|
if (!selection.is_empty()) object_idx = selection.get_object_idx();
|
||||||
|
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
||||||
|
queue_job( worker, [volume_type,
|
||||||
|
screen_coor,
|
||||||
|
object_idx,
|
||||||
|
ff = font_file,
|
||||||
|
text = m_text,
|
||||||
|
&raycast_manager = m_raycast_manager,
|
||||||
|
name = create_volume_name(),
|
||||||
|
tc = create_configuration(),
|
||||||
|
fi = m_font_manager.get_font_item()
|
||||||
|
](Job::Ctl &ctl) {
|
||||||
|
// It is neccessary to create some shape
|
||||||
|
// Emboss text window is opened by creation new embosstext object
|
||||||
|
TriangleMesh tm = (ff == nullptr) ?
|
||||||
|
create_default_mesh() :
|
||||||
|
create_mesh(text.c_str(), *ff, fi.prop);
|
||||||
|
if (tm.its.empty()) tm = create_default_mesh();
|
||||||
|
if (ctl.was_canceled()) return;
|
||||||
|
|
||||||
|
std::optional<RaycastManager::Hit> hit;
|
||||||
|
if (object_idx.has_value()) {
|
||||||
|
// By position of cursor create transformation to put text on surface of model
|
||||||
|
const ModelObjectPtrs &objects = wxGetApp().plater()->model().objects;
|
||||||
|
raycast_manager.actualize(objects);
|
||||||
|
if (ctl.was_canceled()) return;
|
||||||
|
hit = raycast_manager.unproject(screen_coor);
|
||||||
|
|
||||||
|
// 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 also hit must exist.
|
||||||
|
// But there is proper behavior when hit doesn't exists.
|
||||||
|
// When this assert appear distquish remove of it.
|
||||||
|
assert(hit.has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hit.has_value()) {
|
||||||
|
// create new object
|
||||||
|
// calculate X,Y offset position for lay on platter in place of
|
||||||
|
// mouse click
|
||||||
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
|
Vec2d bed_coor = CameraUtils::get_z0_position(camera, screen_coor);
|
||||||
|
|
||||||
|
// check point is on build plate:
|
||||||
|
Pointfs bed_shape = wxGetApp().plater()->build_volume().bed_shape();
|
||||||
|
Points bed_shape_;
|
||||||
|
bed_shape_.reserve(bed_shape.size());
|
||||||
|
for (const Vec2d &p : bed_shape)
|
||||||
|
bed_shape_.emplace_back(p.cast<int>());
|
||||||
|
Polygon bed(bed_shape_);
|
||||||
|
if (!bed.contains(bed_coor.cast<int>()))
|
||||||
|
// mouse pose is out of build plate so create object in center of plate
|
||||||
|
bed_coor = bed.centroid().cast<double>();
|
||||||
|
|
||||||
|
double z = tc.font_item.prop.emboss / 2;
|
||||||
|
Vec3d offset(bed_coor.x(), bed_coor.y(), z);
|
||||||
|
offset -= tm.center();
|
||||||
|
Transform3d::TranslationType tt(offset.x(), offset.y(), offset.z());
|
||||||
|
Transform3d trmat(tt);
|
||||||
|
create_emboss_object(std::move(tm), trmat, name, tc);
|
||||||
|
// Gizmo will open when successfuly create new object
|
||||||
|
// Gizmo can't be open when selection is empty
|
||||||
|
} else {
|
||||||
|
Transform3d transformation = Emboss::create_transformation_onto_surface(hit->position, hit->normal);
|
||||||
|
create_emboss_volume(std::move(tm), transformation, name, tc, volume_type, *object_idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRAW_PLACE_TO_ADD_TEXT
|
||||||
|
static void draw_place_to_add_text() {
|
||||||
|
ImVec2 mp = ImGui::GetMousePos();
|
||||||
|
Vec2d mouse_pos(mp.x, mp.y);
|
||||||
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
|
Vec3d p1 = CameraUtils::get_z0_position(camera, mouse_pos);
|
||||||
|
std::vector<Vec3d> rect3d{p1 + Vec3d(5, 5, 0), p1 + Vec3d(-5, 5, 0),
|
||||||
|
p1 + Vec3d(-5, -5, 0), p1 + Vec3d(5, -5, 0)};
|
||||||
|
Points rect2d = CameraUtils::project(camera, rect3d);
|
||||||
|
ImGuiWrapper::draw(Slic3r::Polygon(rect2d));
|
||||||
|
}
|
||||||
|
#endif // DRAW_PLACE_TO_ADD_TEXT
|
||||||
|
|
||||||
|
|
||||||
bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event)
|
bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event)
|
||||||
{
|
{
|
||||||
if (mouse_event.Dragging()) {
|
if (mouse_event.Dragging()) {
|
||||||
@ -319,6 +392,10 @@ void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
|||||||
// draw suggested position of window
|
// draw suggested position of window
|
||||||
draw_fine_position(m_parent.get_selection());
|
draw_fine_position(m_parent.get_selection());
|
||||||
#endif // SHOW_FINE_POSITION
|
#endif // SHOW_FINE_POSITION
|
||||||
|
#ifdef DRAW_PLACE_TO_ADD_TEXT
|
||||||
|
draw_place_to_add_text();
|
||||||
|
#endif // DRAW_PLACE_TO_ADD_TEXT
|
||||||
|
|
||||||
|
|
||||||
// check if is set window offset
|
// check if is set window offset
|
||||||
if (m_set_window_offset.has_value()) {
|
if (m_set_window_offset.has_value()) {
|
||||||
@ -375,18 +452,6 @@ void GLGizmoEmboss::on_set_state()
|
|||||||
// to reload fonts from system, when install new one
|
// to reload fonts from system, when install new one
|
||||||
wxFontEnumerator::InvalidateCache();
|
wxFontEnumerator::InvalidateCache();
|
||||||
|
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
bool create_new_object = selection.is_empty();
|
|
||||||
// When add Text on empty plate, Create new object with volume
|
|
||||||
if (create_new_object) {
|
|
||||||
set_default_text();
|
|
||||||
create_emboss_object(create_mesh(), create_volume_name(), create_configuration());
|
|
||||||
|
|
||||||
// gizmo will open when successfuly create new object
|
|
||||||
GLGizmoBase::m_state = GLGizmoBase::Off;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try(when exist) set configuration by volume
|
// Try(when exist) set configuration by volume
|
||||||
load_configuration(get_selected_volume());
|
load_configuration(get_selected_volume());
|
||||||
|
|
||||||
@ -395,7 +460,7 @@ void GLGizmoEmboss::on_set_state()
|
|||||||
|
|
||||||
// when open by hyperlink it needs to show up
|
// when open by hyperlink it needs to show up
|
||||||
// or after key 'T' windows doesn't appear
|
// or after key 'T' windows doesn't appear
|
||||||
m_parent.reload_scene(true);
|
m_parent.set_as_dirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +579,7 @@ Slic3r::TriangleMesh GLGizmoEmboss::create_mesh()
|
|||||||
// Emboss text window is opened by creation new embosstext object
|
// Emboss text window is opened by creation new embosstext object
|
||||||
std::shared_ptr<Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
std::shared_ptr<Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
||||||
if (font_file == nullptr) return create_default_mesh();
|
if (font_file == nullptr) return create_default_mesh();
|
||||||
const FontItem &fi = m_font_manager.get_font_item();
|
const FontItem &fi = m_font_manager.get_font_item();
|
||||||
TriangleMesh result = create_mesh(m_text.c_str(), *font_file, fi.prop);
|
TriangleMesh result = create_mesh(m_text.c_str(), *font_file, fi.prop);
|
||||||
if (result.its.empty()) return create_default_mesh();
|
if (result.its.empty()) return create_default_mesh();
|
||||||
return result;
|
return result;
|
||||||
@ -652,15 +717,8 @@ void GLGizmoEmboss::draw_window()
|
|||||||
m_imgui->disabled_begin(!exist_font_file);
|
m_imgui->disabled_begin(!exist_font_file);
|
||||||
if (m_volume == nullptr) {
|
if (m_volume == nullptr) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(_u8L("Generate preview").c_str())) {
|
if (ImGui::Button(_u8L("Generate object").c_str()))
|
||||||
const Selection &s = m_parent.get_selection();
|
create_volume(ModelVolumeType::MODEL_PART);
|
||||||
auto selected_indices = s.get_instance_idxs();
|
|
||||||
if (selected_indices.empty()) {
|
|
||||||
create_emboss_object(create_mesh(), create_volume_name(), create_configuration());
|
|
||||||
} else {
|
|
||||||
create_volume(ModelVolumeType::MODEL_PART);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_imgui->disabled_end();
|
m_imgui->disabled_end();
|
||||||
|
|
||||||
@ -1238,6 +1296,7 @@ const ImVec2 &GLGizmoEmboss::get_minimal_window_size() const
|
|||||||
m_gui_cfg->minimal_window_size;
|
m_gui_cfg->minimal_window_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ALLOW_ADD_FONT_BY_OS_SELECTOR
|
||||||
bool GLGizmoEmboss::choose_font_by_wxdialog()
|
bool GLGizmoEmboss::choose_font_by_wxdialog()
|
||||||
{
|
{
|
||||||
wxFontData data;
|
wxFontData data;
|
||||||
@ -1287,7 +1346,9 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif // ALLOW_ADD_FONT_BY_OS_SELECTOR
|
||||||
|
|
||||||
|
#ifdef ALLOW_ADD_FONT_BY_FILE
|
||||||
bool GLGizmoEmboss::choose_true_type_file()
|
bool GLGizmoEmboss::choose_true_type_file()
|
||||||
{
|
{
|
||||||
wxArrayString input_files;
|
wxArrayString input_files;
|
||||||
@ -1318,6 +1379,7 @@ bool GLGizmoEmboss::choose_true_type_file()
|
|||||||
if (font_loaded) process();
|
if (font_loaded) process();
|
||||||
return font_loaded;
|
return font_loaded;
|
||||||
}
|
}
|
||||||
|
#endif // ALLOW_ADD_FONT_BY_FILE
|
||||||
|
|
||||||
bool GLGizmoEmboss::choose_svg_file()
|
bool GLGizmoEmboss::choose_svg_file()
|
||||||
{
|
{
|
||||||
@ -1618,29 +1680,31 @@ public:
|
|||||||
Priv() = delete;
|
Priv() = delete;
|
||||||
struct EmbossObject
|
struct EmbossObject
|
||||||
{
|
{
|
||||||
TriangleMesh mesh;
|
TriangleMesh mesh;
|
||||||
std::string name;
|
Transform3d transformation;
|
||||||
|
std::string name;
|
||||||
TextConfiguration cfg;
|
TextConfiguration cfg;
|
||||||
|
|
||||||
EmbossObject(TriangleMesh && mesh,
|
EmbossObject(TriangleMesh && mesh,
|
||||||
std::string name,
|
const Transform3d& transformation,
|
||||||
TextConfiguration cfg)
|
const std::string& name,
|
||||||
: mesh(std::move(mesh)), name(name), cfg(cfg)
|
const TextConfiguration& cfg)
|
||||||
|
: mesh(std::move(mesh))
|
||||||
|
, transformation(transformation) // copy
|
||||||
|
, name(name) // copy
|
||||||
|
, cfg(cfg) // copy
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
struct EmbossVolume : public EmbossObject
|
struct EmbossVolume : public EmbossObject
|
||||||
{
|
{
|
||||||
ModelVolumeType type;
|
ModelVolumeType type;
|
||||||
size_t object_idx;
|
size_t object_idx;
|
||||||
Transform3d transformation;
|
|
||||||
EmbossVolume(TriangleMesh && mesh,
|
EmbossVolume(TriangleMesh && mesh,
|
||||||
Transform3d transformation,
|
const Transform3d& transformation,
|
||||||
std::string name,
|
const std::string& name,
|
||||||
TextConfiguration cfg,
|
const TextConfiguration& cfg,
|
||||||
ModelVolumeType type,
|
ModelVolumeType type,
|
||||||
size_t object_idx)
|
size_t object_idx)
|
||||||
: EmbossObject(std::move(mesh), name, cfg)
|
: EmbossObject(std::move(mesh), transformation, name, cfg)
|
||||||
, transformation(transformation)
|
|
||||||
, type(type)
|
, type(type)
|
||||||
, object_idx(object_idx)
|
, object_idx(object_idx)
|
||||||
{}
|
{}
|
||||||
@ -1651,13 +1715,14 @@ public:
|
|||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
void GLGizmoEmboss::create_emboss_object(TriangleMesh && mesh,
|
void GLGizmoEmboss::create_emboss_object(TriangleMesh &&mesh,
|
||||||
std::string name,
|
const Transform3d& transformation,
|
||||||
TextConfiguration cfg)
|
const std::string& name,
|
||||||
|
const TextConfiguration& cfg)
|
||||||
{
|
{
|
||||||
// Move data to call after is not working
|
// Move data to call after is not working
|
||||||
// data are owen by lambda
|
// data are owned by lambda
|
||||||
auto data = new Priv::EmbossObject(std::move(mesh), name, cfg);
|
auto data = new Priv::EmbossObject(std::move(mesh), transformation, name, cfg);
|
||||||
wxGetApp().plater()->CallAfter([data]() {
|
wxGetApp().plater()->CallAfter([data]() {
|
||||||
ScopeGuard sg([data]() { delete data; });
|
ScopeGuard sg([data]() { delete data; });
|
||||||
Priv::create_emboss_object(*data);
|
Priv::create_emboss_object(*data);
|
||||||
@ -1673,8 +1738,7 @@ void GLGizmoEmboss::create_emboss_volume(TriangleMesh && mesh,
|
|||||||
{
|
{
|
||||||
// Move data to call after is not working
|
// Move data to call after is not working
|
||||||
// data are owen by lambda
|
// data are owen by lambda
|
||||||
auto data = new Priv::EmbossVolume(std::move(mesh), transformation, name, cfg, type,
|
auto data = new Priv::EmbossVolume(std::move(mesh), transformation, name, cfg, type, object_idx);
|
||||||
object_idx);
|
|
||||||
wxGetApp().plater()->CallAfter([data]() {
|
wxGetApp().plater()->CallAfter([data]() {
|
||||||
ScopeGuard sg([data]() { delete data; });
|
ScopeGuard sg([data]() { delete data; });
|
||||||
Priv::create_emboss_volume(*data);
|
Priv::create_emboss_volume(*data);
|
||||||
@ -1687,17 +1751,18 @@ void Priv::create_emboss_object(EmbossObject &data)
|
|||||||
Plater * plater = app.plater();
|
Plater * plater = app.plater();
|
||||||
ObjectList * obj_list = app.obj_list();
|
ObjectList * obj_list = app.obj_list();
|
||||||
GLCanvas3D * canvas = plater->canvas3D();
|
GLCanvas3D * canvas = plater->canvas3D();
|
||||||
GLGizmosManager &manager = canvas->get_gizmos_manager();
|
|
||||||
|
|
||||||
plater->take_snapshot(_L("Add Emboss text object"));
|
plater->take_snapshot(_L("Add Emboss text object"));
|
||||||
// Create new object and change selection
|
// Create new object and change selection
|
||||||
bool center = true;
|
bool center = false;
|
||||||
obj_list->load_mesh_object(std::move(data.mesh), data.name, center,
|
obj_list->load_mesh_object(std::move(data.mesh), data.name, center, &data.cfg, &data.transformation);
|
||||||
&data.cfg);
|
|
||||||
|
|
||||||
// new object successfuly added so open gizmo
|
// When add new object selection is empty.
|
||||||
assert(manager.get_current_type() != GLGizmosManager::Emboss);
|
// Gizmo is automaticaly close when Selection is empty
|
||||||
manager.open_gizmo(GLGizmosManager::Emboss);
|
// new object successfuly added so open gizmo when it was closed
|
||||||
|
GLGizmosManager &manager = canvas->get_gizmos_manager();
|
||||||
|
if(manager.get_current_type() != GLGizmosManager::Emboss)
|
||||||
|
manager.open_gizmo(GLGizmosManager::Emboss);
|
||||||
|
|
||||||
// redraw scene
|
// redraw scene
|
||||||
canvas->reload_scene(true);
|
canvas->reload_scene(true);
|
||||||
|
@ -76,7 +76,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
void set_default_text();
|
void set_default_text();
|
||||||
TriangleMesh create_default_mesh();
|
static TriangleMesh create_default_mesh();
|
||||||
TriangleMesh create_mesh();
|
TriangleMesh create_mesh();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -221,8 +221,9 @@ private:
|
|||||||
|
|
||||||
// call after functions to work outside of drawing
|
// call after functions to work outside of drawing
|
||||||
static void create_emboss_object(TriangleMesh && mesh,
|
static void create_emboss_object(TriangleMesh && mesh,
|
||||||
std::string name,
|
const Transform3d &transformation,
|
||||||
TextConfiguration cfg);
|
const std::string &name,
|
||||||
|
const TextConfiguration &cfg);
|
||||||
static void create_emboss_volume(TriangleMesh && mesh,
|
static void create_emboss_volume(TriangleMesh && mesh,
|
||||||
Transform3d transformation,
|
Transform3d transformation,
|
||||||
std::string name,
|
std::string name,
|
||||||
|
@ -1178,7 +1178,7 @@ std::string ImGuiWrapper::trunc(const std::string &text,
|
|||||||
return "Should not be accessible";
|
return "Should not be accessible";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 ImGuiWrapper::suggest_location(const ImVec2 & dialog_size,
|
ImVec2 ImGuiWrapper::suggest_location(const ImVec2 &dialog_size,
|
||||||
const Slic3r::Polygon &interest)
|
const Slic3r::Polygon &interest)
|
||||||
{
|
{
|
||||||
Plater * plater = wxGetApp().plater();
|
Plater * plater = wxGetApp().plater();
|
||||||
|
@ -181,7 +181,7 @@ Vec3f MeshRaycaster::get_triangle_normal(size_t facet_idx) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
||||||
Vec3d& point, Vec3d& direction) const
|
Vec3d& point, Vec3d& direction)
|
||||||
{
|
{
|
||||||
Matrix4d modelview = camera.get_view_matrix().matrix();
|
Matrix4d modelview = camera.get_view_matrix().matrix();
|
||||||
Matrix4d projection= camera.get_projection_matrix().matrix();
|
Matrix4d projection= camera.get_projection_matrix().matrix();
|
||||||
|
@ -121,8 +121,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
static void line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
||||||
Vec3d& point, Vec3d& direction) const;
|
Vec3d& point, Vec3d& direction);
|
||||||
|
|
||||||
// Given a mouse position, this returns true in case it is on the mesh.
|
// Given a mouse position, this returns true in case it is on the mesh.
|
||||||
bool unproject_on_mesh(
|
bool unproject_on_mesh(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user