Blender  V3.3
Classes | Macros | Typedefs | Functions
pbvh_bmesh.c File Reference
#include "MEM_guardedalloc.h"
#include "BLI_buffer.h"
#include "BLI_ghash.h"
#include "BLI_heap_simple.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
#include "BKE_pbvh.h"
#include "GPU_buffers.h"
#include "bmesh.h"
#include "pbvh_intern.h"
#include "BKE_global.h"

Go to the source code of this file.

Classes

struct  EdgeQueue
 
struct  EdgeQueueContext
 
struct  FastNodeBuildInfo
 

Macros

#define USE_EDGEQUEUE_EVEN_SUBDIV
 
#define USE_EDGEQUEUE_FRONTFACE
 
#define USE_EDGEQUEUE_TAG
 
#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)
 
#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
 

Typedefs

typedef struct EdgeQueue EdgeQueue
 

Functions

static void pbvh_bmesh_node_finalize (PBVH *pbvh, const int node_index, const int cd_vert_node_offset, const int cd_face_node_offset)
 
static void pbvh_bmesh_node_split (PBVH *pbvh, const BBC *bbc_array, int node_index)
 
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_face (PBVH *pbvh, const BMFace *key)
 
BLI_INLINE PBVHNode * pbvh_bmesh_node_from_vert (PBVH *pbvh, const BMVert *key)
 
BLI_INLINE PBVHNode * pbvh_bmesh_node_from_face (PBVH *pbvh, const BMFace *key)
 
static BMVert * pbvh_bmesh_vert_create (PBVH *pbvh, int node_index, const float co[3], const float no[3], const int cd_vert_mask_offset)
 
static BMFace * pbvh_bmesh_face_create (PBVH *pbvh, int node_index, BMVert *v_tri[3], BMEdge *e_tri[3], const BMFace *f_example)
 
static int pbvh_bmesh_node_vert_use_count_at_most (PBVH *pbvh, PBVHNode *node, BMVert *v, const int count_max)
 
static PBVHNode * pbvh_bmesh_vert_other_node_find (PBVH *pbvh, BMVert *v)
 
static void pbvh_bmesh_vert_ownership_transfer (PBVH *pbvh, PBVHNode *new_owner, BMVert *v)
 
static void pbvh_bmesh_vert_remove (PBVH *pbvh, BMVert *v)
 
static void pbvh_bmesh_face_remove (PBVH *pbvh, BMFace *f)
 
static void pbvh_bmesh_edge_loops (BLI_Buffer *buf, BMEdge *e)
 
static void pbvh_bmesh_node_drop_orig (PBVHNode *node)
 
static bool edge_queue_tri_in_sphere (const EdgeQueue *q, BMFace *f)
 
static bool edge_queue_tri_in_circle (const EdgeQueue *q, BMFace *f)
 
static bool check_mask (EdgeQueueContext *eq_ctx, BMVert *v)
 
static void edge_queue_insert (EdgeQueueContext *eq_ctx, BMEdge *e, float priority)
 
static void long_edge_queue_edge_add (EdgeQueueContext *eq_ctx, BMEdge *e)
 
static void long_edge_queue_edge_add_recursive (EdgeQueueContext *eq_ctx, BMLoop *l_edge, BMLoop *l_end, const float len_sq, float limit_len)
 
static void short_edge_queue_edge_add (EdgeQueueContext *eq_ctx, BMEdge *e)
 
static void long_edge_queue_face_add (EdgeQueueContext *eq_ctx, BMFace *f)
 
static void short_edge_queue_face_add (EdgeQueueContext *eq_ctx, BMFace *f)
 
static void long_edge_queue_create (EdgeQueueContext *eq_ctx, PBVH *pbvh, const float center[3], const float view_normal[3], float radius, const bool use_frontface, const bool use_projected)
 
static void short_edge_queue_create (EdgeQueueContext *eq_ctx, PBVH *pbvh, const float center[3], const float view_normal[3], float radius, const bool use_frontface, const bool use_projected)
 
static void pbvh_bmesh_split_edge (EdgeQueueContext *eq_ctx, PBVH *pbvh, BMEdge *e, BLI_Buffer *edge_loops)
 
