Cleanup: simplify init_meta logic
- Remove redundant loop on meta-elements. - Use continue to reduce nested blocks. - Move zero-axis matrix check into a function.
This commit is contained in:
@@ -1158,6 +1158,19 @@ static void polygonize(PROCESS *process)
|
||||
}
|
||||
}
|
||||
|
||||
static bool object_has_zero_axis_matrix(const Object *bob)
|
||||
{
|
||||
if (has_zero_axis_m4(bob->object_to_world().ptr())) {
|
||||
return true;
|
||||
}
|
||||
for (Object *pob = bob->parent; pob; pob = pob->parent) {
|
||||
if (has_zero_axis_m4(pob->object_to_world().ptr())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over ALL objects in the scene and all of its sets, including
|
||||
* making all duplis (not only meta-elements). Copies meta-elements to #process.mainb array.
|
||||
@@ -1168,19 +1181,15 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
|
||||
Scene *sce_iter = scene;
|
||||
Base *base;
|
||||
Object *bob;
|
||||
MetaBall *mb;
|
||||
const MetaElem *ml;
|
||||
float obinv[4][4], obmat[4][4];
|
||||
uint i;
|
||||
int obnr, zero_size = 0;
|
||||
int obnr;
|
||||
char obname[MAX_ID_NAME];
|
||||
SceneBaseIter iter;
|
||||
const eEvaluationMode deg_eval_mode = DEG_get_mode(depsgraph);
|
||||
const short parenting_dupli_transflag = (OB_DUPLIFACES | OB_DUPLIVERTS);
|
||||
|
||||
copy_m4_m4(
|
||||
obmat,
|
||||
ob->object_to_world().ptr()); /* to cope with duplicators from BKE_scene_base_iter_next */
|
||||
/* Copy object matrices to cope with duplicators from #BKE_scene_base_iter_next. */
|
||||
float obinv[4][4], obmat[4][4];
|
||||
copy_m4_m4(obmat, ob->object_to_world().ptr());
|
||||
invert_m4_m4(obinv, ob->object_to_world().ptr());
|
||||
|
||||
BLI_string_split_name_number(ob->id.name + 2, '.', obname, &obnr);
|
||||
@@ -1188,187 +1197,154 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
|
||||
/* make main array */
|
||||
BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 0, nullptr, nullptr);
|
||||
while (BKE_scene_base_iter_next(depsgraph, &iter, &sce_iter, 1, &base, &bob)) {
|
||||
if (bob->type == OB_MBALL) {
|
||||
zero_size = 0;
|
||||
ml = nullptr;
|
||||
if (bob->type != OB_MBALL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If this metaball is the original that's used for duplication, only have it visible when
|
||||
* the instancer is visible too. */
|
||||
if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != nullptr &&
|
||||
(ob->parent->transflag & parenting_dupli_transflag) != 0 &&
|
||||
(BKE_object_visibility(ob->parent, deg_eval_mode) & OB_VISIBLE_SELF) == 0)
|
||||
{
|
||||
/* If this metaball is the original that's used for duplication, only have it visible when
|
||||
* the instancer is visible too. */
|
||||
if ((base->flag_legacy & OB_FROMDUPLI) == 0 && ob->parent != nullptr &&
|
||||
(ob->parent->transflag & parenting_dupli_transflag) != 0 &&
|
||||
(BKE_object_visibility(ob->parent, deg_eval_mode) & OB_VISIBLE_SELF) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
|
||||
/* Pass. */
|
||||
}
|
||||
else {
|
||||
char name[MAX_ID_NAME];
|
||||
int nr;
|
||||
BLI_string_split_name_number(bob->id.name + 2, '.', name, &nr);
|
||||
if (!STREQ(obname, name)) {
|
||||
/* Not part of the mother-ball, continue. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
|
||||
mb = static_cast<MetaBall *>(ob->data);
|
||||
/* When metaball object has zero scale, then MetaElem to this MetaBall
|
||||
* will not be put to `mainb` array. */
|
||||
if (object_has_zero_axis_matrix(bob)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mb->editelems) {
|
||||
ml = static_cast<const MetaElem *>(mb->editelems->first);
|
||||
}
|
||||
else {
|
||||
ml = static_cast<const MetaElem *>(mb->elems.first);
|
||||
}
|
||||
const MetaBall *mb = static_cast<MetaBall *>(bob->data);
|
||||
LISTBASE_FOREACH (const MetaElem *, ml, (mb->editelems ? mb->editelems : &mb->elems)) {
|
||||
if (ml->flag & MB_HIDE) {
|
||||
continue;
|
||||
}
|
||||
float pos[4][4], rot[4][4];
|
||||
float expx, expy, expz;
|
||||
blender::float3 tempmin, tempmax;
|
||||
|
||||
/* make a copy because of duplicates */
|
||||
MetaElem *new_ml = static_cast<MetaElem *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem)));
|
||||
*(new_ml) = *ml;
|
||||
new_ml->bb = static_cast<BoundBox *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox)));
|
||||
new_ml->mat = static_cast<float *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
|
||||
new_ml->imat = static_cast<float *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
|
||||
|
||||
/* too big stiffness seems only ugly due to linear interpolation
|
||||
* no need to have possibility for too big stiffness */
|
||||
if (ml->s > 10.0f) {
|
||||
new_ml->s = 10.0f;
|
||||
}
|
||||
else {
|
||||
char name[MAX_ID_NAME];
|
||||
int nr;
|
||||
|
||||
BLI_string_split_name_number(bob->id.name + 2, '.', name, &nr);
|
||||
if (STREQ(obname, name)) {
|
||||
mb = static_cast<MetaBall *>(bob->data);
|
||||
|
||||
if (mb->editelems) {
|
||||
ml = static_cast<const MetaElem *>(mb->editelems->first);
|
||||
}
|
||||
else {
|
||||
ml = static_cast<const MetaElem *>(mb->elems.first);
|
||||
}
|
||||
}
|
||||
new_ml->s = ml->s;
|
||||
}
|
||||
|
||||
/* when metaball object has zero scale, then MetaElem to this MetaBall
|
||||
* will not be put to mainb array */
|
||||
if (has_zero_axis_m4(bob->object_to_world().ptr())) {
|
||||
zero_size = 1;
|
||||
}
|
||||
else if (bob->parent) {
|
||||
Object *pob = bob->parent;
|
||||
while (pob) {
|
||||
if (has_zero_axis_m4(pob->object_to_world().ptr())) {
|
||||
zero_size = 1;
|
||||
break;
|
||||
}
|
||||
pob = pob->parent;
|
||||
}
|
||||
/* if metaball is negative, set stiffness negative */
|
||||
if (new_ml->flag & MB_NEGATIVE) {
|
||||
new_ml->s = -new_ml->s;
|
||||
}
|
||||
|
||||
if (zero_size) {
|
||||
while (ml) {
|
||||
ml = ml->next;
|
||||
}
|
||||
/* Translation of MetaElem */
|
||||
unit_m4(pos);
|
||||
pos[3][0] = ml->x;
|
||||
pos[3][1] = ml->y;
|
||||
pos[3][2] = ml->z;
|
||||
|
||||
/* Rotation of MetaElem is stored in quat */
|
||||
quat_to_mat4(rot, ml->quat);
|
||||
|
||||
/* Matrix multiply is as follows:
|
||||
* basis object space ->
|
||||
* world ->
|
||||
* ml object space ->
|
||||
* position ->
|
||||
* rotation ->
|
||||
* ml local space
|
||||
*/
|
||||
mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->object_to_world().ptr(), pos, rot);
|
||||
/* ml local space -> basis object space */
|
||||
invert_m4_m4((float(*)[4])new_ml->imat, (float(*)[4])new_ml->mat);
|
||||
|
||||
/* rad2 is inverse of squared radius */
|
||||
new_ml->rad2 = 1 / (ml->rad * ml->rad);
|
||||
|
||||
/* initial dimensions = radius */
|
||||
expx = ml->rad;
|
||||
expy = ml->rad;
|
||||
expz = ml->rad;
|
||||
|
||||
switch (ml->type) {
|
||||
case MB_BALL:
|
||||
break;
|
||||
case MB_CUBE: /* cube is "expanded" by expz, expy and expx */
|
||||
expz += ml->expz;
|
||||
ATTR_FALLTHROUGH;
|
||||
case MB_PLANE: /* plane is "expanded" by expy and expx */
|
||||
expy += ml->expy;
|
||||
ATTR_FALLTHROUGH;
|
||||
case MB_TUBE: /* tube is "expanded" by expx */
|
||||
expx += ml->expx;
|
||||
break;
|
||||
case MB_ELIPSOID: /* ellipsoid is "stretched" by exp* */
|
||||
expx *= ml->expx;
|
||||
expy *= ml->expy;
|
||||
expz *= ml->expz;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
while (ml) {
|
||||
if (!(ml->flag & MB_HIDE)) {
|
||||
float pos[4][4], rot[4][4];
|
||||
float expx, expy, expz;
|
||||
blender::float3 tempmin, tempmax;
|
||||
|
||||
MetaElem *new_ml;
|
||||
/* 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(new_ml->bb->vec[0], -expx, -expy, -expz); /* 0 */
|
||||
copy_v3_fl3(new_ml->bb->vec[1], +expx, -expy, -expz); /* 1 */
|
||||
copy_v3_fl3(new_ml->bb->vec[2], +expx, +expy, -expz); /* 2 */
|
||||
copy_v3_fl3(new_ml->bb->vec[3], -expx, +expy, -expz); /* 3 */
|
||||
copy_v3_fl3(new_ml->bb->vec[4], -expx, -expy, +expz); /* 4 */
|
||||
copy_v3_fl3(new_ml->bb->vec[5], +expx, -expy, +expz); /* 5 */
|
||||
copy_v3_fl3(new_ml->bb->vec[6], +expx, +expy, +expz); /* 6 */
|
||||
copy_v3_fl3(new_ml->bb->vec[7], -expx, +expy, +expz); /* 7 */
|
||||
|
||||
/* make a copy because of duplicates */
|
||||
new_ml = static_cast<MetaElem *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(MetaElem)));
|
||||
*(new_ml) = *ml;
|
||||
new_ml->bb = static_cast<BoundBox *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(BoundBox)));
|
||||
new_ml->mat = static_cast<float *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
|
||||
new_ml->imat = static_cast<float *>(
|
||||
BLI_memarena_alloc(process->pgn_elements, sizeof(float[4][4])));
|
||||
|
||||
/* too big stiffness seems only ugly due to linear interpolation
|
||||
* no need to have possibility for too big stiffness */
|
||||
if (ml->s > 10.0f) {
|
||||
new_ml->s = 10.0f;
|
||||
}
|
||||
else {
|
||||
new_ml->s = ml->s;
|
||||
}
|
||||
|
||||
/* if metaball is negative, set stiffness negative */
|
||||
if (new_ml->flag & MB_NEGATIVE) {
|
||||
new_ml->s = -new_ml->s;
|
||||
}
|
||||
|
||||
/* Translation of MetaElem */
|
||||
unit_m4(pos);
|
||||
pos[3][0] = ml->x;
|
||||
pos[3][1] = ml->y;
|
||||
pos[3][2] = ml->z;
|
||||
|
||||
/* Rotation of MetaElem is stored in quat */
|
||||
quat_to_mat4(rot, ml->quat);
|
||||
|
||||
/* Matrix multiply is as follows:
|
||||
* basis object space ->
|
||||
* world ->
|
||||
* ml object space ->
|
||||
* position ->
|
||||
* rotation ->
|
||||
* ml local space
|
||||
*/
|
||||
mul_m4_series((float(*)[4])new_ml->mat, obinv, bob->object_to_world().ptr(), pos, rot);
|
||||
/* ml local space -> basis object space */
|
||||
invert_m4_m4((float(*)[4])new_ml->imat, (float(*)[4])new_ml->mat);
|
||||
|
||||
/* rad2 is inverse of squared radius */
|
||||
new_ml->rad2 = 1 / (ml->rad * ml->rad);
|
||||
|
||||
/* initial dimensions = radius */
|
||||
expx = ml->rad;
|
||||
expy = ml->rad;
|
||||
expz = ml->rad;
|
||||
|
||||
switch (ml->type) {
|
||||
case MB_BALL:
|
||||
break;
|
||||
case MB_CUBE: /* cube is "expanded" by expz, expy and expx */
|
||||
expz += ml->expz;
|
||||
ATTR_FALLTHROUGH;
|
||||
case MB_PLANE: /* plane is "expanded" by expy and expx */
|
||||
expy += ml->expy;
|
||||
ATTR_FALLTHROUGH;
|
||||
case MB_TUBE: /* tube is "expanded" by expx */
|
||||
expx += ml->expx;
|
||||
break;
|
||||
case MB_ELIPSOID: /* ellipsoid is "stretched" by exp* */
|
||||
expx *= ml->expx;
|
||||
expy *= ml->expy;
|
||||
expz *= ml->expz;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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(new_ml->bb->vec[0], -expx, -expy, -expz); /* 0 */
|
||||
copy_v3_fl3(new_ml->bb->vec[1], +expx, -expy, -expz); /* 1 */
|
||||
copy_v3_fl3(new_ml->bb->vec[2], +expx, +expy, -expz); /* 2 */
|
||||
copy_v3_fl3(new_ml->bb->vec[3], -expx, +expy, -expz); /* 3 */
|
||||
copy_v3_fl3(new_ml->bb->vec[4], -expx, -expy, +expz); /* 4 */
|
||||
copy_v3_fl3(new_ml->bb->vec[5], +expx, -expy, +expz); /* 5 */
|
||||
copy_v3_fl3(new_ml->bb->vec[6], +expx, +expy, +expz); /* 6 */
|
||||
copy_v3_fl3(new_ml->bb->vec[7], -expx, +expy, +expz); /* 7 */
|
||||
|
||||
/* Transformation of meta-elem bounding-box. */
|
||||
for (i = 0; i < 8; i++) {
|
||||
mul_m4_v3((float(*)[4])new_ml->mat, new_ml->bb->vec[i]);
|
||||
}
|
||||
|
||||
/* Find max and min of transformed bounding-box. */
|
||||
INIT_MINMAX(tempmin, tempmax);
|
||||
for (i = 0; i < 8; i++) {
|
||||
blender::math::min_max(blender::float3(new_ml->bb->vec[i]), tempmin, tempmax);
|
||||
}
|
||||
|
||||
/* Set only point 0 and 6 - AABB of meta-elem. */
|
||||
copy_v3_v3(new_ml->bb->vec[0], tempmin);
|
||||
copy_v3_v3(new_ml->bb->vec[6], tempmax);
|
||||
|
||||
/* add new_ml to mainb[] */
|
||||
if (UNLIKELY(process->totelem == process->mem)) {
|
||||
process->mem = process->mem * 2 + 10;
|
||||
process->mainb = static_cast<MetaElem **>(
|
||||
MEM_reallocN(process->mainb, sizeof(MetaElem *) * process->mem));
|
||||
}
|
||||
process->mainb[process->totelem++] = new_ml;
|
||||
}
|
||||
ml = ml->next;
|
||||
}
|
||||
/* Transformation of meta-elem bounding-box. */
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
mul_m4_v3((float(*)[4])new_ml->mat, new_ml->bb->vec[i]);
|
||||
}
|
||||
|
||||
/* Find max and min of transformed bounding-box. */
|
||||
INIT_MINMAX(tempmin, tempmax);
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
blender::math::min_max(blender::float3(new_ml->bb->vec[i]), tempmin, tempmax);
|
||||
}
|
||||
|
||||
/* Set only point 0 and 6 - AABB of meta-elem. */
|
||||
copy_v3_v3(new_ml->bb->vec[0], tempmin);
|
||||
copy_v3_v3(new_ml->bb->vec[6], tempmax);
|
||||
|
||||
/* add new_ml to mainb[] */
|
||||
if (UNLIKELY(process->totelem == process->mem)) {
|
||||
process->mem = process->mem * 2 + 10;
|
||||
process->mainb = static_cast<MetaElem **>(
|
||||
MEM_reallocN(process->mainb, sizeof(MetaElem *) * process->mem));
|
||||
}
|
||||
process->mainb[process->totelem++] = new_ml;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,7 +1352,7 @@ static void init_meta(Depsgraph *depsgraph, PROCESS *process, Scene *scene, Obje
|
||||
if (process->totelem > 0) {
|
||||
copy_v3_v3(process->allbb.min, process->mainb[0]->bb->vec[0]);
|
||||
copy_v3_v3(process->allbb.max, process->mainb[0]->bb->vec[6]);
|
||||
for (i = 1; i < process->totelem; i++) {
|
||||
for (uint i = 1; i < process->totelem; i++) {
|
||||
make_box_union(process->mainb[i]->bb, &process->allbb, &process->allbb);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user