Merge remote-tracking branch 'origin/et_sla_switch_view'
This commit is contained in:
commit
45a84d1815
72
resources/icons/sla_view_original.svg
Normal file
72
resources/icons/sla_view_original.svg
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
|
||||
<svg
|
||||
width="800px"
|
||||
height="800px"
|
||||
viewBox="0 0 1024 1024"
|
||||
class="icon"
|
||||
version="1.1"
|
||||
id="svg842"
|
||||
sodipodi:docname="sla_view_original.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
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="defs846" />
|
||||
<sodipodi:namedview
|
||||
id="namedview844"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.69208076"
|
||||
inkscape:cx="399.51985"
|
||||
inkscape:cy="496.32936"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg842" />
|
||||
<path
|
||||
d="M964.266667 812.8c2.133333-8.533333 2.133333-17.066667 2.133333-23.466667s0-17.066667-2.133333-23.466666l49.066666-36.266667c4.266667-4.266667 6.4-10.666667 4.266667-14.933333l-49.066667-83.2c-2.133333-4.266667-8.533333-6.4-14.933333-4.266667l-55.466667 25.6c-12.8-10.666667-27.733333-19.2-42.666666-25.6l-6.4-61.866667c0-6.4-6.4-10.666667-10.666667-10.666666h-96c-6.4 0-10.666667 4.266667-10.666667 10.666666l-6.4 61.866667c-14.933333 6.4-29.866667 14.933333-42.666666 25.6l-55.466667-25.6c-6.4-2.133333-12.8 0-14.933333 4.266667l-49.066667 83.2c-2.133333 4.266667-2.133333 12.8 4.266667 14.933333l49.066666 36.266667c-2.133333 8.533333-2.133333 17.066667-2.133333 23.466666s0 17.066667 2.133333 23.466667l-49.066666 36.266667c-4.266667 4.266667-6.4 10.666667-4.266667 14.933333l49.066667 83.2c2.133333 4.266667 8.533333 6.4 14.933333 4.266667l55.466667-25.6c12.8 10.666667 27.733333 19.2 42.666666 25.6l6.4 61.866666c0 6.4 6.4 10.666667 10.666667 10.666667h96c6.4 0 10.666667-4.266667 10.666667-10.666667l6.4-61.866666c14.933333-6.4 29.866667-14.933333 42.666666-25.6l55.466667 25.6c6.4 2.133333 12.8 0 14.933333-4.266667l49.066667-83.2c2.133333-4.266667 2.133333-12.8-4.266667-14.933333l-49.066666-36.266667zM789.333333 900.266667c-61.866667 0-110.933333-49.066667-110.933333-110.933334 0-61.866667 49.066667-110.933333 110.933333-110.933333 61.866667 0 110.933333 49.066667 110.933334 110.933333 0 61.866667-49.066667 110.933333-110.933334 110.933334z"
|
||||
fill="#607D8B"
|
||||
id="path838"
|
||||
style="fill:#ffffff;fill-opacity:1" />
|
||||
<path
|
||||
d="M789.333333 661.333333c-70.4 0-128 57.6-128 128s57.6 128 128 128 128-57.6 128-128-57.6-128-128-128z m0 192c-36.266667 0-64-27.733333-64-64s27.733333-64 64-64 64 27.733333 64 64-27.733333 64-64 64z"
|
||||
fill="#455A64"
|
||||
id="path840"
|
||||
style="fill:#646464;fill-opacity:0" />
|
||||
<path
|
||||
d="M 464.75606,385.71647 H 220.52618 c -23.46667,0 -42.66667,19.2 -42.66667,42.66668 v 171.15708 c 0,23.46667 19.2,42.66667 42.66667,42.66667 h 244.22988 c 23.46668,0 42.66668,-19.2 42.66668,-42.66667 V 428.38315 c 0,-23.46668 -19.2,-42.66668 -42.66668,-42.66668 z"
|
||||
style="fill:#f7c0a1;stroke-width:1.28;fill-opacity:1"
|
||||
id="path1447"
|
||||
sodipodi:nodetypes="sssssssss" />
|
||||
<path
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers"
|
||||
d="m 158.31475,281.62793 c -9.13538,-2.47451 -17.55246,-9.78885 -21.77597,-18.92305 -2.14973,-4.64921 -2.18374,-5.6297 -2.18374,-62.96031 v -58.23755 l 2.5171,-5.10855 c 3.53239,-7.16911 11.05319,-14.20236 17.94366,-16.78042 l 5.66954,-2.12124 H 400 639.51466 l 5.66953,2.12124 c 6.89048,2.57806 14.41128,9.61131 17.94367,16.78042 l 2.5171,5.10855 v 58.23755 58.23755 l -2.83063,5.76399 c -3.30254,6.725 -10.14711,13.42226 -16.91326,16.54928 l -4.77719,2.2078 -239.08046,0.19191 c -186.73355,0.14989 -240.09819,-0.0838 -243.72867,-1.06717 z"
|
||||
id="path7485"
|
||||
transform="scale(1.28)" />
|
||||
<path
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers"
|
||||
d="m 437.21118,499.60629 c -10.08409,-1.70675 -19.55357,-8.84836 -24.15393,-18.21621 l -2.84014,-5.78344 v -75.09578 -75.09579 l 2.84014,-5.78344 c 3.4061,-6.93594 9.17745,-12.3958 16.96062,-16.04525 l 5.74203,-2.69238 h 102.17113 102.17114 l 5.74203,2.69238 c 7.78317,3.64945 13.55451,9.10931 16.96062,16.04525 l 2.84014,5.78344 0.12731,66.92209 c 0.10556,55.49011 -0.0746,65.14125 -1.0544,56.49709 -0.97739,-8.62265 -1.60428,-10.87483 -3.62597,-13.02682 l -2.44427,-2.60181 h -41.24765 -41.24765 l -2.50783,2.50784 c -1.37931,1.37931 -2.5167,3.56322 -2.52753,4.85313 -0.0297,3.54851 -4.90813,49.01817 -5.27775,49.19231 -0.17708,0.0835 -5.14956,2.57971 -11.04995,5.54727 l -10.72797,5.39556 -14.94254,-0.0316 -14.94253,-0.0316 -12.03854,-5.65658 c -16.76712,-7.87841 -21.03033,-7.77771 -25.74014,0.60802 l -2.83433,5.04647 -15.83653,-0.11915 c -8.71009,-0.0655 -17.94207,-0.47549 -20.51551,-0.91106 z"
|
||||
id="path7524"
|
||||
transform="scale(1.28)" />
|
||||
<path
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers"
|
||||
d="m 154.98937,680.48972 c -7.22252,-2.82207 -13.15353,-8.19884 -17.12576,-15.5254 l -3.50857,-6.47134 v -58.23755 c 0,-57.52794 0.0269,-58.29576 2.20781,-63.01474 3.12702,-6.76614 9.82428,-13.61071 16.54928,-16.91326 l 5.76399,-2.83062 152.41872,-0.27172 152.41871,-0.27172 -12.21117,20.70595 c -6.71614,11.38827 -12.48085,21.74042 -12.81046,23.00479 -1.33796,5.13249 0.30977,6.86623 21.05574,22.15497 11.25014,8.29079 20.61354,15.37577 20.80755,15.7444 0.194,0.36863 -0.1096,4.69322 -0.67466,9.61021 -0.66837,5.81596 -0.68702,12.03751 -0.0533,17.80415 l 0.97403,8.86416 -19.66637,14.61906 c -10.8165,8.04047 -20.1462,15.51562 -20.73266,16.61144 -1.65622,3.09465 -1.2651,7.94874 0.99788,12.38455 l 2.06417,4.04614 -141.78323,-0.0478 c -136.20291,-0.0459 -141.9764,-0.12328 -146.69167,-1.96569 z"
|
||||
id="path7563"
|
||||
transform="scale(1.28)" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers;fill-rule:nonzero;stroke:none;stroke-opacity:1"
|
||||
d="m 604.62085,664.56707 c -24.60818,-5.96525 -40.42276,-29.63578 -36.74461,-54.99766 4.89008,-33.71857 40.85293,-52.20054 71.62153,-36.80764 18.19443,9.1023 28.95735,30.19449 25.97417,50.90177 -4.18305,29.03597 -32.17825,47.85408 -60.85109,40.90353 z"
|
||||
id="path7602"
|
||||
transform="scale(1.28)" />
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
56
resources/icons/sla_view_processed.svg
Normal file
56
resources/icons/sla_view_processed.svg
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
|
||||
<svg
|
||||
width="800px"
|
||||
height="800px"
|
||||
viewBox="0 0 1024 1024"
|
||||
class="icon"
|
||||
version="1.1"
|
||||
id="svg842"
|
||||
sodipodi:docname="sla_view_processed.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
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="defs846" />
|
||||
<sodipodi:namedview
|
||||
id="namedview844"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.69208076"
|
||||
inkscape:cx="392.29526"
|
||||
inkscape:cy="502.10903"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg842" />
|
||||
<path
|
||||
d="M789.333333 661.333333c-70.4 0-128 57.6-128 128s57.6 128 128 128 128-57.6 128-128-57.6-128-128-128z m0 192c-36.266667 0-64-27.733333-64-64s27.733333-64 64-64 64 27.733333 64 64-27.733333 64-64 64z"
|
||||
fill="#455A64"
|
||||
id="path840"
|
||||
style="fill:#646464;fill-opacity:0" />
|
||||
<path
|
||||
d="M 809.35888,294.17114 H 565.129 c -23.46667,0 -42.66667,19.2 -42.66667,42.66668 l 0,356.86333 c 0,23.46667 19.2,42.66667 42.66667,42.66667 h 244.22988 c 23.46668,0 42.66668,-19.2 42.66668,-42.66667 l 0,-356.86333 c 0,-23.46668 -19.2,-42.66668 -42.66668,-42.66668 z"
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:1.28"
|
||||
id="path1447-4"
|
||||
sodipodi:nodetypes="sssssssss" />
|
||||
<path
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers"
|
||||
d="m 158.31475,281.62793 c -9.13538,-2.47451 -17.55246,-9.78885 -21.77597,-18.92305 -2.14973,-4.64921 -2.18374,-5.6297 -2.18374,-62.96031 v -58.23755 l 2.5171,-5.10855 c 3.53239,-7.16911 11.05319,-14.20236 17.94366,-16.78042 l 5.66954,-2.12124 H 400 639.51466 l 5.66953,2.12124 c 6.89048,2.57806 14.41128,9.61131 17.94367,16.78042 l 2.5171,5.10855 v 58.23755 58.23755 l -2.83063,5.76399 c -3.30254,6.725 -10.14711,13.42226 -16.91326,16.54928 l -4.77719,2.2078 -239.08046,0.19191 c -186.73355,0.14989 -240.09819,-0.0838 -243.72867,-1.06717 z"
|
||||
id="path7485"
|
||||
transform="scale(1.28)" />
|
||||
<path
|
||||
style="fill:#ed6b21;fill-opacity:1;stroke-width:0;paint-order:stroke fill markers"
|
||||
d="m 201.98898,872.0074 c -11.69328,-3.16737 -22.46714,-12.52973 -27.87324,-24.2215 -2.75165,-5.95099 -2.79518,-7.20602 -2.79518,-80.5892 v -74.54406 l 3.22188,-6.53895 c 4.52146,-9.17646 14.14809,-18.17902 22.96789,-21.47894 l 7.25701,-2.71518 H 511.3461 817.92486 l 7.257,2.71518 c 8.81982,3.29992 18.44644,12.30248 22.9679,21.47894 l 3.22189,6.53895 v 74.54406 74.54406 l -3.62321,7.37791 c -4.22725,8.608 -12.9883,17.18049 -21.64897,21.18308 l -6.1148,2.82598 -306.02299,0.24565 C 274.94273,873.56524 206.636,873.26611 201.98898,872.0074 Z"
|
||||
id="path7485-7" />
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
@ -166,6 +166,8 @@ namespace ImGui
|
||||
const wchar_t PauseHoverButton = 0x261B;
|
||||
const wchar_t OpenButton = 0x261C;
|
||||
const wchar_t OpenHoverButton = 0x261D;
|
||||
const wchar_t SlaViewOriginal = 0x261E;
|
||||
const wchar_t SlaViewProcessed = 0x261F;
|
||||
|
||||
const wchar_t LegendTravel = 0x2701;
|
||||
const wchar_t LegendWipe = 0x2702;
|
||||
|
@ -2097,6 +2097,14 @@ bool ModelObject::has_solid_mesh() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelObject::has_negative_volume_mesh() const
|
||||
{
|
||||
for (const ModelVolume* volume : volumes)
|
||||
if (volume->is_negative_volume())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ModelVolume::set_material_id(t_model_material_id material_id)
|
||||
{
|
||||
m_material_id = material_id;
|
||||
|
@ -503,6 +503,8 @@ public:
|
||||
|
||||
// Detect if object has at least one solid mash
|
||||
bool has_solid_mesh() const;
|
||||
// Detect if object has at least one negative volume mash
|
||||
bool has_negative_volume_mesh() const;
|
||||
bool is_cut() const { return cut_id.id().valid(); }
|
||||
bool has_connectors() const;
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
#define ENABLE_MATRICES_DEBUG 0
|
||||
// Shows an imgui dialog containing data from class ObjectManipulation
|
||||
#define ENABLE_OBJECT_MANIPULATION_DEBUG 0
|
||||
// Shows an imgui dialog containing data for class GLCanvas3D::SLAView
|
||||
#define ENABLE_SLA_VIEW_DEBUG_WINDOW 0
|
||||
|
||||
|
||||
// Enable rendering of objects using environment map
|
||||
|
@ -611,10 +611,28 @@ void GLVolumeCollection::load_object_auxiliary(
|
||||
if (convex_hull.has_value())
|
||||
v.set_convex_hull(*convex_hull);
|
||||
v.is_modifier = false;
|
||||
v.shader_outside_printer_detection_enabled = (step == slaposSupportTree);
|
||||
v.shader_outside_printer_detection_enabled = (step == slaposSupportTree || step == slaposDrillHoles);
|
||||
v.set_instance_transformation(model_instance.get_transformation());
|
||||
};
|
||||
|
||||
if (milestone == SLAPrintObjectStep::slaposDrillHoles) {
|
||||
if (print_object->get_parts_to_slice().size() > 1) {
|
||||
// Get the mesh.
|
||||
TriangleMesh backend_mesh;
|
||||
std::shared_ptr<const indexed_triangle_set> preview_mesh_ptr = print_object->get_mesh_to_print();
|
||||
if (preview_mesh_ptr != nullptr)
|
||||
backend_mesh = TriangleMesh(*preview_mesh_ptr);
|
||||
if (!backend_mesh.empty()) {
|
||||
backend_mesh.transform(mesh_trafo_inv);
|
||||
TriangleMesh convex_hull = backend_mesh.convex_hull_3d();
|
||||
for (const std::pair<size_t, size_t>& instance_idx : instances) {
|
||||
const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first];
|
||||
add_volume(obj_idx, (int)instance_idx.first, model_instance, slaposDrillHoles, backend_mesh, GLVolume::MODEL_COLOR[0], convex_hull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the support mesh.
|
||||
if (milestone == SLAPrintObjectStep::slaposSupportTree) {
|
||||
TriangleMesh supports_mesh = print_object->support_mesh();
|
||||
@ -922,7 +940,7 @@ void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* con
|
||||
}
|
||||
|
||||
for (GLVolume* volume : volumes) {
|
||||
if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || volume->volume_idx() < 0)
|
||||
if (volume == nullptr || volume->is_modifier || volume->is_wipe_tower || volume->is_sla_pad() || volume->is_sla_support())
|
||||
continue;
|
||||
|
||||
int extruder_id = volume->extruder_id - 1;
|
||||
|
@ -4066,69 +4066,58 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
}
|
||||
};
|
||||
|
||||
auto image_icon = [&imgui](ImGuiWindow& window, const ImVec2& pos, float size, const wchar_t& icon_id) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
const ImTextureID tex_id = io.Fonts->TexID;
|
||||
const float tex_w = static_cast<float>(io.Fonts->TexWidth);
|
||||
const float tex_h = static_cast<float>(io.Fonts->TexHeight);
|
||||
const ImFontAtlas::CustomRect* const rect = imgui.GetTextureCustomRect(icon_id);
|
||||
const ImVec2 uv0 = { static_cast<float>(rect->X) / tex_w, static_cast<float>(rect->Y) / tex_h };
|
||||
const ImVec2 uv1 = { static_cast<float>(rect->X + rect->Width) / tex_w, static_cast<float>(rect->Y + rect->Height) / tex_h };
|
||||
window.DrawList->AddImage(tex_id, pos, { pos.x + size, pos.y + size }, uv0, uv1, ImGuiWrapper::to_ImU32({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||
};
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendTravel);
|
||||
toggle_button(Preview::OptionType::Travel, _u8L("Travel"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendTravel);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::Wipe, _u8L("Wipe"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendWipe);
|
||||
toggle_button(Preview::OptionType::Wipe, _u8L("Wipe"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendWipe);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::Retractions, _u8L("Retractions"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendRetract);
|
||||
toggle_button(Preview::OptionType::Retractions, _u8L("Retractions"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendRetract);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::Unretractions, _u8L("Deretractions"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendDeretract);
|
||||
toggle_button(Preview::OptionType::Unretractions, _u8L("Deretractions"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendDeretract);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::Seams, _u8L("Seams"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendSeams);
|
||||
toggle_button(Preview::OptionType::Seams, _u8L("Seams"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendSeams);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::ToolChanges, _u8L("Tool changes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendToolChanges);
|
||||
toggle_button(Preview::OptionType::ToolChanges, _u8L("Tool changes"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendToolChanges);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::ColorChanges, _u8L("Color changes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendColorChanges);
|
||||
toggle_button(Preview::OptionType::ColorChanges, _u8L("Color changes"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendColorChanges);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::PausePrints, _u8L("Print pauses"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendPausePrints);
|
||||
toggle_button(Preview::OptionType::PausePrints, _u8L("Print pauses"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendPausePrints);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::CustomGCodes, _u8L("Custom G-codes"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendCustomGCodes);
|
||||
toggle_button(Preview::OptionType::CustomGCodes, _u8L("Custom G-codes"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendCustomGCodes);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
toggle_button(Preview::OptionType::CenterOfGravity, _u8L("Center of gravity"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendCOG);
|
||||
toggle_button(Preview::OptionType::CenterOfGravity, _u8L("Center of gravity"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendCOG);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
if (!wxGetApp().is_gcode_viewer()) {
|
||||
toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendShells);
|
||||
toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendShells);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
}
|
||||
toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendToolMarker);
|
||||
toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [&imgui](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
imgui.draw_icon(window, pos, size, ImGui::LegendToolMarker);
|
||||
});
|
||||
|
||||
bool size_dirty = !ImGui::GetCurrentWindow()->ScrollbarY && ImGui::CalcWindowNextAutoFitSize(ImGui::GetCurrentWindow()).x != ImGui::GetWindowWidth();
|
||||
|
@ -1070,6 +1070,250 @@ void GLCanvas3D::load_arrange_settings()
|
||||
m_arrange_settings_fff_seq_print.alignment = arr_alignment ;
|
||||
}
|
||||
|
||||
static std::vector<int> processed_objects_idxs(const Model& model, const SLAPrint& sla_print, const GLVolumePtrs& volumes)
|
||||
{
|
||||
std::vector<int> ret;
|
||||
GLVolumePtrs matching_volumes;
|
||||
std::copy_if(volumes.begin(), volumes.end(), std::back_inserter(matching_volumes), [](GLVolume* v) {
|
||||
return v->volume_idx() == -(int)slaposDrillHoles; });
|
||||
for (const GLVolume* v : matching_volumes) {
|
||||
const int mo_idx = v->object_idx();
|
||||
const ModelObject* model_object = (mo_idx < (int)model.objects.size()) ? model.objects[mo_idx] : nullptr;
|
||||
if (model_object != nullptr && model_object->instances[v->instance_idx()]->is_printable()) {
|
||||
const SLAPrintObject* print_object = sla_print.get_print_object_by_model_object_id(model_object->id());
|
||||
if (print_object != nullptr && print_object->get_parts_to_slice().size() > 1)
|
||||
ret.push_back(mo_idx);
|
||||
}
|
||||
}
|
||||
std::sort(ret.begin(), ret.end());
|
||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||
return ret;
|
||||
};
|
||||
|
||||
static bool composite_id_match(const GLVolume::CompositeID& id1, const GLVolume::CompositeID& id2)
|
||||
{
|
||||
return id1.object_id == id2.object_id && id1.instance_id == id2.instance_id;
|
||||
}
|
||||
|
||||
static bool object_contains_negative_volumes(const Model& model, int obj_id) {
|
||||
return (0 <= obj_id && obj_id < (int)model.objects.size()) ? model.objects[obj_id]->has_negative_volume_mesh() : false;
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::detect_type_from_volumes(const GLVolumePtrs& volumes)
|
||||
{
|
||||
for (auto& [id, type] : m_instances_cache) {
|
||||
type = ESLAViewType::Original;
|
||||
}
|
||||
|
||||
for (const GLVolume* v : volumes) {
|
||||
if (v->volume_idx() == -(int)slaposDrillHoles) {
|
||||
if (object_contains_negative_volumes(*m_parent.get_model(), v->composite_id.object_id)) {
|
||||
const InstancesCacheItem* instance = find_instance_item(v->composite_id);
|
||||
assert(instance != nullptr);
|
||||
set_type(instance->first, ESLAViewType::Processed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::set_type(ESLAViewType new_type)
|
||||
{
|
||||
for (auto& [id, type] : m_instances_cache) {
|
||||
type = new_type;
|
||||
if (new_type == ESLAViewType::Processed)
|
||||
select_full_instance(id);
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::set_type(const GLVolume::CompositeID& id, ESLAViewType new_type)
|
||||
{
|
||||
InstancesCacheItem* instance = find_instance_item(id);
|
||||
assert(instance != nullptr);
|
||||
instance->second = new_type;
|
||||
if (new_type == ESLAViewType::Processed)
|
||||
select_full_instance(id);
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::update_volumes_visibility(GLVolumePtrs& volumes)
|
||||
{
|
||||
const SLAPrint* sla_print = m_parent.sla_print();
|
||||
const std::vector<int> mo_idxs = (sla_print != nullptr) ? processed_objects_idxs(*m_parent.get_model(), *sla_print, volumes) : std::vector<int>();
|
||||
|
||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume);
|
||||
|
||||
for (GLVolume* v : volumes) {
|
||||
const int obj_idx = v->object_idx();
|
||||
bool active = std::find(mo_idxs.begin(), mo_idxs.end(), obj_idx) == mo_idxs.end();
|
||||
if (!active) {
|
||||
const InstancesCacheItem* instance = find_instance_item(v->composite_id);
|
||||
assert(instance != nullptr);
|
||||
active = (instance->second == ESLAViewType::Processed) ? v->volume_idx() < 0 : v->volume_idx() != -(int)slaposDrillHoles;
|
||||
}
|
||||
v->is_active = active;
|
||||
auto it = std::find_if(raycasters->begin(), raycasters->end(), [v](std::shared_ptr<SceneRaycasterItem> item) { return item->get_raycaster() == v->mesh_raycaster.get(); });
|
||||
if (it != raycasters->end())
|
||||
(*it)->set_active(v->is_active);
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::update_instances_cache(const std::vector<std::pair<GLVolume::CompositeID, GLVolume::CompositeID>>& new_to_old_ids_map)
|
||||
{
|
||||
// First, extract current instances list from the volumes
|
||||
const GLVolumePtrs& volumes = m_parent.get_volumes().volumes;
|
||||
std::vector<InstancesCacheItem> new_instances_cache;
|
||||
for (const GLVolume* v : volumes) {
|
||||
new_instances_cache.emplace_back(v->composite_id, ESLAViewType::Original);
|
||||
}
|
||||
|
||||
std::sort(new_instances_cache.begin(), new_instances_cache.end(),
|
||||
[](const InstancesCacheItem& i1, const InstancesCacheItem& i2) {
|
||||
return i1.first.object_id < i2.first.object_id || (i1.first.object_id == i2.first.object_id && i1.first.instance_id < i2.first.instance_id); });
|
||||
|
||||
new_instances_cache.erase(std::unique(new_instances_cache.begin(), new_instances_cache.end(),
|
||||
[](const InstancesCacheItem& i1, const InstancesCacheItem& i2) {
|
||||
return composite_id_match(i1.first, i2.first); }), new_instances_cache.end());
|
||||
|
||||
// Second, update instances type from previous state
|
||||
for (auto& inst_type : new_instances_cache) {
|
||||
const auto map_to_old_it = std::find_if(new_to_old_ids_map.begin(), new_to_old_ids_map.end(), [&inst_type](const std::pair<GLVolume::CompositeID, GLVolume::CompositeID>& item) {
|
||||
return composite_id_match(inst_type.first, item.first); });
|
||||
|
||||
const GLVolume::CompositeID old_inst_id = (map_to_old_it != new_to_old_ids_map.end()) ? map_to_old_it->second : inst_type.first;
|
||||
const InstancesCacheItem* old_instance = find_instance_item(old_inst_id);
|
||||
if (old_instance != nullptr)
|
||||
inst_type.second = old_instance->second;
|
||||
}
|
||||
|
||||
m_instances_cache = new_instances_cache;
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::render_switch_button()
|
||||
{
|
||||
const SLAPrint* sla_print = m_parent.sla_print();
|
||||
if (sla_print == nullptr)
|
||||
return;
|
||||
|
||||
const std::vector<int> mo_idxs = processed_objects_idxs(*m_parent.get_model(), *sla_print, m_parent.get_volumes().volumes);
|
||||
if (mo_idxs.empty())
|
||||
return;
|
||||
|
||||
Selection& selection = m_parent.get_selection();
|
||||
const int obj_idx = selection.get_object_idx();
|
||||
if (std::find(mo_idxs.begin(), mo_idxs.end(), obj_idx) == mo_idxs.end())
|
||||
return;
|
||||
|
||||
if (!object_contains_negative_volumes(*m_parent.get_model(), obj_idx))
|
||||
return;
|
||||
|
||||
const int inst_idx = selection.get_instance_idx();
|
||||
if (inst_idx < 0)
|
||||
return;
|
||||
|
||||
const GLVolume::CompositeID composite_id(obj_idx, 0, inst_idx);
|
||||
const InstancesCacheItem* sel_instance = find_instance_item(composite_id);
|
||||
if (sel_instance == nullptr)
|
||||
return;
|
||||
|
||||
const ESLAViewType type = sel_instance->second;
|
||||
|
||||
BoundingBoxf ss_box;
|
||||
if (m_use_instance_bbox) {
|
||||
const Selection::EMode mode = selection.get_mode();
|
||||
if (obj_idx >= 0 && inst_idx >= 0) {
|
||||
const Selection::IndicesList selected_idxs = selection.get_volume_idxs();
|
||||
std::vector<unsigned int> idxs_as_vector;
|
||||
idxs_as_vector.assign(selected_idxs.begin(), selected_idxs.end());
|
||||
selection.add_instance(obj_idx, inst_idx, true);
|
||||
ss_box = selection.get_screen_space_bounding_box();
|
||||
selection.add_volumes(mode, idxs_as_vector, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ss_box.defined)
|
||||
ss_box = selection.get_screen_space_bounding_box();
|
||||
assert(ss_box.defined);
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
ImGui::SetNextWindowPos(ImVec2((float)ss_box.max.x(), (float)ss_box.center().y()), ImGuiCond_Always, ImVec2(0.0, 0.5));
|
||||
imgui.begin(std::string("SLAViewSwitch"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration);
|
||||
const float icon_size = 1.5 * ImGui::GetTextLineHeight();
|
||||
if (imgui.draw_radio_button(_u8L("SLA view"), 1.5f * icon_size, true,
|
||||
[this, &imgui, sel_instance](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
const wchar_t icon_id = (sel_instance->second == ESLAViewType::Original) ? ImGui::SlaViewProcessed : ImGui::SlaViewOriginal;
|
||||
imgui.draw_icon(window, pos, size, icon_id);
|
||||
})) {
|
||||
switch (sel_instance->second)
|
||||
{
|
||||
case ESLAViewType::Original: { m_parent.set_sla_view_type(sel_instance->first, ESLAViewType::Processed); break; }
|
||||
case ESLAViewType::Processed: { m_parent.set_sla_view_type(sel_instance->first, ESLAViewType::Original); break; }
|
||||
default: { assert(false); break; }
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
|
||||
ImGui::BeginTooltip();
|
||||
wxString tooltip;
|
||||
switch (type)
|
||||
{
|
||||
case ESLAViewType::Original: { tooltip = _L("Show as processed"); break; }
|
||||
case ESLAViewType::Processed: { tooltip = _L("Show as original"); break; }
|
||||
default: { assert(false); break; }
|
||||
}
|
||||
|
||||
imgui.text(tooltip);
|
||||
ImGui::EndTooltip();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
imgui.end();
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
|
||||
#if ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
void GLCanvas3D::SLAView::render_debug_window()
|
||||
{
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
imgui.begin(std::string("SLAView"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
|
||||
for (const auto& [id, type] : m_instances_cache) {
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "(" + std::to_string(id.object_id) + ", " + std::to_string(id.instance_id) + ")");
|
||||
ImGui::SameLine();
|
||||
imgui.text_colored(ImGui::GetStyleColorVec4(ImGuiCol_Text), (type == ESLAViewType::Original) ? "Original" : "Processed");
|
||||
}
|
||||
if (!m_instances_cache.empty())
|
||||
ImGui::Separator();
|
||||
|
||||
imgui.checkbox("Use instance bounding box", m_use_instance_bbox);
|
||||
imgui.end();
|
||||
}
|
||||
#endif // ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
|
||||
GLCanvas3D::SLAView::InstancesCacheItem* GLCanvas3D::SLAView::find_instance_item(const GLVolume::CompositeID& id)
|
||||
{
|
||||
auto it = std::find_if(m_instances_cache.begin(), m_instances_cache.end(),
|
||||
[&id](const InstancesCacheItem& item) { return composite_id_match(item.first, id); });
|
||||
return (it == m_instances_cache.end()) ? nullptr : &(*it);
|
||||
}
|
||||
|
||||
void GLCanvas3D::SLAView::select_full_instance(const GLVolume::CompositeID& id)
|
||||
{
|
||||
bool extended_selection = false;
|
||||
Selection& selection = m_parent.get_selection();
|
||||
const Selection::ObjectIdxsToInstanceIdxsMap& sel_cache = selection.get_content();
|
||||
auto obj_it = sel_cache.find(id.object_id);
|
||||
if (obj_it != sel_cache.end()) {
|
||||
auto inst_it = std::find(obj_it->second.begin(), obj_it->second.end(), id.instance_id);
|
||||
if (inst_it != obj_it->second.end()) {
|
||||
selection.add_instance(id.object_id, id.instance_id);
|
||||
extended_selection = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (extended_selection)
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
|
||||
}
|
||||
|
||||
PrinterTechnology GLCanvas3D::current_printer_technology() const
|
||||
{
|
||||
return m_process->current_printer_technology();
|
||||
@ -1111,6 +1355,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
||||
, m_render_sla_auxiliaries(true)
|
||||
, m_labels(*this)
|
||||
, m_slope(m_volumes)
|
||||
, m_sla_view(*this)
|
||||
{
|
||||
if (m_canvas != nullptr) {
|
||||
m_timer.SetOwner(m_canvas);
|
||||
@ -1643,6 +1888,15 @@ void GLCanvas3D::render()
|
||||
wxGetApp().obj_manipul()->render_debug_window();
|
||||
#endif // ENABLE_OBJECT_MANIPULATION_DEBUG
|
||||
|
||||
if (wxGetApp().plater()->is_view3D_shown() && current_printer_technology() == ptSLA) {
|
||||
const GLGizmosManager::EType type = m_gizmos.get_current_type();
|
||||
if (type == GLGizmosManager::EType::Undefined)
|
||||
m_sla_view.render_switch_button();
|
||||
#if ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
m_sla_view.render_debug_window();
|
||||
#endif // ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
}
|
||||
|
||||
std::string tooltip;
|
||||
|
||||
// Negative coordinate means out of the window, likely because the window was deactivated.
|
||||
@ -1882,6 +2136,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
size_t volume_idx;
|
||||
};
|
||||
|
||||
std::vector<std::pair<GLVolume::CompositeID, GLVolume::CompositeID>> new_to_old_ids_map;
|
||||
|
||||
// SLA steps to pull the preview meshes for.
|
||||
typedef std::array<SLAPrintObjectStep, 3> SLASteps;
|
||||
SLASteps sla_steps = { slaposDrillHoles, slaposSupportTree, slaposPad };
|
||||
@ -2047,12 +2303,14 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx);
|
||||
m_volumes.volumes.back()->geometry_id = key.geometry_id;
|
||||
update_object_list = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Recycling an old GLVolume.
|
||||
GLVolume &existing_volume = *m_volumes.volumes[it->volume_idx];
|
||||
assert(existing_volume.geometry_id == key.geometry_id);
|
||||
// Update the Object/Volume/Instance indices into the current Model.
|
||||
if (existing_volume.composite_id != it->composite_id) {
|
||||
new_to_old_ids_map.push_back(std::make_pair(it->composite_id, existing_volume.composite_id));
|
||||
existing_volume.composite_id = it->composite_id;
|
||||
update_object_list = true;
|
||||
}
|
||||
@ -2106,7 +2364,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
}
|
||||
else {
|
||||
// Recycling an old GLVolume. Update the Object/Instance indices into the current Model.
|
||||
m_volumes.volumes[it->volume_idx]->composite_id = GLVolume::CompositeID(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx);
|
||||
const GLVolume::CompositeID new_id(object_idx, m_volumes.volumes[it->volume_idx]->volume_idx(), instance_idx);
|
||||
new_to_old_ids_map.push_back(std::make_pair(new_id, m_volumes.volumes[it->volume_idx]->composite_id));
|
||||
m_volumes.volumes[it->volume_idx]->composite_id = new_id;
|
||||
m_volumes.volumes[it->volume_idx]->set_instance_transformation(model_object->instances[instance_idx]->get_transformation());
|
||||
}
|
||||
}
|
||||
@ -2174,6 +2434,24 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
else
|
||||
m_selection.volumes_changed(map_glvolume_old_to_new);
|
||||
|
||||
if (printer_technology == ptSLA) {
|
||||
std::sort(new_to_old_ids_map.begin(), new_to_old_ids_map.end(),
|
||||
[](const std::pair<GLVolume::CompositeID, GLVolume::CompositeID>& i1, const std::pair<GLVolume::CompositeID, GLVolume::CompositeID>& i2) {
|
||||
return i1.first.object_id < i2.first.object_id || (i1.first.object_id == i2.first.object_id && i1.first.instance_id < i2.first.instance_id); });
|
||||
|
||||
new_to_old_ids_map.erase(std::unique(new_to_old_ids_map.begin(), new_to_old_ids_map.end(),
|
||||
[](const std::pair<GLVolume::CompositeID, GLVolume::CompositeID>& i1, const std::pair<GLVolume::CompositeID, GLVolume::CompositeID>& i2) {
|
||||
return composite_id_match(i1.first, i2.first); }), new_to_old_ids_map.end());
|
||||
|
||||
m_sla_view.update_instances_cache(new_to_old_ids_map);
|
||||
if (m_sla_view_type_detection_active) {
|
||||
m_sla_view.detect_type_from_volumes(m_volumes.volumes);
|
||||
m_sla_view_type_detection_active = false;
|
||||
}
|
||||
m_sla_view.update_volumes_visibility(m_volumes.volumes);
|
||||
update_object_list = true;
|
||||
}
|
||||
|
||||
m_gizmos.update_data();
|
||||
m_gizmos.refresh_on_off_state();
|
||||
|
||||
@ -4203,6 +4481,20 @@ std::pair<SlicingParameters, const std::vector<double>> GLCanvas3D::get_layers_h
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_sla_view_type(ESLAViewType type)
|
||||
{
|
||||
m_sla_view.set_type(type);
|
||||
m_sla_view.update_volumes_visibility(m_volumes.volumes);
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_sla_view_type(const GLVolume::CompositeID& id, ESLAViewType type)
|
||||
{
|
||||
m_sla_view.set_type(id, type);
|
||||
m_sla_view.update_volumes_visibility(m_volumes.volumes);
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::_is_shown_on_screen() const
|
||||
{
|
||||
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
|
||||
|
@ -466,6 +466,12 @@ public:
|
||||
int alignment = 0;
|
||||
};
|
||||
|
||||
enum class ESLAViewType
|
||||
{
|
||||
Original,
|
||||
Processed
|
||||
};
|
||||
|
||||
private:
|
||||
wxGLCanvas* m_canvas;
|
||||
wxGLContext* m_context;
|
||||
@ -545,11 +551,37 @@ private:
|
||||
bool m_tooltip_enabled{ true };
|
||||
Slope m_slope;
|
||||
|
||||
class SLAView
|
||||
{
|
||||
public:
|
||||
explicit SLAView(GLCanvas3D& parent) : m_parent(parent) {}
|
||||
void detect_type_from_volumes(const GLVolumePtrs& volumes);
|
||||
void set_type(ESLAViewType type);
|
||||
void set_type(const GLVolume::CompositeID& id, ESLAViewType type);
|
||||
void update_volumes_visibility(GLVolumePtrs& volumes);
|
||||
void update_instances_cache(const std::vector<std::pair<GLVolume::CompositeID, GLVolume::CompositeID>>& new_to_old_ids_map);
|
||||
void render_switch_button();
|
||||
|
||||
#if ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
void render_debug_window();
|
||||
#endif // ENABLE_SLA_VIEW_DEBUG_WINDOW
|
||||
|
||||
private:
|
||||
GLCanvas3D& m_parent;
|
||||
typedef std::pair<GLVolume::CompositeID, ESLAViewType> InstancesCacheItem;
|
||||
std::vector<InstancesCacheItem> m_instances_cache;
|
||||
bool m_use_instance_bbox{ true };
|
||||
|
||||
InstancesCacheItem* find_instance_item(const GLVolume::CompositeID& id);
|
||||
void select_full_instance(const GLVolume::CompositeID& id);
|
||||
};
|
||||
|
||||
SLAView m_sla_view;
|
||||
bool m_sla_view_type_detection_active{ false };
|
||||
|
||||
ArrangeSettings m_arrange_settings_fff, m_arrange_settings_sla,
|
||||
m_arrange_settings_fff_seq_print;
|
||||
|
||||
PrinterTechnology current_printer_technology() const;
|
||||
|
||||
bool is_arrange_alignment_enabled() const;
|
||||
|
||||
template<class Self>
|
||||
@ -654,7 +686,7 @@ private:
|
||||
GLModel m_background;
|
||||
|
||||
public:
|
||||
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
|
||||
GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed);
|
||||
~GLCanvas3D();
|
||||
|
||||
bool is_initialized() const { return m_initialized; }
|
||||
@ -767,6 +799,8 @@ public:
|
||||
void zoom_to_gcode();
|
||||
void select_view(const std::string& direction);
|
||||
|
||||
PrinterTechnology current_printer_technology() const;
|
||||
|
||||
void update_volumes_colors_by_extruder();
|
||||
|
||||
bool is_dragging() const { return m_gizmos.is_dragging() || (m_moving && !m_mouse.scene_position.isApprox(m_mouse.drag.start_position_3D)); }
|
||||
@ -954,6 +988,10 @@ public:
|
||||
|
||||
std::pair<SlicingParameters, const std::vector<double>> get_layers_height_data(int object_id);
|
||||
|
||||
void set_sla_view_type(ESLAViewType type);
|
||||
void set_sla_view_type(const GLVolume::CompositeID& id, ESLAViewType type);
|
||||
void enable_sla_view_type_detection() { m_sla_view_type_detection_active = true; }
|
||||
|
||||
private:
|
||||
bool _is_shown_on_screen() const;
|
||||
|
||||
|
@ -758,6 +758,10 @@ void ObjectList::selection_changed()
|
||||
wxGetApp().obj_layers()->update_scene_from_editor_selection();
|
||||
}
|
||||
}
|
||||
else if (type & itVolume) {
|
||||
if (printer_technology() == ptSLA)
|
||||
wxGetApp().plater()->canvas3D()->set_sla_view_type(scene_selection().get_first_volume()->composite_id, GLCanvas3D::ESLAViewType::Original);
|
||||
}
|
||||
}
|
||||
|
||||
part_selection_changed();
|
||||
|
@ -87,6 +87,8 @@ void GLGizmoSlaSupports::data_changed(bool is_serializing)
|
||||
register_point_raycasters_for_picking();
|
||||
else
|
||||
update_point_raycasters_for_picking_transform();
|
||||
|
||||
m_c->instances_hider()->set_hide_full_scene(true);
|
||||
}
|
||||
|
||||
// m_parent.toggle_model_objects_visibility(false);
|
||||
|
@ -978,6 +978,9 @@ bool GLGizmosManager::activate_gizmo(EType type)
|
||||
return false; // gizmo refused to be turned on.
|
||||
}
|
||||
|
||||
if (m_parent.current_printer_technology() == ptSLA)
|
||||
m_parent.set_sla_view_type(GLCanvas3D::ESLAViewType::Original);
|
||||
|
||||
new_gizmo.register_raycasters_for_picking();
|
||||
|
||||
// sucessful activation of gizmo
|
||||
|
@ -104,6 +104,8 @@ static const std::map<const wchar_t, std::string> font_icons_large = {
|
||||
{ImGui::PauseHoverButton , "notification_pause_hover" },
|
||||
{ImGui::OpenButton , "notification_open" },
|
||||
{ImGui::OpenHoverButton , "notification_open_hover" },
|
||||
{ImGui::SlaViewOriginal , "sla_view_original" },
|
||||
{ImGui::SlaViewProcessed , "sla_view_processed" },
|
||||
};
|
||||
|
||||
static const std::map<const wchar_t, std::string> font_icons_extra_large = {
|
||||
@ -490,6 +492,18 @@ bool ImGuiWrapper::radio_button(const wxString &label, bool active)
|
||||
return ImGui::RadioButton(label_utf8.c_str(), active);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::draw_icon(ImGuiWindow& window, const ImVec2& pos, float size, wchar_t icon_id)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
const ImTextureID tex_id = io.Fonts->TexID;
|
||||
const float tex_w = static_cast<float>(io.Fonts->TexWidth);
|
||||
const float tex_h = static_cast<float>(io.Fonts->TexHeight);
|
||||
const ImFontAtlas::CustomRect* const rect = GetTextureCustomRect(icon_id);
|
||||
const ImVec2 uv0 = { static_cast<float>(rect->X) / tex_w, static_cast<float>(rect->Y) / tex_h };
|
||||
const ImVec2 uv1 = { static_cast<float>(rect->X + rect->Width) / tex_w, static_cast<float>(rect->Y + rect->Height) / tex_h };
|
||||
window.DrawList->AddImage(tex_id, pos, { pos.x + size, pos.y + size }, uv0, uv1, ImGuiWrapper::to_ImU32({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::draw_radio_button(const std::string& name, float size, bool active,
|
||||
std::function<void(ImGuiWindow& window, const ImVec2& pos, float size)> draw_callback)
|
||||
{
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
bool button(const wxString& label, float width, float height);
|
||||
bool button(const wxString& label, const ImVec2 &size, bool enable); // default size = ImVec2(0.f, 0.f)
|
||||
bool radio_button(const wxString &label, bool active);
|
||||
void draw_icon(ImGuiWindow& window, const ImVec2& pos, float size, wchar_t icon_id);
|
||||
bool draw_radio_button(const std::string& name, float size, bool active, std::function<void(ImGuiWindow& window, const ImVec2& pos, float size)> draw_callback);
|
||||
bool checkbox(const wxString &label, bool &value);
|
||||
static void text(const char *label);
|
||||
|
@ -4080,8 +4080,10 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
||||
// If RELOAD_SLA_SUPPORT_POINTS, then the SLA gizmo is updated (reload_scene calls update_gizmos_data)
|
||||
if (view3D->is_dragging())
|
||||
delayed_scene_refresh = true;
|
||||
else
|
||||
else {
|
||||
view3D->get_canvas3d()->enable_sla_view_type_detection();
|
||||
this->update_sla_scene();
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@ -6944,10 +6946,12 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
||||
|
||||
p->config->set_key_value(opt_key, config.option(opt_key)->clone());
|
||||
if (opt_key == "printer_technology") {
|
||||
this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
|
||||
const PrinterTechnology printer_technology = config.opt_enum<PrinterTechnology>(opt_key);
|
||||
this->set_printer_technology(printer_technology);
|
||||
p->sidebar->show_sliced_info_sizer(false);
|
||||
p->reset_gcode_toolpaths();
|
||||
p->view3D->get_canvas3d()->reset_sequential_print_clearance();
|
||||
p->view3D->get_canvas3d()->set_sla_view_type(GLCanvas3D::ESLAViewType::Original);
|
||||
}
|
||||
else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") {
|
||||
bed_shape_changed = true;
|
||||
|
@ -858,6 +858,43 @@ std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_s
|
||||
return { out_box, out_trafo.get_matrix_no_scaling_factor() };
|
||||
}
|
||||
|
||||
BoundingBoxf Selection::get_screen_space_bounding_box()
|
||||
{
|
||||
BoundingBoxf ss_box;
|
||||
if (!is_empty()) {
|
||||
const auto& [box, box_trafo] = get_bounding_box_in_current_reference_system();
|
||||
|
||||
// vertices
|
||||
std::vector<Vec3d> vertices = {
|
||||
{ box.min.x(), box.min.y(), box.min.z() },
|
||||
{ box.max.x(), box.min.y(), box.min.z() },
|
||||
{ box.max.x(), box.max.y(), box.min.z() },
|
||||
{ box.min.x(), box.max.y(), box.min.z() },
|
||||
{ box.min.x(), box.min.y(), box.max.z() },
|
||||
{ box.max.x(), box.min.y(), box.max.z() },
|
||||
{ box.max.x(), box.max.y(), box.max.z() },
|
||||
{ box.min.x(), box.max.y(), box.max.z() }
|
||||
};
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Matrix4d projection_view_matrix = camera.get_projection_matrix().matrix() * camera.get_view_matrix().matrix();
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
|
||||
const double half_w = 0.5 * double(viewport[2]);
|
||||
const double h = double(viewport[3]);
|
||||
const double half_h = 0.5 * h;
|
||||
for (const Vec3d& v : vertices) {
|
||||
const Vec3d world = box_trafo * v;
|
||||
const Vec4d clip = projection_view_matrix * Vec4d(world.x(), world.y(), world.z(), 1.0);
|
||||
const Vec3d ndc = Vec3d(clip.x(), clip.y(), clip.z()) / clip.w();
|
||||
const Vec2d ss = Vec2d(half_w * ndc.x() + double(viewport[0]) + half_w, h - (half_h * ndc.y() + double(viewport[1]) + half_h));
|
||||
ss_box.merge(ss);
|
||||
}
|
||||
}
|
||||
|
||||
return ss_box;
|
||||
}
|
||||
|
||||
void Selection::setup_cache()
|
||||
{
|
||||
if (!m_valid)
|
||||
@ -1717,8 +1754,7 @@ std::vector<unsigned int> Selection::get_volume_idxs_from_volume(unsigned int ob
|
||||
{
|
||||
std::vector<unsigned int> idxs;
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) {
|
||||
const GLVolume* v = (*m_volumes)[i];
|
||||
if (v->object_idx() == (int)object_idx && v->volume_idx() == (int)volume_idx) {
|
||||
if ((int)instance_idx != -1 && v->instance_idx() == (int)instance_idx)
|
||||
|
@ -319,6 +319,9 @@ public:
|
||||
// and the transform to place and orient it in world coordinates
|
||||
std::pair<BoundingBoxf3, Transform3d> get_bounding_box_in_reference_system(ECoordinatesType type) const;
|
||||
|
||||
// Returns the screen space bounding box
|
||||
BoundingBoxf get_screen_space_bounding_box();
|
||||
|
||||
void setup_cache();
|
||||
|
||||
void translate(const Vec3d& displacement, TransformationType transformation_type);
|
||||
|
Loading…
Reference in New Issue
Block a user