static bool pbvh_bmesh_subdivide_long_edges (EdgeQueueContext *eq_ctx, PBVH *pbvh, BLI_Buffer *edge_loops)
 
static void pbvh_bmesh_collapse_edge (PBVH *pbvh, BMEdge *e, BMVert *v1, BMVert *v2, GHash *deleted_verts, BLI_Buffer *deleted_faces, EdgeQueueContext *eq_ctx)
 
static bool pbvh_bmesh_collapse_short_edges (EdgeQueueContext *eq_ctx, PBVH *pbvh, BLI_Buffer *deleted_faces)
 
bool pbvh_bmesh_node_raycast (PBVHNode *node, const float ray_start[3], const float ray_normal[3], struct IsectRayPrecalc *isect_precalc, float *depth, bool use_original, int *r_active_vertex_index, float *r_face_normal)
 
bool BKE_pbvh_bmesh_node_raycast_detail (PBVHNode *node, const float ray_start[3], struct IsectRayPrecalc *isect_precalc, float *depth, float *r_edge_length)
 
bool pbvh_bmesh_node_nearest_to_ray (PBVHNode *node, const float ray_start[3], const float ray_normal[3], float *depth, float *dist_sq, bool use_original)
 
void pbvh_bmesh_normals_update (PBVHNode **nodes, int totnode)
 
static void pbvh_bmesh_node_limit_ensure_fast (PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, struct FastNodeBuildInfo *node, MemArena *arena)
 
static void pbvh_bmesh_create_nodes_fast_recursive (PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, struct FastNodeBuildInfo *node, int node_index)
 
void BKE_pbvh_build_bmesh (PBVH *pbvh, BMesh *bm, bool smooth_shading, BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset)
 
bool BKE_pbvh_bmesh_update_topology (PBVH *pbvh, PBVHTopologyUpdateMode mode, const float center[3], const float view_normal[3], float radius, const bool use_frontface, const bool use_projected)
 
void BKE_pbvh_bmesh_node_save_orig (BMesh *bm, PBVHNode *node)
 
void BKE_pbvh_bmesh_after_stroke (PBVH *pbvh)
 
void BKE_pbvh_bmesh_detail_size_set (PBVH *pbvh, float detail_size)
 
void BKE_pbvh_node_mark_topology_update (PBVHNode *node)
 
GSet * BKE_pbvh_bmesh_node_unique_verts (PBVHNode *node)
 
GSet * BKE_pbvh_bmesh_node_other_verts (PBVHNode *node)
 
struct GSet * BKE_pbvh_bmesh_node_faces (PBVHNode *node)
 

BMesh Utility API

Ensure we don't have dirty tags for the edge queue, and that they are left cleared. (slow, even for debug mode, so leave disabled for now).

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 void bm_edges_from_tri (BMesh *bm, BMVert *v_tri[3], BMEdge *e_tri[3])
 
BLI_INLINE void bm_face_as_array_index_tri (BMFace *f, int r_index[3])
 
static BMFace * bm_face_exists_tri_from_loop_vert (BMLoop *l_radial_first, BMVert *v_opposite)
 
static BMVert * 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;

Definition at line 95 of file pbvh_bmesh.c.

◆ BM_FACES_OF_VERT_ITER_END

#define BM_FACES_OF_VERT_ITER_END
Value:
} \
BM_LOOPS_OF_VERT_ITER_END; \
} \
((void)0)
SyclQueue void void size_t num_bytes void

Definition at line 101 of file pbvh_bmesh.c.

◆ 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
Definition: bmesh_class.h:128
struct BMEdge * e
Definition: bmesh_class.h:97

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 65 of file pbvh_bmesh.c.

◆ 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: bmesh_class.h:625

Definition at line 82 of file pbvh_bmesh.c.

◆ EDGE_QUEUE_DISABLE

#define EDGE_QUEUE_DISABLE (   e)     BM_elem_flag_disable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)

Definition at line 751 of file pbvh_bmesh.c.

◆ EDGE_QUEUE_ENABLE

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

Definition at line 749 of file pbvh_bmesh.c.

◆ EDGE_QUEUE_TEST

#define EDGE_QUEUE_TEST (   e)    (BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG))

Definition at line 748 of file pbvh_bmesh.c.

