Browse Source

add single_color_model; colormap_model

cflin
cflin 2 years ago
parent
commit
76faa16a95
  1. 4
      .gitignore
  2. 11
      CMakeLists.txt
  3. 129725
      assets/armadillo.obj
  4. 2
      comparisons/Bullet/README.md
  5. 3
      engine/CMakeLists.txt
  6. 26
      engine/engine.json.in
  7. 1
      src/CMakeLists.txt
  8. 14
      src/main.cpp
  9. 7
      src/path_config.h.in
  10. 8
      src/viewer/UIMenu.cpp
  11. 4
      src/viewer/UISimState.cpp
  12. 12
      src/viewer/UISimState.hpp
  13. 10
      src/viewer/UIStaticSimState.cpp
  14. 169
      src/viewer/UIStaticSimState.h
  15. 16
      static_sim/CMakeLists.txt
  16. 46
      static_sim/SimTargetOption.h
  17. 8
      static_sim/StaticSim.cpp
  18. 107
      static_sim/StaticSim.h

4
.gitignore

@ -1,4 +1,6 @@
cmake-*/
.idea/
stl/
output/
*.und/
path_config.h
engine.json

11
CMakeLists.txt

@ -24,6 +24,10 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/RigidIPCOptions.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/RigidIPCOptions.cmake)
endif ()
# Edit start
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Edit end
################################################################################
project(RigidIPC
@ -285,6 +289,9 @@ if(RIGID_IPC_WITH_OPENGL)
src/viewer/igl_viewer_ext.cpp
src/viewer/UISimState.cpp
src/viewer/UIMenu.cpp
# Edit start
src/viewer/UIStaticSimState.cpp
# Edit end
)
endif ()
@ -343,3 +350,7 @@ endif()
if (RIGID_IPC_WITH_PYTHON)
add_subdirectory(python)
endif ()
add_subdirectory(src)
add_subdirectory(engine)
add_subdirectory(static_sim)

129725
assets/armadillo.obj

File diff suppressed because it is too large

2
comparisons/Bullet/README.md

@ -2,7 +2,7 @@
Bullet provides two ways of modeling contacts between complex geometries. Similar to our method, the first way uses the triangle mesh geometry directly (`btGImpactMeshShape`). The second way uses convex shapes (or compound convex shapes). Bullet additionally, provides a direct way of generating approximate convex decompositions of concave shapes through Volumetric Hierarchical Approximate Decomposition (V-HACD).
## Triangle Mesh Collisions (`btGImpactMeshShape`)
## Triangle Model Collisions (`btGImpactMeshShape`)
We modified the ImportMJCFDemo example to automatically take an MJCF scene file as input, run the scene for 10 simulated seconds, and then terminate. We use `GImpact` for any input triangle meshes, and enforce only one substep for each time step (time step size fixed at `1e-2`, `1e-3`, or `1e-4` s for our experiments). To do this we implemented mesh volume computation and enabled automatic mass computation from density input (`m=ρV`), and we also enabled mesh scaling, `dt`, and `mu` setting from MJCF file which are not supported in the original demo.

3
engine/CMakeLists.txt

@ -0,0 +1,3 @@
# replace the absolute path to the local directory with a relative one
set(LOCAL_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "PATH TO LOCAL DIR")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/engine.json.in ${CMAKE_CURRENT_SOURCE_DIR}/engine.json @ONLY)

26
engine/engine.json → engine/engine.json.in

@ -6,7 +6,7 @@
"coefficient_restitution": -1,
"gravity": [0, 9.8, 0],
"rigid_bodies": [{
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/crank.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/crank.stl",
"density": 1000,
"angular_velocity": [0, 0, 450],
"torque": [0, 0, 300],
@ -14,59 +14,59 @@
"is_dof_fixed": [true, true, true, true, true, false],
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston1_head.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston1_head.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston1_pin.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston1_pin.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston1_mid.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston1_mid.stl",
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston2_head.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston2_head.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston2_pin.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston2_pin.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston2_mid.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston2_mid.stl",
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston3_head.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston3_head.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston3_pin.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston3_pin.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston3_mid.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston3_mid.stl",
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston4_head.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston4_head.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston4_pin.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston4_pin.stl",
"is_dof_fixed": [true, false, true, true, true, true],
"density": 1000,
"scale": 0.001
}, {
"mesh": "/home/oo/project/vscode/rigid_ipc/rigid-ipc/engine/stl/piston4_mid.stl",
"mesh": "@LOCAL_DIR_PATH@/stl/piston4_mid.stl",
"density": 1000,
"scale": 0.001
}]

1
src/CMakeLists.txt

@ -0,0 +1 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/path_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/path_config.h @ONLY)

14
src/main.cpp

@ -11,10 +11,11 @@
#include <SimState.hpp>
#ifdef RIGID_IPC_WITH_OPENGL
#include <viewer/UISimState.hpp>
#include "viewer/UIStaticSimState.h"
#endif
#include <logger.hpp>
#include <profiler.hpp>
#include "path_config.h"
int main(int argc, char* argv[])
{
using namespace ipc::rigid;
@ -88,7 +89,16 @@ int main(int argc, char* argv[])
if (with_viewer) {
#ifdef RIGID_IPC_WITH_OPENGL
UISimState ui;
// UISimState ui;
// ui.launch(scene_path);
// Static Simulation
ssim::SimTargetOption option;
option.set_option(option.U_NORM);
std::string obj_path=CMAKE_SOURCE_DIR "/assets/armadillo.obj";
std::shared_ptr<ssim::StaticSim> sp_StaticSim = std::make_shared<ssim::StaticSim>(option,obj_path);
UIStaticSimState ui(sp_StaticSim);
ui.launch(scene_path);
#else
exit(app.exit(CLI::Error(

7
src/path_config.h.in

@ -0,0 +1,7 @@
#ifndef PATH_CONFIG_H_IN
#define PATH_CONFIG_H_IN
#cmakedefine CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@"
#endif

8
src/viewer/UIMenu.cpp

@ -236,10 +236,10 @@ void UISimState::draw_settings()
ImGui::EndTooltip();
}
if (ImGui::Button("应力##IO", ImVec2(-1, 0))) {
std::string fname = igl::file_dialog_open();
if (fname != "") {
load(fname);
}
// std::string fname = igl::file_dialog_open();
// if (fname != "") {
// load(fname);
// }
}
}

4
src/viewer/UISimState.cpp

@ -5,7 +5,7 @@
#include <physics/rigid_body_problem.hpp>
#include <utils/eigen_ext.hpp>
#include "path_config.h"
namespace ipc::rigid {
UISimState::UISimState()
@ -55,7 +55,7 @@ void UISimState::init(igl::opengl::glfw::Viewer* _viewer)
ImGuiIO& io = ImGui::GetIO();
io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF(
"/home/oo/project/vscode/rigid_ipc/rigid-ipc/src/viewer/Arial Unicode MS.TTF",
CMAKE_SOURCE_DIR "/src/viewer/Arial Unicode MS.TTF",
14.0f, nullptr, io.Fonts->GetGlyphRangesChineseFull());
viewer->data().clear();

12
src/viewer/UISimState.hpp

@ -28,7 +28,7 @@ class UISimState : public igl::opengl::glfw::imgui::ImGuiMenu {
public:
UISimState();
~UISimState() override {}
virtual ~UISimState() override {}
enum PlayerState { Playing = 0, Paused, TotalPlayerStatus };
@ -40,11 +40,11 @@ public:
std::shared_ptr<igl::opengl::ViewerDataExt>
get_data(const std::string& data) const;
void launch(const std::string& inital_scene);
void load_scene();
void redraw_scene();
bool pre_draw_loop();
bool post_draw_loop();
virtual void launch(const std::string& inital_scene);
virtual void load_scene();
virtual void redraw_scene();
virtual bool pre_draw_loop();
virtual bool post_draw_loop();
bool custom_key_pressed(unsigned int unicode_key, int modifiers);

10
src/viewer/UIStaticSimState.cpp

@ -0,0 +1,10 @@
//
// Created by cflin on 4/7/23.
//
#include "UIStaticSimState.h"
namespace ipc {
namespace rigid {
} // ipc
} // rigid

169
src/viewer/UIStaticSimState.h

@ -0,0 +1,169 @@
//
// Created by cflin on 4/7/23.
//
#ifndef RIGIDIPC_UISTATICSIMSTATE_H
#define RIGIDIPC_UISTATICSIMSTATE_H
#include <memory> // shared_ptr
#include <spdlog/spdlog.h>
#include <igl/Timer.h>
#include <igl/opengl/glfw/Viewer.h>
#include <igl/opengl/glfw/imgui/ImGuiMenu.h>
#include <igl/png/render_to_png.h>
#include <igl/png/writePNG.h>
#include <igl/jet.h>
#include <viewer/igl_viewer_ext.hpp>
#include "UISimState.hpp"
#include "path_config.h"
#include "../../static_sim/StaticSim.h"
namespace ipc {
namespace rigid {
struct GUICtrl {
bool mesh_visible = true;
bool single_color = false;
};
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;
}
virtual ~UIStaticSimState() override {}
virtual void init(igl::opengl::glfw::Viewer *_viewer) override {
Super::init(_viewer);
ImGuiIO &io = ImGui::GetIO();
io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF(
CMAKE_SOURCE_DIR "/src/viewer/Arial Unicode MS.TTF",
14.0f, nullptr, io.Fonts->GetGlyphRangesChineseFull());
viewer->data().clear();
load_scene();
}
// virtual void draw_menu() override;
void load_scene() {
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);
// plot
viewer->data().set_mesh(V, F);
// colormap
Eigen::MatrixXd C;
igl::jet(Target, true, C);
viewer->data().set_colors(C);
m_has_scene = true;
int dim = V.cols();
m_viewer.core().trackball_angle.setIdentity();
m_viewer.core().set_rotation_type(
dim == 2 ? igl::opengl::ViewerCore::ROTATION_TYPE_NO_ROTATION
: igl::opengl::ViewerCore::
ROTATION_TYPE_TWO_AXIS_VALUATOR_FIXED_UP);
m_viewer.core().orthographic = dim == 2;
m_viewer.core().lighting_factor = 0.0; // dim == 2 ? 0.0 : 1.0;
// mesh_data->data().set_face_based(true);
assert(dim == 3.0);
m_viewer.core().align_camera_center(
V, F);
// Default colors
m_viewer.core().background_color << 0.9f, 0.9f, 0.9f, 0.4f;
// background_color << 0.3f, 0.3f, 0.5f, 1.0f;
// Camera parameters
m_viewer.core().camera_zoom = 1.0f;
m_viewer.core().camera_translation << 0, 0, 0;
}
void launch(const std::string &inital_scene) override {
m_viewer.plugins.push_back(this);
m_viewer.core().set_rotation_type(
igl::opengl::ViewerCore::ROTATION_TYPE_NO_ROTATION);
m_viewer.core().orthographic = true;
m_viewer.core().is_animating = true;
m_viewer.core().lighting_factor = 0.0;
m_viewer.core().animation_max_fps = 120.0;
// this->inital_scene = inital_scene;
m_viewer.callback_pre_draw = [&](igl::opengl::glfw::Viewer &) {
return pre_draw_loop();
};
m_viewer.callback_post_draw = [&](igl::opengl::glfw::Viewer &) {
return post_draw_loop();
};
m_viewer.callback_key_pressed = [&](igl::opengl::glfw::Viewer &,
unsigned int unicode_key,
int modifiers) {
return custom_key_pressed(unicode_key, modifiers);
};
m_viewer.launch(
/*resizable=*/true, /*fullscreen=*/false,
/*name=*/"静力学仿真");
}
// void load_scene();
void redraw_scene() {
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);
// plot
viewer->data().set_mesh(V, F);
if (!gui_ctrl_.mesh_visible) {
viewer->data().show_overlay = false;
viewer->data().show_lines = false;
}
if (!gui_ctrl_.single_color) {
// colormap
Eigen::MatrixXd C;
igl::jet(Target, true, C);
viewer->data().set_colors(C);
} else {
// single color
viewer->data().set_colors(Eigen::RowVector3d(1, 0, 0));
}
}
bool pre_draw_loop() {
redraw_scene();
return false;
}
bool post_draw_loop() {
return false;
}
private:
std::shared_ptr<ssim::StaticSim> sp_StaticSim_;
ssim::SimTargetOption::Target display_target;
GUICtrl gui_ctrl_;
};
} // ipc
} // rigid
#endif //RIGIDIPC_UISTATICSIMSTATE_H

16
static_sim/CMakeLists.txt

@ -0,0 +1,16 @@
# Static Simulation Project
add_library(StaticSim STATIC StaticSim.cpp)
# eigen
target_link_libraries(StaticSim PUBLIC Eigen3::Eigen)
# igl
include(libigl)
target_link_libraries(StaticSim PUBLIC
igl::core
igl::predicates
)
target_link_libraries(StaticSim PUBLIC spdlog::spdlog)
# IPC link static simulation
target_link_libraries(rigid_ipc_sim PUBLIC StaticSim)

46
static_sim/SimTargetOption.h

@ -0,0 +1,46 @@
//
// Created by cflin on 4/7/23.
//
#ifndef RIGIDIPC_SIMTARGETOPTION_H
#define RIGIDIPC_SIMTARGETOPTION_H
namespace ssim {
class SimTargetOption {
public:
static const int NUM_TARGETS = 10;
enum Target{
U_NORM = 0,S_NORM, S_X, S_Y, S_Z
};
SimTargetOption(int init_state=0) : state(init_state) {}
void set_option(int option) {
state |= (1 << option);
}
void unset_option(int option) {
state &= ~(1 << option);
}
bool is_option_set(int option) const {
return state & (1 << option);
}
void clear() {
state = 0;
}
void set() {
state = INT_MAX;
}
private:
int state;
};
} // ssim
#endif //RIGIDIPC_SIMTARGETOPTION_H

8
static_sim/StaticSim.cpp

@ -0,0 +1,8 @@
//
// Created by cflin on 4/7/23.
//
#include "StaticSim.h"
namespace ssim {
} // ssim

107
static_sim/StaticSim.h

@ -0,0 +1,107 @@
//
// Created by cflin on 4/7/23.
//
#ifndef RIGIDIPC_STATICSIM_H
#define RIGIDIPC_STATICSIM_H
#include <igl/readOBJ.h>
#include <Eigen/Dense>
#include <spdlog/spdlog.h>
#include "SimTargetOption.h"
namespace ssim {
struct Model {
Eigen::MatrixX3d V;
Eigen::MatrixX3i F;
Model() = default;
Model(const Eigen::MatrixX3d &V, const Eigen::MatrixX3i &F) : V(V), F(F) {}
int NumVertex() const{
return V.rows();
};
};
class StaticSim {
using MeshModel = Model;
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 StlModel &stl, const SimTargetOption &option) : stl_(stl), option_(option) {
map_target_to_evaluated_.resize(option_.NUM_TARGETS);
// TODO: boundary condition && solve
for (int i = 0; i < option_.NUM_TARGETS; ++i) {
MapAppendTarget(i);
}
// ...
}
Eigen::MatrixXd EvaluateTarget(SimTargetOption::Target target) {
if (!option_.is_option_set(target)) {
// new target, update option_ and map_
MapAppendTarget(target);
option_.set_option(target);
}
return map_target_to_evaluated_[target];
}
void set_stl(const std::string &stl_path) {
// TODO read stl file
}
Model get_mesh() const {
return mesh_;
}
Model get_stl() const {
return stl_;
}
private:
MeshModel mesh_;
StlModel stl_;
SimTargetOption option_;
std::vector<Eigen::MatrixXd> map_target_to_evaluated_;
Eigen::MatrixXd EvaluateUNorm() const {
// TODO
return (Eigen::VectorXd::Random(mesh_.NumVertex()).array() + 1.0) * 50;
}
Eigen::MatrixXd EvaluateSNorm() const {
// TODO
return (Eigen::VectorXd::Random(mesh_.NumVertex()).array() + 1.0) * 50;
}
void MapAppendTarget(int target) {
switch (target) {
case SimTargetOption::U_NORM:
map_target_to_evaluated_[target] = EvaluateUNorm();
break;
case SimTargetOption::S_NORM:
map_target_to_evaluated_[target] = EvaluateSNorm();
break;
default:
spdlog::warn("Wrong target {:d} !(TODO)", target);
}
}
};
} // ssim
#endif //RIGIDIPC_STATICSIM_H
Loading…
Cancel
Save