diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-05-18 11:22:31 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-05-18 11:22:31 +0300 |
commit | 5dfe88adbaeec63ede5c76dd84457e240f2fb602 (patch) | |
tree | 334a479946186325c1144e88ac0a61815348f2d0 /source/blender/blenkernel/intern | |
parent | 3dfce097e49b8dd443ecd364ff57d5fadc4a2c8c (diff) |
Fix T44553: Dyntopo ignores front-face option
When 'Front Faces' brush option was enabled, dyntop would still adjust detail on back-faces.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_bmesh.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index e631a4a365d..9f092bd651f 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -48,6 +48,9 @@ # include "BKE_global.h" #endif +/* Support for only operating on front-faces */ +#define USE_EDGEQUEUE_FRONTFACE + /* don't add edges into the queue multiple times */ #define USE_EDGEQUEUE_TAG /** @@ -598,6 +601,12 @@ typedef struct { #ifdef USE_EDGEQUEUE_EVEN_SUBDIV float limit_len; #endif + +#ifdef USE_EDGEQUEUE_FRONTFACE + const float *view_normal; + unsigned int use_view_normal : 1; +#endif + } EdgeQueue; typedef struct { @@ -719,6 +728,14 @@ static void long_edge_queue_edge_add_recursive( { BLI_assert(len_sq > SQUARE(limit_len)); +#ifdef USE_EDGEQUEUE_FRONTFACE + if (eq_ctx->q->use_view_normal) { + if (dot_v3v3(l_edge->f->no, eq_ctx->q->view_normal) < 0.0f) { + return; + } + } +#endif + #ifdef USE_EDGEQUEUE_TAG if (EDGE_QUEUE_TEST(l_edge->e) == false) #endif @@ -787,6 +804,14 @@ static void long_edge_queue_face_add( EdgeQueueContext *eq_ctx, BMFace *f) { +#ifdef USE_EDGEQUEUE_FRONTFACE + if (eq_ctx->q->use_view_normal) { + if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) { + return; + } + } +#endif + if (edge_queue_tri_in_sphere(eq_ctx->q, f)) { BMLoop *l_iter; BMLoop *l_first; @@ -814,6 +839,14 @@ static void short_edge_queue_face_add( EdgeQueueContext *eq_ctx, BMFace *f) { +#ifdef USE_EDGEQUEUE_FRONTFACE + if (eq_ctx->q->use_view_normal) { + if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) { + return; + } + } +#endif + if (edge_queue_tri_in_sphere(eq_ctx->q, f)) { BMLoop *l_iter; BMLoop *l_first; @@ -837,7 +870,7 @@ static void short_edge_queue_face_add( */ static void long_edge_queue_create( EdgeQueueContext *eq_ctx, - PBVH *bvh, const float center[3], + PBVH *bvh, const float center[3], const float view_normal[3], float radius) { int n; @@ -850,6 +883,13 @@ static void long_edge_queue_create( eq_ctx->q->limit_len = bvh->bm_max_edge_len; #endif +#ifdef USE_EDGEQUEUE_FRONTFACE + eq_ctx->q->view_normal = view_normal; + eq_ctx->q->use_view_normal = (view_normal != NULL); +#else + UNUSED_VARS(view_normal); +#endif + #ifdef USE_EDGEQUEUE_TAG_VERIFY pbvh_bmesh_edge_tag_verify(bvh); #endif @@ -886,7 +926,7 @@ static void long_edge_queue_create( */ static void short_edge_queue_create( EdgeQueueContext *eq_ctx, - PBVH *bvh, const float center[3], + PBVH *bvh, const float center[3], const float view_normal[3], float radius) { int n; @@ -899,6 +939,13 @@ static void short_edge_queue_create( eq_ctx->q->limit_len = bvh->bm_min_edge_len; #endif +#ifdef USE_EDGEQUEUE_FRONTFACE + eq_ctx->q->view_normal = view_normal; + eq_ctx->q->use_view_normal = (view_normal != NULL); +#else + UNUSED_VARS(view_normal); +#endif + for (n = 0; n < bvh->totnode; n++) { PBVHNode *node = &bvh->nodes[n]; @@ -1704,7 +1751,8 @@ void BKE_pbvh_build_bmesh( /* Collapse short edges, subdivide long edges */ bool BKE_pbvh_bmesh_update_topology( PBVH *bvh, PBVHTopologyUpdateMode mode, - const float center[3], float radius) + const float center[3], const float view_normal[3], + float radius) { /* 2 is enough for edge faces - manifold edge */ BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2); @@ -1716,12 +1764,16 @@ bool BKE_pbvh_bmesh_update_topology( bool modified = false; int n; + if (view_normal) { + BLI_assert(len_squared_v3(view_normal) != 0.0f); + } + if (mode & PBVH_Collapse) { EdgeQueue q; BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]), 0, 128, BLI_MEMPOOL_NOP); EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset}; - short_edge_queue_create(&eq_ctx, bvh, center, radius); + short_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius); modified |= !BLI_heap_is_empty(q.heap); pbvh_bmesh_collapse_short_edges(&eq_ctx, bvh, &deleted_faces); @@ -1734,7 +1786,7 @@ bool BKE_pbvh_bmesh_update_topology( BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert *[2]), 0, 128, BLI_MEMPOOL_NOP); EdgeQueueContext eq_ctx = {&q, queue_pool, bvh->bm, cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset}; - long_edge_queue_create(&eq_ctx, bvh, center, radius); + long_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius); modified |= !BLI_heap_is_empty(q.heap); pbvh_bmesh_subdivide_long_edges(&eq_ctx, bvh, &edge_loops); BLI_heap_free(q.heap, NULL); |