Add dynamic topology support to the PBVH
* Add BLI_pbvh_build_bmesh(), similar to the other PBVH builders but specialized for BMesh. Whereas the PBVH leaf nodes for mesh and grids only store a start-index and count into the primitive indices array, the BMesh version uses GHashes to store the full set of faces and vertices in leaf nodes * Update PBVH iterator to handle BMesh * Make some of the pbvh.c functions non-static so they can be used by the new pbvh_bmesh code * The BLI_pbvh_bmesh_update_topology() function is the main reason for adding BMesh support to the PBVH. This function is used during a sculpt stroke to dynamically collapse edges that are particular short and subdivide edges that are particularly long.
This commit is contained in:
@@ -27,13 +27,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BLI_bitmap.h"
|
#include "BLI_bitmap.h"
|
||||||
|
#include "BLI_ghash.h"
|
||||||
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
|
/* Needed for BMesh functions used in the PBVH iterator macro */
|
||||||
|
#include "bmesh.h"
|
||||||
|
|
||||||
struct CCGElem;
|
struct CCGElem;
|
||||||
struct CCGKey;
|
struct CCGKey;
|
||||||
struct CustomData;
|
struct CustomData;
|
||||||
struct DMFlagMat;
|
struct DMFlagMat;
|
||||||
struct DMGridAdjacency;
|
struct DMGridAdjacency;
|
||||||
struct ListBase;
|
struct GHash;
|
||||||
struct MFace;
|
struct MFace;
|
||||||
struct MVert;
|
struct MVert;
|
||||||
struct PBVH;
|
struct PBVH;
|
||||||
@@ -63,6 +68,9 @@ void BLI_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
|
|||||||
struct DMGridAdjacency *gridadj, int totgrid,
|
struct DMGridAdjacency *gridadj, int totgrid,
|
||||||
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
|
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
|
||||||
unsigned int **grid_hidden);
|
unsigned int **grid_hidden);
|
||||||
|
void BLI_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
|
||||||
|
struct BMLog *log);
|
||||||
|
|
||||||
void BLI_pbvh_free(PBVH *bvh);
|
void BLI_pbvh_free(PBVH *bvh);
|
||||||
|
|
||||||
/* Hierarchical Search in the BVH, two methods:
|
/* Hierarchical Search in the BVH, two methods:
|
||||||
@@ -86,7 +94,7 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
|
|||||||
const float ray_start[3], const float ray_normal[3],
|
const float ray_start[3], const float ray_normal[3],
|
||||||
int original);
|
int original);
|
||||||
|
|
||||||
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int 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);
|
||||||
|
|
||||||
@@ -100,6 +108,7 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
PBVH_FACES,
|
PBVH_FACES,
|
||||||
PBVH_GRIDS,
|
PBVH_GRIDS,
|
||||||
|
PBVH_BMESH
|
||||||
} PBVHType;
|
} PBVHType;
|
||||||
|
|
||||||
PBVHType BLI_pbvh_type(const PBVH *bvh);
|
PBVHType BLI_pbvh_type(const PBVH *bvh);
|
||||||
@@ -110,6 +119,17 @@ unsigned int **BLI_pbvh_grid_hidden(const PBVH *bvh);
|
|||||||
/* multires level, only valid for type == PBVH_GRIDS */
|
/* multires level, only valid for type == PBVH_GRIDS */
|
||||||
void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
|
void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
|
||||||
|
|
||||||
|
/* Only valid for type == PBVH_BMESH */
|
||||||
|
BMesh *BLI_pbvh_get_bmesh(PBVH *pbvh);
|
||||||
|
void BLI_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PBVH_Subdivide = 1,
|
||||||
|
PBVH_Collapse = 2,
|
||||||
|
} PBVHTopologyUpdateMode;
|
||||||
|
int BLI_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
|
||||||
|
const float center[3], float radius);
|
||||||
|
|
||||||
/* Node Access */
|
/* Node Access */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -122,12 +142,15 @@ typedef enum {
|
|||||||
PBVH_UpdateRedraw = 32,
|
PBVH_UpdateRedraw = 32,
|
||||||
|
|
||||||
PBVH_RebuildDrawBuffers = 64,
|
PBVH_RebuildDrawBuffers = 64,
|
||||||
PBVH_FullyHidden = 128
|
PBVH_FullyHidden = 128,
|
||||||
|
|
||||||
|
PBVH_UpdateTopology = 256,
|
||||||
} PBVHNodeFlags;
|
} PBVHNodeFlags;
|
||||||
|
|
||||||
void BLI_pbvh_node_mark_update(PBVHNode *node);
|
void BLI_pbvh_node_mark_update(PBVHNode *node);
|
||||||
void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
|
void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
|
||||||
void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
|
void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
|
||||||
|
void BLI_pbvh_node_mark_topology_update(PBVHNode *node);
|
||||||
|
|
||||||
void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
|
void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
|
||||||
int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
|
int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
|
||||||
@@ -147,6 +170,11 @@ int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
|
|||||||
/* test if AABB is at least partially outside the planes' volume */
|
/* test if AABB is at least partially outside the planes' volume */
|
||||||
int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
|
int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
|
||||||
|
|
||||||
|
struct GHash *BLI_pbvh_bmesh_node_unique_verts(PBVHNode *node);
|
||||||
|
struct GHash *BLI_pbvh_bmesh_node_other_verts(PBVHNode *node);
|
||||||
|
void BLI_pbvh_bmesh_node_save_orig(PBVHNode *node);
|
||||||
|
void BLI_pbvh_bmesh_after_stroke(PBVH *bvh);
|
||||||
|
|
||||||
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
|
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
|
||||||
|
|
||||||
void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
|
void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
|
||||||
@@ -169,7 +197,6 @@ float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
|
|||||||
void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
|
void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
|
||||||
int BLI_pbvh_isDeformed(struct PBVH *pbvh);
|
int BLI_pbvh_isDeformed(struct PBVH *pbvh);
|
||||||
|
|
||||||
|
|
||||||
/* Vertex Iterator */
|
/* Vertex Iterator */
|
||||||
|
|
||||||
/* this iterator has quite a lot of code, but it's designed to:
|
/* this iterator has quite a lot of code, but it's designed to:
|
||||||
@@ -205,9 +232,15 @@ typedef struct PBVHVertexIter {
|
|||||||
int *vert_indices;
|
int *vert_indices;
|
||||||
float *vmask;
|
float *vmask;
|
||||||
|
|
||||||
|
/* bmesh */
|
||||||
|
struct GHashIterator bm_unique_verts;
|
||||||
|
struct GHashIterator bm_other_verts;
|
||||||
|
struct CustomData *bm_vdata;
|
||||||
|
|
||||||
/* result: these are all computed in the macro, but we assume
|
/* result: these are all computed in the macro, but we assume
|
||||||
* that compiler optimization's will skip the ones we don't use */
|
* that compiler optimization's will skip the ones we don't use */
|
||||||
struct MVert *mvert;
|
struct MVert *mvert;
|
||||||
|
struct BMVert *bm_vert;
|
||||||
float *co;
|
float *co;
|
||||||
short *no;
|
short *no;
|
||||||
float *fno;
|
float *fno;
|
||||||
@@ -249,7 +282,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
|
|||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
else { \
|
else if (vi.mverts) { \
|
||||||
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
|
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
|
||||||
if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
|
if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
|
||||||
continue; \
|
continue; \
|
||||||
@@ -258,6 +291,24 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
|
|||||||
if (vi.vmask) \
|
if (vi.vmask) \
|
||||||
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
|
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
|
||||||
} \
|
} \
|
||||||
|
else { \
|
||||||
|
if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
|
||||||
|
vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
|
||||||
|
BLI_ghashIterator_step(&vi.bm_unique_verts); \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_other_verts); \
|
||||||
|
BLI_ghashIterator_step(&vi.bm_other_verts); \
|
||||||
|
} \
|
||||||
|
if (mode == PBVH_ITER_UNIQUE && \
|
||||||
|
BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \
|
||||||
|
continue; \
|
||||||
|
vi.co = vi.bm_vert->co; \
|
||||||
|
vi.fno = vi.bm_vert->no; \
|
||||||
|
vi.mask = CustomData_bmesh_get(vi.bm_vdata, \
|
||||||
|
vi.bm_vert->head.data, \
|
||||||
|
CD_PAINT_MASK); \
|
||||||
|
}
|
||||||
|
|
||||||
#define BLI_pbvh_vertex_iter_end \
|
#define BLI_pbvh_vertex_iter_end \
|
||||||
} \
|
} \
|
||||||
|
@@ -124,6 +124,7 @@ set(SRC
|
|||||||
intern/particle.c
|
intern/particle.c
|
||||||
intern/particle_system.c
|
intern/particle_system.c
|
||||||
intern/pbvh.c
|
intern/pbvh.c
|
||||||
|
intern/pbvh_bmesh.c
|
||||||
intern/pointcache.c
|
intern/pointcache.c
|
||||||
intern/property.c
|
intern/property.c
|
||||||
intern/report.c
|
intern/report.c
|
||||||
|
@@ -66,14 +66,14 @@ typedef struct PBVHIter {
|
|||||||
int stackspace;
|
int stackspace;
|
||||||
} PBVHIter;
|
} PBVHIter;
|
||||||
|
|
||||||
static void BB_reset(BB *bb)
|
void BB_reset(BB *bb)
|
||||||
{
|
{
|
||||||
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
|
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
|
||||||
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
|
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand the bounding box to include a new coordinate */
|
/* Expand the bounding box to include a new coordinate */
|
||||||
static void BB_expand(BB *bb, float co[3])
|
void BB_expand(BB *bb, const float co[3])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
@@ -83,7 +83,7 @@ static void BB_expand(BB *bb, float co[3])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Expand the bounding box to include another bounding box */
|
/* Expand the bounding box to include another bounding box */
|
||||||
static void BB_expand_with_bb(BB *bb, BB *bb2)
|
void BB_expand_with_bb(BB *bb, BB *bb2)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
@@ -93,7 +93,7 @@ static void BB_expand_with_bb(BB *bb, BB *bb2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
|
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
|
||||||
static int BB_widest_axis(BB *bb)
|
int BB_widest_axis(const BB *bb)
|
||||||
{
|
{
|
||||||
float dim[3];
|
float dim[3];
|
||||||
int i;
|
int i;
|
||||||
@@ -115,7 +115,7 @@ static int BB_widest_axis(BB *bb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BBC_update_centroid(BBC *bbc)
|
void BBC_update_centroid(BBC *bbc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 3; ++i)
|
for (i = 0; i < 3; ++i)
|
||||||
@@ -220,7 +220,7 @@ static int partition_indices_material(PBVH *bvh, int lo, int hi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grow_nodes(PBVH *bvh, int totnode)
|
void pbvh_grow_nodes(PBVH *bvh, int totnode)
|
||||||
{
|
{
|
||||||
if (totnode > bvh->node_mem_count) {
|
if (totnode > bvh->node_mem_count) {
|
||||||
PBVHNode *prev = bvh->nodes;
|
PBVHNode *prev = bvh->nodes;
|
||||||
@@ -433,7 +433,7 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
|
|||||||
|
|
||||||
/* Add two child nodes */
|
/* Add two child nodes */
|
||||||
bvh->nodes[node_index].children_offset = bvh->totnode;
|
bvh->nodes[node_index].children_offset = bvh->totnode;
|
||||||
grow_nodes(bvh, bvh->totnode + 2);
|
pbvh_grow_nodes(bvh, bvh->totnode + 2);
|
||||||
|
|
||||||
/* Update parent node bounding box */
|
/* Update parent node bounding box */
|
||||||
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
|
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
|
||||||
@@ -601,6 +601,13 @@ void BLI_pbvh_free(PBVH *bvh)
|
|||||||
if (node->face_vert_indices)
|
if (node->face_vert_indices)
|
||||||
MEM_freeN(node->face_vert_indices);
|
MEM_freeN(node->face_vert_indices);
|
||||||
BLI_pbvh_node_layer_disp_free(node);
|
BLI_pbvh_node_layer_disp_free(node);
|
||||||
|
|
||||||
|
if (node->bm_faces)
|
||||||
|
BLI_ghash_free(node->bm_faces, NULL, NULL);
|
||||||
|
if (node->bm_unique_verts)
|
||||||
|
BLI_ghash_free(node->bm_unique_verts, NULL, NULL);
|
||||||
|
if (node->bm_other_verts)
|
||||||
|
BLI_ghash_free(node->bm_other_verts, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,6 +627,11 @@ void BLI_pbvh_free(PBVH *bvh)
|
|||||||
if (bvh->prim_indices)
|
if (bvh->prim_indices)
|
||||||
MEM_freeN(bvh->prim_indices);
|
MEM_freeN(bvh->prim_indices);
|
||||||
|
|
||||||
|
if (bvh->bm_vert_to_node)
|
||||||
|
BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
|
||||||
|
if (bvh->bm_face_to_node)
|
||||||
|
BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
|
||||||
|
|
||||||
MEM_freeN(bvh);
|
MEM_freeN(bvh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,6 +912,11 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||||||
float (*vnor)[3];
|
float (*vnor)[3];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
if (bvh->type == PBVH_BMESH) {
|
||||||
|
pbvh_bmesh_normals_update(nodes, totnode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (bvh->type != PBVH_FACES)
|
if (bvh->type != PBVH_FACES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -993,8 +1010,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
|
|||||||
MEM_freeN(vnor);
|
MEM_freeN(vnor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
|
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
|
||||||
int totnode, int flag)
|
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
@@ -1041,6 +1057,11 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||||||
node->prim_indices,
|
node->prim_indices,
|
||||||
node->totprim);
|
node->totprim);
|
||||||
break;
|
break;
|
||||||
|
case PBVH_BMESH:
|
||||||
|
node->draw_buffers =
|
||||||
|
GPU_build_bmesh_buffers(bvh->flags &
|
||||||
|
PBVH_DYNTOPO_SMOOTH_SHADING);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->flag &= ~PBVH_RebuildDrawBuffers;
|
node->flag &= ~PBVH_RebuildDrawBuffers;
|
||||||
@@ -1068,6 +1089,13 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
|
|||||||
node->face_vert_indices,
|
node->face_vert_indices,
|
||||||
bvh->show_diffuse_color);
|
bvh->show_diffuse_color);
|
||||||
break;
|
break;
|
||||||
|
case PBVH_BMESH:
|
||||||
|
GPU_update_bmesh_buffers(node->draw_buffers,
|
||||||
|
bvh->bm,
|
||||||
|
node->bm_faces,
|
||||||
|
node->bm_unique_verts,
|
||||||
|
node->bm_other_verts);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->flag &= ~PBVH_UpdateDrawBuffers;
|
node->flag &= ~PBVH_UpdateDrawBuffers;
|
||||||
@@ -1222,6 +1250,12 @@ void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
|
|||||||
*key = bvh->gridkey;
|
*key = bvh->gridkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BMesh *BLI_pbvh_get_bmesh(PBVH *bvh)
|
||||||
|
{
|
||||||
|
BLI_assert(bvh->type == PBVH_BMESH);
|
||||||
|
return bvh->bm;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************** Node Access ***********************************/
|
/***************************** Node Access ***********************************/
|
||||||
|
|
||||||
void BLI_pbvh_node_mark_update(PBVHNode *node)
|
void BLI_pbvh_node_mark_update(PBVHNode *node)
|
||||||
@@ -1264,6 +1298,11 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to
|
|||||||
if (totvert) *totvert = node->uniq_verts + node->face_verts;
|
if (totvert) *totvert = node->uniq_verts + node->face_verts;
|
||||||
if (uniquevert) *uniquevert = node->uniq_verts;
|
if (uniquevert) *uniquevert = node->uniq_verts;
|
||||||
break;
|
break;
|
||||||
|
case PBVH_BMESH:
|
||||||
|
tot = BLI_ghash_size(node->bm_unique_verts);
|
||||||
|
if (totvert) *totvert = tot + BLI_ghash_size(node->bm_other_verts);
|
||||||
|
if (uniquevert) *uniquevert = tot;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,6 +1318,7 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
|
|||||||
if (gridadj) *gridadj = bvh->gridadj;
|
if (gridadj) *gridadj = bvh->gridadj;
|
||||||
break;
|
break;
|
||||||
case PBVH_FACES:
|
case PBVH_FACES:
|
||||||
|
case PBVH_BMESH:
|
||||||
if (grid_indices) *grid_indices = NULL;
|
if (grid_indices) *grid_indices = NULL;
|
||||||
if (totgrid) *totgrid = 0;
|
if (totgrid) *totgrid = 0;
|
||||||
if (maxgrid) *maxgrid = 0;
|
if (maxgrid) *maxgrid = 0;
|
||||||
@@ -1345,11 +1385,11 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
|
|||||||
BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
|
BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ray_face_intersection(const float ray_start[3],
|
int ray_face_intersection(const float ray_start[3],
|
||||||
const float ray_normal[3],
|
const float ray_normal[3],
|
||||||
const float *t0, const float *t1,
|
const float *t0, const float *t1,
|
||||||
const float *t2, const float *t3,
|
const float *t2, const float *t3,
|
||||||
float *fdist)
|
float *fdist)
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
|
|
||||||
@@ -1455,7 +1495,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int 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)
|
||||||
{
|
{
|
||||||
@@ -1473,6 +1513,9 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
|
|||||||
hit |= pbvh_grids_node_raycast(bvh, node, origco,
|
hit |= pbvh_grids_node_raycast(bvh, node, origco,
|
||||||
ray_start, ray_normal, dist);
|
ray_start, ray_normal, dist);
|
||||||
break;
|
break;
|
||||||
|
case PBVH_BMESH:
|
||||||
|
hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hit;
|
return hit;
|
||||||
@@ -1803,12 +1846,18 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
|
|||||||
vi->vert_indices = vert_indices;
|
vi->vert_indices = vert_indices;
|
||||||
vi->mverts = verts;
|
vi->mverts = verts;
|
||||||
|
|
||||||
|
if (bvh->type == PBVH_BMESH) {
|
||||||
|
BLI_ghashIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
|
||||||
|
BLI_ghashIterator_init(&vi->bm_other_verts, node->bm_other_verts);
|
||||||
|
vi->bm_vdata = &bvh->bm->vdata;
|
||||||
|
}
|
||||||
|
|
||||||
vi->gh = NULL;
|
vi->gh = NULL;
|
||||||
if (vi->grids && mode == PBVH_ITER_UNIQUE)
|
if (vi->grids && mode == PBVH_ITER_UNIQUE)
|
||||||
vi->grid_hidden = bvh->grid_hidden;
|
vi->grid_hidden = bvh->grid_hidden;
|
||||||
|
|
||||||
vi->mask = NULL;
|
vi->mask = NULL;
|
||||||
if (!vi->grids)
|
if (bvh->type == PBVH_FACES)
|
||||||
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
|
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1414
source/blender/blenkernel/intern/pbvh_bmesh.c
Normal file
1414
source/blender/blenkernel/intern/pbvh_bmesh.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@ typedef struct {
|
|||||||
float bmin[3], bmax[3], bcentroid[3];
|
float bmin[3], bmax[3], bcentroid[3];
|
||||||
} BBC;
|
} BBC;
|
||||||
|
|
||||||
|
/* Note: this structure is getting large, might want to split it into
|
||||||
|
* union'd structs */
|
||||||
struct PBVHNode {
|
struct PBVHNode {
|
||||||
/* Opaque handle for drawing code */
|
/* Opaque handle for drawing code */
|
||||||
GPU_Buffers *draw_buffers;
|
GPU_Buffers *draw_buffers;
|
||||||
@@ -86,7 +88,7 @@ struct PBVHNode {
|
|||||||
|
|
||||||
/* Indicates whether this node is a leaf or not; also used for
|
/* Indicates whether this node is a leaf or not; also used for
|
||||||
* marking various updates that need to be applied. */
|
* marking various updates that need to be applied. */
|
||||||
PBVHNodeFlags flag : 8;
|
PBVHNodeFlags flag : 16;
|
||||||
|
|
||||||
/* Used for raycasting: how close bb is to the ray point. */
|
/* Used for raycasting: how close bb is to the ray point. */
|
||||||
float tmin;
|
float tmin;
|
||||||
@@ -96,10 +98,25 @@ struct PBVHNode {
|
|||||||
|
|
||||||
int proxy_count;
|
int proxy_count;
|
||||||
PBVHProxyNode *proxies;
|
PBVHProxyNode *proxies;
|
||||||
|
|
||||||
|
/* Dyntopo */
|
||||||
|
GHash *bm_faces;
|
||||||
|
GHash *bm_unique_verts;
|
||||||
|
GHash *bm_other_verts;
|
||||||
|
float (*bm_orco)[3];
|
||||||
|
int (*bm_ortri)[3];
|
||||||
|
int bm_tot_ortri;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PBVH_DYNTOPO_SMOOTH_SHADING = 1
|
||||||
|
} PBVHFlags;
|
||||||
|
|
||||||
|
typedef struct PBVHBMeshLog PBVHBMeshLog;
|
||||||
|
|
||||||
struct PBVH {
|
struct PBVH {
|
||||||
PBVHType type;
|
PBVHType type;
|
||||||
|
PBVHFlags flags;
|
||||||
|
|
||||||
PBVHNode *nodes;
|
PBVHNode *nodes;
|
||||||
int node_mem_count, totnode;
|
int node_mem_count, totnode;
|
||||||
@@ -136,6 +153,34 @@ struct PBVH {
|
|||||||
int deformed;
|
int deformed;
|
||||||
|
|
||||||
int show_diffuse_color;
|
int show_diffuse_color;
|
||||||
|
|
||||||
|
/* Dynamic topology */
|
||||||
|
BMesh *bm;
|
||||||
|
GHash *bm_face_to_node;
|
||||||
|
GHash *bm_vert_to_node;
|
||||||
|
float bm_max_edge_len;
|
||||||
|
float bm_min_edge_len;
|
||||||
|
|
||||||
|
struct BMLog *bm_log;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* pbvh.c */
|
||||||
|
void BB_reset(BB *bb);
|
||||||
|
void BB_expand(BB *bb, const float co[3]);
|
||||||
|
void BB_expand_with_bb(BB *bb, BB *bb2);
|
||||||
|
void BBC_update_centroid(BBC *bbc);
|
||||||
|
int BB_widest_axis(const BB *bb);
|
||||||
|
void pbvh_grow_nodes(PBVH *bvh, int totnode);
|
||||||
|
int ray_face_intersection(const float ray_start[3], const float ray_normal[3],
|
||||||
|
const float *t0, const float *t1, const float *t2,
|
||||||
|
const float *t3, float *fdist);
|
||||||
|
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
|
||||||
|
|
||||||
|
/* pbvh_bmesh.c */
|
||||||
|
int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
|
||||||
|
const float ray_normal[3], float *dist,
|
||||||
|
int use_original);
|
||||||
|
|
||||||
|
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user