Cleanup: Move more PBVH code to C++ namespaces

Also remove redundant parts of function names.
This commit is contained in:
Hans Goudey
2023-12-15 22:51:10 -05:00
parent 912c4c60d8
commit 3d82c9c239
17 changed files with 365 additions and 356 deletions
+70 -67
View File
@@ -157,54 +157,52 @@ PBVH *build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subdiv_ccg);
*/
PBVH *build_bmesh(BMesh *bm, BMLog *log, int cd_vert_node_offset, int cd_face_node_offset);
} // namespace blender::bke::pbvh
void update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset);
void BKE_pbvh_update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset);
void BKE_pbvh_build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user);
void BKE_pbvh_free(PBVH *pbvh);
void build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user);
void free(PBVH *pbvh);
/* Hierarchical Search in the BVH, two methods:
* - For each hit calling a callback.
* - Gather nodes in an array (easy to multi-thread) see blender::bke::pbvh::search_gather.
*/
void BKE_pbvh_search_callback(PBVH *pbvh,
blender::FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitCallback hcb,
void *hit_data);
void search_callback(PBVH *pbvh,
FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitCallback hcb,
void *hit_data);
/* Ray-cast
* the hit callback is called for all leaf nodes intersecting the ray;
* it's up to the callback to find the primitive within the leaves that is
* hit first */
void BKE_pbvh_raycast(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original);
void raycast(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original);
bool BKE_pbvh_node_raycast(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
blender::Span<int> corner_verts,
blender::Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal);
bool raycast_node(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
Span<int> corner_verts,
Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal);
bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length);
bool bmesh_node_raycast_detail(PBVHNode *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length);
/**
* For orthographic cameras, project the far away ray segment points to the root node so
@@ -216,39 +214,40 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
* dividing view3d->clip_end by the object scale, which for small object and large
* clip_end's can easily lead to floating-point overflows.
*/
void BKE_pbvh_clip_ray_ortho(
void clip_ray_ortho(
PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]);
void BKE_pbvh_find_nearest_to_ray(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original);
void find_nearest_to_ray(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original);
bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
blender::Span<int> corner_verts,
blender::Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq);
bool find_nearest_to_ray_node(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
Span<int> corner_verts,
Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq);
/* Drawing */
void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes);
void BKE_pbvh_get_frustum_planes(const PBVH *pbvh, PBVHFrustumPlanes *planes);
void set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes);
void get_frustum_planes(const PBVH *pbvh, PBVHFrustumPlanes *planes);
void BKE_pbvh_draw_cb(
const Mesh &mesh,
PBVH *pbvh,
bool update_only_visible,
const PBVHFrustumPlanes &update_frustum,
const PBVHFrustumPlanes &draw_frustum,
blender::FunctionRef<void(blender::draw::pbvh::PBVHBatches *batches,
const blender::draw::pbvh::PBVH_GPU_Args &args)> draw_fn);
void draw_cb(const Mesh &mesh,
PBVH *pbvh,
bool update_only_visible,
const PBVHFrustumPlanes &update_frustum,
const PBVHFrustumPlanes &draw_frustum,
FunctionRef<void(draw::pbvh::PBVHBatches *batches,
const draw::pbvh::PBVH_GPU_Args &args)> draw_fn);
} // namespace blender::bke::pbvh
/* PBVH Access */
@@ -292,16 +291,20 @@ enum PBVHTopologyUpdateMode {
};
ENUM_OPERATORS(PBVHTopologyUpdateMode, PBVH_Collapse);
namespace blender::bke::pbvh {
/**
* Collapse short edges, subdivide long edges.
*/
bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
float radius,
bool use_frontface,
bool use_projected);
bool bmesh_update_topology(PBVH *pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
float radius,
bool use_frontface,
bool use_projected);
} // namespace blender::bke::pbvh
/* Node Access */
+5 -8
View File
@@ -419,14 +419,11 @@ struct PBVHData {
}
};
NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node);
void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
PBVHData &BKE_pbvh_pixels_data_get(PBVH &pbvh);
void BKE_pbvh_pixels_collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tiles);
NodeData &node_data_get(PBVHNode &node);
void mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user);
PBVHData &data_get(PBVH &pbvh);
void collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tiles);
void BKE_pbvh_pixels_copy_pixels(PBVH &pbvh,
Image &image,
ImageUser &image_user,
image::TileNumber tile_number);
void copy_pixels(PBVH &pbvh, Image &image, ImageUser &image_user, image::TileNumber tile_number);
} // namespace blender::bke::pbvh::pixels
+2 -1
View File
@@ -451,6 +451,7 @@ void multires_flush_sculpt_updates(Object *object)
void multires_force_sculpt_rebuild(Object *object)
{
using namespace blender;
multires_flush_sculpt_updates(object);
if (object == nullptr || object->sculpt == nullptr) {
@@ -460,7 +461,7 @@ void multires_force_sculpt_rebuild(Object *object)
SculptSession *ss = object->sculpt;
if (ss->pbvh != nullptr) {
BKE_pbvh_free(ss->pbvh);
bke::pbvh::free(ss->pbvh);
object->sculpt->pbvh = nullptr;
}
}
+6 -4
View File
@@ -1430,6 +1430,7 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
static void sculptsession_free_pbvh(Object *object)
{
using namespace blender;
SculptSession *ss = object->sculpt;
if (!ss) {
@@ -1437,7 +1438,7 @@ static void sculptsession_free_pbvh(Object *object)
}
if (ss->pbvh) {
BKE_pbvh_free(ss->pbvh);
bke::pbvh::free(ss->pbvh);
ss->pbvh = nullptr;
}
@@ -2638,14 +2639,15 @@ SculptAttribute *BKE_sculpt_attribute_ensure(Object *ob,
static void sculptsession_bmesh_attr_update_internal(Object *ob)
{
using namespace blender;
SculptSession *ss = ob->sculpt;
sculptsession_bmesh_add_layers(ob);
if (ss->pbvh) {
BKE_pbvh_update_bmesh_offsets(ss->pbvh,
ob->sculpt->attrs.dyntopo_node_id_vertex->bmesh_cd_offset,
ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
bke::pbvh::update_bmesh_offsets(ss->pbvh,
ob->sculpt->attrs.dyntopo_node_id_vertex->bmesh_cd_offset,
ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
}
}
+92 -84
View File
@@ -886,9 +886,7 @@ PBVH *build_grids(const CCGKey *key, Mesh *mesh, SubdivCCG *subdiv_ccg)
return pbvh.release();
}
} // namespace blender::bke::pbvh
void BKE_pbvh_free(PBVH *pbvh)
void free(PBVH *pbvh)
{
for (PBVHNode &node : pbvh->nodes) {
if (node.flag & PBVH_Leaf) {
@@ -898,15 +896,17 @@ void BKE_pbvh_free(PBVH *pbvh)
}
if (node.flag & (PBVH_Leaf | PBVH_TexLeaf)) {
pbvh_node_pixels_free(&node);
node_pixels_free(&node);
}
}
pbvh_pixels_free(pbvh);
pixels_free(pbvh);
delete pbvh;
}
} // namespace blender::bke::pbvh
static void pbvh_iter_begin(PBVHIter *iter, PBVH *pbvh, blender::FunctionRef<bool(PBVHNode &)> scb)
{
iter->pbvh = pbvh;
@@ -1082,10 +1082,12 @@ float BKE_pbvh_node_get_tmin(const PBVHNode *node)
return node->tmin;
}
void BKE_pbvh_search_callback(PBVH *pbvh,
blender::FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitCallback hcb,
void *hit_data)
namespace blender::bke::pbvh {
void search_callback(PBVH *pbvh,
FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitCallback hcb,
void *hit_data)
{
if (pbvh->nodes.is_empty()) {
return;
@@ -1104,10 +1106,10 @@ void BKE_pbvh_search_callback(PBVH *pbvh,
pbvh_iter_end(&iter);
}
static void BKE_pbvh_search_callback_occluded(PBVH *pbvh,
blender::FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitOccludedCallback hcb,
void *hit_data)
static void search_callback_occluded(PBVH *pbvh,
FunctionRef<bool(PBVHNode &)> scb,
BKE_pbvh_HitOccludedCallback hcb,
void *hit_data)
{
if (pbvh->nodes.is_empty()) {
return;
@@ -1154,8 +1156,6 @@ static bool update_search(PBVHNode *node, const int flag)
return true;
}
namespace blender::bke::pbvh {
static void normals_calc_faces(const Span<float3> positions,
const blender::OffsetIndices<int> faces,
const Span<int> corner_verts,
@@ -1254,7 +1254,7 @@ void update_normals(PBVH &pbvh, SubdivCCG *subdiv_ccg)
&pbvh, [&](PBVHNode &node) { return update_search(&node, PBVH_UpdateNormals); });
if (pbvh.header.type == PBVH_BMESH) {
pbvh_bmesh_normals_update(nodes);
bmesh_normals_update(nodes);
}
else if (pbvh.header.type == PBVH_FACES) {
pbvh_faces_update_normals(pbvh, nodes, *pbvh.mesh);
@@ -1909,6 +1909,8 @@ bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node)
/********************************* Ray-cast ***********************************/
namespace blender::bke::pbvh {
struct RaycastData {
IsectRayAABB_Precalc ray;
bool original;
@@ -1922,19 +1924,19 @@ static bool ray_aabb_intersect(PBVHNode *node, RaycastData *rcd)
return isect_ray_aabb_v3(&rcd->ray, node->vb.min, node->vb.max, &node->tmin);
}
void BKE_pbvh_raycast(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original)
void raycast(PBVH *pbvh,
BKE_pbvh_HitOccludedCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original)
{
RaycastData rcd;
isect_ray_aabb_v3_precalc(&rcd.ray, ray_start, ray_normal);
rcd.original = original;
BKE_pbvh_search_callback_occluded(
search_callback_occluded(
pbvh, [&](PBVHNode &node) { return ray_aabb_intersect(&node, &rcd); }, cb, data);
}
@@ -2074,7 +2076,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
for (const int i : node->prim_indices.index_range()) {
const int looptri_i = node->prim_indices[i];
const MLoopTri *lt = &pbvh->looptris[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
const int3 face_verts = node->face_vert_indices[i];
if (!hide_poly.is_empty() && hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
@@ -2214,19 +2216,19 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh,
return hit;
}
bool BKE_pbvh_node_raycast(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal)
bool raycast_node(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
PBVHVertRef *active_vertex,
int *active_face_grid_index,
float *face_normal)
{
bool hit = false;
@@ -2263,21 +2265,21 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
break;
case PBVH_BMESH:
BM_mesh_elem_index_ensure(pbvh->header.bm, BM_VERT);
hit = pbvh_bmesh_node_raycast(node,
ray_start,
ray_normal,
isect_precalc,
depth,
use_origco,
active_vertex,
face_normal);
hit = bmesh_node_raycast(node,
ray_start,
ray_normal,
isect_precalc,
depth,
use_origco,
active_vertex,
face_normal);
break;
}
return hit;
}
void BKE_pbvh_clip_ray_ortho(
void clip_ray_ortho(
PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
{
if (pbvh->nodes.is_empty()) {
@@ -2393,19 +2395,19 @@ static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node, FindNearestRayData *rcd)
return depth > 0.0f;
}
void BKE_pbvh_find_nearest_to_ray(PBVH *pbvh,
BKE_pbvh_SearchNearestCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original)
void find_nearest_to_ray(PBVH *pbvh,
BKE_pbvh_SearchNearestCallback cb,
void *data,
const float ray_start[3],
const float ray_normal[3],
bool original)
{
FindNearestRayData ncd;
dist_squared_ray_to_aabb_v3_precalc(&ncd.dist_ray_to_aabb_precalc, ray_start, ray_normal);
ncd.original = original;
BKE_pbvh_search_callback_occluded(
search_callback_occluded(
pbvh, [&](PBVHNode &node) { return nearest_to_ray_aabb_dist_sq(&node, &ncd); }, cb, data);
}
@@ -2425,7 +2427,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
for (const int i : node->prim_indices.index_range()) {
const int looptri_i = node->prim_indices[i];
const MLoopTri *lt = &pbvh->looptris[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
const int3 face_verts = node->face_vert_indices[i];
if (!hide_poly.is_empty() && hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
@@ -2516,16 +2518,16 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH *pbvh,
return hit;
}
bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq)
bool find_nearest_to_ray_node(PBVH *pbvh,
PBVHNode *node,
float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
const Span<bool> hide_poly,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq)
{
bool hit = false;
@@ -2543,8 +2545,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *pbvh,
pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
break;
case PBVH_BMESH:
hit = pbvh_bmesh_node_nearest_to_ray(
node, ray_start, ray_normal, depth, dist_sq, use_origco);
hit = bmesh_node_nearest_to_ray(node, ray_start, ray_normal, depth, dist_sq, use_origco);
break;
}
@@ -2593,14 +2594,17 @@ static PlaneAABBIsect test_frustum_aabb(const Bounds<float3> &bounds,
return ret;
}
} // namespace blender::bke::pbvh
bool BKE_pbvh_node_frustum_contain_AABB(const PBVHNode *node, const PBVHFrustumPlanes *data)
{
return test_frustum_aabb(node->vb, data) != ISECT_OUTSIDE;
return blender::bke::pbvh::test_frustum_aabb(node->vb, data) !=
blender::bke::pbvh::ISECT_OUTSIDE;
}
bool BKE_pbvh_node_frustum_exclude_AABB(const PBVHNode *node, const PBVHFrustumPlanes *data)
{
return test_frustum_aabb(node->vb, data) != ISECT_INSIDE;
return blender::bke::pbvh::test_frustum_aabb(node->vb, data) != blender::bke::pbvh::ISECT_INSIDE;
}
static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
@@ -2665,6 +2669,8 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
return args;
}
namespace blender::bke::pbvh {
static void node_update_draw_buffers(const Mesh &mesh, PBVH &pbvh, PBVHNode &node)
{
/* Create and update draw buffers. The functions called here must not
@@ -2685,10 +2691,10 @@ static void node_update_draw_buffers(const Mesh &mesh, PBVH &pbvh, PBVHNode &nod
}
}
void pbvh_free_draw_buffers(PBVH & /*pbvh*/, PBVHNode *node)
void free_draw_buffers(PBVH & /*pbvh*/, PBVHNode *node)
{
if (node->draw_batches) {
blender::draw::pbvh::node_free(node->draw_batches);
draw::pbvh::node_free(node->draw_batches);
node->draw_batches = nullptr;
}
}
@@ -2698,7 +2704,6 @@ static void pbvh_update_draw_buffers(const Mesh &mesh,
Span<PBVHNode *> nodes,
int update_flag)
{
using namespace blender;
if (pbvh.header.type == PBVH_BMESH && !pbvh.header.bm) {
/* BMesh hasn't been created yet */
return;
@@ -2708,7 +2713,7 @@ static void pbvh_update_draw_buffers(const Mesh &mesh,
/* Free buffers uses OpenGL, so not in parallel. */
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_RebuildDrawBuffers) {
pbvh_free_draw_buffers(pbvh, node);
free_draw_buffers(pbvh, node);
}
else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_batches) {
const draw::pbvh::PBVH_GPU_Args args = pbvh_draw_args_init(mesh, pbvh, *node);
@@ -2737,17 +2742,14 @@ static void pbvh_update_draw_buffers(const Mesh &mesh,
}
}
void BKE_pbvh_draw_cb(
const Mesh &mesh,
PBVH *pbvh,
bool update_only_visible,
const PBVHFrustumPlanes &update_frustum,
const PBVHFrustumPlanes &draw_frustum,
const blender::FunctionRef<void(blender::draw::pbvh::PBVHBatches *batches,
const blender::draw::pbvh::PBVH_GPU_Args &args)> draw_fn)
void draw_cb(const Mesh &mesh,
PBVH *pbvh,
bool update_only_visible,
const PBVHFrustumPlanes &update_frustum,
const PBVHFrustumPlanes &draw_frustum,
const FunctionRef<void(draw::pbvh::PBVHBatches *batches,
const draw::pbvh::PBVH_GPU_Args &args)> draw_fn)
{
using namespace blender;
using namespace blender::bke::pbvh;
pbvh->draw_cache_invalid = false;
if (update_only_visible) {
@@ -2788,6 +2790,8 @@ void BKE_pbvh_draw_cb(
}
}
} // namespace blender::bke::pbvh
void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
void (*draw_fn)(PBVHNode *node,
void *user_data,
@@ -3016,7 +3020,9 @@ bool pbvh_has_face_sets(PBVH *pbvh)
return false;
}
void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes)
namespace blender::bke::pbvh {
void set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes)
{
pbvh->num_planes = planes->num_planes;
for (int i = 0; i < pbvh->num_planes; i++) {
@@ -3024,7 +3030,7 @@ void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes)
}
}
void BKE_pbvh_get_frustum_planes(const PBVH *pbvh, PBVHFrustumPlanes *planes)
void get_frustum_planes(const PBVH *pbvh, PBVHFrustumPlanes *planes)
{
planes->num_planes = pbvh->num_planes;
for (int i = 0; i < planes->num_planes; i++) {
@@ -3032,6 +3038,8 @@ void BKE_pbvh_get_frustum_planes(const PBVH *pbvh, PBVHFrustumPlanes *planes)
}
}
} // namespace blender::bke::pbvh
Mesh *BKE_pbvh_get_mesh(PBVH *pbvh)
{
return pbvh->mesh;
+46 -58
View File
@@ -33,19 +33,14 @@
static CLG_LogRef LOG = {"pbvh.bmesh"};
using blender::Array;
using blender::Bounds;
using blender::float3;
using blender::IndexRange;
using blender::Span;
using blender::Vector;
/* Avoid skinny faces */
#define USE_EDGEQUEUE_EVEN_SUBDIV
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
# include "BKE_global.h"
#endif
namespace blender::bke::pbvh {
/* Support for only operating on front-faces. */
#define USE_EDGEQUEUE_FRONTFACE
@@ -127,7 +122,7 @@ static Bounds<float3> negative_bounds()
return {float3(std::numeric_limits<float>::max()), float3(std::numeric_limits<float>::lowest())};
}
static std::array<BMEdge *, 3> bm_edges_from_tri(BMesh *bm, const blender::Span<BMVert *> v_tri)
static std::array<BMEdge *, 3> bm_edges_from_tri(BMesh *bm, const Span<BMVert *> v_tri)
{
return {
BM_edge_create(bm, v_tri[0], v_tri[1], nullptr, BM_CREATE_NO_DOUBLE),
@@ -214,7 +209,6 @@ static void pbvh_bmesh_node_finalize(PBVH *pbvh,
const int cd_vert_node_offset,
const int cd_face_node_offset)
{
using namespace blender;
PBVHNode *n = &pbvh->nodes[node_index];
bool has_visible = false;
@@ -265,7 +259,6 @@ static void pbvh_bmesh_node_split(PBVH *pbvh,
const Span<Bounds<float3>> face_bounds,
int node_index)
{
using namespace blender;
const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
const int cd_face_node_offset = pbvh->cd_face_node_offset;
PBVHNode *n = &pbvh->nodes[node_index];
@@ -315,8 +308,8 @@ static void pbvh_bmesh_node_split(PBVH *pbvh,
}
/* Enforce at least one primitive in each node */
blender::Set<BMFace *, 0> *empty = nullptr;
blender::Set<BMFace *, 0> *other;
Set<BMFace *, 0> *empty = nullptr;
Set<BMFace *, 0> *other;
if (c1->bm_faces.is_empty()) {
empty = &c1->bm_faces;
other = &c2->bm_faces;
@@ -353,7 +346,7 @@ static void pbvh_bmesh_node_split(PBVH *pbvh,
n->layer_disp = nullptr;
if (n->draw_batches) {
blender::draw::pbvh::node_free(n->draw_batches);
draw::pbvh::node_free(n->draw_batches);
}
n->flag &= ~PBVH_Leaf;
@@ -373,7 +366,6 @@ static void pbvh_bmesh_node_split(PBVH *pbvh,
/** Recursively split the node if it exceeds the leaf_limit. */
static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
{
using namespace blender;
PBVHNode &node = pbvh->nodes[node_index];
const int faces_num = node.bm_faces.size();
if (faces_num <= pbvh->leaf_limit) {
@@ -474,8 +466,8 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
*/
static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
int node_index,
const blender::Span<BMVert *> v_tri,
const blender::Span<BMEdge *> e_tri,
const Span<BMVert *> v_tri,
const Span<BMEdge *> e_tri,
const BMFace *f_example)
{
PBVHNode *node = &pbvh->nodes[node_index];
@@ -1774,14 +1766,14 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH *pbvh
/************************* Called from pbvh.cc *************************/
bool pbvh_bmesh_node_raycast(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal)
bool bmesh_node_raycast(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *depth,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal)
{
bool hit = false;
float nearest_vertex_co[3] = {0.0f};
@@ -1854,11 +1846,11 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
return hit;
}
bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length)
bool bmesh_node_raycast_detail(PBVHNode *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length)
{
if (node->flag & PBVH_FullyHidden) {
return false;
@@ -1897,12 +1889,12 @@ bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
return hit;
}
bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq,
bool use_original)
bool bmesh_node_nearest_to_ray(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq,
bool use_original)
{
bool hit = false;
@@ -1934,7 +1926,7 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
return hit;
}
void pbvh_bmesh_normals_update(Span<PBVHNode *> nodes)
void bmesh_normals_update(Span<PBVHNode *> nodes)
{
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_UpdateNormals) {
@@ -1965,12 +1957,11 @@ struct FastNodeBuildInfo {
* to a sub part of the arrays.
*/
static void pbvh_bmesh_node_limit_ensure_fast(PBVH *pbvh,
const blender::MutableSpan<BMFace *> nodeinfo,
const blender::Span<Bounds<float3>> face_bounds,
const MutableSpan<BMFace *> nodeinfo,
const Span<Bounds<float3>> face_bounds,
FastNodeBuildInfo *node,
MemArena *arena)
{
using namespace blender;
FastNodeBuildInfo *child1, *child2;
if (node->totface <= pbvh->leaf_limit) {
@@ -2066,12 +2057,11 @@ static void pbvh_bmesh_node_limit_ensure_fast(PBVH *pbvh,
}
static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
const blender::Span<BMFace *> nodeinfo,
const blender::Span<Bounds<float3>> face_bounds,
const Span<BMFace *> nodeinfo,
const Span<Bounds<float3>> face_bounds,
FastNodeBuildInfo *node,
int node_index)
{
using namespace blender;
PBVHNode *n = &pbvh->nodes[node_index];
/* Two cases, node does not have children or does have children. */
if (node->child1) {
@@ -2152,14 +2142,12 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
/***************************** Public API *****************************/
void BKE_pbvh_update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset)
void update_bmesh_offsets(PBVH *pbvh, int cd_vert_node_offset, int cd_face_node_offset)
{
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_face_node_offset = cd_face_node_offset;
}
namespace blender::bke::pbvh {
PBVH *build_bmesh(BMesh *bm,
BMLog *log,
const int cd_vert_node_offset,
@@ -2178,7 +2166,7 @@ PBVH *build_bmesh(BMesh *bm,
/* TODO: choose leaf limit better. */
pbvh->leaf_limit = 400;
BKE_pbvh_update_bmesh_offsets(pbvh.get(), cd_vert_node_offset, cd_face_node_offset);
pbvh::update_bmesh_offsets(pbvh.get(), cd_vert_node_offset, cd_face_node_offset);
if (bm->totface == 0) {
return {};
@@ -2234,15 +2222,13 @@ PBVH *build_bmesh(BMesh *bm,
return pbvh.release();
}
} // namespace blender::bke::pbvh
bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
float radius,
const bool use_frontface,
const bool use_projected)
bool bmesh_update_topology(PBVH *pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
float radius,
const bool use_frontface,
const bool use_projected)
{
const int cd_vert_mask_offset = CustomData_get_offset_named(
&pbvh->header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
@@ -2320,6 +2306,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
return modified;
}
} // namespace blender::bke::pbvh
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool use_original)
{
/* Skip if original coords/triangles are already saved. */
@@ -2376,7 +2364,7 @@ void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool u
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
bm_face_as_array_index_tri(f, node->bm_ortri[i]);
blender::bke::pbvh::bm_face_as_array_index_tri(f, node->bm_ortri[i]);
i++;
}
node->bm_tot_ortri = i;
@@ -2389,10 +2377,10 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
PBVHNode *n = &pbvh->nodes[i];
if (n->flag & PBVH_Leaf) {
/* Free orco/ortri data. */
pbvh_bmesh_node_drop_orig(n);
blender::bke::pbvh::pbvh_bmesh_node_drop_orig(n);
/* Recursively split nodes that have gotten too many elements. */
pbvh_bmesh_node_limit_ensure(pbvh, i);
blender::bke::pbvh::pbvh_bmesh_node_limit_ensure(pbvh, i);
}
}
}
+22 -20
View File
@@ -128,8 +128,6 @@ struct PBVHNode {
int debug_draw_gen = 0;
};
typedef struct PBVHBMeshLog PBVHBMeshLog;
struct PBVH {
PBVHPublic header;
@@ -212,6 +210,8 @@ struct PBVH {
/* pbvh.cc */
namespace blender::bke::pbvh {
bool ray_face_intersection_quad(const float ray_start[3],
IsectRayPrecalc *isect_precalc,
const float t0[3],
@@ -244,25 +244,27 @@ bool ray_face_nearest_tri(const float ray_start[3],
/* pbvh_bmesh.cc */
bool pbvh_bmesh_node_raycast(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *dist,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal);
bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq,
bool use_original);
bool bmesh_node_raycast(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
float *dist,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal);
bool bmesh_node_nearest_to_ray(PBVHNode *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq,
bool use_original);
void pbvh_bmesh_normals_update(blender::Span<PBVHNode *> nodes);
void bmesh_normals_update(Span<PBVHNode *> nodes);
/* pbvh_pixels.hh */
void pbvh_node_pixels_free(PBVHNode *node);
void pbvh_pixels_free(PBVH *pbvh);
void pbvh_free_draw_buffers(PBVH &pbvh, PBVHNode *node);
void node_pixels_free(PBVHNode *node);
void pixels_free(PBVH *pbvh);
void free_draw_buffers(PBVH &pbvh, PBVHNode *node);
} // namespace blender::bke::pbvh
+27 -23
View File
@@ -71,7 +71,7 @@ static int count_node_pixels(PBVHNode &node)
return 0;
}
NodeData &data = BKE_pbvh_pixels_node_data_get(node);
NodeData &data = node_data_get(node);
int totpixel = 0;
@@ -119,7 +119,7 @@ static void split_pixel_node(
const Bounds<float3> cb = node->vb;
if (count_node_pixels(*node) <= pbvh->pixel_leaf_limit || split->depth >= pbvh->depth_limit) {
BKE_pbvh_pixels_node_data_get(split->node).rebuild_undo_regions();
node_data_get(split->node).rebuild_undo_regions();
return;
}
@@ -147,7 +147,7 @@ static void split_pixel_node(
child2->vb = cb;
child2->vb.min[axis] = mid;
NodeData &data = BKE_pbvh_pixels_node_data_get(split->node);
NodeData &data = node_data_get(split->node);
NodeData *data1 = MEM_new<NodeData>(__func__);
NodeData *data2 = MEM_new<NodeData>(__func__);
@@ -181,8 +181,8 @@ static void split_pixel_node(
continue;
}
const Span<float3> vert_cos = BKE_pbvh_get_vert_positions(pbvh);
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(*pbvh);
const Span<float3> positions = BKE_pbvh_get_vert_positions(pbvh);
PBVHData &pbvh_data = data_get(*pbvh);
for (const PackedPixelRow &row : tile.pixel_rows) {
UDIMTilePixels *tile1 = &data1->tiles[i];
@@ -193,9 +193,9 @@ static void split_pixel_node(
float verts[3][3];
copy_v3_v3(verts[0], vert_cos[tri[0]]);
copy_v3_v3(verts[1], vert_cos[tri[1]]);
copy_v3_v3(verts[2], vert_cos[tri[2]]);
copy_v3_v3(verts[0], positions[tri[0]]);
copy_v3_v3(verts[1], positions[tri[1]]);
copy_v3_v3(verts[2], positions[tri[2]]);
float2 delta = uv_prim.delta_barycentric_coord_u;
float2 uv1 = row.start_barycentric_coord;
@@ -258,7 +258,7 @@ static void split_pixel_node(
data.clear_data();
}
else {
pbvh_node_pixels_free(node);
node_pixels_free(node);
}
BLI_thread_queue_push(tdata->new_nodes, static_cast<void *>(split1));
@@ -416,7 +416,7 @@ static void extract_barycentric_pixels(UDIMTilePixels &tile_data,
/** Update the geometry primitives of the pbvh. */
static void update_geom_primitives(PBVH &pbvh, const uv_islands::MeshData &mesh_data)
{
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
PBVHData &pbvh_data = data_get(pbvh);
pbvh_data.clear_data();
for (const MLoopTri &lt : mesh_data.looptris) {
pbvh_data.geom_primitives.append(int3(mesh_data.corner_verts[lt.tri[0]],
@@ -717,7 +717,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
}
/* Add solution for non-manifold parts of the model. */
BKE_pbvh_pixels_copy_update(*pbvh, *image, *image_user, mesh_data);
copy_update(*pbvh, *image, *image_user, mesh_data);
/* Rebuild the undo regions. */
for (PBVHNode *node : nodes_to_update) {
@@ -766,21 +766,21 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
return true;
}
NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node)
NodeData &node_data_get(PBVHNode &node)
{
BLI_assert(node.pixels.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
return *node_data;
}
PBVHData &BKE_pbvh_pixels_data_get(PBVH &pbvh)
PBVHData &data_get(PBVH &pbvh)
{
BLI_assert(pbvh.pixels.data != nullptr);
PBVHData *data = static_cast<PBVHData *>(pbvh.pixels.data);
return *data;
}
void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user)
void mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user)
{
BLI_assert(node.pixels.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
@@ -801,7 +801,7 @@ void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &i
}
}
void BKE_pbvh_pixels_collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tiles)
void collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tiles)
{
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
node_data->collect_dirty_tiles(r_dirty_tiles);
@@ -809,18 +809,20 @@ void BKE_pbvh_pixels_collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumbe
} // namespace blender::bke::pbvh::pixels
using namespace blender::bke::pbvh::pixels;
namespace blender::bke::pbvh {
void BKE_pbvh_build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
void build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
{
if (update_pixels(pbvh, mesh, image, image_user) && PBVH_PIXELS_SPLIT_NODES_ENABLED) {
split_pixel_nodes(pbvh, mesh, image, image_user);
if (pixels::update_pixels(pbvh, mesh, image, image_user) &&
pixels::PBVH_PIXELS_SPLIT_NODES_ENABLED)
{
pixels::split_pixel_nodes(pbvh, mesh, image, image_user);
}
}
void pbvh_node_pixels_free(PBVHNode *node)
void node_pixels_free(PBVHNode *node)
{
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
pixels::NodeData *node_data = static_cast<pixels::NodeData *>(node->pixels.node_data);
if (!node_data) {
return;
@@ -830,9 +832,11 @@ void pbvh_node_pixels_free(PBVHNode *node)
node->pixels.node_data = nullptr;
}
void pbvh_pixels_free(PBVH *pbvh)
void pixels_free(PBVH *pbvh)
{
PBVHData *pbvh_data = static_cast<PBVHData *>(pbvh->pixels.data);
pixels::PBVHData *pbvh_data = static_cast<pixels::PBVHData *>(pbvh->pixels.data);
MEM_delete(pbvh_data);
pbvh->pixels.data = nullptr;
}
} // namespace blender::bke::pbvh
@@ -340,7 +340,7 @@ struct Rows {
continue;
}
float new_distance = blender::math::distance(float2(destination), float2(source));
float new_distance = math::distance(float2(destination), float2(source));
if (new_distance < found_distance) {
found_distance = new_distance;
found_source = source;
@@ -395,8 +395,8 @@ struct Rows {
if (source.type != PixelType::Brush) {
continue;
}
float new_distance = blender::math::distance(float2(sx, sy),
float2(pixel.copy_command.destination));
float new_distance = math::distance(float2(sx, sy),
float2(pixel.copy_command.destination));
if (new_distance < found_distance) {
found_source = int2(sx, sy);
found_distance = new_distance;
@@ -458,7 +458,7 @@ struct Rows {
point,
tile_edge.vertex_1.coordinate,
tile_edge.vertex_2.coordinate);
float distance_to_edge = blender::math::distance(closest_edge_point, point);
float distance_to_edge = math::distance(closest_edge_point, point);
if (distance_to_edge < margin && distance_to_edge < pixel.distance) {
if (pixel.type != PixelType::SelectedForCloserExamination) {
selected_pixels.append(std::reference_wrapper<Pixel>(pixel));
@@ -498,15 +498,14 @@ struct Rows {
}
}
}
};
}; // namespace blender::bke::pbvh::pixels
void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data)
void copy_update(PBVH &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data)
{
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
PBVHData &pbvh_data = data_get(pbvh);
pbvh_data.tiles_copy_pixels.clear();
const NonManifoldUVEdges non_manifold_edges(mesh_data);
if (non_manifold_edges.is_empty()) {
@@ -546,12 +545,9 @@ void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
}
}
void BKE_pbvh_pixels_copy_pixels(PBVH &pbvh,
Image &image,
ImageUser &image_user,
image::TileNumber tile_number)
void copy_pixels(PBVH &pbvh, Image &image, ImageUser &image_user, image::TileNumber tile_number)
{
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh);
PBVHData &pbvh_data = data_get(pbvh);
std::optional<std::reference_wrapper<CopyPixelTile>> pixel_tile =
pbvh_data.tiles_copy_pixels.find_tile(tile_number);
if (!pixel_tile.has_value()) {
@@ -16,9 +16,9 @@
namespace blender::bke::pbvh::pixels {
void BKE_pbvh_pixels_copy_update(PBVH &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data);
void copy_update(PBVH &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data);
} // namespace blender::bke::pbvh::pixels
@@ -1332,12 +1332,12 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
if (p && (p->flags & PAINT_SCULPT_DELAY_UPDATES)) {
update_frustum.planes = update_planes;
update_frustum.num_planes = 6;
BKE_pbvh_get_frustum_planes(pbvh, &update_frustum);
bke::pbvh::get_frustum_planes(pbvh, &update_frustum);
if (!navigating) {
drw_sculpt_get_frustum_planes(scd->ob, update_planes);
update_frustum.planes = update_planes;
update_frustum.num_planes = 6;
BKE_pbvh_set_frustum_planes(pbvh, &update_frustum);
bke::pbvh::set_frustum_planes(pbvh, &update_frustum);
}
}
else {
@@ -1366,7 +1366,7 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
Mesh *mesh = static_cast<Mesh *>(scd->ob->data);
bke::pbvh::update_normals(*pbvh, mesh->runtime->subdiv_ccg.get());
BKE_pbvh_draw_cb(
bke::pbvh::draw_cb(
*mesh,
pbvh,
update_only_visible,
+19 -19
View File
@@ -76,10 +76,10 @@ static Vector<SculptBatch> sculpt_batches_get_ex(const Object *ob,
if (paint && (paint->flags & PAINT_SCULPT_DELAY_UPDATES)) {
if (navigating) {
BKE_pbvh_get_frustum_planes(pbvh, &update_frustum);
bke::pbvh::get_frustum_planes(pbvh, &update_frustum);
}
else {
BKE_pbvh_set_frustum_planes(pbvh, &update_frustum);
bke::pbvh::set_frustum_planes(pbvh, &update_frustum);
}
}
@@ -100,23 +100,23 @@ static Vector<SculptBatch> sculpt_batches_get_ex(const Object *ob,
bke::pbvh::update_normals(*pbvh, mesh->runtime->subdiv_ccg.get());
Vector<SculptBatch> result_batches;
BKE_pbvh_draw_cb(*mesh,
pbvh,
update_only_visible,
update_frustum,
draw_frustum,
[&](pbvh::PBVHBatches *batches, const pbvh::PBVH_GPU_Args &args) {
SculptBatch batch{};
if (use_wire) {
batch.batch = pbvh::lines_get(batches, attrs, args, fast_mode);
}
else {
batch.batch = pbvh::tris_get(batches, attrs, args, fast_mode);
}
batch.material_slot = pbvh::material_index_get(batches);
batch.debug_index = result_batches.size();
result_batches.append(batch);
});
bke::pbvh::draw_cb(*mesh,
pbvh,
update_only_visible,
update_frustum,
draw_frustum,
[&](pbvh::PBVHBatches *batches, const pbvh::PBVH_GPU_Args &args) {
SculptBatch batch{};
if (use_wire) {
batch.batch = pbvh::lines_get(batches, attrs, args, fast_mode);
}
else {
batch.batch = pbvh::tris_get(batches, attrs, args, fast_mode);
}
batch.material_slot = pbvh::material_index_get(batches);
batch.debug_index = result_batches.size();
result_batches.append(batch);
});
return result_batches;
}
+43 -37
View File
@@ -1339,7 +1339,7 @@ static void paint_mesh_restore_node(Object *ob, const undo::Type type, PBVHNode
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
bke::SpanAttributeWriter<float> mask = attributes.lookup_or_add_for_write_span<float>(
".sculpt_mask", ATTR_DOMAIN_POINT);
blender::array_utils::scatter(
array_utils::scatter(
unode->mask.as_span(), BKE_pbvh_node_get_unique_vert_indices(node), mask.span);
mask.finish();
break;
@@ -2867,6 +2867,7 @@ static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings,
SculptSession *ss,
Object *ob)
{
using namespace blender;
BLI_assert(ob->type == OB_MESH);
Mesh *mesh = (Mesh *)ob->data;
@@ -2876,7 +2877,7 @@ static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings,
return;
}
BKE_pbvh_build_pixels(ss->pbvh, mesh, image, image_user);
bke::pbvh::build_pixels(ss->pbvh, mesh, image, image_user);
}
/** \} */
@@ -3195,6 +3196,7 @@ static void sculpt_topology_update(Sculpt *sd,
UnifiedPaintSettings * /*ups*/,
PaintModeSettings * /*paint_mode_settings*/)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
SculptSession *ss = ob->sculpt;
@@ -3240,13 +3242,13 @@ static void sculpt_topology_update(Sculpt *sd,
}
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
BKE_pbvh_bmesh_update_topology(ss->pbvh,
mode,
ss->cache->location,
ss->cache->view_normal,
ss->cache->radius,
(brush->flag & BRUSH_FRONTFACE) != 0,
(brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
bke::pbvh::bmesh_update_topology(ss->pbvh,
mode,
ss->cache->location,
ss->cache->view_normal,
ss->cache->radius,
(brush->flag & BRUSH_FRONTFACE) != 0,
(brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
}
/* Update average stroke position. */
@@ -4762,6 +4764,7 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b
static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
return;
@@ -4782,19 +4785,19 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
}
}
if (BKE_pbvh_node_raycast(srd->ss->pbvh,
node,
origco,
use_origco,
srd->corner_verts,
srd->hide_poly,
srd->ray_start,
srd->ray_normal,
&srd->isect_precalc,
&srd->depth,
&srd->active_vertex,
&srd->active_face_grid_index,
srd->face_normal))
if (bke::pbvh::raycast_node(srd->ss->pbvh,
node,
origco,
use_origco,
srd->corner_verts,
srd->hide_poly,
srd->ray_start,
srd->ray_normal,
&srd->isect_precalc,
&srd->depth,
&srd->active_vertex,
&srd->active_face_grid_index,
srd->face_normal))
{
srd->hit = true;
*tmin = srd->depth;
@@ -4803,6 +4806,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
if (BKE_pbvh_node_get_tmin(node) >= *tmin) {
return;
@@ -4823,16 +4827,16 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *t
}
}
if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
node,
origco,
use_origco,
srd->corner_verts,
srd->hide_poly,
srd->ray_start,
srd->ray_normal,
&srd->depth,
&srd->dist_sq_to_ray))
if (bke::pbvh::find_nearest_to_ray_node(srd->ss->pbvh,
node,
origco,
use_origco,
srd->corner_verts,
srd->hide_poly,
srd->ray_start,
srd->ray_normal,
&srd->depth,
&srd->dist_sq_to_ray))
{
srd->hit = true;
*tmin = srd->dist_sq_to_ray;
@@ -4846,6 +4850,7 @@ float SCULPT_raycast_init(ViewContext *vc,
float ray_normal[3],
bool original)
{
using namespace blender;
float obimat[4][4];
float dist;
Object *ob = vc->obact;
@@ -4873,7 +4878,7 @@ float SCULPT_raycast_init(ViewContext *vc,
ED_view3d_win_to_origin(vc->region, mval, ray_start);
mul_m4_v3(obimat, ray_start);
BKE_pbvh_clip_ray_ortho(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
bke::pbvh::clip_ray_ortho(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
dist = len_v3v3(ray_start, ray_end);
}
@@ -4930,7 +4935,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
srd.face_normal = face_normal;
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
bke::pbvh::raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
/* Cursor is not over the mesh, return default values. */
if (!srd.hit) {
@@ -5077,7 +5082,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
srd.face_normal = face_normal;
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
bke::pbvh::raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
if (srd.hit) {
hit = true;
copy_v3_v3(out, ray_normal);
@@ -5105,7 +5110,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
srd.depth = FLT_MAX;
srd.dist_sq_to_ray = FLT_MAX;
BKE_pbvh_find_nearest_to_ray(
bke::pbvh::find_nearest_to_ray(
ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
if (srd.hit && srd.dist_sq_to_ray) {
hit = true;
@@ -6012,6 +6017,7 @@ void node_update(auto_mask::NodeData &automask_data, PBVHVertexIter &vd)
bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool original)
{
using namespace blender;
float ray_start[3], ray_end[3], ray_normal[3], face_normal[3];
float co[3];
@@ -6039,7 +6045,7 @@ bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool origi
srd.face_normal = face_normal;
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
bke::pbvh::raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
return srd.hit;
}
@@ -117,7 +117,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
const double start_time = PIL_check_seconds_timer();
while (BKE_pbvh_bmesh_update_topology(
while (bke::pbvh::bmesh_update_topology(
ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false))
{
for (PBVHNode *node : nodes) {
@@ -203,7 +203,7 @@ static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
{
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
SculptDetailRaycastData *srd = static_cast<SculptDetailRaycastData *>(data_v);
if (BKE_pbvh_bmesh_node_raycast_detail(
if (bke::pbvh::bmesh_node_raycast_detail(
node, srd->ray_start, &srd->isect_precalc, &srd->depth, &srd->edge_length))
{
srd->hit = true;
@@ -231,7 +231,8 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, const int mval[2
srd.edge_length = 0.0f;
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
BKE_pbvh_raycast(ob->sculpt->pbvh, sculpt_raycast_detail_cb, &srd, ray_start, ray_normal, false);
bke::pbvh::raycast(
ob->sculpt->pbvh, sculpt_raycast_detail_cb, &srd, ray_start, ray_normal, false);
if (srd.hit && srd.edge_length > 0.0f) {
/* Convert edge length to world space detail resolution. */
@@ -47,11 +47,12 @@
void SCULPT_pbvh_clear(Object *ob)
{
using namespace blender;
SculptSession *ss = ob->sculpt;
/* Clear out any existing DM and PBVH. */
if (ss->pbvh) {
BKE_pbvh_free(ss->pbvh);
bke::pbvh::free(ss->pbvh);
ss->pbvh = nullptr;
}
@@ -334,8 +334,8 @@ static void do_paint_pixels(TexturePaintingUserData *data, const int n)
const Brush *brush = data->brush;
PBVH *pbvh = ss->pbvh;
PBVHNode *node = data->nodes[n];
PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(*pbvh);
NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
PBVHData &pbvh_data = bke::pbvh::pixels::data_get(*pbvh);
NodeData &node_data = bke::pbvh::pixels::node_data_get(*node);
const int thread_id = BLI_task_parallel_thread_id(nullptr);
const Span<float3> positions = SCULPT_mesh_deformed_positions_get(ss);
@@ -473,7 +473,7 @@ static void do_push_undo_tile(TexturePaintingUserData *data, const int n)
{
PBVHNode *node = data->nodes[n];
NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
NodeData &node_data = bke::pbvh::pixels::node_data_get(*node);
Image *image = data->image_data.image;
ImageUser *image_user = data->image_data.image_user;
@@ -504,7 +504,7 @@ static Vector<image::TileNumber> collect_dirty_tiles(Span<PBVHNode *> nodes)
{
Vector<image::TileNumber> dirty_tiles;
for (PBVHNode *node : nodes) {
BKE_pbvh_pixels_collect_dirty_tiles(*node, dirty_tiles);
bke::pbvh::pixels::collect_dirty_tiles(*node, dirty_tiles);
}
return dirty_tiles;
}
@@ -513,7 +513,7 @@ static void fix_non_manifold_seam_bleeding(PBVH &pbvh,
Span<TileNumber> tile_numbers_to_fix)
{
for (image::TileNumber tile_number : tile_numbers_to_fix) {
BKE_pbvh_pixels_copy_pixels(
bke::pbvh::pixels::copy_pixels(
pbvh, *user_data.image_data.image, *user_data.image_data.image_user, tile_number);
}
}
@@ -591,6 +591,6 @@ void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings,
fix_non_manifold_seam_bleeding(*ob, data);
for (PBVHNode *node : texnodes) {
BKE_pbvh_pixels_mark_image_dirty(*node, *data.image_data.image, *data.image_data.image_user);
bke::pbvh::pixels::mark_image_dirty(*node, *data.image_data.image, *data.image_data.image_user);
}
}
@@ -1031,10 +1031,10 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, UndoSculpt &usculpt)
data.modified_color_verts = modified_verts_color;
data.modified_face_set_faces = modified_faces_face_set;
if (use_multires_undo) {
BKE_pbvh_search_callback(ss->pbvh, {}, update_modified_node_grids, &data);
bke::pbvh::search_callback(ss->pbvh, {}, update_modified_node_grids, &data);
}
else {
BKE_pbvh_search_callback(ss->pbvh, {}, update_modified_node_mesh, &data);
bke::pbvh::search_callback(ss->pbvh, {}, update_modified_node_mesh, &data);
}
if (changed_position) {