◆ 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 (   pbvh,
  node,
  v,
  n 
)     (pbvh_bmesh_node_vert_use_count_at_most(pbvh, node, v, (n) + 1) == n)

Definition at line 550 of file pbvh_bmesh.c.

◆ USE_EDGEQUEUE_EVEN_SUBDIV

#define USE_EDGEQUEUE_EVEN_SUBDIV

Definition at line 26 of file pbvh_bmesh.c.

◆ USE_EDGEQUEUE_FRONTFACE

#define USE_EDGEQUEUE_FRONTFACE

Definition at line 32 of file pbvh_bmesh.c.

◆ USE_EDGEQUEUE_TAG

#define USE_EDGEQUEUE_TAG

Definition at line 35 of file pbvh_bmesh.c.

Typedef Documentation

◆ EdgeQueue

typedef struct EdgeQueue EdgeQueue

Function Documentation

◆ BKE_pbvh_bmesh_after_stroke()

void BKE_pbvh_bmesh_after_stroke ( PBVH *  pbvh)

◆ BKE_pbvh_bmesh_detail_size_set()

void BKE_pbvh_bmesh_detail_size_set ( PBVH *  pbvh,
float  detail_size 
)

◆ BKE_pbvh_bmesh_node_faces()

struct GSet* BKE_pbvh_bmesh_node_faces ( PBVHNode *  node)

Definition at line 2113 of file pbvh_bmesh.c.

References node.

Referenced by partialvis_update_bmesh(), and sculpt_undo_bmesh_push().

◆ BKE_pbvh_bmesh_node_other_verts()

GSet* BKE_pbvh_bmesh_node_other_verts ( PBVHNode *  node)

Definition at line 2108 of file pbvh_bmesh.c.

References node.

Referenced by partialvis_update_bmesh(), and pbvh_bmesh_node_visibility_update().

◆ BKE_pbvh_bmesh_node_raycast_detail()

bool BKE_pbvh_bmesh_node_raycast_detail ( PBVHNode *  node,
const float  ray_start[3],
struct IsectRayPrecalc *  isect_precalc,
float *  depth,
float *  r_edge_length 
)

◆ BKE_pbvh_bmesh_node_save_orig()

void BKE_pbvh_bmesh_node_save_orig ( struct BMesh *  bm,
PBVHNode *  node 
)

In order to perform operations on the original node coordinates (currently just ray-cast), store the node's triangles and vertices.

Skips triangles that are hidden.

Definition at line 2020 of file pbvh_bmesh.c.

References BLI_gset_len(), BLI_gsetIterator_getKey(), bm, BM_elem_flag_test, BM_ELEM_HIDDEN, BM_elem_index_get, BM_elem_index_set, bm_face_as_array_index_tri(), BM_ITER_ELEM, BM_VERT, BM_VERTS_OF_FACE, BMVert::co, copy_v3_v3(), BMesh::elem_index_dirty, GSET_ITER, MEM_mallocN, node, and v.

Referenced by sculpt_topology_update().

◆ BKE_pbvh_bmesh_node_unique_verts()

GSet* BKE_pbvh_bmesh_node_unique_verts ( PBVHNode *  node)

Definition at line 2103 of file pbvh_bmesh.c.

References node.

Referenced by partialvis_update_bmesh(), and pbvh_bmesh_node_visibility_update().

◆ BKE_pbvh_bmesh_update_topology()

bool BKE_pbvh_bmesh_update_topology ( PBVH *  pbvh,
PBVHTopologyUpdateMode  mode,
const float  center[3],
const float  view_normal[3],
float  radius,
bool  use_frontface,
bool  use_projected 
)

◆ BKE_pbvh_build_bmesh()

void BKE_pbvh_build_bmesh ( PBVH *  pbvh,
struct BMesh *  bm,
bool  smooth_shading,
struct BMLog *  log,
int  cd_vert_node_offset,
int  cd_face_node_offset 
)

◆ BKE_pbvh_node_mark_topology_update()

void BKE_pbvh_node_mark_topology_update ( PBVHNode *  node)

Definition at line 2098 of file pbvh_bmesh.c.

References node, and PBVH_UpdateTopology.

Referenced by sculpt_detail_flood_fill_exec(), and sculpt_topology_update().

◆ bm_edges_from_tri()

static void bm_edges_from_tri ( BMesh *  bm,
BMVert *  v_tri[3],
BMEdge *  e_tri[3] 
)
static

Definition at line 107 of file pbvh_bmesh.c.

References bm, BM_CREATE_NO_DOUBLE, BM_edge_create(), and NULL.

Referenced by pbvh_bmesh_collapse_edge(), and pbvh_bmesh_split_edge().

◆ bm_face_as_array_index_tri()

BLI_INLINE void bm_face_as_array_index_tri ( BMFace *  f,
int  r_index[3] 
)

◆ bm_face_exists_tri_from_loop_vert()

static BMFace* bm_face_exists_tri_from_loop_vert ( BMLoop *  l_radial_first,
BMVert *  v_opposite 
)
static

A version of BM_face_exists, optimized for triangles when we know the loop and the opposite vertex.

Check if any triangle is formed by (l_radial_first->v, l_radial_first->next->v, v_opposite), at either winding (since its a triangle no special checks are needed).

l_radial_first->v & l_radial_first->next->v
+---+
|  /
| /
+ v_opposite

Its assumed that l_radial_first is never forming the target face.

Definition at line 144 of file pbvh_bmesh.c.

References BLI_assert, ELEM, BMLoop::f, BMFace::len, BMLoop::next, NULL, BMLoop::prev, BMLoop::radial_next, and BMLoop::v.

Referenced by pbvh_bmesh_collapse_edge().

◆ bm_vert_hash_lookup_chain()

static BMVert* bm_vert_hash_lookup_chain ( GHash *  deleted_verts,
BMVert *  v 
)
static

Uses a map of vertices to lookup the final target. References can't point to previous items (would cause infinite loop).

Definition at line 164 of file pbvh_bmesh.c.

References BLI_ghash_lookup_p(), NULL, and v.

Referenced by pbvh_bmesh_collapse_short_edges().

◆ check_mask()

static bool check_mask ( EdgeQueueContext *  eq_ctx,
BMVert *  v 
)
static

Definition at line 819 of file pbvh_bmesh.c.

References BM_ELEM_CD_GET_FLOAT, EdgeQueueContext::cd_vert_mask_offset, and v.

Referenced by edge_queue_insert().

◆ edge_queue_insert()

static void edge_queue_insert ( EdgeQueueContext *  eq_ctx,
BMEdge *  e,
float  priority 
)
static

◆ edge_queue_tri_in_circle()

static bool edge_queue_tri_in_circle ( const EdgeQueue *  q,
BMFace *  f 
)
static

◆ edge_queue_tri_in_sphere()

static bool edge_queue_tri_in_sphere ( const EdgeQueue *  q,
BMFace *  f 
)
static

◆ long_edge_queue_create()

static void long_edge_queue_create ( EdgeQueueContext *  eq_ctx,
PBVH *  pbvh,
const float  center[3],
const float  view_normal[3],
float  radius,
const bool  use_frontface,
const bool  use_projected 
)
static

◆ long_edge_queue_edge_add()

static void long_edge_queue_edge_add ( EdgeQueueContext *  eq_ctx,
BMEdge *  e 
)
static

◆ long_edge_queue_edge_add_recursive()

static void long_edge_queue_edge_add_recursive ( EdgeQueueContext *  eq_ctx,
BMLoop *  l_edge,
BMLoop *  l_end,
const float  len_sq,
float  limit_len 
)
static

◆ long_edge_queue_face_add()

static void long_edge_queue_face_add ( EdgeQueueContext *  eq_ctx,
BMFace *  f 
)
static

◆ pbvh_bmesh_collapse_edge()

static void pbvh_bmesh_collapse_edge ( PBVH *  pbvh,
BMEdge *  e,
BMVert *  v1,
BMVert *  v2,
GHash *  deleted_verts,
BLI_Buffer *  deleted_faces,
EdgeQueueContext *  eq_ctx 
)
static

◆ pbvh_bmesh_collapse_short_edges()

static bool pbvh_bmesh_collapse_short_edges ( EdgeQueueContext *  eq_ctx,
PBVH *  pbvh,
BLI_Buffer *  deleted_faces 
)
static

◆ pbvh_bmesh_create_nodes_fast_recursive()

static void pbvh_bmesh_create_nodes_fast_recursive ( PBVH *  pbvh,
BMFace **  nodeinfo,
BBC *  bbc_array,
struct FastNodeBuildInfo *  node,
int  node_index 
)
static

◆ pbvh_bmesh_edge_loops()

static void pbvh_bmesh_edge_loops ( BLI_Buffer *  buf,
BMEdge *  e 
)
static

◆ pbvh_bmesh_face_create()

static BMFace* pbvh_bmesh_face_create ( PBVH *  pbvh,
int  node_index,
BMVert *  v_tri[3],
BMEdge *  e_tri[3],
const BMFace *  f_example 
)
static

◆ pbvh_bmesh_face_remove()

static void pbvh_bmesh_face_remove ( PBVH *  pbvh,
BMFace *  f 
)
static

◆ pbvh_bmesh_node_drop_orig()

static void pbvh_bmesh_node_drop_orig ( PBVHNode *  node)
static

Definition at line 702 of file pbvh_bmesh.c.

References MEM_freeN, node, and NULL.

Referenced by BKE_pbvh_bmesh_after_stroke().

◆ pbvh_bmesh_node_finalize()

static void pbvh_bmesh_node_finalize ( PBVH *  pbvh,
const int  node_index,
const int  cd_vert_node_offset,
const int  cd_face_node_offset 
)
static

◆ pbvh_bmesh_node_from_face()

BLI_INLINE PBVHNode* pbvh_bmesh_node_from_face ( PBVH *  pbvh,
const BMFace *  key 
)

◆ pbvh_bmesh_node_from_vert()

BLI_INLINE PBVHNode* pbvh_bmesh_node_from_vert ( PBVH *  pbvh,
const BMVert *  key 
)

◆ pbvh_bmesh_node_index_from_face()

BLI_INLINE int pbvh_bmesh_node_index_from_face ( PBVH *  pbvh,
const BMFace *  key 
)

◆ pbvh_bmesh_node_index_from_vert()

BLI_INLINE int pbvh_bmesh_node_index_from_vert ( PBVH *  pbvh,
const BMVert *  key 
)

◆ pbvh_bmesh_node_limit_ensure()

static bool pbvh_bmesh_node_limit_ensure ( PBVH *  pbvh,
int  node_index 
)
static

◆ pbvh_bmesh_node_limit_ensure_fast()

static void pbvh_bmesh_node_limit_ensure_fast ( PBVH *  pbvh,
BMFace **  nodeinfo,
BBC *  bbc_array,
struct FastNodeBuildInfo *  node,
MemArena *  arena 
)
static

Recursively split the node if it exceeds the leaf_limit. This function is multi-thread-able since each invocation applies to a sub part of the arrays.

Definition at line 1682 of file pbvh_bmesh.c.

References BB_expand(), BB_reset(), BB_widest_axis(), BBC::bcentroid, BLI_assert, BLI_memarena_alloc(), BM_elem_index_get, BB::bmax, BB::bmin, FastNodeBuildInfo::child1, FastNodeBuildInfo::child2, PBVH::leaf_limit, node, NULL, FastNodeBuildInfo::start, and FastNodeBuildInfo::totface.

Referenced by BKE_pbvh_build_bmesh().

◆ pbvh_bmesh_node_nearest_to_ray()

bool pbvh_bmesh_node_nearest_to_ray ( PBVHNode *  node,
const float  ray_start[3],
const float  ray_normal[3],
float *  depth,
float *  dist_sq,
bool  use_original 
)

◆ pbvh_bmesh_node_raycast()

bool pbvh_bmesh_node_raycast ( PBVHNode *  node,
const float  ray_start[3],
const float  ray_normal[3],
struct IsectRayPrecalc *  isect_precalc,
float *  depth,
bool  use_original,
int *  r_active_vertex_index,
float *  r_face_normal 
)

◆ pbvh_bmesh_node_split()

static void pbvh_bmesh_node_split ( PBVH *  pbvh,
const BBC *  bbc_array,
int  node_index 
)
static

◆ pbvh_bmesh_node_vert_use_count_at_most()

