Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/mball.c')
-rw-r--r--source/blender/blenkernel/intern/mball.c649
1 files changed, 336 insertions, 313 deletions
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 43819e1e80e..0546c85db67 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -112,19 +112,6 @@ typedef struct intlists { /* list of list of integers */
struct intlists *next; /* remaining elements */
} INTLISTS;
-typedef struct process { /* parameters, function, storage */
- /* what happens here? floats, I think. */
- /* float (*function)(void); */ /* implicit surface function */
- float (*function)(float, float, float);
- float size, delta; /* cube size, normal delta */
- int bounds; /* cube range within lattice */
- CUBES *cubes; /* active cubes */
- VERTICES vertices; /* surface vertices */
- CENTERLIST **centers; /* cube center hash table */
- CORNER **corners; /* corner value hash table */
- EDGELIST **edges; /* edge and vertex id hash table */
-} PROCESS;
-
/* dividing scene using octal tree makes polygonisation faster */
typedef struct ml_pointer {
struct ml_pointer *next, *prev;
@@ -153,20 +140,41 @@ struct pgn_elements {
char *data;
};
-/* Forward declarations */
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb);
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k);
-static CORNER *setcorner(PROCESS *p, int i, int j, int k);
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f);
-
-/* Global variables */
-static struct {
+typedef struct process { /* parameters, function, storage */
+ /* ** old G_mb contents ** */
float thresh;
int totelem;
MetaElem **mainb;
octal_tree *metaball_tree;
-} G_mb = {0};
+
+ /* ** old process contents ** */
+
+ /* what happens here? floats, I think. */
+ /* float (*function)(void); */ /* implicit surface function */
+ float (*function)(struct process*, float, float, float);
+ float size, delta; /* cube size, normal delta */
+ int bounds; /* cube range within lattice */
+ CUBES *cubes; /* active cubes */
+ VERTICES vertices; /* surface vertices */
+ CENTERLIST **centers; /* cube center hash table */
+ CORNER **corners; /* corner value hash table */
+ EDGELIST **edges; /* edge and vertex id hash table */
+
+ /* Runtime things */
+ int *indices;
+ int totindex, curindex;
+
+ int pgn_offset;
+ struct pgn_elements *pgn_current;
+ ListBase pgn_list;
+} PROCESS;
+
+/* Forward declarations */
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb);
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k);
+static CORNER *setcorner(PROCESS *process, int i, int j, int k);
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f);
/* Functions */
@@ -519,43 +527,23 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
Scene *sce_iter = scene;
Base *base;
Object *ob, *bob = basis;
- MetaElem *ml = NULL;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- G_mb.totelem = 0;
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
return NULL;
-
+
while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
-
if (ob->type == OB_MBALL) {
- if (ob == bob) {
- MetaBall *mb = ob->data;
-
- /* if bob object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
- }
- else {
+ if (ob != bob) {
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* object ob has to be in same "group" ... it means, that it has to have
* same base of its name */
if (strcmp(obname, basisname) == 0) {
- MetaBall *mb = ob->data;
-
- /* if object is in edit mode, then dynamic list of all MetaElems
- * is stored in editelems */
- if (mb->editelems) ml = mb->editelems->first;
- /* if bob object is in object mode */
- else ml = mb->elems.first;
-
if (obnr < basisnr) {
if (!(ob->flag & OB_FROMDUPLI)) {
basis = ob;
@@ -564,12 +552,6 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
}
}
}
-
- for ( ; ml; ml = ml->next) {
- if (!(ml->flag & MB_HIDE)) {
- G_mb.totelem++;
- }
- }
}
}
@@ -768,60 +750,57 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
return node;
}
-static float metaball(float x, float y, float z)
+static float metaball(PROCESS *process, float x, float y, float z)
/* float x, y, z; */
{
+ octal_tree *metaball_tree = process->metaball_tree;
struct octal_node *node;
struct ml_pointer *ml_p;
float dens = 0;
int a;
- if (G_mb.totelem > 1) {
- node = find_metaball_octal_node(G_mb.metaball_tree->first, x, y, z, G_mb.metaball_tree->depth);
+ if (process->totelem > 1) {
+ node = find_metaball_octal_node(metaball_tree->first, x, y, z, metaball_tree->depth);
if (node) {
for (ml_p = node->elems.first; ml_p; ml_p = ml_p->next) {
dens += densfunc(ml_p->ml, x, y, z);
}
- dens += -0.5f * (G_mb.metaball_tree->pos - node->pos);
- dens += 0.5f * (G_mb.metaball_tree->neg - node->neg);
+ dens += -0.5f * (metaball_tree->pos - node->pos);
+ dens += 0.5f * (metaball_tree->neg - node->neg);
}
else {
- for (a = 0; a < G_mb.totelem; a++) {
- dens += densfunc(G_mb.mainb[a], x, y, z);
+ for (a = 0; a < process->totelem; a++) {
+ dens += densfunc(process->mainb[a], x, y, z);
}
}
}
else {
- dens += densfunc(G_mb.mainb[0], x, y, z);
+ dens += densfunc(process->mainb[0], x, y, z);
}
- return G_mb.thresh - dens;
+ return process->thresh - dens;
}
/* ******************************************** */
-static int *indices = NULL;
-static int totindex, curindex;
-
-
-static void accum_mballfaces(int i1, int i2, int i3, int i4)
+static void accum_mballfaces(PROCESS *process, int i1, int i2, int i3, int i4)
{
int *newi, *cur;
/* static int i = 0; I would like to delete altogether, but I don't dare to, yet */
- if (totindex == curindex) {
- totindex += 256;
- newi = MEM_mallocN(4 * sizeof(int) * totindex, "vertindex");
+ if (process->totindex == process->curindex) {
+ process->totindex += 256;
+ newi = MEM_mallocN(4 * sizeof(int) * process->totindex, "vertindex");
- if (indices) {
- memcpy(newi, indices, 4 * sizeof(int) * (totindex - 256));
- MEM_freeN(indices);
+ if (process->indices) {
+ memcpy(newi, process->indices, 4 * sizeof(int) * (process->totindex - 256));
+ MEM_freeN(process->indices);
}
- indices = newi;
+ process->indices = newi;
}
- cur = indices + 4 * curindex;
+ cur = process->indices + 4 * process->curindex;
/* displists now support array drawing, we treat tri's as fake quad */
@@ -833,63 +812,62 @@ static void accum_mballfaces(int i1, int i2, int i3, int i4)
else
cur[3] = i4;
- curindex++;
+ process->curindex++;
}
/* ******************* MEMORY MANAGEMENT *********************** */
-static void *new_pgn_element(int size)
+static void *new_pgn_element(PROCESS *process, int size)
{
/* during polygonize 1000s of elements are allocated
* and never freed in between. Freeing only done at the end.
*/
int blocksize = 16384;
- static int offs = 0; /* the current free address */
- static struct pgn_elements *cur = NULL;
- static ListBase lb = {NULL, NULL};
void *adr;
if (size > 10000 || size == 0) {
printf("incorrect use of new_pgn_element\n");
}
else if (size == -1) {
- cur = lb.first;
+ struct pgn_elements *cur = process->pgn_list.first;
while (cur) {
MEM_freeN(cur->data);
cur = cur->next;
}
- BLI_freelistN(&lb);
+ BLI_freelistN(&process->pgn_list);
return NULL;
}
size = 4 * ( (size + 3) / 4);
- if (cur) {
- if (size + offs < blocksize) {
- adr = (void *) (cur->data + offs);
- offs += size;
+ if (process->pgn_current) {
+ if (size + process->pgn_offset < blocksize) {
+ adr = (void *) (process->pgn_current->data + process->pgn_offset);
+ process->pgn_offset += size;
return adr;
}
}
- cur = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
- cur->data = MEM_callocN(blocksize, "newpgn");
- BLI_addtail(&lb, cur);
+ process->pgn_current = MEM_callocN(sizeof(struct pgn_elements), "newpgn");
+ process->pgn_current->data = MEM_callocN(blocksize, "newpgn");
+ BLI_addtail(&process->pgn_list, process->pgn_current);
- offs = size;
- return cur->data;
+ process->pgn_offset = size;
+ return process->pgn_current->data;
}
-static void freepolygonize(PROCESS *p)
+static void freepolygonize(PROCESS *process)
{
- MEM_freeN(p->corners);
- MEM_freeN(p->edges);
- MEM_freeN(p->centers);
+ MEM_freeN(process->corners);
+ MEM_freeN(process->edges);
+ MEM_freeN(process->centers);
- new_pgn_element(-1);
-
- if (p->vertices.ptr) MEM_freeN(p->vertices.ptr);
+ new_pgn_element(process, -1);
+
+ if (process->vertices.ptr) {
+ MEM_freeN(process->vertices.ptr);
+ }
}
/**** Cubical Polygonization (optional) ****/
@@ -928,7 +906,7 @@ static int rightface[12] = {
/* docube: triangulate the cube directly, without decomposition */
-static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
+static void docube(PROCESS *process, CUBE *cube, MetaBall *mb)
{
INTLISTS *polys;
CORNER *c1, *c2;
@@ -945,45 +923,45 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
c1 = cube->corners[corner1[edges->i]];
c2 = cube->corners[corner2[edges->i]];
- indexar[count] = vertid(c1, c2, p, mb);
+ indexar[count] = vertid(process, c1, c2, mb);
count++;
}
if (count > 2) {
switch (count) {
case 3:
- accum_mballfaces(indexar[2], indexar[1], indexar[0], 0);
+ accum_mballfaces(process, indexar[2], indexar[1], indexar[0], 0);
break;
case 4:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
break;
case 5:
- if (indexar[0] == 0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
+ if (indexar[0] == 0) accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ else accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[4], indexar[3], indexar[0], 0);
+ accum_mballfaces(process, indexar[4], indexar[3], indexar[0], 0);
break;
case 6:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
break;
case 7:
if (indexar[0] == 0) {
- accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
- accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
+ accum_mballfaces(process, indexar[0], indexar[3], indexar[2], indexar[1]);
+ accum_mballfaces(process, indexar[0], indexar[5], indexar[4], indexar[3]);
}
else {
- accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
- accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
+ accum_mballfaces(process, indexar[3], indexar[2], indexar[1], indexar[0]);
+ accum_mballfaces(process, indexar[5], indexar[4], indexar[3], indexar[0]);
}
- accum_mballfaces(indexar[6], indexar[5], indexar[0], 0);
+ accum_mballfaces(process, indexar[6], indexar[5], indexar[0], 0);
break;
}
@@ -996,10 +974,10 @@ static void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
* if surface crosses face, compute other four corners of adjacent cube
* and add new cube to cube stack */
-static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4, PROCESS *p)
+static void testface(PROCESS *process, int i, int j, int k, CUBE *old, int bit, int c1, int c2, int c3, int c4)
{
CUBE newc;
- CUBES *oldcubes = p->cubes;
+ CUBES *oldcubes = process->cubes;
CORNER *corn1, *corn2, *corn3, *corn4;
int n, pos;
@@ -1015,12 +993,13 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
/* test if cube out of bounds */
/*if ( abs(i) > p->bounds || abs(j) > p->bounds || abs(k) > p->bounds) return;*/
/* test if already visited (always as last) */
- if (setcenter(p->centers, i, j, k)) return;
-
+ if (setcenter(process, process->centers, i, j, k)) {
+ return;
+ }
/* create new cube and add cube to top of stack: */
- p->cubes = (CUBES *) new_pgn_element(sizeof(CUBES));
- p->cubes->next = oldcubes;
+ process->cubes = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ process->cubes->next = oldcubes;
newc.i = i;
newc.j = j;
@@ -1032,22 +1011,22 @@ static void testface(int i, int j, int k, CUBE *old, int bit, int c1, int c2, in
newc.corners[FLIP(c3, bit)] = corn3;
newc.corners[FLIP(c4, bit)] = corn4;
- if (newc.corners[0] == NULL) newc.corners[0] = setcorner(p, i, j, k);
- if (newc.corners[1] == NULL) newc.corners[1] = setcorner(p, i, j, k + 1);
- if (newc.corners[2] == NULL) newc.corners[2] = setcorner(p, i, j + 1, k);
- if (newc.corners[3] == NULL) newc.corners[3] = setcorner(p, i, j + 1, k + 1);
- if (newc.corners[4] == NULL) newc.corners[4] = setcorner(p, i + 1, j, k);
- if (newc.corners[5] == NULL) newc.corners[5] = setcorner(p, i + 1, j, k + 1);
- if (newc.corners[6] == NULL) newc.corners[6] = setcorner(p, i + 1, j + 1, k);
- if (newc.corners[7] == NULL) newc.corners[7] = setcorner(p, i + 1, j + 1, k + 1);
+ if (newc.corners[0] == NULL) newc.corners[0] = setcorner(process, i, j, k);
+ if (newc.corners[1] == NULL) newc.corners[1] = setcorner(process, i, j, k + 1);
+ if (newc.corners[2] == NULL) newc.corners[2] = setcorner(process, i, j + 1, k);
+ if (newc.corners[3] == NULL) newc.corners[3] = setcorner(process, i, j + 1, k + 1);
+ if (newc.corners[4] == NULL) newc.corners[4] = setcorner(process, i + 1, j, k);
+ if (newc.corners[5] == NULL) newc.corners[5] = setcorner(process, i + 1, j, k + 1);
+ if (newc.corners[6] == NULL) newc.corners[6] = setcorner(process, i + 1, j + 1, k);
+ if (newc.corners[7] == NULL) newc.corners[7] = setcorner(process, i + 1, j + 1, k + 1);
- p->cubes->cube = newc;
+ process->cubes->cube = newc;
}
/* setcorner: return corner with the given lattice location
* set (and cache) its function value */
-static CORNER *setcorner(PROCESS *p, int i, int j, int k)
+static CORNER *setcorner(PROCESS *process, int i, int j, int k)
{
/* for speed, do corner value caching here */
CORNER *c;
@@ -1055,7 +1034,7 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
/* does corner exist? */
index = HASH(i, j, k);
- c = p->corners[index];
+ c = process->corners[index];
for (; c != NULL; c = c->next) {
if (c->i == i && c->j == j && c->k == k) {
@@ -1063,18 +1042,18 @@ static CORNER *setcorner(PROCESS *p, int i, int j, int k)
}
}
- c = (CORNER *) new_pgn_element(sizeof(CORNER));
+ c = (CORNER *) new_pgn_element(process, sizeof(CORNER));
c->i = i;
- c->co[0] = ((float)i - 0.5f) * p->size;
+ c->co[0] = ((float)i - 0.5f) * process->size;
c->j = j;
- c->co[1] = ((float)j - 0.5f) * p->size;
+ c->co[1] = ((float)j - 0.5f) * process->size;
c->k = k;
- c->co[2] = ((float)k - 0.5f) * p->size;
- c->value = p->function(c->co[0], c->co[1], c->co[2]);
+ c->co[2] = ((float)k - 0.5f) * process->size;
+ c->value = process->function(process, c->co[0], c->co[1], c->co[2]);
- c->next = p->corners[index];
- p->corners[index] = c;
+ c->next = process->corners[index];
+ process->corners[index] = c;
return c;
}
@@ -1196,7 +1175,7 @@ void BKE_mball_cubeTable_free(void)
/* setcenter: set (i, j, k) entry of table[]
* return 1 if already set; otherwise, set and return 0 */
-static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
+static int setcenter(PROCESS *process, CENTERLIST *table[], const int i, const int j, const int k)
{
int index;
CENTERLIST *newc, *l, *q;
@@ -1208,7 +1187,7 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
if (l->i == i && l->j == j && l->k == k) return 1;
}
- newc = (CENTERLIST *) new_pgn_element(sizeof(CENTERLIST));
+ newc = (CENTERLIST *) new_pgn_element(process, sizeof(CENTERLIST));
newc->i = i;
newc->j = j;
newc->k = k;
@@ -1221,7 +1200,8 @@ static int setcenter(CENTERLIST *table[], const int i, const int j, const int k)
/* setedge: set vertex id for edge */
-static void setedge(EDGELIST *table[],
+static void setedge(PROCESS *process,
+ EDGELIST *table[],
int i1, int j1,
int k1, int i2,
int j2, int k2,
@@ -1242,7 +1222,7 @@ static void setedge(EDGELIST *table[],
k2 = t;
}
index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
- newe = (EDGELIST *) new_pgn_element(sizeof(EDGELIST));
+ newe = (EDGELIST *) new_pgn_element(process, sizeof(EDGELIST));
newe->i1 = i1;
newe->j1 = j1;
newe->k1 = k1;
@@ -1316,14 +1296,14 @@ static void addtovertices(VERTICES *vertices, VERTEX v)
/* vnormal: compute unit length surface normal at point */
-static void vnormal(const float point[3], PROCESS *p, float r_no[3])
+static void vnormal(PROCESS *process, const float point[3], float r_no[3])
{
- const float delta = 0.2f * p->delta;
- const float f = p->function(point[0], point[1], point[2]);
+ const float delta = 0.2f * process->delta;
+ const float f = process->function(process, point[0], point[1], point[2]);
- r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- r_no[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ r_no[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ r_no[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ r_no[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
#if 1
normalize_v3(r_no);
@@ -1335,11 +1315,11 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
delta *= 2.0f;
- f = p->function(point[0], point[1], point[2]);
+ f = process->function(process, point[0], point[1], point[2]);
- tvec[0] = p->function(point[0] + delta, point[1], point[2]) - f;
- tvec[1] = p->function(point[0], point[1] + delta, point[2]) - f;
- tvec[2] = p->function(point[0], point[1], point[2] + delta) - f;
+ tvec[0] = process->function(process, point[0] + delta, point[1], point[2]) - f;
+ tvec[1] = process->function(process, point[0], point[1] + delta, point[2]) - f;
+ tvec[2] = process->function(process, point[0], point[1], point[2] + delta) - f;
if (normalize_v3(tvec) != 0.0f) {
add_v3_v3(r_no, tvec);
@@ -1350,32 +1330,30 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3])
}
-static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb)
+static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2, MetaBall *mb)
{
VERTEX v;
- int vid = getedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
+ int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
if (vid != -1) {
return vid; /* previously computed */
}
- converge(c1->co, c2->co, c1->value, c2->value, p->function, v.co, mb, 1); /* position */
- vnormal(v.co, p, v.no);
+ converge(process, c1->co, c2->co, c1->value, c2->value, v.co, mb, 1); /* position */
+ vnormal(process, v.co, v.no);
- addtovertices(&p->vertices, v); /* save vertex */
- vid = p->vertices.count - 1;
- setedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
+ addtovertices(&process->vertices, v); /* save vertex */
+ vid = process->vertices.count - 1;
+ setedge(process, process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
return vid;
}
-
-
/* converge: from two points of differing sign, converge to zero crossing */
/* watch it: p1 and p2 are used to calculate */
-static void converge(const float p1[3], const float p2[3], float v1, float v2,
- float (*function)(float, float, float), float p[3], MetaBall *mb, int f)
+static void converge(PROCESS *process, const float p1[3], const float p2[3], float v1, float v2,
+ float p[3], MetaBall *mb, int f)
{
int i = 0;
float pos[3], neg[3];
@@ -1426,8 +1404,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[0] = 0.5f * (pos[0] + neg[0]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
- else neg[0] = p[0];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[0] = p[0];
+ else neg[0] = p[0];
}
}
@@ -1437,8 +1415,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[1] = 0.5f * (pos[1] + neg[1]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
- else neg[1] = p[1];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[1] = p[1];
+ else neg[1] = p[1];
}
}
@@ -1448,8 +1426,8 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
while (1) {
if (i++ == RES) return;
p[2] = 0.5f * (pos[2] + neg[2]);
- if ((function(p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
- else neg[2] = p[2];
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) pos[2] = p[2];
+ else neg[2] = p[2];
}
}
@@ -1461,7 +1439,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
return;
}
- if ((function(p[0], p[1], p[2])) > 0.0f) {
+ if ((process->function(process, p[0], p[1], p[2])) > 0.0f) {
copy_v3_v3(pos, &p[0]);
}
else {
@@ -1471,7 +1449,7 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
}
/* ************************************** */
-static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
+static void add_cube(PROCESS *process, int i, int j, int k, int count)
{
CUBES *ncube;
int n;
@@ -1483,11 +1461,11 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
for (b = j - 1; b < j + count; b++)
for (c = k - 1; c < k + count; c++) {
/* test if cube has been found before */
- if (setcenter(mbproc->centers, a, b, c) == 0) {
+ if (setcenter(process, process->centers, a, b, c) == 0) {
/* push cube on stack: */
- ncube = (CUBES *) new_pgn_element(sizeof(CUBES));
- ncube->next = mbproc->cubes;
- mbproc->cubes = ncube;
+ ncube = (CUBES *) new_pgn_element(process, sizeof(CUBES));
+ ncube->next = process->cubes;
+ process->cubes = ncube;
ncube->cube.i = a;
ncube->cube.j = b;
@@ -1495,18 +1473,18 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
/* set corners of initial cube: */
for (n = 0; n < 8; n++)
- ncube->cube.corners[n] = setcorner(mbproc, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
+ ncube->cube.corners[n] = setcorner(process, a + MB_BIT(n, 2), b + MB_BIT(n, 1), c + MB_BIT(n, 0));
}
}
}
-static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
+static void find_first_points(PROCESS *process, MetaBall *mb, int a)
{
MetaElem *ml;
float f;
- ml = G_mb.mainb[a];
+ ml = process->mainb[a];
f = 1.0f - (mb->thresh / ml->s);
/* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be
@@ -1521,7 +1499,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
calc_mballco(ml, in);
- in_v = mbproc->function(in[0], in[1], in[2]);
+ in_v = process->function(process, in[0], in[1], in[2]);
for (i = 0; i < 3; i++) {
switch (ml->type) {
@@ -1566,16 +1544,16 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
calc_mballco(ml, out);
- /*out_v = mbproc->function(out[0], out[1], out[2]);*/ /*UNUSED*/
+ /*out_v = process->function(out[0], out[1], out[2]);*/ /*UNUSED*/
/* find "first points" on Implicit Surface of MetaElemnt ml */
copy_v3_v3(workp, in);
workp_v = in_v;
max_len = len_v3v3(out, in);
- nx = abs((out[0] - in[0]) / mbproc->size);
- ny = abs((out[1] - in[1]) / mbproc->size);
- nz = abs((out[2] - in[2]) / mbproc->size);
+ nx = abs((out[0] - in[0]) / process->size);
+ ny = abs((out[1] - in[1]) / process->size);
+ nz = abs((out[2] - in[2]) / process->size);
max_dim = max_fff(nx, ny, nz);
if (max_dim != 0.0f) {
@@ -1589,22 +1567,22 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
add_v3_v3(workp, dvec);
/* compute value of implicite function */
- tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
+ tmp_v = process->function(process, workp[0], workp[1], workp[2]);
/* add cube to the stack, when value of implicite function crosses zero value */
if ((tmp_v < 0.0f && workp_v >= 0.0f) || (tmp_v > 0.0f && workp_v <= 0.0f)) {
/* indexes of CUBE, which includes "first point" */
- c_i = (int)floor(workp[0] / mbproc->size);
- c_j = (int)floor(workp[1] / mbproc->size);
- c_k = (int)floor(workp[2] / mbproc->size);
+ c_i = (int)floor(workp[0] / process->size);
+ c_j = (int)floor(workp[1] / process->size);
+ c_k = (int)floor(workp[2] / process->size);
/* add CUBE (with indexes c_i, c_j, c_k) to the stack,
* this cube includes found point of Implicit Surface */
if ((ml->flag & MB_NEGATIVE) == 0) {
- add_cube(mbproc, c_i, c_j, c_k, 1);
+ add_cube(process, c_i, c_j, c_k, 1);
}
else {
- add_cube(mbproc, c_i, c_j, c_k, 2);
+ add_cube(process, c_i, c_j, c_k, 2);
}
}
len = len_v3v3(workp, in);
@@ -1618,43 +1596,43 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
}
}
-static void polygonize(PROCESS *mbproc, MetaBall *mb)
+static void polygonize(PROCESS *process, MetaBall *mb)
{
CUBE c;
int a;
- mbproc->vertices.count = mbproc->vertices.max = 0;
- mbproc->vertices.ptr = NULL;
+ process->vertices.count = process->vertices.max = 0;
+ process->vertices.ptr = NULL;
/* allocate hash tables and build cube polygon table: */
- mbproc->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
- mbproc->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
- mbproc->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
+ process->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
+ process->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
+ process->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
makecubetable();
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
/* try to find 8 points on the surface for each MetaElem */
- find_first_points(mbproc, mb, a);
+ find_first_points(process, mb, a);
}
/* polygonize all MetaElems of current MetaBall */
- while (mbproc->cubes != NULL) { /* process active cubes till none left */
- c = mbproc->cubes->cube;
+ while (process->cubes != NULL) { /* process active cubes till none left */
+ c = process->cubes->cube;
/* polygonize the cube directly: */
- docube(&c, mbproc, mb);
+ docube(process, &c, mb);
/* pop current cube from stack */
- mbproc->cubes = mbproc->cubes->next;
+ process->cubes = process->cubes->next;
/* test six face directions, maybe add to stack: */
- testface(c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF, mbproc);
- testface(c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF, mbproc);
- testface(c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF, mbproc);
- testface(c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF, mbproc);
- testface(c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN, mbproc);
- testface(c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF, mbproc);
+ testface(process, c.i - 1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF);
+ testface(process, c.i + 1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF);
+ testface(process, c.i, c.j - 1, c.k, &c, 1, LBN, LBF, RBN, RBF);
+ testface(process, c.i, c.j + 1, c.k, &c, 1, LTN, LTF, RTN, RTF);
+ testface(process, c.i, c.j, c.k - 1, &c, 0, LBN, LTN, RBN, RTN);
+ testface(process, c.i, c.j, c.k + 1, &c, 0, LBF, LTF, RBF, RTF);
}
}
@@ -1666,7 +1644,7 @@ BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
v[2] = z;
}
-static float init_meta(Scene *scene, Object *ob) /* return totsize */
+static float init_meta(PROCESS *process, Scene *scene, Object *ob) /* return totsize */
{
Scene *sce_iter = scene;
Base *base;
@@ -1733,7 +1711,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
ml_count++;
ml = ml->next;
}
- G_mb.totelem -= ml_count;
+ process->totelem -= ml_count;
}
else {
while (ml) {
@@ -1763,12 +1741,12 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
mul_m4_m4m4(temp1, temp2, temp3);
/* make a copy because of duplicates */
- G_mb.mainb[a] = new_pgn_element(sizeof(MetaElem));
- *(G_mb.mainb[a]) = *ml;
- G_mb.mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
+ process->mainb[a] = new_pgn_element(process, sizeof(MetaElem));
+ *(process->mainb[a]) = *ml;
+ process->mainb[a]->bb = new_pgn_element(process, sizeof(BoundBox));
- mat = new_pgn_element(4 * 4 * sizeof(float));
- imat = new_pgn_element(4 * 4 * sizeof(float));
+ mat = new_pgn_element(process, 4 * 4 * sizeof(float));
+ imat = new_pgn_element(process, 4 * 4 * sizeof(float));
/* mat is the matrix to transform from mball into the basis-mball */
invert_m4_m4(obinv, obmat);
@@ -1778,10 +1756,10 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
invert_m4_m4(imat, mat);
- G_mb.mainb[a]->rad2 = ml->rad * ml->rad;
+ process->mainb[a]->rad2 = ml->rad * ml->rad;
- G_mb.mainb[a]->mat = (float *) mat;
- G_mb.mainb[a]->imat = (float *) imat;
+ process->mainb[a]->mat = (float *) mat;
+ process->mainb[a]->imat = (float *) imat;
if (!MB_TYPE_SIZE_SQUARED(ml->type)) {
expx = ml->expx;
@@ -1796,40 +1774,40 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* untransformed Bounding Box of MetaElem */
/* TODO, its possible the elem type has been changed and the exp* values can use a fallback */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
- copy_v3_fl3(G_mb.mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[0], -expx, -expy, -expz); /* 0 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[1], +expx, -expy, -expz); /* 1 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[2], +expx, +expy, -expz); /* 2 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[3], -expx, +expy, -expz); /* 3 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[4], -expx, -expy, +expz); /* 4 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[5], +expx, -expy, +expz); /* 5 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[6], +expx, +expy, +expz); /* 6 */
+ copy_v3_fl3(process->mainb[a]->bb->vec[7], -expx, +expy, +expz); /* 7 */
/* transformation of Metalem bb */
for (i = 0; i < 8; i++)
- mul_m4_v3((float (*)[4])mat, G_mb.mainb[a]->bb->vec[i]);
+ mul_m4_v3((float (*)[4])mat, process->mainb[a]->bb->vec[i]);
/* find max and min of transformed bb */
for (i = 0; i < 8; i++) {
/* find maximums */
- if (G_mb.mainb[a]->bb->vec[i][0] > max_x) max_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] > max_y) max_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] > max_z) max_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] > max_x) max_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] > max_y) max_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] > max_z) max_z = process->mainb[a]->bb->vec[i][2];
/* find minimums */
- if (G_mb.mainb[a]->bb->vec[i][0] < min_x) min_x = G_mb.mainb[a]->bb->vec[i][0];
- if (G_mb.mainb[a]->bb->vec[i][1] < min_y) min_y = G_mb.mainb[a]->bb->vec[i][1];
- if (G_mb.mainb[a]->bb->vec[i][2] < min_z) min_z = G_mb.mainb[a]->bb->vec[i][2];
+ if (process->mainb[a]->bb->vec[i][0] < min_x) min_x = process->mainb[a]->bb->vec[i][0];
+ if (process->mainb[a]->bb->vec[i][1] < min_y) min_y = process->mainb[a]->bb->vec[i][1];
+ if (process->mainb[a]->bb->vec[i][2] < min_z) min_z = process->mainb[a]->bb->vec[i][2];
}
/* create "new" bb, only point 0 and 6, which are
* necessary for octal tree filling */
- G_mb.mainb[a]->bb->vec[0][0] = min_x - ml->rad;
- G_mb.mainb[a]->bb->vec[0][1] = min_y - ml->rad;
- G_mb.mainb[a]->bb->vec[0][2] = min_z - ml->rad;
+ process->mainb[a]->bb->vec[0][0] = min_x - ml->rad;
+ process->mainb[a]->bb->vec[0][1] = min_y - ml->rad;
+ process->mainb[a]->bb->vec[0][2] = min_z - ml->rad;
- G_mb.mainb[a]->bb->vec[6][0] = max_x + ml->rad;
- G_mb.mainb[a]->bb->vec[6][1] = max_y + ml->rad;
- G_mb.mainb[a]->bb->vec[6][2] = max_z + ml->rad;
+ process->mainb[a]->bb->vec[6][0] = max_x + ml->rad;
+ process->mainb[a]->bb->vec[6][1] = max_y + ml->rad;
+ process->mainb[a]->bb->vec[6][2] = max_z + ml->rad;
a++;
}
@@ -1842,13 +1820,13 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* totsize (= 'manhattan' radius) */
totsize = 0.0;
- for (a = 0; a < G_mb.totelem; a++) {
+ for (a = 0; a < process->totelem; a++) {
- vec[0] = G_mb.mainb[a]->x + G_mb.mainb[a]->rad + G_mb.mainb[a]->expx;
- vec[1] = G_mb.mainb[a]->y + G_mb.mainb[a]->rad + G_mb.mainb[a]->expy;
- vec[2] = G_mb.mainb[a]->z + G_mb.mainb[a]->rad + G_mb.mainb[a]->expz;
+ vec[0] = process->mainb[a]->x + process->mainb[a]->rad + process->mainb[a]->expx;
+ vec[1] = process->mainb[a]->y + process->mainb[a]->rad + process->mainb[a]->expy;
+ vec[2] = process->mainb[a]->z + process->mainb[a]->rad + process->mainb[a]->expz;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1857,11 +1835,11 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
size = fabsf(vec[2]);
if (size > totsize) totsize = size;
- vec[0] = G_mb.mainb[a]->x - G_mb.mainb[a]->rad;
- vec[1] = G_mb.mainb[a]->y - G_mb.mainb[a]->rad;
- vec[2] = G_mb.mainb[a]->z - G_mb.mainb[a]->rad;
+ vec[0] = process->mainb[a]->x - process->mainb[a]->rad;
+ vec[1] = process->mainb[a]->y - process->mainb[a]->rad;
+ vec[2] = process->mainb[a]->z - process->mainb[a]->rad;
- calc_mballco(G_mb.mainb[a], vec);
+ calc_mballco(process->mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1871,8 +1849,8 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
if (size > totsize) totsize = size;
}
- for (a = 0; a < G_mb.totelem; a++) {
- G_mb.thresh += densfunc(G_mb.mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
+ for (a = 0; a < process->totelem; a++) {
+ process->thresh += densfunc(process->mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
}
return totsize;
@@ -2181,20 +2159,20 @@ static void free_metaball_octal_node(octal_node *node)
}
/* If scene include more than one MetaElem, then octree is used */
-static void init_metaball_octal_tree(int depth)
+static void init_metaball_octal_tree(PROCESS *process, int depth)
{
struct octal_node *node;
ml_pointer *ml_p;
float size[3];
int a;
- G_mb.metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
- G_mb.metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
+ process->metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
+ process->metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
/* maximal depth of octree */
- G_mb.metaball_tree->depth = depth;
+ process->metaball_tree->depth = depth;
- G_mb.metaball_tree->neg = node->neg = 0;
- G_mb.metaball_tree->pos = node->pos = 0;
+ process->metaball_tree->neg = node->neg = 0;
+ process->metaball_tree->pos = node->pos = 0;
node->elems.first = NULL;
node->elems.last = NULL;
@@ -2207,26 +2185,26 @@ static void init_metaball_octal_tree(int depth)
node->x_max = node->y_max = node->z_max = -FLT_MAX;
/* size of octal tree scene */
- for (a = 0; a < G_mb.totelem; a++) {
- if (G_mb.mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = G_mb.mainb[a]->bb->vec[0][0];
- if (G_mb.mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = G_mb.mainb[a]->bb->vec[0][1];
- if (G_mb.mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = G_mb.mainb[a]->bb->vec[0][2];
+ for (a = 0; a < process->totelem; a++) {
+ if (process->mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = process->mainb[a]->bb->vec[0][0];
+ if (process->mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = process->mainb[a]->bb->vec[0][1];
+ if (process->mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = process->mainb[a]->bb->vec[0][2];
- if (G_mb.mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = G_mb.mainb[a]->bb->vec[6][0];
- if (G_mb.mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = G_mb.mainb[a]->bb->vec[6][1];
- if (G_mb.mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = G_mb.mainb[a]->bb->vec[6][2];
+ if (process->mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = process->mainb[a]->bb->vec[6][0];
+ if (process->mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = process->mainb[a]->bb->vec[6][1];
+ if (process->mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = process->mainb[a]->bb->vec[6][2];
ml_p = MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
- ml_p->ml = G_mb.mainb[a];
+ ml_p->ml = process->mainb[a];
BLI_addtail(&node->elems, ml_p);
- if ((G_mb.mainb[a]->flag & MB_NEGATIVE) == 0) {
+ if ((process->mainb[a]->flag & MB_NEGATIVE) == 0) {
/* number of positive MetaElem in scene */
- G_mb.metaball_tree->pos++;
+ process->metaball_tree->pos++;
}
else {
/* number of negative MetaElem in scene */
- G_mb.metaball_tree->neg++;
+ process->metaball_tree->neg++;
}
}
@@ -2236,61 +2214,106 @@ static void init_metaball_octal_tree(int depth)
size[2] = node->z_max - node->z_min;
/* first node is subdivided recursively */
- subdivide_metaball_octal_node(node, size[0], size[1], size[2], G_mb.metaball_tree->depth);
+ subdivide_metaball_octal_node(node, size[0], size[1], size[2], process->metaball_tree->depth);
+}
+
+static void mball_count(PROCESS *process, Scene *scene, Object *basis)
+{
+ Scene *sce_iter = scene;
+ Base *base;
+ Object *ob, *bob = basis;
+ MetaElem *ml = NULL;
+ int basisnr, obnr;
+ char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
+
+ BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
+ process->totelem = 0;
+
+ /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
+ if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+ return;
+
+ while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+ if (ob->type == OB_MBALL) {
+ if (ob == bob) {
+ MetaBall *mb = ob->data;
+
+ /* if bob object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ else {
+ BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
+
+ /* object ob has to be in same "group" ... it means, that it has to have
+ * same base of its name */
+ if (strcmp(obname, basisname) == 0) {
+ MetaBall *mb = ob->data;
+
+ /* if object is in edit mode, then dynamic list of all MetaElems
+ * is stored in editelems */
+ if (mb->editelems) ml = mb->editelems->first;
+ /* if bob object is in object mode */
+ else ml = mb->elems.first;
+ }
+ }
+
+ for ( ; ml; ml = ml->next) {
+ if (!(ml->flag & MB_HIDE)) {
+ process->totelem++;
+ }
+ }
+ }
+ }
}
void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
{
- PROCESS mbproc;
MetaBall *mb;
DispList *dl;
int a, nr_cubes;
float *co, *no, totsize, width;
+ PROCESS process = {0};
mb = ob->data;
- if (G_mb.totelem == 0) return;
+ mball_count(&process, scene, ob);
+
+ if (process.totelem == 0) return;
if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
if (G.moving && mb->flag == MB_UPDATE_FAST) return;
- curindex = totindex = 0;
- indices = NULL;
- G_mb.thresh = mb->thresh;
+ process.thresh = mb->thresh;
/* total number of MetaElems (totelem) is precomputed in find_basis_mball() function */
- G_mb.mainb = MEM_mallocN(sizeof(void *) * G_mb.totelem, "mainb");
+ process.mainb = MEM_mallocN(sizeof(void *) * process.totelem, "mainb");
/* initialize all mainb (MetaElems) */
- totsize = init_meta(scene, ob);
-
- if (G_mb.metaball_tree) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
- }
+ totsize = init_meta(&process, scene, ob);
/* if scene includes more than one MetaElem, then octal tree optimization is used */
- if ((G_mb.totelem > 1) && (G_mb.totelem <= 64)) init_metaball_octal_tree(1);
- if ((G_mb.totelem > 64) && (G_mb.totelem <= 128)) init_metaball_octal_tree(2);
- if ((G_mb.totelem > 128) && (G_mb.totelem <= 512)) init_metaball_octal_tree(3);
- if ((G_mb.totelem > 512) && (G_mb.totelem <= 1024)) init_metaball_octal_tree(4);
- if (G_mb.totelem > 1024) init_metaball_octal_tree(5);
+ if ((process.totelem > 1) && (process.totelem <= 64)) init_metaball_octal_tree(&process, 1);
+ if ((process.totelem > 64) && (process.totelem <= 128)) init_metaball_octal_tree(&process, 2);
+ if ((process.totelem > 128) && (process.totelem <= 512)) init_metaball_octal_tree(&process, 3);
+ if ((process.totelem > 512) && (process.totelem <= 1024)) init_metaball_octal_tree(&process, 4);
+ if (process.totelem > 1024) init_metaball_octal_tree(&process, 5);
/* don't polygonize metaballs with too high resolution (base mball to small)
* note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
- if (G_mb.metaball_tree) {
- if (ob->size[0] <= 0.00001f * (G_mb.metaball_tree->first->x_max - G_mb.metaball_tree->first->x_min) ||
- ob->size[1] <= 0.00001f * (G_mb.metaball_tree->first->y_max - G_mb.metaball_tree->first->y_min) ||
- ob->size[2] <= 0.00001f * (G_mb.metaball_tree->first->z_max - G_mb.metaball_tree->first->z_min))
+ if (process.metaball_tree) {
+ if (ob->size[0] <= 0.00001f * (process.metaball_tree->first->x_max - process.metaball_tree->first->x_min) ||
+ ob->size[1] <= 0.00001f * (process.metaball_tree->first->y_max - process.metaball_tree->first->y_min) ||
+ ob->size[2] <= 0.00001f * (process.metaball_tree->first->z_max - process.metaball_tree->first->z_min))
{
- new_pgn_element(-1); /* free values created by init_meta */
+ new_pgn_element(&process, -1); /* free values created by init_meta */
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free tree */
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
return;
}
@@ -2308,46 +2331,46 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
nr_cubes = (int)(0.5f + totsize / width);
/* init process */
- mbproc.function = metaball;
- mbproc.size = width;
- mbproc.bounds = nr_cubes;
- mbproc.cubes = NULL;
- mbproc.delta = width / (float)(RES * RES);
+ process.function = metaball;
+ process.size = width;
+ process.bounds = nr_cubes;
+ process.cubes = NULL;
+ process.delta = width / (float)(RES * RES);
- polygonize(&mbproc, mb);
+ polygonize(&process, mb);
- MEM_freeN(G_mb.mainb);
+ MEM_freeN(process.mainb);
/* free octal tree */
- if (G_mb.totelem > 1) {
- free_metaball_octal_node(G_mb.metaball_tree->first);
- MEM_freeN(G_mb.metaball_tree);
- G_mb.metaball_tree = NULL;
+ if (process.totelem > 1) {
+ free_metaball_octal_node(process.metaball_tree->first);
+ MEM_freeN(process.metaball_tree);
+ process.metaball_tree = NULL;
}
- if (curindex) {
- VERTEX *ptr = mbproc.vertices.ptr;
+ if (process.curindex) {
+ VERTEX *ptr = process.vertices.ptr;
dl = MEM_callocN(sizeof(DispList), "mbaldisp");
BLI_addtail(dispbase, dl);
dl->type = DL_INDEX4;
- dl->nr = mbproc.vertices.count;
- dl->parts = curindex;
+ dl->nr = process.vertices.count;
+ dl->parts = process.curindex;
- dl->index = indices;
- indices = NULL;
+ dl->index = process.indices;
+ process.indices = NULL;
- a = mbproc.vertices.count;
+ a = process.vertices.count;
dl->verts = co = MEM_mallocN(sizeof(float) * 3 * a, "mballverts");
dl->nors = no = MEM_mallocN(sizeof(float) * 3 * a, "mballnors");
- for (a = 0; a < mbproc.vertices.count; ptr++, a++, no += 3, co += 3) {
+ for (a = 0; a < process.vertices.count; ptr++, a++, no += 3, co += 3) {
copy_v3_v3(co, ptr->co);
copy_v3_v3(no, ptr->no);
}
}
- freepolygonize(&mbproc);
+ freepolygonize(&process);
}
/* basic vertex data functions */