Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
grad.cpp File Reference
#include "grad.h"
#include <Eigen/Geometry>
#include <vector>
#include "PI.h"
#include "per_face_normals.h"
#include "volume.h"
#include "doublearea.h"
+ Include dependency graph for grad.cpp:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

template<typename DerivedV , typename DerivedF >
IGL_INLINE void grad_tet (const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &T, Eigen::SparseMatrix< typename DerivedV::Scalar > &G, bool uniform)
 
template<typename DerivedV , typename DerivedF >
IGL_INLINE void grad_tri (const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, Eigen::SparseMatrix< typename DerivedV::Scalar > &G, bool uniform)
 

Function Documentation

◆ grad_tet()

template<typename DerivedV , typename DerivedF >
IGL_INLINE void grad_tet ( const Eigen::PlainObjectBase< DerivedV > &  V,
const Eigen::PlainObjectBase< DerivedF > &  T,
Eigen::SparseMatrix< typename DerivedV::Scalar > &  G,
bool  uniform 
)
21 {
22 using namespace Eigen;
23 assert(T.cols() == 4);
24 const int n = V.rows(); int m = T.rows();
25
26 /*
27 F = [ ...
28 T(:,1) T(:,2) T(:,3); ...
29 T(:,1) T(:,3) T(:,4); ...
30 T(:,1) T(:,4) T(:,2); ...
31 T(:,2) T(:,4) T(:,3)]; */
32 MatrixXi F(4*m,3);
33 for (int i = 0; i < m; i++) {
34 F.row(0*m + i) << T(i,0), T(i,1), T(i,2);
35 F.row(1*m + i) << T(i,0), T(i,2), T(i,3);
36 F.row(2*m + i) << T(i,0), T(i,3), T(i,1);
37 F.row(3*m + i) << T(i,1), T(i,3), T(i,2);
38 }
39 // compute volume of each tet
41 igl::volume(V,T,vol);
42
45 if (!uniform) {
46 // compute tetrahedron face normals
47 igl::per_face_normals(V,F,N); int norm_rows = N.rows();
48 for (int i = 0; i < norm_rows; i++)
49 N.row(i) /= N.row(i).norm();
50 igl::doublearea(V,F,A); A/=2.;
51 } else {
52 // Use a uniform tetrahedra as a reference, with the same volume as the original one:
53 //
54 // Use normals of the uniform tet (V = h*[0,0,0;1,0,0;0.5,sqrt(3)/2.,0;0.5,sqrt(3)/6.,sqrt(2)/sqrt(3)])
55 // 0 0 1.0000
56 // 0.8165 -0.4714 -0.3333
57 // 0 0.9428 -0.3333
58 // -0.8165 -0.4714 -0.3333
59 for (int i = 0; i < m; i++) {
60 N.row(0*m+i) << 0,0,1;
61 double a = sqrt(2)*std::cbrt(3*vol(i)); // area of a face in a uniform tet with volume = vol(i)
62 A(0*m+i) = (pow(a,2)*sqrt(3))/4.;
63 }
64 for (int i = 0; i < m; i++) {
65 N.row(1*m+i) << 0.8165,-0.4714,-0.3333;
66 double a = sqrt(2)*std::cbrt(3*vol(i));
67 A(1*m+i) = (pow(a,2)*sqrt(3))/4.;
68 }
69 for (int i = 0; i < m; i++) {
70 N.row(2*m+i) << 0,0.9428,-0.3333;
71 double a = sqrt(2)*std::cbrt(3*vol(i));
72 A(2*m+i) = (pow(a,2)*sqrt(3))/4.;
73 }
74 for (int i = 0; i < m; i++) {
75 N.row(3*m+i) << -0.8165,-0.4714,-0.3333;
76 double a = sqrt(2)*std::cbrt(3*vol(i));
77 A(3*m+i) = (pow(a,2)*sqrt(3))/4.;
78 }
79
80 }
81
82 /* G = sparse( ...
83 [0*m + repmat(1:m,1,4) ...
84 1*m + repmat(1:m,1,4) ...
85 2*m + repmat(1:m,1,4)], ...
86 repmat([T(:,4);T(:,2);T(:,3);T(:,1)],3,1), ...
87 repmat(A./(3*repmat(vol,4,1)),3,1).*N(:), ...
88 3*m,n);*/
89 std::vector<Triplet<double> > G_t;
90 for (int i = 0; i < 4*m; i++) {
91 int T_j; // j indexes : repmat([T(:,4);T(:,2);T(:,3);T(:,1)],3,1)
92 switch (i/m) {
93 case 0:
94 T_j = 3;
95 break;
96 case 1:
97 T_j = 1;
98 break;
99 case 2:
100 T_j = 2;
101 break;
102 case 3:
103 T_j = 0;
104 break;
105 }
106 int i_idx = i%m;
107 int j_idx = T(i_idx,T_j);
108
109 double val_before_n = A(i)/(3*vol(i_idx));
110 G_t.push_back(Triplet<double>(0*m+i_idx, j_idx, val_before_n * N(i,0)));
111 G_t.push_back(Triplet<double>(1*m+i_idx, j_idx, val_before_n * N(i,1)));
112 G_t.push_back(Triplet<double>(2*m+i_idx, j_idx, val_before_n * N(i,2)));
113 }
114 G.resize(3*m,n);
115 G.setFromTriplets(G_t.begin(), G_t.end());
116}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const
Definition PlainObjectBase.h:153
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const
Definition PlainObjectBase.h:151
void setFromTriplets(const InputIterators &begin, const InputIterators &end)
Definition SparseMatrix.h:993
void resize(Index rows, Index cols)
Definition SparseMatrix.h:621
A small structure to hold a non zero as a triplet (i,j,value).
Definition SparseUtil.h:155
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half &a, const half &b)
Definition Half.h:477
Definition LDLT.h:16
@ F
Definition libslic3r.h:102
IGL_INLINE void per_face_normals(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, const Eigen::MatrixBase< DerivedZ > &Z, Eigen::PlainObjectBase< DerivedN > &N)
Definition per_face_normals.cpp:13
IGL_INLINE void doublearea(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedF > &F, Eigen::PlainObjectBase< DeriveddblA > &dblA)
Definition doublearea.cpp:17
IGL_INLINE void volume(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedT > &T, Eigen::PlainObjectBase< Derivedvol > &vol)
Definition volume.cpp:15

