mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-10 08:17:51 -06:00
Port Emboss & SVG gizmo from PrusaSlicer (#2819)
* Rework UI jobs to make them more understandable and flexible. * Update Orca specific jobs * Fix progress issue * Fix dark mode and window radius * Update cereal version from 1.2.2 to 1.3.0 (cherry picked from commit prusa3d/PrusaSlicer@057232a275) * Initial port of Emboss gizmo * Bump up CGAL version to 5.4 (cherry picked from commit prusa3d/PrusaSlicer@1bf9dee3e7) * Fix text rotation * Fix test dragging * Add text gizmo to right click menu * Initial port of SVG gizmo * Fix text rotation * Fix Linux build * Fix "from surface" * Fix -90 rotation * Fix icon path * Fix loading font with non-ascii name * Fix storing non-utf8 font descriptor in 3mf file * Fix filtering with non-utf8 characters * Emboss: Use Orca style input dialog * Fix build on macOS * Fix tooltip color in light mode * InputText: fixed incorrect padding when FrameBorder > 0. (ocornut/imgui#4794, ocornut/imgui#3781) InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (ocornut/imgui#3781, ocornut/imgui#4794) (cherry picked from commit ocornut/imgui@072caa4a90) (cherry picked from commit ocornut/imgui@bdd2a94315) * SVG: Use Orca style input dialog * Fix job progress update * Fix crash when select editing text in preview screen * Use Orca checkbox style * Fix issue that toolbar icons are kept regenerated * Emboss: Fix text & icon alignment * SVG: Fix text & icon alignment * Emboss: fix toolbar icon mouse hover state * Add a simple subtle outline effect by drawing back faces using wireframe mode * Disable selection outlines * Show outline in white if the model color is too dark * Make the outline algorithm more reliable * Enable cull face, which fix render on Linux * Fix `disable_cullface` * Post merge fix * Optimize selection rendering * Fix scale gizmo * Emboss: Fix text rotation if base object is scaled * Fix volume synchronize * Fix emboss rotation * Emboss: Fix advance toggle * Fix text position after reopened the project * Make font style preview darker * Make font style preview selector height shorter --------- Co-authored-by: tamasmeszaros <meszaros.q@gmail.com> Co-authored-by: ocornut <omarcornut@gmail.com> Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
7a8e1929ee
commit
933aa3050b
197 changed files with 27190 additions and 2454 deletions
|
@ -1588,7 +1588,6 @@ void GLCanvas3D::enable_legend_texture(bool enable)
|
|||
void GLCanvas3D::enable_picking(bool enable)
|
||||
{
|
||||
m_picking_enabled = enable;
|
||||
m_selection.set_mode(Selection::Instance);
|
||||
}
|
||||
|
||||
void GLCanvas3D::enable_moving(bool enable)
|
||||
|
@ -2171,7 +2170,17 @@ std::vector<int> GLCanvas3D::load_object(const Model& model, int obj_idx)
|
|||
|
||||
void GLCanvas3D::mirror_selection(Axis axis)
|
||||
{
|
||||
m_selection.mirror(axis);
|
||||
TransformationType transformation_type;
|
||||
if (wxGetApp().obj_manipul()->is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
else if (wxGetApp().obj_manipul()->is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
|
||||
transformation_type.set_relative();
|
||||
|
||||
m_selection.setup_cache();
|
||||
m_selection.mirror(axis, transformation_type);
|
||||
|
||||
do_mirror(L("Mirror Object"));
|
||||
// BBS
|
||||
//wxGetApp().obj_manipul()->set_dirty();
|
||||
|
@ -3364,7 +3373,9 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
else
|
||||
displacement = multiplier * direction;
|
||||
|
||||
m_selection.translate(displacement);
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
m_selection.translate(displacement, trafo_type);
|
||||
m_dirty = true;
|
||||
}
|
||||
);}
|
||||
|
@ -4136,7 +4147,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D);
|
||||
TransformationType trafo_type;
|
||||
trafo_type.set_relative();
|
||||
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type);
|
||||
if (current_printer_technology() == ptFFF && (fff_print()->config().print_sequence == PrintSequence::ByObject))
|
||||
update_sequential_clearance();
|
||||
// BBS
|
||||
|
@ -4364,6 +4377,40 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
else
|
||||
evt.Skip();
|
||||
|
||||
// Detection of doubleclick on text to open emboss edit window
|
||||
auto type = m_gizmos.get_current_type();
|
||||
if (evt.LeftDClick() && !m_hover_volume_idxs.empty() &&
|
||||
(type == GLGizmosManager::EType::Undefined ||
|
||||
type == GLGizmosManager::EType::Move ||
|
||||
type == GLGizmosManager::EType::Rotate ||
|
||||
type == GLGizmosManager::EType::Scale ||
|
||||
type == GLGizmosManager::EType::Emboss ||
|
||||
type == GLGizmosManager::EType::Svg) ) {
|
||||
for (int hover_volume_id : m_hover_volume_idxs) {
|
||||
const GLVolume &hover_gl_volume = *m_volumes.volumes[hover_volume_id];
|
||||
int object_idx = hover_gl_volume.object_idx();
|
||||
if (object_idx < 0 || static_cast<size_t>(object_idx) >= m_model->objects.size()) continue;
|
||||
const ModelObject* hover_object = m_model->objects[object_idx];
|
||||
int hover_volume_idx = hover_gl_volume.volume_idx();
|
||||
if (hover_volume_idx < 0 || static_cast<size_t>(hover_volume_idx) >= hover_object->volumes.size()) continue;
|
||||
const ModelVolume* hover_volume = hover_object->volumes[hover_volume_idx];
|
||||
|
||||
if (hover_volume->text_configuration.has_value()) {
|
||||
m_selection.add_volumes(Selection::EMode::Volume, {(unsigned) hover_volume_id});
|
||||
if (type != GLGizmosManager::EType::Emboss)
|
||||
m_gizmos.open_gizmo(GLGizmosManager::EType::Emboss);
|
||||
wxGetApp().obj_list()->update_selections();
|
||||
return;
|
||||
} else if (hover_volume->emboss_shape.has_value()) {
|
||||
m_selection.add_volumes(Selection::EMode::Volume, {(unsigned) hover_volume_id});
|
||||
if (type != GLGizmosManager::EType::Svg)
|
||||
m_gizmos.open_gizmo(GLGizmosManager::EType::Svg);
|
||||
wxGetApp().obj_list()->update_selections();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_moving)
|
||||
show_sinking_contours();
|
||||
|
||||
|
@ -4460,6 +4507,9 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
|||
int instance_idx = v->instance_idx();
|
||||
int volume_idx = v->volume_idx();
|
||||
|
||||
if (volume_idx < 0)
|
||||
continue;
|
||||
|
||||
std::pair<int, int> done_id(object_idx, instance_idx);
|
||||
|
||||
if (0 <= object_idx && object_idx < (int)m_model->objects.size()) {
|
||||
|
@ -4469,10 +4519,10 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
|||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance)
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
if (model_object->volumes[volume_idx]->get_offset() != v->get_volume_offset()) {
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
// BBS: backup
|
||||
Slic3r::save_object_mesh(*model_object);
|
||||
}
|
||||
|
@ -4564,26 +4614,26 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
|||
Selection::EMode selection_mode = m_selection.get_mode();
|
||||
|
||||
for (const GLVolume* v : m_volumes.volumes) {
|
||||
int object_idx = v->object_idx();
|
||||
const int object_idx = v->object_idx();
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
continue;
|
||||
|
||||
int instance_idx = v->instance_idx();
|
||||
int volume_idx = v->volume_idx();
|
||||
const int instance_idx = v->instance_idx();
|
||||
const int volume_idx = v->volume_idx();
|
||||
|
||||
if (volume_idx < 0)
|
||||
continue;
|
||||
|
||||
done.insert(std::pair<int, int>(object_idx, instance_idx));
|
||||
|
||||
// Rotate instances/volumes.
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance) {
|
||||
model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation());
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
}
|
||||
if (selection_mode == Selection::Instance)
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
if (model_object->volumes[volume_idx]->get_rotation() != v->get_volume_rotation()) {
|
||||
model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation());
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
// BBS: backup
|
||||
Slic3r::save_object_mesh(*model_object);
|
||||
}
|
||||
|
@ -4645,27 +4695,27 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
|
|||
Selection::EMode selection_mode = m_selection.get_mode();
|
||||
|
||||
for (const GLVolume* v : m_volumes.volumes) {
|
||||
int object_idx = v->object_idx();
|
||||
const int object_idx = v->object_idx();
|
||||
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
|
||||
continue;
|
||||
|
||||
int instance_idx = v->instance_idx();
|
||||
int volume_idx = v->volume_idx();
|
||||
const int instance_idx = v->instance_idx();
|
||||
const int volume_idx = v->volume_idx();
|
||||
|
||||
if (volume_idx < 0)
|
||||
continue;
|
||||
|
||||
done.insert(std::pair<int, int>(object_idx, instance_idx));
|
||||
|
||||
// Rotate instances/volumes
|
||||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance) {
|
||||
model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor());
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
}
|
||||
if (selection_mode == Selection::Instance)
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
if (model_object->volumes[volume_idx]->get_scaling_factor() != v->get_volume_scaling_factor()) {
|
||||
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
|
||||
model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor());
|
||||
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
|
||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
// BBS: backup
|
||||
Slic3r::save_object_mesh(*model_object);
|
||||
}
|
||||
|
@ -4756,10 +4806,10 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
|
|||
ModelObject* model_object = m_model->objects[object_idx];
|
||||
if (model_object != nullptr) {
|
||||
if (selection_mode == Selection::Instance)
|
||||
model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror());
|
||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||
else if (selection_mode == Selection::Volume) {
|
||||
if (model_object->volumes[volume_idx]->get_mirror() != v->get_volume_mirror()) {
|
||||
model_object->volumes[volume_idx]->set_mirror(v->get_volume_mirror());
|
||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
||||
// BBS: backup
|
||||
Slic3r::save_object_mesh(*model_object);
|
||||
}
|
||||
|
@ -5210,6 +5260,14 @@ bool GLCanvas3D::is_object_sinking(int object_idx) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void GLCanvas3D::apply_retina_scale(Vec2d &screen_coordinate) const
|
||||
{
|
||||
#if ENABLE_RETINA_GL
|
||||
double scale = static_cast<double>(m_retina_helper->get_scale_factor());
|
||||
screen_coordinate *= scale;
|
||||
#endif // ENABLE_RETINA_GL
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_is_shown_on_screen() const
|
||||
{
|
||||
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
|
||||
|
@ -7148,12 +7206,14 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale()
|
|||
|
||||
auto* m_notification = wxGetApp().plater()->get_notification_manager();
|
||||
m_notification->set_scale(sc);
|
||||
m_gizmos.set_overlay_scale(sc);
|
||||
#else
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
m_main_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size * scale);
|
||||
m_assemble_view_toolbar.set_icons_size(size);
|
||||
m_separator_toolbar.set_icons_size(size);
|
||||
collapse_toolbar.set_icons_size(size / 2.0);
|
||||
m_gizmos.set_overlay_icon_size(size);
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
// Update collapse toolbar
|
||||
|
@ -7210,31 +7270,6 @@ void GLCanvas3D::_render_overlays()
|
|||
_render_assemble_control();
|
||||
_render_assemble_info();
|
||||
|
||||
// main toolbar and undoredo toolbar need to be both updated before rendering because both their sizes are needed
|
||||
// to correctly place them
|
||||
#if ENABLE_RETINA_GL
|
||||
const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(/*true*/);
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
m_main_toolbar.set_scale(scale);
|
||||
m_assemble_view_toolbar.set_scale(scale);
|
||||
m_separator_toolbar.set_scale(scale);
|
||||
wxGetApp().plater()->get_collapse_toolbar().set_scale(scale / 2.0);
|
||||
m_gizmos.set_overlay_scale(scale);
|
||||
#else
|
||||
// BBS adjust display scale
|
||||
const float size = int(GLToolbar::Default_Icons_Size * wxGetApp().toolbar_icon_scale(/*true*/));
|
||||
const float gizmo_size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale());
|
||||
//const float size = int(GLToolbar::Default_Icons_Size);
|
||||
//const float gizmo_size = int(GLGizmosManager::Default_Icons_Size);
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
m_main_toolbar.set_icons_size(gizmo_size);
|
||||
m_assemble_view_toolbar.set_icons_size(gizmo_size);
|
||||
m_separator_toolbar.set_icons_size(gizmo_size);
|
||||
wxGetApp().plater()->get_collapse_toolbar().set_icons_size(size / 2.0);
|
||||
m_gizmos.set_overlay_icon_size(gizmo_size);
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
_render_separator_toolbar_right();
|
||||
_render_separator_toolbar_left();
|
||||
_render_main_toolbar();
|
||||
|
@ -8077,7 +8112,7 @@ void GLCanvas3D::_render_assemble_control() const
|
|||
const float text_size_x = std::max(imgui->calc_text_size(_L("Reset direction")).x + 2 * ImGui::GetStyle().FramePadding.x,
|
||||
std::max(imgui->calc_text_size(_L("Explosion Ratio")).x, imgui->calc_text_size(_L("Section View")).x));
|
||||
const float slider_width = 75.0f;
|
||||
const float value_size = imgui->calc_text_size("3.00").x + text_padding * 2;
|
||||
const float value_size = imgui->calc_text_size(std::string_view{"3.00"}).x + text_padding * 2;
|
||||
const float item_spacing = imgui->get_item_spacing().x;
|
||||
ImVec2 window_padding = ImGui::GetStyle().WindowPadding;
|
||||
|
||||
|
@ -9511,5 +9546,108 @@ void GLCanvas3D::GizmoHighlighter::blink()
|
|||
invalidate();
|
||||
}
|
||||
|
||||
const ModelVolume *get_model_volume(const GLVolume &v, const Model &model)
|
||||
{
|
||||
const ModelVolume * ret = nullptr;
|
||||
|
||||
if (v.object_idx() < (int)model.objects.size()) {
|
||||
const ModelObject *obj = model.objects[v.object_idx()];
|
||||
if (v.volume_idx() < (int)obj->volumes.size())
|
||||
ret = obj->volumes[v.volume_idx()];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ModelVolume *get_model_volume(const ObjectID &volume_id, const ModelObjectPtrs &objects)
|
||||
{
|
||||
for (const ModelObject *obj : objects)
|
||||
for (ModelVolume *vol : obj->volumes)
|
||||
if (vol->id() == volume_id)
|
||||
return vol;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModelVolume *get_model_volume(const GLVolume &v, const ModelObject& object) {
|
||||
if (v.volume_idx() < 0)
|
||||
return nullptr;
|
||||
|
||||
size_t volume_idx = static_cast<size_t>(v.volume_idx());
|
||||
if (volume_idx >= object.volumes.size())
|
||||
return nullptr;
|
||||
|
||||
return object.volumes[volume_idx];
|
||||
}
|
||||
|
||||
ModelVolume *get_model_volume(const GLVolume &v, const ModelObjectPtrs &objects)
|
||||
{
|
||||
if (v.object_idx() < 0)
|
||||
return nullptr;
|
||||
size_t objext_idx = static_cast<size_t>(v.object_idx());
|
||||
if (objext_idx >= objects.size())
|
||||
return nullptr;
|
||||
if (objects[objext_idx] == nullptr)
|
||||
return nullptr;
|
||||
return get_model_volume(v, *objects[objext_idx]);
|
||||
}
|
||||
|
||||
GLVolume *get_first_hovered_gl_volume(const GLCanvas3D &canvas) {
|
||||
int hovered_id_signed = canvas.get_first_hover_volume_idx();
|
||||
if (hovered_id_signed < 0)
|
||||
return nullptr;
|
||||
|
||||
size_t hovered_id = static_cast<size_t>(hovered_id_signed);
|
||||
const GLVolumePtrs &volumes = canvas.get_volumes().volumes;
|
||||
if (hovered_id >= volumes.size())
|
||||
return nullptr;
|
||||
|
||||
return volumes[hovered_id];
|
||||
}
|
||||
|
||||
GLVolume *get_selected_gl_volume(const GLCanvas3D &canvas) {
|
||||
const GLVolume *gl_volume = get_selected_gl_volume(canvas.get_selection());
|
||||
if (gl_volume == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const GLVolumePtrs &gl_volumes = canvas.get_volumes().volumes;
|
||||
for (GLVolume *v : gl_volumes)
|
||||
if (v->composite_id == gl_volume->composite_id)
|
||||
return v;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModelObject *get_model_object(const GLVolume &gl_volume, const Model &model) {
|
||||
return get_model_object(gl_volume, model.objects);
|
||||
}
|
||||
|
||||
ModelObject *get_model_object(const GLVolume &gl_volume, const ModelObjectPtrs &objects) {
|
||||
if (gl_volume.object_idx() < 0)
|
||||
return nullptr;
|
||||
size_t objext_idx = static_cast<size_t>(gl_volume.object_idx());
|
||||
if (objext_idx >= objects.size())
|
||||
return nullptr;
|
||||
return objects[objext_idx];
|
||||
}
|
||||
|
||||
ModelInstance *get_model_instance(const GLVolume &gl_volume, const Model& model) {
|
||||
return get_model_instance(gl_volume, model.objects);
|
||||
}
|
||||
|
||||
ModelInstance *get_model_instance(const GLVolume &gl_volume, const ModelObjectPtrs &objects) {
|
||||
if (gl_volume.instance_idx() < 0)
|
||||
return nullptr;
|
||||
ModelObject *object = get_model_object(gl_volume, objects);
|
||||
return get_model_instance(gl_volume, *object);
|
||||
}
|
||||
|
||||
ModelInstance *get_model_instance(const GLVolume &gl_volume, const ModelObject &object) {
|
||||
if (gl_volume.instance_idx() < 0)
|
||||
return nullptr;
|
||||
size_t instance_idx = static_cast<size_t>(gl_volume.instance_idx());
|
||||
if (instance_idx >= object.instances.size())
|
||||
return nullptr;
|
||||
return object.instances[instance_idx];
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue