cleanup: C99 and vertex array comments
GPU_buffer no longer has a fallback to client vertex arrays, so remove comments about it. Changed a few internal structs/function interfaces to use bool where appropriate. Use for-loop scope and flexible declaration placement. PBVH does the same thing but needs ~150 fewer lines to do it! The change to BLI_ghashIterator_init is admittedly hackish but makes GHASH_ITER_INDEX nicer to use.
This commit is contained in:
parent
7bbcb643f2
commit
77ac33db7b
Notes:
blender-bot
2023-02-14 06:17:14 +01:00
Referenced by commit 254282c6cb
, Fix crash when ding dyntopo sculpting
|
@ -98,7 +98,7 @@ void BKE_pbvh_raycast(
|
|||
bool original);
|
||||
|
||||
bool BKE_pbvh_node_raycast(
|
||||
PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
|
||||
PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist);
|
||||
|
||||
|
@ -210,7 +210,7 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
|
|||
|
||||
void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
|
||||
void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]);
|
||||
void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r_totface);
|
||||
void BKE_pbvh_get_grid_updates(PBVH *bvh, bool clear, void ***r_gridfaces, int *r_totface);
|
||||
void BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
|
||||
void **gridfaces,
|
||||
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
|
||||
|
|
|
@ -1415,7 +1415,7 @@ void multires_stitch_grids(Object *ob)
|
|||
int totface;
|
||||
|
||||
if (ccgdm->pbvh) {
|
||||
BKE_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
|
||||
BKE_pbvh_get_grid_updates(ccgdm->pbvh, false, (void ***)&faces, &totface);
|
||||
|
||||
if (totface) {
|
||||
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
|
||||
typedef struct PBVHStack {
|
||||
PBVHNode *node;
|
||||
int revisiting;
|
||||
bool revisiting;
|
||||
} PBVHStack;
|
||||
|
||||
typedef struct PBVHIter {
|
||||
|
@ -87,8 +87,7 @@ void BB_reset(BB *bb)
|
|||
/* Expand the bounding box to include a new coordinate */
|
||||
void BB_expand(BB *bb, const float co[3])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
|
||||
bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
|
||||
}
|
||||
|
@ -97,8 +96,7 @@ void BB_expand(BB *bb, const float co[3])
|
|||
/* Expand the bounding box to include another bounding box */
|
||||
void BB_expand_with_bb(BB *bb, BB *bb2)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
|
||||
bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[i]);
|
||||
}
|
||||
|
@ -108,9 +106,8 @@ void BB_expand_with_bb(BB *bb, BB *bb2)
|
|||
int BB_widest_axis(const BB *bb)
|
||||
{
|
||||
float dim[3];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
dim[i] = bb->bmax[i] - bb->bmin[i];
|
||||
|
||||
if (dim[0] > dim[1]) {
|
||||
|
@ -129,8 +126,7 @@ int BB_widest_axis(const BB *bb)
|
|||
|
||||
void BBC_update_centroid(BBC *bbc)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 3; ++i)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
|
||||
}
|
||||
|
||||
|
@ -170,13 +166,13 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
|
|||
// BB_expand(&node->vb, co);
|
||||
//}
|
||||
|
||||
static int face_materials_match(const MPoly *f1, const MPoly *f2)
|
||||
static bool face_materials_match(const MPoly *f1, const MPoly *f2)
|
||||
{
|
||||
return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
|
||||
(f1->mat_nr == f2->mat_nr));
|
||||
}
|
||||
|
||||
static int grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2)
|
||||
static bool grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2)
|
||||
{
|
||||
return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
|
||||
(f1->mat_nr == f2->mat_nr));
|
||||
|
@ -279,29 +275,24 @@ static int map_insert_vert(PBVH *bvh, GHash *map,
|
|||
/* Find vertices used by the faces in this node and update the draw buffers */
|
||||
static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
||||
{
|
||||
GHashIterator gh_iter;
|
||||
GHash *map;
|
||||
int i, j, totface;
|
||||
bool has_visible = false;
|
||||
int (*face_vert_indices)[4];
|
||||
int *vert_indices;
|
||||
|
||||
node->uniq_verts = node->face_verts = 0;
|
||||
totface = node->totprim;
|
||||
const int totface = node->totprim;
|
||||
|
||||
/* reserve size is rough guess */
|
||||
map = BLI_ghash_int_new_ex("build_mesh_leaf_node gh", 2 * totface);
|
||||
GHash *map = BLI_ghash_int_new_ex("build_mesh_leaf_node gh", 2 * totface);
|
||||
|
||||
face_vert_indices = MEM_callocN(sizeof(int[4]) * totface,
|
||||
"bvh node face vert indices");
|
||||
int (*face_vert_indices)[4] = MEM_callocN(sizeof(int[4]) * totface,
|
||||
"bvh node face vert indices");
|
||||
|
||||
node->face_vert_indices = (const int (*)[4])face_vert_indices;
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
for (int i = 0; i < totface; ++i) {
|
||||
const MLoopTri *lt = &bvh->looptri[node->prim_indices[i]];
|
||||
const int sides = 3;
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
for (int j = 0; j < sides; ++j) {
|
||||
face_vert_indices[i][j] =
|
||||
map_insert_vert(bvh, map, &node->face_verts,
|
||||
&node->uniq_verts, bvh->mloop[lt->tri[j]].v);
|
||||
|
@ -312,12 +303,12 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
|||
}
|
||||
}
|
||||
|
||||
vert_indices = MEM_callocN(sizeof(int) *
|
||||
(node->uniq_verts + node->face_verts),
|
||||
"bvh node vert indices");
|
||||
int *vert_indices = MEM_callocN(sizeof(int) * (node->uniq_verts + node->face_verts),
|
||||
"bvh node vert indices");
|
||||
node->vert_indices = vert_indices;
|
||||
|
||||
/* Build the vertex list, unique verts first */
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, map) {
|
||||
void *value = BLI_ghashIterator_getValue(&gh_iter);
|
||||
int ndx = GET_INT_FROM_POINTER(value);
|
||||
|
@ -329,10 +320,10 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
|||
GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
|
||||
}
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
for (int i = 0; i < totface; ++i) {
|
||||
const int sides = 3;
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
for (int j = 0; j < sides; ++j) {
|
||||
if (face_vert_indices[i][j] < 0)
|
||||
face_vert_indices[i][j] =
|
||||
-face_vert_indices[i][j] +
|
||||
|
@ -350,10 +341,8 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
|||
static void update_vb(PBVH *bvh, PBVHNode *node, BBC *prim_bbc,
|
||||
int offset, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
BB_reset(&node->vb);
|
||||
for (i = offset + count - 1; i >= offset; --i) {
|
||||
for (int i = offset + count - 1; i >= offset; --i) {
|
||||
BB_expand_with_bb(&node->vb, (BB *)(&prim_bbc[bvh->prim_indices[i]]));
|
||||
}
|
||||
node->orig_vb = node->vb;
|
||||
|
@ -364,19 +353,19 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
|
|||
int *grid_indices, int totgrid,
|
||||
int gridsize)
|
||||
{
|
||||
int gridarea = (gridsize - 1) * (gridsize - 1);
|
||||
int i, x, y, totquad;
|
||||
const int gridarea = (gridsize - 1) * (gridsize - 1);
|
||||
int totquad = 0;
|
||||
|
||||
/* grid hidden layer is present, so have to check each grid for
|
||||
* visibility */
|
||||
|
||||
for (i = 0, totquad = 0; i < totgrid; i++) {
|
||||
for (int i = 0; i < totgrid; i++) {
|
||||
const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
|
||||
|
||||
if (gh) {
|
||||
/* grid hidden are present, have to check each element */
|
||||
for (y = 0; y < gridsize - 1; y++) {
|
||||
for (x = 0; x < gridsize - 1; x++) {
|
||||
for (int y = 0; y < gridsize - 1; y++) {
|
||||
for (int x = 0; x < gridsize - 1; x++) {
|
||||
if (!paint_is_grid_face_hidden(gh, gridsize, x, y))
|
||||
totquad++;
|
||||
}
|
||||
|
@ -418,36 +407,34 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc,
|
|||
|
||||
/* Return zero if all primitives in the node can be drawn with the
|
||||
* same material (including flat/smooth shading), non-zero otherwise */
|
||||
static int leaf_needs_material_split(PBVH *bvh, int offset, int count)
|
||||
static bool leaf_needs_material_split(PBVH *bvh, int offset, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (count <= 1)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (bvh->looptri) {
|
||||
const MLoopTri *first = &bvh->looptri[bvh->prim_indices[offset]];
|
||||
const MPoly *mp = &bvh->mpoly[first->poly];
|
||||
|
||||
for (i = offset + count - 1; i > offset; --i) {
|
||||
for (int i = offset + count - 1; i > offset; --i) {
|
||||
int prim = bvh->prim_indices[i];
|
||||
const MPoly *mp_other = &bvh->mpoly[bvh->looptri[prim].poly];
|
||||
if (!face_materials_match(mp, mp_other)) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]];
|
||||
|
||||
for (i = offset + count - 1; i > offset; --i) {
|
||||
for (int i = offset + count - 1; i > offset; --i) {
|
||||
int prim = bvh->prim_indices[i];
|
||||
if (!grid_materials_match(first, &bvh->grid_flag_mats[prim]))
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,11 +452,11 @@ static int leaf_needs_material_split(PBVH *bvh, int offset, int count)
|
|||
static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
||||
int offset, int count)
|
||||
{
|
||||
int i, axis, end, below_leaf_limit;
|
||||
int end;
|
||||
BB cb_backing;
|
||||
|
||||
/* Decide whether this is a leaf or not */
|
||||
below_leaf_limit = count <= bvh->leaf_limit;
|
||||
const bool below_leaf_limit = count <= bvh->leaf_limit;
|
||||
if (below_leaf_limit) {
|
||||
if (!leaf_needs_material_split(bvh, offset, count)) {
|
||||
build_leaf(bvh, node_index, prim_bbc, offset, count);
|
||||
|
@ -489,10 +476,10 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
|||
if (!cb) {
|
||||
cb = &cb_backing;
|
||||
BB_reset(cb);
|
||||
for (i = offset + count - 1; i >= offset; --i)
|
||||
for (int i = offset + count - 1; i >= offset; --i)
|
||||
BB_expand(cb, prim_bbc[bvh->prim_indices[i]].bcentroid);
|
||||
}
|
||||
axis = BB_widest_axis(cb);
|
||||
const int axis = BB_widest_axis(cb);
|
||||
|
||||
/* Partition primitives along that axis */
|
||||
end = partition_indices(bvh->prim_indices,
|
||||
|
@ -515,15 +502,13 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
|||
|
||||
static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (totprim != bvh->totprim) {
|
||||
bvh->totprim = totprim;
|
||||
if (bvh->nodes) MEM_freeN(bvh->nodes);
|
||||
if (bvh->prim_indices) MEM_freeN(bvh->prim_indices);
|
||||
bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
|
||||
"bvh prim indices");
|
||||
for (i = 0; i < totprim; ++i)
|
||||
for (int i = 0; i < totprim; ++i)
|
||||
bvh->prim_indices[i] = i;
|
||||
bvh->totnode = 0;
|
||||
if (bvh->node_mem_count < 100) {
|
||||
|
@ -546,7 +531,6 @@ void BKE_pbvh_build_mesh(
|
|||
{
|
||||
BBC *prim_bbc = NULL;
|
||||
BB cb;
|
||||
int i, j;
|
||||
|
||||
bvh->type = PBVH_FACES;
|
||||
bvh->mpoly = mpoly;
|
||||
|
@ -563,14 +547,14 @@ void BKE_pbvh_build_mesh(
|
|||
/* For each face, store the AABB and the AABB centroid */
|
||||
prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc");
|
||||
|
||||
for (i = 0; i < looptri_num; ++i) {
|
||||
for (int i = 0; i < looptri_num; ++i) {
|
||||
const MLoopTri *lt = &looptri[i];
|
||||
const int sides = 3;
|
||||
BBC *bbc = prim_bbc + i;
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
|
||||
for (j = 0; j < sides; ++j)
|
||||
for (int j = 0; j < sides; ++j)
|
||||
BB_expand((BB *)bbc, verts[bvh->mloop[lt->tri[j]].v].co);
|
||||
|
||||
BBC_update_centroid(bbc);
|
||||
|
@ -589,10 +573,7 @@ void BKE_pbvh_build_mesh(
|
|||
void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
||||
int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
||||
{
|
||||
BBC *prim_bbc = NULL;
|
||||
BB cb;
|
||||
int gridsize = key->grid_size;
|
||||
int i, j;
|
||||
const int gridsize = key->grid_size;
|
||||
|
||||
bvh->type = PBVH_GRIDS;
|
||||
bvh->grids = grids;
|
||||
|
@ -603,18 +584,19 @@ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
|||
bvh->grid_hidden = grid_hidden;
|
||||
bvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
|
||||
|
||||
BB cb;
|
||||
BB_reset(&cb);
|
||||
|
||||
/* For each grid, store the AABB and the AABB centroid */
|
||||
prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
|
||||
BBC *prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc");
|
||||
|
||||
for (i = 0; i < totgrid; ++i) {
|
||||
for (int i = 0; i < totgrid; ++i) {
|
||||
CCGElem *grid = grids[i];
|
||||
BBC *bbc = prim_bbc + i;
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
|
||||
for (j = 0; j < gridsize * gridsize; ++j)
|
||||
for (int j = 0; j < gridsize * gridsize; ++j)
|
||||
BB_expand((BB *)bbc, CCG_elem_offset_co(key, grid, j));
|
||||
|
||||
BBC_update_centroid(bbc);
|
||||
|
@ -637,11 +619,8 @@ PBVH *BKE_pbvh_new(void)
|
|||
|
||||
void BKE_pbvh_free(PBVH *bvh)
|
||||
{
|
||||
PBVHNode *node;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bvh->totnode; ++i) {
|
||||
node = &bvh->nodes[i];
|
||||
for (int i = 0; i < bvh->totnode; ++i) {
|
||||
PBVHNode *node = &bvh->nodes[i];
|
||||
|
||||
if (node->flag & PBVH_Leaf) {
|
||||
if (node->draw_buffers)
|
||||
|
@ -684,8 +663,7 @@ void BKE_pbvh_free(PBVH *bvh)
|
|||
|
||||
void BKE_pbvh_free_layer_disp(PBVH *bvh)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < bvh->totnode; ++i)
|
||||
for (int i = 0; i < bvh->totnode; ++i)
|
||||
BKE_pbvh_node_layer_disp_free(&bvh->nodes[i]);
|
||||
}
|
||||
|
||||
|
@ -699,7 +677,7 @@ static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback s
|
|||
iter->stackspace = STACK_FIXED_DEPTH;
|
||||
|
||||
iter->stack[0].node = bvh->nodes;
|
||||
iter->stack[0].revisiting = 0;
|
||||
iter->stack[0].revisiting = false;
|
||||
iter->stacksize = 1;
|
||||
}
|
||||
|
||||
|
@ -709,7 +687,7 @@ static void pbvh_iter_end(PBVHIter *iter)
|
|||
MEM_freeN(iter->stack);
|
||||
}
|
||||
|
||||
static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
|
||||
static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting)
|
||||
{
|
||||
if (UNLIKELY(iter->stacksize == iter->stackspace)) {
|
||||
iter->stackspace *= 2;
|
||||
|
@ -730,23 +708,20 @@ static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, int revisiting)
|
|||
|
||||
static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
||||
{
|
||||
PBVHNode *node;
|
||||
int revisiting;
|
||||
|
||||
/* purpose here is to traverse tree, visiting child nodes before their
|
||||
* parents, this order is necessary for e.g. computing bounding boxes */
|
||||
|
||||
while (iter->stacksize) {
|
||||
/* pop node */
|
||||
iter->stacksize--;
|
||||
node = iter->stack[iter->stacksize].node;
|
||||
PBVHNode *node = iter->stack[iter->stacksize].node;
|
||||
|
||||
/* on a mesh with no faces this can happen
|
||||
* can remove this check if we know meshes have at least 1 face */
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
revisiting = iter->stack[iter->stacksize].revisiting;
|
||||
bool revisiting = iter->stack[iter->stacksize].revisiting;
|
||||
|
||||
/* revisiting node already checked */
|
||||
if (revisiting)
|
||||
|
@ -761,11 +736,11 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
|||
}
|
||||
else {
|
||||
/* come back later when children are done */
|
||||
pbvh_stack_push(iter, node, 1);
|
||||
pbvh_stack_push(iter, node, true);
|
||||
|
||||
/* push two child nodes on the stack */
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, false);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,12 +749,10 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
|||
|
||||
static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
||||
{
|
||||
PBVHNode *node;
|
||||
|
||||
while (iter->stacksize) {
|
||||
/* pop node */
|
||||
iter->stacksize--;
|
||||
node = iter->stack[iter->stacksize].node;
|
||||
PBVHNode *node = iter->stack[iter->stacksize].node;
|
||||
|
||||
/* on a mesh with no faces this can happen
|
||||
* can remove this check if we know meshes have at least 1 face */
|
||||
|
@ -792,8 +765,8 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
|||
return node;
|
||||
}
|
||||
else {
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, false);
|
||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,7 +930,6 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
int totnode, float (*face_nors)[3])
|
||||
{
|
||||
float (*vnor)[3];
|
||||
int n;
|
||||
|
||||
if (bvh->type == PBVH_BMESH) {
|
||||
BLI_assert(face_nors == NULL);
|
||||
|
@ -983,18 +955,17 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
*/
|
||||
|
||||
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
|
||||
for (n = 0; n < totnode; n++) {
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
if ((node->flag & PBVH_UpdateNormals)) {
|
||||
int i, j, totface, *faces;
|
||||
unsigned int mpoly_prev = UINT_MAX;
|
||||
float fn[3];
|
||||
|
||||
faces = node->prim_indices;
|
||||
totface = node->totprim;
|
||||
const int *faces = node->prim_indices;
|
||||
const int totface = node->totprim;
|
||||
|
||||
for (i = 0; i < totface; ++i) {
|
||||
for (int i = 0; i < totface; ++i) {
|
||||
const MLoopTri *lt = &bvh->looptri[faces[i]];
|
||||
const unsigned int vtri[3] = {
|
||||
bvh->mloop[lt->tri[0]].v,
|
||||
|
@ -1014,7 +985,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < sides; ++j) {
|
||||
for (int j = 0; j < sides; ++j) {
|
||||
int v = vtri[j];
|
||||
|
||||
if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
|
||||
|
@ -1033,17 +1004,14 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
}
|
||||
|
||||
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
|
||||
for (n = 0; n < totnode; n++) {
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
const int *verts;
|
||||
int i, totvert;
|
||||
const int *verts = node->vert_indices;
|
||||
const int totvert = node->uniq_verts;
|
||||
|
||||
verts = node->vert_indices;
|
||||
totvert = node->uniq_verts;
|
||||
|
||||
for (i = 0; i < totvert; ++i) {
|
||||
for (int i = 0; i < totvert; ++i) {
|
||||
const int v = verts[i];
|
||||
MVert *mvert = &bvh->verts[v];
|
||||
|
||||
|
@ -1067,11 +1035,9 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||
|
||||
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* update BB, redraw flag */
|
||||
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
|
||||
for (n = 0; n < totnode; n++) {
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
if ((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
|
||||
|
@ -1088,12 +1054,9 @@ void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
|
|||
|
||||
static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
||||
{
|
||||
PBVHNode *node;
|
||||
int n;
|
||||
|
||||
/* can't be done in parallel with OpenGL */
|
||||
for (n = 0; n < totnode; n++) {
|
||||
node = nodes[n];
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
if (node->flag & PBVH_RebuildDrawBuffers) {
|
||||
GPU_free_pbvh_buffers(node->draw_buffers);
|
||||
|
@ -1116,8 +1079,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||
break;
|
||||
case PBVH_BMESH:
|
||||
node->draw_buffers =
|
||||
GPU_build_bmesh_pbvh_buffers(bvh->flags &
|
||||
PBVH_DYNTOPO_SMOOTH_SHADING);
|
||||
GPU_build_bmesh_pbvh_buffers(bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1163,13 +1125,10 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||
|
||||
static void pbvh_draw_BB(PBVH *bvh)
|
||||
{
|
||||
PBVHNode *node;
|
||||
int a;
|
||||
|
||||
GPU_init_draw_pbvh_BB();
|
||||
|
||||
for (a = 0; a < bvh->totnode; a++) {
|
||||
node = &bvh->nodes[a];
|
||||
for (int a = 0; a < bvh->totnode; a++) {
|
||||
PBVHNode *node = &bvh->nodes[a];
|
||||
|
||||
GPU_draw_pbvh_BB(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
|
||||
}
|
||||
|
@ -1210,12 +1169,12 @@ static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
|
|||
|
||||
void BKE_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
if (!bvh->nodes)
|
||||
return;
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
|
||||
&nodes, &totnode);
|
||||
|
||||
|
@ -1251,24 +1210,18 @@ void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
|
|||
copy_v3_v3(bb_max, bb.bmax);
|
||||
}
|
||||
|
||||
void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r_totface)
|
||||
void BKE_pbvh_get_grid_updates(PBVH *bvh, bool clear, void ***r_gridfaces, int *r_totface)
|
||||
{
|
||||
PBVHIter iter;
|
||||
GSet *face_set = BLI_gset_ptr_new(__func__);
|
||||
PBVHNode *node;
|
||||
GSetIterator gs_iter;
|
||||
GSet *face_set;
|
||||
void *face, **faces;
|
||||
unsigned i;
|
||||
int tot;
|
||||
|
||||
face_set = BLI_gset_ptr_new(__func__);
|
||||
PBVHIter iter;
|
||||
|
||||
pbvh_iter_begin(&iter, bvh, NULL, NULL);
|
||||
|
||||
while ((node = pbvh_iter_next(&iter))) {
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
for (i = 0; i < node->totprim; ++i) {
|
||||
face = bvh->gridfaces[node->prim_indices[i]];
|
||||
for (unsigned i = 0; i < node->totprim; ++i) {
|
||||
void *face = bvh->gridfaces[node->prim_indices[i]];
|
||||
if (!BLI_gset_haskey(face_set, face))
|
||||
BLI_gset_insert(face_set, face);
|
||||
}
|
||||
|
@ -1280,7 +1233,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r
|
|||
|
||||
pbvh_iter_end(&iter);
|
||||
|
||||
tot = BLI_gset_size(face_set);
|
||||
const int tot = BLI_gset_size(face_set);
|
||||
if (tot == 0) {
|
||||
*r_totface = 0;
|
||||
*r_gridfaces = NULL;
|
||||
|
@ -1288,8 +1241,9 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r
|
|||
return;
|
||||
}
|
||||
|
||||
faces = MEM_mallocN(sizeof(*faces) * tot, "PBVH Grid Faces");
|
||||
void **faces = MEM_mallocN(sizeof(*faces) * tot, "PBVH Grid Faces");
|
||||
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER_INDEX (gs_iter, face_set, i) {
|
||||
faces[i] = BLI_gsetIterator_getKey(&gs_iter);
|
||||
}
|
||||
|
@ -1589,12 +1543,11 @@ static bool pbvh_grids_node_raycast(
|
|||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist)
|
||||
{
|
||||
int totgrid = node->totprim;
|
||||
int gridsize = bvh->gridkey.grid_size;
|
||||
int i, x, y;
|
||||
const int totgrid = node->totprim;
|
||||
const int gridsize = bvh->gridkey.grid_size;
|
||||
bool hit = false;
|
||||
|
||||
for (i = 0; i < totgrid; ++i) {
|
||||
for (int i = 0; i < totgrid; ++i) {
|
||||
CCGElem *grid = bvh->grids[node->prim_indices[i]];
|
||||
BLI_bitmap *gh;
|
||||
|
||||
|
@ -1603,8 +1556,8 @@ static bool pbvh_grids_node_raycast(
|
|||
|
||||
gh = bvh->grid_hidden[node->prim_indices[i]];
|
||||
|
||||
for (y = 0; y < gridsize - 1; ++y) {
|
||||
for (x = 0; x < gridsize - 1; ++x) {
|
||||
for (int y = 0; y < gridsize - 1; ++y) {
|
||||
for (int x = 0; x < gridsize - 1; ++x) {
|
||||
/* check if grid face is hidden */
|
||||
if (gh) {
|
||||
if (paint_is_grid_face_hidden(gh, gridsize, x, y))
|
||||
|
@ -1640,14 +1593,14 @@ static bool pbvh_grids_node_raycast(
|
|||
}
|
||||
|
||||
bool BKE_pbvh_node_raycast(
|
||||
PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
|
||||
PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist)
|
||||
{
|
||||
bool hit = false;
|
||||
|
||||
if (node->flag & PBVH_FullyHidden)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
switch (bvh->type) {
|
||||
case PBVH_FACES:
|
||||
|
@ -1713,9 +1666,6 @@ void BKE_pbvh_raycast_project_ray_root(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//#include "GPU_glew.h"
|
||||
|
||||
typedef struct {
|
||||
DMSetMaterial setMaterial;
|
||||
bool wireframe;
|
||||
|
@ -1728,14 +1678,14 @@ void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
|
|||
|
||||
#if 0
|
||||
/* XXX: Just some quick code to show leaf nodes in different colors */
|
||||
float col[3]; int i;
|
||||
float col[3];
|
||||
|
||||
if (0) { //is_partial) {
|
||||
col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
|
||||
}
|
||||
else {
|
||||
srand((long long)node);
|
||||
for (i = 0; i < 3; ++i)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
|
||||
}
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
||||
|
@ -1768,10 +1718,9 @@ static PlaneAABBIsect test_planes_aabb(const float bb_min[3],
|
|||
{
|
||||
float vmin[3], vmax[3];
|
||||
PlaneAABBIsect ret = ISECT_INSIDE;
|
||||
int i, axis;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (axis = 0; axis < 3; ++axis) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int axis = 0; axis < 3; ++axis) {
|
||||
if (planes[i][axis] > 0) {
|
||||
vmin[axis] = bb_min[axis];
|
||||
vmax[axis] = bb_max[axis];
|
||||
|
@ -1821,9 +1770,9 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
|
|||
{
|
||||
PBVHNodeDrawData draw_data = {setMaterial, wireframe, fast};
|
||||
PBVHNode **nodes;
|
||||
int a, totnode;
|
||||
int totnode;
|
||||
|
||||
for (a = 0; a < bvh->totnode; a++)
|
||||
for (int a = 0; a < bvh->totnode; a++)
|
||||
pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
|
||||
|
||||
BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
|
||||
|
@ -1849,8 +1798,6 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
|
|||
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
|
||||
DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
||||
{
|
||||
int a;
|
||||
|
||||
bvh->grids = grids;
|
||||
bvh->gridfaces = gridfaces;
|
||||
|
||||
|
@ -1858,7 +1805,7 @@ void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
|
|||
bvh->grid_flag_mats = flagmats;
|
||||
bvh->grid_hidden = grid_hidden;
|
||||
|
||||
for (a = 0; a < bvh->totnode; ++a)
|
||||
for (int a = 0; a < bvh->totnode; ++a)
|
||||
BKE_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
|
||||
}
|
||||
}
|
||||
|
@ -1885,17 +1832,15 @@ void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
|
|||
|
||||
float (*BKE_pbvh_get_vertCos(PBVH *pbvh))[3]
|
||||
{
|
||||
int a;
|
||||
float (*vertCos)[3] = NULL;
|
||||
|
||||
if (pbvh->verts) {
|
||||
float *co;
|
||||
MVert *mvert = pbvh->verts;
|
||||
|
||||
vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
|
||||
co = (float *)vertCos;
|
||||
float *co = (float *)vertCos;
|
||||
|
||||
for (a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
|
||||
for (int a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
|
||||
copy_v3_v3(co, mvert->co);
|
||||
}
|
||||
}
|
||||
|
@ -1905,8 +1850,6 @@ float (*BKE_pbvh_get_vertCos(PBVH *pbvh))[3]
|
|||
|
||||
void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
||||
{
|
||||
int a;
|
||||
|
||||
if (!pbvh->deformed) {
|
||||
if (pbvh->verts) {
|
||||
/* if pbvh is not already deformed, verts/faces points to the */
|
||||
|
@ -1916,14 +1859,14 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|||
pbvh->verts = MEM_dupallocN(pbvh->verts);
|
||||
pbvh->looptri = MEM_dupallocN(pbvh->looptri);
|
||||
|
||||
pbvh->deformed = 1;
|
||||
pbvh->deformed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pbvh->verts) {
|
||||
MVert *mvert = pbvh->verts;
|
||||
/* copy new verts coords */
|
||||
for (a = 0; a < pbvh->totvert; ++a, ++mvert) {
|
||||
for (int a = 0; a < pbvh->totvert; ++a, ++mvert) {
|
||||
copy_v3_v3(mvert->co, vertCos[a]);
|
||||
mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
}
|
||||
|
@ -1935,7 +1878,7 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|||
pbvh->looptri, pbvh->totprim,
|
||||
NULL);
|
||||
|
||||
for (a = 0; a < pbvh->totnode; ++a)
|
||||
for (int a = 0; a < pbvh->totnode; ++a)
|
||||
BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
|
||||
|
||||
BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
|
||||
|
@ -1956,7 +1899,6 @@ PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
|
|||
|
||||
#pragma omp critical
|
||||
{
|
||||
|
||||
index = node->proxy_count;
|
||||
|
||||
node->proxy_count++;
|
||||
|
@ -1977,9 +1919,7 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
|
|||
{
|
||||
#pragma omp critical
|
||||
{
|
||||
int p;
|
||||
|
||||
for (p = 0; p < node->proxy_count; p++) {
|
||||
for (int p = 0; p < node->proxy_count; p++) {
|
||||
MEM_freeN(node->proxies[p].co);
|
||||
node->proxies[p].co = NULL;
|
||||
}
|
||||
|
@ -1993,12 +1933,11 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
|
|||
|
||||
void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
|
||||
{
|
||||
PBVHNode **array = NULL, *node;
|
||||
PBVHNode **array = NULL;
|
||||
int tot = 0, space = 0;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < pbvh->totnode; n++) {
|
||||
node = pbvh->nodes + n;
|
||||
for (int n = 0; n < pbvh->totnode; n++) {
|
||||
PBVHNode *node = pbvh->nodes + n;
|
||||
|
||||
if (node->proxy_count > 0) {
|
||||
if (tot == space) {
|
||||
|
|
|
@ -87,17 +87,16 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index, const int cd_ver
|
|||
|
||||
GSET_ITER (gs_iter, n->bm_faces) {
|
||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
BMVert *v;
|
||||
|
||||
/* Update ownership of faces */
|
||||
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
|
||||
|
||||
/* Update vertices */
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
/* Update vertices */
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
|
||||
do {
|
||||
v = l_iter->v;
|
||||
BMVert *v = l_iter->v;
|
||||
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
||||
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
BLI_gset_add(n->bm_other_verts, v);
|
||||
|
@ -131,15 +130,9 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index, const int cd_ver
|
|||
/* Recursively split the node if it exceeds the leaf_limit */
|
||||
static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_index)
|
||||
{
|
||||
GSet *empty, *other;
|
||||
GSetIterator gs_iter;
|
||||
PBVHNode *n, *c1, *c2;
|
||||
BB cb;
|
||||
float mid;
|
||||
int axis, children;
|
||||
const int cd_vert_node_offset = bvh->cd_vert_node_offset;
|
||||
const int cd_face_node_offset = bvh->cd_face_node_offset;
|
||||
n = &bvh->nodes[node_index];
|
||||
PBVHNode *n = &bvh->nodes[node_index];
|
||||
|
||||
if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) {
|
||||
/* Node limit not exceeded */
|
||||
|
@ -148,7 +141,9 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
}
|
||||
|
||||
/* Calculate bounding box around primitive centroids */
|
||||
BB cb;
|
||||
BB_reset(&cb);
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER (gs_iter, n->bm_faces) {
|
||||
const BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
|
@ -157,11 +152,11 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
}
|
||||
|
||||
/* Find widest axis and its midpoint */
|
||||
axis = BB_widest_axis(&cb);
|
||||
mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
||||
const int axis = BB_widest_axis(&cb);
|
||||
const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
||||
|
||||
/* Add two new child nodes */
|
||||
children = bvh->totnode;
|
||||
const int children = bvh->totnode;
|
||||
n->children_offset = children;
|
||||
pbvh_grow_nodes(bvh, bvh->totnode + 2);
|
||||
|
||||
|
@ -169,8 +164,8 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
n = &bvh->nodes[node_index];
|
||||
|
||||
/* Initialize children */
|
||||
c1 = &bvh->nodes[children];
|
||||
c2 = &bvh->nodes[children + 1];
|
||||
PBVHNode *c1 = &bvh->nodes[children],
|
||||
*c2 = &bvh->nodes[children + 1];
|
||||
c1->flag |= PBVH_Leaf;
|
||||
c2->flag |= PBVH_Leaf;
|
||||
c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
|
||||
|
@ -188,7 +183,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
}
|
||||
|
||||
/* Enforce at least one primitive in each node */
|
||||
empty = NULL;
|
||||
GSet *empty = NULL, *other;
|
||||
if (BLI_gset_size(c1->bm_faces) == 0) {
|
||||
empty = c1->bm_faces;
|
||||
other = c2->bm_faces;
|
||||
|
@ -242,7 +237,6 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
n->flag &= ~PBVH_Leaf;
|
||||
|
||||
/* Recurse */
|
||||
c1 = c2 = NULL;
|
||||
pbvh_bmesh_node_split(bvh, bbc_array, children);
|
||||
pbvh_bmesh_node_split(bvh, bbc_array, children + 1);
|
||||
|
||||
|
@ -259,30 +253,24 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
|
|||
/* Recursively split the node if it exceeds the leaf_limit */
|
||||
static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
|
||||
{
|
||||
GSet *bm_faces;
|
||||
int bm_faces_size;
|
||||
GSetIterator gs_iter;
|
||||
BBC *bbc_array;
|
||||
unsigned int i;
|
||||
|
||||
bm_faces = bvh->nodes[node_index].bm_faces;
|
||||
bm_faces_size = BLI_gset_size(bm_faces);
|
||||
GSet *bm_faces = bvh->nodes[node_index].bm_faces;
|
||||
const int bm_faces_size = BLI_gset_size(bm_faces);
|
||||
if (bm_faces_size <= bvh->leaf_limit) {
|
||||
/* Node limit not exceeded */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* For each BMFace, store the AABB and AABB centroid */
|
||||
bbc_array = MEM_mallocN(sizeof(BBC) * bm_faces_size, "BBC");
|
||||
BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm_faces_size, "BBC");
|
||||
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER_INDEX (gs_iter, bm_faces, i) {
|
||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
BBC *bbc = &bbc_array[i];
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
do {
|
||||
BB_expand((BB *)bbc, l_iter->v->co);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
@ -347,12 +335,11 @@ static BMVert *pbvh_bmesh_vert_create(
|
|||
const int cd_vert_mask_offset)
|
||||
{
|
||||
PBVHNode *node = &bvh->nodes[node_index];
|
||||
BMVert *v;
|
||||
|
||||
BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
|
||||
|
||||
/* avoid initializing customdata because its quite involved */
|
||||
v = BM_vert_create(bvh->bm, co, NULL, BM_CREATE_SKIP_CD);
|
||||
BMVert *v = BM_vert_create(bvh->bm, co, NULL, BM_CREATE_SKIP_CD);
|
||||
CustomData_bmesh_set_default(&bvh->bm->vdata, &v->head.data);
|
||||
|
||||
/* This value is logged below */
|
||||
|
@ -374,13 +361,12 @@ static BMFace *pbvh_bmesh_face_create(
|
|||
BMVert *v_tri[3], BMEdge *e_tri[3],
|
||||
const BMFace *f_example)
|
||||
{
|
||||
BMFace *f;
|
||||
PBVHNode *node = &bvh->nodes[node_index];
|
||||
|
||||
/* ensure we never add existing face */
|
||||
BLI_assert(BM_face_exists(v_tri, 3, NULL) == false);
|
||||
|
||||
f = BM_face_create(bvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NO_DOUBLE);
|
||||
BMFace *f = BM_face_create(bvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NO_DOUBLE);
|
||||
f->head.hflag = f_example->head.hflag;
|
||||
|
||||
BLI_gset_insert(node->bm_faces, f);
|
||||
|
@ -442,14 +428,10 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
|
|||
{
|
||||
BMIter bm_iter;
|
||||
BMFace *f;
|
||||
PBVHNode *current_node;
|
||||
|
||||
current_node = pbvh_bmesh_node_lookup(bvh, v);
|
||||
PBVHNode *current_node = pbvh_bmesh_node_lookup(bvh, v);
|
||||
|
||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||
PBVHNode *f_node;
|
||||
|
||||
f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||
PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||
|
||||
if (f_node != current_node)
|
||||
return f_node;
|
||||
|
@ -462,13 +444,10 @@ static void pbvh_bmesh_vert_ownership_transfer(
|
|||
PBVH *bvh, PBVHNode *new_owner,
|
||||
BMVert *v)
|
||||
{
|
||||
PBVHNode *current_owner;
|
||||
|
||||
current_owner = pbvh_bmesh_node_lookup(bvh, v);
|
||||
PBVHNode *current_owner = pbvh_bmesh_node_lookup(bvh, v);
|
||||
/* mark node for update */
|
||||
current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
|
||||
|
||||
|
||||
BLI_assert(current_owner != new_owner);
|
||||
|
||||
/* Remove current ownership */
|
||||
|
@ -486,21 +465,18 @@ static void pbvh_bmesh_vert_ownership_transfer(
|
|||
|
||||
static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
||||
{
|
||||
PBVHNode *v_node;
|
||||
BMIter bm_iter;
|
||||
BMFace *f;
|
||||
|
||||
/* never match for first time */
|
||||
int f_node_index_prev = DYNTOPO_NODE_NONE;
|
||||
|
||||
v_node = pbvh_bmesh_node_lookup(bvh, v);
|
||||
PBVHNode *v_node = pbvh_bmesh_node_lookup(bvh, v);
|
||||
BLI_gset_remove(v_node->bm_unique_verts, v, NULL);
|
||||
BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
|
||||
/* Have to check each neighboring face's node */
|
||||
BMIter bm_iter;
|
||||
BMFace *f;
|
||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||
const int f_node_index = pbvh_bmesh_node_lookup_index(bvh, f);
|
||||
PBVHNode *f_node;
|
||||
|
||||
/* faces often share the same node,
|
||||
* quick check to avoid redundant #BLI_gset_remove calls */
|
||||
|
@ -508,7 +484,7 @@ static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
|||
continue;
|
||||
f_node_index_prev = f_node_index;
|
||||
|
||||
f_node = &bvh->nodes[f_node_index];
|
||||
PBVHNode *f_node = &bvh->nodes[f_node_index];
|
||||
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
|
||||
|
||||
/* Remove current ownership */
|
||||
|
@ -521,19 +497,14 @@ static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
|||
|
||||
static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
|
||||
{
|
||||
PBVHNode *f_node;
|
||||
BMVert *v;
|
||||
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||
PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||
|
||||
/* Check if any of this face's vertices need to be removed
|
||||
* from the node */
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
do {
|
||||
v = l_iter->v;
|
||||
BMVert *v = l_iter->v;
|
||||
if (pbvh_bmesh_node_vert_use_count_is_equal(bvh, f_node, v, 1)) {
|
||||
if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
|
||||
/* Find a different node that uses 'v' */
|
||||
|
@ -630,12 +601,10 @@ typedef struct {
|
|||
* (it's a requirement that edges enter and leave a clean tag state) */
|
||||
static void pbvh_bmesh_edge_tag_verify(PBVH *bvh)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < bvh->totnode; n++) {
|
||||
for (int n = 0; n < bvh->totnode; n++) {
|
||||
PBVHNode *node = &bvh->nodes[n];
|
||||
GSetIterator gs_iter;
|
||||
if (node->bm_faces) {
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER (gs_iter, node->bm_faces) {
|
||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
BMEdge *e_tri[3];
|
||||
|
@ -668,21 +637,19 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
|
|||
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 */
|
||||
return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
|
||||
return len_squared_v3v3(q->center, 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)
|
||||
{
|
||||
return (BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f);
|
||||
return BM_ELEM_CD_GET_FLOAT(v, eq_ctx->cd_vert_mask_offset) < 1.0f;
|
||||
}
|
||||
|
||||
static void edge_queue_insert(
|
||||
EdgeQueueContext *eq_ctx, BMEdge *e,
|
||||
float priority)
|
||||
{
|
||||
BMVert **pair;
|
||||
|
||||
/* Don't let topology update affect fully masked vertices. This used to
|
||||
* have a 50% mask cutoff, with the reasoning that you can't do a 50%
|
||||
* topology update. But this gives an ugly border in the mesh. The mask
|
||||
|
@ -694,7 +661,7 @@ static void edge_queue_insert(
|
|||
!(BM_elem_flag_test_bool(e->v1, BM_ELEM_HIDDEN) ||
|
||||
BM_elem_flag_test_bool(e->v2, BM_ELEM_HIDDEN)))
|
||||
{
|
||||
pair = BLI_mempool_alloc(eq_ctx->pool);
|
||||
BMVert **pair = BLI_mempool_alloc(eq_ctx->pool);
|
||||
pair[0] = e->v1;
|
||||
pair[1] = e->v2;
|
||||
BLI_heap_insert(eq_ctx->q->heap, priority, pair);
|
||||
|
@ -757,19 +724,15 @@ static void long_edge_queue_edge_add_recursive(
|
|||
#define EVEN_GENERATION_SCALE 1.6f
|
||||
|
||||
const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
|
||||
float limit_len_sq;
|
||||
BMLoop *l_iter;
|
||||
|
||||
limit_len *= EVEN_GENERATION_SCALE;
|
||||
limit_len_sq = SQUARE(limit_len);
|
||||
const float limit_len_sq = SQUARE(limit_len);
|
||||
|
||||
l_iter = l_edge;
|
||||
BMLoop *l_iter = l_edge;
|
||||
do {
|
||||
float len_sq_other;
|
||||
BMLoop *l_adjacent[2] = {l_iter->next, l_iter->prev};
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
|
||||
len_sq_other = BM_edge_calc_length_squared(l_adjacent[i]->e);
|
||||
for (int i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
|
||||
float len_sq_other = BM_edge_calc_length_squared(l_adjacent[i]->e);
|
||||
if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
|
||||
// edge_queue_insert(eq_ctx, l_adjacent[i]->e, -len_sq_other);
|
||||
long_edge_queue_edge_add_recursive(
|
||||
|
@ -813,24 +776,20 @@ static void long_edge_queue_face_add(
|
|||
#endif
|
||||
|
||||
if (edge_queue_tri_in_sphere(eq_ctx->q, f)) {
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
/* Check each edge of the face */
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
do {
|
||||
{
|
||||
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
|
||||
const float len_sq = BM_edge_calc_length_squared(l_iter->e);
|
||||
if (len_sq > eq_ctx->q->limit_len_squared) {
|
||||
long_edge_queue_edge_add_recursive(
|
||||
eq_ctx, l_iter->radial_next, l_iter,
|
||||
len_sq, eq_ctx->q->limit_len);
|
||||
}
|
||||
#else
|
||||
long_edge_queue_edge_add(eq_ctx, l_iter->e);
|
||||
#endif
|
||||
const float len_sq = BM_edge_calc_length_squared(l_iter->e);
|
||||
if (len_sq > eq_ctx->q->limit_len_squared) {
|
||||
long_edge_queue_edge_add_recursive(
|
||||
eq_ctx, l_iter->radial_next, l_iter,
|
||||
len_sq, eq_ctx->q->limit_len);
|
||||
}
|
||||
#else
|
||||
long_edge_queue_edge_add(eq_ctx, l_iter->e);
|
||||
#endif
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
}
|
||||
}
|
||||
|
@ -873,8 +832,6 @@ static void long_edge_queue_create(
|
|||
PBVH *bvh, const float center[3], const float view_normal[3],
|
||||
float radius)
|
||||
{
|
||||
int n;
|
||||
|
||||
eq_ctx->q->heap = BLI_heap_new();
|
||||
eq_ctx->q->center = center;
|
||||
eq_ctx->q->radius_squared = radius * radius;
|
||||
|
@ -894,8 +851,7 @@ static void long_edge_queue_create(
|
|||
pbvh_bmesh_edge_tag_verify(bvh);
|
||||
#endif
|
||||
|
||||
|
||||
for (n = 0; n < bvh->totnode; n++) {
|
||||
for (int n = 0; n < bvh->totnode; n++) {
|
||||
PBVHNode *node = &bvh->nodes[n];
|
||||
|
||||
/* Check leaf nodes marked for topology update */
|
||||
|
@ -929,8 +885,6 @@ static void short_edge_queue_create(
|
|||
PBVH *bvh, const float center[3], const float view_normal[3],
|
||||
float radius)
|
||||
{
|
||||
int n;
|
||||
|
||||
eq_ctx->q->heap = BLI_heap_new();
|
||||
eq_ctx->q->center = center;
|
||||
eq_ctx->q->radius_squared = radius * radius;
|
||||
|
@ -946,7 +900,7 @@ static void short_edge_queue_create(
|
|||
UNUSED_VARS(view_normal);
|
||||
#endif
|
||||
|
||||
for (n = 0; n < bvh->totnode; n++) {
|
||||
for (int n = 0; n < bvh->totnode; n++) {
|
||||
PBVHNode *node = &bvh->nodes[n];
|
||||
|
||||
/* Check leaf nodes marked for topology update */
|
||||
|
@ -979,9 +933,7 @@ static void pbvh_bmesh_split_edge(
|
|||
EdgeQueueContext *eq_ctx, PBVH *bvh,
|
||||
BMEdge *e, BLI_Buffer *edge_loops)
|
||||
{
|
||||
BMVert *v_new;
|
||||
float co_mid[3], no_mid[3];
|
||||
int i, node_index;
|
||||
|
||||
/* Get all faces adjacent to the edge */
|
||||
pbvh_bmesh_edge_loops(edge_loops, e);
|
||||
|
@ -991,8 +943,8 @@ static void pbvh_bmesh_split_edge(
|
|||
mid_v3_v3v3(no_mid, e->v1->no, e->v2->no);
|
||||
normalize_v3(no_mid);
|
||||
|
||||
node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
|
||||
v_new = pbvh_bmesh_vert_create(bvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
|
||||
int node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
|
||||
BMVert *v_new = pbvh_bmesh_vert_create(bvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
|
||||
|
||||
/* update paint mask */
|
||||
if (eq_ctx->cd_vert_mask_offset != -1) {
|
||||
|
@ -1004,17 +956,16 @@ static void pbvh_bmesh_split_edge(
|
|||
}
|
||||
|
||||
/* For each face, add two new triangles and delete the original */
|
||||
for (i = 0; i < edge_loops->count; i++) {
|
||||
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;
|
||||
BMVert *v_tri[3];
|
||||
BMEdge *e_tri[3];
|
||||
int ni;
|
||||
|
||||
BLI_assert(f_adj->len == 3);
|
||||
ni = BM_ELEM_CD_GET_INT(f_adj, eq_ctx->cd_face_node_offset);
|
||||
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;
|
||||
|
@ -1153,11 +1104,7 @@ static void pbvh_bmesh_collapse_edge(
|
|||
BLI_Buffer *deleted_faces,
|
||||
EdgeQueueContext *eq_ctx)
|
||||
{
|
||||
BMIter bm_iter;
|
||||
BMFace *f;
|
||||
BMLoop *l_adj;
|
||||
BMVert *v_del, *v_conn;
|
||||
int i;
|
||||
float mask_v1 = BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset);
|
||||
|
||||
/* one of the two vertices may be masked, select the correct one for deletion */
|
||||
|
@ -1174,6 +1121,7 @@ static void pbvh_bmesh_collapse_edge(
|
|||
pbvh_bmesh_vert_remove(bvh, v_del);
|
||||
|
||||
/* Remove all faces adjacent to the edge */
|
||||
BMLoop *l_adj;
|
||||
while ((l_adj = e->l)) {
|
||||
BMFace *f_adj = l_adj->f;
|
||||
|
||||
|
@ -1192,16 +1140,17 @@ static void pbvh_bmesh_collapse_edge(
|
|||
* really buy anything. */
|
||||
BLI_buffer_empty(deleted_faces);
|
||||
|
||||
BMIter bm_iter;
|
||||
BMFace *f;
|
||||
|
||||
BM_ITER_ELEM (f, &bm_iter, v_del, BM_FACES_OF_VERT) {
|
||||
BMVert *v_tri[3];
|
||||
BMFace *existing_face;
|
||||
PBVHNode *n;
|
||||
int ni;
|
||||
|
||||
/* Get vertices, replace use of v_del with v_conn */
|
||||
// BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
|
||||
BM_face_as_array_vert_tri(f, v_tri);
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (v_tri[i] == v_del) {
|
||||
v_tri[i] = v_conn;
|
||||
}
|
||||
|
@ -1217,8 +1166,8 @@ static void pbvh_bmesh_collapse_edge(
|
|||
}
|
||||
else {
|
||||
BMEdge *e_tri[3];
|
||||
n = pbvh_bmesh_node_lookup(bvh, f);
|
||||
ni = n - bvh->nodes;
|
||||
PBVHNode *n = pbvh_bmesh_node_lookup(bvh, f);
|
||||
int ni = n - bvh->nodes;
|
||||
bm_edges_from_tri(bvh->bm, v_tri, e_tri);
|
||||
pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f);
|
||||
|
||||
|
@ -1232,16 +1181,14 @@ static void pbvh_bmesh_collapse_edge(
|
|||
}
|
||||
|
||||
/* Delete the tagged faces */
|
||||
for (i = 0; i < deleted_faces->count; i++) {
|
||||
for (int i = 0; i < deleted_faces->count; i++) {
|
||||
BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
|
||||
BMLoop *l_iter;
|
||||
BMVert *v_tri[3];
|
||||
BMEdge *e_tri[3];
|
||||
int j;
|
||||
|
||||
/* Get vertices and edges of face */
|
||||
BLI_assert(f_del->len == 3);
|
||||
l_iter = BM_FACE_FIRST_LOOP(f_del);
|
||||
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;
|
||||
|
@ -1252,14 +1199,14 @@ static void pbvh_bmesh_collapse_edge(
|
|||
|
||||
/* Check if any of the face's edges are now unused by any
|
||||
* face, if so delete them */
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (BM_edge_is_wire(e_tri[j]))
|
||||
BM_edge_kill(bvh->bm, e_tri[j]);
|
||||
}
|
||||
|
||||
/* Check if any of the face's vertices are now unused, if so
|
||||
* remove them from the PBVH */
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if ((v_tri[j] != v_del) && (v_tri[j]->e == NULL)) {
|
||||
BLI_gset_insert(deleted_verts, v_tri[j]);
|
||||
pbvh_bmesh_vert_remove(bvh, v_tri[j]);
|
||||
|
@ -1291,18 +1238,14 @@ static bool pbvh_bmesh_collapse_short_edges(
|
|||
PBVH *bvh,
|
||||
BLI_Buffer *deleted_faces)
|
||||
{
|
||||
float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
|
||||
GSet *deleted_verts;
|
||||
const float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
|
||||
bool any_collapsed = false;
|
||||
|
||||
deleted_verts = BLI_gset_ptr_new("deleted_verts");
|
||||
GSet *deleted_verts = BLI_gset_ptr_new("deleted_verts");
|
||||
|
||||
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
|
||||
BMVert **pair = BLI_heap_popmin(eq_ctx->q->heap);
|
||||
BMVert *v1 = pair[0], *v2 = pair[1];
|
||||
BMEdge *e;
|
||||
|
||||
BLI_mempool_free(eq_ctx->pool, pair);
|
||||
BMVert *v1 = pair[0], *v2 = pair[1];
|
||||
pair = NULL;
|
||||
|
||||
/* Check the verts still exist */
|
||||
|
@ -1313,6 +1256,7 @@ static bool pbvh_bmesh_collapse_short_edges(
|
|||
}
|
||||
|
||||
/* Check that the edge still exists */
|
||||
BMEdge *e;
|
||||
if (!(e = BM_edge_exists(v1, v2))) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1355,8 +1299,7 @@ bool pbvh_bmesh_node_raycast(
|
|||
bool hit = false;
|
||||
|
||||
if (use_original && node->bm_tot_ortri) {
|
||||
int i;
|
||||
for (i = 0; i < node->bm_tot_ortri; i++) {
|
||||
for (int i = 0; i < node->bm_tot_ortri; i++) {
|
||||
const int *t = node->bm_ortri[i];
|
||||
hit |= ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
|
@ -1395,13 +1338,13 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
|||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist, float *r_detail)
|
||||
{
|
||||
if (node->flag & PBVH_FullyHidden)
|
||||
return 0;
|
||||
|
||||
GSetIterator gs_iter;
|
||||
bool hit = false;
|
||||
BMFace *f_hit = NULL;
|
||||
|
||||
if (node->flag & PBVH_FullyHidden)
|
||||
return 0;
|
||||
|
||||
GSET_ITER (gs_iter, node->bm_faces) {
|
||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
|
||||
|
@ -1425,12 +1368,11 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
|||
}
|
||||
|
||||
if (hit) {
|
||||
float len1, len2, len3;
|
||||
BMVert *v_tri[3];
|
||||
BM_face_as_array_vert_tri(f_hit, v_tri);
|
||||
len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
|
||||
len2 = len_squared_v3v3(v_tri[1]->co, v_tri[2]->co);
|
||||
len3 = len_squared_v3v3(v_tri[2]->co, v_tri[0]->co);
|
||||
float len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
|
||||
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 */
|
||||
*r_detail = sqrtf(max_fff(len1, len2, len3));
|
||||
|
@ -1442,9 +1384,7 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
|||
|
||||
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < totnode; n++) {
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
|
@ -1476,25 +1416,18 @@ typedef struct FastNodeBuildInfo {
|
|||
* to a sub part of the arrays */
|
||||
static void pbvh_bmesh_node_limit_ensure_fast(PBVH *bvh, BMFace **nodeinfo, BBC *bbc_array, FastNodeBuildInfo *node, MemArena *arena)
|
||||
{
|
||||
BMFace *f;
|
||||
BB cb;
|
||||
BBC *bbc;
|
||||
float mid;
|
||||
int axis, i;
|
||||
int end;
|
||||
FastNodeBuildInfo *child1, *child2;
|
||||
int num_child1, num_child2;
|
||||
BMFace *tmp;
|
||||
|
||||
if (node->totface <= bvh->leaf_limit) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate bounding box around primitive centroids */
|
||||
BB cb;
|
||||
BB_reset(&cb);
|
||||
for (i = 0; i < node->totface; i++) {
|
||||
f = nodeinfo[i + node->start];
|
||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
for (int i = 0; i < node->totface; i++) {
|
||||
BMFace *f = nodeinfo[i + node->start];
|
||||
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
|
||||
BB_expand(&cb, bbc->bcentroid);
|
||||
}
|
||||
|
@ -1502,16 +1435,16 @@ static void pbvh_bmesh_node_limit_ensure_fast(PBVH *bvh, BMFace **nodeinfo, BBC
|
|||
/* initialize the children */
|
||||
|
||||
/* Find widest axis and its midpoint */
|
||||
axis = BB_widest_axis(&cb);
|
||||
mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
||||
const int axis = BB_widest_axis(&cb);
|
||||
const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
||||
|
||||
num_child1 = 0, num_child2 = 0;
|
||||
int num_child1 = 0, num_child2 = 0;
|
||||
|
||||
/* split vertices along the middle line */
|
||||
end = node->start + node->totface;
|
||||
for (i = node->start; i < end - num_child2; i++) {
|
||||
f = nodeinfo[i];
|
||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
const int end = node->start + node->totface;
|
||||
for (int i = node->start; i < end - num_child2; i++) {
|
||||
BMFace *f = nodeinfo[i];
|
||||
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
|
||||
if (bbc->bcentroid[axis] > mid) {
|
||||
int i_iter = end - num_child2 - 1;
|
||||
|
@ -1531,7 +1464,7 @@ static void pbvh_bmesh_node_limit_ensure_fast(PBVH *bvh, BMFace **nodeinfo, BBC
|
|||
}
|
||||
|
||||
if (candidate != -1) {
|
||||
tmp = nodeinfo[i];
|
||||
BMFace *tmp = nodeinfo[i];
|
||||
nodeinfo[i] = nodeinfo[candidate];
|
||||
nodeinfo[candidate] = tmp;
|
||||
/* increase both counts */
|
||||
|
@ -1574,8 +1507,6 @@ static void pbvh_bmesh_node_limit_ensure_fast(PBVH *bvh, BMFace **nodeinfo, BBC
|
|||
|
||||
pbvh_bmesh_node_limit_ensure_fast(bvh, nodeinfo, bbc_array, child1, arena);
|
||||
pbvh_bmesh_node_limit_ensure_fast(bvh, nodeinfo, bbc_array, child2, arena);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *bvh, BMFace **nodeinfo, BBC *bbc_array, FastNodeBuildInfo *node, int node_index)
|
||||
|
@ -1605,12 +1536,6 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *bvh, BMFace **nodeinfo,
|
|||
const int cd_face_node_offset = bvh->cd_face_node_offset;
|
||||
|
||||
bool has_visible = false;
|
||||
int i, end;
|
||||
BMFace *f;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
BMVert *v;
|
||||
BBC *bbc;
|
||||
|
||||
n->flag = PBVH_Leaf;
|
||||
n->bm_faces = BLI_gset_ptr_new_ex("bm_faces", node->totface);
|
||||
|
@ -1621,20 +1546,21 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *bvh, BMFace **nodeinfo,
|
|||
|
||||
BB_reset(&n->vb);
|
||||
|
||||
end = node->start + node->totface;
|
||||
const int end = node->start + node->totface;
|
||||
|
||||
for (i = node->start; i < end; i++) {
|
||||
f = nodeinfo[i];
|
||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
for (int i = node->start; i < end; i++) {
|
||||
BMFace *f = nodeinfo[i];
|
||||
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
|
||||
/* 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 */
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
do {
|
||||
v = l_iter->v;
|
||||
BMVert *v = l_iter->v;
|
||||
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
||||
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
BLI_gset_add(n->bm_other_verts, v);
|
||||
|
@ -1654,8 +1580,8 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *bvh, BMFace **nodeinfo,
|
|||
}
|
||||
|
||||
BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
|
||||
n->vb.bmin[1] <= n->vb.bmax[1] &&
|
||||
n->vb.bmin[2] <= n->vb.bmax[2]);
|
||||
n->vb.bmin[1] <= n->vb.bmax[1] &&
|
||||
n->vb.bmin[2] <= n->vb.bmax[2]);
|
||||
|
||||
n->orig_vb = n->vb;
|
||||
|
||||
|
@ -1675,16 +1601,6 @@ void BKE_pbvh_build_bmesh(
|
|||
PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log,
|
||||
const int cd_vert_node_offset, const int cd_face_node_offset)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
BMVert *v;
|
||||
int i;
|
||||
/* bounding box array of all faces, no need to recalculate every time */
|
||||
BBC *bbc_array;
|
||||
BMFace **nodeinfo;
|
||||
FastNodeBuildInfo rootnode = {0};
|
||||
MemArena *arena;
|
||||
|
||||
bvh->cd_vert_node_offset = cd_vert_node_offset;
|
||||
bvh->cd_face_node_offset = cd_face_node_offset;
|
||||
bvh->bm = bm;
|
||||
|
@ -1700,18 +1616,20 @@ void BKE_pbvh_build_bmesh(
|
|||
if (smooth_shading)
|
||||
bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
|
||||
|
||||
/* calculate all bounding boxes once for all faces */
|
||||
bbc_array = MEM_mallocN(sizeof(BBC) * bm->totface, "BBC");
|
||||
nodeinfo = MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo");
|
||||
arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast PBVH node storage");
|
||||
/* bounding box array of all faces, no need to recalculate every time */
|
||||
BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm->totface, "BBC");
|
||||
BMFace **nodeinfo = MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo");
|
||||
MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast PBVH node storage");
|
||||
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX(f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
BBC *bbc = &bbc_array[i];
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
BB_expand((BB *)bbc, l_iter->v->co);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
@ -1723,6 +1641,7 @@ void BKE_pbvh_build_bmesh(
|
|||
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
|
||||
}
|
||||
|
||||
BMVert *v;
|
||||
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||
}
|
||||
|
@ -1731,6 +1650,7 @@ void BKE_pbvh_build_bmesh(
|
|||
bm->elem_index_dirty |= BM_FACE;
|
||||
|
||||
/* setup root node */
|
||||
FastNodeBuildInfo rootnode = {0};
|
||||
rootnode.totface = bm->totface;
|
||||
|
||||
/* start recursion, assign faces to nodes accordingly */
|
||||
|
@ -1764,7 +1684,6 @@ bool BKE_pbvh_bmesh_update_topology(
|
|||
const int cd_face_node_offset = bvh->cd_face_node_offset;
|
||||
|
||||
bool modified = false;
|
||||
int n;
|
||||
|
||||
if (view_normal) {
|
||||
BLI_assert(len_squared_v3(view_normal) != 0.0f);
|
||||
|
@ -1796,7 +1715,7 @@ bool BKE_pbvh_bmesh_update_topology(
|
|||
}
|
||||
|
||||
/* Unmark nodes */
|
||||
for (n = 0; n < bvh->totnode; n++) {
|
||||
for (int n = 0; n < bvh->totnode; n++) {
|
||||
PBVHNode *node = &bvh->nodes[n];
|
||||
|
||||
if (node->flag & PBVH_Leaf &&
|
||||
|
@ -1832,23 +1751,21 @@ BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
|
|||
* Skips triangles that are hidden. */
|
||||
void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
|
||||
{
|
||||
GSetIterator gs_iter;
|
||||
int i, totvert, tottri;
|
||||
|
||||
/* Skip if original coords/triangles are already saved */
|
||||
if (node->bm_orco)
|
||||
return;
|
||||
|
||||
totvert = (BLI_gset_size(node->bm_unique_verts) +
|
||||
BLI_gset_size(node->bm_other_verts));
|
||||
const int totvert = BLI_gset_size(node->bm_unique_verts) +
|
||||
BLI_gset_size(node->bm_other_verts);
|
||||
|
||||
tottri = BLI_gset_size(node->bm_faces);
|
||||
const int tottri = BLI_gset_size(node->bm_faces);
|
||||
|
||||
node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
|
||||
node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
|
||||
|
||||
/* Copy out the vertices and assign a temporary index */
|
||||
i = 0;
|
||||
int i = 0;
|
||||
GSetIterator gs_iter;
|
||||
GSET_ITER (gs_iter, node->bm_unique_verts) {
|
||||
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
|
||||
copy_v3_v3(node->bm_orco[i], v->co);
|
||||
|
@ -1888,9 +1805,7 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
|
|||
|
||||
void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bvh->totnode; i++) {
|
||||
for (int i = 0; i < bvh->totnode; i++) {
|
||||
PBVHNode *n = &bvh->nodes[i];
|
||||
if (n->flag & PBVH_Leaf) {
|
||||
/* Free orco/ortri data */
|
||||
|
@ -1935,15 +1850,11 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node)
|
|||
|
||||
static void pbvh_bmesh_print(PBVH *bvh)
|
||||
{
|
||||
GSetIterator gs_iter;
|
||||
int n;
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
BMVert *v;
|
||||
|
||||
fprintf(stderr, "\npbvh=%p\n", bvh);
|
||||
fprintf(stderr, "bm_face_to_node:\n");
|
||||
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||
fprintf(stderr, " %d -> %d\n",
|
||||
BM_elem_index_get(v),
|
||||
|
@ -1951,17 +1862,19 @@ static void pbvh_bmesh_print(PBVH *bvh)
|
|||
}
|
||||
|
||||
fprintf(stderr, "bm_vert_to_node:\n");
|
||||
BMVert *v;
|
||||
BM_ITER_MESH(v, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||
fprintf(stderr, " %d -> %d\n",
|
||||
BM_elem_index_get(v),
|
||||
pbvh_bmesh_node_lookup_index(bvh, v));
|
||||
}
|
||||
|
||||
for (n = 0; n < bvh->totnode; n++) {
|
||||
for (int n = 0; n < bvh->totnode; n++) {
|
||||
PBVHNode *node = &bvh->nodes[n];
|
||||
if (!(node->flag & PBVH_Leaf))
|
||||
continue;
|
||||
|
||||
GSetIterator gs_iter;
|
||||
fprintf(stderr, "node %d\n faces:\n", n);
|
||||
GSET_ITER (gs_iter, node->bm_faces)
|
||||
fprintf(stderr, " %d\n",
|
||||
|
@ -1979,9 +1892,8 @@ static void pbvh_bmesh_print(PBVH *bvh)
|
|||
|
||||
static void print_flag_factors(int flag)
|
||||
{
|
||||
int i;
|
||||
printf("flag=0x%x:\n", flag);
|
||||
for (i = 0; i < 32; i++) {
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (flag & (1 << i)) {
|
||||
printf(" %d (1 << %d)\n", 1 << i, i);
|
||||
}
|
||||
|
@ -1994,23 +1906,16 @@ static void print_flag_factors(int flag)
|
|||
|
||||
static void pbvh_bmesh_verify(PBVH *bvh)
|
||||
{
|
||||
GSetIterator gs_iter;
|
||||
int i;
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
BMVert *v;
|
||||
|
||||
GSet *faces_all;
|
||||
GSet *verts_all;
|
||||
|
||||
|
||||
/* build list of faces & verts to lookup */
|
||||
faces_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totface);
|
||||
verts_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totvert);
|
||||
|
||||
GSet *faces_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totface);
|
||||
BMFace *f;
|
||||
BMIter iter;
|
||||
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||
BLI_gset_insert(faces_all, f);
|
||||
}
|
||||
|
||||
GSet *verts_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totvert);
|
||||
BMVert *v;
|
||||
BM_ITER_MESH(v, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
BLI_gset_insert(verts_all, v);
|
||||
|
@ -2020,7 +1925,7 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
/* Check vert/face counts */
|
||||
{
|
||||
int totface = 0, totvert = 0;
|
||||
for (i = 0; i < bvh->totnode; i++) {
|
||||
for (int i = 0; i < bvh->totnode; i++) {
|
||||
PBVHNode *n = &bvh->nodes[i];
|
||||
totface += n->bm_faces ? BLI_gset_size(n->bm_faces) : 0;
|
||||
totvert += n->bm_unique_verts ? BLI_gset_size(n->bm_unique_verts) : 0;
|
||||
|
@ -2062,16 +1967,12 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
|
||||
/* Check verts */
|
||||
BM_ITER_MESH(v, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
||||
BMIter bm_iter;
|
||||
PBVHNode *n;
|
||||
bool found;
|
||||
|
||||
/* vertex isn't tracked */
|
||||
if (BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
n = pbvh_bmesh_node_lookup(bvh, v);
|
||||
PBVHNode *n = pbvh_bmesh_node_lookup(bvh, v);
|
||||
|
||||
/* Check that the vert's node is a leaf */
|
||||
BLI_assert(n->flag & PBVH_Leaf);
|
||||
|
@ -2084,6 +1985,8 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
|
||||
/* Check that the vert's node also contains one of the vert's
|
||||
* adjacent faces */
|
||||
bool found = false;
|
||||
BMIter bm_iter;
|
||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||
if (pbvh_bmesh_node_lookup(bvh, f) == n) {
|
||||
found = true;
|
||||
|
@ -2095,13 +1998,12 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
#if 1
|
||||
/* total freak stuff, check if node exists somewhere else */
|
||||
/* Slow */
|
||||
for (i = 0; i < bvh->totnode; i++) {
|
||||
for (int i = 0; i < bvh->totnode; i++) {
|
||||
PBVHNode *n_other = &bvh->nodes[i];
|
||||
if ((n != n_other) && (n_other->bm_unique_verts)) {
|
||||
BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts, v));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2110,7 +2012,7 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
/* Slow */
|
||||
BM_ITER_MESH (vi, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
||||
bool has_unique = false;
|
||||
for (i = 0; i < bvh->totnode; i++) {
|
||||
for (int i = 0; i < bvh->totnode; i++) {
|
||||
PBVHNode *n = &bvh->nodes[i];
|
||||
if ((n->bm_unique_verts != NULL) && BLI_gset_haskey(n->bm_unique_verts, vi))
|
||||
has_unique = true;
|
||||
|
@ -2124,9 +2026,10 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||
#endif
|
||||
|
||||
/* Check that node elements are recorded in the top level */
|
||||
for (i = 0; i < bvh->totnode; i++) {
|
||||
for (int i = 0; i < bvh->totnode; i++) {
|
||||
PBVHNode *n = &bvh->nodes[i];
|
||||
if (n->flag & PBVH_Leaf) {
|
||||
GSetIterator gs_iter;
|
||||
|
||||
GSET_ITER (gs_iter, n->bm_faces) {
|
||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||
|
|
|
@ -95,7 +95,7 @@ void BLI_ghash_flag_clear(GHash *gh, unsigned int flag);
|
|||
|
||||
GHashIterator *BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh);
|
||||
unsigned BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh);
|
||||
void BLI_ghashIterator_free(GHashIterator *ghi);
|
||||
void BLI_ghashIterator_step(GHashIterator *ghi);
|
||||
|
||||
|
@ -116,15 +116,15 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi
|
|||
# define _gh_Entry void
|
||||
#endif
|
||||
|
||||
#define GHASH_ITER(gh_iter_, ghash_) \
|
||||
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||
BLI_ghashIterator_step(&gh_iter_))
|
||||
#define GHASH_ITER(gh_iter_, ghash_) \
|
||||
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||
BLI_ghashIterator_step(&gh_iter_))
|
||||
|
||||
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_) \
|
||||
for (BLI_ghashIterator_init(&gh_iter_, ghash_), i_ = 0; \
|
||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||
BLI_ghashIterator_step(&gh_iter_), i_++)
|
||||
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_) \
|
||||
for (unsigned i_ = BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||
BLI_ghashIterator_step(&gh_iter_), i_++)
|
||||
|
||||
/** \name Callbacks for GHash
|
||||
*
|
||||
|
@ -243,21 +243,21 @@ GSet *BLI_gset_pair_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
|
|||
|
||||
/* rely on inline api for now */
|
||||
BLI_INLINE GSetIterator *BLI_gsetIterator_new(GSet *gs) { return (GSetIterator *)BLI_ghashIterator_new((GHash *)gs); }
|
||||
BLI_INLINE void BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs) { BLI_ghashIterator_init((GHashIterator *)gsi, (GHash *)gs); }
|
||||
BLI_INLINE unsigned BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs) { BLI_ghashIterator_init((GHashIterator *)gsi, (GHash *)gs); return 0; }
|
||||
BLI_INLINE void BLI_gsetIterator_free(GSetIterator *gsi) { BLI_ghashIterator_free((GHashIterator *)gsi); }
|
||||
BLI_INLINE void *BLI_gsetIterator_getKey(GSetIterator *gsi) { return BLI_ghashIterator_getKey((GHashIterator *)gsi); }
|
||||
BLI_INLINE void BLI_gsetIterator_step(GSetIterator *gsi) { BLI_ghashIterator_step((GHashIterator *)gsi); }
|
||||
BLI_INLINE bool BLI_gsetIterator_done(GSetIterator *gsi) { return BLI_ghashIterator_done((GHashIterator *)gsi); }
|
||||
|
||||
#define GSET_ITER(gs_iter_, gset_) \
|
||||
for (BLI_gsetIterator_init(&gs_iter_, gset_); \
|
||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||
BLI_gsetIterator_step(&gs_iter_))
|
||||
#define GSET_ITER(gs_iter_, gset_) \
|
||||
for (BLI_gsetIterator_init(&gs_iter_, gset_); \
|
||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||
BLI_gsetIterator_step(&gs_iter_))
|
||||
|
||||
#define GSET_ITER_INDEX(gs_iter_, gset_, i_) \
|
||||
for (BLI_gsetIterator_init(&gs_iter_, gset_), i_ = 0; \
|
||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||
BLI_gsetIterator_step(&gs_iter_), i_++)
|
||||
#define GSET_ITER_INDEX(gs_iter_, gset_, i_) \
|
||||
for (unsigned i_ = BLI_gsetIterator_init(&gs_iter_, gset_); \
|
||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||
BLI_gsetIterator_step(&gs_iter_), i_++)
|
||||
|
||||
|
||||
/* For testing, debugging only */
|
||||
|
|
|
@ -934,7 +934,7 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh)
|
|||
* \param ghi The GHashIterator to initialize.
|
||||
* \param gh The GHash to iterate over.
|
||||
*/
|
||||
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
|
||||
unsigned BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
|
||||
{
|
||||
ghi->gh = gh;
|
||||
ghi->curEntry = NULL;
|
||||
|
@ -947,6 +947,7 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
|
|||
ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
|
||||
} while (!ghi->curEntry);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -229,7 +229,7 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
|
|||
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
||||
unsigned int **grid_hidden, int gridsize, const struct CCGKey *key);
|
||||
|
||||
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading);
|
||||
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading);
|
||||
|
||||
/* update */
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
/** \file blender/gpu/intern/gpu_buffers.c
|
||||
* \ingroup gpu
|
||||
*
|
||||
* Mesh drawing using OpenGL VBO (Vertex Buffer Objects),
|
||||
* with fall-back to vertex arrays.
|
||||
* Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
@ -101,7 +100,6 @@ const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
|
|||
|
||||
#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
|
||||
|
||||
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
|
||||
static GPUBufferState GLStates = 0;
|
||||
static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
|
||||
|
||||
|
@ -864,10 +862,9 @@ void GPU_buffers_unbind(void)
|
|||
}
|
||||
if (GLStates & GPU_BUFFER_COLOR_STATE)
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
|
||||
/* not guaranteed we used VBOs but in that case it's just a no-op */
|
||||
if (GLStates & GPU_BUFFER_ELEMENT_STATE)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
|
||||
GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
|
||||
GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
|
||||
|
@ -881,7 +878,6 @@ void GPU_buffers_unbind(void)
|
|||
}
|
||||
attribData[0].index = -1;
|
||||
|
||||
/* not guaranteed we used VBOs but in that case it's just a no-op */
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -1004,15 +1000,15 @@ struct GPU_PBVH_Buffers {
|
|||
BLI_bitmap * const *grid_hidden;
|
||||
const int *grid_indices;
|
||||
int totgrid;
|
||||
int has_hidden;
|
||||
bool has_hidden;
|
||||
|
||||
int use_bmesh;
|
||||
bool use_bmesh;
|
||||
|
||||
unsigned int tot_tri, tot_quad;
|
||||
|
||||
/* The PBVH ensures that either all faces in the node are
|
||||
* smooth-shaded or all faces are flat-shaded */
|
||||
int smooth;
|
||||
bool smooth;
|
||||
|
||||
bool show_diffuse_color;
|
||||
bool use_matcaps;
|
||||
|
@ -1283,10 +1279,10 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
|
|||
|
||||
buffers->show_diffuse_color = show_diffuse_color;
|
||||
buffers->use_matcaps = GPU_material_use_matcaps_get();
|
||||
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
||||
|
||||
/* Build VBO */
|
||||
if (buffers->vert_buf) {
|
||||
int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
||||
const int has_mask = key->has_mask;
|
||||
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
|
||||
|
||||
|
@ -1311,7 +1307,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
|
|||
CCGElem *elem = CCG_grid_elem(key, grid, x, y);
|
||||
|
||||
copy_v3_v3(vd->co, CCG_elem_co(key, elem));
|
||||
if (smooth) {
|
||||
if (buffers->smooth) {
|
||||
normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
|
||||
|
||||
if (has_mask) {
|
||||
|
@ -1323,7 +1319,7 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
|
|||
}
|
||||
}
|
||||
|
||||
if (!smooth) {
|
||||
if (!buffers->smooth) {
|
||||
/* for flat shading, recalc normals and set the last vertex of
|
||||
* each triangle in the index buffer to have the flat normal as
|
||||
* that is what opengl will use */
|
||||
|
@ -1376,8 +1372,6 @@ void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
|
|||
buffers->grid_flag_mats = grid_flag_mats;
|
||||
buffers->gridkey = *key;
|
||||
|
||||
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
||||
|
||||
//printf("node updated %p\n", buffers);
|
||||
}
|
||||
|
||||
|
@ -1518,7 +1512,7 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
|||
|
||||
if (totquad == fully_visible_totquad) {
|
||||
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
|
||||
buffers->has_hidden = 0;
|
||||
buffers->has_hidden = false;
|
||||
}
|
||||
else {
|
||||
buffers->tot_quad = totquad;
|
||||
|
@ -1532,7 +1526,7 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
|||
FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
|
||||
}
|
||||
|
||||
buffers->has_hidden = 1;
|
||||
buffers->has_hidden = true;
|
||||
}
|
||||
|
||||
/* Build coord/normal VBO */
|
||||
|
@ -1812,7 +1806,7 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
|
|||
}
|
||||
}
|
||||
|
||||
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
|
||||
GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading)
|
||||
{
|
||||
GPU_PBVH_Buffers *buffers;
|
||||
|
||||
|
|
Loading…
Reference in New Issue