Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
igl::flip_avoiding Namespace Reference

Functions

IGL_INLINE int SolveP3 (std::vector< double > &x, double a, double b, double c)
 
IGL_INLINE double get_smallest_pos_quad_zero (double a, double b, double c)
 
IGL_INLINE double get_min_pos_root_2D (const Eigen::MatrixXd &uv, const Eigen::MatrixXi &F, Eigen::MatrixXd &d, int f)
 
IGL_INLINE double get_min_pos_root_3D (const Eigen::MatrixXd &uv, const Eigen::MatrixXi &F, Eigen::MatrixXd &direc, int f)
 
IGL_INLINE double compute_max_step_from_singularities (const Eigen::MatrixXd &uv, const Eigen::MatrixXi &F, Eigen::MatrixXd &d)
 

Function Documentation

◆ compute_max_step_from_singularities()

IGL_INLINE double igl::flip_avoiding::compute_max_step_from_singularities ( const Eigen::MatrixXd &  uv,
const Eigen::MatrixXi &  F,
Eigen::MatrixXd &  d 
)
277 {
278 using namespace std;
279 double max_step = INFINITY;
280
281 // The if statement is outside the for loops to avoid branching/ease parallelizing
282 if (uv.cols() == 2)
283 {
284 for (int f = 0; f < F.rows(); f++)
285 {
286 double min_positive_root = get_min_pos_root_2D(uv,F,d,f);
287 max_step = std::min(max_step, min_positive_root);
288 }
289 }
290 else
291 { // volumetric deformation
292 for (int f = 0; f < F.rows(); f++)
293 {
294 double min_positive_root = get_min_pos_root_3D(uv,F,d,f);
295 max_step = std::min(max_step, min_positive_root);
296 }
297 }
298 return max_step;
299 }
IGL_INLINE double get_min_pos_root_2D(const Eigen::MatrixXd &uv, const Eigen::MatrixXi &F, Eigen::MatrixXd &d, int f)
Definition flip_avoiding_line_search.cpp:112
STL namespace.

References get_min_pos_root_2D(), and get_min_pos_root_3D().

Referenced by igl::flip_avoiding_line_search().

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

◆ get_min_pos_root_2D()

IGL_INLINE double igl::flip_avoiding::get_min_pos_root_2D ( const Eigen::MatrixXd &  uv,
const Eigen::MatrixXi &  F,
Eigen::MatrixXd &  d,
int  f 
)
116 {
117 using namespace std;
118 /*
119 Finding the smallest timestep t s.t a triangle get degenerated (<=> det = 0)
120 The following code can be derived by a symbolic expression in matlab:
121
122 Symbolic matlab:
123 U11 = sym('U11');
124 U12 = sym('U12');
125 U21 = sym('U21');
126 U22 = sym('U22');
127 U31 = sym('U31');
128 U32 = sym('U32');
129
130 V11 = sym('V11');
131 V12 = sym('V12');
132 V21 = sym('V21');
133 V22 = sym('V22');
134 V31 = sym('V31');
135 V32 = sym('V32');
136
137 t = sym('t');
138
139 U1 = [U11,U12];
140 U2 = [U21,U22];
141 U3 = [U31,U32];
142
143 V1 = [V11,V12];
144 V2 = [V21,V22];
145 V3 = [V31,V32];
146
147 A = [(U2+V2*t) - (U1+ V1*t)];
148 B = [(U3+V3*t) - (U1+ V1*t)];
149 C = [A;B];
150
151 solve(det(C), t);
152 cf = coeffs(det(C),t); % Now cf(1),cf(2),cf(3) holds the coefficients for the polynom. at order c,b,a
153 */
154
155 int v1 = F(f,0); int v2 = F(f,1); int v3 = F(f,2);
156 // get quadratic coefficients (ax^2 + b^x + c)
157 const double& U11 = uv(v1,0);
158 const double& U12 = uv(v1,1);
159 const double& U21 = uv(v2,0);
160 const double& U22 = uv(v2,1);
161 const double& U31 = uv(v3,0);
162 const double& U32 = uv(v3,1);
163
164 const double& V11 = d(v1,0);
165 const double& V12 = d(v1,1);
166 const double& V21 = d(v2,0);
167 const double& V22 = d(v2,1);
168 const double& V31 = d(v3,0);
169 const double& V32 = d(v3,1);
170
171 double a = V11*V22 - V12*V21 - V11*V32 + V12*V31 + V21*V32 - V22*V31;
172 double b = U11*V22 - U12*V21 - U21*V12 + U22*V11 - U11*V32 + U12*V31 + U31*V12 - U32*V11 + U21*V32 - U22*V31 - U31*V22 + U32*V21;
173 double c = U11*U22 - U12*U21 - U11*U32 + U12*U31 + U21*U32 - U22*U31;
174
175 return get_smallest_pos_quad_zero(a,b,c);
176 }
IGL_INLINE double get_smallest_pos_quad_zero(double a, double b, double c)
Definition flip_avoiding_line_search.cpp:64

