[Bf-blender-cvs] [9bab119] dyntopo_holes: Experimental options for sculpting holes

Campbell Barton noreply at git.blender.org
Sun Oct 5 14:54:22 CEST 2014


Commit: 9bab11901bd97ce1bbf5e351367b1cc6e71a84a3
Author: Campbell Barton
Date:   Sun Oct 5 14:43:35 2014 +0200
Branches: dyntopo_holes
https://developer.blender.org/rB9bab11901bd97ce1bbf5e351367b1cc6e71a84a3

Experimental options for sculpting holes

- don't bridge loops with shared vertices (USE_BRIDGE_STRICT)
- cleanup dangling faces after making the bridge (USE_BRIDGE_CLEAN)

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

M	source/blender/blenkernel/intern/pbvh_bmesh.c

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

diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 581dec7..df2b098 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -569,6 +569,25 @@ static void long_edge_queue_edge_add(EdgeQueueContext *eq_ctx,
 		edge_queue_insert(eq_ctx, e, -len_sq);
 }
 
+#if 0
+static float bm_edge_calc_sharpness(BMEdge *e)
+{
+	if (BM_edge_is_manifold(e)) {
+		float axis[3], ang;
+		sub_v3_v3v3(axis, e->v1->co, e->v2->co);
+		ang = angle_on_axis_v3v3v3_v3(
+		        e->l->prev->v->co,
+		        e->v1->co,
+		        e->l->radial_next->prev->v->co,
+		        axis);
+		return ang / M_PI;
+	}
+	else {
+		return 1.0f;
+	}
+}
+#endif
+
 static void short_edge_queue_edge_add(EdgeQueueContext *eq_ctx,
                                       BMEdge *e)
 {
@@ -1211,7 +1230,12 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
 
 /* remove sides of the bridge when there are adjacent holes,
  * so 2 holes form a larger hole (typically what you want) */
-#define USE_BRIDGE_MERGE_HOLES
+// #define USE_BRIDGE_MERGE_HOLES
+
+/* disallow bridges sharing vertices */
+// #define USE_BRIDGE_STRICT
+
+#define USE_BRIDGE_CLEAN
 
 /* radial walk the vert edges */
 static bool bm_vert_ordered_fan_walk(BMVert *v, BLI_Buffer *buf)
@@ -1275,7 +1299,9 @@ static void pbvh_bmesh_delete_edge_face_tagged_radial(
 		} while ((l_iter = l_next) != l_rim);
 	}
 }
+#endif  /* USE_BRIDGE_MERGE_HOLES */
 
+#if defined(USE_BRIDGE_MERGE_HOLES) || defined(USE_BRIDGE_STRICT)
 static void bm_earray_tag(
         BMElemF **earr, int earr_num,
         bool tag)
@@ -1293,8 +1319,22 @@ static void bm_earray_tag(
 		}
 	}
 }
+#endif
 
-#endif  /* USE_BRIDGE_MERGE_HOLES */
+#ifdef USE_BRIDGE_STRICT
+static bool bm_earray_tag_check_any(
+        BMElemF **earr, int earr_num)
+{
+	int i;
+
+	for (i = 0; i < earr_num; i++) {
+		if (BM_elem_flag_test(earr[i], BM_ELEM_TAG)) {
+			return true;
+		}
+	}
+	return false;
+}
+#endif
 
 static void bm_varray_center(
         const BMVert **varr, const int varr_num,
@@ -1495,7 +1535,9 @@ static void pbvh_bmesh_collapse_close_verts(EdgeQueueContext *eq_ctx,
 	int counter = 0;
 	BLI_buffer_declare_static(BMVert *, edge_verts_v1, BLI_BUFFER_NOP, 32);
 	BLI_buffer_declare_static(BMVert *, edge_verts_v2, BLI_BUFFER_NOP, 32);
-
+#ifdef USE_BRIDGE_CLEAN
+	BLI_buffer_declare_static(BMFace *, face_clean, BLI_BUFFER_NOP, 32);
+#endif
 	GSet *deleted_verts = BLI_gset_ptr_new_ex("deleted_verts", BLI_heap_size(eq_ctx->q->heap));
 
 	while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
@@ -1530,6 +1572,15 @@ static void pbvh_bmesh_collapse_close_verts(EdgeQueueContext *eq_ctx,
 		if (!bm_vert_ordered_fan_walk(v2, &edge_verts_v2) || (edge_verts_v2.count < 3))
 			continue;
 
+#ifdef USE_BRIDGE_STRICT
+		bm_earray_tag(edge_verts_v1.data, edge_verts_v1.count, false);
+		bm_earray_tag(edge_verts_v2.data, edge_verts_v2.count, true);
+		if (bm_earray_tag_check_any(edge_verts_v1.data, edge_verts_v1.count)) {
+			printf("Bridges share verts!\n");
+			continue;
+		}
+#endif
+
 #ifdef USE_BRIDGE_MERGE_HOLES
 		bm_earray_tag(edge_verts_v1.data, edge_verts_v1.count, true);
 		bm_earray_tag(edge_verts_v2.data, edge_verts_v2.count, true);
@@ -1580,10 +1631,55 @@ static void pbvh_bmesh_collapse_close_verts(EdgeQueueContext *eq_ctx,
 		BM_log_vert_removed(bvh->bm_log, v2, eq_ctx->cd_vert_mask_offset);
 		BM_vert_kill(bvh->bm, v2);
 		BLI_gset_insert(deleted_verts, v2);
+
+
+#ifdef USE_BRIDGE_CLEAN
+		{
+			BLI_Buffer *bufs[2] = {&edge_verts_v1, &edge_verts_v2};
+			int i, j;
+
+
+			for (j = 0; j < 2; j++) {
+				BMVert **varr = BLI_buffer_array(bufs[j], BMVert *);
+				for (i = 0; i < bufs[j]->count; i++) {
+					BMVert *v = varr[i];
+
+					if (!BLI_gset_haskey(deleted_verts, v)) {
+						BMIter bm_iter;
+						BMLoop *l;
+
+						face_clean.count = 0;
+						BM_ITER_ELEM (l, &bm_iter, v, BM_LOOPS_OF_VERT) {
+							if ((BM_edge_is_boundary(l->prev->e) ||
+							     BM_edge_is_boundary(l->e) ||
+							     BM_edge_is_boundary(l->next->e)))
+							{
+								BLI_buffer_append(&face_clean, BMFace *, l->f);
+							}
+						}
+
+						if (face_clean.count != 0) {
+							BMFace **farr = BLI_buffer_array(&face_clean, BMFace *);
+							int k;
+							for (k = 0; k < face_clean.count; k++) {
+								pbvh_bmesh_delete_vert_face(bvh, NULL, farr[k], deleted_verts, eq_ctx);
+								printf("Cleaning bad face!\n");
+							}
+						}
+					}
+				}
+			}
+		}
+#endif
+
 	}
 	BLI_buffer_free(&edge_verts_v1);
 	BLI_buffer_free(&edge_verts_v2);
 
+#ifdef USE_BRIDGE_CLEAN
+	BLI_buffer_free(&face_clean);
+#endif
+
 	BLI_gset_free(deleted_verts, NULL);
 }




More information about the Bf-blender-cvs mailing list