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:
authorCampbell Barton <ideasman42@gmail.com>2013-03-03 09:43:47 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-03-03 09:43:47 +0400
commitb390192b7024d26f421bdc93e63e8603dab18cf2 (patch)
treedf9a1817fdff9c7688dfa2e5d150caec6885503e /source/blender/modifiers
parent79e80d83229aaa1d81da84edc3102db0b00171d9 (diff)
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.
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c227
1 files changed, 47 insertions, 180 deletions
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index 2530a230e0a..d5620f91d6e 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -137,13 +137,13 @@ static void sphere_do(
int i, defgrp_index;
int has_radius = 0;
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 mat[4][4], imat[4][4];
- fac = cmd->fac;
- facm = 1.0f - fac;
-
flag = cmd->flag;
type = cmd->type; /* projection type: sphere or cylinder */
@@ -193,67 +193,6 @@ static void sphere_do(
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++) {
float tmp_co[3];
@@ -276,6 +215,16 @@ static void sphere_do(
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);
if (flag & MOD_CAST_X)
@@ -308,14 +257,13 @@ static void cuboid_do(
int i, defgrp_index;
int has_radius = 0;
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 center[3] = {0.0f, 0.0f, 0.0f};
float mat[4][4], imat[4][4];
- fac = cmd->fac;
- facm = 1.0f - fac;
-
flag = cmd->flag;
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[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
- /* 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) */
+ /* ready to apply the effect, one vertex at a time */
for (i = 0; i < numVerts; i++) {
int octant, coord;
- float d[3], dmax, fbb, apex[3];
+ float d[3], dmax, apex[3], fbb;
float tmp_co[3];
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;
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) {
@@ -552,11 +414,16 @@ static void cuboid_do(
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;
+ /* 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)