Refactor: Sculpt: Change PBVH and PBVHNode to public classes

Part of #118145.

These days we aren't really benefiting from making PBVH an opaque type.
As we remove its responsibilities to focus it on being a BVH tree and look
to improve performance with data-oriented design, that will only become
more true.

There are some other future developments the current header structure
makes difficult:
- Storing selections of nodes with `IndexMask` for simpler iteration, etc.
- Specialization of node type for each PBVH type
- Reducing overhead of access to node data as nodes get smaller
- General C++ cleanliness and consistency

This PR moves `PBVH` to `blender::bke::pbvh::Tree` and moves `PBVHNode`
to `blender::bke::pbvh::Node`. Both are classes visible to elsewhere in Blender
but with private data fields.

The difficult part about the change is that we're in the middle of a transition
removing data from PBVH. Rather than making some data truly private I
chose to just give it the `_` suffix, since it will ideally be removed later.
Other things should be class methods or implemented as part of friend
classes. But the "fake" private status is much simpler for now and avoids
increasing the scope of this PR too much. Though that's a bit ugly, there's a
straightforward way to resolve these issues-- it just looks like the sort of
inconsistency you'd expect in the middle of a large refactor.

Pull Request: https://projects.blender.org/blender/blender/pulls/124919
This commit is contained in:
Hans Goudey
2024-07-23 22:31:27 +02:00
committed by Hans Goudey
parent 73e519ded2
commit 7daefd730b
90 changed files with 2720 additions and 2570 deletions

View File

@@ -38,7 +38,10 @@ struct EnumPropertyItem;
namespace blender {
namespace bke {
enum class AttrDomain : int8_t;
namespace pbvh {
class Tree;
}
} // namespace bke
namespace ed::sculpt_paint {
namespace expand {
struct Cache;
@@ -62,7 +65,6 @@ struct MLoopCol;
struct MPropCol;
struct MultiresModifierData;
struct Object;
struct PBVH;
struct Paint;
struct PaintCurve;
struct PaintModeSettings;
@@ -409,7 +411,7 @@ struct SculptAttributeParams {
int simple_array : 1;
/* Do not mark CustomData layer as temporary. Cannot be combined with simple_array. Doesn't
* work with PBVH_GRIDS.
* work with bke::pbvh::Type::Grids.
*/
int permanent : 1; /* Cannot be combined with simple_array. */
int stroke_only : 1; /* Release layer at end of struct */
@@ -432,7 +434,7 @@ struct SculptAttribute {
/* Data is a flat array outside the CustomData system.
* This will be true if simple_array is requested in
* SculptAttributeParams, or the PBVH type is PBVH_GRIDS or PBVH_BMESH.
* SculptAttributeParams, or the tree type is bke::pbvh::Type::Grids or bke::pbvh::Type::BMesh.
*/
bool simple_array = false;
/* Data stored per BMesh element. */
@@ -493,7 +495,8 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
/* Depsgraph for the Cloth Brush solver to get the colliders. */
Depsgraph *depsgraph = nullptr;
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
/* These are always assigned to base mesh data when using Type::Mesh and Type::Grids.
*/
blender::MutableSpan<blender::float3> vert_positions;
blender::OffsetIndices<int> faces;
blender::Span<int> corner_verts;
@@ -541,8 +544,8 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
/* Limit surface/grids. */
SubdivCCG *subdiv_ccg = nullptr;
/* PBVH acceleration structure */
std::unique_ptr<PBVH> pbvh;
/* BVH tree acceleration structure */
std::unique_ptr<blender::bke::pbvh::Tree> pbvh;
/* Object is deformed with some modifiers. */
bool deform_modifiers_active = false;
@@ -623,7 +626,8 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
} mode = {};
eObjectMode mode_type;
/* This flag prevents PBVH from being freed when creating the vp_handle for texture paint. */
/* This flag prevents bke::pbvh::Tree from being freed when creating the vp_handle for
* texture paint. */
bool building_vp_handle = false;
/**
@@ -730,18 +734,18 @@ void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
MultiresModifierData *mmd);
void BKE_sculpt_toolsettings_data_ensure(Main *bmain, Scene *scene);
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob);
blender::bke::pbvh::Tree *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob);
void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);
/**
* Test if PBVH can be used directly for drawing, which is faster than
* Test if blender::bke::pbvh::Tree can be used directly for drawing, which is faster than
* drawing the mesh and all updates that come with it.
*/
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d);
/** C accessor for #Object::sculpt::pbvh. */
PBVH *BKE_object_sculpt_pbvh_get(Object *object);
blender::bke::pbvh::Tree *BKE_object_sculpt_pbvh_get(Object *object);
bool BKE_object_sculpt_use_dyntopo(const Object *object);
/* paint_canvas.cc */

View File

@@ -6,20 +6,30 @@
/** \file
* \ingroup bke
* \brief External data structures for PBVH. Does not include internal data structures.
*/
#include "BLI_utildefines.h"
struct PBVHNode;
struct BMesh;
struct BMVert;
struct BMFace;
namespace blender::draw::pbvh {
struct PBVHBatches;
}
enum PBVHType {
PBVH_FACES,
PBVH_GRIDS,
PBVH_BMESH,
namespace blender::bke::pbvh {
class Node;
class Tree;
enum class Type {
Mesh,
Grids,
BMesh,
};
} // namespace blender::bke::pbvh
/* #PBVHNodeFlags is needed by `DRW_render.hh` and `draw_cache.cc`. */
enum PBVHNodeFlags {
PBVH_Leaf = 1 << 0,
@@ -64,22 +74,8 @@ struct PBVHVertRef {
#define PBVH_REF_NONE -1LL
/* Public members of PBVH, used for inlined functions. */
struct PBVHPublic {
PBVHType type;
BMesh *bm;
};
struct PBVH;
struct PBVHNode;
inline PBVHType BKE_pbvh_type(const PBVH &pbvh)
{
return ((const PBVHPublic &)pbvh).type;
}
void BKE_pbvh_draw_debug_cb(PBVH &pbvh,
void (*draw_fn)(PBVHNode *node,
void BKE_pbvh_draw_debug_cb(blender::bke::pbvh::Tree &pbvh,
void (*draw_fn)(blender::bke::pbvh::Node *node,
void *user_data,
const float bmin[3],
const float bmax[3],

View File

@@ -12,6 +12,7 @@
#include <optional>
#include <string>
#include "BLI_array.hh"
#include "BLI_bit_group_vector.hh"
#include "BLI_bounds_types.hh"
#include "BLI_compiler_compat.h"
@@ -20,7 +21,9 @@
#include "BLI_index_mask_fwd.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_set.hh"
#include "BLI_span.hh"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
#include "DNA_customdata_types.h"
@@ -38,15 +41,14 @@ struct CCGKey;
struct CustomData;
struct IsectRayPrecalc;
struct Mesh;
struct PBVH;
struct PBVHNode;
struct SubdivCCG;
struct Image;
struct ImageUser;
namespace blender {
namespace bke {
enum class AttrDomain : int8_t;
}
namespace bke::pbvh {
class Node;
class Tree;
} // namespace bke::pbvh
namespace draw::pbvh {
struct PBVHBatches;
struct PBVH_GPU_Args;
@@ -63,11 +65,11 @@ struct PBVHColorBufferNode {
struct PBVHPixels {
/**
* Storage for texture painting on PBVH level.
* Storage for texture painting on blender::bke::pbvh::Tree level.
*
* Contains #blender::bke::pbvh::pixels::PBVHData
*/
void *data;
void *data = nullptr;
};
struct PBVHPixelsNode {
@@ -79,17 +81,185 @@ struct PBVHPixelsNode {
void *node_data = nullptr;
};
namespace blender::bke::pbvh {
class Tree;
/**
* \todo Most data is public but should either be removed or become private in the future.
* The "_" suffix means that fields shouldn't be used by consumers of the `bke::pbvh` API.
*/
class Node {
friend Tree;
public:
/* Opaque handle for drawing code */
draw::pbvh::PBVHBatches *draw_batches_ = nullptr;
/** Axis aligned min and max of all vertex positions in the node. */
Bounds<float3> bounds_ = {};
/** Bounds from the start of current brush stroke. */
Bounds<float3> bounds_orig_ = {};
/* For internal nodes, the offset of the children in the blender::bke::pbvh::Tree
* 'nodes' array. */
int children_offset_ = 0;
/* List of primitives for this node. Semantics depends on
* blender::bke::pbvh::Tree type:
*
* - Type::Mesh: Indices into the #blender::bke::pbvh::Tree::corner_tris array.
* - Type::Grids: Multires grid indices.
* - Type::BMesh: Unused. See Node.bm_faces.
*
* NOTE: This is a pointer inside of blender::bke::pbvh::Tree.prim_indices; it
* is not allocated separately per node.
*/
Span<int> prim_indices_;
/* Array of indices into the mesh's vertex array. Contains the
* indices of all vertices used by faces that are within this
* node's bounding box.
*
* Note that a vertex might be used by a multiple faces, and
* these faces might be in different leaf nodes. Such a vertex
* will appear in the vert_indices array of each of those leaf
* nodes.
*
* In order to support cases where you want access to multiple
* nodes' vertices without duplication, the vert_indices array
* is ordered such that the first part of the array, up to
* index 'uniq_verts', contains "unique" vertex indices. These
* vertices might not be truly unique to this node, but if
* they appear in another node's vert_indices array, they will
* be above that node's 'uniq_verts' value.
*
* Used for leaf nodes in a mesh-based blender::bke::pbvh::Tree (not multires.)
*/
Array<int, 0> vert_indices_;
/** The number of vertices in #vert_indices not shared with (owned by) another node. */
int uniq_verts_ = 0;
/* Array of indices into the Mesh's corner array.
* Type::Mesh only.
*/
Array<int, 0> corner_indices_;
/* An array mapping face corners into the vert_indices
* array. The array is sized to match 'totprim', and each of
* the face's corners gets an index into the vert_indices
* array, in the same order as the corners in the original
* triangle.
*
* Used for leaf nodes in a mesh-based blender::bke::pbvh::Tree (not multires.)
*/
Array<int3, 0> face_vert_indices_;
/* Indicates whether this node is a leaf or not; also used for
* marking various updates that need to be applied. */
PBVHNodeFlags flag_ = PBVHNodeFlags(0);
/* Used for ray-casting: how close the bounding-box is to the ray point. */
float tmin_ = 0.0f;
/* Dyntopo */
/* Set of pointers to the BMFaces used by this node.
* NOTE: Type::BMesh only. Faces are always triangles
* (dynamic topology forcibly triangulates the mesh).
*/
Set<BMFace *, 0> bm_faces_;
Set<BMVert *, 0> bm_unique_verts_;
Set<BMVert *, 0> bm_other_verts_;
/* Deprecated. Stores original coordinates of triangles. */
float (*bm_orco_)[3] = nullptr;
int (*bm_ortri_)[3] = nullptr;
BMVert **bm_orvert_ = nullptr;
int bm_tot_ortri_ = 0;
/* Used to store the brush color during a stroke and composite it over the original color */
PBVHColorBufferNode color_buffer_;
PBVHPixelsNode pixels_;
/* Used to flash colors of updated node bounding boxes in
* debug draw mode (when G.debug_value / bpy.app.debug_value is 889).
*/
int debug_draw_gen_ = 0;
};
/**
* \todo Most data is public but should either be removed or become private in the future.
* The "_" suffix means that fields shouldn't be used by consumers of the `bke::pbvh` API.
*/
class Tree {
friend Node;
Type type_;
public:
BMesh *bm_ = nullptr;
Vector<Node> nodes_;
/* Memory backing for Node.prim_indices. */
Array<int> prim_indices_;
/* Mesh data. The evaluated deform mesh for mesh sculpting, and the base mesh for grids. */
Mesh *mesh_ = nullptr;
/** Local array used when not sculpting base mesh positions directly. */
Array<float3> vert_positions_deformed_;
/** Local array used when not sculpting base mesh positions directly. */
Array<float3> vert_normals_deformed_;
/** Local array used when not sculpting base mesh positions directly. */
Array<float3> face_normals_deformed_;
MutableSpan<float3> vert_positions_;
Span<float3> vert_normals_;
Span<float3> face_normals_;
/* Grid Data */
SubdivCCG *subdiv_ccg_ = nullptr;
/* flag are verts/faces deformed */
bool deformed_ = false;
/* Dynamic topology */
float bm_max_edge_len_;
float bm_min_edge_len_;
int cd_vert_node_offset_ = -1;
int cd_face_node_offset_ = -1;
float planes_[6][4];
int num_planes_;
BMLog *bm_log_ = nullptr;
PBVHPixels pixels_;
public:
Tree(const Type type) : type_(type) {}
~Tree();
Type type() const
{
return this->type_;
}
};
} // namespace blender::bke::pbvh
struct PBVHFrustumPlanes {
float (*planes)[4];
int num_planes;
};
BLI_INLINE BMesh *BKE_pbvh_get_bmesh(PBVH &pbvh)
BLI_INLINE BMesh *BKE_pbvh_get_bmesh(blender::bke::pbvh::Tree &pbvh)
{
return ((PBVHPublic &)pbvh).bm;
return pbvh.bm_;
}
Mesh *BKE_pbvh_get_mesh(PBVH &pbvh);
Mesh *BKE_pbvh_get_mesh(blender::bke::pbvh::Tree &pbvh);
BLI_INLINE PBVHVertRef BKE_pbvh_make_vref(intptr_t i)
{
@@ -97,20 +267,20 @@ BLI_INLINE PBVHVertRef BKE_pbvh_make_vref(intptr_t i)
return ret;
}
BLI_INLINE int BKE_pbvh_vertex_to_index(PBVH &pbvh, PBVHVertRef v)
BLI_INLINE int BKE_pbvh_vertex_to_index(blender::bke::pbvh::Tree &pbvh, PBVHVertRef v)
{
return (BKE_pbvh_type(pbvh) == PBVH_BMESH && v.i != PBVH_REF_NONE ?
return (pbvh.type() == blender::bke::pbvh::Type::BMesh && v.i != PBVH_REF_NONE ?
BM_elem_index_get((BMVert *)(v.i)) :
(v.i));
}
BLI_INLINE PBVHVertRef BKE_pbvh_index_to_vertex(PBVH &pbvh, int index)
BLI_INLINE PBVHVertRef BKE_pbvh_index_to_vertex(blender::bke::pbvh::Tree &pbvh, int index)
{
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS:
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Mesh:
case blender::bke::pbvh::Type::Grids:
return BKE_pbvh_make_vref(index);
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
return BKE_pbvh_make_vref((intptr_t)BKE_pbvh_get_bmesh(pbvh)->vtable[index]);
}
@@ -124,47 +294,47 @@ namespace blender::bke::pbvh {
/**
* Do a full rebuild with on Mesh data structure.
*/
std::unique_ptr<PBVH> build_mesh(Mesh *mesh);
void update_mesh_pointers(PBVH &pbvh, Mesh *mesh);
std::unique_ptr<Tree> build_mesh(Mesh *mesh);
void update_mesh_pointers(Tree &pbvh, Mesh *mesh);
/**
* Do a full rebuild with on Grids data structure.
*/
std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);
std::unique_ptr<Tree> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);
/**
* Build a PBVH from a BMesh.
* Build a Tree from a BMesh.
*/
std::unique_ptr<PBVH> build_bmesh(BMesh *bm,
std::unique_ptr<Tree> build_bmesh(BMesh *bm,
BMLog *log,
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);
void update_bmesh_offsets(Tree &pbvh, int cd_vert_node_offset, int cd_face_node_offset);
void build_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image_user);
void free(std::unique_ptr<PBVH> &pbvh);
void build_pixels(Tree &pbvh, Mesh *mesh, Image *image, ImageUser *image_user);
void free(std::unique_ptr<Tree> &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.
* - Gather nodes in an array (easy to multi-thread) see search_gather.
*/
void search_callback(PBVH &pbvh,
FunctionRef<bool(PBVHNode &)> filter_fn,
FunctionRef<void(PBVHNode &)> hit_fn);
void search_callback(Tree &pbvh,
FunctionRef<bool(Node &)> filter_fn,
FunctionRef<void(Node &)> hit_fn);
/* 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 raycast(PBVH &pbvh,
FunctionRef<void(PBVHNode &node, float *tmin)> cb,
void raycast(Tree &pbvh,
FunctionRef<void(Node &node, float *tmin)> cb,
const float ray_start[3],
const float ray_normal[3],
bool original);
bool raycast_node(PBVH &pbvh,
PBVHNode *node,
bool raycast_node(Tree &pbvh,
Node *node,
const float (*origco)[3],
bool use_origco,
Span<int> corner_verts,
@@ -179,7 +349,7 @@ bool raycast_node(PBVH &pbvh,
int *active_face_grid_index,
float *face_normal);
bool bmesh_node_raycast_detail(PBVHNode *node,
bool bmesh_node_raycast_detail(Node *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
@@ -196,16 +366,16 @@ bool bmesh_node_raycast_detail(PBVHNode *node,
* clip_end's can easily lead to floating-point overflows.
*/
void clip_ray_ortho(
PBVH &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]);
Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]);
void find_nearest_to_ray(PBVH &pbvh,
const FunctionRef<void(PBVHNode &node, float *tmin)> fn,
void find_nearest_to_ray(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> fn,
const float ray_start[3],
const float ray_normal[3],
bool original);
bool find_nearest_to_ray_node(PBVH &pbvh,
PBVHNode *node,
bool find_nearest_to_ray_node(Tree &pbvh,
Node *node,
const float (*origco)[3],
bool use_origco,
Span<int> corner_verts,
@@ -218,24 +388,24 @@ bool find_nearest_to_ray_node(PBVH &pbvh,
float *dist_sq);
/* Drawing */
void set_frustum_planes(PBVH &pbvh, PBVHFrustumPlanes *planes);
void get_frustum_planes(const PBVH &pbvh, PBVHFrustumPlanes *planes);
void set_frustum_planes(Tree &pbvh, PBVHFrustumPlanes *planes);
void get_frustum_planes(const Tree &pbvh, PBVHFrustumPlanes *planes);
void draw_cb(const Mesh &mesh,
PBVH &pbvh,
Tree &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);
/**
* Get the PBVH root's bounding box.
* Get the Tree root's bounding box.
*/
Bounds<float3> bounds_get(const PBVH &pbvh);
Bounds<float3> bounds_get(const Tree &pbvh);
} // namespace blender::bke::pbvh
void BKE_pbvh_sync_visibility_from_verts(PBVH &pbvh, Mesh *mesh);
void BKE_pbvh_sync_visibility_from_verts(blender::bke::pbvh::Tree &pbvh, Mesh *mesh);
namespace blender::bke::pbvh {
@@ -249,13 +419,13 @@ int count_grid_quads(const BitGroupVector<> &grid_visibility,
} // namespace blender::bke::pbvh
int BKE_pbvh_get_grid_num_verts(const PBVH &pbvh);
int BKE_pbvh_get_grid_num_faces(const PBVH &pbvh);
int BKE_pbvh_get_grid_num_verts(const blender::bke::pbvh::Tree &pbvh);
int BKE_pbvh_get_grid_num_faces(const blender::bke::pbvh::Tree &pbvh);
/**
* Only valid for type == #PBVH_BMESH.
* Only valid for type == #blender::bke::pbvh::Type::BMesh.
*/
void BKE_pbvh_bmesh_detail_size_set(PBVH &pbvh, float detail_size);
void BKE_pbvh_bmesh_detail_size_set(blender::bke::pbvh::Tree &pbvh, float detail_size);
enum PBVHTopologyUpdateMode {
PBVH_Subdivide = 1,
@@ -268,7 +438,7 @@ namespace blender::bke::pbvh {
/**
* Collapse short edges, subdivide long edges.
*/
bool bmesh_update_topology(PBVH &pbvh,
bool bmesh_update_topology(Tree &pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
@@ -280,66 +450,69 @@ bool bmesh_update_topology(PBVH &pbvh,
/* Node Access */
void BKE_pbvh_node_mark_update(PBVHNode *node);
void BKE_pbvh_node_mark_update_mask(PBVHNode *node);
void BKE_pbvh_node_mark_update_color(PBVHNode *node);
void BKE_pbvh_node_mark_update_face_sets(PBVHNode *node);
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node);
void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
void BKE_pbvh_node_mark_redraw(PBVHNode *node);
void BKE_pbvh_node_mark_positions_update(PBVHNode *node);
void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
bool BKE_pbvh_node_fully_hidden_get(const PBVHNode *node);
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked);
bool BKE_pbvh_node_fully_masked_get(const PBVHNode *node);
void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
bool BKE_pbvh_node_fully_unmasked_get(const PBVHNode *node);
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_update_mask(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_update_color(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_update_face_sets(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_update_visibility(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_rebuild_draw(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_redraw(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_positions_update(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_mark_topology_update(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_fully_hidden_set(blender::bke::pbvh::Node *node, int fully_hidden);
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node *node);
void BKE_pbvh_node_fully_masked_set(blender::bke::pbvh::Node *node, int fully_masked);
bool BKE_pbvh_node_fully_masked_get(const blender::bke::pbvh::Node *node);
void BKE_pbvh_node_fully_unmasked_set(blender::bke::pbvh::Node *node, int fully_masked);
bool BKE_pbvh_node_fully_unmasked_get(const blender::bke::pbvh::Node *node);
void BKE_pbvh_mark_rebuild_pixels(PBVH &pbvh);
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh);
namespace blender::bke::pbvh {
Span<int> node_grid_indices(const PBVHNode &node);
Span<int> node_grid_indices(const Node &node);
Span<int> node_verts(const PBVHNode &node);
Span<int> node_unique_verts(const PBVHNode &node);
Span<int> node_corners(const PBVHNode &node);
Span<int> node_verts(const Node &node);
Span<int> node_unique_verts(const Node &node);
Span<int> node_corners(const Node &node);
/**
* Gather the indices of all faces (not triangles) used by the node.
* For convenience, pass a reference to the data in the result.
*/
Span<int> node_face_indices_calc_mesh(Span<int> corner_tri_faces,
const PBVHNode &node,
const Node &node,
Vector<int> &faces);
/**
* Gather the indices of all base mesh faces in the node.
* For convenience, pass a reference to the data in the result.
*/
Span<int> node_face_indices_calc_grids(const PBVH &pbvh, const PBVHNode &node, Vector<int> &faces);
Span<int> node_face_indices_calc_grids(const Tree &pbvh, const Node &node, Vector<int> &faces);
Bounds<float3> node_bounds(const PBVHNode &node);
Bounds<float3> node_bounds(const Node &node);
} // namespace blender::bke::pbvh
blender::Bounds<blender::float3> BKE_pbvh_node_get_original_BB(const PBVHNode *node);
blender::Bounds<blender::float3> BKE_pbvh_node_get_original_BB(
const blender::bke::pbvh::Node *node);
float BKE_pbvh_node_get_tmin(const PBVHNode *node);
float BKE_pbvh_node_get_tmin(const blender::bke::pbvh::Node *node);
/**
* Test if AABB is at least partially inside the #PBVHFrustumPlanes volume.
*/
bool BKE_pbvh_node_frustum_contain_AABB(const PBVHNode *node, const PBVHFrustumPlanes *frustum);
bool BKE_pbvh_node_frustum_contain_AABB(const blender::bke::pbvh::Node *node,
const PBVHFrustumPlanes *frustum);
/**
* Test if AABB is at least partially outside the #PBVHFrustumPlanes volume.
*/
bool BKE_pbvh_node_frustum_exclude_AABB(const PBVHNode *node, const PBVHFrustumPlanes *frustum);
bool BKE_pbvh_node_frustum_exclude_AABB(const blender::bke::pbvh::Node *node,
const PBVHFrustumPlanes *frustum);
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node);
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_other_verts(PBVHNode *node);
const blender::Set<BMFace *, 0> &BKE_pbvh_bmesh_node_faces(PBVHNode *node);
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::Node *node);
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_other_verts(blender::bke::pbvh::Node *node);
const blender::Set<BMFace *, 0> &BKE_pbvh_bmesh_node_faces(blender::bke::pbvh::Node *node);
/**
* In order to perform operations on the original node coordinates
@@ -347,8 +520,11 @@ const blender::Set<BMFace *, 0> &BKE_pbvh_bmesh_node_faces(PBVHNode *node);
*
* Skips triangles that are hidden.
*/
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool use_original);
void BKE_pbvh_bmesh_after_stroke(PBVH &pbvh);
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm,
BMLog *log,
blender::bke::pbvh::Node *node,
bool use_original);
void BKE_pbvh_bmesh_after_stroke(blender::bke::pbvh::Tree &pbvh);
namespace blender::bke::pbvh {
@@ -356,31 +532,32 @@ namespace blender::bke::pbvh {
* Recalculate node bounding boxes based on the current coordinates. Calculation is only done for
* affected nodes with the #PBVH_UpdateBB flag set.
*/
void update_bounds(PBVH &pbvh);
void update_bounds(Tree &pbvh);
/**
* Copy all current node bounds to the original bounds. "Original" bounds are typically from before
* a brush stroke started (while the "regular" bounds update on every change of positions). These
* are stored to optimize the BVH traversal for original coordinates enabled by various "use
* original" arguments in the PBVH API.
* original" arguments in the Tree API.
*/
void store_bounds_orig(PBVH &pbvh);
void store_bounds_orig(Tree &pbvh);
void update_mask(PBVH &pbvh);
void update_visibility(PBVH &pbvh);
void update_normals(PBVH &pbvh, SubdivCCG *subdiv_ccg);
void update_mask(Tree &pbvh);
void update_visibility(Tree &pbvh);
void update_normals(Tree &pbvh, SubdivCCG *subdiv_ccg);
} // namespace blender::bke::pbvh
blender::Bounds<blender::float3> BKE_pbvh_redraw_BB(PBVH &pbvh);
blender::Bounds<blender::float3> BKE_pbvh_redraw_BB(blender::bke::pbvh::Tree &pbvh);
namespace blender::bke::pbvh {
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
Span<const PBVHNode *> nodes,
Span<const Node *> nodes,
IndexMaskMemory &memory);
}
void BKE_pbvh_subdiv_cgg_set(PBVH &pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_subdiv_cgg_set(blender::bke::pbvh::Tree &pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_vert_coords_apply(PBVH &pbvh, blender::Span<blender::float3> vert_positions);
bool BKE_pbvh_is_deformed(const PBVH &pbvh);
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh,
blender::Span<blender::float3> vert_positions);
bool BKE_pbvh_is_deformed(const blender::bke::pbvh::Tree &pbvh);
/* Vertex Iterator. */
@@ -441,7 +618,10 @@ struct PBVHVertexIter {
bool visible;
};
void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode);
void pbvh_vertex_iter_init(blender::bke::pbvh::Tree &pbvh,
blender::bke::pbvh::Node *node,
PBVHVertexIter *vi,
int mode);
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \
pbvh_vertex_iter_init(pbvh, node, &vi, mode); \
@@ -520,41 +700,42 @@ void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
#define PBVH_FACE_ITER_VERTS_RESERVED 8
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
void BKE_pbvh_node_get_bm_orco_data(blender::bke::pbvh::Node *node,
int (**r_orco_tris)[3],
int *r_orco_tris_num,
float (**r_orco_coords)[3],
BMVert ***r_orco_verts);
bool pbvh_has_mask(const PBVH &pbvh);
bool pbvh_has_mask(const blender::bke::pbvh::Tree &pbvh);
bool pbvh_has_face_sets(PBVH &pbvh);
bool pbvh_has_face_sets(blender::bke::pbvh::Tree &pbvh);
blender::Span<blender::float3> BKE_pbvh_get_vert_positions(const PBVH &pbvh);
blender::MutableSpan<blender::float3> BKE_pbvh_get_vert_positions(PBVH &pbvh);
blender::Span<blender::float3> BKE_pbvh_get_vert_normals(const PBVH &pbvh);
blender::Span<blender::float3> BKE_pbvh_get_vert_positions(const blender::bke::pbvh::Tree &pbvh);
blender::MutableSpan<blender::float3> BKE_pbvh_get_vert_positions(blender::bke::pbvh::Tree &pbvh);
blender::Span<blender::float3> BKE_pbvh_get_vert_normals(const blender::bke::pbvh::Tree &pbvh);
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node);
void BKE_pbvh_node_color_buffer_free(PBVH &pbvh);
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(blender::bke::pbvh::Node *node);
void BKE_pbvh_node_color_buffer_free(blender::bke::pbvh::Tree &pbvh);
void BKE_pbvh_ensure_node_loops(PBVH &pbvh, blender::Span<blender::int3> corner_tris);
int BKE_pbvh_debug_draw_gen_get(PBVHNode &node);
void BKE_pbvh_ensure_node_loops(blender::bke::pbvh::Tree &pbvh,
blender::Span<blender::int3> corner_tris);
int BKE_pbvh_debug_draw_gen_get(blender::bke::pbvh::Node &node);
namespace blender::bke::pbvh {
Vector<PBVHNode *> search_gather(PBVH &pbvh,
FunctionRef<bool(PBVHNode &)> scb,
PBVHNodeFlags leaf_flag = PBVH_Leaf);
Vector<Node *> search_gather(Tree &pbvh,
FunctionRef<bool(Node &)> scb,
PBVHNodeFlags leaf_flag = PBVH_Leaf);
void node_update_mask_mesh(Span<float> mask, PBVHNode &node);
void node_update_mask_grids(const CCGKey &key, Span<CCGElem *> grids, PBVHNode &node);
void node_update_mask_bmesh(int mask_offset, PBVHNode &node);
void node_update_mask_mesh(Span<float> mask, Node &node);
void node_update_mask_grids(const CCGKey &key, Span<CCGElem *> grids, Node &node);
void node_update_mask_bmesh(int mask_offset, Node &node);
void node_update_visibility_mesh(Span<bool> hide_vert, PBVHNode &node);
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, PBVHNode &node);
void node_update_visibility_bmesh(PBVHNode &node);
void node_update_visibility_mesh(Span<bool> hide_vert, Node &node);
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, Node &node);
void node_update_visibility_bmesh(Node &node);
void update_node_bounds_mesh(Span<float3> positions, PBVHNode &node);
void update_node_bounds_grids(const CCGKey &key, Span<CCGElem *> grids, PBVHNode &node);
void update_node_bounds_bmesh(PBVHNode &node);
void update_node_bounds_mesh(Span<float3> positions, Node &node);
void update_node_bounds_grids(const CCGKey &key, Span<CCGElem *> grids, Node &node);
void update_node_bounds_bmesh(Node &node);
} // namespace blender::bke::pbvh

View File

@@ -416,11 +416,14 @@ struct PBVHData {
}
};
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);
NodeData &node_data_get(blender::bke::pbvh::Node &node);
void mark_image_dirty(blender::bke::pbvh::Node &node, Image &image, ImageUser &image_user);
PBVHData &data_get(blender::bke::pbvh::Tree &pbvh);
void collect_dirty_tiles(blender::bke::pbvh::Node &node, Vector<image::TileNumber> &r_dirty_tiles);
void copy_pixels(PBVH &pbvh, Image &image, ImageUser &image_user, image::TileNumber tile_number);
void copy_pixels(blender::bke::pbvh::Tree &pbvh,
Image &image,
ImageUser &image_user,
image::TileNumber tile_number);
} // namespace blender::bke::pbvh::pixels

View File

@@ -26,7 +26,9 @@ struct Mesh;
struct MeshElemMap;
struct MultiresModifierData;
struct Object;
struct PBVH;
namespace blender::bke::pbvh {
class Tree;
}
struct SubsurfModifierData;
/**************************** External *****************************/

View File

@@ -11,7 +11,6 @@
#include "BKE_mesh_legacy_derived_mesh.hh"
struct MeshElemMap;
struct PBVH;
/* -------------------------------------------------------------------- */

View File

@@ -509,8 +509,8 @@ void mesh_remesh_reproject_attributes(const Mesh &src, Mesh &dst)
/* The main idea in the following code is to trade some complexity in sampling for the benefit of
* only using and building a single BVH tree. Since sculpt mode doesn't generally deal with loose
* vertices and edges, we use the standard "triangles" BVH which won't contain them. Also, only
* relying on a single BVH should reduce memory usage, and work better if the BVH and PBVH are
* ever merged.
* relying on a single BVH should reduce memory usage, and work better if the BVH and pbvh::Tree
* are ever merged.
*
* One key decision is separating building transfer index maps from actually transferring any
* attribute data. This is important to keep attribute storage independent from the specifics of

View File

@@ -398,8 +398,8 @@ void multires_flush_sculpt_updates(Object *object)
}
SculptSession *sculpt_session = object->sculpt;
if (BKE_pbvh_type(*sculpt_session->pbvh) != PBVH_GRIDS || !sculpt_session->multires.active ||
sculpt_session->multires.modifier == nullptr)
if (sculpt_session->pbvh->type() != blender::bke::pbvh::Type::Grids ||
!sculpt_session->multires.active || sculpt_session->multires.modifier == nullptr)
{
return;
}
@@ -1204,7 +1204,8 @@ void multires_stitch_grids(Object *ob)
if (subdiv_ccg == nullptr) {
return;
}
BLI_assert(sculpt_session->pbvh && BKE_pbvh_type(*sculpt_session->pbvh) == PBVH_GRIDS);
BLI_assert(sculpt_session->pbvh &&
sculpt_session->pbvh->type() == blender::bke::pbvh::Type::Grids);
BKE_subdiv_ccg_average_stitch_faces(*subdiv_ccg, IndexMask(subdiv_ccg->faces.size()));
}

View File

@@ -80,22 +80,19 @@
#include "bmesh.hh"
/* For #PBVH::~PBVH(). */
#include "pbvh_intern.hh"
using blender::float3;
using blender::MutableSpan;
using blender::Span;
using blender::Vector;
using blender::bke::AttrDomain;
static void sculpt_attribute_update_refs(Object *ob, PBVHType pbvhtype);
static void sculpt_attribute_update_refs(Object *ob, blender::bke::pbvh::Type pbvhtype);
static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
AttrDomain domain,
eCustomDataType proptype,
const char *name,
const SculptAttributeParams *params,
PBVHType pbvhtype,
blender::bke::pbvh::Type pbvhtype,
bool flat_array_for_bmesh);
static void sculptsession_bmesh_add_layers(Object *ob);
@@ -1763,7 +1760,7 @@ static MultiresModifierData *sculpt_multires_modifier_get(const Scene *scene,
}
/* Weight paint operates on original vertices, and needs to treat multires as regular modifier
* to make it so that PBVH vertices are at the multires surface. */
* to make it so that pbvh::Tree vertices are at the multires surface. */
if ((ob->mode & OB_MODE_SCULPT) == 0) {
return nullptr;
}
@@ -1933,13 +1930,13 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss.subdiv_ccg = mesh_eval->runtime->subdiv_ccg.get();
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
blender::bke::pbvh::Tree *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
BLI_assert(pbvh == ss.pbvh.get());
UNUSED_VARS_NDEBUG(pbvh);
BKE_pbvh_subdiv_cgg_set(*ss.pbvh, ss.subdiv_ccg);
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ss.pbvh));
sculpt_attribute_update_refs(ob, ss.pbvh->type());
sculpt_update_persistent_base(ob);
if (ob->type == OB_MESH) {
@@ -2005,7 +2002,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
if (key_data.data() != nullptr) {
if (!pbvh_deformed) {
/* apply shape keys coordinates to PBVH */
/* apply shape keys coordinates to pbvh::Tree */
BKE_pbvh_vert_coords_apply(*ss.pbvh, key_data);
}
if (ss.deform_cos.is_empty()) {
@@ -2050,8 +2047,8 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval)
if (ss && ss->building_vp_handle == false) {
if (!ss->cache && !ss->filter_cache && !ss->expand_cache) {
if (ss->pbvh) {
/* PBVH nodes may contain dirty normal tags. To avoid losing that information when the PBVH
* is deleted, make sure all tagged geometry normals are up to date.
/* pbvh::Tree nodes may contain dirty normal tags. To avoid losing that information when
* the pbvh::Tree is deleted, make sure all tagged geometry normals are up to date.
* See #122947 for more information. */
blender::bke::pbvh::update_normals(*ss->pbvh, ss->subdiv_ccg);
}
@@ -2066,9 +2063,9 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval)
BKE_sculptsession_free_vwpaint_data(ob_eval->sculpt);
}
else if (ss->pbvh) {
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(*ss->pbvh, {});
Vector<blender::bke::pbvh::Node *> nodes = blender::bke::pbvh::search_gather(*ss->pbvh, {});
for (PBVHNode *node : nodes) {
for (blender::bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update(node);
}
}
@@ -2077,7 +2074,7 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval)
void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
{
/* Update after mesh evaluation in the dependency graph, to rebuild PBVH or
/* Update after mesh evaluation in the dependency graph, to rebuild pbvh::Tree or
* other data when modifiers change the mesh. */
Object *ob_orig = DEG_get_original_object(ob_eval);
@@ -2243,7 +2240,7 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
bool deformed = false;
/* Active modifiers means extra deformation, which can't be handled correct
* on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
* on birth of pbvh::Tree and sculpt "layer" levels, so use pbvh::Tree only for internal brush
* stuff and show final evaluated mesh so user would see actual object shape. */
deformed |= object->sculpt->deform_modifiers_active;
@@ -2252,7 +2249,7 @@ static bool check_sculpt_object_deformed(Object *object, const bool for_construc
}
else {
/* As in case with modifiers, we can't synchronize deformation made against
* PBVH and non-locked keyblock, so also use PBVH only for brushes and
* pbvh::Tree and non-locked keyblock, so also use pbvh::Tree only for brushes and
* final DM to give final result to user. */
deformed |= object->sculpt->shapekey_active && (object->shapeflag & OB_SHAPE_LOCK) == 0;
}
@@ -2292,7 +2289,7 @@ void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
namespace blender::bke {
static std::unique_ptr<PBVH> build_pbvh_for_dynamic_topology(Object *ob)
static std::unique_ptr<pbvh::Tree> build_pbvh_for_dynamic_topology(Object *ob)
{
sculptsession_bmesh_add_layers(ob);
@@ -2302,10 +2299,11 @@ static std::unique_ptr<PBVH> build_pbvh_for_dynamic_topology(Object *ob)
ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
}
static std::unique_ptr<PBVH> build_pbvh_from_regular_mesh(Object *ob, const Mesh *me_eval_deform)
static std::unique_ptr<pbvh::Tree> build_pbvh_from_regular_mesh(Object *ob,
const Mesh *me_eval_deform)
{
Mesh *mesh = BKE_object_get_original_mesh(ob);
std::unique_ptr<PBVH> pbvh = pbvh::build_mesh(mesh);
std::unique_ptr<pbvh::Tree> pbvh = pbvh::build_mesh(mesh);
const bool is_deformed = check_sculpt_object_deformed(ob, true);
if (is_deformed && me_eval_deform != nullptr) {
@@ -2315,7 +2313,7 @@ static std::unique_ptr<PBVH> build_pbvh_from_regular_mesh(Object *ob, const Mesh
return pbvh;
}
static std::unique_ptr<PBVH> build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
static std::unique_ptr<pbvh::Tree> build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
{
Mesh *base_mesh = BKE_mesh_from_object(ob);
BKE_sculpt_sync_face_visibility_to_grids(base_mesh, subdiv_ccg);
@@ -2325,7 +2323,7 @@ static std::unique_ptr<PBVH> build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_c
} // namespace blender::bke
PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
blender::bke::pbvh::Tree *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
{
using namespace blender::bke;
if (ob->sculpt == nullptr) {
@@ -2335,13 +2333,13 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
if (ob->sculpt->pbvh) {
/* NOTE: It is possible that pointers to grids or other geometry data changed. Need to update
* those pointers. */
const PBVHType pbvh_type = BKE_pbvh_type(*ob->sculpt->pbvh);
const pbvh::Type pbvh_type = ob->sculpt->pbvh->type();
switch (pbvh_type) {
case PBVH_FACES:
case pbvh::Type::Mesh:
pbvh::update_mesh_pointers(*ob->sculpt->pbvh, BKE_object_get_original_mesh(ob));
break;
case PBVH_GRIDS:
case PBVH_BMESH:
case pbvh::Type::Grids:
case pbvh::Type::BMesh:
break;
}
@@ -2351,7 +2349,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
ob->sculpt->islands_valid = false;
if (ob->sculpt->bm != nullptr) {
/* Sculpting on a BMesh (dynamic-topology) gets a special PBVH. */
/* Sculpting on a BMesh (dynamic-topology) gets a special pbvh::Tree. */
ob->sculpt->pbvh = build_pbvh_for_dynamic_topology(ob);
}
else {
@@ -2366,11 +2364,11 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
}
}
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ob->sculpt->pbvh));
sculpt_attribute_update_refs(ob, ob->sculpt->pbvh->type());
return ob->sculpt->pbvh.get();
}
PBVH *BKE_object_sculpt_pbvh_get(Object *object)
blender::bke::pbvh::Tree *BKE_object_sculpt_pbvh_get(Object *object)
{
if (!object->sculpt) {
return nullptr;
@@ -2390,14 +2388,14 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
return false;
}
if (BKE_pbvh_type(*ss->pbvh) == PBVH_FACES) {
/* Regular mesh only draws from PBVH without modifiers and shape keys, or for
* external engines that do not have access to the PBVH like Eevee does. */
if (ss->pbvh->type() == blender::bke::pbvh::Type::Mesh) {
/* Regular mesh only draws from pbvh::Tree without modifiers and shape keys, or for
* external engines that do not have access to the pbvh::Tree like Eevee does. */
const bool external_engine = rv3d && rv3d->view_render != nullptr;
return !(ss->shapekey_active || ss->deform_modifiers_active || external_engine);
}
/* Multires and dyntopo always draw directly from the PBVH. */
/* Multires and dyntopo always draw directly from the pbvh::Tree. */
return true;
}
@@ -2456,7 +2454,7 @@ static CustomData *sculpt_get_cdata(Object *ob, AttrDomain domain)
switch (domain) {
case AttrDomain::Point:
/* Cannot get vertex domain for multires grids. */
if (ss.pbvh && BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
if (ss.pbvh && ss.pbvh->type() == blender::bke::pbvh::Type::Grids) {
return nullptr;
}
@@ -2494,7 +2492,7 @@ static bool sculpt_attribute_create(SculptSession *ss,
const char *name,
SculptAttribute *out,
const SculptAttributeParams *params,
PBVHType pbvhtype,
blender::bke::pbvh::Type pbvhtype,
bool flat_array_for_bmesh)
{
Mesh *mesh = BKE_object_get_original_mesh(ob);
@@ -2507,8 +2505,10 @@ static bool sculpt_attribute_create(SculptSession *ss,
out->domain = domain;
STRNCPY_UTF8(out->name, name);
/* Force non-CustomData simple_array mode if not PBVH_FACES. */
if (pbvhtype == PBVH_GRIDS || (pbvhtype == PBVH_BMESH && flat_array_for_bmesh)) {
/* Force non-CustomData simple_array mode if not pbvh::Type::Mesh. */
if (pbvhtype == blender::bke::pbvh::Type::Grids ||
(pbvhtype == blender::bke::pbvh::Type::BMesh && flat_array_for_bmesh))
{
if (permanent) {
printf(
"%s: error: tried to make permanent customdata in multires or bmesh mode; will make "
@@ -2612,7 +2612,9 @@ static bool sculpt_attribute_create(SculptSession *ss,
return true;
}
static bool sculpt_attr_update(Object *ob, SculptAttribute *attr, PBVHType pbvh_type)
static bool sculpt_attr_update(Object *ob,
SculptAttribute *attr,
blender::bke::pbvh::Type pbvh_type)
{
SculptSession *ss = ob->sculpt;
int elem_num = sculpt_attr_elem_count_get(ob, attr->domain);
@@ -2625,7 +2627,7 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr, PBVHType pbvh_
/* Check if we are a coerced simple array and shouldn't be. */
bad |= attr->simple_array && !attr->params.simple_array &&
!ELEM(pbvh_type, PBVH_GRIDS, PBVH_BMESH);
!ELEM(pbvh_type, blender::bke::pbvh::Type::Grids, blender::bke::pbvh::Type::BMesh);
CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
if (cdata && !attr->simple_array) {
@@ -2697,9 +2699,12 @@ static SculptAttribute *sculpt_alloc_attr(SculptSession *ss)
return nullptr;
}
/* The PBVH is NOT guaranteed to exist at the point of this method being called. */
static SculptAttribute *sculpt_attribute_get_ex(
Object *ob, PBVHType pbvhtype, AttrDomain domain, eCustomDataType proptype, const char *name)
/* The pbvh::Tree is NOT guaranteed to exist at the point of this method being called. */
static SculptAttribute *sculpt_attribute_get_ex(Object *ob,
blender::bke::pbvh::Type pbvhtype,
AttrDomain domain,
eCustomDataType proptype,
const char *name)
{
SculptSession *ss = ob->sculpt;
/* See if attribute is cached in ss->temp_attributes. */
@@ -2760,7 +2765,7 @@ SculptAttribute *BKE_sculpt_attribute_get(Object *ob,
SculptSession *ss = ob->sculpt;
BLI_assert(ss->pbvh != nullptr);
return sculpt_attribute_get_ex(ob, BKE_pbvh_type(*ss->pbvh), domain, proptype, name);
return sculpt_attribute_get_ex(ob, ss->pbvh->type(), domain, proptype, name);
}
static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
@@ -2768,7 +2773,7 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
eCustomDataType proptype,
const char *name,
const SculptAttributeParams *params,
PBVHType pbvhtype,
blender::bke::pbvh::Type pbvhtype,
bool flat_array_for_bmesh)
{
SculptSession *ss = ob->sculpt;
@@ -2804,7 +2809,7 @@ SculptAttribute *BKE_sculpt_attribute_ensure(Object *ob,
SculptAttributeParams temp_params = *params;
return sculpt_attribute_ensure_ex(
ob, domain, proptype, name, &temp_params, BKE_pbvh_type(*ob->sculpt->pbvh), true);
ob, domain, proptype, name, &temp_params, ob->sculpt->pbvh->type(), true);
}
static void sculptsession_bmesh_attr_update_internal(Object *ob)
@@ -2832,7 +2837,7 @@ static void sculptsession_bmesh_add_layers(Object *ob)
CD_PROP_INT32,
SCULPT_ATTRIBUTE_NAME(dyntopo_node_id_vertex),
&params,
PBVH_BMESH,
blender::bke::pbvh::Type::BMesh,
false);
ss->attrs.dyntopo_node_id_face = sculpt_attribute_ensure_ex(
@@ -2841,7 +2846,7 @@ static void sculptsession_bmesh_add_layers(Object *ob)
CD_PROP_INT32,
SCULPT_ATTRIBUTE_NAME(dyntopo_node_id_face),
&params,
PBVH_BMESH,
blender::bke::pbvh::Type::BMesh,
false);
}
@@ -2858,7 +2863,7 @@ void BKE_sculpt_attributes_destroy_temporary_stroke(Object *ob)
}
}
static void sculpt_attribute_update_refs(Object *ob, PBVHType pbvhtype)
static void sculpt_attribute_update_refs(Object *ob, blender::bke::pbvh::Type pbvhtype)
{
SculptSession *ss = ob->sculpt;
@@ -2957,9 +2962,9 @@ bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr)
}
if (ss->pbvh) {
/* If the PBVH doesn't exist, we cannot update references
/* If the pbvh::Tree doesn't exist, we cannot update references
* This can occur when all the attributes are being deleted. */
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ss->pbvh));
sculpt_attribute_update_refs(ob, ss->pbvh->type());
}
}

View File

@@ -59,19 +59,19 @@ using blender::bke::AttrDomain;
*/
// #define TEST_PBVH_FACE_SPLIT
/* Uncomment to test that faces are only assigned to one PBVHNode */
/* Uncomment to test that faces are only assigned to one Node */
// #define VALIDATE_UNIQUE_NODE_FACES
#define STACK_FIXED_DEPTH 100
struct PBVHStack {
PBVHNode *node;
blender::bke::pbvh::Node *node;
bool revisiting;
};
struct PBVHIter {
PBVH *pbvh;
blender::FunctionRef<bool(PBVHNode &)> scb;
blender::bke::pbvh::Tree *pbvh;
blender::FunctionRef<bool(blender::bke::pbvh::Node &)> scb;
PBVHStack *stack;
int stacksize;
@@ -199,42 +199,42 @@ static void build_mesh_leaf_node(const Span<int> corner_verts,
const Span<int> tri_faces,
const Span<bool> hide_poly,
MutableSpan<bool> vert_bitmap,
PBVHNode *node)
Node *node)
{
node->uniq_verts = 0;
node->uniq_verts_ = 0;
int shared_verts = 0;
const Span<int> prim_indices = node->prim_indices;
const Span<int> prim_indices = node->prim_indices_;
/* reserve size is rough guess */
Map<int, int> map;
map.reserve(prim_indices.size());
node->face_vert_indices.reinitialize(prim_indices.size());
node->face_vert_indices_.reinitialize(prim_indices.size());
for (const int i : prim_indices.index_range()) {
const int3 &tri = corner_tris[prim_indices[i]];
for (int j = 0; j < 3; j++) {
node->face_vert_indices[i][j] = map_insert_vert(
map, vert_bitmap, &shared_verts, &node->uniq_verts, corner_verts[tri[j]]);
node->face_vert_indices_[i][j] = map_insert_vert(
map, vert_bitmap, &shared_verts, &node->uniq_verts_, corner_verts[tri[j]]);
}
}
node->vert_indices.reinitialize(node->uniq_verts + shared_verts);
node->vert_indices_.reinitialize(node->uniq_verts_ + shared_verts);
/* Build the vertex list, unique verts first */
for (const MapItem<int, int> item : map.items()) {
int value = item.value;
if (value < 0) {
value = -value + node->uniq_verts - 1;
value = -value + node->uniq_verts_ - 1;
}
node->vert_indices[value] = item.key;
node->vert_indices_[value] = item.key;
}
for (const int i : prim_indices.index_range()) {
for (int j = 0; j < 3; j++) {
if (node->face_vert_indices[i][j] < 0) {
node->face_vert_indices[i][j] = -node->face_vert_indices[i][j] + node->uniq_verts - 1;
if (node->face_vert_indices_[i][j] < 0) {
node->face_vert_indices_[i][j] = -node->face_vert_indices_[i][j] + node->uniq_verts_ - 1;
}
}
}
@@ -248,16 +248,16 @@ static void build_mesh_leaf_node(const Span<int> corner_verts,
}
static void update_vb(const Span<int> prim_indices,
PBVHNode *node,
Node *node,
const Span<Bounds<float3>> prim_bounds,
int offset,
int count)
{
node->bounds = prim_bounds[prim_indices[offset]];
node->bounds_ = prim_bounds[prim_indices[offset]];
for (const int i : IndexRange(offset, count).drop_front(1)) {
node->bounds = bounds::merge(node->bounds, prim_bounds[prim_indices[i]]);
node->bounds_ = bounds::merge(node->bounds_, prim_bounds[prim_indices[i]]);
}
node->bounds_orig = node->bounds;
node->bounds_orig_ = node->bounds_;
}
int count_grid_quads(const BitGroupVector<> &grid_hidden,
@@ -294,17 +294,17 @@ int count_grid_quads(const BitGroupVector<> &grid_hidden,
return totquad;
}
static void build_grid_leaf_node(PBVH &pbvh, PBVHNode *node)
static void build_grid_leaf_node(Tree &pbvh, Node *node)
{
int totquads = count_grid_quads(pbvh.subdiv_ccg->grid_hidden,
node->prim_indices,
pbvh.subdiv_ccg->grid_size,
pbvh.subdiv_ccg->grid_size);
int totquads = count_grid_quads(pbvh.subdiv_ccg_->grid_hidden,
node->prim_indices_,
pbvh.subdiv_ccg_->grid_size,
pbvh.subdiv_ccg_->grid_size);
BKE_pbvh_node_fully_hidden_set(node, (totquads == 0));
BKE_pbvh_node_mark_rebuild_draw(node);
}
static void build_leaf(PBVH &pbvh,
static void build_leaf(Tree &pbvh,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> tri_faces,
@@ -315,13 +315,13 @@ static void build_leaf(PBVH &pbvh,
int offset,
int count)
{
PBVHNode &node = pbvh.nodes[node_index];
node.flag |= PBVH_Leaf;
Node &node = pbvh.nodes_[node_index];
node.flag_ |= PBVH_Leaf;
node.prim_indices = pbvh.prim_indices.as_span().slice(offset, count);
node.prim_indices_ = pbvh.prim_indices_.as_span().slice(offset, count);
/* Still need vb for searches */
update_vb(pbvh.prim_indices, &node, prim_bounds, offset, count);
update_vb(pbvh.prim_indices_, &node, prim_bounds, offset, count);
if (!corner_tris.is_empty()) {
build_mesh_leaf_node(corner_verts, corner_tris, tri_faces, hide_poly, vert_bitmap, &node);
@@ -333,7 +333,7 @@ static void build_leaf(PBVH &pbvh,
/* Return zero if all primitives in the node can be drawn with the
* same material (including flat/smooth shading), non-zero otherwise */
static bool leaf_needs_material_split(PBVH &pbvh,
static bool leaf_needs_material_split(Tree &pbvh,
const Span<int> prim_to_face_map,
const Span<int> material_indices,
const Span<bool> sharp_faces,
@@ -344,9 +344,9 @@ static bool leaf_needs_material_split(PBVH &pbvh,
return false;
}
const int first = prim_to_face_map[pbvh.prim_indices[offset]];
const int first = prim_to_face_map[pbvh.prim_indices_[offset]];
for (int i = offset + count - 1; i > offset; i--) {
int prim = pbvh.prim_indices[i];
int prim = pbvh.prim_indices_[i];
if (!face_materials_match(material_indices, sharp_faces, first, prim_to_face_map[prim])) {
return true;
}
@@ -356,30 +356,32 @@ static bool leaf_needs_material_split(PBVH &pbvh,
}
#ifdef TEST_PBVH_FACE_SPLIT
static void test_face_boundaries(PBVH &pbvh, const Mesh &mesh)
static void test_face_boundaries(Tree &pbvh, const Mesh &mesh)
{
if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
if (pbvh.type() == Type::Mesh) {
int faces_num = mesh.faces_num;
Array<int> node_map(faces_num, -1);
for (int i = 0; i < pbvh.totnode; i++) {
PBVHNode *node = pbvh.nodes + i;
if (!(node->flag & PBVH_Leaf)) {
Node *node = pbvh.nodes_ + i;
if (!(node->flag_ & PBVH_Leaf)) {
continue;
}
for (int j = 0; j < node->totprim; j++) {
int face_i = mesh.corner_tri_faces()[node->prim_indices[j]];
int face_i = mesh.corner_tri_faces()[node->prim_indices_[j]];
if (node_map[face_i] >= 0 && node_map[face_i] != i) {
int old_i = node_map[face_i];
int prim_i = node->prim_indices - pbvh.prim_indices + j;
int prim_i = node->prim_indices_ - pbvh.prim_indices_ + j;
printf("PBVH split error; face: %d, prim_i: %d, node1: %d, node2: %d, totprim: %d\n",
face_i,
prim_i,
old_i,
i,
node->totprim);
printf(
"Tree split error; face: %d, prim_i: %d, node1: %d, node2: %d, "
"totprim: %d\n",
face_i,
prim_i,
old_i,
i,
node->totprim);
}
node_map[face_i] = i;
@@ -400,7 +402,7 @@ static void test_face_boundaries(PBVH &pbvh, const Mesh &mesh)
* offset and start indicate a range in the array of primitive indices
*/
static void build_sub(PBVH &pbvh,
static void build_sub(Tree &pbvh,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> tri_faces,
@@ -417,14 +419,14 @@ static void build_sub(PBVH &pbvh,
int *prim_scratch,
int depth)
{
const Span<int> prim_to_face_map = pbvh.header.type == PBVH_FACES ?
const Span<int> prim_to_face_map = pbvh.type() == Type::Mesh ?
tri_faces :
pbvh.subdiv_ccg->grid_to_face_map;
pbvh.subdiv_ccg_->grid_to_face_map;
int end;
if (!prim_scratch) {
prim_scratch = static_cast<int *>(
MEM_malloc_arrayN(pbvh.prim_indices.size(), sizeof(int), __func__));
MEM_malloc_arrayN(pbvh.prim_indices_.size(), sizeof(int), __func__));
}
/* Decide whether this is a leaf or not */
@@ -453,11 +455,11 @@ static void build_sub(PBVH &pbvh,
}
/* Add two child nodes */
pbvh.nodes[node_index].children_offset = pbvh.nodes.size();
pbvh.nodes.resize(pbvh.nodes.size() + 2);
pbvh.nodes_[node_index].children_offset_ = pbvh.nodes_.size();
pbvh.nodes_.resize(pbvh.nodes_.size() + 2);
/* Update parent node bounding box */
update_vb(pbvh.prim_indices, &pbvh.nodes[node_index], prim_bounds, offset, count);
update_vb(pbvh.prim_indices_, &pbvh.nodes_[node_index], prim_bounds, offset, count);
Bounds<float3> cb_backing;
if (!below_leaf_limit) {
@@ -465,7 +467,7 @@ static void build_sub(PBVH &pbvh,
if (!cb) {
cb_backing = negative_bounds();
for (int i = offset + count - 1; i >= offset; i--) {
const int prim = pbvh.prim_indices[i];
const int prim = pbvh.prim_indices_[i];
const float3 center = math::midpoint(prim_bounds[prim].min, prim_bounds[prim].max);
math::min_max(center, cb_backing.min, cb_backing.max);
}
@@ -474,7 +476,7 @@ static void build_sub(PBVH &pbvh,
const int axis = math::dominant_axis(cb->max - cb->min);
/* Partition primitives along that axis */
end = partition_prim_indices(pbvh.prim_indices,
end = partition_prim_indices(pbvh.prim_indices_,
prim_scratch,
offset,
offset + count,
@@ -485,7 +487,7 @@ static void build_sub(PBVH &pbvh,
}
else {
/* Partition primitives by material */
end = partition_indices_material_faces(pbvh.prim_indices,
end = partition_indices_material_faces(pbvh.prim_indices_,
prim_to_face_map,
material_indices,
sharp_faces,
@@ -503,7 +505,7 @@ static void build_sub(PBVH &pbvh,
sharp_faces,
leaf_limit,
vert_bitmap,
pbvh.nodes[node_index].children_offset,
pbvh.nodes_[node_index].children_offset_,
nullptr,
prim_bounds,
offset,
@@ -519,7 +521,7 @@ static void build_sub(PBVH &pbvh,
sharp_faces,
leaf_limit,
vert_bitmap,
pbvh.nodes[node_index].children_offset + 1,
pbvh.nodes_[node_index].children_offset_ + 1,
nullptr,
prim_bounds,
end,
@@ -532,7 +534,7 @@ static void build_sub(PBVH &pbvh,
}
}
static void pbvh_build(PBVH &pbvh,
static void pbvh_build(Tree &pbvh,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const Span<int> tri_faces,
@@ -545,12 +547,12 @@ static void pbvh_build(PBVH &pbvh,
const Span<Bounds<float3>> prim_bounds,
int totprim)
{
pbvh.nodes.clear_and_shrink();
pbvh.nodes_.clear_and_shrink();
pbvh.prim_indices.reinitialize(totprim);
array_utils::fill_index_range<int>(pbvh.prim_indices);
pbvh.prim_indices_.reinitialize(totprim);
array_utils::fill_index_range<int>(pbvh.prim_indices_);
pbvh.nodes.resize(1);
pbvh.nodes_.resize(1);
build_sub(pbvh,
corner_verts,
@@ -571,29 +573,29 @@ static void pbvh_build(PBVH &pbvh,
}
#ifdef VALIDATE_UNIQUE_NODE_FACES
static void pbvh_validate_node_prims(PBVH &pbvh, const Span<int> tri_faces)
static void pbvh_validate_node_prims(Tree &pbvh, const Span<int> tri_faces)
{
int totface = 0;
if (pbvh.header.type == PBVH_BMESH) {
if (pbvh.type() == Type::BMesh) {
return;
}
for (int i = 0; i < pbvh.totnode; i++) {
PBVHNode *node = pbvh.nodes + i;
Node *node = pbvh.nodes_ + i;
if (!(node->flag & PBVH_Leaf)) {
if (!(node->flag_ & PBVH_Leaf)) {
continue;
}
for (int j = 0; j < node->totprim; j++) {
int face_i;
if (pbvh.header.type == PBVH_FACES) {
face_i = tri_faces[node->prim_indices[j]];
if (pbvh.type() == Type::Mesh) {
face_i = tri_faces[node->prim_indices_[j]];
}
else {
face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh.subdiv_ccg, node->prim_indices[j]);
face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh.subdiv_ccg_, node->prim_indices_[j]);
}
totface = max_ii(totface, face_i + 1);
@@ -607,20 +609,20 @@ static void pbvh_validate_node_prims(PBVH &pbvh, const Span<int> tri_faces)
}
for (int i = 0; i < pbvh.totnode; i++) {
PBVHNode *node = pbvh.nodes + i;
Node *node = pbvh.nodes_ + i;
if (!(node->flag & PBVH_Leaf)) {
if (!(node->flag_ & PBVH_Leaf)) {
continue;
}
for (int j = 0; j < node->totprim; j++) {
int face_i;
if (pbvh.header.type == PBVH_FACES) {
face_i = tri_faces[node->prim_indices[j]];
if (pbvh.type() == Type::Mesh) {
face_i = tri_faces[node->prim_indices_[j]];
}
else {
face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh.subdiv_ccg, node->prim_indices[j]);
face_i = BKE_subdiv_ccg_grid_to_face_index(pbvh.subdiv_ccg_, node->prim_indices_[j]);
}
if (facemap[face_i] != -1 && facemap[face_i] != i) {
@@ -637,28 +639,27 @@ static void pbvh_validate_node_prims(PBVH &pbvh, const Span<int> tri_faces)
}
#endif
void update_mesh_pointers(PBVH &pbvh, Mesh *mesh)
void update_mesh_pointers(Tree &pbvh, Mesh *mesh)
{
BLI_assert(pbvh.header.type == PBVH_FACES);
if (!pbvh.deformed) {
/* Deformed data not matching the original mesh are owned directly by the PBVH, and are
* set separately by #BKE_pbvh_vert_coords_apply. */
pbvh.vert_positions = mesh->vert_positions_for_write();
pbvh.vert_normals = mesh->vert_normals();
pbvh.face_normals = mesh->face_normals();
BLI_assert(pbvh.type() == Type::Mesh);
if (!pbvh.deformed_) {
/* Deformed data not matching the original mesh are owned directly by the
* Tree, and are set separately by #BKE_pbvh_vert_coords_apply. */
pbvh.vert_positions_ = mesh->vert_positions_for_write();
pbvh.vert_normals_ = mesh->vert_normals();
pbvh.face_normals_ = mesh->face_normals();
}
}
std::unique_ptr<PBVH> build_mesh(Mesh *mesh)
std::unique_ptr<Tree> build_mesh(Mesh *mesh)
{
std::unique_ptr<PBVH> pbvh = std::make_unique<PBVH>();
pbvh->header.type = PBVH_FACES;
std::unique_ptr<Tree> pbvh = std::make_unique<Tree>(Type::Mesh);
MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
const Span<int> corner_verts = mesh->corner_verts();
const Span<int3> corner_tris = mesh->corner_tris();
pbvh->mesh = mesh;
pbvh->mesh_ = mesh;
update_mesh_pointers(*pbvh, mesh);
const Span<int> tri_faces = mesh->corner_tri_faces();
@@ -725,12 +726,11 @@ std::unique_ptr<PBVH> build_mesh(Mesh *mesh)
return pbvh;
}
std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
std::unique_ptr<Tree> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
{
std::unique_ptr<PBVH> pbvh = std::make_unique<PBVH>();
pbvh->header.type = PBVH_GRIDS;
std::unique_ptr<Tree> pbvh = std::make_unique<Tree>(Type::Grids);
pbvh->subdiv_ccg = subdiv_ccg;
pbvh->subdiv_ccg_ = subdiv_ccg;
/* Find maximum number of grids per face. */
int max_grids = 1;
@@ -748,8 +748,8 @@ std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
*/
const int leaf_limit = max_ii(LEAF_LIMIT / (key.grid_area), max_grids);
/* We also need the base mesh for PBVH draw. */
pbvh->mesh = mesh;
/* We also need the base mesh for Tree draw. */
pbvh->mesh_ = mesh;
/* For each grid, store the AABB and the AABB centroid */
Array<Bounds<float3>> prim_bounds(grids.size());
@@ -798,33 +798,29 @@ std::unique_ptr<PBVH> build_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
return pbvh;
}
} // namespace blender::bke::pbvh
PBVH::~PBVH()
Tree::~Tree()
{
for (PBVHNode &node : this->nodes) {
if (node.flag & PBVH_Leaf) {
if (node.draw_batches) {
blender::draw::pbvh::node_free(node.draw_batches);
for (Node &node : this->nodes_) {
if (node.flag_ & PBVH_Leaf) {
if (node.draw_batches_) {
blender::draw::pbvh::node_free(node.draw_batches_);
}
}
if (node.flag & (PBVH_Leaf | PBVH_TexLeaf)) {
blender::bke::pbvh::node_pixels_free(&node);
if (node.flag_ & (PBVH_Leaf | PBVH_TexLeaf)) {
node_pixels_free(&node);
}
}
blender::bke::pbvh::pixels_free(this);
pixels_free(this);
}
namespace blender::bke::pbvh {
void free(std::unique_ptr<PBVH> &pbvh)
void free(std::unique_ptr<Tree> &pbvh)
{
pbvh.reset();
}
static void pbvh_iter_begin(PBVHIter *iter, PBVH &pbvh, FunctionRef<bool(PBVHNode &)> scb)
static void pbvh_iter_begin(PBVHIter *iter, Tree &pbvh, FunctionRef<bool(Node &)> scb)
{
iter->pbvh = &pbvh;
iter->scb = scb;
@@ -832,7 +828,7 @@ static void pbvh_iter_begin(PBVHIter *iter, PBVH &pbvh, FunctionRef<bool(PBVHNod
iter->stack = iter->stackfixed;
iter->stackspace = STACK_FIXED_DEPTH;
iter->stack[0].node = &pbvh.nodes.first();
iter->stack[0].node = &pbvh.nodes_.first();
iter->stack[0].revisiting = false;
iter->stacksize = 1;
}
@@ -844,7 +840,7 @@ static void pbvh_iter_end(PBVHIter *iter)
}
}
static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting)
static void pbvh_stack_push(PBVHIter *iter, Node *node, bool revisiting)
{
if (UNLIKELY(iter->stacksize == iter->stackspace)) {
iter->stackspace *= 2;
@@ -864,7 +860,7 @@ static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting)
iter->stacksize++;
}
static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
static Node *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
{
/* purpose here is to traverse tree, visiting child nodes before their
* parents, this order is necessary for e.g. computing bounding boxes */
@@ -872,7 +868,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
while (iter->stacksize) {
/* pop node */
iter->stacksize--;
PBVHNode *node = iter->stack[iter->stacksize].node;
Node *node = iter->stack[iter->stacksize].node;
/* on a mesh with no faces this can happen
* can remove this check if we know meshes have at least 1 face */
@@ -891,7 +887,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
continue; /* don't traverse, outside of search zone */
}
if (node->flag & leaf_flag) {
if (node->flag_ & leaf_flag) {
/* immediately hit leaf node */
return node;
}
@@ -900,19 +896,19 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag)
pbvh_stack_push(iter, node, true);
/* push two child nodes on the stack */
pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset + 1], false);
pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset], false);
pbvh_stack_push(iter, &iter->pbvh->nodes_[node->children_offset_ + 1], false);
pbvh_stack_push(iter, &iter->pbvh->nodes_[node->children_offset_], false);
}
return nullptr;
}
static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
static Node *pbvh_iter_next_occluded(PBVHIter *iter)
{
while (iter->stacksize) {
/* pop node */
iter->stacksize--;
PBVHNode *node = iter->stack[iter->stacksize].node;
Node *node = iter->stack[iter->stacksize].node;
/* on a mesh with no faces this can happen
* can remove this check if we know meshes have at least 1 face */
@@ -924,20 +920,20 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
continue; /* don't traverse, outside of search zone */
}
if (node->flag & PBVH_Leaf) {
if (node->flag_ & PBVH_Leaf) {
/* immediately hit leaf node */
return node;
}
pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset + 1], false);
pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset], false);
pbvh_stack_push(iter, &iter->pbvh->nodes_[node->children_offset_ + 1], false);
pbvh_stack_push(iter, &iter->pbvh->nodes_[node->children_offset_], false);
}
return nullptr;
}
struct node_tree {
PBVHNode *data;
Node *data;
node_tree *left;
node_tree *right;
@@ -945,7 +941,7 @@ struct node_tree {
static void node_tree_insert(node_tree *tree, node_tree *new_node)
{
if (new_node->data->tmin < tree->data->tmin) {
if (new_node->data->tmin_ < tree->data->tmin_) {
if (tree->left) {
node_tree_insert(tree->left, new_node);
}
@@ -964,7 +960,7 @@ static void node_tree_insert(node_tree *tree, node_tree *new_node)
}
static void traverse_tree(node_tree *tree,
const FunctionRef<void(PBVHNode &node, float *tmin)> hit_fn,
const FunctionRef<void(Node &node, float *tmin)> hit_fn,
float *tmin)
{
if (tree->left) {
@@ -995,27 +991,27 @@ static void free_tree(node_tree *tree)
} // namespace blender::bke::pbvh
float BKE_pbvh_node_get_tmin(const PBVHNode *node)
float BKE_pbvh_node_get_tmin(const blender::bke::pbvh::Node *node)
{
return node->tmin;
return node->tmin_;
}
namespace blender::bke::pbvh {
void search_callback(PBVH &pbvh,
FunctionRef<bool(PBVHNode &)> filter_fn,
FunctionRef<void(PBVHNode &)> hit_fn)
void search_callback(Tree &pbvh,
FunctionRef<bool(Node &)> filter_fn,
FunctionRef<void(Node &)> hit_fn)
{
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return;
}
PBVHIter iter;
PBVHNode *node;
Node *node;
pbvh_iter_begin(&iter, pbvh, filter_fn);
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
if (node->flag & PBVH_Leaf) {
if (node->flag_ & PBVH_Leaf) {
hit_fn(*node);
}
}
@@ -1023,21 +1019,21 @@ void search_callback(PBVH &pbvh,
pbvh_iter_end(&iter);
}
static void search_callback_occluded(PBVH &pbvh,
const FunctionRef<bool(PBVHNode &)> scb,
const FunctionRef<void(PBVHNode &node, float *tmin)> hit_fn)
static void search_callback_occluded(Tree &pbvh,
const FunctionRef<bool(Node &)> scb,
const FunctionRef<void(Node &node, float *tmin)> hit_fn)
{
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return;
}
PBVHIter iter;
PBVHNode *node;
Node *node;
node_tree *tree = nullptr;
pbvh_iter_begin(&iter, pbvh, scb);
while ((node = pbvh_iter_next_occluded(&iter))) {
if (node->flag & PBVH_Leaf) {
if (node->flag_ & PBVH_Leaf) {
node_tree *new_node = static_cast<node_tree *>(malloc(sizeof(node_tree)));
new_node->data = node;
@@ -1063,10 +1059,10 @@ static void search_callback_occluded(PBVH &pbvh,
}
}
static bool update_search(PBVHNode *node, const int flag)
static bool update_search(Node *node, const int flag)
{
if (node->flag & PBVH_Leaf) {
return (node->flag & flag) != 0;
if (node->flag_ & PBVH_Leaf) {
return (node->flag_ & flag) != 0;
}
return true;
@@ -1098,13 +1094,13 @@ static void calc_node_face_normals(const Span<float3> positions,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Span<int> corner_tri_faces,
const Span<const PBVHNode *> nodes,
const Span<const Node *> nodes,
MutableSpan<float3> face_normals)
{
threading::EnumerableThreadSpecific<Vector<int>> all_index_data;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<int> &node_faces = all_index_data.local();
for (const PBVHNode *node : nodes.slice(range)) {
for (const Node *node : nodes.slice(range)) {
normals_calc_faces(positions,
faces,
corner_verts,
@@ -1140,40 +1136,40 @@ static void calc_boundary_vert_normals(const GroupedSpan<int> vert_to_face_map,
static void calc_node_vert_normals(const GroupedSpan<int> vert_to_face_map,
const Span<float3> face_normals,
const Span<PBVHNode *> nodes,
const Span<Node *> nodes,
MutableSpan<float3> vert_normals)
{
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const PBVHNode *node : nodes.slice(range)) {
for (const Node *node : nodes.slice(range)) {
normals_calc_verts_simple(
vert_to_face_map, face_normals, node_unique_verts(*node), vert_normals);
}
});
}
static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
static void update_normals_faces(Tree &pbvh, Span<Node *> nodes, Mesh &mesh)
{
/* Position changes are tracked on a per-node level, so all the vertex and face normals for every
* affected node are recalculated. However, the additional complexity comes from the fact that
* changing vertex normals also changes surrounding face normals. Those changed face normals then
* change the normals of all connected vertices, which can be in other nodes. So the set of
* vertices that need recalculated normals can propagate into unchanged/untagged PBVH nodes.
* vertices that need recalculated normals can propagate into unchanged/untagged Tree nodes.
*
* Currently we have no good way of finding neighboring PBVH nodes, so we use the vertex to
* Currently we have no good way of finding neighboring Tree nodes, so we use the vertex to
* face topology map to find the neighboring vertices that need normal recalculation.
*
* Those boundary face and vertex indices are deduplicated with #VectorSet in order to avoid
* duplicate work recalculation for the same vertex, and to make parallel storage for vertices
* during recalculation thread-safe. */
const Span<float3> positions = pbvh.vert_positions;
const Span<float3> positions = pbvh.vert_positions_;
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const Span<int> tri_faces = mesh.corner_tri_faces();
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
VectorSet<int> boundary_faces;
for (const PBVHNode *node : nodes) {
for (const int vert : node->vert_indices.as_span().drop_front(node->uniq_verts)) {
for (const Node *node : nodes) {
for (const int vert : node->vert_indices_.as_span().drop_front(node->uniq_verts_)) {
boundary_faces.add_multiple(vert_to_face_map[vert]);
}
}
@@ -1181,11 +1177,11 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
VectorSet<int> boundary_verts;
threading::parallel_invoke(
[&]() {
if (pbvh.deformed) {
if (pbvh.deformed_) {
calc_node_face_normals(
positions, faces, corner_verts, tri_faces, nodes, pbvh.face_normals_deformed);
positions, faces, corner_verts, tri_faces, nodes, pbvh.face_normals_deformed_);
calc_boundary_face_normals(
positions, faces, corner_verts, boundary_faces, pbvh.face_normals_deformed);
positions, faces, corner_verts, boundary_faces, pbvh.face_normals_deformed_);
}
else {
mesh.runtime->face_normals_cache.update([&](Vector<float3> &r_data) {
@@ -1193,7 +1189,7 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
calc_boundary_face_normals(positions, faces, corner_verts, boundary_faces, r_data);
});
/* #SharedCache::update() reallocates cached vectors if they were shared initially. */
pbvh.face_normals = mesh.runtime->face_normals_cache.data();
pbvh.face_normals_ = mesh.runtime->face_normals_cache.data();
}
},
[&]() {
@@ -1204,95 +1200,96 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
}
});
if (pbvh.deformed) {
calc_node_vert_normals(vert_to_face_map, pbvh.face_normals, nodes, pbvh.vert_normals_deformed);
if (pbvh.deformed_) {
calc_node_vert_normals(
vert_to_face_map, pbvh.face_normals_, nodes, pbvh.vert_normals_deformed_);
calc_boundary_vert_normals(
vert_to_face_map, pbvh.face_normals, boundary_verts, pbvh.vert_normals_deformed);
vert_to_face_map, pbvh.face_normals_, boundary_verts, pbvh.vert_normals_deformed_);
}
else {
mesh.runtime->vert_normals_cache.update([&](Vector<float3> &r_data) {
calc_node_vert_normals(vert_to_face_map, pbvh.face_normals, nodes, r_data);
calc_boundary_vert_normals(vert_to_face_map, pbvh.face_normals, boundary_verts, r_data);
calc_node_vert_normals(vert_to_face_map, pbvh.face_normals_, nodes, r_data);
calc_boundary_vert_normals(vert_to_face_map, pbvh.face_normals_, boundary_verts, r_data);
});
pbvh.vert_normals = mesh.runtime->vert_normals_cache.data();
pbvh.vert_normals_ = mesh.runtime->vert_normals_cache.data();
}
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_UpdateNormals;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_UpdateNormals;
}
}
void update_normals(PBVH &pbvh, SubdivCCG *subdiv_ccg)
void update_normals(Tree &pbvh, SubdivCCG *subdiv_ccg)
{
Vector<PBVHNode *> nodes = search_gather(
pbvh, [&](PBVHNode &node) { return update_search(&node, PBVH_UpdateNormals); });
Vector<Node *> nodes = search_gather(
pbvh, [&](Node &node) { return update_search(&node, PBVH_UpdateNormals); });
if (nodes.is_empty()) {
return;
}
if (pbvh.header.type == PBVH_BMESH) {
if (pbvh.type() == Type::BMesh) {
bmesh_normals_update(nodes);
}
else if (pbvh.header.type == PBVH_FACES) {
update_normals_faces(pbvh, nodes, *pbvh.mesh);
else if (pbvh.type() == Type::Mesh) {
update_normals_faces(pbvh, nodes, *pbvh.mesh_);
}
else if (pbvh.header.type == PBVH_GRIDS) {
else if (pbvh.type() == Type::Grids) {
IndexMaskMemory memory;
const IndexMask faces_to_update = nodes_to_face_selection_grids(*subdiv_ccg, nodes, memory);
BKE_subdiv_ccg_update_normals(*subdiv_ccg, faces_to_update);
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_UpdateNormals;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_UpdateNormals;
}
}
}
void update_node_bounds_mesh(const Span<float3> positions, PBVHNode &node)
void update_node_bounds_mesh(const Span<float3> positions, Node &node)
{
Bounds<float3> bounds = negative_bounds();
for (const int vert : node_verts(node)) {
math::min_max(positions[vert], bounds.min, bounds.max);
}
node.bounds = bounds;
node.bounds_ = bounds;
}
void update_node_bounds_grids(const CCGKey &key, const Span<CCGElem *> grids, PBVHNode &node)
void update_node_bounds_grids(const CCGKey &key, const Span<CCGElem *> grids, Node &node)
{
Bounds<float3> bounds = negative_bounds();
for (const int grid : node.prim_indices) {
for (const int grid : node.prim_indices_) {
for (const int i : IndexRange(key.grid_area)) {
math::min_max(CCG_elem_offset_co(key, grids[grid], i), bounds.min, bounds.max);
}
}
node.bounds = bounds;
node.bounds_ = bounds;
}
void update_node_bounds_bmesh(PBVHNode &node)
void update_node_bounds_bmesh(Node &node)
{
Bounds<float3> bounds = negative_bounds();
for (const BMVert *vert : node.bm_unique_verts) {
for (const BMVert *vert : node.bm_unique_verts_) {
math::min_max(float3(vert->co), bounds.min, bounds.max);
}
for (const BMVert *vert : node.bm_other_verts) {
for (const BMVert *vert : node.bm_other_verts_) {
math::min_max(float3(vert->co), bounds.min, bounds.max);
}
node.bounds = bounds;
node.bounds_ = bounds;
}
static bool update_leaf_node_bounds(PBVH &pbvh)
static bool update_leaf_node_bounds(Tree &pbvh)
{
Vector<PBVHNode *> nodes = search_gather(
pbvh, [&](PBVHNode &node) { return update_search(&node, PBVH_UpdateBB); });
Vector<Node *> nodes = search_gather(
pbvh, [&](Node &node) { return update_search(&node, PBVH_UpdateBB); });
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
switch (pbvh.header.type) {
case PBVH_FACES:
update_node_bounds_mesh(pbvh.vert_positions, *node);
for (Node *node : nodes.as_span().slice(range)) {
switch (pbvh.type()) {
case Type::Mesh:
update_node_bounds_mesh(pbvh.vert_positions_, *node);
break;
case PBVH_GRIDS:
case Type::Grids:
update_node_bounds_grids(
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg), pbvh.subdiv_ccg->grids, *node);
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_), pbvh.subdiv_ccg_->grids, *node);
break;
case PBVH_BMESH:
case Type::BMesh:
update_node_bounds_bmesh(*node);
break;
}
@@ -1306,85 +1303,85 @@ struct BoundsMergeInfo {
bool update;
};
static BoundsMergeInfo merge_child_bounds(MutableSpan<PBVHNode> nodes, const int node_index)
static BoundsMergeInfo merge_child_bounds(MutableSpan<Node> nodes, const int node_index)
{
PBVHNode &node = nodes[node_index];
if (node.flag & PBVH_Leaf) {
const bool update = node.flag & PBVH_UpdateBB;
node.flag &= ~PBVH_UpdateBB;
return {node.bounds, update};
Node &node = nodes[node_index];
if (node.flag_ & PBVH_Leaf) {
const bool update = node.flag_ & PBVH_UpdateBB;
node.flag_ &= ~PBVH_UpdateBB;
return {node.bounds_, update};
}
const BoundsMergeInfo info_0 = merge_child_bounds(nodes, node.children_offset + 0);
const BoundsMergeInfo info_1 = merge_child_bounds(nodes, node.children_offset + 1);
const BoundsMergeInfo info_0 = merge_child_bounds(nodes, node.children_offset_ + 0);
const BoundsMergeInfo info_1 = merge_child_bounds(nodes, node.children_offset_ + 1);
const bool update = info_0.update || info_1.update;
if (update) {
node.bounds = bounds::merge(info_0.bounds, info_1.bounds);
node.bounds_ = bounds::merge(info_0.bounds, info_1.bounds);
}
node.flag &= ~PBVH_UpdateBB;
return {node.bounds, update};
node.flag_ &= ~PBVH_UpdateBB;
return {node.bounds_, update};
}
static void flush_bounds_to_parents(PBVH &pbvh)
static void flush_bounds_to_parents(Tree &pbvh)
{
pbvh.nodes.first().bounds = merge_child_bounds(pbvh.nodes, 0).bounds;
pbvh.nodes_.first().bounds_ = merge_child_bounds(pbvh.nodes_, 0).bounds;
}
void update_bounds(PBVH &pbvh)
void update_bounds(Tree &pbvh)
{
if (update_leaf_node_bounds(pbvh)) {
flush_bounds_to_parents(pbvh);
}
}
void store_bounds_orig(PBVH &pbvh)
void store_bounds_orig(Tree &pbvh)
{
MutableSpan<PBVHNode> nodes = pbvh.nodes;
MutableSpan<Node> nodes = pbvh.nodes_;
threading::parallel_for(nodes.index_range(), 256, [&](const IndexRange range) {
for (const int i : range) {
nodes[i].bounds_orig = nodes[i].bounds;
nodes[i].bounds_orig_ = nodes[i].bounds_;
}
});
}
void node_update_mask_mesh(const Span<float> mask, PBVHNode &node)
void node_update_mask_mesh(const Span<float> mask, Node &node)
{
const Span<int> verts = node_verts(node);
const bool fully_masked = std::all_of(
verts.begin(), verts.end(), [&](const int vert) { return mask[vert] == 1.0f; });
const bool fully_unmasked = std::all_of(
verts.begin(), verts.end(), [&](const int vert) { return mask[vert] <= 0.0f; });
SET_FLAG_FROM_TEST(node.flag, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag, fully_unmasked, PBVH_FullyUnmasked);
node.flag &= ~PBVH_UpdateMask;
SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
node.flag_ &= ~PBVH_UpdateMask;
}
static void update_mask_mesh(const Mesh &mesh, const Span<PBVHNode *> nodes)
static void update_mask_mesh(const Mesh &mesh, const Span<Node *> nodes)
{
const AttributeAccessor attributes = mesh.attributes();
const VArraySpan<float> mask = *attributes.lookup<float>(".sculpt_mask", AttrDomain::Point);
if (mask.is_empty()) {
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_FullyMasked;
node->flag |= PBVH_FullyUnmasked;
node->flag &= ~PBVH_UpdateMask;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_FullyMasked;
node->flag_ |= PBVH_FullyUnmasked;
node->flag_ &= ~PBVH_UpdateMask;
}
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_mask_mesh(mask, *node);
}
});
}
void node_update_mask_grids(const CCGKey &key, const Span<CCGElem *> grids, PBVHNode &node)
void node_update_mask_grids(const CCGKey &key, const Span<CCGElem *> grids, Node &node)
{
BLI_assert(key.has_mask);
bool fully_masked = true;
bool fully_unmasked = true;
for (const int grid : node.prim_indices) {
for (const int grid : node.prim_indices_) {
CCGElem *elem = grids[grid];
for (const int i : IndexRange(key.grid_area)) {
const float mask = CCG_elem_offset_mask(key, elem, i);
@@ -1392,179 +1389,179 @@ void node_update_mask_grids(const CCGKey &key, const Span<CCGElem *> grids, PBVH
fully_unmasked &= mask <= 0.0f;
}
}
SET_FLAG_FROM_TEST(node.flag, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag, fully_unmasked, PBVH_FullyUnmasked);
node.flag &= ~PBVH_UpdateMask;
SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
node.flag_ &= ~PBVH_UpdateMask;
}
static void update_mask_grids(const SubdivCCG &subdiv_ccg, const Span<PBVHNode *> nodes)
static void update_mask_grids(const SubdivCCG &subdiv_ccg, const Span<Node *> nodes)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
if (!key.has_mask) {
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_FullyMasked;
node->flag |= PBVH_FullyUnmasked;
node->flag &= ~PBVH_UpdateMask;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_FullyMasked;
node->flag_ |= PBVH_FullyUnmasked;
node->flag_ &= ~PBVH_UpdateMask;
}
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_mask_grids(key, subdiv_ccg.grids, *node);
}
});
}
void node_update_mask_bmesh(const int mask_offset, PBVHNode &node)
void node_update_mask_bmesh(const int mask_offset, Node &node)
{
BLI_assert(mask_offset != -1);
bool fully_masked = true;
bool fully_unmasked = true;
for (const BMVert *vert : node.bm_unique_verts) {
for (const BMVert *vert : node.bm_unique_verts_) {
fully_masked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) == 1.0f;
fully_unmasked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) <= 0.0f;
}
for (const BMVert *vert : node.bm_other_verts) {
for (const BMVert *vert : node.bm_other_verts_) {
fully_masked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) == 1.0f;
fully_unmasked &= BM_ELEM_CD_GET_FLOAT(vert, mask_offset) <= 0.0f;
}
SET_FLAG_FROM_TEST(node.flag, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag, fully_unmasked, PBVH_FullyUnmasked);
node.flag &= ~PBVH_UpdateMask;
SET_FLAG_FROM_TEST(node.flag_, fully_masked, PBVH_FullyMasked);
SET_FLAG_FROM_TEST(node.flag_, fully_unmasked, PBVH_FullyUnmasked);
node.flag_ &= ~PBVH_UpdateMask;
}
static void update_mask_bmesh(const BMesh &bm, const Span<PBVHNode *> nodes)
static void update_mask_bmesh(const BMesh &bm, const Span<Node *> nodes)
{
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
if (offset == -1) {
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_FullyMasked;
node->flag |= PBVH_FullyUnmasked;
node->flag &= ~PBVH_UpdateMask;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_FullyMasked;
node->flag_ |= PBVH_FullyUnmasked;
node->flag_ &= ~PBVH_UpdateMask;
}
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_mask_bmesh(offset, *node);
}
});
}
void update_mask(PBVH &pbvh)
void update_mask(Tree &pbvh)
{
Vector<PBVHNode *> nodes = search_gather(
pbvh, [&](PBVHNode &node) { return update_search(&node, PBVH_UpdateMask); });
Vector<Node *> nodes = search_gather(
pbvh, [&](Node &node) { return update_search(&node, PBVH_UpdateMask); });
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
update_mask_mesh(*pbvh.mesh, nodes);
switch (pbvh.type()) {
case Type::Mesh:
update_mask_mesh(*pbvh.mesh_, nodes);
break;
case PBVH_GRIDS:
update_mask_grids(*pbvh.subdiv_ccg, nodes);
case Type::Grids:
update_mask_grids(*pbvh.subdiv_ccg_, nodes);
break;
case PBVH_BMESH:
update_mask_bmesh(*pbvh.header.bm, nodes);
case Type::BMesh:
update_mask_bmesh(*pbvh.bm_, nodes);
break;
}
}
void node_update_visibility_mesh(const Span<bool> hide_vert, PBVHNode &node)
void node_update_visibility_mesh(const Span<bool> hide_vert, Node &node)
{
BLI_assert(!hide_vert.is_empty());
const Span<int> verts = node_verts(node);
const bool fully_hidden = std::all_of(
verts.begin(), verts.end(), [&](const int vert) { return hide_vert[vert]; });
SET_FLAG_FROM_TEST(node.flag, fully_hidden, PBVH_FullyHidden);
node.flag &= ~PBVH_UpdateVisibility;
SET_FLAG_FROM_TEST(node.flag_, fully_hidden, PBVH_FullyHidden);
node.flag_ &= ~PBVH_UpdateVisibility;
}
static void update_visibility_faces(const Mesh &mesh, const Span<PBVHNode *> nodes)
static void update_visibility_faces(const Mesh &mesh, const Span<Node *> nodes)
{
const AttributeAccessor attributes = mesh.attributes();
const VArraySpan<bool> hide_vert = *attributes.lookup<bool>(".hide_vert", AttrDomain::Point);
if (hide_vert.is_empty()) {
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_FullyHidden;
node->flag &= ~PBVH_UpdateVisibility;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_FullyHidden;
node->flag_ &= ~PBVH_UpdateVisibility;
}
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_visibility_mesh(hide_vert, *node);
}
});
}
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, PBVHNode &node)
void node_update_visibility_grids(const BitGroupVector<> &grid_hidden, Node &node)
{
BLI_assert(!grid_hidden.is_empty());
const bool fully_hidden = std::none_of(
node.prim_indices.begin(), node.prim_indices.end(), [&](const int grid) {
node.prim_indices_.begin(), node.prim_indices_.end(), [&](const int grid) {
return bits::any_bit_unset(grid_hidden[grid]);
});
SET_FLAG_FROM_TEST(node.flag, fully_hidden, PBVH_FullyHidden);
node.flag &= ~PBVH_UpdateVisibility;
SET_FLAG_FROM_TEST(node.flag_, fully_hidden, PBVH_FullyHidden);
node.flag_ &= ~PBVH_UpdateVisibility;
}
static void update_visibility_grids(PBVH &pbvh, const Span<PBVHNode *> nodes)
static void update_visibility_grids(Tree &pbvh, const Span<Node *> nodes)
{
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg_->grid_hidden;
if (grid_hidden.is_empty()) {
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_FullyHidden;
node->flag &= ~PBVH_UpdateVisibility;
for (Node *node : nodes) {
node->flag_ &= ~PBVH_FullyHidden;
node->flag_ &= ~PBVH_UpdateVisibility;
}
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_visibility_grids(grid_hidden, *node);
}
});
}
void node_update_visibility_bmesh(PBVHNode &node)
void node_update_visibility_bmesh(Node &node)
{
const bool unique_hidden = std::all_of(
node.bm_unique_verts.begin(), node.bm_unique_verts.end(), [&](const BMVert *vert) {
node.bm_unique_verts_.begin(), node.bm_unique_verts_.end(), [&](const BMVert *vert) {
return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
});
const bool other_hidden = std::all_of(
node.bm_other_verts.begin(), node.bm_other_verts.end(), [&](const BMVert *vert) {
node.bm_other_verts_.begin(), node.bm_other_verts_.end(), [&](const BMVert *vert) {
return BM_elem_flag_test(vert, BM_ELEM_HIDDEN);
});
SET_FLAG_FROM_TEST(node.flag, unique_hidden && other_hidden, PBVH_FullyHidden);
node.flag &= ~PBVH_UpdateVisibility;
SET_FLAG_FROM_TEST(node.flag_, unique_hidden && other_hidden, PBVH_FullyHidden);
node.flag_ &= ~PBVH_UpdateVisibility;
}
static void update_visibility_bmesh(const Span<PBVHNode *> nodes)
static void update_visibility_bmesh(const Span<Node *> nodes)
{
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_visibility_bmesh(*node);
}
});
}
void update_visibility(PBVH &pbvh)
void update_visibility(Tree &pbvh)
{
Vector<PBVHNode *> nodes = search_gather(
pbvh, [&](PBVHNode &node) { return update_search(&node, PBVH_UpdateVisibility); });
Vector<Node *> nodes = search_gather(
pbvh, [&](Node &node) { return update_search(&node, PBVH_UpdateVisibility); });
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
update_visibility_faces(*pbvh.mesh, nodes);
switch (pbvh.type()) {
case Type::Mesh:
update_visibility_faces(*pbvh.mesh_, nodes);
break;
case PBVH_GRIDS:
case Type::Grids:
update_visibility_grids(pbvh, nodes);
break;
case PBVH_BMESH:
case Type::BMesh:
update_visibility_bmesh(nodes);
break;
}
@@ -1572,21 +1569,21 @@ void update_visibility(PBVH &pbvh)
} // namespace blender::bke::pbvh
Bounds<float3> BKE_pbvh_redraw_BB(PBVH &pbvh)
Bounds<float3> BKE_pbvh_redraw_BB(blender::bke::pbvh::Tree &pbvh)
{
using namespace blender;
using namespace blender::bke::pbvh;
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return {};
}
Bounds<float3> bounds = negative_bounds();
PBVHIter iter;
pbvh_iter_begin(&iter, pbvh, {});
PBVHNode *node;
Node *node;
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
if (node->flag & PBVH_UpdateRedraw) {
bounds = bounds::merge(bounds, node->bounds);
if (node->flag_ & PBVH_UpdateRedraw) {
bounds = bounds::merge(bounds, node->bounds_);
}
}
pbvh_iter_end(&iter);
@@ -1597,7 +1594,7 @@ Bounds<float3> BKE_pbvh_redraw_BB(PBVH &pbvh)
namespace blender::bke::pbvh {
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
const Span<const PBVHNode *> nodes,
const Span<const Node *> nodes,
IndexMaskMemory &memory)
{
const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
@@ -1606,8 +1603,8 @@ IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
* overhead regardless of selection size, but that is small. */
Array<bool> faces_to_update(subdiv_ccg.faces.size(), false);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const PBVHNode *node : nodes.slice(range)) {
for (const int grid : node->prim_indices) {
for (const Node *node : nodes.slice(range)) {
for (const int grid : node->prim_indices_) {
faces_to_update[grid_to_face_map[grid]] = true;
}
}
@@ -1615,158 +1612,158 @@ IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
return IndexMask::from_bools(faces_to_update, memory);
}
Bounds<float3> bounds_get(const PBVH &pbvh)
Bounds<float3> bounds_get(const Tree &pbvh)
{
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return float3(0);
}
return pbvh.nodes.first().bounds;
return pbvh.nodes_.first().bounds_;
}
} // namespace blender::bke::pbvh
int BKE_pbvh_get_grid_num_verts(const PBVH &pbvh)
int BKE_pbvh_get_grid_num_verts(const blender::bke::pbvh::Tree &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_GRIDS);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
return pbvh.subdiv_ccg->grids.size() * key.grid_area;
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
return pbvh.subdiv_ccg_->grids.size() * key.grid_area;
}
int BKE_pbvh_get_grid_num_faces(const PBVH &pbvh)
int BKE_pbvh_get_grid_num_faces(const blender::bke::pbvh::Tree &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_GRIDS);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
return pbvh.subdiv_ccg->grids.size() * square_i(key.grid_size - 1);
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Grids);
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
return pbvh.subdiv_ccg_->grids.size() * square_i(key.grid_size - 1);
}
/***************************** Node Access ***********************************/
void BKE_pbvh_node_mark_update(PBVHNode *node)
void BKE_pbvh_node_mark_update(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw |
PBVH_RebuildPixels;
node->flag_ |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw |
PBVH_RebuildPixels;
}
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
void BKE_pbvh_node_mark_update_mask(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
node->flag_ |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
void BKE_pbvh_node_mark_update_color(PBVHNode *node)
void BKE_pbvh_node_mark_update_color(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
node->flag_ |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
void BKE_pbvh_node_mark_update_face_sets(PBVHNode *node)
void BKE_pbvh_node_mark_update_face_sets(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
void BKE_pbvh_mark_rebuild_pixels(PBVH &pbvh)
void BKE_pbvh_mark_rebuild_pixels(blender::bke::pbvh::Tree &pbvh)
{
for (PBVHNode &node : pbvh.nodes) {
if (node.flag & PBVH_Leaf) {
node.flag |= PBVH_RebuildPixels;
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (node.flag_ & PBVH_Leaf) {
node.flag_ |= PBVH_RebuildPixels;
}
}
}
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
void BKE_pbvh_node_mark_update_visibility(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateVisibility | PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers |
PBVH_UpdateRedraw;
node->flag_ |= PBVH_UpdateVisibility | PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers |
PBVH_UpdateRedraw;
}
void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node)
void BKE_pbvh_node_mark_rebuild_draw(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
node->flag_ |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
void BKE_pbvh_node_mark_redraw(PBVHNode *node)
void BKE_pbvh_node_mark_redraw(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
void BKE_pbvh_node_mark_positions_update(PBVHNode *node)
void BKE_pbvh_node_mark_positions_update(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateNormals | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw | PBVH_UpdateBB;
node->flag_ |= PBVH_UpdateNormals | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw | PBVH_UpdateBB;
}
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
void BKE_pbvh_node_fully_hidden_set(blender::bke::pbvh::Node *node, int fully_hidden)
{
BLI_assert(node->flag & PBVH_Leaf);
BLI_assert(node->flag_ & PBVH_Leaf);
if (fully_hidden) {
node->flag |= PBVH_FullyHidden;
node->flag_ |= PBVH_FullyHidden;
}
else {
node->flag &= ~PBVH_FullyHidden;
node->flag_ &= ~PBVH_FullyHidden;
}
}
bool BKE_pbvh_node_fully_hidden_get(const PBVHNode *node)
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node *node)
{
return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyHidden);
return (node->flag_ & PBVH_Leaf) && (node->flag_ & PBVH_FullyHidden);
}
void BKE_pbvh_node_fully_masked_set(PBVHNode *node, int fully_masked)
void BKE_pbvh_node_fully_masked_set(blender::bke::pbvh::Node *node, int fully_masked)
{
BLI_assert(node->flag & PBVH_Leaf);
BLI_assert(node->flag_ & PBVH_Leaf);
if (fully_masked) {
node->flag |= PBVH_FullyMasked;
node->flag_ |= PBVH_FullyMasked;
}
else {
node->flag &= ~PBVH_FullyMasked;
node->flag_ &= ~PBVH_FullyMasked;
}
}
bool BKE_pbvh_node_fully_masked_get(const PBVHNode *node)
bool BKE_pbvh_node_fully_masked_get(const blender::bke::pbvh::Node *node)
{
return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyMasked);
return (node->flag_ & PBVH_Leaf) && (node->flag_ & PBVH_FullyMasked);
}
void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked)
void BKE_pbvh_node_fully_unmasked_set(blender::bke::pbvh::Node *node, int fully_masked)
{
BLI_assert(node->flag & PBVH_Leaf);
BLI_assert(node->flag_ & PBVH_Leaf);
if (fully_masked) {
node->flag |= PBVH_FullyUnmasked;
node->flag_ |= PBVH_FullyUnmasked;
}
else {
node->flag &= ~PBVH_FullyUnmasked;
node->flag_ &= ~PBVH_FullyUnmasked;
}
}
bool BKE_pbvh_node_fully_unmasked_get(const PBVHNode *node)
bool BKE_pbvh_node_fully_unmasked_get(const blender::bke::pbvh::Node *node)
{
return (node->flag & PBVH_Leaf) && (node->flag & PBVH_FullyUnmasked);
return (node->flag_ & PBVH_Leaf) && (node->flag_ & PBVH_FullyUnmasked);
}
namespace blender::bke::pbvh {
Span<int> node_corners(const PBVHNode &node)
Span<int> node_corners(const Node &node)
{
return node.corner_indices;
return node.corner_indices_;
}
Span<int> node_verts(const PBVHNode &node)
Span<int> node_verts(const Node &node)
{
return node.vert_indices;
return node.vert_indices_;
}
Span<int> node_unique_verts(const PBVHNode &node)
Span<int> node_unique_verts(const Node &node)
{
return node.vert_indices.as_span().take_front(node.uniq_verts);
return node.vert_indices_.as_span().take_front(node.uniq_verts_);
}
Span<int> node_face_indices_calc_mesh(const Span<int> corner_tri_faces,
const PBVHNode &node,
const Node &node,
Vector<int> &faces)
{
faces.clear();
int prev_face = -1;
for (const int tri : node.prim_indices) {
for (const int tri : node.prim_indices_) {
const int face = corner_tri_faces[tri];
if (face != prev_face) {
faces.append(face);
@@ -1776,12 +1773,12 @@ Span<int> node_face_indices_calc_mesh(const Span<int> corner_tri_faces,
return faces.as_span();
}
Span<int> node_face_indices_calc_grids(const PBVH &pbvh, const PBVHNode &node, Vector<int> &faces)
Span<int> node_face_indices_calc_grids(const Tree &pbvh, const Node &node, Vector<int> &faces)
{
faces.clear();
const Span<int> grid_to_face_map = pbvh.subdiv_ccg->grid_to_face_map;
const Span<int> grid_to_face_map = pbvh.subdiv_ccg_->grid_to_face_map;
int prev_face = -1;
for (const int prim : node.prim_indices) {
for (const int prim : node.prim_indices_) {
const int face = grid_to_face_map[prim];
if (face != prev_face) {
faces.append(face);
@@ -1791,39 +1788,39 @@ Span<int> node_face_indices_calc_grids(const PBVH &pbvh, const PBVHNode &node, V
return faces.as_span();
}
Span<int> node_grid_indices(const PBVHNode &node)
Span<int> node_grid_indices(const Node &node)
{
return node.prim_indices;
return node.prim_indices_;
}
} // namespace blender::bke::pbvh
namespace blender::bke::pbvh {
Bounds<float3> node_bounds(const PBVHNode &node)
Bounds<float3> node_bounds(const Node &node)
{
return node.bounds;
return node.bounds_;
}
} // namespace blender::bke::pbvh
Bounds<float3> BKE_pbvh_node_get_original_BB(const PBVHNode *node)
Bounds<float3> BKE_pbvh_node_get_original_BB(const blender::bke::pbvh::Node *node)
{
return node->bounds_orig;
return node->bounds_orig_;
}
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
void BKE_pbvh_node_get_bm_orco_data(blender::bke::pbvh::Node *node,
int (**r_orco_tris)[3],
int *r_orco_tris_num,
float (**r_orco_coords)[3],
BMVert ***r_orco_verts)
{
*r_orco_tris = node->bm_ortri;
*r_orco_tris_num = node->bm_tot_ortri;
*r_orco_coords = node->bm_orco;
*r_orco_tris = node->bm_ortri_;
*r_orco_tris_num = node->bm_tot_ortri_;
*r_orco_coords = node->bm_orco_;
if (r_orco_verts) {
*r_orco_verts = node->bm_orvert;
*r_orco_verts = node->bm_orvert_;
}
}
@@ -1836,16 +1833,16 @@ struct RaycastData {
bool original;
};
static bool ray_aabb_intersect(PBVHNode &node, const RaycastData &rcd)
static bool ray_aabb_intersect(Node &node, const RaycastData &rcd)
{
if (rcd.original) {
return isect_ray_aabb_v3(&rcd.ray, node.bounds_orig.min, node.bounds_orig.max, &node.tmin);
return isect_ray_aabb_v3(&rcd.ray, node.bounds_orig_.min, node.bounds_orig_.max, &node.tmin_);
}
return isect_ray_aabb_v3(&rcd.ray, node.bounds.min, node.bounds.max, &node.tmin);
return isect_ray_aabb_v3(&rcd.ray, node.bounds_.min, node.bounds_.max, &node.tmin_);
}
void raycast(PBVH &pbvh,
const FunctionRef<void(PBVHNode &node, float *tmin)> hit_fn,
void raycast(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> hit_fn,
const float ray_start[3],
const float ray_normal[3],
bool original)
@@ -1856,7 +1853,7 @@ void raycast(PBVH &pbvh,
rcd.original = original;
search_callback_occluded(
pbvh, [&](PBVHNode &node) { return ray_aabb_intersect(node, rcd); }, hit_fn);
pbvh, [&](Node &node) { return ray_aabb_intersect(node, rcd); }, hit_fn);
}
bool ray_face_intersection_quad(const float ray_start[3],
@@ -1975,8 +1972,8 @@ bool ray_face_nearest_tri(const float ray_start[3],
return false;
}
static bool pbvh_faces_node_raycast(PBVH &pbvh,
const PBVHNode *node,
static bool pbvh_faces_node_raycast(Tree &pbvh,
const Node *node,
const float (*origco)[3],
const Span<int> corner_verts,
const Span<int3> corner_tris,
@@ -1991,14 +1988,14 @@ static bool pbvh_faces_node_raycast(PBVH &pbvh,
float *r_face_normal)
{
using namespace blender;
const Span<float3> positions = pbvh.vert_positions;
const Span<float3> positions = pbvh.vert_positions_;
bool hit = false;
float nearest_vertex_co[3] = {0.0f};
for (const int i : node->prim_indices.index_range()) {
const int tri_i = node->prim_indices[i];
for (const int i : node->prim_indices_.index_range()) {
const int tri_i = node->prim_indices_[i];
const int3 &tri = corner_tris[tri_i];
const int3 face_verts = node->face_vert_indices[i];
const int3 face_verts = node->face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
@@ -2047,8 +2044,8 @@ static bool pbvh_faces_node_raycast(PBVH &pbvh,
return hit;
}
static bool pbvh_grids_node_raycast(PBVH &pbvh,
PBVHNode *node,
static bool pbvh_grids_node_raycast(Tree &pbvh,
Node *node,
const float (*origco)[3],
const float ray_start[3],
const float ray_normal[3],
@@ -2058,16 +2055,16 @@ static bool pbvh_grids_node_raycast(PBVH &pbvh,
int *r_active_grid_index,
float *r_face_normal)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
const int totgrid = node->prim_indices.size();
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
const int totgrid = node->prim_indices_.size();
const int gridsize = key.grid_size;
bool hit = false;
float nearest_vertex_co[3] = {0.0};
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg->grids;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg_->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg_->grids;
for (int i = 0; i < totgrid; i++) {
const int grid_index = node->prim_indices[i];
const int grid_index = node->prim_indices_[i];
CCGElem *grid = grids[grid_index];
if (!grid) {
continue;
@@ -2141,8 +2138,8 @@ static bool pbvh_grids_node_raycast(PBVH &pbvh,
return hit;
}
bool raycast_node(PBVH &pbvh,
PBVHNode *node,
bool raycast_node(Tree &pbvh,
Node *node,
const float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
@@ -2159,12 +2156,12 @@ bool raycast_node(PBVH &pbvh,
{
bool hit = false;
if (node->flag & PBVH_FullyHidden) {
if (node->flag_ & PBVH_FullyHidden) {
return false;
}
switch (pbvh.header.type) {
case PBVH_FACES:
switch (pbvh.type()) {
case Type::Mesh:
hit |= pbvh_faces_node_raycast(pbvh,
node,
origco,
@@ -2180,7 +2177,7 @@ bool raycast_node(PBVH &pbvh,
active_face_grid_index,
face_normal);
break;
case PBVH_GRIDS:
case Type::Grids:
hit |= pbvh_grids_node_raycast(pbvh,
node,
origco,
@@ -2192,8 +2189,8 @@ bool raycast_node(PBVH &pbvh,
active_face_grid_index,
face_normal);
break;
case PBVH_BMESH:
BM_mesh_elem_index_ensure(pbvh.header.bm, BM_VERT);
case Type::BMesh:
BM_mesh_elem_index_ensure(pbvh.bm_, BM_VERT);
hit = bmesh_node_raycast(node,
ray_start,
ray_normal,
@@ -2209,9 +2206,9 @@ bool raycast_node(PBVH &pbvh,
}
void clip_ray_ortho(
PBVH &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
Tree &pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3])
{
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return;
}
float rootmin_start, rootmin_end;
@@ -2223,10 +2220,10 @@ void clip_ray_ortho(
const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
if (original) {
bb_root = BKE_pbvh_node_get_original_BB(&pbvh.nodes.first());
bb_root = BKE_pbvh_node_get_original_BB(&pbvh.nodes_.first());
}
else {
bb_root = node_bounds(pbvh.nodes.first());
bb_root = node_bounds(pbvh.nodes_.first());
}
/* Calc rough clipping to avoid overflow later. See #109555. */
@@ -2297,7 +2294,7 @@ void clip_ray_ortho(
/* -------------------------------------------------------------------- */
static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node,
static bool nearest_to_ray_aabb_dist_sq(Node *node,
const DistRayAABB_Precalc &dist_ray_to_aabb_precalc,
const bool original)
{
@@ -2305,23 +2302,23 @@ static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node,
if (original) {
/* BKE_pbvh_node_get_original_BB */
bb_min = node->bounds_orig.min;
bb_max = node->bounds_orig.max;
bb_min = node->bounds_orig_.min;
bb_max = node->bounds_orig_.max;
}
else {
bb_min = node->bounds.min;
bb_max = node->bounds.max;
bb_min = node->bounds_.min;
bb_max = node->bounds_.max;
}
float co_dummy[3], depth;
node->tmin = dist_squared_ray_to_aabb_v3(
node->tmin_ = dist_squared_ray_to_aabb_v3(
&dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth);
/* Ideally we would skip distances outside the range. */
return depth > 0.0f;
}
void find_nearest_to_ray(PBVH &pbvh,
const FunctionRef<void(PBVHNode &node, float *tmin)> fn,
void find_nearest_to_ray(Tree &pbvh,
const FunctionRef<void(Node &node, float *tmin)> fn,
const float ray_start[3],
const float ray_normal[3],
const bool original)
@@ -2331,14 +2328,12 @@ void find_nearest_to_ray(PBVH &pbvh,
search_callback_occluded(
pbvh,
[&](PBVHNode &node) {
return nearest_to_ray_aabb_dist_sq(&node, ray_dist_precalc, original);
},
[&](Node &node) { return nearest_to_ray_aabb_dist_sq(&node, ray_dist_precalc, original); },
fn);
}
static bool pbvh_faces_node_nearest_to_ray(PBVH &pbvh,
const PBVHNode *node,
static bool pbvh_faces_node_nearest_to_ray(Tree &pbvh,
const Node *node,
const float (*origco)[3],
const Span<int> corner_verts,
const Span<int3> corner_tris,
@@ -2350,13 +2345,13 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH &pbvh,
float *dist_sq)
{
using namespace blender;
const Span<float3> positions = pbvh.vert_positions;
const Span<float3> positions = pbvh.vert_positions_;
bool hit = false;
for (const int i : node->prim_indices.index_range()) {
const int tri_i = node->prim_indices[i];
for (const int i : node->prim_indices_.index_range()) {
const int tri_i = node->prim_indices_[i];
const int3 &corner_tri = corner_tris[tri_i];
const int3 face_verts = node->face_vert_indices[i];
const int3 face_verts = node->face_vert_indices_[i];
if (!hide_poly.is_empty() && hide_poly[corner_tri_faces[tri_i]]) {
continue;
@@ -2387,23 +2382,23 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH &pbvh,
return hit;
}
static bool pbvh_grids_node_nearest_to_ray(PBVH &pbvh,
PBVHNode *node,
static bool pbvh_grids_node_nearest_to_ray(Tree &pbvh,
Node *node,
const float (*origco)[3],
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq)
{
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
const int totgrid = node->prim_indices.size();
const CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
const int totgrid = node->prim_indices_.size();
const int gridsize = key.grid_size;
bool hit = false;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg->grids;
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg_->grid_hidden;
const Span<CCGElem *> grids = pbvh.subdiv_ccg_->grids;
for (int i = 0; i < totgrid; i++) {
CCGElem *grid = grids[node->prim_indices[i]];
CCGElem *grid = grids[node->prim_indices_[i]];
if (!grid) {
continue;
}
@@ -2412,7 +2407,7 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH &pbvh,
for (int x = 0; x < gridsize - 1; x++) {
/* check if grid face is hidden */
if (!grid_hidden.is_empty()) {
if (paint_is_grid_face_hidden(grid_hidden[node->prim_indices[i]], gridsize, x, y)) {
if (paint_is_grid_face_hidden(grid_hidden[node->prim_indices_[i]], gridsize, x, y)) {
continue;
}
}
@@ -2448,8 +2443,8 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH &pbvh,
return hit;
}
bool find_nearest_to_ray_node(PBVH &pbvh,
PBVHNode *node,
bool find_nearest_to_ray_node(Tree &pbvh,
Node *node,
const float (*origco)[3],
bool use_origco,
const Span<int> corner_verts,
@@ -2463,12 +2458,12 @@ bool find_nearest_to_ray_node(PBVH &pbvh,
{
bool hit = false;
if (node->flag & PBVH_FullyHidden) {
if (node->flag_ & PBVH_FullyHidden) {
return false;
}
switch (pbvh.header.type) {
case PBVH_FACES:
switch (pbvh.type()) {
case Type::Mesh:
hit |= pbvh_faces_node_nearest_to_ray(pbvh,
node,
origco,
@@ -2481,11 +2476,11 @@ bool find_nearest_to_ray_node(PBVH &pbvh,
depth,
dist_sq);
break;
case PBVH_GRIDS:
case Type::Grids:
hit |= pbvh_grids_node_nearest_to_ray(
pbvh, node, origco, ray_start, ray_normal, depth, dist_sq);
break;
case PBVH_BMESH:
case Type::BMesh:
hit = bmesh_node_nearest_to_ray(node, ray_start, ray_normal, depth, dist_sq, use_origco);
break;
}
@@ -2537,76 +2532,80 @@ static PlaneAABBIsect test_frustum_aabb(const Bounds<float3> &bounds,
} // namespace blender::bke::pbvh
bool BKE_pbvh_node_frustum_contain_AABB(const PBVHNode *node, const PBVHFrustumPlanes *data)
bool BKE_pbvh_node_frustum_contain_AABB(const blender::bke::pbvh::Node *node,
const PBVHFrustumPlanes *data)
{
return blender::bke::pbvh::test_frustum_aabb(node->bounds, data) !=
return blender::bke::pbvh::test_frustum_aabb(node->bounds_, data) !=
blender::bke::pbvh::ISECT_OUTSIDE;
}
bool BKE_pbvh_node_frustum_exclude_AABB(const PBVHNode *node, const PBVHFrustumPlanes *data)
bool BKE_pbvh_node_frustum_exclude_AABB(const blender::bke::pbvh::Node *node,
const PBVHFrustumPlanes *data)
{
return blender::bke::pbvh::test_frustum_aabb(node->bounds, data) !=
return blender::bke::pbvh::test_frustum_aabb(node->bounds_, data) !=
blender::bke::pbvh::ISECT_INSIDE;
}
static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
PBVH &pbvh,
const PBVHNode &node)
blender::bke::pbvh::Tree &pbvh,
const blender::bke::pbvh::Node &node)
{
/* TODO: Use an explicit argument for the original mesh to avoid relying on #PBVH::mesh. */
/* TODO: Use an explicit argument for the original mesh to avoid relying on
* #Tree::mesh. */
blender::draw::pbvh::PBVH_GPU_Args args{};
args.pbvh_type = pbvh.header.type;
args.pbvh_type = pbvh.type();
/* Occasionally, the evaluated and original meshes are out of sync. Prefer using the pbvh mesh in
* these cases. See #115856 and #121008 */
args.face_sets_color_default = pbvh.mesh ? pbvh.mesh->face_sets_color_default :
mesh.face_sets_color_default;
args.face_sets_color_seed = pbvh.mesh ? pbvh.mesh->face_sets_color_seed :
mesh.face_sets_color_seed;
args.face_sets_color_default = pbvh.mesh_ ? pbvh.mesh_->face_sets_color_default :
mesh.face_sets_color_default;
args.face_sets_color_seed = pbvh.mesh_ ? pbvh.mesh_->face_sets_color_seed :
mesh.face_sets_color_seed;
args.active_color = pbvh.mesh ? pbvh.mesh->active_color_attribute : mesh.active_color_attribute;
args.render_color = pbvh.mesh ? pbvh.mesh->default_color_attribute :
mesh.default_color_attribute;
args.active_color = pbvh.mesh_ ? pbvh.mesh_->active_color_attribute :
mesh.active_color_attribute;
args.render_color = pbvh.mesh_ ? pbvh.mesh_->default_color_attribute :
mesh.default_color_attribute;
switch (pbvh.header.type) {
case PBVH_FACES:
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Mesh:
args.vert_data = &mesh.vert_data;
args.corner_data = &mesh.corner_data;
args.face_data = &mesh.face_data;
args.mesh = pbvh.mesh;
args.vert_positions = pbvh.vert_positions;
args.mesh = pbvh.mesh_;
args.vert_positions = pbvh.vert_positions_;
args.corner_verts = mesh.corner_verts();
args.corner_edges = mesh.corner_edges();
args.corner_tris = mesh.corner_tris();
args.vert_normals = pbvh.vert_normals;
args.face_normals = pbvh.face_normals;
args.vert_normals = pbvh.vert_normals_;
args.face_normals = pbvh.face_normals_;
/* Retrieve data from the original mesh. Ideally that would be passed to this function to
* make it clearer when each is used. */
args.hide_poly = *pbvh.mesh->attributes().lookup<bool>(".hide_poly", AttrDomain::Face);
args.hide_poly = *pbvh.mesh_->attributes().lookup<bool>(".hide_poly", AttrDomain::Face);
args.prim_indices = node.prim_indices;
args.prim_indices = node.prim_indices_;
args.tri_faces = mesh.corner_tri_faces();
break;
case PBVH_GRIDS:
args.vert_data = &pbvh.mesh->vert_data;
args.corner_data = &pbvh.mesh->corner_data;
args.face_data = &pbvh.mesh->face_data;
args.ccg_key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
args.mesh = pbvh.mesh;
args.grid_indices = node.prim_indices;
args.subdiv_ccg = pbvh.subdiv_ccg;
args.grids = pbvh.subdiv_ccg->grids;
args.vert_normals = pbvh.vert_normals;
case blender::bke::pbvh::Type::Grids:
args.vert_data = &pbvh.mesh_->vert_data;
args.corner_data = &pbvh.mesh_->corner_data;
args.face_data = &pbvh.mesh_->face_data;
args.ccg_key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
args.mesh = pbvh.mesh_;
args.grid_indices = node.prim_indices_;
args.subdiv_ccg = pbvh.subdiv_ccg_;
args.grids = pbvh.subdiv_ccg_->grids;
args.vert_normals = pbvh.vert_normals_;
break;
case PBVH_BMESH:
args.bm = pbvh.header.bm;
case blender::bke::pbvh::Type::BMesh:
args.bm = pbvh.bm_;
args.vert_data = &args.bm->vdata;
args.corner_data = &args.bm->ldata;
args.face_data = &args.bm->pdata;
args.bm_faces = &node.bm_faces;
args.bm_faces = &node.bm_faces_;
args.cd_mask_layer = CustomData_get_offset_named(
&pbvh.header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
&pbvh.bm_->vdata, CD_PROP_FLOAT, ".sculpt_mask");
break;
}
@@ -2616,79 +2615,79 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
namespace blender::bke::pbvh {
static void node_update_draw_buffers(const Mesh &mesh, PBVH &pbvh, PBVHNode &node)
static void node_update_draw_buffers(const Mesh &mesh, Tree &pbvh, Node &node)
{
/* Create and update draw buffers. The functions called here must not
* do any OpenGL calls. Flags are not cleared immediately, that happens
* after GPU_pbvh_buffer_flush() which does the final OpenGL calls. */
if (node.flag & PBVH_RebuildDrawBuffers) {
if (node.flag_ & PBVH_RebuildDrawBuffers) {
const blender::draw::pbvh::PBVH_GPU_Args args = pbvh_draw_args_init(mesh, pbvh, node);
node.draw_batches = blender::draw::pbvh::node_create(args);
node.draw_batches_ = blender::draw::pbvh::node_create(args);
}
if (node.flag & PBVH_UpdateDrawBuffers) {
node.debug_draw_gen++;
if (node.flag_ & PBVH_UpdateDrawBuffers) {
node.debug_draw_gen_++;
if (node.draw_batches) {
if (node.draw_batches_) {
const blender::draw::pbvh::PBVH_GPU_Args args = pbvh_draw_args_init(mesh, pbvh, node);
blender::draw::pbvh::node_update(node.draw_batches, args);
blender::draw::pbvh::node_update(node.draw_batches_, args);
}
}
}
void free_draw_buffers(PBVH & /*pbvh*/, PBVHNode *node)
void free_draw_buffers(Tree & /*pbvh*/, Node *node)
{
if (node->draw_batches) {
draw::pbvh::node_free(node->draw_batches);
node->draw_batches = nullptr;
if (node->draw_batches_) {
draw::pbvh::node_free(node->draw_batches_);
node->draw_batches_ = nullptr;
}
}
static void pbvh_update_draw_buffers(const Mesh &mesh,
PBVH &pbvh,
Span<PBVHNode *> nodes,
Tree &pbvh,
Span<Node *> nodes,
int update_flag)
{
if (pbvh.header.type == PBVH_BMESH && !pbvh.header.bm) {
if (pbvh.type() == Type::BMesh && !pbvh.bm_) {
/* BMesh hasn't been created yet */
return;
}
if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh.header.type, PBVH_GRIDS, PBVH_BMESH)) {
if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh.type(), Type::Grids, Type::BMesh)) {
/* Free buffers uses OpenGL, so not in parallel. */
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_RebuildDrawBuffers) {
for (Node *node : nodes) {
if (node->flag_ & PBVH_RebuildDrawBuffers) {
free_draw_buffers(pbvh, node);
}
else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_batches) {
else if ((node->flag_ & PBVH_UpdateDrawBuffers) && node->draw_batches_) {
const draw::pbvh::PBVH_GPU_Args args = pbvh_draw_args_init(mesh, pbvh, *node);
draw::pbvh::update_pre(node->draw_batches, args);
draw::pbvh::update_pre(node->draw_batches_, args);
}
}
}
/* Parallel creation and update of draw buffers. */
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (Node *node : nodes.slice(range)) {
node_update_draw_buffers(mesh, pbvh, *node);
}
});
/* Flush buffers uses OpenGL, so not in parallel. */
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_UpdateDrawBuffers) {
for (Node *node : nodes) {
if (node->flag_ & PBVH_UpdateDrawBuffers) {
if (node->draw_batches) {
draw::pbvh::node_gpu_flush(node->draw_batches);
if (node->draw_batches_) {
draw::pbvh::node_gpu_flush(node->draw_batches_);
}
}
node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
node->flag_ &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
}
}
void draw_cb(const Mesh &mesh,
PBVH &pbvh,
Tree &pbvh,
bool update_only_visible,
const PBVHFrustumPlanes &update_frustum,
const PBVHFrustumPlanes &draw_frustum,
@@ -2697,11 +2696,11 @@ void draw_cb(const Mesh &mesh,
{
if (update_only_visible) {
int update_flag = 0;
Vector<PBVHNode *> nodes = search_gather(pbvh, [&](PBVHNode &node) {
Vector<Node *> nodes = search_gather(pbvh, [&](Node &node) {
if (!BKE_pbvh_node_frustum_contain_AABB(&node, &update_frustum)) {
return false;
}
update_flag |= node.flag;
update_flag |= node.flag_;
return true;
});
if (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers)) {
@@ -2710,33 +2709,32 @@ void draw_cb(const Mesh &mesh,
}
else {
/* Get all nodes with draw updates, also those outside the view. */
Vector<PBVHNode *> nodes = search_gather(pbvh, [&](PBVHNode &node) {
Vector<Node *> nodes = search_gather(pbvh, [&](Node &node) {
return update_search(&node, PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
});
pbvh_update_draw_buffers(mesh, pbvh, nodes, PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
}
/* Draw visible nodes. */
Vector<PBVHNode *> nodes = search_gather(pbvh, [&](PBVHNode &node) {
return BKE_pbvh_node_frustum_contain_AABB(&node, &draw_frustum);
});
Vector<Node *> nodes = search_gather(
pbvh, [&](Node &node) { return BKE_pbvh_node_frustum_contain_AABB(&node, &draw_frustum); });
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_FullyHidden) {
for (Node *node : nodes) {
if (node->flag_ & PBVH_FullyHidden) {
continue;
}
if (!node->draw_batches) {
if (!node->draw_batches_) {
continue;
}
const draw::pbvh::PBVH_GPU_Args args = pbvh_draw_args_init(mesh, pbvh, *node);
draw_fn(node->draw_batches, args);
draw_fn(node->draw_batches_, args);
}
}
} // namespace blender::bke::pbvh
void BKE_pbvh_draw_debug_cb(PBVH &pbvh,
void (*draw_fn)(PBVHNode *node,
void BKE_pbvh_draw_debug_cb(blender::bke::pbvh::Tree &pbvh,
void (*draw_fn)(blender::bke::pbvh::Node *node,
void *user_data,
const float bmin[3],
const float bmax[3],
@@ -2745,53 +2743,54 @@ void BKE_pbvh_draw_debug_cb(PBVH &pbvh,
{
PBVHNodeFlags flag = PBVH_Leaf;
for (PBVHNode &node : pbvh.nodes) {
if (node.flag & PBVH_TexLeaf) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (node.flag_ & PBVH_TexLeaf) {
flag = PBVH_TexLeaf;
break;
}
}
for (PBVHNode &node : pbvh.nodes) {
if (!(node.flag & flag)) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (!(node.flag_ & flag)) {
continue;
}
draw_fn(&node, user_data, node.bounds.min, node.bounds.max, node.flag);
draw_fn(&node, user_data, node.bounds_.min, node.bounds_.max, node.flag_);
}
}
void BKE_pbvh_vert_coords_apply(PBVH &pbvh, const Span<float3> vert_positions)
void BKE_pbvh_vert_coords_apply(blender::bke::pbvh::Tree &pbvh, const Span<float3> vert_positions)
{
using namespace blender::bke::pbvh;
if (!pbvh.deformed) {
if (!pbvh.vert_positions.is_empty()) {
/* When the PBVH is deformed, it creates a separate vertex position array that it owns
* directly. Conceptually these copies often aren't and often adds extra indirection, but:
if (!pbvh.deformed_) {
if (!pbvh.vert_positions_.is_empty()) {
/* When the Tree is deformed, it creates a separate vertex position array
* that it owns directly. Conceptually these copies often aren't and often adds extra
* indirection, but:
* - Sculpting shape keys, the deformations are flushed back to the keys as a separate step.
* - Sculpting on a deformed mesh, deformations are also flushed to original positions
* separately.
* - The PBVH currently always assumes we want to change positions, and has no way to avoid
* calculating normals if it's only used for painting, for example. */
pbvh.vert_positions_deformed = pbvh.vert_positions.as_span();
pbvh.vert_positions = pbvh.vert_positions_deformed;
* - The Tree currently always assumes we want to change positions, and
* has no way to avoid calculating normals if it's only used for painting, for example. */
pbvh.vert_positions_deformed_ = pbvh.vert_positions_.as_span();
pbvh.vert_positions_ = pbvh.vert_positions_deformed_;
pbvh.vert_normals_deformed = pbvh.vert_normals;
pbvh.vert_normals = pbvh.vert_normals_deformed;
pbvh.vert_normals_deformed_ = pbvh.vert_normals_;
pbvh.vert_normals_ = pbvh.vert_normals_deformed_;
pbvh.face_normals_deformed = pbvh.face_normals;
pbvh.face_normals = pbvh.face_normals_deformed;
pbvh.face_normals_deformed_ = pbvh.face_normals_;
pbvh.face_normals_ = pbvh.face_normals_deformed_;
pbvh.deformed = true;
pbvh.deformed_ = true;
}
}
if (!pbvh.vert_positions.is_empty()) {
MutableSpan<float3> positions = pbvh.vert_positions;
if (!pbvh.vert_positions_.is_empty()) {
MutableSpan<float3> positions = pbvh.vert_positions_;
positions.copy_from(vert_positions);
for (PBVHNode &node : pbvh.nodes) {
for (Node &node : pbvh.nodes_) {
BKE_pbvh_node_mark_positions_update(&node);
}
@@ -2800,32 +2799,34 @@ void BKE_pbvh_vert_coords_apply(PBVH &pbvh, const Span<float3> vert_positions)
}
}
bool BKE_pbvh_is_deformed(const PBVH &pbvh)
bool BKE_pbvh_is_deformed(const blender::bke::pbvh::Tree &pbvh)
{
return pbvh.deformed;
return pbvh.deformed_;
}
/* Proxies */
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(blender::bke::pbvh::Node *node)
{
if (!node->color_buffer.color) {
node->color_buffer.color = static_cast<float(*)[4]>(
MEM_callocN(sizeof(float[4]) * node->uniq_verts, "Color buffer"));
if (!node->color_buffer_.color) {
node->color_buffer_.color = static_cast<float(*)[4]>(
MEM_callocN(sizeof(float[4]) * node->uniq_verts_, "Color buffer"));
}
return &node->color_buffer;
return &node->color_buffer_;
}
void BKE_pbvh_node_color_buffer_free(PBVH &pbvh)
void BKE_pbvh_node_color_buffer_free(blender::bke::pbvh::Tree &pbvh)
{
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, {});
Vector<blender::bke::pbvh::Node *> nodes = search_gather(pbvh, {});
for (PBVHNode *node : nodes) {
MEM_SAFE_FREE(node->color_buffer.color);
for (blender::bke::pbvh::Node *node : nodes) {
MEM_SAFE_FREE(node->color_buffer_.color);
}
}
void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
void pbvh_vertex_iter_init(blender::bke::pbvh::Tree &pbvh,
blender::bke::pbvh::Node *node,
PBVHVertexIter *vi,
int mode)
{
vi->grid = nullptr;
vi->no = nullptr;
@@ -2835,27 +2836,27 @@ void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
int uniq_verts;
int totvert;
switch (pbvh.header.type) {
case PBVH_GRIDS:
totvert = node->prim_indices.size() *
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg).grid_area;
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Grids:
totvert = node->prim_indices_.size() *
BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_).grid_area;
uniq_verts = totvert;
break;
case PBVH_FACES:
totvert = node->vert_indices.size();
uniq_verts = node->uniq_verts;
case blender::bke::pbvh::Type::Mesh:
totvert = node->vert_indices_.size();
uniq_verts = node->uniq_verts_;
break;
case PBVH_BMESH:
totvert = node->bm_unique_verts.size() + node->bm_other_verts.size();
uniq_verts = node->bm_unique_verts.size();
case blender::bke::pbvh::Type::BMesh:
totvert = node->bm_unique_verts_.size() + node->bm_other_verts_.size();
uniq_verts = node->bm_unique_verts_.size();
break;
}
if (pbvh.header.type == PBVH_GRIDS) {
vi->key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
vi->grids = pbvh.subdiv_ccg->grids.data();
vi->grid_indices = node->prim_indices.data();
vi->totgrid = node->prim_indices.size();
if (pbvh.type() == blender::bke::pbvh::Type::Grids) {
vi->key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
vi->grids = pbvh.subdiv_ccg_->grids.data();
vi->grid_indices = node->prim_indices_.data();
vi->totgrid = node->prim_indices_.size();
vi->gridsize = vi->key.grid_size;
}
else {
@@ -2872,143 +2873,144 @@ void pbvh_vertex_iter_init(PBVH &pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
else {
vi->totvert = uniq_verts;
}
vi->vert_indices = node->vert_indices.data();
vi->vert_positions = pbvh.vert_positions;
vi->is_mesh = !pbvh.vert_positions.is_empty();
vi->vert_indices = node->vert_indices_.data();
vi->vert_positions = pbvh.vert_positions_;
vi->is_mesh = !pbvh.vert_positions_.is_empty();
if (pbvh.header.type == PBVH_BMESH) {
vi->bm_unique_verts = node->bm_unique_verts.begin();
vi->bm_unique_verts_end = node->bm_unique_verts.end();
vi->bm_other_verts = node->bm_other_verts.begin();
vi->bm_other_verts_end = node->bm_other_verts.end();
vi->bm_vdata = &pbvh.header.bm->vdata;
if (pbvh.type() == blender::bke::pbvh::Type::BMesh) {
vi->bm_unique_verts = node->bm_unique_verts_.begin();
vi->bm_unique_verts_end = node->bm_unique_verts_.end();
vi->bm_other_verts = node->bm_other_verts_.begin();
vi->bm_other_verts_end = node->bm_other_verts_.end();
vi->bm_vdata = &pbvh.bm_->vdata;
vi->cd_vert_mask_offset = CustomData_get_offset_named(
vi->bm_vdata, CD_PROP_FLOAT, ".sculpt_mask");
}
vi->gh.reset();
if (vi->grids && mode == PBVH_ITER_UNIQUE) {
vi->grid_hidden = pbvh.subdiv_ccg->grid_hidden.is_empty() ? nullptr :
&pbvh.subdiv_ccg->grid_hidden;
vi->grid_hidden = pbvh.subdiv_ccg_->grid_hidden.is_empty() ? nullptr :
&pbvh.subdiv_ccg_->grid_hidden;
}
vi->mask = 0.0f;
if (pbvh.header.type == PBVH_FACES) {
vi->vert_normals = pbvh.vert_normals;
if (pbvh.type() == blender::bke::pbvh::Type::Mesh) {
vi->vert_normals = pbvh.vert_normals_;
vi->hide_vert = static_cast<const bool *>(
CustomData_get_layer_named(&pbvh.mesh->vert_data, CD_PROP_BOOL, ".hide_vert"));
CustomData_get_layer_named(&pbvh.mesh_->vert_data, CD_PROP_BOOL, ".hide_vert"));
vi->vmask = static_cast<const float *>(
CustomData_get_layer_named(&pbvh.mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask"));
CustomData_get_layer_named(&pbvh.mesh_->vert_data, CD_PROP_FLOAT, ".sculpt_mask"));
}
}
bool pbvh_has_mask(const PBVH &pbvh)
bool pbvh_has_mask(const blender::bke::pbvh::Tree &pbvh)
{
switch (pbvh.header.type) {
case PBVH_GRIDS:
return BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg).has_mask;
case PBVH_FACES:
return pbvh.mesh->attributes().contains(".sculpt_mask");
case PBVH_BMESH:
return pbvh.header.bm &&
CustomData_has_layer_named(&pbvh.header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Grids:
return BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_).has_mask;
case blender::bke::pbvh::Type::Mesh:
return pbvh.mesh_->attributes().contains(".sculpt_mask");
case blender::bke::pbvh::Type::BMesh:
return pbvh.bm_ &&
CustomData_has_layer_named(&pbvh.bm_->vdata, CD_PROP_FLOAT, ".sculpt_mask");
}
return false;
}
bool pbvh_has_face_sets(PBVH &pbvh)
bool pbvh_has_face_sets(blender::bke::pbvh::Tree &pbvh)
{
switch (pbvh.header.type) {
case PBVH_GRIDS:
case PBVH_FACES:
return pbvh.mesh->attributes().contains(".sculpt_face_set");
case PBVH_BMESH:
return CustomData_has_layer_named(&pbvh.header.bm->pdata, CD_PROP_FLOAT, ".sculpt_mask");
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Grids:
case blender::bke::pbvh::Type::Mesh:
return pbvh.mesh_->attributes().contains(".sculpt_face_set");
case blender::bke::pbvh::Type::BMesh:
return CustomData_has_layer_named(&pbvh.bm_->pdata, CD_PROP_FLOAT, ".sculpt_mask");
}
return false;
}
namespace blender::bke::pbvh {
void set_frustum_planes(PBVH &pbvh, PBVHFrustumPlanes *planes)
void set_frustum_planes(Tree &pbvh, PBVHFrustumPlanes *planes)
{
pbvh.num_planes = planes->num_planes;
for (int i = 0; i < pbvh.num_planes; i++) {
copy_v4_v4(pbvh.planes[i], planes->planes[i]);
pbvh.num_planes_ = planes->num_planes;
for (int i = 0; i < pbvh.num_planes_; i++) {
copy_v4_v4(pbvh.planes_[i], planes->planes[i]);
}
}
void get_frustum_planes(const PBVH &pbvh, PBVHFrustumPlanes *planes)
void get_frustum_planes(const Tree &pbvh, PBVHFrustumPlanes *planes)
{
planes->num_planes = pbvh.num_planes;
planes->num_planes = pbvh.num_planes_;
for (int i = 0; i < planes->num_planes; i++) {
copy_v4_v4(planes->planes[i], pbvh.planes[i]);
copy_v4_v4(planes->planes[i], pbvh.planes_[i]);
}
}
} // namespace blender::bke::pbvh
Mesh *BKE_pbvh_get_mesh(PBVH &pbvh)
Mesh *BKE_pbvh_get_mesh(blender::bke::pbvh::Tree &pbvh)
{
return pbvh.mesh;
return pbvh.mesh_;
}
Span<float3> BKE_pbvh_get_vert_positions(const PBVH &pbvh)
Span<float3> BKE_pbvh_get_vert_positions(const blender::bke::pbvh::Tree &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_FACES);
return pbvh.vert_positions;
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Mesh);
return pbvh.vert_positions_;
}
MutableSpan<float3> BKE_pbvh_get_vert_positions(PBVH &pbvh)
MutableSpan<float3> BKE_pbvh_get_vert_positions(blender::bke::pbvh::Tree &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_FACES);
return pbvh.vert_positions;
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Mesh);
return pbvh.vert_positions_;
}
Span<float3> BKE_pbvh_get_vert_normals(const PBVH &pbvh)
Span<float3> BKE_pbvh_get_vert_normals(const blender::bke::pbvh::Tree &pbvh)
{
BLI_assert(pbvh.header.type == PBVH_FACES);
return pbvh.vert_normals;
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Mesh);
return pbvh.vert_normals_;
}
void BKE_pbvh_subdiv_cgg_set(PBVH &pbvh, SubdivCCG *subdiv_ccg)
void BKE_pbvh_subdiv_cgg_set(blender::bke::pbvh::Tree &pbvh, SubdivCCG *subdiv_ccg)
{
pbvh.subdiv_ccg = subdiv_ccg;
pbvh.subdiv_ccg_ = subdiv_ccg;
}
void BKE_pbvh_ensure_node_loops(PBVH &pbvh, const Span<blender::int3> corner_tris)
void BKE_pbvh_ensure_node_loops(blender::bke::pbvh::Tree &pbvh,
const Span<blender::int3> corner_tris)
{
using namespace blender;
BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES);
BLI_assert(pbvh.type() == blender::bke::pbvh::Type::Mesh);
int totloop = 0;
/* Check if nodes already have loop indices. */
for (PBVHNode &node : pbvh.nodes) {
if (!(node.flag & PBVH_Leaf)) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (!(node.flag_ & PBVH_Leaf)) {
continue;
}
if (!node.corner_indices.is_empty()) {
if (!node.corner_indices_.is_empty()) {
return;
}
totloop += node.prim_indices.size() * 3;
totloop += node.prim_indices_.size() * 3;
}
BLI_bitmap *visit = BLI_BITMAP_NEW(totloop, __func__);
/* Create loop indices from node loop triangles. */
Vector<int> corner_indices;
for (PBVHNode &node : pbvh.nodes) {
if (!(node.flag & PBVH_Leaf)) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (!(node.flag_ & PBVH_Leaf)) {
continue;
}
corner_indices.clear();
for (const int i : node.prim_indices) {
for (const int i : node.prim_indices_) {
const int3 &tri = corner_tris[i];
for (int k = 0; k < 3; k++) {
@@ -3019,41 +3021,41 @@ void BKE_pbvh_ensure_node_loops(PBVH &pbvh, const Span<blender::int3> corner_tri
}
}
node.corner_indices = corner_indices.as_span();
node.corner_indices_ = corner_indices.as_span();
}
MEM_SAFE_FREE(visit);
}
int BKE_pbvh_debug_draw_gen_get(PBVHNode &node)
int BKE_pbvh_debug_draw_gen_get(blender::bke::pbvh::Node &node)
{
return node.debug_draw_gen;
return node.debug_draw_gen_;
}
void BKE_pbvh_sync_visibility_from_verts(PBVH &pbvh, Mesh *mesh)
void BKE_pbvh_sync_visibility_from_verts(blender::bke::pbvh::Tree &pbvh, Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
switch (pbvh.header.type) {
case PBVH_FACES: {
switch (pbvh.type()) {
case blender::bke::pbvh::Type::Mesh: {
mesh_hide_vert_flush(*mesh);
break;
}
case PBVH_BMESH: {
case blender::bke::pbvh::Type::BMesh: {
BMIter iter;
BMVert *v;
BMEdge *e;
BMFace *f;
BM_ITER_MESH (f, &iter, pbvh.header.bm, BM_FACES_OF_MESH) {
BM_ITER_MESH (f, &iter, pbvh.bm_, BM_FACES_OF_MESH) {
BM_elem_flag_disable(f, BM_ELEM_HIDDEN);
}
BM_ITER_MESH (e, &iter, pbvh.header.bm, BM_EDGES_OF_MESH) {
BM_ITER_MESH (e, &iter, pbvh.bm_, BM_EDGES_OF_MESH) {
BM_elem_flag_disable(e, BM_ELEM_HIDDEN);
}
BM_ITER_MESH (v, &iter, pbvh.header.bm, BM_VERTS_OF_MESH) {
BM_ITER_MESH (v, &iter, pbvh.bm_, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
continue;
}
@@ -3067,10 +3069,10 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH &pbvh, Mesh *mesh)
}
break;
}
case PBVH_GRIDS: {
case blender::bke::pbvh::Type::Grids: {
const OffsetIndices faces = mesh->faces();
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg->grid_hidden;
CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg);
const BitGroupVector<> &grid_hidden = pbvh.subdiv_ccg_->grid_hidden;
CCGKey key = BKE_subdiv_ccg_key_top_level(*pbvh.subdiv_ccg_);
IndexMaskMemory memory;
const IndexMask hidden_faces =
@@ -3106,22 +3108,22 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH &pbvh, Mesh *mesh)
}
namespace blender::bke::pbvh {
Vector<PBVHNode *> search_gather(PBVH &pbvh,
const FunctionRef<bool(PBVHNode &)> scb,
PBVHNodeFlags leaf_flag)
Vector<Node *> search_gather(Tree &pbvh,
const FunctionRef<bool(Node &)> scb,
PBVHNodeFlags leaf_flag)
{
if (pbvh.nodes.is_empty()) {
if (pbvh.nodes_.is_empty()) {
return {};
}
PBVHIter iter;
Vector<PBVHNode *> nodes;
Vector<Node *> nodes;
pbvh_iter_begin(&iter, pbvh, scb);
PBVHNode *node;
Node *node;
while ((node = pbvh_iter_next(&iter, leaf_flag))) {
if (node->flag & leaf_flag) {
if (node->flag_ & leaf_flag) {
nodes.append(node);
}
}

View File

@@ -57,7 +57,7 @@ namespace blender::bke::pbvh {
// #define USE_VERIFY
#ifdef USE_VERIFY
static void pbvh_bmesh_verify(PBVH *pbvh);
static void pbvh_bmesh_verify(Tree *pbvh);
#endif
/* TODO: choose leaf limit better. */
@@ -205,17 +205,17 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
/****************************** Building ******************************/
/** Update node data after splitting. */
static void pbvh_bmesh_node_finalize(PBVH &pbvh,
static void pbvh_bmesh_node_finalize(Tree &pbvh,
const int node_index,
const int cd_vert_node_offset,
const int cd_face_node_offset)
{
PBVHNode *n = &pbvh.nodes[node_index];
Node *n = &pbvh.nodes_[node_index];
bool has_visible = false;
n->bounds = negative_bounds();
n->bounds_ = negative_bounds();
for (BMFace *f : n->bm_faces) {
for (BMFace *f : n->bm_faces_) {
/* Update ownership of faces. */
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
@@ -225,17 +225,17 @@ static void pbvh_bmesh_node_finalize(PBVH &pbvh,
do {
BMVert *v = l_iter->v;
if (!n->bm_unique_verts.contains(v)) {
if (!n->bm_unique_verts_.contains(v)) {
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
n->bm_other_verts.add(v);
n->bm_other_verts_.add(v);
}
else {
n->bm_unique_verts.add(v);
n->bm_unique_verts_.add(v);
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
}
}
/* Update node bounding box. */
math::min_max(float3(v->co), n->bounds.min, n->bounds.max);
math::min_max(float3(v->co), n->bounds_.min, n->bounds_.max);
} while ((l_iter = l_iter->next) != l_first);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
@@ -243,28 +243,28 @@ static void pbvh_bmesh_node_finalize(PBVH &pbvh,
}
}
BLI_assert(n->bounds.min[0] <= n->bounds.max[0] && n->bounds.min[1] <= n->bounds.max[1] &&
n->bounds.min[2] <= n->bounds.max[2]);
BLI_assert(n->bounds_.min[0] <= n->bounds_.max[0] && n->bounds_.min[1] <= n->bounds_.max[1] &&
n->bounds_.min[2] <= n->bounds_.max[2]);
n->bounds_orig = n->bounds;
n->bounds_orig_ = n->bounds_;
/* Build GPU buffers for new node and update vertex normals. */
BKE_pbvh_node_mark_rebuild_draw(n);
BKE_pbvh_node_fully_hidden_set(n, !has_visible);
n->flag |= PBVH_UpdateNormals;
n->flag_ |= PBVH_UpdateNormals;
}
/** Recursively split the node if it exceeds the leaf_limit. */
static void pbvh_bmesh_node_split(PBVH &pbvh,
static void pbvh_bmesh_node_split(Tree &pbvh,
const Span<Bounds<float3>> face_bounds,
int node_index)
{
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];
const int cd_vert_node_offset = pbvh.cd_vert_node_offset_;
const int cd_face_node_offset = pbvh.cd_face_node_offset_;
Node *n = &pbvh.nodes_[node_index];
if (n->bm_faces.size() <= leaf_limit) {
if (n->bm_faces_.size() <= leaf_limit) {
/* Node limit not exceeded. */
pbvh_bmesh_node_finalize(pbvh, node_index, cd_vert_node_offset, cd_face_node_offset);
return;
@@ -272,7 +272,7 @@ static void pbvh_bmesh_node_split(PBVH &pbvh,
/* Calculate bounding box around primitive centroids. */
Bounds<float3> cb = negative_bounds();
for (BMFace *f : n->bm_faces) {
for (BMFace *f : n->bm_faces_) {
const int i = BM_elem_index_get(f);
const float3 center = math::midpoint(face_bounds[i].min, face_bounds[i].max);
math::min_max(center, cb.min, cb.max);
@@ -283,41 +283,41 @@ static void pbvh_bmesh_node_split(PBVH &pbvh,
const float mid = math::midpoint(cb.max[axis], cb.min[axis]);
/* Add two new child nodes. */
const int children = pbvh.nodes.size();
n->children_offset = children;
pbvh.nodes.resize(pbvh.nodes.size() + 2);
const int children = pbvh.nodes_.size();
n->children_offset_ = children;
pbvh.nodes_.resize(pbvh.nodes_.size() + 2);
/* Array reallocated, update current node pointer. */
n = &pbvh.nodes[node_index];
n = &pbvh.nodes_[node_index];
/* Initialize children */
PBVHNode *c1 = &pbvh.nodes[children], *c2 = &pbvh.nodes[children + 1];
c1->flag |= PBVH_Leaf;
c2->flag |= PBVH_Leaf;
c1->bm_faces.reserve(n->bm_faces.size() / 2);
c2->bm_faces.reserve(n->bm_faces.size() / 2);
Node *c1 = &pbvh.nodes_[children], *c2 = &pbvh.nodes_[children + 1];
c1->flag_ |= PBVH_Leaf;
c2->flag_ |= PBVH_Leaf;
c1->bm_faces_.reserve(n->bm_faces_.size() / 2);
c2->bm_faces_.reserve(n->bm_faces_.size() / 2);
/* Partition the parent node's faces between the two children. */
for (BMFace *f : n->bm_faces) {
for (BMFace *f : n->bm_faces_) {
const int i = BM_elem_index_get(f);
if (math::midpoint(face_bounds[i].min[axis], face_bounds[i].max[axis]) < mid) {
c1->bm_faces.add(f);
c1->bm_faces_.add(f);
}
else {
c2->bm_faces.add(f);
c2->bm_faces_.add(f);
}
}
/* Enforce at least one primitive in each node */
Set<BMFace *, 0> *empty = nullptr;
Set<BMFace *, 0> *other;
if (c1->bm_faces.is_empty()) {
empty = &c1->bm_faces;
other = &c2->bm_faces;
if (c1->bm_faces_.is_empty()) {
empty = &c1->bm_faces_;
other = &c2->bm_faces_;
}
else if (c2->bm_faces.is_empty()) {
empty = &c2->bm_faces;
other = &c1->bm_faces;
else if (c2->bm_faces_.is_empty()) {
empty = &c2->bm_faces_;
other = &c1->bm_faces_;
}
if (empty) {
for (BMFace *f : *other) {
@@ -330,39 +330,39 @@ static void pbvh_bmesh_node_split(PBVH &pbvh,
/* Clear this node */
/* Mark this node's unique verts as unclaimed. */
for (BMVert *v : n->bm_unique_verts) {
for (BMVert *v : n->bm_unique_verts_) {
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, DYNTOPO_NODE_NONE);
}
/* Unclaim faces. */
for (BMFace *f : n->bm_faces) {
for (BMFace *f : n->bm_faces_) {
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, DYNTOPO_NODE_NONE);
}
n->bm_faces.clear_and_shrink();
n->bm_faces_.clear_and_shrink();
if (n->draw_batches) {
draw::pbvh::node_free(n->draw_batches);
if (n->draw_batches_) {
draw::pbvh::node_free(n->draw_batches_);
}
n->flag &= ~PBVH_Leaf;
n->flag_ &= ~PBVH_Leaf;
/* Recurse. */
pbvh_bmesh_node_split(pbvh, face_bounds, children);
pbvh_bmesh_node_split(pbvh, face_bounds, children + 1);
/* Array maybe reallocated, update current node pointer */
n = &pbvh.nodes[node_index];
n = &pbvh.nodes_[node_index];
/* Update bounding box. */
n->bounds = bounds::merge(pbvh.nodes[n->children_offset].bounds,
pbvh.nodes[n->children_offset + 1].bounds);
n->bounds_orig = n->bounds;
n->bounds_ = bounds::merge(pbvh.nodes_[n->children_offset_].bounds_,
pbvh.nodes_[n->children_offset_ + 1].bounds_);
n->bounds_orig_ = n->bounds_;
}
/** Recursively split the node if it exceeds the leaf_limit. */
static bool pbvh_bmesh_node_limit_ensure(PBVH &pbvh, int node_index)
static bool pbvh_bmesh_node_limit_ensure(Tree &pbvh, int node_index)
{
PBVHNode &node = pbvh.nodes[node_index];
const int faces_num = node.bm_faces.size();
Node &node = pbvh.nodes_[node_index];
const int faces_num = node.bm_faces_.size();
if (faces_num <= leaf_limit) {
/* Node limit not exceeded */
return false;
@@ -372,7 +372,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH &pbvh, int node_index)
Array<Bounds<float3>> face_bounds(faces_num);
int i = 0;
for (BMFace *f : node.bm_faces) {
for (BMFace *f : node.bm_faces_) {
face_bounds[i] = negative_bounds();
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
@@ -387,7 +387,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH &pbvh, int node_index)
}
/* Likely this is already dirty. */
pbvh.header.bm->elem_index_dirty |= BM_FACE;
pbvh.bm_->elem_index_dirty |= BM_FACE;
pbvh_bmesh_node_split(pbvh, face_bounds, node_index);
@@ -396,33 +396,33 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH &pbvh, int node_index)
/**********************************************************************/
BLI_INLINE int pbvh_bmesh_node_index_from_vert(PBVH &pbvh, const BMVert *key)
BLI_INLINE int pbvh_bmesh_node_index_from_vert(Tree &pbvh, const BMVert *key)
{
const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh.cd_vert_node_offset);
const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh.cd_vert_node_offset_);
BLI_assert(node_index != DYNTOPO_NODE_NONE);
BLI_assert(node_index < pbvh.nodes.size());
BLI_assert(node_index < pbvh.nodes_.size());
return node_index;
}
BLI_INLINE int pbvh_bmesh_node_index_from_face(PBVH &pbvh, const BMFace *key)
BLI_INLINE int pbvh_bmesh_node_index_from_face(Tree &pbvh, const BMFace *key)
{
const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh.cd_face_node_offset);
const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh.cd_face_node_offset_);
BLI_assert(node_index != DYNTOPO_NODE_NONE);
BLI_assert(node_index < pbvh.nodes.size());
BLI_assert(node_index < pbvh.nodes_.size());
return node_index;
}
BLI_INLINE PBVHNode *pbvh_bmesh_node_from_vert(PBVH &pbvh, const BMVert *key)
BLI_INLINE Node *pbvh_bmesh_node_from_vert(Tree &pbvh, const BMVert *key)
{
return &pbvh.nodes[pbvh_bmesh_node_index_from_vert(pbvh, key)];
return &pbvh.nodes_[pbvh_bmesh_node_index_from_vert(pbvh, key)];
}
BLI_INLINE PBVHNode *pbvh_bmesh_node_from_face(PBVH &pbvh, const BMFace *key)
BLI_INLINE Node *pbvh_bmesh_node_from_face(Tree &pbvh, const BMFace *key)
{
return &pbvh.nodes[pbvh_bmesh_node_index_from_face(pbvh, key)];
return &pbvh.nodes_[pbvh_bmesh_node_index_from_face(pbvh, key)];
}
static BMVert *pbvh_bmesh_vert_create(PBVH &pbvh,
static BMVert *pbvh_bmesh_vert_create(Tree &pbvh,
const BMVert *v1,
const BMVert *v2,
const int node_index,
@@ -430,25 +430,25 @@ static BMVert *pbvh_bmesh_vert_create(PBVH &pbvh,
const float no[3],
const int cd_vert_mask_offset)
{
PBVHNode *node = &pbvh.nodes[node_index];
Node *node = &pbvh.nodes_[node_index];
BLI_assert((pbvh.nodes.size() == 1 || node_index) && node_index <= pbvh.nodes.size());
BLI_assert((pbvh.nodes_.size() == 1 || node_index) && node_index <= pbvh.nodes_.size());
/* Avoid initializing custom-data because its quite involved. */
BMVert *v = BM_vert_create(pbvh.header.bm, co, nullptr, BM_CREATE_NOP);
BMVert *v = BM_vert_create(pbvh.bm_, co, nullptr, BM_CREATE_NOP);
BM_data_interp_from_verts(pbvh.header.bm, v1, v2, v, 0.5f);
BM_data_interp_from_verts(pbvh.bm_, v1, v2, v, 0.5f);
/* This value is logged below. */
copy_v3_v3(v->no, no);
node->bm_unique_verts.add(v);
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset, node_index);
node->bm_unique_verts_.add(v);
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset_, node_index);
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Log the new vertex. */
BM_log_vert_added(pbvh.bm_log, v, cd_vert_mask_offset);
BM_log_vert_added(pbvh.bm_log_, v, cd_vert_mask_offset);
return v;
}
@@ -456,29 +456,28 @@ static BMVert *pbvh_bmesh_vert_create(PBVH &pbvh,
/**
* \note Callers are responsible for checking if the face exists before adding.
*/
static BMFace *pbvh_bmesh_face_create(PBVH &pbvh,
static BMFace *pbvh_bmesh_face_create(Tree &pbvh,
int node_index,
const Span<BMVert *> v_tri,
const Span<BMEdge *> e_tri,
const BMFace *f_example)
{
PBVHNode *node = &pbvh.nodes[node_index];
Node *node = &pbvh.nodes_[node_index];
/* Ensure we never add existing face. */
BLI_assert(!BM_face_exists(v_tri.data(), 3));
BMFace *f = BM_face_create(
pbvh.header.bm, v_tri.data(), e_tri.data(), 3, f_example, BM_CREATE_NOP);
BMFace *f = BM_face_create(pbvh.bm_, v_tri.data(), e_tri.data(), 3, f_example, BM_CREATE_NOP);
f->head.hflag = f_example->head.hflag;
node->bm_faces.add(f);
BM_ELEM_CD_SET_INT(f, pbvh.cd_face_node_offset, node_index);
node->bm_faces_.add(f);
BM_ELEM_CD_SET_INT(f, pbvh.cd_face_node_offset_, node_index);
node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
node->flag &= ~PBVH_FullyHidden;
node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
node->flag_ &= ~PBVH_FullyHidden;
/* Log the new face. */
BM_log_face_added(pbvh.bm_log, f);
BM_log_face_added(pbvh.bm_log_, f);
return f;
}
@@ -486,8 +485,8 @@ static BMFace *pbvh_bmesh_face_create(PBVH &pbvh,
#define pbvh_bmesh_node_vert_use_count_is_equal(pbvh, node, v, n) \
(pbvh_bmesh_node_vert_use_count_at_most(pbvh, node, v, (n) + 1) == n)
static int pbvh_bmesh_node_vert_use_count_at_most(PBVH &pbvh,
PBVHNode *node,
static int pbvh_bmesh_node_vert_use_count_at_most(Tree &pbvh,
Node *node,
BMVert *v,
const int count_max)
{
@@ -495,7 +494,7 @@ static int pbvh_bmesh_node_vert_use_count_at_most(PBVH &pbvh,
BMFace *f;
BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
Node *f_node = pbvh_bmesh_node_from_face(pbvh, f);
if (f_node == node) {
count++;
if (count == count_max) {
@@ -509,13 +508,13 @@ static int pbvh_bmesh_node_vert_use_count_at_most(PBVH &pbvh,
}
/** Return a node that uses vertex `v` other than its current owner. */
static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH &pbvh, BMVert *v)
static Node *pbvh_bmesh_vert_other_node_find(Tree &pbvh, BMVert *v)
{
PBVHNode *current_node = pbvh_bmesh_node_from_vert(pbvh, v);
Node *current_node = pbvh_bmesh_node_from_vert(pbvh, v);
BMFace *f;
BM_FACES_OF_VERT_ITER_BEGIN (f, v) {
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
Node *f_node = pbvh_bmesh_node_from_face(pbvh, f);
if (f_node != current_node) {
return f_node;
@@ -526,33 +525,33 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH &pbvh, BMVert *v)
return nullptr;
}
static void pbvh_bmesh_vert_ownership_transfer(PBVH &pbvh, PBVHNode *new_owner, BMVert *v)
static void pbvh_bmesh_vert_ownership_transfer(Tree &pbvh, Node *new_owner, BMVert *v)
{
PBVHNode *current_owner = pbvh_bmesh_node_from_vert(pbvh, v);
current_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
Node *current_owner = pbvh_bmesh_node_from_vert(pbvh, v);
current_owner->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
BLI_assert(current_owner != new_owner);
/* Remove current ownership. */
current_owner->bm_unique_verts.remove(v);
current_owner->bm_unique_verts_.remove(v);
/* Set new ownership */
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset, new_owner - pbvh.nodes.data());
new_owner->bm_unique_verts.add(v);
new_owner->bm_other_verts.remove(v);
BLI_assert(!new_owner->bm_other_verts.contains(v));
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset_, new_owner - pbvh.nodes_.data());
new_owner->bm_unique_verts_.add(v);
new_owner->bm_other_verts_.remove(v);
BLI_assert(!new_owner->bm_other_verts_.contains(v));
new_owner->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
new_owner->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
}
static void pbvh_bmesh_vert_remove(PBVH &pbvh, BMVert *v)
static void pbvh_bmesh_vert_remove(Tree &pbvh, BMVert *v)
{
/* Never match for first time. */
int f_node_index_prev = DYNTOPO_NODE_NONE;
PBVHNode *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
v_node->bm_unique_verts.remove(v);
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset, DYNTOPO_NODE_NONE);
Node *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
v_node->bm_unique_verts_.remove(v);
BM_ELEM_CD_SET_INT(v, pbvh.cd_vert_node_offset_, DYNTOPO_NODE_NONE);
/* Have to check each neighboring face's node. */
BMFace *f;
@@ -563,22 +562,22 @@ static void pbvh_bmesh_vert_remove(PBVH &pbvh, BMVert *v)
if (f_node_index_prev != f_node_index) {
f_node_index_prev = f_node_index;
PBVHNode *f_node = &pbvh.nodes[f_node_index];
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
Node *f_node = &pbvh.nodes_[f_node_index];
f_node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_TopologyUpdated;
/* Remove current ownership. */
f_node->bm_other_verts.remove(v);
f_node->bm_other_verts_.remove(v);
BLI_assert(!f_node->bm_unique_verts.contains(v));
BLI_assert(!f_node->bm_other_verts.contains(v));
BLI_assert(!f_node->bm_unique_verts_.contains(v));
BLI_assert(!f_node->bm_other_verts_.contains(v));
}
}
BM_FACES_OF_VERT_ITER_END;
}
static void pbvh_bmesh_face_remove(PBVH &pbvh, BMFace *f)
static void pbvh_bmesh_face_remove(Tree &pbvh, BMFace *f)
{
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
Node *f_node = pbvh_bmesh_node_from_face(pbvh, f);
/* Check if any of this face's vertices need to be removed from the node. */
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
@@ -586,9 +585,9 @@ static void pbvh_bmesh_face_remove(PBVH &pbvh, BMFace *f)
do {
BMVert *v = l_iter->v;
if (pbvh_bmesh_node_vert_use_count_is_equal(pbvh, f_node, v, 1)) {
if (f_node->bm_unique_verts.contains(v)) {
if (f_node->bm_unique_verts_.contains(v)) {
/* Find a different node that uses 'v'. */
PBVHNode *new_node;
Node *new_node;
new_node = pbvh_bmesh_vert_other_node_find(pbvh, v);
BLI_assert(new_node || BM_vert_face_count_is_equal(v, 1));
@@ -599,20 +598,20 @@ static void pbvh_bmesh_face_remove(PBVH &pbvh, BMFace *f)
}
else {
/* Remove from other verts. */
f_node->bm_other_verts.remove(v);
f_node->bm_other_verts_.remove(v);
}
}
} while ((l_iter = l_iter->next) != l_first);
/* Remove face from node and top level. */
f_node->bm_faces.remove(f);
BM_ELEM_CD_SET_INT(f, pbvh.cd_face_node_offset, DYNTOPO_NODE_NONE);
f_node->bm_faces_.remove(f);
BM_ELEM_CD_SET_INT(f, pbvh.cd_face_node_offset_, DYNTOPO_NODE_NONE);
/* Log removed face. */
BM_log_face_removed(pbvh.bm_log, f);
BM_log_face_removed(pbvh.bm_log_, f);
/* Mark node for update. */
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
f_node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_TopologyUpdated;
}
static Array<BMLoop *> pbvh_bmesh_edge_loops(BMEdge *e)
@@ -628,12 +627,12 @@ static Array<BMLoop *> pbvh_bmesh_edge_loops(BMEdge *e)
return loops;
}
static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
static void pbvh_bmesh_node_drop_orig(Node *node)
{
MEM_SAFE_FREE(node->bm_orco);
MEM_SAFE_FREE(node->bm_ortri);
MEM_SAFE_FREE(node->bm_orvert);
node->bm_tot_ortri = 0;
MEM_SAFE_FREE(node->bm_orco_);
MEM_SAFE_FREE(node->bm_ortri_);
MEM_SAFE_FREE(node->bm_orvert_);
node->bm_tot_ortri_ = 0;
}
/****************************** EdgeQueue *****************************/
@@ -677,13 +676,13 @@ struct EdgeQueueContext {
#ifdef USE_EDGEQUEUE_TAG_VERIFY
/* simply check no edges are tagged
* (it's a requirement that edges enter and leave a clean tag state) */
static void pbvh_bmesh_edge_tag_verify(PBVH *pbvh)
static void pbvh_bmesh_edge_tag_verify(Tree *pbvh)
{
for (int n = 0; n < pbvh->totnode; n++) {
PBVHNode *node = &pbvh->nodes[n];
if (node->bm_faces) {
Node *node = &pbvh->nodes_[n];
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);
BMEdge *e_tri[3];
BMLoop *l_iter;
@@ -983,7 +982,7 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
/**
* Create a priority queue containing vertex pairs connected by a long
* edge as defined by PBVH.bm_max_edge_len.
* edge as defined by Tree.bm_max_edge_len.
*
* Only nodes marked for topology update are checked, and in those
* nodes only edges used by a face intersecting the (center, radius)
@@ -992,7 +991,7 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
* The highest priority (lowest number) is given to the longest edge.
*/
static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
PBVH &pbvh,
Tree &pbvh,
const float center[3],
const float view_normal[3],
float radius,
@@ -1002,9 +1001,9 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
eq_ctx->q->heap = BLI_heapsimple_new();
eq_ctx->q->center = center;
eq_ctx->q->radius_squared = radius * radius;
eq_ctx->q->limit_len_squared = pbvh.bm_max_edge_len * pbvh.bm_max_edge_len;
eq_ctx->q->limit_len_squared = pbvh.bm_max_edge_len_ * pbvh.bm_max_edge_len_;
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
eq_ctx->q->limit_len = pbvh.bm_max_edge_len;
eq_ctx->q->limit_len = pbvh.bm_max_edge_len_;
#endif
eq_ctx->q->view_normal = view_normal;
@@ -1027,12 +1026,12 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
pbvh_bmesh_edge_tag_verify(pbvh);
#endif
for (PBVHNode &node : pbvh.nodes) {
for (Node &node : pbvh.nodes_) {
/* Check leaf nodes marked for topology update. */
if ((node.flag & PBVH_Leaf) && (node.flag & PBVH_UpdateTopology) &&
!(node.flag & PBVH_FullyHidden))
if ((node.flag_ & PBVH_Leaf) && (node.flag_ & PBVH_UpdateTopology) &&
!(node.flag_ & PBVH_FullyHidden))
{
for (BMFace *f : node.bm_faces) {
for (BMFace *f : node.bm_faces_) {
long_edge_queue_face_add(eq_ctx, f);
}
}
@@ -1041,7 +1040,7 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
/**
* Create a priority queue containing vertex pairs connected by a
* short edge as defined by PBVH.bm_min_edge_len.
* short edge as defined by Tree.bm_min_edge_len.
*
* Only nodes marked for topology update are checked, and in those
* nodes only edges used by a face intersecting the (center, radius)
@@ -1050,7 +1049,7 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx,
* The highest priority (lowest number) is given to the shortest edge.
*/
static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
PBVH &pbvh,
Tree &pbvh,
const float center[3],
const float view_normal[3],
float radius,
@@ -1060,9 +1059,9 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
eq_ctx->q->heap = BLI_heapsimple_new();
eq_ctx->q->center = center;
eq_ctx->q->radius_squared = radius * radius;
eq_ctx->q->limit_len_squared = pbvh.bm_min_edge_len * pbvh.bm_min_edge_len;
eq_ctx->q->limit_len_squared = pbvh.bm_min_edge_len_ * pbvh.bm_min_edge_len_;
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
eq_ctx->q->limit_len = pbvh.bm_min_edge_len;
eq_ctx->q->limit_len = pbvh.bm_min_edge_len_;
#endif
eq_ctx->q->view_normal = view_normal;
@@ -1081,12 +1080,12 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere;
}
for (PBVHNode &node : pbvh.nodes) {
for (Node &node : pbvh.nodes_) {
/* Check leaf nodes marked for topology update */
if ((node.flag & PBVH_Leaf) && (node.flag & PBVH_UpdateTopology) &&
!(node.flag & PBVH_FullyHidden))
if ((node.flag_ & PBVH_Leaf) && (node.flag_ & PBVH_UpdateTopology) &&
!(node.flag_ & PBVH_FullyHidden))
{
for (BMFace *f : node.bm_faces) {
for (BMFace *f : node.bm_faces_) {
short_edge_queue_face_add(eq_ctx, f);
}
}
@@ -1120,9 +1119,9 @@ static void merge_edge_data(BMesh &bm, BMEdge &dst, const BMEdge &src)
BM_data_interp_from_edges(&bm, &src, &dst, &dst, 0.5f);
}
static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH &pbvh, BMEdge *e)
static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, Tree &pbvh, BMEdge *e)
{
BMesh *bm = pbvh.header.bm;
BMesh *bm = pbvh.bm_;
float co_mid[3], no_mid[3];
@@ -1155,7 +1154,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH &pbvh, BMEdge *
BMVert *v2 = l_adj->next->v;
if (ni != node_index && i == 0) {
pbvh_bmesh_vert_ownership_transfer(pbvh, &pbvh.nodes[ni], v_new);
pbvh_bmesh_vert_ownership_transfer(pbvh, &pbvh.nodes_[ni], v_new);
}
/* The 2 new faces created and assigned to `f_new` have their
@@ -1208,8 +1207,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH &pbvh, BMEdge *
BM_face_kill(bm, f_adj);
/* Ensure new vertex is in the node */
if (!pbvh.nodes[ni].bm_unique_verts.contains(v_new)) {
pbvh.nodes[ni].bm_other_verts.add(v_new);
if (!pbvh.nodes_[ni].bm_unique_verts_.contains(v_new)) {
pbvh.nodes_[ni].bm_other_verts_.add(v_new);
}
if (BM_vert_edge_count_is_over(v_opp, 8)) {
@@ -1224,7 +1223,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH &pbvh, BMEdge *
BM_edge_kill(bm, e);
}
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH &pbvh)
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, Tree &pbvh)
{
const double start_time = BLI_time_now_seconds();
@@ -1249,7 +1248,7 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH &pbvh
BLI_assert(len_squared_v3v3(v1->co, v2->co) > eq_ctx->q->limit_len_squared);
/* Check that the edge's vertices are still in the PBVH. It's
/* Check that the edge's vertices are still in the Tree. It's
* possible that an edge collapse has deleted adjacent faces
* and the node has been split, thus leaving wire edges and
* associated vertices. */
@@ -1519,9 +1518,9 @@ static void merge_face_edge_data(BMesh &bm,
}
static void pbvh_bmesh_collapse_edge(
PBVH &pbvh, BMEdge *e, BMVert *v1, BMVert *v2, GHash *deleted_verts, EdgeQueueContext *eq_ctx)
Tree &pbvh, BMEdge *e, BMVert *v1, BMVert *v2, GHash *deleted_verts, EdgeQueueContext *eq_ctx)
{
BMesh &bm = *pbvh.header.bm;
BMesh &bm = *pbvh.bm_;
const bool v1_on_boundary = is_boundary_vert(*v1);
const bool v2_on_boundary = is_boundary_vert(*v2);
@@ -1555,7 +1554,7 @@ static void pbvh_bmesh_collapse_edge(
v_conn = v1;
}
/* Remove the merge vertex from the PBVH. */
/* Remove the merge vertex from the Tree. */
pbvh_bmesh_vert_remove(pbvh, v_del);
/* For all remaining faces of v_del, create a new face that is the
@@ -1614,16 +1613,16 @@ static void pbvh_bmesh_collapse_edge(
const std::array<BMVert *, 3> v_tri{v_conn, l->next->v, l->prev->v};
BLI_assert(!BM_face_exists(v_tri.data(), 3));
PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
int ni = n - pbvh.nodes.data();
Node *n = pbvh_bmesh_node_from_face(pbvh, f);
int ni = n - pbvh.nodes_.data();
const std::array<BMEdge *, 3> e_tri = bm_edges_from_tri(&bm, v_tri);
BMFace *new_face = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
merge_face_edge_data(bm, f, new_face, v_del, l, v_conn);
/* Ensure that v_conn is in the new face's node */
if (!n->bm_unique_verts.contains(v_conn)) {
n->bm_other_verts.add(v_conn);
if (!n->bm_unique_verts_.contains(v_conn)) {
n->bm_other_verts_.add(v_conn);
}
}
}
@@ -1655,12 +1654,12 @@ static void pbvh_bmesh_collapse_edge(
}
/* Check if any of the face's vertices are now unused, if so
* remove them from the PBVH */
* remove them from the Tree */
for (const int j : IndexRange(3)) {
if ((v_tri[j] != v_del) && (v_tri[j]->e == nullptr)) {
pbvh_bmesh_vert_remove(pbvh, v_tri[j]);
BM_log_vert_removed(pbvh.bm_log, v_tri[j], eq_ctx->cd_vert_mask_offset);
BM_log_vert_removed(pbvh.bm_log_, v_tri[j], eq_ctx->cd_vert_mask_offset);
if (v_tri[j] == v_conn) {
v_conn = nullptr;
@@ -1677,7 +1676,7 @@ static void pbvh_bmesh_collapse_edge(
* However, if the vertex is on a boundary, do not move it to preserve the shape of the
* boundary. */
if (v_conn != nullptr && !is_boundary_vert(*v_conn)) {
BM_log_vert_before_modified(pbvh.bm_log, v_conn, eq_ctx->cd_vert_mask_offset);
BM_log_vert_before_modified(pbvh.bm_log_, v_conn, eq_ctx->cd_vert_mask_offset);
mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
add_v3_v3(v_conn->no, v_del->no);
normalize_v3(v_conn->no);
@@ -1687,25 +1686,25 @@ static void pbvh_bmesh_collapse_edge(
/* Update bounding boxes attached to the connected vertex.
* Note that we can often get-away without this but causes #48779. */
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, l->f);
f_node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateBB;
Node *f_node = pbvh_bmesh_node_from_face(pbvh, l->f);
f_node->flag_ |= PBVH_UpdateDrawBuffers | PBVH_UpdateNormals | PBVH_UpdateBB;
}
BM_LOOPS_OF_VERT_ITER_END;
}
/* Delete v_del */
BLI_assert(!BM_vert_face_check(v_del));
BM_log_vert_removed(pbvh.bm_log, v_del, eq_ctx->cd_vert_mask_offset);
BM_log_vert_removed(pbvh.bm_log_, v_del, eq_ctx->cd_vert_mask_offset);
/* v_conn == nullptr is OK */
BLI_ghash_insert(deleted_verts, v_del, v_conn);
BM_vert_kill(&bm, v_del);
}
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH &pbvh)
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, Tree &pbvh)
{
const double start_time = BLI_time_now_seconds();
const float min_len_squared = pbvh.bm_min_edge_len * pbvh.bm_min_edge_len;
const float min_len_squared = pbvh.bm_min_edge_len_ * pbvh.bm_min_edge_len_;
bool any_collapsed = false;
/* Deleted verts point to vertices they were merged into, or nullptr when removed. */
GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts");
@@ -1737,9 +1736,9 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH &pbvh
continue;
}
/* Check that the edge's vertices are still in the PBVH. It's possible that an edge collapse
* has deleted adjacent faces and the node has been split, thus leaving wire edges and
* associated vertices. */
/* Check that the edge's vertices are still in the Tree. It's possible that
* an edge collapse has deleted adjacent faces and the node has been split, thus leaving wire
* edges and associated vertices. */
if ((BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE) ||
(BM_ELEM_CD_GET_INT(e->v2, eq_ctx->cd_vert_node_offset) == DYNTOPO_NODE_NONE))
{
@@ -1760,7 +1759,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH &pbvh
/************************* Called from pbvh.cc *************************/
bool bmesh_node_raycast(PBVHNode *node,
bool bmesh_node_raycast(Node *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@@ -1772,15 +1771,15 @@ bool bmesh_node_raycast(PBVHNode *node,
bool hit = false;
float nearest_vertex_co[3] = {0.0f};
use_original = use_original && node->bm_tot_ortri;
use_original = use_original && node->bm_tot_ortri_;
if (use_original && node->bm_tot_ortri) {
for (int i = 0; i < node->bm_tot_ortri; i++) {
if (use_original && node->bm_tot_ortri_) {
for (int i = 0; i < node->bm_tot_ortri_; i++) {
float *cos[3];
cos[0] = node->bm_orco[node->bm_ortri[i][0]];
cos[1] = node->bm_orco[node->bm_ortri[i][1]];
cos[2] = node->bm_orco[node->bm_ortri[i][2]];
cos[0] = node->bm_orco_[node->bm_ortri_[i][0]];
cos[1] = node->bm_orco_[node->bm_ortri_[i][1]];
cos[2] = node->bm_orco_[node->bm_ortri_[i][2]];
if (ray_face_intersection_tri(ray_start, isect_precalc, cos[0], cos[1], cos[2], depth)) {
hit = true;
@@ -1797,7 +1796,7 @@ bool bmesh_node_raycast(PBVHNode *node,
len_squared_v3v3(location, cos[j]) < len_squared_v3v3(location, nearest_vertex_co))
{
copy_v3_v3(nearest_vertex_co, cos[j]);
r_active_vertex->i = intptr_t(node->bm_orvert[node->bm_ortri[i][j]]);
r_active_vertex->i = intptr_t(node->bm_orvert_[node->bm_ortri_[i][j]]);
}
}
}
@@ -1805,7 +1804,7 @@ bool bmesh_node_raycast(PBVHNode *node,
}
}
else {
for (BMFace *f : node->bm_faces) {
for (BMFace *f : node->bm_faces_) {
BLI_assert(f->len == 3);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
@@ -1841,20 +1840,20 @@ bool bmesh_node_raycast(PBVHNode *node,
return hit;
}
bool bmesh_node_raycast_detail(PBVHNode *node,
bool bmesh_node_raycast_detail(Node *node,
const float ray_start[3],
IsectRayPrecalc *isect_precalc,
float *depth,
float *r_edge_length)
{
if (node->flag & PBVH_FullyHidden) {
if (node->flag_ & PBVH_FullyHidden) {
return false;
}
bool hit = false;
BMFace *f_hit = nullptr;
for (BMFace *f : node->bm_faces) {
for (BMFace *f : node->bm_faces_) {
BLI_assert(f->len == 3);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMVert *v_tri[3];
@@ -1884,7 +1883,7 @@ bool bmesh_node_raycast_detail(PBVHNode *node,
return hit;
}
bool bmesh_node_nearest_to_ray(PBVHNode *node,
bool bmesh_node_nearest_to_ray(Node *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
@@ -1893,20 +1892,20 @@ bool bmesh_node_nearest_to_ray(PBVHNode *node,
{
bool hit = false;
if (use_original && node->bm_tot_ortri) {
for (int i = 0; i < node->bm_tot_ortri; i++) {
const int *t = node->bm_ortri[i];
if (use_original && node->bm_tot_ortri_) {
for (int i = 0; i < node->bm_tot_ortri_; i++) {
const int *t = node->bm_ortri_[i];
hit |= ray_face_nearest_tri(ray_start,
ray_normal,
node->bm_orco[t[0]],
node->bm_orco[t[1]],
node->bm_orco[t[2]],
node->bm_orco_[t[0]],
node->bm_orco_[t[1]],
node->bm_orco_[t[2]],
depth,
dist_sq);
}
}
else {
for (BMFace *f : node->bm_faces) {
for (BMFace *f : node->bm_faces_) {
BLI_assert(f->len == 3);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMVert *v_tri[3];
@@ -1921,20 +1920,20 @@ bool bmesh_node_nearest_to_ray(PBVHNode *node,
return hit;
}
void bmesh_normals_update(Span<PBVHNode *> nodes)
void bmesh_normals_update(Span<Node *> nodes)
{
for (PBVHNode *node : nodes) {
if (node->flag & PBVH_UpdateNormals) {
for (BMFace *face : node->bm_faces) {
for (Node *node : nodes) {
if (node->flag_ & PBVH_UpdateNormals) {
for (BMFace *face : node->bm_faces_) {
BM_face_normal_update(face);
}
for (BMVert *vert : node->bm_unique_verts) {
for (BMVert *vert : node->bm_unique_verts_) {
BM_vert_normal_update(vert);
}
for (BMVert *vert : node->bm_other_verts) {
for (BMVert *vert : node->bm_other_verts_) {
BM_vert_normal_update(vert);
}
node->flag &= ~PBVH_UpdateNormals;
node->flag_ &= ~PBVH_UpdateNormals;
}
}
}
@@ -1951,7 +1950,7 @@ struct FastNodeBuildInfo {
* This function is multi-thread-able since each invocation applies
* to a sub part of the arrays.
*/
static void pbvh_bmesh_node_limit_ensure_fast(PBVH *pbvh,
static void pbvh_bmesh_node_limit_ensure_fast(Tree *pbvh,
const MutableSpan<BMFace *> nodeinfo,
const Span<Bounds<float3>> face_bounds,
FastNodeBuildInfo *node,
@@ -2052,43 +2051,43 @@ static void pbvh_bmesh_node_limit_ensure_fast(PBVH *pbvh,
pbvh_bmesh_node_limit_ensure_fast(pbvh, nodeinfo, face_bounds, child2, arena);
}
static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
static void pbvh_bmesh_create_nodes_fast_recursive(Tree *pbvh,
const Span<BMFace *> nodeinfo,
const Span<Bounds<float3>> face_bounds,
FastNodeBuildInfo *node,
int node_index)
{
PBVHNode *n = &pbvh->nodes[node_index];
Node *n = &pbvh->nodes_[node_index];
/* Two cases, node does not have children or does have children. */
if (node->child1) {
int children_offset = pbvh->nodes.size();
int children_offset_ = pbvh->nodes_.size();
n->children_offset = children_offset;
pbvh->nodes.resize(pbvh->nodes.size() + 2);
n->children_offset_ = children_offset_;
pbvh->nodes_.resize(pbvh->nodes_.size() + 2);
pbvh_bmesh_create_nodes_fast_recursive(
pbvh, nodeinfo, face_bounds, node->child1, children_offset);
pbvh, nodeinfo, face_bounds, node->child1, children_offset_);
pbvh_bmesh_create_nodes_fast_recursive(
pbvh, nodeinfo, face_bounds, node->child2, children_offset + 1);
pbvh, nodeinfo, face_bounds, node->child2, children_offset_ + 1);
n = &pbvh->nodes[node_index];
n = &pbvh->nodes_[node_index];
/* Update bounding box. */
n->bounds = bounds::merge(pbvh->nodes[n->children_offset].bounds,
pbvh->nodes[n->children_offset + 1].bounds);
n->bounds_orig = n->bounds;
n->bounds_ = bounds::merge(pbvh->nodes_[n->children_offset_].bounds_,
pbvh->nodes_[n->children_offset_ + 1].bounds_);
n->bounds_orig_ = n->bounds_;
}
else {
/* Node does not have children so it's a leaf node, populate with faces and tag accordingly
* this is an expensive part but it's not so easily thread-able due to vertex node indices. */
const int cd_vert_node_offset = pbvh->cd_vert_node_offset;
const int cd_face_node_offset = pbvh->cd_face_node_offset;
const int cd_vert_node_offset = pbvh->cd_vert_node_offset_;
const int cd_face_node_offset = pbvh->cd_face_node_offset_;
bool has_visible = false;
n->flag = PBVH_Leaf;
n->bm_faces.reserve(node->totface);
n->flag_ = PBVH_Leaf;
n->bm_faces_.reserve(node->totface);
n->bounds = face_bounds[node->start];
n->bounds_ = face_bounds[node->start];
const int end = node->start + node->totface;
@@ -2096,7 +2095,7 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
BMFace *f = nodeinfo[i];
/* Update ownership of faces. */
n->bm_faces.add_new(f);
n->bm_faces_.add_new(f);
BM_ELEM_CD_SET_INT(f, cd_face_node_offset, node_index);
/* Update vertices. */
@@ -2104,12 +2103,12 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
BMLoop *l_iter = l_first;
do {
BMVert *v = l_iter->v;
if (!n->bm_unique_verts.contains(v)) {
if (!n->bm_unique_verts_.contains(v)) {
if (BM_ELEM_CD_GET_INT(v, cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
n->bm_other_verts.add(v);
n->bm_other_verts_.add(v);
}
else {
n->bm_unique_verts.add(v);
n->bm_unique_verts_.add(v);
BM_ELEM_CD_SET_INT(v, cd_vert_node_offset, node_index);
}
}
@@ -2120,44 +2119,42 @@ static void pbvh_bmesh_create_nodes_fast_recursive(PBVH *pbvh,
has_visible = true;
}
n->bounds = bounds::merge(n->bounds, face_bounds[BM_elem_index_get(f)]);
n->bounds_ = bounds::merge(n->bounds_, face_bounds[BM_elem_index_get(f)]);
}
BLI_assert(n->bounds.min[0] <= n->bounds.max[0] && n->bounds.min[1] <= n->bounds.max[1] &&
n->bounds.min[2] <= n->bounds.max[2]);
BLI_assert(n->bounds_.min[0] <= n->bounds_.max[0] && n->bounds_.min[1] <= n->bounds_.max[1] &&
n->bounds_.min[2] <= n->bounds_.max[2]);
n->bounds_orig = n->bounds;
n->bounds_orig_ = n->bounds_;
/* Build GPU buffers for new node and update vertex normals. */
BKE_pbvh_node_mark_rebuild_draw(n);
BKE_pbvh_node_fully_hidden_set(n, !has_visible);
n->flag |= PBVH_UpdateNormals;
n->flag_ |= PBVH_UpdateNormals;
}
}
/***************************** Public API *****************************/
void update_bmesh_offsets(PBVH &pbvh, int cd_vert_node_offset, int cd_face_node_offset)
void update_bmesh_offsets(Tree &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;
pbvh.cd_vert_node_offset_ = cd_vert_node_offset;
pbvh.cd_face_node_offset_ = cd_face_node_offset;
}
std::unique_ptr<PBVH> build_bmesh(BMesh *bm,
std::unique_ptr<Tree> build_bmesh(BMesh *bm,
BMLog *log,
const int cd_vert_node_offset,
const int cd_face_node_offset)
{
std::unique_ptr<PBVH> pbvh = std::make_unique<PBVH>();
pbvh->header.type = PBVH_BMESH;
std::unique_ptr<Tree> pbvh = std::make_unique<Tree>(Type::BMesh);
pbvh->header.bm = bm;
pbvh->bm_ = bm;
BKE_pbvh_bmesh_detail_size_set(*pbvh, 0.75);
pbvh->header.type = PBVH_BMESH;
pbvh->bm_log = log;
pbvh->bm_log_ = log;
pbvh::update_bmesh_offsets(*pbvh, cd_vert_node_offset, cd_face_node_offset);
@@ -2168,7 +2165,7 @@ std::unique_ptr<PBVH> build_bmesh(BMesh *bm,
/* bounding box array of all faces, no need to recalculate every time. */
Array<Bounds<float3>> face_bounds(bm->totface);
Array<BMFace *> nodeinfo(bm->totface);
MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast PBVH node storage");
MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "fast Tree node storage");
BMIter iter;
BMFace *f;
@@ -2206,7 +2203,7 @@ std::unique_ptr<PBVH> build_bmesh(BMesh *bm,
* next we need to assign those to the gsets of the nodes. */
/* Start with all faces in the root node. */
pbvh->nodes.append({});
pbvh->nodes_.append({});
/* Take root node and visit and populate children recursively. */
pbvh_bmesh_create_nodes_fast_recursive(pbvh.get(), nodeinfo, face_bounds, &rootnode, 0);
@@ -2215,7 +2212,7 @@ std::unique_ptr<PBVH> build_bmesh(BMesh *bm,
return pbvh;
}
bool bmesh_update_topology(PBVH &pbvh,
bool bmesh_update_topology(Tree &pbvh,
PBVHTopologyUpdateMode mode,
const float center[3],
const float view_normal[3],
@@ -2224,9 +2221,9 @@ bool bmesh_update_topology(PBVH &pbvh,
const bool use_projected)
{
const int cd_vert_mask_offset = CustomData_get_offset_named(
&pbvh.header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
const int cd_vert_node_offset = pbvh.cd_vert_node_offset;
const int cd_face_node_offset = pbvh.cd_face_node_offset;
&pbvh.bm_->vdata, CD_PROP_FLOAT, ".sculpt_mask");
const int cd_vert_node_offset = pbvh.cd_vert_node_offset_;
const int cd_face_node_offset = pbvh.cd_face_node_offset_;
bool modified = false;
@@ -2240,7 +2237,7 @@ bool bmesh_update_topology(PBVH &pbvh,
EdgeQueueContext eq_ctx = {
&q,
queue_pool,
pbvh.header.bm,
pbvh.bm_,
cd_vert_mask_offset,
cd_vert_node_offset,
cd_face_node_offset,
@@ -2259,7 +2256,7 @@ bool bmesh_update_topology(PBVH &pbvh,
EdgeQueueContext eq_ctx = {
&q,
queue_pool,
pbvh.header.bm,
pbvh.bm_,
cd_vert_mask_offset,
cd_vert_node_offset,
cd_face_node_offset,
@@ -2273,21 +2270,21 @@ bool bmesh_update_topology(PBVH &pbvh,
}
/* Unmark nodes. */
for (PBVHNode &node : pbvh.nodes) {
if (node.flag & PBVH_Leaf && node.flag & PBVH_UpdateTopology) {
node.flag &= ~PBVH_UpdateTopology;
for (Node &node : pbvh.nodes_) {
if (node.flag_ & PBVH_Leaf && node.flag_ & PBVH_UpdateTopology) {
node.flag_ &= ~PBVH_UpdateTopology;
}
}
/* Go over all changed nodes and check if anything needs to be updated. */
for (PBVHNode &node : pbvh.nodes) {
if (node.flag & PBVH_Leaf && node.flag & PBVH_TopologyUpdated) {
node.flag &= ~PBVH_TopologyUpdated;
for (Node &node : pbvh.nodes_) {
if (node.flag_ & PBVH_Leaf && node.flag_ & PBVH_TopologyUpdated) {
node.flag_ &= ~PBVH_TopologyUpdated;
if (node.bm_ortri) {
if (node.bm_ortri_) {
/* Reallocate original triangle data. */
pbvh_bmesh_node_drop_orig(&node);
BKE_pbvh_bmesh_node_save_orig(pbvh.header.bm, pbvh.bm_log, &node, true);
BKE_pbvh_bmesh_node_save_orig(pbvh.bm_, pbvh.bm_log_, &node, true);
}
}
}
@@ -2301,53 +2298,57 @@ bool bmesh_update_topology(PBVH &pbvh,
} // namespace blender::bke::pbvh
/* Updates a given PBVH Node with the original coordinates of the corresponding BMesh vertex.
* Attempts to retrieve the value from the BMLog, falls back to the vertex's current coordinates
* if it is either not found in the log or not requested. */
/* Updates a given Tree Node with the original coordinates of the corresponding
* BMesh vertex. Attempts to retrieve the value from the BMLog, falls back to the vertex's current
* coordinates if it is either not found in the log or not requested. */
static void BKE_pbvh_bmesh_node_copy_original_co(
BMLog *log, PBVHNode *node, BMVert *v, int i, bool use_original)
BMLog *log, blender::bke::pbvh::Node *node, BMVert *v, int i, bool use_original)
{
if (!use_original) {
copy_v3_v3(node->bm_orco[i], v->co);
copy_v3_v3(node->bm_orco_[i], v->co);
}
else {
const float *origco = BM_log_find_original_vert_co(log, v);
if (origco) {
copy_v3_v3(node->bm_orco[i], origco);
copy_v3_v3(node->bm_orco_[i], origco);
}
else {
copy_v3_v3(node->bm_orco[i], v->co);
copy_v3_v3(node->bm_orco_[i], v->co);
}
}
node->bm_orvert[i] = v;
node->bm_orvert_[i] = v;
BM_elem_index_set(v, i); /* set_dirty! */
}
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool use_original)
void BKE_pbvh_bmesh_node_save_orig(BMesh *bm,
BMLog *log,
blender::bke::pbvh::Node *node,
bool use_original)
{
/* Skip if original coords/triangles are already saved. */
if (node->bm_orco) {
if (node->bm_orco_) {
return;
}
const int totvert = node->bm_unique_verts.size() + node->bm_other_verts.size();
const int totvert = node->bm_unique_verts_.size() + node->bm_other_verts_.size();
const int tottri = node->bm_faces.size();
const int tottri = node->bm_faces_.size();
node->bm_orco = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*node->bm_orco) * totvert, __func__));
node->bm_ortri = static_cast<int(*)[3]>(MEM_mallocN(sizeof(*node->bm_ortri) * tottri, __func__));
node->bm_orvert = static_cast<BMVert **>(
MEM_mallocN(sizeof(*node->bm_orvert) * totvert, __func__));
node->bm_orco_ = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*node->bm_orco_) * totvert, __func__));
node->bm_ortri_ = static_cast<int(*)[3]>(
MEM_mallocN(sizeof(*node->bm_ortri_) * tottri, __func__));
node->bm_orvert_ = static_cast<BMVert **>(
MEM_mallocN(sizeof(*node->bm_orvert_) * totvert, __func__));
/* Copy out the vertices and assign a temporary index. */
int i = 0;
for (BMVert *v : node->bm_unique_verts) {
for (BMVert *v : node->bm_unique_verts_) {
BKE_pbvh_bmesh_node_copy_original_co(log, node, v, i, use_original);
i++;
}
for (BMVert *v : node->bm_other_verts) {
for (BMVert *v : node->bm_other_verts_) {
BKE_pbvh_bmesh_node_copy_original_co(log, node, v, i, use_original);
i++;
}
@@ -2356,62 +2357,62 @@ void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool u
/* Copy the triangles */
i = 0;
for (BMFace *f : node->bm_faces) {
for (BMFace *f : node->bm_faces_) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
blender::bke::pbvh::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;
node->bm_tot_ortri_ = i;
}
void BKE_pbvh_bmesh_after_stroke(PBVH &pbvh)
void BKE_pbvh_bmesh_after_stroke(blender::bke::pbvh::Tree &pbvh)
{
const int totnode = pbvh.nodes.size();
const int totnode = pbvh.nodes_.size();
for (int i = 0; i < totnode; i++) {
PBVHNode *n = &pbvh.nodes[i];
if (n->flag & PBVH_Leaf) {
blender::bke::pbvh::Node *n = &pbvh.nodes_[i];
if (n->flag_ & PBVH_Leaf) {
/* Free orco/ortri data. */
blender::bke::pbvh::pbvh_bmesh_node_drop_orig(n);
pbvh_bmesh_node_drop_orig(n);
/* Recursively split nodes that have gotten too many elements. */
blender::bke::pbvh::pbvh_bmesh_node_limit_ensure(pbvh, i);
pbvh_bmesh_node_limit_ensure(pbvh, i);
}
}
}
void BKE_pbvh_bmesh_detail_size_set(PBVH &pbvh, float detail_size)
void BKE_pbvh_bmesh_detail_size_set(blender::bke::pbvh::Tree &pbvh, float detail_size)
{
pbvh.bm_max_edge_len = detail_size;
pbvh.bm_min_edge_len = pbvh.bm_max_edge_len * 0.4f;
pbvh.bm_max_edge_len_ = detail_size;
pbvh.bm_min_edge_len_ = pbvh.bm_max_edge_len_ * 0.4f;
}
void BKE_pbvh_node_mark_topology_update(PBVHNode *node)
void BKE_pbvh_node_mark_topology_update(blender::bke::pbvh::Node *node)
{
node->flag |= PBVH_UpdateTopology;
node->flag_ |= PBVH_UpdateTopology;
}
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node)
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::Node *node)
{
return node->bm_unique_verts;
return node->bm_unique_verts_;
}
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
const blender::Set<BMVert *, 0> &BKE_pbvh_bmesh_node_other_verts(blender::bke::pbvh::Node *node)
{
return node->bm_other_verts;
return node->bm_other_verts_;
}
const blender::Set<BMFace *, 0> &BKE_pbvh_bmesh_node_faces(PBVHNode *node)
const blender::Set<BMFace *, 0> &BKE_pbvh_bmesh_node_faces(blender::bke::pbvh::Node *node)
{
return node->bm_faces;
return node->bm_faces_;
}
/****************************** Debugging *****************************/
#if 0
static void pbvh_bmesh_print(PBVH *pbvh)
static void pbvh_bmesh_print(Tree *pbvh)
{
fprintf(stderr, "\npbvh=%p\n", pbvh);
fprintf(stderr, "bm_face_to_node:\n");
@@ -2431,20 +2432,20 @@ static void pbvh_bmesh_print(PBVH *pbvh)
}
for (int n = 0; n < pbvh->totnode; n++) {
PBVHNode *node = &pbvh->nodes[n];
Node *node = &pbvh->nodes_[n];
if (!(node->flag & PBVH_Leaf)) {
continue;
}
GSetIterator gs_iter;
fprintf(stderr, "node %d\n faces:\n", n);
GSET_ITER (gs_iter, node->bm_faces)
GSET_ITER (gs_iter, node->bm_faces_)
fprintf(stderr, " %d\n", BM_elem_index_get((BMFace *)BLI_gsetIterator_getKey(&gs_iter)));
fprintf(stderr, " unique verts:\n");
GSET_ITER (gs_iter, node->bm_unique_verts)
GSET_ITER (gs_iter, node->bm_unique_verts_)
fprintf(stderr, " %d\n", BM_elem_index_get((BMVert *)BLI_gsetIterator_getKey(&gs_iter)));
fprintf(stderr, " other verts:\n");
GSET_ITER (gs_iter, node->bm_other_verts)
GSET_ITER (gs_iter, node->bm_other_verts_)
fprintf(stderr, " %d\n", BM_elem_index_get((BMVert *)BLI_gsetIterator_getKey(&gs_iter)));
}
}
@@ -2462,7 +2463,7 @@ static void print_flag_factors(int flag)
#ifdef USE_VERIFY
static void pbvh_bmesh_verify(PBVH *pbvh)
static void pbvh_bmesh_verify(Tree *pbvh)
{
/* Build list of faces & verts to lookup. */
GSet *faces_all = BLI_gset_ptr_new_ex(__func__, pbvh->header.bm->totface);
@@ -2471,7 +2472,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
{
BMFace *f;
BM_ITER_MESH (f, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
BLI_assert(BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE);
BLI_assert(BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset_) != DYNTOPO_NODE_NONE);
BLI_gset_insert(faces_all, f);
}
}
@@ -2480,7 +2481,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
{
BMVert *v;
BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset_) != DYNTOPO_NODE_NONE) {
BLI_gset_insert(verts_all, v);
}
}
@@ -2490,9 +2491,9 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
{
int totface = 0, totvert = 0;
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *n = &pbvh->nodes[i];
totface += n->bm_faces.is_empty() ? n->bm_faces.size() : 0;
totvert += n->bm_unique_verts ? n->bm_unique_verts.size() : 0;
Node *n = &pbvh->nodes_[i];
totface += n->bm_faces_.is_empty() ? n->bm_faces_.size() : 0;
totvert += n->bm_unique_verts_ ? n->bm_unique_verts_.size() : 0;
}
BLI_assert(totface == BLI_gset_len(faces_all));
@@ -2504,29 +2505,30 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
BM_ITER_MESH (f, &iter, pbvh->header.bm, BM_FACES_OF_MESH) {
BMIter bm_iter;
BMVert *v;
PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, f);
Node *n = pbvh_bmesh_node_lookup(pbvh, f);
/* Check that the face's node is a leaf. */
BLI_assert(n->flag & PBVH_Leaf);
/* Check that the face's node knows it owns the face. */
BLI_assert(n->bm_faces.contains(f));
BLI_assert(n->bm_faces_.contains(f));
/* Check the face's vertices... */
BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
PBVHNode *nv;
Node *nv;
/* Check that the vertex is in the node. */
BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v) ^ BLI_gset_haskey(n->bm_other_verts, v));
BLI_assert(BLI_gset_haskey(n->bm_unique_verts_, v) ^
BLI_gset_haskey(n->bm_other_verts_, v));
/* Check that the vertex has a node owner. */
nv = pbvh_bmesh_node_lookup(pbvh, v);
/* Check that the vertex's node knows it owns the vert. */
BLI_assert(BLI_gset_haskey(nv->bm_unique_verts, v));
BLI_assert(BLI_gset_haskey(nv->bm_unique_verts_, v));
/* Check that the vertex isn't duplicated as an 'other' vert. */
BLI_assert(!BLI_gset_haskey(nv->bm_other_verts, v));
BLI_assert(!BLI_gset_haskey(nv->bm_other_verts_, v));
}
}
}
@@ -2536,20 +2538,20 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
BMVert *v;
BM_ITER_MESH (v, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
/* Vertex isn't tracked. */
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) == DYNTOPO_NODE_NONE) {
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset_) == DYNTOPO_NODE_NONE) {
continue;
}
PBVHNode *n = pbvh_bmesh_node_lookup(pbvh, v);
Node *n = pbvh_bmesh_node_lookup(pbvh, v);
/* Check that the vert's node is a leaf. */
BLI_assert(n->flag & PBVH_Leaf);
/* Check that the vert's node knows it owns the vert. */
BLI_assert(BLI_gset_haskey(n->bm_unique_verts, v));
BLI_assert(BLI_gset_haskey(n->bm_unique_verts_, v));
/* Check that the vertex isn't duplicated as an 'other' vert. */
BLI_assert(!BLI_gset_haskey(n->bm_other_verts, v));
BLI_assert(!BLI_gset_haskey(n->bm_other_verts_, v));
/* Check that the vert's node also contains one of the vert's adjacent faces. */
bool found = false;
@@ -2567,9 +2569,9 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
/* total freak stuff, check if node exists somewhere else */
/* Slow */
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *n_other = &pbvh->nodes[i];
if ((n != n_other) && (n_other->bm_unique_verts)) {
BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts, v));
Node *n_other = &pbvh->nodes_[i];
if ((n != n_other) && (n_other->bm_unique_verts_)) {
BLI_assert(!BLI_gset_haskey(n_other->bm_unique_verts_, v));
}
}
# endif
@@ -2582,8 +2584,8 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
BM_ITER_MESH (vi, &iter, pbvh->header.bm, BM_VERTS_OF_MESH) {
bool has_unique = false;
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *n = &pbvh->nodes[i];
if ((n->bm_unique_verts != nullptr) && BLI_gset_haskey(n->bm_unique_verts, vi)) {
Node *n = &pbvh->nodes_[i];
if ((n->bm_unique_verts_ != nullptr) && BLI_gset_haskey(n->bm_unique_verts_, vi)) {
has_unique = true;
}
}
@@ -2597,25 +2599,25 @@ static void pbvh_bmesh_verify(PBVH *pbvh)
/* Check that node elements are recorded in the top level */
for (int i = 0; i < pbvh->totnode; i++) {
PBVHNode *n = &pbvh->nodes[i];
Node *n = &pbvh->nodes_[i];
if (n->flag & PBVH_Leaf) {
GSetIterator gs_iter;
for (BMFace *f : n->bm_faces) {
PBVHNode *n_other = pbvh_bmesh_node_lookup(pbvh, f);
for (BMFace *f : n->bm_faces_) {
Node *n_other = pbvh_bmesh_node_lookup(pbvh, f);
BLI_assert(n == n_other);
BLI_assert(BLI_gset_haskey(faces_all, f));
}
GSET_ITER (gs_iter, n->bm_unique_verts) {
GSET_ITER (gs_iter, n->bm_unique_verts_) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
PBVHNode *n_other = pbvh_bmesh_node_lookup(pbvh, v);
BLI_assert(!BLI_gset_haskey(n->bm_other_verts, v));
Node *n_other = pbvh_bmesh_node_lookup(pbvh, v);
BLI_assert(!BLI_gset_haskey(n->bm_other_verts_, v));
BLI_assert(n == n_other);
BLI_assert(BLI_gset_haskey(verts_all, v));
}
GSET_ITER (gs_iter, n->bm_other_verts) {
GSET_ITER (gs_iter, n->bm_other_verts_) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
/* this happens sometimes and seems harmless */
// BLI_assert(!BM_vert_face_check(v));

View File

@@ -4,166 +4,12 @@
#pragma once
#include "BLI_array.hh"
#include "BLI_bounds_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_set.hh"
#include "BLI_span.hh"
#include "BLI_vector.hh"
#include "BKE_pbvh.hh"
/** \file
* \ingroup bke
*/
namespace blender::draw::pbvh {
struct PBVHBatches;
}
struct BMVert;
struct BMFace;
/* NOTE: this structure is getting large, might want to split it into
* union'd structs */
struct PBVHNode {
/* Opaque handle for drawing code */
blender::draw::pbvh::PBVHBatches *draw_batches = nullptr;
/** Axis aligned min and max of all vertex positions in the node. */
blender::Bounds<blender::float3> bounds = {};
/** Bounds from the start of current brush stroke. */
blender::Bounds<blender::float3> bounds_orig = {};
/* For internal nodes, the offset of the children in the PBVH
* 'nodes' array. */
int children_offset = 0;
/* List of primitives for this node. Semantics depends on
* PBVH type:
*
* - PBVH_FACES: Indices into the #PBVH::corner_tris array.
* - PBVH_GRIDS: Multires grid indices.
* - PBVH_BMESH: Unused. See PBVHNode.bm_faces.
*
* NOTE: This is a pointer inside of PBVH.prim_indices; it
* is not allocated separately per node.
*/
blender::Span<int> prim_indices;
/* Array of indices into the mesh's vertex array. Contains the
* indices of all vertices used by faces that are within this
* node's bounding box.
*
* Note that a vertex might be used by a multiple faces, and
* these faces might be in different leaf nodes. Such a vertex
* will appear in the vert_indices array of each of those leaf
* nodes.
*
* In order to support cases where you want access to multiple
* nodes' vertices without duplication, the vert_indices array
* is ordered such that the first part of the array, up to
* index 'uniq_verts', contains "unique" vertex indices. These
* vertices might not be truly unique to this node, but if
* they appear in another node's vert_indices array, they will
* be above that node's 'uniq_verts' value.
*
* Used for leaf nodes in a mesh-based PBVH (not multires.)
*/
blender::Array<int, 0> vert_indices;
/** The number of vertices in #vert_indices not shared with (owned by) another node. */
int uniq_verts = 0;
/* Array of indices into the Mesh's corner array.
* PBVH_FACES only.
*/
blender::Array<int, 0> corner_indices;
/* An array mapping face corners into the vert_indices
* array. The array is sized to match 'totprim', and each of
* the face's corners gets an index into the vert_indices
* array, in the same order as the corners in the original
* triangle.
*
* Used for leaf nodes in a mesh-based PBVH (not multires.)
*/
blender::Array<blender::int3, 0> face_vert_indices;
/* Indicates whether this node is a leaf or not; also used for
* marking various updates that need to be applied. */
PBVHNodeFlags flag = PBVHNodeFlags(0);
/* Used for ray-casting: how close the bounding-box is to the ray point. */
float tmin = 0.0f;
/* Dyntopo */
/* Set of pointers to the BMFaces used by this node.
* NOTE: PBVH_BMESH only. Faces are always triangles
* (dynamic topology forcibly triangulates the mesh).
*/
blender::Set<BMFace *, 0> bm_faces;
blender::Set<BMVert *, 0> bm_unique_verts;
blender::Set<BMVert *, 0> bm_other_verts;
/* Deprecated. Stores original coordinates of triangles. */
float (*bm_orco)[3] = nullptr;
int (*bm_ortri)[3] = nullptr;
BMVert **bm_orvert = nullptr;
int bm_tot_ortri = 0;
/* Used to store the brush color during a stroke and composite it over the original color */
PBVHColorBufferNode color_buffer;
PBVHPixelsNode pixels;
/* Used to flash colors of updated node bounding boxes in
* debug draw mode (when G.debug_value / bpy.app.debug_value is 889).
*/
int debug_draw_gen = 0;
};
struct PBVH {
PBVHPublic header;
blender::Vector<PBVHNode> nodes;
/* Memory backing for PBVHNode.prim_indices. */
blender::Array<int> prim_indices;
/* Mesh data. The evaluated deform mesh for mesh sculpting, and the base mesh for grids. */
Mesh *mesh;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> vert_positions_deformed;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> vert_normals_deformed;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> face_normals_deformed;
blender::MutableSpan<blender::float3> vert_positions;
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> face_normals;
/* Grid Data */
SubdivCCG *subdiv_ccg;
/* flag are verts/faces deformed */
bool deformed;
/* Dynamic topology */
float bm_max_edge_len;
float bm_min_edge_len;
int cd_vert_node_offset;
int cd_face_node_offset;
float planes[6][4];
int num_planes;
BMLog *bm_log;
PBVHPixels pixels;
~PBVH();
};
/* pbvh.cc */
namespace blender::bke::pbvh {
@@ -200,7 +46,7 @@ bool ray_face_nearest_tri(const float ray_start[3],
/* pbvh_bmesh.cc */
bool bmesh_node_raycast(PBVHNode *node,
bool bmesh_node_raycast(blender::bke::pbvh::Node *node,
const float ray_start[3],
const float ray_normal[3],
IsectRayPrecalc *isect_precalc,
@@ -208,19 +54,19 @@ bool bmesh_node_raycast(PBVHNode *node,
bool use_original,
PBVHVertRef *r_active_vertex,
float *r_face_normal);
bool bmesh_node_nearest_to_ray(PBVHNode *node,
bool bmesh_node_nearest_to_ray(blender::bke::pbvh::Node *node,
const float ray_start[3],
const float ray_normal[3],
float *depth,
float *dist_sq,
bool use_original);
void bmesh_normals_update(Span<PBVHNode *> nodes);
void bmesh_normals_update(Span<blender::bke::pbvh::Node *> nodes);
/* pbvh_pixels.hh */
void node_pixels_free(PBVHNode *node);
void pixels_free(PBVH *pbvh);
void free_draw_buffers(PBVH &pbvh, PBVHNode *node);
void node_pixels_free(blender::bke::pbvh::Node *node);
void pixels_free(blender::bke::pbvh::Tree *pbvh);
void free_draw_buffers(blender::bke::pbvh::Tree &pbvh, blender::bke::pbvh::Node *node);
} // namespace blender::bke::pbvh

View File

@@ -62,9 +62,9 @@ static float2 calc_barycentric_delta_x(const ImBuf *image_buffer,
return calc_barycentric_delta(uvs, start_uv, end_uv);
}
static int count_node_pixels(PBVHNode &node)
static int count_node_pixels(Node &node)
{
if (!node.pixels.node_data) {
if (!node.pixels_.node_data) {
return 0;
}
@@ -85,7 +85,7 @@ struct SplitQueueData {
ThreadQueue *new_nodes;
TaskPool *pool;
PBVH *pbvh;
Tree *pbvh;
Mesh *mesh;
Image *image;
ImageUser *image_user;
@@ -93,7 +93,7 @@ struct SplitQueueData {
struct SplitNodePair {
SplitNodePair *parent;
PBVHNode node;
Node node;
int children_offset = 0;
int depth = 0;
int source_index = -1;
@@ -102,18 +102,18 @@ struct SplitNodePair {
SplitNodePair(SplitNodePair *node_parent = nullptr) : parent(node_parent)
{
memset(static_cast<void *>(&node), 0, sizeof(PBVHNode));
memset(static_cast<void *>(&node), 0, sizeof(Node));
}
};
static void split_thread_job(TaskPool *__restrict pool, void *taskdata);
static void split_pixel_node(
PBVH &pbvh, SplitNodePair *split, Image *image, ImageUser *image_user, SplitQueueData *tdata)
Tree &pbvh, SplitNodePair *split, Image *image, ImageUser *image_user, SplitQueueData *tdata)
{
PBVHNode *node = &split->node;
Node *node = &split->node;
const Bounds<float3> cb = node->bounds;
const Bounds<float3> cb = node->bounds_;
if (count_node_pixels(*node) <= pixel_leaf_limit || split->depth >= depth_limit) {
node_data_get(split->node).rebuild_undo_regions();
@@ -124,7 +124,7 @@ static void split_pixel_node(
const int axis = math::dominant_axis(cb.max - cb.min);
const float mid = (cb.max[axis] + cb.min[axis]) * 0.5f;
node->flag = (PBVHNodeFlags)(int(node->flag) & int(~PBVH_TexLeaf));
node->flag_ = (PBVHNodeFlags)(int(node->flag_) & int(~PBVH_TexLeaf));
SplitNodePair *split1 = MEM_new<SplitNodePair>("split_pixel_node split1", split);
SplitNodePair *split2 = MEM_new<SplitNodePair>("split_pixel_node split1", split);
@@ -132,24 +132,24 @@ static void split_pixel_node(
split1->depth = split->depth + 1;
split2->depth = split->depth + 1;
PBVHNode *child1 = &split1->node;
PBVHNode *child2 = &split2->node;
Node *child1 = &split1->node;
Node *child2 = &split2->node;
child1->flag = PBVH_TexLeaf;
child2->flag = PBVH_TexLeaf;
child1->flag_ = PBVH_TexLeaf;
child2->flag_ = PBVH_TexLeaf;
child1->bounds = cb;
child1->bounds.max[axis] = mid;
child1->bounds_ = cb;
child1->bounds_.max[axis] = mid;
child2->bounds = cb;
child2->bounds.min[axis] = mid;
child2->bounds_ = cb;
child2->bounds_.min[axis] = mid;
NodeData &data = node_data_get(split->node);
NodeData *data1 = MEM_new<NodeData>(__func__);
NodeData *data2 = MEM_new<NodeData>(__func__);
child1->pixels.node_data = static_cast<void *>(data1);
child2->pixels.node_data = static_cast<void *>(data2);
child1->pixels_.node_data = static_cast<void *>(data1);
child2->pixels_.node_data = static_cast<void *>(data2);
data1->uv_primitives = data.uv_primitives;
data2->uv_primitives = data.uv_primitives;
@@ -251,7 +251,7 @@ static void split_pixel_node(
data.undo_regions.clear();
if (node->flag & PBVH_Leaf) {
if (node->flag_ & PBVH_Leaf) {
data.clear_data();
}
else {
@@ -267,7 +267,7 @@ static void split_pixel_node(
static void split_flush_final_nodes(SplitQueueData *tdata)
{
PBVH *pbvh = tdata->pbvh;
Tree *pbvh = tdata->pbvh;
Vector<SplitNodePair *> splits;
while (!BLI_thread_queue_is_empty(tdata->new_nodes)) {
@@ -280,9 +280,9 @@ static void split_flush_final_nodes(SplitQueueData *tdata)
}
if (!newsplit->parent->children_offset) {
newsplit->parent->children_offset = pbvh->nodes.size();
newsplit->parent->children_offset = pbvh->nodes_.size();
pbvh->nodes.resize(pbvh->nodes.size() + 2);
pbvh->nodes_.resize(pbvh->nodes_.size() + 2);
newsplit->source_index = newsplit->parent->children_offset;
}
else {
@@ -293,8 +293,8 @@ static void split_flush_final_nodes(SplitQueueData *tdata)
for (SplitNodePair *split : splits) {
BLI_assert(split->source_index != -1);
split->node.children_offset = split->children_offset;
pbvh->nodes[split->source_index] = split->node;
split->node.children_offset_ = split->children_offset;
pbvh->nodes_[split->source_index] = split->node;
}
for (SplitNodePair *split : splits) {
@@ -311,7 +311,7 @@ static void split_thread_job(TaskPool *__restrict pool, void *taskdata)
split_pixel_node(*tdata->pbvh, split, tdata->image, tdata->image_user, tdata);
}
static void split_pixel_nodes(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
static void split_pixel_nodes(Tree &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
{
if (G.debug_value == 891) {
return;
@@ -329,13 +329,13 @@ static void split_pixel_nodes(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *i
tdata.new_nodes = BLI_thread_queue_init();
/* Set up initial jobs before initializing threads. */
for (const int i : pbvh.nodes.index_range()) {
if (pbvh.nodes[i].flag & PBVH_TexLeaf) {
for (const int i : pbvh.nodes_.index_range()) {
if (pbvh.nodes_[i].flag_ & PBVH_TexLeaf) {
SplitNodePair *split = MEM_new<SplitNodePair>("split_pixel_nodes split");
split->source_index = i;
split->is_old = true;
split->node = pbvh.nodes[i];
split->node = pbvh.nodes_[i];
split->tdata = &tdata;
BLI_task_pool_push(pool, split_thread_job, static_cast<void *>(split), false, nullptr);
@@ -354,7 +354,7 @@ static void split_pixel_nodes(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *i
/**
* During debugging this check could be enabled.
* It will write to each image pixel that is covered by the PBVH.
* It will write to each image pixel that is covered by the Tree.
*/
constexpr bool USE_WATERTIGHT_CHECK = false;
@@ -403,7 +403,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)
static void update_geom_primitives(Tree &pbvh, const uv_islands::MeshData &mesh_data)
{
PBVHData &pbvh_data = data_get(pbvh);
pbvh_data.clear_data();
@@ -449,8 +449,8 @@ struct EncodePixelsUserData {
const uv_islands::MeshData *mesh_data;
Image *image;
ImageUser *image_user;
PBVH *pbvh;
Vector<PBVHNode *> *nodes;
Tree *pbvh;
Vector<Node *> *nodes;
const uv_islands::UVIslandsMask *uv_masks;
/** Lookup to retrieve the UV primitives based on the primitive index. */
const UVPrimitiveLookup *uv_primitive_lookup;
@@ -461,8 +461,8 @@ static void do_encode_pixels(EncodePixelsUserData *data, const int n)
const uv_islands::MeshData &mesh_data = *data->mesh_data;
Image *image = data->image;
ImageUser image_user = *data->image_user;
PBVHNode *node = (*data->nodes)[n];
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
Node *node = (*data->nodes)[n];
NodeData *node_data = static_cast<NodeData *>(node->pixels_.node_data);
const uv_islands::UVIslandsMask &uv_masks = *data->uv_masks;
LISTBASE_FOREACH (ImageTile *, tile, &data->image->tiles) {
@@ -477,7 +477,7 @@ static void do_encode_pixels(EncodePixelsUserData *data, const int n)
tile_data.tile_number = image_tile.get_tile_number();
float2 tile_offset = float2(image_tile.get_tile_offset());
for (const int geom_prim_index : node->prim_indices) {
for (const int geom_prim_index : node->prim_indices_) {
for (const UVPrimitiveLookup::Entry &entry :
data->uv_primitive_lookup->lookup[geom_prim_index])
{
@@ -529,28 +529,28 @@ static void do_encode_pixels(EncodePixelsUserData *data, const int n)
}
}
static bool should_pixels_be_updated(const PBVHNode &node)
static bool should_pixels_be_updated(const Node &node)
{
if ((node.flag & (PBVH_Leaf | PBVH_TexLeaf)) == 0) {
if ((node.flag_ & (PBVH_Leaf | PBVH_TexLeaf)) == 0) {
return false;
}
if (node.children_offset != 0) {
if (node.children_offset_ != 0) {
return false;
}
if ((node.flag & PBVH_RebuildPixels) != 0) {
if ((node.flag_ & PBVH_RebuildPixels) != 0) {
return true;
}
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
if (node_data != nullptr) {
return false;
}
return true;
}
static int64_t count_nodes_to_update(PBVH &pbvh)
static int64_t count_nodes_to_update(Tree &pbvh)
{
int64_t result = 0;
for (PBVHNode &node : pbvh.nodes) {
for (Node &node : pbvh.nodes_) {
if (should_pixels_be_updated(node)) {
result++;
}
@@ -567,38 +567,38 @@ static int64_t count_nodes_to_update(PBVH &pbvh)
*
* returns if there were any nodes found (true).
*/
static bool find_nodes_to_update(PBVH &pbvh, Vector<PBVHNode *> &r_nodes_to_update)
static bool find_nodes_to_update(Tree &pbvh, Vector<Node *> &r_nodes_to_update)
{
int64_t nodes_to_update_len = count_nodes_to_update(pbvh);
if (nodes_to_update_len == 0) {
return false;
}
/* Init or reset PBVH pixel data when changes detected. */
if (pbvh.pixels.data == nullptr) {
/* Init or reset Tree pixel data when changes detected. */
if (pbvh.pixels_.data == nullptr) {
PBVHData *pbvh_data = MEM_new<PBVHData>(__func__);
pbvh.pixels.data = pbvh_data;
pbvh.pixels_.data = pbvh_data;
}
else {
PBVHData *pbvh_data = static_cast<PBVHData *>(pbvh.pixels.data);
PBVHData *pbvh_data = static_cast<PBVHData *>(pbvh.pixels_.data);
pbvh_data->clear_data();
}
r_nodes_to_update.reserve(nodes_to_update_len);
for (PBVHNode &node : pbvh.nodes) {
for (Node &node : pbvh.nodes_) {
if (!should_pixels_be_updated(node)) {
continue;
}
r_nodes_to_update.append(&node);
node.flag = static_cast<PBVHNodeFlags>(node.flag | PBVH_RebuildPixels);
node.flag_ = static_cast<PBVHNodeFlags>(node.flag_ | PBVH_RebuildPixels);
if (node.pixels.node_data == nullptr) {
if (node.pixels_.node_data == nullptr) {
NodeData *node_data = MEM_new<NodeData>(__func__);
node.pixels.node_data = node_data;
node.pixels_.node_data = node_data;
}
else {
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
node_data->clear_data();
}
}
@@ -606,7 +606,7 @@ static bool find_nodes_to_update(PBVH &pbvh, Vector<PBVHNode *> &r_nodes_to_upda
return true;
}
static void apply_watertight_check(PBVH &pbvh, Image *image, ImageUser *image_user)
static void apply_watertight_check(Tree &pbvh, Image *image, ImageUser *image_user)
{
ImageUser watertight = *image_user;
LISTBASE_FOREACH (ImageTile *, tile_data, &image->tiles) {
@@ -616,11 +616,11 @@ static void apply_watertight_check(PBVH &pbvh, Image *image, ImageUser *image_us
if (image_buffer == nullptr) {
continue;
}
for (PBVHNode &node : pbvh.nodes) {
if ((node.flag & PBVH_Leaf) == 0) {
for (Node &node : pbvh.nodes_) {
if ((node.flag_ & PBVH_Leaf) == 0) {
continue;
}
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
UDIMTilePixels *tile_node_data = node_data->find_tile_data(image_tile);
if (tile_node_data == nullptr) {
continue;
@@ -646,9 +646,9 @@ static void apply_watertight_check(PBVH &pbvh, Image *image, ImageUser *image_us
BKE_image_partial_update_mark_full_update(image);
}
static bool update_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
static bool update_pixels(Tree &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
{
Vector<PBVHNode *> nodes_to_update;
Vector<Node *> nodes_to_update;
if (!find_nodes_to_update(pbvh, nodes_to_update)) {
return false;
@@ -664,7 +664,7 @@ static bool update_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image
const VArraySpan uv_map = *attributes.lookup<float2>(active_uv_name, AttrDomain::Corner);
uv_islands::MeshData mesh_data(
mesh->corner_tris(), mesh->corner_verts(), uv_map, pbvh.vert_positions);
mesh->corner_tris(), mesh->corner_verts(), uv_map, pbvh.vert_positions_);
uv_islands::UVIslands islands(mesh_data);
uv_islands::UVIslandsMask uv_masks;
@@ -711,20 +711,20 @@ static bool update_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image
copy_update(pbvh, *image, *image_user, mesh_data);
/* Rebuild the undo regions. */
for (PBVHNode *node : nodes_to_update) {
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
for (Node *node : nodes_to_update) {
NodeData *node_data = static_cast<NodeData *>(node->pixels_.node_data);
node_data->rebuild_undo_regions();
}
/* Clear the UpdatePixels flag. */
for (PBVHNode *node : nodes_to_update) {
node->flag = static_cast<PBVHNodeFlags>(node->flag & ~PBVH_RebuildPixels);
for (Node *node : nodes_to_update) {
node->flag_ = static_cast<PBVHNodeFlags>(node->flag_ & ~PBVH_RebuildPixels);
}
/* Add PBVH_TexLeaf flag */
for (PBVHNode &node : pbvh.nodes) {
if (node.flag & PBVH_Leaf) {
node.flag = (PBVHNodeFlags)(int(node.flag) | int(PBVH_TexLeaf));
for (Node &node : pbvh.nodes_) {
if (node.flag_ & PBVH_Leaf) {
node.flag_ = (PBVHNodeFlags)(int(node.flag_) | int(PBVH_TexLeaf));
}
}
@@ -735,7 +735,7 @@ static bool update_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image
int64_t compressed_data_len = 0;
int64_t num_pixels = 0;
for (int n = 0; n < pbvh->totnode; n++) {
PBVHNode *node = &pbvh->nodes[n];
Node *node = &pbvh->nodes[n];
if ((node->flag & PBVH_Leaf) == 0) {
continue;
}
@@ -757,24 +757,24 @@ static bool update_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image
return true;
}
NodeData &node_data_get(PBVHNode &node)
NodeData &node_data_get(Node &node)
{
BLI_assert(node.pixels.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
BLI_assert(node.pixels_.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
return *node_data;
}
PBVHData &data_get(PBVH &pbvh)
PBVHData &data_get(Tree &pbvh)
{
BLI_assert(pbvh.pixels.data != nullptr);
PBVHData *data = static_cast<PBVHData *>(pbvh.pixels.data);
BLI_assert(pbvh.pixels_.data != nullptr);
PBVHData *data = static_cast<PBVHData *>(pbvh.pixels_.data);
return *data;
}
void mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user)
void mark_image_dirty(Node &node, Image &image, ImageUser &image_user)
{
BLI_assert(node.pixels.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
BLI_assert(node.pixels_.node_data != nullptr);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
if (node_data->flags.dirty) {
ImageUser local_image_user = image_user;
LISTBASE_FOREACH (ImageTile *, tile, &image.tiles) {
@@ -792,9 +792,9 @@ void mark_image_dirty(PBVHNode &node, Image &image, ImageUser &image_user)
}
}
void collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tiles)
void collect_dirty_tiles(Node &node, Vector<image::TileNumber> &r_dirty_tiles)
{
NodeData *node_data = static_cast<NodeData *>(node.pixels.node_data);
NodeData *node_data = static_cast<NodeData *>(node.pixels_.node_data);
node_data->collect_dirty_tiles(r_dirty_tiles);
}
@@ -802,7 +802,7 @@ void collect_dirty_tiles(PBVHNode &node, Vector<image::TileNumber> &r_dirty_tile
namespace blender::bke::pbvh {
void build_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
void build_pixels(Tree &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
{
if (pixels::update_pixels(pbvh, mesh, image, image_user) &&
pixels::PBVH_PIXELS_SPLIT_NODES_ENABLED)
@@ -811,23 +811,23 @@ void build_pixels(PBVH &pbvh, Mesh *mesh, Image *image, ImageUser *image_user)
}
}
void node_pixels_free(PBVHNode *node)
void node_pixels_free(Node *node)
{
pixels::NodeData *node_data = static_cast<pixels::NodeData *>(node->pixels.node_data);
pixels::NodeData *node_data = static_cast<pixels::NodeData *>(node->pixels_.node_data);
if (!node_data) {
return;
}
MEM_delete(node_data);
node->pixels.node_data = nullptr;
node->pixels_.node_data = nullptr;
}
void pixels_free(PBVH *pbvh)
void pixels_free(Tree *pbvh)
{
pixels::PBVHData *pbvh_data = static_cast<pixels::PBVHData *>(pbvh->pixels.data);
pixels::PBVHData *pbvh_data = static_cast<pixels::PBVHData *>(pbvh->pixels_.data);
MEM_delete(pbvh_data);
pbvh->pixels.data = nullptr;
pbvh->pixels_.data = nullptr;
}
} // namespace blender::bke::pbvh

View File

@@ -169,13 +169,13 @@ class NonManifoldUVEdges : public Vector<Edge<CoordSpace::UV>> {
class PixelNodesTileData : public Vector<std::reference_wrapper<UDIMTilePixels>> {
public:
PixelNodesTileData(PBVH &pbvh, const image::ImageTileWrapper &image_tile)
PixelNodesTileData(blender::bke::pbvh::Tree &pbvh, const image::ImageTileWrapper &image_tile)
{
reserve(count_nodes(pbvh, image_tile));
for (PBVHNode &node : pbvh.nodes) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (should_add_node(node, image_tile)) {
NodeData &node_data = *static_cast<NodeData *>(node.pixels.node_data);
NodeData &node_data = *static_cast<NodeData *>(node.pixels_.node_data);
UDIMTilePixels &tile_pixels = *node_data.find_tile_data(image_tile);
append(tile_pixels);
}
@@ -183,25 +183,27 @@ class PixelNodesTileData : public Vector<std::reference_wrapper<UDIMTilePixels>>
}
private:
static bool should_add_node(PBVHNode &node, const image::ImageTileWrapper &image_tile)
static bool should_add_node(blender::bke::pbvh::Node &node,
const image::ImageTileWrapper &image_tile)
{
if ((node.flag & PBVH_Leaf) == 0) {
if ((node.flag_ & PBVH_Leaf) == 0) {
return false;
}
if (node.pixels.node_data == nullptr) {
if (node.pixels_.node_data == nullptr) {
return false;
}
NodeData &node_data = *static_cast<NodeData *>(node.pixels.node_data);
NodeData &node_data = *static_cast<NodeData *>(node.pixels_.node_data);
if (node_data.find_tile_data(image_tile) == nullptr) {
return false;
}
return true;
}
static int64_t count_nodes(PBVH &pbvh, const image::ImageTileWrapper &image_tile)
static int64_t count_nodes(blender::bke::pbvh::Tree &pbvh,
const image::ImageTileWrapper &image_tile)
{
int64_t result = 0;
for (PBVHNode &node : pbvh.nodes) {
for (blender::bke::pbvh::Node &node : pbvh.nodes_) {
if (should_add_node(node, image_tile)) {
result++;
}
@@ -499,7 +501,7 @@ struct Rows {
}
};
void copy_update(PBVH &pbvh,
void copy_update(blender::bke::pbvh::Tree &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data)
@@ -544,7 +546,10 @@ void copy_update(PBVH &pbvh,
}
}
void copy_pixels(PBVH &pbvh, Image &image, ImageUser &image_user, image::TileNumber tile_number)
void copy_pixels(blender::bke::pbvh::Tree &pbvh,
Image &image,
ImageUser &image_user,
image::TileNumber tile_number)
{
PBVHData &pbvh_data = data_get(pbvh);
std::optional<std::reference_wrapper<CopyPixelTile>> pixel_tile =

View File

@@ -16,7 +16,7 @@
namespace blender::bke::pbvh::pixels {
void copy_update(PBVH &pbvh,
void copy_update(Tree &pbvh,
Image &image,
ImageUser &image_user,
const uv_islands::MeshData &mesh_data);

View File

@@ -5,11 +5,11 @@
/** \file
* \ingroup bke
*
* UV Islands for PBVH Pixel extraction. When primitives share an edge they belong to the same UV
* Island.
* UV Islands for pbvh::Tree Pixel extraction. When primitives share an edge they belong to the
* same UV Island.
*
* \note Similar to `uvedit_islands.cc`, but optimized for PBVH painting without using BMesh for
* performance reasons. Non-manifold meshes only (i.e. edges must have less than 3 faces).
* \note Similar to `uvedit_islands.cc`, but optimized for pbvh::Tree painting without using BMesh
* for performance reasons. Non-manifold meshes only (i.e. edges must have less than 3 faces).
*
* Polygons (face with more than 3 edges) are supported as they are split up to primitives.
*

View File

@@ -47,7 +47,7 @@
#define MAX_TREETYPE 32
/* Setting zero so we can catch bugs in BLI_task/KDOPBVH.
* TODO(sergey): Deduplicate the limits with PBVH from BKE.
* TODO(sergey): Deduplicate the limits with blender::bke::pbvh::Tree from BKE.
*/
#ifndef NDEBUG
# define KDOPBVH_THREAD_LEAF_THRESHOLD 0

View File

@@ -20,11 +20,11 @@
#include "DNA_customdata_types.h"
#include "BKE_ccg.hh"
#include "BKE_pbvh.hh"
namespace blender::gpu {
class Batch;
}
struct PBVHNode;
struct Mesh;
struct CustomData;
struct SubdivCCG;
@@ -32,7 +32,10 @@ struct BMesh;
struct BMFace;
namespace blender::bke {
enum class AttrDomain : int8_t;
namespace pbvh {
class Node;
}
} // namespace blender::bke
namespace blender::draw::pbvh {
@@ -60,7 +63,7 @@ using AttributeRequest = std::variant<CustomRequest, GenericRequest>;
struct PBVHBatches;
struct PBVH_GPU_Args {
int pbvh_type;
bke::pbvh::Type pbvh_type;
BMesh *bm;
const Mesh *mesh;

View File

@@ -243,7 +243,7 @@ bool SyncModule::sync_sculpt(Object *ob,
inst_.volume.object_sync(ob_handle);
}
/* Use a valid bounding box. The PBVH module already does its own culling, but a valid */
/* Use a valid bounding box. The pbvh::Tree module already does its own culling, but a valid */
/* bounding box is still needed for directional shadow tile-map bounds computation. */
const Bounds<float3> bounds = bke::pbvh::bounds_get(*ob_ref.object->sculpt->pbvh);
const float3 center = math::midpoint(bounds.min, bounds.max);

View File

@@ -37,18 +37,18 @@ void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
blender::gpu::Batch *sculpt_overlays;
PBVH *pbvh = ob->sculpt->pbvh.get();
blender::bke::pbvh::Tree *pbvh = ob->sculpt->pbvh.get();
const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d);
if (!pbvh) {
/* It is possible to have SculptSession without PBVH. This happens, for example, when toggling
* object mode to sculpt then to edit mode. */
/* It is possible to have SculptSession without pbvh::Tree. This happens, for example, when
* toggling object mode to sculpt then to edit mode. */
return;
}
if (!pbvh_has_mask(*pbvh) && !pbvh_has_face_sets(*pbvh)) {
/* The SculptSession and the PBVH can be created without a Mask data-layer or Face Set
/* The SculptSession and the pbvh::Tree can be created without a Mask data-layer or Face Set
* data-layer. (masks data-layers are created after using a mask tool), so in these cases there
* is nothing to draw. */
return;

View File

@@ -244,7 +244,8 @@ ObjectState::ObjectState(const SceneState &scene_state,
}
if (sculpt_pbvh) {
if (color_type == V3D_SHADING_TEXTURE_COLOR && BKE_pbvh_type(*ob->sculpt->pbvh) != PBVH_FACES)
if (color_type == V3D_SHADING_TEXTURE_COLOR &&
ob->sculpt->pbvh->type() != bke::pbvh::Type::Mesh)
{
/* Force use of material color for sculpt. */
color_type = V3D_SHADING_MATERIAL_COLOR;

View File

@@ -950,7 +950,10 @@ void DRW_mesh_batch_cache_get_attributes(Object *object,
blender::draw::DRW_Attributes **r_attrs,
blender::draw::DRW_MeshCDMask **r_cd_needed);
void DRW_sculpt_debug_cb(
PBVHNode *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag);
void DRW_sculpt_debug_cb(blender::bke::pbvh::Node *node,
void *user_data,
const float bmin[3],
const float bmax[3],
PBVHNodeFlags flag);
bool DRW_is_viewport_compositor_enabled();

View File

@@ -556,7 +556,7 @@ static bool mesh_batch_cache_valid(Object &object, Mesh &mesh)
return false;
}
/* NOTE: PBVH draw data should not be checked here. */
/* NOTE: bke::pbvh::Tree draw data should not be checked here. */
if (cache->is_editmode != (mesh.runtime->edit_mesh != nullptr)) {
return false;
@@ -1490,7 +1490,7 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph &task_graph,
return;
}
/* TODO(pablodp606): This always updates the sculpt normals for regular drawing (non-PBVH).
/* TODO(pablodp606): This always updates the sculpt normals for regular drawing (non-pbvh::Tree).
* This makes tools that sample the surface per step get wrong normals until a redraw happens.
* Normal updates should be part of the brush loop and only run during the stroke when the
* brush needs to sample the surface. The drawing code should only update the normals

View File

@@ -1284,8 +1284,11 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd,
}
}
void DRW_sculpt_debug_cb(
PBVHNode *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag)
void DRW_sculpt_debug_cb(blender::bke::pbvh::Node *node,
void *user_data,
const float bmin[3],
const float bmax[3],
PBVHNodeFlags flag)
{
int *debug_node_nr = (int *)user_data;
BoundBox bb;
@@ -1327,8 +1330,8 @@ static void drw_sculpt_get_frustum_planes(const Object *ob, float planes[6][4])
static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
{
using namespace blender;
/* PBVH should always exist for non-empty meshes, created by depsgraph eval. */
PBVH *pbvh = (scd->ob->sculpt) ? scd->ob->sculpt->pbvh.get() : nullptr;
/* pbvh::Tree should always exist for non-empty meshes, created by depsgraph eval. */
bke::pbvh::Tree *pbvh = (scd->ob->sculpt) ? scd->ob->sculpt->pbvh.get() : nullptr;
if (!pbvh) {
return;
}
@@ -1342,7 +1345,7 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
paint = BKE_paint_get_active_from_context(drwctx->evil_C);
}
/* Frustum planes to show only visible PBVH nodes. */
/* Frustum planes to show only visible pbvh::Tree nodes. */
float update_planes[6][4];
float draw_planes[6][4];
PBVHFrustumPlanes update_frustum;
@@ -1399,7 +1402,8 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
DRW_debug_modelmat(scd->ob->object_to_world().ptr());
BKE_pbvh_draw_debug_cb(
*pbvh,
(void (*)(PBVHNode *n, void *d, const float min[3], const float max[3], PBVHNodeFlags f))
(void (*)(
bke::pbvh::Node *n, void *d, const float min[3], const float max[3], PBVHNodeFlags f))
DRW_sculpt_debug_cb,
&debug_node_nr);
}

View File

@@ -5,8 +5,8 @@
/** \file
* \ingroup gpu
*
* PBVH drawing.
* Embeds GPU meshes inside of PBVH nodes, used by mesh sculpt mode.
* bke::pbvh::Tree drawing.
* Embeds GPU meshes inside of bke::pbvh::Tree nodes, used by mesh sculpt mode.
*/
#include <algorithm>
@@ -65,7 +65,7 @@ static bool pbvh_attr_supported(const AttributeRequest &request)
}
const GenericRequest &attr = std::get<GenericRequest>(request);
if (!ELEM(attr.domain, bke::AttrDomain::Point, bke::AttrDomain::Face, bke::AttrDomain::Corner)) {
/* PBVH drawing does not support edge domain attributes. */
/* blender::bke::pbvh::Tree drawing does not support edge domain attributes. */
return false;
}
bool type_supported = false;
@@ -337,7 +337,7 @@ struct PBVHBatches {
Map<std::string, PBVHBatch> batches;
gpu::IndexBuf *tri_index = nullptr;
gpu::IndexBuf *lines_index = nullptr;
int faces_count = 0; /* Used by PBVH_BMESH and PBVH_GRIDS */
int faces_count = 0; /* Used by bke::pbvh::Type::BMesh and bke::pbvh::Type::Grids */
bool use_flat_layout = false;
int material_index = 0;
@@ -380,15 +380,15 @@ static int count_visible_tris_bmesh(const Set<BMFace *, 0> &faces)
static int count_faces(const PBVH_GPU_Args &args)
{
switch (args.pbvh_type) {
case PBVH_FACES:
case bke::pbvh::Type::Mesh:
return count_visible_tris_mesh(args.prim_indices, args.tri_faces, args.hide_poly);
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
return bke::pbvh::count_grid_quads(args.subdiv_ccg->grid_hidden,
args.grid_indices,
args.ccg_key.grid_size,
args.ccg_key.grid_size);
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return count_visible_tris_bmesh(*args.bm_faces);
}
BLI_assert_unreachable();
@@ -1083,13 +1083,13 @@ void PBVHBatches::update(const PBVH_GPU_Args &args)
}
for (PBVHVbo &vbo : this->vbos) {
switch (args.pbvh_type) {
case PBVH_FACES:
case bke::pbvh::Type::Mesh:
fill_vbo_faces(vbo, args);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
fill_vbo_grids(vbo, args, this->use_flat_layout);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
fill_vbo_bmesh(vbo, args);
break;
}
@@ -1146,13 +1146,13 @@ int PBVHBatches::create_vbo(const AttributeRequest &request, const PBVH_GPU_Args
vbos.append_as(request);
vbos.last().vert_buf = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC);
switch (args.pbvh_type) {
case PBVH_FACES:
case bke::pbvh::Type::Mesh:
fill_vbo_faces(vbos.last(), args);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
fill_vbo_grids(vbos.last(), args, use_flat_layout);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
fill_vbo_bmesh(vbos.last(), args);
break;
}
@@ -1162,7 +1162,7 @@ int PBVHBatches::create_vbo(const AttributeRequest &request, const PBVH_GPU_Args
void PBVHBatches::update_pre(const PBVH_GPU_Args &args)
{
if (args.pbvh_type == PBVH_BMESH) {
if (args.pbvh_type == bke::pbvh::Type::BMesh) {
int count = count_faces(args);
if (faces_count != count) {
@@ -1380,7 +1380,7 @@ static void create_grids_index_flat_layout(const PBVH_GPU_Args &args,
static int material_index_get(const PBVH_GPU_Args &args)
{
switch (args.pbvh_type) {
case PBVH_FACES: {
case bke::pbvh::Type::Mesh: {
if (args.prim_indices.is_empty()) {
return 0;
}
@@ -1389,7 +1389,7 @@ static int material_index_get(const PBVH_GPU_Args &args)
"material_index", bke::AttrDomain::Face, 0);
return material_indices[args.tri_faces[args.prim_indices.first()]];
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (args.grid_indices.is_empty()) {
return 0;
}
@@ -1399,7 +1399,7 @@ static int material_index_get(const PBVH_GPU_Args &args)
return material_indices[BKE_subdiv_ccg_grid_to_face_index(*args.subdiv_ccg,
args.grid_indices.first())];
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return 0;
}
BLI_assert_unreachable();
@@ -1470,7 +1470,7 @@ static void create_index_grids(const PBVH_GPU_Args &args,
void PBVHBatches::create_index(const PBVH_GPU_Args &args)
{
switch (args.pbvh_type) {
case PBVH_FACES:
case bke::pbvh::Type::Mesh:
lines_index = create_index_faces(args.mesh->edges(),
args.corner_verts,
args.corner_edges,
@@ -1479,10 +1479,10 @@ void PBVHBatches::create_index(const PBVH_GPU_Args &args)
args.hide_poly,
args.prim_indices);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
lines_index = create_index_bmesh(args, faces_count);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
create_index_grids(args, false, *this);
if (args.ccg_key.level > coarse_level) {
create_index_grids(args, true, *this);
@@ -1583,7 +1583,7 @@ gpu::Batch *tris_get(PBVHBatches *batches,
const PBVH_GPU_Args &args,
bool do_coarse_grids)
{
do_coarse_grids &= args.pbvh_type == PBVH_GRIDS;
do_coarse_grids &= args.pbvh_type == bke::pbvh::Type::Grids;
PBVHBatch &batch = ensure_batch(*batches, attrs, args, do_coarse_grids);
return batch.tris;
}
@@ -1593,7 +1593,7 @@ gpu::Batch *lines_get(PBVHBatches *batches,
const PBVH_GPU_Args &args,
bool do_coarse_grids)
{
do_coarse_grids &= args.pbvh_type == PBVH_GRIDS;
do_coarse_grids &= args.pbvh_type == bke::pbvh::Type::Grids;
PBVHBatch &batch = ensure_batch(*batches, attrs, args, do_coarse_grids);
return batch.lines;
}

View File

@@ -41,8 +41,8 @@ static Vector<SculptBatch> sculpt_batches_get_ex(const Object *ob,
const bool use_wire,
const Span<pbvh::AttributeRequest> attrs)
{
/* PBVH should always exist for non-empty meshes, created by depsgraph eval. */
PBVH *pbvh = ob->sculpt ? ob->sculpt->pbvh.get() : nullptr;
/* pbvh::Tree should always exist for non-empty meshes, created by depsgraph eval. */
bke::pbvh::Tree *pbvh = ob->sculpt ? ob->sculpt->pbvh.get() : nullptr;
if (!pbvh) {
return {};
}
@@ -57,7 +57,7 @@ static Vector<SculptBatch> sculpt_batches_get_ex(const Object *ob,
paint = BKE_paint_get_active_from_context(drwctx->evil_C);
}
/* Frustum planes to show only visible PBVH nodes. */
/* Frustum planes to show only visible pbvh::Tree nodes. */
float4 draw_planes[6];
PBVHFrustumPlanes draw_frustum = {reinterpret_cast<float(*)[4]>(draw_planes), 6};
float4 update_planes[6];

View File

@@ -51,7 +51,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float3 &direction,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -96,7 +96,7 @@ static void calc_bmesh(const Sculpt &sd,
void do_bmesh_topology_rake_brush(const Sculpt &sd,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
const float input_strength)
{
const SculptSession &ss = *object.sculpt;

View File

@@ -60,7 +60,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -106,7 +106,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float4 &test_plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -151,7 +151,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float4 &test_plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -191,7 +191,7 @@ static void calc_bmesh(const Sculpt &sd,
}
} // namespace clay_cc
void do_clay_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_clay_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -221,10 +221,10 @@ void do_clay_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
const float bstrength = fabsf(ss.cache->bstrength);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -246,7 +246,7 @@ void do_clay_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -254,7 +254,7 @@ void do_clay_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -46,7 +46,7 @@ static void calc_faces(const Sculpt &sd,
const bool flip,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -103,7 +103,7 @@ static void calc_grids(const Sculpt &sd,
const float4 &plane,
const float strength,
const bool flip,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -160,7 +160,7 @@ static void calc_bmesh(const Sculpt &sd,
const float4 &plane,
const float strength,
const bool flip,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -211,7 +211,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace clay_strips_cc
void do_clay_strips_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_clay_strips_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
if (math::is_zero(ss.cache->grab_delta_symmetry)) {
@@ -274,10 +274,10 @@ void do_clay_strips_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nod
const float strength = std::abs(ss.cache->bstrength);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -301,7 +301,7 @@ void do_clay_strips_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nod
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -309,7 +309,7 @@ void do_clay_strips_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nod
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -47,7 +47,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -96,7 +96,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float4 &plane_tilt,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls)
{
@@ -145,7 +145,7 @@ static void calc_bmesh(const Sculpt &sd,
const float4 &plane_tilt,
const float strength,
Object &object,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -189,7 +189,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace clay_thumb_cc
void do_clay_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_clay_thumb_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -254,10 +254,10 @@ void do_clay_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
plane_from_point_normal_v3(plane_tilt, location, normal_tilt);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -279,7 +279,7 @@ void do_clay_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -287,7 +287,7 @@ void do_clay_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -72,7 +72,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -130,7 +130,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -185,7 +185,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -238,7 +238,7 @@ static void do_crease_or_blob_brush(const Scene &scene,
const Sculpt &sd,
const bool invert_strength,
Object &object,
Span<PBVHNode *> nodes)
Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -260,10 +260,10 @@ static void do_crease_or_blob_brush(const Scene &scene,
(invert_strength ? -1.0f : 1.0f);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -285,7 +285,7 @@ static void do_crease_or_blob_brush(const Scene &scene,
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -293,7 +293,7 @@ static void do_crease_or_blob_brush(const Scene &scene,
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -306,12 +306,18 @@ static void do_crease_or_blob_brush(const Scene &scene,
} // namespace crease_cc
void do_crease_brush(const Scene &scene, const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_crease_brush(const Scene &scene,
const Sculpt &sd,
Object &object,
Span<bke::pbvh::Node *> nodes)
{
do_crease_or_blob_brush(scene, sd, false, object, nodes);
}
void do_blob_brush(const Scene &scene, const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_blob_brush(const Scene &scene,
const Sculpt &sd,
Object &object,
Span<bke::pbvh::Node *> nodes)
{
do_crease_or_blob_brush(scene, sd, true, object, nodes);
}

View File

@@ -41,7 +41,7 @@ static void calc_faces(const Sculpt &sd,
const float3 &offset,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -85,7 +85,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -128,7 +128,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -171,16 +171,16 @@ static void calc_bmesh(const Sculpt &sd,
static void offset_positions(const Sculpt &sd,
Object &object,
const float3 &offset,
Span<PBVHNode *> nodes)
Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -201,7 +201,7 @@ static void offset_positions(const Sculpt &sd,
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -209,7 +209,7 @@ static void offset_positions(const Sculpt &sd,
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -220,7 +220,7 @@ static void offset_positions(const Sculpt &sd,
}
}
void do_draw_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_draw_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -234,7 +234,7 @@ void do_draw_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
offset_positions(sd, object, offset, nodes);
}
void do_nudge_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_nudge_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
@@ -245,7 +245,7 @@ void do_nudge_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
offset_positions(sd, object, offset * ss.cache->bstrength, nodes);
}
void do_gravity_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_gravity_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;

View File

@@ -69,7 +69,7 @@ BLI_NOINLINE static void fill_factor_from_hide_and_mask(const Mesh &mesh,
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const bke::AttributeAccessor attributes = mesh.attributes();
if (const VArray mask = *attributes.lookup<float>(".sculpt_mask", bke::AttrDomain::Point)) {
const VArraySpan span(mask);
@@ -116,7 +116,7 @@ static void calc_faces(Object &object,
const float strength,
const int face_set_id,
Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Span<int> face_indices,
MeshLocalData &tls,
const MutableSpan<int> face_sets)
@@ -167,10 +167,10 @@ static void calc_faces(Object &object,
static void do_draw_face_sets_brush_mesh(Object &object,
const Brush &brush,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
Mesh &mesh = *static_cast<Mesh *>(object.data);
@@ -229,7 +229,7 @@ static void calc_grids(Object &object,
const Brush &brush,
const float strength,
const int face_set_id,
const PBVHNode &node,
const bke::pbvh::Node &node,
GridLocalData &tls,
const MutableSpan<int> face_sets)
{
@@ -271,7 +271,7 @@ static void calc_grids(Object &object,
static void do_draw_face_sets_brush_grids(Object &object,
const Brush &brush,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
@@ -281,7 +281,7 @@ static void do_draw_face_sets_brush_grids(Object &object,
threading::EnumerableThreadSpecific<GridLocalData> all_tls;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
GridLocalData &tls = all_tls.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
for (const int i : range) {
undo::push_node(object, node, undo::Type::FaceSet);
@@ -309,7 +309,7 @@ BLI_NOINLINE static void fill_factor_from_hide_and_mask(const BMesh &bm,
{
BLI_assert(faces.size() == r_factors.size());
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const int mask_offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
int i = 0;
for (BMFace *f : faces) {
@@ -367,7 +367,7 @@ static void calc_bmesh(Object &object,
const Brush &brush,
const float strength,
const int face_set_id,
PBVHNode &node,
bke::pbvh::Node &node,
BMeshLocalData &tls,
const int cd_offset)
{
@@ -414,7 +414,7 @@ static void calc_bmesh(Object &object,
static void do_draw_face_sets_brush_bmesh(Object &object,
const Brush &brush,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const int cd_offset = face_set::ensure_face_sets_bmesh(object);
@@ -432,19 +432,19 @@ static void do_draw_face_sets_brush_bmesh(Object &object,
} // namespace draw_face_sets_cc
void do_draw_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_draw_face_sets_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
do_draw_face_sets_brush_mesh(object, brush, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
do_draw_face_sets_brush_grids(object, brush, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
do_draw_face_sets_brush_bmesh(object, brush, nodes);
break;
}

View File

@@ -40,7 +40,7 @@ static void calc_faces(const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -85,7 +85,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -131,7 +131,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -177,16 +177,16 @@ static void calc_bmesh(const Sculpt &sd,
static void offset_positions(const Sculpt &sd,
Object &object,
const float3 &offset,
Span<PBVHNode *> nodes)
Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -198,7 +198,7 @@ static void offset_positions(const Sculpt &sd,
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -206,7 +206,7 @@ static void offset_positions(const Sculpt &sd,
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -217,7 +217,7 @@ static void offset_positions(const Sculpt &sd,
}
}
void do_draw_sharp_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_draw_sharp_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);

View File

@@ -82,7 +82,7 @@ static void calc_faces(const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
MutableSpan<float3> positions_orig)
@@ -127,7 +127,7 @@ static void calc_faces(const Sculpt &sd,
}
static void calc_grids(
const Sculpt &sd, Object &object, const Brush &brush, PBVHNode &node, LocalData &tls)
const Sculpt &sd, Object &object, const Brush &brush, bke::pbvh::Node &node, LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -170,7 +170,7 @@ static void calc_grids(
}
static void calc_bmesh(
const Sculpt &sd, Object &object, const Brush &brush, PBVHNode &node, LocalData &tls)
const Sculpt &sd, Object &object, const Brush &brush, bke::pbvh::Node &node, LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -213,16 +213,18 @@ static void calc_bmesh(
} // namespace draw_vector_displacement_cc
void do_draw_vector_displacement_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_draw_vector_displacement_brush(const Sculpt &sd,
Object &object,
Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -236,7 +238,7 @@ void do_draw_vector_displacement_brush(const Sculpt &sd, Object &object, Span<PB
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -244,7 +246,7 @@ void do_draw_vector_displacement_brush(const Sculpt &sd, Object &object, Span<PB
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -89,7 +89,7 @@ static void calc_faces(const Sculpt &sd,
const KelvinletParams &kelvinet_params,
const float3 &offset,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -123,7 +123,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const KelvinletParams &kelvinet_params,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -160,7 +160,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const KelvinletParams &kelvinet_params,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -192,7 +192,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace elastic_deform_cc
void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -224,10 +224,10 @@ void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
&params, ss.cache->radius, force, 1.0f, brush.elastic_deform_volume_preservation);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -247,7 +247,7 @@ void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -255,7 +255,7 @@ void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -43,7 +43,7 @@ static void calc_faces(const Sculpt &sd,
const Span<float3> vert_normals,
const Span<float3> all_translations,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -91,7 +91,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const Span<float3> all_translations,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -138,7 +138,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const Span<float3> all_translations,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -183,7 +183,7 @@ static void calc_translations_faces(const Span<float3> vert_positions,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const GroupedSpan<int> vert_to_face_map,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls,
const MutableSpan<float3> all_translations)
{
@@ -204,7 +204,7 @@ static void calc_translations_faces(const Span<float3> vert_positions,
}
static void calc_translations_grids(const SubdivCCG &subdiv_ccg,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls,
const MutableSpan<float3> all_translations)
{
@@ -221,7 +221,7 @@ static void calc_translations_grids(const SubdivCCG &subdiv_ccg,
scatter_data_grids(subdiv_ccg, translations.as_span(), grids, all_translations);
}
static void calc_translations_bmesh(PBVHNode &node,
static void calc_translations_bmesh(bke::pbvh::Node &node,
LocalData &tls,
const MutableSpan<float3> all_translations)
{
@@ -247,14 +247,14 @@ static void calc_translations_bmesh(PBVHNode &node,
static void precalc_translations(Object &object, const MutableSpan<float3> translations)
{
SculptSession &ss = *object.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Vector<PBVHNode *> effective_nodes = bke::pbvh::search_gather(
pbvh, [&](PBVHNode &node) { return !node_fully_masked_or_hidden(node); });
Vector<bke::pbvh::Node *> effective_nodes = bke::pbvh::search_gather(
pbvh, [&](bke::pbvh::Node &node) { return !node_fully_masked_or_hidden(node); });
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const OffsetIndices faces = mesh.faces();
@@ -275,7 +275,7 @@ static void precalc_translations(Object &object, const MutableSpan<float3> trans
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
threading::parallel_for(effective_nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
@@ -285,7 +285,7 @@ static void precalc_translations(Object &object, const MutableSpan<float3> trans
});
break;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);
threading::parallel_for(effective_nodes.index_range(), 1, [&](const IndexRange range) {
@@ -300,11 +300,11 @@ static void precalc_translations(Object &object, const MutableSpan<float3> trans
} // namespace enhance_details_cc
void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
if (SCULPT_stroke_is_first_brush_step(*ss.cache)) {
ss.cache->detail_directions.reinitialize(SCULPT_vertex_count_get(ss));
@@ -315,8 +315,8 @@ void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
MutableSpan<float3> translations = ss.cache->detail_directions;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -341,7 +341,7 @@ void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -349,7 +349,7 @@ void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -43,7 +43,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -94,7 +94,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -144,7 +144,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -190,7 +190,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace fill_cc
void do_fill_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_fill_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -208,10 +208,10 @@ void do_fill_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
plane_from_point_normal_v3(plane, area_co, area_no);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -233,7 +233,7 @@ void do_fill_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -241,7 +241,7 @@ void do_fill_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -42,7 +42,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -91,7 +91,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -139,7 +139,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -183,7 +183,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace flatten_cc
void do_flatten_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_flatten_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -201,10 +201,10 @@ void do_flatten_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
plane_from_point_normal_v3(plane, area_co, area_no);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -226,7 +226,7 @@ void do_flatten_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -234,7 +234,7 @@ void do_flatten_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -53,7 +53,7 @@ static void calc_faces(const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -102,7 +102,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -152,7 +152,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -199,7 +199,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace grab_cc
void do_grab_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_grab_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -213,10 +213,10 @@ void do_grab_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
grab_delta *= ss.cache->bstrength;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -229,7 +229,7 @@ void do_grab_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -237,7 +237,7 @@ void do_grab_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -48,7 +48,7 @@ static void calc_faces(const Sculpt &sd,
const float3 &scale,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -92,7 +92,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &scale,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -137,7 +137,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &scale,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -179,7 +179,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace inflate_cc
void do_inflate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_inflate_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -187,10 +187,10 @@ void do_inflate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
const float3 scale = ss.cache->scale * ss.cache->radius * ss.cache->bstrength;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -211,7 +211,7 @@ void do_inflate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -219,7 +219,7 @@ void do_inflate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -123,7 +123,7 @@ static void calc_faces(const Sculpt &sd,
const Span<float3> persistent_base_positions,
const Span<float3> persistent_base_normals,
Object &object,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
MutableSpan<float> layer_displacement_factor,
MutableSpan<float3> positions_orig)
@@ -218,7 +218,7 @@ static void calc_faces(const Sculpt &sd,
static void calc_grids(const Sculpt &sd,
const Brush &brush,
Object &object,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
MutableSpan<float> layer_displacement_factor)
{
@@ -286,7 +286,7 @@ static void calc_grids(const Sculpt &sd,
static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
Object &object,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
MutableSpan<float> layer_displacement_factor)
{
@@ -351,16 +351,16 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace layer_cc
void do_layer_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_layer_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
const MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -413,7 +413,7 @@ void do_layer_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
persistent_disp_attr.finish();
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (ss.cache->layer_displacement_factor.is_empty()) {
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(ss), 0.0f);
}
@@ -426,7 +426,7 @@ void do_layer_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
if (ss.cache->layer_displacement_factor.is_empty()) {
ss.cache->layer_displacement_factor = Array<float>(SCULPT_vertex_count_get(ss), 0.0f);
}

View File

@@ -64,7 +64,7 @@ static void calc_faces(const Brush &brush,
const float strength,
const Span<float3> positions,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
Mesh &mesh,
LocalData &tls,
@@ -111,8 +111,11 @@ static void calc_faces(const Brush &brush,
array_utils::scatter(new_masks.as_span(), verts, mask);
}
static void calc_grids(
Object &object, const Brush &brush, const float strength, PBVHNode &node, LocalData &tls)
static void calc_grids(Object &object,
const Brush &brush,
const float strength,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -157,8 +160,11 @@ static void calc_grids(
mask::scatter_mask_grids(new_masks.as_span(), subdiv_ccg, grids);
}
static void calc_bmesh(
Object &object, const Brush &brush, const float strength, PBVHNode &node, LocalData &tls)
static void calc_bmesh(Object &object,
const Brush &brush,
const float strength,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const BMesh &bm = *ss.bm;
@@ -205,18 +211,18 @@ static void calc_bmesh(
} // namespace mask_cc
void do_mask_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_mask_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
const float bstrength = ss.cache->bstrength;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const blender::bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -244,7 +250,7 @@ void do_mask_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
mask.finish();
break;
}
case PBVH_GRIDS: {
case blender::bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -253,7 +259,7 @@ void do_mask_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_BMESH: {
case blender::bke::pbvh::Type::BMesh: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -130,7 +130,7 @@ static void sample_node_surface_mesh(const Object &object,
const float4x4 &mat,
const Span<float3> vert_positions,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
ScrapeSampleData &sample,
LocalData &tls)
{
@@ -174,7 +174,7 @@ static void sample_node_surface_mesh(const Object &object,
static void sample_node_surface_grids(const Object &object,
const Brush &brush,
const float4x4 &mat,
const PBVHNode &node,
const bke::pbvh::Node &node,
ScrapeSampleData &sample,
LocalData &tls)
{
@@ -220,7 +220,7 @@ static void sample_node_surface_grids(const Object &object,
static void sample_node_surface_bmesh(const Object &object,
const Brush &brush,
const float4x4 &mat,
PBVHNode &node,
bke::pbvh::Node &node,
ScrapeSampleData &sample,
LocalData &tls)
{
@@ -266,13 +266,13 @@ static void sample_node_surface_bmesh(const Object &object,
static ScrapeSampleData sample_surface(const Object &object,
const Brush &brush,
const float4x4 &mat,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
return threading::parallel_reduce(
@@ -290,7 +290,7 @@ static ScrapeSampleData sample_surface(const Object &object,
join_samples);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
return threading::parallel_reduce(
nodes.index_range(),
1,
@@ -305,7 +305,7 @@ static ScrapeSampleData sample_surface(const Object &object,
join_samples);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
return threading::parallel_reduce(
nodes.index_range(),
1,
@@ -333,7 +333,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -393,7 +393,7 @@ static void calc_grids(const Sculpt &sd,
const std::array<float4, 2> &scrape_planes,
const float angle,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls)
{
@@ -453,7 +453,7 @@ static void calc_bmesh(const Sculpt &sd,
const std::array<float4, 2> &scrape_planes,
const float angle,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
Object &object,
LocalData &tls)
{
@@ -506,7 +506,9 @@ static void calc_bmesh(const Sculpt &sd,
apply_translations(translations, verts);
}
void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, const Span<PBVHNode *> nodes)
void do_multiplane_scrape_brush(const Sculpt &sd,
Object &object,
const Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -630,10 +632,10 @@ void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, const Span<PBV
const float strength = std::abs(ss.cache->bstrength);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -657,7 +659,7 @@ void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, const Span<PBV
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -673,7 +675,7 @@ void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, const Span<PBV
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -49,7 +49,7 @@ static void calc_node(const Sculpt &sd,
Object &object,
const Brush &brush,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -95,7 +95,7 @@ static void calc_node(const Sculpt &sd,
} // namespace multires_displacement_eraser_cc
void do_displacement_eraser_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_displacement_eraser_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);

View File

@@ -33,8 +33,11 @@ struct LocalData {
Vector<float> distances;
};
static void calc_node(
Object &object, const Brush &brush, const float strength, const PBVHNode &node, LocalData &tls)
static void calc_node(Object &object,
const Brush &brush,
const float strength,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -152,7 +155,7 @@ BLI_NOINLINE static void eval_all_limit_positions(const SubdivCCG &subdiv_ccg,
BLI_NOINLINE static void store_node_prev_displacement(const Span<float3> limit_positions,
const Span<CCGElem *> elems,
const CCGKey &key,
const PBVHNode &node,
const bke::pbvh::Node &node,
const MutableSpan<float3> prev_displacement)
{
for (const int grid : bke::pbvh::node_grid_indices(node)) {
@@ -166,7 +169,7 @@ BLI_NOINLINE static void store_node_prev_displacement(const Span<float3> limit_p
} // namespace multires_displacement_smear_cc
void do_displacement_smear_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_displacement_smear_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
SculptSession &ss = *ob.sculpt;

View File

@@ -66,7 +66,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -118,7 +118,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const std::array<float3, 2> &stroke_xz,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -169,7 +169,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const std::array<float3, 2> &stroke_xz,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -217,7 +217,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace pinch_cc
void do_pinch_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_pinch_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -247,10 +247,10 @@ void do_pinch_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
math::normalize(mat.z_axis())};
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -272,7 +272,7 @@ void do_pinch_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -280,7 +280,7 @@ void do_pinch_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -671,7 +671,7 @@ static void filter_factors_on_face_sets_bmesh(const bool relax_face_sets,
BLI_NOINLINE static void calc_factors_faces(const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
const bool relax_face_sets,
Object &object,
@@ -713,7 +713,7 @@ BLI_NOINLINE static void calc_factors_faces(const Brush &brush,
static void do_relax_face_sets_brush_mesh(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength,
const bool relax_face_sets)
{
@@ -724,7 +724,7 @@ static void do_relax_face_sets_brush_mesh(const Sculpt &sd,
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -786,7 +786,7 @@ static void do_relax_face_sets_brush_mesh(const Sculpt &sd,
BLI_NOINLINE static void calc_factors_grids(const Brush &brush,
const Span<int> corner_verts,
const OffsetIndices<int> faces,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
const bool relax_face_sets,
Object &object,
@@ -838,7 +838,7 @@ BLI_NOINLINE static void calc_factors_grids(const Brush &brush,
static void do_relax_face_sets_brush_grids(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength,
const bool relax_face_sets)
{
@@ -908,7 +908,7 @@ static void do_relax_face_sets_brush_grids(const Sculpt &sd,
static void calc_factors_bmesh(Object &object,
const Brush &brush,
PBVHNode &node,
bke::pbvh::Node &node,
const float strength,
const bool relax_face_sets,
BMeshLocalData &tls,
@@ -948,7 +948,7 @@ static void calc_factors_bmesh(Object &object,
static void do_relax_face_sets_brush_bmesh(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength,
const bool relax_face_sets)
{
@@ -1005,7 +1005,7 @@ static void do_relax_face_sets_brush_bmesh(const Sculpt &sd,
/** \name Topology Relax
* \{ */
BLI_NOINLINE static void calc_topology_relax_factors_faces(const Brush &brush,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
Object &object,
MeshLocalData &tls,
@@ -1044,7 +1044,7 @@ BLI_NOINLINE static void calc_topology_relax_factors_faces(const Brush &brush,
static void do_topology_relax_brush_mesh(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength)
{
const SculptSession &ss = *object.sculpt;
@@ -1054,7 +1054,7 @@ static void do_topology_relax_brush_mesh(const Sculpt &sd,
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -1111,7 +1111,7 @@ static void do_topology_relax_brush_mesh(const Sculpt &sd,
}
BLI_NOINLINE static void calc_topology_relax_factors_grids(const Brush &brush,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
Object &object,
GridLocalData &tls,
@@ -1155,7 +1155,7 @@ BLI_NOINLINE static void calc_topology_relax_factors_grids(const Brush &brush,
static void do_topology_relax_brush_grids(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength)
{
const SculptSession &ss = *object.sculpt;
@@ -1222,7 +1222,7 @@ static void do_topology_relax_brush_grids(const Sculpt &sd,
static void calc_topology_relax_factors_bmesh(Object &object,
const Brush &brush,
PBVHNode &node,
bke::pbvh::Node &node,
const float strength,
BMeshLocalData &tls,
MutableSpan<float3> positions,
@@ -1264,7 +1264,7 @@ static void calc_topology_relax_factors_bmesh(Object &object,
static void do_topology_relax_brush_bmesh(const Sculpt &sd,
const Brush &brush,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float strength)
{
Array<int> node_offset_data;
@@ -1317,7 +1317,7 @@ static void do_topology_relax_brush_bmesh(const Sculpt &sd,
} // namespace relax_cc
void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -1331,16 +1331,16 @@ void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
const bool relax_face_sets = !(ss.cache->iteration_count % 3 == 0);
for (const float strength : strengths) {
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
do_relax_face_sets_brush_mesh(
sd, brush, object, nodes, strength * strength, relax_face_sets);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
do_relax_face_sets_brush_grids(
sd, brush, object, nodes, strength * strength, relax_face_sets);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
do_relax_face_sets_brush_bmesh(
sd, brush, object, nodes, strength * strength, relax_face_sets);
break;
@@ -1348,7 +1348,7 @@ void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
}
}
void do_topology_relax_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_topology_relax_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
const SculptSession &ss = *object.sculpt;
@@ -1362,14 +1362,14 @@ void do_topology_relax_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
boundary::ensure_boundary_info(object);
for (int i = 0; i < 4; i++) {
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
do_topology_relax_brush_mesh(sd, brush, object, nodes, strength);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
do_topology_relax_brush_grids(sd, brush, object, nodes, strength);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
do_topology_relax_brush_bmesh(sd, brush, object, nodes, strength);
break;
}

View File

@@ -57,7 +57,7 @@ static void calc_faces(const Sculpt &sd,
const Brush &brush,
const float angle,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -105,7 +105,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float angle,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -155,7 +155,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float angle,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -201,7 +201,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace rotate_cc
void do_rotate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_rotate_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -210,10 +210,10 @@ void do_rotate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
const float angle = ss.cache->vertex_rotation * flip[ss.cache->mirror_symmetry_pass];
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -225,7 +225,7 @@ void do_rotate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -233,7 +233,7 @@ void do_rotate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -43,7 +43,7 @@ static void calc_faces(const Sculpt &sd,
const float strength,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -94,7 +94,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -144,7 +144,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
const float4 &plane,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -191,7 +191,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace scrape_cc
void do_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_scrape_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -209,10 +209,10 @@ void do_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
plane_from_point_normal_v3(plane, area_co, area_no);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -234,7 +234,7 @@ void do_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -242,7 +242,7 @@ void do_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -60,7 +60,7 @@ BLI_NOINLINE static void apply_positions_faces(const Sculpt &sd,
const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
Object &object,
LocalData &tls,
@@ -108,7 +108,7 @@ BLI_NOINLINE static void apply_positions_faces(const Sculpt &sd,
BLI_NOINLINE static void do_smooth_brush_mesh(const Sculpt &sd,
const Brush &brush,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
const float brush_strength)
{
const SculptSession &ss = *object.sculpt;
@@ -118,7 +118,7 @@ BLI_NOINLINE static void do_smooth_brush_mesh(const Sculpt &sd,
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -132,7 +132,7 @@ BLI_NOINLINE static void do_smooth_brush_mesh(const Sculpt &sd,
/* Calculate the new positions into a separate array in a separate loop because multiple loops
* are updated in parallel. Without this there would be non-threadsafe access to changing
* positions in other PBVH nodes. */
* positions in other bke::pbvh::Tree nodes. */
for (const float strength : iteration_strengths(brush_strength)) {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
@@ -179,7 +179,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float strength,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -230,7 +230,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -279,7 +279,7 @@ static void calc_bmesh(const Sculpt &sd,
void do_smooth_brush(const Sculpt &sd,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const float brush_strength)
{
SculptSession &ss = *object.sculpt;
@@ -287,11 +287,11 @@ void do_smooth_brush(const Sculpt &sd,
boundary::ensure_boundary_info(object);
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES:
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh:
do_smooth_brush_mesh(sd, brush, object, nodes, brush_strength);
break;
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const Mesh &base_mesh = *static_cast<const Mesh *>(object.data);
const OffsetIndices faces = base_mesh.faces();
const Span<int> corner_verts = base_mesh.corner_verts();
@@ -315,7 +315,7 @@ void do_smooth_brush(const Sculpt &sd,
}
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);
threading::EnumerableThreadSpecific<LocalData> all_tls;

View File

@@ -68,7 +68,7 @@ static void calc_smooth_masks_faces(const OffsetIndices<int> faces,
static void apply_masks_faces(const Brush &brush,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float strength,
Object &object,
LocalData &tls,
@@ -117,7 +117,7 @@ static void apply_masks_faces(const Brush &brush,
static void do_smooth_brush_mesh(const Brush &brush,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
const float brush_strength)
{
const SculptSession &ss = *object.sculpt;
@@ -127,7 +127,7 @@ static void do_smooth_brush_mesh(const Brush &brush,
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -179,8 +179,11 @@ static void do_smooth_brush_mesh(const Brush &brush,
mask.finish();
}
static void calc_grids(
Object &object, const Brush &brush, const float strength, const PBVHNode &node, LocalData &tls)
static void calc_grids(Object &object,
const Brush &brush,
const float strength,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -230,7 +233,7 @@ static void calc_bmesh(Object &object,
const int mask_offset,
const Brush &brush,
const float strength,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -281,18 +284,18 @@ static void calc_bmesh(Object &object,
void do_smooth_mask_brush(const Sculpt &sd,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float brush_strength)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
boundary::ensure_boundary_info(object);
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
do_smooth_brush_mesh(brush, object, nodes, brush_strength);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::EnumerableThreadSpecific<LocalData> all_tls;
for (const float strength : iteration_strengths(brush_strength)) {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -304,7 +307,7 @@ void do_smooth_mask_brush(const Sculpt &sd,
}
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
threading::EnumerableThreadSpecific<LocalData> all_tls;
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);

View File

@@ -165,7 +165,7 @@ static void calc_faces(const Sculpt &sd,
const float3 &grab_delta,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
const MutableSpan<float3> positions_orig)
{
@@ -230,7 +230,7 @@ static void calc_grids(const Sculpt &sd,
const Brush &brush,
SculptProjectVector *spvc,
const float3 &grab_delta,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -295,7 +295,7 @@ static void calc_bmesh(const Sculpt &sd,
const Brush &brush,
SculptProjectVector *spvc,
const float3 &grab_delta,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -356,7 +356,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace snake_hook_cc
void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -380,10 +380,10 @@ void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
}
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -405,7 +405,7 @@ void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -413,7 +413,7 @@ void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> node
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -39,7 +39,7 @@ static void calc_faces(const Sculpt &sd,
const Brush &brush,
const float3 &offset,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -85,7 +85,7 @@ static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -132,7 +132,7 @@ static void calc_bmesh(const Sculpt &sd,
Object &object,
const Brush &brush,
const float3 &offset,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -176,7 +176,7 @@ static void calc_bmesh(const Sculpt &sd,
} // namespace thumb_cc
void do_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_thumb_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -186,10 +186,10 @@ void do_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
const float3 offset = math::cross(math::cross(normal, grab_delta), normal) * ss.cache->bstrength;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -201,7 +201,7 @@ void do_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -209,7 +209,7 @@ void do_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -159,7 +159,7 @@ static void calc_faces(const Sculpt &sd,
const Span<int> corner_verts,
const GroupedSpan<int> vert_to_face_map,
const Span<bool> hide_poly,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -209,8 +209,11 @@ static void calc_faces(const Sculpt &sd,
write_translations(sd, object, positions_eval, verts, translations, positions_orig);
}
static void calc_grids(
const Sculpt &sd, Object &object, const Brush &brush, const PBVHNode &node, LocalData &tls)
static void calc_grids(const Sculpt &sd,
Object &object,
const Brush &brush,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -255,7 +258,7 @@ static void calc_grids(
}
static void calc_bmesh(
const Sculpt &sd, Object &object, const Brush &brush, PBVHNode &node, LocalData &tls)
const Sculpt &sd, Object &object, const Brush &brush, bke::pbvh::Node &node, LocalData &tls)
{
SculptSession &ss = *object.sculpt;
const StrokeCache &cache = *ss.cache;
@@ -302,7 +305,7 @@ static void calc_bmesh(
} // namespace topology_slide_cc
void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes)
void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes)
{
const SculptSession &ss = *object.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -312,10 +315,10 @@ void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
}
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES: {
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
const OffsetIndices faces = mesh.faces();
@@ -341,7 +344,7 @@ void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
});
break;
}
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -349,7 +352,7 @@ void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<PBVHNode *>
}
});
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -9,56 +9,66 @@
struct Scene;
struct Sculpt;
struct Object;
struct PBVHNode;
namespace blender::bke::pbvh {
class Node;
}
namespace blender::ed::sculpt_paint {
void do_clay_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_clay_strips_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_clay_thumb_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_crease_brush(const Scene &scene, const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_blob_brush(const Scene &scene, const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_clay_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_clay_strips_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_clay_thumb_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_crease_brush(const Scene &scene,
const Sculpt &sd,
Object &ob,
Span<bke::pbvh::Node *> nodes);
void do_blob_brush(const Scene &scene,
const Sculpt &sd,
Object &ob,
Span<bke::pbvh::Node *> nodes);
void do_bmesh_topology_rake_brush(const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float strength);
void do_displacement_eraser_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_displacement_smear_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_draw_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_displacement_eraser_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_displacement_smear_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_draw_face_sets_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
/** A simple normal-direction displacement. */
void do_draw_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_draw_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
/** A simple normal-direction displacement based on image texture RGB/XYZ values. */
void do_draw_vector_displacement_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_draw_sharp_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_fill_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_flatten_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_grab_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_gravity_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_inflate_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_layer_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_draw_vector_displacement_brush(const Sculpt &sd,
Object &object,
Span<bke::pbvh::Node *> nodes);
void do_draw_sharp_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_elastic_deform_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_enhance_details_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_fill_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_flatten_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_grab_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_gravity_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_inflate_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void do_layer_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
/** A brush that modifies mask values instead of position. */
void do_mask_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_pinch_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_nudge_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_rotate_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_scrape_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_mask_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_multiplane_scrape_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_pinch_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_nudge_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_relax_face_sets_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_rotate_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_scrape_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
/** Smooth positions with neighboring vertices. */
void do_smooth_brush(const Sculpt &sd,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float brush_strength);
/** Smooth mask values with neighboring vertices. */
void do_smooth_mask_brush(const Sculpt &sd,
Object &object,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float brush_strength);
void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_thumb_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_topology_relax_brush(const Sculpt &sd, Object &object, Span<PBVHNode *> nodes);
void do_snake_hook_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_thumb_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_topology_slide_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
void do_topology_relax_brush(const Sculpt &sd, Object &object, Span<bke::pbvh::Node *> nodes);
} // namespace blender::ed::sculpt_paint

View File

@@ -40,13 +40,17 @@ struct BMFace;
struct Brush;
struct Mesh;
struct Object;
struct PBVH;
struct PBVHNode;
struct Sculpt;
struct SculptSession;
struct SubdivCCG;
struct SubdivCCGCoord;
struct SubdivCCGNeighbors;
namespace blender {
namespace bke::pbvh {
class Node;
class Tree;
} // namespace bke::pbvh
} // namespace blender
namespace blender::ed::sculpt_paint {
struct StrokeCache;
@@ -80,8 +84,9 @@ void transform_positions(Span<float3> src, const float4x4 &transform, MutableSpa
* Note on the various positions arrays:
* - positions_orig: Positions owned by the original mesh. Not the same as `positions_eval` if
* there are deform modifiers.
* - positions_eval: Positions after procedural deformation, used to build the PBVH. Translations
* are built for these values, then applied to `positions_orig`.
* - positions_eval: Positions after procedural deformation, used to build the
* blender::bke::pbvh::Tree. Translations are built for these values, then applied to
* `positions_orig`.
*/
/** Fill the output array with all positions in the geometry referenced by the indices. */
@@ -276,17 +281,17 @@ namespace auto_mask {
*/
void calc_vert_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
Span<int> verts,
MutableSpan<float> factors);
void calc_grids_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
Span<int> grids,
MutableSpan<float> factors);
void calc_vert_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Set<BMVert *, 0> &verts,
MutableSpan<float> factors);
@@ -297,7 +302,7 @@ void calc_face_factors(const Object &object,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Span<int> face_indices,
const MutableSpan<float> factors);
@@ -351,11 +356,14 @@ void apply_translations_to_shape_keys(Object &object,
MutableSpan<float3> positions_mesh);
/**
* Currently the PBVH owns its own copy of deformed positions that needs to be updated to stay in
* sync with brush deformations.
* \todo This should be removed one the PBVH no longer stores this copy of deformed positions.
* Currently the pbvh::Tree owns its own copy of deformed positions that needs to be updated to
* stay in sync with brush deformations.
* \todo This should be removed one the pbvh::Tree no longer stores this copy of deformed
* positions.
*/
void apply_translations_to_pbvh(PBVH &pbvh, Span<int> verts, Span<float3> positions_orig);
void apply_translations_to_pbvh(bke::pbvh::Tree &pbvh,
Span<int> verts,
Span<float3> positions_orig);
/**
* Write the new translated positions to the original mesh, taking into account inverse
@@ -373,11 +381,12 @@ void write_translations(const Sculpt &sd,
* Creates OffsetIndices based on each node's unique vertex count, allowing for easy slicing of a
* new array.
*/
OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes, Array<int> &node_data);
OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes,
OffsetIndices<int> create_node_vert_offsets(Span<bke::pbvh::Node *> nodes, Array<int> &node_data);
OffsetIndices<int> create_node_vert_offsets(Span<bke::pbvh::Node *> nodes,
const CCGKey &key,
Array<int> &node_data);
OffsetIndices<int> create_node_vert_offsets_bmesh(Span<PBVHNode *> nodes, Array<int> &node_data);
OffsetIndices<int> create_node_vert_offsets_bmesh(Span<bke::pbvh::Node *> nodes,
Array<int> &node_data);
/**
* Find vertices connected to the indexed vertices across faces.

View File

@@ -1155,7 +1155,7 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
return;
}
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != blender::bke::pbvh::Type::Mesh) {
return;
}
@@ -1428,7 +1428,7 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcon
paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location);
}
pcontext->is_multires = ss.pbvh != nullptr && BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS;
pcontext->is_multires = ss.pbvh != nullptr && ss.pbvh->type() == blender::bke::pbvh::Type::Grids;
pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt;
}

View File

@@ -4,7 +4,7 @@
/** \file
* \ingroup edsculpt
* Implements the PBVH node hiding operator.
* Implements the bke::pbvh::Tree node hiding operator.
*/
#include "MEM_guardedalloc.h"
@@ -55,7 +55,7 @@ namespace blender::ed::sculpt_paint::hide {
/** \name Public API
* \{ */
Span<int> node_visible_verts(const PBVHNode &node,
Span<int> node_visible_verts(const bke::pbvh::Node &node,
const Span<bool> hide_vert,
Vector<int> &indices)
{
@@ -81,21 +81,21 @@ void sync_all_from_faces(Object &object)
SCULPT_topology_islands_invalidate(ss);
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
/* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for
* vertices and edges consistent. */
bke::mesh_hide_face_flush(mesh);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
/* In addition to making the hide status of the base mesh consistent, we also have to
* propagate the status to the Multires grids. */
bke::mesh_hide_face_flush(mesh);
BKE_sculpt_sync_face_visibility_to_grids(&mesh, ss.subdiv_ccg);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMesh &bm = *ss.bm;
BMIter iter;
BMFace *f;
@@ -141,7 +141,7 @@ void tag_update_visibility(const bContext &C)
}
}
void mesh_show_all(Object &object, const Span<PBVHNode *> nodes)
void mesh_show_all(Object &object, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -150,7 +150,7 @@ void mesh_show_all(Object &object, const Span<PBVHNode *> nodes)
{
const VArraySpan hide_vert(attribute);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
if (std::any_of(verts.begin(), verts.end(), [&](const int i) { return hide_vert[i]; })) {
undo::push_node(object, node, undo::Type::HideVert);
@@ -159,23 +159,23 @@ void mesh_show_all(Object &object, const Span<PBVHNode *> nodes)
}
});
}
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_fully_hidden_set(node, false);
}
attributes.remove(".hide_vert");
bke::mesh_hide_vert_flush(mesh);
}
void grids_show_all(Depsgraph &depsgraph, Object &object, const Span<PBVHNode *> nodes)
void grids_show_all(Depsgraph &depsgraph, Object &object, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
PBVH &pbvh = *object.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
bool any_changed = false;
if (!grid_hidden.is_empty()) {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
if (std::any_of(grids.begin(), grids.end(), [&](const int i) {
return bits::any_bit_set(grid_hidden[i]);
@@ -191,7 +191,7 @@ void grids_show_all(Depsgraph &depsgraph, Object &object, const Span<PBVHNode *>
if (!any_changed) {
return;
}
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_fully_hidden_set(node, false);
}
BKE_subdiv_ccg_grid_hidden_free(subdiv_ccg);
@@ -203,7 +203,7 @@ void grids_show_all(Depsgraph &depsgraph, Object &object, const Span<PBVHNode *>
/* -------------------------------------------------------------------- */
/** \name Internal Visibility Utilities
* Functions that assist with applying changes to the different PBVH types.
* Functions that assist with applying changes to the different bke::pbvh::Tree types.
* \{ */
enum class VisAction {
@@ -232,7 +232,7 @@ static void calc_face_hide(const Span<int> node_faces,
/* Updates a node's face's visibility based on the updated vertex visibility. */
static void flush_face_changes_node(Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const Span<bool> hide_vert)
{
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -251,7 +251,7 @@ static void flush_face_changes_node(Mesh &mesh,
threading::EnumerableThreadSpecific<TLS> all_tls;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TLS &tls = all_tls.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> node_faces = bke::pbvh::node_face_indices_calc_mesh(
tri_faces, *node, tls.face_indices);
@@ -296,7 +296,7 @@ static void flush_edge_changes(Mesh &mesh, const Span<bool> hide_vert)
}
static void vert_hide_update(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(Span<int>, MutableSpan<bool>)> calc_hide)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
@@ -308,7 +308,7 @@ static void vert_hide_update(Object &object,
threading::EnumerableThreadSpecific<Vector<bool>> all_new_hide;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<bool> &new_hide = all_new_hide.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
new_hide.reinitialize(verts.size());
@@ -336,17 +336,17 @@ static void vert_hide_update(Object &object,
static void grid_hide_update(Depsgraph &depsgraph,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(const int, MutableBoundedBitSpan)> calc_hide)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
PBVH &pbvh = *object.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
BitGroupVector<> &grid_hidden = BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg);
bool any_changed = false;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
BitGroupVector<> new_hide(grids.size(), grid_hidden.group_size());
for (const int i : grids.index_range()) {
@@ -418,11 +418,11 @@ static void partialvis_update_bmesh_faces(const Set<BMFace *, 0> &faces)
}
static void partialvis_update_bmesh_nodes(Object &ob,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const VisAction action,
const FunctionRef<bool(BMVert *v)> vert_test_fn)
{
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
bool any_changed = false;
bool any_visible = false;
@@ -453,7 +453,7 @@ static void partialvis_update_bmesh_nodes(Object &ob,
static void partialvis_all_update_mesh(Object &object,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -477,7 +477,7 @@ static void partialvis_all_update_mesh(Object &object,
static void partialvis_all_update_grids(Depsgraph &depsgraph,
Object &object,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
switch (action) {
case VisAction::Hide:
@@ -494,7 +494,7 @@ static void partialvis_all_update_grids(Depsgraph &depsgraph,
static void partialvis_all_update_bmesh(Object &ob,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
partialvis_update_bmesh_nodes(ob, nodes, action, [](const BMVert * /*vert*/) { return true; });
}
@@ -506,7 +506,7 @@ static int hide_show_all_exec(bContext *C, wmOperator *op)
const VisAction action = VisAction(RNA_enum_get(op->ptr, "action"));
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, &ob);
bke::pbvh::Tree *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, &ob);
BLI_assert(BKE_object_sculpt_pbvh_get(&ob) == pbvh);
/* Start undo. */
@@ -519,16 +519,16 @@ static int hide_show_all_exec(bContext *C, wmOperator *op)
break;
}
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*pbvh, {});
switch (BKE_pbvh_type(*pbvh)) {
case PBVH_FACES:
switch (pbvh->type()) {
case bke::pbvh::Type::Mesh:
partialvis_all_update_mesh(ob, action, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
partialvis_all_update_grids(*depsgraph, ob, action, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
partialvis_all_update_bmesh(ob, action, nodes);
break;
}
@@ -544,7 +544,7 @@ static int hide_show_all_exec(bContext *C, wmOperator *op)
static void partialvis_masked_update_mesh(Object &object,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -572,7 +572,7 @@ static void partialvis_masked_update_mesh(Object &object,
static void partialvis_masked_update_grids(Depsgraph &depsgraph,
Object &object,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
@@ -602,11 +602,10 @@ static void partialvis_masked_update_grids(Depsgraph &depsgraph,
}
static void partialvis_masked_update_bmesh(Object &ob,
PBVH *pbvh,
const VisAction action,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
BMesh *bm = BKE_pbvh_get_bmesh(*pbvh);
BMesh *bm = ob.sculpt->bm;
const int mask_offset = CustomData_get_offset_named(&bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
const auto mask_test_fn = [&](const BMVert *v) {
const float vmask = BM_ELEM_CD_GET_FLOAT(v, mask_offset);
@@ -623,7 +622,7 @@ static int hide_show_masked_exec(bContext *C, wmOperator *op)
const VisAction action = VisAction(RNA_enum_get(op->ptr, "action"));
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, &ob);
bke::pbvh::Tree *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, &ob);
BLI_assert(BKE_object_sculpt_pbvh_get(&ob) == pbvh);
/* Start undo. */
@@ -636,17 +635,17 @@ static int hide_show_masked_exec(bContext *C, wmOperator *op)
break;
}
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*pbvh, {});
switch (BKE_pbvh_type(*pbvh)) {
case PBVH_FACES:
switch (pbvh->type()) {
case bke::pbvh::Type::Mesh:
partialvis_masked_update_mesh(ob, action, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
partialvis_masked_update_grids(*depsgraph, ob, action, nodes);
break;
case PBVH_BMESH:
partialvis_masked_update_bmesh(ob, pbvh, action, nodes);
case bke::pbvh::Type::BMesh:
partialvis_masked_update_bmesh(ob, action, nodes);
break;
}
@@ -705,7 +704,7 @@ void PAINT_OT_hide_show_all(wmOperatorType *ot)
hide_show_operator_properties(ot);
}
static void invert_visibility_mesh(Object &object, const Span<PBVHNode *> nodes)
static void invert_visibility_mesh(Object &object, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> tri_faces = mesh.corner_tri_faces();
@@ -716,7 +715,7 @@ static void invert_visibility_mesh(Object &object, const Span<PBVHNode *> nodes)
threading::EnumerableThreadSpecific<Vector<int>> all_index_data;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<int> &faces = all_index_data.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(object, node, undo::Type::HideFace);
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, faces);
for (const int face : faces) {
@@ -733,15 +732,15 @@ static void invert_visibility_mesh(Object &object, const Span<PBVHNode *> nodes)
static void invert_visibility_grids(Depsgraph &depsgraph,
Object &object,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
PBVH &pbvh = *object.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
BitGroupVector<> &grid_hidden = BKE_subdiv_ccg_grid_hidden_ensure(subdiv_ccg);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(object, node, undo::Type::HideVert);
for (const int i : bke::pbvh::node_grid_indices(*node)) {
bits::invert(grid_hidden[i]);
@@ -755,10 +754,10 @@ static void invert_visibility_grids(Depsgraph &depsgraph,
BKE_pbvh_sync_visibility_from_verts(pbvh, &mesh);
}
static void invert_visibility_bmesh(Object &object, const Span<PBVHNode *> nodes)
static void invert_visibility_bmesh(Object &object, const Span<bke::pbvh::Node *> nodes)
{
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(object, node, undo::Type::HideVert);
bool fully_hidden = true;
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
@@ -770,7 +769,7 @@ static void invert_visibility_bmesh(Object &object, const Span<PBVHNode *> nodes
}
});
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
partialvis_update_bmesh_faces(BKE_pbvh_bmesh_node_faces(node));
}
});
@@ -781,19 +780,19 @@ static int visibility_invert_exec(bContext *C, wmOperator *op)
Object &object = *CTX_data_active_object(C);
Depsgraph &depsgraph = *CTX_data_ensure_evaluated_depsgraph(C);
PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(&depsgraph, &object);
bke::pbvh::Tree *pbvh = BKE_sculpt_object_pbvh_ensure(&depsgraph, &object);
BLI_assert(BKE_object_sculpt_pbvh_get(&object) == pbvh);
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*pbvh, {});
undo::push_begin(object, op);
switch (BKE_pbvh_type(*pbvh)) {
case PBVH_FACES:
switch (pbvh->type()) {
case bke::pbvh::Type::Mesh:
invert_visibility_mesh(object, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
invert_visibility_grids(depsgraph, object, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
invert_visibility_bmesh(object, nodes);
break;
}
@@ -892,12 +891,12 @@ static void propagate_vertex_visibility(Mesh &mesh,
}
static void update_undo_state(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const Span<bool> old_hide_vert,
const Span<bool> new_hide_vert)
{
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
for (const int vert : bke::pbvh::node_unique_verts(*node)) {
if (old_hide_vert[vert] != new_hide_vert[vert]) {
undo::push_node(object, node, undo::Type::HideVert);
@@ -908,7 +907,7 @@ static void update_undo_state(Object &object,
});
}
static void update_node_visibility_from_face_changes(const Span<PBVHNode *> nodes,
static void update_node_visibility_from_face_changes(const Span<bke::pbvh::Node *> nodes,
const Span<int> tri_faces,
const Span<bool> orig_hide_poly,
const Span<bool> new_hide_poly,
@@ -917,7 +916,7 @@ static void update_node_visibility_from_face_changes(const Span<PBVHNode *> node
threading::EnumerableThreadSpecific<Vector<int>> all_face_indices;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<int> &face_indices = all_face_indices.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
bool any_changed = false;
const Span<int> indices = bke::pbvh::node_face_indices_calc_mesh(
tri_faces, *node, face_indices);
@@ -937,7 +936,7 @@ static void update_node_visibility_from_face_changes(const Span<PBVHNode *> node
}
static void grow_shrink_visibility_mesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const VisAction action,
const int iterations)
{
@@ -993,8 +992,8 @@ struct DualBitBuffer {
static void grow_shrink_visibility_grid(Depsgraph &depsgraph,
Object &object,
PBVH &pbvh,
const Span<PBVHNode *> nodes,
bke::pbvh::Tree &pbvh,
const Span<bke::pbvh::Node *> nodes,
const VisAction action,
const int iterations)
{
@@ -1018,7 +1017,7 @@ static void grow_shrink_visibility_grid(Depsgraph &depsgraph,
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const int node_index : range) {
PBVHNode *node = nodes[node_index];
bke::pbvh::Node *node = nodes[node_index];
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
for (const int grid_index : grids) {
@@ -1066,7 +1065,7 @@ static void grow_shrink_visibility_grid(Depsgraph &depsgraph,
if (!node_changed[node_index]) {
continue;
}
PBVHNode *node = nodes[node_index];
bke::pbvh::Node *node = nodes[node_index];
BKE_pbvh_node_mark_update_visibility(node);
bke::pbvh::node_update_visibility_grids(grid_hidden, *node);
@@ -1090,7 +1089,7 @@ static Array<bool> duplicate_visibility_bmesh(const Object &object)
}
static void grow_shrink_visibility_bmesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const VisAction action,
const int iterations)
{
@@ -1114,12 +1113,12 @@ static int visibility_filter_exec(bContext *C, wmOperator *op)
Object &object = *CTX_data_active_object(C);
Depsgraph &depsgraph = *CTX_data_ensure_evaluated_depsgraph(C);
PBVH &pbvh = *BKE_sculpt_object_pbvh_ensure(&depsgraph, &object);
bke::pbvh::Tree &pbvh = *BKE_sculpt_object_pbvh_ensure(&depsgraph, &object);
BLI_assert(BKE_object_sculpt_pbvh_get(&object) == &pbvh);
const VisAction mode = VisAction(RNA_enum_get(op->ptr, "action"));
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
const SculptSession &ss = *object.sculpt;
int num_verts = SCULPT_vertex_count_get(ss);
@@ -1133,14 +1132,14 @@ static int visibility_filter_exec(bContext *C, wmOperator *op)
}
undo::push_begin(object, op);
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh:
grow_shrink_visibility_mesh(object, nodes, mode, iterations);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
grow_shrink_visibility_grid(depsgraph, object, pbvh, nodes, mode, iterations);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
grow_shrink_visibility_bmesh(object, nodes, mode, iterations);
break;
}
@@ -1214,9 +1213,9 @@ static void partialvis_gesture_update_mesh(gesture::GestureData &gesture_data)
HideShowOperation *operation = reinterpret_cast<HideShowOperation *>(gesture_data.operation);
Object *object = gesture_data.vc.obact;
const VisAction action = operation->action;
const Span<PBVHNode *> nodes = gesture_data.nodes;
const Span<bke::pbvh::Node *> nodes = gesture_data.nodes;
PBVH &pbvh = *object->sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object->sculpt->pbvh;
Mesh *mesh = static_cast<Mesh *>(object->data);
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
if (action == VisAction::Show && !attributes.contains(".hide_vert")) {
@@ -1242,7 +1241,7 @@ static void partialvis_gesture_update_grids(Depsgraph &depsgraph,
HideShowOperation *operation = reinterpret_cast<HideShowOperation *>(gesture_data.operation);
Object *object = gesture_data.vc.obact;
const VisAction action = operation->action;
const Span<PBVHNode *> nodes = gesture_data.nodes;
const Span<bke::pbvh::Node *> nodes = gesture_data.nodes;
SubdivCCG &subdiv_ccg = *object->sculpt->subdiv_ccg;
@@ -1289,14 +1288,14 @@ static void hide_show_apply_for_symmetry_pass(bContext &C, gesture::GestureData
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(&C);
switch (BKE_pbvh_type(*gesture_data.ss->pbvh)) {
case PBVH_FACES:
switch (gesture_data.ss->pbvh->type()) {
case bke::pbvh::Type::Mesh:
partialvis_gesture_update_mesh(gesture_data);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
partialvis_gesture_update_grids(*depsgraph, gesture_data);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
partialvis_gesture_update_bmesh(gesture_data);
break;
}

View File

@@ -40,7 +40,6 @@ struct Main;
struct MTex;
struct Object;
struct Paint;
struct PBVHNode;
struct PointerRNA;
struct RegionView3D;
struct ReportList;
@@ -57,10 +56,17 @@ struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
namespace blender::ed::sculpt_paint {
namespace blender {
namespace bke {
namespace pbvh {
class Node;
}
} // namespace bke
namespace ed::sculpt_paint {
struct PaintStroke;
struct StrokeCache;
} // namespace blender::ed::sculpt_paint
} // namespace ed::sculpt_paint
} // namespace blender
struct CoNo {
float co[3];
@@ -471,8 +477,8 @@ enum BrushStrokeMode {
namespace blender::ed::sculpt_paint::hide {
void sync_all_from_faces(Object &object);
void mesh_show_all(Object &object, Span<PBVHNode *> nodes);
void grids_show_all(Depsgraph &depsgraph, Object &object, Span<PBVHNode *> nodes);
void mesh_show_all(Object &object, Span<bke::pbvh::Node *> nodes);
void grids_show_all(Depsgraph &depsgraph, Object &object, Span<bke::pbvh::Node *> nodes);
void tag_update_visibility(const bContext &C);
void PAINT_OT_hide_show_masked(wmOperatorType *ot);
@@ -512,7 +518,7 @@ void average_neighbor_mask_bmesh(int mask_offset,
/** Write to the mask attribute for each node, storing undo data. */
void write_mask_mesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
FunctionRef<void(MutableSpan<float>, Span<int>)> write_fn);
/**
@@ -520,7 +526,7 @@ void write_mask_mesh(Object &object,
* if the data is actually changed.
*/
void update_mask_mesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
FunctionRef<void(MutableSpan<float>, Span<int>)> update_fn);
void PAINT_OT_mask_flood_fill(wmOperatorType *ot);
@@ -597,7 +603,7 @@ void init_session_data(const ToolSettings &ts, Object &ob);
void init_session(
Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, eObjectMode object_mode);
Vector<PBVHNode *> pbvh_gather_generic(Object &ob, const VPaint &wp, const Brush &brush);
Vector<bke::pbvh::Node *> pbvh_gather_generic(Object &ob, const VPaint &wp, const Brush &brush);
void mode_enter_generic(
Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, eObjectMode mode_flag);

View File

@@ -55,8 +55,8 @@ namespace blender::ed::sculpt_paint::mask {
Array<float> duplicate_mask(const Object &object)
{
const SculptSession &ss = *object.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArray mask = *attributes.lookup_or_default<float>(
@@ -65,7 +65,7 @@ Array<float> duplicate_mask(const Object &object)
mask.materialize(result);
return result;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
@@ -81,7 +81,7 @@ Array<float> duplicate_mask(const Object &object)
}
return result;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMesh &bm = *ss.bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
Array<float> result(bm.totvert);
@@ -126,7 +126,7 @@ void gather_mask_bmesh(const BMesh &bm,
{
BLI_assert(verts.size() == r_mask.size());
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const int mask_offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
int i = 0;
for (const BMVert *vert : verts) {
@@ -267,7 +267,7 @@ void average_neighbor_mask_bmesh(const int mask_offset,
}
void update_mask_mesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
FunctionRef<void(MutableSpan<float>, Span<int>)> update_fn)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
@@ -288,7 +288,7 @@ void update_mask_mesh(Object &object,
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
threading::isolate_task([&]() {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = hide::node_visible_verts(*node, hide_vert, tls.visible_verts);
tls.mask.reinitialize(verts.size());
array_utils::gather<float>(mask.span, verts, tls.mask);
@@ -341,7 +341,7 @@ static const EnumPropertyItem mode_items[] = {
{int(FloodFillMode::InverseMeshValue), "INVERT", 0, "Invert", "Invert the mask"},
{0}};
static Span<int> get_hidden_verts(const PBVHNode &node,
static Span<int> get_hidden_verts(const bke::pbvh::Node &node,
const Span<bool> hide_vert,
Vector<int> &indices)
{
@@ -360,7 +360,7 @@ static Span<int> get_hidden_verts(const PBVHNode &node,
return indices;
}
static bool try_remove_mask_mesh(Object &object, const Span<PBVHNode *> nodes)
static bool try_remove_mask_mesh(Object &object, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -383,7 +383,7 @@ static bool try_remove_mask_mesh(Object &object, const Span<PBVHNode *> nodes)
return init;
}
Vector<int> &index_data = all_index_data.local();
for (const PBVHNode *node : nodes.slice(range)) {
for (const bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = get_hidden_verts(*node, hide_vert, index_data);
if (std::any_of(verts.begin(), verts.end(), [&](int i) { return mask[i] > 0.0f; })) {
return true;
@@ -398,7 +398,7 @@ static bool try_remove_mask_mesh(Object &object, const Span<PBVHNode *> nodes)
/* Store undo data for nodes with changed mask. */
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
if (std::all_of(verts.begin(), verts.end(), [&](const int i) { return mask[i] == 0.0f; })) {
continue;
@@ -412,7 +412,7 @@ static bool try_remove_mask_mesh(Object &object, const Span<PBVHNode *> nodes)
return true;
}
static void fill_mask_mesh(Object &object, const float value, const Span<PBVHNode *> nodes)
static void fill_mask_mesh(Object &object, const float value, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -429,7 +429,7 @@ static void fill_mask_mesh(Object &object, const float value, const Span<PBVHNod
threading::EnumerableThreadSpecific<Vector<int>> all_index_data;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<int> &index_data = all_index_data.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> verts = hide::node_visible_verts(*node, hide_vert, index_data);
if (std::all_of(verts.begin(), verts.end(), [&](int i) { return mask.span[i] == value; })) {
continue;
@@ -448,7 +448,7 @@ static void fill_mask_grids(Main &bmain,
Depsgraph &depsgraph,
Object &object,
const float value,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
@@ -466,7 +466,7 @@ static void fill_mask_grids(Main &bmain,
const Span<CCGElem *> grids = subdiv_ccg.grids;
bool any_changed = false;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> grid_indices = bke::pbvh::node_grid_indices(*node);
if (std::all_of(grid_indices.begin(), grid_indices.end(), [&](const int grid) {
CCGElem *elem = grids[grid];
@@ -507,7 +507,7 @@ static void fill_mask_grids(Main &bmain,
}
}
static void fill_mask_bmesh(Object &object, const float value, const Span<PBVHNode *> nodes)
static void fill_mask_bmesh(Object &object, const float value, const Span<bke::pbvh::Node *> nodes)
{
BMesh &bm = *object.sculpt->bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
@@ -522,7 +522,7 @@ static void fill_mask_bmesh(Object &object, const float value, const Span<PBVHNo
undo::push_node(object, nodes.first(), undo::Type::Mask);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
bool redraw = false;
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
if (!BM_elem_flag_test(vert, BM_ELEM_HIDDEN)) {
@@ -542,21 +542,21 @@ static void fill_mask_bmesh(Object &object, const float value, const Span<PBVHNo
static void fill_mask(
Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object, const float value)
{
PBVH &pbvh = *object.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES:
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh:
fill_mask_mesh(object, value, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
fill_mask_grids(bmain, scene, depsgraph, object, value, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
fill_mask_bmesh(object, value, nodes);
break;
}
/* Avoid calling #BKE_pbvh_node_mark_update_mask by doing that update here. */
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_fully_masked_set(node, value == 1.0f);
BKE_pbvh_node_fully_unmasked_set(node, value == 0.0f);
}
@@ -566,7 +566,7 @@ static void invert_mask_grids(Main &bmain,
const Scene &scene,
Depsgraph &depsgraph,
Object &object,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
@@ -578,7 +578,7 @@ static void invert_mask_grids(Main &bmain,
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(object, node, undo::Type::Mask);
const Span<int> grid_indices = bke::pbvh::node_grid_indices(*node);
@@ -606,7 +606,7 @@ static void invert_mask_grids(Main &bmain,
multires_mark_as_modified(&depsgraph, &object, MULTIRES_COORDS_MODIFIED);
}
static void invert_mask_bmesh(Object &object, const Span<PBVHNode *> nodes)
static void invert_mask_bmesh(Object &object, const Span<bke::pbvh::Node *> nodes)
{
BMesh &bm = *object.sculpt->bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
@@ -617,7 +617,7 @@ static void invert_mask_bmesh(Object &object, const Span<PBVHNode *> nodes)
undo::push_node(object, nodes.first(), undo::Type::Mask);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
if (!BM_elem_flag_test(vert, BM_ELEM_HIDDEN)) {
BM_ELEM_CD_SET_FLOAT(vert, offset, 1.0f - BM_ELEM_CD_GET_FLOAT(vert, offset));
@@ -631,19 +631,19 @@ static void invert_mask_bmesh(Object &object, const Span<PBVHNode *> nodes)
static void invert_mask(Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object)
{
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*object.sculpt->pbvh, {});
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES:
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*object.sculpt->pbvh, {});
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh:
write_mask_mesh(object, nodes, [&](MutableSpan<float> mask, const Span<int> verts) {
for (const int vert : verts) {
mask[vert] = 1.0f - mask[vert];
}
});
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
invert_mask_grids(bmain, scene, depsgraph, object, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
invert_mask_bmesh(object, nodes);
break;
}
@@ -745,12 +745,12 @@ static float mask_gesture_get_new_value(const float elem, FloodFillMode mode, fl
static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureData &gesture_data)
{
const PBVH &pbvh = *gesture_data.ss->pbvh;
const Span<PBVHNode *> nodes = gesture_data.nodes;
const bke::pbvh::Tree &pbvh = *gesture_data.ss->pbvh;
const Span<bke::pbvh::Node *> nodes = gesture_data.nodes;
const MaskOperation &op = *reinterpret_cast<const MaskOperation *>(gesture_data.operation);
Object &object = *gesture_data.vc.obact;
switch (BKE_pbvh_type(*gesture_data.ss->pbvh)) {
case PBVH_FACES: {
switch (gesture_data.ss->pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Span<float3> positions = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> normals = BKE_pbvh_get_vert_normals(pbvh);
update_mask_mesh(object, nodes, [&](MutableSpan<float> node_mask, const Span<int> verts) {
@@ -763,13 +763,13 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
SubdivCCG &subdiv_ccg = *gesture_data.ss->subdiv_ccg;
const Span<CCGElem *> grids = subdiv_ccg.grids;
const BitGroupVector<> &grid_hidden = subdiv_ccg.grid_hidden;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
bool any_changed = false;
for (const int grid : bke::pbvh::node_grid_indices(*node)) {
CCGElem *elem = grids[grid];
@@ -792,11 +792,11 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMesh &bm = *gesture_data.ss->bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
bool any_changed = false;
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
if (gesture::is_affected(gesture_data, vert->co, vert->no)) {
@@ -820,10 +820,10 @@ static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureDa
static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(&C);
if (BKE_pbvh_type(*gesture_data.ss->pbvh) == PBVH_GRIDS) {
if (gesture_data.ss->pbvh->type() == bke::pbvh::Type::Grids) {
multires_mark_as_modified(depsgraph, gesture_data.vc.obact, MULTIRES_COORDS_MODIFIED);
}
blender::bke::pbvh::update_mask(*gesture_data.ss->pbvh);
bke::pbvh::update_mask(*gesture_data.ss->pbvh);
undo::push_end(*gesture_data.vc.obact);
}

View File

@@ -120,7 +120,7 @@ template<typename Color> static Color fromFloat(const ColorPaint4f &c)
}
}
/* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */
/* Use for 'blur' brush, align with pbvh::Tree nodes, created and freed on each update. */
template<typename BlendType> struct VPaintAverageAccum {
BlendType len;
BlendType value[3];
@@ -291,15 +291,15 @@ void init_session_data(const ToolSettings &ts, Object &ob)
}
}
Vector<PBVHNode *> pbvh_gather_generic(Object &ob, const VPaint &wp, const Brush &brush)
Vector<bke::pbvh::Node *> pbvh_gather_generic(Object &ob, const VPaint &wp, const Brush &brush)
{
SculptSession &ss = *ob.sculpt;
const bool use_normal = vwpaint::use_normal(wp);
Vector<PBVHNode *> nodes;
Vector<bke::pbvh::Node *> nodes;
/* Build a list of all nodes that are potentially within the brush's area of influence */
if (brush.falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
nodes = bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_sphere(node, ss.cache->location, ss.cache->radius_squared, true);
});
@@ -310,7 +310,7 @@ Vector<PBVHNode *> pbvh_gather_generic(Object &ob, const VPaint &wp, const Brush
else {
const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(
ss.cache->location, ss.cache->view_normal);
nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
nodes = bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_cylinder(ray_dist_precalc, node, ss.cache->radius_squared, true);
});
@@ -1017,7 +1017,7 @@ static void do_vpaint_brush_blur_loops(const bContext *C,
VPaintData &vpd,
Object &ob,
Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
GMutableSpan attribute)
{
SculptSession &ss = *ob.sculpt;
@@ -1161,7 +1161,7 @@ static void do_vpaint_brush_blur_verts(const bContext *C,
VPaintData &vpd,
Object &ob,
Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
GMutableSpan attribute)
{
SculptSession &ss = *ob.sculpt;
@@ -1296,7 +1296,7 @@ static void do_vpaint_brush_smear(const bContext *C,
VPaintData &vpd,
Object &ob,
Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
GMutableSpan attribute)
{
SculptSession &ss = *ob.sculpt;
@@ -1487,7 +1487,7 @@ static void calculate_average_color(VPaintData &vpd,
Mesh &mesh,
const Brush &brush,
const GSpan attribute,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const GroupedSpan<int> vert_to_face = mesh.vert_to_face_map();
@@ -1603,7 +1603,7 @@ static void vpaint_do_draw(const bContext *C,
VPaintData &vpd,
Object &ob,
Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
GMutableSpan attribute)
{
SculptSession &ss = *ob.sculpt;
@@ -1757,7 +1757,7 @@ static void vpaint_do_blur(const bContext *C,
VPaintData &vpd,
Object &ob,
Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
GMutableSpan attribute)
{
if (vpd.domain == AttrDomain::Point) {
@@ -1774,9 +1774,9 @@ static void vpaint_paint_leaves(bContext *C,
Object &ob,
Mesh &mesh,
GMutableSpan attribute,
const Span<PBVHNode *> nodes)
const Span<bke::pbvh::Node *> nodes)
{
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::Color);
}
@@ -1816,14 +1816,15 @@ static void vpaint_do_paint(bContext *C,
ss.cache->radial_symmetry_pass = i;
SCULPT_cache_calc_brushdata_symm(*ss.cache, symm, axis, angle);
Vector<PBVHNode *> nodes = vwpaint::pbvh_gather_generic(ob, vp, brush);
Vector<bke::pbvh::Node *> nodes = vwpaint::pbvh_gather_generic(ob, vp, brush);
bke::GSpanAttributeWriter attribute = mesh.attributes_for_write().lookup_for_write_span(
mesh.active_color_attribute);
BLI_assert(attribute.domain == vpd.domain);
if (attribute.domain == bke::AttrDomain::Corner) {
/* The sculpt undo system needs PBVH node corner indices for corner domain color attributes. */
/* The sculpt undo system needs bke::pbvh::Tree node corner indices for corner domain
* color attributes. */
BKE_pbvh_ensure_node_loops(*ss.pbvh, mesh.corner_tris());
}
@@ -2215,19 +2216,20 @@ static int vertex_color_set_exec(bContext *C, wmOperator *op)
BKE_sculpt_update_object_for_edit(CTX_data_ensure_evaluated_depsgraph(C), &obact, true);
undo::push_begin(obact, op);
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(*obact.sculpt->pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*obact.sculpt->pbvh, {});
const Mesh &mesh = *static_cast<const Mesh *>(obact.data);
/* The sculpt undo system needs PBVH node corner indices for corner domain color attributes. */
/* The sculpt undo system needs bke::pbvh::Tree node corner indices for corner domain
* color attributes. */
BKE_pbvh_ensure_node_loops(*obact.sculpt->pbvh, mesh.corner_tris());
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(obact, node, undo::Type::Color);
}
fill_active_color(obact, paintcol, true, affect_alpha);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_color(node);
}
undo::push_end(obact);

View File

@@ -305,6 +305,7 @@ static void transform_active_color(bContext *C,
wmOperator *op,
const FunctionRef<void(ColorGeometry4f &color)> transform_fn)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
Object &obact = *CTX_data_active_object(C);
@@ -313,19 +314,20 @@ static void transform_active_color(bContext *C,
undo::push_begin(obact, op);
PBVH &pbvh = *obact.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *obact.sculpt->pbvh;
const Mesh &mesh = *static_cast<const Mesh *>(obact.data);
/* The sculpt undo system needs PBVH node corner indices for corner domain color attributes. */
/* The sculpt undo system needs pbvh::Tree node corner indices for corner domain color
* attributes. */
BKE_pbvh_ensure_node_loops(pbvh, mesh.corner_tris());
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
for (bke::pbvh::Node *node : nodes) {
undo::push_node(obact, node, undo::Type::Color);
}
transform_active_color_data(*BKE_mesh_from_object(&obact), transform_fn);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_color(node);
}

View File

@@ -1062,7 +1062,7 @@ static void precompute_weight_values(
* \{ */
static void parallel_nodes_loop_with_mirror_check(const Mesh &mesh,
const Span<PBVHNode *> nodes,
const Span<blender::bke::pbvh::Node *> nodes,
FunctionRef<void(IndexRange)> fn)
{
/* NOTE: current mirroring code cannot be run in parallel */
@@ -1081,7 +1081,7 @@ static void do_wpaint_brush_blur(const Scene &scene,
WPaintData &wpd,
const WeightPaintInfo &wpi,
Mesh &mesh,
const Span<PBVHNode *> nodes)
const Span<blender::bke::pbvh::Node *> nodes)
{
using namespace blender;
SculptSession &ss = *ob.sculpt;
@@ -1177,7 +1177,7 @@ static void do_wpaint_brush_smear(const Scene &scene,
WPaintData &wpd,
const WeightPaintInfo &wpi,
Mesh &mesh,
const Span<PBVHNode *> nodes)
const Span<blender::bke::pbvh::Node *> nodes)
{
using namespace blender;
SculptSession &ss = *ob.sculpt;
@@ -1297,7 +1297,7 @@ static void do_wpaint_brush_draw(const Scene &scene,
const WeightPaintInfo &wpi,
Mesh &mesh,
const float strength,
const Span<PBVHNode *> nodes)
const Span<blender::bke::pbvh::Node *> nodes)
{
using namespace blender;
SculptSession &ss = *ob.sculpt;
@@ -1373,7 +1373,7 @@ static float calculate_average_weight(Object &ob,
const Brush &brush,
const VPaint &vp,
WeightPaintInfo &wpi,
const Span<PBVHNode *> nodes)
const Span<blender::bke::pbvh::Node *> nodes)
{
using namespace blender;
SculptSession &ss = *ob.sculpt;
@@ -1443,7 +1443,7 @@ static void wpaint_paint_leaves(bContext *C,
WPaintData &wpd,
WeightPaintInfo &wpi,
Mesh &mesh,
const Span<PBVHNode *> nodes)
const Span<blender::bke::pbvh::Node *> nodes)
{
const Scene &scene = *CTX_data_scene(C);
const Brush &brush = *ob.sculpt->cache->brush;
@@ -1636,7 +1636,7 @@ static void wpaint_do_paint(bContext *C,
ss.cache->radial_symmetry_pass = i;
SCULPT_cache_calc_brushdata_symm(*ss.cache, symm, axis, angle);
Vector<PBVHNode *> nodes = vwpaint::pbvh_gather_generic(ob, wp, brush);
Vector<blender::bke::pbvh::Node *> nodes = vwpaint::pbvh_gather_generic(ob, wp, brush);
wpaint_paint_leaves(C, ob, wp, wpd, wpi, mesh, nodes);
}

View File

@@ -130,9 +130,9 @@ bool ED_sculpt_report_if_shape_key_is_locked(const Object &ob, ReportList *repor
}
/* -------------------------------------------------------------------- */
/** \name Sculpt PBVH Abstraction API
/** \name Sculpt bke::pbvh::Tree Abstraction API
*
* This is read-only, for writing use PBVH vertex iterators. There vd.index matches
* This is read-only, for writing use bke::pbvh::Tree vertex iterators. There vd.index matches
* the indices used here.
*
* For multi-resolution, the same vertex in multiple grids is counted multiple times, with
@@ -142,18 +142,17 @@ bool ED_sculpt_report_if_shape_key_is_locked(const Object &ob, ReportList *repor
SculptMaskWriteInfo SCULPT_mask_get_for_write(SculptSession &ss)
{
SculptMaskWriteInfo info;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh: {
Mesh *mesh = BKE_pbvh_get_mesh(*ss.pbvh);
info.layer = static_cast<float *>(CustomData_get_layer_named_for_write(
&mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask", mesh->verts_num));
break;
}
case PBVH_BMESH:
info.bm_offset = CustomData_get_offset_named(
&BKE_pbvh_get_bmesh(*ss.pbvh)->vdata, CD_PROP_FLOAT, ".sculpt_mask");
case blender::bke::pbvh::Type::BMesh:
info.bm_offset = CustomData_get_offset_named(&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
break;
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
break;
}
return info;
@@ -161,7 +160,7 @@ SculptMaskWriteInfo SCULPT_mask_get_for_write(SculptSession &ss)
void SCULPT_vertex_random_access_ensure(SculptSession &ss)
{
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == blender::bke::pbvh::Type::BMesh) {
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);
}
@@ -169,12 +168,12 @@ void SCULPT_vertex_random_access_ensure(SculptSession &ss)
int SCULPT_vertex_count_get(const SculptSession &ss)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
return ss.totvert;
case PBVH_BMESH:
return BM_mesh_elem_count(BKE_pbvh_get_bmesh(*ss.pbvh), BM_VERT);
case PBVH_GRIDS:
case blender::bke::pbvh::Type::BMesh:
return BM_mesh_elem_count(ss.bm, BM_VERT);
case blender::bke::pbvh::Type::Grids:
return BKE_pbvh_get_grid_num_verts(*ss.pbvh);
}
@@ -183,17 +182,17 @@ int SCULPT_vertex_count_get(const SculptSession &ss)
const float *SCULPT_vertex_co_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh: {
if (ss.shapekey_active || ss.deform_modifiers_active) {
const Span<float3> positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
return positions[vertex.i];
}
return ss.vert_positions[vertex.i];
}
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
return ((BMVert *)vertex.i)->co;
case PBVH_GRIDS: {
case blender::bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -206,16 +205,16 @@ const float *SCULPT_vertex_co_get(const SculptSession &ss, PBVHVertRef vertex)
const blender::float3 SCULPT_vertex_normal_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh: {
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(*ss.pbvh);
return vert_normals[vertex.i];
}
case PBVH_BMESH: {
case blender::bke::pbvh::Type::BMesh: {
BMVert *v = (BMVert *)vertex.i;
return v->no;
}
case PBVH_GRIDS: {
case blender::bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -238,7 +237,7 @@ const float *SCULPT_vertex_persistent_co_get(const SculptSession &ss, PBVHVertRe
const float *SCULPT_vertex_co_for_grab_active_get(const SculptSession &ss, PBVHVertRef vertex)
{
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == blender::bke::pbvh::Type::Mesh) {
/* Always grab active shape key if the sculpt happens on shapekey. */
if (ss.shapekey_active) {
const Span<float3> positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
@@ -255,11 +254,11 @@ const float *SCULPT_vertex_co_for_grab_active_get(const SculptSession &ss, PBVHV
float3 SCULPT_vertex_limit_surface_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
case PBVH_BMESH:
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
case blender::bke::pbvh::Type::BMesh:
return SCULPT_vertex_co_get(ss, vertex);
case PBVH_GRIDS: {
case blender::bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -292,7 +291,11 @@ float SCULPT_mask_get_at_grids_vert_index(const SubdivCCG &subdiv_ccg,
PBVHVertRef SCULPT_active_vertex_get(const SculptSession &ss)
{
if (ELEM(BKE_pbvh_type(*ss.pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) {
if (ELEM(ss.pbvh->type(),
blender::bke::pbvh::Type::Mesh,
blender::bke::pbvh::Type::BMesh,
blender::bke::pbvh::Type::Grids))
{
return ss.active_vertex;
}
@@ -306,14 +309,14 @@ const float *SCULPT_active_vertex_co_get(const SculptSession &ss)
MutableSpan<float3> SCULPT_mesh_deformed_positions_get(SculptSession &ss)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
if (ss.shapekey_active || ss.deform_modifiers_active) {
return BKE_pbvh_get_vert_positions(*ss.pbvh);
}
return ss.vert_positions;
case PBVH_BMESH:
case PBVH_GRIDS:
case blender::bke::pbvh::Type::BMesh:
case blender::bke::pbvh::Type::Grids:
return {};
}
return {};
@@ -346,13 +349,13 @@ namespace face_set {
int active_face_set_get(const SculptSession &ss)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
if (!ss.face_sets) {
return SCULPT_FACE_SET_NONE;
}
return ss.face_sets[ss.active_face_index];
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
return SCULPT_FACE_SET_NONE;
}
@@ -360,7 +363,7 @@ int active_face_set_get(const SculptSession &ss)
ss.active_grid_index);
return ss.face_sets[face_index];
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return SCULPT_FACE_SET_NONE;
}
return SCULPT_FACE_SET_NONE;
@@ -372,17 +375,17 @@ namespace hide {
bool vert_visible_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh *mesh = BKE_pbvh_get_mesh(*ss.pbvh);
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray hide_vert = *attributes.lookup_or_default<bool>(
".hide_vert", bke::AttrDomain::Point, false);
return !hide_vert[vertex.i];
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN);
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -396,8 +399,8 @@ bool vert_visible_get(const SculptSession &ss, PBVHVertRef vertex)
bool vert_any_face_visible_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.hide_poly) {
return true;
}
@@ -408,9 +411,9 @@ bool vert_any_face_visible_get(const SculptSession &ss, PBVHVertRef vertex)
}
return false;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return true;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
return true;
}
return true;
@@ -418,8 +421,8 @@ bool vert_any_face_visible_get(const SculptSession &ss, PBVHVertRef vertex)
bool vert_all_faces_visible_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.hide_poly) {
return true;
}
@@ -430,7 +433,7 @@ bool vert_all_faces_visible_get(const SculptSession &ss, PBVHVertRef vertex)
}
return true;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMVert *v = (BMVert *)vertex.i;
BMEdge *e = v->e;
@@ -454,7 +457,7 @@ bool vert_all_faces_visible_get(const SculptSession &ss, PBVHVertRef vertex)
return true;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (!ss.hide_poly) {
return true;
}
@@ -516,8 +519,8 @@ namespace face_set {
int vert_face_set_get(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.face_sets) {
return SCULPT_FACE_SET_NONE;
}
@@ -529,9 +532,9 @@ int vert_face_set_get(const SculptSession &ss, PBVHVertRef vertex)
}
return face_set;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return 0;
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
return SCULPT_FACE_SET_NONE;
}
@@ -546,8 +549,8 @@ int vert_face_set_get(const SculptSession &ss, PBVHVertRef vertex)
bool vert_has_face_set(const SculptSession &ss, PBVHVertRef vertex, int face_set)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
if (!ss.face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
@@ -558,9 +561,9 @@ bool vert_has_face_set(const SculptSession &ss, PBVHVertRef vertex, int face_set
}
return false;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return true;
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
if (!ss.face_sets) {
return face_set == SCULPT_FACE_SET_NONE;
}
@@ -575,15 +578,15 @@ bool vert_has_face_set(const SculptSession &ss, PBVHVertRef vertex, int face_set
bool vert_has_unique_face_set(const SculptSession &ss, PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
return vert_has_unique_face_set(ss.vert_to_face_map, ss.face_sets, vertex.i);
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMVert *v = (BMVert *)vertex.i;
return vert_has_unique_face_set(v);
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -854,14 +857,14 @@ void SCULPT_vertex_neighbors_get(const SculptSession &ss,
SculptVertexNeighborIter *iter)
{
using namespace blender::ed::sculpt_paint;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
sculpt_vertex_neighbors_get_faces(ss, vertex, iter);
return;
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
sculpt_vertex_neighbors_get_bmesh(vertex, iter);
return;
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
sculpt_vertex_neighbors_get_grids(ss, vertex, include_duplicates, iter);
return;
}
@@ -878,18 +881,18 @@ namespace boundary {
bool vert_is_boundary(const SculptSession &ss, const PBVHVertRef vertex)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
if (!hide::vert_all_faces_visible_get(ss, vertex)) {
return true;
}
return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex.i);
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMVert *v = (BMVert *)vertex.i;
return BM_vert_is_boundary(v);
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const CCGKey key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
const int grid_index = vertex.i / key.grid_area;
const int index_in_grid = vertex.i - grid_index * key.grid_area;
@@ -1007,7 +1010,7 @@ struct NearestVertexData {
namespace blender::ed::sculpt_paint {
std::optional<int> nearest_vert_calc_mesh(const PBVH &pbvh,
std::optional<int> nearest_vert_calc_mesh(const bke::pbvh::Tree &pbvh,
const Span<float3> vert_positions,
const Span<bool> hide_vert,
const float3 &location,
@@ -1015,8 +1018,8 @@ std::optional<int> nearest_vert_calc_mesh(const PBVH &pbvh,
const bool use_original)
{
const float max_distance_sq = max_distance * max_distance;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(
const_cast<PBVH &>(pbvh), [&](PBVHNode &node) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(
const_cast<bke::pbvh::Tree &>(pbvh), [&](bke::pbvh::Node &node) {
return node_in_sphere(node, location, max_distance_sq, use_original);
});
if (nodes.is_empty()) {
@@ -1052,15 +1055,15 @@ std::optional<int> nearest_vert_calc_mesh(const PBVH &pbvh,
return nearest.vert;
}
std::optional<SubdivCCGCoord> nearest_vert_calc_grids(PBVH &pbvh,
std::optional<SubdivCCGCoord> nearest_vert_calc_grids(bke::pbvh::Tree &pbvh,
const SubdivCCG &subdiv_ccg,
const float3 &location,
const float max_distance,
const bool use_original)
{
const float max_distance_sq = max_distance * max_distance;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(
const_cast<PBVH &>(pbvh), [&](PBVHNode &node) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(
const_cast<bke::pbvh::Tree &>(pbvh), [&](bke::pbvh::Node &node) {
return node_in_sphere(node, location, max_distance_sq, use_original);
});
if (nodes.is_empty()) {
@@ -1105,14 +1108,14 @@ std::optional<SubdivCCGCoord> nearest_vert_calc_grids(PBVH &pbvh,
return nearest.coord;
}
std::optional<BMVert *> nearest_vert_calc_bmesh(PBVH &pbvh,
std::optional<BMVert *> nearest_vert_calc_bmesh(bke::pbvh::Tree &pbvh,
const float3 &location,
const float max_distance,
const bool use_original)
{
const float max_distance_sq = max_distance * max_distance;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(
const_cast<PBVH &>(pbvh), [&](PBVHNode &node) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(
const_cast<bke::pbvh::Tree &>(pbvh), [&](bke::pbvh::Node &node) {
return node_in_sphere(node, location, max_distance_sq, use_original);
});
if (nodes.is_empty()) {
@@ -1154,8 +1157,8 @@ PBVHVertRef nearest_vert_calc(const Object &object,
const bool use_original)
{
const SculptSession &ss = *object.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
const bke::AttributeAccessor attributes = mesh.attributes();
@@ -1164,7 +1167,7 @@ PBVHVertRef nearest_vert_calc(const Object &object,
*ss.pbvh, vert_positions, hide_vert, location, max_distance, use_original);
return nearest ? PBVHVertRef{*nearest} : PBVHVertRef{PBVH_REF_NONE};
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const std::optional<SubdivCCGCoord> nearest = nearest_vert_calc_grids(
@@ -1173,7 +1176,7 @@ PBVHVertRef nearest_vert_calc(const Object &object,
CCG_grid_xy_to_index(key.grid_size, nearest->x, nearest->y)} :
PBVHVertRef{PBVH_REF_NONE};
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const std::optional<BMVert *> nearest = nearest_vert_calc_bmesh(
*ss.pbvh, location, max_distance, use_original);
return nearest ? PBVHVertRef{intptr_t(*nearest)} : PBVHVertRef{PBVH_REF_NONE};
@@ -1325,7 +1328,7 @@ static void orig_vert_data_unode_init(SculptOrigVertData &data,
}
SculptOrigVertData SCULPT_orig_vert_data_init(const Object &ob,
const PBVHNode &node,
const blender::bke::pbvh::Node &node,
const blender::ed::sculpt_paint::undo::Type type)
{
using namespace blender::ed::sculpt_paint;
@@ -1417,7 +1420,7 @@ namespace dyntopo {
bool stroke_is_dyntopo(const SculptSession &ss, const Brush &brush)
{
return ((BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) &&
return ((ss.pbvh->type() == bke::pbvh::Type::BMesh) &&
(!ss.cache || (!ss.cache->alt_smooth)) &&
@@ -1441,16 +1444,16 @@ namespace undo {
static void restore_mask_from_undo_step(Object &object)
{
SculptSession &ss = *object.sculpt;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
bke::SpanAttributeWriter<float> mask = attributes.lookup_or_add_for_write_span<float>(
".sculpt_mask", bke::AttrDomain::Point);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::Mask)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
array_utils::scatter(unode->mask.as_span(), verts, mask.span);
@@ -1461,10 +1464,10 @@ static void restore_mask_from_undo_step(Object &object)
mask.finish();
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const int offset = CustomData_get_offset_named(&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
if (offset != -1) {
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
if (undo::get_node(node, undo::Type::Mask)) {
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
const float orig_mask = BM_log_original_mask(ss.bm_log, vert);
@@ -1476,13 +1479,13 @@ static void restore_mask_from_undo_step(Object &object)
}
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const BitGroupVector<> grid_hidden = subdiv_ccg.grid_hidden;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::Mask)) {
int index = 0;
for (const int grid : unode->grids) {
@@ -1506,16 +1509,16 @@ static void restore_mask_from_undo_step(Object &object)
static void restore_color_from_undo_step(Object &object)
{
SculptSession &ss = *object.sculpt;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
BLI_assert(BKE_pbvh_type(*ss.pbvh) == PBVH_FACES);
BLI_assert(ss.pbvh->type() == bke::pbvh::Type::Mesh);
Mesh &mesh = *static_cast<Mesh *>(object.data);
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = ss.vert_to_face_map;
bke::GSpanAttributeWriter color_attribute = color::active_color_attribute_for_write(mesh);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::Color)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
for (const int i : verts.index_range()) {
@@ -1536,14 +1539,14 @@ static void restore_color_from_undo_step(Object &object)
static void restore_face_set_from_undo_step(Object &object)
{
SculptSession &ss = *object.sculpt;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
case bke::pbvh::Type::Grids: {
bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(object);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::FaceSet)) {
const Span<int> faces = unode->face_indices;
const Span<int> face_sets = unode->face_sets;
@@ -1555,7 +1558,7 @@ static void restore_face_set_from_undo_step(Object &object)
attribute.finish();
break;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
break;
}
}
@@ -1563,10 +1566,10 @@ static void restore_face_set_from_undo_step(Object &object)
void restore_position_from_undo_step(Object &object)
{
SculptSession &ss = *object.sculpt;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
MutableSpan positions_eval = BKE_pbvh_get_vert_positions(*ss.pbvh);
MutableSpan positions_orig = mesh.vert_positions_for_write();
@@ -1581,7 +1584,7 @@ void restore_position_from_undo_step(Object &object)
threading::EnumerableThreadSpecific<LocalData> all_tls;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::Position)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
const Span<float3> undo_positions = unode->position.as_span().take_front(verts.size());
@@ -1618,12 +1621,12 @@ void restore_position_from_undo_step(Object &object)
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
if (!undo::get_bmesh_log_entry()) {
return;
}
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
if (const float *orig_co = BM_log_find_original_vert_co(ss.bm_log, vert)) {
copy_v3_v3(vert->co, orig_co);
@@ -1634,13 +1637,13 @@ void restore_position_from_undo_step(Object &object)
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const BitGroupVector<> grid_hidden = subdiv_ccg.grid_hidden;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
if (const undo::Node *unode = undo::get_node(node, undo::Type::Position)) {
int index = 0;
for (const int grid : unode->grids) {
@@ -1710,7 +1713,7 @@ static void sculpt_extend_redraw_rect_previous(Object &ob, rcti &rect)
* prevent partial-redraw issues caused by fast strokes. This is
* needed here (not in sculpt_flush_update) as it was before
* because redraw rectangle should be the same in both of
* optimized PBVH draw function and 3d view redraw, if not -- some
* optimized bke::pbvh::Tree draw function and 3d view redraw, if not -- some
* mesh parts could disappear from screen (sergey). */
SculptSession &ss = *ob.sculpt;
@@ -1731,7 +1734,7 @@ bool SCULPT_get_redraw_rect(const ARegion &region,
rcti &rect)
{
using namespace blender;
PBVH *pbvh = ob.sculpt->pbvh.get();
bke::pbvh::Tree *pbvh = ob.sculpt->pbvh.get();
if (!pbvh) {
return false;
}
@@ -2127,7 +2130,7 @@ static void calc_area_normal_and_center_node_mesh(const SculptSession &ss,
const Brush &brush,
const bool use_area_nos,
const bool use_area_cos,
const PBVHNode &node,
const bke::pbvh::Node &node,
AreaNormalCenterData &anctd)
{
const float3 &view_normal = ss.cache ? ss.cache->view_normal : ss.cursor_view_normal;
@@ -2207,7 +2210,7 @@ static void calc_area_normal_and_center_node_grids(const SculptSession &ss,
const Brush &brush,
const bool use_area_nos,
const bool use_area_cos,
const PBVHNode &node,
const bke::pbvh::Node &node,
AreaNormalCenterData &anctd)
{
const float3 &view_normal = ss.cache ? ss.cache->view_normal : ss.cursor_view_normal;
@@ -2281,7 +2284,7 @@ static void calc_area_normal_and_center_node_bmesh(const SculptSession &ss,
const bool use_area_nos,
const bool use_area_cos,
const bool has_bm_orco,
const PBVHNode &node,
const bke::pbvh::Node &node,
AreaNormalCenterData &anctd)
{
const float3 &view_normal = ss.cache ? ss.cache->view_normal : ss.cursor_view_normal;
@@ -2309,7 +2312,7 @@ static void calc_area_normal_and_center_node_bmesh(const SculptSession &ss,
int(*orco_tris)[3];
int orco_tris_num;
BKE_pbvh_node_get_bm_orco_data(
&const_cast<PBVHNode &>(node), &orco_tris, &orco_tris_num, &orco_coords, nullptr);
&const_cast<bke::pbvh::Node &>(node), &orco_tris, &orco_tris_num, &orco_coords, nullptr);
for (int i = 0; i < orco_tris_num; i++) {
const float *co_tri[3] = {
@@ -2343,7 +2346,7 @@ static void calc_area_normal_and_center_node_bmesh(const SculptSession &ss,
}
}
else {
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&const_cast<PBVHNode &>(node))) {
for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&const_cast<bke::pbvh::Node &>(node))) {
if (BM_elem_flag_test(vert, BM_ELEM_HIDDEN)) {
continue;
}
@@ -2402,15 +2405,15 @@ static AreaNormalCenterData calc_area_normal_and_center_reduce(const AreaNormalC
void calc_area_center(const Brush &brush,
const Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float r_area_co[3])
{
const SculptSession &ss = *ob.sculpt;
int n;
AreaNormalCenterData anctd;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(*ss.pbvh);
@@ -2438,7 +2441,7 @@ void calc_area_center(const Brush &brush,
calc_area_normal_and_center_reduce);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const bool has_bm_orco = ss.bm && dyntopo::stroke_is_dyntopo(ss, brush);
anctd = threading::parallel_reduce(
@@ -2455,7 +2458,7 @@ void calc_area_center(const Brush &brush,
calc_area_normal_and_center_reduce);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
anctd = threading::parallel_reduce(
nodes.index_range(),
1,
@@ -2492,13 +2495,15 @@ void calc_area_center(const Brush &brush,
}
}
std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVHNode *> nodes)
std::optional<float3> calc_area_normal(const Brush &brush,
Object &ob,
Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
AreaNormalCenterData anctd;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(*ss.pbvh);
@@ -2526,7 +2531,7 @@ std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVH
calc_area_normal_and_center_reduce);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const bool has_bm_orco = ss.bm && dyntopo::stroke_is_dyntopo(ss, brush);
anctd = threading::parallel_reduce(
@@ -2543,7 +2548,7 @@ std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVH
calc_area_normal_and_center_reduce);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
anctd = threading::parallel_reduce(
nodes.index_range(),
1,
@@ -2571,7 +2576,7 @@ std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVH
void calc_area_normal_and_center(const Brush &brush,
const Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float r_area_no[3],
float r_area_co[3])
{
@@ -2579,8 +2584,8 @@ void calc_area_normal_and_center(const Brush &brush,
int n;
AreaNormalCenterData anctd;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(*ss.pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(*ss.pbvh);
@@ -2608,7 +2613,7 @@ void calc_area_normal_and_center(const Brush &brush,
calc_area_normal_and_center_reduce);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const bool has_bm_orco = ss.bm && dyntopo::stroke_is_dyntopo(ss, brush);
anctd = threading::parallel_reduce(
@@ -2625,7 +2630,7 @@ void calc_area_normal_and_center(const Brush &brush,
calc_area_normal_and_center_reduce);
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
anctd = threading::parallel_reduce(
nodes.index_range(),
1,
@@ -2984,7 +2989,7 @@ void SCULPT_calc_vertex_displacement(const SculptSession &ss,
namespace blender::ed::sculpt_paint {
bool node_fully_masked_or_hidden(const PBVHNode &node)
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node)
{
if (BKE_pbvh_node_fully_hidden_get(&node)) {
return true;
@@ -2995,7 +3000,7 @@ bool node_fully_masked_or_hidden(const PBVHNode &node)
return false;
}
bool node_in_sphere(const PBVHNode &node,
bool node_in_sphere(const bke::pbvh::Node &node,
const float3 &location,
const float radius_sq,
const bool original)
@@ -3007,7 +3012,7 @@ bool node_in_sphere(const PBVHNode &node,
}
bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc,
const PBVHNode &node,
const bke::pbvh::Node &node,
const float radius_sq,
const bool original)
{
@@ -3022,17 +3027,17 @@ bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc,
return dist_sq < radius_sq || true;
}
static Vector<PBVHNode *> sculpt_pbvh_gather_cursor_update(Object &ob, bool use_original)
static Vector<bke::pbvh::Node *> sculpt_pbvh_gather_cursor_update(Object &ob, bool use_original)
{
SculptSession &ss = *ob.sculpt;
const float3 center = ss.cache ? ss.cache->location : ss.cursor_location;
return bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
return bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_sphere(node, center, ss.cursor_radius, use_original);
});
}
/** \return All nodes that are potentially within the cursor or brush's area of influence. */
static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(
static Vector<bke::pbvh::Node *> sculpt_pbvh_gather_generic_intern(
Object &ob, const Brush &brush, bool use_original, float radius_scale, PBVHNodeFlags flag)
{
SculptSession &ss = *ob.sculpt;
@@ -3049,7 +3054,7 @@ static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(
case PAINT_FALLOFF_SHAPE_SPHERE: {
return bke::pbvh::search_gather(
*ss.pbvh,
[&](PBVHNode &node) {
[&](bke::pbvh::Node &node) {
if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
return false;
}
@@ -3063,7 +3068,7 @@ static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(
center, ss.cache->view_normal);
return bke::pbvh::search_gather(
*ss.pbvh,
[&](PBVHNode &node) {
[&](bke::pbvh::Node &node) {
if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
return false;
}
@@ -3076,24 +3081,24 @@ static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(
return {};
}
static Vector<PBVHNode *> sculpt_pbvh_gather_generic(Object &ob,
const Brush &brush,
const bool use_original,
const float radius_scale)
static Vector<bke::pbvh::Node *> sculpt_pbvh_gather_generic(Object &ob,
const Brush &brush,
const bool use_original,
const float radius_scale)
{
return sculpt_pbvh_gather_generic_intern(ob, brush, use_original, radius_scale, PBVH_Leaf);
}
static Vector<PBVHNode *> sculpt_pbvh_gather_texpaint(Object &ob,
const Brush &brush,
const bool use_original,
const float radius_scale)
static Vector<bke::pbvh::Node *> sculpt_pbvh_gather_texpaint(Object &ob,
const Brush &brush,
const bool use_original,
const float radius_scale)
{
return sculpt_pbvh_gather_generic_intern(ob, brush, use_original, radius_scale, PBVH_TexLeaf);
}
/* Calculate primary direction of movement for many brushes. */
static float3 calc_sculpt_normal(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
static float3 calc_sculpt_normal(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
const SculptSession &ss = *ob.sculpt;
@@ -3113,7 +3118,7 @@ static float3 calc_sculpt_normal(const Sculpt &sd, Object &ob, Span<PBVHNode *>
return {};
}
static void update_sculpt_normal(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
static void update_sculpt_normal(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
StrokeCache &cache = *ob.sculpt->cache;
@@ -3455,8 +3460,11 @@ bool SCULPT_tool_needs_all_pbvh_nodes(const Brush &brush)
namespace blender::ed::sculpt_paint {
void calc_brush_plane(
const Brush &brush, Object &ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
void calc_brush_plane(const Brush &brush,
Object &ob,
Span<bke::pbvh::Node *> nodes,
float r_area_no[3],
float r_area_co[3])
{
const SculptSession &ss = *ob.sculpt;
@@ -3619,7 +3627,8 @@ static void sculpt_topology_update(const Scene & /*scene*/,
const bool use_original = sculpt_tool_needs_original(brush.sculpt_tool) ? true :
!ss.cache->accum;
const float radius_scale = 1.25f;
Vector<PBVHNode *> nodes = sculpt_pbvh_gather_generic(ob, brush, use_original, radius_scale);
Vector<bke::pbvh::Node *> nodes = sculpt_pbvh_gather_generic(
ob, brush, use_original, radius_scale);
/* Only act if some verts are inside the brush area. */
if (nodes.is_empty()) {
@@ -3643,7 +3652,7 @@ static void sculpt_topology_update(const Scene & /*scene*/,
}
}
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(
ob, node, brush.sculpt_tool == SCULPT_TOOL_MASK ? undo::Type::Mask : undo::Type::Position);
BKE_pbvh_node_mark_update(node);
@@ -3665,14 +3674,14 @@ static void sculpt_topology_update(const Scene & /*scene*/,
mul_m4_v3(ob.object_to_world().ptr(), location);
}
static void push_undo_nodes(Object &ob, const Brush &brush, const Span<PBVHNode *> nodes)
static void push_undo_nodes(Object &ob, const Brush &brush, const Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
bool need_coords = ss.cache->supports_gravity;
if (brush.sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) {
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_face_sets(node);
}
@@ -3686,7 +3695,7 @@ static void push_undo_nodes(Object &ob, const Brush &brush, const Span<PBVHNode
}
else if (brush.sculpt_tool == SCULPT_TOOL_MASK) {
undo::push_nodes(ob, nodes, undo::Type::Mask);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_mask(node);
}
}
@@ -3698,7 +3707,7 @@ static void push_undo_nodes(Object &ob, const Brush &brush, const Span<PBVHNode
}
}
undo::push_nodes(ob, nodes, undo::Type::Color);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_color(node);
}
}
@@ -3708,7 +3717,7 @@ static void push_undo_nodes(Object &ob, const Brush &brush, const Span<PBVHNode
if (need_coords) {
undo::push_nodes(ob, nodes, undo::Type::Position);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_positions_update(node);
}
}
@@ -3722,7 +3731,7 @@ static void do_brush_action(const Scene &scene,
PaintModeSettings &paint_mode_settings)
{
SculptSession &ss = *ob.sculpt;
Vector<PBVHNode *> nodes, texnodes;
Vector<bke::pbvh::Node *> nodes, texnodes;
const bool use_original = sculpt_tool_needs_original(brush.sculpt_tool) ? true :
!ss.cache->accum;
@@ -3781,7 +3790,7 @@ static void do_brush_action(const Scene &scene,
}
/* For anchored brushes with spherical falloff, we start off with zero radius, thus we have no
* PBVH nodes on the first brush step. */
* bke::pbvh::Tree nodes on the first brush step. */
if (!nodes.is_empty() ||
((brush.falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) && (brush.flag & BRUSH_ANCHORED)))
{
@@ -4031,7 +4040,7 @@ static void do_brush_action(const Scene &scene,
ups.last_stroke_valid = true;
}
/* Flush displacement from deformed PBVH vertex to original mesh. */
/* Flush displacement from deformed bke::pbvh::Tree vertex to original mesh. */
static void sculpt_flush_pbvhvert_deform(SculptSession &ss,
const PBVHVertexIter &vd,
MutableSpan<float3> positions)
@@ -4054,7 +4063,7 @@ static void sculpt_flush_pbvhvert_deform(SculptSession &ss,
} // namespace blender::ed::sculpt_paint
/**
* Copy the modified vertices from the #PBVH to the active key.
* Copy the modified vertices from the #bke::pbvh::Tree to the active key.
*/
static void sculpt_update_keyblock(Object &ob)
{
@@ -4081,7 +4090,7 @@ void SCULPT_flush_stroke_deform(const Sculpt & /*sd*/, Object &ob, bool is_proxy
* deformation to original base. */
Mesh *mesh = (Mesh *)ob.data;
Vector<PBVHNode *> nodes;
Vector<bke::pbvh::Node *> nodes;
Array<float3> vertCos;
if (ss.shapekey_active) {
@@ -5136,7 +5145,7 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object &ob, const Brush &b
}
}
static void sculpt_raycast_cb(PBVHNode &node, SculptRaycastData &srd, float *tmin)
static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData &srd, float *tmin)
{
using namespace blender;
using namespace blender::ed::sculpt_paint;
@@ -5147,7 +5156,7 @@ static void sculpt_raycast_cb(PBVHNode &node, SculptRaycastData &srd, float *tmi
bool use_origco = false;
if (srd.original && srd.ss->cache) {
if (BKE_pbvh_type(*srd.ss->pbvh) == PBVH_BMESH) {
if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) {
use_origco = true;
}
else {
@@ -5179,7 +5188,7 @@ static void sculpt_raycast_cb(PBVHNode &node, SculptRaycastData &srd, float *tmi
}
}
static void sculpt_find_nearest_to_ray_cb(PBVHNode &node,
static void sculpt_find_nearest_to_ray_cb(blender::bke::pbvh::Node &node,
SculptFindNearestToRayData &srd,
float *tmin)
{
@@ -5192,7 +5201,7 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode &node,
bool use_origco = false;
if (srd.original && srd.ss->cache) {
if (BKE_pbvh_type(*srd.ss->pbvh) == PBVH_BMESH) {
if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) {
use_origco = true;
}
else {
@@ -5293,7 +5302,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
return false;
}
/* PBVH raycast to get active vertex and face normal. */
/* bke::pbvh::Tree raycast to get active vertex and face normal. */
depth = SCULPT_raycast_init(&vc, mval, ray_start, ray_end, ray_normal, original);
SCULPT_stroke_modifiers_check(C, ob, brush);
@@ -5301,7 +5310,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
srd.original = original;
srd.ss = ob.sculpt;
srd.hit = false;
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
srd.corner_verts = mesh.corner_verts();
srd.corner_tris = mesh.corner_tris();
@@ -5317,7 +5326,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
bke::pbvh::raycast(
*ss.pbvh,
[&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
[&](bke::pbvh::Node &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
ray_start,
ray_normal,
srd.original);
@@ -5335,16 +5344,16 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
SCULPT_vertex_random_access_ensure(ss);
copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss));
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
ss.active_face_index = srd.active_face_grid_index;
ss.active_grid_index = 0;
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
ss.active_face_index = 0;
ss.active_grid_index = srd.active_face_grid_index;
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
ss.active_face_index = 0;
ss.active_grid_index = 0;
break;
@@ -5383,7 +5392,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
}
ss.cursor_radius = radius;
Vector<PBVHNode *> nodes = sculpt_pbvh_gather_cursor_update(ob, original);
Vector<bke::pbvh::Node *> nodes = sculpt_pbvh_gather_cursor_update(ob, original);
/* In case there are no nodes under the cursor, return the face normal. */
if (nodes.is_empty()) {
@@ -5440,7 +5449,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
depth = SCULPT_raycast_init(&vc, mval, ray_start, ray_end, ray_normal, original);
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
BM_mesh_elem_table_ensure(ss.bm, BM_VERT);
BM_mesh_elem_index_ensure(ss.bm, BM_VERT);
}
@@ -5452,7 +5461,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
srd.ray_start = ray_start;
srd.ray_normal = ray_normal;
srd.hit = false;
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
srd.corner_verts = mesh.corner_verts();
srd.corner_tris = mesh.corner_tris();
@@ -5467,7 +5476,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
bke::pbvh::raycast(
*ss.pbvh,
[&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
[&](bke::pbvh::Node &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
ray_start,
ray_normal,
srd.original);
@@ -5487,7 +5496,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
srd.original = original;
srd.ss = ob.sculpt;
srd.hit = false;
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
srd.corner_verts = mesh.corner_verts();
srd.corner_tris = mesh.corner_tris();
@@ -5502,7 +5511,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C,
bke::pbvh::find_nearest_to_ray(
*ss.pbvh,
[&](PBVHNode &node, float *tmin) { sculpt_find_nearest_to_ray_cb(node, srd, tmin); },
[&](bke::pbvh::Node &node, float *tmin) { sculpt_find_nearest_to_ray_cb(node, srd, tmin); },
ray_start,
ray_normal,
srd.original);
@@ -5634,7 +5643,7 @@ void flush_update_step(bContext *C, UpdateType update_type)
ED_region_tag_redraw(&region);
if (update_type == UpdateType::Image) {
/* Early exit when only need to update the images. We don't want to tag any geometry updates
* that would rebuilt the PBVH. */
* that would rebuilt the bke::pbvh::Tree. */
return;
}
}
@@ -5677,15 +5686,16 @@ void flush_update_step(bContext *C, UpdateType update_type)
}
if (update_type == UpdateType::Position && !ss.shapekey_active) {
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
/* Updating mesh positions without marking caches dirty is generally not good, but since
* sculpt mode has special requirements and is expected to have sole ownership of the mesh it
* modifies, it's generally okay. */
if (use_pbvh_draw) {
/* When drawing from PBVH is used, vertex and face normals are updated later in
* #bke::pbvh::update_normals. However, we update the mesh's bounds eagerly here since they
* are trivial to access from the PBVH. Updating the object's evaluated geometry bounding
* box is necessary because sculpt strokes don't cause an object reevaluation. */
/* When drawing from bke::pbvh::Tree is used, vertex and face normals are updated
* later in #bke::pbvh::update_normals. However, we update the mesh's bounds eagerly here
* since they are trivial to access from the bke::pbvh::Tree. Updating the
* object's evaluated geometry bounding box is necessary because sculpt strokes don't cause
* an object reevaluation. */
mesh->tag_positions_changed_no_normals();
/* Sculpt mode does not use or recalculate face corner normals, so they are cleared. */
mesh->runtime->corner_normals_cache.tag_dirty();
@@ -5769,7 +5779,7 @@ void flush_update_done(const bContext *C, Object &ob, UpdateType update_type)
BKE_sculpt_attributes_destroy_temporary_stroke(&ob);
if (update_type == UpdateType::Position) {
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
BKE_pbvh_bmesh_after_stroke(*ss.pbvh);
}
@@ -5839,13 +5849,13 @@ static void sculpt_stroke_undo_end(const bContext *C, Brush *brush)
bool SCULPT_handles_colors_report(SculptSession &ss, ReportList *reports)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
return true;
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
BKE_report(reports, RPT_ERROR, "Not supported in dynamic topology mode");
return false;
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
BKE_report(reports, RPT_ERROR, "Not supported in multiresolution mode");
return false;
}
@@ -5957,7 +5967,7 @@ static void sculpt_stroke_update_step(bContext *C,
SCULPT_TOOL_CLOTH,
SCULPT_TOOL_POSE,
SCULPT_TOOL_SMOOTH) ||
BKE_pbvh_type(*ss.pbvh) != PBVH_FACES))
ss.pbvh->type() != bke::pbvh::Type::Mesh))
{
if (ss.deform_modifiers_active) {
SCULPT_flush_stroke_deform(sd, ob, sculpt_tool_is_proxy_used(brush.sculpt_tool));
@@ -6087,7 +6097,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
if (ELEM(brush.sculpt_tool, SCULPT_TOOL_DISPLACEMENT_SMEAR, SCULPT_TOOL_DISPLACEMENT_ERASER)) {
if (!ss.pbvh || BKE_pbvh_type(*ss.pbvh) != PBVH_GRIDS) {
if (!ss.pbvh || ss.pbvh->type() != bke::pbvh::Type::Grids) {
BKE_report(op->reports, RPT_ERROR, "Only supported in multiresolution mode");
return OPERATOR_CANCELLED;
}
@@ -6267,7 +6277,7 @@ struct NearestVertexFakeNeighborData {
static void do_fake_neighbor_search_task(SculptSession &ss,
const float nearest_vertex_search_co[3],
const float max_distance_sq,
PBVHNode *node,
bke::pbvh::Node *node,
NearestVertexFakeNeighborData *nvtd)
{
PBVHVertexIter vd;
@@ -6295,7 +6305,7 @@ static PBVHVertRef fake_neighbor_search(Object &ob, const PBVHVertRef vertex, fl
const float3 center = SCULPT_vertex_co_get(ss, vertex);
const float max_distance_sq = max_distance * max_distance;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_sphere(node, center, max_distance_sq, false);
});
if (nodes.is_empty()) {
@@ -6450,7 +6460,7 @@ bool SCULPT_vertex_is_occluded(SculptSession &ss, PBVHVertRef vertex, bool origi
srd.depth = depth;
srd.face_normal = face_normal;
srd.corner_verts = ss.corner_verts;
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
srd.corner_tris = BKE_pbvh_get_mesh(*ss.pbvh)->corner_tris();
srd.corner_tri_faces = BKE_pbvh_get_mesh(*ss.pbvh)->corner_tri_faces();
}
@@ -6458,7 +6468,7 @@ bool SCULPT_vertex_is_occluded(SculptSession &ss, PBVHVertRef vertex, bool origi
isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
bke::pbvh::raycast(
*ss.pbvh,
[&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
[&](bke::pbvh::Node &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
ray_start,
ray_normal,
srd.original);
@@ -6510,7 +6520,9 @@ void SCULPT_topology_islands_ensure(Object &ob)
using namespace blender::ed::sculpt_paint;
SculptSession &ss = *ob.sculpt;
if (ss.attrs.topology_island_key && ss.islands_valid && BKE_pbvh_type(*ss.pbvh) != PBVH_BMESH) {
if (ss.attrs.topology_island_key && ss.islands_valid &&
ss.pbvh->type() != bke::pbvh::Type::BMesh)
{
return;
}
@@ -6752,7 +6764,7 @@ void fill_factor_from_hide(const Mesh &mesh,
{
BLI_assert(verts.size() == r_factors.size());
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const bke::AttributeAccessor attributes = mesh.attributes();
if (const VArray hide_vert = *attributes.lookup<bool>(".hide_vert", bke::AttrDomain::Point)) {
const VArraySpan span(hide_vert);
@@ -6803,7 +6815,7 @@ void fill_factor_from_hide_and_mask(const Mesh &mesh,
{
BLI_assert(verts.size() == r_factors.size());
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const bke::AttributeAccessor attributes = mesh.attributes();
if (const VArray mask = *attributes.lookup<float>(".sculpt_mask", bke::AttrDomain::Point)) {
const VArraySpan span(mask);
@@ -6831,7 +6843,7 @@ void fill_factor_from_hide_and_mask(const BMesh &bm,
{
BLI_assert(verts.size() == r_factors.size());
/* TODO: Avoid overhead of accessing attributes for every PBVH node. */
/* TODO: Avoid overhead of accessing attributes for every bke::pbvh::Tree node. */
const int mask_offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
int i = 0;
for (const BMVert *vert : verts) {
@@ -7389,7 +7401,9 @@ void apply_translations_to_shape_keys(Object &object,
}
}
void apply_translations_to_pbvh(PBVH &pbvh, Span<int> verts, const Span<float3> translations)
void apply_translations_to_pbvh(bke::pbvh::Tree &pbvh,
Span<int> verts,
const Span<float3> translations)
{
if (!BKE_pbvh_is_deformed(pbvh)) {
return;
@@ -7489,7 +7503,7 @@ void transform_positions(const Span<float3> src,
}
}
OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes, Array<int> &node_data)
OffsetIndices<int> create_node_vert_offsets(Span<bke::pbvh::Node *> nodes, Array<int> &node_data)
{
node_data.reinitialize(nodes.size() + 1);
for (const int i : nodes.index_range()) {
@@ -7498,7 +7512,7 @@ OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes, Array<int> &
return offset_indices::accumulate_counts_to_offsets(node_data);
}
OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes,
OffsetIndices<int> create_node_vert_offsets(Span<bke::pbvh::Node *> nodes,
const CCGKey &key,
Array<int> &node_data)
{
@@ -7509,7 +7523,8 @@ OffsetIndices<int> create_node_vert_offsets(Span<PBVHNode *> nodes,
return offset_indices::accumulate_counts_to_offsets(node_data);
}
OffsetIndices<int> create_node_vert_offsets_bmesh(Span<PBVHNode *> nodes, Array<int> &node_data)
OffsetIndices<int> create_node_vert_offsets_bmesh(Span<bke::pbvh::Node *> nodes,
Array<int> &node_data)
{
node_data.reinitialize(nodes.size() + 1);
for (const int i : nodes.index_range()) {

View File

@@ -598,7 +598,7 @@ static void mesh_orig_vert_data_update(SculptOrigVertData &orig_data, const int
void calc_vert_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Span<int> verts,
const MutableSpan<float> factors)
{
@@ -618,7 +618,7 @@ void calc_face_factors(const Object &object,
const OffsetIndices<int> faces,
const Span<int> corner_verts,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Span<int> face_indices,
const MutableSpan<float> factors)
{
@@ -644,7 +644,7 @@ void calc_face_factors(const Object &object,
void calc_grids_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Span<int> grids,
const MutableSpan<float> factors)
{
@@ -668,7 +668,7 @@ void calc_grids_factors(const Object &object,
void calc_vert_factors(const Object &object,
const Cache &cache,
const PBVHNode &node,
const bke::pbvh::Node &node,
const Set<BMVert *, 0> &verts,
const MutableSpan<float> factors)
{
@@ -687,7 +687,7 @@ void calc_vert_factors(const Object &object,
}
}
NodeData node_begin(const Object &object, const Cache *automasking, const PBVHNode &node)
NodeData node_begin(const Object &object, const Cache *automasking, const bke::pbvh::Node &node)
{
if (!automasking) {
return {};

View File

@@ -348,7 +348,7 @@ static void edit_data_init(SculptSession &ss,
{
const int totvert = SCULPT_vertex_count_get(ss);
const bool has_duplicates = BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS;
const bool has_duplicates = ss.pbvh->type() == bke::pbvh::Type::Grids;
boundary.edit_info = Array<SculptBoundaryEditInfo>(totvert);
@@ -580,7 +580,7 @@ static float displacement_from_grab_delta_get(SculptSession &ss, SculptBoundary
return dist_signed_to_plane_v3(pos, plane);
}
static void boundary_brush_bend_task(Object &ob, const Brush &brush, PBVHNode *node)
static void boundary_brush_bend_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symm_area = ss.cache->mirror_symmetry_pass;
@@ -628,7 +628,7 @@ static void boundary_brush_bend_task(Object &ob, const Brush &brush, PBVHNode *n
BKE_pbvh_vertex_iter_end;
}
static void brush_slide_task(Object &ob, const Brush &brush, PBVHNode *node)
static void brush_slide_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symm_area = ss.cache->mirror_symmetry_pass;
@@ -668,7 +668,7 @@ static void brush_slide_task(Object &ob, const Brush &brush, PBVHNode *node)
BKE_pbvh_vertex_iter_end;
}
static void brush_inflate_task(Object &ob, const Brush &brush, PBVHNode *node)
static void brush_inflate_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symm_area = ss.cache->mirror_symmetry_pass;
@@ -708,7 +708,7 @@ static void brush_inflate_task(Object &ob, const Brush &brush, PBVHNode *node)
BKE_pbvh_vertex_iter_end;
}
static void brush_grab_task(Object &ob, const Brush &brush, PBVHNode *node)
static void brush_grab_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symm_area = ss.cache->mirror_symmetry_pass;
@@ -745,7 +745,7 @@ static void brush_grab_task(Object &ob, const Brush &brush, PBVHNode *node)
BKE_pbvh_vertex_iter_end;
}
static void brush_twist_task(Object &ob, const Brush &brush, PBVHNode *node)
static void brush_twist_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symm_area = ss.cache->mirror_symmetry_pass;
@@ -793,7 +793,7 @@ static void brush_twist_task(Object &ob, const Brush &brush, PBVHNode *node)
BKE_pbvh_vertex_iter_end;
}
static void brush_smooth_task(Object &ob, const Brush &brush, PBVHNode *node)
static void brush_smooth_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const int symmetry_pass = ss.cache->mirror_symmetry_pass;
@@ -907,7 +907,7 @@ static void init_falloff(SculptSession &ss,
}
}
void do_boundary_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_boundary_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);

View File

@@ -78,7 +78,7 @@ static void cloth_brush_simulation_location_get(const SculptSession &ss,
copy_v3_v3(r_location, ss.cache->location);
}
Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession &ss, const Brush &brush)
Vector<bke::pbvh::Node *> brush_affected_nodes_gather(SculptSession &ss, const Brush &brush)
{
BLI_assert(ss.cache);
BLI_assert(brush.sculpt_tool == SCULPT_TOOL_CLOTH);
@@ -87,7 +87,7 @@ Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession &ss, const Brush &b
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
const float radius_squared = math::square(ss.cache->initial_radius *
(1.0 + brush.cloth_sim_limit));
return bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
return bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_sphere(node, ss.cache->initial_location, radius_squared, false);
});
}
@@ -95,7 +95,7 @@ Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession &ss, const Brush &b
return bke::pbvh::search_gather(*ss.pbvh, {});
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
const float radius_squared = math::square(ss.cache->radius * (1.0 + brush.cloth_sim_limit));
return bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
return bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return node_in_sphere(node, ss.cache->location, radius_squared, false);
});
}
@@ -276,7 +276,7 @@ static void do_cloth_brush_build_constraints_task(Object &ob,
SimulationData &cloth_sim,
float *cloth_sim_initial_location,
float cloth_sim_radius,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
@@ -410,7 +410,7 @@ static void do_cloth_brush_apply_forces_task(Object &ob,
const float *grab_delta,
float (*imat)[4],
float *area_co,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
SimulationData &cloth_sim = *ss.cache->cloth_sim;
@@ -698,7 +698,7 @@ static void do_cloth_brush_solve_simulation_task(Object &ob,
const Brush *brush,
SimulationData &cloth_sim,
const float time_step,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
@@ -765,15 +765,15 @@ static float get_vert_mask(const SculptSession &ss,
const SimulationData &cloth_sim,
const int vert_index)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
return cloth_sim.mask_mesh.is_empty() ? 0.0f : cloth_sim.mask_mesh[vert_index];
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
return cloth_sim.mask_cd_offset_bmesh == -1 ?
0.0f :
BM_ELEM_CD_GET_FLOAT(BM_vert_at_index(BKE_pbvh_get_bmesh(*ss.pbvh), vert_index),
BM_ELEM_CD_GET_FLOAT(BM_vert_at_index(ss.bm, vert_index),
cloth_sim.mask_cd_offset_bmesh);
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
return SCULPT_mask_get_at_grids_vert_index(*ss.subdiv_ccg, cloth_sim.grid_key, vert_index);
}
BLI_assert_unreachable();
@@ -887,7 +887,7 @@ static void cloth_brush_satisfy_constraints(SculptSession &ss,
void do_simulation_step(const Sculpt &sd,
Object &ob,
SimulationData &cloth_sim,
Span<PBVHNode *> nodes)
Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
@@ -903,7 +903,9 @@ void do_simulation_step(const Sculpt &sd,
});
}
static void cloth_brush_apply_brush_foces(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
static void cloth_brush_apply_brush_foces(const Sculpt &sd,
Object &ob,
Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -975,7 +977,7 @@ static void cloth_brush_apply_brush_foces(const Sculpt &sd, Object &ob, Span<PBV
* them. */
static void cloth_sim_initialize_default_node_state(SculptSession &ss, SimulationData &cloth_sim)
{
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
cloth_sim.node_state = Array<NodeSimState>(nodes.size());
cloth_sim.node_state_index = BLI_ghash_ptr_new("node sim state indices");
@@ -1025,18 +1027,18 @@ std::unique_ptr<SimulationData> brush_simulation_create(Object &ob,
cloth_sim_initialize_default_node_state(ss, *cloth_sim);
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh *mesh = static_cast<const Mesh *>(ob.data);
const bke::AttributeAccessor attributes = mesh->attributes();
cloth_sim->mask_mesh = *attributes.lookup<float>(".sculpt_mask", bke::AttrDomain::Point);
break;
}
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
cloth_sim->mask_cd_offset_bmesh = CustomData_get_offset_named(
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
cloth_sim->grid_key = BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg);
break;
}
@@ -1046,7 +1048,7 @@ std::unique_ptr<SimulationData> brush_simulation_create(Object &ob,
void ensure_nodes_constraints(const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
SimulationData &cloth_sim,
/* Cannot be `const`, because it is assigned to a `non-const`
* variable. NOLINTNEXTLINE: readability-non-const-parameter. */
@@ -1102,10 +1104,10 @@ void brush_store_simulation_state(const SculptSession &ss, SimulationData &cloth
}
}
void sim_activate_nodes(SimulationData &cloth_sim, Span<PBVHNode *> nodes)
void sim_activate_nodes(SimulationData &cloth_sim, Span<bke::pbvh::Node *> nodes)
{
/* Activate the nodes inside the simulation area. */
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim.node_state_index, node));
cloth_sim.node_state[node_index] = SCULPT_CLOTH_NODE_ACTIVE;
}
@@ -1113,7 +1115,7 @@ void sim_activate_nodes(SimulationData &cloth_sim, Span<PBVHNode *> nodes)
static void sculpt_cloth_ensure_constraints_in_simulation_area(const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes)
Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
@@ -1124,7 +1126,7 @@ static void sculpt_cloth_ensure_constraints_in_simulation_area(const Sculpt &sd,
ensure_nodes_constraints(sd, ob, nodes, *ss.cache->cloth_sim, sim_location, limit);
}
void do_cloth_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_cloth_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
@@ -1339,7 +1341,7 @@ static void cloth_filter_apply_forces_task(Object &ob,
const Sculpt &sd,
const eSculptClothFilterType filter_type,
const float filter_strength,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
@@ -1473,7 +1475,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
/* Update and write the simulation to the nodes. */
do_simulation_step(sd, ob, *ss.filter_cache->cloth_sim, ss.filter_cache->nodes);
for (PBVHNode *node : ss.filter_cache->nodes) {
for (bke::pbvh::Node *node : ss.filter_cache->nodes) {
BKE_pbvh_node_mark_positions_update(node);
}

View File

@@ -103,13 +103,13 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
if (nodes.is_empty()) {
return OPERATOR_CANCELLED;
}
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_topology_update(node);
}
/* Get the bounding box, its center and size. */
@@ -131,7 +131,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
while (bke::pbvh::bmesh_update_topology(
*ss.pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false))
{
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_topology_update(node);
}
}
@@ -140,7 +140,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
undo::push_end(ob);
/* Force rebuild of PBVH for better BB placement. */
/* Force rebuild of bke::pbvh::Tree for better BB placement. */
SCULPT_pbvh_clear(ob);
/* Redraw. */
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, &ob);
@@ -210,7 +210,9 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2])
}
}
static void sculpt_raycast_detail_cb(PBVHNode &node, SculptDetailRaycastData &srd, float *tmin)
static void sculpt_raycast_detail_cb(bke::pbvh::Node &node,
SculptDetailRaycastData &srd,
float *tmin)
{
if (BKE_pbvh_node_get_tmin(&node) < *tmin) {
if (bke::pbvh::bmesh_node_raycast_detail(
@@ -243,7 +245,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, const int mval[2
bke::pbvh::raycast(
*ob.sculpt->pbvh,
[&](PBVHNode &node, float *tmin) { sculpt_raycast_detail_cb(node, srd, tmin); },
[&](bke::pbvh::Node &node, float *tmin) { sculpt_raycast_detail_cb(node, srd, tmin); },
ray_start,
ray_normal,
false);
@@ -297,7 +299,7 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode)
/* Pick sample detail. */
switch (mode) {
case SAMPLE_DETAIL_DYNTOPO:
if (BKE_pbvh_type(*ss.pbvh) != PBVH_BMESH) {
if (ss.pbvh->type() != bke::pbvh::Type::BMesh) {
CTX_wm_area_set(C, prev_area);
CTX_wm_region_set(C, prev_region);
return OPERATOR_CANCELLED;
@@ -305,7 +307,7 @@ static int sample_detail(bContext *C, const int event_xy[2], int mode)
sample_detail_dyntopo(C, &vc, mval);
break;
case SAMPLE_DETAIL_VOXEL:
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != bke::pbvh::Type::Mesh) {
CTX_wm_area_set(C, prev_area);
CTX_wm_region_set(C, prev_region);
return OPERATOR_CANCELLED;

View File

@@ -46,12 +46,12 @@ void SCULPT_pbvh_clear(Object &ob)
{
using namespace blender;
SculptSession &ss = *ob.sculpt;
/* Clear out any existing DM and PBVH. */
/* Clear out any existing DM and bke::pbvh::Tree. */
bke::pbvh::free(ss.pbvh);
BKE_object_free_derived_caches(&ob);
/* Tag to rebuild PBVH in depsgraph. */
/* Tag to rebuild bke::pbvh::Tree in depsgraph. */
DEG_id_tag_update(&ob.id, ID_RECALC_GEOMETRY);
}
@@ -109,7 +109,7 @@ void enable_ex(Main &bmain, Depsgraph &depsgraph, Object &ob)
ss.bm_log = BM_log_create(ss.bm);
/* Update dependency graph, so modifiers that depend on dyntopo being enabled
* are re-evaluated and the PBVH is re-created. */
* are re-evaluated and the bke::pbvh::Tree is re-created. */
DEG_id_tag_update(&ob.id, ID_RECALC_GEOMETRY);
BKE_scene_graph_update_tagged(&depsgraph, &bmain);
}
@@ -167,7 +167,7 @@ static void disable(
BKE_ptcache_object_reset(&scene, &ob, PTCACHE_RESET_OUTDATED);
/* Update dependency graph, so modifiers that depend on dyntopo being enabled
* are re-evaluated and the PBVH is re-created. */
* are re-evaluated and the bke::pbvh::Tree is re-created. */
DEG_id_tag_update(&ob.id, ID_RECALC_GEOMETRY);
BKE_scene_graph_update_tagged(&depsgraph, &bmain);
}

View File

@@ -150,15 +150,15 @@ static bool is_face_in_active_component(const SculptSession &ss,
{
PBVHVertRef vertex;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
vertex.i = corner_verts[faces[f].start()];
break;
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
vertex.i = faces[f].start() * BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg).grid_area;
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
vertex.i = reinterpret_cast<intptr_t>(ss.bm->ftable[f]->l_first->v);
break;
}
@@ -529,7 +529,7 @@ static bool normal_floodfill_fn(SculptSession &ss,
CLAMP(data->dists[to_v_i], 0.0f, 1.0f);
}
else {
/* PBVH_GRIDS duplicate handling. */
/* bke::pbvh::Type::Grids duplicate handling. */
data->edge_factor[to_v_i] = data->edge_factor[from_v_i];
data->dists[to_v_i] = data->dists[from_v_i];
}
@@ -692,7 +692,7 @@ static Array<float> diagonals_falloff_create(Object &ob, const PBVHVertRef v)
/* This algorithm uses mesh data (faces and loops), so this falloff type can't be initialized for
* Multires. It also does not make sense to implement it for dyntopo as the result will be the
* same as Topology falloff. */
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != bke::pbvh::Type::Mesh) {
return dists;
}
@@ -839,10 +839,10 @@ static void vert_to_face_falloff(SculptSession &ss, Mesh *mesh, Cache *expand_ca
MEM_malloc_arrayN(mesh->faces_num, sizeof(float), __func__));
}
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
vert_to_face_falloff_mesh(mesh, expand_cache);
}
else if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
else if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
vert_to_face_falloff_grids(ss, mesh, expand_cache);
}
else {
@@ -862,7 +862,7 @@ static void geodesics_from_state_boundary(Object &ob,
const BitSpan enabled_verts)
{
SculptSession &ss = *ob.sculpt;
BLI_assert(BKE_pbvh_type(*ss.pbvh) == PBVH_FACES);
BLI_assert(ss.pbvh->type() == bke::pbvh::Type::Mesh);
Set<int> initial_verts;
const BitVector<> boundary_verts = boundary_from_enabled(ss, enabled_verts, false);
@@ -920,7 +920,7 @@ static void resursion_step_add(Object &ob,
const eSculptExpandRecursionType recursion_type)
{
SculptSession &ss = *ob.sculpt;
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != bke::pbvh::Type::Mesh) {
return;
}
@@ -975,7 +975,7 @@ static void init_from_face_set_boundary(Object &ob,
enabled_verts[i].set();
}
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
geodesics_from_state_boundary(ob, expand_cache, enabled_verts);
}
else {
@@ -1028,7 +1028,7 @@ static void calc_falloff_from_vert_and_symmetry(Cache *expand_cache,
expand_cache->falloff_type = falloff_type;
SculptSession &ss = *ob.sculpt;
const bool has_topology_info = BKE_pbvh_type(*ss.pbvh) == PBVH_FACES;
const bool has_topology_info = ss.pbvh->type() == bke::pbvh::Type::Mesh;
switch (falloff_type) {
case SCULPT_EXPAND_FALLOFF_GEODESIC:
@@ -1079,7 +1079,7 @@ static void calc_falloff_from_vert_and_symmetry(Cache *expand_cache,
*/
static void snap_init_from_enabled(const Object &object, SculptSession &ss, Cache *expand_cache)
{
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != bke::pbvh::Type::Mesh) {
return;
}
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
@@ -1141,8 +1141,8 @@ static void restore_face_set_data(Object &object, Cache *expand_cache)
face_sets.span.copy_from(expand_cache->original_face_sets);
face_sets.finish();
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*object.sculpt->pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*object.sculpt->pbvh, {});
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_face_sets(node);
}
}
@@ -1151,13 +1151,13 @@ static void restore_color_data(Object &ob, Cache *expand_cache)
{
SculptSession &ss = *ob.sculpt;
Mesh &mesh = *static_cast<Mesh *>(ob.data);
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = ss.vert_to_face_map;
bke::GSpanAttributeWriter color_attribute = color::active_color_attribute_for_write(mesh);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
for (const int vert : bke::pbvh::node_unique_verts(*node)) {
color::color_vert_set(faces,
corner_verts,
@@ -1174,8 +1174,8 @@ static void restore_color_data(Object &ob, Cache *expand_cache)
static void write_mask_data(SculptSession &ss, const Span<float> mask)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh *mesh = BKE_pbvh_get_mesh(*ss.pbvh);
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
attributes.remove(".sculpt_mask");
@@ -1184,8 +1184,8 @@ static void write_mask_data(SculptSession &ss, const Span<float> mask)
bke::AttributeInitVArray(VArray<float>::ForSpan(mask)));
break;
}
case PBVH_BMESH: {
BMesh &bm = *BKE_pbvh_get_bmesh(*ss.pbvh);
case bke::pbvh::Type::BMesh: {
BMesh &bm = *ss.bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
BM_mesh_elem_table_ensure(&bm, BM_VERT);
@@ -1194,7 +1194,7 @@ static void write_mask_data(SculptSession &ss, const Span<float> mask)
}
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
const Span<CCGElem *> grids = subdiv_ccg.grids;
@@ -1211,7 +1211,7 @@ static void write_mask_data(SculptSession &ss, const Span<float> mask)
}
}
for (PBVHNode *node : bke::pbvh::search_gather(*ss.pbvh, {})) {
for (bke::pbvh::Node *node : bke::pbvh::search_gather(*ss.pbvh, {})) {
BKE_pbvh_node_mark_update_mask(node);
}
}
@@ -1259,7 +1259,7 @@ static void sculpt_expand_cancel(bContext *C, wmOperator * /*op*/)
/* Functions to update the sculpt mesh data. */
static void update_mask_mesh(const SculptSession &ss,
PBVHNode *node,
bke::pbvh::Node *node,
const MutableSpan<float> mask)
{
const Cache *expand_cache = ss.expand_cache;
@@ -1308,7 +1308,7 @@ static void update_mask_mesh(const SculptSession &ss,
}
}
static void update_mask_grids(const SculptSession &ss, PBVHNode *node)
static void update_mask_grids(const SculptSession &ss, bke::pbvh::Node *node)
{
const Cache *expand_cache = ss.expand_cache;
SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
@@ -1363,7 +1363,7 @@ static void update_mask_grids(const SculptSession &ss, PBVHNode *node)
}
}
static void update_mask_bmesh(SculptSession &ss, const int mask_offset, PBVHNode *node)
static void update_mask_bmesh(SculptSession &ss, const int mask_offset, bke::pbvh::Node *node)
{
const Cache *expand_cache = ss.expand_cache;
@@ -1436,13 +1436,13 @@ static void face_sets_update(Object &object, Cache *expand_cache)
face_sets.finish();
for (PBVHNode *node : expand_cache->nodes) {
for (bke::pbvh::Node *node : expand_cache->nodes) {
BKE_pbvh_node_mark_update_face_sets(node);
}
}
/**
* Callback to update vertex colors per PBVH node.
* Callback to update vertex colors per bke::pbvh::Tree node.
*/
static void colors_update_task(SculptSession &ss,
const OffsetIndices<int> faces,
@@ -1450,7 +1450,7 @@ static void colors_update_task(SculptSession &ss,
const GroupedSpan<int> vert_to_face_map,
const Span<bool> hide_vert,
const Span<float> mask,
PBVHNode *node,
bke::pbvh::Node *node,
bke::GSpanAttributeWriter &color_attribute)
{
Cache *expand_cache = ss.expand_cache;
@@ -1592,12 +1592,12 @@ static void update_for_vert(bContext *C, Object &ob, const PBVHVertRef vertex)
face_sets_restore(ob, expand_cache);
}
const Span<PBVHNode *> nodes = expand_cache->nodes;
const Span<bke::pbvh::Node *> nodes = expand_cache->nodes;
switch (expand_cache->target) {
case SCULPT_EXPAND_TARGET_MASK: {
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
bke::SpanAttributeWriter mask = attributes.lookup_for_write_span<float>(".sculpt_mask");
@@ -1612,7 +1612,7 @@ static void update_for_vert(bContext *C, Object &ob, const PBVHVertRef vertex)
mask.finish();
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const int i : range) {
update_mask_grids(ss, nodes[i]);
@@ -1620,7 +1620,7 @@ static void update_for_vert(bContext *C, Object &ob, const PBVHVertRef vertex)
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const int mask_offset = CustomData_get_offset_named(
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
@@ -1747,8 +1747,8 @@ static void finish(bContext *C)
undo::push_end(ob);
/* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_update_mask(node);
}
@@ -1879,15 +1879,15 @@ static void ensure_sculptsession_data(Object &ob)
*/
static int active_face_set_id_get(SculptSession &ss, Cache *expand_cache)
{
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
return expand_cache->original_face_sets[ss.active_face_index];
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg,
ss.active_grid_index);
return expand_cache->original_face_sets[face_index];
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
/* Dyntopo does not support Face Set functionality. */
BLI_assert(false);
}
@@ -2201,16 +2201,16 @@ static void cache_initial_config_set(bContext *C, wmOperator *op, Cache *expand_
static void undo_push(Object &ob, Cache *expand_cache)
{
SculptSession &ss = *ob.sculpt;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
switch (expand_cache->target) {
case SCULPT_EXPAND_TARGET_MASK:
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::Mask);
}
break;
case SCULPT_EXPAND_TARGET_FACE_SETS:
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::FaceSet);
}
break;
@@ -2219,7 +2219,7 @@ static void undo_push(Object &ob, Cache *expand_cache)
/* The sculpt undo system needs corner indices for corner domain color attributes. */
BKE_pbvh_ensure_node_loops(*ss.pbvh, mesh.corner_tris());
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::Color);
}
break;
@@ -2230,8 +2230,8 @@ static void undo_push(Object &ob, Cache *expand_cache)
static bool any_nonzero_mask(const Object &object)
{
const SculptSession &ss = *object.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan mask = *attributes.lookup<float>(".sculpt_mask");
@@ -2241,7 +2241,7 @@ static bool any_nonzero_mask(const Object &object)
return std::any_of(
mask.begin(), mask.end(), [&](const float value) { return value > 0.0f; });
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
if (!key.has_mask) {
@@ -2256,7 +2256,7 @@ static bool any_nonzero_mask(const Object &object)
return false;
});
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMesh &bm = *ss.bm;
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
if (offset == -1) {
@@ -2326,7 +2326,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* Face Set operations are not supported in dyntopo. */
if (ss.expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS &&
BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH)
ss.pbvh->type() == bke::pbvh::Type::BMesh)
{
expand_cache_free(ss);
return OPERATOR_CANCELLED;
@@ -2342,7 +2342,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
const float mouse[2] = {float(event->mval[0]), float(event->mval[1])};
set_initial_components_for_mouse(C, ob, ss.expand_cache, mouse);
/* Cache PBVH nodes. */
/* Cache bke::pbvh::Tree nodes. */
ss.expand_cache->nodes = bke::pbvh::search_gather(*ss.pbvh, {});
/* Store initial state. */

View File

@@ -70,9 +70,9 @@ namespace blender::ed::sculpt_paint::face_set {
int find_next_available_id(Object &object)
{
SculptSession &ss = *object.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
case PBVH_GRIDS: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
case bke::pbvh::Type::Grids: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
const VArraySpan<int> face_sets = *attributes.lookup<int>(".sculpt_face_set",
@@ -90,7 +90,7 @@ int find_next_available_id(Object &object)
[](const int a, const int b) { return std::max(a, b); });
return max + 1;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
BMesh &bm = *ss.bm;
const int cd_offset = CustomData_get_offset_named(
&bm.pdata, CD_PROP_INT32, ".sculpt_face_set");
@@ -213,10 +213,10 @@ Array<int> duplicate_face_sets(const Mesh &mesh)
* \{ */
static void face_sets_update(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(Span<int>, MutableSpan<int>)> calc_face_sets)
{
PBVH &pbvh = *object.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> tri_faces = mesh.corner_tri_faces();
@@ -230,9 +230,9 @@ static void face_sets_update(Object &object,
threading::EnumerableThreadSpecific<TLS> all_tls;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TLS &tls = all_tls.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> faces =
BKE_pbvh_type(pbvh) == PBVH_FACES ?
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
@@ -260,23 +260,23 @@ enum class CreateMode {
Selection = 3,
};
static void clear_face_sets(Object &object, const Span<PBVHNode *> nodes)
static void clear_face_sets(Object &object, const Span<bke::pbvh::Node *> nodes)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
if (!attributes.contains(".sculpt_face_set")) {
return;
}
const PBVH &pbvh = *object.sculpt->pbvh;
const bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
const Span<int> tri_faces = mesh.corner_tri_faces();
const int default_face_set = mesh.face_sets_color_default;
const VArraySpan face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
threading::EnumerableThreadSpecific<Vector<int>> all_face_indices;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
Vector<int> &face_indices = all_face_indices.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> faces =
BKE_pbvh_type(pbvh) == PBVH_FACES ?
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, face_indices);
if (std::any_of(faces.begin(), faces.end(), [&](const int face) {
@@ -305,7 +305,7 @@ static int create_op_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
/* Dyntopo not supported. */
return OPERATOR_CANCELLED;
}
@@ -319,7 +319,7 @@ static int create_op_exec(bContext *C, wmOperator *op)
const int next_face_set = find_next_available_id(object);
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
switch (mode) {
case CreateMode::Masked: {
const OffsetIndices faces = mesh.faces();
@@ -562,19 +562,19 @@ static int init_op_exec(bContext *C, wmOperator *op)
BKE_sculpt_update_object_for_edit(depsgraph, &ob, false);
/* Dyntopo not supported. */
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
return OPERATOR_CANCELLED;
}
PBVH &pbvh = *ob.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
bke::pbvh::Tree &pbvh = *ob.sculpt->pbvh;
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
if (nodes.is_empty()) {
return OPERATOR_CANCELLED;
}
undo::push_begin(ob, op);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::FaceSet);
}
@@ -665,7 +665,7 @@ static int init_op_exec(bContext *C, wmOperator *op)
undo::push_end(ob);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_redraw(node);
}
@@ -748,10 +748,10 @@ enum class VisibilityMode {
};
static void face_hide_update(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
const FunctionRef<void(Span<int>, MutableSpan<bool>)> calc_hide)
{
PBVH &pbvh = *object.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<int> tri_faces = mesh.corner_tri_faces();
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
@@ -767,9 +767,9 @@ static void face_hide_update(Object &object,
threading::EnumerableThreadSpecific<TLS> all_tls;
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TLS &tls = all_tls.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
const Span<int> faces =
BKE_pbvh_type(pbvh) == PBVH_FACES ?
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
@@ -794,16 +794,16 @@ static void face_hide_update(Object &object,
}
}
static void show_all(Depsgraph &depsgraph, Object &object, const Span<PBVHNode *> nodes)
static void show_all(Depsgraph &depsgraph, Object &object, const Span<bke::pbvh::Node *> nodes)
{
switch (BKE_pbvh_type(*object.sculpt->pbvh)) {
case PBVH_FACES:
switch (object.sculpt->pbvh->type()) {
case bke::pbvh::Type::Mesh:
hide::mesh_show_all(object, nodes);
break;
case PBVH_GRIDS:
case bke::pbvh::Type::Grids:
hide::grids_show_all(depsgraph, object, nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
BLI_assert_unreachable();
break;
}
@@ -818,7 +818,7 @@ static int change_visibility_exec(bContext *C, wmOperator *op)
Mesh *mesh = BKE_object_get_original_mesh(&object);
BKE_sculpt_update_object_for_edit(&depsgraph, &object, false);
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
/* Not supported for dyntopo. There is no active face. */
return OPERATOR_CANCELLED;
}
@@ -828,8 +828,8 @@ static int change_visibility_exec(bContext *C, wmOperator *op)
undo::push_begin(object, op);
PBVH &pbvh = *object.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
bke::pbvh::Tree &pbvh = *object.sculpt->pbvh;
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
const bke::AttributeAccessor attributes = mesh->attributes();
const VArraySpan<bool> hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
@@ -971,11 +971,11 @@ static int randomize_colors_exec(bContext *C, wmOperator * /*op*/)
}
/* Dyntopo not supported. */
if (BKE_pbvh_type(*ss.pbvh) == PBVH_BMESH) {
if (ss.pbvh->type() == bke::pbvh::Type::BMesh) {
return OPERATOR_CANCELLED;
}
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Mesh *mesh = static_cast<Mesh *>(ob.data);
const bke::AttributeAccessor attributes = mesh->attributes();
@@ -990,8 +990,8 @@ static int randomize_colors_exec(bContext *C, wmOperator * /*op*/)
mesh->face_sets_color_seed += 1;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_redraw(node);
}
@@ -1037,7 +1037,7 @@ static void edit_grow_shrink(Object &object,
undo::push_begin(object, op);
const Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
const Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
face_sets_update(object, nodes, [&](const Span<int> indices, MutableSpan<int> face_sets) {
for (const int i : indices.index_range()) {
const int face = indices[i];
@@ -1196,13 +1196,13 @@ static bool edit_is_operation_valid(const Object &object,
const EditMode mode,
const bool modify_hidden)
{
if (BKE_pbvh_type(*object.sculpt->pbvh) == PBVH_BMESH) {
if (object.sculpt->pbvh->type() == bke::pbvh::Type::BMesh) {
/* Dyntopo is not supported. */
return false;
}
if (mode == EditMode::DeleteGeometry) {
if (BKE_pbvh_type(*object.sculpt->pbvh) == PBVH_GRIDS) {
if (object.sculpt->pbvh->type() == bke::pbvh::Type::Grids) {
/* Modification of base mesh geometry requires special remapping of multi-resolution
* displacement, which does not happen here.
* Disable delete operation. It can be supported in the future by doing similar displacement
@@ -1217,7 +1217,7 @@ static bool edit_is_operation_valid(const Object &object,
}
if (ELEM(mode, EditMode::FairPositions, EditMode::FairTangency)) {
if (BKE_pbvh_type(*object.sculpt->pbvh) == PBVH_GRIDS) {
if (object.sculpt->pbvh->type() == bke::pbvh::Type::Grids) {
/* TODO: Multi-resolution topology representation using grids and duplicates can't be used
* directly by the fair algorithm. Multi-resolution topology needs to be exposed in a
* different way or converted to a mesh for this operation. */
@@ -1255,14 +1255,14 @@ static void edit_modify_coordinates(
{
const Sculpt &sd = *CTX_data_tool_settings(C)->sculpt;
SculptSession &ss = *ob.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
const float strength = RNA_float_get(op->ptr, "strength");
undo::push_begin(ob, op);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_positions_update(node);
undo::push_node(ob, node, undo::Type::Position);
}
@@ -1435,7 +1435,8 @@ static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &ges
undo::push_begin(*gesture_data.vc.obact, &op);
}
static void gesture_apply_mesh(gesture::GestureData &gesture_data, const Span<PBVHNode *> nodes)
static void gesture_apply_mesh(gesture::GestureData &gesture_data,
const Span<bke::pbvh::Node *> nodes)
{
FaceSetOperation *face_set_operation = (FaceSetOperation *)gesture_data.operation;
const int new_face_set = face_set_operation->new_face_set_id;
@@ -1443,7 +1444,7 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const Span<PB
Mesh &mesh = *static_cast<Mesh *>(object.data);
bke::AttributeAccessor attributes = mesh.attributes();
SculptSession &ss = *gesture_data.ss;
const PBVH &pbvh = *ss.pbvh;
const bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<float3> positions = ss.vert_positions;
const OffsetIndices<int> faces = mesh.faces();
@@ -1459,10 +1460,10 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const Span<PB
threading::EnumerableThreadSpecific<TLS> all_tls;
threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) {
TLS &tls = all_tls.local();
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(*gesture_data.vc.obact, node, undo::Type::FaceSet);
const Span<int> node_faces =
BKE_pbvh_type(pbvh) == PBVH_FACES ?
pbvh.type() == bke::pbvh::Type::Mesh ?
bke::pbvh::node_face_indices_calc_mesh(tri_faces, *node, tls.face_indices) :
bke::pbvh::node_face_indices_calc_grids(pbvh, *node, tls.face_indices);
@@ -1489,7 +1490,8 @@ static void gesture_apply_mesh(gesture::GestureData &gesture_data, const Span<PB
face_sets.finish();
}
static void gesture_apply_bmesh(gesture::GestureData &gesture_data, const Span<PBVHNode *> nodes)
static void gesture_apply_bmesh(gesture::GestureData &gesture_data,
const Span<bke::pbvh::Node *> nodes)
{
FaceSetOperation *face_set_operation = (FaceSetOperation *)gesture_data.operation;
const int new_face_set = face_set_operation->new_face_set_id;
@@ -1498,7 +1500,7 @@ static void gesture_apply_bmesh(gesture::GestureData &gesture_data, const Span<P
const int offset = CustomData_get_offset_named(&bm->pdata, CD_PROP_INT32, ".sculpt_face_set");
threading::parallel_for(gesture_data.nodes.index_range(), 1, [&](const IndexRange range) {
for (PBVHNode *node : nodes.slice(range)) {
for (bke::pbvh::Node *node : nodes.slice(range)) {
undo::push_node(*gesture_data.vc.obact, node, undo::Type::FaceSet);
bool any_updated = false;
@@ -1524,12 +1526,12 @@ static void gesture_apply_bmesh(gesture::GestureData &gesture_data, const Span<P
static void gesture_apply_for_symmetry_pass(bContext & /*C*/, gesture::GestureData &gesture_data)
{
switch (BKE_pbvh_type(*gesture_data.ss->pbvh)) {
case PBVH_GRIDS:
case PBVH_FACES:
switch (gesture_data.ss->pbvh->type()) {
case bke::pbvh::Type::Grids:
case bke::pbvh::Type::Mesh:
gesture_apply_mesh(gesture_data, gesture_data.nodes);
break;
case PBVH_BMESH:
case bke::pbvh::Type::BMesh:
gesture_apply_bmesh(gesture_data, gesture_data.nodes);
}
}

View File

@@ -84,7 +84,7 @@ static void color_filter_task(Object &ob,
const int mode,
const float filter_strength,
const float *filter_fill_color,
PBVHNode *node,
bke::pbvh::Node *node,
bke::GSpanAttributeWriter &color_attribute)
{
SculptSession &ss = *ob.sculpt;
@@ -313,7 +313,7 @@ static void sculpt_color_filter_apply(bContext *C, wmOperator *op, Object &ob)
sculpt_color_presmooth_init(mesh, ss);
}
const Span<PBVHNode *> nodes = ss.filter_cache->nodes;
const Span<bke::pbvh::Node *> nodes = ss.filter_cache->nodes;
const OffsetIndices<int> faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();

View File

@@ -50,7 +50,7 @@ static void mask_filter_task(SculptSession &ss,
const FilterType mode,
const Span<float> prev_mask,
const SculptMaskWriteInfo mask_write,
PBVHNode *node)
bke::pbvh::Node *node)
{
bool update = false;
@@ -131,7 +131,7 @@ static void mask_filter_task(SculptSession &ss,
}
mask = clamp_f(mask, 0.0f, 1.0f);
if (mask != vd.mask) {
SCULPT_mask_vert_set(BKE_pbvh_type(*ss.pbvh), mask_write, mask, vd);
SCULPT_mask_vert_set(ss.pbvh->type(), mask_write, mask, vd);
update = true;
}
}
@@ -161,16 +161,16 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
BKE_sculpt_update_object_for_edit(depsgraph, &ob, false);
SculptSession &ss = *ob.sculpt;
PBVH &pbvh = *ob.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *ob.sculpt->pbvh;
SCULPT_vertex_random_access_ensure(ss);
int num_verts = SCULPT_vertex_count_get(ss);
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
undo::push_begin(ob, op);
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
undo::push_node(ob, node, undo::Type::Mask);
}

View File

@@ -107,7 +107,7 @@ void cache_init(bContext *C,
float start_strength)
{
SculptSession &ss = *ob.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
ss.filter_cache = MEM_new<filter::Cache>(__func__);
ss.filter_cache->start_filter_strength = start_strength;
@@ -119,7 +119,7 @@ void cache_init(bContext *C,
}
ss.filter_cache->nodes = bke::pbvh::search_gather(
pbvh, [&](PBVHNode &node) { return !node_fully_masked_or_hidden(node); });
pbvh, [&](bke::pbvh::Node &node) { return !node_fully_masked_or_hidden(node); });
undo::push_nodes(ob, ss.filter_cache->nodes, undo_type);
@@ -142,7 +142,7 @@ void cache_init(bContext *C,
float co[3];
if (vc.rv3d && SCULPT_stroke_get_location(C, co, mval_fl, false)) {
Vector<PBVHNode *> nodes;
Vector<bke::pbvh::Node *> nodes;
/* Get radius from brush. */
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
@@ -162,7 +162,7 @@ void cache_init(bContext *C,
}
const float radius_sq = math::square(radius);
nodes = bke::pbvh::search_gather(pbvh, [&](PBVHNode &node) {
nodes = bke::pbvh::search_gather(pbvh, [&](bke::pbvh::Node &node) {
return !node_fully_masked_or_hidden(node) && node_in_sphere(node, co, radius_sq, true);
});
@@ -301,7 +301,7 @@ static bool sculpt_mesh_filter_is_continuous(eSculptMeshFilterType type)
static void mesh_filter_task(Object &ob,
const eSculptMeshFilterType filter_type,
const float filter_strength,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
@@ -596,7 +596,7 @@ static void mesh_filter_sharpen_init(SculptSession &ss,
static void mesh_filter_surface_smooth_displace_task(Object &ob,
const float filter_strength,
PBVHNode *node)
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
PBVHVertexIter vd;
@@ -676,7 +676,7 @@ static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op)
SCULPT_vertex_random_access_ensure(ss);
const Span<PBVHNode *> nodes = ss.filter_cache->nodes;
const Span<bke::pbvh::Node *> nodes = ss.filter_cache->nodes;
/* The relax mesh filter needs updated normals. */
if (ELEM(MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS)) {
@@ -785,7 +785,7 @@ static void sculpt_mesh_filter_cancel(bContext *C, wmOperator * /*op*/)
undo::restore_position_from_undo_step(ob);
blender::bke::pbvh::update_bounds(*ss->pbvh);
bke::pbvh::update_bounds(*ss->pbvh);
}
static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)

View File

@@ -252,11 +252,11 @@ static Array<float> geodesic_fallback_create(Object &ob, const Set<int> &initial
Array<float> distances_create(Object &ob, const Set<int> &initial_verts, const float limit_radius)
{
SculptSession &ss = *ob.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
return geodesic_mesh_create(ob, initial_verts, limit_radius);
case PBVH_BMESH:
case PBVH_GRIDS:
case bke::pbvh::Type::BMesh:
case bke::pbvh::Type::Grids:
return geodesic_fallback_create(ob, initial_verts);
}
BLI_assert_unreachable();

View File

@@ -320,7 +320,7 @@ static void flip_for_symmetry_pass(GestureData &gesture_data, const ePaintSymmet
flip_plane(gesture_data.line.side_plane[1], gesture_data.line.true_side_plane[1], symmpass);
}
static Vector<PBVHNode *> update_affected_nodes_by_line_plane(GestureData &gesture_data)
static Vector<bke::pbvh::Node *> update_affected_nodes_by_line_plane(GestureData &gesture_data)
{
SculptSession &ss = *gesture_data.ss;
float clip_planes[3][4];
@@ -332,7 +332,7 @@ static Vector<PBVHNode *> update_affected_nodes_by_line_plane(GestureData &gestu
frustum.planes = clip_planes;
frustum.num_planes = gesture_data.line.use_side_planes ? 3 : 1;
return gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
return gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);
});
}
@@ -348,7 +348,7 @@ static void update_affected_nodes_by_clip_planes(GestureData &gesture_data)
frustum.planes = clip_planes;
frustum.num_planes = 4;
gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](PBVHNode &node) {
gesture_data.nodes = bke::pbvh::search_gather(*ss.pbvh, [&](bke::pbvh::Node &node) {
switch (gesture_data.selection_type) {
case SelectionType::Inside:
return BKE_pbvh_node_frustum_contain_AABB(&node, &frustum);

View File

@@ -160,7 +160,7 @@ struct Node {
/* Multires. */
/** Indices of grids in the PBVH node. */
/** Indices of grids in the pbvh::Tree node. */
Array<int> grids;
BitGroupVector<> grid_hidden;
@@ -258,7 +258,7 @@ struct Cache {
Array<float3> limit_surface_co;
/* unmasked nodes */
Vector<PBVHNode *> nodes;
Vector<bke::pbvh::Node *> nodes;
/* Cloth filter. */
std::unique_ptr<cloth::SimulationData> cloth_sim;
@@ -597,9 +597,9 @@ struct Cache {
/* Controls how much texture distortion will be applied to the current falloff */
float texture_distortion_strength;
/* Cached PBVH nodes. This allows to skip gathering all nodes from the PBVH each time expand
* needs to update the state of the elements. */
Vector<PBVHNode *> nodes;
/* Cached pbvh::Tree nodes. This allows to skip gathering all nodes from the pbvh::Tree each time
* expand needs to update the state of the elements. */
Vector<bke::pbvh::Node *> nodes;
/* Expand state options. */
@@ -683,7 +683,7 @@ bool SCULPT_brush_cursor_poll(bContext *C);
/**
* Returns true if sculpt session can handle color attributes
* (BKE_pbvh_type(*ss->pbvh) == PBVH_FACES). If false an error
* (ss->pbvh->type() == bke::pbvh::Type::Mesh). If false an error
* message will be shown to the user. Operators should return
* OPERATOR_CANCELLED in this case.
*
@@ -715,7 +715,7 @@ void flush_update_done(const bContext *C, Object &ob, UpdateType update_type);
void SCULPT_pbvh_clear(Object &ob);
/**
* Flush displacement from deformed PBVH to original layer.
* Flush displacement from deformed blender::bke::pbvh::Tree to original layer.
*/
void SCULPT_flush_stroke_deform(const Sculpt &sd, Object &ob, bool is_proxy_used);
@@ -814,25 +814,25 @@ struct SculptMaskWriteInfo {
int bm_offset = -1;
};
SculptMaskWriteInfo SCULPT_mask_get_for_write(SculptSession &ss);
inline void SCULPT_mask_vert_set(const PBVHType type,
inline void SCULPT_mask_vert_set(const blender::bke::pbvh::Type type,
const SculptMaskWriteInfo mask_write,
const float value,
PBVHVertexIter &vd)
{
switch (type) {
case PBVH_FACES:
case blender::bke::pbvh::Type::Mesh:
mask_write.layer[vd.index] = value;
break;
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
BM_ELEM_CD_SET_FLOAT(vd.bm_vert, mask_write.bm_offset, value);
break;
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
CCG_elem_mask(vd.key, vd.grid) = value;
break;
}
}
/** Ensure random access; required for PBVH_BMESH */
/** Ensure random access; required for blender::bke::pbvh::Type::BMesh */
void SCULPT_vertex_random_access_ensure(SculptSession &ss);
int SCULPT_vertex_count_get(const SculptSession &ss);
@@ -883,7 +883,7 @@ void SCULPT_vertex_neighbors_get(const SculptSession &ss,
neighbor_iterator.index = neighbor_iterator.neighbor_indices[neighbor_iterator.i];
/**
* Iterate over neighboring and duplicate vertices (for PBVH_GRIDS).
* Iterate over neighboring and duplicate vertices (for blender::bke::pbvh::Type::Grids).
* Duplicates come first since they are nearest for flood-fill.
*/
#define SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator) \
@@ -911,7 +911,7 @@ Span<BMVert *> vert_neighbors_get_interior_bmesh(BMVert &vert, Vector<BMVert *,
PBVHVertRef SCULPT_active_vertex_get(const SculptSession &ss);
const float *SCULPT_active_vertex_co_get(const SculptSession &ss);
/* Returns PBVH deformed vertices array if shape keys or deform modifiers are used, otherwise
/* Returns pbvh::Tree deformed vertices array if shape keys or deform modifiers are used, otherwise
* returns mesh original vertices array. */
blender::MutableSpan<blender::float3> SCULPT_mesh_deformed_positions_get(SculptSession &ss);
@@ -967,7 +967,9 @@ bool vert_is_boundary(BMVert *vert);
namespace hide {
Span<int> node_visible_verts(const PBVHNode &node, Span<bool> hide_vert, Vector<int> &indices);
Span<int> node_visible_verts(const bke::pbvh::Node &node,
Span<bool> hide_vert,
Vector<int> &indices);
bool vert_visible_get(const SculptSession &ss, PBVHVertRef vertex);
@@ -1039,10 +1041,10 @@ Set<int> gather_hidden_face_sets(Span<bool> hide_poly, Span<int> face_sets);
* handles #BMesh, #Mesh, and multi-resolution.
*/
SculptOrigVertData SCULPT_orig_vert_data_init(const Object &ob,
const PBVHNode &node,
const blender::bke::pbvh::Node &node,
blender::ed::sculpt_paint::undo::Type type);
/**
* Update a #SculptOrigVertData for a particular vertex from the PBVH iterator.
* Update a #SculptOrigVertData for a particular vertex from the blender::bke::pbvh::Tree iterator.
*/
void SCULPT_orig_vert_data_update(SculptOrigVertData &orig_data, const PBVHVertexIter &iter);
void SCULPT_orig_vert_data_update(SculptOrigVertData &orig_data, const BMVert &vert);
@@ -1060,11 +1062,13 @@ namespace blender::ed::sculpt_paint {
void calc_brush_plane(const Brush &brush,
Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float r_area_no[3],
float r_area_co[3]);
std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVHNode *> nodes);
std::optional<float3> calc_area_normal(const Brush &brush,
Object &ob,
Span<bke::pbvh::Node *> nodes);
/**
* This calculates flatten center and area normal together,
@@ -1072,30 +1076,30 @@ std::optional<float3> calc_area_normal(const Brush &brush, Object &ob, Span<PBVH
*/
void calc_area_normal_and_center(const Brush &brush,
const Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float r_area_no[3],
float r_area_co[3]);
void calc_area_center(const Brush &brush,
const Object &ob,
Span<PBVHNode *> nodes,
Span<bke::pbvh::Node *> nodes,
float r_area_co[3]);
PBVHVertRef nearest_vert_calc(const Object &object,
const float3 &location,
float max_distance,
bool use_original);
std::optional<int> nearest_vert_calc_mesh(const PBVH &pbvh,
std::optional<int> nearest_vert_calc_mesh(const bke::pbvh::Tree &pbvh,
const Span<float3> vert_positions,
const Span<bool> hide_vert,
const float3 &location,
const float max_distance,
const bool use_original);
std::optional<SubdivCCGCoord> nearest_vert_calc_grids(PBVH &pbvh,
std::optional<SubdivCCGCoord> nearest_vert_calc_grids(bke::pbvh::Tree &pbvh,
const SubdivCCG &subdiv_ccg,
const float3 &location,
const float max_distance,
const bool use_original);
std::optional<BMVert *> nearest_vert_calc_bmesh(PBVH &pbvh,
std::optional<BMVert *> nearest_vert_calc_bmesh(bke::pbvh::Tree &pbvh,
const float3 &location,
const float max_distance,
const bool use_original);
@@ -1137,10 +1141,13 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest &test, const float co[3]);
namespace blender::ed::sculpt_paint {
bool node_fully_masked_or_hidden(const PBVHNode &node);
bool node_in_sphere(const PBVHNode &node, const float3 &location, float radius_sq, bool original);
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node);
bool node_in_sphere(const bke::pbvh::Node &node,
const float3 &location,
float radius_sq,
bool original);
bool node_in_cylinder(const DistRayAABB_Precalc &dist_ray_precalc,
const PBVHNode &node,
const bke::pbvh::Node &node,
float radius_sq,
bool original);
@@ -1328,17 +1335,17 @@ namespace detail_size {
constexpr float RELATIVE_SCALE_FACTOR = 0.4f;
/**
* Converts from Sculpt#constant_detail to the PBVH max edge length.
* Converts from Sculpt#constant_detail to the pbvh::Tree max edge length.
*/
float constant_to_detail_size(const float constant_detail, const Object &ob);
/**
* Converts from Sculpt#detail_percent to the PBVH max edge length.
* Converts from Sculpt#detail_percent to the pbvh::Tree max edge length.
*/
float brush_to_detail_size(const float brush_percent, const float brush_radius);
/**
* Converts from Sculpt#detail_size to the PBVH max edge length.
* Converts from Sculpt#detail_size to the pbvh::Tree max edge length.
*/
float relative_to_detail_size(const float relative_detail,
const float brush_radius,
@@ -1403,16 +1410,16 @@ struct NodeData {
};
/**
* Call before PBVH vertex iteration.
* Call before pbvh::Tree vertex iteration.
*/
NodeData node_begin(const Object &object, const Cache *automasking, const PBVHNode &node);
NodeData node_begin(const Object &object, const Cache *automasking, const bke::pbvh::Node &node);
/* Call before factor_get and SCULPT_brush_strength_factor. */
void node_update(NodeData &automask_data, const PBVHVertexIter &vd);
void node_update(NodeData &automask_data, const BMVert &vert);
/**
* Call before factor_get and SCULPT_brush_strength_factor. The index is in the range of the PBVH
* node's vertex indices.
* Call before factor_get and SCULPT_brush_strength_factor. The index is in the range of the
* pbvh::Tree node's vertex indices.
*/
void node_update(NodeData &automask_data, int i);
@@ -1455,8 +1462,9 @@ namespace blender::ed::sculpt_paint::geodesic {
/**
* Returns an array indexed by vertex index containing the geodesic distance to the closest vertex
* in the initial vertex set. The caller is responsible for freeing the array.
* Geodesic distances will only work when used with PBVH_FACES, for other types of PBVH it will
* fallback to euclidean distances to one of the initial vertices in the set.
* Geodesic distances will only work when used with blender::bke::pbvh::Type::Mesh, for other
* types of blender::bke::pbvh::Tree it will fallback to euclidean distances to one of the initial
* vertices in the set.
*/
Array<float> distances_create(Object &ob, const Set<int> &initial_verts, float limit_radius);
Array<float> distances_create_from_vert_and_symm(Object &ob,
@@ -1571,7 +1579,7 @@ struct SimulationData {
ListBase *collider_list;
int totnode;
/** #PBVHNode pointer as a key, index in #SimulationData.node_state as value. */
/** #blender::bke::pbvh::Node pointer as a key, index in #SimulationData.node_state as value. */
GHash *node_state_index;
Array<NodeSimState> node_state;
@@ -1583,7 +1591,7 @@ struct SimulationData {
};
/* Main cloth brush function */
void do_cloth_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_cloth_brush(const Sculpt &sd, Object &ob, Span<blender::bke::pbvh::Node *> nodes);
/* Public functions. */
@@ -1595,18 +1603,18 @@ std::unique_ptr<SimulationData> brush_simulation_create(Object &ob,
bool needs_deform_coords);
void brush_simulation_init(const SculptSession &ss, SimulationData &cloth_sim);
void sim_activate_nodes(SimulationData &cloth_sim, Span<PBVHNode *> nodes);
void sim_activate_nodes(SimulationData &cloth_sim, Span<blender::bke::pbvh::Node *> nodes);
void brush_store_simulation_state(const SculptSession &ss, SimulationData &cloth_sim);
void do_simulation_step(const Sculpt &sd,
Object &ob,
SimulationData &cloth_sim,
Span<PBVHNode *> nodes);
Span<blender::bke::pbvh::Node *> nodes);
void ensure_nodes_constraints(const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes,
Span<blender::bke::pbvh::Node *> nodes,
SimulationData &cloth_sim,
float initial_location[3],
float radius);
@@ -1627,7 +1635,8 @@ void plane_falloff_preview_draw(uint gpuattr,
const float outline_col[3],
float outline_alpha);
Vector<PBVHNode *> brush_affected_nodes_gather(SculptSession &ss, const Brush &brush);
Vector<blender::bke::pbvh::Node *> brush_affected_nodes_gather(SculptSession &ss,
const Brush &brush);
bool is_cloth_deform_brush(const Brush &brush);
@@ -1697,7 +1706,7 @@ void surface_smooth_displace_step(SculptSession &ss,
PBVHVertRef vertex,
float beta,
float fade);
void do_surface_smooth_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
void do_surface_smooth_brush(const Sculpt &sd, Object &ob, Span<blender::bke::pbvh::Node *> nodes);
/* Slide/Relax */
void relax_vertex(SculptSession &ss,
@@ -1726,13 +1735,13 @@ void SCULPT_cache_calc_brushdata_symm(blender::ed::sculpt_paint::StrokeCache &ca
namespace blender::ed::sculpt_paint::undo {
/**
* Store undo data of the given type for a PBVH node. This function can be called by multiple
* threads concurrently, as long as they don't pass the same PBVH node.
* Store undo data of the given type for a pbvh::Tree node. This function can be called by multiple
* threads concurrently, as long as they don't pass the same pbvh::Tree node.
*
* This is only possible when building an undo step, in between #push_begin and #push_end.
*/
void push_node(const Object &object, const PBVHNode *node, undo::Type type);
void push_nodes(Object &object, Span<const PBVHNode *> nodes, undo::Type type);
void push_node(const Object &object, const bke::pbvh::Node *node, undo::Type type);
void push_nodes(Object &object, Span<const bke::pbvh::Node *> nodes, undo::Type type);
/**
* Retrieve the undo data of a given type for the active undo step. For example, this is used to
@@ -1740,7 +1749,7 @@ void push_nodes(Object &object, Span<const PBVHNode *> nodes, undo::Type type);
*
* This is only possible when building an undo step, in between #push_begin and #push_end.
*/
const undo::Node *get_node(const PBVHNode *node, undo::Type type);
const undo::Node *get_node(const bke::pbvh::Node *node, undo::Type type);
/**
* Pushes an undo step using the operator name. This is necessary for
@@ -1774,14 +1783,14 @@ struct OrigPositionData {
* Retrieve positions from the latest undo state. This is often used for modal actions that depend
* on the initial state of the geometry from before the start of the action.
*/
OrigPositionData orig_position_data_get_mesh(const Object &object, const PBVHNode &node);
OrigPositionData orig_position_data_get_grids(const Object &object, const PBVHNode &node);
OrigPositionData orig_position_data_get_mesh(const Object &object, const bke::pbvh::Node &node);
OrigPositionData orig_position_data_get_grids(const Object &object, const bke::pbvh::Node &node);
void orig_position_data_gather_bmesh(const BMLog &bm_log,
const Set<BMVert *, 0> &verts,
MutableSpan<float3> positions,
MutableSpan<float3> normals);
Span<float4> orig_color_data_get_mesh(const Object &object, const PBVHNode &node);
Span<float4> orig_color_data_get_mesh(const Object &object, const bke::pbvh::Node &node);
}
@@ -1903,7 +1912,7 @@ struct GestureData {
LineData line;
/* Task Callback Data. */
Vector<PBVHNode *> nodes;
Vector<bke::pbvh::Node *> nodes;
~GestureData();
};
@@ -1917,7 +1926,7 @@ struct Operation {
void (*apply_for_symmetry_pass)(bContext &, GestureData &);
/* Remaining actions after finishing the symmetry passes iterations
* (updating data-layers, tagging PBVH updates...). */
* (updating data-layers, tagging bke::pbvh::Tree updates...). */
void (*end)(bContext &, GestureData &);
};
@@ -2050,7 +2059,7 @@ namespace blender::ed::sculpt_paint::pose {
/**
* Main Brush Function.
*/
void do_pose_brush(const Sculpt &sd, Object &ob, blender::Span<PBVHNode *> nodes);
void do_pose_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
/**
* Calculate the pose origin and (Optionally the pose factor)
* that is used when using the pose brush.
@@ -2090,7 +2099,7 @@ std::unique_ptr<SculptBoundaryPreview> preview_data_init(Object &object,
float radius);
/* Main Brush Function. */
void do_boundary_brush(const Sculpt &sd, Object &ob, blender::Span<PBVHNode *> nodes);
void do_boundary_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
void edges_preview_draw(uint gpuattr,
SculptSession &ss,
@@ -2149,9 +2158,9 @@ bke::GSpanAttributeWriter active_color_attribute_for_write(Mesh &mesh);
void do_paint_brush(PaintModeSettings &paint_mode_settings,
const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes,
Span<PBVHNode *> texnodes);
void do_smear_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes);
Span<bke::pbvh::Node *> nodes,
Span<bke::pbvh::Node *> texnodes);
void do_smear_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes);
}
}
@@ -2169,7 +2178,7 @@ bool SCULPT_paint_image_canvas_get(PaintModeSettings &paint_mode_settings,
void SCULPT_do_paint_brush_image(PaintModeSettings &paint_mode_settings,
const Sculpt &sd,
Object &ob,
blender::Span<PBVHNode *> texnodes);
blender::Span<blender::bke::pbvh::Node *> texnodes);
bool SCULPT_use_image_paint_brush(PaintModeSettings &settings, Object &ob);
namespace blender::ed::sculpt_paint {

View File

@@ -47,7 +47,7 @@ enum class InitMode {
};
void write_mask_mesh(Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
FunctionRef<void(MutableSpan<float>, Span<int>)> write_fn)
{
Mesh &mesh = *static_cast<Mesh *>(object.data);
@@ -79,7 +79,7 @@ static void init_mask_grids(Main &bmain,
Scene &scene,
Depsgraph &depsgraph,
Object &object,
const Span<PBVHNode *> nodes,
const Span<bke::pbvh::Node *> nodes,
FunctionRef<void(const BitGroupVector<> &, int, CCGElem *)> write_fn)
{
MultiresModifierData *mmd = BKE_sculpt_multires_active(&scene, &object);
@@ -116,8 +116,8 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
BKE_sculpt_update_object_for_edit(&depsgraph, &ob, false);
PBVH &pbvh = *ob.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
bke::pbvh::Tree &pbvh = *ob.sculpt->pbvh;
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
if (nodes.is_empty()) {
return OPERATOR_CANCELLED;
}
@@ -127,8 +127,8 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
const InitMode mode = InitMode(RNA_enum_get(op->ptr, "mode"));
const int seed = BLI_time_now_seconds();
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
switch (mode) {
case InitMode::Random:
write_mask_mesh(ob, nodes, [&](MutableSpan<float> mask, Span<int> verts) {
@@ -157,7 +157,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
}
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
Main &bmain = *CTX_data_main(C);
Scene &scene = *CTX_data_scene(C);
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
@@ -223,7 +223,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
}
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const int offset = CustomData_get_offset_named(&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const int i : range) {

View File

@@ -169,7 +169,7 @@ static bool sculpt_no_multires_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (SCULPT_mode_poll(C) && ob->sculpt && ob->sculpt->pbvh) {
return BKE_pbvh_type(*ob->sculpt->pbvh) != PBVH_GRIDS;
return ob->sculpt->pbvh->type() != blender::bke::pbvh::Type::Grids;
}
return false;
}
@@ -181,7 +181,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
Object &ob = *CTX_data_active_object(C);
const Sculpt &sd = *CTX_data_tool_settings(C)->sculpt;
SculptSession &ss = *ob.sculpt;
PBVH *pbvh = ss.pbvh.get();
blender::bke::pbvh::Tree *pbvh = ss.pbvh.get();
const float dist = RNA_float_get(op->ptr, "merge_tolerance");
if (!pbvh) {
@@ -194,8 +194,8 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
switch (BKE_pbvh_type(*pbvh)) {
case PBVH_BMESH: {
switch (pbvh->type()) {
case blender::bke::pbvh::Type::BMesh: {
/* Dyntopo Symmetrize. */
/* To simplify undo for symmetrize, all BMesh elements are logged
@@ -228,7 +228,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
break;
}
case PBVH_FACES: {
case blender::bke::pbvh::Type::Mesh: {
/* Mesh Symmetrize. */
undo::geometry_begin(ob, op);
Mesh *mesh = static_cast<Mesh *>(ob.data);
@@ -240,7 +240,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
break;
}
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
return OPERATOR_CANCELLED;
}
@@ -584,7 +584,7 @@ void geometry_preview_lines_update(bContext *C, SculptSession &ss, float radius)
ss.preview_vert_count = 0;
int totpoints = 0;
/* This function is called from the cursor drawing code, so the PBVH may not be build yet. */
/* This function is called from the cursor drawing code, so the tree may not be build yet. */
if (!ss.pbvh) {
return;
}
@@ -593,7 +593,7 @@ void geometry_preview_lines_update(bContext *C, SculptSession &ss, float radius)
return;
}
if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
return;
}
@@ -805,7 +805,7 @@ static void sculpt_mask_by_color_contiguous(Object &object,
ss, from_v, to_v, is_duplicate, colors, active_color, threshold, invert, new_mask);
});
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
update_mask_mesh(object, nodes, [&](MutableSpan<float> node_mask, const Span<int> verts) {
for (const int i : verts.index_range()) {
@@ -828,7 +828,7 @@ static void sculpt_mask_by_color_full_mesh(Object &object,
mesh.active_color_attribute, bke::AttrDomain::Point, {});
const float4 active_color = float4(colors[vertex.i]);
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
update_mask_mesh(object, nodes, [&](MutableSpan<float> node_mask, const Span<int> verts) {
for (const int i : verts.index_range()) {
@@ -990,7 +990,7 @@ static void bake_mask_mesh(const Object &object,
const auto_mask::Cache &automasking,
const CavityBakeMixMode mode,
const float factor,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls,
const MutableSpan<float> mask)
{
@@ -1021,7 +1021,7 @@ static void bake_mask_grids(Object &object,
const auto_mask::Cache &automasking,
const CavityBakeMixMode mode,
const float factor,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls)
{
SculptSession &ss = *object.sculpt;
@@ -1055,7 +1055,7 @@ static void bake_mask_bmesh(Object &object,
const auto_mask::Cache &automasking,
const CavityBakeMixMode mode,
const float factor,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls)
{
const SculptSession &ss = *object.sculpt;
@@ -1106,7 +1106,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
CavityBakeMixMode mode = CavityBakeMixMode(RNA_enum_get(op->ptr, "mix_mode"));
float factor = RNA_float_get(op->ptr, "mix_factor");
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
/* Set up automasking settings. */
Sculpt sd2 = sd;
@@ -1173,8 +1173,8 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
undo::push_nodes(ob, nodes, undo::Type::Mask);
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
bke::SpanAttributeWriter mask = attributes.lookup_or_add_for_write_span<float>(
@@ -1194,7 +1194,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -1205,7 +1205,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
bke::pbvh::update_mask(*ss.pbvh);
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -280,7 +280,7 @@ static void do_color_smooth_task(const Object &object,
const GroupedSpan<int> vert_to_face_map,
const Span<bool> hide_poly,
const Brush &brush,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls,
bke::GSpanAttributeWriter &color_attribute)
{
@@ -362,7 +362,7 @@ static void do_paint_brush_task(Object &object,
const Brush &brush,
const float4x4 &mat,
const float4 wet_mix_sampled_color,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
bke::GSpanAttributeWriter &color_attribute)
{
@@ -495,7 +495,7 @@ static void do_sample_wet_paint_task(const Object &object,
const GSpan color_attribute,
const bke::AttrDomain color_domain,
const Brush &brush,
const PBVHNode &node,
const bke::pbvh::Node &node,
LocalData &tls,
SampleWetPaintData &swptd)
{
@@ -528,8 +528,8 @@ static void do_sample_wet_paint_task(const Object &object,
void do_paint_brush(PaintModeSettings &paint_mode_settings,
const Sculpt &sd,
Object &ob,
Span<PBVHNode *> nodes,
Span<PBVHNode *> texnodes)
Span<bke::pbvh::Node *> nodes,
Span<bke::pbvh::Node *> texnodes)
{
if (SCULPT_use_image_paint_brush(paint_mode_settings, ob)) {
SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes);
@@ -673,7 +673,7 @@ static void do_smear_brush_task(Object &object,
const Span<int> corner_verts,
const GroupedSpan<int> vert_to_face_map,
const Brush &brush,
PBVHNode &node,
bke::pbvh::Node &node,
LocalData &tls,
bke::GSpanAttributeWriter &color_attribute)
{
@@ -820,7 +820,7 @@ static void do_smear_brush_task(Object &object,
}
}
void do_smear_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_smear_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
SculptSession &ss = *ob.sculpt;

View File

@@ -53,7 +53,7 @@ struct ImageData {
struct TexturePaintingUserData {
Object *ob;
const Brush *brush;
Span<PBVHNode *> nodes;
Span<bke::pbvh::Node *> nodes;
ImageData image_data;
};
@@ -331,8 +331,8 @@ static void do_paint_pixels(TexturePaintingUserData *data, const int n)
Object *ob = data->ob;
SculptSession &ss = *ob->sculpt;
const Brush *brush = data->brush;
PBVH &pbvh = *ss.pbvh;
PBVHNode *node = data->nodes[n];
bke::pbvh::Tree &pbvh = *ss.pbvh;
bke::pbvh::Node *node = data->nodes[n];
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);
@@ -471,7 +471,7 @@ static void push_undo(const NodeData &node_data,
static void do_push_undo_tile(TexturePaintingUserData *data, const int n)
{
PBVHNode *node = data->nodes[n];
bke::pbvh::Node *node = data->nodes[n];
NodeData &node_data = bke::pbvh::pixels::node_data_get(*node);
Image *image = data->image_data.image;
@@ -500,15 +500,15 @@ static void do_push_undo_tile(TexturePaintingUserData *data, const int n)
/** \name Fix non-manifold edge bleeding.
* \{ */
static Vector<image::TileNumber> collect_dirty_tiles(Span<PBVHNode *> nodes)
static Vector<image::TileNumber> collect_dirty_tiles(Span<bke::pbvh::Node *> nodes)
{
Vector<image::TileNumber> dirty_tiles;
for (PBVHNode *node : nodes) {
for (bke::pbvh::Node *node : nodes) {
bke::pbvh::pixels::collect_dirty_tiles(*node, dirty_tiles);
}
return dirty_tiles;
}
static void fix_non_manifold_seam_bleeding(PBVH &pbvh,
static void fix_non_manifold_seam_bleeding(bke::pbvh::Tree &pbvh,
TexturePaintingUserData &user_data,
Span<TileNumber> tile_numbers_to_fix)
{
@@ -564,7 +564,7 @@ bool SCULPT_use_image_paint_brush(PaintModeSettings &settings, Object &ob)
void SCULPT_do_paint_brush_image(PaintModeSettings &paint_mode_settings,
const Sculpt &sd,
Object &ob,
const blender::Span<PBVHNode *> texnodes)
const blender::Span<blender::bke::pbvh::Node *> texnodes)
{
using namespace blender;
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
@@ -590,7 +590,7 @@ void SCULPT_do_paint_brush_image(PaintModeSettings &paint_mode_settings,
});
fix_non_manifold_seam_bleeding(ob, data);
for (PBVHNode *node : texnodes) {
for (bke::pbvh::Node *node : texnodes) {
bke::pbvh::pixels::mark_image_dirty(
*node, *data.image_data.image, *data.image_data.image_user);
}

View File

@@ -129,7 +129,7 @@ static void pose_solve_scale_chain(SculptPoseIKChain &ik_chain, const float scal
}
}
static void do_pose_brush_task(Object &ob, const Brush &brush, PBVHNode *node)
static void do_pose_brush_task(Object &ob, const Brush &brush, bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
SculptPoseIKChain &ik_chain = *ss.cache->pose_ik_chain;
@@ -193,7 +193,7 @@ static void pose_brush_grow_factor_task(Object &ob,
const float pose_initial_co[3],
const float *prev_mask,
MutableSpan<float> pose_factor,
PBVHNode *node,
bke::pbvh::Node *node,
PoseGrowFactorData *gftd)
{
SculptSession &ss = *ob.sculpt;
@@ -233,9 +233,9 @@ static void sculpt_pose_grow_pose_factor(Object &ob,
float *r_pose_origin,
MutableSpan<float> pose_factor)
{
PBVH &pbvh = *ob.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *ob.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
PoseGrowFactorData gftd;
gftd.pos_count = 0;
@@ -536,7 +536,9 @@ void calc_pose_data(Object &ob,
}
}
static void pose_brush_init_task(SculptSession &ss, MutableSpan<float> pose_factor, PBVHNode *node)
static void pose_brush_init_task(SculptSession &ss,
MutableSpan<float> pose_factor,
bke::pbvh::Node *node)
{
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin (*ss.pbvh, node, vd, PBVH_ITER_UNIQUE) {
@@ -950,9 +952,9 @@ std::unique_ptr<SculptPoseIKChain> ik_chain_init(Object &ob,
void pose_brush_init(Object &ob, SculptSession &ss, const Brush &brush)
{
PBVH &pbvh = *ob.sculpt->pbvh;
bke::pbvh::Tree &pbvh = *ob.sculpt->pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(pbvh, {});
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(pbvh, {});
/* Init the IK chain that is going to be used to deform the vertices. */
ss.cache->pose_ik_chain = ik_chain_init(
@@ -1094,7 +1096,7 @@ static void sculpt_pose_align_pivot_local_space(float r_mat[4][4],
ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
}
void do_pose_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_pose_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
SculptSession &ss = *ob.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);

View File

@@ -48,7 +48,7 @@ static void apply_projection_mesh(const Sculpt &sd,
const gesture::GestureData &gesture_data,
const Span<float3> positions_eval,
const Span<float3> vert_normals,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -77,7 +77,7 @@ static void apply_projection_mesh(const Sculpt &sd,
static void apply_projection_grids(const Sculpt &sd,
const gesture::GestureData &gesture_data,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
LocalData &tls)
{
@@ -110,7 +110,7 @@ static void apply_projection_grids(const Sculpt &sd,
static void apply_projection_bmesh(const Sculpt &sd,
const gesture::GestureData &gesture_data,
PBVHNode &node,
bke::pbvh::Node &node,
Object &object,
LocalData &tls)
{
@@ -144,15 +144,15 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g
{
Object &object = *gesture_data.vc.obact;
SculptSession &ss = *object.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
const Sculpt &sd = *CTX_data_tool_settings(&C)->sculpt;
const Span<PBVHNode *> nodes = gesture_data.nodes;
const Span<bke::pbvh::Node *> nodes = gesture_data.nodes;
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (gesture_data.shape_type) {
case gesture::ShapeType::Line:
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(object.data);
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(pbvh);
@@ -173,7 +173,7 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {
@@ -183,7 +183,7 @@ static void gesture_apply_for_symmetry_pass(bContext &C, gesture::GestureData &g
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
LocalData &tls = all_tls.local();
for (const int i : range) {

View File

@@ -315,8 +315,8 @@ float neighbor_mask_average(SculptSession &ss,
float avg = 0.0f;
int total = 0;
SculptVertexNeighborIter ni;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
avg += write_info.layer[ni.vertex.i];
total++;
@@ -324,7 +324,7 @@ float neighbor_mask_average(SculptSession &ss,
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
return avg / total;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
avg += SCULPT_mask_get_at_grids_vert_index(
*ss.subdiv_ccg, BKE_subdiv_ccg_key_top_level(*ss.subdiv_ccg), ni.vertex.i);
@@ -333,7 +333,7 @@ float neighbor_mask_average(SculptSession &ss,
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
return avg / total;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
Vector<BMVert *, 64> neighbors;
for (BMVert *neighbor :
vert_neighbors_get_bmesh(*reinterpret_cast<BMVert *>(vertex.i), neighbors))
@@ -426,7 +426,9 @@ void surface_smooth_displace_step(SculptSession &ss,
}
}
static void do_surface_smooth_brush_laplacian_task(Object &ob, const Brush &brush, PBVHNode *node)
static void do_surface_smooth_brush_laplacian_task(Object &ob,
const Brush &brush,
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const float bstrength = ss.cache->bstrength;
@@ -470,7 +472,9 @@ static void do_surface_smooth_brush_laplacian_task(Object &ob, const Brush &brus
BKE_pbvh_vertex_iter_end;
}
static void do_surface_smooth_brush_displace_task(Object &ob, const Brush &brush, PBVHNode *node)
static void do_surface_smooth_brush_displace_task(Object &ob,
const Brush &brush,
bke::pbvh::Node *node)
{
SculptSession &ss = *ob.sculpt;
const float bstrength = ss.cache->bstrength;
@@ -508,7 +512,7 @@ static void do_surface_smooth_brush_displace_task(Object &ob, const Brush &brush
BKE_pbvh_vertex_iter_end;
}
void do_surface_smooth_brush(const Sculpt &sd, Object &ob, Span<PBVHNode *> nodes)
void do_surface_smooth_brush(const Sculpt &sd, Object &ob, Span<bke::pbvh::Node *> nodes)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);

View File

@@ -188,7 +188,7 @@ BLI_NOINLINE static void filter_translations_with_symmetry(const Span<float3> po
static void transform_node_mesh(const Sculpt &sd,
const std::array<float4x4, 8> &transform_mats,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -215,7 +215,7 @@ static void transform_node_mesh(const Sculpt &sd,
static void transform_node_grids(const Sculpt &sd,
const std::array<float4x4, 8> &transform_mats,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls)
{
@@ -247,7 +247,7 @@ static void transform_node_grids(const Sculpt &sd,
static void transform_node_bmesh(const Sculpt &sd,
const std::array<float4x4, 8> &transform_mats,
PBVHNode &node,
bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls)
{
@@ -288,12 +288,12 @@ static void sculpt_transform_all_vertices(const Sculpt &sd, Object &ob)
/* Regular transform applies all symmetry passes at once as it is split by symmetry areas
* (each vertex can only be transformed once by the transform matrix of its area). */
PBVH &pbvh = *ss.pbvh;
const Span<PBVHNode *> nodes = ss.filter_cache->nodes;
bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<bke::pbvh::Node *> nodes = ss.filter_cache->nodes;
threading::EnumerableThreadSpecific<TransformLocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -307,7 +307,7 @@ static void sculpt_transform_all_vertices(const Sculpt &sd, Object &ob)
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TransformLocalData &tls = all_tls.local();
for (const int i : range) {
@@ -317,7 +317,7 @@ static void sculpt_transform_all_vertices(const Sculpt &sd, Object &ob)
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TransformLocalData &tls = all_tls.local();
for (const int i : range) {
@@ -356,7 +356,7 @@ static void elastic_transform_node_mesh(const Sculpt &sd,
const float4x4 &elastic_transform_mat,
const float3 &elastic_transform_pivot,
const Span<float3> positions_eval,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls,
const MutableSpan<float3> positions_orig)
@@ -386,7 +386,7 @@ static void elastic_transform_node_grids(const Sculpt &sd,
const KelvinletParams &params,
const float4x4 &elastic_transform_mat,
const float3 &elastic_transform_pivot,
const PBVHNode &node,
const bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls)
{
@@ -417,7 +417,7 @@ static void elastic_transform_node_bmesh(const Sculpt &sd,
const KelvinletParams &params,
const float4x4 &elastic_transform_mat,
const float3 &elastic_transform_pivot,
PBVHNode &node,
bke::pbvh::Node &node,
Object &object,
TransformLocalData &tls)
{
@@ -453,8 +453,8 @@ static void transform_radius_elastic(const Sculpt &sd, Object &ob, const float t
std::array<float4x4, 8> transform_mats = transform_matrices_init(
ss, symm, ss.filter_cache->transform_displacement_mode);
PBVH &pbvh = *ss.pbvh;
const Span<PBVHNode *> nodes = ss.filter_cache->nodes;
bke::pbvh::Tree &pbvh = *ss.pbvh;
const Span<bke::pbvh::Node *> nodes = ss.filter_cache->nodes;
KelvinletParams params;
/* TODO(pablodp606): These parameters can be exposed if needed as transform strength and volume
@@ -478,8 +478,8 @@ static void transform_radius_elastic(const Sculpt &sd, Object &ob, const float t
const int symm_area = SCULPT_get_vertex_symm_area(elastic_transform_pivot);
float4x4 elastic_transform_mat = transform_mats[symm_area];
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
Mesh &mesh = *static_cast<Mesh *>(ob.data);
const Span<float3> positions_eval = BKE_pbvh_get_vert_positions(pbvh);
MutableSpan<float3> positions_orig = mesh.vert_positions_for_write();
@@ -500,7 +500,7 @@ static void transform_radius_elastic(const Sculpt &sd, Object &ob, const float t
});
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TransformLocalData &tls = all_tls.local();
for (const int i : range) {
@@ -511,7 +511,7 @@ static void transform_radius_elastic(const Sculpt &sd, Object &ob, const float t
});
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
TransformLocalData &tls = all_tls.local();
for (const int i : range) {
@@ -664,10 +664,10 @@ static float3 average_unmasked_position(const Object &object,
const ePaintSymmetryFlags symm)
{
const SculptSession &ss = *object.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(
pbvh, [&](PBVHNode &node) { return !node_fully_masked_or_hidden(node); });
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(
pbvh, [&](bke::pbvh::Node &node) { return !node_fully_masked_or_hidden(node); });
struct LocalData {
Vector<float> factors;
@@ -675,8 +675,8 @@ static float3 average_unmasked_position(const Object &object,
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(pbvh);
const AveragePositionAccumulation total = threading::parallel_reduce(
@@ -686,7 +686,7 @@ static float3 average_unmasked_position(const Object &object,
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
threading::isolate_task([&]() {
for (const PBVHNode *node : nodes.as_span().slice(range)) {
for (const bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
tls.positions.reinitialize(verts.size());
@@ -706,7 +706,7 @@ static float3 average_unmasked_position(const Object &object,
combine_average_position_accumulation);
return float3(math::safe_divide(total.position, total.weight_total));
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const AveragePositionAccumulation total = threading::parallel_reduce(
nodes.index_range(),
@@ -714,7 +714,7 @@ static float3 average_unmasked_position(const Object &object,
AveragePositionAccumulation{},
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
for (const PBVHNode *node : nodes.as_span().slice(range)) {
for (const bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
const MutableSpan positions = gather_grids_positions(
subdiv_ccg, grids, tls.positions);
@@ -731,14 +731,14 @@ static float3 average_unmasked_position(const Object &object,
combine_average_position_accumulation);
return float3(math::safe_divide(total.position, total.weight_total));
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const AveragePositionAccumulation total = threading::parallel_reduce(
nodes.index_range(),
1,
AveragePositionAccumulation{},
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(node);
const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
@@ -776,10 +776,10 @@ static float3 average_mask_border_position(const Object &object,
const ePaintSymmetryFlags symm)
{
const SculptSession &ss = *object.sculpt;
PBVH &pbvh = *ss.pbvh;
bke::pbvh::Tree &pbvh = *ss.pbvh;
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(
pbvh, [&](PBVHNode &node) { return !node_fully_masked_or_hidden(node); });
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(
pbvh, [&](bke::pbvh::Node &node) { return !node_fully_masked_or_hidden(node); });
struct LocalData {
Vector<float> factors;
@@ -788,8 +788,8 @@ static float3 average_mask_border_position(const Object &object,
};
threading::EnumerableThreadSpecific<LocalData> all_tls;
switch (BKE_pbvh_type(pbvh)) {
case PBVH_FACES: {
switch (pbvh.type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const Span<float3> vert_positions = BKE_pbvh_get_vert_positions(pbvh);
const bke::AttributeAccessor attributes = mesh.attributes();
@@ -802,7 +802,7 @@ static float3 average_mask_border_position(const Object &object,
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
threading::isolate_task([&]() {
for (const PBVHNode *node : nodes.as_span().slice(range)) {
for (const bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Span<int> verts = bke::pbvh::node_unique_verts(*node);
tls.positions.reinitialize(verts.size());
@@ -828,7 +828,7 @@ static float3 average_mask_border_position(const Object &object,
combine_average_position_accumulation);
return float3(math::safe_divide(total.position, total.weight_total));
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
const AveragePositionAccumulation total = threading::parallel_reduce(
nodes.index_range(),
@@ -836,7 +836,7 @@ static float3 average_mask_border_position(const Object &object,
AveragePositionAccumulation{},
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
for (const PBVHNode *node : nodes.as_span().slice(range)) {
for (const bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
const MutableSpan positions = gather_grids_positions(
subdiv_ccg, grids, tls.positions);
@@ -858,14 +858,14 @@ static float3 average_mask_border_position(const Object &object,
combine_average_position_accumulation);
return float3(math::safe_divide(total.position, total.weight_total));
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
const AveragePositionAccumulation total = threading::parallel_reduce(
nodes.index_range(),
1,
AveragePositionAccumulation{},
[&](const IndexRange range, AveragePositionAccumulation sum) {
LocalData &tls = all_tls.local();
for (PBVHNode *node : nodes.as_span().slice(range)) {
for (bke::pbvh::Node *node : nodes.as_span().slice(range)) {
const Set<BMVert *, 0> &verts = BKE_pbvh_bmesh_node_unique_verts(node);
const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);

View File

@@ -511,8 +511,8 @@ static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &ges
Object *object = gesture_data.vc.obact;
SculptSession &ss = *object->sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES:
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh:
face_set::create_face_sets_mesh(*object);
break;
default:
@@ -743,12 +743,12 @@ static bool can_invoke(const bContext &C)
return true;
}
static void report_invalid_mode(const PBVHType pbvh_type, ReportList &reports)
static void report_invalid_mode(const blender::bke::pbvh::Type pbvh_type, ReportList &reports)
{
if (pbvh_type == PBVH_BMESH) {
if (pbvh_type == bke::pbvh::Type::BMesh) {
BKE_report(&reports, RPT_ERROR, "Not supported in dynamic topology mode");
}
else if (pbvh_type == PBVH_GRIDS) {
else if (pbvh_type == bke::pbvh::Type::Grids) {
BKE_report(&reports, RPT_ERROR, "Not supported in multiresolution mode");
}
else {
@@ -760,9 +760,9 @@ static bool can_exec(const bContext &C, ReportList &reports)
{
const Object &object = *CTX_data_active_object(&C);
const SculptSession &ss = *object.sculpt;
if (BKE_pbvh_type(*ss.pbvh) != PBVH_FACES) {
if (ss.pbvh->type() != bke::pbvh::Type::Mesh) {
/* Not supported in Multires and Dyntopo. */
report_invalid_mode(BKE_pbvh_type(*ss.pbvh), reports);
report_invalid_mode(ss.pbvh->type(), reports);
return false;
}

View File

@@ -190,9 +190,9 @@ struct StepData {
std::mutex nodes_mutex;
/**
* #undo::Node is stored per PBVH node to reduce data storage needed for changes only impacting
* #undo::Node is stored per pbvh::Node to reduce data storage needed for changes only impacting
* small portions of the mesh. During undo step creation and brush evaluation we often need to
* look up the undo state for a specific PBVH node. That lookup must be protected by a lock since
* look up the undo state for a specific node. That lookup must be protected by a lock since
* nodes are pushed from multiple threads. This map speeds up undo node access to reduce the
* amount of time we wait for the lock.
*
@@ -202,7 +202,7 @@ struct StepData {
* should be unnecessary. However, to remove it, first the storage of the undo type should be
* moved to #StepData from #Node.
*/
Map<const PBVHNode *, std::unique_ptr<Node>> undo_nodes_by_pbvh_node;
Map<const bke::pbvh::Node *, std::unique_ptr<Node>> undo_nodes_by_pbvh_node;
/** Storage of per-node undo data after creation of the undo step is finished. */
Vector<std::unique_ptr<Node>> nodes;
@@ -465,8 +465,8 @@ static void restore_position_mesh(Object &object, Node &unode, MutableSpan<bool>
/* Propagate new coords to keyblock. */
SCULPT_vertcos_to_key(object, ss.shapekey_active, key_positions);
/* PBVH uses its own vertex array, so coords should be */
/* propagated to PBVH here. */
/* bke::pbvh::Tree uses its own vertex array, so coords should be */
/* propagated to bke::pbvh::Tree here. */
BKE_pbvh_vert_coords_apply(*ss.pbvh, key_positions);
MEM_freeN(vertCos);
@@ -679,8 +679,8 @@ static void bmesh_restore_generic(StepData &step_data, Object &object, SculptSes
}
if (step_data.type == Type::Mask) {
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (bke::pbvh::Node *node : nodes) {
BKE_pbvh_node_mark_redraw(node);
}
}
@@ -941,7 +941,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_position_grids(grids, key, *unode, modified_grids);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
const Span<int> grids = bke::pbvh::node_grid_indices(node);
if (indices_contain_true(modified_grids, grids)) {
BKE_pbvh_node_mark_positions_update(&node);
@@ -957,7 +957,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_position_mesh(object, *unode, modified_verts);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
BKE_pbvh_node_mark_positions_update(&node);
}
@@ -985,7 +985,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_vert_visibility_grids(subdiv_ccg, *unode, modified_grids);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(node))) {
BKE_pbvh_node_mark_update_visibility(&node);
}
@@ -996,7 +996,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_vert_visibility_mesh(object, *unode, modified_verts);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
BKE_pbvh_node_mark_update_visibility(&node);
}
@@ -1024,7 +1024,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
if (use_multires_undo(step_data, ss)) {
Vector<int> faces_vector;
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.pbvh, node, faces_vector);
@@ -1036,7 +1036,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
else {
const Span<int> tri_faces = mesh.corner_tri_faces();
Vector<int> faces_vector;
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_mesh(
tri_faces, node, faces_vector);
@@ -1061,7 +1061,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_mask_grids(object, *unode, modified_grids);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(node))) {
BKE_pbvh_node_mark_update_mask(&node);
}
@@ -1072,7 +1072,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
for (std::unique_ptr<Node> &unode : step_data.nodes) {
restore_mask_mesh(object, *unode, modified_verts);
}
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
BKE_pbvh_node_mark_update_mask(&node);
}
@@ -1094,7 +1094,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
}
if (use_multires_undo(step_data, ss)) {
Vector<int> faces_vector;
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
*ss.pbvh, node, faces_vector);
@@ -1106,7 +1106,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
else {
const Span<int> tri_faces = mesh.corner_tri_faces();
Vector<int> faces_vector;
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
faces_vector.clear();
const Span<int> faces = bke::pbvh::node_face_indices_calc_mesh(
tri_faces, node, faces_vector);
@@ -1125,7 +1125,7 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
Array<bool> modified_verts(ss.totvert, false);
restore_color(object, step_data, modified_verts);
bke::pbvh::search_callback(*ss.pbvh, {}, [&](PBVHNode &node) {
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
BKE_pbvh_node_mark_update_color(&node);
}
@@ -1165,7 +1165,7 @@ static void free_step_data(StepData &step_data)
step_data.~StepData();
}
const Node *get_node(const PBVHNode *node, const Type type)
const Node *get_node(const bke::pbvh::Node *node, const Type type)
{
StepData *step_data = get_step_data();
if (!step_data) {
@@ -1184,7 +1184,9 @@ const Node *get_node(const PBVHNode *node, const Type type)
return node_ptr->get();
}
static void alloc_and_store_hidden(const SculptSession &ss, const PBVHNode &node, Node &unode)
static void alloc_and_store_hidden(const SculptSession &ss,
const bke::pbvh::Node &node,
Node &unode)
{
if (!ss.subdiv_ccg) {
return;
@@ -1249,7 +1251,7 @@ static void store_coords(const Object &object, Node &unode)
}
}
static void store_hidden(const Object &object, const PBVHNode &node, Node &unode)
static void store_hidden(const Object &object, const bke::pbvh::Node &node, Node &unode)
{
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
const bke::AttributeAccessor attributes = mesh.attributes();
@@ -1314,7 +1316,7 @@ static void store_mask(const Object &object, Node &unode)
}
}
static void store_color(const Object &object, const PBVHNode &node, Node &unode)
static void store_color(const Object &object, const bke::pbvh::Node &node, Node &unode)
{
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
@@ -1371,7 +1373,7 @@ static void store_face_sets(const Mesh &mesh, Node &unode)
}
static void fill_node_data(const Object &object,
const PBVHNode *node,
const bke::pbvh::Node *node,
const Type type,
Node &unode)
{
@@ -1380,7 +1382,7 @@ static void fill_node_data(const Object &object,
const Mesh &mesh = *static_cast<Mesh *>(object.data);
int verts_num;
if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
unode.grids = bke::pbvh::node_grid_indices(*node);
const int grid_area = ss.subdiv_ccg->grid_size * ss.subdiv_ccg->grid_size;
@@ -1401,7 +1403,7 @@ static void fill_node_data(const Object &object,
}
if (need_faces) {
if (BKE_pbvh_type(*ss.pbvh) == PBVH_FACES) {
if (ss.pbvh->type() == bke::pbvh::Type::Mesh) {
bke::pbvh::node_face_indices_calc_mesh(mesh.corner_tri_faces(), *node, unode.face_indices);
}
else {
@@ -1424,7 +1426,7 @@ static void fill_node_data(const Object &object,
break;
}
case Type::HideVert: {
if (BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS) {
if (ss.pbvh->type() == bke::pbvh::Type::Grids) {
alloc_and_store_hidden(ss, *node, unode);
}
else {
@@ -1466,10 +1468,10 @@ static void fill_node_data(const Object &object,
}
/**
* Dynamic topology stores only one undo node per stroke, regardless of the number of PBVH nodes
* modified.
* Dynamic topology stores only one undo node per stroke, regardless of the number of
* bke::pbvh::Tree nodes modified.
*/
BLI_NOINLINE static void bmesh_push(const Object &object, const PBVHNode *node, Type type)
BLI_NOINLINE static void bmesh_push(const Object &object, const bke::pbvh::Node *node, Type type)
{
StepData *step_data = get_step_data();
const SculptSession &ss = *object.sculpt;
@@ -1511,7 +1513,7 @@ BLI_NOINLINE static void bmesh_push(const Object &object, const PBVHNode *node,
&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
/* The vertices and node aren't changed, though pointers to them are stored in the log. */
PBVHNode *node_mut = const_cast<PBVHNode *>(node);
bke::pbvh::Node *node_mut = const_cast<bke::pbvh::Node *>(node);
switch (type) {
case Type::None:
@@ -1556,10 +1558,10 @@ BLI_NOINLINE static void bmesh_push(const Object &object, const PBVHNode *node,
}
/**
* Add an undo node for the PBVH node to the step's storage. If the node was newly created and
* needs to be filled with data, set \a r_new to true.
* Add an undo node for the bke::pbvh::Tree node to the step's storage. If the node was
* newly created and needs to be filled with data, set \a r_new to true.
*/
static Node *ensure_node(StepData &step_data, const PBVHNode &node, bool &r_new)
static Node *ensure_node(StepData &step_data, const bke::pbvh::Node &node, bool &r_new)
{
std::scoped_lock lock(step_data.nodes_mutex);
r_new = false;
@@ -1571,7 +1573,7 @@ static Node *ensure_node(StepData &step_data, const PBVHNode &node, bool &r_new)
return unode.get();
}
void push_node(const Object &object, const PBVHNode *node, Type type)
void push_node(const Object &object, const bke::pbvh::Node *node, Type type)
{
SculptSession &ss = *object.sculpt;
if (ss.bm || ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
@@ -1595,11 +1597,11 @@ void push_node(const Object &object, const PBVHNode *node, Type type)
fill_node_data(object, node, type, *unode);
}
void push_nodes(Object &object, const Span<const PBVHNode *> nodes, const Type type)
void push_nodes(Object &object, const Span<const bke::pbvh::Node *> nodes, const Type type)
{
SculptSession &ss = *object.sculpt;
if (ss.bm || ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
for (const PBVHNode *node : nodes) {
for (const bke::pbvh::Node *node : nodes) {
bmesh_push(object, node, type);
}
return;
@@ -1609,8 +1611,8 @@ void push_nodes(Object &object, const Span<const PBVHNode *> nodes, const Type t
BLI_assert(ELEM(step_data->type, Type::None, type));
step_data->type = type;
Vector<std::pair<const PBVHNode *, Node *>, 32> nodes_to_fill;
for (const PBVHNode *node : nodes) {
Vector<std::pair<const bke::pbvh::Node *, Node *>, 32> nodes_to_fill;
for (const bke::pbvh::Node *node : nodes) {
bool newly_added;
Node *unode = ensure_node(*step_data, *node, newly_added);
if (newly_added) {
@@ -1687,19 +1689,19 @@ void push_begin_ex(Object &ob, const char *name)
const SculptSession &ss = *ob.sculpt;
switch (BKE_pbvh_type(*ss.pbvh)) {
case PBVH_FACES: {
switch (ss.pbvh->type()) {
case bke::pbvh::Type::Mesh: {
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
us->data.mesh_verts_num = ss.totvert;
us->data.mesh_corners_num = mesh.corners_num;
break;
}
case PBVH_GRIDS: {
case bke::pbvh::Type::Grids: {
us->data.mesh_grids_num = ss.subdiv_ccg->grids.size();
us->data.grid_size = ss.subdiv_ccg->grid_size;
break;
}
case PBVH_BMESH: {
case bke::pbvh::Type::BMesh: {
break;
}
}
@@ -2068,20 +2070,20 @@ static void push_all_grids(Object *object)
{
SculptSession &ss = *object->sculpt;
/* It is possible that undo push is done from an object state where there is no PBVH. This
/* It is possible that undo push is done from an object state where there is no tree. This
* happens, for example, when an operation which tagged for geometry update was performed prior
* to the current operation without making any stroke in between.
*
* Skip pushing nodes based on the following logic: on redo Type::Position will
* ensure PBVH for the new base geometry, which will have same coordinates as if we create PBVH
* here.
* ensure pbvh::Tree for the new base geometry, which will have same coordinates as if we create
* pbvh::Tree here.
*/
if (ss.pbvh == nullptr) {
return;
}
Vector<PBVHNode *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (PBVHNode *node : nodes) {
Vector<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
for (bke::pbvh::Node *node : nodes) {
push_node(*object, node, Type::Position);
}
}
@@ -2123,14 +2125,16 @@ void push_multires_mesh_end(bContext *C, const char *str)
namespace blender::ed::sculpt_paint {
OrigPositionData orig_position_data_get_mesh(const Object & /*object*/, const PBVHNode &node)
OrigPositionData orig_position_data_get_mesh(const Object & /*object*/,
const bke::pbvh::Node &node)
{
const undo::Node *unode = undo::get_node(&node, undo::Type::Position);
return {unode->position.as_span().take_front(unode->unique_verts_num),
unode->normal.as_span().take_front(unode->unique_verts_num)};
}
OrigPositionData orig_position_data_get_grids(const Object & /*object*/, const PBVHNode &node)
OrigPositionData orig_position_data_get_grids(const Object & /*object*/,
const bke::pbvh::Node &node)
{
const undo::Node *unode = undo::get_node(&node, undo::Type::Position);
return {unode->position.as_span(), unode->normal.as_span()};
@@ -2152,7 +2156,7 @@ void orig_position_data_gather_bmesh(const BMLog &bm_log,
}
}
Span<float4> orig_color_data_get_mesh(const Object & /*object*/, const PBVHNode &node)
Span<float4> orig_color_data_get_mesh(const Object & /*object*/, const bke::pbvh::Node &node)
{
const undo::Node *unode = undo::get_node(&node, undo::Type::Color);
return unode->col.as_span();

View File

@@ -367,16 +367,16 @@ static void stats_object_sculpt(const Object *ob, SceneStats *stats)
return;
}
switch (BKE_pbvh_type(*ss->pbvh)) {
case PBVH_FACES:
switch (ss->pbvh->type()) {
case blender::bke::pbvh::Type::Mesh:
stats->totvertsculpt = ss->totvert;
stats->totfacesculpt = ss->totfaces;
break;
case PBVH_BMESH:
case blender::bke::pbvh::Type::BMesh:
stats->totvertsculpt = ob->sculpt->bm->totvert;
stats->tottri = ob->sculpt->bm->totface;
break;
case PBVH_GRIDS:
case blender::bke::pbvh::Type::Grids:
stats->totvertsculpt = BKE_pbvh_get_grid_num_verts(*ss->pbvh);
stats->totfacesculpt = BKE_pbvh_get_grid_num_faces(*ss->pbvh);
break;

View File

@@ -483,7 +483,7 @@ static void rna_PaintModeSettings_canvas_source_update(bContext *C, PointerRNA *
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
/* When canvas source changes the PBVH would require updates when switching between color
/* When canvas source changes the pbvh::Tree would require updates when switching between color
* attributes. */
if (ob && ob->type == OB_MESH) {
BKE_texpaint_slots_refresh_object(scene, ob);