References Eigen::PlainObjectBase< Derived >::cols(), igl::doublearea(), igl::per_face_normals(), Eigen::SparseMatrix< _Scalar, _Options, _StorageIndex >::resize(), Eigen::PlainObjectBase< Derived >::rows(), Eigen::SparseMatrix< _Scalar, _Options, _StorageIndex >::setFromTriplets(), sqrt(), and igl::volume().

Referenced by igl::grad().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ grad_tri()

template<typename DerivedV , typename DerivedF >
IGL_INLINE void grad_tri ( const Eigen::PlainObjectBase< DerivedV > &  V,
const Eigen::PlainObjectBase< DerivedF > &  F,
Eigen::SparseMatrix< typename DerivedV::Scalar > &  G,
bool  uniform 
)
123{
125 eperp21(F.rows(),3), eperp13(F.rows(),3);
126
127 for (int i=0;i<F.rows();++i)
128 {
129 // renaming indices of vertices of triangles for convenience
130 int i1 = F(i,0);
131 int i2 = F(i,1);
132 int i3 = F(i,2);
133
134 // #F x 3 matrices of triangle edge vectors, named after opposite vertices
135 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v32 = V.row(i3) - V.row(i2);
136 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v13 = V.row(i1) - V.row(i3);
137 Eigen::Matrix<typename DerivedV::Scalar, 1, 3> v21 = V.row(i2) - V.row(i1);
139 // area of parallelogram is twice area of triangle
140 // area of parallelogram is || v1 x v2 ||
141 // This does correct l2 norm of rows, so that it contains #F list of twice
142 // triangle areas
143 double dblA = std::sqrt(n.dot(n));
145 if (!uniform) {
146 // now normalize normals to get unit normals
147 u = n / dblA;
148 } else {
149 // Abstract equilateral triangle v1=(0,0), v2=(h,0), v3=(h/2, (sqrt(3)/2)*h)
150
151 // get h (by the area of the triangle)
152 double h = sqrt( (dblA)/sin(igl::PI / 3.0)); // (h^2*sin(60))/2. = Area => h = sqrt(2*Area/sin_60)
153
155 v1 << 0,0,0;
156 v2 << h,0,0;
157 v3 << h/2.,(sqrt(3)/2.)*h,0;
158
159 // now fix v32,v13,v21 and the normal
160 v32 = v3-v2;
161 v13 = v1-v3;
162 v21 = v2-v1;
163 n = v32.cross(v13);
164 }
165
166 // rotate each vector 90 degrees around normal
167 double norm21 = std::sqrt(v21.dot(v21));
168 double norm13 = std::sqrt(v13.dot(v13));
169 eperp21.row(i) = u.cross(v21);
170 eperp21.row(i) = eperp21.row(i) / std::sqrt(eperp21.row(i).dot(eperp21.row(i)));
171 eperp21.row(i) *= norm21 / dblA;
172 eperp13.row(i) = u.cross(v13);
173 eperp13.row(i) = eperp13.row(i) / std::sqrt(eperp13.row(i).dot(eperp13.row(i)));
174 eperp13.row(i) *= norm13 / dblA;
175 }
176
177 std::vector<int> rs;
178 rs.reserve(F.rows()*4*3);
179 std::vector<int> cs;
180 cs.reserve(F.rows()*4*3);
181 std::vector<double> vs;
182 vs.reserve(F.rows()*4*3);
183
184 // row indices
185 for(int r=0;r<3;r++)
186 {
187 for(int j=0;j<4;j++)
188 {
189 for(int i=r*F.rows();i<(r+1)*F.rows();i++) rs.push_back(i);
190 }
191 }
192
193 // column indices
194 for(int r=0;r<3;r++)
195 {
196 for(int i=0;i<F.rows();i++) cs.push_back(F(i,1));
197 for(int i=0;i<F.rows();i++) cs.push_back(F(i,0));
198 for(int i=0;i<F.rows();i++) cs.push_back(F(i,2));
199 for(int i=0;i<F.rows();i++) cs.push_back(F(i,0));
200 }
201
202 // values
203 for(int i=0;i<F.rows();i++) vs.push_back(eperp13(i,0));
204 for(int i=0;i<F.rows();i++) vs.push_back(-eperp13(i,0));
205 for(int i=0;i<F.rows();i++) vs.push_back(eperp21(i,0));
206 for(int i=0;i<F.rows();i++) vs.push_back(-eperp21(i,0));
207 for(int i=0;i<F.rows();i++) vs.push_back(eperp13(i,1));
208 for(int i=0;i<F.rows();i++) vs.push_back(-eperp13(i,1));
209 for(int i=0;i<F.rows();i++) vs.push_back(eperp21(i,1));
210 for(int i=0;i<F.rows();i++) vs.push_back(-eperp21(i,1));
211 for(int i=0;i<F.rows();i++) vs.push_back(eperp13(i,2));
212 for(int i=0;i<F.rows();i++) vs.push_back(-eperp13(i,2));
213 for(int i=0;i<F.rows();i++) vs.push_back(eperp21(i,2));
214 for(int i=0;i<F.rows();i++) vs.push_back(-eperp21(i,2));
215
216 // create sparse gradient operator matrix
217 G.resize(3*F.rows(),V.rows());
218 std::vector<Eigen::Triplet<typename DerivedV::Scalar> > triplets;
219 for (int i=0;i<(int)vs.size();++i)
220 {
221 triplets.push_back(Eigen::Triplet<typename DerivedV::Scalar>(rs[i],cs[i],vs[i]));
222 }
223 G.setFromTriplets(triplets.begin(), triplets.end());
224}
EIGEN_DEVICE_FUNC const SinReturnType sin() const
Definition ArrayCwiseUnaryOps.h:220
const double PI
Definition PI.h:16

References igl::PI, Eigen::SparseMatrix< _Scalar, _Options, _StorageIndex >::resize(), Eigen::PlainObjectBase< Derived >::rows(), Eigen::SparseMatrix< _Scalar, _Options, _StorageIndex >::setFromTriplets(), sin(), and sqrt().

Referenced by igl::grad().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: