Browse Source

add static simulation interfaces

cflin
cflin 2 years ago
parent
commit
bd5483b29d
  1. 135
      src/viewer/ColorbarPlugin.h
  2. 20
      src/viewer/UIStaticSimState.h
  3. 7
      static_sim/SimTargetOption.h
  4. 109
      static_sim/StaticSim.h

135
src/viewer/ColorbarPlugin.h

@ -0,0 +1,135 @@
//
// Created by cflin on 4/8/23.
//
#ifndef RIGIDIPC_COLORBARPLUGIN_H
#define RIGIDIPC_COLORBARPLUGIN_H
#include <Eigen/Dense>
#include <igl/opengl/glfw/Viewer.h>
#include <igl/opengl/glfw/imgui/ImGuiMenu.h>
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<igl::ColorMapType>(i),f,0.0,1.0,rgb);
// std::cout<<std::endl;
// std::cout<<rgb<<std::endl;
texture_from_colormap(rgb, id);
colormaps_[i] = id;
}
}
// Draws a combo box for selecting the colormap
int draw_colormap_combo() const {
const char *items[]{
"Inferno",
"Jet",
"Magma",
"Parula",
"Plasma",
"Viridis",
};
static int selected_index = 5;
static const char *current_item = items[selected_index];
ImVec2 combo_pos = ImGui::GetCursorScreenPos();
if (ImGui::BeginCombo("Colormap##combo", "")) {
for (int n = 0; n < IM_ARRAYSIZE(items); ++n) {
// You can store your selection however you want, outside or inside your objects
bool is_selected = (current_item == items[n]);
ImGui::PushID(n);
if (ImGui::Selectable("", is_selected)) {
current_item = items[n];
selected_index = n;
}
ImGui::SameLine(0, 0);
ImGui::Image(
reinterpret_cast<ImTextureID>(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<ImTextureID>(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<ImTextureID>(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<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> cmap;
if (rgb.maxCoeff() > 1.0) {
cmap = rgb.cast<unsigned char>();
} else {
cmap = (rgb.array() * 255.f).cast<unsigned char>();
}
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<GLuint, igl::NUM_COLOR_MAP_TYPES> colormaps_;
igl::ColorMapType colormap_type_ = igl::COLOR_MAP_TYPE_VIRIDIS;
};
#endif //RIGIDIPC_COLORBARPLUGIN_H

20
src/viewer/UIStaticSimState.h

@ -15,26 +15,26 @@
#include <igl/png/render_to_png.h>
#include <igl/png/writePNG.h>
#include <igl/jet.h>
#include <igl/colormap.h>
#include <viewer/igl_viewer_ext.hpp>
#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<ssim::StaticSim> 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<ssim::StaticSim> 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<ssim::StaticSim> sp_StaticSim_;
ssim::SimTargetOption::Target display_target;
GUICtrl gui_ctrl_;
// ColorbarPlugin colorbar_plugin_;
};
} // ipc

7
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);

109
static_sim/StaticSim.h

@ -9,6 +9,7 @@
#include <Eigen/Dense>
#include <spdlog/spdlog.h>
#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<Eigen::MatrixXd> 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);
}
}

Loading…
Cancel
Save