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))) {
// 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_legends();
if (m_has_scene) {
if (ImGui::CollapsingHeader(
@ -68,15 +69,8 @@ namespace ipc::rigid {
ImGui::SetNextWindowSizeConstraints(
ImVec2(200.0f, 30.0f), ImVec2(legends_width, -1.0f));
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
@ -103,10 +97,7 @@ namespace ipc::rigid {
}
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))) {
// 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();
start_recording(fname);
}
@ -145,7 +136,7 @@ namespace ipc::rigid {
}
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;
pre_draw_loop();
m_player_state = PlayerState::Paused;
@ -161,13 +152,56 @@ namespace ipc::rigid {
void UISimState::draw_settings() {
auto config = m_state.get_active_config();
ImGui::BeginChild(
"##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 300), false,
ImGuiWindowFlags_HorizontalScrollbar);
static auto get_display_json = [&](const nlohmann::json &cur_state) {
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();
}
void UISimState::draw_legends() {
@ -180,18 +214,19 @@ namespace ipc::rigid {
/// visibility checkbox
bool tmp = ptr->visibility();
if (!ptr->is_com()) {
if (ImGui::Checkbox(("##UI-" + label).c_str(), &tmp)) {
if (ImGui::Checkbox(("网格可视化##UI-" + label).c_str(), &tmp)) {
ptr->visibility(tmp);
}
/// Color
ImGui::SameLine();
if (ImGui::DoubleColorEdit3(
(label + "##UI-color").c_str(), ptr->m_color)) {
ptr->recolor();
}
// /// Color
// ImGui::SameLine();
// if (ImGui::DoubleColorEdit3(
// (label + "##UI-color").c_str(), ptr->m_color)) {
// ptr->recolor();
// }
} else if (ImGui::Checkbox((label + "##UI-check").c_str(), &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->AddFontFromFileTTF(
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();
@ -272,7 +272,7 @@ void UISimState::start_recording(const std::string& filename)
height = static_cast<int>(m_gif_scale * height);
GifBegin(&m_gif_writer, filename.c_str(), width, height, m_gif_delay);
m_scene_changed = true;
// post_draw_loop();
// post_draw_loop();
m_is_gif_recording = true;
}

213
src/viewer/imgui_ext.cpp

@ -1,127 +1,138 @@
#include "imgui_ext.hpp"
#include "imgui.h"
#include <X11/X.h>
#include <iostream>
#include <spdlog/spdlog.h>
namespace ImGui {
bool InputIntBounded(
const char* label,
int* val,
int lower_bound,
int upper_bound,
int step,
int step_fast,
ImGuiInputTextFlags flags)
{
int unbounded_val = *val;
if (ImGui::InputInt(label, &unbounded_val, step, step_fast, flags)) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
*val = unbounded_val;
return true;
bool InputIntBounded(
const char *label,
int *val,
int lower_bound,
int upper_bound,
int step,
int step_fast,
ImGuiInputTextFlags flags) {
int unbounded_val = *val;
if (ImGui::InputInt(label, &unbounded_val, step, step_fast, flags)) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
*val = unbounded_val;
return true;
}
}
return false;
}
return false;
}
bool InputDoubleBounded(
const char* label,
double* val,
double lower_bound,
double upper_bound,
double step,
double step_fast,
const char* format,
ImGuiInputTextFlags flags)
{
double unbounded_val = *val;
if (ImGui::InputDouble(
label, &unbounded_val, step, step_fast, format, flags)) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
*val = unbounded_val;
return true;
bool InputDoubleBounded(
const char *label,
double *val,
double lower_bound,
double upper_bound,
double step,
double step_fast,
const char *format,
ImGuiInputTextFlags flags) {
double unbounded_val = *val;
if (ImGui::InputDouble(
label, &unbounded_val, step, step_fast, format, flags)) {
if (unbounded_val >= lower_bound && unbounded_val <= upper_bound) {
*val = unbounded_val;
return true;
}
}
return false;
}
return false;
}
bool DragDouble(
const char* label,
double* v,
double v_speed,
double v_min,
double v_max,
const char* format,
float power)
{
bool DragDouble(
const char *label,
double *v,
double v_speed,
double v_min,
double v_max,
const char *format,
float power) {
return DragScalar(
label, ImGuiDataType_Double, v, float(v_speed), &v_min, &v_max, format,
power);
}
return DragScalar(
label, ImGuiDataType_Double, v, float(v_speed), &v_min, &v_max, format,
power);
}
bool DoubleColorEdit3(const char* label, Eigen::RowVector3d& color)
{
Eigen::Vector3f color_f = color.cast<float>();
bool changed = false;
if (ImGui::ColorEdit3(
label, color_f.data(),
ImGuiColorEditFlags_NoInputs
bool DoubleColorEdit3(const char *label, Eigen::RowVector3d &color) {
Eigen::Vector3f color_f = color.cast<float>();
bool changed = false;
if (ImGui::ColorEdit3(
label, color_f.data(),
ImGuiColorEditFlags_NoInputs
| ImGuiColorEditFlags_PickerHueWheel)) {
color = color_f.cast<double>();
changed = true;
color = color_f.cast<double>();
changed = true;
}
return changed;
}
return changed;
}
void HelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
void HelpMarker(const char *desc) {
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
}
void TreeNodeJson(const nlohmann::json json)
{
static const ImVec4 label_color =
ImVec4(241.f / 255.f, 196.f / 255.f, 15.f / 255.f, 1.0f);
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing() * 0.1f);
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 1);
for (auto& j : json.items()) {
if (j.value().is_object()) {
ImGui::PushStyleColor(ImGuiCol_Text, label_color);
if (ImGui::TreeNode(j.key().c_str())) {
ImGui::PopStyleColor();
TreeNodeJson(j.value());
ImGui::TreePop();
} else {
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>());
void TreeNodeJson(const nlohmann::json json) {
static const ImVec4 label_color =
// 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::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 1);
for (auto &j: json.items()) {
if (j.value().is_object()) {
ImGui::PushStyleColor(ImGuiCol_Text, label_color);
if (ImGui::TreeNode(j.key().c_str())) {
ImGui::PopStyleColor();
TreeNodeJson(j.value());
ImGui::TreePop();
} else {
ImGui::PopStyleColor();
}
} 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)
{
ImGuiIO& io = ImGui::GetIO();
io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF("/home/oo/project/vscode/rigid_ipc/rigid-ipc/src/viewer/DroidSans.ttf", 14.0f, nullptr,
io.Fonts->GetGlyphRangesChineseFull());
}
void reload_font(int font_size) {
ImGuiIO &io = ImGui::GetIO();
io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF("/home/oo/project/vscode/rigid_ipc/rigid-ipc/src/viewer/DroidSans.ttf", 14.0f,
nullptr,
io.Fonts->GetGlyphRangesChineseFull());
}
} // namespace ImGui

Loading…
Cancel
Save