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:
@@ -98,7 +98,7 @@ void BKE_pbvh_raycast(
|
|||||||
bool original);
|
bool original);
|
||||||
|
|
||||||
bool BKE_pbvh_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],
|
const float ray_start[3], const float ray_normal[3],
|
||||||
float *dist);
|
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_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_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 BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
|
||||||
void **gridfaces,
|
void **gridfaces,
|
||||||
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
|
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
|
||||||
|
@@ -1415,7 +1415,7 @@ void multires_stitch_grids(Object *ob)
|
|||||||
int totface;
|
int totface;
|
||||||
|
|
||||||
if (ccgdm->pbvh) {
|
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) {
|
if (totface) {
|
||||||
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
|
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
|
||||||
|
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
typedef struct PBVHStack {
|
typedef struct PBVHStack {
|
||||||
PBVHNode *node;
|
PBVHNode *node;
|
||||||
int revisiting;
|
bool revisiting;
|
||||||
} PBVHStack;
|
} PBVHStack;
|
||||||
|
|
||||||
typedef struct PBVHIter {
|
typedef struct PBVHIter {
|
||||||
@@ -87,8 +87,7 @@ void BB_reset(BB *bb)
|
|||||||
/* Expand the bounding box to include a new coordinate */
|
/* Expand the bounding box to include a new coordinate */
|
||||||
void BB_expand(BB *bb, const float co[3])
|
void BB_expand(BB *bb, const float co[3])
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
|
bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
|
||||||
bb->bmax[i] = max_ff(bb->bmax[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 */
|
/* Expand the bounding box to include another bounding box */
|
||||||
void BB_expand_with_bb(BB *bb, BB *bb2)
|
void BB_expand_with_bb(BB *bb, BB *bb2)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < 3; ++i) {
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
|
bb->bmin[i] = min_ff(bb->bmin[i], bb2->bmin[i]);
|
||||||
bb->bmax[i] = max_ff(bb->bmax[i], bb2->bmax[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)
|
int BB_widest_axis(const BB *bb)
|
||||||
{
|
{
|
||||||
float dim[3];
|
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];
|
dim[i] = bb->bmax[i] - bb->bmin[i];
|
||||||
|
|
||||||
if (dim[0] > dim[1]) {
|
if (dim[0] > dim[1]) {
|
||||||
@@ -129,8 +126,7 @@ int BB_widest_axis(const BB *bb)
|
|||||||
|
|
||||||
void BBC_update_centroid(BBC *bbc)
|
void BBC_update_centroid(BBC *bbc)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < 3; ++i)
|
||||||
for (i = 0; i < 3; ++i)
|
|
||||||
bbc->bcentroid[i] = (bbc->bmin[i] + bbc->bmax[i]) * 0.5f;
|
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);
|
// 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) &&
|
return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
|
||||||
(f1->mat_nr == f2->mat_nr));
|
(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) &&
|
return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) &&
|
||||||
(f1->mat_nr == f2->mat_nr));
|
(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 */
|
/* Find vertices used by the faces in this node and update the draw buffers */
|
||||||
static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
|
||||||
{
|
{
|
||||||
GHashIterator gh_iter;
|
|
||||||
GHash *map;
|
|
||||||
int i, j, totface;
|
|
||||||
bool has_visible = false;
|
bool has_visible = false;
|
||||||
int (*face_vert_indices)[4];
|
|
||||||
int *vert_indices;
|
|
||||||
|
|
||||||
node->uniq_verts = node->face_verts = 0;
|
node->uniq_verts = node->face_verts = 0;
|
||||||
totface = node->totprim;
|
const int totface = node->totprim;
|
||||||
|
|
||||||
/* reserve size is rough guess */
|
/* 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,
|
int (*face_vert_indices)[4] = MEM_callocN(sizeof(int[4]) * totface,
|
||||||
"bvh node face vert indices");
|
"bvh node face vert indices");
|
||||||
|
|
||||||
node->face_vert_indices = (const int (*)[4])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 MLoopTri *lt = &bvh->looptri[node->prim_indices[i]];
|
||||||
const int sides = 3;
|
const int sides = 3;
|
||||||
|
|
||||||
for (j = 0; j < sides; ++j) {
|
for (int j = 0; j < sides; ++j) {
|
||||||
face_vert_indices[i][j] =
|
face_vert_indices[i][j] =
|
||||||
map_insert_vert(bvh, map, &node->face_verts,
|
map_insert_vert(bvh, map, &node->face_verts,
|
||||||
&node->uniq_verts, bvh->mloop[lt->tri[j]].v);
|
&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) *
|
int *vert_indices = MEM_callocN(sizeof(int) * (node->uniq_verts + node->face_verts),
|
||||||
(node->uniq_verts + node->face_verts),
|
"bvh node vert indices");
|
||||||
"bvh node vert indices");
|
|
||||||
node->vert_indices = vert_indices;
|
node->vert_indices = vert_indices;
|
||||||
|
|
||||||
/* Build the vertex list, unique verts first */
|
/* Build the vertex list, unique verts first */
|
||||||
|
GHashIterator gh_iter;
|
||||||
GHASH_ITER (gh_iter, map) {
|
GHASH_ITER (gh_iter, map) {
|
||||||
void *value = BLI_ghashIterator_getValue(&gh_iter);
|
void *value = BLI_ghashIterator_getValue(&gh_iter);
|
||||||
int ndx = GET_INT_FROM_POINTER(value);
|
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));
|
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;
|
const int sides = 3;
|
||||||
|
|
||||||
for (j = 0; j < sides; ++j) {
|
for (int j = 0; j < sides; ++j) {
|
||||||
if (face_vert_indices[i][j] < 0)
|
if (face_vert_indices[i][j] < 0)
|
||||||
face_vert_indices[i][j] =
|
face_vert_indices[i][j] =
|
||||||
-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,
|
static void update_vb(PBVH *bvh, PBVHNode *node, BBC *prim_bbc,
|
||||||
int offset, int count)
|
int offset, int count)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
BB_reset(&node->vb);
|
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]]));
|
BB_expand_with_bb(&node->vb, (BB *)(&prim_bbc[bvh->prim_indices[i]]));
|
||||||
}
|
}
|
||||||
node->orig_vb = node->vb;
|
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 *grid_indices, int totgrid,
|
||||||
int gridsize)
|
int gridsize)
|
||||||
{
|
{
|
||||||
int gridarea = (gridsize - 1) * (gridsize - 1);
|
const int gridarea = (gridsize - 1) * (gridsize - 1);
|
||||||
int i, x, y, totquad;
|
int totquad = 0;
|
||||||
|
|
||||||
/* grid hidden layer is present, so have to check each grid for
|
/* grid hidden layer is present, so have to check each grid for
|
||||||
* visibility */
|
* 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]];
|
const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
|
||||||
|
|
||||||
if (gh) {
|
if (gh) {
|
||||||
/* grid hidden are present, have to check each element */
|
/* grid hidden are present, have to check each element */
|
||||||
for (y = 0; y < gridsize - 1; y++) {
|
for (int y = 0; y < gridsize - 1; y++) {
|
||||||
for (x = 0; x < gridsize - 1; x++) {
|
for (int x = 0; x < gridsize - 1; x++) {
|
||||||
if (!paint_is_grid_face_hidden(gh, gridsize, x, y))
|
if (!paint_is_grid_face_hidden(gh, gridsize, x, y))
|
||||||
totquad++;
|
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
|
/* Return zero if all primitives in the node can be drawn with the
|
||||||
* same material (including flat/smooth shading), non-zero otherwise */
|
* 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)
|
if (count <= 1)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (bvh->looptri) {
|
if (bvh->looptri) {
|
||||||
const MLoopTri *first = &bvh->looptri[bvh->prim_indices[offset]];
|
const MLoopTri *first = &bvh->looptri[bvh->prim_indices[offset]];
|
||||||
const MPoly *mp = &bvh->mpoly[first->poly];
|
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];
|
int prim = bvh->prim_indices[i];
|
||||||
const MPoly *mp_other = &bvh->mpoly[bvh->looptri[prim].poly];
|
const MPoly *mp_other = &bvh->mpoly[bvh->looptri[prim].poly];
|
||||||
if (!face_materials_match(mp, mp_other)) {
|
if (!face_materials_match(mp, mp_other)) {
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]];
|
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];
|
int prim = bvh->prim_indices[i];
|
||||||
if (!grid_materials_match(first, &bvh->grid_flag_mats[prim]))
|
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,
|
static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
||||||
int offset, int count)
|
int offset, int count)
|
||||||
{
|
{
|
||||||
int i, axis, end, below_leaf_limit;
|
int end;
|
||||||
BB cb_backing;
|
BB cb_backing;
|
||||||
|
|
||||||
/* Decide whether this is a leaf or not */
|
/* 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 (below_leaf_limit) {
|
||||||
if (!leaf_needs_material_split(bvh, offset, count)) {
|
if (!leaf_needs_material_split(bvh, offset, count)) {
|
||||||
build_leaf(bvh, node_index, prim_bbc, 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) {
|
if (!cb) {
|
||||||
cb = &cb_backing;
|
cb = &cb_backing;
|
||||||
BB_reset(cb);
|
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);
|
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 */
|
/* Partition primitives along that axis */
|
||||||
end = partition_indices(bvh->prim_indices,
|
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)
|
static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if (totprim != bvh->totprim) {
|
if (totprim != bvh->totprim) {
|
||||||
bvh->totprim = totprim;
|
bvh->totprim = totprim;
|
||||||
if (bvh->nodes) MEM_freeN(bvh->nodes);
|
if (bvh->nodes) MEM_freeN(bvh->nodes);
|
||||||
if (bvh->prim_indices) MEM_freeN(bvh->prim_indices);
|
if (bvh->prim_indices) MEM_freeN(bvh->prim_indices);
|
||||||
bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
|
bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
|
||||||
"bvh prim indices");
|
"bvh prim indices");
|
||||||
for (i = 0; i < totprim; ++i)
|
for (int i = 0; i < totprim; ++i)
|
||||||
bvh->prim_indices[i] = i;
|
bvh->prim_indices[i] = i;
|
||||||
bvh->totnode = 0;
|
bvh->totnode = 0;
|
||||||
if (bvh->node_mem_count < 100) {
|
if (bvh->node_mem_count < 100) {
|
||||||
@@ -546,7 +531,6 @@ void BKE_pbvh_build_mesh(
|
|||||||
{
|
{
|
||||||
BBC *prim_bbc = NULL;
|
BBC *prim_bbc = NULL;
|
||||||
BB cb;
|
BB cb;
|
||||||
int i, j;
|
|
||||||
|
|
||||||
bvh->type = PBVH_FACES;
|
bvh->type = PBVH_FACES;
|
||||||
bvh->mpoly = mpoly;
|
bvh->mpoly = mpoly;
|
||||||
@@ -563,14 +547,14 @@ void BKE_pbvh_build_mesh(
|
|||||||
/* For each face, store the AABB and the AABB centroid */
|
/* For each face, store the AABB and the AABB centroid */
|
||||||
prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc");
|
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 MLoopTri *lt = &looptri[i];
|
||||||
const int sides = 3;
|
const int sides = 3;
|
||||||
BBC *bbc = prim_bbc + i;
|
BBC *bbc = prim_bbc + i;
|
||||||
|
|
||||||
BB_reset((BB *)bbc);
|
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);
|
BB_expand((BB *)bbc, verts[bvh->mloop[lt->tri[j]].v].co);
|
||||||
|
|
||||||
BBC_update_centroid(bbc);
|
BBC_update_centroid(bbc);
|
||||||
@@ -589,10 +573,7 @@ void BKE_pbvh_build_mesh(
|
|||||||
void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
||||||
int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
||||||
{
|
{
|
||||||
BBC *prim_bbc = NULL;
|
const int gridsize = key->grid_size;
|
||||||
BB cb;
|
|
||||||
int gridsize = key->grid_size;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
bvh->type = PBVH_GRIDS;
|
bvh->type = PBVH_GRIDS;
|
||||||
bvh->grids = grids;
|
bvh->grids = grids;
|
||||||
@@ -603,18 +584,19 @@ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids,
|
|||||||
bvh->grid_hidden = grid_hidden;
|
bvh->grid_hidden = grid_hidden;
|
||||||
bvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
|
bvh->leaf_limit = max_ii(LEAF_LIMIT / ((gridsize - 1) * (gridsize - 1)), 1);
|
||||||
|
|
||||||
|
BB cb;
|
||||||
BB_reset(&cb);
|
BB_reset(&cb);
|
||||||
|
|
||||||
/* For each grid, store the AABB and the AABB centroid */
|
/* 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];
|
CCGElem *grid = grids[i];
|
||||||
BBC *bbc = prim_bbc + i;
|
BBC *bbc = prim_bbc + i;
|
||||||
|
|
||||||
BB_reset((BB *)bbc);
|
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));
|
BB_expand((BB *)bbc, CCG_elem_offset_co(key, grid, j));
|
||||||
|
|
||||||
BBC_update_centroid(bbc);
|
BBC_update_centroid(bbc);
|
||||||
@@ -637,11 +619,8 @@ PBVH *BKE_pbvh_new(void)
|
|||||||
|
|
||||||
void BKE_pbvh_free(PBVH *bvh)
|
void BKE_pbvh_free(PBVH *bvh)
|
||||||
{
|
{
|
||||||
PBVHNode *node;
|
for (int i = 0; i < bvh->totnode; ++i) {
|
||||||
int i;
|
PBVHNode *node = &bvh->nodes[i];
|
||||||
|
|
||||||
for (i = 0; i < bvh->totnode; ++i) {
|
|
||||||
node = &bvh->nodes[i];
|
|
||||||
|
|
||||||
if (node->flag & PBVH_Leaf) {
|
if (node->flag & PBVH_Leaf) {
|
||||||
if (node->draw_buffers)
|
if (node->draw_buffers)
|
||||||
@@ -684,8 +663,7 @@ void BKE_pbvh_free(PBVH *bvh)
|
|||||||
|
|
||||||
void BKE_pbvh_free_layer_disp(PBVH *bvh)
|
void BKE_pbvh_free_layer_disp(PBVH *bvh)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < bvh->totnode; ++i)
|
||||||
for (i = 0; i < bvh->totnode; ++i)
|
|
||||||
BKE_pbvh_node_layer_disp_free(&bvh->nodes[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->stackspace = STACK_FIXED_DEPTH;
|
||||||
|
|
||||||
iter->stack[0].node = bvh->nodes;
|
iter->stack[0].node = bvh->nodes;
|
||||||
iter->stack[0].revisiting = 0;
|
iter->stack[0].revisiting = false;
|
||||||
iter->stacksize = 1;
|
iter->stacksize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,7 +687,7 @@ static void pbvh_iter_end(PBVHIter *iter)
|
|||||||
MEM_freeN(iter->stack);
|
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)) {
|
if (UNLIKELY(iter->stacksize == iter->stackspace)) {
|
||||||
iter->stackspace *= 2;
|
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)
|
static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
||||||
{
|
{
|
||||||
PBVHNode *node;
|
|
||||||
int revisiting;
|
|
||||||
|
|
||||||
/* purpose here is to traverse tree, visiting child nodes before their
|
/* purpose here is to traverse tree, visiting child nodes before their
|
||||||
* parents, this order is necessary for e.g. computing bounding boxes */
|
* parents, this order is necessary for e.g. computing bounding boxes */
|
||||||
|
|
||||||
while (iter->stacksize) {
|
while (iter->stacksize) {
|
||||||
/* pop node */
|
/* pop node */
|
||||||
iter->stacksize--;
|
iter->stacksize--;
|
||||||
node = iter->stack[iter->stacksize].node;
|
PBVHNode *node = iter->stack[iter->stacksize].node;
|
||||||
|
|
||||||
/* on a mesh with no faces this can happen
|
/* on a mesh with no faces this can happen
|
||||||
* can remove this check if we know meshes have at least 1 face */
|
* can remove this check if we know meshes have at least 1 face */
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
revisiting = iter->stack[iter->stacksize].revisiting;
|
bool revisiting = iter->stack[iter->stacksize].revisiting;
|
||||||
|
|
||||||
/* revisiting node already checked */
|
/* revisiting node already checked */
|
||||||
if (revisiting)
|
if (revisiting)
|
||||||
@@ -761,11 +736,11 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* come back later when children are done */
|
/* 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 */
|
/* 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 + 1, false);
|
||||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
|
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)
|
static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
||||||
{
|
{
|
||||||
PBVHNode *node;
|
|
||||||
|
|
||||||
while (iter->stacksize) {
|
while (iter->stacksize) {
|
||||||
/* pop node */
|
/* pop node */
|
||||||
iter->stacksize--;
|
iter->stacksize--;
|
||||||
node = iter->stack[iter->stacksize].node;
|
PBVHNode *node = iter->stack[iter->stacksize].node;
|
||||||
|
|
||||||
/* on a mesh with no faces this can happen
|
/* on a mesh with no faces this can happen
|
||||||
* can remove this check if we know meshes have at least 1 face */
|
* 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;
|
return node;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, 0);
|
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset + 1, false);
|
||||||
pbvh_stack_push(iter, iter->bvh->nodes + node->children_offset, 0);
|
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])
|
int totnode, float (*face_nors)[3])
|
||||||
{
|
{
|
||||||
float (*vnor)[3];
|
float (*vnor)[3];
|
||||||
int n;
|
|
||||||
|
|
||||||
if (bvh->type == PBVH_BMESH) {
|
if (bvh->type == PBVH_BMESH) {
|
||||||
BLI_assert(face_nors == NULL);
|
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)
|
#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];
|
PBVHNode *node = nodes[n];
|
||||||
|
|
||||||
if ((node->flag & PBVH_UpdateNormals)) {
|
if ((node->flag & PBVH_UpdateNormals)) {
|
||||||
int i, j, totface, *faces;
|
|
||||||
unsigned int mpoly_prev = UINT_MAX;
|
unsigned int mpoly_prev = UINT_MAX;
|
||||||
float fn[3];
|
float fn[3];
|
||||||
|
|
||||||
faces = node->prim_indices;
|
const int *faces = node->prim_indices;
|
||||||
totface = node->totprim;
|
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 MLoopTri *lt = &bvh->looptri[faces[i]];
|
||||||
const unsigned int vtri[3] = {
|
const unsigned int vtri[3] = {
|
||||||
bvh->mloop[lt->tri[0]].v,
|
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];
|
int v = vtri[j];
|
||||||
|
|
||||||
if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) {
|
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)
|
#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];
|
PBVHNode *node = nodes[n];
|
||||||
|
|
||||||
if (node->flag & PBVH_UpdateNormals) {
|
if (node->flag & PBVH_UpdateNormals) {
|
||||||
const int *verts;
|
const int *verts = node->vert_indices;
|
||||||
int i, totvert;
|
const int totvert = node->uniq_verts;
|
||||||
|
|
||||||
verts = node->vert_indices;
|
for (int i = 0; i < totvert; ++i) {
|
||||||
totvert = node->uniq_verts;
|
|
||||||
|
|
||||||
for (i = 0; i < totvert; ++i) {
|
|
||||||
const int v = verts[i];
|
const int v = verts[i];
|
||||||
MVert *mvert = &bvh->verts[v];
|
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)
|
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
|
|
||||||
/* update BB, redraw flag */
|
/* update BB, redraw flag */
|
||||||
#pragma omp parallel for private(n) schedule(static) if (totnode > PBVH_OMP_LIMIT)
|
#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];
|
PBVHNode *node = nodes[n];
|
||||||
|
|
||||||
if ((flag & PBVH_UpdateBB) && (node->flag & PBVH_UpdateBB))
|
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)
|
static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
||||||
{
|
{
|
||||||
PBVHNode *node;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
/* can't be done in parallel with OpenGL */
|
/* can't be done in parallel with OpenGL */
|
||||||
for (n = 0; n < totnode; n++) {
|
for (int n = 0; n < totnode; n++) {
|
||||||
node = nodes[n];
|
PBVHNode *node = nodes[n];
|
||||||
|
|
||||||
if (node->flag & PBVH_RebuildDrawBuffers) {
|
if (node->flag & PBVH_RebuildDrawBuffers) {
|
||||||
GPU_free_pbvh_buffers(node->draw_buffers);
|
GPU_free_pbvh_buffers(node->draw_buffers);
|
||||||
@@ -1116,8 +1079,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||||||
break;
|
break;
|
||||||
case PBVH_BMESH:
|
case PBVH_BMESH:
|
||||||
node->draw_buffers =
|
node->draw_buffers =
|
||||||
GPU_build_bmesh_pbvh_buffers(bvh->flags &
|
GPU_build_bmesh_pbvh_buffers(bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
|
||||||
PBVH_DYNTOPO_SMOOTH_SHADING);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,13 +1125,10 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||||||
|
|
||||||
static void pbvh_draw_BB(PBVH *bvh)
|
static void pbvh_draw_BB(PBVH *bvh)
|
||||||
{
|
{
|
||||||
PBVHNode *node;
|
|
||||||
int a;
|
|
||||||
|
|
||||||
GPU_init_draw_pbvh_BB();
|
GPU_init_draw_pbvh_BB();
|
||||||
|
|
||||||
for (a = 0; a < bvh->totnode; a++) {
|
for (int a = 0; a < bvh->totnode; a++) {
|
||||||
node = &bvh->nodes[a];
|
PBVHNode *node = &bvh->nodes[a];
|
||||||
|
|
||||||
GPU_draw_pbvh_BB(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
|
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])
|
void BKE_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
|
||||||
{
|
{
|
||||||
PBVHNode **nodes;
|
|
||||||
int totnode;
|
|
||||||
|
|
||||||
if (!bvh->nodes)
|
if (!bvh->nodes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PBVHNode **nodes;
|
||||||
|
int totnode;
|
||||||
|
|
||||||
BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
|
BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
|
||||||
&nodes, &totnode);
|
&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);
|
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;
|
PBVHNode *node;
|
||||||
GSetIterator gs_iter;
|
PBVHIter iter;
|
||||||
GSet *face_set;
|
|
||||||
void *face, **faces;
|
|
||||||
unsigned i;
|
|
||||||
int tot;
|
|
||||||
|
|
||||||
face_set = BLI_gset_ptr_new(__func__);
|
|
||||||
|
|
||||||
pbvh_iter_begin(&iter, bvh, NULL, NULL);
|
pbvh_iter_begin(&iter, bvh, NULL, NULL);
|
||||||
|
|
||||||
while ((node = pbvh_iter_next(&iter))) {
|
while ((node = pbvh_iter_next(&iter))) {
|
||||||
if (node->flag & PBVH_UpdateNormals) {
|
if (node->flag & PBVH_UpdateNormals) {
|
||||||
for (i = 0; i < node->totprim; ++i) {
|
for (unsigned i = 0; i < node->totprim; ++i) {
|
||||||
face = bvh->gridfaces[node->prim_indices[i]];
|
void *face = bvh->gridfaces[node->prim_indices[i]];
|
||||||
if (!BLI_gset_haskey(face_set, face))
|
if (!BLI_gset_haskey(face_set, face))
|
||||||
BLI_gset_insert(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);
|
pbvh_iter_end(&iter);
|
||||||
|
|
||||||
tot = BLI_gset_size(face_set);
|
const int tot = BLI_gset_size(face_set);
|
||||||
if (tot == 0) {
|
if (tot == 0) {
|
||||||
*r_totface = 0;
|
*r_totface = 0;
|
||||||
*r_gridfaces = NULL;
|
*r_gridfaces = NULL;
|
||||||
@@ -1288,8 +1241,9 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***r_gridfaces, int *r
|
|||||||
return;
|
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) {
|
GSET_ITER_INDEX (gs_iter, face_set, i) {
|
||||||
faces[i] = BLI_gsetIterator_getKey(&gs_iter);
|
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],
|
const float ray_start[3], const float ray_normal[3],
|
||||||
float *dist)
|
float *dist)
|
||||||
{
|
{
|
||||||
int totgrid = node->totprim;
|
const int totgrid = node->totprim;
|
||||||
int gridsize = bvh->gridkey.grid_size;
|
const int gridsize = bvh->gridkey.grid_size;
|
||||||
int i, x, y;
|
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
for (i = 0; i < totgrid; ++i) {
|
for (int i = 0; i < totgrid; ++i) {
|
||||||
CCGElem *grid = bvh->grids[node->prim_indices[i]];
|
CCGElem *grid = bvh->grids[node->prim_indices[i]];
|
||||||
BLI_bitmap *gh;
|
BLI_bitmap *gh;
|
||||||
|
|
||||||
@@ -1603,8 +1556,8 @@ static bool pbvh_grids_node_raycast(
|
|||||||
|
|
||||||
gh = bvh->grid_hidden[node->prim_indices[i]];
|
gh = bvh->grid_hidden[node->prim_indices[i]];
|
||||||
|
|
||||||
for (y = 0; y < gridsize - 1; ++y) {
|
for (int y = 0; y < gridsize - 1; ++y) {
|
||||||
for (x = 0; x < gridsize - 1; ++x) {
|
for (int x = 0; x < gridsize - 1; ++x) {
|
||||||
/* check if grid face is hidden */
|
/* check if grid face is hidden */
|
||||||
if (gh) {
|
if (gh) {
|
||||||
if (paint_is_grid_face_hidden(gh, gridsize, x, y))
|
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(
|
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],
|
const float ray_start[3], const float ray_normal[3],
|
||||||
float *dist)
|
float *dist)
|
||||||
{
|
{
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
if (node->flag & PBVH_FullyHidden)
|
if (node->flag & PBVH_FullyHidden)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
switch (bvh->type) {
|
switch (bvh->type) {
|
||||||
case PBVH_FACES:
|
case PBVH_FACES:
|
||||||
@@ -1713,9 +1666,6 @@ void BKE_pbvh_raycast_project_ray_root(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//#include "GPU_glew.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DMSetMaterial setMaterial;
|
DMSetMaterial setMaterial;
|
||||||
bool wireframe;
|
bool wireframe;
|
||||||
@@ -1728,14 +1678,14 @@ void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* XXX: Just some quick code to show leaf nodes in different colors */
|
/* XXX: Just some quick code to show leaf nodes in different colors */
|
||||||
float col[3]; int i;
|
float col[3];
|
||||||
|
|
||||||
if (0) { //is_partial) {
|
if (0) { //is_partial) {
|
||||||
col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
|
col[0] = (rand() / (float)RAND_MAX); col[1] = col[2] = 0.6;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
srand((long long)node);
|
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;
|
col[i] = (rand() / (float)RAND_MAX) * 0.3 + 0.7;
|
||||||
}
|
}
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
|
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];
|
float vmin[3], vmax[3];
|
||||||
PlaneAABBIsect ret = ISECT_INSIDE;
|
PlaneAABBIsect ret = ISECT_INSIDE;
|
||||||
int i, axis;
|
|
||||||
|
|
||||||
for (i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
for (axis = 0; axis < 3; ++axis) {
|
for (int axis = 0; axis < 3; ++axis) {
|
||||||
if (planes[i][axis] > 0) {
|
if (planes[i][axis] > 0) {
|
||||||
vmin[axis] = bb_min[axis];
|
vmin[axis] = bb_min[axis];
|
||||||
vmax[axis] = bb_max[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};
|
PBVHNodeDrawData draw_data = {setMaterial, wireframe, fast};
|
||||||
PBVHNode **nodes;
|
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]);
|
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),
|
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,
|
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
|
||||||
DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
||||||
{
|
{
|
||||||
int a;
|
|
||||||
|
|
||||||
bvh->grids = grids;
|
bvh->grids = grids;
|
||||||
bvh->gridfaces = gridfaces;
|
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_flag_mats = flagmats;
|
||||||
bvh->grid_hidden = grid_hidden;
|
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]);
|
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]
|
float (*BKE_pbvh_get_vertCos(PBVH *pbvh))[3]
|
||||||
{
|
{
|
||||||
int a;
|
|
||||||
float (*vertCos)[3] = NULL;
|
float (*vertCos)[3] = NULL;
|
||||||
|
|
||||||
if (pbvh->verts) {
|
if (pbvh->verts) {
|
||||||
float *co;
|
|
||||||
MVert *mvert = pbvh->verts;
|
MVert *mvert = pbvh->verts;
|
||||||
|
|
||||||
vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
|
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);
|
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])
|
void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
||||||
{
|
{
|
||||||
int a;
|
|
||||||
|
|
||||||
if (!pbvh->deformed) {
|
if (!pbvh->deformed) {
|
||||||
if (pbvh->verts) {
|
if (pbvh->verts) {
|
||||||
/* if pbvh is not already deformed, verts/faces points to the */
|
/* 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->verts = MEM_dupallocN(pbvh->verts);
|
||||||
pbvh->looptri = MEM_dupallocN(pbvh->looptri);
|
pbvh->looptri = MEM_dupallocN(pbvh->looptri);
|
||||||
|
|
||||||
pbvh->deformed = 1;
|
pbvh->deformed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pbvh->verts) {
|
if (pbvh->verts) {
|
||||||
MVert *mvert = pbvh->verts;
|
MVert *mvert = pbvh->verts;
|
||||||
/* copy new verts coords */
|
/* 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]);
|
copy_v3_v3(mvert->co, vertCos[a]);
|
||||||
mvert->flag |= ME_VERT_PBVH_UPDATE;
|
mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||||
}
|
}
|
||||||
@@ -1935,7 +1878,7 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
|
|||||||
pbvh->looptri, pbvh->totprim,
|
pbvh->looptri, pbvh->totprim,
|
||||||
NULL);
|
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_node_mark_update(&pbvh->nodes[a]);
|
||||||
|
|
||||||
BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
|
BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
|
||||||
@@ -1956,7 +1899,6 @@ PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
|
|||||||
|
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
{
|
{
|
||||||
|
|
||||||
index = node->proxy_count;
|
index = node->proxy_count;
|
||||||
|
|
||||||
node->proxy_count++;
|
node->proxy_count++;
|
||||||
@@ -1977,9 +1919,7 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
|
|||||||
{
|
{
|
||||||
#pragma omp critical
|
#pragma omp critical
|
||||||
{
|
{
|
||||||
int p;
|
for (int p = 0; p < node->proxy_count; p++) {
|
||||||
|
|
||||||
for (p = 0; p < node->proxy_count; p++) {
|
|
||||||
MEM_freeN(node->proxies[p].co);
|
MEM_freeN(node->proxies[p].co);
|
||||||
node->proxies[p].co = NULL;
|
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)
|
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 tot = 0, space = 0;
|
||||||
int n;
|
|
||||||
|
|
||||||
for (n = 0; n < pbvh->totnode; n++) {
|
for (int n = 0; n < pbvh->totnode; n++) {
|
||||||
node = pbvh->nodes + n;
|
PBVHNode *node = pbvh->nodes + n;
|
||||||
|
|
||||||
if (node->proxy_count > 0) {
|
if (node->proxy_count > 0) {
|
||||||
if (tot == space) {
|
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) {
|
GSET_ITER (gs_iter, n->bm_faces) {
|
||||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
BMLoop *l_iter;
|
|
||||||
BMLoop *l_first;
|
|
||||||
BMVert *v;
|
|
||||||
|
|
||||||
/* Update ownership of faces */
|
/* Update ownership of faces */
|
||||||
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
|
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
|
||||||
|
|
||||||
/* Update vertices */
|
/* 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 {
|
do {
|
||||||
v = l_iter->v;
|
BMVert *v = l_iter->v;
|
||||||
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
||||||
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||||
BLI_gset_add(n->bm_other_verts, v);
|
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 */
|
/* 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)
|
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_vert_node_offset = bvh->cd_vert_node_offset;
|
||||||
const int cd_face_node_offset = bvh->cd_face_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) {
|
if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) {
|
||||||
/* Node limit not exceeded */
|
/* 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 */
|
/* Calculate bounding box around primitive centroids */
|
||||||
|
BB cb;
|
||||||
BB_reset(&cb);
|
BB_reset(&cb);
|
||||||
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, n->bm_faces) {
|
GSET_ITER (gs_iter, n->bm_faces) {
|
||||||
const BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
const BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
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 */
|
/* Find widest axis and its midpoint */
|
||||||
axis = BB_widest_axis(&cb);
|
const int axis = BB_widest_axis(&cb);
|
||||||
mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
||||||
|
|
||||||
/* Add two new child nodes */
|
/* Add two new child nodes */
|
||||||
children = bvh->totnode;
|
const int children = bvh->totnode;
|
||||||
n->children_offset = children;
|
n->children_offset = children;
|
||||||
pbvh_grow_nodes(bvh, bvh->totnode + 2);
|
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];
|
n = &bvh->nodes[node_index];
|
||||||
|
|
||||||
/* Initialize children */
|
/* Initialize children */
|
||||||
c1 = &bvh->nodes[children];
|
PBVHNode *c1 = &bvh->nodes[children],
|
||||||
c2 = &bvh->nodes[children + 1];
|
*c2 = &bvh->nodes[children + 1];
|
||||||
c1->flag |= PBVH_Leaf;
|
c1->flag |= PBVH_Leaf;
|
||||||
c2->flag |= PBVH_Leaf;
|
c2->flag |= PBVH_Leaf;
|
||||||
c1->bm_faces = BLI_gset_ptr_new_ex("bm_faces", BLI_gset_size(n->bm_faces) / 2);
|
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 */
|
/* Enforce at least one primitive in each node */
|
||||||
empty = NULL;
|
GSet *empty = NULL, *other;
|
||||||
if (BLI_gset_size(c1->bm_faces) == 0) {
|
if (BLI_gset_size(c1->bm_faces) == 0) {
|
||||||
empty = c1->bm_faces;
|
empty = c1->bm_faces;
|
||||||
other = c2->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;
|
n->flag &= ~PBVH_Leaf;
|
||||||
|
|
||||||
/* Recurse */
|
/* Recurse */
|
||||||
c1 = c2 = NULL;
|
|
||||||
pbvh_bmesh_node_split(bvh, bbc_array, children);
|
pbvh_bmesh_node_split(bvh, bbc_array, children);
|
||||||
pbvh_bmesh_node_split(bvh, bbc_array, children + 1);
|
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 */
|
/* Recursively split the node if it exceeds the leaf_limit */
|
||||||
static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
|
static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
|
||||||
{
|
{
|
||||||
GSet *bm_faces;
|
GSet *bm_faces = bvh->nodes[node_index].bm_faces;
|
||||||
int bm_faces_size;
|
const int bm_faces_size = BLI_gset_size(bm_faces);
|
||||||
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);
|
|
||||||
if (bm_faces_size <= bvh->leaf_limit) {
|
if (bm_faces_size <= bvh->leaf_limit) {
|
||||||
/* Node limit not exceeded */
|
/* Node limit not exceeded */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For each BMFace, store the AABB and AABB centroid */
|
/* 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) {
|
GSET_ITER_INDEX (gs_iter, bm_faces, i) {
|
||||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
BBC *bbc = &bbc_array[i];
|
BBC *bbc = &bbc_array[i];
|
||||||
BMLoop *l_iter;
|
|
||||||
BMLoop *l_first;
|
|
||||||
|
|
||||||
BB_reset((BB *)bbc);
|
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 {
|
do {
|
||||||
BB_expand((BB *)bbc, l_iter->v->co);
|
BB_expand((BB *)bbc, l_iter->v->co);
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
@@ -347,12 +335,11 @@ static BMVert *pbvh_bmesh_vert_create(
|
|||||||
const int cd_vert_mask_offset)
|
const int cd_vert_mask_offset)
|
||||||
{
|
{
|
||||||
PBVHNode *node = &bvh->nodes[node_index];
|
PBVHNode *node = &bvh->nodes[node_index];
|
||||||
BMVert *v;
|
|
||||||
|
|
||||||
BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
|
BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
|
||||||
|
|
||||||
/* avoid initializing customdata because its quite involved */
|
/* 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);
|
CustomData_bmesh_set_default(&bvh->bm->vdata, &v->head.data);
|
||||||
|
|
||||||
/* This value is logged below */
|
/* This value is logged below */
|
||||||
@@ -374,13 +361,12 @@ static BMFace *pbvh_bmesh_face_create(
|
|||||||
BMVert *v_tri[3], BMEdge *e_tri[3],
|
BMVert *v_tri[3], BMEdge *e_tri[3],
|
||||||
const BMFace *f_example)
|
const BMFace *f_example)
|
||||||
{
|
{
|
||||||
BMFace *f;
|
|
||||||
PBVHNode *node = &bvh->nodes[node_index];
|
PBVHNode *node = &bvh->nodes[node_index];
|
||||||
|
|
||||||
/* ensure we never add existing face */
|
/* ensure we never add existing face */
|
||||||
BLI_assert(BM_face_exists(v_tri, 3, NULL) == false);
|
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;
|
f->head.hflag = f_example->head.hflag;
|
||||||
|
|
||||||
BLI_gset_insert(node->bm_faces, f);
|
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;
|
BMIter bm_iter;
|
||||||
BMFace *f;
|
BMFace *f;
|
||||||
PBVHNode *current_node;
|
PBVHNode *current_node = pbvh_bmesh_node_lookup(bvh, v);
|
||||||
|
|
||||||
current_node = pbvh_bmesh_node_lookup(bvh, v);
|
|
||||||
|
|
||||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||||
PBVHNode *f_node;
|
PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||||
|
|
||||||
f_node = pbvh_bmesh_node_lookup(bvh, f);
|
|
||||||
|
|
||||||
if (f_node != current_node)
|
if (f_node != current_node)
|
||||||
return f_node;
|
return f_node;
|
||||||
@@ -462,13 +444,10 @@ static void pbvh_bmesh_vert_ownership_transfer(
|
|||||||
PBVH *bvh, PBVHNode *new_owner,
|
PBVH *bvh, PBVHNode *new_owner,
|
||||||
BMVert *v)
|
BMVert *v)
|
||||||
{
|
{
|
||||||
PBVHNode *current_owner;
|
PBVHNode *current_owner = pbvh_bmesh_node_lookup(bvh, v);
|
||||||
|
|
||||||
current_owner = pbvh_bmesh_node_lookup(bvh, v);
|
|
||||||
/* mark node for update */
|
/* mark node for update */
|
||||||
current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
|
current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
|
||||||
|
|
||||||
|
|
||||||
BLI_assert(current_owner != new_owner);
|
BLI_assert(current_owner != new_owner);
|
||||||
|
|
||||||
/* Remove current ownership */
|
/* Remove current ownership */
|
||||||
@@ -486,21 +465,18 @@ static void pbvh_bmesh_vert_ownership_transfer(
|
|||||||
|
|
||||||
static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
||||||
{
|
{
|
||||||
PBVHNode *v_node;
|
|
||||||
BMIter bm_iter;
|
|
||||||
BMFace *f;
|
|
||||||
|
|
||||||
/* never match for first time */
|
/* never match for first time */
|
||||||
int f_node_index_prev = DYNTOPO_NODE_NONE;
|
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);
|
BLI_gset_remove(v_node->bm_unique_verts, v, NULL);
|
||||||
BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
BM_ELEM_CD_SET_INT(v, bvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
||||||
|
|
||||||
/* Have to check each neighboring face's node */
|
/* Have to check each neighboring face's node */
|
||||||
|
BMIter bm_iter;
|
||||||
|
BMFace *f;
|
||||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||||
const int f_node_index = pbvh_bmesh_node_lookup_index(bvh, f);
|
const int f_node_index = pbvh_bmesh_node_lookup_index(bvh, f);
|
||||||
PBVHNode *f_node;
|
|
||||||
|
|
||||||
/* faces often share the same node,
|
/* faces often share the same node,
|
||||||
* quick check to avoid redundant #BLI_gset_remove calls */
|
* quick check to avoid redundant #BLI_gset_remove calls */
|
||||||
@@ -508,7 +484,7 @@ static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
|
|||||||
continue;
|
continue;
|
||||||
f_node_index_prev = f_node_index;
|
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;
|
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB;
|
||||||
|
|
||||||
/* Remove current ownership */
|
/* 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)
|
static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
|
||||||
{
|
{
|
||||||
PBVHNode *f_node;
|
PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, f);
|
||||||
BMVert *v;
|
|
||||||
|
|
||||||
BMLoop *l_iter;
|
|
||||||
BMLoop *l_first;
|
|
||||||
|
|
||||||
f_node = pbvh_bmesh_node_lookup(bvh, f);
|
|
||||||
|
|
||||||
/* Check if any of this face's vertices need to be removed
|
/* Check if any of this face's vertices need to be removed
|
||||||
* from the node */
|
* 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 {
|
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 (pbvh_bmesh_node_vert_use_count_is_equal(bvh, f_node, v, 1)) {
|
||||||
if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
|
if (BLI_gset_haskey(f_node->bm_unique_verts, v)) {
|
||||||
/* Find a different node that uses '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) */
|
* (it's a requirement that edges enter and leave a clean tag state) */
|
||||||
static void pbvh_bmesh_edge_tag_verify(PBVH *bvh)
|
static void pbvh_bmesh_edge_tag_verify(PBVH *bvh)
|
||||||
{
|
{
|
||||||
int n;
|
for (int n = 0; n < bvh->totnode; n++) {
|
||||||
|
|
||||||
for (n = 0; n < bvh->totnode; n++) {
|
|
||||||
PBVHNode *node = &bvh->nodes[n];
|
PBVHNode *node = &bvh->nodes[n];
|
||||||
GSetIterator gs_iter;
|
|
||||||
if (node->bm_faces) {
|
if (node->bm_faces) {
|
||||||
|
GSetIterator gs_iter;
|
||||||
GSET_ITER (gs_iter, node->bm_faces) {
|
GSET_ITER (gs_iter, node->bm_faces) {
|
||||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
BMEdge *e_tri[3];
|
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);
|
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));
|
return len_squared_v3v3(q->center, 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)
|
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(
|
static void edge_queue_insert(
|
||||||
EdgeQueueContext *eq_ctx, BMEdge *e,
|
EdgeQueueContext *eq_ctx, BMEdge *e,
|
||||||
float priority)
|
float priority)
|
||||||
{
|
{
|
||||||
BMVert **pair;
|
|
||||||
|
|
||||||
/* Don't let topology update affect fully masked vertices. This used to
|
/* 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%
|
* 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
|
* 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->v1, BM_ELEM_HIDDEN) ||
|
||||||
BM_elem_flag_test_bool(e->v2, 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[0] = e->v1;
|
||||||
pair[1] = e->v2;
|
pair[1] = e->v2;
|
||||||
BLI_heap_insert(eq_ctx->q->heap, priority, pair);
|
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
|
#define EVEN_GENERATION_SCALE 1.6f
|
||||||
|
|
||||||
const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
|
const float len_sq_cmp = len_sq * EVEN_EDGELEN_THRESHOLD;
|
||||||
float limit_len_sq;
|
|
||||||
BMLoop *l_iter;
|
|
||||||
|
|
||||||
limit_len *= EVEN_GENERATION_SCALE;
|
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 {
|
do {
|
||||||
float len_sq_other;
|
|
||||||
BMLoop *l_adjacent[2] = {l_iter->next, l_iter->prev};
|
BMLoop *l_adjacent[2] = {l_iter->next, l_iter->prev};
|
||||||
int i;
|
for (int i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
|
||||||
for (i = 0; i < ARRAY_SIZE(l_adjacent); i++) {
|
float len_sq_other = BM_edge_calc_length_squared(l_adjacent[i]->e);
|
||||||
len_sq_other = BM_edge_calc_length_squared(l_adjacent[i]->e);
|
|
||||||
if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
|
if (len_sq_other > max_ff(len_sq_cmp, limit_len_sq)) {
|
||||||
// edge_queue_insert(eq_ctx, l_adjacent[i]->e, -len_sq_other);
|
// edge_queue_insert(eq_ctx, l_adjacent[i]->e, -len_sq_other);
|
||||||
long_edge_queue_edge_add_recursive(
|
long_edge_queue_edge_add_recursive(
|
||||||
@@ -813,24 +776,20 @@ static void long_edge_queue_face_add(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (edge_queue_tri_in_sphere(eq_ctx->q, f)) {
|
if (edge_queue_tri_in_sphere(eq_ctx->q, 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);
|
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||||
|
BMLoop *l_iter = l_first;
|
||||||
do {
|
do {
|
||||||
{
|
|
||||||
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
|
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
|
||||||
const float len_sq = BM_edge_calc_length_squared(l_iter->e);
|
const float len_sq = BM_edge_calc_length_squared(l_iter->e);
|
||||||
if (len_sq > eq_ctx->q->limit_len_squared) {
|
if (len_sq > eq_ctx->q->limit_len_squared) {
|
||||||
long_edge_queue_edge_add_recursive(
|
long_edge_queue_edge_add_recursive(
|
||||||
eq_ctx, l_iter->radial_next, l_iter,
|
eq_ctx, l_iter->radial_next, l_iter,
|
||||||
len_sq, eq_ctx->q->limit_len);
|
len_sq, eq_ctx->q->limit_len);
|
||||||
}
|
|
||||||
#else
|
|
||||||
long_edge_queue_edge_add(eq_ctx, l_iter->e);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
long_edge_queue_edge_add(eq_ctx, l_iter->e);
|
||||||
|
#endif
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} 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],
|
PBVH *bvh, const float center[3], const float view_normal[3],
|
||||||
float radius)
|
float radius)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
|
|
||||||
eq_ctx->q->heap = BLI_heap_new();
|
eq_ctx->q->heap = BLI_heap_new();
|
||||||
eq_ctx->q->center = center;
|
eq_ctx->q->center = center;
|
||||||
eq_ctx->q->radius_squared = radius * radius;
|
eq_ctx->q->radius_squared = radius * radius;
|
||||||
@@ -894,8 +851,7 @@ static void long_edge_queue_create(
|
|||||||
pbvh_bmesh_edge_tag_verify(bvh);
|
pbvh_bmesh_edge_tag_verify(bvh);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (int n = 0; n < bvh->totnode; n++) {
|
||||||
for (n = 0; n < bvh->totnode; n++) {
|
|
||||||
PBVHNode *node = &bvh->nodes[n];
|
PBVHNode *node = &bvh->nodes[n];
|
||||||
|
|
||||||
/* Check leaf nodes marked for topology update */
|
/* 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],
|
PBVH *bvh, const float center[3], const float view_normal[3],
|
||||||
float radius)
|
float radius)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
|
|
||||||
eq_ctx->q->heap = BLI_heap_new();
|
eq_ctx->q->heap = BLI_heap_new();
|
||||||
eq_ctx->q->center = center;
|
eq_ctx->q->center = center;
|
||||||
eq_ctx->q->radius_squared = radius * radius;
|
eq_ctx->q->radius_squared = radius * radius;
|
||||||
@@ -946,7 +900,7 @@ static void short_edge_queue_create(
|
|||||||
UNUSED_VARS(view_normal);
|
UNUSED_VARS(view_normal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (n = 0; n < bvh->totnode; n++) {
|
for (int n = 0; n < bvh->totnode; n++) {
|
||||||
PBVHNode *node = &bvh->nodes[n];
|
PBVHNode *node = &bvh->nodes[n];
|
||||||
|
|
||||||
/* Check leaf nodes marked for topology update */
|
/* Check leaf nodes marked for topology update */
|
||||||
@@ -979,9 +933,7 @@ static void pbvh_bmesh_split_edge(
|
|||||||
EdgeQueueContext *eq_ctx, PBVH *bvh,
|
EdgeQueueContext *eq_ctx, PBVH *bvh,
|
||||||
BMEdge *e, BLI_Buffer *edge_loops)
|
BMEdge *e, BLI_Buffer *edge_loops)
|
||||||
{
|
{
|
||||||
BMVert *v_new;
|
|
||||||
float co_mid[3], no_mid[3];
|
float co_mid[3], no_mid[3];
|
||||||
int i, node_index;
|
|
||||||
|
|
||||||
/* Get all faces adjacent to the edge */
|
/* Get all faces adjacent to the edge */
|
||||||
pbvh_bmesh_edge_loops(edge_loops, e);
|
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);
|
mid_v3_v3v3(no_mid, e->v1->no, e->v2->no);
|
||||||
normalize_v3(no_mid);
|
normalize_v3(no_mid);
|
||||||
|
|
||||||
node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
|
int 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);
|
BMVert *v_new = pbvh_bmesh_vert_create(bvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
|
||||||
|
|
||||||
/* update paint mask */
|
/* update paint mask */
|
||||||
if (eq_ctx->cd_vert_mask_offset != -1) {
|
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 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);
|
BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
|
||||||
BMFace *f_adj = l_adj->f;
|
BMFace *f_adj = l_adj->f;
|
||||||
BMFace *f_new;
|
BMFace *f_new;
|
||||||
BMVert *v_opp, *v1, *v2;
|
BMVert *v_opp, *v1, *v2;
|
||||||
BMVert *v_tri[3];
|
BMVert *v_tri[3];
|
||||||
BMEdge *e_tri[3];
|
BMEdge *e_tri[3];
|
||||||
int ni;
|
|
||||||
|
|
||||||
BLI_assert(f_adj->len == 3);
|
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 */
|
/* Find the vertex not in the edge */
|
||||||
v_opp = l_adj->prev->v;
|
v_opp = l_adj->prev->v;
|
||||||
@@ -1153,11 +1104,7 @@ static void pbvh_bmesh_collapse_edge(
|
|||||||
BLI_Buffer *deleted_faces,
|
BLI_Buffer *deleted_faces,
|
||||||
EdgeQueueContext *eq_ctx)
|
EdgeQueueContext *eq_ctx)
|
||||||
{
|
{
|
||||||
BMIter bm_iter;
|
|
||||||
BMFace *f;
|
|
||||||
BMLoop *l_adj;
|
|
||||||
BMVert *v_del, *v_conn;
|
BMVert *v_del, *v_conn;
|
||||||
int i;
|
|
||||||
float mask_v1 = BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset);
|
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 */
|
/* 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);
|
pbvh_bmesh_vert_remove(bvh, v_del);
|
||||||
|
|
||||||
/* Remove all faces adjacent to the edge */
|
/* Remove all faces adjacent to the edge */
|
||||||
|
BMLoop *l_adj;
|
||||||
while ((l_adj = e->l)) {
|
while ((l_adj = e->l)) {
|
||||||
BMFace *f_adj = l_adj->f;
|
BMFace *f_adj = l_adj->f;
|
||||||
|
|
||||||
@@ -1192,16 +1140,17 @@ static void pbvh_bmesh_collapse_edge(
|
|||||||
* really buy anything. */
|
* really buy anything. */
|
||||||
BLI_buffer_empty(deleted_faces);
|
BLI_buffer_empty(deleted_faces);
|
||||||
|
|
||||||
|
BMIter bm_iter;
|
||||||
|
BMFace *f;
|
||||||
|
|
||||||
BM_ITER_ELEM (f, &bm_iter, v_del, BM_FACES_OF_VERT) {
|
BM_ITER_ELEM (f, &bm_iter, v_del, BM_FACES_OF_VERT) {
|
||||||
BMVert *v_tri[3];
|
BMVert *v_tri[3];
|
||||||
BMFace *existing_face;
|
BMFace *existing_face;
|
||||||
PBVHNode *n;
|
|
||||||
int ni;
|
|
||||||
|
|
||||||
/* Get vertices, replace use of v_del with v_conn */
|
/* 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_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3);
|
||||||
BM_face_as_array_vert_tri(f, v_tri);
|
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) {
|
if (v_tri[i] == v_del) {
|
||||||
v_tri[i] = v_conn;
|
v_tri[i] = v_conn;
|
||||||
}
|
}
|
||||||
@@ -1217,8 +1166,8 @@ static void pbvh_bmesh_collapse_edge(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BMEdge *e_tri[3];
|
BMEdge *e_tri[3];
|
||||||
n = pbvh_bmesh_node_lookup(bvh, f);
|
PBVHNode *n = pbvh_bmesh_node_lookup(bvh, f);
|
||||||
ni = n - bvh->nodes;
|
int ni = n - bvh->nodes;
|
||||||
bm_edges_from_tri(bvh->bm, v_tri, e_tri);
|
bm_edges_from_tri(bvh->bm, v_tri, e_tri);
|
||||||
pbvh_bmesh_face_create(bvh, ni, v_tri, e_tri, f);
|
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 */
|
/* 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);
|
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 */
|
/* Get vertices and edges of face */
|
||||||
BLI_assert(f_del->len == 3);
|
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[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[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;
|
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
|
/* Check if any of the face's edges are now unused by any
|
||||||
* face, if so delete them */
|
* 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]))
|
if (BM_edge_is_wire(e_tri[j]))
|
||||||
BM_edge_kill(bvh->bm, e_tri[j]);
|
BM_edge_kill(bvh->bm, e_tri[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if any of the face's vertices are now unused, if so
|
/* Check if any of the face's vertices are now unused, if so
|
||||||
* remove them from the PBVH */
|
* 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)) {
|
if ((v_tri[j] != v_del) && (v_tri[j]->e == NULL)) {
|
||||||
BLI_gset_insert(deleted_verts, v_tri[j]);
|
BLI_gset_insert(deleted_verts, v_tri[j]);
|
||||||
pbvh_bmesh_vert_remove(bvh, v_tri[j]);
|
pbvh_bmesh_vert_remove(bvh, v_tri[j]);
|
||||||
@@ -1291,18 +1238,14 @@ static bool pbvh_bmesh_collapse_short_edges(
|
|||||||
PBVH *bvh,
|
PBVH *bvh,
|
||||||
BLI_Buffer *deleted_faces)
|
BLI_Buffer *deleted_faces)
|
||||||
{
|
{
|
||||||
float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
|
const float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
|
||||||
GSet *deleted_verts;
|
|
||||||
bool any_collapsed = false;
|
bool any_collapsed = false;
|
||||||
|
GSet *deleted_verts = BLI_gset_ptr_new("deleted_verts");
|
||||||
deleted_verts = BLI_gset_ptr_new("deleted_verts");
|
|
||||||
|
|
||||||
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
|
while (!BLI_heap_is_empty(eq_ctx->q->heap)) {
|
||||||
BMVert **pair = BLI_heap_popmin(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);
|
BLI_mempool_free(eq_ctx->pool, pair);
|
||||||
|
BMVert *v1 = pair[0], *v2 = pair[1];
|
||||||
pair = NULL;
|
pair = NULL;
|
||||||
|
|
||||||
/* Check the verts still exist */
|
/* Check the verts still exist */
|
||||||
@@ -1313,6 +1256,7 @@ static bool pbvh_bmesh_collapse_short_edges(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the edge still exists */
|
/* Check that the edge still exists */
|
||||||
|
BMEdge *e;
|
||||||
if (!(e = BM_edge_exists(v1, v2))) {
|
if (!(e = BM_edge_exists(v1, v2))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1355,8 +1299,7 @@ bool pbvh_bmesh_node_raycast(
|
|||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
if (use_original && node->bm_tot_ortri) {
|
if (use_original && node->bm_tot_ortri) {
|
||||||
int i;
|
for (int i = 0; i < node->bm_tot_ortri; i++) {
|
||||||
for (i = 0; i < node->bm_tot_ortri; i++) {
|
|
||||||
const int *t = node->bm_ortri[i];
|
const int *t = node->bm_ortri[i];
|
||||||
hit |= ray_face_intersection_tri(
|
hit |= ray_face_intersection_tri(
|
||||||
ray_start, ray_normal,
|
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],
|
const float ray_start[3], const float ray_normal[3],
|
||||||
float *dist, float *r_detail)
|
float *dist, float *r_detail)
|
||||||
{
|
{
|
||||||
|
if (node->flag & PBVH_FullyHidden)
|
||||||
|
return 0;
|
||||||
|
|
||||||
GSetIterator gs_iter;
|
GSetIterator gs_iter;
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
BMFace *f_hit = NULL;
|
BMFace *f_hit = NULL;
|
||||||
|
|
||||||
if (node->flag & PBVH_FullyHidden)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
GSET_ITER (gs_iter, node->bm_faces) {
|
GSET_ITER (gs_iter, node->bm_faces) {
|
||||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
|
|
||||||
@@ -1425,12 +1368,11 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
float len1, len2, len3;
|
|
||||||
BMVert *v_tri[3];
|
BMVert *v_tri[3];
|
||||||
BM_face_as_array_vert_tri(f_hit, v_tri);
|
BM_face_as_array_vert_tri(f_hit, v_tri);
|
||||||
len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
|
float len1 = len_squared_v3v3(v_tri[0]->co, v_tri[1]->co);
|
||||||
len2 = len_squared_v3v3(v_tri[1]->co, v_tri[2]->co);
|
float 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 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_detail = sqrtf(max_fff(len1, len2, len3));
|
*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)
|
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
|
||||||
{
|
{
|
||||||
int n;
|
for (int n = 0; n < totnode; n++) {
|
||||||
|
|
||||||
for (n = 0; n < totnode; n++) {
|
|
||||||
PBVHNode *node = nodes[n];
|
PBVHNode *node = nodes[n];
|
||||||
|
|
||||||
if (node->flag & PBVH_UpdateNormals) {
|
if (node->flag & PBVH_UpdateNormals) {
|
||||||
@@ -1476,25 +1416,18 @@ typedef struct FastNodeBuildInfo {
|
|||||||
* to a sub part of the arrays */
|
* 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)
|
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;
|
FastNodeBuildInfo *child1, *child2;
|
||||||
int num_child1, num_child2;
|
|
||||||
BMFace *tmp;
|
|
||||||
|
|
||||||
if (node->totface <= bvh->leaf_limit) {
|
if (node->totface <= bvh->leaf_limit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate bounding box around primitive centroids */
|
/* Calculate bounding box around primitive centroids */
|
||||||
|
BB cb;
|
||||||
BB_reset(&cb);
|
BB_reset(&cb);
|
||||||
for (i = 0; i < node->totface; i++) {
|
for (int i = 0; i < node->totface; i++) {
|
||||||
f = nodeinfo[i + node->start];
|
BMFace *f = nodeinfo[i + node->start];
|
||||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||||
|
|
||||||
BB_expand(&cb, bbc->bcentroid);
|
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 */
|
/* initialize the children */
|
||||||
|
|
||||||
/* Find widest axis and its midpoint */
|
/* Find widest axis and its midpoint */
|
||||||
axis = BB_widest_axis(&cb);
|
const int axis = BB_widest_axis(&cb);
|
||||||
mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
|
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 */
|
/* split vertices along the middle line */
|
||||||
end = node->start + node->totface;
|
const int end = node->start + node->totface;
|
||||||
for (i = node->start; i < end - num_child2; i++) {
|
for (int i = node->start; i < end - num_child2; i++) {
|
||||||
f = nodeinfo[i];
|
BMFace *f = nodeinfo[i];
|
||||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||||
|
|
||||||
if (bbc->bcentroid[axis] > mid) {
|
if (bbc->bcentroid[axis] > mid) {
|
||||||
int i_iter = end - num_child2 - 1;
|
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) {
|
if (candidate != -1) {
|
||||||
tmp = nodeinfo[i];
|
BMFace *tmp = nodeinfo[i];
|
||||||
nodeinfo[i] = nodeinfo[candidate];
|
nodeinfo[i] = nodeinfo[candidate];
|
||||||
nodeinfo[candidate] = tmp;
|
nodeinfo[candidate] = tmp;
|
||||||
/* increase both counts */
|
/* 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, child1, arena);
|
||||||
pbvh_bmesh_node_limit_ensure_fast(bvh, nodeinfo, bbc_array, child2, 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)
|
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;
|
const int cd_face_node_offset = bvh->cd_face_node_offset;
|
||||||
|
|
||||||
bool has_visible = false;
|
bool has_visible = false;
|
||||||
int i, end;
|
|
||||||
BMFace *f;
|
|
||||||
BMLoop *l_iter;
|
|
||||||
BMLoop *l_first;
|
|
||||||
BMVert *v;
|
|
||||||
BBC *bbc;
|
|
||||||
|
|
||||||
n->flag = PBVH_Leaf;
|
n->flag = PBVH_Leaf;
|
||||||
n->bm_faces = BLI_gset_ptr_new_ex("bm_faces", node->totface);
|
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);
|
BB_reset(&n->vb);
|
||||||
|
|
||||||
end = node->start + node->totface;
|
const int end = node->start + node->totface;
|
||||||
|
|
||||||
for (i = node->start; i < end; i++) {
|
for (int i = node->start; i < end; i++) {
|
||||||
f = nodeinfo[i];
|
BMFace *f = nodeinfo[i];
|
||||||
bbc = &bbc_array[BM_elem_index_get(f)];
|
BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||||
|
|
||||||
/* Update ownership of faces */
|
/* Update ownership of faces */
|
||||||
BLI_gset_insert(n->bm_faces, f);
|
BLI_gset_insert(n->bm_faces, f);
|
||||||
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
|
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
|
||||||
|
|
||||||
/* Update vertices */
|
/* 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 {
|
do {
|
||||||
v = l_iter->v;
|
BMVert *v = l_iter->v;
|
||||||
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
if (!BLI_gset_haskey(n->bm_unique_verts, v)) {
|
||||||
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||||
BLI_gset_add(n->bm_other_verts, v);
|
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] &&
|
BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
|
||||||
n->vb.bmin[1] <= n->vb.bmax[1] &&
|
n->vb.bmin[1] <= n->vb.bmax[1] &&
|
||||||
n->vb.bmin[2] <= n->vb.bmax[2]);
|
n->vb.bmin[2] <= n->vb.bmax[2]);
|
||||||
|
|
||||||
n->orig_vb = n->vb;
|
n->orig_vb = n->vb;
|
||||||
|
|
||||||
@@ -1675,16 +1601,6 @@ void BKE_pbvh_build_bmesh(
|
|||||||
PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log,
|
PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log,
|
||||||
const int cd_vert_node_offset, const int cd_face_node_offset)
|
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_vert_node_offset = cd_vert_node_offset;
|
||||||
bvh->cd_face_node_offset = cd_face_node_offset;
|
bvh->cd_face_node_offset = cd_face_node_offset;
|
||||||
bvh->bm = bm;
|
bvh->bm = bm;
|
||||||
@@ -1700,18 +1616,20 @@ void BKE_pbvh_build_bmesh(
|
|||||||
if (smooth_shading)
|
if (smooth_shading)
|
||||||
bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
|
bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
|
||||||
|
|
||||||
/* calculate all bounding boxes once for all faces */
|
/* bounding box array of all faces, no need to recalculate every time */
|
||||||
bbc_array = MEM_mallocN(sizeof(BBC) * bm->totface, "BBC");
|
BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm->totface, "BBC");
|
||||||
nodeinfo = MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo");
|
BMFace **nodeinfo = MEM_mallocN(sizeof(*nodeinfo) * bm->totface, "nodeinfo");
|
||||||
arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast PBVH node storage");
|
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) {
|
BM_ITER_MESH_INDEX(f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||||
BBC *bbc = &bbc_array[i];
|
BBC *bbc = &bbc_array[i];
|
||||||
BMLoop *l_iter;
|
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||||
BMLoop *l_first;
|
BMLoop *l_iter = l_first;
|
||||||
|
|
||||||
BB_reset((BB *)bbc);
|
BB_reset((BB *)bbc);
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
|
||||||
do {
|
do {
|
||||||
BB_expand((BB *)bbc, l_iter->v->co);
|
BB_expand((BB *)bbc, l_iter->v->co);
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} 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);
|
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_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||||
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
|
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;
|
bm->elem_index_dirty |= BM_FACE;
|
||||||
|
|
||||||
/* setup root node */
|
/* setup root node */
|
||||||
|
FastNodeBuildInfo rootnode = {0};
|
||||||
rootnode.totface = bm->totface;
|
rootnode.totface = bm->totface;
|
||||||
|
|
||||||
/* start recursion, assign faces to nodes accordingly */
|
/* 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;
|
const int cd_face_node_offset = bvh->cd_face_node_offset;
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
int n;
|
|
||||||
|
|
||||||
if (view_normal) {
|
if (view_normal) {
|
||||||
BLI_assert(len_squared_v3(view_normal) != 0.0f);
|
BLI_assert(len_squared_v3(view_normal) != 0.0f);
|
||||||
@@ -1796,7 +1715,7 @@ bool BKE_pbvh_bmesh_update_topology(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unmark nodes */
|
/* Unmark nodes */
|
||||||
for (n = 0; n < bvh->totnode; n++) {
|
for (int n = 0; n < bvh->totnode; n++) {
|
||||||
PBVHNode *node = &bvh->nodes[n];
|
PBVHNode *node = &bvh->nodes[n];
|
||||||
|
|
||||||
if (node->flag & PBVH_Leaf &&
|
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. */
|
* Skips triangles that are hidden. */
|
||||||
void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
|
void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
|
||||||
{
|
{
|
||||||
GSetIterator gs_iter;
|
|
||||||
int i, totvert, tottri;
|
|
||||||
|
|
||||||
/* Skip if original coords/triangles are already saved */
|
/* Skip if original coords/triangles are already saved */
|
||||||
if (node->bm_orco)
|
if (node->bm_orco)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
totvert = (BLI_gset_size(node->bm_unique_verts) +
|
const int totvert = BLI_gset_size(node->bm_unique_verts) +
|
||||||
BLI_gset_size(node->bm_other_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_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__);
|
||||||
node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
|
node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__);
|
||||||
|
|
||||||
/* Copy out the vertices and assign a temporary index */
|
/* 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) {
|
GSET_ITER (gs_iter, node->bm_unique_verts) {
|
||||||
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
|
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
|
||||||
copy_v3_v3(node->bm_orco[i], v->co);
|
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)
|
void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < bvh->totnode; i++) {
|
||||||
|
|
||||||
for (i = 0; i < bvh->totnode; i++) {
|
|
||||||
PBVHNode *n = &bvh->nodes[i];
|
PBVHNode *n = &bvh->nodes[i];
|
||||||
if (n->flag & PBVH_Leaf) {
|
if (n->flag & PBVH_Leaf) {
|
||||||
/* Free orco/ortri data */
|
/* Free orco/ortri data */
|
||||||
@@ -1935,15 +1850,11 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node)
|
|||||||
|
|
||||||
static void pbvh_bmesh_print(PBVH *bvh)
|
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, "\npbvh=%p\n", bvh);
|
||||||
fprintf(stderr, "bm_face_to_node:\n");
|
fprintf(stderr, "bm_face_to_node:\n");
|
||||||
|
|
||||||
|
BMIter iter;
|
||||||
|
BMFace *f;
|
||||||
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||||
fprintf(stderr, " %d -> %d\n",
|
fprintf(stderr, " %d -> %d\n",
|
||||||
BM_elem_index_get(v),
|
BM_elem_index_get(v),
|
||||||
@@ -1951,17 +1862,19 @@ static void pbvh_bmesh_print(PBVH *bvh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "bm_vert_to_node:\n");
|
fprintf(stderr, "bm_vert_to_node:\n");
|
||||||
|
BMVert *v;
|
||||||
BM_ITER_MESH(v, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH(v, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||||
fprintf(stderr, " %d -> %d\n",
|
fprintf(stderr, " %d -> %d\n",
|
||||||
BM_elem_index_get(v),
|
BM_elem_index_get(v),
|
||||||
pbvh_bmesh_node_lookup_index(bvh, 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];
|
PBVHNode *node = &bvh->nodes[n];
|
||||||
if (!(node->flag & PBVH_Leaf))
|
if (!(node->flag & PBVH_Leaf))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
GSetIterator gs_iter;
|
||||||
fprintf(stderr, "node %d\n faces:\n", n);
|
fprintf(stderr, "node %d\n faces:\n", n);
|
||||||
GSET_ITER (gs_iter, node->bm_faces)
|
GSET_ITER (gs_iter, node->bm_faces)
|
||||||
fprintf(stderr, " %d\n",
|
fprintf(stderr, " %d\n",
|
||||||
@@ -1979,9 +1892,8 @@ static void pbvh_bmesh_print(PBVH *bvh)
|
|||||||
|
|
||||||
static void print_flag_factors(int flag)
|
static void print_flag_factors(int flag)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
printf("flag=0x%x:\n", flag);
|
printf("flag=0x%x:\n", flag);
|
||||||
for (i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
if (flag & (1 << i)) {
|
if (flag & (1 << i)) {
|
||||||
printf(" %d (1 << %d)\n", 1 << i, 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)
|
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 */
|
/* build list of faces & verts to lookup */
|
||||||
faces_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totface);
|
GSet *faces_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totface);
|
||||||
verts_all = BLI_gset_ptr_new_ex(__func__, bvh->bm->totvert);
|
BMFace *f;
|
||||||
|
BMIter iter;
|
||||||
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH(f, &iter, bvh->bm, BM_FACES_OF_MESH) {
|
||||||
BLI_gset_insert(faces_all, f);
|
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) {
|
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) {
|
if (BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||||
BLI_gset_insert(verts_all, v);
|
BLI_gset_insert(verts_all, v);
|
||||||
@@ -2020,7 +1925,7 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||||||
/* Check vert/face counts */
|
/* Check vert/face counts */
|
||||||
{
|
{
|
||||||
int totface = 0, totvert = 0;
|
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];
|
PBVHNode *n = &bvh->nodes[i];
|
||||||
totface += n->bm_faces ? BLI_gset_size(n->bm_faces) : 0;
|
totface += n->bm_faces ? BLI_gset_size(n->bm_faces) : 0;
|
||||||
totvert += n->bm_unique_verts ? BLI_gset_size(n->bm_unique_verts) : 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 */
|
/* Check verts */
|
||||||
BM_ITER_MESH(v, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
BM_ITER_MESH(v, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
||||||
BMIter bm_iter;
|
|
||||||
PBVHNode *n;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
/* vertex isn't tracked */
|
/* vertex isn't tracked */
|
||||||
if (BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
|
if (BM_ELEM_CD_GET_INT(v, bvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
|
||||||
continue;
|
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 */
|
/* Check that the vert's node is a leaf */
|
||||||
BLI_assert(n->flag & PBVH_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
|
/* Check that the vert's node also contains one of the vert's
|
||||||
* adjacent faces */
|
* adjacent faces */
|
||||||
|
bool found = false;
|
||||||
|
BMIter bm_iter;
|
||||||
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
|
||||||
if (pbvh_bmesh_node_lookup(bvh, f) == n) {
|
if (pbvh_bmesh_node_lookup(bvh, f) == n) {
|
||||||
found = true;
|
found = true;
|
||||||
@@ -2095,13 +1998,12 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||||||
#if 1
|
#if 1
|
||||||
/* total freak stuff, check if node exists somewhere else */
|
/* total freak stuff, check if node exists somewhere else */
|
||||||
/* Slow */
|
/* Slow */
|
||||||
for (i = 0; i < bvh->totnode; i++) {
|
for (int i = 0; i < bvh->totnode; i++) {
|
||||||
PBVHNode *n_other = &bvh->nodes[i];
|
PBVHNode *n_other = &bvh->nodes[i];
|
||||||
if ((n != n_other) && (n_other->bm_unique_verts)) {
|
if ((n != n_other) && (n_other->bm_unique_verts)) {
|
||||||
BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts, v));
|
BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts, v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2110,7 +2012,7 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||||||
/* Slow */
|
/* Slow */
|
||||||
BM_ITER_MESH (vi, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
BM_ITER_MESH (vi, &iter, bvh->bm, BM_VERTS_OF_MESH) {
|
||||||
bool has_unique = false;
|
bool has_unique = false;
|
||||||
for (i = 0; i < bvh->totnode; i++) {
|
for (int i = 0; i < bvh->totnode; i++) {
|
||||||
PBVHNode *n = &bvh->nodes[i];
|
PBVHNode *n = &bvh->nodes[i];
|
||||||
if ((n->bm_unique_verts != NULL) && BLI_gset_haskey(n->bm_unique_verts, vi))
|
if ((n->bm_unique_verts != NULL) && BLI_gset_haskey(n->bm_unique_verts, vi))
|
||||||
has_unique = true;
|
has_unique = true;
|
||||||
@@ -2124,9 +2026,10 @@ static void pbvh_bmesh_verify(PBVH *bvh)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check that node elements are recorded in the top level */
|
/* 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];
|
PBVHNode *n = &bvh->nodes[i];
|
||||||
if (n->flag & PBVH_Leaf) {
|
if (n->flag & PBVH_Leaf) {
|
||||||
|
GSetIterator gs_iter;
|
||||||
|
|
||||||
GSET_ITER (gs_iter, n->bm_faces) {
|
GSET_ITER (gs_iter, n->bm_faces) {
|
||||||
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
|
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;
|
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_free(GHashIterator *ghi);
|
||||||
void BLI_ghashIterator_step(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
|
# define _gh_Entry void
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GHASH_ITER(gh_iter_, ghash_) \
|
#define GHASH_ITER(gh_iter_, ghash_) \
|
||||||
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
||||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||||
BLI_ghashIterator_step(&gh_iter_))
|
BLI_ghashIterator_step(&gh_iter_))
|
||||||
|
|
||||||
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_) \
|
#define GHASH_ITER_INDEX(gh_iter_, ghash_, i_) \
|
||||||
for (BLI_ghashIterator_init(&gh_iter_, ghash_), i_ = 0; \
|
for (unsigned i_ = BLI_ghashIterator_init(&gh_iter_, ghash_); \
|
||||||
BLI_ghashIterator_done(&gh_iter_) == false; \
|
BLI_ghashIterator_done(&gh_iter_) == false; \
|
||||||
BLI_ghashIterator_step(&gh_iter_), i_++)
|
BLI_ghashIterator_step(&gh_iter_), i_++)
|
||||||
|
|
||||||
/** \name Callbacks for GHash
|
/** \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 */
|
/* rely on inline api for now */
|
||||||
BLI_INLINE GSetIterator *BLI_gsetIterator_new(GSet *gs) { return (GSetIterator *)BLI_ghashIterator_new((GHash *)gs); }
|
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_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_getKey(GSetIterator *gsi) { return BLI_ghashIterator_getKey((GHashIterator *)gsi); }
|
||||||
BLI_INLINE void BLI_gsetIterator_step(GSetIterator *gsi) { BLI_ghashIterator_step((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); }
|
BLI_INLINE bool BLI_gsetIterator_done(GSetIterator *gsi) { return BLI_ghashIterator_done((GHashIterator *)gsi); }
|
||||||
|
|
||||||
#define GSET_ITER(gs_iter_, gset_) \
|
#define GSET_ITER(gs_iter_, gset_) \
|
||||||
for (BLI_gsetIterator_init(&gs_iter_, gset_); \
|
for (BLI_gsetIterator_init(&gs_iter_, gset_); \
|
||||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||||
BLI_gsetIterator_step(&gs_iter_))
|
BLI_gsetIterator_step(&gs_iter_))
|
||||||
|
|
||||||
#define GSET_ITER_INDEX(gs_iter_, gset_, i_) \
|
#define GSET_ITER_INDEX(gs_iter_, gset_, i_) \
|
||||||
for (BLI_gsetIterator_init(&gs_iter_, gset_), i_ = 0; \
|
for (unsigned i_ = BLI_gsetIterator_init(&gs_iter_, gset_); \
|
||||||
BLI_gsetIterator_done(&gs_iter_) == false; \
|
BLI_gsetIterator_done(&gs_iter_) == false; \
|
||||||
BLI_gsetIterator_step(&gs_iter_), i_++)
|
BLI_gsetIterator_step(&gs_iter_), i_++)
|
||||||
|
|
||||||
|
|
||||||
/* For testing, debugging only */
|
/* For testing, debugging only */
|
||||||
|
@@ -934,7 +934,7 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh)
|
|||||||
* \param ghi The GHashIterator to initialize.
|
* \param ghi The GHashIterator to initialize.
|
||||||
* \param gh The GHash to iterate over.
|
* \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->gh = gh;
|
||||||
ghi->curEntry = NULL;
|
ghi->curEntry = NULL;
|
||||||
@@ -947,6 +947,7 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
|
|||||||
ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
|
ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
|
||||||
} while (!ghi->curEntry);
|
} 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,
|
GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
|
||||||
unsigned int **grid_hidden, int gridsize, const struct CCGKey *key);
|
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 */
|
/* update */
|
||||||
|
|
||||||
|
@@ -28,8 +28,7 @@
|
|||||||
/** \file blender/gpu/intern/gpu_buffers.c
|
/** \file blender/gpu/intern/gpu_buffers.c
|
||||||
* \ingroup gpu
|
* \ingroup gpu
|
||||||
*
|
*
|
||||||
* Mesh drawing using OpenGL VBO (Vertex Buffer Objects),
|
* Mesh drawing using OpenGL VBO (Vertex Buffer Objects)
|
||||||
* with fall-back to vertex arrays.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -101,7 +100,6 @@ const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
|
|||||||
|
|
||||||
#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
|
#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
|
||||||
|
|
||||||
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
|
|
||||||
static GPUBufferState GLStates = 0;
|
static GPUBufferState GLStates = 0;
|
||||||
static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 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)
|
if (GLStates & GPU_BUFFER_COLOR_STATE)
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
|
if (GLStates & GPU_BUFFER_ELEMENT_STATE)
|
||||||
/* not guaranteed we used VBOs but in that case it's just a no-op */
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
|
||||||
GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
|
GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
|
||||||
GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
|
GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
|
||||||
GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
|
GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
|
||||||
@@ -881,7 +878,6 @@ void GPU_buffers_unbind(void)
|
|||||||
}
|
}
|
||||||
attribData[0].index = -1;
|
attribData[0].index = -1;
|
||||||
|
|
||||||
/* not guaranteed we used VBOs but in that case it's just a no-op */
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,15 +1000,15 @@ struct GPU_PBVH_Buffers {
|
|||||||
BLI_bitmap * const *grid_hidden;
|
BLI_bitmap * const *grid_hidden;
|
||||||
const int *grid_indices;
|
const int *grid_indices;
|
||||||
int totgrid;
|
int totgrid;
|
||||||
int has_hidden;
|
bool has_hidden;
|
||||||
|
|
||||||
int use_bmesh;
|
bool use_bmesh;
|
||||||
|
|
||||||
unsigned int tot_tri, tot_quad;
|
unsigned int tot_tri, tot_quad;
|
||||||
|
|
||||||
/* The PBVH ensures that either all faces in the node are
|
/* The PBVH ensures that either all faces in the node are
|
||||||
* smooth-shaded or all faces are flat-shaded */
|
* smooth-shaded or all faces are flat-shaded */
|
||||||
int smooth;
|
bool smooth;
|
||||||
|
|
||||||
bool show_diffuse_color;
|
bool show_diffuse_color;
|
||||||
bool use_matcaps;
|
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->show_diffuse_color = show_diffuse_color;
|
||||||
buffers->use_matcaps = GPU_material_use_matcaps_get();
|
buffers->use_matcaps = GPU_material_use_matcaps_get();
|
||||||
|
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
||||||
|
|
||||||
/* Build VBO */
|
/* Build VBO */
|
||||||
if (buffers->vert_buf) {
|
if (buffers->vert_buf) {
|
||||||
int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
|
||||||
const int has_mask = key->has_mask;
|
const int has_mask = key->has_mask;
|
||||||
float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
|
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);
|
CCGElem *elem = CCG_grid_elem(key, grid, x, y);
|
||||||
|
|
||||||
copy_v3_v3(vd->co, CCG_elem_co(key, elem));
|
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));
|
normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
|
||||||
|
|
||||||
if (has_mask) {
|
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
|
/* for flat shading, recalc normals and set the last vertex of
|
||||||
* each triangle in the index buffer to have the flat normal as
|
* each triangle in the index buffer to have the flat normal as
|
||||||
* that is what opengl will use */
|
* 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->grid_flag_mats = grid_flag_mats;
|
||||||
buffers->gridkey = *key;
|
buffers->gridkey = *key;
|
||||||
|
|
||||||
buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
|
|
||||||
|
|
||||||
//printf("node updated %p\n", buffers);
|
//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) {
|
if (totquad == fully_visible_totquad) {
|
||||||
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
|
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
|
||||||
buffers->has_hidden = 0;
|
buffers->has_hidden = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buffers->tot_quad = totquad;
|
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);
|
FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers->has_hidden = 1;
|
buffers->has_hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build coord/normal VBO */
|
/* 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;
|
GPU_PBVH_Buffers *buffers;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user