static int pbvh_bmesh_node_vert_use_count_at_most ( PBVH *  pbvh,
PBVHNode *  node,
BMVert *  v,
const int  count_max 
)
static

◆ pbvh_bmesh_normals_update()

void pbvh_bmesh_normals_update ( PBVHNode **  nodes,
int  totnode 
)

◆ pbvh_bmesh_split_edge()

static void pbvh_bmesh_split_edge ( EdgeQueueContext *  eq_ctx,
PBVH *  pbvh,
BMEdge *  e,
BLI_Buffer *  edge_loops 
)
static

The 2 new faces created and assigned to f_new have their verts & edges shuffled around.

  • faces wind anticlockwise in this example.
  • original edge is (v1, v2)
  • original face is (v1, v2, v3)
        + v3(v_opp)
       /|\
      / | \
     /  |  \
  e4/   |   \ e3
   /    |e5  \
  /     |     \
 /  e1  |  e2  \
+-------+-------+
v1      v4(v_new) v2
 (first) (second)
  • f_new (first): v_tri=(v1, v4, v3), e_tri=(e1, e5, e4)
  • f_new (second): v_tri=(v4, v2, v3), e_tri=(e2, e3, e5)

Definition at line 1105 of file pbvh_bmesh.c.

References BLI_assert, BLI_buffer_at, BLI_gset_add(), BLI_gset_haskey(), PBVH::bm, BM_CREATE_NO_DOUBLE, BM_edge_create(), BM_edge_kill(), bm_edges_from_tri(), BM_EDGES_OF_VERT, BM_ELEM_CD_GET_FLOAT, BM_ELEM_CD_GET_INT, BM_ELEM_CD_SET_FLOAT, BM_face_kill(), BM_ITER_ELEM, PBVHNode::bm_other_verts, PBVHNode::bm_unique_verts, BM_vert_edge_count_is_over, EdgeQueueContext::cd_face_node_offset, EdgeQueueContext::cd_vert_mask_offset, EdgeQueueContext::cd_vert_node_offset, BMVert::co, BLI_Buffer::count, e, BMLoop::f, BMFace::len, long_edge_queue_edge_add(), long_edge_queue_face_add(), mid_v3_v3v3(), BMLoop::next, BMVert::no, PBVH::nodes, normalize_v3(), NULL, pbvh_bmesh_edge_loops(), pbvh_bmesh_face_create(), pbvh_bmesh_face_remove(), pbvh_bmesh_vert_create(), pbvh_bmesh_vert_ownership_transfer(), BMLoop::prev, BMLoop::v, v1, and v2.

Referenced by pbvh_bmesh_subdivide_long_edges().

◆ pbvh_bmesh_subdivide_long_edges()

static bool pbvh_bmesh_subdivide_long_edges ( EdgeQueueContext *  eq_ctx,
PBVH *  pbvh,
BLI_Buffer *  edge_loops 
)
static

◆ pbvh_bmesh_vert_create()

static BMVert* pbvh_bmesh_vert_create ( PBVH *  pbvh,
int  node_index,
const float  co[3],
const float  no[3],
const int  cd_vert_mask_offset 
)
static

◆ pbvh_bmesh_vert_other_node_find()

static PBVHNode* pbvh_bmesh_vert_other_node_find ( PBVH *  pbvh,
BMVert *  v 
)
static

◆ pbvh_bmesh_vert_ownership_transfer()

static void pbvh_bmesh_vert_ownership_transfer ( PBVH *  pbvh,
PBVHNode *  new_owner,
BMVert *  v 
)
static

◆ pbvh_bmesh_vert_remove()

static void pbvh_bmesh_vert_remove ( PBVH *  pbvh,
BMVert *  v 
)
static

◆ short_edge_queue_create()

static void short_edge_queue_create ( EdgeQueueContext *  eq_ctx,
PBVH *  pbvh,
const float  center[3],
const float  view_normal[3],
float  radius,
const bool  use_frontface,
const bool  use_projected 
)
static

◆ short_edge_queue_edge_add()

static void short_edge_queue_edge_add ( EdgeQueueContext *  eq_ctx,
BMEdge *  e 
)
static

◆ short_edge_queue_face_add()

static void short_edge_queue_face_add ( EdgeQueueContext *  eq_ctx,
BMFace *  f 
)
static