[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