References get_smallest_pos_quad_zero().

Referenced by compute_max_step_from_singularities().

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

◆ get_min_pos_root_3D()

IGL_INLINE double igl::flip_avoiding::get_min_pos_root_3D ( const Eigen::MatrixXd &  uv,
const Eigen::MatrixXi &  F,
Eigen::MatrixXd &  direc,
int  f 
)
182 {
183 using namespace std;
184 /*
185 Searching for the roots of:
186 +-1/6 * |ax ay az 1|
187 |bx by bz 1|
188 |cx cy cz 1|
189 |dx dy dz 1|
190 Every point ax,ay,az has a search direction a_dx,a_dy,a_dz, and so we add those to the matrix, and solve the cubic to find the step size t for a 0 volume
191 Symbolic matlab:
192 syms a_x a_y a_z a_dx a_dy a_dz % tetrahedera point and search direction
193 syms b_x b_y b_z b_dx b_dy b_dz
194 syms c_x c_y c_z c_dx c_dy c_dz
195 syms d_x d_y d_z d_dx d_dy d_dz
196 syms t % Timestep var, this is what we're looking for
197
198
199 a_plus_t = [a_x,a_y,a_z] + t*[a_dx,a_dy,a_dz];
200 b_plus_t = [b_x,b_y,b_z] + t*[b_dx,b_dy,b_dz];
201 c_plus_t = [c_x,c_y,c_z] + t*[c_dx,c_dy,c_dz];
202 d_plus_t = [d_x,d_y,d_z] + t*[d_dx,d_dy,d_dz];
203
204 vol_mat = [a_plus_t,1;b_plus_t,1;c_plus_t,1;d_plus_t,1]
205 //cf = coeffs(det(vol_det),t); % Now cf(1),cf(2),cf(3),cf(4) holds the coefficients for the polynom
206 [coefficients,terms] = coeffs(det(vol_det),t); % terms = [ t^3, t^2, t, 1], Coefficients hold the coeff we seek
207 */
208 int v1 = F(f,0); int v2 = F(f,1); int v3 = F(f,2); int v4 = F(f,3);
209 const double& a_x = uv(v1,0);
210 const double& a_y = uv(v1,1);
211 const double& a_z = uv(v1,2);
212 const double& b_x = uv(v2,0);
213 const double& b_y = uv(v2,1);
214 const double& b_z = uv(v2,2);
215 const double& c_x = uv(v3,0);
216 const double& c_y = uv(v3,1);
217 const double& c_z = uv(v3,2);
218 const double& d_x = uv(v4,0);
219 const double& d_y = uv(v4,1);
220 const double& d_z = uv(v4,2);
221
222 const double& a_dx = direc(v1,0);
223 const double& a_dy = direc(v1,1);
224 const double& a_dz = direc(v1,2);
225 const double& b_dx = direc(v2,0);
226 const double& b_dy = direc(v2,1);
227 const double& b_dz = direc(v2,2);
228 const double& c_dx = direc(v3,0);
229 const double& c_dy = direc(v3,1);
230 const double& c_dz = direc(v3,2);
231 const double& d_dx = direc(v4,0);
232 const double& d_dy = direc(v4,1);
233 const double& d_dz = direc(v4,2);
234
235 // Find solution for: a*t^3 + b*t^2 + c*d +d = 0
236 double a = a_dx*b_dy*c_dz - a_dx*b_dz*c_dy - a_dy*b_dx*c_dz + a_dy*b_dz*c_dx + a_dz*b_dx*c_dy - a_dz*b_dy*c_dx - a_dx*b_dy*d_dz + a_dx*b_dz*d_dy + a_dy*b_dx*d_dz - a_dy*b_dz*d_dx - a_dz*b_dx*d_dy + a_dz*b_dy*d_dx + a_dx*c_dy*d_dz - a_dx*c_dz*d_dy - a_dy*c_dx*d_dz + a_dy*c_dz*d_dx + a_dz*c_dx*d_dy - a_dz*c_dy*d_dx - b_dx*c_dy*d_dz + b_dx*c_dz*d_dy + b_dy*c_dx*d_dz - b_dy*c_dz*d_dx - b_dz*c_dx*d_dy + b_dz*c_dy*d_dx;
237
238 double b = a_dy*b_dz*c_x - a_dy*b_x*c_dz - a_dz*b_dy*c_x + a_dz*b_x*c_dy + a_x*b_dy*c_dz - a_x*b_dz*c_dy - a_dx*b_dz*c_y + a_dx*b_y*c_dz + a_dz*b_dx*c_y - a_dz*b_y*c_dx - a_y*b_dx*c_dz + a_y*b_dz*c_dx + a_dx*b_dy*c_z - a_dx*b_z*c_dy - a_dy*b_dx*c_z + a_dy*b_z*c_dx + a_z*b_dx*c_dy - a_z*b_dy*c_dx - a_dy*b_dz*d_x + a_dy*b_x*d_dz + a_dz*b_dy*d_x - a_dz*b_x*d_dy - a_x*b_dy*d_dz + a_x*b_dz*d_dy + a_dx*b_dz*d_y - a_dx*b_y*d_dz - a_dz*b_dx*d_y + a_dz*b_y*d_dx + a_y*b_dx*d_dz - a_y*b_dz*d_dx - a_dx*b_dy*d_z + a_dx*b_z*d_dy + a_dy*b_dx*d_z - a_dy*b_z*d_dx - a_z*b_dx*d_dy + a_z*b_dy*d_dx + a_dy*c_dz*d_x - a_dy*c_x*d_dz - a_dz*c_dy*d_x + a_dz*c_x*d_dy + a_x*c_dy*d_dz - a_x*c_dz*d_dy - a_dx*c_dz*d_y + a_dx*c_y*d_dz + a_dz*c_dx*d_y - a_dz*c_y*d_dx - a_y*c_dx*d_dz + a_y*c_dz*d_dx + a_dx*c_dy*d_z - a_dx*c_z*d_dy - a_dy*c_dx*d_z + a_dy*c_z*d_dx + a_z*c_dx*d_dy - a_z*c_dy*d_dx - b_dy*c_dz*d_x + b_dy*c_x*d_dz + b_dz*c_dy*d_x - b_dz*c_x*d_dy - b_x*c_dy*d_dz + b_x*c_dz*d_dy + b_dx*c_dz*d_y - b_dx*c_y*d_dz - b_dz*c_dx*d_y + b_dz*c_y*d_dx + b_y*c_dx*d_dz - b_y*c_dz*d_dx - b_dx*c_dy*d_z + b_dx*c_z*d_dy + b_dy*c_dx*d_z - b_dy*c_z*d_dx - b_z*c_dx*d_dy + b_z*c_dy*d_dx;
239
240 double c = a_dz*b_x*c_y - a_dz*b_y*c_x - a_x*b_dz*c_y + a_x*b_y*c_dz + a_y*b_dz*c_x - a_y*b_x*c_dz - a_dy*b_x*c_z + a_dy*b_z*c_x + a_x*b_dy*c_z - a_x*b_z*c_dy - a_z*b_dy*c_x + a_z*b_x*c_dy + a_dx*b_y*c_z - a_dx*b_z*c_y - a_y*b_dx*c_z + a_y*b_z*c_dx + a_z*b_dx*c_y - a_z*b_y*c_dx - a_dz*b_x*d_y + a_dz*b_y*d_x + a_x*b_dz*d_y - a_x*b_y*d_dz - a_y*b_dz*d_x + a_y*b_x*d_dz + a_dy*b_x*d_z - a_dy*b_z*d_x - a_x*b_dy*d_z + a_x*b_z*d_dy + a_z*b_dy*d_x - a_z*b_x*d_dy - a_dx*b_y*d_z + a_dx*b_z*d_y + a_y*b_dx*d_z - a_y*b_z*d_dx - a_z*b_dx*d_y + a_z*b_y*d_dx + a_dz*c_x*d_y - a_dz*c_y*d_x - a_x*c_dz*d_y + a_x*c_y*d_dz + a_y*c_dz*d_x - a_y*c_x*d_dz - a_dy*c_x*d_z + a_dy*c_z*d_x + a_x*c_dy*d_z - a_x*c_z*d_dy - a_z*c_dy*d_x + a_z*c_x*d_dy + a_dx*c_y*d_z - a_dx*c_z*d_y - a_y*c_dx*d_z + a_y*c_z*d_dx + a_z*c_dx*d_y - a_z*c_y*d_dx - b_dz*c_x*d_y + b_dz*c_y*d_x + b_x*c_dz*d_y - b_x*c_y*d_dz - b_y*c_dz*d_x + b_y*c_x*d_dz + b_dy*c_x*d_z - b_dy*c_z*d_x - b_x*c_dy*d_z + b_x*c_z*d_dy + b_z*c_dy*d_x - b_z*c_x*d_dy - b_dx*c_y*d_z + b_dx*c_z*d_y + b_y*c_dx*d_z - b_y*c_z*d_dx - b_z*c_dx*d_y + b_z*c_y*d_dx;
241
242 double d = a_x*b_y*c_z - a_x*b_z*c_y - a_y*b_x*c_z + a_y*b_z*c_x + a_z*b_x*c_y - a_z*b_y*c_x - a_x*b_y*d_z + a_x*b_z*d_y + a_y*b_x*d_z - a_y*b_z*d_x - a_z*b_x*d_y + a_z*b_y*d_x + a_x*c_y*d_z - a_x*c_z*d_y - a_y*c_x*d_z + a_y*c_z*d_x + a_z*c_x*d_y - a_z*c_y*d_x - b_x*c_y*d_z + b_x*c_z*d_y + b_y*c_x*d_z - b_y*c_z*d_x - b_z*c_x*d_y + b_z*c_y*d_x;
243
244 if (std::abs(a)<=1.e-10)
245 {
246 return get_smallest_pos_quad_zero(b,c,d);
247 }
248 b/=a; c/=a; d/=a; // normalize it all
249 std::vector<double> res(3);
250 int real_roots_num = SolveP3(res,b,c,d);
251 switch (real_roots_num)
252 {
253 case 1:
254 return (res[0] >= 0) ? res[0]:INFINITY;
255 case 2:
256 {
257 double max_root = std::max(res[0],res[1]); double min_root = std::min(res[0],res[1]);
258 if (min_root > 0) return min_root;
259 if (max_root > 0) return max_root;
260 return INFINITY;
261 }
262 case 3:
263 default:
264 {
265 std::sort(res.begin(),res.end());
266 if (res[0] > 0) return res[0];
267 if (res[1] > 0) return res[1];
268 if (res[2] > 0) return res[2];
269 return INFINITY;
270 }
271 }
272 }

