Blender
V3.3
|
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines_stack.h"
#include "BKE_customdata.h"
#include "bmesh.h"
#include "intern/bmesh_operators_private.h"
Go to the source code of this file.
Classes | |
struct | InterpFace |
struct | SplitEdgeInfo |
Macros | |
#define | USE_LOOP_CUSTOMDATA_MERGE |
#define | ELE_NEW 1 |
#define | VERT_ORIG_STORE(_v) |
#define | VERT_ORIG_GET(_v) (const float *)BLI_ghash_lookup_default(vert_coords, (_v), (_v)->co) |
#define | VERT_ORIG_REMOVE(_v) BLI_ghash_remove(vert_coords, (_v), NULL, NULL) |
Functions | |
Inset Individual | |
Each face has a smaller face created inside it (simple logic). | |
static void | bmo_face_inset_individual (BMesh *bm, BMFace *f, MemArena *interp_arena, const float thickness, const float depth, const bool use_even_offset, const bool use_relative_offset, const bool use_interpolate) |
void | bmo_inset_individual_exec (BMesh *bm, BMOperator *op) |
Generic Face Interpolation | |
Interpolation, this is more complex for regions since we're not creating new faces and throwing away old ones, so instead, store face data needed for interpolation.
| |
typedef struct InterpFace | InterpFace |
static void | bm_interp_face_store (InterpFace *iface, BMesh *bm, BMFace *f, MemArena *interp_arena) |
static void | bm_interp_face_free (InterpFace *iface, BMesh *bm) |
static void | bm_loop_customdata_merge (BMesh *bm, BMEdge *e_connect, BMLoop *l_a_outer, BMLoop *l_b_outer, BMLoop *l_a_inner, BMLoop *l_b_inner) |
Inset Region | |
The boundary between tagged and untagged faces is inset (more involved logic). | |
typedef struct SplitEdgeInfo | SplitEdgeInfo |
static BMLoop * | bm_edge_is_mixed_face_tag (BMLoop *l) |
static float | bm_edge_info_average_length (BMVert *v, SplitEdgeInfo *edge_info) |
static float | bm_edge_info_average_length_fallback (BMVert *v_lookup, SplitEdgeInfo *edge_info, BMesh *bm, void **vert_lengths_p) |
static float | bm_edge_info_average_length_with_fallback (BMVert *v, SplitEdgeInfo *edge_info, BMesh *bm, void **vert_lengths_p) |
void | bmo_inset_region_exec (BMesh *bm, BMOperator *op) |
Inset face regions. Inset individual faces.
Definition in file bmo_inset.c.
#define ELE_NEW 1 |
Definition at line 26 of file bmo_inset.c.
#define USE_LOOP_CUSTOMDATA_MERGE |
Definition at line 24 of file bmo_inset.c.
#define VERT_ORIG_GET | ( | _v | ) | (const float *)BLI_ghash_lookup_default(vert_coords, (_v), (_v)->co) |
#define VERT_ORIG_REMOVE | ( | _v | ) | BLI_ghash_remove(vert_coords, (_v), NULL, NULL) |
#define VERT_ORIG_STORE | ( | _v | ) |
typedef struct InterpFace InterpFace |
typedef struct SplitEdgeInfo SplitEdgeInfo |
|
static |
Definition at line 498 of file bmo_inset.c.
References BM_EDGES_OF_VERT, BM_elem_index_get, BM_ITER_ELEM, e, float(), len, SplitEdgeInfo::length, and v.
Referenced by bm_edge_info_average_length_fallback(), and bm_edge_info_average_length_with_fallback().
|
static |
Fill in any vertices that are in the inset region but not connected to an edge being inset.
This is lazily initialized since it's a relatively expensive operation, and it's not needed in cases where all vertices being inset are connected to edges that are part of the inset.
Use to fill in length accumulated values based on the topological distance to vertices at the inset boundaries.
Unlike edge-lengths of vertices immediately around the vertex, this ensures the values are more evenly distributed.
The number of connected vertices we have added to length_accum
. The sign of the value is used to avoid mixing current and previous passes.
vert_stack
.length_accum
has not yet been divided.length_accum
value has been divided.Definition at line 534 of file bmo_inset.c.
References BLI_assert, bm, bm_edge_info_average_length(), BM_edge_other_vert(), BM_EDGES_OF_MESH, BM_EDGES_OF_VERT, BM_elem_flag_test, BM_elem_index_get, BM_ELEM_TAG, BM_ITER_ELEM, BM_ITER_MESH, BM_mesh_elem_index_ensure(), BM_VERT, count, e, float(), MEM_callocN, MEM_freeN, MEM_mallocN, NULL, STACK_DECLARE, STACK_INIT, STACK_PUSH, STACK_REMOVE, STACK_SIZE, BMesh::totvert, UNLIKELY, and v.
Referenced by bm_edge_info_average_length_with_fallback().
|
static |
Definition at line 635 of file bmo_inset.c.
References bm, bm_edge_info_average_length(), bm_edge_info_average_length_fallback(), blender::math::length(), and v.
Referenced by bmo_inset_region_exec().
Return the tag loop where there is:
Definition at line 470 of file bmo_inset.c.
References BM_elem_flag_test, BM_ELEM_TAG, BMLoop::f, l, LIKELY, NULL, and BMLoop::radial_next.
Referenced by bmo_inset_region_exec().
|
static |
Definition at line 86 of file bmo_inset.c.
References InterpFace::blocks_l, InterpFace::blocks_v, bm, CustomData_bmesh_free_block(), InterpFace::f, BMesh::ldata, BMFace::len, and BMesh::vdata.
Referenced by bmo_face_inset_individual(), and bmo_inset_region_exec().
|
static |
Definition at line 51 of file bmo_inset.c.
References axis_dominant_v3_to_m3(), InterpFace::axis_mat, BLI_assert, BLI_memarena_alloc(), InterpFace::blocks_l, InterpFace::blocks_v, bm, BM_elem_index_set, BM_FACE_FIRST_LOOP, BM_face_is_normal_valid(), BM_LOOP, BMVert::co, InterpFace::cos_2d, CustomData_bmesh_copy_data(), BMHeader::data, BMesh::elem_index_dirty, InterpFace::f, float(), BMVert::head, BMLoop::head, BMesh::ldata, BMFace::len, mul_v2_m3v3(), BMLoop::next, BMFace::no, NULL, BMLoop::v, and BMesh::vdata.
Referenced by bmo_face_inset_individual(), and bmo_inset_region_exec().
|
static |
This function merges loop customdata (UV's) where interpolating the values across the face causes values to diverge.
Check for diverged values at the vert shared by l_a_inner & l_b_inner.
-----------------------+ l_a_outer--> /|<--l_b_outer / | (face a) / | / <--e_connect / | e_a l_a_inner--> / <--l_b_inner -----------------+ | /| | l_a/b_inner_inset| (face b) / | | / |e_b | (inset face(s)) | | / | |
Definition at line 103 of file bmo_inset.c.
References BLI_assert, bm, BM_edge_in_face(), BM_edge_other_loop(), BM_ELEM_CD_GET_VOID_P, BM_elem_flag_test, BM_ELEM_TAG, BM_ITER_ELEM, BM_LOOPS_OF_VERT, CDT_MIX_MIX, CustomData_data_copy_value(), CustomData_data_equals(), CustomData_data_mix_value(), CustomData_layer_has_math(), BMLoop::e, ELEM, BMLoop::f, CustomData::layers, BMesh::ldata, BMLoop::next, offset, CustomDataLayer::offset, BMLoop::prev, CustomData::totlayer, type, CustomDataLayer::type, BMLoop::v, and void.
Referenced by bmo_inset_region_exec().
|
static |
Definition at line 248 of file bmo_inset.c.
References add_v3_v3v3(), InterpFace::axis_mat, BLI_array_alloca, BLI_memarena_alloc(), InterpFace::blocks_l, InterpFace::blocks_v, bm, BM_CREATE_NO_DOUBLE, BM_CREATE_NOP, BM_edge_calc_face_tangent(), BM_edge_calc_length(), BM_edge_create(), BM_elem_attrs_copy(), BM_face_create_quad_tri(), BM_FACE_FIRST_LOOP, BM_face_interp_from_face_ex(), BM_face_loop_separate(), bm_interp_face_free(), bm_interp_face_store(), BM_vert_create(), BMO_face_flag_enable, BMVert::co, copy_v3_v3(), InterpFace::cos_2d, BMLoop::e, ELE_NEW, InterpFace::f, float(), BMFace::len, madd_v3_v3fl(), mul_v3_fl(), BMLoop::next, BMVert::no, BMFace::no, normalize_v3(), NULL, BMLoop::prev, BMLoop::radial_next, shell_v3v3_mid_normalized_to_dist(), BMLoop::v, verts, and void.
Referenced by bmo_inset_individual_exec().
void bmo_inset_individual_exec | ( | BMesh * | bm, |
BMOperator * | op | ||
) |
Individual Face Inset. Find all tagged faces (f), duplicate edges around faces, inset verts of created edges, create new faces between old and new edges, fill face between connected new edges, kill old face (f).
Definition at line 401 of file bmo_inset.c.
References BLI_memarena_clear(), BLI_memarena_free(), BLI_memarena_new(), BLI_MEMARENA_STD_BUFSIZE, bm, BM_ELEM_TAG, BM_FACE, BM_mesh_elem_hflag_disable_all(), bmo_face_inset_individual(), BMO_ITER, BMO_slot_bool_get(), BMO_slot_buffer_from_enabled_flag(), BMO_slot_buffer_hflag_enable(), BMO_slot_float_get(), ELE_NEW, NULL, BMOperator::slots_in, and BMOperator::slots_out.
void bmo_inset_region_exec | ( | BMesh * | bm, |
BMOperator * | op | ||
) |
This case where only one edge attached to #v_split is used. i.e. the face to inset is on a boundary.
We want the inset to align flush with the boundary edge, not the normal of the interior <--- edge which would give an unsightly bump. --+-------------------------+---------------+-- |^v_other ^e_other /^v_split | | / | | / | | / <- tag split edge | | / | | / | | / | --+-----------------+-----------------------+-- | | | |
Loops vars from newly created face (face_a/b)
l_a->e & l_b->prev->e +------------------------------------+ |\ l_a l_b /| | \ l_a->prev->e l_b->e / | | \ l_a->prev l_b->next / | | +----------------------------+ | | |l_a_other ^ l_b_other| | | | l_b->next->e &... | | | | l_a->prev->prev->e | | | | (inset face) | | | +----------------------------+ | | / \ | | / \ | |/ | +------------------------------------+
Definition at line 651 of file bmo_inset.c.
References add_v3_v3(), add_v3_v3v3(), InterpFace::axis_mat, BLI_assert, BLI_ghash_free(), BLI_ghash_ptr_new(), BLI_memarena_alloc(), BLI_memarena_free(), BLI_memarena_new(), BLI_MEMARENA_STD_BUFSIZE, InterpFace::blocks_l, InterpFace::blocks_v, bm, BM_CREATE_NOP, BM_EDGE, BM_edge_calc_face_tangent(), BM_edge_calc_length(), BM_edge_create(), bm_edge_info_average_length_with_fallback(), BM_edge_is_boundary(), BM_edge_is_manifold(), bm_edge_is_mixed_face_tag(), BM_edge_ordered_verts_ex(), BM_edge_other_loop(), BM_edge_other_vert(), BM_EDGES_OF_MESH, BM_EDGES_OF_VERT, BM_elem_attrs_copy(), BM_elem_flag_disable, BM_elem_flag_enable, BM_elem_flag_test, BM_elem_index_get, BM_elem_index_set, BM_ELEM_TAG, BM_FACE, BM_face_copy_shared(), BM_face_create_verts(), BM_FACE_FIRST_LOOP, BM_face_interp_from_face_ex(), BM_FACES_OF_VERT, bm_interp_face_free(), bm_interp_face_store(), BM_ITER_ELEM, BM_ITER_MESH, BM_ITER_MESH_INDEX, bm_loop_customdata_merge(), BM_loop_other_vert_loop(), BM_mesh_elem_hflag_disable_all(), BM_mesh_elem_hflag_enable_all(), BM_VERT, BM_vert_calc_shell_factor(), BM_vert_create(), BM_vert_splice(), BM_VERTS_OF_EDGE, BM_VERTS_OF_MESH, bmesh_kernel_edge_separate(), bmesh_kernel_vert_separate(), BMO_face_flag_enable, BMO_ITER, BMO_slot_bool_get(), BMO_slot_buffer_from_enabled_flag(), BMO_slot_buffer_hflag_disable(), BMO_slot_buffer_hflag_enable(), BMO_slot_float_get(), BMVert::co, compare_v3v3(), copy_v3_v3(), InterpFace::cos_2d, cross_v3_v3v3(), CustomData_bmesh_copy_data(), CustomData_bmesh_free_block_data(), CustomData_has_math(), BMHeader::data, dot_v3v3(), BMVert::e, BMLoop::e, e, SplitEdgeInfo::e_new, SplitEdgeInfo::e_old, ELE_NEW, BMesh::elem_index_dirty, BMLoop::f, InterpFace::f, float(), BMLoop::head, if(), BMEdge::l, l, SplitEdgeInfo::l, l_b, BMesh::ldata, len_squared_v3(), len_squared_v3v3(), blender::math::length(), SplitEdgeInfo::length, madd_v3_v3fl(), madd_v3_v3v3fl(), MEM_callocN, MEM_freeN, MEM_mallocN, mid_v3_v3v3(), mul_v3_fl(), negate_v3(), BMLoop::next, BMVert::no, BMFace::no, SplitEdgeInfo::no, normalize_v3(), NULL, BMLoop::prev, shell_v3v3_mid_normalized_to_dist(), shell_v3v3_normalized_to_dist(), BMOperator::slots_in, BMOperator::slots_out, sub_v3_v3v3(), BMesh::totface, BMesh::totvert, BMLoop::v, v, BMEdge::v1, v1, BMEdge::v2, v2, VERT_ORIG_GET, VERT_ORIG_REMOVE, VERT_ORIG_STORE, and zero_v3().