Browse Source

update ui

master
cflin 2 years ago
parent
commit
d926b56f01
  1. 89
      src/viewer/UIMenu.cpp
  2. 4
      src/viewer/UISimState.cpp
  3. 213
      src/viewer/imgui_ext.cpp

89
src/viewer/UIMenu.cpp

@ -40,10 +40,11 @@ namespace ipc::rigid {
// CCD_IM_ARRAYSIZE(level_strings))) { // CCD_IM_ARRAYSIZE(level_strings))) {
// set_logger_level(static_cast<spdlog::level::level_enum>(log_level)); // set_logger_level(static_cast<spdlog::level::level_enum>(log_level));
// } // }
set_logger_level(spdlog::level::level_enum::off); // set_logger_level(spdlog::level::level_enum::off);
draw_io(); draw_io();
draw_legends();
if (m_has_scene) { if (m_has_scene) {
if (ImGui::CollapsingHeader( if (ImGui::CollapsingHeader(
@ -68,15 +69,8 @@ namespace ipc::rigid {
ImGui::SetNextWindowSizeConstraints( ImGui::SetNextWindowSizeConstraints(
ImVec2(200.0f, 30.0f), ImVec2(legends_width, -1.0f)); ImVec2(200.0f, 30.0f), ImVec2(legends_width, -1.0f));
bool _colors_menu_visible = true; bool _colors_menu_visible = true;
// TODO: only add edge
// ImGui::Begin(
// "Legend", &_colors_menu_visible,
// ImGuiWindowFlags_NoSavedSettings
// | ImGuiWindowFlags_AlwaysAutoResize);
// {
// draw_legends();
// }
// ImGui::End();
} }
} // namespace ipc::rigid } // namespace ipc::rigid
@ -103,10 +97,7 @@ namespace ipc::rigid {
} }
ImGui::EndChild(); ImGui::EndChild();
if (ImGui::Button("Save simulation", ImVec2(-1, 0))) {
std::string fname = igl::file_dialog_save();
save(fname);
}
// if (ImGui::Button("Save OBJ sequence", ImVec2(-1, 0))) { // if (ImGui::Button("Save OBJ sequence", ImVec2(-1, 0))) {
// std::string dir_name = igl::file_dialog_save(); // std::string dir_name = igl::file_dialog_save();
@ -122,7 +113,7 @@ namespace ipc::rigid {
// } // }
// } // }
if (ImGui::Button("Start recording", ImVec2(-1, 0))) { if (ImGui::Button("记录gif", ImVec2(-1, 0))) {
std::string fname = igl::file_dialog_save(); std::string fname = igl::file_dialog_save();
start_recording(fname); start_recording(fname);
} }
@ -145,7 +136,7 @@ namespace ipc::rigid {
} }
m_player_state = static_cast<PlayerState>(player_state); m_player_state = static_cast<PlayerState>(player_state);
if (ImGui::Button("Step##SimPlayer", ImVec2(-1, 0))) { if (ImGui::Button("逐步仿真##SimPlayer", ImVec2(-1, 0))) {
m_player_state = PlayerState::Playing; m_player_state = PlayerState::Playing;
pre_draw_loop(); pre_draw_loop();
m_player_state = PlayerState::Paused; m_player_state = PlayerState::Paused;
@ -161,13 +152,56 @@ namespace ipc::rigid {
void UISimState::draw_settings() { void UISimState::draw_settings() {
auto config = m_state.get_active_config(); auto config = m_state.get_active_config();
ImGui::BeginChild( static auto get_display_json = [&](const nlohmann::json &cur_state) {
"##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 300), false,
ImGuiWindowFlags_HorizontalScrollbar); nlohmann::json display_json = {
{"总模型", {{"角动量", cur_state["angular_momentum"]},
{"线动量", cur_state["linear_momentum"]},
{"动能", cur_state["kinetic_energy"]},
{"势能", cur_state["potential_energy"]},}
}
};
auto v_rigid_bodies = cur_state["rigid_bodies"];
for (int i = 0; i < v_rigid_bodies.size(); ++i) {
char str_i[10];
sprintf(str_i, "刚体%3d", i + 1);
display_json["子模型"][str_i] = {
{"角速度", v_rigid_bodies[i]["angular_velocity"]},
{"线速度", v_rigid_bodies[i]["linear_velocity"]},
{"位置", v_rigid_bodies[i]["position"]},
{"旋转角", v_rigid_bodies[i]["rotation"]},
};
}
display_json["时间步"]= m_state.problem_ptr->timestep();
return display_json;
// Eigen::Vector3d angular_momentum(current_state[" angular_momentum"][0], current_state[" angular_momentum"][1], current_state[" angular_momentum"][2]);
// angular_momentum
// kinetic_energy
// linear_momentum
// potential_energy
// for () // rigid_bodies
// angular_velocity
// linear_velocity
// position
// rotation
};
ImGui::BeginChild("##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 300), false,
ImGuiWindowFlags_HorizontalScrollbar);
{ {
ImGui::TreeNodeJson(config); // ImGui::TreeNodeJson(config);
assert(!m_state.state_sequence.empty());
auto cur_state = m_state.state_sequence.back();
auto disp_state = get_display_json(cur_state);
ImGui::TreeNodeJson(disp_state);
}
if (ImGui::Button("导出仿真结果", ImVec2(-1, 0))) {
std::string fname = igl::file_dialog_save();
save(fname);
} }
ImGui::EndChild(); ImGui::EndChild();
} }
void UISimState::draw_legends() { void UISimState::draw_legends() {
@ -180,18 +214,19 @@ namespace ipc::rigid {
/// visibility checkbox /// visibility checkbox
bool tmp = ptr->visibility(); bool tmp = ptr->visibility();
if (!ptr->is_com()) { if (!ptr->is_com()) {
if (ImGui::Checkbox(("##UI-" + label).c_str(), &tmp)) { if (ImGui::Checkbox(("网格可视化##UI-" + label).c_str(), &tmp)) {
ptr->visibility(tmp); ptr->visibility(tmp);
} }
/// Color // /// Color
ImGui::SameLine(); // ImGui::SameLine();
if (ImGui::DoubleColorEdit3( // if (ImGui::DoubleColorEdit3(
(label + "##UI-color").c_str(), ptr->m_color)) { // (label + "##UI-color").c_str(), ptr->m_color)) {
ptr->recolor(); // ptr->recolor();
} // }
} else if (ImGui::Checkbox((label + "##UI-check").c_str(), &tmp)) { } else if (ImGui::Checkbox((label + "##UI-check").c_str(), &tmp)) {
ptr->visibility(tmp); ptr->visibility(tmp);
} }
break;
} }
} }

4
src/viewer/UISimState.cpp

@ -55,7 +55,7 @@ void UISimState::init(igl::opengl::glfw::Viewer* _viewer)
io.Fonts->Clear(); io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF( io.Fonts->AddFontFromFileTTF(
CMAKE_SOURCE_DIR "/src/viewer/Arial Unicode MS.TTF", CMAKE_SOURCE_DIR "/src/viewer/Arial Unicode MS.TTF",
14.0f, nullptr, io.Fonts->GetGlyphRangesChineseFull()); 14.0f*2, nullptr, io.Fonts->GetGlyphRangesChineseFull());
viewer->data().clear(); viewer->data().clear();
@ -272,7 +272,7 @@ void UISimState::start_recording(const std::string& filename)
height = static_cast<int>(m_gif_scale * height); height = static_cast<int>(m_gif_scale * height);
GifBegin(&m_gif_writer, filename.c_str(), width, height, m_gif_delay); GifBegin(&m_gif_writer, filename.c_str(), width, height, m_gif_delay);
m_scene_changed = true; m_scene_changed = true;
// post_draw_loop(); // post_draw_loop();
m_is_gif_recording = true; m_is_gif_recording = true;
} }

213
src/viewer/imgui_ext.cpp

@ -1,127 +1,138 @@
#include "imgui_ext.hpp" #include "imgui_ext.hpp"
#include "imgui.h" #include "imgui.h"
#include <X11/X.h> #include <X11/X.h>
#include <iostream>
#include <spdlog/spdlog.h>
namespace ImGui { namespace ImGui {
bool InputIntBounded( bool InputIntBounded(
const char* label, const char *label,
int* val, int *val,
int lower_bound, int lower_bound,
int upper_bound, int upper_bound,
int step, int step,
int step_fast, int step_fast,
ImGuiInputTextFlags flags) ImGuiInputTextFlags flags) {
{ int unbounded_val = *val;
int unbounded_val = *val; if (ImGui::InputInt(label, &unbounded_val, step, step_fast, flags)) {
if (ImGui::InputInt(label, &unbounded_val, step, step_fast, flags)) { if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) { *val = unbounded_val;
*val = unbounded_val; return true;
return true; }
} }
return false;
} }
return false;
}
bool InputDoubleBounded( bool InputDoubleBounded(
const char* label, const char *label,
double* val, double *val,
double lower_bound, double lower_bound,
double upper_bound, double upper_bound,
double step, double step,
double step_fast, double step_fast,
const char* format, const char *format,
ImGuiInputTextFlags flags) ImGuiInputTextFlags flags) {
{ double unbounded_val = *val;
double unbounded_val = *val; if (ImGui::InputDouble(
if (ImGui::InputDouble( label, &unbounded_val, step, step_fast, format, flags)) {
label, &unbounded_val, step, step_fast, format, flags)) { if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) { *val = unbounded_val;
*val = unbounded_val; return true;
return true; }
} }
return false;
} }
return false;
}
bool DragDouble( bool DragDouble(
const char* label, const char *label,
double* v, double *v,
double v_speed, double v_speed,
double v_min, double v_min,
double v_max, double v_max,
const char* format, const char *format,
float power) float power) {
{
return DragScalar( return DragScalar(
label, ImGuiDataType_Double, v, float(v_speed), &v_min, &v_max, format, label, ImGuiDataType_Double, v, float(v_speed), &v_min, &v_max, format,
power); power);
} }
bool DoubleColorEdit3(const char* label, Eigen::RowVector3d& color) bool DoubleColorEdit3(const char *label, Eigen::RowVector3d &color) {
{ Eigen::Vector3f color_f = color.cast<float>();
Eigen::Vector3f color_f = color.cast<float>(); bool changed = false;
bool changed = false; if (ImGui::ColorEdit3(
if (ImGui::ColorEdit3( label, color_f.data(),
label, color_f.data(), ImGuiColorEditFlags_NoInputs
ImGuiColorEditFlags_NoInputs
| ImGuiColorEditFlags_PickerHueWheel)) { | ImGuiColorEditFlags_PickerHueWheel)) {
color = color_f.cast<double>(); color = color_f.cast<double>();
changed = true; changed = true;
}
return changed;
} }
return changed;
}
void HelpMarker(const char* desc) void HelpMarker(const char *desc) {
{ ImGui::TextDisabled("(?)");
ImGui::TextDisabled("(?)"); if (ImGui::IsItemHovered()) {
if (ImGui::IsItemHovered()) { ImGui::BeginTooltip();
ImGui::BeginTooltip(); ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); ImGui::TextUnformatted(desc);
ImGui::TextUnformatted(desc); ImGui::PopTextWrapPos();
ImGui::PopTextWrapPos(); ImGui::EndTooltip();
ImGui::EndTooltip(); }
} }
}
void TreeNodeJson(const nlohmann::json json) void TreeNodeJson(const nlohmann::json json) {
{ static const ImVec4 label_color =
static const ImVec4 label_color = // ImVec4(241.f / 255.f, 196.f / 255.f, 15.f / 255.f, 1.0f);
ImVec4(241.f / 255.f, 196.f / 255.f, 15.f / 255.f, 1.0f); ImVec4(0.9, 0.9, 0.9, 1.0f);
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing() * 0.1f); ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing() * 0.1f);
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 1); ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 1);
for (auto& j : json.items()) { for (auto &j: json.items()) {
if (j.value().is_object()) { if (j.value().is_object()) {
ImGui::PushStyleColor(ImGuiCol_Text, label_color); ImGui::PushStyleColor(ImGuiCol_Text, label_color);
if (ImGui::TreeNode(j.key().c_str())) { if (ImGui::TreeNode(j.key().c_str())) {
ImGui::PopStyleColor(); ImGui::PopStyleColor();
TreeNodeJson(j.value()); TreeNodeJson(j.value());
ImGui::TreePop(); ImGui::TreePop();
} else { } else {
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
} else {
ImGui::Bullet();
ImGui::TextColored(label_color, "%s: ", j.key().c_str());
ImGui::SameLine();
if (j.value().is_number_float()) {
ImGui::Text("%g", j.value().get<double>());
} else { } else {
ImGui::Text("%s", j.value().dump().c_str()); ImGui::Bullet();
ImGui::TextColored(label_color, "%s: ", j.key().c_str());
ImGui::SameLine();
if (j.value().is_number_float()) {
ImGui::Text("%g", j.value().get<double>());
} else if (j.value().is_array()) {
std::string the_arr;
char buffer[20];
for (int i = 0; i < j.value().size(); ++i) {
double the_val = j.value()[i].get<double>();
if (the_val == 0) {
buffer[0] = '0';
buffer[1] = '\0';
} else {
sprintf(buffer, "%.2e", the_val);
}
the_arr += (i > 0 ? std::string(" ,") : std::string("")) + std::string(buffer);
}
ImGui::Text("%s", the_arr.c_str());
} else {
spdlog::error("wrong json data!");
}
} }
} }
ImGui::PopStyleVar();
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing() * 0.1f);
} }
ImGui::PopStyleVar();
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing() * 0.1f);
}
void reload_font(int font_size) void reload_font(int font_size) {
{ ImGuiIO &io = ImGui::GetIO();
ImGuiIO& io = ImGui::GetIO(); io.Fonts->Clear();
io.Fonts->Clear(); io.Fonts->AddFontFromFileTTF("/home/oo/project/vscode/rigid_ipc/rigid-ipc/src/viewer/DroidSans.ttf", 14.0f,
io.Fonts->AddFontFromFileTTF("/home/oo/project/vscode/rigid_ipc/rigid-ipc/src/viewer/DroidSans.ttf", 14.0f, nullptr, nullptr,
io.Fonts->GetGlyphRangesChineseFull()); io.Fonts->GetGlyphRangesChineseFull());
} }
} // namespace ImGui } // namespace ImGui

Loading…
Cancel
Save