References get_smallest_pos_quad_zero(), and SolveP3().

Referenced by compute_max_step_from_singularities().

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

◆ get_smallest_pos_quad_zero()

IGL_INLINE double igl::flip_avoiding::get_smallest_pos_quad_zero ( double  a,
double  b,
double  c 
)
65 {
66 using namespace std;
67 double t1, t2;
68 if(std::abs(a) > 1.0e-10)
69 {
70 double delta_in = pow(b, 2) - 4 * a * c;
71 if(delta_in <= 0)
72 {
73 return INFINITY;
74 }
75
76 double delta = sqrt(delta_in); // delta >= 0
77 if(b >= 0) // avoid subtracting two similar numbers
78 {
79 double bd = - b - delta;
80 t1 = 2 * c / bd;
81 t2 = bd / (2 * a);
82 }
83 else
84 {
85 double bd = - b + delta;
86 t1 = bd / (2 * a);
87 t2 = (2 * c) / bd;
88 }
89
90 assert (std::isfinite(t1));
91 assert (std::isfinite(t2));
92
93 if(a < 0) std::swap(t1, t2); // make t1 > t2
94 // return the smaller positive root if it exists, otherwise return infinity
95 if(t1 > 0)
96 {
97 return t2 > 0 ? t2 : t1;
98 }
99 else
100 {
101 return INFINITY;
102 }
103 }
104 else
105 {
106 if(b == 0) return INFINITY; // just to avoid divide-by-zero
107 t1 = -c / b;
108 return t1 > 0 ? t1 : INFINITY;
109 }
110 }
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152

