Blender  V2.93
Curvature.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is:
17  * GTS - Library for the manipulation of triangulated surfaces
18  * Copyright (C) 1999 Stephane Popinet
19  * and:
20  * OGF/Graphite: Geometry and Graphics Programming Library + Utilities
21  * Copyright (C) 2000-2003 Bruno Levy
22  * Contact: Bruno Levy <levy@loria.fr>
23  * ISA Project
24  * LORIA, INRIA Lorraine,
25  * Campus Scientifique, BP 239
26  * 54506 VANDOEUVRE LES NANCY CEDEX
27  * FRANCE
28  */
29 
36 #include <cassert>
37 #include <cstdlib> // for malloc and free
38 #include <set>
39 #include <stack>
40 
41 #include "Curvature.h"
42 #include "WEdge.h"
43 
44 #include "../geometry/normal_cycle.h"
45 
46 #include "BLI_math.h"
47 
48 namespace Freestyle {
49 
50 static bool angle_obtuse(WVertex *v, WFace *f)
51 {
52  WOEdge *e;
53  f->getOppositeEdge(v, e);
54 
55  Vec3r vec1(e->GetaVertex()->GetVertex() - v->GetVertex());
56  Vec3r vec2(e->GetbVertex()->GetVertex() - v->GetVertex());
57  return ((vec1 * vec2) < 0);
58 }
59 
60 // FIXME
61 // WVvertex is useless but kept for history reasons
62 static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
63 {
64  bool b = false;
65  for (int i = 0; i < 3; i++) {
66  b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
67  }
68  return b;
69 }
70 
72 {
73  /* cf. Appendix B of [Meyer et al 2002] */
74  real udotv, denom;
75 
76  Vec3r u(v1->GetVertex() - vo->GetVertex());
77  Vec3r v(v2->GetVertex() - vo->GetVertex());
78 
79  udotv = u * v;
80  denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
81 
82  /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function
83  * below. */
84  if (denom == 0.0) {
85  return 0.0;
86  }
87  return (udotv / denom);
88 }
89 
91 {
92  /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
93  real udotv, denom;
94 
95  Vec3r u(v1->GetVertex() - vo->GetVertex());
96  Vec3r v(v2->GetVertex() - vo->GetVertex());
97 
98  udotv = u * v;
99  denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
100 
101  /* Note: I assume this is what they mean by using atan2(). -Ray Jones */
102 
103  /* tan = denom/udotv = y/x (see man page for atan2) */
104  return (fabs(atan2(denom, udotv)));
105 }
106 
129 {
130  real area = 0.0;
131 
132  if (!v) {
133  return false;
134  }
135 
136  /* this operator is not defined for boundary edges */
137  if (v->isBoundary()) {
138  return false;
139  }
140 
142 
143  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
144  area += (*itE)->GetaFace()->getArea();
145  }
146 
147  Kh = Vec3r(0.0, 0.0, 0.0);
148 
149  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
150  WOEdge *e = (*itE)->getPrevOnFace();
151 #if 0
152  if ((e->GetaVertex() == v) || (e->GetbVertex() == v)) {
153  cerr << "BUG ";
154  }
155 #endif
156  WVertex *v1 = e->GetaVertex();
157  WVertex *v2 = e->GetbVertex();
158  real temp;
159 
160  temp = cotan(v1, v, v2);
161  Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex()));
162 
163  temp = cotan(v2, v, v1);
164  Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
165  }
166  if (area > 0.0) {
167  Kh[0] /= 2 * area;
168  Kh[1] /= 2 * area;
169  Kh[2] /= 2 * area;
170  }
171  else {
172  return false;
173  }
174 
175  return true;
176 }
177 
195 {
196  real area = 0.0;
197  real angle_sum = 0.0;
198 
199  if (!v) {
200  return false;
201  }
202  if (!Kg) {
203  return false;
204  }
205 
206  /* this operator is not defined for boundary edges */
207  if (v->isBoundary()) {
208  *Kg = 0.0;
209  return false;
210  }
211 
213  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
214  area += (*itE)->GetaFace()->getArea();
215  }
216 
217  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
218  WOEdge *e = (*itE)->getPrevOnFace();
219  WVertex *v1 = e->GetaVertex();
220  WVertex *v2 = e->GetbVertex();
221  angle_sum += angle_from_cotan(v, v1, v2);
222  }
223 
224  *Kg = (2.0 * M_PI - angle_sum) / area;
225 
226  return true;
227 }
228 
244 {
245  real temp = Kh * Kh - Kg;
246 
247  if (!K1 || !K2) {
248  return;
249  }
250 
251  if (temp < 0.0) {
252  temp = 0.0;
253  }
254  temp = sqrt(temp);
255  *K1 = Kh + temp;
256  *K2 = Kh - temp;
257 }
258 
259 /* from Maple */
260 static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
261 {
262  real temp;
263 
264  temp = 1.0 / (m21 * m12 - m11 * m22);
265  *x1 = (m12 * b2 - m22 * b1) * temp;
266  *x2 = (m11 * b2 - m21 * b1) * temp;
267 }
268 
269 /* from Maple - largest eigenvector of [a b; b c] */
270 static void eigenvector(real a, real b, real c, Vec3r e)
271 {
272  if (b == 0.0) {
273  e[0] = 0.0;
274  }
275  else {
276  e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b);
277  }
278  e[1] = 1.0;
279  e[2] = 0.0;
280 }
281 
298 {
299  Vec3r N;
300  real normKh;
301 
302  Vec3r basis1, basis2, d, eig;
303  real ve2, vdotN;
304  real aterm_da, bterm_da, cterm_da, const_da;
305  real aterm_db, bterm_db, cterm_db, const_db;
306  real a, b, c;
307  real K1, K2;
308  real *weights, *kappas, *d1s, *d2s;
309  int edge_count;
310  real err_e1, err_e2;
311  int e;
313 
314  /* compute unit normal */
315  normKh = Kh.norm();
316 
317  if (normKh > 0.0) {
318  Kh.normalize();
319  }
320  else {
321  /* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by
322  * averaging the adjacent triangles
323  */
324  N[0] = N[1] = N[2] = 0.0;
325 
326  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
327  N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
328  }
329  real normN = N.norm();
330  if (normN <= 0.0) {
331  return;
332  }
333  N.normalize();
334  }
335 
336  /* construct a basis from N: */
337  /* set basis1 to any component not the largest of N */
338  basis1[0] = basis1[1] = basis1[2] = 0.0;
339  if (fabs(N[0]) > fabs(N[1])) {
340  basis1[1] = 1.0;
341  }
342  else {
343  basis1[0] = 1.0;
344  }
345 
346  /* make basis2 orthogonal to N */
347  basis2 = (N ^ basis1);
348  basis2.normalize();
349 
350  /* make basis1 orthogonal to N and basis2 */
351  basis1 = (N ^ basis2);
352  basis1.normalize();
353 
354  aterm_da = bterm_da = cterm_da = const_da = 0.0;
355  aterm_db = bterm_db = cterm_db = const_db = 0.0;
356  int nb_edges = v->GetEdges().size();
357 
358  weights = (real *)malloc(sizeof(real) * nb_edges);
359  kappas = (real *)malloc(sizeof(real) * nb_edges);
360  d1s = (real *)malloc(sizeof(real) * nb_edges);
361  d2s = (real *)malloc(sizeof(real) * nb_edges);
362  edge_count = 0;
363 
364  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
365  WOEdge *e;
366  WFace *f1, *f2;
367  real weight, kappa, d1, d2;
368  Vec3r vec_edge;
369  if (!*itE) {
370  continue;
371  }
372  e = *itE;
373 
374  /* since this vertex passed the tests in gts_vertex_mean_curvature_normal(), this should be
375  * true. */
376  // g_assert(gts_edge_face_number (e, s) == 2);
377 
378  /* identify the two triangles bordering e in s */
379  f1 = e->GetaFace();
380  f2 = e->GetbFace();
381 
382  /* We are solving for the values of the curvature tensor
383  * B = [ a b ; b c ].
384  * The computations here are from section 5 of [Meyer et al 2002].
385  *
386  * The first step is to calculate the linear equations governing the values of (a,b,c). These
387  * can be computed by setting the derivatives of the error E to zero (section 5.3).
388  *
389  * Since a + c = norm(Kh), we only compute the linear equations for dE/da and dE/db. (NB:
390  * [Meyer et al 2002] has the equation a + b = norm(Kh), but I'm almost positive this is
391  * incorrect).
392  *
393  * Note that the w_ij (defined in section 5.2) are all scaled by (1/8*A_mixed). We drop this
394  * uniform scale factor because the solution of the linear equations doesn't rely on it.
395  *
396  * The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are
397  * also const_dy terms that are the constant factors in the equations.
398  */
399 
400  /* find the vector from v along edge e */
401  vec_edge = Vec3r(-1 * e->GetVec());
402 
403  ve2 = vec_edge.squareNorm();
404  vdotN = vec_edge * N;
405 
406  /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
407  kappa = 2.0 * vdotN / ve2;
408 
409  /* section 5.2 */
410 
411  /* I don't like performing a minimization where some of the weights can be negative (as can be
412  * the case if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness.
413  */
414  weight = 0.0;
415  if (!triangle_obtuse(v, f1)) {
416  weight += ve2 *
417  cotan(
418  f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) /
419  8.0;
420  }
421  else {
422  if (angle_obtuse(v, f1)) {
423  weight += ve2 * f1->getArea() / 4.0;
424  }
425  else {
426  weight += ve2 * f1->getArea() / 8.0;
427  }
428  }
429 
430  if (!triangle_obtuse(v, f2)) {
431  weight += ve2 * cotan(f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) /
432  8.0;
433  }
434  else {
435  if (angle_obtuse(v, f2)) {
436  weight += ve2 * f1->getArea() / 4.0;
437  }
438  else {
439  weight += ve2 * f1->getArea() / 8.0;
440  }
441  }
442 
443  /* projection of edge perpendicular to N (section 5.3) */
444  d[0] = vec_edge[0] - vdotN * N[0];
445  d[1] = vec_edge[1] - vdotN * N[1];
446  d[2] = vec_edge[2] - vdotN * N[2];
447  d.normalize();
448 
449  /* not explicit in the paper, but necessary. Move d to 2D basis. */
450  d1 = d * basis1;
451  d2 = d * basis2;
452 
453  /* store off the curvature, direction of edge, and weights for later use */
454  weights[edge_count] = weight;
455  kappas[edge_count] = kappa;
456  d1s[edge_count] = d1;
457  d2s[edge_count] = d2;
458  edge_count++;
459 
460  /* Finally, update the linear equations */
461  aterm_da += weight * d1 * d1 * d1 * d1;
462  bterm_da += weight * d1 * d1 * 2 * d1 * d2;
463  cterm_da += weight * d1 * d1 * d2 * d2;
464  const_da += weight * d1 * d1 * (-kappa);
465 
466  aterm_db += weight * d1 * d2 * d1 * d1;
467  bterm_db += weight * d1 * d2 * 2 * d1 * d2;
468  cterm_db += weight * d1 * d2 * d2 * d2;
469  const_db += weight * d1 * d2 * (-kappa);
470  }
471 
472  /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
473  aterm_da -= cterm_da;
474  const_da += cterm_da * normKh;
475 
476  aterm_db -= cterm_db;
477  const_db += cterm_db * normKh;
478 
479  /* check for solvability of the linear system */
480  if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) &&
481  ((const_da != 0.0) || (const_db != 0.0))) {
482  linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b);
483 
484  c = normKh - a;
485 
486  eigenvector(a, b, c, eig);
487  }
488  else {
489  /* region of v is planar */
490  eig[0] = 1.0;
491  eig[1] = 0.0;
492  }
493 
494  /* Although the eigenvectors of B are good estimates of the principal directions, it seems that
495  * which one is attached to which curvature direction is a bit arbitrary. This may be a bug in my
496  * implementation, or just a side-effect of the inaccuracy of B due to the discrete nature of the
497  * sampling.
498  *
499  * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors
500  * by comparing the curvature estimates computed above and the curvatures calculated from the
501  * discrete differential operators.
502  */
503 
504  gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
505 
506  err_e1 = err_e2 = 0.0;
507  /* loop through the values previously saved */
508  for (e = 0; e < edge_count; e++) {
509  real weight, kappa, d1, d2;
510  real temp1, temp2;
511  real delta;
512 
513  weight = weights[e];
514  kappa = kappas[e];
515  d1 = d1s[e];
516  d2 = d2s[e];
517 
518  temp1 = fabs(eig[0] * d1 + eig[1] * d2);
519  temp1 = temp1 * temp1;
520  temp2 = fabs(eig[1] * d1 - eig[0] * d2);
521  temp2 = temp2 * temp2;
522 
523  /* err_e1 is for K1 associated with e1 */
524  delta = K1 * temp1 + K2 * temp2 - kappa;
525  err_e1 += weight * delta * delta;
526 
527  /* err_e2 is for K1 associated with e2 */
528  delta = K2 * temp1 + K1 * temp2 - kappa;
529  err_e2 += weight * delta * delta;
530  }
531  free(weights);
532  free(kappas);
533  free(d1s);
534  free(d2s);
535 
536  /* rotate eig by a right angle if that would decrease the error */
537  if (err_e2 < err_e1) {
538  real temp = eig[0];
539 
540  eig[0] = eig[1];
541  eig[1] = -temp;
542  }
543 
544  e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0];
545  e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1];
546  e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2];
547  e1.normalize();
548 
549  /* make N,e1,e2 a right handed coordinate system */
550  e2 = N ^ e1;
551  e2.normalize();
552 }
553 
554 namespace OGF {
555 
556 #if 0
557 inline static real angle(WOEdge *h)
558 {
559  const Vec3r &n1 = h->GetbFace()->GetNormal();
560  const Vec3r &n2 = h->GetaFace()->GetNormal();
561  const Vec3r v = h->GetVec();
562  real sine = (n1 ^ n2) * v / v.norm();
563  if (sine >= 1.0) {
564  return M_PI / 2.0;
565  }
566  if (sine <= -1.0) {
567  return -M_PI / 2.0;
568  }
569  return ::asin(sine);
570 }
571 #endif
572 
573 // precondition1: P is inside the sphere
574 // precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
575 static bool sphere_clip_vector(const Vec3r &O, real r, const Vec3r &P, Vec3r &V)
576 {
577  Vec3r W = P - O;
578  real a = V.squareNorm();
579  real b = 2.0 * V * W;
580  real c = W.squareNorm() - r * r;
581  real delta = b * b - 4 * a * c;
582  if (delta < 0) {
583  // Should not happen, but happens sometimes (numerical precision)
584  return true;
585  }
586  real t = -b + ::sqrt(delta) / (2.0 * a);
587  if (t < 0.0) {
588  // Should not happen, but happens sometimes (numerical precision)
589  return true;
590  }
591  if (t >= 1.0) {
592  // Inside the sphere
593  return false;
594  }
595 
596  V[0] = (t * V.x());
597  V[1] = (t * V.y());
598  V[2] = (t * V.z());
599 
600  return true;
601 }
602 
603 // TODO: check optimizations:
604 // use marking ? (measure *timings* ...)
606 {
607  // in case we have a non-manifold vertex, skip it...
608  if (start->isBoundary()) {
609  return;
610  }
611 
612  std::set<WVertex *> vertices;
613  const Vec3r &O = start->GetVertex();
614  std::stack<WVertex *> S;
615  S.push(start);
616  vertices.insert(start);
617  while (!S.empty()) {
618  WVertex *v = S.top();
619  S.pop();
620  if (v->isBoundary()) {
621  continue;
622  }
623  const Vec3r &P = v->GetVertex();
624  WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
625  WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
626  for (; woeit != woeitend; ++woeit) {
627  WOEdge *h = *woeit;
628  if ((v == start) || h->GetVec() * (O - P) > 0.0) {
629  Vec3r V(-1 * h->GetVec());
630  bool isect = sphere_clip_vector(O, radius, P, V);
631  assert(h->GetOwner()->GetNumberOfOEdges() ==
632  2); // Because otherwise v->isBoundary() would be true
634 
635  if (!isect) {
636  WVertex *w = h->GetaVertex();
637  if (vertices.find(w) == vertices.end()) {
638  vertices.insert(w);
639  S.push(w);
640  }
641  }
642  }
643  }
644  }
645 }
646 
648 {
649  // in case we have a non-manifold vertex, skip it...
650  if (start->isBoundary()) {
651  return;
652  }
653 
656  for (; woeit != woeitend; ++woeit) {
657  WOEdge *h = (*woeit)->twin();
659  WOEdge *hprev = h->getPrevOnFace();
660  nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle());
661  }
662 }
663 
664 } // namespace OGF
665 
666 } /* namespace Freestyle */
sqrt(x)+1/max(0
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
#define M_PI
Definition: BLI_math_base.h:38
#define UNUSED(x)
GTS - Library for the manipulation of triangulated surfaces.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Classes to define a Winged Edge data structure.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
void accumulate_dihedral_angle(const Vec3r &edge, real angle, real neigh_area=1.0)
Definition: normal_cycle.h:127
value_type squareNorm() const
Definition: VecMat.h:114
value_type norm() const
Definition: VecMat.h:109
Vec< T, N > & normalize()
Definition: VecMat.h:119
short GetNumberOfOEdges()
Definition: WEdge.h:633
float getArea()
Definition: WEdge.cpp:419
bool getOppositeEdge(const WVertex *v, WOEdge *&e)
Definition: WEdge.cpp:390
WOEdge * GetNextOEdge(WOEdge *iOEdge)
Definition: WEdge.h:901
const vector< WOEdge * > & getEdgeList()
Definition: WEdge.h:765
const Vec3f & GetVec()
Definition: WEdge.h:459
WVertex * GetaVertex()
Definition: WEdge.h:434
WOEdge * twin()
Definition: WEdge.cpp:211
WEdge * GetOwner()
Definition: WEdge.h:454
WOEdge * getPrevOnFace()
Definition: WEdge.cpp:216
WVertex * GetbVertex()
Definition: WEdge.h:439
const float GetAngle()
Definition: WEdge.h:464
bool isBoundary()
Definition: WEdge.cpp:112
Vec3f & GetVertex()
Definition: WEdge.h:87
virtual incoming_edge_iterator incoming_edges_begin()
Definition: WEdge.cpp:142
virtual incoming_edge_iterator incoming_edges_end()
Definition: WEdge.cpp:156
static float P(float k)
Definition: math_interp.c:41
VecMat::Vec3< real > Vec3r
Definition: Geom.h:42
static bool sphere_clip_vector(const Vec3r &O, real r, const Vec3r &P, Vec3r &V)
Definition: Curvature.cpp:575
void compute_curvature_tensor(WVertex *start, real radius, NormalCycle &nc)
Definition: Curvature.cpp:605
void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle &nc)
Definition: Curvature.cpp:647
inherits from class Rep
Definition: AppCanvas.cpp:32
void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
Definition: Curvature.cpp:297
bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
Definition: Curvature.cpp:194
static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
Definition: Curvature.cpp:62
static unsigned c
Definition: RandGen.cpp:97
static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
Definition: Curvature.cpp:90
bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
Definition: Curvature.cpp:128
static void eigenvector(real a, real b, real c, Vec3r e)
Definition: Curvature.cpp:270
static bool angle_obtuse(WVertex *v, WFace *f)
Definition: Curvature.cpp:50
static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
Definition: Curvature.cpp:260
static real cotan(WVertex *vo, WVertex *v1, WVertex *v2)
Definition: Curvature.cpp:71
void gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2)
Definition: Curvature.cpp:243
static unsigned a[3]
Definition: RandGen.cpp:92
double real
Definition: Precision.h:26
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
Definition: rall1d.h:391
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:429
static void area(int d1, int d2, int e1, int e2, float weights[2])
params N
ccl_device_inline float2 fabs(const float2 &a)
CCL_NAMESPACE_BEGIN struct View V