Browse Source

add tips windows

master
cflin 2 years ago
parent
commit
e74c3058dd
  1. 7
      README.md
  2. 159
      src/viewer/StaticSimGUIMenu.cpp
  3. 29
      src/viewer/Util.h

7
README.md

@ -21,3 +21,10 @@ To run the program, simply execute the binary:
## Usage
The load files are in `sim-test/rigid-test/*/json`, generated by `sim-test/rigid-test/*/*.json.in`.
---
## Detailed steps
1. 点击加载文件,选择.json配置文件(选择错误后缀会有提醒).
2. 设置边界条件和材料,点击开始计算.
3. 查看仿真结果,并可选择导出.
4. 可选择结果对比(需要预先准备文件),选择对应例子的`/ref_res`文件夹(错误文件夹名会有提醒),显示对比结果.

159
src/viewer/StaticSimGUIMenu.cpp

@ -15,20 +15,51 @@ namespace ssim {
auto io_menu = [&]() {
static std::string f_json;
static bool show_popup = false;
if (ImGui::Button("加载文件##IO", ImVec2(-1, 0))) {
#ifndef DEBUG_SSIM
f_json = igl::file_dialog_open();
if (f_json == "") return;
reload_json(f_json);
if (!JudgeEndWith(f_json, ".json")) {
// wrong file suffix, tip to reload
show_popup = true;
} else {
show_popup = false;
reload_json(f_json);
#else
f_json ="/debug/abspath/to/sim-test/rigid-test/cube/config.json/";
reload_json(CMAKE_SOURCE_DIR "/sim-test/rigid-test/cube/config.json");
f_json ="/debug/abspath/to/sim-test/rigid-test/cube/config.json/";
reload_json(CMAKE_SOURCE_DIR "/sim-test/rigid-test/cube/config.json");
#endif
gui_ctrl_.is_initialized = true;
gui_ctrl_.is_loaded_json = true;
gui_ctrl_.has_load_cmp_file= false;
gui_ctrl_.is_initialized = true;
gui_ctrl_.is_loaded_json = true;
gui_ctrl_.has_load_cmp_file = false;
}
}
// tip window
if (show_popup) {
static float popup_time = 0.0f;
const float popup_duration = 7.0f; // 显示时间
ImGui::SetNextWindowPos(ImVec2(600, 500)); // 窗口位置
ImGui::SetNextWindowBgAlpha(0.5f); // 背景透明度
ImGui::Begin("提示", &show_popup, ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoSavedSettings);
ImGui::Text("文件类型错误!\n请选择.json配置文件.");
ImGui::End();
if (popup_time == 0.0f) {
popup_time = ImGui::GetTime();
} else if (ImGui::GetTime() - popup_time > popup_duration) {
show_popup = false;
popup_time = 0.0f;
}
}
if (gui_ctrl_.is_loaded_json) {
ImGui::BeginChild("##filename", ImVec2(-1, ImGui::GetFontSize() * 3), false,
ImGuiWindowFlags_HorizontalScrollbar);
@ -72,10 +103,12 @@ namespace ssim {
static bool is_drag[2];
ImGui::PushItemWidth(-80);
is_drag[0] = ImGui::DragFloat3(("最小值 " + std::to_string(i + 1) + "##Dir").c_str(),
v_min_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[1] = ImGui::DragFloat3(("最大值 " + std::to_string(i + 1) + "##Dir").c_str(),
v_max_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[0] = ImGui::DragFloat3(
("最小值 " + std::to_string(i + 1) + "##Dir").c_str(),
v_min_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[1] = ImGui::DragFloat3(
("最大值 " + std::to_string(i + 1) + "##Dir").c_str(),
v_max_point.data(), 0.01, 0.0, 1.0, "%.3f");
ImGui::PopItemWidth();
if (is_drag[0] || is_drag[1]) {
gui_ctrl_.is_modified = true;
@ -100,16 +133,20 @@ namespace ssim {
std::vector<float> v_max_point = {(float) i_NBC.relMaxBBox.x(),
(float) i_NBC.relMaxBBox.y(),
(float) i_NBC.relMaxBBox.z()};
std::vector<float> v_force = {(float) i_NBC.force.x(), (float) i_NBC.force.y(),
std::vector<float> v_force = {(float) i_NBC.force.x(),
(float) i_NBC.force.y(),
(float) i_NBC.force.z()};
static bool is_drag[3];
ImGui::PushItemWidth(-80);
is_drag[0] = ImGui::DragFloat3(("最小值 " + std::to_string(i + 1) + "##Neu").c_str(),
v_min_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[1] = ImGui::DragFloat3(("最大值 " + std::to_string(i + 1) + "##Neu").c_str(),
v_max_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[2] = ImGui::DragFloat3(("" + std::to_string(i + 1) + " (N)" + "##Neu").c_str(),
v_force.data(), 1, -1e10, 1e10, "%.3f");
is_drag[0] = ImGui::DragFloat3(
("最小值 " + std::to_string(i + 1) + "##Neu").c_str(),
v_min_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[1] = ImGui::DragFloat3(
("最大值 " + std::to_string(i + 1) + "##Neu").c_str(),
v_max_point.data(), 0.01, 0.0, 1.0, "%.3f");
is_drag[2] = ImGui::DragFloat3(
("" + std::to_string(i + 1) + " (N)" + "##Neu").c_str(),
v_force.data(), 1, -1e10, 1e10, "%.3f");
ImGui::PopItemWidth();
if (is_drag[0] || is_drag[1] || is_drag[2]) {
gui_ctrl_.is_modified = true;
@ -130,15 +167,19 @@ namespace ssim {
if (ImGui::CollapsingHeader("材料设置", ImGuiTreeNodeFlags_DefaultOpen)) {
static const int item_width = 200;
ImGui::SetNextItemWidth(item_width);
ImGui::InputFloat("杨氏模量 (Pa)", &sp_StaticSim_->get_material_property().Youngs_Modulus, 1.0f, 2e11f,
ImGui::InputFloat("杨氏模量 (Pa)",
&sp_StaticSim_->get_material_property().Youngs_Modulus, 1.0f,
2e11f,
"%.2e");
ImGui::SetNextItemWidth(item_width);
ImGui::InputFloat("泊松比", &sp_StaticSim_->get_material_property().Poisson_ratio, 0.01f, 1.0f,
ImGui::InputFloat("泊松比", &sp_StaticSim_->get_material_property().Poisson_ratio,
0.01f, 1.0f,
"%.3f");
ImGui::SetNextItemWidth(item_width);
ImGui::InputFloat("密度 (kg/m^3)", &sp_StaticSim_->get_material_property().density, 1.0f, 1000.0f,
ImGui::InputFloat("密度 (kg/m^3)", &sp_StaticSim_->get_material_property().density,
1.0f, 1000.0f,
"%.3f");
}
@ -158,7 +199,8 @@ namespace ssim {
};
auto result_menu = [&]() {
ImGui::TextWrapped("柔顺度 (compliance): %.3e",
sp_StaticSim_->EvaluateTarget(ssim::SimTargetOption::COMPLIANCE)(0, 0));
sp_StaticSim_->EvaluateTarget(ssim::SimTargetOption::COMPLIANCE)(0,
0));
static const ImVec2 button_size(200, 40);
static bool arr_extract[SimTargetOption::Target::ENUM_SIZE] = {false};
int idx = 0;
@ -229,7 +271,8 @@ namespace ssim {
if (ImGui::Button("导出结果文件", button_size)) {
std::string extract_dir = ssim::directory_dialog_save();
spdlog::info("extract to: {}", extract_dir);
std::vector<bool> v_is_extract(arr_extract, arr_extract + SimTargetOption::Target::ENUM_SIZE);
std::vector<bool> v_is_extract(arr_extract,
arr_extract + SimTargetOption::Target::ENUM_SIZE);
sp_StaticSim_->ExtractTarget(extract_dir, v_is_extract, is_extract_coord);
}
ImGui::SameLine();
@ -241,35 +284,65 @@ namespace ssim {
static std::vector<double> v_error(SimTargetOption::Target::ENUM_SIZE, EMPTY);
static bool show_popup = false;
if (ImGui::Button("导入Ansys文件", ImVec2(-1, 0))) {
std::string input_dir = ssim::directory_dialog_save();
spdlog::info("input from: {}", input_dir);
for (int i = 0; i < ssim::SimTargetOption::Target::ENUM_SIZE; ++i) {
std::string target_name = SimTargetOption::GetTargetName(i);
std::ifstream iif(input_dir + "/" + target_name + ".txt");
Eigen::VectorXd cpt_cur_target = sp_StaticSim_->EvaluateTarget(
static_cast<ssim::SimTargetOption::Target>(i));
Eigen::VectorXd ref_cur_target = cpt_cur_target;
int cnt = 0;
if (!iif.is_open()) {
continue;
}
double t;
while (iif >> t) {
ref_cur_target[cnt++] = t;
}
double cur_error = (cpt_cur_target - ref_cur_target).norm() / ref_cur_target.norm();
v_error[i] = cur_error;
if (!JudgeEndWith(input_dir, "/ref_res")) {
show_popup = true;
} else {
show_popup = false;
spdlog::info("input from: {}", input_dir);
for (int i = 0; i < ssim::SimTargetOption::Target::ENUM_SIZE; ++i) {
std::string target_name = SimTargetOption::GetTargetName(i);
std::ifstream iif(input_dir + "/" + target_name + ".txt");
Eigen::VectorXd cpt_cur_target = sp_StaticSim_->EvaluateTarget(
static_cast<ssim::SimTargetOption::Target>(i));
Eigen::VectorXd ref_cur_target = cpt_cur_target;
int cnt = 0;
if (!iif.is_open()) {
continue;
}
double t;
while (iif >> t) {
ref_cur_target[cnt++] = t;
}
double cur_error =
(cpt_cur_target - ref_cur_target).norm() / ref_cur_target.norm();
v_error[i] = cur_error;
}
gui_ctrl_.has_load_cmp_file = true;
}
}
if(show_popup) {
// wrong input file tip
static float popup_time = 0.0f;
const float popup_duration = 7.0f; // 显示时间为5秒
ImGui::SetNextWindowPos(ImVec2(600, 500)); // 窗口位置
ImGui::SetNextWindowBgAlpha(0.5f); // 背景透明度
ImGui::Begin("提示", &show_popup, ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoSavedSettings);
ImGui::Text("文件夹类型错误!\n请选择ref_res文件夹.");
ImGui::End();
if (popup_time == 0.0f) {
popup_time = ImGui::GetTime();
} else if (ImGui::GetTime() - popup_time > popup_duration) {
show_popup = false;
popup_time = 0.0f;
}
gui_ctrl_.has_load_cmp_file = true;
}
if (gui_ctrl_.has_load_cmp_file) {
for (int i = 0; i < SimTargetOption::Target::ENUM_SIZE; ++i) {
if (v_error[i] != EMPTY) {
ImGui::TextWrapped((SimTargetOption::GetTargetName(i) + std::string("误差: %.5f %%")).c_str(),
ImGui::TextWrapped((SimTargetOption::GetTargetName(i) +
std::string("误差: %.5f %%")).c_str(),
v_error[i]);
}
}

29
src/viewer/Util.h

@ -4,17 +4,19 @@
#ifndef EXAMPLE_UTIL_H
#define EXAMPLE_UTIL_H
#include <string>
#include <cstdio>
#include <cstring>
#include <Eigen/Eigen>
#ifdef _WIN32
#include <windows.h>
#include <Commdlg.h>
#include <Commdlg.h>
#endif
namespace ssim {
inline std::string directory_dialog_save(){
inline std::string directory_dialog_save() {
const int FILE_DIALOG_MAX_BUFFER = 1024;
char buffer[FILE_DIALOG_MAX_BUFFER];
buffer[0] = '\0';
@ -85,34 +87,29 @@ namespace ssim {
#else
// For every other machine type use zenity
FILE * output = popen("/usr/bin/zenity --directory --file-selection --save","r");
if (output)
{
FILE *output = popen("/usr/bin/zenity --directory --file-selection --save", "r");
if (output) {
auto ret = fgets(buffer, FILE_DIALOG_MAX_BUFFER, output);
if (ret == NULL || ferror(output))
{
if (ret == NULL || ferror(output)) {
// I/O error
buffer[0] = '\0';
}
if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0')
{
if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0') {
// File name too long, buffer has been filled, so we return empty string instead
buffer[0] = '\0';
}
}
// Replace last '\n' by '\0'
if(strlen(buffer) > 0)
{
buffer[strlen(buffer)-1] = '\0';
if (strlen(buffer) > 0) {
buffer[strlen(buffer) - 1] = '\0';
}
#endif
return std::string(buffer);
}
void texture_from_colormap(const Eigen::MatrixXd &rgb, GLuint & id)
{
void texture_from_colormap(const Eigen::MatrixXd &rgb, GLuint &id) {
int width = 1;
int height = (int) rgb.rows();
@ -141,6 +138,10 @@ namespace ssim {
glBindTexture(GL_TEXTURE_2D, 0);
}
inline bool JudgeEndWith(const std::string &str, const std::string &suffix) {
if (suffix.size() > str.size()) return false;
return str.rfind(suffix) == str.size() - suffix.size();
}

Loading…
Cancel
Save