From bd5483b29d6adf67a7526ee9af6c16cdadcdb4cb Mon Sep 17 00:00:00 2001 From: cflin Date: Sat, 8 Apr 2023 12:08:58 +0800 Subject: [PATCH] add static simulation interfaces --- src/viewer/ColorbarPlugin.h | 135 ++++++++++++++++++++++++++++++++++ src/viewer/UIStaticSimState.h | 20 ++--- static_sim/SimTargetOption.h | 7 +- static_sim/StaticSim.h | 109 ++++++++++++++++++++------- 4 files changed, 230 insertions(+), 41 deletions(-) create mode 100644 src/viewer/ColorbarPlugin.h diff --git a/src/viewer/ColorbarPlugin.h b/src/viewer/ColorbarPlugin.h new file mode 100644 index 0000000..ef4161f --- /dev/null +++ b/src/viewer/ColorbarPlugin.h @@ -0,0 +1,135 @@ +// +// Created by cflin on 4/8/23. +// + +#ifndef RIGIDIPC_COLORBARPLUGIN_H +#define RIGIDIPC_COLORBARPLUGIN_H + +#include +#include +#include + +class ColorbarPlugin { +public: + ColorbarPlugin() { + // initialize + Eigen::MatrixXd rgb; + Eigen::MatrixXd f=Eigen::VectorXd::LinSpaced(100,0.0,1.0); + for (size_t i = 0; i < igl::NUM_COLOR_MAP_TYPES; ++i) { + GLuint id = 0; + igl::colormap(static_cast(i),f,0.0,1.0,rgb); +// std::cout<(colormaps_[n]), + ImVec2(ImGui::GetTextLineHeight(), ImGui::GetTextLineHeight()), + ImVec2(0, 0), ImVec2(1, 1)); + ImGui::SameLine(); + ImGui::Text("%s", items[n]); + if (is_selected) { + ImGui::SetItemDefaultFocus(); + } + ImGui::PopID(); + } + ImGui::EndCombo(); + } + + ImVec2 backup_pos = ImGui::GetCursorScreenPos(); + ImGuiStyle &style = ImGui::GetStyle(); + ImGui::SetCursorScreenPos(ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y + style.FramePadding.y)); + float h = ImGui::GetTextLineHeight(); + ImGui::Image( + reinterpret_cast(colormaps_[selected_index]), + ImVec2(h, h)); + ImGui::SameLine(); + ImGui::Text("%s", current_item); + ImGui::SetCursorScreenPos(backup_pos); + + return selected_index; + } + + void draw_colorbar(igl::ColorMapType cm, float xmin, float xmax, + const Eigen::Vector4f &background_color) const { + ImVec4 color(0, 0, 0, 1); + auto rgb = background_color; + // http://stackoverflow.com/a/3943023/112731 + if (rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114 > 186) { + color = ImVec4(1, 1, 1, 1); + } + float w = 20; + float h = 100; + ImGui::BeginGroup(); + ImGui::BeginGroup(); + ImGui::TextColored(color, "%.3g", xmin); + ImGui::Dummy(ImVec2(0, h - 2 * ImGui::GetTextLineHeightWithSpacing())); + ImGui::TextColored(color, "%.3g", xmax); + ImGui::EndGroup(); + ImGui::SameLine(); + ImGui::Image(reinterpret_cast(colormaps_[cm]), ImVec2(w, h)); + ImGui::EndGroup(); + } + + static void texture_from_colormap(const Eigen::MatrixXd &rgb, GLuint &id) { + int width = 1; + int height = (int) rgb.rows(); + + Eigen::Matrix cmap; + if (rgb.maxCoeff() > 1.0) { + cmap = rgb.cast(); + } else { + cmap = (rgb.array() * 255.f).cast(); + } + assert(cmap.cols() == 3); + cmap.conservativeResize(cmap.rows(), 4); + cmap.col(3).setConstant(255); + + if (id == 0) { + glGenTextures(1, &id); + } + glBindTexture(GL_TEXTURE_2D, id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, + width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cmap.data()); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } + +protected: + std::array colormaps_; + igl::ColorMapType colormap_type_ = igl::COLOR_MAP_TYPE_VIRIDIS; +}; + + +#endif //RIGIDIPC_COLORBARPLUGIN_H diff --git a/src/viewer/UIStaticSimState.h b/src/viewer/UIStaticSimState.h index f9172f4..85abf1c 100644 --- a/src/viewer/UIStaticSimState.h +++ b/src/viewer/UIStaticSimState.h @@ -15,26 +15,26 @@ #include #include #include +#include #include #include "UISimState.hpp" #include "path_config.h" #include "../../static_sim/StaticSim.h" - +#include "ColorbarPlugin.h" namespace ipc { namespace rigid { struct GUICtrl { bool mesh_visible = true; bool single_color = false; + ssim::SimTargetOption::Target target_to_evaluate = ssim::SimTargetOption::U_NORM; }; class UIStaticSimState : public UISimState { typedef igl::opengl::glfw::imgui::ImGuiMenu Super; public: - UIStaticSimState(std::shared_ptr sp_StaticSim) : UISimState(),sp_StaticSim_(sp_StaticSim),display_target(ssim::SimTargetOption::U_NORM) { - // set gui_ctrl_; - gui_ctrl_.single_color = true; - gui_ctrl_.mesh_visible = true; + UIStaticSimState(std::shared_ptr sp_StaticSim) : UISimState(), sp_StaticSim_(sp_StaticSim), + gui_ctrl_() { } virtual ~UIStaticSimState() override {} @@ -56,7 +56,7 @@ namespace ipc { ssim::Model model = sp_StaticSim_->get_mesh(); const Eigen::MatrixXd &V = model.V; const Eigen::MatrixXi &F = model.F; - Eigen::MatrixXd Target = sp_StaticSim_->EvaluateTarget(display_target); + Eigen::MatrixXd Target = sp_StaticSim_->EvaluateTarget(gui_ctrl_.target_to_evaluate); // plot viewer->data().set_mesh(V, F); @@ -123,7 +123,7 @@ namespace ipc { const Eigen::MatrixXd &V = model.V; const Eigen::MatrixXi &F = model.F; - Eigen::MatrixXd Target = sp_StaticSim_->EvaluateTarget(display_target); + Eigen::MatrixXd target = sp_StaticSim_->EvaluateTarget(gui_ctrl_.target_to_evaluate); // plot viewer->data().set_mesh(V, F); @@ -136,11 +136,12 @@ namespace ipc { if (!gui_ctrl_.single_color) { // colormap Eigen::MatrixXd C; - igl::jet(Target, true, C); + igl::jet(target, true, C); viewer->data().set_colors(C); } else { // single color viewer->data().set_colors(Eigen::RowVector3d(1, 0, 0)); +// colorbar_plugin_.draw_colorbar(igl::ColorMapType::COLOR_MAP_TYPE_JET,0,1,/*background_color=*/Eigen::Vector4f(1,1,1,0)); } @@ -158,9 +159,8 @@ namespace ipc { private: std::shared_ptr sp_StaticSim_; - ssim::SimTargetOption::Target display_target; GUICtrl gui_ctrl_; - +// ColorbarPlugin colorbar_plugin_; }; } // ipc diff --git a/static_sim/SimTargetOption.h b/static_sim/SimTargetOption.h index f4215f9..8a63ff9 100644 --- a/static_sim/SimTargetOption.h +++ b/static_sim/SimTargetOption.h @@ -9,12 +9,11 @@ namespace ssim { class SimTargetOption { public: - static const int NUM_TARGETS = 10; - enum Target{ - U_NORM = 0,S_NORM, S_X, S_Y, S_Z + enum Target { + U_NORM = 0, UX, UY, UZ, S_NORM, S_VON_Mises,/*primary stress*/SX, SY, SZ, COMPLIANCE, ENUM_SIZE }; - SimTargetOption(int init_state=0) : state(init_state) {} + SimTargetOption(int init_state = 0) : state(init_state) {} void set_option(int option) { state |= (1 << option); diff --git a/static_sim/StaticSim.h b/static_sim/StaticSim.h index 11c61de..1c2a27f 100644 --- a/static_sim/StaticSim.h +++ b/static_sim/StaticSim.h @@ -9,6 +9,7 @@ #include #include #include "SimTargetOption.h" + namespace ssim { struct Model { Eigen::MatrixX3d V; @@ -17,7 +18,8 @@ namespace ssim { Model() = default; Model(const Eigen::MatrixX3d &V, const Eigen::MatrixX3i &F) : V(V), F(F) {} - int NumVertex() const{ + + int NumVertex() const { return V.rows(); }; }; @@ -27,44 +29,39 @@ namespace ssim { using StlModel = Model; public: - StaticSim(const SimTargetOption &option,const std::string & obj_path){ - igl::readOBJ(obj_path,mesh_.V,mesh_.F); - // set option - option_=option; - map_target_to_evaluated_.resize(option_.NUM_TARGETS); - for (int i = 0; i < option_.NUM_TARGETS; ++i) { - if(option_.is_option_set(i)) - MapAppendTarget(i); - } - } + StaticSim(const SimTargetOption &option, const std::string &obj_path) : option_(option) { + igl::readOBJ(obj_path, mesh_.V, mesh_.F); + int ENUM_SIZE=SimTargetOption::Target::ENUM_SIZE; + map_target_to_evaluated_.resize(ENUM_SIZE); - StaticSim(const StlModel &stl, const SimTargetOption &option) : stl_(stl), option_(option) { - map_target_to_evaluated_.resize(option_.NUM_TARGETS); - // TODO: boundary condition && solve + // TODO: meshing(fill mesh_ and stl_) && boundary condition && solve - for (int i = 0; i < option_.NUM_TARGETS; ++i) { - MapAppendTarget(i); + // Save results to map_target_to_evaluated_ + for (int i = 0; i < ENUM_SIZE; ++i) { + if (option_.is_option_set(i)) + MapAppendTarget(i); } - // ... } + Eigen::MatrixXd EvaluateTarget(SimTargetOption::Target target) { if (!option_.is_option_set(target)) { - // new target, update option_ and map_ + // If no cache, update option_ and map_ MapAppendTarget(target); option_.set_option(target); } + // Return cache return map_target_to_evaluated_[target]; } - void set_stl(const std::string &stl_path) { - // TODO read stl file - } - + /// Model after meshing + /// \return Model Model get_mesh() const { return mesh_; } + /// Origin model(.stl or .obj) + /// \return Model Model get_stl() const { return stl_; } @@ -75,27 +72,85 @@ namespace ssim { SimTargetOption option_; std::vector map_target_to_evaluated_; +#define RANDOM_COLOR_FOR_DEBUG (Eigen::VectorXd::LinSpaced(mesh_.NumVertex(),0,100) ) + // TODO: Evaluate + // Return: #mesh.V.rows() x 1 Eigen::MatrixXd EvaluateUNorm() const { - // TODO - return (Eigen::VectorXd::Random(mesh_.NumVertex()).array() + 1.0) * 50; + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateUX() const { + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateUY() const { + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateUZ() const { + return RANDOM_COLOR_FOR_DEBUG; } Eigen::MatrixXd EvaluateSNorm() const { - // TODO - return (Eigen::VectorXd::Random(mesh_.NumVertex()).array() + 1.0) * 50; + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateSVonMises() const { + return RANDOM_COLOR_FOR_DEBUG; } + Eigen::MatrixXd EvaluateSX() const { + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateSY() const { + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateSZ() const { + return RANDOM_COLOR_FOR_DEBUG; + } + + Eigen::MatrixXd EvaluateCompliance() { + return RANDOM_COLOR_FOR_DEBUG; + } + + void MapAppendTarget(int target) { switch (target) { case SimTargetOption::U_NORM: map_target_to_evaluated_[target] = EvaluateUNorm(); break; + case SimTargetOption::UX: + map_target_to_evaluated_[target] = EvaluateUX(); + break; + case SimTargetOption::UY: + map_target_to_evaluated_[target] = EvaluateUY(); + break; + case SimTargetOption::UZ: + map_target_to_evaluated_[target] = EvaluateUZ(); + break; case SimTargetOption::S_NORM: map_target_to_evaluated_[target] = EvaluateSNorm(); break; + case SimTargetOption::S_VON_Mises: + map_target_to_evaluated_[target] = EvaluateSVonMises(); + break; + case SimTargetOption::SX: + map_target_to_evaluated_[target] = EvaluateSX(); + break; + case SimTargetOption::SY: + map_target_to_evaluated_[target] = EvaluateSY(); + break; + case SimTargetOption::SZ: + map_target_to_evaluated_[target] = EvaluateSZ(); + break; + case SimTargetOption::COMPLIANCE: + map_target_to_evaluated_[target] = EvaluateCompliance(); + break; default: - spdlog::warn("Wrong target {:d} !(TODO)", target); + spdlog::warn("Wrong target {:d} !", target); } }