[Bf-blender-cvs] [4268554f126] soc-2018-npr: Make vertex wig sampling reflect the method in the paper
Sebastian Parborg
noreply at git.blender.org
Tue Jul 17 11:26:59 CEST 2018
Commit: 4268554f1269ef181103ed458343864596ac2dcc
Author: Sebastian Parborg
Date: Tue Jul 10 11:22:09 2018 +0200
Branches: soc-2018-npr
https://developer.blender.org/rB4268554f1269ef181103ed458343864596ac2dcc
Make vertex wig sampling reflect the method in the paper
===================================================================
M source/blender/modifiers/intern/MOD_mybmesh.c
===================================================================
diff --git a/source/blender/modifiers/intern/MOD_mybmesh.c b/source/blender/modifiers/intern/MOD_mybmesh.c
index c2e518b0caf..6464fd40581 100644
--- a/source/blender/modifiers/intern/MOD_mybmesh.c
+++ b/source/blender/modifiers/intern/MOD_mybmesh.c
@@ -47,6 +47,7 @@
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
#include "BLI_memarena.h"
+#include "BLI_rand.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
@@ -2919,21 +2920,39 @@ static void null_opti_edge(BMEdge *e, BLI_Buffer *inco_faces){
IncoFace *inface = &BLI_buffer_at(inco_faces, IncoFace, i);
if( inface->face != NULL && inface->face == f ){
inface->face = NULL;
+ break;
}
}
}
}
-static void null_opti_vert(BMVert *v, BLI_Buffer *inco_faces){
+static void null_opti_vert(MeshData *m_d, BMVert *v, bool back_f, BLI_Buffer *inco_faces){
BMFace *f;
BMIter iter;
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
+ float no[3], P[3];
+ BM_face_calc_normal(f, no);
+ BM_face_calc_center_mean(f, P);
+ bool found_face = false;
+ bool face_good = back_f == calc_if_B_nor(m_d->cam_loc, P, no);
+
+
for(int i = 0; i < inco_faces->count; i++){
IncoFace *inface = &BLI_buffer_at(inco_faces, IncoFace, i);
if( inface->face != NULL && inface->face == f ){
- inface->face = NULL;
+ found_face = true;
+ if( face_good ){
+ inface->face = NULL;
+ }
+ break;
}
}
+ if( !found_face && !face_good ){
+ IncoFace new_inface;
+ new_inface.face = f;
+ new_inface.back_f = back_f;
+ BLI_buffer_append(inco_faces, IncoFace, new_inface);
+ }
}
}
@@ -2971,7 +2990,7 @@ static void optimization( MeshData *m_d ){
continue;
}
- /*{
+ {
// This shouldn't be needed, but in case we manage to have inconsistent
// faces that borders our contour line, don't mark it for adjustment.
BMVert *v;
@@ -2989,7 +3008,7 @@ static void optimization( MeshData *m_d ){
continue;
}
- }*/
+ }
BM_face_calc_center_mean(face, P);
if( b_f != calc_if_B_nor(m_d->cam_loc, P, face->no) ){
@@ -3251,7 +3270,7 @@ static void optimization( MeshData *m_d ){
if( done ){
//Good vert smooth
- null_opti_vert(vert, &inco_faces);
+ null_opti_vert(m_d, vert, inface->back_f, &inco_faces);
break;
}
}
@@ -3262,9 +3281,12 @@ static void optimization( MeshData *m_d ){
}
// 3. Vertex wiggling in paramter space
- {
+ int fixed_verts = 0;
+ do {
int face_i;
+ fixed_verts = 0;
+
for(face_i = 0; face_i < inco_faces.count; face_i++){
IncoFace *inface = &BLI_buffer_at(&inco_faces, IncoFace, face_i);
@@ -3280,60 +3302,61 @@ static void optimization( MeshData *m_d ){
BMVert *orig_v = BLI_ghash_lookup(m_d->vert_hash, vert);
if( orig_v != NULL ){
// This vert exists in the original mesh
- int edge_count = BM_vert_edge_count(vert);
-
- // We are going to search for a new position using a spiral
- float end_radius = 0;
- float cur_radian = 0;
- float max_turns = 4; // How many turnings the spiral should have
+ int face_count = BM_vert_face_count(vert);
+ int face_idx, vert_idx;
+ int nr_inco_faces = 0;
+ float (*store_2d)[3][3] = BLI_array_alloca(store_2d, face_count);
+ float *face_area = BLI_array_alloca(face_area, face_count);
+ float tot_face_area = 0;
+ float mat[3][3];
bool done = false;
- BMEdge *e;
- BMIter iter;
- BM_ITER_ELEM (e, &iter, vert, BM_EDGES_OF_VERT) {
- end_radius += BM_edge_calc_length(e);
- }
+ axis_dominant_v3_to_m3(mat, vert->no);
- end_radius = end_radius / (float)edge_count;
- //end_radius = end_radius / 2.0f;
+ BMFace *f;
+ BMVert *face_vert;
+ BMIter iter_f, iter_f_v;
+ BM_ITER_ELEM_INDEX (f, &iter_f, vert, BM_FACES_OF_VERT, face_idx) {
+ BM_ITER_ELEM_INDEX (face_vert, &iter_f_v, f, BM_VERTS_OF_FACE, vert_idx) {
+ mul_v2_m3v3(store_2d[face_idx][vert_idx], mat, face_vert->co);
+ }
- {
- // radius = b * theta
- float b = (end_radius / max_turns) * (1.0f / (2.0f * M_PI));
- float step_size = (max_turns * 2.0f * M_PI) / 100.0f;
- int i;
+ float no[3];
+ float P[3];
+ BM_face_calc_normal(f, no);
+ BM_face_calc_center_mean(f, P);
+ if( inface->back_f != calc_if_B_nor(m_d->cam_loc, P, no) ){
+ nr_inco_faces++;
+ }
+ face_area[face_idx] = BM_face_calc_area(f);
+ tot_face_area += face_area[face_idx];
+ }
- BMFace *f;
- BMIter iter_f;
+ {
+ float old_pos[3], best_pos[3], best_dist = 0;
+ int best_inco_faces = nr_inco_faces;
- float mat[3][3];
- float center_v2[2];
- float old_pos[3];
+ RNG *rng = BLI_rng_new(0);
copy_v3_v3( old_pos, vert->co );
+ copy_v3_v3( best_pos, vert->co );
- axis_dominant_v3_to_m3(mat, vert->no);
- mul_v2_m3v3(center_v2, mat, vert->co);
-
- for( i=0; i<100; i++ ){
- float theta = step_size * (float)i;
- float r = b * theta;
- float pos_v2[2] = { center_v2[0], center_v2[1] };
-
- bool found_point = true;
+ for( face_idx = 0; face_idx < face_count; face_idx++ ){
+ int samples = (face_area[face_idx] / tot_face_area) * 100;
- pos_v2[0] += r * cosf(theta);
- pos_v2[1] += r * sinf(theta);
+ for(int i=0; i < samples; i++ ){
+ float cur_v2[2];
// TODO check if the new point lies inside any of the new mesh faces
+ BLI_rng_get_tri_sample_float_v2(rng, store_2d[face_idx][0], store_2d[face_idx][1], store_2d[face_idx][2], cur_v2);
BM_ITER_ELEM (f, &iter_f, orig_v, BM_FACES_OF_VERT) {
- if( point_inside_v2( mat, pos_v2, f ) ){
+ if( point_inside_v2( mat, cur_v2, f ) ){
float P[3], du[3], dv[3];
float uv_P[2];
- get_uv_point( f, uv_P, pos_v2, mat );
+ get_uv_point( f, uv_P, cur_v2, mat );
openSubdiv_evaluateLimit(m_d->eval, BM_elem_index_get(f), uv_P[0], uv_P[1], P, du, dv);
copy_v3_v3(vert->co, P);
@@ -3342,31 +3365,55 @@ static void optimization( MeshData *m_d ){
}
}
+ int new_inco_faces = 0;
+ bool fold = false;
+ float new_dist = len_v3v3(old_pos, vert->co);
+
BM_ITER_ELEM (f, &iter_f, vert, BM_FACES_OF_VERT) {
float no[3];
float P[3];
BM_face_calc_normal(f, no);
BM_face_calc_center_mean(f, P);
- if( inface->back_f != calc_if_B_nor(m_d->cam_loc, P, no) ){
- found_point = false;
+ //Will this new vert pos create a potential fold?
+ if( dot_v3v3( f->no, no ) < 0.5f ){
+ fold = true;
break;
}
+
+ if( inface->back_f != calc_if_B_nor(m_d->cam_loc, P, no) ){
+ new_inco_faces++;
+ }
}
- if( found_point ){
+ if( fold ){
+ continue;
+ }
+
+ if( new_inco_faces < best_inco_faces ){
+ best_inco_faces = new_inco_faces;
+ best_dist = new_dist;
+ copy_v3_v3( best_pos, vert->co );
+ done = true;
+ } else if (new_inco_faces == best_inco_faces && new_dist < best_dist){
+ best_dist = new_dist;
+ copy_v3_v3( best_pos, vert->co );
done = true;
- break;
}
+
+ }
}
+ BLI_rng_free(rng);
+ copy_v3_v3(vert->co, best_pos);
+
if( done ){
- null_opti_vert(vert, &inco_faces);
+ null_opti_vert(m_d, vert, inface->back_f, &inco_faces);
+ fixed_verts++;
printf("Vertex wiggle\n");
break;
} else {
printf("Bad Vertex wiggle\n");
- copy_v3_v3(vert->co, old_pos);
}
}
@@ -3374,7 +3421,7 @@ static void optimization( MeshData *m_d ){
}
}
}
- }
+ } while( fixed_verts > 0 );
// 4. Edge Splitting
{
@@ -3398,6 +3445,7 @@ static void optimization( MeshData *m_d ){
BMVert *orig_v = NULL;
BMFace *f;
BMIter iter_f;
+ int f_idx;
if( BM_edge_face_count(edge) != 2 ){
//We managed to create a non manifold mesh in the previous steps
@@ -3409,6 +3457,9 @@ static void optimization( MeshData *m_d ){
// Storage for vertex pos
// This is used later to see if the edge split will be ok or not
float store[4][2][3];
+ float store_2d[4][3];
+ float face_area[2];
+ float mat[3][3];
int j = 0;
orig_v = BLI_ghash_lookup(m_d->vert_hash, edge->v1);
@@ -3422,7 +3473,9 @@ static void optimization( MeshData *m_d ){
continue;
}
- BM_ITER_ELEM (f, &iter_f, edge, BM_FACES_OF_EDGE) {
+ axis_dominant_v3_to_m3(mat, orig_v->no);
+
+ BM_ITER_ELEM_INDEX (f, &iter_f, edge, BM_FACES_OF_EDGE, f_idx) {
int i;
BMLoop *l;
l = BM_FACE_FIRST_LOOP(f);
@@ -3430,33 +3483,33 @@ static void optimization( MeshData *m_d ){
if( l->e != edge ) {
copy_v3_v3(store[j][0], l->v->co);
copy_v3_v3(store[j][1], (l->next)->v->co);
+
+ mul_v2_m3v3(store_2d[j], mat, l->v->co);
j++;
}
l = l->next;
}
+ face_area[f_idx] = BM_face_calc_area(f);
}
{
- //Do 10 samples but don't check end and start point
- float step = 1.0f/11.0f;
- float step_arr[] = { step*5.0f, step*6.0f, step*4.0f, step*7.0f, step*3.0f,
- step*8.0f, step*2.0f, step*9.0f, step*1.0f, step*10.0f };
+ float tot_area = face_area[0] + face_area[1];
+ bool done = false;
+ int first_sample_count = (face_area[0] / tot_area) * 100;
- float mat[3][3];
- float start[2], end[2];
- int i;
- bool done = false;
+ RNG *rng = BLI_rng_new(0);
- axis_dominant_v3_to_m3(mat, orig_v->no);
- mul_v2_m3v3(start, mat, edge->v1->co);
- mul_v2_m3v3(end, mat, edge->v2->co);
- for( i = 0; i < 10; i++ ){
+ for(int i = 0; i < 100; i++ ){
float cur_v2[2];
float P[3], du[3], dv[3];
bool found_point = false;
- interp_v2_v2v2(cur_v2, start, end, step_arr[i]);
+ if( first_sample_count < i ){
+ BLI_rng_get_tri_sample_float_v2(rng, store_2d[0], store_2d[1], store_2d[2], cur_v2);
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list