mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-26 10:11:10 -06:00
Merge branch 'lm_fdm_custom_supports_backend'
This commit is contained in:
commit
8afc9338de
13 changed files with 358 additions and 46 deletions
|
|
@ -259,7 +259,8 @@ Point Bed3D::point_projection(const Point& point) const
|
|||
return m_polygon.point_projection(point);
|
||||
}
|
||||
|
||||
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes) const
|
||||
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||
bool show_axes, bool show_texture) const
|
||||
{
|
||||
m_scale_factor = scale_factor;
|
||||
|
||||
|
|
@ -270,9 +271,9 @@ void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool sho
|
|||
|
||||
switch (m_type)
|
||||
{
|
||||
case System: { render_system(canvas, bottom); break; }
|
||||
case System: { render_system(canvas, bottom, show_texture); break; }
|
||||
default:
|
||||
case Custom: { render_custom(canvas, bottom); break; }
|
||||
case Custom: { render_custom(canvas, bottom, show_texture); break; }
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
|
@ -384,12 +385,13 @@ void Bed3D::render_axes() const
|
|||
m_axes.render();
|
||||
}
|
||||
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom) const
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const
|
||||
{
|
||||
if (!bottom)
|
||||
render_model();
|
||||
|
||||
render_texture(bottom, canvas);
|
||||
if (show_texture)
|
||||
render_texture(bottom, canvas);
|
||||
}
|
||||
|
||||
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
|
||||
|
|
@ -564,7 +566,7 @@ void Bed3D::render_model() const
|
|||
}
|
||||
}
|
||||
|
||||
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) const
|
||||
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const
|
||||
{
|
||||
if (m_texture_filename.empty() && m_model_filename.empty())
|
||||
{
|
||||
|
|
@ -575,7 +577,8 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom) const
|
|||
if (!bottom)
|
||||
render_model();
|
||||
|
||||
render_texture(bottom, canvas);
|
||||
if (show_texture)
|
||||
render_texture(bottom, canvas);
|
||||
}
|
||||
|
||||
void Bed3D::render_default(bool bottom) const
|
||||
|
|
|
|||
|
|
@ -103,11 +103,15 @@ public:
|
|||
// Return true if the bed shape changed, so the calee will update the UI.
|
||||
bool set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model);
|
||||
|
||||
const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; }
|
||||
const BoundingBoxf3& get_bounding_box(bool extended) const {
|
||||
return extended ? m_extended_bounding_box : m_bounding_box;
|
||||
}
|
||||
|
||||
bool contains(const Point& point) const;
|
||||
Point point_projection(const Point& point) const;
|
||||
|
||||
void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes) const;
|
||||
void render(GLCanvas3D& canvas, bool bottom, float scale_factor,
|
||||
bool show_axes, bool show_texture) const;
|
||||
|
||||
private:
|
||||
void calc_bounding_boxes() const;
|
||||
|
|
@ -115,10 +119,10 @@ private:
|
|||
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
|
||||
std::tuple<EType, std::string, std::string> detect_type(const Pointfs& shape) const;
|
||||
void render_axes() const;
|
||||
void render_system(GLCanvas3D& canvas, bool bottom) const;
|
||||
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const;
|
||||
void render_texture(bool bottom, GLCanvas3D& canvas) const;
|
||||
void render_model() const;
|
||||
void render_custom(GLCanvas3D& canvas, bool bottom) const;
|
||||
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const;
|
||||
void render_default(bool bottom) const;
|
||||
void reset();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5341,14 +5341,19 @@ void GLCanvas3D::_render_background() const
|
|||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_bed(float theta, bool show_axes) const
|
||||
void GLCanvas3D::_render_bed(bool bottom, bool show_axes) const
|
||||
{
|
||||
float scale_factor = 1.0;
|
||||
#if ENABLE_RETINA_GL
|
||||
scale_factor = m_retina_helper->get_scale_factor();
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
bool show_texture = ! bottom ||
|
||||
(m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::SlaSupports);
|
||||
|
||||
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
wxGetApp().plater()->get_bed().render(const_cast<GLCanvas3D&>(*this), theta, scale_factor, show_axes);
|
||||
wxGetApp().plater()->get_bed().render(const_cast<GLCanvas3D&>(*this), bottom, scale_factor, show_axes, show_texture);
|
||||
#else
|
||||
m_bed.render(const_cast<GLCanvas3D&>(*this), theta, scale_factor, show_axes);
|
||||
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||
|
|
|
|||
|
|
@ -755,7 +755,7 @@ private:
|
|||
void _picking_pass() const;
|
||||
void _rectangular_selection_picking_pass() const;
|
||||
void _render_background() const;
|
||||
void _render_bed(float theta, bool show_axes) const;
|
||||
void _render_bed(bool bottom, bool show_axes) const;
|
||||
void _render_objects() const;
|
||||
void _render_selection() const;
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/PresetBundle.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ bool GLGizmoFdmSupports::on_init()
|
|||
m_desc["block"] = _L("Block supports");
|
||||
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
|
||||
m_desc["remove"] = _L("Remove selection");
|
||||
m_desc["remove_all"] = _L("Remove all");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -191,7 +193,16 @@ void GLGizmoFdmSupports::update_mesh()
|
|||
// This mesh does not account for the possible Z up SLA offset.
|
||||
const TriangleMesh* mesh = &mv->mesh();
|
||||
|
||||
m_selected_facets[volume_id].assign(mesh->its.indices.size(), SelType::NONE);
|
||||
m_selected_facets[volume_id].assign(mesh->its.indices.size(), FacetSupportType::NONE);
|
||||
|
||||
// Load current state from ModelVolume.
|
||||
for (FacetSupportType type : {FacetSupportType::ENFORCER, FacetSupportType::BLOCKER}) {
|
||||
const std::vector<int>& list = mv->m_supported_facets.get_facets(type);
|
||||
for (int i : list)
|
||||
m_selected_facets[volume_id][i] = type;
|
||||
}
|
||||
update_vertex_buffers(mv, volume_id, true, true);
|
||||
|
||||
m_neighbors[volume_id].resize(3 * mesh->its.indices.size());
|
||||
|
||||
// Prepare vector of vertex_index - facet_index pairs to quickly find adjacent facets
|
||||
|
|
@ -247,16 +258,16 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
|| action == SLAGizmoEventType::RightDown
|
||||
|| (action == SLAGizmoEventType::Dragging && m_button_down != Button::None)) {
|
||||
|
||||
SelType new_state = SelType::NONE;
|
||||
FacetSupportType new_state = FacetSupportType::NONE;
|
||||
if (! shift_down) {
|
||||
if (action == SLAGizmoEventType::Dragging)
|
||||
new_state = m_button_down == Button::Left
|
||||
? SelType::ENFORCER
|
||||
: SelType::BLOCKER;
|
||||
? FacetSupportType::ENFORCER
|
||||
: FacetSupportType::BLOCKER;
|
||||
else
|
||||
new_state = action == SLAGizmoEventType::LeftDown
|
||||
? SelType::ENFORCER
|
||||
: SelType::BLOCKER;
|
||||
? FacetSupportType::ENFORCER
|
||||
: FacetSupportType::BLOCKER;
|
||||
}
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
|
|
@ -383,9 +394,9 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
|
||||
// Now just select all facets that passed.
|
||||
for (size_t next_facet : facets_to_select) {
|
||||
SelType& facet = m_selected_facets[mesh_id][next_facet];
|
||||
FacetSupportType& facet = m_selected_facets[mesh_id][next_facet];
|
||||
|
||||
if (facet != new_state && facet != SelType::NONE) {
|
||||
if (facet != new_state && facet != FacetSupportType::NONE) {
|
||||
// this triangle is currently in the other VBA.
|
||||
// Both VBAs need to be refreshed.
|
||||
update_both = true;
|
||||
|
|
@ -395,8 +406,8 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
}
|
||||
|
||||
update_vertex_buffers(mv, mesh_id,
|
||||
new_state == SelType::ENFORCER || update_both,
|
||||
new_state == SelType::BLOCKER || update_both
|
||||
new_state == FacetSupportType::ENFORCER || update_both,
|
||||
new_state == FacetSupportType::BLOCKER || update_both
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -420,6 +431,18 @@ bool GLGizmoFdmSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::RightUp)
|
||||
&& m_button_down != Button::None) {
|
||||
m_button_down = Button::None;
|
||||
|
||||
// Synchronize gizmo with ModelVolume data.
|
||||
ModelObject* mo = m_c->selection_info()->model_object();
|
||||
int idx = -1;
|
||||
for (ModelVolume* mv : mo->volumes) {
|
||||
++idx;
|
||||
if (! mv->is_model_part())
|
||||
continue;
|
||||
for (int i=0; i<int(m_selected_facets[idx].size()); ++i)
|
||||
mv->m_supported_facets.set_facet(i, m_selected_facets[idx][i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -434,16 +457,16 @@ void GLGizmoFdmSupports::update_vertex_buffers(const ModelVolume* mv,
|
|||
{
|
||||
const TriangleMesh* mesh = &mv->mesh();
|
||||
|
||||
for (SelType type : {SelType::ENFORCER, SelType::BLOCKER}) {
|
||||
if ((type == SelType::ENFORCER && ! update_enforcers)
|
||||
|| (type == SelType::BLOCKER && ! update_blockers))
|
||||
for (FacetSupportType type : {FacetSupportType::ENFORCER, FacetSupportType::BLOCKER}) {
|
||||
if ((type == FacetSupportType::ENFORCER && ! update_enforcers)
|
||||
|| (type == FacetSupportType::BLOCKER && ! update_blockers))
|
||||
continue;
|
||||
|
||||
GLIndexedVertexArray& iva = m_ivas[mesh_id][type==SelType::ENFORCER ? 0 : 1];
|
||||
GLIndexedVertexArray& iva = m_ivas[mesh_id][type==FacetSupportType::ENFORCER ? 0 : 1];
|
||||
iva.release_geometry();
|
||||
size_t triangle_cnt=0;
|
||||
for (size_t facet_idx=0; facet_idx<m_selected_facets[mesh_id].size(); ++facet_idx) {
|
||||
SelType status = m_selected_facets[mesh_id][facet_idx];
|
||||
FacetSupportType status = m_selected_facets[mesh_id][facet_idx];
|
||||
if (status != type)
|
||||
continue;
|
||||
for (int i=0; i<3; ++i)
|
||||
|
|
@ -471,6 +494,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
|
||||
const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f);
|
||||
const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f);
|
||||
const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f);
|
||||
const float minimal_slider_width = m_imgui->scaled(4.f);
|
||||
|
||||
float caption_max = 0.f;
|
||||
|
|
@ -484,6 +508,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
|
||||
float window_width = minimal_slider_width + std::max(cursor_slider_left, clipping_slider_left);
|
||||
window_width = std::max(window_width, total_text_max);
|
||||
window_width = std::max(window_width, button_width);
|
||||
|
||||
auto draw_text_with_caption = [this, &caption_max](const wxString& caption, const wxString& text) {
|
||||
static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f);
|
||||
|
|
@ -499,6 +524,20 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||
|
||||
m_imgui->text("");
|
||||
|
||||
if (m_imgui->button(m_desc.at("remove_all"))) {
|
||||
ModelObject* mo = m_c->selection_info()->model_object();
|
||||
int idx = -1;
|
||||
for (ModelVolume* mv : mo->volumes) {
|
||||
++idx;
|
||||
if (mv->is_model_part()) {
|
||||
m_selected_facets[idx].assign(m_selected_facets[idx].size(), FacetSupportType::NONE);
|
||||
mv->m_supported_facets.clear();
|
||||
update_vertex_buffers(mv, idx, true, true);
|
||||
m_parent.set_as_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
|
||||
|
||||
m_imgui->text(m_desc.at("cursor_size"));
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class FacetSupportType : int8_t;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
enum class SLAGizmoEventType : unsigned char;
|
||||
|
|
@ -26,15 +29,9 @@ private:
|
|||
static constexpr float CursorRadiusMax = 8.f;
|
||||
static constexpr float CursorRadiusStep = 0.2f;
|
||||
|
||||
enum class SelType : int8_t {
|
||||
NONE,
|
||||
ENFORCER,
|
||||
BLOCKER
|
||||
};
|
||||
|
||||
// For each model-part volume, store a list of statuses of
|
||||
// individual facets (one of the enum values above).
|
||||
std::vector<std::vector<SelType>> m_selected_facets;
|
||||
std::vector<std::vector<FacetSupportType>> m_selected_facets;
|
||||
|
||||
// Store two vertex buffer arrays (for enforcers/blockers)
|
||||
// for each model-part volume.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue