Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/simulation/intern/eigen_utils.h')
-rw-r--r--source/blender/simulation/intern/eigen_utils.h236
1 files changed, 236 insertions, 0 deletions
diff --git a/source/blender/simulation/intern/eigen_utils.h b/source/blender/simulation/intern/eigen_utils.h
new file mode 100644
index 00000000000..c186cf567df
--- /dev/null
+++ b/source/blender/simulation/intern/eigen_utils.h
@@ -0,0 +1,236 @@
+/*
+ * 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.
+ */
+
+#ifndef __EIGEN_UTILS_H__
+#define __EIGEN_UTILS_H__
+
+/** \file
+ * \ingroup bph
+ */
+
+#if defined(__GNUC__) && !defined(__clang__)
+# 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"
+#include "implicit.h"
+
+typedef float Scalar;
+
+/* slightly extended Eigen vector class
+ * with conversion to/from plain C float array
+ */
+class Vector3 : public Eigen::Vector3f {
+ public:
+ typedef float *ctype;
+
+ Vector3()
+ {
+ }
+
+ Vector3(const ctype &v)
+ {
+ for (int k = 0; k < 3; k++) {
+ coeffRef(k) = v[k];
+ }
+ }
+
+ Vector3 &operator=(const ctype &v)
+ {
+ for (int k = 0; k < 3; k++) {
+ coeffRef(k) = v[k];
+ }
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return data();
+ }
+};
+
+/* slightly extended Eigen matrix class
+ * with conversion to/from plain C float array
+ */
+class Matrix3 : public Eigen::Matrix3f {
+ public:
+ typedef float (*ctype)[3];
+
+ Matrix3()
+ {
+ }
+
+ Matrix3(const ctype &v)
+ {
+ for (int k = 0; k < 3; k++) {
+ for (int l = 0; l < 3; l++) {
+ coeffRef(l, k) = v[k][l];
+ }
+ }
+ }
+
+ Matrix3 &operator=(const ctype &v)
+ {
+ for (int k = 0; k < 3; k++) {
+ for (int l = 0; l < 3; l++) {
+ coeffRef(l, k) = v[k][l];
+ }
+ }
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return (ctype)data();
+ }
+};
+
+typedef Eigen::VectorXf lVector;
+
+/* Extension of dense Eigen vectors,
+ * providing 3-float block access for blenlib math functions
+ */
+class lVector3f : public Eigen::VectorXf {
+ public:
+ typedef Eigen::VectorXf base_t;
+
+ lVector3f()
+ {
+ }
+
+ template<typename T> lVector3f &operator=(T rhs)
+ {
+ base_t::operator=(rhs);
+ return *this;
+ }
+
+ float *v3(int vertex)
+ {
+ return &coeffRef(3 * vertex);
+ }
+
+ const float *v3(int vertex) const
+ {
+ 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.
+ * 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().
+ */
+struct lMatrix3fCtor {
+ lMatrix3fCtor()
+ {
+ }
+
+ void reset()
+ {
+ m_trips.clear();
+ }
+
+ void reserve(int numverts)
+ {
+ /* reserve for diagonal entries */
+ m_trips.reserve(numverts * 9);
+ }
+
+ void add(int i, int j, const Matrix3 &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; k++) {
+ for (int l = 0; l < 3; l++) {
+ m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
+ }
+ }
+ }
+
+ void sub(int i, int j, const Matrix3 &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; k++) {
+ for (int l = 0; l < 3; l++) {
+ m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
+ }
+ }
+ }
+
+ inline void construct(lMatrix &m)
+ {
+ m.setFromTriplets(m_trips.begin(), m_trips.end());
+ m_trips.clear();
+ }
+
+ private:
+ TripletList m_trips;
+};
+
+typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar>>
+ ConjugateGradient;
+
+using Eigen::ComputationInfo;
+
+BLI_INLINE void print_lvector(const lVector3f &v)
+{
+ for (int i = 0; i < v.rows(); i++) {
+ if (i > 0 && i % 3 == 0) {
+ printf("\n");
+ }
+
+ printf("%f,\n", v[i]);
+ }
+}
+
+BLI_INLINE void print_lmatrix(const lMatrix &m)
+{
+ for (int j = 0; j < m.rows(); j++) {
+ if (j > 0 && j % 3 == 0) {
+ printf("\n");
+ }
+
+ for (int i = 0; i < m.cols(); i++) {
+ if (i > 0 && i % 3 == 0) {
+ printf(" ");
+ }
+
+ implicit_print_matrix_elem(m.coeff(j, i));
+ }
+ printf("\n");
+ }
+}
+
+#endif