[Bf-blender-cvs] [7eb51ebaae9] soc-2017-normal-tools: Rewrote the code for sharp edges on weighted modifier.
Rohan Rathi
noreply at git.blender.org
Sun Aug 6 20:01:20 CEST 2017
Commit: 7eb51ebaae938801ea9287d68ce8867d40d0ea9b
Author: Rohan Rathi
Date: Sun Aug 6 23:27:59 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rB7eb51ebaae938801ea9287d68ce8867d40d0ea9b
Rewrote the code for sharp edges on weighted modifier.
===================================================================
M source/blender/modifiers/intern/MOD_weighted_normal.c
===================================================================
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c
index ca736cd2025..021ceee2a06 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -29,10 +29,8 @@
#include "DNA_object_types.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_deform.h"
#include "BKE_mesh.h"
-#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_stack.h"
@@ -41,6 +39,10 @@
#include "MOD_modifiertypes.h"
#include "MOD_util.h"
+#define INDEX_UNSET INT_MIN
+#define INDEX_INVALID -1
+#define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
+
typedef struct pair {
float val; /* contains mode based value (face area/ corner angle) */
int index; /* index value per poly or per loop */
@@ -72,22 +74,57 @@ static int sort_by_index(const void *p1, const void *p2)
return 0;
}
+/* Copied function used to fan around the current vertex */
+static void loop_manifold_fan_around_vert_next(
+ const MLoop *mloops, const MPoly *mpolys,
+ const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index,
+ const MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index)
+{
+ const MLoop *mlfan_next;
+ const MPoly *mpfan_next;
+ *r_mlfan_curr_index = (e2lfan_curr[0] == *r_mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
+ *r_mpfan_curr_index = loop_to_poly[*r_mlfan_curr_index];
+
+ BLI_assert(*r_mlfan_curr_index >= 0);
+ BLI_assert(*r_mpfan_curr_index >= 0);
+
+ mlfan_next = &mloops[*r_mlfan_curr_index];
+ mpfan_next = &mpolys[*r_mpfan_curr_index];
+ if (((*r_mlfan_curr)->v == mlfan_next->v && (*r_mlfan_curr)->v == mv_pivot_index) ||
+ ((*r_mlfan_curr)->v != mlfan_next->v && (*r_mlfan_curr)->v != mv_pivot_index))
+ {
+ *r_mlfan_vert_index = *r_mlfan_curr_index;
+ if (--(*r_mlfan_curr_index) < mpfan_next->loopstart) {
+ *r_mlfan_curr_index = mpfan_next->loopstart + mpfan_next->totloop - 1;
+ }
+ }
+ else {
+ if (++(*r_mlfan_curr_index) >= mpfan_next->loopstart + mpfan_next->totloop) {
+ *r_mlfan_curr_index = mpfan_next->loopstart;
+ }
+ *r_mlfan_vert_index = *r_mlfan_curr_index;
+ }
+ *r_mlfan_curr = &mloops[*r_mlfan_curr_index];
+}
+
static void apply_weights_sharp_loops(WeightedNormalModifierData *wnmd, int *loop_index, int size, pair *mode_pair,
- float (*loop_normal)[3], int *loops_to_poly, float (*polynors)[3])
+ float(*loop_normal)[3], int *loops_to_poly, float(*polynors)[3])
{
+ float weight = (float)wnmd->weight / 10.0f;
+
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE
- && mode_pair[loops_to_poly[loop_index[j]]].val > mode_pair[loops_to_poly[loop_index[j + 1]]].val) {
- int temp = loop_index[j];
- loop_index[j] = loop_index[j + 1];
- loop_index[j + 1] = temp;
+ && mode_pair[loops_to_poly[loop_index[j]]].val < mode_pair[loops_to_poly[loop_index[j + 1]]].val) {
+ int temp = loop_index[j];
+ loop_index[j] = loop_index[j + 1];
+ loop_index[j + 1] = temp;
}
- else if (wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_ANGLE || wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE
- && mode_pair[loop_index[j]].val > mode_pair[loop_index[j + 1]].val) {
- int temp = loop_index[j];
- loop_index[j] = loop_index[j + 1];
- loop_index[j + 1] = temp;
+ else if ((wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_ANGLE || wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE)
+ && mode_pair[loop_index[j]].val < mode_pair[loop_index[j + 1]].val) {
+ int temp = loop_index[j];
+ loop_index[j] = loop_index[j + 1];
+ loop_index[j + 1] = temp;
}
}
}
@@ -110,9 +147,15 @@ static void apply_weights_sharp_loops(WeightedNormalModifierData *wnmd, int *loo
vertcount++;
cur_val = mode_pair[j].val;
}
- float n_weight = pow(wnmd->weight, vertcount);
+ float n_weight = pow(weight, vertcount);
+
+ if (wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE) {
+ copy_v3_v3(wnor, polynors[mode_pair[j].index]);
+ }
+ else if (wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_ANGLE || wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE) {
+ copy_v3_v3(wnor, polynors[loops_to_poly[j]]);
+ }
- copy_v3_v3(wnor, polynors[mode_pair[j].index]);
mul_v3_fl(wnor, mode_pair[j].val * (1.0f / n_weight));
add_v3_v3(custom_normal, wnor);
}
@@ -123,6 +166,54 @@ static void apply_weights_sharp_loops(WeightedNormalModifierData *wnmd, int *loo
}
}
+/* Modified version of loop_split_worker_do which sets custom_normals without considering smoothness of faces or loop normal space array
+ Used only to work on sharp edges */
+static void loop_split_worker(WeightedNormalModifierData *wnmd, pair *mode_pair, MLoop *ml_curr, MLoop *ml_prev, int ml_curr_index,
+ int ml_prev_index, int *e2l_prev, int mp_index, float (*loop_normal)[3], int *loops_to_poly, float (*polynors)[3], MEdge *medge,
+ MLoop *mloop, MPoly *mpoly, int (*edge_to_loops)[2])
+{
+ if (e2l_prev) {
+ int *e2lfan_curr = e2l_prev;
+ MLoop *mlfan_curr = ml_prev;
+ int mlfan_curr_index = ml_prev_index;
+ int mlfan_vert_index = ml_curr_index;
+ int mpfan_curr_index = mp_index;
+
+ BLI_Stack *loop_index = BLI_stack_new(sizeof(int), "__func__");
+
+ while (true) {
+ const unsigned int mv_pivot_index = ml_curr->v;
+ const MEdge *me_curr = &medge[mlfan_curr->e];
+ const MEdge *me_org = &medge[ml_curr->e];
+
+ BLI_stack_push(loop_index, &mlfan_vert_index);
+
+ if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) {
+ break;
+ }
+
+ loop_manifold_fan_around_vert_next(
+ mloop, mpoly, loops_to_poly, e2lfan_curr, mv_pivot_index,
+ &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index);
+
+ e2lfan_curr = edge_to_loops[mlfan_curr->e];
+ }
+
+ int *index = MEM_mallocN(sizeof(*index) * BLI_stack_count(loop_index), "__func__");
+ int cur = 0;
+ while (!BLI_stack_is_empty(loop_index)) {
+ BLI_stack_pop(loop_index, &index[cur]);
+ cur++;
+ }
+ apply_weights_sharp_loops(wnmd, index, cur, mode_pair, loop_normal, loops_to_poly, polynors);
+ MEM_freeN(index);
+ BLI_stack_free(loop_index);
+ }
+ else {
+ copy_v3_v3(loop_normal[ml_curr_index], polynors[loops_to_poly[ml_curr_index]]);
+ }
+}
+
static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object *ob, DerivedMesh *dm,
short(*clnors)[2], MVert *mvert, const int numVerts, MEdge *medge,
const int numEdges, MLoop *mloop, const int numLoops, MPoly *mpoly,
@@ -199,10 +290,6 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
else {
float(*loop_normal)[3] = MEM_callocN(sizeof(*loop_normal) * numLoops, "__func__");
int *loops_to_poly = MEM_mallocN(sizeof(*loops_to_poly) * numLoops, "__func__");
- int numSharpVerts = 0;
-
- BLI_bitmap *sharp_verts = BLI_BITMAP_NEW(numVerts, "__func__");
- int *loops_per_vert = MEM_callocN(sizeof(*loops_per_vert) * numVerts, "__func__");
BKE_mesh_normals_loop_split(mvert, numVerts, medge, numEdges, mloop, loop_normal, numLoops, mpoly, polynors,
numPoly, true, (float)M_PI, NULL, clnors, loops_to_poly);
@@ -212,11 +299,6 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
const int ml_index_end = ml_index + mpoly[mp_index].totloop;
for (int i = ml_index; i < ml_index_end; i++) {
- if ((medge[mloop[i].e].flag & ME_SHARP) && !BLI_BITMAP_TEST(sharp_verts, mloop[i].v)) {
- numSharpVerts++;
- BLI_BITMAP_ENABLE(sharp_verts, mloop[i].v);
- }
- loops_per_vert[mloop[i].v]++;
loops_to_poly[i] = mp_index;
if (!is_zero_v3(custom_normal[mloop[i].v])) {
copy_v3_v3(loop_normal[i], custom_normal[mloop[i].v]);
@@ -225,143 +307,73 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Object
}
if (keep_sharp) {
- void **loops_of_vert = MEM_mallocN(sizeof(loops_of_vert) * numSharpVerts, "__func__");
- int cur = 0;
+ int (*edge_to_loops)[2] = MEM_callocN(sizeof(*edge_to_loops) * numEdges, "__func__");
if (wnmd->mode == MOD_WEIGHTEDNORMAL_MODE_FACE) {
qsort(mode_pair, numPoly, sizeof(*mode_pair), sort_by_index);
}
else {
qsort(mode_pair, numLoops, sizeof(*mode_pair), sort_by_index);
-
}
- for (int mp_index = 0; mp_index < numPoly; mp_index++) {
- int ml_index = mpoly[mp_index].loopstart;
- const int ml_index_end = ml_index + mpoly[mp_index].totloop;
-
- for (int i = ml_index, k = 0; i < ml_index_end; i++) {
-
- if (BLI_BITMAP_TEST(sharp_verts, mloop[i].v)) {
- bool found = false;
- for (k = 0; k < cur; k++) {
- if (mloop[i].v == *(int *)loops_of_vert[k]) {
- found = true;
- break;
- }
- }
- if (found) {
- int *loops = loops_of_vert[k];
- while (*loops != -1) {
- loops++;
- }
- *loops = i;
+
+ MPoly *mp;
+ int mp_index;
+ for (mp = mpoly, mp_index = 0; mp_index < numPoly; mp++, mp_index++) {
+ int ml_curr_index = mp->loopstart;
+ const int ml_last_index = (ml_curr_index + mp->totloop) - 1;
+
+ MLoop *ml_curr = &mloop[ml_curr_index];
+
+ for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
+ int *e2l = edge_to_loops[ml_curr->e];
+
+ if ((e2l[0] | e2l[1]) == 0) {
+ e2l[0] = ml_curr_index;
+ e2l[1] = INDEX_UNSET; /* Not considering smoothness of faces, UNSET if first loop encountered on this edge */
+ }
+ else if (e2l[1] == INDEX_UNSET) {
+ if ((medge[ml_curr->e].flag & ME_SHARP) || ml_curr->v == mloop[e2l[0]].v) {
+ e2l[1] = INDEX_INVALID;
}
else {
- int *loops;
- loops_of_vert[k] = loops = MEM_callocN(sizeof(*loops) * (loops_per_vert[mloop[i].v] + 1), "__func__");
- memset(loops, -1, sizeof(*loops) * (loops_per_vert[mloop[i].v] + 1));
- loops[0] = mloop[i].v;
- loops[1] = i;
- cur++;
+ e2l[1] = ml_curr_index;
}
}
}
}
- for (int i = 0; i < numSharpVerts; i++) {
- int *loops = loops_of_vert[i];
- int totloop = loops_per_vert[*loops];
- loops++;
- int *base_loop = loops;
- BLI_Stack *loop_index = BLI_stack_new(sizeof(int), "__func__");
+ for (mp
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list