| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) Blender Foundation | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							| 
									
										
										
										
											2020-11-06 01:41:31 -05:00
										 |  |  |  * \ingroup sim | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 17:00:54 +01:00
										 |  |  | #if defined(__GNUC__) && !defined(__clang__)
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  | #  pragma GCC diagnostic push
 | 
					
						
							|  |  |  | /* XXX suppress verbose warnings in eigen */ | 
					
						
							|  |  |  | #  pragma GCC diagnostic ignored "-Wlogical-op"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Eigen/Sparse>
 | 
					
						
							|  |  |  | #include <Eigen/src/Core/util/DisableStupidWarnings.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __GNUC__
 | 
					
						
							|  |  |  | #  pragma GCC diagnostic pop
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-06 16:45:06 +01:00
										 |  |  | #include "implicit.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef float Scalar; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* slightly extended Eigen vector class
 | 
					
						
							|  |  |  |  * with conversion to/from plain C float array | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | class Vector3 : public Eigen::Vector3f { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  public: | 
					
						
							|  |  |  |   typedef float *ctype; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   Vector3() | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   Vector3(const ctype &v) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |       coeffRef(k) = v[k]; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 08:15:25 +11:00
										 |  |  |   Vector3 &operator=(const ctype &v) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |       coeffRef(k) = v[k]; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   operator ctype() | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return data(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* slightly extended Eigen matrix class
 | 
					
						
							|  |  |  |  * with conversion to/from plain C float array | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | class Matrix3 : public Eigen::Matrix3f { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  public: | 
					
						
							|  |  |  |   typedef float (*ctype)[3]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   Matrix3() | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   Matrix3(const ctype &v) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							|  |  |  |       for (int l = 0; l < 3; l++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |         coeffRef(l, k) = v[k][l]; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 08:15:25 +11:00
										 |  |  |   Matrix3 &operator=(const ctype &v) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							|  |  |  |       for (int l = 0; l < 3; l++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |         coeffRef(l, k) = v[k][l]; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   operator ctype() | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return (ctype)data(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | typedef Eigen::VectorXf lVector; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  | /* Extension of dense Eigen vectors,
 | 
					
						
							|  |  |  |  * providing 3-float block access for blenlib math functions | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | class lVector3f : public Eigen::VectorXf { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  public: | 
					
						
							|  |  |  |   typedef Eigen::VectorXf base_t; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   lVector3f() | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 08:15:25 +11:00
										 |  |  |   template<typename T> lVector3f &operator=(T rhs) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     base_t::operator=(rhs); | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 08:15:25 +11:00
										 |  |  |   float *v3(int vertex) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     return &coeffRef(3 * vertex); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 08:15:25 +11:00
										 |  |  |   const float *v3(int vertex) const | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     return &coeffRef(3 * vertex); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef Eigen::Triplet<Scalar> Triplet; | 
					
						
							|  |  |  | typedef std::vector<Triplet> TripletList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef Eigen::SparseMatrix<Scalar> lMatrix; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Constructor type that provides more convenient handling of Eigen triplets
 | 
					
						
							|  |  |  |  * for efficient construction of sparse 3x3 block matrices. | 
					
						
							| 
									
										
										
										
											2019-04-30 14:41:33 +10:00
										 |  |  |  * This should be used for building lMatrix instead of writing to such lMatrix directly (which is | 
					
						
							|  |  |  |  * very inefficient). After all elements have been defined using the set() method, the actual | 
					
						
							|  |  |  |  * matrix can be filled using construct(). | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | struct lMatrix3fCtor { | 
					
						
							|  |  |  |   lMatrix3fCtor() | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   void reset() | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_trips.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   void reserve(int numverts) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* reserve for diagonal entries */ | 
					
						
							|  |  |  |     m_trips.reserve(numverts * 9); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   void add(int i, int j, const Matrix3 &m) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     i *= 3; | 
					
						
							|  |  |  |     j *= 3; | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							|  |  |  |       for (int l = 0; l < 3; l++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |         m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k))); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  |   void sub(int i, int j, const Matrix3 &m) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     i *= 3; | 
					
						
							|  |  |  |     j *= 3; | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int k = 0; k < 3; k++) { | 
					
						
							|  |  |  |       for (int l = 0; l < 3; l++) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |         m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k))); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |   inline void construct(lMatrix &m) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m.setFromTriplets(m_trips.begin(), m_trips.end()); | 
					
						
							|  |  |  |     m_trips.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |  private: | 
					
						
							|  |  |  |   TripletList m_trips; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar>> | 
					
						
							|  |  |  |     ConjugateGradient; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using Eigen::ComputationInfo; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-08 18:45:28 +01:00
										 |  |  | BLI_INLINE void print_lvector(const lVector3f &v) | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |   for (int i = 0; i < v.rows(); i++) { | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     if (i > 0 && i % 3 == 0) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |       printf("\n"); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |     printf("%f,\n", v[i]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BLI_INLINE void print_lmatrix(const lMatrix &m) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |   for (int j = 0; j < m.rows(); j++) { | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     if (j > 0 && j % 3 == 0) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |       printf("\n"); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-08 00:12:26 +10:00
										 |  |  |     for (int i = 0; i < m.cols(); i++) { | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       if (i > 0 && i % 3 == 0) { | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |         printf("  "); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 15:14:43 +01:00
										 |  |  |       implicit_print_matrix_elem(m.coeff(j, i)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     printf("\n"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |