More SLA support points improvements
- unselected objects are hidden when SLA gizmo is active - support volumes are hidden when editing mode is active - 3mf support points format versioning
This commit is contained in:
parent
21026ec9a8
commit
f568f93f08
@ -776,10 +776,19 @@ namespace Slic3r {
|
||||
std::vector<std::string> objects;
|
||||
boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
|
||||
|
||||
// Info on format versioning - see 3mf.hpp
|
||||
int version = 0;
|
||||
if (!objects.empty() && objects[0].find("support_points_format_version=") != std::string::npos) {
|
||||
objects[0].erase(objects[0].begin(), objects[0].begin() + 30); // removes the string
|
||||
version = std::stoi(objects[0]);
|
||||
objects.erase(objects.begin()); // pop the header
|
||||
}
|
||||
|
||||
for (const std::string& object : objects)
|
||||
{
|
||||
std::vector<std::string> object_data;
|
||||
boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
|
||||
|
||||
if (object_data.size() != 2)
|
||||
{
|
||||
add_error("Error while reading object data");
|
||||
@ -813,12 +822,22 @@ namespace Slic3r {
|
||||
|
||||
std::vector<sla::SupportPoint> sla_support_points;
|
||||
|
||||
for (unsigned int i=0; i<object_data_points.size(); i+=5)
|
||||
if (version == 0) {
|
||||
for (unsigned int i=0; i<object_data_points.size(); i+=3)
|
||||
sla_support_points.emplace_back(std::atof(object_data_points[i+0].c_str()),
|
||||
std::atof(object_data_points[i+1].c_str()),
|
||||
std::atof(object_data_points[i+2].c_str()),
|
||||
0.4f,
|
||||
false);
|
||||
}
|
||||
if (version == 1) {
|
||||
for (unsigned int i=0; i<object_data_points.size(); i+=5)
|
||||
sla_support_points.emplace_back(std::atof(object_data_points[i+0].c_str()),
|
||||
std::atof(object_data_points[i+1].c_str()),
|
||||
std::atof(object_data_points[i+2].c_str()),
|
||||
std::atof(object_data_points[i+3].c_str()),
|
||||
std::atof(object_data_points[i+4].c_str()));
|
||||
}
|
||||
|
||||
if (!sla_support_points.empty())
|
||||
m_sla_support_points.insert(IdToSlaSupportPointsMap::value_type(object_id, sla_support_points));
|
||||
@ -1983,6 +2002,9 @@ namespace Slic3r {
|
||||
|
||||
if (!out.empty())
|
||||
{
|
||||
// Adds version header at the beginning:
|
||||
out = std::string("support_points_format_version=") + std::to_string(support_points_format_version) + std::string("\n") + out;
|
||||
|
||||
if (!mz_zip_writer_add_mem(&archive, SLA_SUPPORT_POINTS_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
|
||||
{
|
||||
add_error("Unable to add sla support points file to archive");
|
||||
|
@ -3,6 +3,23 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
/* The format for saving the SLA points was changing in the past. This enum holds the latest version that is being currently used.
|
||||
* Examples of the Slic3r_PE_sla_support_points.txt for historically used versions:
|
||||
|
||||
* version 0 : object_id=1|-12.055421 -2.658771 10.000000
|
||||
object_id=2|-14.051745 -3.570338 5.000000
|
||||
// no header and x,y,z positions of the points)
|
||||
|
||||
* version 1 : ThreeMF_support_points_version=1
|
||||
object_id=1|-12.055421 -2.658771 10.000000 0.4 0.0
|
||||
object_id=2|-14.051745 -3.570338 5.000000 0.6 1.0
|
||||
// introduced header with version number; x,y,z,head_size,is_new_island)
|
||||
*/
|
||||
|
||||
enum {
|
||||
support_points_format_version = 1
|
||||
};
|
||||
|
||||
class Model;
|
||||
class DynamicPrintConfig;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Geometry.hpp"
|
||||
#include <libslic3r/SLA/SLASupportTree.hpp>
|
||||
#include <libslic3r/SLA/SLACommon.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -52,20 +52,7 @@ SLAAutoSupports::SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3
|
||||
const Config& config, std::function<void(void)> throw_on_cancel)
|
||||
: m_config(config), m_V(emesh.V), m_F(emesh.F), m_throw_on_cancel(throw_on_cancel)
|
||||
{
|
||||
// Find all separate islands that will need support. The coord_t number denotes height
|
||||
// of a point just below the mesh (so that we can later project the point precisely
|
||||
// on the mesh by raycasting (done by igl) and not risking we will place the point inside).
|
||||
/*std::vector<std::pair<ExPolygon, coord_t>> islands = */
|
||||
process(slices, heights);
|
||||
|
||||
// Uniformly cover each of the islands with support points.
|
||||
/*for (const auto& island : islands) {
|
||||
std::vector<Vec3d> points = uniformly_cover(island);
|
||||
m_throw_on_cancel();
|
||||
project_upward_onto_mesh(points);
|
||||
m_output.insert(m_output.end(), points.begin(), points.end());
|
||||
m_throw_on_cancel();
|
||||
}*/
|
||||
project_onto_mesh(m_output);
|
||||
}
|
||||
|
||||
@ -104,10 +91,14 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std::
|
||||
const ExPolygons& expolys_top = slices[i];
|
||||
|
||||
const float height = (i>2 ? heights[i-3] : heights[0]-(heights[1]-heights[0]));
|
||||
const float layer_height = (i!=0 ? heights[i]-heights[i-1] : heights[0]);
|
||||
|
||||
const float safe_angle = 5.f * (M_PI/180.f); // smaller number - less supports
|
||||
const float offset = scale_((i!=0 ? heights[i]-heights[i-1] : heights[0]) / std::tan(safe_angle));
|
||||
const float pixel_area = 0.047f * 0.047f; // FIXME: calculate actual pixel area from printer config
|
||||
const float offset = scale_(layer_height / std::tan(safe_angle));
|
||||
|
||||
// FIXME: calculate actual pixel area from printer config:
|
||||
//const float pixel_area = pow(wxGetApp().preset_bundle->project_config.option<ConfigOptionFloat>("display_width") / wxGetApp().preset_bundle->project_config.option<ConfigOptionInt>("display_pixels_x"), 2.f); //
|
||||
const float pixel_area = pow(0.047f, 2.f);
|
||||
|
||||
// Check all ExPolygons on this slice and check whether they are new or belonging to something below.
|
||||
for (const ExPolygon& polygon : expolys_top) {
|
||||
@ -119,12 +110,11 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std::
|
||||
const ExPolygon* bottom = s.polygon;
|
||||
if (polygon.overlaps(*bottom) || bottom->overlaps(polygon)) {
|
||||
m_structures_new.back().structures_below.push_back(&s);
|
||||
|
||||
coord_t centroids_dist = (bottom->contour.centroid() - polygon.contour.centroid()).norm();
|
||||
if (centroids_dist != 0) {
|
||||
float mult = std::min(1.f, 1.f - std::min(1.f, 500.f * (float)(centroids_dist * centroids_dist) / (float)bottom->area()));
|
||||
s.supports_force *= mult;
|
||||
}
|
||||
//s.supports_force *= std::min(1.f, ((float)polygon.area()/(float)bottom->area()));
|
||||
float mult = std::min(1.f, 1.f - std::min(1.f, (1600.f * layer_height) * (float)(centroids_dist * centroids_dist) / (float)bottom->area()));
|
||||
s.supports_force *= mult;
|
||||
s.supports_force *= std::min(1.f, 20.f * ((float)bottom->area() / (float)polygon.area()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,7 +166,7 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std::
|
||||
}
|
||||
|
||||
e = diff_ex(ExPolygons{*s.polygon}, e);
|
||||
s.supports_force /= std::max(1., (e_area / (s.polygon->area()*SCALING_FACTOR*SCALING_FACTOR)));
|
||||
s.supports_force /= std::max(1., (layer_height / 0.3f) * (e_area / (s.polygon->area()*SCALING_FACTOR*SCALING_FACTOR)));
|
||||
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <libslic3r/Point.hpp>
|
||||
#include <libslic3r/TriangleMesh.hpp>
|
||||
#include <libslic3r/SLA/SLASupportTree.hpp>
|
||||
#include <libslic3r/SLA/SLACommon.hpp>
|
||||
|
||||
// #define SLA_AUTOSUPPORTS_DEBUG
|
||||
|
||||
|
48
src/libslic3r/SLA/SLACommon.hpp
Normal file
48
src/libslic3r/SLA/SLACommon.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef SLACOMMON_HPP
|
||||
#define SLACOMMON_HPP
|
||||
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Typedef from Point.hpp
|
||||
typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> Vec3f;
|
||||
|
||||
namespace sla {
|
||||
|
||||
struct SupportPoint {
|
||||
Vec3f pos;
|
||||
float head_front_radius;
|
||||
bool is_new_island;
|
||||
|
||||
SupportPoint() :
|
||||
pos(Vec3f::Zero()), head_front_radius(0.f), is_new_island(false) {}
|
||||
|
||||
SupportPoint(float pos_x, float pos_y, float pos_z, float head_radius, bool new_island) :
|
||||
pos(pos_x, pos_y, pos_z), head_front_radius(head_radius), is_new_island(new_island) {}
|
||||
|
||||
SupportPoint(Vec3f position, float head_radius, bool new_island) :
|
||||
pos(position), head_front_radius(head_radius), is_new_island(new_island) {}
|
||||
|
||||
SupportPoint(Eigen::Matrix<float, 5, 1, Eigen::DontAlign> data) :
|
||||
pos(data(0), data(1), data(2)), head_front_radius(data(3)), is_new_island(data(4)) {}
|
||||
|
||||
bool operator==(const SupportPoint& sp) const { return (pos==sp.pos) && head_front_radius==sp.head_front_radius && is_new_island==sp.is_new_island; }
|
||||
};
|
||||
|
||||
|
||||
/// An index-triangle structure for libIGL functions. Also serves as an
|
||||
/// alternative (raw) input format for the SLASupportTree
|
||||
struct EigenMesh3D {
|
||||
Eigen::MatrixXd V;
|
||||
Eigen::MatrixXi F;
|
||||
double ground_level = 0;
|
||||
};
|
||||
|
||||
|
||||
} // namespace sla
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
#endif // SLASUPPORTTREE_HPP
|
@ -7,6 +7,9 @@
|
||||
#include <memory>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include "SLACommon.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Needed types from Point.hpp
|
||||
@ -34,26 +37,6 @@ enum class PillarConnectionMode {
|
||||
dynamic
|
||||
};
|
||||
|
||||
struct SupportPoint {
|
||||
Vec3f pos;
|
||||
float head_front_radius;
|
||||
bool is_new_island;
|
||||
|
||||
SupportPoint() :
|
||||
pos(Vec3f::Zero()), head_front_radius(0.f), is_new_island(false) {}
|
||||
|
||||
SupportPoint(float pos_x, float pos_y, float pos_z, float head_radius, bool new_island) :
|
||||
pos(pos_x, pos_y, pos_z), head_front_radius(head_radius), is_new_island(new_island) {}
|
||||
|
||||
SupportPoint(Vec3f position, float head_radius, bool new_island) :
|
||||
pos(position), head_front_radius(head_radius), is_new_island(new_island) {}
|
||||
|
||||
SupportPoint(Eigen::Matrix<float, 5, 1, Eigen::DontAlign> data) :
|
||||
pos(data(0), data(1), data(2)), head_front_radius(data(3)), is_new_island(data(4)) {}
|
||||
|
||||
bool operator==(const SupportPoint& sp) const { return (pos==sp.pos) && head_front_radius==sp.head_front_radius && is_new_island==sp.is_new_island; }
|
||||
};
|
||||
|
||||
struct SupportConfig {
|
||||
// Radius in mm of the pointing side of the head.
|
||||
double head_front_radius_mm = 0.2;
|
||||
@ -122,14 +105,6 @@ struct Controller {
|
||||
std::function<void(void)> cancelfn = [](){};
|
||||
};
|
||||
|
||||
/// An index-triangle structure for libIGL functions. Also serves as an
|
||||
/// alternative (raw) input format for the SLASupportTree
|
||||
struct EigenMesh3D {
|
||||
Eigen::MatrixXd V;
|
||||
Eigen::MatrixXi F;
|
||||
double ground_level = 0;
|
||||
};
|
||||
|
||||
using PointSet = Eigen::MatrixXd;
|
||||
|
||||
EigenMesh3D to_eigenmesh(const TriangleMesh& m);
|
||||
|
@ -4031,6 +4031,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
||||
, m_moving(false)
|
||||
, m_color_by("volume")
|
||||
, m_reload_delayed(false)
|
||||
, m_render_sla_auxiliaries(true)
|
||||
#if !ENABLE_IMGUI
|
||||
, m_external_gizmo_widgets_parent(nullptr)
|
||||
#endif // not ENABLE_IMGUI
|
||||
@ -4186,6 +4187,27 @@ int GLCanvas3D::check_volumes_outside_state() const
|
||||
return (int)state;
|
||||
}
|
||||
|
||||
void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible)
|
||||
{
|
||||
for (GLVolume* vol : m_volumes.volumes) {
|
||||
if (vol->composite_id.volume_id < 0)
|
||||
vol->is_active = visible;
|
||||
}
|
||||
|
||||
m_render_sla_auxiliaries = visible;
|
||||
}
|
||||
|
||||
void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo)
|
||||
{
|
||||
for (GLVolume* vol : m_volumes.volumes) {
|
||||
if (mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
|
||||
vol->is_active = visible;
|
||||
}
|
||||
if (visible && !mo)
|
||||
toggle_sla_auxiliaries_visibility(true);
|
||||
}
|
||||
|
||||
|
||||
void GLCanvas3D::set_config(const DynamicPrintConfig* config)
|
||||
{
|
||||
m_config = config;
|
||||
@ -4732,7 +4754,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
if (it != model_volume_state.end() && it->geometry_id == key.geometry_id)
|
||||
mvs = &(*it);
|
||||
}
|
||||
if (mvs == nullptr || force_full_scene_refresh) {
|
||||
if (mvs == nullptr || force_full_scene_refresh || (volume->composite_id.volume_id < 0 && !m_render_sla_auxiliaries)) {
|
||||
// This GLVolume will be released.
|
||||
if (volume->is_wipe_tower) {
|
||||
// There is only one wipe tower.
|
||||
@ -4841,7 +4863,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
size_t volumes_count = m_volumes.volumes.size();
|
||||
|
||||
for (size_t istep = 0; istep < sla_steps.size(); ++istep)
|
||||
if (!instances[istep].empty())
|
||||
if (!instances[istep].empty() && m_render_sla_auxiliaries)
|
||||
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_use_VBOs && m_initialized);
|
||||
}
|
||||
|
||||
@ -6622,6 +6644,9 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||
unsigned int volume_id = 0;
|
||||
for (GLVolume* vol : m_volumes.volumes)
|
||||
{
|
||||
if (vol->composite_id.volume_id < 0 && !m_render_sla_auxiliaries)
|
||||
continue;
|
||||
|
||||
if (fake_colors)
|
||||
{
|
||||
// Object picking mode. Render the object with a color encoding the object index.
|
||||
|
@ -910,6 +910,7 @@ private:
|
||||
bool m_multisample_allowed;
|
||||
bool m_regenerate_volumes;
|
||||
bool m_moving;
|
||||
bool m_render_sla_auxiliaries;
|
||||
|
||||
std::string m_color_by;
|
||||
|
||||
@ -940,6 +941,9 @@ public:
|
||||
void reset_volumes();
|
||||
int check_volumes_outside_state() const;
|
||||
|
||||
void toggle_sla_auxiliaries_visibility(bool visible);
|
||||
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr);
|
||||
|
||||
void set_config(const DynamicPrintConfig* config);
|
||||
void set_process(BackgroundSlicingProcess* process);
|
||||
void set_model(Model* model);
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/SLA/SLASupportTree.hpp"
|
||||
#include "libslic3r/SLA/SLACommon.hpp"
|
||||
#include "libslic3r/SLAPrint.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
@ -1792,14 +1792,18 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const G
|
||||
for (const SLAPrintObject* po : m_parent.sla_print()->objects()) {
|
||||
if (po->model_object()->id() == model_object->id()) {
|
||||
const Eigen::MatrixXd& points = po->get_support_points();
|
||||
for (unsigned int i=0; i<points.rows();++i) {
|
||||
Vec3f pos(po->trafo().inverse().cast<float>() * Vec3f(points(i,0), points(i,1), points(i,2)));
|
||||
model_object->sla_support_points.emplace_back(pos(0), pos(1), pos(2), points(i, 3), points(i, 4));
|
||||
}
|
||||
for (unsigned int i=0; i<points.rows();++i)
|
||||
model_object->sla_support_points.emplace_back(po->trafo().inverse().cast<float>() * Vec3f(points(i,0), points(i,1), points(i,2)),
|
||||
points(i, 3), points(i, 4));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_editing_mode_cache = m_model_object->sla_support_points; // make a copy of ModelObject's support points
|
||||
if (m_state == On) {
|
||||
m_parent.toggle_model_objects_visibility(false);
|
||||
m_parent.toggle_model_objects_visibility(true, m_model_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1809,7 +1813,7 @@ void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
|
||||
for (unsigned int i=0; i<m_grabbers.size(); ++i) {
|
||||
bool supports_new_island = m_lock_unique_islands && m_model_object && m_model_object->sla_support_points[i].is_new_island;
|
||||
bool supports_new_island = m_lock_unique_islands && m_editing_mode_cache[i].is_new_island;
|
||||
Grabber& g = m_grabbers[i];
|
||||
if (m_editing_mode) {
|
||||
g.color[0] = supports_new_island ? 0.f : 1.f;
|
||||
@ -1888,7 +1892,7 @@ void GLGizmoSlaSupports::render_grabbers(const GLCanvas3D::Selection& selection,
|
||||
::glPushMatrix();
|
||||
::glLoadIdentity();
|
||||
::glTranslated(grabber_world_position(0), grabber_world_position(1), grabber_world_position(2) + z_shift);
|
||||
::gluSphere(m_quadric, m_model_object->sla_support_points[i].head_front_radius, 64, 36);
|
||||
::gluSphere(m_quadric, m_editing_mode_cache[i].head_front_radius, 64, 36);
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
@ -1938,7 +1942,7 @@ void GLGizmoSlaSupports::update_mesh()
|
||||
// we'll now reload Grabbers (selection might have changed):
|
||||
m_grabbers.clear();
|
||||
|
||||
for (const sla::SupportPoint& point : m_model_object->sla_support_points) {
|
||||
for (const sla::SupportPoint& point : m_editing_mode_cache) {
|
||||
m_grabbers.push_back(Grabber());
|
||||
m_grabbers.back().center = point.pos.cast<double>();
|
||||
}
|
||||
@ -2009,7 +2013,7 @@ void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
|
||||
m_grabbers.push_back(Grabber());
|
||||
m_grabbers.back().center = new_pos.cast<double>();
|
||||
|
||||
m_model_object->sla_support_points.emplace_back(new_pos, m_new_point_head_diameter, false);
|
||||
m_editing_mode_cache.emplace_back(new_pos, m_new_point_head_diameter, false);
|
||||
|
||||
// This should trigger the support generation
|
||||
// wxGetApp().plater()->reslice();
|
||||
@ -2024,16 +2028,16 @@ void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
|
||||
|
||||
if (delete_all) {
|
||||
m_grabbers.clear();
|
||||
m_model_object->sla_support_points.clear();
|
||||
m_editing_mode_cache.clear();
|
||||
|
||||
// This should trigger the support generation
|
||||
// wxGetApp().plater()->reslice();
|
||||
}
|
||||
else
|
||||
if (m_hover_id != -1) {
|
||||
if (!m_model_object->sla_support_points[m_hover_id].is_new_island || !m_lock_unique_islands) {
|
||||
if (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands) {
|
||||
m_grabbers.erase(m_grabbers.begin() + m_hover_id);
|
||||
m_model_object->sla_support_points.erase(m_model_object->sla_support_points.begin() + m_hover_id);
|
||||
m_editing_mode_cache.erase(m_editing_mode_cache.begin() + m_hover_id);
|
||||
m_hover_id = -1;
|
||||
|
||||
// This should trigger the support generation
|
||||
@ -2045,15 +2049,15 @@ void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
|
||||
|
||||
void GLGizmoSlaSupports::on_update(const UpdateData& data, const GLCanvas3D::Selection& selection)
|
||||
{
|
||||
if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_model_object->sla_support_points[m_hover_id].is_new_island || !m_lock_unique_islands)) {
|
||||
if (m_editing_mode && m_hover_id != -1 && data.mouse_pos && (!m_editing_mode_cache[m_hover_id].is_new_island || !m_lock_unique_islands)) {
|
||||
Vec3f new_pos;
|
||||
try {
|
||||
new_pos = unproject_on_mesh(Vec2d((*data.mouse_pos)(0), (*data.mouse_pos)(1)));
|
||||
}
|
||||
catch (...) { return; }
|
||||
m_grabbers[m_hover_id].center = new_pos.cast<double>();
|
||||
m_model_object->sla_support_points[m_hover_id].pos = new_pos;
|
||||
m_model_object->sla_support_points[m_hover_id].is_new_island = false;
|
||||
m_editing_mode_cache[m_hover_id].pos = new_pos;
|
||||
m_editing_mode_cache[m_hover_id].is_new_island = false;
|
||||
// Do not update immediately, wait until the mouse is released.
|
||||
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
}
|
||||
@ -2102,24 +2106,32 @@ RENDER_AGAIN:
|
||||
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove |/* ImGuiWindowFlags_NoResize | */ImGuiWindowFlags_NoCollapse);
|
||||
|
||||
ImGui::PushItemWidth(100.0f);
|
||||
|
||||
bool force_refresh = m_editing_mode;
|
||||
|
||||
/*bool force_refresh = m_editing_mode;
|
||||
if (m_imgui->radio_button(_(L("Automatic")), !m_editing_mode))
|
||||
m_editing_mode = false;
|
||||
ImGui::SameLine();
|
||||
if (m_imgui->radio_button(_(L("Manual")), m_editing_mode))
|
||||
m_editing_mode = true;
|
||||
force_refresh = force_refresh != m_editing_mode;
|
||||
m_imgui->text("");
|
||||
|
||||
|
||||
|
||||
if (force_refresh) { // mode has just changed!
|
||||
if (m_editing_mode)
|
||||
m_editing_mode_cache = m_model_object->sla_support_points;
|
||||
else
|
||||
m_model_object->sla_support_points = m_editing_mode_cache;
|
||||
}
|
||||
*/
|
||||
|
||||
bool force_refresh = false;
|
||||
bool remove_all_points = false;
|
||||
bool old_editing_state = m_editing_mode;
|
||||
|
||||
if (m_editing_mode) {
|
||||
m_imgui->text(_(L("Left mouse click - add point")));
|
||||
m_imgui->text(_(L("Right mouse click - remove point")));
|
||||
m_imgui->text(" ");
|
||||
|
||||
|
||||
m_imgui->text(" "); // vertical gap
|
||||
|
||||
std::vector<wxString> options = {"0.2", "0.4", "0.6", "0.8", "1.0"};
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(1) << m_new_point_head_diameter;
|
||||
@ -2130,30 +2142,77 @@ RENDER_AGAIN:
|
||||
|
||||
bool changed = m_lock_unique_islands;
|
||||
m_imgui->checkbox(_(L("Lock supports under new islands")), m_lock_unique_islands);
|
||||
force_refresh |= changed != m_lock_unique_islands;
|
||||
force_refresh |= changed != m_lock_unique_islands;
|
||||
|
||||
remove_all_points = m_imgui->button(_(L("Remove all points")) + (m_model_object == nullptr ? "" : " (" + std::to_string(m_editing_mode_cache.size())+")"));
|
||||
|
||||
m_imgui->text(" "); // vertical gap
|
||||
|
||||
bool apply_changes = m_imgui->button(_(L("Apply changes")));
|
||||
if (apply_changes) {
|
||||
m_model_object->sla_support_points = m_editing_mode_cache;
|
||||
m_editing_mode = false;
|
||||
force_refresh = true;
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
}
|
||||
ImGui::SameLine();
|
||||
bool discard_changes = m_imgui->button(_(L("Cancel")));
|
||||
if (discard_changes) {
|
||||
m_editing_mode_cache = m_model_object->sla_support_points;
|
||||
m_editing_mode = false;
|
||||
|
||||
m_grabbers.clear();
|
||||
for (const sla::SupportPoint& point : m_editing_mode_cache) {
|
||||
m_grabbers.push_back(Grabber());
|
||||
m_grabbers.back().center = point.pos.cast<double>();
|
||||
}
|
||||
|
||||
force_refresh = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//m_imgui->text("Some settings could");
|
||||
//m_imgui->text("be exposed here...");
|
||||
m_imgui->text("");
|
||||
m_imgui->text("");
|
||||
|
||||
m_imgui->text("");
|
||||
|
||||
bool generate =m_imgui->button(_(L("Auto-generate points")));
|
||||
force_refresh |= generate;
|
||||
if (generate)
|
||||
if (generate) {
|
||||
m_model_object->sla_support_points.clear();
|
||||
m_grabbers.clear();
|
||||
m_editing_mode_cache.clear();
|
||||
wxGetApp().plater()->reslice();
|
||||
}
|
||||
|
||||
bool remove_all_clicked = m_imgui->button(_(L("Remove all points")) + (m_model_object == nullptr ? "" : " (" + std::to_string(m_model_object->sla_support_points.size())+")"));
|
||||
|
||||
m_imgui->end();
|
||||
|
||||
if (remove_all_clicked) {
|
||||
delete_current_grabber(true);
|
||||
if (first_run) {
|
||||
first_run = false;
|
||||
goto RENDER_AGAIN;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
bool editing_clicked = m_imgui->button("Editing");
|
||||
if (editing_clicked) {
|
||||
m_editing_mode_cache = m_model_object->sla_support_points;
|
||||
m_editing_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (remove_all_clicked || force_refresh) {
|
||||
m_imgui->end();
|
||||
|
||||
if (m_editing_mode != old_editing_state) { // user just toggled between editing/non-editing mode
|
||||
m_parent.toggle_sla_auxiliaries_visibility(!m_editing_mode);
|
||||
force_refresh = true;
|
||||
}
|
||||
|
||||
|
||||
if (remove_all_points) {
|
||||
force_refresh = true;
|
||||
delete_current_grabber(true);
|
||||
/*if (first_run) {
|
||||
first_run = false;
|
||||
goto RENDER_AGAIN;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (force_refresh) {
|
||||
m_parent.reload_scene(true);
|
||||
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_IMGUI
|
||||
@ -2174,6 +2233,20 @@ std::string GLGizmoSlaSupports::on_get_name() const
|
||||
return L("SLA Support Points [L]");
|
||||
}
|
||||
|
||||
void GLGizmoSlaSupports::on_set_state()
|
||||
{
|
||||
if (m_state == On) {
|
||||
if (is_mesh_update_necessary())
|
||||
update_mesh();
|
||||
|
||||
m_parent.toggle_model_objects_visibility(false);
|
||||
if (m_model_object)
|
||||
m_parent.toggle_model_objects_visibility(true, m_model_object);
|
||||
}
|
||||
if (m_state == Off)
|
||||
m_parent.toggle_model_objects_visibility(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// GLGizmoCut
|
||||
|
@ -485,13 +485,10 @@ private:
|
||||
bool m_lock_unique_islands = false;
|
||||
bool m_editing_mode = false;
|
||||
float m_new_point_head_diameter = 0.4f;
|
||||
std::vector<sla::SupportPoint> m_editing_mode_cache;
|
||||
|
||||
protected:
|
||||
void on_set_state() override {
|
||||
if (m_state == On && is_mesh_update_necessary()) {
|
||||
update_mesh();
|
||||
}
|
||||
}
|
||||
void on_set_state() override;
|
||||
|
||||
#if ENABLE_IMGUI
|
||||
virtual void on_render_input_window(float x, float y, const GLCanvas3D::Selection& selection) override;
|
||||
|
Loading…
Reference in New Issue
Block a user