SLA support points improvements

- semi-intelligent algorithm to place support points
- enhanced ImGui dialog with editing/non-editing mode
- support points can have different head diameter (only implemented in GUI so far)
- autogenerated points supporting emerging islands are annotated and the info is kept
This commit is contained in:
Lukas Matena 2019-01-30 08:26:23 +01:00
parent f4243c694f
commit 21026ec9a8
16 changed files with 433 additions and 495 deletions

View file

@ -3381,22 +3381,14 @@ void GLCanvas3D::Gizmos::set_flattening_data(const ModelObject* model_object)
reinterpret_cast<GLGizmoFlatten*>(it->second)->set_flattening_data(model_object);
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection)
#else
void GLCanvas3D::Gizmos::set_model_object_ptr(ModelObject* model_object)
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
{
if (!m_enabled)
return;
GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
if (it != m_gizmos.end())
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
reinterpret_cast<GLGizmoSlaSupports*>(it->second)->set_sla_support_data(model_object, selection);
#else
reinterpret_cast<GLGizmoSlaSupports*>(it->second)->set_model_object_ptr(model_object);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
void GLCanvas3D::Gizmos::clicked_on_object(const Vec2d& mouse_position)
@ -7137,11 +7129,7 @@ void GLCanvas3D::_update_gizmos_data()
m_gizmos.set_rotation(Vec3d::Zero());
ModelObject* model_object = m_model->objects[m_selection.get_object_idx()];
m_gizmos.set_flattening_data(model_object);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
m_gizmos.set_sla_support_data(model_object, m_selection);
#else
m_gizmos.set_model_object_ptr(model_object);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
else if (m_selection.is_single_volume() || m_selection.is_single_modifier())
{
@ -7149,22 +7137,14 @@ void GLCanvas3D::_update_gizmos_data()
m_gizmos.set_scale(volume->get_volume_scaling_factor());
m_gizmos.set_rotation(Vec3d::Zero());
m_gizmos.set_flattening_data(nullptr);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
m_gizmos.set_sla_support_data(nullptr, m_selection);
#else
m_gizmos.set_model_object_ptr(nullptr);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
else
{
m_gizmos.set_scale(Vec3d::Ones());
m_gizmos.set_rotation(Vec3d::Zero());
m_gizmos.set_flattening_data(m_selection.is_from_single_object() ? m_model->objects[m_selection.get_object_idx()] : nullptr);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
m_gizmos.set_sla_support_data(nullptr, m_selection);
#else
m_gizmos.set_model_object_ptr(nullptr);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
}

View file

@ -779,11 +779,7 @@ private:
void set_flattening_data(const ModelObject* model_object);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection);
#else
void set_model_object_ptr(ModelObject* model_object);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
void clicked_on_object(const Vec2d& mouse_position);
void delete_current_grabber(bool delete_all = false);

View file

@ -1741,28 +1741,20 @@ Vec3d GLGizmoFlatten::get_flattening_normal() const
}
GLGizmoSlaSupports::GLGizmoSlaSupports(GLCanvas3D& parent)
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
: GLGizmoBase(parent), m_starting_center(Vec3d::Zero()), m_quadric(nullptr)
#else
: GLGizmoBase(parent), m_starting_center(Vec3d::Zero())
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
{
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
m_quadric = ::gluNewQuadric();
if (m_quadric != nullptr)
// using GLU_FILL does not work when the instance's transformation
// contains mirroring (normals are reverted)
::gluQuadricDrawStyle(m_quadric, GLU_FILL);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
GLGizmoSlaSupports::~GLGizmoSlaSupports()
{
if (m_quadric != nullptr)
::gluDeleteQuadric(m_quadric);
}
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
bool GLGizmoSlaSupports::on_init()
{
@ -1782,7 +1774,6 @@ bool GLGizmoSlaSupports::on_init()
return true;
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection)
{
m_starting_center = Vec3d::Zero();
@ -1801,59 +1792,37 @@ 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)
model_object->sla_support_points.push_back(Vec3f(po->trafo().inverse().cast<float>() * Vec3f(points(i,0), points(i,1), points(i,2))));
break;
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));
}
break;
}
}
}
}
}
#else
void GLGizmoSlaSupports::set_model_object_ptr(ModelObject* model_object)
{
if (model_object != nullptr) {
m_starting_center = Vec3d::Zero();
m_model_object = model_object;
int selected_instance = m_parent.get_selection().get_instance_idx();
assert(selected_instance < (int)model_object->instances.size());
m_instance_matrix = model_object->instances[selected_instance]->get_matrix();
if (is_mesh_update_necessary())
update_mesh();
}
}
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
void GLGizmoSlaSupports::on_render(const GLCanvas3D::Selection& selection) const
{
::glEnable(GL_BLEND);
::glEnable(GL_DEPTH_TEST);
#if !ENABLE_SLA_SUPPORT_GIZMO_MOD
// the dragged_offset is a vector measuring where was the object moved
// with the gizmo being on. This is reset in set_model_object_ptr and
// does not work correctly when there are multiple copies.
if (m_starting_center == Vec3d::Zero())
m_starting_center = selection.get_bounding_box().center();
Vec3d dragged_offset = selection.get_bounding_box().center() - m_starting_center;
#endif // !ENABLE_SLA_SUPPORT_GIZMO_MOD
for (auto& g : m_grabbers) {
g.color[0] = 1.f;
g.color[1] = 0.f;
g.color[2] = 0.f;
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;
Grabber& g = m_grabbers[i];
if (m_editing_mode) {
g.color[0] = supports_new_island ? 0.f : 1.f;
g.color[1] = 0.f;
g.color[2] = supports_new_island ? 1.f : 0.f;
}
else {
for (unsigned char i=0; i<3; ++i) g.color[i] = 0.5f;
}
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
render_grabbers(selection, false);
#else
//::glTranslatef((GLfloat)dragged_offset(0), (GLfloat)dragged_offset(1), (GLfloat)dragged_offset(2));
render_grabbers(false);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
#if !ENABLE_IMGUI
render_tooltip_texture();
@ -1870,14 +1839,9 @@ void GLGizmoSlaSupports::on_render_for_picking(const GLCanvas3D::Selection& sele
m_grabbers[i].color[1] = 1.0f;
m_grabbers[i].color[2] = picking_color_component(i);
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
render_grabbers(selection, true);
#else
render_grabbers(true);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
}
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
void GLGizmoSlaSupports::render_grabbers(const GLCanvas3D::Selection& selection, bool picking) const
{
if (m_quadric == nullptr)
@ -1924,8 +1888,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);
const float diameter = 0.8f;
::gluSphere(m_quadric, diameter/2.f, 64, 36);
::gluSphere(m_quadric, m_model_object->sla_support_points[i].head_front_radius, 64, 36);
::glPopMatrix();
}
@ -1934,65 +1897,10 @@ void GLGizmoSlaSupports::render_grabbers(const GLCanvas3D::Selection& selection,
::glPopMatrix();
}
#else
void GLGizmoSlaSupports::render_grabbers(bool picking) const
{
if (m_parent.get_selection().is_empty())
return;
float z_shift = m_parent.get_selection().get_volume(0)->get_sla_shift_z();
::glTranslatef((GLfloat)0, (GLfloat)0, (GLfloat)z_shift);
int selected_instance = m_parent.get_selection().get_instance_idx();
assert(selected_instance < (int)m_model_object->instances.size());
float render_color_inactive[3] = { 0.5f, 0.5f, 0.5f };
for (const ModelInstance* inst : m_model_object->instances) {
bool active = inst == m_model_object->instances[selected_instance];
if (picking && ! active)
continue;
for (int i = 0; i < (int)m_grabbers.size(); ++i)
{
if (!m_grabbers[i].enabled)
continue;
float render_color[3];
if (! picking && active && m_hover_id == i) {
render_color[0] = 1.0f - m_grabbers[i].color[0];
render_color[1] = 1.0f - m_grabbers[i].color[1];
render_color[2] = 1.0f - m_grabbers[i].color[2];
}
else
::memcpy((void*)render_color, active ? (const void*)m_grabbers[i].color : (const void*)render_color_inactive, 3 * sizeof(float));
if (!picking)
::glEnable(GL_LIGHTING);
::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]);
::glPushMatrix();
Vec3d center = inst->get_matrix() * m_grabbers[i].center;
::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2));
GLUquadricObj *quadric;
quadric = ::gluNewQuadric();
::gluQuadricDrawStyle(quadric, GLU_FILL );
::gluSphere( quadric , 0.4, 64 , 32 );
::gluDeleteQuadric(quadric);
::glPopMatrix();
if (!picking)
::glDisable(GL_LIGHTING);
}
}
::glTranslatef((GLfloat)0, (GLfloat)0, (GLfloat)-z_shift);
}
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
bool GLGizmoSlaSupports::is_mesh_update_necessary() const
{
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
return (m_state == On) && (m_model_object != nullptr) && (m_model_object != m_old_model_object) && !m_model_object->instances.empty();
#else
return m_state == On && m_model_object && !m_model_object->instances.empty() && !m_instance_matrix.isApprox(m_source_data.matrix);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
//if (m_state != On || !m_model_object || m_model_object->instances.empty() || ! m_instance_matrix.isApprox(m_source_data.matrix))
// return false;
@ -2027,27 +1935,19 @@ void GLGizmoSlaSupports::update_mesh()
m_AABB = igl::AABB<Eigen::MatrixXf,3>();
m_AABB.init(m_V, m_F);
#if !ENABLE_SLA_SUPPORT_GIZMO_MOD
m_source_data.matrix = m_instance_matrix;
#endif // !ENABLE_SLA_SUPPORT_GIZMO_MOD
// we'll now reload Grabbers (selection might have changed):
m_grabbers.clear();
for (const Vec3f& point : m_model_object->sla_support_points) {
for (const sla::SupportPoint& point : m_model_object->sla_support_points) {
m_grabbers.push_back(Grabber());
m_grabbers.back().center = point.cast<double>();
m_grabbers.back().center = point.pos.cast<double>();
}
}
Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
{
// if the gizmo doesn't have the V, F structures for igl, calculate them first:
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
if (m_V.size() == 0)
#else
if (m_V.size() == 0 || is_mesh_update_necessary())
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
update_mesh();
Eigen::Matrix<GLint, 4, 1, Eigen::DontAlign> viewport;
@ -2064,20 +1964,15 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
igl::Hit hit;
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
const GLCanvas3D::Selection& selection = m_parent.get_selection();
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
double z_offset = volume->get_sla_shift_z();
#else
double z_offset = m_parent.get_selection().get_volume(0)->get_sla_shift_z();
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
point1(2) -= z_offset;
point2(2) -= z_offset;
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
Transform3d inv = volume->get_instance_transformation().get_matrix().inverse();
#else
Transform3d inv = m_instance_matrix.inverse();
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
point1 = inv * point1;
point2 = inv * point2;
@ -2091,7 +1986,9 @@ Vec3f GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos)
void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
{
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
if (!m_editing_mode)
return;
int instance_id = m_parent.get_selection().get_instance_idx();
if (m_old_instance_id != instance_id)
{
@ -2102,7 +1999,6 @@ void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
}
if (instance_id == -1)
return;
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
Vec3f new_pos;
try {
@ -2112,7 +2008,8 @@ 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.push_back(new_pos);
m_model_object->sla_support_points.emplace_back(new_pos, m_new_point_head_diameter, false);
// This should trigger the support generation
// wxGetApp().plater()->reslice();
@ -2122,6 +2019,9 @@ void GLGizmoSlaSupports::clicked_on_object(const Vec2d& mouse_position)
void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
{
if (!m_editing_mode && !delete_all)
return;
if (delete_all) {
m_grabbers.clear();
m_model_object->sla_support_points.clear();
@ -2131,26 +2031,29 @@ void GLGizmoSlaSupports::delete_current_grabber(bool delete_all)
}
else
if (m_hover_id != -1) {
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_hover_id = -1;
if (!m_model_object->sla_support_points[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_hover_id = -1;
// This should trigger the support generation
// wxGetApp().plater()->reslice();
// This should trigger the support generation
// wxGetApp().plater()->reslice();
}
}
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
void GLGizmoSlaSupports::on_update(const UpdateData& data, const GLCanvas3D::Selection& selection)
{
if (m_hover_id != -1 && data.mouse_pos) {
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)) {
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] = new_pos;
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;
// Do not update immediately, wait until the mouse is released.
// m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}
@ -2196,14 +2099,46 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, const GLCanvas
RENDER_AGAIN:
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
m_imgui->set_next_window_bg_alpha(0.5f);
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove |/* ImGuiWindowFlags_NoResize | */ImGuiWindowFlags_NoCollapse);
ImGui::PushItemWidth(100.0f);
m_imgui->text(_(L("Left mouse click - add point")));
m_imgui->text(_(L("Right mouse click - remove point")));
m_imgui->text(" ");
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("");
bool generate = m_imgui->button(_(L("Generate points automatically")));
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(" ");
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;
wxString str = ss.str();
m_imgui->combo(_(L("Head diameter")), options, str);
force_refresh |= std::abs(atof(str) - m_new_point_head_diameter) > 0.001;
m_new_point_head_diameter = atof(str);
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;
}
else {
bool generate =m_imgui->button(_(L("Auto-generate points")));
force_refresh |= generate;
if (generate)
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();
@ -2216,7 +2151,7 @@ RENDER_AGAIN:
}
}
if (remove_all_clicked || generate) {
if (remove_all_clicked || force_refresh) {
m_parent.reload_scene(true);
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
}

View file

@ -441,27 +441,16 @@ class GLGizmoSlaSupports : public GLGizmoBase
{
private:
ModelObject* m_model_object = nullptr;
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
ModelObject* m_old_model_object = nullptr;
int m_old_instance_id = -1;
#else
Transform3d m_instance_matrix;
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
Vec3f unproject_on_mesh(const Vec2d& mouse_pos);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
GLUquadricObj* m_quadric;
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
Eigen::MatrixXf m_V; // vertices
Eigen::MatrixXi m_F; // facets indices
igl::AABB<Eigen::MatrixXf,3> m_AABB;
struct SourceDataSummary {
#if !ENABLE_SLA_SUPPORT_GIZMO_MOD
BoundingBoxf3 bounding_box;
Transform3d matrix;
#endif // !ENABLE_SLA_SUPPORT_GIZMO_MOD
Vec3d mesh_first_point;
};
@ -472,12 +461,8 @@ private:
public:
explicit GLGizmoSlaSupports(GLCanvas3D& parent);
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
virtual ~GLGizmoSlaSupports();
void set_sla_support_data(ModelObject* model_object, const GLCanvas3D::Selection& selection);
#else
void set_model_object_ptr(ModelObject* model_object);
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
void clicked_on_object(const Vec2d& mouse_position);
void delete_current_grabber(bool delete_all);
@ -487,11 +472,7 @@ private:
virtual void on_render(const GLCanvas3D::Selection& selection) const;
virtual void on_render_for_picking(const GLCanvas3D::Selection& selection) const;
#if ENABLE_SLA_SUPPORT_GIZMO_MOD
void render_grabbers(const GLCanvas3D::Selection& selection, bool picking = false) const;
#else
void render_grabbers(bool picking = false) const;
#endif // ENABLE_SLA_SUPPORT_GIZMO_MOD
bool is_mesh_update_necessary() const;
void update_mesh();
@ -501,6 +482,10 @@ private:
mutable GLTexture m_reset_texture;
#endif // not ENABLE_IMGUI
bool m_lock_unique_islands = false;
bool m_editing_mode = false;
float m_new_point_head_diameter = 0.4f;
protected:
void on_set_state() override {
if (m_state == On && is_mesh_update_necessary()) {

View file

@ -125,6 +125,12 @@ bool ImGuiWrapper::button(const wxString &label)
return ImGui::Button(label_utf8.c_str());
}
bool ImGuiWrapper::radio_button(const wxString &label, bool active)
{
auto label_utf8 = into_u8(label);
return ImGui::RadioButton(label_utf8.c_str(), active);
}
bool ImGuiWrapper::input_double(const std::string &label, const double &value, const std::string &format)
{
return ImGui::InputDouble(label.c_str(), const_cast<double*>(&value), 0.0f, 0.0f, format.c_str());
@ -161,6 +167,26 @@ void ImGuiWrapper::text(const wxString &label)
ImGui::Text(label_utf8.c_str(), NULL);
}
void ImGuiWrapper::combo(const wxString& label, const std::vector<wxString>& options, wxString& selection)
{
const char* selection_u8 = into_u8(selection).c_str();
// this is to force the label to the left of the widget:
text(label);
ImGui::SameLine();
if (ImGui::BeginCombo("", selection_u8)) {
for (const wxString& option : options) {
const char* option_u8 = into_u8(option).c_str();
bool is_selected = (selection_u8 == nullptr) ? false : strcmp(option_u8, selection_u8) == 0;
if (ImGui::Selectable(option_u8, is_selected))
selection = option_u8;
}
ImGui::EndCombo();
}
}
void ImGuiWrapper::disabled_begin(bool disabled)
{
wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call");

View file

@ -47,10 +47,12 @@ public:
void end();
bool button(const wxString &label);
bool radio_button(const wxString &label, bool active);
bool input_double(const std::string &label, const double &value, const std::string &format = "%.3f");
bool input_vec3(const std::string &label, const Vec3d &value, float width, const std::string &format = "%.3f");
bool checkbox(const wxString &label, bool &value);
void text(const wxString &label);
void combo(const wxString& label, const std::vector<wxString>& options, wxString& current_selection);
void disabled_begin(bool disabled);
void disabled_end();