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)
106 for (
size_t d = 0; d <
dim_; ++d)
108 assert(displacement[
"value"].is_array());
112 if (displacement.contains(
"interpolation"))
114 if (displacement[
"interpolation"].is_array())
116 for (
int ii = 0; ii < displacement[
"interpolation"].size(); ++ii)
125 const std::vector<Eigen::MatrixXd> &vertices,
126 const Eigen::VectorXi &codim_vertices,
127 const Eigen::MatrixXi &codim_edges,
128 const Eigen::MatrixXi &
faces,
131 if (vertices.size() == 0 || vertices[0].size() == 0)
136 std::array<std::vector<Eigen::MatrixXd>, 3> displacements_xyz;
137 for (
size_t i = 0; i < vertices.size(); ++i)
139 Eigen::MatrixXd displacement = vertices[i] - vertices[0];
140 for (
size_t d = 0; d <
dim_; ++d)
141 displacements_xyz[d].push_back(displacement.col(d));
145 for (
size_t d = 0; d <
dim_; ++d)
147 const std::vector<Eigen::MatrixXd> displacements = displacements_xyz[d];
149 [displacements, fps](
double x,
double y,
double z,
double t,
int index) ->
double {
150 const double frame = t * fps;
151 const double interp = frame - floor(frame);
152 const int frame0 = (int)floor(frame);
153 const int frame1 = (int)ceil(frame);
154 if (frame1 >= displacements.size())
155 return displacements.back()(index);
156 const double u0 = displacements[frame0](index);
157 const double u1 = displacements[frame1](index);
158 return (u1 - u0) * interp + u0;
166 dim_ = origin.size();
167 assert(normal.size() >=
dim_);
168 assert(origin.size() >=
dim_);
169 planes_.emplace_back(origin.head(
dim_), normal.head(
dim_).normalized());
187 for (
size_t k = 0; k <
val.size(); ++k)
194 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)
205 for (
size_t k = 0; k <
val.size(); ++k)
215 const int offset = sol.rows() -
v_.rows() * (sol.cols() == 1 ?
dim_ : 1);
219 for (
int k = 0; k <
endings_.size(); ++k)
224 for (
int i = start; i < to; ++i)
226 for (
int d = 0; d <
dim_; ++d)
228 const int sol_row = sol.cols() == 1 ? (offset + i *
dim_ + d) : (offset + i);
229 const int sol_col = sol.cols() == 1 ? 0 : d;
230 sol(sol_row, sol_col) = disp.eval(
v_.row(i), d, t, i - start);
236 assert(
endings_.empty() || (start * (sol.cols() == 1 ?
dim_ : 1) + offset) == sol.rows());
242 sol.bottomRows(
v_.rows() * (sol.cols() == 1 ?
dim_ : 1)).setZero();
249 d.set_unit_type(units.
length());
255 constexpr int size_x = 10;
256 constexpr int size_y = 10;
262 vis_v_.resize(size_x + 1, 2);
263 for (
int x = 0;
x <= size_x; ++
x)
265 vis_v_.row(
x) = (
x - size_x / 2.0) * tangent;
269 for (
int x = 0;
x < size_x; ++
x)
280 const Eigen::Vector3d cross_x = Eigen::Vector3d::UnitX().cross(
normal);
281 const Eigen::Vector3d cross_y = Eigen::Vector3d::UnitY().cross(
normal);
283 Eigen::Vector3d tangent_x, tangent_y;
284 if (cross_x.squaredNorm() > cross_y.squaredNorm())
286 tangent_x = cross_x.normalized();
287 tangent_y =
normal.cross(cross_x).normalized();
291 tangent_x = cross_y.normalized();
292 tangent_y =
normal.cross(cross_y).normalized();
295 vis_v_.resize((size_x + 1) * (size_y + 1), 3);
296 for (
int x = 0;
x <= size_x; ++
x)
298 for (
int y = 0;
y <= size_y; ++
y)
300 vis_v_.row(
x * size_y +
y) = (
x - size_x / 2.0) * tangent_x + (
y - size_y / 2.0) * tangent_y;
304 vis_f_.resize(2 * size_x * size_y, 3);
305 for (
int x = 0;
x < size_x; ++
x)
307 for (
int y = 0;
y < size_y; ++
y)
309 vis_f_.row(2 * (
x * size_x +
y)) <<
x * size_x +
y,
x * size_x +
y + 1, (
x + 1) * size_x +
y;
310 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_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 append_mesh(const Eigen::MatrixXd &vertices, const Eigen::VectorXi &codim_vertices, const Eigen::MatrixXi &codim_edges, const Eigen::MatrixXi &faces, const json &displacement)
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)