[Bf-blender-cvs] [fa86bbb0542] soc-2017-sculpting_improvements: Inner vertices now get calculated as well as edgerings. Problem with holes in the edgerings.

Sebastian Witt noreply at git.blender.org
Tue Aug 15 09:59:51 CEST 2017


Commit: fa86bbb054281c0b3911c08549f4781f5af3bd6d
Author: Sebastian Witt
Date:   Tue Aug 15 09:58:30 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBfa86bbb054281c0b3911c08549f4781f5af3bd6d

Inner vertices now get calculated as well as edgerings. Problem with holes in the edgerings.

===================================================================

M	source/blender/editors/sculpt_paint/sculpt.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5f1e595a226..9b2e3600616 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -234,8 +234,6 @@ typedef struct IntersectionData {
 	float *intersection_points;		/* exact positions where the two shapes connect */
 	GHash *edge_hash;
 	int num_intersection_points;	/* 3 times intersection point count*/
-	int first_e;
-	bool flip;
 } IntersectionData;
 
 typedef enum {
@@ -7221,8 +7219,7 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
 	BKE_pbvh_get_tri(bvh, &ltris);
 	GHash *edge_hash = BLI_ghash_int_new("edges within intersection");
 	float *int_points = NULL;
-	bool first_e_flip;
-	int first_e;
+	bool e_flip_orientation;
 	IntersectionData *i_data;
 	BLI_array_declare(int_points);
 
@@ -7242,20 +7239,22 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
 					copy_v3_v3(p2, me->mvert[me->medge[e_start + e].v2].co);
 					for (int tri_i = 0; tri_i < tri_node_bind_tot; tri_i ++) {
 						lt = ltris[sil->inter_tris[tri_node_bind + tri_i]];
-						/* Maybe isect with epsilon flexibility needed? */
-						if (isect_line_segment_tri_v3(p1, p2,
+						/* TODO: Negative epsilon for better results. Still produces holes. */
+						if (isect_line_segment_tri_epsilon_v3(p1, p2,
 													  me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co,
-													  &t_lambda, NULL))
+													  &t_lambda, NULL, -0.00001f))
 						{
-							if (BLI_array_count(int_points) == 0) {
-								first_e_flip = shared_dir_normal(p1, p2, me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co);
-								first_e = e_start + e;
-							}
-							BLI_ghash_insert(edge_hash, SET_INT_IN_POINTER(e_start + e), SET_INT_IN_POINTER(BLI_array_count(int_points)));
+							e_flip_orientation = shared_dir_normal(p1, p2, me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co);
+							/*TODO: Bad practise? Pointer is negative if edge orientation needs to be flipped to target inwards. */
+							BLI_ghash_insert(edge_hash, SET_INT_IN_POINTER(e_start + e), SET_INT_IN_POINTER(e_flip_orientation ? (BLI_array_count(int_points) + 1) : -(BLI_array_count(int_points) + 1)));
 							BLI_array_grow_items(int_points, 3);
 							interp_v3_v3v3(&int_points[BLI_array_count(int_points) - 3], p1, p2, t_lambda);
 #ifdef DEBUG_DRAW
-							bl_debug_color_set(0x0000ff);
+							if(t_lambda > 0.999999f || t_lambda < 0.000001f) {
+								bl_debug_color_set(0xff3333);
+							} else {
+								bl_debug_color_set(0x0000ff);
+							}
 							bl_debug_draw_point(&int_points[BLI_array_count(int_points) - 3], 0.05f);
 							bl_debug_color_set(0x000000);
 							bl_debug_draw_edge_add(p1, p2);
@@ -7269,17 +7268,11 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
 			BLI_mutex_lock(&data->mutex);
 			if (BLI_array_count(int_points) > 0) {
 				i_data = add_isect_chunk(sil);
-				i_data->flip = first_e_flip;
-				i_data->first_e = first_e;
 				i_data->edge_hash = edge_hash;
 				i_data->intersection_points = MEM_callocN(sizeof(float) * BLI_array_count(int_points), "exact intersecting points");
 				i_data->num_intersection_points = BLI_array_count(int_points);
 				memcpy(i_data->intersection_points, int_points, BLI_array_count(int_points) * sizeof(float));
-				//if (sil->isect_chunk)
-				//prep_float_shared_mem((float**)&sil->intersection_points, &sil->num_intersection_points, &int_points_shared_start, BLI_array_count(int_points), "exact intersecting points");
-				//memcpy(&sil->intersection_points[int_points_shared_start], int_points, BLI_array_count(int_points) * sizeof(float));
 			}
-
 			BLI_mutex_unlock(&data->mutex);
 
 			BLI_array_free(int_points);
@@ -7290,6 +7283,82 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
 	BLI_ghash_free(edge_hash, NULL, NULL);
 }
 
+static void remove_connected_from_edgehash(MeshElemMap *emap, GHash *edge_hash, int v) {
+	for (int e = 0; e < emap[v].count; e++) {
+		BLI_ghash_remove(edge_hash, emap[v].indices[e], NULL, NULL);
+	}
+}
+
+static void remove_connected_from_edgehash_list(MeshElemMap *emap, GHash **edge_hash, int num_hash, int v) {
+	for (int e = 0; e < emap[v].count; e++) {
+		for(int i = 0; i < num_hash; i++) {
+			BLI_ghash_remove(edge_hash[i], emap[v].indices[e], NULL, NULL);
+		}
+	}
+}
+
+static bool has_cross_border_neighbour(Mesh *me, GHash *vert_hash, GHash *edge_hash, MeshElemMap *emap, int edge, int l_v_edge, int depth) {
+	int v_edge;
+
+	v_edge = me->medge[edge].v1 == l_v_edge ? me->medge[edge].v2 : me->medge[edge].v1;
+
+	if (depth == 0) {
+		return BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge));
+	} else {
+		if(!BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge))){
+			for (int e = 0; e < emap[v_edge].count; e++) {
+				if(emap[v_edge].indices[e] != edge) {
+					if(has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, depth - 1)){
+						return true;
+					}
+				}
+			}
+		} else {
+			BLI_ghash_remove(edge_hash, edge, NULL, NULL);
+		}
+	}
+	return false;
+}
+
+/* Get the adjacent edge which connects the edges within the edge_hash. Used to create multiple ordered loops
+ * v_edge is the endpoint off curr_edge from which to branch off
+ * TODO: One wide strips might get cutoff */
+static int get_adjacent_edge(Mesh *me, MeshElemMap *emap, int curr_edge, int v_edge, GHash *edge_hash, GHash *vert_hash)
+{
+	for (int e = 0; e < emap[v_edge].count; e++) {
+		if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, 1)) {
+			return emap[v_edge].indices[e];
+		}
+	}
+	for (int e = 0; e < emap[v_edge].count; e++) {
+		if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, 2)) {
+			return emap[v_edge].indices[e];
+		}
+	}
+	/*End Of Loop. Shouldn't happen with two manifold meshes*/
+	return -1;
+}
+
+static int get_adjacent_edge_from_list(Mesh *me, MeshElemMap *emap, int curr_edge, int v_edge, GHash **edge_hash, int num_hash, GHash *vert_hash)
+{
+	for (int e = 0; e < emap[v_edge].count; e++) {
+		for (int i = 0; i < num_hash; i++) {
+			if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash[i], emap, emap[v_edge].indices[e], v_edge, 1)) {
+				return emap[v_edge].indices[e];
+			}
+		}
+	}
+	for (int e = 0; e < emap[v_edge].count; e++) {
+		for (int i = 0; i < num_hash; i++) {
+			if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash[i], emap, emap[v_edge].indices[e], v_edge, 2)) {
+				return emap[v_edge].indices[e];
+			}
+		}
+	}
+	/*End Of Loop. Shouldn't happen with two manifold meshes*/
+	return -1;
+}
+
 static void check_preceding_intersecting_edges(Object *ob, SilhouetteData *sil, SpineBranch *branch, PBVHNode **nodes, int tot_edge)
 {
 	printf("Checking preceding edges.\n Total edges to check: %i\n Total Triangles: %i\n Total Nodes: %i\n", tot_edge, sil->num_inter_tris, sil->num_inter_nodes);
@@ -7333,11 +7402,23 @@ static void crawl_mesh_rec (Mesh *me, MeshElemMap *emap, GHash *vert_hash, Inter
 static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 {
 	IntersectionData *data = sil->isect_chunk;
+	GHash **isect_ghash_dupe;
 	MeshElemMap *emap;
 	GHash *vert_hash = BLI_ghash_int_new("vertices within intersection");
 	int *emap_mem;
-	MEdge *first_e = NULL;
+	int start_edge;
 	int inside_vert;
+	GHashIterState pop_state;
+	void *tkey, *tv;
+	int first_e, comp_v, curr_edge, last_edge, tmp_curr_edge, r_size;
+
+	/*TODO: remove, while loop safety if bug occurs*/
+	int breaker;
+
+	int *edge_ring_fillet = NULL;
+	int *ring_start = NULL;
+	BLI_array_declare(edge_ring_fillet);
+	BLI_array_declare(ring_start);
 
 	if (!data) {
 		return;
@@ -7346,14 +7427,77 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 	/* TODO: Maybe only generate partial map with only the silhouette inside? */
 	BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
 
-	first_e = &me->medge[data->first_e];
-
-	/*TODO: Invert for clipping functionality!*/
-	inside_vert = !data->flip ^ sil->do_subtract ? first_e->v2 : first_e->v1;
+	isect_ghash_dupe = MEM_callocN(sizeof(GHash *) * sil->num_isect_data, "edge hash duplicate");
+	for (int i = 0; i < sil->num_isect_data; i++) {
+		isect_ghash_dupe[i] = BLI_ghash_copy(data[i].edge_hash, NULL, NULL);
+	}
+
+	for(int i = 0; i < sil->num_isect_data; i++) {
+		memset(&pop_state, 0, sizeof(GHashIterState));
+		while (BLI_ghash_pop(isect_ghash_dupe[i], &pop_state, &tkey, &tv)) {
+			first_e = (int) tkey;
+			inside_vert = ((int)tv > 0) ^ sil->do_subtract ? me->medge[first_e].v1 : me->medge[first_e].v2;
+
+			crawl_mesh_rec(me, emap, vert_hash, data, sil->num_isect_data, inside_vert);
+
+			breaker = me->totedge;
+			comp_v = BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(me->medge[first_e].v1)) ? me->medge[first_e].v2 : me->medge[first_e].v1;
+			BLI_assert(!BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(comp_v)));
+			start_edge = -1;
+			start_edge = get_adjacent_edge_from_list(me, emap, first_e, comp_v, isect_ghash_dupe, sil->num_isect_data, vert_hash);
+			if(start_edge >= 0) {
+				BLI_array_append(ring_start, BLI_array_count(edge_ring_fillet));
+				curr_edge = start_edge;
+				last_edge = -1;
+
+				while(!(curr_edge == start_edge && last_edge != -1) && curr_edge != -1 && breaker > 0) {
+					BLI_array_append(edge_ring_fillet, curr_edge);
+					if(last_edge == -1) {
+						comp_v = me->medge[start_edge].v1;
+					} else {
+						if (me->medge[curr_edge].v1 == me->medge[last_edge].v1 || me->medge[curr_edge].v1 == me->medge[last_edge].v2) {
+							comp_v = me->medge[curr_edge].v2;
+						} else {
+							comp_v = me->medge[curr_edge].v1;
+						}
+					}
+					remove_connected_from_edgehash_list(e

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list