Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh_bmesh.c')
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 4bfda8ebf28..187891e7210 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -718,20 +718,24 @@ static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
/****************************** EdgeQueue *****************************/
-typedef struct {
+struct EdgeQueue;
+
+typedef struct EdgeQueue {
Heap *heap;
const float *center;
+ float center_proj[3]; /* for when we use projected coords. */
float radius_squared;
float limit_len_squared;
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
float limit_len;
#endif
-#ifdef USE_EDGEQUEUE_FRONTFACE
+ bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMFace *f);
+
const float *view_normal;
+#ifdef USE_EDGEQUEUE_FRONTFACE
unsigned int use_view_normal : 1;
#endif
-
} EdgeQueue;
typedef struct {
@@ -785,7 +789,6 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
float c[3];
/* Get closest point in triangle to sphere center */
- // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
BM_face_as_array_vert_tri(f, v_tri);
closest_on_tri_to_point_v3(c, q->center, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
@@ -794,6 +797,25 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
return len_squared_v3v3(q->center, c) <= q->radius_squared;
}
+static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
+{
+ BMVert *v_tri[3];
+ float c[3];
+ float tri_proj[3][3];
+
+ /* Get closest point in triangle to sphere center */
+ BM_face_as_array_vert_tri(f, v_tri);
+
+ project_plane_normalized_v3_v3v3(tri_proj[0], v_tri[0]->co, q->view_normal);
+ project_plane_normalized_v3_v3v3(tri_proj[1], v_tri[1]->co, q->view_normal);
+ project_plane_normalized_v3_v3v3(tri_proj[2], v_tri[2]->co, q->view_normal);
+
+ closest_on_tri_to_point_v3(c, q->center_proj, tri_proj[0], tri_proj[1], tri_proj[2]);
+
+ /* Check if triangle intersects the sphere */
+ return len_squared_v3v3(q->center_proj, c) <= q->radius_squared;
+}
+
/* Return true if the vertex mask is less than 1.0, false otherwise */
static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v)
{
@@ -929,7 +951,7 @@ static void long_edge_queue_face_add(
}
#endif
- if (edge_queue_tri_in_sphere(eq_ctx->q, f)) {
+ if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
/* Check each edge of the face */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
@@ -960,7 +982,7 @@ static void short_edge_queue_face_add(
}
#endif
- if (edge_queue_tri_in_sphere(eq_ctx->q, f)) {
+ if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
BMLoop *l_iter;
BMLoop *l_first;
@@ -984,7 +1006,7 @@ static void short_edge_queue_face_add(
static void long_edge_queue_create(
EdgeQueueContext *eq_ctx,
PBVH *bvh, const float center[3], const float view_normal[3],
- float radius)
+ float radius, const bool use_frontface, const bool use_projected)
{
eq_ctx->q->heap = BLI_heap_new();
eq_ctx->q->center = center;
@@ -994,13 +1016,22 @@ 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);
+
+#ifdef USE_EDGEQUEUE_FRONTFACE
+ eq_ctx->q->use_view_normal = use_frontface;
#else
- UNUSED_VARS(view_normal);
+ UNUSED_VARS(use_frontface);
#endif
+ if (use_projected) {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle;
+ project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal);
+ }
+ else {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
+ }
+
#ifdef USE_EDGEQUEUE_TAG_VERIFY
pbvh_bmesh_edge_tag_verify(bvh);
#endif
@@ -1037,7 +1068,7 @@ static void long_edge_queue_create(
static void short_edge_queue_create(
EdgeQueueContext *eq_ctx,
PBVH *bvh, const float center[3], const float view_normal[3],
- float radius)
+ float radius, const bool use_frontface, const bool use_projected)
{
eq_ctx->q->heap = BLI_heap_new();
eq_ctx->q->center = center;
@@ -1047,13 +1078,22 @@ 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);
+
+#ifdef USE_EDGEQUEUE_FRONTFACE
+ eq_ctx->q->use_view_normal = use_frontface;
#else
- UNUSED_VARS(view_normal);
+ UNUSED_VARS(use_frontface);
#endif
+ if (use_projected) {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle;
+ project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal);
+ }
+ else {
+ eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
+ }
+
for (int n = 0; n < bvh->totnode; n++) {
PBVHNode *node = &bvh->nodes[n];
@@ -1895,7 +1935,7 @@ void BKE_pbvh_build_bmesh(
bool BKE_pbvh_bmesh_update_topology(
PBVH *bvh, PBVHTopologyUpdateMode mode,
const float center[3], const float view_normal[3],
- float radius)
+ float radius, const bool use_frontface, const bool use_projected)
{
/* 2 is enough for edge faces - manifold edge */
BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
@@ -1918,7 +1958,7 @@ bool BKE_pbvh_bmesh_update_topology(
cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset,
};
- short_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius);
+ short_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius, use_frontface, use_projected);
modified |= pbvh_bmesh_collapse_short_edges(
&eq_ctx, bvh, &deleted_faces);
BLI_heap_free(q.heap, NULL);
@@ -1933,7 +1973,7 @@ bool BKE_pbvh_bmesh_update_topology(
cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset,
};
- long_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius);
+ long_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius, use_frontface, use_projected);
modified |= pbvh_bmesh_subdivide_long_edges(
&eq_ctx, bvh, &edge_loops);
BLI_heap_free(q.heap, NULL);