References sqrt().

Referenced by get_min_pos_root_2D(), and get_min_pos_root_3D().

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

◆ SolveP3()

IGL_INLINE int igl::flip_avoiding::SolveP3 ( std::vector< double > &  x,
double  a,
double  b,
double  c 
)
26 { // solve cubic equation x^3 + a*x^2 + b*x + c
27 using namespace std;
28 double a2 = a*a;
29 double q = (a2 - 3*b)/9;
30 double r = (a*(2*a2-9*b) + 27*c)/54;
31 double r2 = r*r;
32 double q3 = q*q*q;
33 double A,B;
34 if(r2<q3)
35 {
36 double t=r/sqrt(q3);
37 if( t<-1) t=-1;
38 if( t> 1) t= 1;
39 t=acos(t);
40 a/=3; q=-2*sqrt(q);
41 x[0]=q*cos(t/3)-a;
42 x[1]=q*cos((t+(2*igl::PI))/3)-a;
43 x[2]=q*cos((t-(2*igl::PI))/3)-a;
44 return(3);
45 }
46 else
47 {
48 A =-pow(fabs(r)+sqrt(r2-q3),1./3);
49 if( r<0 ) A=-A;
50 B = A==0? 0 : B=q/A;
51
52 a/=3;
53 x[0] =(A+B)-a;
54 x[1] =-0.5*(A+B)-a;
55 x[2] = 0.5*sqrt(3.)*(A-B);
56 if(fabs(x[2])<1e-14)
57 {
58 x[2]=x[1]; return(2);
59 }
60 return(1);
61 }
62 }
EIGEN_DEVICE_FUNC const AcosReturnType acos() const
Definition ArrayCwiseUnaryOps.h:262
EIGEN_DEVICE_FUNC const CosReturnType cos() const
Definition ArrayCwiseUnaryOps.h:202
const double PI
Definition PI.h:16

References acos(), cos(), igl::PI, and sqrt().

Referenced by get_min_pos_root_3D().

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