9#include <ipc/utils/eigen_ext.hpp>
13 using namespace utils;
41 const Eigen::MatrixXd &vertices,
42 const Eigen::VectorXi &codim_vertices,
43 const Eigen::MatrixXi &codim_edges,
44 const Eigen::MatrixXi &
faces)
46 if (vertices.size() == 0)
50 dim_ = vertices.cols();
51 assert(
dim_ == vertices.cols());
53 if (codim_vertices.size())
56 codim_v_.tail(codim_vertices.size()) = codim_vertices.array() +
v_.rows();
58 in_v_.conservativeResize(
in_v_.size() + codim_vertices.size());
59 in_v_.tail(codim_vertices.size()) = codim_vertices.array() +
v_.rows();
62 if (codim_edges.size())
64 e_.conservativeResize(
e_.rows() + codim_edges.rows(), 2);
65 e_.bottomRows(codim_edges.rows()) = codim_edges.array() +
v_.rows();
67 in_e_.conservativeResize(
in_e_.rows() + codim_edges.rows(), 2);
68 in_e_.bottomRows(codim_edges.rows()) = codim_edges.array() +
v_.rows();
73 f_.conservativeResize(
f_.rows() +
faces.rows(), 3);
79 Eigen::MatrixXi edges;
80 igl::edges(
faces, edges);
82 e_.conservativeResize(
e_.rows() + edges.rows(), 2);
83 e_.bottomRows(edges.rows()) = edges.array() +
v_.rows();
85 else if (
faces.size())
90 v_.conservativeResize(
v_.rows() + vertices.rows(),
dim_);
91 v_.bottomRows(vertices.rows()) = vertices;
97 const Eigen::MatrixXd &vertices,
98 const Eigen::VectorXi &codim_vertices,
99 const Eigen::MatrixXi &codim_edges,
100 const Eigen::MatrixXi &
faces,
101 const json &displacement,
102 const std::string &root_path)
107 for (
size_t d = 0; d <
dim_; ++d)
109 assert(displacement[
"value"].is_array());
110 displacements_.back().value[d].init(displacement[
"value"][d], root_path);
113 if (displacement.contains(
"interpolation"))
115 if (displacement[
"interpolation"].is_array())
117 for (
int ii = 0; ii < displacement[
"interpolation"].size(); ++ii)
126 const std::vector<Eigen::MatrixXd> &vertices,
127 const Eigen::VectorXi &codim_vertices,
128 const Eigen::MatrixXi &codim_edges,
129 const Eigen::MatrixXi &
faces,
132 if (vertices.size() == 0 || vertices[0].size() == 0)
137 std::array<std::vector<Eigen::MatrixXd>, 3> displacements_xyz;
138 for (
size_t i = 0; i < vertices.size(); ++i)
140 Eigen::MatrixXd displacement = vertices[i] - vertices[0];
141 for (
size_t d = 0; d <
dim_; ++d)
142 displacements_xyz[d].push_back(displacement.col(d));
146 for (
size_t d = 0; d <
dim_; ++d)
148 const std::vector<Eigen::MatrixXd> displacements = displacements_xyz[d];
150 [displacements, fps](
double x,
double y,
double z,
double t,
int index) ->
double {
151 const double frame = t * fps;
152 const double interp = frame - floor(frame);
153 const int frame0 = (int)floor(frame);
154 const int frame1 = (int)ceil(frame);
155 if (frame1 >= displacements.size())
156 return displacements.back()(index);
157 const double u0 = displacements[frame0](index);
158 const double u1 = displacements[frame1](index);
159 return (u1 - u0) * interp + u0;
167 dim_ = origin.size();
168 assert(normal.size() >=
dim_);
169 assert(origin.size() >=
dim_);
170 planes_.emplace_back(origin.head(
dim_), normal.head(
dim_).normalized());
192 for (
size_t k = 0; k <
val.size(); ++k)
199 void Obstacle::change_displacement(
const int oid,
const std::function<Eigen::MatrixXd(
double x,
double y,
double z,
double t)> &func,
const std::shared_ptr<Interpolation> &interp)
214 for (
size_t k = 0; k <
val.size(); ++k)
224 const int offset = sol.rows() -
v_.rows() * (sol.cols() == 1 ?
dim_ : 1);
228 for (
int k = 0; k <
endings_.size(); ++k)
233 for (
int i = start; i < to; ++i)
235 for (
int d = 0; d <
dim_; ++d)
237 const int sol_row = sol.cols() == 1 ? (offset + i *
dim_ + d) : (offset + i);
238 const int sol_col = sol.cols() == 1 ? 0 : d;
239 sol(sol_row, sol_col) = disp.eval(
v_.row(i), d, t, i - start);
245 assert(
endings_.empty() || (start * (sol.cols() == 1 ?
dim_ : 1) + offset) == sol.rows());
251 sol.bottomRows(
v_.rows() * (sol.cols() == 1 ?
dim_ : 1)).setZero();
258 d.set_unit_type(units.
length());
264 constexpr int size_x = 10;
265 constexpr int size_y = 10;
271 vis_v_.resize(size_x + 1, 2);
272 for (
int x = 0;
x <= size_x; ++
x)
274 vis_v_.row(
x) = (
x - size_x / 2.0) * tangent;
278 for (
int x = 0;
x < size_x; ++
x)
289 const Eigen::Vector3d cross_x = Eigen::Vector3d::UnitX().cross(
normal);
290 const Eigen::Vector3d cross_y = Eigen::Vector3d::UnitY().cross(
normal);
292 Eigen::Vector3d tangent_x, tangent_y;
293 if (cross_x.squaredNorm() > cross_y.squaredNorm())
295 tangent_x = cross_x.normalized();
296 tangent_y =
normal.cross(cross_x).normalized();
300 tangent_x = cross_y.normalized();
301 tangent_y =
normal.cross(cross_y).normalized();
304 vis_v_.resize((size_x + 1) * (size_y + 1), 3);
305 for (
int x = 0;
x <= size_x; ++
x)
307 for (
int y = 0;
y <= size_y; ++
y)
309 vis_v_.row(
x * size_y +
y) = (
x - size_x / 2.0) * tangent_x + (
y - size_y / 2.0) * tangent_y;
313 vis_f_.resize(2 * size_x * size_y, 3);
314 for (
int x = 0;
x < size_x; ++
x)
316 for (
int y = 0;
y < size_y; ++
y)
318 vis_f_.row(2 * (
x * size_x +
y)) <<
x * size_x +
y,
x * size_x +
y + 1, (
x + 1) * size_x +
y;
319 vis_f_.row(2 * (
x * size_x +
y) + 1) <<
x * size_x +
y + 1, (
x + 1) * size_x + (
y + 1), (
x + 1) * size_x +
y;
std::vector< Eigen::VectorXi > faces
const std::string & length() const
void construct_vis_mesh()
const VectorNd & normal() const
std::vector< Plane > planes_
void change_displacement(const int oid, const Eigen::RowVector3d &val, const std::shared_ptr< utils::Interpolation > &interp=std::make_shared< utils::NoInterpolation >())
void append_mesh(const Eigen::MatrixXd &vertices, const Eigen::VectorXi &codim_vertices, const Eigen::MatrixXi &codim_edges, const Eigen::MatrixXi &faces, const json &displacement, const std::string &root_path)
void append_plane(const VectorNd &point, const VectorNd &normal)
void set_zero(Eigen::MatrixXd &sol) const
void append_mesh_sequence(const std::vector< Eigen::MatrixXd > &vertices, const Eigen::VectorXi &codim_vertices, const Eigen::MatrixXi &codim_edges, const Eigen::MatrixXi &faces, const int fps)
void update_displacement(const double t, Eigen::MatrixXd &sol) const
void set_units(const Units &units)
std::vector< assembler::TensorBCValue > displacements_
std::vector< int > endings_
static std::shared_ptr< Interpolation > build(const json ¶ms)
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, 3, 1 > VectorNd
void log_and_throw_error(const std::string &msg)