Cleanup: style
[blender.git] / source / blender / physics / intern / eigen_utils.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Lukas Toenne
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #ifndef __EIGEN_UTILS_H__
29 #define __EIGEN_UTILS_H__
30
31 /** \file blender/physics/intern/eigen_utils.h
32  *  \ingroup bph
33  */
34
35 #if defined(__GNUC__) && !defined(__clang__)
36 #  pragma GCC diagnostic push
37 /* XXX suppress verbose warnings in eigen */
38 #  pragma GCC diagnostic ignored "-Wlogical-op"
39 #endif
40
41 #include <Eigen/Sparse>
42 #include <Eigen/src/Core/util/DisableStupidWarnings.h>
43
44 #ifdef __GNUC__
45 #  pragma GCC diagnostic pop
46 #endif
47
48 #include "BLI_utildefines.h"
49
50
51 typedef float Scalar;
52
53 /* slightly extended Eigen vector class
54  * with conversion to/from plain C float array
55  */
56 class Vector3 : public Eigen::Vector3f {
57 public:
58         typedef float *ctype;
59
60         Vector3()
61         {
62         }
63
64         Vector3(const ctype &v)
65         {
66                 for (int k = 0; k < 3; ++k)
67                         coeffRef(k) = v[k];
68         }
69
70         Vector3& operator =(const ctype &v)
71         {
72                 for (int k = 0; k < 3; ++k)
73                         coeffRef(k) = v[k];
74                 return *this;
75         }
76
77         operator ctype()
78         {
79                 return data();
80         }
81 };
82
83 /* slightly extended Eigen matrix class
84  * with conversion to/from plain C float array
85  */
86 class Matrix3 : public Eigen::Matrix3f {
87 public:
88         typedef float (*ctype)[3];
89
90         Matrix3()
91         {
92         }
93
94         Matrix3(const ctype &v)
95         {
96                 for (int k = 0; k < 3; ++k)
97                         for (int l = 0; l < 3; ++l)
98                                 coeffRef(l, k) = v[k][l];
99         }
100
101         Matrix3& operator =(const ctype &v)
102         {
103                 for (int k = 0; k < 3; ++k)
104                         for (int l = 0; l < 3; ++l)
105                                 coeffRef(l, k) = v[k][l];
106                 return *this;
107         }
108
109         operator ctype()
110         {
111                 return (ctype)data();
112         }
113 };
114
115 typedef Eigen::VectorXf lVector;
116
117 /* Extension of dense Eigen vectors,
118  * providing 3-float block access for blenlib math functions
119  */
120 class lVector3f : public Eigen::VectorXf {
121 public:
122         typedef Eigen::VectorXf base_t;
123
124         lVector3f()
125         {
126         }
127
128         template <typename T>
129         lVector3f& operator =(T rhs)
130         {
131                 base_t::operator=(rhs);
132                 return *this;
133         }
134
135         float *v3(int vertex)
136         {
137                 return &coeffRef(3 * vertex);
138         }
139
140         const float *v3(int vertex) const
141         {
142                 return &coeffRef(3 * vertex);
143         }
144 };
145
146 typedef Eigen::Triplet<Scalar> Triplet;
147 typedef std::vector<Triplet> TripletList;
148
149 typedef Eigen::SparseMatrix<Scalar> lMatrix;
150
151 /* Constructor type that provides more convenient handling of Eigen triplets
152  * for efficient construction of sparse 3x3 block matrices.
153  * This should be used for building lMatrix instead of writing to such lMatrix directly (which is very inefficient).
154  * After all elements have been defined using the set() method, the actual matrix can be filled using construct().
155  */
156 struct lMatrix3fCtor {
157         lMatrix3fCtor()
158         {
159         }
160
161         void reset()
162         {
163                 m_trips.clear();
164         }
165
166         void reserve(int numverts)
167         {
168                 /* reserve for diagonal entries */
169                 m_trips.reserve(numverts * 9);
170         }
171
172         void add(int i, int j, const Matrix3 &m)
173         {
174                 i *= 3;
175                 j *= 3;
176                 for (int k = 0; k < 3; ++k)
177                         for (int l = 0; l < 3; ++l)
178                                 m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
179         }
180
181         void sub(int i, int j, const Matrix3 &m)
182         {
183                 i *= 3;
184                 j *= 3;
185                 for (int k = 0; k < 3; ++k)
186                         for (int l = 0; l < 3; ++l)
187                                 m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
188         }
189
190         inline void construct(lMatrix &m)
191         {
192                 m.setFromTriplets(m_trips.begin(), m_trips.end());
193                 m_trips.clear();
194         }
195
196 private:
197         TripletList m_trips;
198 };
199
200 typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar> > ConjugateGradient;
201
202 using Eigen::ComputationInfo;
203
204 BLI_INLINE void print_lvector(const lVector3f &v)
205 {
206         for (int i = 0; i < v.rows(); ++i) {
207                 if (i > 0 && i % 3 == 0)
208                         printf("\n");
209
210                 printf("%f,\n", v[i]);
211         }
212 }
213
214 BLI_INLINE void print_lmatrix(const lMatrix &m)
215 {
216         for (int j = 0; j < m.rows(); ++j) {
217                 if (j > 0 && j % 3 == 0)
218                         printf("\n");
219
220                 for (int i = 0; i < m.cols(); ++i) {
221                         if (i > 0 && i % 3 == 0)
222                                 printf("  ");
223
224                         implicit_print_matrix_elem(m.coeff(j, i));
225                 }
226                 printf("\n");
227         }
228 }
229
230 #endif