diff --git a/CMakeLists.txt b/CMakeLists.txt index de303c4..967c772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -351,6 +351,7 @@ if (RIGID_IPC_WITH_PYTHON) add_subdirectory(python) endif () -add_subdirectory(src) add_subdirectory(engine) -add_subdirectory(static_sim) \ No newline at end of file +add_subdirectory(static_sim) + +target_compile_definitions(rigid_ipc_sim PUBLIC CMAKE_SOURCE_DIR="${CMAKE_SOURCE_DIR}") \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index ffdaa07..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/path_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/path_config.h @ONLY) diff --git a/src/SimState.cpp b/src/SimState.cpp index e70d96d..c8296cb 100644 --- a/src/SimState.cpp +++ b/src/SimState.cpp @@ -271,17 +271,14 @@ nlohmann::json SimState::get_active_config() { nlohmann::json active_args; active_args["时间步"] = problem_ptr->timestep(); - // active_args["scene_type"] = problem_ptr->name(); - - // active_args[problem_ptr->name()] = problem_ptr->settings(); - // active_args[problem_ptr->constraint().name()] = - // problem_ptr->constraint().settings(); - // active_args[problem_ptr->solver().name()] = - // problem_ptr->solver().settings(); - // if (problem_ptr->solver().has_inner_solver()) { - // active_args[problem_ptr->solver().inner_solver().name()] = - // problem_ptr->solver().inner_solver().settings(); - // } + active_args["scene_type"] = problem_ptr->name(); + + active_args[problem_ptr->name()] = problem_ptr->settings(); + active_args[problem_ptr->constraint().name()] = + problem_ptr->constraint().settings(); + active_args[problem_ptr->solver().name()] = + problem_ptr->solver().settings(); + return active_args; } diff --git a/src/main.cpp b/src/main.cpp index 2360be2..f4a1e29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,6 @@ #endif #include #include -#include "path_config.h" int main(int argc, char* argv[]) { using namespace ipc::rigid; @@ -89,17 +88,9 @@ int main(int argc, char* argv[]) if (with_viewer) { #ifdef RIGID_IPC_WITH_OPENGL -// 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 sp_StaticSim = std::make_shared(option,obj_path); - - UIStaticSimState ui(sp_StaticSim); + UISimState ui; ui.launch(scene_path); + #else exit(app.exit(CLI::Error( "gui", diff --git a/src/viewer/UIMenu.cpp b/src/viewer/UIMenu.cpp index 67c3209..bc7ee99 100644 --- a/src/viewer/UIMenu.cpp +++ b/src/viewer/UIMenu.cpp @@ -10,333 +10,189 @@ namespace ipc::rigid { -void UISimState::draw_menu() -{ - // if (m_show_vertex_data) { - // draw_labels_window(); - // } - - float menu_width = 220.f * menu_scaling(); - static bool player_menu = true; - static bool settings_menu = true; - static bool collisions_menu = true; - - //-------------------------------------------------------------------------- - ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver); - ImGui::SetNextWindowSizeConstraints( - ImVec2(menu_width, -1.0f), ImVec2(menu_width, -1.0f)); - bool _viewer_menu_visible = true; - - ImGui::Begin( - "控制菜单", &_viewer_menu_visible, - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize); - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.6f); - { - const char* level_strings[] = { "trace", "debug", "info", "warning", - "error", "critical", "off" }; - int log_level = spdlog::get_level(); - // if (ImGui::Combo( - // "log-level##logger", &log_level, level_strings, - // CCD_IM_ARRAYSIZE(level_strings))) { - // set_logger_level(static_cast(log_level)); + void UISimState::draw_menu() { + // if (m_show_vertex_data) { + // draw_labels_window(); // } - draw_io(); - if (m_has_scene) { + float menu_width = 220.f * menu_scaling(); + static bool player_menu = true; + static bool settings_menu = true; + static bool collisions_menu = true; - if (ImGui::CollapsingHeader( - "运行", &player_menu, ImGuiTreeNodeFlags_DefaultOpen)) { - draw_simulation_player(); - } - ImGui::Spacing(); - if (ImGui::CollapsingHeader( - "结果", &settings_menu, ImGuiTreeNodeFlags_DefaultOpen)) - draw_settings(); - } - } - ImGui::PopItemWidth(); - ImGui::End(); - - //-------------------------------------------------------------------------- - if (m_has_scene) { - float legends_width = 270.f * menu_scaling(); - ImGui::SetNextWindowPos( - ImVec2(ImGui::GetIO().DisplaySize.x - legends_width, 0.0f), - ImGuiCond_FirstUseEver); + //-------------------------------------------------------------------------- + ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSizeConstraints( - ImVec2(200.0f, 30.0f), ImVec2(legends_width, -1.0f)); - bool _colors_menu_visible = true; - - // ImGui::Begin( - // "Legend", &_colors_menu_visible, - // ImGuiWindowFlags_NoSavedSettings - // | ImGuiWindowFlags_AlwaysAutoResize); - // { - // draw_legends(); - // } - // ImGui::End(); - } -} // namespace ipc::rigid + ImVec2(menu_width, -1.0f), ImVec2(menu_width, -1.0f)); + bool _viewer_menu_visible = true; -void UISimState::draw_io() -{ - if (ImGui::Button("加载文件##IO", ImVec2(-1, 0))) { - std::string fname = igl::file_dialog_open(); - if (fname != "") { - load(fname); - } - } - if (m_has_scene) { - if (ImGui::Button("重新加载##IO", ImVec2(-1, 0))) { - reload(); - } - ImGui::BeginChild( - "##filename", - ImVec2( - ImGui::GetWindowContentRegionWidth() * 0.9f, - ImGui::GetFontSize() * 3), - false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::Begin( + "菜单", &_viewer_menu_visible, + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.6f); { - ImGui::Text("%s", m_state.scene_file.c_str()); - ImGui::SetScrollHere(1.0f); - } - ImGui::EndChild(); +// const char* level_strings[] = { "trace", "debug", "info", "warning", +// "error", "critical", "off" }; +// int log_level = spdlog::get_level(); +// if (ImGui::Combo( +// "log-level##logger", &log_level, level_strings, +// CCD_IM_ARRAYSIZE(level_strings))) { +// set_logger_level(static_cast(log_level)); +// } + set_logger_level(spdlog::level::level_enum::off); - // 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(); - // if (dir_name != "") { - // save_obj_sequence(dir_name); - // } - // } - - // if (ImGui::Button("Save gltf", ImVec2(-1, 0))) { - // std::string filename = igl::file_dialog_save(); - // if (filename != "") { - // save_gltf(filename); - // } - // } + draw_io(); + if (m_has_scene) { - // if (ImGui::Button("Save screenshot", ImVec2(-1, 0))) { - // std::string fname = igl::file_dialog_save(); - // save_screenshot(fname); - // } - // if (m_is_gif_recording) { - // if (ImGui::Button("End recording", ImVec2(-1, 0))) { - // end_recording(); - // } - // } else if (ImGui::Button("Start recording", ImVec2(-1, 0))) { - // std::string fname = igl::file_dialog_save(); - // start_recording(fname); - // } - } -} + if (ImGui::CollapsingHeader( + "运行", &player_menu, ImGuiTreeNodeFlags_DefaultOpen)) { + draw_simulation_player(); + } + if (ImGui::CollapsingHeader( + "结果", &settings_menu, ImGuiTreeNodeFlags_DefaultOpen)) + draw_settings(); + } + } + ImGui::PopItemWidth(); + ImGui::End(); -void UISimState::draw_simulation_player() -{ - int player_state = static_cast(m_player_state); + //-------------------------------------------------------------------------- + if (m_has_scene) { + float legends_width = 270.f * menu_scaling(); + ImGui::SetNextWindowPos( + ImVec2(ImGui::GetIO().DisplaySize.x - legends_width, 0.0f), + ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f), ImGuiCond_FirstUseEver); + 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 - ImGui::RadioButton("开始##SimPlayer", &player_state, PlayerState::Playing); - ImGui::RadioButton("暂停##SimPlayer", &player_state, PlayerState::Paused); - if (m_player_state == PlayerState::Playing - && player_state == PlayerState::Paused && !replaying) { - log_simulation_time(); - } - if (m_state.m_num_simulation_steps >= m_state.m_max_simulation_steps - && m_player_state == PlayerState::Paused - && player_state == PlayerState::Playing) { - m_state.m_max_simulation_steps = -1; // Turn off breaking - } - m_player_state = static_cast(player_state); + void UISimState::draw_io() { + if (ImGui::Button("加载文件##IO", ImVec2(-1, 0))) { + std::string fname = igl::file_dialog_open(); + if (fname != "") { + load(fname); + } + } + if (m_has_scene) { + if (ImGui::Button("重新加载##IO", ImVec2(-1, 0))) { + reload(); + } + ImGui::BeginChild( + "##filename", + ImVec2( + ImGui::GetWindowContentRegionWidth() * 0.9f, + ImGui::GetFontSize() * 3), + false, ImGuiWindowFlags_HorizontalScrollbar); + { + ImGui::Text("%s", m_state.scene_file.c_str()); + ImGui::SetScrollHere(1.0f); + } + ImGui::EndChild(); - if (ImGui::CollapsingHeader( - "边界条件设置##SimPlayer", ImGuiTreeNodeFlags_DefaultOpen)) { - // -------------------------------------------------------------------- - ImGui::Checkbox("边界包围盒", &m_bkp_has_intersections); + if (ImGui::Button("Save simulation", ImVec2(-1, 0))) { + std::string fname = igl::file_dialog_save(); + save(fname); + } - // ImGui::Checkbox("受力", &m_state.m_solve_collisions); - static float zoom = 50.0f; - static float zoom1 = 50.0f; - static float zoom2 = 50.0f; - ImGui::SliderFloat("x-受力", &zoom, -50, 50, "%.3f"); - ImGui::SliderFloat("y-受力", &zoom1, -50, 50, "%.3f"); - ImGui::SliderFloat("z-受力", &zoom2, -50, 50, "%.3f"); + // if (ImGui::Button("Save OBJ sequence", ImVec2(-1, 0))) { + // std::string dir_name = igl::file_dialog_save(); + // if (dir_name != "") { + // save_obj_sequence(dir_name); + // } + // } + + // if (ImGui::Button("Save gltf", ImVec2(-1, 0))) { + // std::string filename = igl::file_dialog_save(); + // if (filename != "") { + // save_gltf(filename); + // } + // } + + if (ImGui::Button("Start recording", ImVec2(-1, 0))) { + std::string fname = igl::file_dialog_save(); + start_recording(fname); + } + } } - // ImGui::Checkbox("受力大小", &m_bkp_optimization_failed); - // ImGui::SameLine(); - // ImGui::HelpMarker("yes - stop playing if step optimization failed."); + void UISimState::draw_simulation_player() { + int player_state = static_cast(m_player_state); - // ImGui::Checkbox("pause on collisions", &m_bkp_had_collision); - // ImGui::SameLine(); - // ImGui::HelpMarker("yes - stop playing if step had a collision."); - - // -------------------------------------------------------------------- - // if (ImGui::SliderInt( - // "step##Replay", &m_state.m_num_simulation_steps, 0, - // m_state.state_sequence.size() - 1)) { - // replaying = true; - // } + ImGui::RadioButton("开始##SimPlayer", &player_state, PlayerState::Playing); + ImGui::RadioButton("暂停##SimPlayer", &player_state, PlayerState::Paused); + if (m_player_state == PlayerState::Playing + && player_state == PlayerState::Paused && !replaying) { + log_simulation_time(); + } + if (m_state.m_num_simulation_steps >= m_state.m_max_simulation_steps + && m_player_state == PlayerState::Paused + && player_state == PlayerState::Playing) { + m_state.m_max_simulation_steps = -1; // Turn off breaking + } + m_player_state = static_cast(player_state); - // if (ImGui::Button("结果##SimPlayer", ImVec2(-1, 0))) { - // m_player_state = PlayerState::Playing; - // pre_draw_loop(); - // m_player_state = PlayerState::Paused; - // } - // -------------------------------------------------------------------- - if (ImGui::CollapsingHeader("材料设置", ImGuiTreeNodeFlags_DefaultOpen)) { - static float f0 = 0.001f; - static float f1 = 0.001f; - static float f2 = 0.001f; - ImGui::InputFloat("杨氏模量", &f0, 0.01f, 1.0f, "%.3f"); - ImGui::InputFloat("泊松比", &f1, 0.01f, 1.0f, "%.3f"); - ImGui::InputFloat("密度", &f2, 0.01f, 1.0f, "%.3f"); + if (ImGui::Button("Step##SimPlayer", ImVec2(-1, 0))) { + m_player_state = PlayerState::Playing; + pre_draw_loop(); + m_player_state = PlayerState::Paused; + } + // -------------------------------------------------------------------- + // -------------------------------------------------------------------- + if (ImGui::SliderInt( + "步##Replay", &m_state.m_num_simulation_steps, 0, + m_state.state_sequence.size() - 1)) { + replaying = true; + } } - if (ImGui::CollapsingHeader( - "其他设置", ImGuiTreeNodeFlags_DefaultOpen)) { - static float f3 = 0.01f; - ImGui::InputFloat("时间步", &f3, 0.01f, 1.0f, "%.2f");} -} -void UISimState::draw_settings() -{ - // auto config = m_state.get_active_config(); - // ImGui::BeginChild( - // "##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 20), false, - // ImGuiWindowFlags_HorizontalScrollbar); - // { - // ImGui::TreeNodeJson(config); - // } - // ImGui::EndChild(); - // if (ImGui::Button("应力##IO", ImVec2(-1, 0))) { - // std::string fname = igl::file_dialog_save(); - // if (fname != "") { - // load(fname); - // } - // } - // ImGui::Checkbox("柔顺度(compliance)", &compliance); - - char* desc = "121.82"; - ImGui::Text("柔顺度(compliance)"); - if (ImGui::IsItemHovered()) { - // 显示工具的提示 - ImGui::BeginTooltip(); - // 使得文字的区域可以自己控制, - // 但是这里我感觉更推荐使用:TextWrapped接口,之后的部分有提到他们的区别 - ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); - ImGui::TextUnformatted(desc); - ImGui::PopTextWrapPos(); - // 结束工具提示 - ImGui::EndTooltip(); - } - if (ImGui::Button("应力##IO", ImVec2(-1, 0))) { -// std::string fname = igl::file_dialog_open(); -// if (fname != "") { -// load(fname); -// } + void UISimState::draw_settings() { + auto config = m_state.get_active_config(); + ImGui::BeginChild( + "##config", ImVec2(ImGui::GetWindowContentRegionWidth(), 300), false, + ImGuiWindowFlags_HorizontalScrollbar); + { + ImGui::TreeNodeJson(config); + } + ImGui::EndChild(); } -} -void UISimState::draw_legends() -{ - static float second_col = 100; - float slider_width = ImGui::GetWindowWidth() * 0.2f; - for (auto& data : datas_) { - const std::string& label = data.first; - const auto& ptr = data.second; - - /// visibility checkbox - bool tmp = ptr->visibility(); - if (!ptr->is_com()) { - if (ImGui::Checkbox(("##UI-" + label).c_str(), &tmp)) { + void UISimState::draw_legends() { + static float second_col = 100; + float slider_width = ImGui::GetWindowWidth() * 0.2f; + for (auto &data: datas_) { + const std::string &label = data.first; + const auto &ptr = data.second; + + /// visibility checkbox + bool tmp = ptr->visibility(); + if (!ptr->is_com()) { + 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(); + } + } else if (ImGui::Checkbox((label + "##UI-check").c_str(), &tmp)) { ptr->visibility(tmp); } - /// 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); } - - /// other specific attributes - if (ptr->is_mesh()) { - ImGui::SameLine(second_col); - if (ImGui::Checkbox( - ("数据##UI-" + label).c_str(), &m_show_vertex_data)) { } - ptr->show_vertex_data = m_show_vertex_data; - ptr->update_vertex_data(); - - ImGui::SameLine(); - ImGui::PushItemWidth(slider_width); - { - float point_size = ptr->data().point_size / pixel_ratio(); - if (ImGui::SliderFloat( - ("顶点##UI-scaling" + label).c_str(), &point_size, - 0.00f, 10.0f, "%1.f")) { - ptr->data().point_size = point_size * pixel_ratio(); - } - } - ImGui::PopItemWidth(); - - } else if (ptr->is_scalar_field()) { - ImGui::SameLine(); - if (ImGui::Checkbox( - ("log##UI-" + label).c_str(), &ptr->m_use_log_scale)) { - ptr->recolor(); - } - ImGui::SameLine(); - bool show_iso = ptr->data().show_overlay; - if (ImGui::Checkbox(("isolines##UI-" + label).c_str(), &show_iso)) { - ptr->data().show_overlay = show_iso; - } - ImGui::SameLine(); - bool show_faces = ptr->data().show_faces; - if (ImGui::Checkbox(("faces##UI-" + label).c_str(), &show_faces)) { - ptr->data().show_faces = show_faces; - } - - } // else if (ptr->is_vector_field()) { - // ImGui::SameLine(second_col); - // if (ImGui::Checkbox( - // ("norm##UI-" + label).c_str(), &ptr->m_normalized)) { - // ptr->recolor(); - // } - // ImGui::SameLine(); - // ImGui::PushItemWidth(slider_width); - // { - // float aux = float(ptr->m_scaling); - // if (ImGui::SliderFloat( - // ("scale##UI-scaling" + label).c_str(), &aux, 0.00f, - // 10.0f, "%1.f")) { - // ptr->m_scaling = double(aux); - // ptr->recolor(); - // } - // } - // ImGui::PopItemWidth(); - // } else if (ptr->is_com()) { - // ImGui::SameLine(); - // ImGui::PushItemWidth(ImGui::GetWindowWidth() - 150); - // { - // float aux = float(ptr->m_scaling); - // if (ImGui::SliderFloat( - // ("scale##UI-com-scaling" + label).c_str(), &aux, - // 0.00f, 10.0f, "%1.1f", 1.0f)) { - // ptr->m_scaling = double(aux); - // ptr->recolor(); - // } - // } - // ImGui::PopItemWidth(); - // } } -} } // namespace ipc::rigid diff --git a/src/viewer/UISimState.cpp b/src/viewer/UISimState.cpp index db17de4..d6bab91 100644 --- a/src/viewer/UISimState.cpp +++ b/src/viewer/UISimState.cpp @@ -5,7 +5,7 @@ #include #include -#include "path_config.h" + namespace ipc::rigid { UISimState::UISimState() @@ -45,12 +45,11 @@ void UISimState::launch(const std::string& inital_scene) }; m_viewer.launch( /*resizable=*/true, /*fullscreen=*/false, - /*name=*/"仿真"); + /*name=*/"动力学仿真"); } void UISimState::init(igl::opengl::glfw::Viewer* _viewer) { - Super::init(_viewer); ImGuiIO& io = ImGui::GetIO(); io.Fonts->Clear(); @@ -76,6 +75,7 @@ void UISimState::init(igl::opengl::glfw::Viewer* _viewer) viewer->append_mesh(); com_data = std::make_unique(_viewer); // com_data->visibility(true); + // TODO:? com_data->visibility(false); datas_.emplace_back("edges", mesh_data); @@ -139,7 +139,7 @@ void UISimState::load_scene() 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); + 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); diff --git a/src/viewer/UIStaticSimState.h b/src/viewer/UIStaticSimState.h index f9172f4..e439458 100644 --- a/src/viewer/UIStaticSimState.h +++ b/src/viewer/UIStaticSimState.h @@ -18,7 +18,6 @@ #include #include "UISimState.hpp" -#include "path_config.h" #include "../../static_sim/StaticSim.h" namespace ipc {