Blender  V3.3
mball_tessellate.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <ctype.h>
9 #include <float.h>
10 #include <math.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "MEM_guardedalloc.h"
16 
17 #include "DNA_meta_types.h"
18 #include "DNA_object_types.h"
19 #include "DNA_scene_types.h"
20 
21 #include "BLI_listbase.h"
22 #include "BLI_math.h"
23 #include "BLI_memarena.h"
24 #include "BLI_string_utils.h"
25 #include "BLI_utildefines.h"
26 
27 #include "BKE_global.h"
28 
29 #include "BKE_displist.h"
30 #include "BKE_mball_tessellate.h" /* own include */
31 #include "BKE_object.h"
32 #include "BKE_scene.h"
33 
34 #include "DEG_depsgraph.h"
35 #include "DEG_depsgraph_query.h"
36 
37 #include "BLI_strict_flags.h"
38 
39 /* experimental (faster) normal calculation */
40 // #define USE_ACCUM_NORMAL
41 
42 #define MBALL_ARRAY_LEN_INIT 4096
43 
44 /* Data types */
45 
46 typedef struct corner { /* corner of a cube */
47  int i, j, k; /* (i, j, k) is index within lattice */
48  float co[3], value; /* location and function value */
49  struct corner *next;
51 
52 typedef struct cube { /* partitioning cell (cube) */
53  int i, j, k; /* lattice location of cube */
54  CORNER *corners[8]; /* eight corners */
55 } CUBE;
56 
57 typedef struct cubes { /* linked list of cubes acting as stack */
58  CUBE cube; /* a single cube */
59  struct cubes *next; /* remaining elements */
61 
62 typedef struct centerlist { /* list of cube locations */
63  int i, j, k; /* cube location */
64  struct centerlist *next; /* remaining elements */
66 
67 typedef struct edgelist { /* list of edges */
68  int i1, j1, k1, i2, j2, k2; /* edge corner ids */
69  int vid; /* vertex id */
70  struct edgelist *next; /* remaining elements */
72 
73 typedef struct intlist { /* list of integers */
74  int i; /* an integer */
75  struct intlist *next; /* remaining elements */
77 
78 typedef struct intlists { /* list of list of integers */
79  INTLIST *list; /* a list of integers */
80  struct intlists *next; /* remaining elements */
82 
83 typedef struct Box { /* an AABB with pointer to metalelem */
84  float min[3], max[3];
85  const MetaElem *ml;
86 } Box;
87 
88 typedef struct MetaballBVHNode { /* BVH node */
89  Box bb[2]; /* AABB of children */
90  struct MetaballBVHNode *child[2];
92 
93 typedef struct process { /* parameters, storage */
94  float thresh, size; /* mball threshold, single cube size */
95  float delta; /* small delta for calculating normals */
96  unsigned int converge_res; /* converge procedure resolution (more = slower) */
97 
98  MetaElem **mainb; /* array of all metaelems */
99  unsigned int totelem, mem; /* number of metaelems */
100 
101  MetaballBVHNode metaball_bvh; /* The simplest bvh */
102  Box allbb; /* Bounding box of all metaelems */
103 
104  MetaballBVHNode **bvh_queue; /* Queue used during bvh traversal */
105  unsigned int bvh_queue_size;
106 
107  CUBES *cubes; /* stack of cubes waiting for polygonization */
108  CENTERLIST **centers; /* cube center hash table */
109  CORNER **corners; /* corner value hash table */
110  EDGELIST **edges; /* edge and vertex id hash table */
111 
112  int (*indices)[4]; /* output indices */
113  unsigned int totindex; /* size of memory allocated for indices */
114  unsigned int curindex; /* number of currently added indices */
115 
116  float (*co)[3], (*no)[3]; /* surface vertices - positions and normals */
117  unsigned int totvertex; /* memory size */
118  unsigned int curvertex; /* currently added vertices */
119 
120  /* memory allocation from common pool */
123 
124 /* Forward declarations */
125 static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2);
126 static void add_cube(PROCESS *process, int i, int j, int k);
127 static void make_face(PROCESS *process, int i1, int i2, int i3, int i4);
128 static void converge(PROCESS *process, const CORNER *c1, const CORNER *c2, float r_p[3]);
129 
130 /* ******************* SIMPLE BVH ********************* */
131 
132 static void make_box_union(const BoundBox *a, const Box *b, Box *r_out)
133 {
134  r_out->min[0] = min_ff(a->vec[0][0], b->min[0]);
135  r_out->min[1] = min_ff(a->vec[0][1], b->min[1]);
136  r_out->min[2] = min_ff(a->vec[0][2], b->min[2]);
137 
138  r_out->max[0] = max_ff(a->vec[6][0], b->max[0]);
139  r_out->max[1] = max_ff(a->vec[6][1], b->max[1]);
140  r_out->max[2] = max_ff(a->vec[6][2], b->max[2]);
141 }
142 
143 static void make_box_from_metaelem(Box *r, const MetaElem *ml)
144 {
145  copy_v3_v3(r->max, ml->bb->vec[6]);
146  copy_v3_v3(r->min, ml->bb->vec[0]);
147  r->ml = ml;
148 }
149 
155 static unsigned int partition_mainb(
156  MetaElem **mainb, unsigned int start, unsigned int end, unsigned int s, float div)
157 {
158  unsigned int i = start, j = end - 1;
159  div *= 2.0f;
160 
161  while (1) {
162  while (i < j && div > (mainb[i]->bb->vec[6][s] + mainb[i]->bb->vec[0][s])) {
163  i++;
164  }
165  while (j > i && div < (mainb[j]->bb->vec[6][s] + mainb[j]->bb->vec[0][s])) {
166  j--;
167  }
168 
169  if (i >= j) {
170  break;
171  }
172 
173  SWAP(MetaElem *, mainb[i], mainb[j]);
174  i++;
175  j--;
176  }
177 
178  if (i == start) {
179  i++;
180  }
181 
182  return i;
183 }
184 
190  unsigned int start,
191  unsigned int end,
192  const Box *allbox)
193 {
194  unsigned int part, j, s;
195  float dim[3], div;
196 
197  /* Maximum bvh queue size is number of nodes which are made, equals calls to this function. */
199 
200  dim[0] = allbox->max[0] - allbox->min[0];
201  dim[1] = allbox->max[1] - allbox->min[1];
202  dim[2] = allbox->max[2] - allbox->min[2];
203 
204  s = 0;
205  if (dim[1] > dim[0] && dim[1] > dim[2]) {
206  s = 1;
207  }
208  else if (dim[2] > dim[1] && dim[2] > dim[0]) {
209  s = 2;
210  }
211 
212  div = allbox->min[s] + (dim[s] / 2.0f);
213 
214  part = partition_mainb(process->mainb, start, end, s, div);
215 
216  make_box_from_metaelem(&node->bb[0], process->mainb[start]);
217  node->child[0] = NULL;
218 
219  if (part > start + 1) {
220  for (j = start; j < part; j++) {
221  make_box_union(process->mainb[j]->bb, &node->bb[0], &node->bb[0]);
222  }
223 
225  build_bvh_spatial(process, node->child[0], start, part, &node->bb[0]);
226  }
227 
228  node->child[1] = NULL;
229  if (part < end) {
230  make_box_from_metaelem(&node->bb[1], process->mainb[part]);
231 
232  if (part < end - 1) {
233  for (j = part; j < end; j++) {
234  make_box_union(process->mainb[j]->bb, &node->bb[1], &node->bb[1]);
235  }
236 
238  build_bvh_spatial(process, node->child[1], part, end, &node->bb[1]);
239  }
240  }
241  else {
242  INIT_MINMAX(node->bb[1].min, node->bb[1].max);
243  }
244 }
245 
246 /* ******************** ARITH ************************* */
247 
261 #define L 0 /* Left direction: -x, -i. */
262 #define R 1 /* Right direction: +x, +i. */
263 #define B 2 /* Bottom direction: -y, -j. */
264 #define T 3 /* Top direction: +y, +j. */
265 #define N 4 /* Near direction: -z, -k. */
266 #define F 5 /* Far direction: +z, +k. */
267 #define LBN 0 /* Left bottom near corner. */
268 #define LBF 1 /* Left bottom far corner. */
269 #define LTN 2 /* Left top near corner. */
270 #define LTF 3 /* Left top far corner. */
271 #define RBN 4 /* Right bottom near corner. */
272 #define RBF 5 /* Right bottom far corner. */
273 #define RTN 6 /* Right top near corner. */
274 #define RTF 7 /* Right top far corner. */
275 
281 #define HASHBIT (5)
283 #define HASHSIZE (size_t)(1 << (3 * HASHBIT))
284 
285 #define HASH(i, j, k) ((((((i)&31) << 5) | ((j)&31)) << 5) | ((k)&31))
286 
287 #define MB_BIT(i, bit) (((i) >> (bit)) & 1)
288 // #define FLIP(i, bit) ((i) ^ 1 << (bit)) /* flip the given bit of i */
289 
290 /* ******************** DENSITY COPMPUTATION ********************* */
291 
300 static float densfunc(const MetaElem *ball, float x, float y, float z)
301 {
302  float dist2;
303  float dvec[3] = {x, y, z};
304 
305  mul_m4_v3((const float(*)[4])ball->imat, dvec);
306 
307  switch (ball->type) {
308  case MB_BALL:
309  /* do nothing */
310  break;
311  case MB_CUBE:
312  if (dvec[2] > ball->expz) {
313  dvec[2] -= ball->expz;
314  }
315  else if (dvec[2] < -ball->expz) {
316  dvec[2] += ball->expz;
317  }
318  else {
319  dvec[2] = 0.0;
320  }
322  case MB_PLANE:
323  if (dvec[1] > ball->expy) {
324  dvec[1] -= ball->expy;
325  }
326  else if (dvec[1] < -ball->expy) {
327  dvec[1] += ball->expy;
328  }
329  else {
330  dvec[1] = 0.0;
331  }
333  case MB_TUBE:
334  if (dvec[0] > ball->expx) {
335  dvec[0] -= ball->expx;
336  }
337  else if (dvec[0] < -ball->expx) {
338  dvec[0] += ball->expx;
339  }
340  else {
341  dvec[0] = 0.0;
342  }
343  break;
344  case MB_ELIPSOID:
345  dvec[0] /= ball->expx;
346  dvec[1] /= ball->expy;
347  dvec[2] /= ball->expz;
348  break;
349 
350  /* *** deprecated, could be removed?, do-versioned at least *** */
351  case MB_TUBEX:
352  if (dvec[0] > ball->len) {
353  dvec[0] -= ball->len;
354  }
355  else if (dvec[0] < -ball->len) {
356  dvec[0] += ball->len;
357  }
358  else {
359  dvec[0] = 0.0;
360  }
361  break;
362  case MB_TUBEY:
363  if (dvec[1] > ball->len) {
364  dvec[1] -= ball->len;
365  }
366  else if (dvec[1] < -ball->len) {
367  dvec[1] += ball->len;
368  }
369  else {
370  dvec[1] = 0.0;
371  }
372  break;
373  case MB_TUBEZ:
374  if (dvec[2] > ball->len) {
375  dvec[2] -= ball->len;
376  }
377  else if (dvec[2] < -ball->len) {
378  dvec[2] += ball->len;
379  }
380  else {
381  dvec[2] = 0.0;
382  }
383  break;
384  /* *** end deprecated *** */
385  }
386 
387  /* ball->rad2 is inverse of squared rad */
388  dist2 = 1.0f - (len_squared_v3(dvec) * ball->rad2);
389 
390  /* ball->s is negative if metaball is negative */
391  return (dist2 < 0.0f) ? 0.0f : (ball->s * dist2 * dist2 * dist2);
392 }
393 
398 static float metaball(PROCESS *process, float x, float y, float z)
399 {
400  float dens = 0.0f;
401  unsigned int front = 0, back = 0;
403 
404  process->bvh_queue[front++] = &process->metaball_bvh;
405 
406  while (front != back) {
407  node = process->bvh_queue[back++];
408 
409  for (int i = 0; i < 2; i++) {
410  if ((node->bb[i].min[0] <= x) && (node->bb[i].max[0] >= x) && (node->bb[i].min[1] <= y) &&
411  (node->bb[i].max[1] >= y) && (node->bb[i].min[2] <= z) && (node->bb[i].max[2] >= z)) {
412  if (node->child[i]) {
413  process->bvh_queue[front++] = node->child[i];
414  }
415  else {
416  dens += densfunc(node->bb[i].ml, x, y, z);
417  }
418  }
419  }
420  }
421 
422  return process->thresh - dens;
423 }
424 
428 static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
429 {
430  int *cur;
431 
432 #ifdef USE_ACCUM_NORMAL
433  float n[3];
434 #endif
435 
438  process->indices = MEM_reallocN(process->indices, sizeof(int[4]) * process->totindex);
439  }
440 
441  cur = process->indices[process->curindex++];
442 
443  /* #DispList supports array drawing, treat tri's as fake quad. */
444 
445  cur[0] = i1;
446  cur[1] = i2;
447  cur[2] = i3;
448  cur[3] = i4;
449 
450 #ifdef USE_ACCUM_NORMAL
451  if (i4 == i3) {
452  normal_tri_v3(n, process->co[i1], process->co[i2], process->co[i3]);
454  process->no[i2],
455  process->no[i3],
456  NULL,
457  n,
458  process->co[i1],
459  process->co[i2],
460  process->co[i3],
461  NULL);
462  }
463  else {
464  normal_quad_v3(n, process->co[i1], process->co[i2], process->co[i3], process->co[i4]);
466  process->no[i2],
467  process->no[i3],
468  process->no[i4],
469  n,
470  process->co[i1],
471  process->co[i2],
472  process->co[i3],
473  process->co[i4]);
474  }
475 #endif
476 }
477 
478 /* Frees allocated memory */
480 {
481  if (process->corners) {
483  }
484  if (process->edges) {
486  }
487  if (process->centers) {
489  }
490  if (process->mainb) {
492  }
493  if (process->bvh_queue) {
495  }
496  if (process->pgn_elements) {
498  }
499 }
500 
501 /* **************** POLYGONIZATION ************************ */
502 
503 /**** Cubical Polygonization (optional) ****/
504 
505 #define LB 0 /* left bottom edge */
506 #define LT 1 /* left top edge */
507 #define LN 2 /* left near edge */
508 #define LF 3 /* left far edge */
509 #define RB 4 /* right bottom edge */
510 #define RT 5 /* right top edge */
511 #define RN 6 /* right near edge */
512 #define RF 7 /* right far edge */
513 #define BN 8 /* bottom near edge */
514 #define BF 9 /* bottom far edge */
515 #define TN 10 /* top near edge */
516 #define TF 11 /* top far edge */
517 
518 static INTLISTS *cubetable[256];
519 static char faces[256];
520 
521 /* edge: LB, LT, LN, LF, RB, RT, RN, RF, BN, BF, TN, TF */
522 static int corner1[12] = {
523  LBN,
524  LTN,
525  LBN,
526  LBF,
527  RBN,
528  RTN,
529  RBN,
530  RBF,
531  LBN,
532  LBF,
533  LTN,
534  LTF,
535 };
536 static int corner2[12] = {
537  LBF,
538  LTF,
539  LTN,
540  LTF,
541  RBF,
542  RTF,
543  RTN,
544  RTF,
545  RBN,
546  RBF,
547  RTN,
548  RTF,
549 };
550 static int leftface[12] = {
551  B,
552  L,
553  L,
554  F,
555  R,
556  T,
557  N,
558  R,
559  N,
560  B,
561  T,
562  F,
563 };
564 /* face on left when going corner1 to corner2 */
565 static int rightface[12] = {
566  L,
567  T,
568  N,
569  L,
570  B,
571  R,
572  R,
573  F,
574  B,
575  F,
576  N,
577  T,
578 };
579 /* face on right when going corner1 to corner2 */
580 
584 static void docube(PROCESS *process, CUBE *cube)
585 {
586  INTLISTS *polys;
587  CORNER *c1, *c2;
588  int i, index = 0, count, indexar[8];
589 
590  /* Determine which case cube falls into. */
591  for (i = 0; i < 8; i++) {
592  if (cube->corners[i]->value > 0.0f) {
593  index += (1 << i);
594  }
595  }
596 
597  /* Using faces[] table, adds neighboring cube if surface intersects face in this direction. */
598  if (MB_BIT(faces[index], 0)) {
599  add_cube(process, cube->i - 1, cube->j, cube->k);
600  }
601  if (MB_BIT(faces[index], 1)) {
602  add_cube(process, cube->i + 1, cube->j, cube->k);
603  }
604  if (MB_BIT(faces[index], 2)) {
605  add_cube(process, cube->i, cube->j - 1, cube->k);
606  }
607  if (MB_BIT(faces[index], 3)) {
608  add_cube(process, cube->i, cube->j + 1, cube->k);
609  }
610  if (MB_BIT(faces[index], 4)) {
611  add_cube(process, cube->i, cube->j, cube->k - 1);
612  }
613  if (MB_BIT(faces[index], 5)) {
614  add_cube(process, cube->i, cube->j, cube->k + 1);
615  }
616 
617  /* Using cubetable[], determines polygons for output. */
618  for (polys = cubetable[index]; polys; polys = polys->next) {
619  INTLIST *edges;
620 
621  count = 0;
622  /* Sets needed vertex id's lying on the edges. */
623  for (edges = polys->list; edges; edges = edges->next) {
624  c1 = cube->corners[corner1[edges->i]];
625  c2 = cube->corners[corner2[edges->i]];
626 
627  indexar[count] = vertid(process, c1, c2);
628  count++;
629  }
630 
631  /* Adds faces to output. */
632  if (count > 2) {
633  switch (count) {
634  case 3:
635  make_face(process, indexar[2], indexar[1], indexar[0], indexar[0]); /* triangle */
636  break;
637  case 4:
638  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
639  break;
640  case 5:
641  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
642  make_face(process, indexar[4], indexar[3], indexar[0], indexar[0]); /* triangle */
643  break;
644  case 6:
645  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
646  make_face(process, indexar[5], indexar[4], indexar[3], indexar[0]);
647  break;
648  case 7:
649  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
650  make_face(process, indexar[5], indexar[4], indexar[3], indexar[0]);
651  make_face(process, indexar[6], indexar[5], indexar[0], indexar[0]); /* triangle */
652  break;
653  }
654  }
655  }
656 }
657 
662 static CORNER *setcorner(PROCESS *process, int i, int j, int k)
663 {
664  /* for speed, do corner value caching here */
665  CORNER *c;
666  int index;
667 
668  /* does corner exist? */
669  index = HASH(i, j, k);
670  c = process->corners[index];
671 
672  for (; c != NULL; c = c->next) {
673  if (c->i == i && c->j == j && c->k == k) {
674  return c;
675  }
676  }
677 
679 
680  c->i = i;
681  c->co[0] = ((float)i - 0.5f) * process->size;
682  c->j = j;
683  c->co[1] = ((float)j - 0.5f) * process->size;
684  c->k = k;
685  c->co[2] = ((float)k - 0.5f) * process->size;
686 
687  c->value = metaball(process, c->co[0], c->co[1], c->co[2]);
688 
689  c->next = process->corners[index];
690  process->corners[index] = c;
691 
692  return c;
693 }
694 
698 static int nextcwedge(int edge, int face)
699 {
700  switch (edge) {
701  case LB:
702  return (face == L) ? LF : BN;
703  case LT:
704  return (face == L) ? LN : TF;
705  case LN:
706  return (face == L) ? LB : TN;
707  case LF:
708  return (face == L) ? LT : BF;
709  case RB:
710  return (face == R) ? RN : BF;
711  case RT:
712  return (face == R) ? RF : TN;
713  case RN:
714  return (face == R) ? RT : BN;
715  case RF:
716  return (face == R) ? RB : TF;
717  case BN:
718  return (face == B) ? RB : LN;
719  case BF:
720  return (face == B) ? LB : RF;
721  case TN:
722  return (face == T) ? LT : RN;
723  case TF:
724  return (face == T) ? RT : LF;
725  }
726  return 0;
727 }
728 
732 static int otherface(int edge, int face)
733 {
734  int other = leftface[edge];
735  return face == other ? rightface[edge] : other;
736 }
737 
741 static void makecubetable(void)
742 {
743  static bool is_done = false;
744  int i, e, c, done[12], pos[8];
745 
746  if (is_done) {
747  return;
748  }
749  is_done = true;
750 
751  for (i = 0; i < 256; i++) {
752  for (e = 0; e < 12; e++) {
753  done[e] = 0;
754  }
755  for (c = 0; c < 8; c++) {
756  pos[c] = MB_BIT(i, c);
757  }
758  for (e = 0; e < 12; e++) {
759  if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) {
760  INTLIST *ints = NULL;
761  INTLISTS *lists = MEM_callocN(sizeof(INTLISTS), "mball_intlist");
762  int start = e, edge = e;
763 
764  /* get face that is to right of edge from pos to neg corner: */
765  int face = pos[corner1[e]] ? rightface[e] : leftface[e];
766 
767  while (1) {
768  edge = nextcwedge(edge, face);
769  done[edge] = 1;
770  if (pos[corner1[edge]] != pos[corner2[edge]]) {
771  INTLIST *tmp = ints;
772 
773  ints = MEM_callocN(sizeof(INTLIST), "mball_intlist");
774  ints->i = edge;
775  ints->next = tmp; /* add edge to head of list */
776 
777  if (edge == start) {
778  break;
779  }
780  face = otherface(edge, face);
781  }
782  }
783  lists->list = ints; /* add ints to head of table entry */
784  lists->next = cubetable[i];
785  cubetable[i] = lists;
786  }
787  }
788  }
789 
790  for (i = 0; i < 256; i++) {
791  INTLISTS *polys;
792  faces[i] = 0;
793  for (polys = cubetable[i]; polys; polys = polys->next) {
794  INTLIST *edges;
795 
796  for (edges = polys->list; edges; edges = edges->next) {
797  if (ELEM(edges->i, LB, LT, LN, LF)) {
798  faces[i] |= 1 << L;
799  }
800  if (ELEM(edges->i, RB, RT, RN, RF)) {
801  faces[i] |= 1 << R;
802  }
803  if (ELEM(edges->i, LB, RB, BN, BF)) {
804  faces[i] |= 1 << B;
805  }
806  if (ELEM(edges->i, LT, RT, TN, TF)) {
807  faces[i] |= 1 << T;
808  }
809  if (ELEM(edges->i, LN, RN, BN, TN)) {
810  faces[i] |= 1 << N;
811  }
812  if (ELEM(edges->i, LF, RF, BF, TF)) {
813  faces[i] |= 1 << F;
814  }
815  }
816  }
817  }
818 }
819 
821 {
822  for (int i = 0; i < 256; i++) {
823  INTLISTS *lists = cubetable[i];
824  while (lists) {
825  INTLISTS *nlists = lists->next;
826 
827  INTLIST *ints = lists->list;
828  while (ints) {
829  INTLIST *nints = ints->next;
830  MEM_freeN(ints);
831  ints = nints;
832  }
833 
834  MEM_freeN(lists);
835  lists = nlists;
836  }
837  cubetable[i] = NULL;
838  }
839 }
840 
841 /**** Storage ****/
842 
846 static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
847 {
848  int index;
849  CENTERLIST *newc, *l, *q;
850 
851  index = HASH(i, j, k);
852  q = table[index];
853 
854  for (l = q; l != NULL; l = l->next) {
855  if (l->i == i && l->j == j && l->k == k) {
856  return 1;
857  }
858  }
859 
861  newc->i = i;
862  newc->j = j;
863  newc->k = k;
864  newc->next = q;
865  table[index] = newc;
866 
867  return 0;
868 }
869 
873 static void setedge(PROCESS *process, int i1, int j1, int k1, int i2, int j2, int k2, int vid)
874 {
875  int index;
876  EDGELIST *newe;
877 
878  if (i1 > i2 || (i1 == i2 && (j1 > j2 || (j1 == j2 && k1 > k2)))) {
879  int t = i1;
880  i1 = i2;
881  i2 = t;
882  t = j1;
883  j1 = j2;
884  j2 = t;
885  t = k1;
886  k1 = k2;
887  k2 = t;
888  }
889  index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
891 
892  newe->i1 = i1;
893  newe->j1 = j1;
894  newe->k1 = k1;
895  newe->i2 = i2;
896  newe->j2 = j2;
897  newe->k2 = k2;
898  newe->vid = vid;
899  newe->next = process->edges[index];
900  process->edges[index] = newe;
901 }
902 
906 static int getedge(EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, int k2)
907 {
908  EDGELIST *q;
909 
910  if (i1 > i2 || (i1 == i2 && (j1 > j2 || (j1 == j2 && k1 > k2)))) {
911  int t = i1;
912  i1 = i2;
913  i2 = t;
914  t = j1;
915  j1 = j2;
916  j2 = t;
917  t = k1;
918  k1 = k2;
919  k2 = t;
920  }
921  q = table[HASH(i1, j1, k1) + HASH(i2, j2, k2)];
922  for (; q != NULL; q = q->next) {
923  if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 && q->i2 == i2 && q->j2 == j2 && q->k2 == k2) {
924  return q->vid;
925  }
926  }
927  return -1;
928 }
929 
933 static void addtovertices(PROCESS *process, const float v[3], const float no[3])
934 {
937  process->co = MEM_reallocN(process->co, process->totvertex * sizeof(float[3]));
938  process->no = MEM_reallocN(process->no, process->totvertex * sizeof(float[3]));
939  }
940 
943 
944  process->curvertex++;
945 }
946 
947 #ifndef USE_ACCUM_NORMAL
953 static void vnormal(PROCESS *process, const float point[3], float r_no[3])
954 {
955  const float delta = process->delta;
956  const float f = metaball(process, point[0], point[1], point[2]);
957 
958  r_no[0] = metaball(process, point[0] + delta, point[1], point[2]) - f;
959  r_no[1] = metaball(process, point[0], point[1] + delta, point[2]) - f;
960  r_no[2] = metaball(process, point[0], point[1], point[2] + delta) - f;
961 }
962 #endif /* USE_ACCUM_NORMAL */
963 
969 static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2)
970 {
971  float v[3], no[3];
972  int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
973 
974  if (vid != -1) {
975  return vid; /* previously computed */
976  }
977 
978  converge(process, c1, c2, v); /* position */
979 
980 #ifdef USE_ACCUM_NORMAL
981  zero_v3(no);
982 #else
983  vnormal(process, v, no);
984 #endif
985 
986  addtovertices(process, v, no); /* save vertex */
987  vid = (int)process->curvertex - 1;
988  setedge(process, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
989 
990  return vid;
991 }
992 
997 static void converge(PROCESS *process, const CORNER *c1, const CORNER *c2, float r_p[3])
998 {
999  float c1_value, c1_co[3];
1000  float c2_value, c2_co[3];
1001 
1002  if (c1->value < c2->value) {
1003  c1_value = c2->value;
1004  copy_v3_v3(c1_co, c2->co);
1005  c2_value = c1->value;
1006  copy_v3_v3(c2_co, c1->co);
1007  }
1008  else {
1009  c1_value = c1->value;
1010  copy_v3_v3(c1_co, c1->co);
1011  c2_value = c2->value;
1012  copy_v3_v3(c2_co, c2->co);
1013  }
1014 
1015  for (uint i = 0; i < process->converge_res; i++) {
1016  interp_v3_v3v3(r_p, c1_co, c2_co, 0.5f);
1017  float dens = metaball(process, r_p[0], r_p[1], r_p[2]);
1018 
1019  if (dens > 0.0f) {
1020  c1_value = dens;
1021  copy_v3_v3(c1_co, r_p);
1022  }
1023  else {
1024  c2_value = dens;
1025  copy_v3_v3(c2_co, r_p);
1026  }
1027  }
1028 
1029  float tmp = -c1_value / (c2_value - c1_value);
1030  interp_v3_v3v3(r_p, c1_co, c2_co, tmp);
1031 }
1032 
1036 static void add_cube(PROCESS *process, int i, int j, int k)
1037 {
1038  CUBES *ncube;
1039  int n;
1040 
1041  /* test if cube has been found before */
1042  if (setcenter(process, process->centers, i, j, k) == 0) {
1043  /* push cube on stack: */
1044  ncube = BLI_memarena_alloc(process->pgn_elements, sizeof(CUBES));
1045  ncube->next = process->cubes;
1046  process->cubes = ncube;
1047 
1048  ncube->cube.i = i;
1049  ncube->cube.j = j;
1050  ncube->cube.k = k;
1051 
1052  /* set corners of initial cube: */
1053  for (n = 0; n < 8; n++) {
1054  ncube->cube.corners[n] = setcorner(
1055  process, i + MB_BIT(n, 2), j + MB_BIT(n, 1), k + MB_BIT(n, 0));
1056  }
1057  }
1058 }
1059 
1060 static void next_lattice(int r[3], const float pos[3], const float size)
1061 {
1062  r[0] = (int)ceil((pos[0] / size) + 0.5f);
1063  r[1] = (int)ceil((pos[1] / size) + 0.5f);
1064  r[2] = (int)ceil((pos[2] / size) + 0.5f);
1065 }
1066 static void prev_lattice(int r[3], const float pos[3], const float size)
1067 {
1068  next_lattice(r, pos, size);
1069  r[0]--;
1070  r[1]--;
1071  r[2]--;
1072 }
1073 static void closest_latice(int r[3], const float pos[3], const float size)
1074 {
1075  r[0] = (int)floorf(pos[0] / size + 1.0f);
1076  r[1] = (int)floorf(pos[1] / size + 1.0f);
1077  r[2] = (int)floorf(pos[2] / size + 1.0f);
1078 }
1079 
1083 static void find_first_points(PROCESS *process, const unsigned int em)
1084 {
1085  const MetaElem *ml;
1086  int center[3], lbn[3], rtf[3], it[3], dir[3], add[3];
1087  float tmp[3], a, b;
1088 
1089  ml = process->mainb[em];
1090 
1091  mid_v3_v3v3(tmp, ml->bb->vec[0], ml->bb->vec[6]);
1093  prev_lattice(lbn, ml->bb->vec[0], process->size);
1094  next_lattice(rtf, ml->bb->vec[6], process->size);
1095 
1096  for (dir[0] = -1; dir[0] <= 1; dir[0]++) {
1097  for (dir[1] = -1; dir[1] <= 1; dir[1]++) {
1098  for (dir[2] = -1; dir[2] <= 1; dir[2]++) {
1099  if (dir[0] == 0 && dir[1] == 0 && dir[2] == 0) {
1100  continue;
1101  }
1102 
1103  copy_v3_v3_int(it, center);
1104 
1105  b = setcorner(process, it[0], it[1], it[2])->value;
1106  do {
1107  it[0] += dir[0];
1108  it[1] += dir[1];
1109  it[2] += dir[2];
1110  a = b;
1111  b = setcorner(process, it[0], it[1], it[2])->value;
1112 
1113  if (a * b < 0.0f) {
1114  add[0] = it[0] - dir[0];
1115  add[1] = it[1] - dir[1];
1116  add[2] = it[2] - dir[2];
1117  DO_MIN(it, add);
1118  add_cube(process, add[0], add[1], add[2]);
1119  break;
1120  }
1121  } while ((it[0] > lbn[0]) && (it[1] > lbn[1]) && (it[2] > lbn[2]) && (it[0] < rtf[0]) &&
1122  (it[1] < rtf[1]) && (it[2] < rtf[2]));
1123  }
1124  }
1125  }
1126 }
1127 
1135 {
1136  CUBE c;
1137 
1138  process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
1139  process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
1140  process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
1142  "Metaball BVH Queue");
1143 
1144  makecubetable();
1145 
1146  for (uint i = 0; i < process->totelem; i++) {
1148  }
1149 
1150  while (process->cubes != NULL) {
1151  c = process->cubes->cube;
1153 
1154  docube(process, &c);
1155  }
1156 }
1157 
1164 {
1165  Scene *sce_iter = scene;
1166  Base *base;
1167  Object *bob;
1168  MetaBall *mb;
1169  const MetaElem *ml;
1170  float obinv[4][4], obmat[4][4];
1171  unsigned int i;
1172  int obnr, zero_size = 0;
1173  char obname[MAX_ID_NAME];
1174  SceneBaseIter iter;
1175  const eEvaluationMode deg_eval_mode = DEG_get_mode(depsgraph);
1176  const short parenting_dupli_transflag = (OB_DUPLIFACES | OB_DUPLIVERTS);
1177 
1178  copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from BKE_scene_base_iter_next */
1179  invert_m4_m4(obinv, ob->obmat);
1180 
1181  BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
1182 
1183  /* make main array */
1184  BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 0, NULL, NULL);
1185  while (BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 1, &base, &bob)) {
1186  if (bob->type == OB_MBALL) {
1187  zero_size = 0;
1188  ml = NULL;
1189 
1190  /* If this metaball is the original that's used for duplication, only have it visible when
1191  * the instancer is visible too. */
1192  if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != NULL &&
1193  (ob->parent->transflag & parenting_dupli_transflag) != 0 &&
1194  (BKE_object_visibility(ob->parent, deg_eval_mode) & OB_VISIBLE_SELF) == 0) {
1195  continue;
1196  }
1197 
1198  if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
1199  mb = ob->data;
1200 
1201  if (mb->editelems) {
1202  ml = mb->editelems->first;
1203  }
1204  else {
1205  ml = mb->elems.first;
1206  }
1207  }
1208  else {
1209  char name[MAX_ID_NAME];
1210  int nr;
1211 
1212  BLI_split_name_num(name, &nr, bob->id.name + 2, '.');
1213  if (STREQ(obname, name)) {
1214  mb = bob->data;
1215 
1216  if (mb->editelems) {
1217  ml = mb->editelems->first;
1218  }
1219  else {
1220  ml = mb->elems.first;
1221  }
1222  }
1223  }
1224 
1225  /* when metaball object has zero scale, then MetaElem to this MetaBall
1226  * will not be put to mainb array */
1227  if (has_zero_axis_m4(bob->obmat)) {
1228  zero_size = 1;
1229  }
1230  else if (bob->parent) {
1231  struct Object *pob = bob->parent;
1232  while (pob) {
1233  if (has_zero_axis_m4(pob->obmat)) {
1234  zero_size = 1;
1235  break;
1236  }
1237  pob = pob->parent;
1238  }
1239  }
1240 
1241  if (zero_size) {
1242  while (ml) {
1243  ml = ml->next;
1244  }
1245  }
1246  else {
1247  while (ml) {
1248  if (!(ml->flag & MB_HIDE)) {
1249  float pos[4][4], rot[4][4];
1250  float expx, expy, expz;
1251  float tempmin[3], tempmax[3];
1252 
1253  MetaElem *new_ml;
1254 
1255  /* make a copy because of duplicates */
1256  new_ml = BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem));
1257  *(new_ml) = *ml;
1258  new_ml->bb = BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox));
1259  new_ml->mat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
1260  new_ml->imat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
1261 
1262  /* too big stiffness seems only ugly due to linear interpolation
1263  * no need to have possibility for too big stiffness */
1264  if (ml->s > 10.0f) {
1265  new_ml->s = 10.0f;
1266  }
1267  else {
1268  new_ml->s = ml->s;
1269  }
1270 
1271  /* if metaball is negative, set stiffness negative */
1272  if (new_ml->flag & MB_NEGATIVE) {
1273  new_ml->s = -new_ml->s;
1274  }
1275 
1276  /* Translation of MetaElem */
1277  unit_m4(pos);
1278  pos[3][0] = ml->x;
1279  pos[3][1] = ml->y;
1280  pos[3][2] = ml->z;
1281 
1282  /* Rotation of MetaElem is stored in quat */
1283  quat_to_mat4(rot, ml->quat);
1284 
1285  /* Matrix multiply is as follows:
1286  * basis object space ->
1287  * world ->
1288  * ml object space ->
1289  * position ->
1290  * rotation ->
1291  * ml local space
1292  */
1293  mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->obmat, pos, rot);
1294  /* ml local space -> basis object space */
1295  invert_m4_m4((float(*)[4])new_ml->imat, (float(*)[4])new_ml->mat);
1296 
1297  /* rad2 is inverse of squared radius */
1298  new_ml->rad2 = 1 / (ml->rad * ml->rad);
1299 
1300  /* initial dimensions = radius */
1301  expx = ml->rad;
1302  expy = ml->rad;
1303  expz = ml->rad;
1304 
1305  switch (ml->type) {
1306  case MB_BALL:
1307  break;
1308  case MB_CUBE: /* cube is "expanded" by expz, expy and expx */
1309  expz += ml->expz;
1311  case MB_PLANE: /* plane is "expanded" by expy and expx */
1312  expy += ml->expy;
1314  case MB_TUBE: /* tube is "expanded" by expx */
1315  expx += ml->expx;
1316  break;
1317  case MB_ELIPSOID: /* ellipsoid is "stretched" by exp* */
1318  expx *= ml->expx;
1319  expy *= ml->expy;
1320  expz *= ml->expz;
1321  break;
1322  }
1323 
1324  /* untransformed Bounding Box of MetaElem */
1325  /* TODO: its possible the elem type has been changed and the exp*
1326  * values can use a fallback. */
1327  copy_v3_fl3(new_ml->bb->vec[0], -expx, -expy, -expz); /* 0 */
1328  copy_v3_fl3(new_ml->bb->vec[1], +expx, -expy, -expz); /* 1 */
1329  copy_v3_fl3(new_ml->bb->vec[2], +expx, +expy, -expz); /* 2 */
1330  copy_v3_fl3(new_ml->bb->vec[3], -expx, +expy, -expz); /* 3 */
1331  copy_v3_fl3(new_ml->bb->vec[4], -expx, -expy, +expz); /* 4 */
1332  copy_v3_fl3(new_ml->bb->vec[5], +expx, -expy, +expz); /* 5 */
1333  copy_v3_fl3(new_ml->bb->vec[6], +expx, +expy, +expz); /* 6 */
1334  copy_v3_fl3(new_ml->bb->vec[7], -expx, +expy, +expz); /* 7 */
1335 
1336  /* transformation of Metalem bb */
1337  for (i = 0; i < 8; i++) {
1338  mul_m4_v3((float(*)[4])new_ml->mat, new_ml->bb->vec[i]);
1339  }
1340 
1341  /* find max and min of transformed bb */
1342  INIT_MINMAX(tempmin, tempmax);
1343  for (i = 0; i < 8; i++) {
1344  DO_MINMAX(new_ml->bb->vec[i], tempmin, tempmax);
1345  }
1346 
1347  /* set only point 0 and 6 - AABB of Metaelem */
1348  copy_v3_v3(new_ml->bb->vec[0], tempmin);
1349  copy_v3_v3(new_ml->bb->vec[6], tempmax);
1350 
1351  /* add new_ml to mainb[] */
1352  if (UNLIKELY(process->totelem == process->mem)) {
1353  process->mem = process->mem * 2 + 10;
1355  }
1356  process->mainb[process->totelem++] = new_ml;
1357  }
1358  ml = ml->next;
1359  }
1360  }
1361  }
1362  }
1363 
1364  /* compute AABB of all Metaelems */
1365  if (process->totelem > 0) {
1366  copy_v3_v3(process->allbb.min, process->mainb[0]->bb->vec[0]);
1367  copy_v3_v3(process->allbb.max, process->mainb[0]->bb->vec[6]);
1368  for (i = 1; i < process->totelem; i++) {
1370  }
1371  }
1372 }
1373 
1375 {
1376  PROCESS process = {0};
1377  const bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
1378 
1379  MetaBall *mb = ob->data;
1380 
1381  process.thresh = mb->thresh;
1382 
1383  if (process.thresh < 0.001f) {
1384  process.converge_res = 16;
1385  }
1386  else if (process.thresh < 0.01f) {
1387  process.converge_res = 8;
1388  }
1389  else if (process.thresh < 0.1f) {
1390  process.converge_res = 4;
1391  }
1392  else {
1393  process.converge_res = 2;
1394  }
1395 
1396  if (!is_render && (mb->flag == MB_UPDATE_NEVER)) {
1397  return;
1398  }
1399  if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) {
1400  return;
1401  }
1402 
1403  if (is_render) {
1404  process.size = mb->rendersize;
1405  }
1406  else {
1407  process.size = mb->wiresize;
1408  if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_HALFRES) {
1409  process.size *= 2.0f;
1410  }
1411  }
1412 
1413  process.delta = process.size * 0.001f;
1414 
1416 
1417  /* initialize all mainb (MetaElems) */
1418  init_meta(depsgraph, &process, scene, ob);
1419  if (process.totelem == 0) {
1421  return;
1422  }
1423 
1425 
1426  /* Don't polygonize meta-balls with too high resolution (base mball too small)
1427  * NOTE: Eps was 0.0001f but this was giving problems for blood animation for
1428  * the open movie "Sintel", using 0.00001f. */
1429  if (ob->scale[0] < 0.00001f * (process.allbb.max[0] - process.allbb.min[0]) ||
1430  ob->scale[1] < 0.00001f * (process.allbb.max[1] - process.allbb.min[1]) ||
1431  ob->scale[2] < 0.00001f * (process.allbb.max[2] - process.allbb.min[2])) {
1433  return;
1434  }
1435 
1436  polygonize(&process);
1437  if (process.curindex == 0) {
1439  return;
1440  }
1441 
1442  /* add resulting surface to displist */
1443 
1444  /* Avoid over-allocation since this is stored in the displist. */
1445  if (process.curindex != process.totindex) {
1447  }
1449  process.co = MEM_reallocN(process.co, process.curvertex * sizeof(float[3]));
1450  process.no = MEM_reallocN(process.no, process.curvertex * sizeof(float[3]));
1451  }
1452 
1453  DispList *dl = MEM_callocN(sizeof(DispList), "mballdisp");
1454  BLI_addtail(dispbase, dl);
1455  dl->type = DL_INDEX4;
1456  dl->nr = (int)process.curvertex;
1457  dl->parts = (int)process.curindex;
1458 
1459  dl->index = (int *)process.indices;
1460 
1461  for (uint a = 0; a < process.curvertex; a++) {
1463  }
1464 
1465  dl->verts = (float *)process.co;
1466  dl->nors = (float *)process.no;
1467 
1469 }
typedef float(TangentPoint)[2]
display list (or rather multi purpose list) stuff.
@ DL_INDEX4
Definition: BKE_displist.h:28
@ G_TRANSFORM_OBJ
Definition: BKE_global.h:247
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:248
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:150
int BKE_object_visibility(const struct Object *ob, int dag_eval_mode)
int BKE_scene_base_iter_next(struct Depsgraph *depsgraph, struct SceneBaseIter *iter, struct Scene **scene, int val, struct Base **base, struct Object **ob)
Definition: scene.cc:2109
#define ATTR_FALLTHROUGH
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
Definition: math_geom.c:50
void accumulate_vertex_normals_v3(float n1[3], float n2[3], float n3[3], float n4[3], const float f_no[3], const float co1[3], const float co2[3], const float co3[3], const float co4[3])
Definition: math_geom.c:5014
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:33
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
bool has_zero_axis_m4(const float matrix[4][4])
Definition: math_matrix.c:3119
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
#define mul_m4_series(...)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE void zero_v3(float r[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:94
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:64
#define BLI_MEMARENA_STD_BUFSIZE
Definition: BLI_memarena.h:20
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:116
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
size_t BLI_split_name_num(char *left, int *nr, const char *name, char delim)
Definition: string_utils.c:25
unsigned int uint
Definition: BLI_sys_types.h:67
#define INIT_MINMAX(min, max)
#define DO_MINMAX(vec, min, max)
#define SWAP(type, a, b)
#define UNLIKELY(x)
#define ELEM(...)
#define DO_MIN(vec, min)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
eEvaluationMode
Definition: DEG_depsgraph.h:44
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
#define MAX_ID_NAME
Definition: DNA_ID.h:337
#define MB_BALL
#define MB_TUBE
#define MB_TUBEY
#define MB_TUBEZ
#define MB_ELIPSOID
#define MB_HIDE
#define MB_NEGATIVE
#define MB_TUBEX
#define MB_UPDATE_NEVER
#define MB_UPDATE_FAST
#define MB_UPDATE_HALFRES
#define MB_PLANE
#define MB_CUBE
Object is a sort of wrapper for general info.
@ OB_MBALL
@ OB_DUPLIFACES
@ OB_DUPLIVERTS
#define OB_FROMDUPLI
NSNotificationCenter * center
_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 z
_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 y
_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 i1
_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
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
OperationNode * node
Scene scene
const Depsgraph * depsgraph
#define rot(x, k)
uint pos
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
#define N
static void addtovertices(PROCESS *process, const float v[3], const float no[3])
static int corner1[12]
#define RTN
#define T
#define B
static void closest_latice(int r[3], const float pos[3], const float size)
#define RB
struct corner CORNER
#define TF
#define BN
void BKE_mball_cubeTable_free(void)
static void vnormal(PROCESS *process, const float point[3], float r_no[3])
static int rightface[12]
#define MBALL_ARRAY_LEN_INIT
#define HASHSIZE
static INTLISTS * cubetable[256]
struct intlist INTLIST
static void polygonize(PROCESS *process)
#define LF
#define RBN
struct Box Box
#define F
#define RTF
static void make_box_from_metaelem(Box *r, const MetaElem *ml)
struct MetaballBVHNode MetaballBVHNode
static void docube(PROCESS *process, CUBE *cube)
static int getedge(EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, int k2)
#define LTN
#define R
static void next_lattice(int r[3], const float pos[3], const float size)
struct edgelist EDGELIST
static int leftface[12]
static void find_first_points(PROCESS *process, const unsigned int em)
struct cubes CUBES
static void freepolygonize(PROCESS *process)
#define LTF
#define RF
static int nextcwedge(int edge, int face)
#define HASH(i, j, k)
static void build_bvh_spatial(PROCESS *process, MetaballBVHNode *node, unsigned int start, unsigned int end, const Box *allbox)
void BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase)
struct intlists INTLISTS
#define LN
static float metaball(PROCESS *process, float x, float y, float z)
#define LBF
static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Object *ob)
static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2)
#define L
#define LBN
#define LT
static void makecubetable(void)
static unsigned int partition_mainb(MetaElem **mainb, unsigned int start, unsigned int end, unsigned int s, float div)
#define RBF
struct cube CUBE
#define MB_BIT(i, bit)
#define BF
struct centerlist CENTERLIST
static int otherface(int edge, int face)
static void prev_lattice(int r[3], const float pos[3], const float size)
static void make_box_union(const BoundBox *a, const Box *b, Box *r_out)
#define LB
#define RN
static void add_cube(PROCESS *process, int i, int j, int k)
#define RT
static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
static CORNER * setcorner(PROCESS *process, int i, int j, int k)
static void setedge(PROCESS *process, int i1, int j1, int k1, int i2, int j2, int k2, int vid)
#define TN
static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
static float densfunc(const MetaElem *ball, float x, float y, float z)
struct process PROCESS
static char faces[256]
static int corner2[12]
static void converge(PROCESS *process, const CORNER *c1, const CORNER *c2, float r_p[3])
#define G(x, y, z)
#define floorf(x)
Definition: metal/compat.h:224
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
bool add(void *owner, const AttributeIDRef &attribute_id, eAttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
struct BMLoop * next
Definition: bmesh_class.h:233
int flag_legacy
float vec[8][3]
float max[3]
const MetaElem * ml
float min[3]
short type
Definition: BKE_displist.h:55
float * verts
Definition: BKE_displist.h:58
int * index
Definition: BKE_displist.h:59
float * nors
Definition: BKE_displist.h:58
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
float thresh
ListBase elems
float rendersize
float wiresize
ListBase * editelems
float expy
float * imat
struct MetaElem * next
short type
float expx
float expz
float quat[4]
float rad2
struct BoundBox * bb
float * mat
short flag
struct MetaballBVHNode * child[2]
short transflag
float scale[3]
float obmat[4][4]
struct Object * parent
void * data
struct centerlist * next
struct corner * next
float co[3]
float value
CORNER * corners[8]
struct cubes * next
struct edgelist * next
struct intlist * next
INTLIST * list
struct intlists * next
int(* indices)[4]
MetaballBVHNode metaball_bvh
unsigned int mem
EDGELIST ** edges
float(* co)[3]
float thresh
unsigned int totelem
unsigned int totindex
MetaElem ** mainb
unsigned int bvh_queue_size
MemArena * pgn_elements
float((* no)[3]
CENTERLIST ** centers
unsigned int curindex
MetaballBVHNode ** bvh_queue
unsigned int curvertex
CORNER ** corners
CUBES * cubes
unsigned int totvertex
unsigned int converge_res