Cleanup: Comment style, reduce variable scope in pbvh_bmesh.cc

Just superfical cleanups to make working int his file more pleasant.
This commit is contained in:
Hans Goudey
2023-10-18 18:08:46 +02:00
parent fc1ee65104
commit 45478706b8

View File

@@ -26,6 +26,7 @@
#include "bmesh.h"
#include "pbvh_intern.hh"
using blender::IndexRange;
using blender::Span;
/* Avoid skinny faces */
@@ -34,10 +35,10 @@ using blender::Span;
# include "BKE_global.h"
#endif
/* Support for only operating on front-faces */
/* Support for only operating on front-faces. */
#define USE_EDGEQUEUE_FRONTFACE
/* don't add edges into the queue multiple times */
/* Don't add edges into the queue multiple times. */
#define USE_EDGEQUEUE_TAG
/**
* Ensure we don't have dirty tags for the edge queue, and that they are left cleared.
@@ -178,11 +179,11 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
return v;
}
if (*v_next_p == nullptr) {
/* removed and not remapped */
/* Removed and not remapped. */
return nullptr;
}
/* remapped */
/* Remapped. */
v = *v_next_p;
}
}
@@ -191,7 +192,7 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
/****************************** Building ******************************/
/* Update node data after splitting */
/* Update node data after splitting. */
static void pbvh_bmesh_node_finalize(PBVH *pbvh,
const int node_index,
const int cd_vert_node_offset,
@@ -201,7 +202,7 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
PBVHNode *n = &pbvh->nodes[node_index];
bool has_visible = false;
/* Create vert hash sets */
/* Create vert hash sets. */
n->bm_unique_verts = BLI_gset_ptr_new("bm_unique_verts");
n->bm_other_verts = BLI_gset_ptr_new("bm_other_verts");
@@ -210,10 +211,10 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
GSET_ITER (gs_iter, n->bm_faces) {
BMFace *f = static_cast<BMFace *>(BLI_gsetIterator_getKey(&gs_iter));
/* Update ownership of faces */
/* Update ownership of faces. */
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
/* Update vertices */
/* Update vertices. */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
@@ -228,7 +229,7 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
}
}
/* Update node bounding box */
/* Update node bounding box. */
BB_expand(&n->vb, v->co);
} while ((l_iter = l_iter->next) != l_first);
@@ -242,14 +243,14 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
n->orig_vb = n->vb;
/* Build GPU buffers for new node and update vertex normals */
/* Build GPU buffers for new node and update vertex normals. */
BKE_pbvh_node_mark_rebuild_draw(n);
BKE_pbvh_node_fully_hidden_set(n, !has_visible);
n->flag |= PBVH_UpdateNormals;
}
/* Recursively split the node if it exceeds the leaf_limit */
/* Recursively split the node if it exceeds the leaf_limit. */
static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_index)
{
const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
@@ -257,12 +258,12 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
PBVHNode *n = &pbvh->nodes[node_index];
if (BLI_gset_len(n->bm_faces) <= pbvh->leaf_limit) {
/* Node limit not exceeded */
/* Node limit not exceeded. */
pbvh_bmesh_node_finalize(pbvh, node_index, cd_vert_node_offset, cd_face_node_offset);
return;
}
/* Calculate bounding box around primitive centroids */
/* Calculate bounding box around primitive centroids. */
BB cb;
BB_reset(&cb);
GSetIterator gs_iter;
@@ -273,16 +274,16 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
BB_expand(&cb, bbc->bcentroid);
}
/* Find widest axis and its midpoint */
/* Find widest axis and its midpoint. */
const int axis = BB_widest_axis(&cb);
const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
/* Add two new child nodes */
/* Add two new child nodes. */
const int children = pbvh->nodes.size();
n->children_offset = children;
pbvh_grow_nodes(pbvh, pbvh->nodes.size() + 2);
/* Array reallocated, update current node pointer */
/* Array reallocated, update current node pointer. */
n = &pbvh->nodes[node_index];
/* Initialize children */
@@ -292,7 +293,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
c2->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_len(n->bm_faces) / 2);
/* Partition the parent node's faces between the two children */
/* Partition the parent node's faces between the two children. */
GSET_ITER (gs_iter, n->bm_faces) {
BMFace *f = static_cast<BMFace *>(BLI_gsetIterator_getKey(&gs_iter));
const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
@@ -326,7 +327,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
/* Clear this node */
/* Mark this node's unique verts as unclaimed */
/* Mark this node's unique verts as unclaimed. */
if (n->bm_unique_verts) {
GSET_ITER (gs_iter, n->bm_unique_verts) {
BMVert *v = static_cast<BMVert *>(BLI_gsetIterator_getKey(&gs_iter));
@@ -335,7 +336,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
BLI_gset_free(n->bm_unique_verts, nullptr);
}
/* Unclaim faces */
/* Unclaim faces. */
GSET_ITER (gs_iter, n->bm_faces) {
BMFace *f = static_cast<BMFace *>(BLI_gsetIterator_getKey(&gs_iter));
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
@@ -360,21 +361,21 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind
}
n->flag &= ~PBVH_Leaf;
/* Recurse */
/* Recurse. */
pbvh_bmesh_node_split(pbvh, bbc_array, children);
pbvh_bmesh_node_split(pbvh, bbc_array, children + 1);
/* Array maybe reallocated, update current node pointer */
n = &pbvh->nodes[node_index];
/* Update bounding box */
/* Update bounding box. */
BB_reset(&n->vb);
BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset].vb);
BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset + 1].vb);
n->orig_vb = n->vb;
}
/* Recursively split the node if it exceeds the leaf_limit */
/* Recursively split the node if it exceeds the leaf_limit. */
static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
{
GSet *bm_faces = pbvh->nodes[node_index].bm_faces;
@@ -387,7 +388,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
/* Trigger draw manager cache invalidation. */
pbvh->draw_cache_invalid = true;
/* For each BMFace, store the AABB and AABB centroid */
/* For each BMFace, store the AABB and AABB centroid. */
BBC *bbc_array = static_cast<BBC *>(MEM_mallocN(sizeof(BBC) * bm_faces_size, "BBC"));
GSetIterator gs_iter;
@@ -404,7 +405,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
} while ((l_iter = l_iter->next) != l_first);
BBC_update_centroid(bbc);
/* so we can do direct lookups on 'bbc_array' */
/* So we can do direct lookups on 'bbc_array'. */
BM_elem_index_set(f, i); /* set_dirty! */
}
/* Likely this is already dirty. */
@@ -493,12 +494,12 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
BLI_assert((pbvh->nodes.size() == 1 || node_index) && node_index <= pbvh->nodes.size());
/* avoid initializing customdata because its quite involved */
/* Avoid initializing customdata because its quite involved. */
BMVert *v = BM_vert_create(pbvh->header.bm, co, nullptr, BM_CREATE_NOP);
BM_data_interp_from_verts(pbvh->header.bm, v1, v2, v, 0.5f);
/* This value is logged below */
/* This value is logged below. */
copy_v3_v3(v->no, no);
BLI_gset_insert(node->bm_unique_verts, v);
@@ -506,7 +507,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Log the new vertex */
/* Log the new vertex. */
BM_log_vert_added(pbvh->bm_log, v, cd_vert_mask_offset);
return v;
@@ -523,7 +524,7 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
{
PBVHNode *node = &pbvh->nodes[node_index];
/* ensure we never add existing face */
/* Ensure we never add existing face. */
BLI_assert(!BM_face_exists(v_tri.data(), 3));
BMFace *f = BM_face_create(
@@ -533,17 +534,17 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
BLI_gset_insert(node->bm_faces, f);
BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, node_index);
/* mark node for update */
/* mark node for update. */
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
node->flag &= ~PBVH_FullyHidden;
/* Log the new face */
/* Log the new face. */
BM_log_face_added(pbvh->bm_log, f);
return f;
}
/* Return the number of faces in 'node' that use vertex 'v' */
/* Return the number of faces in 'node' that use vertex 'v'. */
#if 0
static int pbvh_bmesh_node_vert_use_count(PBVH *pbvh, PBVHNode *node, BMVert *v)
{
@@ -587,7 +588,7 @@ static int pbvh_bmesh_node_vert_use_count_at_most(PBVH *pbvh,
return count;
}
/* Return a node that uses vertex 'v' other than its current owner */
/* Return a node that uses vertex 'v' other than its current owner. */
static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *pbvh, BMVert *v)
{
PBVHNode *current_node = pbvh_bmesh_node_from_vert(pbvh, v);
@@ -608,12 +609,11 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *pbvh, BMVert *v)
static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner, BMVert *v)
{
PBVHNode *current_owner = pbvh_bmesh_node_from_vert(pbvh, v);
/* mark node for update */
current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
BLI_assert(current_owner != new_owner);
/* Remove current ownership */
/* Remove current ownership. */
BLI_gset_remove(current_owner->bm_unique_verts, v, nullptr);
/* Set new ownership */
@@ -622,33 +622,31 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner,
BLI_gset_remove(new_owner->bm_other_verts, v, nullptr);
BLI_assert(!BLI_gset_haskey(new_owner->bm_other_verts, v));
/* mark node for update */
new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
}
static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
{
/* never match for first time */
/* Never match for first time. */
int f_node_index_prev = DYNTOPO_NODE_NONE;
PBVHNode *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
BLI_gset_remove(v_node->bm_unique_verts, v, nullptr);
BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
/* Have to check each neighboring face's node */
/* Have to check each neighboring face's node. */
BMFace *f;
BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
const int f_node_index = pbvh_bmesh_node_index_from_face(pbvh, f);
/* faces often share the same node,
* quick check to avoid redundant #BLI_gset_remove calls */
/* Faces often share the same node, quick check to avoid redundant #BLI_gset_remove calls. */
if (f_node_index_prev != f_node_index) {
f_node_index_prev = f_node_index;
PBVHNode *f_node = &pbvh->nodes[f_node_index];
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Remove current ownership */
/* Remove current ownership. */
BLI_gset_remove(f_node->bm_other_verts, v, nullptr);
BLI_assert(!BLI_gset_haskey(f_node->bm_unique_verts, v));
@@ -662,15 +660,14 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f)
{
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
/* Check if any of this face's vertices need to be removed
* from the node */
/* Check if any of this face's vertices need to be removed from the node. */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
do {
BMVert *v = l_iter->v;
if (pbvh_bmesh_node_vert_use_count_is_equal(pbvh, f_node, v, 1)) {
if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
/* Find a different node that uses 'v' */
/* Find a different node that uses 'v'. */
PBVHNode *new_node;
new_node = pbvh_bmesh_vert_other_node_find(pbvh, v);
@@ -681,28 +678,27 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f)
}
}
else {
/* Remove from other verts */
/* Remove from other verts. */
BLI_gset_remove(f_node->bm_other_verts, v, nullptr);
}
}
} while ((l_iter = l_iter->next) != l_first);
/* Remove face from node and top level */
/* Remove face from node and top level. */
BLI_gset_remove(f_node->bm_faces, f, nullptr);
BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
/* Log removed face */
/* Log removed face. */
BM_log_face_removed(pbvh->bm_log, f);
/* mark node for update */
/* Mark node for update. */
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
}
static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
{
/* fast-path for most common case where an edge has 2 faces,
* no need to iterate twice.
* This assumes that the buffer */
/* Fast-path for most common case where an edge has 2 faces,
* no need to iterate twice. This assumes that the buffer. */
BMLoop **data = static_cast<BMLoop **>(buf->data);
BLI_assert(buf->alloc_count >= 2);
if (LIKELY(BM_edge_loop_pair(e, &data[0], &data[1]))) {
@@ -727,7 +723,7 @@ static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
struct EdgeQueue {
HeapSimple *heap;
const float *center;
float center_proj[3]; /* for when we use projected coords. */
float center_proj[3]; /* For when we use projected coords. */
float radius_squared;
float limit_len_squared;
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
@@ -795,12 +791,12 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
BMVert *v_tri[3];
float c[3];
/* Get closest point in triangle to sphere center */
/* Get closest point in triangle to sphere center. */
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);
/* Check if triangle intersects the sphere */
/* Check if triangle intersects the sphere. */
return len_squared_v3v3(q->center, c) <= q->radius_squared;
}
@@ -810,7 +806,7 @@ static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
float c[3];
float tri_proj[3][3];
/* Get closest point in triangle to sphere center */
/* 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);
@@ -819,11 +815,11 @@ static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
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 */
/* 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 */
/* Return true if the vertex mask is less than 1.0, false otherwise. */
static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v)
{
return BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f;
@@ -894,7 +890,7 @@ static void long_edge_queue_edge_add_recursive(
if (l_edge->radial_next != l_edge) {
/* How much longer we need to be to consider for subdividing
* (avoids subdividing faces which are only *slightly* skinny) */
* (avoids subdividing faces which are only *slightly* skinny). */
# define EVEN_EDGELEN_THRESHOLD 1.2f
/* How much the limit increases per recursion
* (avoids performing subdivisions too far away). */
@@ -948,7 +944,7 @@ static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
#endif
if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
/* Check each edge of the face */
/* Check each edge of the face. */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
do {
@@ -979,7 +975,7 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
BMLoop *l_iter;
BMLoop *l_first;
/* Check each edge of the face */
/* Check each edge of the face. */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
short_edge_queue_edge_add(eq_ctx, l_iter->e);
@@ -987,7 +983,8 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
}
}
/* Create a priority queue containing vertex pairs connected by a long
/**
* Create a priority queue containing vertex pairs connected by a long
* edge as defined by PBVH.bm_max_edge_len.
*
* Only nodes marked for topology update are checked, and in those
@@ -1033,13 +1030,13 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
#endif
for (PBVHNode &node : pbvh->nodes) {
/* Check leaf nodes marked for topology update */
/* Check leaf nodes marked for topology update. */
if ((node.flag & PBVH_Leaf) && (node.flag & PBVH_UpdateTopology) &&
!(node.flag & PBVH_FullyHidden))
{
GSetIterator gs_iter;
/* Check each face */
/* Check each face. */
GSET_ITER (gs_iter, node.bm_faces) {
BMFace *f = static_cast<BMFace *>(BLI_gsetIterator_getKey(&gs_iter));
@@ -1109,10 +1106,12 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
/*************************** Topology update **************************/
/* Copy custom data from src to dst edge.
/**
* Copy custom data from src to dst edge.
*
* NOTE: The BM_ELEM_TAG is used to tell whether an edge is in the queue for collapse/split,
* so we do not copy this flag as we do not want the new edge to appear in the queue. */
* \note The BM_ELEM_TAG is used to tell whether an edge is in the queue for collapse/split,
* so we do not copy this flag as we do not want the new edge to appear in the queue.
*/
static void copy_edge_data(BMesh &bm, BMEdge &dst, /*const*/ BMEdge &src)
{
dst.head.hflag = src.head.hflag & ~BM_ELEM_TAG;
@@ -1128,10 +1127,10 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
float co_mid[3], no_mid[3];
/* Get all faces adjacent to the edge */
/* Get all faces adjacent to the edge. */
pbvh_bmesh_edge_loops(edge_loops, e);
/* Create a new vertex in current node at the edge's midpoint */
/* Create a new vertex in current node at the edge's midpoint. */
mid_v3_v3v3(co_mid, e->v1->co, e->v2->co);
mid_v3_v3v3(no_mid, e->v1->no, e->v2->no);
normalize_v3(no_mid);
@@ -1140,24 +1139,21 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
BMVert *v_new = pbvh_bmesh_vert_create(
pbvh, e->v1, e->v2, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
/* For each face, add two new triangles and delete the original */
/* For each face, add two new triangles and delete the original. */
for (int i = 0; i < edge_loops->count; i++) {
BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
BMFace *f_adj = l_adj->f;
BMFace *f_new;
BMVert *v_opp, *v1, *v2;
BLI_assert(f_adj->len == 3);
int ni = BM_ELEM_CD_GET_INT(f_adj, eq_ctx->cd_face_node_offset);
/* Find the vertex not in the edge */
v_opp = l_adj->prev->v;
/* Find the vertex not in the edge. */
BMVert *v_opp = l_adj->prev->v;
/* Get e->v1 and e->v2 in the order they appear in the
* existing face so that the new faces' winding orders
* match */
v1 = l_adj->v;
v2 = l_adj->next->v;
/* Get e->v1 and e->v2 in the order they appear in the existing face so that the new faces'
* winding orders match. */
BMVert *v1 = l_adj->v;
BMVert *v2 = l_adj->next->v;
if (ni != node_index && i == 0) {
pbvh_bmesh_vert_ownership_transfer(pbvh, &pbvh->nodes[ni], v_new);
@@ -1194,8 +1190,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
const std::array<BMEdge *, 3> first_edges = bm_edges_from_tri(bm, first_tri);
copy_edge_data(*bm, *first_edges[0], *e);
f_new = pbvh_bmesh_face_create(pbvh, ni, first_tri, first_edges, f_adj);
long_edge_queue_face_add(eq_ctx, f_new);
BMFace *f_new_first = pbvh_bmesh_face_create(pbvh, ni, first_tri, first_edges, f_adj);
long_edge_queue_face_add(eq_ctx, f_new_first);
/* Create second face (v_new, v2, v_opp). */
const std::array<BMVert *, 3> second_tri({v_new, v2, v_opp});
@@ -1206,8 +1202,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
};
copy_edge_data(*bm, *second_edges[0], *e);
f_new = pbvh_bmesh_face_create(pbvh, ni, second_tri, second_edges, f_adj);
long_edge_queue_face_add(eq_ctx, f_new);
BMFace *f_new_second = pbvh_bmesh_face_create(pbvh, ni, second_tri, second_edges, f_adj);
long_edge_queue_face_add(eq_ctx, f_new_second);
/* Delete original */
pbvh_bmesh_face_remove(pbvh, f_adj);
@@ -1221,7 +1217,6 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
if (BM_vert_edge_count_is_over(v_opp, 8)) {
BMIter bm_iter;
BMEdge *e2;
BM_ITER_ELEM (e2, &bm_iter, v_opp, BM_EDGES_OF_VERT) {
long_edge_queue_edge_add(eq_ctx, e2);
}
@@ -1239,13 +1234,14 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
BMVert **pair = static_cast<BMVert **>(BLI_heapsimple_pop_min(eq_ctx->q->heap));
BMVert *v1 = pair[0], *v2 = pair[1];
BMEdge *e;
BMVert *v1 = pair[0];
BMVert *v2 = pair[1];
BLI_mempool_free(eq_ctx->pool, pair);
pair = nullptr;
/* Check that the edge still exists */
BMEdge *e;
if (!(e = BM_edge_exists(v1, v2))) {
continue;
}
@@ -1293,9 +1289,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BLI_Buffer *deleted_faces,
EdgeQueueContext *eq_ctx)
{
BMVert *v_del, *v_conn;
/* one of the two vertices may be masked, select the correct one for deletion */
BMesh &bm = *pbvh->header.bm;
/* Prefer deleting the vertex that is less masked. */
BMVert *v_del;
BMVert *v_conn;
if (BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset) <
BM_ELEM_CD_GET_FLOAT(v2, eq_ctx->cd_vert_mask_offset))
{
@@ -1307,21 +1304,21 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
v_conn = v1;
}
/* Remove the merge vertex from the PBVH */
/* Remove the merge vertex from the PBVH. */
pbvh_bmesh_vert_remove(pbvh, v_del);
/* Remove all faces adjacent to the edge */
/* Remove all faces adjacent to the edge. */
BMLoop *l_adj;
while ((l_adj = e->l)) {
BMFace *f_adj = l_adj->f;
pbvh_bmesh_face_remove(pbvh, f_adj);
BM_face_kill(pbvh->header.bm, f_adj);
BM_face_kill(&bm, f_adj);
}
/* Kill the edge */
/* Kill the edge. */
BLI_assert(BM_edge_is_wire(e));
BM_edge_kill(pbvh->header.bm, e);
BM_edge_kill(&bm, e);
/* For all remaining faces of v_del, create a new face that is the
* same except it uses v_conn instead of v_del */
@@ -1331,7 +1328,6 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BLI_buffer_clear(deleted_faces);
BMLoop *l;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
BMFace *existing_face;
@@ -1366,7 +1362,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BLI_assert(!BM_face_exists(v_tri.data(), 3));
PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
int ni = n - pbvh->nodes.data();
const std::array<BMEdge *, 3> e_tri = bm_edges_from_tri(pbvh->header.bm, v_tri);
const std::array<BMEdge *, 3> e_tri = bm_edges_from_tri(&bm, v_tri);
pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
/* Ensure that v_conn is in the new face's node */
@@ -1379,39 +1375,31 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
}
BM_LOOPS_OF_VERT_ITER_END;
/* Delete the tagged faces */
/* Delete the tagged faces. */
for (int i = 0; i < deleted_faces->count; i++) {
BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
/* Get vertices and edges of face */
/* Get vertices and edges of face. */
BLI_assert(f_del->len == 3);
BMLoop *l_iter = BM_FACE_FIRST_LOOP(f_del);
BMVert *v_tri[3];
BMEdge *e_tri[3];
v_tri[0] = l_iter->v;
e_tri[0] = l_iter->e;
l_iter = l_iter->next;
v_tri[1] = l_iter->v;
e_tri[1] = l_iter->e;
l_iter = l_iter->next;
v_tri[2] = l_iter->v;
e_tri[2] = l_iter->e;
const std::array<BMVert *, 3> v_tri{l_iter->v, l_iter->next->v, l_iter->next->next->v};
const std::array<BMEdge *, 3> e_tri{l_iter->e, l_iter->next->e, l_iter->next->next->e};
/* Remove the face */
pbvh_bmesh_face_remove(pbvh, f_del);
BM_face_kill(pbvh->header.bm, f_del);
BM_face_kill(&bm, f_del);
/* Check if any of the face's edges are now unused by any
* face, if so delete them */
for (int j = 0; j < 3; j++) {
for (const int j : IndexRange(3)) {
if (BM_edge_is_wire(e_tri[j])) {
BM_edge_kill(pbvh->header.bm, e_tri[j]);
BM_edge_kill(&bm, e_tri[j]);
}
}
/* Check if any of the face's vertices are now unused, if so
* remove them from the PBVH */
for (int j = 0; j < 3; j++) {
for (const int j : IndexRange(3)) {
if ((v_tri[j] != v_del) && (v_tri[j]->e == nullptr)) {
pbvh_bmesh_vert_remove(pbvh, v_tri[j]);
@@ -1421,13 +1409,13 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
v_conn = nullptr;
}
BLI_ghash_insert(deleted_verts, v_tri[j], nullptr);
BM_vert_kill(pbvh->header.bm, v_tri[j]);
BM_vert_kill(&bm, v_tri[j]);
}
}
}
/* Move v_conn to the midpoint of v_conn and v_del (if v_conn still exists, it
* may have been deleted above) */
* may have been deleted above). */
if (v_conn != nullptr) {
BM_log_vert_before_modified(pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset);
mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
@@ -1448,7 +1436,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_log_vert_removed(pbvh->bm_log, v_del, eq_ctx->cd_vert_mask_offset);
/* v_conn == nullptr is OK */
BLI_ghash_insert(deleted_verts, v_del, v_conn);
BM_vert_kill(pbvh->header.bm, v_del);
BM_vert_kill(&bm, v_del);
}
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
@@ -1457,23 +1445,24 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
{
const float min_len_squared = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
bool any_collapsed = false;
/* deleted verts point to vertices they were merged into, or nullptr when removed. */
/* Deleted verts point to vertices they were merged into, or nullptr when removed. */
GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts");
while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
BMVert **pair = static_cast<BMVert **>(BLI_heapsimple_pop_min(eq_ctx->q->heap));
BMVert *v1 = pair[0], *v2 = pair[1];
BMVert *v1 = pair[0];
BMVert *v2 = pair[1];
BLI_mempool_free(eq_ctx->pool, pair);
pair = nullptr;
/* Check the verts still exist */
/* Check the verts still exists. */
if (!(v1 = bm_vert_hash_lookup_chain(deleted_verts, v1)) ||
!(v2 = bm_vert_hash_lookup_chain(deleted_verts, v2)) || (v1 == v2))
{
continue;
}
/* Check that the edge still exists */
/* Check that the edge still exists. */
BMEdge *e;
if (!(e = BM_edge_exists(v1, v2))) {
continue;
@@ -1486,9 +1475,8 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
continue;
}
/* Check that the edge's vertices are still in the PBVH. It's
* possible that an edge collapse has deleted adjacent faces
* and the node has been split, thus leaving wire edges and
/* Check that the edge's vertices are still in the PBVH. It's possible that an edge collapse
* has deleted adjacent faces and the node has been split, thus leaving wire edges and
* associated vertices. */
if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
(BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE))
@@ -1542,7 +1530,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
if (r_active_vertex) {
float location[3] = {0.0f};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
for (int j = 0; j < 3; j++) {
for (const int j : IndexRange(3)) {
if (j == 0 || len_squared_v3v3(location, cos[j]) <
len_squared_v3v3(location, nearest_vertex_co)) {
copy_v3_v3(nearest_vertex_co, cos[j]);
@@ -1575,7 +1563,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
if (r_active_vertex) {
float location[3] = {0.0f};
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
for (int j = 0; j < 3; j++) {
for (const int j : IndexRange(3)) {
if (j == 0 || len_squared_v3v3(location, v_tri[j]->co) <
len_squared_v3v3(location, nearest_vertex_co))
{
@@ -1631,7 +1619,7 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
float len2 = len_squared_v3v3(v_tri[1]->co, v_tri[2]->co);
float len3 = len_squared_v3v3(v_tri[2]->co, v_tri[0]->co);
/* detail returned will be set to the maximum allowed size, so take max here */
/* Detail returned will be set to the maximum allowed size, so take max here. */
*r_edge_length = sqrtf(max_fff(len1, len2, len3));
}
@@ -1701,8 +1689,8 @@ void pbvh_bmesh_normals_update(Span<PBVHNode *> nodes)
}
struct FastNodeBuildInfo {
int totface; /* number of faces */
int start; /* start of faces in array */
int totface; /* Number of faces. */
int start; /* Start of faces in array. */
FastNodeBuildInfo *child1;
FastNodeBuildInfo *child2;
};
@@ -1721,7 +1709,7 @@ static void pbvh_bmesh_node_limit_ensure_fast(
return;
}
/* Calculate bounding box around primitive centroids */
/* Calculate bounding box around primitive centroids. */
BB cb;
BB_reset(&cb);
for (int i = 0; i < node->totface; i++) {
@@ -1731,15 +1719,15 @@ static void pbvh_bmesh_node_limit_ensure_fast(
BB_expand(&cb, bbc->bcentroid);
}
/* initialize the children */
/* Initialize the children. */
/* Find widest axis and its midpoint */
/* Find widest axis and its midpoint. */
const int axis = BB_widest_axis(&cb);
const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
int num_child1 = 0, num_child2 = 0;
/* split vertices along the middle line */
/* Split vertices along the middle line. */
const int end = node->start + node->totface;
for (int i = node->start; i < end - num_child2; i++) {
BMFace *f = nodeinfo[i];
@@ -1748,7 +1736,7 @@ static void pbvh_bmesh_node_limit_ensure_fast(
if (bbc->bcentroid[axis] > mid) {
int i_iter = end - num_child2 - 1;
int candidate = -1;
/* found a face that should be part of another node, look for a face to substitute with */
/* Found a face that should be part of another node, look for a face to substitute with. */
for (; i_iter > i; i_iter--) {
BMFace *f_iter = nodeinfo[i_iter];
@@ -1765,13 +1753,13 @@ static void pbvh_bmesh_node_limit_ensure_fast(
BMFace *tmp = nodeinfo[i];
nodeinfo[i] = nodeinfo[candidate];
nodeinfo[candidate] = tmp;
/* increase both counts */
/* Increase both counts. */
num_child1++;
num_child2++;
}
else {
/* not finding candidate means second half of array part is full of
* second node parts, just increase the number of child nodes for it */
/* Not finding candidate means second half of array part is full of
* second node parts, just increase the number of child nodes for it. */
num_child2++;
}
}
@@ -1780,7 +1768,7 @@ static void pbvh_bmesh_node_limit_ensure_fast(
}
}
/* ensure at least one child in each node */
/* Ensure at least one child in each node. */
if (num_child2 == 0) {
num_child2++;
num_child1--;
@@ -1790,8 +1778,8 @@ static void pbvh_bmesh_node_limit_ensure_fast(
num_child2--;
}
/* at this point, faces should have been split along the array range sequentially,
* each sequential part belonging to one node only */
/* At this point, faces should have been split along the array range sequentially,
* each sequential part belonging to one node only. */
BLI_assert((num_child1 + num_child2) == node->totface);
node->child1 = child1 = static_cast<FastNodeBuildInfo *>(
@@ -1813,7 +1801,7 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, FastNodeBuildInfo *node, int node_index)
{
PBVHNode *n = &pbvh->nodes[node_index];
/* two cases, node does not have children or does have children */
/* Two cases, node does not have children or does have children. */
if (node->child1) {
int children_offset = pbvh->nodes.size();
@@ -1826,15 +1814,15 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
n = &pbvh->nodes[node_index];
/* Update bounding box */
/* Update bounding box. */
BB_reset(&n->vb);
BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset].vb);
BB_expand_with_bb(&n->vb, &pbvh->nodes[n->children_offset + 1].vb);
n->orig_vb = n->vb;
}
else {
/* node does not have children so it's a leaf node, populate with faces and tag accordingly
* this is an expensive part but it's not so easily thread-able due to vertex node indices */
/* Node does not have children so it's a leaf node, populate with faces and tag accordingly
* this is an expensive part but it's not so easily thread-able due to vertex node indices. */
const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
const int cd_face_node_offset = pbvh->cd_face_node_offset;
@@ -1855,11 +1843,11 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
BMFace *f = nodeinfo[i];
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
/* Update ownership of faces */
/* Update ownership of faces. */
BLI_gset_insert(n->bm_faces, f);
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
/* Update vertices */
/* Update vertices. */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
do {
@@ -1873,7 +1861,7 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
}
}
/* Update node bounding box */
/* Update node bounding box. */
} while ((l_iter = l_iter->next) != l_first);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
@@ -1888,7 +1876,7 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
n->orig_vb = n->vb;
/* Build GPU buffers for new node and update vertex normals */
/* Build GPU buffers for new node and update vertex normals. */
BKE_pbvh_node_mark_rebuild_draw(n);
BKE_pbvh_node_fully_hidden_set(n, !has_visible);
@@ -1917,12 +1905,12 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
pbvh->header.type = PBVH_BMESH;
pbvh->bm_log = log;
/* TODO: choose leaf limit better */
/* TODO: choose leaf limit better. */
pbvh->leaf_limit = 400;
BKE_pbvh_update_bmesh_offsets(pbvh, cd_vert_node_offset, cd_face_node_offset);
/* bounding box array of all faces, no need to recalculate every time */
/* bounding box array of all faces, no need to recalculate every time. */
BBC *bbc_array = static_cast<BBC *>(MEM_mallocN(sizeof(BBC) * bm->totface, "BBC"));
BMFace **nodeinfo = static_cast<BMFace **>(
MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo"));
@@ -1955,20 +1943,20 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
}
/* setup root node */
/* Set up root node. */
FastNodeBuildInfo rootnode = {0};
rootnode.totface = bm->totface;
/* start recursion, assign faces to nodes accordingly */
/* Start recursion, assign faces to nodes accordingly. */
pbvh_bmesh_node_limit_ensure_fast(pbvh, nodeinfo, bbc_array, &rootnode, arena);
/* We now have all faces assigned to a node,
* next we need to assign those to the gsets of the nodes. */
/* Start with all faces in the root node */
/* Start with all faces in the root node. */
pbvh->nodes.append({});
/* take root node and visit and populate children recursively */
/* Take root node and visit and populate children recursively. */
pbvh_bmesh_create_nodes_fast_recursive(pbvh, nodeinfo, bbc_array, &rootnode, 0);
BLI_memarena_free(arena);
@@ -1984,7 +1972,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
const bool use_frontface,
const bool use_projected)
{
/* 2 is enough for edge faces - manifold edge */
/* 2 is enough for edge faces - manifold edge. */
BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
const int cd_vert_mask_offset = CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK);
@@ -2066,7 +2054,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool use_original)
{
/* Skip if original coords/triangles are already saved */
/* Skip if original coords/triangles are already saved. */
if (node->bm_orco) {
return;
}
@@ -2081,7 +2069,7 @@ void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool u
node->bm_orvert = static_cast<BMVert **>(
MEM_mallocN(sizeof(*node->bm_orvert) * totvert, __func__));
/* Copy out the vertices and assign a temporary index */
/* Copy out the vertices and assign a temporary index. */
int i = 0;
GSetIterator gs_iter;
GSET_ITER (gs_iter, node->bm_unique_verts) {
@@ -2148,11 +2136,10 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
for (int i = 0; i < totnode; i++) {
PBVHNode *n = &pbvh->nodes[i];
if (n->flag & PBVH_Leaf) {
/* Free orco/ortri data */
/* Free orco/ortri data. */
pbvh_bmesh_node_drop_orig(n);
/* Recursively split nodes that have gotten too many
* elements */
/* Recursively split nodes that have gotten too many elements. */
pbvh_bmesh_node_limit_ensure(pbvh, i);
}
}
@@ -2241,7 +2228,7 @@ static void print_flag_factors(int flag)
static void pbvh_bmesh_verify(PBVH *pbvh)
{
/* build list of faces & verts to lookup */
/* Build list of faces & verts to lookup. */
GSet *faces_all = BLI_gset_ptr_new_ex(__func__, pbvh->header.bm->totface);
BMIter iter;
@@ -2263,7 +2250,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
}
}
/* Check vert/face counts */
/* Check vert/face counts. */
{
int totface = 0, totvert = 0;
for (int i = 0; i < pbvh->totnode; i++) {
@@ -2283,26 +2270,26 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
BMVert *v;
PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, f);
/* Check that the face's node is a leaf */
/* Check that the face's node is a leaf. */
BLI_assert(n->flag & PBVH_Leaf);
/* Check that the face's node knows it owns the face */
/* Check that the face's node knows it owns the face. */
BLI_assert(BLI_gset_haskey(n->bm_faces, f));
/* Check the face's vertices... */
BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
PBVHNode *nv;
/* Check that the vertex is in the node */
/* Check that the vertex is in the node. */
BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v) ^ BLI_gset_haskey(n->bm_other_verts, v));
/* Check that the vertex has a node owner */
/* Check that the vertex has a node owner. */
nv = pbvh_bmesh_node_lookup(pbvh, v);
/* Check that the vertex's node knows it owns the vert */
/* Check that the vertex's node knows it owns the vert. */
BLI_assert(BLI_gset_haskey(nv->bm_unique_verts, v));
/* Check that the vertex isn't duplicated as an 'other' vert */
/* Check that the vertex isn't duplicated as an 'other' vert. */
BLI_assert(!BLI_gset_haskey(nv->bm_other_verts, v));
}
}
@@ -2312,24 +2299,23 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
{
BMVert *v;
BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
/* vertex isn't tracked */
/* Vertex isn't tracked. */
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
continue;
}
PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, v);
/* Check that the vert's node is a leaf */
/* Check that the vert's node is a leaf. */
BLI_assert(n->flag & PBVH_Leaf);
/* Check that the vert's node knows it owns the vert */
/* Check that the vert's node knows it owns the vert. */
BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v));
/* Check that the vertex isn't duplicated as an 'other' vert */
/* Check that the vertex isn't duplicated as an 'other' vert. */
BLI_assert(!BLI_gset_haskey(n->bm_other_verts, v));
/* Check that the vert's node also contains one of the vert's
* adjacent faces */
/* Check that the vert's node also contains one of the vert's adjacent faces. */
bool found = false;
BMIter bm_iter;
BMFace *f = nullptr;