Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ build
compile_commands.json
.clangd
CMakeSettings.json
.vs
.vs
snapshots
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include/pd/positional_constraint.h
${CMAKE_CURRENT_SOURCE_DIR}/include/pd/solver.h
${CMAKE_CURRENT_SOURCE_DIR}/include/pd/strain_constraint.h
${CMAKE_CURRENT_SOURCE_DIR}/include/pd/utils.h

# ui
${CMAKE_CURRENT_SOURCE_DIR}/include/ui/mouse_down_handler.h
Expand Down
27 changes: 26 additions & 1 deletion include/pd/solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
#include <iostream>
#include <vector>

// libigl
#include<igl/writePLY.h>

// storing data
#include <filesystem>

namespace pd {
namespace detail {

Expand Down Expand Up @@ -51,6 +57,13 @@ class solver_t
void set_dirty() { dirty_ = true; }
void set_clean() { dirty_ = false; }
bool ready() const { return !dirty_; }

bool is_experinent_set() const { return exp_set_; }

bool record_ = true;
bool collect_snapshots() { return record_; };
std::string snapshots_directory = "../../../snapshots";

void prepare(scalar_type dt)
{
dt_ = dt;
Expand Down Expand Up @@ -87,7 +100,7 @@ class solver_t
set_clean();
}

void step(Eigen::MatrixXd const& fext, int num_iterations = 10)
void step(Eigen::MatrixXd const& fext, int num_iterations = 10, int frame = 0)
{
auto const& constraints = model_->constraints();
auto& positions = model_->positions();
Expand Down Expand Up @@ -145,6 +158,16 @@ class solver_t
Eigen::MatrixXd const qn_plus_1 = detail::unflatten(q);
velocities = (qn_plus_1 - positions) * dt_inv;
positions = qn_plus_1;

if (this->collect_snapshots())
{
//std::cout << experiment;
std::filesystem::create_directory(snapshots_directory); // create directory if doesnt exist
igl::writePLY(
snapshots_directory + "/somemesh" + std::to_string(frame) + ".ply",
positions,
model_->faces());
}
}

private:
Expand All @@ -153,6 +176,8 @@ class solver_t
Eigen::SimplicialCholesky<Eigen::SparseMatrix<scalar_type>> cholesky_decomposition_;
Eigen::MatrixXd A_;
scalar_type dt_;

bool exp_set_;
};

} // namespace pd
Expand Down
12 changes: 12 additions & 0 deletions include/pd/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#include <string>
#include <sstream>
#include<iomanip>

inline std::string float_to_str(float value)
{
std::stringstream stream;
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << value;
return stream.str();
}
6 changes: 5 additions & 1 deletion include/ui/pre_draw_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ struct pre_draw_handler_t
physics_params_t* physics_params;
pd::solver_t* solver;
Eigen::MatrixX3d* fext;


pre_draw_handler_t(
std::function<bool()> is_model_ready,
physics_params_t* physics_params,
pd::solver_t* solver,
Eigen::MatrixX3d* fext)
: is_model_ready(is_model_ready), physics_params(physics_params), solver(solver), fext(fext)
: is_model_ready(is_model_ready),
physics_params(physics_params),
solver(solver),
fext(fext)
{
}

Expand Down
30 changes: 30 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "geometry/get_simple_cloth_model.h"
#include "pd/deformable_mesh.h"
#include "pd/solver.h"
#include "pd/utils.h"
#include "ui/mouse_down_handler.h"
#include "ui/mouse_move_handler.h"
#include "ui/physics_params.h"
Expand All @@ -21,13 +22,16 @@
#include <igl/writeMESH.h>
#include <igl/write_triangle_mesh.h>

#include <string>

int main(int argc, char** argv)
{
pd::deformable_mesh_t model{};
Eigen::MatrixX3d fext;
ui::picking_state_t picking_state{};
ui::physics_params_t physics_params{};
pd::solver_t solver;
//std::string experiment_name = "";

auto const is_model_ready = [&]() {
return model.positions().rows() > 0;
Expand Down Expand Up @@ -91,7 +95,11 @@ int main(int argc, char** argv)
if (ImGui::Button("Load triangle mesh", ImVec2((w - p) / 2.f, 0)))
{
std::string const filename = igl::file_dialog_open();

std::filesystem::path const mesh{filename};

//experiment_name = experiment_name + mesh.stem().u8string() + "_ tri_";

if (std::filesystem::exists(mesh) && std::filesystem::is_regular_file(mesh))
{
Eigen::MatrixXd V;
Expand All @@ -113,6 +121,9 @@ int main(int argc, char** argv)
{
std::string const filename = igl::file_dialog_open();
std::filesystem::path const mesh{filename};

//experiment_name = experiment_name + mesh.stem().u8string() + "_tet_";

if (std::filesystem::exists(mesh) && std::filesystem::is_regular_file(mesh))
{
Eigen::MatrixXd V;
Expand Down Expand Up @@ -147,6 +158,8 @@ int main(int argc, char** argv)
F.resize(1, 3);
F.row(0) = Eigen::RowVector3i{0, 1, 2};

//experiment_name = experiment_name + "to2D_";

reset_simulation_model(V, F, F, false);
}
ImGui::TreePop();
Expand All @@ -168,6 +181,7 @@ int main(int argc, char** argv)
static_cast<std::size_t>(bar_height),
static_cast<std::size_t>(bar_depth));

//experiment_name = experiment_name + "Bar_tet_";
reset_simulation_model(V, F, T, true);
}

Expand All @@ -185,6 +199,7 @@ int main(int argc, char** argv)
{
auto [V, F] = geometry::get_simple_cloth_model(cloth_width, cloth_height);

//experiment_name = experiment_name + "Cloth_tri_";
reset_simulation_model(V, F, F, true);
}

Expand All @@ -200,6 +215,7 @@ int main(int argc, char** argv)
Eigen::MatrixXi F;
Eigen::VectorXi J;
igl::decimate(model.positions(), model.faces(), max_facet_count, V, F, J);

reset_simulation_model(V, F, F);
}
ImGui::TreePop();
Expand All @@ -214,6 +230,7 @@ int main(int argc, char** argv)
viewer.core().align_camera_center(model.positions());
}
ImGui::TreePop();
//experiment_name = experiment_name + "_to3D_";
}
std::string const vertex_count = std::to_string(model.positions().rows());
std::string const element_count = std::to_string(model.elements().rows());
Expand Down Expand Up @@ -294,23 +311,36 @@ int main(int argc, char** argv)
if (is_constraint_type_active[0])
{
model.constrain_edge_lengths(physics_params.edge_constraint_wi);
/*experiment_name = experiment_name + "constrain_edge_lengths_wi" +
float_to_str(physics_params.edge_constraint_wi);*/
}
if (is_constraint_type_active[1])
{
model.constrain_deformation_gradient(
physics_params.deformation_gradient_constraint_wi);
/*experiment_name = experiment_name +
"constrain_deformation_gradient_wi" +
float_to_str(physics_params.deformation_gradient_constraint_wi);*/
}
if (is_constraint_type_active[2])
{
model.constrain_strain(
sigma_min,
sigma_max,
physics_params.strain_limit_constraint_wi);

/* experiment_name = experiment_name +
"constrain_strain_wi" +
float_to_str(physics_params.strain_limit_constraint_wi) +
"_min_" + float_to_str(sigma_min) +
"_max_" + float_to_str(sigma_max);*/
}
}
std::string const constraint_count = std::to_string(model.constraints().size());
ImGui::BulletText(std::string("Constraints: " + constraint_count).c_str());
ImGui::TreePop();

//experiment_name = experiment_name + "Constraints: " + constraint_count;
}
ImGui::InputFloat("Timestep", &physics_params.dt, 0.01f, 0.1f, "%.4f");
ImGui::InputInt("Solver iterations", &physics_params.solver_iterations);
Expand Down
6 changes: 5 additions & 1 deletion src/ui/pre_draw_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace ui {

unsigned int frame_count = 1;
bool pre_draw_handler_t::operator()(igl::opengl::glfw::Viewer& viewer)
{
pd::deformable_mesh_t* model = solver->model();


if (!is_model_ready())
return false;
Expand Down Expand Up @@ -36,7 +38,9 @@ bool pre_draw_handler_t::operator()(igl::opengl::glfw::Viewer& viewer)
solver->prepare(physics_params->dt);
}

solver->step(*fext, physics_params->solver_iterations);
solver->step(*fext, physics_params->solver_iterations, frame_count);

frame_count++;

fext->setZero();
viewer.data().clear();
Expand Down