Commit: cb28ccb0d0554223401fcb57b946165d995cf7ac
Author: Bastien Montagne
Date: Fri Aug 8 18:55:17 2014 +0200
Branches: temp_custom_loop_normals
https://developer.blender.org/rBcb28ccb0d0554223401fcb57b946165d995cf7ac
Various optimizations and fixes to `mesh_normals_loop_custom_set()`.
Among other things, weighting (interpolation) of custom normal in vertex case
was broken (interpolated several times).
===================================================================
M source/blender/blenkernel/intern/mesh_evaluate.c
M source/blender/blenlib/BLI_bitmap.h
===================================================================
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c
b/source/blender/blenkernel/intern/mesh_evaluate.c
index 82e354e..0cf967d 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -1200,6 +1200,8 @@ static void mesh_normals_loop_custom_set(MVert *mverts,
const int numVerts, MEdg
*/
MLoopsNorSpaces lnors_spaces = {NULL};
BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__);
+ /* To avoid interpolating custom vnors more than once in case their
weight is not 1.0f!!! */
+ BLI_bitmap *done_verts = use_vertices ?
BLI_BITMAP_NEW((size_t)numVerts, __func__) : NULL;
float (*lnors)[3] = MEM_callocN(sizeof(*lnors) * (size_t)numLoops,
__func__);
int *loop_to_poly = MEM_mallocN(sizeof(int) * (size_t)numLoops,
__func__);
const float split_angle = (float)M_PI; /* In this case we do not want
to use angle to define smooth fans! */
@@ -1211,91 +1213,103 @@ static void mesh_normals_loop_custom_set(MVert
*mverts, const int numVerts, MEdg
BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops,
lnors, numLoops,
mpolys, polynors, numPolys, split_angle,
&lnors_spaces, NULL, loop_to_poly);
- /* Now, check each current smooth fan (one lnor space per smooth fan!),
and if all its matching custom lnors
- * are not (enough) equal, add sharp edges as needed.
- * This way, next time we run BKE_mesh_normals_loop_split(), we'll get
lnor spaces/smooth fans matching
- * given custom lnors.
- * Note this code *will never* unsharp edges!
- */
- for (i = 0; i < numLoops; i++) {
- if (!lnors_spaces.lspaces[i]) {
- /* This should not happen in theory, but in some rare
case (probably ugly geometry)
- * we can get some NULL loopspaces at this point. :/
- * Maybe we should set those loops' edges as sharp?
- */
- BLI_BITMAP_ENABLE(done_loops, i);
- //printf("WARNING! Getting invalid NULL loop spaces for
loop %d!\n", i);
- continue;
- }
-
- if (!BLI_BITMAP_TEST_BOOL(done_loops, i)) {
- /* Notes:
- * * In case of mono-loop smooth fan, loops is
NULL, so everything is fine (we have nothing to do).
- * * Loops in this linklist are ordered (in
reversed order compared to how they were discovered by
- * BKE_mesh_normals_loop_split(), but this is not
a problem). Hence, we just have to compare
- * current value to the previous one!
- */
- LinkNode *loops = lnors_spaces.lspaces[i]->loops;
- MLoop *prev_ml = NULL;
- const float *org_nor = NULL;
- if (!loops) {
- MLoop *ml = &mloops[i];
- const int idx = use_vertices ? (int)ml->v : i;
- float *nor = custom_loopnors[idx];
- const float fac = custom_loopnors_facs ?
custom_loopnors_facs[idx] : 1.0f;
-
- if (fac != 1.0f) {
- /* Note: inplace modification to get
final custom lnor! */
- interp_v3_v3v3_slerp_safe(nor,
lnors_spaces.lspaces[i]->vec_lnor, nor, fac);
- }
+ if (!use_vertices) {
+ /* Now, check each current smooth fan (one lnor space per
smooth fan!), and if all its matching custom lnors
+ * are not (enough) equal, add sharp edges as needed.
+ * This way, next time we run BKE_mesh_normals_loop_split(),
we'll get lnor spaces/smooth fans matching
+ * given custom lnors.
+ * Note this code *will never* unsharp edges!
+ * And quite obviously, when we set custom normals per
vertices, running this is absolutely useless!
+ */
+ for (i = 0; i < numLoops; i++) {
+ if (!lnors_spaces.lspaces[i]) {
+ /* This should not happen in theory, but in
some rare case (probably ugly geometry)
+ * we can get some NULL loopspaces at this
point. :/
+ * Maybe we should set those loops' edges as
sharp?
+ */
BLI_BITMAP_ENABLE(done_loops, i);
+ printf("WARNING! Getting invalid NULL loop
spaces for loop %d!\n", i);
+ continue;
}
- /* Hidden else, avoids one indentation. ;) */
- while (loops) {
- const int lidx =
GET_INT_FROM_POINTER(loops->link);
- MLoop *ml = &mloops[lidx];
- const int idx = use_vertices ? (int)ml->v :
lidx;
- float *nor = custom_loopnors[idx];
- const float fac = custom_loopnors_facs ?
custom_loopnors_facs[idx] : 1.0f;
- if (fac != 1.0f) {
- /* Note: inplace modification to get
final custom lnor! */
- interp_v3_v3v3_slerp_safe(nor,
lnors_spaces.lspaces[lidx]->vec_lnor, nor, fac);
+ if (!BLI_BITMAP_TEST_BOOL(done_loops, i)) {
+ /* Notes:
+ * * In case of mono-loop smooth fan, loops
is NULL, so everything is fine (we have nothing to do).
+ * * Loops in this linklist are ordered (in
reversed order compared to how they were discovered by
+ * BKE_mesh_normals_loop_split(), but
this is not a problem). Hence, we just have to compare
+ * current value to the previous one!
+ */
+ LinkNode *loops =
lnors_spaces.lspaces[i]->loops;
+ MLoop *prev_ml = NULL;
+ const float *org_nor = NULL;
+ if (!loops) {
+ MLoop *ml = &mloops[i];
+ const int idx = use_vertices ?
(int)ml->v : i;
+ float *nor = custom_loopnors[idx];
+
+ if (custom_loopnors_facs) {
+ const float fac =
custom_loopnors_facs[idx];
+
+ if (fac != 1.0f) {
+ /* Note: inplace
modification to get final custom lnor! */
+
interp_v3_v3v3_slerp_safe(nor, lnors_spaces.lspaces[i]->vec_lnor, nor, fac);
+ }
+ }
+ BLI_BITMAP_ENABLE(done_loops, i);
}
+ /* Hidden else, avoids one indentation. ;) */
+ while (loops) {
+ const int lidx =
GET_INT_FROM_POINTER(loops->link);
+ MLoop *ml = &mloops[lidx];
+ const int idx = use_vertices ?
(int)ml->v : lidx;
+ float *nor = custom_loopnors[idx];
- if (!org_nor) {
- org_nor = nor;
- }
- else if (dot_v3v3(org_nor, nor) < 1.0f - 1e-6f)
{
- /* Current normal differs too much from
org one, we have to tag the edge between
- * previous loop's face and current's
one as sharp.
- * We know those two loops do not point
to the same edge, since we do not allow reversed winding
- * in a same smooth fan.
- */
- const MPoly *mp =
&mpolys[loop_to_poly[lidx]];
- const MLoop *mlp = &mloops[(lidx ==
mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
- medges[(prev_ml->e == mlp->e) ?
prev_ml->e : ml->e].flag |= ME_SHARP;
-
- org_nor = nor;
- }
+ if (custom_loopnors_facs) {
+ const float fac =
custom_loopnors_facs[idx];
+
+ if (fac != 1.0f) {
+ /* Note: inplace
modification to get final custom lnor! */
+
interp_v3_v3v3_slerp_safe(nor, lnors_spaces.lspaces[i]->vec_lnor, nor, fac);
+ }
+ }
+
+ if (!org_nor) {
+ org_nor = nor;
+ }
+ else if (dot_v3v3(org_nor, nor) < 1.0f
- 1e-6f) {
+ /* Current normal differs too
much from org one, we have to tag the edge between
+ * previous loop's face and
current's one as sharp.
+ * We know those two loops do
not point to the same edge, since we do not allow reversed winding
+ * in a same smooth fan.
+ */
+ const MPoly *mp =
&mpolys[loop_to_poly[lidx]];
+ const MLoop *mlp =
&mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
+ medges[(prev_ml->e == mlp->e) ?
prev_ml->e : ml->e].flag |= ME_SHARP;
+
+ org_nor = nor;
+ }
- prev_ml = ml;
- loops = loops->next;
- BLI_BITMAP_ENABLE(done_loops, lidx);
+ prev_ml = ml;
+ loops = loops->next;
+ BLI_BITMAP_ENABLE(done_loops, lidx);
+ }
}
}
- }
- /* And now, recompute our new auto lnors and lnor spaces! */
- BKE_free_loops_normal_spaces(&lnors_spaces);
- BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops,
lnors, numLoops,
- mpolys, polynors, numPolys, split_angle,
&lnors_spaces, NULL, loop_to_poly);
+ /* And now, recompute our new auto lnors and lnor spaces! */
+ BKE_free_loops_normal_spaces(&lnors_spaces);
+ BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges,
mloops, lnors, numLoops,
+ mpolys, polynors, numPolys,
split_angle, &lnors_spaces, NULL, loop_to_poly);
+ }
+ else {
+ BLI_BITMAP_ENABLE_ALL(done_loops, (size_t)numLoops);
+ }
/* And we just have to convert plain object-space custom normals to our
lnor space-encoded ones. */
for (i = 0; i < numLoops; i++) {
if (!lnors_spaces.lspaces[i]) {
BLI_BITMAP_DISABLE(done_loops, i);
- //printf("WARNING! Still getting invalid NULL loop
spaces in second loop for loop %d!\n", i);
+ printf("WARNING! Still getting invalid NULL loop spaces
in second loop for loop %d!\n", i);
continue;
}
@@ -1314,7 +1328,17 @@ static void mesh_normals_loop_custom_set(MVert *mverts,
const int numVerts, MEdg
while (loops) {
const int lidx =
GET_INT_FROM_POINTER(loops->link);
const int idx = use_vertices ?
(int)mloops[lidx].v : lidx;
- const float *nor = custom_loopnors[idx];
+ float *nor = custom_loopnors[idx];
+
+ if (custom_loopnors_facs &&
use_vertices && !BLI_BITMAP_TEST_BOOL(done_verts, idx)) {
+ const float fac =
custom_loopnors_facs[idx];
+
+ if (fac != 1.0f) {
+ /* Note: inplace
modification to get final custom lnor! */
+
interp_v3_v3v3_slerp_safe(nor, lnors_spaces.lspaces[i]->vec_lnor, nor, fac);
+ }
+ BLI_BITMAP_ENABLE(done_verts,
idx);
+ }
nbr_nors++;
add_v3_v3(avg_nor, nor);
@@ -1334,7 +1358,19 @@ static void mesh_normals_loop_custom_set(MVert *mverts,
const int numVerts, MEdg
}
else {
const int idx = use_vertices ? (int)mloops[i].v
: i;
-
BKE_lnor_space_custom_normal_to_data(lnors_spaces.lspaces[i],
custom_loopnors[idx], r_clnors_data[i]);
+ float *nor = custom_loopnors[idx];
+
+ if (custom_loopnors_facs && use_vertices &&
!BLI_BITMAP_TEST_BOOL(done_verts, idx)) {
+ const float fac =
custom_loopnors_facs[idx];
+
+ if (fac != 1.0f) {
+ /* Note: inplace modification
to get final custom lnor! */
+ interp_v3_v3v3_slerp_safe(nor,
lnors_spaces.lspaces[i]->vec_lnor, nor, fac);
+ }
+ BLI_BITMAP_ENABLE(done_verts, idx);
+ }
+
+
BKE_lnor_space_custom_normal_to_data(lnors_spaces.lspaces[i], nor,
r_clnors_data[i]);
BLI_BITMAP_DISABLE(done_loops, i);
}
}
diff --git a/sour
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs