Blender V4.3
pbvh_bmesh.cc File Reference
#include "MEM_guardedalloc.h"
#include "BLI_bounds.hh"
#include "BLI_ghash.h"
#include "BLI_heap_simple.h"
#include "BLI_math_geom.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
#include "BLI_span.hh"
#include "BLI_time.h"
#include "BLI_utildefines.h"
#include "BKE_ccg.hh"
#include "BKE_pbvh_api.hh"
#include "bmesh.hh"
#include "pbvh_intern.hh"
#include "CLG_log.h"
#include "BKE_global.hh"

Go to the source code of this file.

Classes

struct  blender::bke::pbvh::EdgeQueue
 
struct  blender::bke::pbvh::EdgeQueueContext
 
struct  blender::bke::pbvh::FastNodeBuildInfo
 

Namespaces

namespace  blender
 
namespace  blender::bke
 
namespace  blender::bke::pbvh
 

Macros

#define USE_EDGEQUEUE_EVEN_SUBDIV
 
#define USE_EDGEQUEUE_FRONTFACE
 
#define USE_EDGEQUEUE_TAG
 
#define pbvh_bmesh_node_vert_use_count_is_equal(nodes, cd_face_node_offset, node, v, n)    (pbvh_bmesh_node_vert_use_count_at_most(nodes, cd_face_node_offset, node, v, (n) + 1) == n)
 
#define EDGE_QUEUE_TEST(e)   BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
 
#define EDGE_QUEUE_ENABLE(e)    BM_elem_flag_enable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
 
#define EDGE_QUEUE_DISABLE(e)    BM_elem_flag_disable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
 
#define EVEN_EDGELEN_THRESHOLD   1.2f
 
#define EVEN_GENERATION_SCALE   1.6f
 

Functions

static void blender::bke::pbvh::pbvh_bmesh_node_finalize (BMeshNode *n, const int node_index, const int cd_vert_node_offset, const int cd_face_node_offset)
 
static void blender::bke::pbvh::pbvh_bmesh_node_split (Vector< BMeshNode > &nodes, Vector< bool > &node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, const Span< Bounds< float3 > > face_bounds, int node_index)
 
static bool blender::bke::pbvh::pbvh_bmesh_node_limit_ensure (BMesh &bm, Vector< BMeshNode > &nodes, Vector< bool > &node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, int node_index)
 
BLI_INLINE int blender::bke::pbvh::pbvh_bmesh_node_index_from_vert (const int cd_vert_node_offset, const BMVert *key)
 
BLI_INLINE int blender::bke::pbvh::pbvh_bmesh_node_index_from_face (const int cd_face_node_offset, const BMFace *key)
 
BLI_INLINE BMeshNodeblender::bke::pbvh::pbvh_bmesh_node_from_vert (MutableSpan< BMeshNode > nodes, const int cd_vert_node_offset, const BMVert *key)
 
BLI_INLINE BMeshNodeblender::bke::pbvh::pbvh_bmesh_node_from_face (MutableSpan< BMeshNode > nodes, const int cd_face_node_offset, const BMFace *key)
 
static BMVertblender::bke::pbvh::pbvh_bmesh_vert_create (BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, BMLog &bm_log, const BMVert *v1, const BMVert *v2, const int node_index, const float co[3], const float no[3], const int cd_vert_node_offset, const int cd_vert_mask_offset)
 
static BMFaceblender::bke::pbvh::pbvh_bmesh_face_create (BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_face_node_offset, BMLog &bm_log, int node_index, const Span< BMVert * > v_tri, const Span< BMEdge * > e_tri, const BMFace *f_example)
 
static int blender::bke::pbvh::pbvh_bmesh_node_vert_use_count_at_most (MutableSpan< BMeshNode > nodes, const int cd_face_node_offset, BMeshNode *node, BMVert *v, const int count_max)
 
static std::optional< intblender::bke::pbvh::pbvh_bmesh_vert_other_node_find (const int cd_vert_node_offset, const int cd_face_node_offset, BMVert *v)
 
static void blender::bke::pbvh::pbvh_bmesh_vert_ownership_transfer (MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int new_owner_index, BMVert *v)
 
static void blender::bke::pbvh::pbvh_bmesh_vert_remove (MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMVert *v)
 
static void blender::bke::pbvh::pbvh_bmesh_face_remove (MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMLog &bm_log, BMFace *f)
 
static Array< BMLoop * > blender::bke::pbvh::pbvh_bmesh_edge_loops (BMEdge *e)
 
static void blender::bke::pbvh::pbvh_bmesh_node_drop_orig (BMeshNode *node)
 
static bool blender::bke::pbvh::edge_queue_tri_in_sphere (const EdgeQueue *q, BMFace *f)
 
static bool blender::bke::pbvh::edge_queue_tri_in_circle (const EdgeQueue *q, BMFace *f)
 
static bool blender::bke::pbvh::check_mask (EdgeQueueContext *eq_ctx, BMVert *v)
 
static void blender::bke::pbvh::edge_queue_insert (EdgeQueueContext *eq_ctx, BMEdge *e, float priority)
 
static bool blender::bke::pbvh::is_boundary_edge (const BMEdge &edge)
 
static bool blender::bke::pbvh::is_boundary_vert (const BMVert &vertex)
 
static bool blender::bke::pbvh::is_edge_adjacent_to_boundary (const BMEdge &edge)
 
static float blender::bke::pbvh::long_edge_queue_priority (const BMEdge &edge)
 
static float blender::bke::pbvh::short_edge_queue_priority (const BMEdge &edge)
 
static void blender::bke::pbvh::long_edge_queue_edge_add (EdgeQueueContext *eq_ctx, BMEdge *e)
 
static void blender::bke::pbvh::long_edge_queue_edge_add_recursive (EdgeQueueContext *eq_ctx, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len)
 
static void blender::bke::pbvh::short_edge_queue_edge_add (EdgeQueueContext *eq_ctx, BMEdge *e)
 
static void blender::bke::pbvh::long_edge_queue_face_add (EdgeQueueContext *eq_ctx, BMFace *f)
 
static void blender::bke::pbvh::short_edge_queue_face_add (EdgeQueueContext *eq_ctx, BMFace *f)
 
static void blender::bke::pbvh::long_edge_queue_create (EdgeQueueContext *eq_ctx, const float max_edge_len, MutableSpan< BMeshNode > nodes, const float center[3], const float view_normal[3], float radius, const bool use_frontface, const bool use_projected)
 
static void blender::bke::pbvh::short_edge_queue_create (EdgeQueueContext *eq_ctx, const float min_edge_len, MutableSpan< BMeshNode > nodes, const float center[3], const float view_normal[3], float radius, const bool use_frontface, const bool use_projected)
 
static void blender::bke::pbvh::copy_edge_data (BMesh &bm, BMEdge &dst, BMEdge &src)
 
static void blender::bke::pbvh::merge_edge_data (BMesh &bm, BMEdge &dst, const BMEdge &src)
 
static void blender::bke::pbvh::pbvh_bmesh_split_edge (EdgeQueueContext *eq_ctx, BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMLog &bm_log, BMEdge *e)
 
static bool blender::bke::pbvh::pbvh_bmesh_subdivide_long_edges (EdgeQueueContext *eq_ctx, BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMLog &bm_log)
 
static bool blender::bke::pbvh::vert_in_face_adjacent_to_edge (BMVert &vert, BMEdge &edge)
 
static void blender::bke::pbvh::merge_flap_edge_data (BMesh &bm, BMFace *del_face, BMFace *flap_face, BMEdge *e, BMVert *v_del, BMLoop *l_del, BMVert *v_conn)
 
static BMVertblender::bke::pbvh::find_outer_flap_vert (BMFace &face)
 
static void blender::bke::pbvh::try_merge_flap_edge_data_before_dissolve (BMesh &bm, BMFace &face)
 
static void blender::bke::pbvh::merge_face_edge_data (BMesh &bm, BMFace *, BMFace *new_face, BMVert *v_del, BMLoop *l_del, BMVert *v_conn)
 
static void blender::bke::pbvh::pbvh_bmesh_collapse_edge (BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMLog &bm_log, BMEdge *e, BMVert *v1, BMVert *v2, GHash *deleted_verts, EdgeQueueContext *eq_ctx)
 
static bool blender::bke::pbvh::pbvh_bmesh_collapse_short_edges (EdgeQueueContext *eq_ctx, const float min_edge_len, BMesh &bm, MutableSpan< BMeshNode > nodes, MutableSpan< bool > node_changed, const int cd_vert_node_offset, const int cd_face_node_offset, BMLog &bm_log)
 
bool blender::bke::pbvh::node_raycast_bmesh (BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, IsectRayPrecalc *isect_precalc, float *depth, bool use_original, BMVert **r_active_vertex, float3 &r_face_normal)
 
bool blender::bke::pbvh::raycast_node_detail_bmesh (BMeshNode &node, const float3 &ray_start, IsectRayPrecalc *isect_precalc, float *depth, float *r_edge_length)
 
bool blender::bke::pbvh::bmesh_node_nearest_to_ray (BMeshNode &node, const float3 &ray_start, const float3 &ray_normal, float *r_depth, float *dist_sq, bool use_original)
 
void blender::bke::pbvh::bmesh_normals_update (Tree &pbvh, const IndexMask &nodes_to_update)
 
static void blender::bke::pbvh::pbvh_bmesh_node_limit_ensure_fast (const MutableSpan< BMFace * > nodeinfo, const Span< Bounds< float3 > > face_bounds, FastNodeBuildInfo *node, MemArena *arena)
 
static void blender::bke::pbvh::pbvh_bmesh_create_nodes_fast_recursive (Vector< BMeshNode > &nodes, const int cd_vert_node_offset, const int cd_face_node_offset, const Span< BMFace * > nodeinfo, const Span< Bounds< float3 > > face_bounds, FastNodeBuildInfo *node, int node_index)
 
bool blender::bke::pbvh::bmesh_update_topology (BMesh &bm, Tree &pbvh, BMLog &bm_log, PBVHTopologyUpdateMode mode, float min_edge_len, float max_edge_len, const float center[3], const float view_normal[3], float radius, bool use_frontface, bool use_projected)
 
static void blender::bke::pbvh::copy_original_vert (BMLog *log, BMeshNode *node, BMVert *v, int i, bool use_original)
 
void BKE_pbvh_bmesh_node_save_orig (BMesh *bm, BMLog *log, blender::bke::pbvh::BMeshNode *node, bool use_original)
 
void BKE_pbvh_bmesh_after_stroke (BMesh &bm, blender::bke::pbvh::Tree &pbvh)
 
void BKE_pbvh_node_mark_topology_update (blender::bke::pbvh::Node &node)
 
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts (blender::bke::pbvh::BMeshNode *node)
 
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_other_verts (blender::bke::pbvh::BMeshNode *node)
 
const blender::Set< BMFace *, 0 > & BKE_pbvh_bmesh_node_faces (blender::bke::pbvh::BMeshNode *node)
 

Variables

static CLG_LogRef LOG = {"pbvh.bmesh"}
 
constexpr int blender::bke::pbvh::leaf_limit = 400
 

BMesh Utility API

Use some local functions which assume triangles.

#define BM_LOOPS_OF_VERT_ITER_BEGIN(l_iter_radial_, v_)
 
#define BM_LOOPS_OF_VERT_ITER_END
 
#define BM_FACES_OF_VERT_ITER_BEGIN(f_iter_, v_)
 
#define BM_FACES_OF_VERT_ITER_END
 
static Bounds< float3blender::bke::pbvh::negative_bounds ()
 
static std::array< BMEdge *, 3 > blender::bke::pbvh::bm_edges_from_tri (BMesh &bm, const Span< BMVert * > v_tri)
 
BLI_INLINE std::array< BMVert *, 3 > blender::bke::pbvh::bm_face_as_array (BMFace *f)
 
static BMFaceblender::bke::pbvh::bm_face_exists_tri_from_loop_vert (BMLoop *l_radial_first, BMVert *v_opposite)
 
static BMVertblender::bke::pbvh::bm_vert_hash_lookup_chain (GHash *deleted_verts, BMVert *v)
 

Macro Definition Documentation

◆ BM_FACES_OF_VERT_ITER_BEGIN

#define BM_FACES_OF_VERT_ITER_BEGIN ( f_iter_,
v_ )
Value:
{ \
BMLoop *l_iter_radial_; \
BM_LOOPS_OF_VERT_ITER_BEGIN (l_iter_radial_, v_) { \
f_iter_ = l_iter_radial_->f;
struct BMFace * f

Definition at line 107 of file pbvh_bmesh.cc.

Referenced by blender::bke::pbvh::pbvh_bmesh_node_vert_use_count_at_most(), blender::bke::pbvh::pbvh_bmesh_vert_other_node_find(), and blender::bke::pbvh::pbvh_bmesh_vert_remove().

◆ BM_FACES_OF_VERT_ITER_END

◆ BM_LOOPS_OF_VERT_ITER_BEGIN

#define BM_LOOPS_OF_VERT_ITER_BEGIN ( l_iter_radial_,
v_ )
Value:
{ \
struct { \
BMVert *v; \
BMEdge *e_iter, *e_first; \
BMLoop *l_iter_radial; \
} _iter; \
_iter.v = v_; \
if (_iter.v->e) { \
_iter.e_iter = _iter.e_first = _iter.v->e; \
do { \
if (_iter.e_iter->l) { \
_iter.l_iter_radial = _iter.e_iter->l; \
do { \
if (_iter.l_iter_radial->v == _iter.v) { \
l_iter_radial_ = _iter.l_iter_radial;
ATTR_WARN_UNUSED_RESULT const BMVert * v
struct BMLoop * l
struct BMVert * v
struct BMEdge * e

Typically using BM_LOOPS_OF_VERT and BM_FACES_OF_VERT iterators are fine, however this is an area where performance matters so do it in-line.

Take care since 'break' won't works as expected within these macros!

Definition at line 77 of file pbvh_bmesh.cc.

Referenced by blender::bke::pbvh::pbvh_bmesh_collapse_edge().

◆ BM_LOOPS_OF_VERT_ITER_END

#define BM_LOOPS_OF_VERT_ITER_END
Value:
} \
} \
while ((_iter.l_iter_radial = _iter.l_iter_radial->radial_next) != _iter.e_iter->l) \
; \
} \
} \
while ((_iter.e_iter = BM_DISK_EDGE_NEXT(_iter.e_iter, _iter.v)) != _iter.e_first) \
; \
} \
} \
((void)0)
#define BM_DISK_EDGE_NEXT(e, v)

Definition at line 94 of file pbvh_bmesh.cc.

Referenced by blender::bke::pbvh::pbvh_bmesh_collapse_edge().

◆ EDGE_QUEUE_DISABLE

◆ EDGE_QUEUE_ENABLE

#define EDGE_QUEUE_ENABLE ( e)     BM_elem_flag_enable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)

Definition at line 709 of file pbvh_bmesh.cc.

Referenced by blender::bke::pbvh::edge_queue_insert().

◆ EDGE_QUEUE_TEST

◆ EVEN_EDGELEN_THRESHOLD

#define EVEN_EDGELEN_THRESHOLD   1.2f

◆ EVEN_GENERATION_SCALE

#define EVEN_GENERATION_SCALE   1.6f

◆ pbvh_bmesh_node_vert_use_count_is_equal

#define pbvh_bmesh_node_vert_use_count_is_equal ( nodes,
cd_face_node_offset,
node,
v,
n )    (pbvh_bmesh_node_vert_use_count_at_most(nodes, cd_face_node_offset, node, v, (n) + 1) == n)

Definition at line 500 of file pbvh_bmesh.cc.

Referenced by blender::bke::pbvh::pbvh_bmesh_face_remove().

◆ USE_EDGEQUEUE_EVEN_SUBDIV

#define USE_EDGEQUEUE_EVEN_SUBDIV

Definition at line 33 of file pbvh_bmesh.cc.

◆ USE_EDGEQUEUE_FRONTFACE

#define USE_EDGEQUEUE_FRONTFACE

Definition at line 41 of file pbvh_bmesh.cc.

◆ USE_EDGEQUEUE_TAG

#define USE_EDGEQUEUE_TAG

Definition at line 44 of file pbvh_bmesh.cc.

Function Documentation

◆ BKE_pbvh_bmesh_after_stroke()

◆ BKE_pbvh_bmesh_node_faces()

◆ BKE_pbvh_bmesh_node_other_verts()

◆ BKE_pbvh_bmesh_node_save_orig()

◆ BKE_pbvh_bmesh_node_unique_verts()

const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts ( blender::bke::pbvh::BMeshNode * node)

Definition at line 2505 of file pbvh_bmesh.cc.

