9#ifdef IMPLICIT_SOLVER_EIGEN
12# define USE_EIGEN_CONSTRAINED_CG
15# pragma GCC diagnostic push
20# ifndef IMPLICIT_ENABLE_EIGEN_DEBUG
22# define IMPLICIT_NDEBUG
27# include <Eigen/Sparse>
28# include <Eigen/src/Core/util/DisableStupidWarnings.h>
30# ifdef USE_EIGEN_CONSTRAINED_CG
34# ifndef IMPLICIT_ENABLE_EIGEN_DEBUG
35# ifndef IMPLICIT_NDEBUG
38# undef IMPLICIT_NDEBUG
43# pragma GCC diagnostic pop
67static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
72class fVector :
public Eigen::Vector3f {
78 fVector(
const ctype &
v)
80 for (
int k = 0; k < 3; k++) {
87 for (
int k = 0; k < 3; k++) {
102class fMatrix :
public Eigen::Matrix3f {
104 typedef float (*ctype)[3];
108 fMatrix(
const ctype &
v)
110 for (
int k = 0; k < 3; k++) {
111 for (
int l = 0;
l < 3;
l++) {
112 coeffRef(
l, k) =
v[k][
l];
119 for (
int k = 0; k < 3; k++) {
120 for (
int l = 0;
l < 3;
l++) {
121 coeffRef(
l, k) =
v[k][
l];
129 return (ctype)
data();
136class lVector :
public Eigen::VectorXf {
138 typedef Eigen::VectorXf base_t;
144 base_t::operator=(
rhs);
148 float *v3(
int vertex)
150 return &coeffRef(3 * vertex);
153 const float *v3(
int vertex)
const
155 return &coeffRef(3 * vertex);
159typedef Eigen::Triplet<Scalar>
Triplet;
162typedef Eigen::SparseMatrix<Scalar>
lMatrix;
178 void reserve(
int numverts)
181 m_trips.reserve(numverts * 9);
184 void add(
int i,
int j,
const fMatrix &m)
188 for (
int k = 0; k < 3; k++) {
189 for (
int l = 0;
l < 3;
l++) {
190 m_trips.push_back(
Triplet(
i + k, j +
l, m.coeff(
l, k)));
195 void sub(
int i,
int j,
const fMatrix &m)
199 for (
int k = 0; k < 3; k++) {
200 for (
int l = 0;
l < 3;
l++) {
201 m_trips.push_back(
Triplet(
i + k, j +
l, -m.coeff(
l, k)));
206 inline void construct(
lMatrix &m)
208 m.setFromTriplets(m_trips.begin(), m_trips.end());
216# ifdef USE_EIGEN_CORE
217typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar>>
220# ifdef USE_EIGEN_CONSTRAINED_CG
224 Eigen::DiagonalPreconditioner<Scalar>>
227using Eigen::ComputationInfo;
231 for (
int i = 0;
i <
v.rows();
i++) {
232 if (
i > 0 &&
i % 3 == 0) {
242 for (
int j = 0; j < m.rows(); j++) {
243 if (j > 0 && j % 3 == 0) {
247 for (
int i = 0;
i < m.cols();
i++) {
248 if (
i > 0 &&
i % 3 == 0) {
260 m.reserve(Eigen::VectorXi::Constant(m.cols(),
num));
265 return v.data() + 3 * vertex;
270 return v.data() + 3 * vertex;
278 for (
int l = 0;
l < 3;
l++) {
279 for (
int k = 0; k < 3; k++) {
280 tlist.push_back(
Triplet(
i + k, j +
l, m[k][
l]));
289 for (
int l = 0;
l < 3;
l++) {
290 for (
int k = 0; k < 3; k++) {
291 tlist.push_back(
Triplet(
i + k, j +
l, m[k][
l] * factor));
299 t.setFromTriplets(tlist.begin(), tlist.end());
306 t.setFromTriplets(tlist.begin(), tlist.end());
313 t.setFromTriplets(tlist.begin(), tlist.end());
347 r[0][0] += m[0][0] * f;
348 r[0][1] += m[0][1] * f;
349 r[0][2] += m[0][2] * f;
350 r[1][0] += m[1][0] * f;
351 r[1][1] += m[1][1] * f;
352 r[1][2] += m[1][2] * f;
353 r[2][0] += m[2][0] * f;
354 r[2][1] += m[2][1] * f;
355 r[2][2] += m[2][2] * f;
360 r[0][0] = a[0][0] +
b[0][0] * f;
361 r[0][1] = a[0][1] +
b[0][1] * f;
362 r[0][2] = a[0][2] +
b[0][2] * f;
363 r[1][0] = a[1][0] +
b[1][0] * f;
364 r[1][1] = a[1][1] +
b[1][1] * f;
365 r[1][2] = a[1][2] +
b[1][2] * f;
366 r[2][0] = a[2][0] +
b[2][0] * f;
367 r[2][1] = a[2][1] +
b[2][1] * f;
368 r[2][2] = a[2][2] +
b[2][2] * f;
372 typedef std::vector<fMatrix> fMatrixVector;
374 Implicit_Data(
int numverts)
379 void resize(
int numverts)
381 this->numverts = numverts;
382 int tot = 3 * numverts;
386 dFdX.resize(tot, tot);
387 dFdV.resize(tot, tot);
389 tfm.resize(numverts,
I);
403 iM.reserve(numverts);
404 idFdX.reserve(numverts);
405 idFdV.reserve(numverts);
406 iS.reserve(numverts);
432 lMatrixCtor idFdX, idFdV;
489# ifdef USE_EIGEN_CORE
492# ifdef USE_EIGEN_CONSTRAINED_CG
493 typedef ConstraintConjGrad solver_t;
502 cg.setMaxIterations(100);
503 cg.setTolerance(0.01f);
505# ifdef USE_EIGEN_CONSTRAINED_CG
506 cg.filter() =
data->S;
514# ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
525# ifdef USE_EIGEN_CORE
528# ifdef USE_EIGEN_CONSTRAINED_CG
532# ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
544 case Eigen::NoConvergence:
547 case Eigen::InvalidInput:
550 case Eigen::NumericalIssue:
555 result->iterations = cg.iterations();
556 result->error = cg.error();
558 return cg.info() == Eigen::Success;
580 data->iM.add(index, index, m);
585# ifdef CLOTH_ROOT_FRAME
642 int numverts =
data->numverts;
643 for (
int i = 0;
i < numverts;
i++) {
651 data->iS.sub(index, index,
I);
657 Implicit_Data *
data,
int index,
const float c1[3],
const float c2[3],
const float dV[3])
659 float m[3][3], p[3], q[3], u[3], cmat[3][3];
670 data->iS.sub(index, index, m);
682 float m[3][3], p[3], u[3], cmat[3][3];
688 data->iS.sub(index, index, m);
698 data->dFdX.setZero();
699 data->dFdV.setZero();
704 const float acceleration[3],
705 const float omega[3],
706 const float domega_dt[3],
709# ifdef CLOTH_ROOT_FRAME
710 float acc[3],
w[3], dwdt[3];
711 float f[3], dfdx[3][3], dfdv[3][3];
712 float euler[3], coriolis[3], centrifugal[3], rotvel[3];
713 float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
746 data->idFdX.add(index, index, dfdx);
747 data->idFdV.add(index, index, dfdv);
769 int numverts =
data->numverts;
770 for (
int i = 0;
i < numverts;
i++) {
778 data->idFdV.add(
i,
i, tmp);
783 struct Implicit_Data *
data,
int i,
const float f[3],
float dfdx[3][3],
float dfdv[3][3])
785 float tf[3], tdfdx[3][3], tdfdv[3][3];
791 data->idFdX.add(
i,
i, tdfdx);
792 data->idFdV.add(
i,
i, tdfdv);
814 const float effector_scale = 0.02f;
815 float win[3],
nor[3], area;
820 factor = effector_scale * area / 3.0f;
834 const float effector_scale = 0.01;
888 return (-11.541f *
powf(
x, 4) + 34.193f *
powf(
x, 3) - 39.083f *
powf(
x, 2) + 23.116f *
x -
896 return (-46.164f *
powf(
x, 3) + 102.579f *
powf(
x, 2) - 78.166f *
x + 23.116f);
902 float fbstar_fl = cb * (
length -
L);
904 if (tempfb_fl < fbstar_fl) {
916 float fbstar_fl = cb * (
length -
L);
918 if (tempfb_fl < fbstar_fl) {
937 *r_length =
len_v3(r_extent);
942 if ((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) &&
943 (((
length -
L) * 100.0f /
L) > clmd->sim_parms->maxspringlen))
946 s->flags |= CSPRING_FLAG_DEACTIVATE;
961 Implicit_Data *
data,
int i,
int j,
const float f[3],
float dfdx[3][3],
float dfdv[3][3])
966 data->idFdX.add(
i,
i, dfdx);
967 data->idFdX.add(j, j, dfdx);
968 data->idFdX.sub(
i, j, dfdx);
969 data->idFdX.sub(j,
i, dfdx);
971 data->idFdV.add(
i,
i, dfdv);
972 data->idFdV.add(j, j, dfdv);
973 data->idFdV.sub(
i, j, dfdv);
974 data->idFdV.sub(j,
i, dfdv);
989 float extent[3],
length, dir[3], vel[3];
994 if (
length > restlen || no_compress) {
995 float stretch_force, f[3], dfdx[3][3], dfdv[3][3];
997 stretch_force = stiffness * (
length - restlen);
998 if (clamp_force > 0.0f && stretch_force > clamp_force) {
999 stretch_force = clamp_force;
1050 float extent[3],
length, dir[3], vel[3];
1056 float f[3], dfdx[3][3], dfdv[3][3];
1102 Implicit_Data *
data,
int i,
int j,
float edge[3],
float dir[3],
float grad_dir[3][3])
1123 const float goal[3],
1131 float edge_ij[3], dir_ij[3];
1132 float edge_jk[3], dir_jk[3];
1133 float vel_ij[3], vel_jk[3], vel_ortho[3];
1134 float f_bend[3], f_damp[3];
1194 const float goal[3],
1200 const float delta = 0.00001f;
1201 float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
1213 for (a = 0; a < 3; a++) {
1214 spring_angbend_forces(
1215 data,
i, j, k, goal, stiffness, damping, q, dvec_pos[a], dvec_null[a], f);
1218 spring_angbend_forces(
1219 data,
i, j, k, goal, stiffness, damping, q, dvec_neg[a], dvec_null[a], f);
1222 for (
b = 0;
b < 3;
b++) {
1223 dfdx[a][
b] /= delta;
1233 const float goal[3],
1239 const float delta = 0.00001f;
1240 float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
1252 for (a = 0; a < 3; a++) {
1253 spring_angbend_forces(
1254 data,
i, j, k, goal, stiffness, damping, q, dvec_null[a], dvec_pos[a], f);
1257 spring_angbend_forces(
1258 data,
i, j, k, goal, stiffness, damping, q, dvec_null[a], dvec_neg[a], f);
1261 for (
b = 0;
b < 3;
b++) {
1262 dfdv[a][
b] /= delta;
1274 const float target[3],
1280 float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
1281 float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
1283 const float vecnull[3] = {0.0f, 0.0f, 0.0f};
1287 spring_angbend_forces(
data,
i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
1290 spring_angbend_estimate_dfdx(
data,
i, j, k, goal, stiffness, damping,
i, dfk_dxi);
1291 spring_angbend_estimate_dfdx(
data,
i, j, k, goal, stiffness, damping, j, dfk_dxj);
1292 spring_angbend_estimate_dfdx(
data,
i, j, k, goal, stiffness, damping, k, dfk_dxk);
1298 spring_angbend_estimate_dfdv(
data,
i, j, k, goal, stiffness, damping,
i, dfk_dvi);
1299 spring_angbend_estimate_dfdv(
data,
i, j, k, goal, stiffness, damping, j, dfk_dvj);
1300 spring_angbend_estimate_dfdv(
data,
i, j, k, goal, stiffness, damping, k, dfk_dvk);
1311 data->idFdX.add(j, j, dfj_dxj);
1312 data->idFdX.add(k, k, dfk_dxk);
1314 data->idFdX.add(
i, j, dfj_dxi);
1315 data->idFdX.add(j,
i, dfj_dxi);
1316 data->idFdX.add(j, k, dfk_dxj);
1317 data->idFdX.add(k, j, dfk_dxj);
1318 data->idFdX.add(
i, k, dfk_dxi);
1319 data->idFdX.add(k,
i, dfk_dxi);
1321 data->idFdV.add(j, j, dfj_dvj);
1322 data->idFdV.add(k, k, dfk_dvk);
1324 data->idFdV.add(
i, j, dfj_dvi);
1325 data->idFdV.add(j,
i, dfj_dvi);
1326 data->idFdV.add(j, k, dfk_dvj);
1327 data->idFdV.add(k, j, dfk_dvj);
1328 data->idFdV.add(
i, k, dfk_dvi);
1329 data->idFdV.add(k,
i, dfk_dvi);
1336 float edge_ij[3], dir_ij[3], grad_dir_ij[3][3];
1337 float edge_jk[3], dir_jk[3], grad_dir_jk[3][3];
1338 float dist[3], vel_jk[3], vel_jk_ortho[3], projvel[3];
1341 float fi[3], fj[3], fk[3];
1342 float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
1384 madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
1386 madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
1423 const float goal_x[3],
1424 const float goal_v[3],
1431 float root_goal_x[3], root_goal_v[3], extent[3],
length, dir[3], vel[3];
1432 float f[3], dfdx[3][3], dfdv[3][3];
1453 data->idFdX.add(
i,
i, dfdx);
1454 data->idFdV.add(
i,
i, dfdv);
void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void negate_m3(float R[3][3])
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void unit_m3(float m[3][3])
void mul_m3_fl(float R[3][3], float f)
void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void zero_m3(float m[3][3])
void madd_m3_m3m3fl(float R[3][3], const float A[3][3], const float B[3][3], float f)
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void transpose_m3(float R[3][3])
void mul_transposed_m3_v3(const float M[3][3], float r[3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
ATTR_WARN_UNUSED_RESULT const size_t num
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
int SIM_mass_spring_solver_numvert(struct Implicit_Data *id)
@ SIM_SOLVER_INVALID_INPUT
@ SIM_SOLVER_NUMERICAL_ISSUE
@ SIM_SOLVER_NO_CONVERGENCE
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
btGeneric6DofConstraint & operator=(btGeneric6DofConstraint &other)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void reset()
clear internal cached data and reset random seed
A conjugate gradient solver for sparse self-adjoint problems with additional constraints.
BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
std::vector< Triplet > TripletList
Eigen::ConjugateGradient< lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner< Scalar > > ConjugateGradient
BLI_INLINE void print_lmatrix(const lMatrix &m)
Eigen::Triplet< Scalar > Triplet
Eigen::SparseMatrix< Scalar > lMatrix
BLI_INLINE void print_lvector(const lVector3f &v)
float length(VecOp< float, D >) RET
void SIM_mass_spring_add_constraint_ndof1(struct Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
void SIM_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3])
void SIM_mass_spring_add_constraint_ndof0(struct Implicit_Data *data, int index, const float dV[3])
void SIM_mass_spring_force_reference_frame(struct Implicit_Data *data, int index, const float acceleration[3], const float omega[3], const float domega_dt[3], float mass)
void SIM_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float(*winvec)[3])
void SIM_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
bool SIM_mass_spring_force_spring_goal(struct Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3], float stiffness, float damping)
void SIM_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass)
void SIM_mass_spring_set_motion_state(struct Implicit_Data *data, int index, const float x[3], const float v[3])
bool SIM_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, float restlen, float stiffness_tension, float damping_tension, float stiffness_compression, float damping_compression, bool resist_compress, bool new_compress, float clamp_force)
bool SIM_mass_spring_force_spring_bending(struct Implicit_Data *data, int i, int j, float restlen, float kb, float cb)
void SIM_mass_spring_apply_result(struct Implicit_Data *data)
void SIM_mass_spring_set_position(struct Implicit_Data *data, int index, const float x[3])
void SIM_mass_spring_add_constraint_ndof2(struct Implicit_Data *data, int index, const float c1[3], const float dV[3])
BLI_INLINE void implicit_print_matrix_elem(float v)
void SIM_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, const float(*winvec)[3])
void SIM_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
bool SIM_mass_spring_solve_velocities(struct Implicit_Data *data, float dt, struct ImplicitSolverResult *result)
void SIM_mass_spring_force_drag(struct Implicit_Data *data, float drag)
void SIM_mass_spring_clear_constraints(struct Implicit_Data *data)
bool SIM_mass_spring_solve_positions(struct Implicit_Data *data, float dt)
void SIM_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
void SIM_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3])
void SIM_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
void SIM_mass_spring_force_gravity(struct Implicit_Data *data, int index, float mass, const float g[3])
void SIM_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float tfm[3][3])
void SIM_mass_spring_clear_forces(struct Implicit_Data *data)
BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3], const float dfdx[3][3], const float dfdv[3][3])
BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
Implicit_Data * SIM_mass_spring_solver_create(int numverts, int numsprings)
DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3])
BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3])
BLI_INLINE float fb(float length, float L)
DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
BLI_INLINE float fbderiv(float length, float L)
BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[3], float r_dir[3], float *r_length, float r_vel[3])
BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], const float m[3][3])
void SIM_mass_spring_solver_free(Implicit_Data *id)
BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], const float matrixA[3][3], const float matrixB[3][3])
BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], const float m[3][3])
BLI_INLINE float fbstar(float length, float L, float kb, float cb)
BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)