Blender V4.3
bmo_subdivide_edgering.cc File Reference
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BLI_utildefines_stack.h"
#include "BKE_curve.hh"
#include "bmesh.hh"
#include "intern/bmesh_operators_private.hh"

Go to the source code of this file.

Classes

struct  LoopPairStore
 

Macros

#define VERT_SHARED   (1 << 0)
 
#define EDGE_RING   (1 << 0)
 
#define EDGE_RIM   (1 << 1)
 
#define EDGE_IN_STACK   (1 << 2)
 
#define FACE_OUT   (1 << 0)
 
#define FACE_SHARED   (1 << 1)
 
#define FACE_IN_STACK   (1 << 2)
 

Functions

Specialized Utility Functions
static uint bm_verts_tag_count (BMesh *bm)
 
static float bezier_handle_calc_length_v3 (const float co_a[3], const float no_a[3], const float co_b[3], const float no_b[3])
 
static void bm_edgeloop_vert_tag (BMEdgeLoopStore *el_store, const bool tag)
 
static void bmo_edgeloop_vert_tag (BMesh *bm, BMEdgeLoopStore *el_store, const short oflag, const bool tag)
 
static bool bmo_face_is_vert_tag_all (BMesh *bm, BMFace *f, short oflag)
 
static bool bm_vert_is_tag_edge_connect (BMesh *bm, BMVert *v)
 
static bool bm_edgeloop_check_overlap_all (BMesh *bm, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b)
 
Edge Loop Pairs

key (ordered loop pointers).

static GSetbm_edgering_pair_calc (BMesh *bm, ListBase *eloops_rim)
 
Subdivide an edge 'n' times and return an open edgeloop
static void bm_edge_subdiv_as_loop (BMesh *bm, ListBase *eloops, BMEdge *e, BMVert *v_a, const int cuts)
 
Loop Pair Cache (struct and utilities functions)
static void bm_vert_calc_surface_tangent (BMesh *bm, BMVert *v, float r_no[3])
 
static void bm_faces_share_tag_flush (BMesh *bm, BMEdge **e_arr, const uint e_arr_len)
 
static void bm_faces_share_tag_clear (BMesh *bm, BMEdge **e_arr_iter, const uint e_arr_len_iter)
 
static LoopPairStorebm_edgering_pair_store_create (BMesh *bm, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b, const int interp_mode)
 
static void bm_edgering_pair_store_free (LoopPairStore *lpair, const int interp_mode)
 
Interpolation Function
static void bm_edgering_pair_interpolate (BMesh *bm, LoopPairStore *lpair, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b, ListBase *eloops_ring, const int interp_mode, const int cuts, const float smooth, const float *falloff_cache)
 
static void bm_face_slice (BMesh *bm, BMLoop *l, const int cuts)
 
static bool bm_edgering_pair_order_is_flipped (BMesh *, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b)
 
static void bm_edgering_pair_order (BMesh *bm, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b)
 
static void bm_edgering_pair_subdiv (BMesh *bm, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b, ListBase *eloops_ring, const int cuts)
 
static void bm_edgering_pair_ringsubd (BMesh *bm, LoopPairStore *lpair, BMEdgeLoopStore *el_store_a, BMEdgeLoopStore *el_store_b, const int interp_mode, const int cuts, const float smooth, const float *falloff_cache)
 
static bool bm_edge_rim_test_cb (BMEdge *e, void *bm_v)
 
void bmo_subdivide_edgering_exec (BMesh *bm, BMOperator *op)
 

Detailed Description

This operator is a special edge-ring subdivision tool which gives special options for interpolation.

Note
Tagging and flags Tagging here is quite prone to errors if not done carefully.
  • With the exception of EDGE_RIM & EDGE_RIM, all flags need to be cleared on function exit.
  • verts use BM_ELEM_TAG, these need to be cleared before functions exit.
Note
Order of execution with 2+ rings is undefined, so take care.

Definition in file bmo_subdivide_edgering.cc.

Macro Definition Documentation

◆ EDGE_IN_STACK

#define EDGE_IN_STACK   (1 << 2)

Definition at line 42 of file bmo_subdivide_edgering.cc.

Referenced by bm_edgering_pair_subdiv().

◆ EDGE_RIM

◆ EDGE_RING

◆ FACE_IN_STACK

#define FACE_IN_STACK   (1 << 2)

Definition at line 46 of file bmo_subdivide_edgering.cc.

Referenced by bm_edgering_pair_subdiv().

◆ FACE_OUT

◆ FACE_SHARED

#define FACE_SHARED   (1 << 1)

◆ VERT_SHARED

#define VERT_SHARED   (1 << 0)

Function Documentation

◆ bezier_handle_calc_length_v3()

static float bezier_handle_calc_length_v3 ( const float co_a[3],
const float no_a[3],
const float co_b[3],
const float no_b[3] )
static

◆ bm_edge_rim_test_cb()

static bool bm_edge_rim_test_cb ( BMEdge * e,
void * bm_v )
static

Definition at line 1089 of file bmo_subdivide_edgering.cc.

References bm, BMO_edge_flag_test_bool, e, and EDGE_RIM.

Referenced by bmo_subdivide_edgering_exec().

◆ bm_edge_subdiv_as_loop()

static void bm_edge_subdiv_as_loop ( BMesh * bm,
ListBase * eloops,
BMEdge * e,
BMVert * v_a,
const int cuts )
static

◆ bm_edgeloop_check_overlap_all()

static bool bm_edgeloop_check_overlap_all ( BMesh * bm,
BMEdgeLoopStore * el_store_a,
BMEdgeLoopStore * el_store_b )
static

◆ bm_edgeloop_vert_tag()

