Add UI switch for show support structure

This commit is contained in:
Filip Sykala - NTB T15p 2025-01-13 17:52:26 +01:00 committed by Lukas Matena
parent 33f878e5bd
commit 34296a9d62
4 changed files with 416 additions and 64 deletions

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 16 16"
width="16px"
height="16px"
version="1.1"
id="svg6"
sodipodi:docname="support_structure.svg"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10">
</defs><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="14.71875"
inkscape:cy="5.6875"
inkscape:window-width="1920"
inkscape:window-height="1129"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6"><inkscape:grid
type="xygrid"
id="grid185" /></sodipodi:namedview><path
id="path245"
style="fill:#ed6b21;fill-opacity:1;stroke-width:5.0324"
d="M 1,13.998047 H 0.9726562 c -0.51978612,0 -0.94140625,0.421621 -0.94140625,0.941406 v 1.074219 L 1.001953,15.996092 V 15.13281 c 0,-0.07272 0.06205,-0.134765 0.1347657,-0.134765 H 14.857422 c 0.07272,0 0.134765,0.06205 0.134766,0.134765 V 16 l 1.023437,0.01367 v -1.074219 c 0,-0.519785 -0.421621,-0.941406 -0.941406,-0.941406 h -2.064908 l -0.01563,-6.6992189 c 0,-0.1205784 -0.04864,-0.2361381 -0.134766,-0.3222656 L 11.87796,5.7919339 c -0.09048,-0.090434 -0.209093,-0.1344965 -0.326172,-0.1347656 -0.11708,-2.691e-4 -0.232908,0.043455 -0.322265,0.1328125 -0.178715,0.1787146 -0.178715,0.4677697 0,0.6464844 l 0.777833,1.0186129 0.002,1.6933594 -2.9902348,3.3398435 V 7.4898105 C 9.0181212,7.2618516 8.7671402,7.0137588 8.4936842,7.0191074 8.2202282,7.0244574 8.009367,7.2292572 8.0093091,7.481998 l -0.00195,6.516049 H 3.0112622 l 0.00781,-5.9882814 4.7441406,-5.03125 C 7.9367844,2.7958116 7.9322477,2.5075532 7.7495434,2.3339844 7.6581914,2.2472 7.538273,2.204367 7.4214184,2.2070312 7.3045641,2.2096957 7.1898435,2.2582574 7.1030591,2.3496094 L 2.1909497,7.4980469 c -0.079172,0.085262 -0.1796875,0.252336 -0.1796875,0.3710937 v 1.875 1.4746094 2.779297 H 2 Z m 11.009309,-3.337891 0.002,3.337891 H 9.0659502 Z"
sodipodi:nodetypes="cssccssscccssccccsscccccscccccssccsccccccccc" /><path
id="path181"
d="m 2.5194163,0.0390625 c -0.2799997,0 -0.5,0.22000028 -0.5,0.5 v 1 c 0,0.7199993 0.4507818,1.5687504 1.0507812,1.96875 L 4.4393382,4.4199219 5.1366038,3.6816406 3.6287913,2.6777344 C 3.3087916,2.4677346 3.0194163,1.9190621 3.0194163,1.5390625 v -1 c 0,-0.27999972 -0.2200003,-0.5 -0.5,-0.5 z m 11.9999997,0 c -0.28,0 -0.5,0.22000028 -0.5,0.5 v 1 c 0,0.3799996 -0.28961,0.9286721 -0.599609,1.1386719 l -4.3398438,2.890625 c -0.2899997,0.1899998 -0.8213284,0.1899998 -1.1113281,0 L 6.8260569,4.8066406 6.1287913,5.5449219 l 1.28125,0.8535156 c 0.3099997,0.2099998 0.7093754,0.3105469 1.109375,0.3105469 0.3999996,0 0.7993753,-0.1005471 1.109375,-0.3105469 l 4.3398437,-2.890625 c 0.599999,-0.3999996 1.050781,-1.2487507 1.050781,-1.96875 v -1 c 0,-0.27999972 -0.22,-0.5 -0.5,-0.5 z"
style="fill:#808080;fill-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 16 16"
width="16px"
height="16px"
version="1.1"
id="svg6"
sodipodi:docname="support_structure_invisible.svg"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10">
</defs><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="true"
inkscape:zoom="8"
inkscape:cx="2.4375"
inkscape:cy="-14.875"
inkscape:window-width="1920"
inkscape:window-height="1129"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg6"><inkscape:grid
type="xygrid"
id="grid185" /></sodipodi:namedview><path
id="path181"
d="m 2.5194163,0.0390625 c -0.2799997,0 -0.5,0.22000028 -0.5,0.5 v 1 c 0,0.7199993 0.4507818,1.5687504 1.0507812,1.96875 L 4.4393382,4.4199219 5.1366038,3.6816406 3.6287913,2.6777344 C 3.3087916,2.4677346 3.0194163,1.9190621 3.0194163,1.5390625 v -1 c 0,-0.27999972 -0.2200003,-0.5 -0.5,-0.5 z m 11.9999997,0 c -0.28,0 -0.5,0.22000028 -0.5,0.5 v 1 c 0,0.3799996 -0.28961,0.9286721 -0.599609,1.1386719 l -4.3398438,2.890625 c -0.2899997,0.1899998 -0.8213284,0.1899998 -1.1113281,0 L 6.8260569,4.8066406 6.1287913,5.5449219 l 1.28125,0.8535156 c 0.3099997,0.2099998 0.7093754,0.3105469 1.109375,0.3105469 0.3999996,0 0.7993753,-0.1005471 1.109375,-0.3105469 l 4.3398437,-2.890625 c 0.599999,-0.3999996 1.050781,-1.2487507 1.050781,-1.96875 v -1 c 0,-0.27999972 -0.22,-0.5 -0.5,-0.5 z"
style="fill:#808080;fill-opacity:1" /><circle
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.0999999;stroke-linejoin:round;stop-color:#000000"
id="path891-6-7"
cx="7.2478447"
cy="2.8947182"
r="1.25" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1147"
width="1"
height="1"
x="15"
y="15" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1149"
width="1"
height="1"
x="0"
y="15.000001" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1151"
width="1"
height="1"
x="1.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1153"
width="1"
height="1"
x="1.9999999"
y="13" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1155"
width="1"
height="1"
x="1.9999999"
y="11" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1157"
width="1"
height="1"
x="1.9999999"
y="9" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1165"
width="1"
height="1"
x="3.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1167"
width="1"
height="1"
x="5.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1169"
width="1"
height="1"
x="7.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1171"
width="1"
height="1"
x="9.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1173"
width="1"
height="1"
x="11.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1175"
width="1"
height="1"
x="13.5"
y="14" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1177"
width="1"
height="1"
x="12"
y="13" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1179"
width="1"
height="1"
x="12"
y="11" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1181"
width="1"
height="1"
x="12"
y="9" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1183"
width="1"
height="1"
x="12"
y="6.9999995" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1185"
width="1"
height="1"
x="8"
y="13" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1187"
width="1"
height="1"
x="8"
y="11" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1189"
width="1"
height="1"
x="8"
y="9" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1193"
width="1"
height="1"
x="14.992764"
y="-0.71544611"
transform="rotate(45)" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1195"
width="1"
height="1"
x="15.119823"
y="1.0467962"
transform="rotate(45)" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1195-8"
width="1"
height="1"
x="6.7898164"
y="2.6156898"
transform="rotate(45)" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1219"
width="1"
height="1"
x="6.7273164"
y="0.60006464"
transform="rotate(45)" /><rect
style="fill:#999999;fill-opacity:1;stroke-width:0.1;stroke-linejoin:round;stop-color:#000000"
id="rect1221"
width="1"
height="1"
x="6.6726289"
y="-1.5171229"
transform="rotate(45)" /><circle
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.0999999;stroke-linejoin:round;stop-color:#000000"
id="path891"
cx="8.4536505"
cy="7.967514"
r="1.25" /><circle
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.0999999;stroke-linejoin:round;stop-color:#000000"
id="path891-6"
cx="11.844038"
cy="6.4523497"
r="1.25" /></svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -29,8 +29,92 @@
static const double CONE_RADIUS = 0.25;
static const double CONE_HEIGHT = 0.75;
namespace Slic3r {
namespace GUI {
using namespace Slic3r;
using namespace Slic3r::GUI;
namespace {
enum class IconType : unsigned {
show_support_points_selected,
show_support_points_unselected,
show_support_points_hovered,
show_support_structure_selected,
show_support_structure_unselected,
show_support_structure_hovered,
delete_icon,
delete_hovered,
delete_disabled,
// automatic calc of icon's count
_count
};
IconManager::Icons init_icons(IconManager &mng, ImVec2 size = ImVec2{50, 50}) {
mng.release();
// icon order has to match the enum IconType
IconManager::InitTypes init_types {
{"support_structure_invisible.svg", size, IconManager::RasterType::color}, // show_support_points_selected
{"support_structure_invisible.svg", size, IconManager::RasterType::gray_only_data}, // show_support_points_unselected
{"support_structure_invisible.svg", size, IconManager::RasterType::color}, // show_support_points_hovered
{"support_structure.svg", size, IconManager::RasterType::color}, // show_support_structure_selected
{"support_structure.svg", size, IconManager::RasterType::gray_only_data}, // show_support_structure_unselected
{"support_structure.svg", size, IconManager::RasterType::color}, // show_support_structure_hovered
{"delete.svg", size, IconManager::RasterType::white_only_data}, // delete_icon
{"delete.svg", size, IconManager::RasterType::color}, // delete_hovered
{"delete.svg", size, IconManager::RasterType::gray_only_data}, // delete_disabled
};
assert(init_types.size() == static_cast<size_t>(IconType::_count));
std::string path = resources_dir() + "/icons/";
for (IconManager::InitType &init_type : init_types)
init_type.filepath = path + init_type.filepath;
return mng.init(init_types);
}
const IconManager::Icon &get_icon(const IconManager::Icons &icons, IconType type) {
return *icons[static_cast<unsigned>(type)]; }
/// <summary>
/// Draw icon buttons to swap between show structure and only supports points
/// </summary>
/// <param name="show_support_structure">In|Out view mode</param>
/// <param name="icons">all loaded icons</param>
/// <returns>True when change is made</returns>
bool draw_view_mode(bool &show_support_structure, const IconManager::Icons &icons) {
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 8.);
ScopeGuard sg([] { ImGui::PopStyleVar(); });
ImVec4 tint(1, 1, 1, 1);
ImVec4 border = ImGuiPureWrap::COL_ORANGE_DARK;
if (show_support_structure) {
draw(get_icon(icons, IconType::show_support_structure_selected));
if(ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Visible support structure").c_str());
ImGui::SameLine();
if (clickable(get_icon(icons, IconType::show_support_points_unselected),
get_icon(icons, IconType::show_support_points_hovered))) {
show_support_structure = false;
return true;
} else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Click to show support points without support structure").c_str());
} else { // !show_support_structure
if (clickable(get_icon(icons, IconType::show_support_structure_unselected),
get_icon(icons, IconType::show_support_structure_hovered))) {
show_support_structure = true;
return true;
} else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Click to show support structure with pad").c_str());
ImGui::SameLine();
draw(get_icon(icons, IconType::show_support_points_selected));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Visible support points without support structure").c_str());
}
return false;
}
} // namespace
GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoSlaBase(parent, icon_filename, sprite_id, slaposDrillHoles /*slaposSupportPoints*/) {
@ -518,51 +602,21 @@ std::vector<const ConfigOption*> GLGizmoSlaSupports::get_config_options(const st
return out;
}
/*
void GLGizmoSlaSupports::find_intersecting_facets(const igl::AABB<Eigen::MatrixXf, 3>* aabb, const Vec3f& normal, double offset, std::vector<unsigned int>& idxs) const
{
if (aabb->is_leaf()) { // this is a facet
// corner.dot(normal) - offset
idxs.push_back(aabb->m_primitive);
}
else { // not a leaf
using CornerType = Eigen::AlignedBox<float, 3>::CornerType;
bool sign = std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(0))));
for (unsigned int i=1; i<8; ++i)
if (std::signbit(offset - normal.dot(aabb->m_box.corner(CornerType(i)))) != sign) {
find_intersecting_facets(aabb->m_left, normal, offset, idxs);
find_intersecting_facets(aabb->m_right, normal, offset, idxs);
}
}
}
void GLGizmoSlaSupports::make_line_segments() const
{
TriangleMeshSlicer tms(&m_c->m_model_object->volumes.front()->mesh);
Vec3f normal(0.f, 1.f, 1.f);
double d = 0.;
std::vector<IntersectionLine> lines;
find_intersections(&m_AABB, normal, d, lines);
ExPolygons expolys;
tms.make_expolygons_simple(lines, &expolys);
SVG svg("slice_loops.svg", get_extents(expolys));
svg.draw(expolys);
//for (const IntersectionLine &l : lines[i])
// svg.draw(l, "red", 0);
//svg.draw_outline(expolygons, "black", "blue", 0);
svg.Close();
}
*/
void GLGizmoSlaSupports::on_render_input_window(float x, float y, float bottom_limit)
{
// Keep resolution of icons for
static float rendered_line_height;
if (float line_height = ImGui::GetTextLineHeightWithSpacing();
m_icons.empty() ||
rendered_line_height != line_height) { // change of view resolution
rendered_line_height = line_height;
// need regeneration when change resolution(move between monitors)
float width = std::round(line_height / 8 + 1) * 8;
ImVec2 icon_size{width, width};
m_icons = init_icons(m_icon_manager, icon_size);
}
static float last_y = 0.0f;
static float last_h = 0.0f;
@ -681,12 +735,11 @@ RENDER_AGAIN:
ImGuiPureWrap::text(m_desc.at("points_density"));
ImGui::SameLine();
if (ImGui::Checkbox("##ShowSupportStructure", &m_show_support_structure)){
if (draw_view_mode(m_show_support_structure, m_icons)){
show_sla_supports(m_show_support_structure);
if (m_show_support_structure)
reslice_until_step(slaposPad);
} else if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Show/Hide supporting structure").c_str());
}
const char *support_points_density = "support_points_density_relative";
float density = static_cast<const ConfigOptionInt*>(get_config_options({support_points_density})[0])->value;
@ -738,11 +791,6 @@ RENDER_AGAIN:
}
ImVec4 light_gray{0.4f, 0.4f, 0.4f, 1.0f};
ImGui::TextColored(light_gray, stats.c_str());
if (supports.empty()){
ImGui::SameLine();
if (ImGuiPureWrap::button(m_desc.at("auto_generate")))
auto_generate();
}
//ImGui::Separator(); // START temporary debug
//ImGui::Text("Between delimiters is temporary GUI");
@ -756,8 +804,17 @@ RENDER_AGAIN:
//draw_island_config();
//ImGui::Text("Distribution depends on './resources/data/sla_support.svg'\ninstruction for edit are in file");
//ImGui::Separator();
//if (ImGuiPureWrap::button(m_desc.at("auto_generate")))
// auto_generate();
if (ImGuiPureWrap::button(m_desc.at("auto_generate")))
auto_generate();
ImGui::SameLine();
remove_all = button(
get_icon(m_icons, IconType::delete_icon),
get_icon(m_icons, IconType::delete_hovered),
get_icon(m_icons, IconType::delete_disabled),
!is_input_enabled() || m_normal_cache.empty());
if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", m_desc.at("remove_all").c_str());
ImGui::Separator();
if (ImGuiPureWrap::button(m_desc.at("manual_editing")))
@ -765,9 +822,9 @@ RENDER_AGAIN:
m_imgui->disabled_end();
m_imgui->disabled_begin(!is_input_enabled() || m_normal_cache.empty());
remove_all = ImGuiPureWrap::button(m_desc.at("remove_all"));
m_imgui->disabled_end();
//m_imgui->disabled_begin(!is_input_enabled() || m_normal_cache.empty());
//remove_all = ImGuiPureWrap::button(m_desc.at("remove_all"));
//m_imgui->disabled_end();
// ImGuiPureWrap::text("");
// ImGuiPureWrap::text(m_c->m_model_object->sla_points_status == sla::PointsStatus::NoPoints ? _(L("No points (will be autogenerated)")) :
@ -1479,8 +1536,3 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog()
SetSizer(hsizer);
hsizer->SetSizeHints(this);
}
} // namespace GUI
} // namespace Slic3r

View File

@ -8,6 +8,7 @@
#include "GLGizmoSlaBase.hpp"
#include "slic3r/GUI/GLSelectionRectangle.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/IconManager.hpp"
#include "libslic3r/SLA/SupportPoint.hpp"
#include "libslic3r/ObjectID.hpp"
@ -103,6 +104,9 @@ private:
std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo
ObjectID m_old_mo_id;
IconManager m_icon_manager;
IconManager::Icons m_icons;
PickingModel m_sphere;
PickingModel m_cone;
std::vector<std::pair<std::shared_ptr<SceneRaycasterItem>, std::shared_ptr<SceneRaycasterItem>>> m_point_raycasters;