Blender  V3.3
Curvature.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * The Original Code is:
3  * GTS - Library for the manipulation of triangulated surfaces
4  * Copyright 1999 Stephane Popinet
5  * and:
6  * OGF/Graphite: Geometry and Graphics Programming Library + Utilities
7  * Copyright 2000-2003 Bruno Levy <levy@loria.fr> */
8 
15 #include <cassert>
16 #include <cstdlib> // for malloc and free
17 #include <set>
18 #include <stack>
19 
20 #include "Curvature.h"
21 #include "WEdge.h"
22 
23 #include "../geometry/normal_cycle.h"
24 
25 #include "BLI_math.h"
26 
27 namespace Freestyle {
28 
29 static bool angle_obtuse(WVertex *v, WFace *f)
30 {
31  WOEdge *e;
32  f->getOppositeEdge(v, e);
33 
34  Vec3r vec1(e->GetaVertex()->GetVertex() - v->GetVertex());
35  Vec3r vec2(e->GetbVertex()->GetVertex() - v->GetVertex());
36  return ((vec1 * vec2) < 0);
37 }
38 
39 // FIXME
40 // WVvertex is useless but kept for history reasons
41 static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
42 {
43  bool b = false;
44  for (int i = 0; i < 3; i++) {
45  b = b || ((f->getEdgeList()[i]->GetVec() * f->getEdgeList()[(i + 1) % 3]->GetVec()) < 0);
46  }
47  return b;
48 }
49 
51 {
52  /* cf. Appendix B of [Meyer et al 2002] */
53  real udotv, denom;
54 
55  Vec3r u(v1->GetVertex() - vo->GetVertex());
56  Vec3r v(v2->GetVertex() - vo->GetVertex());
57 
58  udotv = u * v;
59  denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
60 
61  /* denom can be zero if u==v. Returning 0 is acceptable, based on the callers of this function
62  * below. */
63  if (denom == 0.0) {
64  return 0.0;
65  }
66  return (udotv / denom);
67 }
68 
70 {
71  /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
72  real udotv, denom;
73 
74  Vec3r u(v1->GetVertex() - vo->GetVertex());
75  Vec3r v(v2->GetVertex() - vo->GetVertex());
76 
77  udotv = u * v;
78  denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv);
79 
80  /* NOTE(Ray Jones): I assume this is what they mean by using #atan2. */
81 
82  /* tan = denom/udotv = y/x (see man page for atan2) */
83  return (fabs(atan2(denom, udotv)));
84 }
85 
87 {
88  real area = 0.0;
89 
90  if (!v) {
91  return false;
92  }
93 
94  /* this operator is not defined for boundary edges */
95  if (v->isBoundary()) {
96  return false;
97  }
98 
100 
101  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
102  area += (*itE)->GetaFace()->getArea();
103  }
104 
105  Kh = Vec3r(0.0, 0.0, 0.0);
106 
107  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
108  WOEdge *e = (*itE)->getPrevOnFace();
109 #if 0
110  if ((e->GetaVertex() == v) || (e->GetbVertex() == v)) {
111  cerr << "BUG ";
112  }
113 #endif
114  WVertex *v1 = e->GetaVertex();
115  WVertex *v2 = e->GetbVertex();
116  real temp;
117 
118  temp = cotan(v1, v, v2);
119  Kh = Vec3r(Kh + temp * (v2->GetVertex() - v->GetVertex()));
120 
121  temp = cotan(v2, v, v1);
122  Kh = Vec3r(Kh + temp * (v1->GetVertex() - v->GetVertex()));
123  }
124  if (area > 0.0) {
125  Kh[0] /= 2 * area;
126  Kh[1] /= 2 * area;
127  Kh[2] /= 2 * area;
128  }
129  else {
130  return false;
131  }
132 
133  return true;
134 }
135 
137 {
138  real area = 0.0;
139  real angle_sum = 0.0;
140 
141  if (!v) {
142  return false;
143  }
144  if (!Kg) {
145  return false;
146  }
147 
148  /* this operator is not defined for boundary edges */
149  if (v->isBoundary()) {
150  *Kg = 0.0;
151  return false;
152  }
153 
155  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
156  area += (*itE)->GetaFace()->getArea();
157  }
158 
159  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
160  WOEdge *e = (*itE)->getPrevOnFace();
161  WVertex *v1 = e->GetaVertex();
162  WVertex *v2 = e->GetbVertex();
163  angle_sum += angle_from_cotan(v, v1, v2);
164  }
165 
166  *Kg = (2.0 * M_PI - angle_sum) / area;
167 
168  return true;
169 }
170 
172 {
173  real temp = Kh * Kh - Kg;
174 
175  if (!K1 || !K2) {
176  return;
177  }
178 
179  if (temp < 0.0) {
180  temp = 0.0;
181  }
182  temp = sqrt(temp);
183  *K1 = Kh + temp;
184  *K2 = Kh - temp;
185 }
186 
187 /* from Maple */
188 static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
189 {
190  real temp;
191 
192  temp = 1.0 / (m21 * m12 - m11 * m22);
193  *x1 = (m12 * b2 - m22 * b1) * temp;
194  *x2 = (m11 * b2 - m21 * b1) * temp;
195 }
196 
197 /* from Maple - largest eigenvector of [a b; b c] */
198 static void eigenvector(real a, real b, real c, Vec3r e)
199 {
200  if (b == 0.0) {
201  e[0] = 0.0;
202  }
203  else {
204  e[0] = -(c - a - sqrt(c * c - 2 * a * c + a * a + 4 * b * b)) / (2 * b);
205  }
206  e[1] = 1.0;
207  e[2] = 0.0;
208 }
209 
211 {
212  Vec3r N;
213  real normKh;
214 
215  Vec3r basis1, basis2, d, eig;
216  real ve2, vdotN;
217  real aterm_da, bterm_da, cterm_da, const_da;
218  real aterm_db, bterm_db, cterm_db, const_db;
219  real a, b, c;
220  real K1, K2;
221  real *weights, *kappas, *d1s, *d2s;
222  int edge_count;
223  real err_e1, err_e2;
224  int e;
226 
227  /* compute unit normal */
228  normKh = Kh.norm();
229 
230  if (normKh > 0.0) {
231  Kh.normalize();
232  }
233  else {
234  /* This vertex is a point of zero mean curvature (flat or saddle point). Compute a normal by
235  * averaging the adjacent triangles
236  */
237  N[0] = N[1] = N[2] = 0.0;
238 
239  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
240  N = Vec3r(N + (*itE)->GetaFace()->GetNormal());
241  }
242  real normN = N.norm();
243  if (normN <= 0.0) {
244  return;
245  }
246  N.normalize();
247  }
248 
249  /* construct a basis from N: */
250  /* set basis1 to any component not the largest of N */
251  basis1[0] = basis1[1] = basis1[2] = 0.0;
252  if (fabs(N[0]) > fabs(N[1])) {
253  basis1[1] = 1.0;
254  }
255  else {
256  basis1[0] = 1.0;
257  }
258 
259  /* make basis2 orthogonal to N */
260  basis2 = (N ^ basis1);
261  basis2.normalize();
262 
263  /* make basis1 orthogonal to N and basis2 */
264  basis1 = (N ^ basis2);
265  basis1.normalize();
266 
267  aterm_da = bterm_da = cterm_da = const_da = 0.0;
268  aterm_db = bterm_db = cterm_db = const_db = 0.0;
269  int nb_edges = v->GetEdges().size();
270 
271  weights = (real *)malloc(sizeof(real) * nb_edges);
272  kappas = (real *)malloc(sizeof(real) * nb_edges);
273  d1s = (real *)malloc(sizeof(real) * nb_edges);
274  d2s = (real *)malloc(sizeof(real) * nb_edges);
275  edge_count = 0;
276 
277  for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
278  WOEdge *e;
279  WFace *f1, *f2;
280  real weight, kappa, d1, d2;
281  Vec3r vec_edge;
282  if (!*itE) {
283  continue;
284  }
285  e = *itE;
286 
287  /* Since this vertex passed the tests in gts_vertex_mean_curvature_normal(),
288  * this should be true. */
289  // g_assert(gts_edge_face_number (e, s) == 2);
290 
291  /* Identify the two triangles bordering e in s. */
292  f1 = e->GetaFace();
293  f2 = e->GetbFace();
294 
295  /* We are solving for the values of the curvature tensor
296  * `B = [ a b ; b c ]`.
297  * The computations here are from section 5 of [Meyer et al 2002].
298  *
299  * The first step is to calculate the linear equations governing the values of (a,b,c). These
300  * can be computed by setting the derivatives of the error E to zero (section 5.3).
301  *
302  * Since a + c = norm(Kh), we only compute the linear equations for `dE/da` and `dE/db`.
303  * (NOTE: [Meyer et al 2002] has the equation `a + b = norm(Kh)`,
304  * but I'm almost positive this is incorrect).
305  *
306  * Note that the w_ij (defined in section 5.2) are all scaled by `(1/8*A_mixed)`. We drop this
307  * uniform scale factor because the solution of the linear equations doesn't rely on it.
308  *
309  * The terms of the linear equations are xterm_dy with x in {a,b,c} and y in {a,b}. There are
310  * also const_dy terms that are the constant factors in the equations.
311  */
312 
313  /* find the vector from v along edge e */
314  vec_edge = Vec3r(-1 * e->GetVec());
315 
316  ve2 = vec_edge.squareNorm();
317  vdotN = vec_edge * N;
318 
319  /* section 5.2 - There is a typo in the computation of kappa. The edges should be x_j-x_i. */
320  kappa = 2.0 * vdotN / ve2;
321 
322  /* section 5.2 */
323 
324  /* I don't like performing a minimization where some of the weights can be negative (as can be
325  * the case if f1 or f2 are obtuse). To ensure all-positive weights, we check for obtuseness.
326  */
327  weight = 0.0;
328  if (!triangle_obtuse(v, f1)) {
329  weight += ve2 *
330  cotan(
331  f1->GetNextOEdge(e->twin())->GetbVertex(), e->GetaVertex(), e->GetbVertex()) /
332  8.0;
333  }
334  else {
335  if (angle_obtuse(v, f1)) {
336  weight += ve2 * f1->getArea() / 4.0;
337  }
338  else {
339  weight += ve2 * f1->getArea() / 8.0;
340  }
341  }
342 
343  if (!triangle_obtuse(v, f2)) {
344  weight += ve2 * cotan(f2->GetNextOEdge(e)->GetbVertex(), e->GetaVertex(), e->GetbVertex()) /
345  8.0;
346  }
347  else {
348  if (angle_obtuse(v, f2)) {
349  weight += ve2 * f1->getArea() / 4.0;
350  }
351  else {
352  weight += ve2 * f1->getArea() / 8.0;
353  }
354  }
355 
356  /* projection of edge perpendicular to N (section 5.3) */
357  d[0] = vec_edge[0] - vdotN * N[0];
358  d[1] = vec_edge[1] - vdotN * N[1];
359  d[2] = vec_edge[2] - vdotN * N[2];
360  d.normalize();
361 
362  /* not explicit in the paper, but necessary. Move d to 2D basis. */
363  d1 = d * basis1;
364  d2 = d * basis2;
365 
366  /* store off the curvature, direction of edge, and weights for later use */
367  weights[edge_count] = weight;
368  kappas[edge_count] = kappa;
369  d1s[edge_count] = d1;
370  d2s[edge_count] = d2;
371  edge_count++;
372 
373  /* Finally, update the linear equations */
374  aterm_da += weight * d1 * d1 * d1 * d1;
375  bterm_da += weight * d1 * d1 * 2 * d1 * d2;
376  cterm_da += weight * d1 * d1 * d2 * d2;
377  const_da += weight * d1 * d1 * (-kappa);
378 
379  aterm_db += weight * d1 * d2 * d1 * d1;
380  bterm_db += weight * d1 * d2 * 2 * d1 * d2;
381  cterm_db += weight * d1 * d2 * d2 * d2;
382  const_db += weight * d1 * d2 * (-kappa);
383  }
384 
385  /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */
386  aterm_da -= cterm_da;
387  const_da += cterm_da * normKh;
388 
389  aterm_db -= cterm_db;
390  const_db += cterm_db * normKh;
391 
392  /* check for solvability of the linear system */
393  if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) &&
394  ((const_da != 0.0) || (const_db != 0.0))) {
395  linsolve(aterm_da, bterm_da, -const_da, aterm_db, bterm_db, -const_db, &a, &b);
396 
397  c = normKh - a;
398 
399  eigenvector(a, b, c, eig);
400  }
401  else {
402  /* region of v is planar */
403  eig[0] = 1.0;
404  eig[1] = 0.0;
405  }
406 
407  /* Although the eigenvectors of B are good estimates of the principal directions, it seems that
408  * which one is attached to which curvature direction is a bit arbitrary. This may be a bug in my
409  * implementation, or just a side-effect of the inaccuracy of B due to the discrete nature of the
410  * sampling.
411  *
412  * To overcome this behavior, we'll evaluate which assignment best matches the given eigenvectors
413  * by comparing the curvature estimates computed above and the curvatures calculated from the
414  * discrete differential operators.
415  */
416 
417  gts_vertex_principal_curvatures(0.5 * normKh, Kg, &K1, &K2);
418 
419  err_e1 = err_e2 = 0.0;
420  /* loop through the values previously saved */
421  for (e = 0; e < edge_count; e++) {
422  real weight, kappa, d1, d2;
423  real temp1, temp2;
424  real delta;
425 
426  weight = weights[e];
427  kappa = kappas[e];
428  d1 = d1s[e];
429  d2 = d2s[e];
430 
431  temp1 = fabs(eig[0] * d1 + eig[1] * d2);
432  temp1 = temp1 * temp1;
433  temp2 = fabs(eig[1] * d1 - eig[0] * d2);
434  temp2 = temp2 * temp2;
435 
436  /* err_e1 is for K1 associated with e1 */
437  delta = K1 * temp1 + K2 * temp2 - kappa;
438  err_e1 += weight * delta * delta;
439 
440  /* err_e2 is for K1 associated with e2 */
441  delta = K2 * temp1 + K1 * temp2 - kappa;
442  err_e2 += weight * delta * delta;
443  }
444  free(weights);
445  free(kappas);
446  free(d1s);
447  free(d2s);
448 
449  /* rotate eig by a right angle if that would decrease the error */
450  if (err_e2 < err_e1) {
451  real temp = eig[0];
452 
453  eig[0] = eig[1];
454  eig[1] = -temp;
455  }
456 
457  e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0];
458  e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1];
459  e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2];
460  e1.normalize();
461 
462  /* make N,e1,e2 a right handed coordinate system */
463  e2 = N ^ e1;
464  e2.normalize();
465 }
466 
467 namespace OGF {
468 
469 #if 0
470 inline static real angle(WOEdge *h)
471 {
472  const Vec3r &n1 = h->GetbFace()->GetNormal();
473  const Vec3r &n2 = h->GetaFace()->GetNormal();
474  const Vec3r v = h->GetVec();
475  real sine = (n1 ^ n2) * v / v.norm();
476  if (sine >= 1.0) {
477  return M_PI_2;
478  }
479  if (sine <= -1.0) {
480  return -M_PI_2;
481  }
482  return ::asin(sine);
483 }
484 #endif
485 
486 // precondition1: P is inside the sphere
487 // precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
488 static bool sphere_clip_vector(const Vec3r &O, real r, const Vec3r &P, Vec3r &V)
489 {
490  Vec3r W = P - O;
491  real a = V.squareNorm();
492  real b = 2.0 * V * W;
493  real c = W.squareNorm() - r * r;
494  real delta = b * b - 4 * a * c;
495  if (delta < 0) {
496  // Should not happen, but happens sometimes (numerical precision)
497  return true;
498  }
499  real t = -b + ::sqrt(delta) / (2.0 * a);
500  if (t < 0.0) {
501  // Should not happen, but happens sometimes (numerical precision)
502  return true;
503  }
504  if (t >= 1.0) {
505  // Inside the sphere
506  return false;
507  }
508 
509  V[0] = (t * V.x());
510  V[1] = (t * V.y());
511  V[2] = (t * V.z());
512 
513  return true;
514 }
515 
516 // TODO: check optimizations:
517 // use marking ? (measure *timings* ...)
519 {
520  // in case we have a non-manifold vertex, skip it...
521  if (start->isBoundary()) {
522  return;
523  }
524 
525  std::set<WVertex *> vertices;
526  const Vec3r &O = start->GetVertex();
527  std::stack<WVertex *> S;
528  S.push(start);
529  vertices.insert(start);
530  while (!S.empty()) {
531  WVertex *v = S.top();
532  S.pop();
533  if (v->isBoundary()) {
534  continue;
535  }
536  const Vec3r &P = v->GetVertex();
537  WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin();
538  WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end();
539  for (; woeit != woeitend; ++woeit) {
540  WOEdge *h = *woeit;
541  if ((v == start) || h->GetVec() * (O - P) > 0.0) {
542  Vec3r V(-1 * h->GetVec());
543  bool isect = sphere_clip_vector(O, radius, P, V);
544  assert(h->GetOwner()->GetNumberOfOEdges() ==
545  2); // Because otherwise v->isBoundary() would be true
547 
548  if (!isect) {
549  WVertex *w = h->GetaVertex();
550  if (vertices.find(w) == vertices.end()) {
551  vertices.insert(w);
552  S.push(w);
553  }
554  }
555  }
556  }
557  }
558 }
559 
561 {
562  // in case we have a non-manifold vertex, skip it...
563  if (start->isBoundary()) {
564  return;
565  }
566 
569  for (; woeit != woeitend; ++woeit) {
570  WOEdge *h = (*woeit)->twin();
572  WOEdge *hprev = h->getPrevOnFace();
573  nc.accumulate_dihedral_angle(hprev->GetVec(), hprev->GetAngle());
574  }
575 }
576 
577 } // namespace OGF
578 
579 } /* namespace Freestyle */
sqrt(x)+1/max(0
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
#define M_PI_2
Definition: BLI_math_base.h:23
#define M_PI
Definition: BLI_math_base.h:20
#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:105
value_type squareNorm() const
Definition: VecMat.h:100
value_type norm() const
Definition: VecMat.h:95
Vec< T, N > & normalize()
Definition: VecMat.h:105
short GetNumberOfOEdges()
Definition: WEdge.h:586
float getArea()
Definition: WEdge.cpp:405
bool getOppositeEdge(const WVertex *v, WOEdge *&e)
Definition: WEdge.cpp:376
WOEdge * GetNextOEdge(WOEdge *iOEdge)
Definition: WEdge.h:854
const vector< WOEdge * > & getEdgeList()
Definition: WEdge.h:718
const Vec3f & GetVec()
Definition: WEdge.h:412
WVertex * GetaVertex()
Definition: WEdge.h:387
WOEdge * twin()
Definition: WEdge.cpp:197
WEdge * GetOwner()
Definition: WEdge.h:407
WOEdge * getPrevOnFace()
Definition: WEdge.cpp:202
WVertex * GetbVertex()
Definition: WEdge.h:392
const float GetAngle()
Definition: WEdge.h:417
bool isBoundary()
Definition: WEdge.cpp:98
Vec3f & GetVertex()
Definition: WEdge.h:73
virtual incoming_edge_iterator incoming_edges_begin()
Definition: WEdge.cpp:128
virtual incoming_edge_iterator incoming_edges_end()
Definition: WEdge.cpp:142
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
static float P(float k)
Definition: math_interp.c:25
#define N
VecMat::Vec3< real > Vec3r
Definition: Geom.h:28
static bool sphere_clip_vector(const Vec3r &O, real r, const Vec3r &P, Vec3r &V)
Definition: Curvature.cpp:488
void compute_curvature_tensor(WVertex *start, real radius, NormalCycle &nc)
Definition: Curvature.cpp:518
void compute_curvature_tensor_one_ring(WVertex *start, NormalCycle &nc)
Definition: Curvature.cpp:560
inherits from class Rep
Definition: AppCanvas.cpp:18
void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, Vec3r &e2)
Definition: Curvature.cpp:210
bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
Definition: Curvature.cpp:136
static bool triangle_obtuse(WVertex *UNUSED(v), WFace *f)
Definition: Curvature.cpp:41
static unsigned c
Definition: RandGen.cpp:83
static real angle_from_cotan(WVertex *vo, WVertex *v1, WVertex *v2)
Definition: Curvature.cpp:69
bool gts_vertex_mean_curvature_normal(WVertex *v, Vec3r &Kh)
Definition: Curvature.cpp:86
static void eigenvector(real a, real b, real c, Vec3r e)
Definition: Curvature.cpp:198
static bool angle_obtuse(WVertex *v, WFace *f)
Definition: Curvature.cpp:29
static void linsolve(real m11, real m12, real b1, real m21, real m22, real b2, real *x1, real *x2)
Definition: Curvature.cpp:188
static real cotan(WVertex *vo, WVertex *v1, WVertex *v2)
Definition: Curvature.cpp:50
void gts_vertex_principal_curvatures(real Kh, real Kg, real *K1, real *K2)
Definition: Curvature.cpp:171
static unsigned a[3]
Definition: RandGen.cpp:78
double real
Definition: Precision.h:12
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])
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
CCL_NAMESPACE_BEGIN struct Window V