Tech ENABLE_SHOW_TOOLPATHS_COG - Show toolpaths center of gravity
This commit is contained in:
parent
f6c7fefec2
commit
92aa6540f5
50
resources/icons/legend_cog.svg
Normal file
50
resources/icons/legend_cog.svg
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 1000 1000"
|
||||
enable-background="new 0 0 1000 1000"
|
||||
xml:space="preserve"
|
||||
id="svg1405"
|
||||
sodipodi:docname="legend_cog.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="defs1409" /><sodipodi:namedview
|
||||
id="namedview1407"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.57417071"
|
||||
inkscape:cx="498.98052"
|
||||
inkscape:cy="500.72217"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g1403" />
|
||||
<metadata
|
||||
id="metadata1400"> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||
<g
|
||||
id="g1403"><g
|
||||
id="g3385"
|
||||
transform="matrix(0.9,0,0,0.9,50,50)"><path
|
||||
id="Delicious"
|
||||
d="M 951.5,309.2 C 914.3,221.2 852.2,146.5 774,93.7 734.9,67.3 691.8,46.3 645.7,32 599.6,17.7 550.7,10 500,10 432.4,10 367.9,23.7 309.3,48.5 221.3,85.7 146.5,147.8 93.7,226 67.3,265.1 46.3,308.2 32,354.3 c -14.3,46 -22,95 -22,145.7 0,67.6 13.7,132.1 38.5,190.8 37.2,88 99.3,162.7 177.5,215.5 39.1,26.4 82.2,47.3 128.3,61.7 46,14.4 95,22 145.7,22 67.5,0 132.1,-13.7 190.7,-38.5 88,-37.2 162.7,-99.3 215.6,-177.5 26.4,-39.1 47.3,-82.3 61.7,-128.3 14.3,-46 22,-95 22,-145.7 0,-67.6 -13.7,-132.1 -38.5,-190.8 z m -61,355.7 c -32.2,76 -85.9,140.8 -153.6,186.4 -33.8,22.9 -71.1,41 -110.9,53.3 -39.8,12.3 -82.1,19 -126,19.1 v 0 -423.2 H 76.3 c 0,-0.2 0,-0.3 0,-0.5 0,-58.6 11.8,-114.2 33.3,-164.9 32.1,-76 85.9,-140.8 153.6,-186.5 33.8,-22.8 71.1,-40.9 110.9,-53.3 39.8,-12.4 82.1,-19 126,-19 V 500 h 423.7 c -0.1,58.6 -11.9,114.2 -33.3,164.9 z" /></g><path
|
||||
style="fill:#ffffff;stroke-width:7.38916;stroke-miterlimit:10;fill-opacity:1"
|
||||
d="m 77.139043,487.37685 c 3.697394,-84.56835 26.698247,-155.86557 72.010107,-223.21429 16.59166,-24.6608 30.37464,-41.20638 53.34679,-64.03941 27.30359,-27.13822 52.65045,-46.7668 84.88257,-65.73293 55.05852,-32.39773 124.18158,-53.51654 183.99427,-56.214822 7.95557,-0.358893 17.65123,-0.906877 21.54594,-1.217743 L 500,76.392444 V 288.19622 500 H 288.29357 76.58715 Z"
|
||||
id="path1516" /><path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:7.38916;stroke-miterlimit:10"
|
||||
d="M 500,711.76464 V 500 h 211.90502 211.90504 l -0.7671,13.23892 c -1.37279,23.69173 -3.21854,41.23939 -6.18546,58.80541 -24.78089,146.71813 -128.58118,271.82029 -269.07425,324.29358 -38.30204,14.30558 -84.14865,23.99629 -120.68965,25.51049 -8.46675,0.35085 -18.02648,0.87257 -21.24385,1.1594 L 500,923.52927 Z"
|
||||
id="path3257" /></g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
18
resources/shaders/toolpaths_cog.fs
Normal file
18
resources/shaders/toolpaths_cog.fs
Normal file
@ -0,0 +1,18 @@
|
||||
#version 110
|
||||
|
||||
const vec4 BLACK = vec4(vec3(0.1), 1.0);
|
||||
const vec4 WHITE = vec4(vec3(1.0), 1.0);
|
||||
|
||||
const float emission_factor = 0.25;
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
varying vec3 world_position;
|
||||
uniform vec3 world_center;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 delta = world_position - world_center;
|
||||
vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0);
|
||||
}
|
40
resources/shaders/toolpaths_cog.vs
Normal file
40
resources/shaders/toolpaths_cog.vs
Normal file
@ -0,0 +1,40 @@
|
||||
#version 110
|
||||
|
||||
#define INTENSITY_CORRECTION 0.6
|
||||
|
||||
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
|
||||
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
|
||||
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
|
||||
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
|
||||
#define LIGHT_TOP_SHININESS 20.0
|
||||
|
||||
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
|
||||
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
|
||||
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
|
||||
|
||||
#define INTENSITY_AMBIENT 0.3
|
||||
|
||||
// x = tainted, y = specular;
|
||||
varying vec2 intensity;
|
||||
varying vec3 world_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
// First transform the normal into camera space and normalize the result.
|
||||
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
|
||||
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
|
||||
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
|
||||
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
|
||||
|
||||
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
|
||||
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
|
||||
|
||||
// Perform the same lighting calculation for the 2nd light source (no specular applied).
|
||||
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
|
||||
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||
|
||||
world_position = gl_Vertex.xyz;
|
||||
gl_Position = ftransform();
|
||||
}
|
@ -165,8 +165,9 @@ namespace ImGui
|
||||
const wchar_t LegendColorChanges = 0x2612;
|
||||
const wchar_t LegendPausePrints = 0x2613;
|
||||
const wchar_t LegendCustomGCodes = 0x2614;
|
||||
const wchar_t LegendShells = 0x2615;
|
||||
const wchar_t LegendToolMarker = 0x2616;
|
||||
const wchar_t LegendCOG = 0x2615;
|
||||
const wchar_t LegendShells = 0x2616;
|
||||
const wchar_t LegendToolMarker = 0x2617;
|
||||
|
||||
// void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
|
@ -72,6 +72,8 @@
|
||||
#define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1)
|
||||
// Enable rework of Reload from disk command
|
||||
#define ENABLE_RELOAD_FROM_DISK_REWORK (1 && ENABLE_2_5_0_ALPHA1)
|
||||
// Enable showing toolpaths center of gravity
|
||||
#define ENABLE_SHOW_TOOLPATHS_COG (1 && ENABLE_2_5_0_ALPHA1)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
@ -160,6 +160,66 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessorResult::MoveVertex& move
|
||||
move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } });
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
void GCodeViewer::COG::render()
|
||||
{
|
||||
if (!m_visible)
|
||||
return;
|
||||
|
||||
init();
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
const Vec3d position = cog();
|
||||
glsafe(::glTranslated(position.x(), position.y(), position.z()));
|
||||
if (m_fixed_size) {
|
||||
const double inv_zoom = wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||
glsafe(::glScaled(inv_zoom, inv_zoom, inv_zoom));
|
||||
}
|
||||
m_model.render();
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
shader->stop_using();
|
||||
|
||||
////Show ImGui window
|
||||
//static float last_window_width = 0.0f;
|
||||
//static size_t last_text_length = 0;
|
||||
|
||||
//ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
//const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
|
||||
//imgui.set_next_window_pos(0.5f * static_cast<float>(cnv_size.get_width()), 0.0f, ImGuiCond_Always, 0.5f, 0.0f);
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
//ImGui::SetNextWindowBgAlpha(0.25f);
|
||||
//imgui.begin(std::string("COG"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
|
||||
//imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Center of mass") + ":");
|
||||
//ImGui::SameLine();
|
||||
//char buf[1024];
|
||||
//const Vec3d position = cog();
|
||||
//sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", position.x(), position.y(), position.z());
|
||||
//imgui.text(std::string(buf));
|
||||
|
||||
//// force extra frame to automatically update window size
|
||||
//const float width = ImGui::GetWindowWidth();
|
||||
//const size_t length = strlen(buf);
|
||||
//if (width != last_window_width || length != last_text_length) {
|
||||
// last_window_width = width;
|
||||
// last_text_length = length;
|
||||
// imgui.set_requires_extra_frame();
|
||||
//}
|
||||
|
||||
//imgui.end();
|
||||
//ImGui::PopStyleVar();
|
||||
}
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
#if ENABLE_PREVIEW_LAYER_TIME
|
||||
float GCodeViewer::Extrusions::Range::step_size(EType type) const
|
||||
{
|
||||
@ -955,6 +1015,9 @@ unsigned int GCodeViewer::get_options_visibility_flags() const
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(EMoveType::Color_change));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(EMoveType::Pause_Print));
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::CustomGCodes), is_toolpath_move_type_visible(EMoveType::Custom_GCode));
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::CenterOfGravity), m_cog.is_visible());
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Shells), m_shells.visible);
|
||||
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ToolMarker), m_sequential_view.marker.is_visible());
|
||||
#if !ENABLE_PREVIEW_LAYOUT
|
||||
@ -978,6 +1041,9 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags)
|
||||
set_toolpath_move_type_visible(EMoveType::Color_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ColorChanges)));
|
||||
set_toolpath_move_type_visible(EMoveType::Pause_Print, is_flag_set(static_cast<unsigned int>(Preview::OptionType::PausePrints)));
|
||||
set_toolpath_move_type_visible(EMoveType::Custom_GCode, is_flag_set(static_cast<unsigned int>(Preview::OptionType::CustomGCodes)));
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
m_cog.set_visible(is_flag_set(static_cast<unsigned int>(Preview::OptionType::CenterOfGravity)));
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
m_shells.visible = is_flag_set(static_cast<unsigned int>(Preview::OptionType::Shells));
|
||||
m_sequential_view.marker.set_visible(is_flag_set(static_cast<unsigned int>(Preview::OptionType::ToolMarker)));
|
||||
#if !ENABLE_PREVIEW_LAYOUT
|
||||
@ -1537,6 +1603,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
||||
if (wxGetApp().is_editor())
|
||||
m_contained_in_bed = wxGetApp().plater()->build_volume().all_paths_inside(gcode_result, m_paths_bounding_box);
|
||||
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
m_cog.reset();
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
m_sequential_view.gcode_ids.clear();
|
||||
for (size_t i = 0; i < gcode_result.moves.size(); ++i) {
|
||||
const GCodeProcessorResult::MoveVertex& move = gcode_result.moves[i];
|
||||
@ -1551,18 +1621,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
||||
std::vector<InstancesOffsets> instances_offsets(m_buffers.size());
|
||||
std::vector<float> options_zs;
|
||||
|
||||
size_t seams_count = 0;
|
||||
std::vector<size_t> biased_seams_ids;
|
||||
|
||||
// toolpaths data -> extract vertices from result
|
||||
for (size_t i = 0; i < m_moves_count; ++i) {
|
||||
const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
|
||||
if (curr.type == EMoveType::Seam) {
|
||||
++seams_count;
|
||||
if (curr.type == EMoveType::Seam)
|
||||
biased_seams_ids.push_back(i - biased_seams_ids.size() - 1);
|
||||
}
|
||||
|
||||
size_t move_id = i - seams_count;
|
||||
const size_t move_id = i - biased_seams_ids.size();
|
||||
|
||||
// skip first vertex
|
||||
if (i == 0)
|
||||
@ -1570,6 +1637,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
||||
|
||||
const GCodeProcessorResult::MoveVertex& prev = gcode_result.moves[i - 1];
|
||||
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
if (curr.type == EMoveType::Extrude &&
|
||||
curr.extrusion_role != erSkirt &&
|
||||
curr.extrusion_role != erSupportMaterial &&
|
||||
curr.extrusion_role != erSupportMaterialInterface &&
|
||||
curr.extrusion_role != erWipeTower &&
|
||||
curr.extrusion_role != erCustom &&
|
||||
curr.extrusion_role != erMixed) {
|
||||
const Vec3d curr_pos = curr.position.cast<double>();
|
||||
const Vec3d prev_pos = prev.position.cast<double>();
|
||||
m_cog.add_segment(curr_pos, prev_pos, curr.mm3_per_mm * (curr_pos - prev_pos).norm());
|
||||
}
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
// update progress dialog
|
||||
++progress_count;
|
||||
if (progress_dialog != nullptr && progress_count % progress_threshold == 0) {
|
||||
@ -1893,14 +1974,14 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
||||
using VboIndexList = std::vector<unsigned int>;
|
||||
std::vector<VboIndexList> vbo_indices(m_buffers.size());
|
||||
|
||||
seams_count = 0;
|
||||
size_t seams_count = 0;
|
||||
|
||||
for (size_t i = 0; i < m_moves_count; ++i) {
|
||||
const GCodeProcessorResult::MoveVertex& curr = gcode_result.moves[i];
|
||||
if (curr.type == EMoveType::Seam)
|
||||
++seams_count;
|
||||
|
||||
size_t move_id = i - seams_count;
|
||||
const size_t move_id = i - seams_count;
|
||||
|
||||
// skip first vertex
|
||||
if (i == 0)
|
||||
@ -4074,15 +4155,6 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
};
|
||||
|
||||
#if ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
// auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) {
|
||||
// const float margin = 3.0f;
|
||||
// const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size));
|
||||
// window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16);
|
||||
// };
|
||||
// auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) {
|
||||
// const float margin = 3.0f;
|
||||
// window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f);
|
||||
// };
|
||||
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;
|
||||
@ -4091,17 +4163,17 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
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, ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||
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 }));
|
||||
};
|
||||
#else
|
||||
auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) {
|
||||
const float margin = 3.0f;
|
||||
auto circle_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const ColorRGBA& color) {
|
||||
const float margin = 3.0f;
|
||||
const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size));
|
||||
window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 16);
|
||||
window.DrawList->AddCircleFilled(center, 0.5f * (size - 2.0f * margin), ImGuiWrapper::to_ImU32(color), 16);
|
||||
};
|
||||
auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const Color& color) {
|
||||
auto line_icon = [](ImGuiWindow& window, const ImVec2& pos, float size, const ColorRGBA& color) {
|
||||
const float margin = 3.0f;
|
||||
window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f);
|
||||
window.DrawList->AddLine({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin, pos.y + margin }, ImGuiWrapper::to_ImU32(color), 3.0f);
|
||||
};
|
||||
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
|
||||
@ -4190,12 +4262,41 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
});
|
||||
ImGui::SameLine();
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
#if ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
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);
|
||||
});
|
||||
#else
|
||||
toggle_button(Preview::OptionType::CenterOfGravity, _u8L("Center of gravity"), [](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
const ImU32 black = ImGuiWrapper::to_ImU32({ 0.0f, 0.0f, 0.0f, 1.0f });
|
||||
const ImU32 white = ImGuiWrapper::to_ImU32({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
const float margin = 3.0f;
|
||||
const ImVec2 center(0.5f * (pos.x + pos.x + size), 0.5f * (pos.y + pos.y + size));
|
||||
const float radius = 0.5f * (size - 2.0f * margin);
|
||||
window.DrawList->PathArcToFast(center, radius, 0, 3);
|
||||
window.DrawList->PathLineTo(center);
|
||||
window.DrawList->PathFillConvex(black);
|
||||
window.DrawList->PathArcToFast(center, radius, 3, 6);
|
||||
window.DrawList->PathLineTo(center);
|
||||
window.DrawList->PathFillConvex(white);
|
||||
window.DrawList->PathArcToFast(center, radius, 6, 9);
|
||||
window.DrawList->PathLineTo(center);
|
||||
window.DrawList->PathFillConvex(black);
|
||||
window.DrawList->PathArcToFast(center, radius, 9, 12);
|
||||
window.DrawList->PathLineTo(center);
|
||||
window.DrawList->PathFillConvex(white);
|
||||
window.DrawList->AddCircle(center, radius, black, 16);
|
||||
});
|
||||
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
ImGui::SameLine();
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
#if ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [image_icon](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
image_icon(window, pos, size, ImGui::LegendShells);
|
||||
#else
|
||||
toggle_button(Preview::OptionType::Shells, _u8L("Shells"), [](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
const ImU32 color = ImGuiWrapper::to_ImU32({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
const float margin = 3.0f;
|
||||
const float proj = 0.25f * size;
|
||||
window.DrawList->AddRect({ pos.x + margin, pos.y + size - margin }, { pos.x + size - margin - proj, pos.y + margin + proj }, color);
|
||||
@ -4212,11 +4313,11 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
image_icon(window, pos, size, ImGui::LegendToolMarker);
|
||||
#else
|
||||
toggle_button(Preview::OptionType::ToolMarker, _u8L("Tool marker"), [](ImGuiWindow& window, const ImVec2& pos, float size) {
|
||||
const ImU32 color = ImGui::GetColorU32({ 1.0f, 1.0f, 1.0f, 0.8f });
|
||||
const ImU32 color = ImGuiWrapper::to_ImU32({ 1.0f, 1.0f, 1.0f, 0.8f });
|
||||
const float margin = 3.0f;
|
||||
const ImVec2 p1(0.5f * (pos.x + pos.x + size), pos.y + size - margin);
|
||||
const ImVec2 p2 = ImVec2(p1.x + 0.25f * size, p1.y - 0.25f * size);
|
||||
const ImVec2 p3 = ImVec2(p1.x - 0.25f * size, p1.y - 0.25f * size);
|
||||
const ImVec2 p2(p1.x + 0.25f * size, p1.y - 0.25f * size);
|
||||
const ImVec2 p3(p1.x - 0.25f * size, p1.y - 0.25f * size);
|
||||
window.DrawList->AddTriangleFilled(p1, p2, p3, color);
|
||||
const float mid_x = 0.5f * (pos.x + pos.x + size);
|
||||
window.DrawList->AddRectFilled({ mid_x - 0.09375f * size, p1.y - 0.25f * size }, { mid_x + 0.09375f * size, pos.y + margin }, color);
|
||||
|
@ -380,6 +380,52 @@ class GCodeViewer
|
||||
bool visible{ false };
|
||||
};
|
||||
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
// helper to render center of gravity
|
||||
class COG
|
||||
{
|
||||
GLModel m_model;
|
||||
bool m_visible{ false };
|
||||
// whether or not to render the model with fixed screen size
|
||||
bool m_fixed_size{ true };
|
||||
double m_total_mass{ 0.0 };
|
||||
Vec3d m_position{ Vec3d::Zero() };
|
||||
|
||||
public:
|
||||
void render();
|
||||
|
||||
void reset() {
|
||||
m_position = Vec3d::Zero();
|
||||
m_total_mass = 0.0;
|
||||
}
|
||||
|
||||
bool is_visible() const { return m_visible; }
|
||||
void set_visible(bool visible) { m_visible = visible; }
|
||||
|
||||
void add_segment(const Vec3d& v1, const Vec3d& v2, double mass) {
|
||||
assert(mass > 0.0);
|
||||
m_position += mass * 0.5 * (v1 + v2);
|
||||
m_total_mass += mass;
|
||||
}
|
||||
|
||||
Vec3d cog() const { return (m_total_mass > 0.0) ? (Vec3d)(m_position / m_total_mass) : Vec3d::Zero(); }
|
||||
|
||||
private:
|
||||
void init() {
|
||||
if (m_model.is_initialized())
|
||||
return;
|
||||
|
||||
const float radius = m_fixed_size ? 10.0f : 1.0f;
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
m_model.init_from(smooth_sphere(32, radius));
|
||||
#else
|
||||
m_model.init_from(its_make_sphere(radius, PI / 32.0));
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
}
|
||||
};
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
// helper to render extrusion paths
|
||||
struct Extrusions
|
||||
{
|
||||
@ -734,6 +780,9 @@ private:
|
||||
Extrusions m_extrusions;
|
||||
SequentialView m_sequential_view;
|
||||
Shells m_shells;
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
COG m_cog;
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
EViewType m_view_type{ EViewType::FeatureType };
|
||||
bool m_legend_enabled{ true };
|
||||
#if ENABLE_PREVIEW_LAYOUT
|
||||
@ -779,6 +828,9 @@ public:
|
||||
|
||||
void reset();
|
||||
void render();
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
void render_cog() { m_cog.render(); }
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
bool has_data() const { return !m_roles.empty(); }
|
||||
bool can_export_toolpaths() const;
|
||||
|
@ -1600,6 +1600,10 @@ void GLCanvas3D::render()
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
_render_selection_center();
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
if (!m_main_toolbar.is_enabled())
|
||||
_render_gcode_cog();
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
// we need to set the mouse's scene position here because the depth buffer
|
||||
// could be invalidated by the following gizmo render methods
|
||||
@ -5415,6 +5419,13 @@ void GLCanvas3D::_render_gcode()
|
||||
m_gcode_viewer.render();
|
||||
}
|
||||
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
void GLCanvas3D::_render_gcode_cog()
|
||||
{
|
||||
m_gcode_viewer.render_cog();
|
||||
}
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
|
||||
void GLCanvas3D::_render_selection()
|
||||
{
|
||||
float scale_factor = 1.0;
|
||||
|
@ -938,6 +938,9 @@ private:
|
||||
void _render_bed_for_picking(bool bottom);
|
||||
void _render_objects(GLVolumeCollection::ERenderType type);
|
||||
void _render_gcode();
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
void _render_gcode_cog();
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
void _render_selection();
|
||||
void _render_sequential_clearance();
|
||||
#if ENABLE_RENDER_SELECTION_CENTER
|
||||
|
@ -1724,7 +1724,7 @@ GLModel::Geometry diamond(unsigned short resolution)
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
// vertices
|
||||
for (unsigned short i = 0; i < resolution; ++i) {
|
||||
float ii = float(i) * step;
|
||||
const float ii = float(i) * step;
|
||||
const Vec3f p = { 0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f };
|
||||
append_vertex(data, p, p.normalized());
|
||||
}
|
||||
@ -1785,5 +1785,73 @@ GLModel::Geometry diamond(unsigned short resolution)
|
||||
return data;
|
||||
}
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
GLModel::Geometry smooth_sphere(unsigned short resolution, float radius)
|
||||
{
|
||||
resolution = std::max<unsigned short>(4, resolution);
|
||||
resolution = std::min<unsigned short>(256, resolution); // ensure no unsigned short overflow of indices
|
||||
|
||||
const unsigned short sectorCount = /*2 **/ resolution;
|
||||
const unsigned short stackCount = resolution;
|
||||
|
||||
const float sectorStep = float(2.0 * M_PI / sectorCount);
|
||||
const float stackStep = float(M_PI / stackCount);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
|
||||
data.vertices.reserve(((stackCount - 1) * sectorCount + 2) * GLModel::Geometry::vertex_stride_floats(data.format));
|
||||
data.indices.reserve(((2 * (stackCount - 1) * sectorCount) * 3) * GLModel::Geometry::index_stride_bytes(data.format));
|
||||
|
||||
// vertices
|
||||
for (unsigned short i = 0; i <= stackCount; ++i) {
|
||||
// from pi/2 to -pi/2
|
||||
const double stackAngle = 0.5 * M_PI - stackStep * i;
|
||||
const double xy = double(radius) * ::cos(stackAngle);
|
||||
const double z = double(radius) * ::sin(stackAngle);
|
||||
if (i == 0 || i == stackCount) {
|
||||
const Vec3f v(float(xy), 0.0f, float(z));
|
||||
data.add_vertex(v, (Vec3f)v.normalized());
|
||||
}
|
||||
else {
|
||||
for (unsigned short j = 0; j < sectorCount; ++j) {
|
||||
// from 0 to 2pi
|
||||
const double sectorAngle = sectorStep * j;
|
||||
const Vec3f v(float(xy * std::cos(sectorAngle)), float(xy * std::sin(sectorAngle)), float(z));
|
||||
data.add_vertex(v, (Vec3f)v.normalized());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// triangles
|
||||
for (unsigned short i = 0; i < stackCount; ++i) {
|
||||
// Beginning of current stack.
|
||||
unsigned short k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount);
|
||||
const unsigned short k1_first = k1;
|
||||
// Beginning of next stack.
|
||||
unsigned short k2 = (i == 0) ? 1 : (k1 + sectorCount);
|
||||
const unsigned short k2_first = k2;
|
||||
for (unsigned short j = 0; j < sectorCount; ++j) {
|
||||
// 2 triangles per sector excluding first and last stacks
|
||||
unsigned short k1_next = k1;
|
||||
unsigned short k2_next = k2;
|
||||
if (i != 0) {
|
||||
k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1);
|
||||
data.add_ushort_triangle(k1, k2, k1_next);
|
||||
}
|
||||
if (i + 1 != stackCount) {
|
||||
k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1);
|
||||
data.add_ushort_triangle(k1_next, k2, k2_next);
|
||||
}
|
||||
k1 = k1_next;
|
||||
k2 = k2_next;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
@ -256,6 +256,14 @@ namespace GUI {
|
||||
// the diamond is contained into a box with size [1, 1, 1]
|
||||
GLModel::Geometry diamond(unsigned short resolution);
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
// create a sphere with the given resolution and smooth normals
|
||||
// the origin of the sphere is in its center
|
||||
GLModel::Geometry smooth_sphere(unsigned short resolution, float radius);
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
|
@ -41,6 +41,10 @@ std::pair<bool, std::string> GLShadersManager::init()
|
||||
// used to render 3D scene background
|
||||
valid &= append_shader("background", { "background.vs", "background.fs" });
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
// used to render toolpaths center of gravity
|
||||
valid &= append_shader("toolpaths_cog", { "toolpaths_cog.vs", "toolpaths_cog.fs" });
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
|
||||
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
|
||||
// used to render printbed
|
||||
|
@ -126,6 +126,9 @@ public:
|
||||
ColorChanges,
|
||||
PausePrints,
|
||||
CustomGCodes,
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
CenterOfGravity,
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
Shells,
|
||||
ToolMarker,
|
||||
#if !ENABLE_PREVIEW_LAYOUT
|
||||
|
@ -64,6 +64,9 @@ static const std::map<const wchar_t, std::string> font_icons = {
|
||||
{ImGui::LegendColorChanges , "legend_colorchanges" },
|
||||
{ImGui::LegendPausePrints , "legend_pauseprints" },
|
||||
{ImGui::LegendCustomGCodes , "legend_customgcodes" },
|
||||
#if ENABLE_SHOW_TOOLPATHS_COG
|
||||
{ImGui::LegendCOG , "legend_cog" },
|
||||
#endif // ENABLE_SHOW_TOOLPATHS_COG
|
||||
{ImGui::LegendShells , "legend_shells" },
|
||||
{ImGui::LegendToolMarker , "legend_toolmarker" },
|
||||
#endif // ENABLE_LEGEND_TOOLBAR_ICONS
|
||||
|
@ -1276,6 +1276,14 @@ void Selection::render_center(bool gizmo_is_dragging)
|
||||
if (!m_valid || is_empty())
|
||||
return;
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
|
||||
const Vec3d center = gizmo_is_dragging ? m_cache.dragging_center : get_bounding_box().center();
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
@ -1284,19 +1292,17 @@ void Selection::render_center(bool gizmo_is_dragging)
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
shader->start_using();
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
m_vbo_sphere.set_color(ColorRGBA::WHITE());
|
||||
#else
|
||||
m_vbo_sphere.set_color(-1, ColorRGBA::WHITE());
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
m_vbo_sphere.render();
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
#if ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
shader->stop_using();
|
||||
#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
|
||||
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user