forked from bartvdbraak/blender
code cleanup: de-duplicate cast modifier logic, had 'optimization' which was only saving a NULL check per loop, causing most of the logic to be copied, ~130 lines.
This commit is contained in:
parent
79e80d8322
commit
b390192b70
@ -137,13 +137,13 @@ static void sphere_do(
|
|||||||
int i, defgrp_index;
|
int i, defgrp_index;
|
||||||
int has_radius = 0;
|
int has_radius = 0;
|
||||||
short flag, type;
|
short flag, type;
|
||||||
float fac, facm, len = 0.0f;
|
float len = 0.0f;
|
||||||
|
float fac = cmd->fac;
|
||||||
|
float facm = 1.0f - fac;
|
||||||
|
const float fac_orig = fac;
|
||||||
float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
|
float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
|
||||||
float mat[4][4], imat[4][4];
|
float mat[4][4], imat[4][4];
|
||||||
|
|
||||||
fac = cmd->fac;
|
|
||||||
facm = 1.0f - fac;
|
|
||||||
|
|
||||||
flag = cmd->flag;
|
flag = cmd->flag;
|
||||||
type = cmd->type; /* projection type: sphere or cylinder */
|
type = cmd->type; /* projection type: sphere or cylinder */
|
||||||
|
|
||||||
@ -193,67 +193,6 @@ static void sphere_do(
|
|||||||
if (len == 0.0f) len = 10.0f;
|
if (len == 0.0f) len = 10.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ready to apply the effect, one vertex at a time;
|
|
||||||
* tiny optimization: the code is separated (with parts repeated)
|
|
||||||
* in two possible cases:
|
|
||||||
* with or w/o a vgroup. With lots of if's in the code below,
|
|
||||||
* further optimization's are possible, if needed */
|
|
||||||
if (dvert) { /* with a vgroup */
|
|
||||||
MDeformVert *dv = dvert;
|
|
||||||
float fac_orig = fac;
|
|
||||||
for (i = 0; i < numVerts; i++, dv++) {
|
|
||||||
float tmp_co[3];
|
|
||||||
float weight;
|
|
||||||
|
|
||||||
copy_v3_v3(tmp_co, vertexCos[i]);
|
|
||||||
if (ctrl_ob) {
|
|
||||||
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
|
|
||||||
mul_m4_v3(mat, tmp_co);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sub_v3_v3(tmp_co, center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_v3_v3(vec, tmp_co);
|
|
||||||
|
|
||||||
if (type == MOD_CAST_TYPE_CYLINDER)
|
|
||||||
vec[2] = 0.0f;
|
|
||||||
|
|
||||||
if (has_radius) {
|
|
||||||
if (len_v3(vec) > cmd->radius) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
weight = defvert_find_weight(dv, defgrp_index);
|
|
||||||
if (weight <= 0.0f) continue;
|
|
||||||
|
|
||||||
fac = fac_orig * weight;
|
|
||||||
facm = 1.0f - fac;
|
|
||||||
|
|
||||||
normalize_v3(vec);
|
|
||||||
|
|
||||||
if (flag & MOD_CAST_X)
|
|
||||||
tmp_co[0] = fac * vec[0] * len + facm * tmp_co[0];
|
|
||||||
if (flag & MOD_CAST_Y)
|
|
||||||
tmp_co[1] = fac * vec[1] * len + facm * tmp_co[1];
|
|
||||||
if (flag & MOD_CAST_Z)
|
|
||||||
tmp_co[2] = fac * vec[2] * len + facm * tmp_co[2];
|
|
||||||
|
|
||||||
if (ctrl_ob) {
|
|
||||||
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
|
|
||||||
mul_m4_v3(imat, tmp_co);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
add_v3_v3(tmp_co, center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_v3_v3(vertexCos[i], tmp_co);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no vgroup */
|
|
||||||
for (i = 0; i < numVerts; i++) {
|
for (i = 0; i < numVerts; i++) {
|
||||||
float tmp_co[3];
|
float tmp_co[3];
|
||||||
|
|
||||||
@ -276,6 +215,16 @@ static void sphere_do(
|
|||||||
if (len_v3(vec) > cmd->radius) continue;
|
if (len_v3(vec) > cmd->radius) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dvert) {
|
||||||
|
const float weight = defvert_find_weight(&dvert[i], defgrp_index);
|
||||||
|
if (weight == 0.0f) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fac = fac_orig * weight;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
}
|
||||||
|
|
||||||
normalize_v3(vec);
|
normalize_v3(vec);
|
||||||
|
|
||||||
if (flag & MOD_CAST_X)
|
if (flag & MOD_CAST_X)
|
||||||
@ -308,14 +257,13 @@ static void cuboid_do(
|
|||||||
int i, defgrp_index;
|
int i, defgrp_index;
|
||||||
int has_radius = 0;
|
int has_radius = 0;
|
||||||
short flag;
|
short flag;
|
||||||
float fac, facm;
|
float fac = cmd->fac;
|
||||||
|
float facm = 1.0f - fac;
|
||||||
|
const float fac_orig = fac;
|
||||||
float min[3], max[3], bb[8][3];
|
float min[3], max[3], bb[8][3];
|
||||||
float center[3] = {0.0f, 0.0f, 0.0f};
|
float center[3] = {0.0f, 0.0f, 0.0f};
|
||||||
float mat[4][4], imat[4][4];
|
float mat[4][4], imat[4][4];
|
||||||
|
|
||||||
fac = cmd->fac;
|
|
||||||
facm = 1.0f - fac;
|
|
||||||
|
|
||||||
flag = cmd->flag;
|
flag = cmd->flag;
|
||||||
|
|
||||||
ctrl_ob = cmd->object;
|
ctrl_ob = cmd->object;
|
||||||
@ -397,118 +345,10 @@ static void cuboid_do(
|
|||||||
bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
|
bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
|
||||||
bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
|
bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
|
||||||
|
|
||||||
/* ready to apply the effect, one vertex at a time;
|
/* ready to apply the effect, one vertex at a time */
|
||||||
* tiny optimization: the code is separated (with parts repeated)
|
|
||||||
* in two possible cases:
|
|
||||||
* with or w/o a vgroup. With lots of if's in the code below,
|
|
||||||
* further optimization's are possible, if needed */
|
|
||||||
if (dvert) { /* with a vgroup */
|
|
||||||
float fac_orig = fac;
|
|
||||||
for (i = 0; i < numVerts; i++) {
|
|
||||||
MDeformWeight *dw = NULL;
|
|
||||||
int j, octant, coord;
|
|
||||||
float d[3], dmax, apex[3], fbb;
|
|
||||||
float tmp_co[3];
|
|
||||||
|
|
||||||
copy_v3_v3(tmp_co, vertexCos[i]);
|
|
||||||
if (ctrl_ob) {
|
|
||||||
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
|
|
||||||
mul_m4_v3(mat, tmp_co);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sub_v3_v3(tmp_co, center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_radius) {
|
|
||||||
if (fabsf(tmp_co[0]) > cmd->radius ||
|
|
||||||
fabsf(tmp_co[1]) > cmd->radius ||
|
|
||||||
fabsf(tmp_co[2]) > cmd->radius)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < dvert[i].totweight; ++j) {
|
|
||||||
if (dvert[i].dw[j].def_nr == defgrp_index) {
|
|
||||||
dw = &dvert[i].dw[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!dw) continue;
|
|
||||||
|
|
||||||
fac = fac_orig * dw->weight;
|
|
||||||
facm = 1.0f - fac;
|
|
||||||
|
|
||||||
/* The algo used to project the vertices to their
|
|
||||||
* bounding box (bb) is pretty simple:
|
|
||||||
* for each vertex v:
|
|
||||||
* 1) find in which octant v is in;
|
|
||||||
* 2) find which outer "wall" of that octant is closer to v;
|
|
||||||
* 3) calculate factor (var fbb) to project v to that wall;
|
|
||||||
* 4) project. */
|
|
||||||
|
|
||||||
/* find in which octant this vertex is in */
|
|
||||||
octant = 0;
|
|
||||||
if (tmp_co[0] > 0.0f) octant += 1;
|
|
||||||
if (tmp_co[1] > 0.0f) octant += 2;
|
|
||||||
if (tmp_co[2] > 0.0f) octant += 4;
|
|
||||||
|
|
||||||
/* apex is the bb's vertex at the chosen octant */
|
|
||||||
copy_v3_v3(apex, bb[octant]);
|
|
||||||
|
|
||||||
/* find which bb plane is closest to this vertex ... */
|
|
||||||
d[0] = tmp_co[0] / apex[0];
|
|
||||||
d[1] = tmp_co[1] / apex[1];
|
|
||||||
d[2] = tmp_co[2] / apex[2];
|
|
||||||
|
|
||||||
/* ... (the closest has the higher (closer to 1) d value) */
|
|
||||||
dmax = d[0];
|
|
||||||
coord = 0;
|
|
||||||
if (d[1] > dmax) {
|
|
||||||
dmax = d[1];
|
|
||||||
coord = 1;
|
|
||||||
}
|
|
||||||
if (d[2] > dmax) {
|
|
||||||
/* dmax = d[2]; */ /* commented, we don't need it */
|
|
||||||
coord = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ok, now we know which coordinate of the vertex to use */
|
|
||||||
|
|
||||||
if (fabsf(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* finally, this is the factor we wanted, to project the vertex
|
|
||||||
* to its bounding box (bb) */
|
|
||||||
fbb = apex[coord] / tmp_co[coord];
|
|
||||||
|
|
||||||
/* calculate the new vertex position */
|
|
||||||
if (flag & MOD_CAST_X)
|
|
||||||
tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
|
|
||||||
if (flag & MOD_CAST_Y)
|
|
||||||
tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
|
|
||||||
if (flag & MOD_CAST_Z)
|
|
||||||
tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
|
|
||||||
|
|
||||||
if (ctrl_ob) {
|
|
||||||
if (flag & MOD_CAST_USE_OB_TRANSFORM) {
|
|
||||||
mul_m4_v3(imat, tmp_co);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
add_v3_v3(tmp_co, center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_v3_v3(vertexCos[i], tmp_co);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no vgroup (check previous case for comments about the code) */
|
|
||||||
for (i = 0; i < numVerts; i++) {
|
for (i = 0; i < numVerts; i++) {
|
||||||
int octant, coord;
|
int octant, coord;
|
||||||
float d[3], dmax, fbb, apex[3];
|
float d[3], dmax, apex[3], fbb;
|
||||||
float tmp_co[3];
|
float tmp_co[3];
|
||||||
|
|
||||||
copy_v3_v3(tmp_co, vertexCos[i]);
|
copy_v3_v3(tmp_co, vertexCos[i]);
|
||||||
@ -530,17 +370,39 @@ static void cuboid_do(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dvert) {
|
||||||
|
const float weight = defvert_find_weight(&dvert[i], defgrp_index);
|
||||||
|
if (weight == 0.0f) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fac = fac_orig * weight;
|
||||||
|
facm = 1.0f - fac;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The algo used to project the vertices to their
|
||||||
|
* bounding box (bb) is pretty simple:
|
||||||
|
* for each vertex v:
|
||||||
|
* 1) find in which octant v is in;
|
||||||
|
* 2) find which outer "wall" of that octant is closer to v;
|
||||||
|
* 3) calculate factor (var fbb) to project v to that wall;
|
||||||
|
* 4) project. */
|
||||||
|
|
||||||
|
/* find in which octant this vertex is in */
|
||||||
octant = 0;
|
octant = 0;
|
||||||
if (tmp_co[0] > 0.0f) octant += 1;
|
if (tmp_co[0] > 0.0f) octant += 1;
|
||||||
if (tmp_co[1] > 0.0f) octant += 2;
|
if (tmp_co[1] > 0.0f) octant += 2;
|
||||||
if (tmp_co[2] > 0.0f) octant += 4;
|
if (tmp_co[2] > 0.0f) octant += 4;
|
||||||
|
|
||||||
|
/* apex is the bb's vertex at the chosen octant */
|
||||||
copy_v3_v3(apex, bb[octant]);
|
copy_v3_v3(apex, bb[octant]);
|
||||||
|
|
||||||
|
/* find which bb plane is closest to this vertex ... */
|
||||||
d[0] = tmp_co[0] / apex[0];
|
d[0] = tmp_co[0] / apex[0];
|
||||||
d[1] = tmp_co[1] / apex[1];
|
d[1] = tmp_co[1] / apex[1];
|
||||||
d[2] = tmp_co[2] / apex[2];
|
d[2] = tmp_co[2] / apex[2];
|
||||||
|
|
||||||
|
/* ... (the closest has the higher (closer to 1) d value) */
|
||||||
dmax = d[0];
|
dmax = d[0];
|
||||||
coord = 0;
|
coord = 0;
|
||||||
if (d[1] > dmax) {
|
if (d[1] > dmax) {
|
||||||
@ -552,11 +414,16 @@ static void cuboid_do(
|
|||||||
coord = 2;
|
coord = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabsf(tmp_co[coord]) < FLT_EPSILON)
|
/* ok, now we know which coordinate of the vertex to use */
|
||||||
|
|
||||||
|
if (fabsf(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* finally, this is the factor we wanted, to project the vertex
|
||||||
|
* to its bounding box (bb) */
|
||||||
fbb = apex[coord] / tmp_co[coord];
|
fbb = apex[coord] / tmp_co[coord];
|
||||||
|
|
||||||
|
/* calculate the new vertex position */
|
||||||
if (flag & MOD_CAST_X)
|
if (flag & MOD_CAST_X)
|
||||||
tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
|
tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
|
||||||
if (flag & MOD_CAST_Y)
|
if (flag & MOD_CAST_Y)
|
||||||
|
Loading…
Reference in New Issue
Block a user