Referenced by blender::ed::sculpt_paint::cloth::apply_filter_forces_bmesh(), blender::ed::sculpt_paint::mask::apply_mask_bmesh(), blender::ed::sculpt_paint::mask::apply_new_mask_bmesh(), blender::ed::sculpt_paint::project::apply_projection_bmesh(), blender::ed::sculpt_paint::smooth::blur_geometry_data_array(), blender::ed::sculpt_paint::undo::bmesh_push(), blender::ed::sculpt_paint::calc_area_normal_and_center_node_bmesh(), blender::ed::sculpt_paint::boundary::calc_bend_bmesh(), blender::ed::sculpt_paint::calc_bmesh(), blender::ed::sculpt_paint::pose::calc_bmesh(), blender::ed::sculpt_paint::cloth::calc_constraint_factors(), blender::ed::sculpt_paint::filter::calc_enhance_details_filter(), blender::ed::sculpt_paint::calc_factors_common_bmesh(), blender::ed::sculpt_paint::calc_factors_common_from_orig_data_bmesh(), blender::ed::sculpt_paint::cloth::calc_forces_bmesh(), blender::ed::sculpt_paint::boundary::calc_grab_bmesh(), blender::ed::sculpt_paint::boundary::calc_inflate_bmesh(), blender::ed::sculpt_paint::filter::calc_inflate_filter(), blender::ed::sculpt_paint::filter::calc_random_filter(), blender::ed::sculpt_paint::filter::calc_relax_face_sets_filter(), blender::ed::sculpt_paint::filter::calc_relax_filter(), blender::ed::sculpt_paint::filter::calc_scale_filter(), blender::ed::sculpt_paint::filter::calc_sharpen_filter(), blender::ed::sculpt_paint::boundary::calc_slide_bmesh(), blender::ed::sculpt_paint::boundary::calc_smooth_bmesh(), blender::ed::sculpt_paint::filter::calc_smooth_filter(), blender::ed::sculpt_paint::filter::calc_sphere_filter(), blender::ed::sculpt_paint::filter::calc_surface_smooth_filter(), blender::ed::sculpt_paint::boundary::calc_twist_bmesh(), blender::ed::sculpt_paint::create_node_vert_offsets_bmesh(), blender::ed::sculpt_paint::mask::decrease_contrast_mask_bmesh(), blender::ed::sculpt_paint::cloth::do_simulation_step(), blender::ed::sculpt_paint::elastic_transform_node_bmesh(), blender::ed::sculpt_paint::cloth::ensure_nodes_constraints(), blender::ed::sculpt_paint::fake_neighbor_search_bmesh(), blender::ed::sculpt_paint::mask::fill_mask_bmesh(), blender::ed::sculpt_paint::mask::gesture_apply_for_symmetry_pass(), blender::ed::sculpt_paint::pose::grow_factors_bmesh(), blender::ed::sculpt_paint::mask::grow_mask_bmesh(), blender::ed::sculpt_paint::mask::increase_contrast_mask_bmesh(), blender::ed::sculpt_paint::mask::invert_mask_bmesh(), blender::ed::sculpt_paint::hide::invert_visibility_bmesh(), blender::ed::sculpt_paint::filter::mesh_filter_sharpen_init(), blender::ed::sculpt_paint::nearest_vert_calc_bmesh(), blender::ed::sculpt_paint::hide::partialvis_update_bmesh_nodes(), blender::ed::sculpt_paint::undo::restore_mask_from_undo_step(), blender::ed::sculpt_paint::undo::restore_position_from_undo_step(), blender::ed::sculpt_paint::sample_node_surface_bmesh(), blender::ed::sculpt_paint::mask::sculpt_mask_init_exec(), blender::ed::sculpt_paint::mask::sharpen_mask_bmesh(), blender::ed::sculpt_paint::mask::shrink_mask_bmesh(), blender::ed::sculpt_paint::mask::smooth_mask_bmesh(), blender::ed::sculpt_paint::transform_node_bmesh(), and blender::ed::sculpt_paint::expand::update_mask_bmesh().

◆ BKE_pbvh_node_mark_topology_update()

Variable Documentation

◆ LOG

CLG_LogRef LOG = {"pbvh.bmesh"}
static

Definition at line 30 of file pbvh_bmesh.cc.