static void bm_edgeloop_vert_tag ( BMEdgeLoopStore * el_store,
const bool tag )
static

◆ bm_edgering_pair_calc()

static GSet * bm_edgering_pair_calc ( BMesh * bm,
ListBase * eloops_rim )
static

Method for finding pairs:

  • first create (vert -> eloop) mapping.
  • loop over all eloops.
    • take first vertex of the eloop (any vertex will do)
      • loop over all edges of the vertex.
        • use the edge-verts and (vert -> eloop) map to create a pair of eloop pointers, add these to a hash.
Note
Each loop pair will be found twice. could sort and optimize this but not really so important.

Definition at line 196 of file bmo_subdivide_edgering.cc.

References BLI_ghash_free(), BLI_ghash_insert(), BLI_ghash_lookup(), BLI_ghash_ptr_new(), BLI_ghashutil_pairalloc(), BLI_gset_ensure_p_ex(), BLI_gset_free(), BLI_gset_len(), BLI_gset_pair_new(), bm, BM_edge_other_vert(), BM_EDGELOOP_NEXT, BM_edgeloop_verts_get(), BM_EDGES_OF_VERT, BM_ITER_ELEM, BMO_edge_flag_test, e, EDGE_RING, GHashPair::first, ListBase::first, GHashPair::second, and v.

Referenced by bmo_subdivide_edgering_exec().

◆ bm_edgering_pair_interpolate()

◆ bm_edgering_pair_order()

static void bm_edgering_pair_order ( BMesh * bm,
BMEdgeLoopStore * el_store_a,
BMEdgeLoopStore * el_store_b )
static

◆ bm_edgering_pair_order_is_flipped()

static bool bm_edgering_pair_order_is_flipped ( BMesh * ,
BMEdgeLoopStore * el_store_a,
BMEdgeLoopStore * el_store_b )
static

◆ bm_edgering_pair_ringsubd()

static void bm_edgering_pair_ringsubd ( BMesh * bm,
LoopPairStore * lpair,
BMEdgeLoopStore * el_store_a,
BMEdgeLoopStore * el_store_b,
const int interp_mode,
const int cuts,
const float smooth,
const float * falloff_cache )
static

◆ bm_edgering_pair_store_create()

◆ bm_edgering_pair_store_free()

static void bm_edgering_pair_store_free ( LoopPairStore * lpair,
const int interp_mode )
static

◆ bm_edgering_pair_subdiv()

◆ bm_face_slice()

static void bm_face_slice ( BMesh * bm,
BMLoop * l,
const int cuts )
static

Cuts up an ngon into many slices.

Definition at line 844 of file bmo_subdivide_edgering.cc.

References bm, BM_face_split(), BMO_face_flag_enable, BMLoop::f, FACE_OUT, l, BMFace::len, BMLoop::next, BMLoop::prev, and BMLoop::radial_next.

Referenced by bm_edgering_pair_subdiv().

◆ bm_faces_share_tag_clear()

static void bm_faces_share_tag_clear ( BMesh * bm,
BMEdge ** e_arr_iter,
const uint e_arr_len_iter )
static

Un-Tag faces connected to an edge loop, clearing FACE_SHARED

Definition at line 411 of file bmo_subdivide_edgering.cc.

References bm, BMO_face_flag_disable, e, BMLoop::f, FACE_SHARED, and BMLoop::radial_next.

Referenced by bm_edgering_pair_store_create().

◆ bm_faces_share_tag_flush()

static void bm_faces_share_tag_flush ( BMesh * bm,
BMEdge ** e_arr,
const uint e_arr_len )
static

Tag faces connected to an edge loop as FACE_SHARED if all vertices are VERT_SHARED.

Definition at line 389 of file bmo_subdivide_edgering.cc.

References bm, BMO_face_flag_enable, BMO_face_flag_test, bmo_face_is_vert_tag_all(), e, BMLoop::f, FACE_SHARED, BMLoop::radial_next, and VERT_SHARED.

Referenced by bm_edgering_pair_store_create().

◆ bm_vert_calc_surface_tangent()

static void bm_vert_calc_surface_tangent ( BMesh * bm,
BMVert * v,
float r_no[3] )
static

Use for finding spline handle direction from surrounding faces.

Resulting normal will always point towards 'FACE_SHARED'

This function must be called after all loops have been created, but before any mesh modifications.

Returns
true on success

Definition at line 323 of file bmo_subdivide_edgering.cc.

References add_v3_v3(), add_v3_v3v3(), BLI_assert, bm, BM_edge_calc_face_tangent(), BM_edge_is_wire(), BM_EDGES_OF_VERT, BM_ITER_ELEM, BM_LOOPS_OF_EDGE, BMO_edge_flag_test, BMO_face_flag_test, e, EDGE_RIM, BMLoop::f, FACE_OUT, FACE_SHARED, l, negate_v3(), normalize_v3(), normalize_v3_v3(), UNLIKELY, and v.

Referenced by bm_edgering_pair_interpolate(), and bm_edgering_pair_store_create().

◆ bm_vert_is_tag_edge_connect()

static bool bm_vert_is_tag_edge_connect ( BMesh * bm,
BMVert * v )
static

◆ bm_verts_tag_count()

static uint bm_verts_tag_count ( BMesh * bm)
static

◆ bmo_edgeloop_vert_tag()

static void bmo_edgeloop_vert_tag ( BMesh * bm,
BMEdgeLoopStore * el_store,
const short oflag,
const bool tag )
static

◆ bmo_face_is_vert_tag_all()

static bool bmo_face_is_vert_tag_all ( BMesh * bm,
BMFace * f,
short oflag )
static

◆ bmo_subdivide_edgering_exec()