Blender  V2.93
mball_tessellate.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <ctype.h>
25 #include <float.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "DNA_meta_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 
37 #include "BLI_listbase.h"
38 #include "BLI_math.h"
39 #include "BLI_memarena.h"
40 #include "BLI_string_utils.h"
41 #include "BLI_utildefines.h"
42 
43 #include "BKE_global.h"
44 
45 #include "BKE_displist.h"
46 #include "BKE_mball_tessellate.h" /* own include */
47 #include "BKE_object.h"
48 #include "BKE_scene.h"
49 
50 #include "DEG_depsgraph.h"
51 #include "DEG_depsgraph_query.h"
52 
53 #include "BLI_strict_flags.h"
54 
55 /* experimental (faster) normal calculation */
56 // #define USE_ACCUM_NORMAL
57 
58 /* Data types */
59 
60 typedef struct corner { /* corner of a cube */
61  int i, j, k; /* (i, j, k) is index within lattice */
62  float co[3], value; /* location and function value */
63  struct corner *next;
65 
66 typedef struct cube { /* partitioning cell (cube) */
67  int i, j, k; /* lattice location of cube */
68  CORNER *corners[8]; /* eight corners */
69 } CUBE;
70 
71 typedef struct cubes { /* linked list of cubes acting as stack */
72  CUBE cube; /* a single cube */
73  struct cubes *next; /* remaining elements */
75 
76 typedef struct centerlist { /* list of cube locations */
77  int i, j, k; /* cube location */
78  struct centerlist *next; /* remaining elements */
80 
81 typedef struct edgelist { /* list of edges */
82  int i1, j1, k1, i2, j2, k2; /* edge corner ids */
83  int vid; /* vertex id */
84  struct edgelist *next; /* remaining elements */
86 
87 typedef struct intlist { /* list of integers */
88  int i; /* an integer */
89  struct intlist *next; /* remaining elements */
91 
92 typedef struct intlists { /* list of list of integers */
93  INTLIST *list; /* a list of integers */
94  struct intlists *next; /* remaining elements */
96 
97 typedef struct Box { /* an AABB with pointer to metalelem */
98  float min[3], max[3];
99  const MetaElem *ml;
100 } Box;
101 
102 typedef struct MetaballBVHNode { /* BVH node */
103  Box bb[2]; /* AABB of children */
104  struct MetaballBVHNode *child[2];
106 
107 typedef struct process { /* parameters, storage */
108  float thresh, size; /* mball threshold, single cube size */
109  float delta; /* small delta for calculating normals */
110  unsigned int converge_res; /* converge procedure resolution (more = slower) */
111 
112  MetaElem **mainb; /* array of all metaelems */
113  unsigned int totelem, mem; /* number of metaelems */
114 
115  MetaballBVHNode metaball_bvh; /* The simplest bvh */
116  Box allbb; /* Bounding box of all metaelems */
117 
118  MetaballBVHNode **bvh_queue; /* Queue used during bvh traversal */
119  unsigned int bvh_queue_size;
120 
121  CUBES *cubes; /* stack of cubes waiting for polygonization */
122  CENTERLIST **centers; /* cube center hash table */
123  CORNER **corners; /* corner value hash table */
124  EDGELIST **edges; /* edge and vertex id hash table */
125 
126  int (*indices)[4]; /* output indices */
127  unsigned int totindex; /* size of memory allocated for indices */
128  unsigned int curindex; /* number of currently added indices */
129 
130  float (*co)[3], (*no)[3]; /* surface vertices - positions and normals */
131  unsigned int totvertex; /* memory size */
132  unsigned int curvertex; /* currently added vertices */
133 
134  /* memory allocation from common pool */
137 
138 /* Forward declarations */
139 static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2);
140 static void add_cube(PROCESS *process, int i, int j, int k);
141 static void make_face(PROCESS *process, int i1, int i2, int i3, int i4);
142 static void converge(PROCESS *process, const CORNER *c1, const CORNER *c2, float r_p[3]);
143 
144 /* ******************* SIMPLE BVH ********************* */
145 
146 static void make_box_union(const BoundBox *a, const Box *b, Box *r_out)
147 {
148  r_out->min[0] = min_ff(a->vec[0][0], b->min[0]);
149  r_out->min[1] = min_ff(a->vec[0][1], b->min[1]);
150  r_out->min[2] = min_ff(a->vec[0][2], b->min[2]);
151 
152  r_out->max[0] = max_ff(a->vec[6][0], b->max[0]);
153  r_out->max[1] = max_ff(a->vec[6][1], b->max[1]);
154  r_out->max[2] = max_ff(a->vec[6][2], b->max[2]);
155 }
156 
157 static void make_box_from_metaelem(Box *r, const MetaElem *ml)
158 {
159  copy_v3_v3(r->max, ml->bb->vec[6]);
160  copy_v3_v3(r->min, ml->bb->vec[0]);
161  r->ml = ml;
162 }
163 
169 static unsigned int partition_mainb(
170  MetaElem **mainb, unsigned int start, unsigned int end, unsigned int s, float div)
171 {
172  unsigned int i = start, j = end - 1;
173  div *= 2.0f;
174 
175  while (1) {
176  while (i < j && div > (mainb[i]->bb->vec[6][s] + mainb[i]->bb->vec[0][s])) {
177  i++;
178  }
179  while (j > i && div < (mainb[j]->bb->vec[6][s] + mainb[j]->bb->vec[0][s])) {
180  j--;
181  }
182 
183  if (i >= j) {
184  break;
185  }
186 
187  SWAP(MetaElem *, mainb[i], mainb[j]);
188  i++;
189  j--;
190  }
191 
192  if (i == start) {
193  i++;
194  }
195 
196  return i;
197 }
198 
204  unsigned int start,
205  unsigned int end,
206  const Box *allbox)
207 {
208  unsigned int part, j, s;
209  float dim[3], div;
210 
211  /* Maximum bvh queue size is number of nodes which are made, equals calls to this function. */
213 
214  dim[0] = allbox->max[0] - allbox->min[0];
215  dim[1] = allbox->max[1] - allbox->min[1];
216  dim[2] = allbox->max[2] - allbox->min[2];
217 
218  s = 0;
219  if (dim[1] > dim[0] && dim[1] > dim[2]) {
220  s = 1;
221  }
222  else if (dim[2] > dim[1] && dim[2] > dim[0]) {
223  s = 2;
224  }
225 
226  div = allbox->min[s] + (dim[s] / 2.0f);
227 
228  part = partition_mainb(process->mainb, start, end, s, div);
229 
230  make_box_from_metaelem(&node->bb[0], process->mainb[start]);
231  node->child[0] = NULL;
232 
233  if (part > start + 1) {
234  for (j = start; j < part; j++) {
235  make_box_union(process->mainb[j]->bb, &node->bb[0], &node->bb[0]);
236  }
237 
239  build_bvh_spatial(process, node->child[0], start, part, &node->bb[0]);
240  }
241 
242  node->child[1] = NULL;
243  if (part < end) {
244  make_box_from_metaelem(&node->bb[1], process->mainb[part]);
245 
246  if (part < end - 1) {
247  for (j = part; j < end; j++) {
248  make_box_union(process->mainb[j]->bb, &node->bb[1], &node->bb[1]);
249  }
250 
252  build_bvh_spatial(process, node->child[1], part, end, &node->bb[1]);
253  }
254  }
255  else {
256  INIT_MINMAX(node->bb[1].min, node->bb[1].max);
257  }
258 }
259 
260 /* ******************** ARITH ************************* */
261 
275 #define L 0 /* left direction: -x, -i */
276 #define R 1 /* right direction: +x, +i */
277 #define B 2 /* bottom direction: -y, -j */
278 #define T 3 /* top direction: +y, +j */
279 #define N 4 /* near direction: -z, -k */
280 #define F 5 /* far direction: +z, +k */
281 #define LBN 0 /* left bottom near corner */
282 #define LBF 1 /* left bottom far corner */
283 #define LTN 2 /* left top near corner */
284 #define LTF 3 /* left top far corner */
285 #define RBN 4 /* right bottom near corner */
286 #define RBF 5 /* right bottom far corner */
287 #define RTN 6 /* right top near corner */
288 #define RTF 7 /* right top far corner */
289 
295 #define HASHBIT (5)
296 #define HASHSIZE (size_t)(1 << (3 * HASHBIT))
298 #define HASH(i, j, k) ((((((i)&31) << 5) | ((j)&31)) << 5) | ((k)&31))
299 
300 #define MB_BIT(i, bit) (((i) >> (bit)) & 1)
301 // #define FLIP(i, bit) ((i) ^ 1 << (bit)) /* flip the given bit of i */
302 
303 /* ******************** DENSITY COPMPUTATION ********************* */
304 
313 static float densfunc(const MetaElem *ball, float x, float y, float z)
314 {
315  float dist2;
316  float dvec[3] = {x, y, z};
317 
318  mul_m4_v3((const float(*)[4])ball->imat, dvec);
319 
320  switch (ball->type) {
321  case MB_BALL:
322  /* do nothing */
323  break;
324  case MB_CUBE:
325  if (dvec[2] > ball->expz) {
326  dvec[2] -= ball->expz;
327  }
328  else if (dvec[2] < -ball->expz) {
329  dvec[2] += ball->expz;
330  }
331  else {
332  dvec[2] = 0.0;
333  }
335  case MB_PLANE:
336  if (dvec[1] > ball->expy) {
337  dvec[1] -= ball->expy;
338  }
339  else if (dvec[1] < -ball->expy) {
340  dvec[1] += ball->expy;
341  }
342  else {
343  dvec[1] = 0.0;
344  }
346  case MB_TUBE:
347  if (dvec[0] > ball->expx) {
348  dvec[0] -= ball->expx;
349  }
350  else if (dvec[0] < -ball->expx) {
351  dvec[0] += ball->expx;
352  }
353  else {
354  dvec[0] = 0.0;
355  }
356  break;
357  case MB_ELIPSOID:
358  dvec[0] /= ball->expx;
359  dvec[1] /= ball->expy;
360  dvec[2] /= ball->expz;
361  break;
362 
363  /* *** deprecated, could be removed?, do-versioned at least *** */
364  case MB_TUBEX:
365  if (dvec[0] > ball->len) {
366  dvec[0] -= ball->len;
367  }
368  else if (dvec[0] < -ball->len) {
369  dvec[0] += ball->len;
370  }
371  else {
372  dvec[0] = 0.0;
373  }
374  break;
375  case MB_TUBEY:
376  if (dvec[1] > ball->len) {
377  dvec[1] -= ball->len;
378  }
379  else if (dvec[1] < -ball->len) {
380  dvec[1] += ball->len;
381  }
382  else {
383  dvec[1] = 0.0;
384  }
385  break;
386  case MB_TUBEZ:
387  if (dvec[2] > ball->len) {
388  dvec[2] -= ball->len;
389  }
390  else if (dvec[2] < -ball->len) {
391  dvec[2] += ball->len;
392  }
393  else {
394  dvec[2] = 0.0;
395  }
396  break;
397  /* *** end deprecated *** */
398  }
399 
400  /* ball->rad2 is inverse of squared rad */
401  dist2 = 1.0f - (len_squared_v3(dvec) * ball->rad2);
402 
403  /* ball->s is negative if metaball is negative */
404  return (dist2 < 0.0f) ? 0.0f : (ball->s * dist2 * dist2 * dist2);
405 }
406 
411 static float metaball(PROCESS *process, float x, float y, float z)
412 {
413  float dens = 0.0f;
414  unsigned int front = 0, back = 0;
416 
417  process->bvh_queue[front++] = &process->metaball_bvh;
418 
419  while (front != back) {
420  node = process->bvh_queue[back++];
421 
422  for (int i = 0; i < 2; i++) {
423  if ((node->bb[i].min[0] <= x) && (node->bb[i].max[0] >= x) && (node->bb[i].min[1] <= y) &&
424  (node->bb[i].max[1] >= y) && (node->bb[i].min[2] <= z) && (node->bb[i].max[2] >= z)) {
425  if (node->child[i]) {
426  process->bvh_queue[front++] = node->child[i];
427  }
428  else {
429  dens += densfunc(node->bb[i].ml, x, y, z);
430  }
431  }
432  }
433  }
434 
435  return process->thresh - dens;
436 }
437 
441 static void make_face(PROCESS *process, int i1, int i2, int i3, int i4)
442 {
443  int *cur;
444 
445 #ifdef USE_ACCUM_NORMAL
446  float n[3];
447 #endif
448 
450  process->totindex += 4096;
451  process->indices = MEM_reallocN(process->indices, sizeof(int[4]) * process->totindex);
452  }
453 
454  cur = process->indices[process->curindex++];
455 
456  /* displists now support array drawing, we treat tri's as fake quad */
457 
458  cur[0] = i1;
459  cur[1] = i2;
460  cur[2] = i3;
461  cur[3] = i4;
462 
463 #ifdef USE_ACCUM_NORMAL
464  if (i4 == i3) {
465  normal_tri_v3(n, process->co[i1], process->co[i2], process->co[i3]);
467  process->no[i2],
468  process->no[i3],
469  NULL,
470  n,
471  process->co[i1],
472  process->co[i2],
473  process->co[i3],
474  NULL);
475  }
476  else {
477  normal_quad_v3(n, process->co[i1], process->co[i2], process->co[i3], process->co[i4]);
479  process->no[i2],
480  process->no[i3],
481  process->no[i4],
482  n,
483  process->co[i1],
484  process->co[i2],
485  process->co[i3],
486  process->co[i4]);
487  }
488 #endif
489 }
490 
491 /* Frees allocated memory */
493 {
494  if (process->corners) {
496  }
497  if (process->edges) {
499  }
500  if (process->centers) {
502  }
503  if (process->mainb) {
505  }
506  if (process->bvh_queue) {
508  }
509  if (process->pgn_elements) {
511  }
512 }
513 
514 /* **************** POLYGONIZATION ************************ */
515 
516 /**** Cubical Polygonization (optional) ****/
517 
518 #define LB 0 /* left bottom edge */
519 #define LT 1 /* left top edge */
520 #define LN 2 /* left near edge */
521 #define LF 3 /* left far edge */
522 #define RB 4 /* right bottom edge */
523 #define RT 5 /* right top edge */
524 #define RN 6 /* right near edge */
525 #define RF 7 /* right far edge */
526 #define BN 8 /* bottom near edge */
527 #define BF 9 /* bottom far edge */
528 #define TN 10 /* top near edge */
529 #define TF 11 /* top far edge */
530 
531 static INTLISTS *cubetable[256];
532 static char faces[256];
533 
534 /* edge: LB, LT, LN, LF, RB, RT, RN, RF, BN, BF, TN, TF */
535 static int corner1[12] = {
536  LBN,
537  LTN,
538  LBN,
539  LBF,
540  RBN,
541  RTN,
542  RBN,
543  RBF,
544  LBN,
545  LBF,
546  LTN,
547  LTF,
548 };
549 static int corner2[12] = {
550  LBF,
551  LTF,
552  LTN,
553  LTF,
554  RBF,
555  RTF,
556  RTN,
557  RTF,
558  RBN,
559  RBF,
560  RTN,
561  RTF,
562 };
563 static int leftface[12] = {
564  B,
565  L,
566  L,
567  F,
568  R,
569  T,
570  N,
571  R,
572  N,
573  B,
574  T,
575  F,
576 };
577 /* face on left when going corner1 to corner2 */
578 static int rightface[12] = {
579  L,
580  T,
581  N,
582  L,
583  B,
584  R,
585  R,
586  F,
587  B,
588  F,
589  N,
590  T,
591 };
592 /* face on right when going corner1 to corner2 */
593 
597 static void docube(PROCESS *process, CUBE *cube)
598 {
599  INTLISTS *polys;
600  CORNER *c1, *c2;
601  int i, index = 0, count, indexar[8];
602 
603  /* Determine which case cube falls into. */
604  for (i = 0; i < 8; i++) {
605  if (cube->corners[i]->value > 0.0f) {
606  index += (1 << i);
607  }
608  }
609 
610  /* Using faces[] table, adds neighboring cube if surface intersects face in this direction. */
611  if (MB_BIT(faces[index], 0)) {
612  add_cube(process, cube->i - 1, cube->j, cube->k);
613  }
614  if (MB_BIT(faces[index], 1)) {
615  add_cube(process, cube->i + 1, cube->j, cube->k);
616  }
617  if (MB_BIT(faces[index], 2)) {
618  add_cube(process, cube->i, cube->j - 1, cube->k);
619  }
620  if (MB_BIT(faces[index], 3)) {
621  add_cube(process, cube->i, cube->j + 1, cube->k);
622  }
623  if (MB_BIT(faces[index], 4)) {
624  add_cube(process, cube->i, cube->j, cube->k - 1);
625  }
626  if (MB_BIT(faces[index], 5)) {
627  add_cube(process, cube->i, cube->j, cube->k + 1);
628  }
629 
630  /* Using cubetable[], determines polygons for output. */
631  for (polys = cubetable[index]; polys; polys = polys->next) {
632  INTLIST *edges;
633 
634  count = 0;
635  /* Sets needed vertex id's lying on the edges. */
636  for (edges = polys->list; edges; edges = edges->next) {
637  c1 = cube->corners[corner1[edges->i]];
638  c2 = cube->corners[corner2[edges->i]];
639 
640  indexar[count] = vertid(process, c1, c2);
641  count++;
642  }
643 
644  /* Adds faces to output. */
645  if (count > 2) {
646  switch (count) {
647  case 3:
648  make_face(process, indexar[2], indexar[1], indexar[0], indexar[0]); /* triangle */
649  break;
650  case 4:
651  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
652  break;
653  case 5:
654  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
655  make_face(process, indexar[4], indexar[3], indexar[0], indexar[0]); /* triangle */
656  break;
657  case 6:
658  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
659  make_face(process, indexar[5], indexar[4], indexar[3], indexar[0]);
660  break;
661  case 7:
662  make_face(process, indexar[3], indexar[2], indexar[1], indexar[0]);
663  make_face(process, indexar[5], indexar[4], indexar[3], indexar[0]);
664  make_face(process, indexar[6], indexar[5], indexar[0], indexar[0]); /* triangle */
665  break;
666  }
667  }
668  }
669 }
670 
675 static CORNER *setcorner(PROCESS *process, int i, int j, int k)
676 {
677  /* for speed, do corner value caching here */
678  CORNER *c;
679  int index;
680 
681  /* does corner exist? */
682  index = HASH(i, j, k);
683  c = process->corners[index];
684 
685  for (; c != NULL; c = c->next) {
686  if (c->i == i && c->j == j && c->k == k) {
687  return c;
688  }
689  }
690 
692 
693  c->i = i;
694  c->co[0] = ((float)i - 0.5f) * process->size;
695  c->j = j;
696  c->co[1] = ((float)j - 0.5f) * process->size;
697  c->k = k;
698  c->co[2] = ((float)k - 0.5f) * process->size;
699 
700  c->value = metaball(process, c->co[0], c->co[1], c->co[2]);
701 
702  c->next = process->corners[index];
703  process->corners[index] = c;
704 
705  return c;
706 }
707 
711 static int nextcwedge(int edge, int face)
712 {
713  switch (edge) {
714  case LB:
715  return (face == L) ? LF : BN;
716  case LT:
717  return (face == L) ? LN : TF;
718  case LN:
719  return (face == L) ? LB : TN;
720  case LF:
721  return (face == L) ? LT : BF;
722  case RB:
723  return (face == R) ? RN : BF;
724  case RT:
725  return (face == R) ? RF : TN;
726  case RN:
727  return (face == R) ? RT : BN;
728  case RF:
729  return (face == R) ? RB : TF;
730  case BN:
731  return (face == B) ? RB : LN;
732  case BF:
733  return (face == B) ? LB : RF;
734  case TN:
735  return (face == T) ? LT : RN;
736  case TF:
737  return (face == T) ? RT : LF;
738  }
739  return 0;
740 }
741 
745 static int otherface(int edge, int face)
746 {
747  int other = leftface[edge];
748  return face == other ? rightface[edge] : other;
749 }
750 
754 static void makecubetable(void)
755 {
756  static bool is_done = false;
757  int i, e, c, done[12], pos[8];
758 
759  if (is_done) {
760  return;
761  }
762  is_done = true;
763 
764  for (i = 0; i < 256; i++) {
765  for (e = 0; e < 12; e++) {
766  done[e] = 0;
767  }
768  for (c = 0; c < 8; c++) {
769  pos[c] = MB_BIT(i, c);
770  }
771  for (e = 0; e < 12; e++) {
772  if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) {
773  INTLIST *ints = NULL;
774  INTLISTS *lists = MEM_callocN(sizeof(INTLISTS), "mball_intlist");
775  int start = e, edge = e;
776 
777  /* get face that is to right of edge from pos to neg corner: */
778  int face = pos[corner1[e]] ? rightface[e] : leftface[e];
779 
780  while (1) {
781  edge = nextcwedge(edge, face);
782  done[edge] = 1;
783  if (pos[corner1[edge]] != pos[corner2[edge]]) {
784  INTLIST *tmp = ints;
785 
786  ints = MEM_callocN(sizeof(INTLIST), "mball_intlist");
787  ints->i = edge;
788  ints->next = tmp; /* add edge to head of list */
789 
790  if (edge == start) {
791  break;
792  }
793  face = otherface(edge, face);
794  }
795  }
796  lists->list = ints; /* add ints to head of table entry */
797  lists->next = cubetable[i];
798  cubetable[i] = lists;
799  }
800  }
801  }
802 
803  for (i = 0; i < 256; i++) {
804  INTLISTS *polys;
805  faces[i] = 0;
806  for (polys = cubetable[i]; polys; polys = polys->next) {
807  INTLIST *edges;
808 
809  for (edges = polys->list; edges; edges = edges->next) {
810  if (ELEM(edges->i, LB, LT, LN, LF)) {
811  faces[i] |= 1 << L;
812  }
813  if (ELEM(edges->i, RB, RT, RN, RF)) {
814  faces[i] |= 1 << R;
815  }
816  if (ELEM(edges->i, LB, RB, BN, BF)) {
817  faces[i] |= 1 << B;
818  }
819  if (ELEM(edges->i, LT, RT, TN, TF)) {
820  faces[i] |= 1 << T;
821  }
822  if (ELEM(edges->i, LN, RN, BN, TN)) {
823  faces[i] |= 1 << N;
824  }
825  if (ELEM(edges->i, LF, RF, BF, TF)) {
826  faces[i] |= 1 << F;
827  }
828  }
829  }
830  }
831 }
832 
834 {
835  for (int i = 0; i < 256; i++) {
836  INTLISTS *lists = cubetable[i];
837  while (lists) {
838  INTLISTS *nlists = lists->next;
839 
840  INTLIST *ints = lists->list;
841  while (ints) {
842  INTLIST *nints = ints->next;
843  MEM_freeN(ints);
844  ints = nints;
845  }
846 
847  MEM_freeN(lists);
848  lists = nlists;
849  }
850  cubetable[i] = NULL;
851  }
852 }
853 
854 /**** Storage ****/
855 
859 static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
860 {
861  int index;
862  CENTERLIST *newc, *l, *q;
863 
864  index = HASH(i, j, k);
865  q = table[index];
866 
867  for (l = q; l != NULL; l = l->next) {
868  if (l->i == i && l->j == j && l->k == k) {
869  return 1;
870  }
871  }
872 
874  newc->i = i;
875  newc->j = j;
876  newc->k = k;
877  newc->next = q;
878  table[index] = newc;
879 
880  return 0;
881 }
882 
886 static void setedge(PROCESS *process, int i1, int j1, int k1, int i2, int j2, int k2, int vid)
887 {
888  int index;
889  EDGELIST *newe;
890 
891  if (i1 > i2 || (i1 == i2 && (j1 > j2 || (j1 == j2 && k1 > k2)))) {
892  int t = i1;
893  i1 = i2;
894  i2 = t;
895  t = j1;
896  j1 = j2;
897  j2 = t;
898  t = k1;
899  k1 = k2;
900  k2 = t;
901  }
902  index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
904 
905  newe->i1 = i1;
906  newe->j1 = j1;
907  newe->k1 = k1;
908  newe->i2 = i2;
909  newe->j2 = j2;
910  newe->k2 = k2;
911  newe->vid = vid;
912  newe->next = process->edges[index];
913  process->edges[index] = newe;
914 }
915 
919 static int getedge(EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, int k2)
920 {
921  EDGELIST *q;
922 
923  if (i1 > i2 || (i1 == i2 && (j1 > j2 || (j1 == j2 && k1 > k2)))) {
924  int t = i1;
925  i1 = i2;
926  i2 = t;
927  t = j1;
928  j1 = j2;
929  j2 = t;
930  t = k1;
931  k1 = k2;
932  k2 = t;
933  }
934  q = table[HASH(i1, j1, k1) + HASH(i2, j2, k2)];
935  for (; q != NULL; q = q->next) {
936  if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 && q->i2 == i2 && q->j2 == j2 && q->k2 == k2) {
937  return q->vid;
938  }
939  }
940  return -1;
941 }
942 
946 static void addtovertices(PROCESS *process, const float v[3], const float no[3])
947 {
948  if (process->curvertex == process->totvertex) {
949  process->totvertex += 4096;
950  process->co = MEM_reallocN(process->co, process->totvertex * sizeof(float[3]));
951  process->no = MEM_reallocN(process->no, process->totvertex * sizeof(float[3]));
952  }
953 
956 
957  process->curvertex++;
958 }
959 
960 #ifndef USE_ACCUM_NORMAL
966 static void vnormal(PROCESS *process, const float point[3], float r_no[3])
967 {
968  const float delta = process->delta;
969  const float f = metaball(process, point[0], point[1], point[2]);
970 
971  r_no[0] = metaball(process, point[0] + delta, point[1], point[2]) - f;
972  r_no[1] = metaball(process, point[0], point[1] + delta, point[2]) - f;
973  r_no[2] = metaball(process, point[0], point[1], point[2] + delta) - f;
974 }
975 #endif /* USE_ACCUM_NORMAL */
976 
982 static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2)
983 {
984  float v[3], no[3];
985  int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
986 
987  if (vid != -1) {
988  return vid; /* previously computed */
989  }
990 
991  converge(process, c1, c2, v); /* position */
992 
993 #ifdef USE_ACCUM_NORMAL
994  zero_v3(no);
995 #else
996  vnormal(process, v, no);
997 #endif
998 
999  addtovertices(process, v, no); /* save vertex */
1000  vid = (int)process->curvertex - 1;
1001  setedge(process, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
1002 
1003  return vid;
1004 }
1005 
1010 static void converge(PROCESS *process, const CORNER *c1, const CORNER *c2, float r_p[3])
1011 {
1012  float c1_value, c1_co[3];
1013  float c2_value, c2_co[3];
1014 
1015  if (c1->value < c2->value) {
1016  c1_value = c2->value;
1017  copy_v3_v3(c1_co, c2->co);
1018  c2_value = c1->value;
1019  copy_v3_v3(c2_co, c1->co);
1020  }
1021  else {
1022  c1_value = c1->value;
1023  copy_v3_v3(c1_co, c1->co);
1024  c2_value = c2->value;
1025  copy_v3_v3(c2_co, c2->co);
1026  }
1027 
1028  for (uint i = 0; i < process->converge_res; i++) {
1029  interp_v3_v3v3(r_p, c1_co, c2_co, 0.5f);
1030  float dens = metaball(process, r_p[0], r_p[1], r_p[2]);
1031 
1032  if (dens > 0.0f) {
1033  c1_value = dens;
1034  copy_v3_v3(c1_co, r_p);
1035  }
1036  else {
1037  c2_value = dens;
1038  copy_v3_v3(c2_co, r_p);
1039  }
1040  }
1041 
1042  float tmp = -c1_value / (c2_value - c1_value);
1043  interp_v3_v3v3(r_p, c1_co, c2_co, tmp);
1044 }
1045 
1049 static void add_cube(PROCESS *process, int i, int j, int k)
1050 {
1051  CUBES *ncube;
1052  int n;
1053 
1054  /* test if cube has been found before */
1055  if (setcenter(process, process->centers, i, j, k) == 0) {
1056  /* push cube on stack: */
1057  ncube = BLI_memarena_alloc(process->pgn_elements, sizeof(CUBES));
1058  ncube->next = process->cubes;
1059  process->cubes = ncube;
1060 
1061  ncube->cube.i = i;
1062  ncube->cube.j = j;
1063  ncube->cube.k = k;
1064 
1065  /* set corners of initial cube: */
1066  for (n = 0; n < 8; n++) {
1067  ncube->cube.corners[n] = setcorner(
1068  process, i + MB_BIT(n, 2), j + MB_BIT(n, 1), k + MB_BIT(n, 0));
1069  }
1070  }
1071 }
1072 
1073 static void next_lattice(int r[3], const float pos[3], const float size)
1074 {
1075  r[0] = (int)ceil((pos[0] / size) + 0.5f);
1076  r[1] = (int)ceil((pos[1] / size) + 0.5f);
1077  r[2] = (int)ceil((pos[2] / size) + 0.5f);
1078 }
1079 static void prev_lattice(int r[3], const float pos[3], const float size)
1080 {
1081  next_lattice(r, pos, size);
1082  r[0]--;
1083  r[1]--;
1084  r[2]--;
1085 }
1086 static void closest_latice(int r[3], const float pos[3], const float size)
1087 {
1088  r[0] = (int)floorf(pos[0] / size + 1.0f);
1089  r[1] = (int)floorf(pos[1] / size + 1.0f);
1090  r[2] = (int)floorf(pos[2] / size + 1.0f);
1091 }
1092 
1096 static void find_first_points(PROCESS *process, const unsigned int em)
1097 {
1098  const MetaElem *ml;
1099  int center[3], lbn[3], rtf[3], it[3], dir[3], add[3];
1100  float tmp[3], a, b;
1101 
1102  ml = process->mainb[em];
1103 
1104  mid_v3_v3v3(tmp, ml->bb->vec[0], ml->bb->vec[6]);
1106  prev_lattice(lbn, ml->bb->vec[0], process->size);
1107  next_lattice(rtf, ml->bb->vec[6], process->size);
1108 
1109  for (dir[0] = -1; dir[0] <= 1; dir[0]++) {
1110  for (dir[1] = -1; dir[1] <= 1; dir[1]++) {
1111  for (dir[2] = -1; dir[2] <= 1; dir[2]++) {
1112  if (dir[0] == 0 && dir[1] == 0 && dir[2] == 0) {
1113  continue;
1114  }
1115 
1116  copy_v3_v3_int(it, center);
1117 
1118  b = setcorner(process, it[0], it[1], it[2])->value;
1119  do {
1120  it[0] += dir[0];
1121  it[1] += dir[1];
1122  it[2] += dir[2];
1123  a = b;
1124  b = setcorner(process, it[0], it[1], it[2])->value;
1125 
1126  if (a * b < 0.0f) {
1127  add[0] = it[0] - dir[0];
1128  add[1] = it[1] - dir[1];
1129  add[2] = it[2] - dir[2];
1130  DO_MIN(it, add);
1131  add_cube(process, add[0], add[1], add[2]);
1132  break;
1133  }
1134  } while ((it[0] > lbn[0]) && (it[1] > lbn[1]) && (it[2] > lbn[2]) && (it[0] < rtf[0]) &&
1135  (it[1] < rtf[1]) && (it[2] < rtf[2]));
1136  }
1137  }
1138  }
1139 }
1140 
1148 {
1149  CUBE c;
1150 
1151  process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
1152  process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
1153  process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
1155  "Metaball BVH Queue");
1156 
1157  makecubetable();
1158 
1159  for (uint i = 0; i < process->totelem; i++) {
1161  }
1162 
1163  while (process->cubes != NULL) {
1164  c = process->cubes->cube;
1166 
1167  docube(process, &c);
1168  }
1169 }
1170 
1176 {
1177  Scene *sce_iter = scene;
1178  Base *base;
1179  Object *bob;
1180  MetaBall *mb;
1181  const MetaElem *ml;
1182  float obinv[4][4], obmat[4][4];
1183  unsigned int i;
1184  int obnr, zero_size = 0;
1185  char obname[MAX_ID_NAME];
1186  SceneBaseIter iter;
1187  const eEvaluationMode deg_eval_mode = DEG_get_mode(depsgraph);
1188  const short parenting_dupli_transflag = (OB_DUPLIFACES | OB_DUPLIVERTS);
1189 
1190  copy_m4_m4(obmat, ob->obmat); /* to cope with duplicators from BKE_scene_base_iter_next */
1191  invert_m4_m4(obinv, ob->obmat);
1192 
1193  BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
1194 
1195  /* make main array */
1196  BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 0, NULL, NULL);
1197  while (BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 1, &base, &bob)) {
1198  if (bob->type == OB_MBALL) {
1199  zero_size = 0;
1200  ml = NULL;
1201 
1202  /* If this metaball is the original that's used for duplication, only have it visible when
1203  * the instancer is visible too. */
1204  if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != NULL &&
1205  (ob->parent->transflag & parenting_dupli_transflag) != 0 &&
1206  (BKE_object_visibility(ob->parent, deg_eval_mode) & OB_VISIBLE_SELF) == 0) {
1207  continue;
1208  }
1209 
1210  if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
1211  mb = ob->data;
1212 
1213  if (mb->editelems) {
1214  ml = mb->editelems->first;
1215  }
1216  else {
1217  ml = mb->elems.first;
1218  }
1219  }
1220  else {
1221  char name[MAX_ID_NAME];
1222  int nr;
1223 
1224  BLI_split_name_num(name, &nr, bob->id.name + 2, '.');
1225  if (STREQ(obname, name)) {
1226  mb = bob->data;
1227 
1228  if (mb->editelems) {
1229  ml = mb->editelems->first;
1230  }
1231  else {
1232  ml = mb->elems.first;
1233  }
1234  }
1235  }
1236 
1237  /* when metaball object has zero scale, then MetaElem to this MetaBall
1238  * will not be put to mainb array */
1239  if (has_zero_axis_m4(bob->obmat)) {
1240  zero_size = 1;
1241  }
1242  else if (bob->parent) {
1243  struct Object *pob = bob->parent;
1244  while (pob) {
1245  if (has_zero_axis_m4(pob->obmat)) {
1246  zero_size = 1;
1247  break;
1248  }
1249  pob = pob->parent;
1250  }
1251  }
1252 
1253  if (zero_size) {
1254  while (ml) {
1255  ml = ml->next;
1256  }
1257  }
1258  else {
1259  while (ml) {
1260  if (!(ml->flag & MB_HIDE)) {
1261  float pos[4][4], rot[4][4];
1262  float expx, expy, expz;
1263  float tempmin[3], tempmax[3];
1264 
1265  MetaElem *new_ml;
1266 
1267  /* make a copy because of duplicates */
1268  new_ml = BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem));
1269  *(new_ml) = *ml;
1270  new_ml->bb = BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox));
1271  new_ml->mat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
1272  new_ml->imat = BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4]));
1273 
1274  /* too big stiffness seems only ugly due to linear interpolation
1275  * no need to have possibility for too big stiffness */
1276  if (ml->s > 10.0f) {
1277  new_ml->s = 10.0f;
1278  }
1279  else {
1280  new_ml->s = ml->s;
1281  }
1282 
1283  /* if metaball is negative, set stiffness negative */
1284  if (new_ml->flag & MB_NEGATIVE) {
1285  new_ml->s = -new_ml->s;
1286  }
1287 
1288  /* Translation of MetaElem */
1289  unit_m4(pos);
1290  pos[3][0] = ml->x;
1291  pos[3][1] = ml->y;
1292  pos[3][2] = ml->z;
1293 
1294  /* Rotation of MetaElem is stored in quat */
1295  quat_to_mat4(rot, ml->quat);
1296 
1297  /* Matrix multiply is as follows:
1298  * basis object space ->
1299  * world ->
1300  * ml object space ->
1301  * position ->
1302  * rotation ->
1303  * ml local space
1304  */
1305  mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->obmat, pos, rot);
1306  /* ml local space -> basis object space */
1307  invert_m4_m4((float(*)[4])new_ml->imat, (float(*)[4])new_ml->mat);
1308 
1309  /* rad2 is inverse of squared radius */
1310  new_ml->rad2 = 1 / (ml->rad * ml->rad);
1311 
1312  /* initial dimensions = radius */
1313  expx = ml->rad;
1314  expy = ml->rad;
1315  expz = ml->rad;
1316 
1317  switch (ml->type) {
1318  case MB_BALL:
1319  break;
1320  case MB_CUBE: /* cube is "expanded" by expz, expy and expx */
1321  expz += ml->expz;
1323  case MB_PLANE: /* plane is "expanded" by expy and expx */
1324  expy += ml->expy;
1326  case MB_TUBE: /* tube is "expanded" by expx */
1327  expx += ml->expx;
1328  break;
1329  case MB_ELIPSOID: /* ellipsoid is "stretched" by exp* */
1330  expx *= ml->expx;
1331  expy *= ml->expy;
1332  expz *= ml->expz;
1333  break;
1334  }
1335 
1336  /* untransformed Bounding Box of MetaElem */
1337  /* TODO, its possible the elem type has been changed and the exp*
1338  * values can use a fallback. */
1339  copy_v3_fl3(new_ml->bb->vec[0], -expx, -expy, -expz); /* 0 */
1340  copy_v3_fl3(new_ml->bb->vec[1], +expx, -expy, -expz); /* 1 */
1341  copy_v3_fl3(new_ml->bb->vec[2], +expx, +expy, -expz); /* 2 */
1342  copy_v3_fl3(new_ml->bb->vec[3], -expx, +expy, -expz); /* 3 */
1343  copy_v3_fl3(new_ml->bb->vec[4], -expx, -expy, +expz); /* 4 */
1344  copy_v3_fl3(new_ml->bb->vec[5], +expx, -expy, +expz); /* 5 */
1345  copy_v3_fl3(new_ml->bb->vec[6], +expx, +expy, +expz); /* 6 */
1346  copy_v3_fl3(new_ml->bb->vec[7], -expx, +expy, +expz); /* 7 */
1347 
1348  /* transformation of Metalem bb */
1349  for (i = 0; i < 8; i++) {
1350  mul_m4_v3((float(*)[4])new_ml->mat, new_ml->bb->vec[i]);
1351  }
1352 
1353  /* find max and min of transformed bb */
1354  INIT_MINMAX(tempmin, tempmax);
1355  for (i = 0; i < 8; i++) {
1356  DO_MINMAX(new_ml->bb->vec[i], tempmin, tempmax);
1357  }
1358 
1359  /* set only point 0 and 6 - AABB of Metaelem */
1360  copy_v3_v3(new_ml->bb->vec[0], tempmin);
1361  copy_v3_v3(new_ml->bb->vec[6], tempmax);
1362 
1363  /* add new_ml to mainb[] */
1364  if (UNLIKELY(process->totelem == process->mem)) {
1365  process->mem = process->mem * 2 + 10;
1367  }
1368  process->mainb[process->totelem++] = new_ml;
1369  }
1370  ml = ml->next;
1371  }
1372  }
1373  }
1374  }
1375 
1376  /* compute AABB of all Metaelems */
1377  if (process->totelem > 0) {
1378  copy_v3_v3(process->allbb.min, process->mainb[0]->bb->vec[0]);
1379  copy_v3_v3(process->allbb.max, process->mainb[0]->bb->vec[6]);
1380  for (i = 1; i < process->totelem; i++) {
1382  }
1383  }
1384 }
1385 
1387 {
1388  MetaBall *mb;
1389  DispList *dl;
1390  unsigned int a;
1391  PROCESS process = {0};
1392  bool is_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
1393 
1394  mb = ob->data;
1395 
1396  process.thresh = mb->thresh;
1397 
1398  if (process.thresh < 0.001f) {
1399  process.converge_res = 16;
1400  }
1401  else if (process.thresh < 0.01f) {
1402  process.converge_res = 8;
1403  }
1404  else if (process.thresh < 0.1f) {
1405  process.converge_res = 4;
1406  }
1407  else {
1408  process.converge_res = 2;
1409  }
1410 
1411  if (!is_render && (mb->flag == MB_UPDATE_NEVER)) {
1412  return;
1413  }
1414  if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) {
1415  return;
1416  }
1417 
1418  if (is_render) {
1419  process.size = mb->rendersize;
1420  }
1421  else {
1422  process.size = mb->wiresize;
1423  if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_HALFRES) {
1424  process.size *= 2.0f;
1425  }
1426  }
1427 
1428  process.delta = process.size * 0.001f;
1429 
1431 
1432  /* initialize all mainb (MetaElems) */
1433  init_meta(depsgraph, &process, scene, ob);
1434 
1435  if (process.totelem > 0) {
1437 
1438  /* Don't polygonize meta-balls with too high resolution (base mball to small)
1439  * note: Eps was 0.0001f but this was giving problems for blood animation for
1440  * the open movie "Sintel", using 0.00001f. */
1441  if (ob->scale[0] > 0.00001f * (process.allbb.max[0] - process.allbb.min[0]) ||
1442  ob->scale[1] > 0.00001f * (process.allbb.max[1] - process.allbb.min[1]) ||
1443  ob->scale[2] > 0.00001f * (process.allbb.max[2] - process.allbb.min[2])) {
1444  polygonize(&process);
1445 
1446  /* add resulting surface to displist */
1447  if (process.curindex) {
1448  dl = MEM_callocN(sizeof(DispList), "mballdisp");
1449  BLI_addtail(dispbase, dl);
1450  dl->type = DL_INDEX4;
1451  dl->nr = (int)process.curvertex;
1452  dl->parts = (int)process.curindex;
1453 
1454  dl->index = (int *)process.indices;
1455 
1456  for (a = 0; a < process.curvertex; a++) {
1458  }
1459 
1460  dl->verts = (float *)process.co;
1461  dl->nors = (float *)process.no;
1462  }
1463  }
1464  }
1465 
1467 }
typedef float(TangentPoint)[2]
display list (or rather multi purpose list) stuff.
@ DL_INDEX4
Definition: BKE_displist.h:44
@ G_TRANSFORM_OBJ
Definition: BKE_global.h:218
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:219
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
int BKE_object_visibility(const struct Object *ob, const 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.c:2160
#define ATTR_FALLTHROUGH
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
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:68
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:5318
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
bool has_zero_axis_m4(const float matrix[4][4])
Definition: math_matrix.c:3240
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
#define mul_m4_series(...)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void quat_to_mat4(float mat[4][4], const float q[4])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
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 mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:270
MINLINE void zero_v3(float r[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
#define BLI_MEMARENA_STD_BUFSIZE
Definition: BLI_memarena.h:36
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:131
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
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, const char delim)
Definition: string_utils.c:55
unsigned int uint
Definition: BLI_sys_types.h:83
#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:51
eEvaluationMode
Definition: DEG_depsgraph.h:60
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
#define MAX_ID_NAME
Definition: DNA_ID.h:269
#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_DUPLIFACES
@ OB_DUPLIVERTS
#define OB_FROMDUPLI
@ OB_MBALL
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 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 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 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)
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
#define floorf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
#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 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])
static void add(GHash *messages, MemArena *memarena, const Message *msg)
Definition: msgfmt.c:268
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
struct BMLoop * next
Definition: bmesh_class.h:245
int flag_legacy
float vec[8][3]
float max[3]
const MetaElem * ml
float min[3]
short type
Definition: BKE_displist.h:71
float * verts
Definition: BKE_displist.h:74
int * index
Definition: BKE_displist.h:75
float * nors
Definition: BKE_displist.h:74
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
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]
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
ccl_device_inline float3 ceil(const float3 &a)
#define G(x, y, z)