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 PBVHNodepbvh_bmesh_node_from_vert (PBVH *pbvh, const BMVert *key)
 
BLI_INLINE PBVHNodepbvh_bmesh_node_from_face (PBVH *pbvh, const BMFace *key)
 
static BMVertpbvh_bmesh_vert_create (PBVH *pbvh, int node_index, const float co[3], const float no[3], const int cd_vert_mask_offset)
 
static BMFacepbvh_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 PBVHNodepbvh_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)
 
GSetBKE_pbvh_bmesh_node_unique_verts (PBVHNode *node)
 
GSetBKE_pbvh_bmesh_node_other_verts (PBVHNode *node)
 
struct GSetBKE_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 BMFacebm_face_exists_tri_from_loop_vert (BMLoop *l_radial_first, BMVert *v_opposite)
 
static BMVertbm_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,
 
)     (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