Blender V4.3
bmesh_bevel.cc File Reference
#include "MEM_guardedalloc.h"
#include "DNA_curveprofile_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "BLI_alloca.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
#include "BKE_curveprofile.h"
#include "BKE_customdata.hh"
#include "BKE_deform.hh"
#include "BKE_mesh.hh"
#include "eigen_capi.h"
#include "bmesh.hh"
#include "bmesh_bevel.hh"
#include "./intern/bmesh_private.hh"

Go to the source code of this file.

Classes

struct  NewVert
 
struct  EdgeHalf
 
struct  Profile
 
struct  ProfileSpacing
 
struct  MathLayerInfo
 
struct  BoundVert
 
struct  VMesh
 
struct  BevVert
 
struct  BevelParams
 

Macros

#define BEVEL_EPSILON_D   1e-6
 
#define BEVEL_EPSILON   1e-6f
 
#define BEVEL_EPSILON_SQ   1e-12f
 
#define BEVEL_EPSILON_BIG   1e-4f
 
#define BEVEL_EPSILON_BIG_SQ   1e-8f
 
#define BEVEL_EPSILON_ANG   DEG2RADF(2.0f)
 
#define BEVEL_SMALL_ANG   DEG2RADF(10.0f)
 
#define BEVEL_SMALL_ANG_DOT   (1.0f - cosf(BEVEL_SMALL_ANG))
 
#define BEVEL_EPSILON_ANG_DOT   (1.0f - cosf(BEVEL_EPSILON_ANG))
 
#define BEVEL_MAX_ADJUST_PCT   10.0f
 
#define BEVEL_MAX_AUTO_ADJUST_PCT   300.0f
 
#define BEVEL_MATCH_SPEC_WEIGHT   0.2
 
#define PRO_SQUARE_R   1e4f
 
#define PRO_CIRCLE_R   2.0f
 
#define PRO_LINE_R   1.0f
 
#define PRO_SQUARE_IN_R   0.0f
 
#define BM_ELEM_LONG_TAG   (1 << 6)
 
#define EDGE_OUT   4
 
#define VERT_OUT   8
 
#define VEC_VALUE_LEN   6
 
#define BEVEL_GOOD_ANGLE   0.1f
 
#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag)   BM_elem_flag_test(eh->e, flag)
 
#define HASNOT_SEAMSHARP(eh, flag)
 
#define BM_BEVEL_EDGE_TAG_ENABLE(bme)   BM_ELEM_API_FLAG_ENABLE((bme), _FLAG_OVERLAP)
 
#define BM_BEVEL_EDGE_TAG_DISABLE(bme)   BM_ELEM_API_FLAG_DISABLE((bme), _FLAG_OVERLAP)
 
#define BM_BEVEL_EDGE_TAG_TEST(bme)   BM_ELEM_API_FLAG_TEST((bme), _FLAG_OVERLAP)
 
#define CIRCLE_FULLNESS_SEGS   11
 

Enumerations

enum  MeshKind {
  M_NONE , M_POLY , M_ADJ , M_TRI_FAN ,
  M_CUTOFF
}
 
enum  FKind {
  F_NONE , F_ORIG , F_VERT , F_EDGE ,
  F_RECON
}
 
enum  AngleKind { ANGLE_SMALLER = -1 , ANGLE_STRAIGHT = 0 , ANGLE_LARGER = 1 }
 

Functions

static void flag_out_edge (BMesh *bm, BMEdge *bme)
 
static void flag_out_vert (BMesh *bm, BMVert *bmv)
 
static void disable_flag_out_edge (BMesh *bm, BMEdge *bme)
 
static void record_face_kind (BevelParams *bp, BMFace *f, FKind fkind)
 
static FKind get_face_kind (BevelParams *bp, BMFace *f)
 
static bool nearly_parallel (const float d1[3], const float d2[3])
 
static bool nearly_parallel_normalized (const float d1[3], const float d2[3])
 
static BoundVertadd_new_bound_vert (MemArena *mem_arena, VMesh *vm, const float co[3])
 
BLI_INLINE void adjust_bound_vert (BoundVert *bv, const float co[3])
 
static NewVertmesh_vert (VMesh *vm, int i, int j, int k)
 
static void create_mesh_bmvert (BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg)
 
static void copy_mesh_vert (VMesh *vm, int ito, int jto, int kto, int ifrom, int jfrom, int kfrom)
 
static EdgeHalffind_edge_half (BevVert *bv, BMEdge *bme)
 
static BevVertfind_bevvert (BevelParams *bp, BMVert *bmv)
 
static EdgeHalffind_other_end_edge_half (BevelParams *bp, EdgeHalf *e, BevVert **r_bvother)
 
static EdgeHalfnext_bev (BevVert *bv, EdgeHalf *from_e)
 
static int count_ccw_edges_between (EdgeHalf *e1, EdgeHalf *e2)
 
static bool edges_face_connected_at_vert (BMEdge *bme1, BMEdge *bme2)
 
static BMFaceboundvert_rep_face (BoundVert *v, BMFace **r_fother)
 
static BMFacebev_create_ngon (BMesh *bm, BMVert **vert_arr, const int totv, BMFace **face_arr, BMFace *facerep, BMEdge **snap_edge_arr, int mat_nr, bool do_interp)
 
static bool contig_ldata_across_loops (BMesh *bm, BMLoop *l1, BMLoop *l2, int layer_index)
 
static bool contig_ldata_across_edge (BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f2)
 
static void swap_face_components (int *face_component, int totface, int c1, int c2)
 
static void math_layer_info_init (BevelParams *bp, BMesh *bm)
 
static BMFacechoose_rep_face (BevelParams *bp, BMFace **face, int nfaces)
 
static void bev_merge_uvs (BMesh *bm, BMVert *v)
 
static void bev_merge_edge_uvs (BMesh *bm, BMEdge *bme, BMVert *v)
 
static void slide_dist (EdgeHalf *e, BMVert *v, float d, float r_slideco[3])
 
static bool is_outside_edge (EdgeHalf *e, const float co[3], BMVert **ret_closer_v)
 
static AngleKind edges_angle_kind (EdgeHalf *e1, EdgeHalf *e2, BMVert *v)
 
static bool point_between_edges (const float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2)
 
static bool edge_edge_angle_less_than_180 (const BMEdge *e1, const BMEdge *e2, const BMFace *f)
 
static void offset_meet_lines_percent_or_absolute (BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float r_l1a[3], float r_l1b[3], float r_l2a[3], float r_l2b[3])
 
static void offset_meet (BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool edges_between, float meetco[3], const EdgeHalf *e_in_plane)
 
static bool offset_meet_edge (EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float meetco[3], float *r_angle)
 
static bool good_offset_on_edge_between (EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v)
 
static bool offset_on_edge_between (BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v, float meetco[3], float *r_sinratio)
 
static void offset_in_plane (EdgeHalf *e, const float plane_no[3], bool left, float r_co[3])
 
static void project_to_edge (const BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
 
static void set_profile_params (BevelParams *bp, BevVert *bv, BoundVert *bndv)
 
static void move_profile_plane (BoundVert *bndv, BMVert *bmvert)
 
static void move_weld_profile_planes (BevVert *bv, BoundVert *bndv1, BoundVert *bndv2)
 
static int bev_ccw_test (BMEdge *a, BMEdge *b, BMFace *f)
 
static bool make_unit_square_map (const float va[3], const float vmid[3], const float vb[3], float r_mat[4][4])
 
static void make_unit_cube_map (const float va[3], const float vb[3], const float vc[3], const float vd[3], float r_mat[4][4])
 
static double superellipse_co (double x, float r, bool rbig)
 
static void get_profile_point (BevelParams *bp, const Profile *pro, int i, int nseg, float r_co[3])
 
static void calculate_profile_segments (const Profile *profile, const float map[4][4], const bool use_map, const bool reversed, const int ns, const double *xvals, const double *yvals, float *r_prof_co)
 
static void calculate_profile (BevelParams *bp, BoundVert *bndv, bool reversed, bool miter)
 
static void snap_to_superellipsoid (float co[3], const float super_r, bool midline)
 
static void check_edge_data_seam_sharp_edges (BevVert *bv, int flag)
 
static void bevel_extend_edge_data_ex (BevVert *bv, int flag)
 
static void bevel_extend_edge_data (BevVert *bv)
 
static void bevel_edges_sharp_boundary (BMesh *bm, BevelParams *bp)
 
static void bevel_harden_normals (BevelParams *bp, BMesh *bm)
 Harden normals for bevel.
 
static void bevel_set_weighted_normal_face_strength (BMesh *bm, BevelParams *bp)
 
static void set_bound_vert_seams (BevVert *bv, bool mark_seam, bool mark_sharp)
 
static int count_bound_vert_seams (BevVert *bv)
 
static bool eh_on_plane (EdgeHalf *e)
 
static void calculate_vm_profiles (BevelParams *bp, BevVert *bv, VMesh *vm)
 
static void build_boundary_vertex_only (BevelParams *bp, BevVert *bv, bool construct)
 
static void build_boundary_terminal_edge (BevelParams *bp, BevVert *bv, EdgeHalf *efirst, const bool construct)
 
static void adjust_miter_coords (BevelParams *bp, BevVert *bv, EdgeHalf *emiter)
 
static void adjust_miter_inner_coords (BevelParams *bp, BevVert *bv, EdgeHalf *emiter)
 
static void build_boundary (BevelParams *bp, BevVert *bv, bool construct)
 
static EdgeHalfnext_edgehalf_bev (BevelParams *bp, EdgeHalf *start_edge, bool toward_bv, BevVert **r_bv)
 
static void regularize_profile_orientation (BevelParams *bp, BMEdge *bme)
 
static void adjust_the_cycle_or_chain (BoundVert *vstart, bool iscycle)
 
static void adjust_offsets (BevelParams *bp, BMesh *bm)
 
static BoundVertpipe_test (BevVert *bv)
 
static VMeshnew_adj_vmesh (MemArena *mem_arena, int count, int seg, BoundVert *bounds)
 
static NewVertmesh_vert_canon (VMesh *vm, int i, int j, int k)
 
static bool is_canon (VMesh *vm, int i, int j, int k)
 
static void vmesh_copy_equiv_verts (VMesh *vm)
 
static void vmesh_center (VMesh *vm, float r_cent[3])
 
static void avg4 (float co[3], const NewVert *v0, const NewVert *v1, const NewVert *v2, const NewVert *v3)
 
static float sabin_gamma (int n)
 
static void fill_vmesh_fracs (VMesh *vm, float *frac, int i)
 
static void fill_profile_fracs (BevelParams *bp, BoundVert *bndv, float *frac, int ns)
 
static int interp_range (const float *frac, int n, const float f, float *r_rest)
 
static VMeshinterp_vmesh (BevelParams *bp, VMesh *vm_in, int nseg)
 
static VMeshcubic_subdiv (BevelParams *bp, VMesh *vm_in)
 
static VMeshmake_cube_corner_square (MemArena *mem_arena, int nseg)
 
static VMeshmake_cube_corner_square_in (MemArena *mem_arena, int nseg)
 
static VMeshmake_cube_corner_adj_vmesh (BevelParams *bp)
 
static int tri_corner_test (BevelParams *bp, BevVert *bv)
 
static VMeshtri_corner_adj_vmesh (BevelParams *bp, BevVert *bv)
 
static VMeshadj_vmesh (BevelParams *bp, BevVert *bv)
 
static void snap_to_pipe_profile (BoundVert *vpipe, bool midline, float co[3])
 
static VMeshpipe_adj_vmesh (BevelParams *bp, BevVert *bv, BoundVert *vpipe)
 
static void get_incident_edges (BMFace *f, BMVert *v, BMEdge **r_e1, BMEdge **r_e2)
 
static BMEdgefind_closer_edge (float *co, BMEdge *e1, BMEdge *e2)
 
static int find_face_internal_boundverts (const BevVert *bv, const BMFace *f, BoundVert *(r_internal[3]))
 
static float projected_boundary_area (BevVert *bv, BMFace *f)
 
static bool is_bad_uv_poly (BevVert *bv, BMFace *frep)
 
static BMFacefrep_for_center_poly (BevelParams *bp, BevVert *bv)
 
static void build_center_ngon (BevelParams *bp, BMesh *bm, BevVert *bv, int mat_nr)
 
static void build_square_in_vmesh (BevelParams *bp, BMesh *bm, BevVert *bv, VMesh *vm1)
 
static void closer_v3_v3v3v3 (float r[3], const float a[3], const float b[3], const float v[3])
 
static VMeshsquare_out_adj_vmesh (BevelParams *bp, BevVert *bv)
 
static BMEdgesnap_edge_for_center_vmesh_vert (int i, int n_bndv, BMEdge *eprev, BMEdge *enext, BMFace **bndv_rep_faces, BMFace *center_frep, const bool *frep_beats_next)
 
static void snap_edges_for_vmesh_vert (int i, int j, int k, int ns, int ns2, int n_bndv, BMEdge *eprev, BMEdge *enext, BMEdge *enextnext, BMFace **bndv_rep_faces, BMFace *center_frep, const bool *frep_beats_next, BMEdge *r_snap_edges[4])
 
static void bevel_build_rings (BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert *vpipe)
 
static void bevel_build_cutoff (BevelParams *bp, BMesh *bm, BevVert *bv)
 
static BMFacebevel_build_poly (BevelParams *bp, BMesh *bm, BevVert *bv)
 
static void bevel_build_trifan (BevelParams *bp, BMesh *bm, BevVert *bv)
 
static void bevel_vert_two_edges (BevelParams *bp, BMesh *bm, BevVert *bv)
 
static void build_vmesh (BevelParams *bp, BMesh *bm, BevVert *bv)
 
static float edge_face_angle (EdgeHalf *e)
 
static int bevel_edge_order_extend (BMesh *bm, BevVert *bv, int i)
 
static bool fast_bevel_edge_order (BevVert *bv)
 
static void find_bevel_edge_order (BMesh *bm, BevVert *bv, BMEdge *first_bme)
 
static BevVertbevel_vert_construct (BMesh *bm, BevelParams *bp, BMVert *v)
 
static bool bev_rebuild_polygon (BMesh *bm, BevelParams *bp, BMFace *f)
 
static void bevel_rebuild_existing_polygons (BMesh *bm, BevelParams *bp, BMVert *v)
 
static void bevel_reattach_wires (BMesh *bm, BevelParams *bp, BMVert *v)
 
static void bev_merge_end_uvs (BMesh *bm, BevVert *bv, EdgeHalf *e)
 
static bool bevvert_is_weld_cross (BevVert *bv)
 
static void weld_cross_attrs_copy (BMesh *bm, BevVert *bv, VMesh *vm, int vmindex, EdgeHalf *e)
 
static void bevel_build_edge_polygons (BMesh *bm, BevelParams *bp, BMEdge *bme)
 
static double find_superellipse_chord_endpoint (double x0, double dtarget, float r, bool rbig)
 
static void find_even_superellipse_chords_general (int seg, float r, double *xvals, double *yvals)
 
static void find_even_superellipse_chords (int n, float r, double *xvals, double *yvals)
 
static float find_profile_fullness (BevelParams *bp)
 
static void set_profile_spacing (BevelParams *bp, ProfileSpacing *pro_spacing, bool custom)
 
static float geometry_collide_offset (BevelParams *bp, EdgeHalf *eb)
 
static float vertex_collide_offset (BevelParams *bp, EdgeHalf *ea)
 
static void bevel_limit_offset (BevelParams *bp, BMesh *bm)
 
void BM_mesh_bevel (BMesh *bm, const float offset, const int offset_type, const int profile_type, const int segments, const float profile, const bool affect_type, const bool use_weights, const bool limit_offset, const MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, const bool harden_normals, const int face_strength_mode, const int miter_outer, const int miter_inner, const float spread, const CurveProfile *custom_profile, const int vmesh_method, const int bweight_offset_vert, const int bweight_offset_edge)
 

Detailed Description

Main functions for beveling a BMesh (used by the tool and modifier)

Definition in file bmesh_bevel.cc.

Macro Definition Documentation

◆ BEV_EXTEND_EDGE_DATA_CHECK

#define BEV_EXTEND_EDGE_DATA_CHECK ( eh,
flag )   BM_elem_flag_test(eh->e, flag)

Definition at line 2283 of file bmesh_bevel.cc.

◆ BEVEL_EPSILON

◆ BEVEL_EPSILON_ANG

#define BEVEL_EPSILON_ANG   DEG2RADF(2.0f)

◆ BEVEL_EPSILON_ANG_DOT

#define BEVEL_EPSILON_ANG_DOT   (1.0f - cosf(BEVEL_EPSILON_ANG))

Difference in dot products that corresponds to 2.0 degree difference between vectors.

Definition at line 55 of file bmesh_bevel.cc.

Referenced by nearly_parallel_normalized().

◆ BEVEL_EPSILON_BIG

#define BEVEL_EPSILON_BIG   1e-4f

◆ BEVEL_EPSILON_BIG_SQ

#define BEVEL_EPSILON_BIG_SQ   1e-8f

Definition at line 49 of file bmesh_bevel.cc.

◆ BEVEL_EPSILON_D

#define BEVEL_EPSILON_D   1e-6

Definition at line 45 of file bmesh_bevel.cc.

Referenced by slide_dist(), and snap_to_pipe_profile().

◆ BEVEL_EPSILON_SQ

#define BEVEL_EPSILON_SQ   1e-12f

Definition at line 47 of file bmesh_bevel.cc.

Referenced by adj_vmesh().

◆ BEVEL_GOOD_ANGLE

#define BEVEL_GOOD_ANGLE   0.1f

Definition at line 1525 of file bmesh_bevel.cc.

Referenced by offset_meet_edge().

◆ BEVEL_MATCH_SPEC_WEIGHT

#define BEVEL_MATCH_SPEC_WEIGHT   0.2

Definition at line 58 of file bmesh_bevel.cc.

Referenced by adjust_the_cycle_or_chain().

◆ BEVEL_MAX_ADJUST_PCT

#define BEVEL_MAX_ADJUST_PCT   10.0f

Definition at line 56 of file bmesh_bevel.cc.

◆ BEVEL_MAX_AUTO_ADJUST_PCT

#define BEVEL_MAX_AUTO_ADJUST_PCT   300.0f

Definition at line 57 of file bmesh_bevel.cc.

◆ BEVEL_SMALL_ANG

#define BEVEL_SMALL_ANG   DEG2RADF(10.0f)

Definition at line 51 of file bmesh_bevel.cc.

Referenced by offset_meet(), and square_out_adj_vmesh().

◆ BEVEL_SMALL_ANG_DOT

#define BEVEL_SMALL_ANG_DOT   (1.0f - cosf(BEVEL_SMALL_ANG))

Difference in dot products that corresponds to 10 degree difference between vectors.

Definition at line 53 of file bmesh_bevel.cc.

Referenced by next_edgehalf_bev().

◆ BM_BEVEL_EDGE_TAG_DISABLE

#define BM_BEVEL_EDGE_TAG_DISABLE ( bme)    BM_ELEM_API_FLAG_DISABLE((bme), _FLAG_OVERLAP)

◆ BM_BEVEL_EDGE_TAG_ENABLE

#define BM_BEVEL_EDGE_TAG_ENABLE ( bme)    BM_ELEM_API_FLAG_ENABLE((bme), _FLAG_OVERLAP)

◆ BM_BEVEL_EDGE_TAG_TEST

#define BM_BEVEL_EDGE_TAG_TEST ( bme)    BM_ELEM_API_FLAG_TEST((bme), _FLAG_OVERLAP)

◆ BM_ELEM_LONG_TAG

#define BM_ELEM_LONG_TAG   (1 << 6)

Definition at line 389 of file bmesh_bevel.cc.

Referenced by bevel_build_edge_polygons(), bevel_harden_normals(), and BM_mesh_bevel().

◆ CIRCLE_FULLNESS_SEGS

#define CIRCLE_FULLNESS_SEGS   11

Referenced by find_profile_fullness().

◆ EDGE_OUT

#define EDGE_OUT   4

Definition at line 392 of file bmesh_bevel.cc.

Referenced by BM_mesh_bevel(), disable_flag_out_edge(), and flag_out_edge().

◆ HASNOT_SEAMSHARP

#define HASNOT_SEAMSHARP ( eh,
flag )
Value:
@ BM_ELEM_SEAM
@ BM_ELEM_SMOOTH
#define BM_elem_flag_test(ele, hflag)
uint8_t flag
Definition wm_window.cc:138

Definition at line 2299 of file bmesh_bevel.cc.

Referenced by check_edge_data_seam_sharp_edges().

◆ PRO_CIRCLE_R

◆ PRO_LINE_R

◆ PRO_SQUARE_IN_R

◆ PRO_SQUARE_R

◆ VEC_VALUE_LEN

#define VEC_VALUE_LEN   6

Referenced by choose_rep_face().

◆ VERT_OUT

#define VERT_OUT   8

Definition at line 393 of file bmesh_bevel.cc.

Referenced by BM_mesh_bevel(), and flag_out_vert().

Enumeration Type Documentation

◆ AngleKind

enum AngleKind

Helper for keeping track of angle kind.

Enumerator
ANGLE_SMALLER 

Angle less than 180 degrees.

ANGLE_STRAIGHT 

180 degree angle.

ANGLE_LARGER 

Angle greater than 180 degrees.

Definition at line 303 of file bmesh_bevel.cc.

◆ FKind

enum FKind

Face classification.

Note
depends on F_RECON > F_EDGE > F_VERT.
Enumerator
F_NONE 

Used when there is no face at all.

F_ORIG 

Original face, not touched.

F_VERT 

Face for construction around a vert.

F_EDGE 

Face for a beveled edge.

F_RECON 

Reconstructed original face with some new verts.

Definition at line 289 of file bmesh_bevel.cc.

◆ MeshKind

enum MeshKind
Enumerator
M_NONE 
M_POLY 
M_ADJ 
M_TRI_FAN 
M_CUTOFF 

Definition at line 236 of file bmesh_bevel.cc.

Function Documentation

◆ add_new_bound_vert()

◆ adj_vmesh()

◆ adjust_bound_vert()

BLI_INLINE void adjust_bound_vert ( BoundVert * bv,
const float co[3] )

◆ adjust_miter_coords()

◆ adjust_miter_inner_coords()

◆ adjust_offsets()

static void adjust_offsets ( BevelParams * bp,
BMesh * bm )
static

Adjust the offsets to try to make them, as much as possible, have even-width bevels with offsets that match their specs. The problem that we can try to ameliorate is that when loop slide is active, the meet point will probably not be the one that makes both sides have their specified width. And because both ends may be on loop slide edges, the widths at each end could be different.

It turns out that the dependent offsets either form chains or cycles, and we can process each of those separately.

Definition at line 3693 of file bmesh_bevel.cc.

References BoundVert::adjchain, adjust_the_cycle_or_chain(), BLI_assert, bm, BM_elem_flag_test, BM_ELEM_TAG, BM_ITER_MESH, BM_VERTS_OF_MESH, VMesh::boundstart, build_boundary(), BoundVert::eon, find_bevvert(), find_other_end_edge_half(), EdgeHalf::leftv, BoundVert::next, EdgeHalf::rightv, v, BoundVert::visited, and BevVert::vmesh.

Referenced by BM_mesh_bevel().

◆ adjust_the_cycle_or_chain()

static void adjust_the_cycle_or_chain ( BoundVert * vstart,
bool iscycle )
static

Adjust the offsets for a single cycle or chain. For chains and some cycles, a fast solution exists. Otherwise, we set up and solve a linear least squares problem that tries to minimize the squared differences of lengths at each end of an edge, and (with smaller weight) the squared differences of the offsets from their specs.

Definition at line 3531 of file bmesh_bevel.cc.

References BEVEL_MATCH_SPEC_WEIGHT, BM_elem_index_get, EdgeHalf::e, EIG_linear_least_squares_solver_new(), EIG_linear_solver_delete(), EIG_linear_solver_matrix_add(), EIG_linear_solver_print_matrix(), EIG_linear_solver_right_hand_side_add(), EIG_linear_solver_solve(), EIG_linear_solver_variable_get(), float, EdgeHalf::offset_l, EdgeHalf::offset_r, printf, and v.

Referenced by adjust_offsets().

◆ avg4()

static void avg4 ( float co[3],
const NewVert * v0,
const NewVert * v1,
const NewVert * v2,
const NewVert * v3 )
static

Definition at line 3931 of file bmesh_bevel.cc.

References add_v3_v3(), add_v3_v3v3(), BMVert::co, NewVert::co, mul_v3_fl(), and v2.

Referenced by cubic_subdiv().

◆ bev_ccw_test()

static int bev_ccw_test ( BMEdge * a,
BMEdge * b,
BMFace * f )
static

Definition at line 1917 of file bmesh_bevel.cc.

References b, BM_face_edge_share_loop(), and BMLoop::next.

Referenced by bevel_vert_construct().

◆ bev_create_ngon()

static BMFace * bev_create_ngon ( BMesh * bm,
BMVert ** vert_arr,
const int totv,
BMFace ** face_arr,
BMFace * facerep,
BMEdge ** snap_edge_arr,
int mat_nr,
bool do_interp )
static

Make ngon from verts alone. Make sure to properly copy face attributes and do custom data interpolation from corresponding elements of face_arr, if that is non-nullptr, else from facerep. If edge_arr is non-nullptr, then for interpolation purposes only, the corresponding elements of vert_arr are snapped to any non-nullptr edges in that array. If mat_nr >= 0 then the material of the face is set to that.

Note
ALL face creation goes through this function, this is important to keep!

Definition at line 674 of file bmesh_bevel.cc.

References BLI_assert, bm, BM_CREATE_NOP, BM_EDGES_OF_FACE, BM_elem_attrs_copy(), BM_elem_flag_enable, BM_ELEM_TAG, BM_face_create_verts(), BM_ITER_ELEM, BM_loop_interp_from_face(), BM_LOOPS_OF_FACE, closest_to_line_segment_v3(), BMVert::co, copy_v3_v3(), flag_out_edge(), l, BMFace::mat_nr, BMLoop::v, BMEdge::v1, and BMEdge::v2.

Referenced by bev_rebuild_polygon(), bevel_build_cutoff(), bevel_build_edge_polygons(), bevel_build_poly(), bevel_build_rings(), and build_center_ngon().

◆ bev_merge_edge_uvs()

◆ bev_merge_end_uvs()

static void bev_merge_end_uvs ( BMesh * bm,
BevVert * bv,
EdgeHalf * e )
static

Definition at line 6839 of file bmesh_bevel.cc.

References bev_merge_uvs(), bm, e, mesh_vert(), v, and BevVert::vmesh.

Referenced by bevel_build_edge_polygons().

◆ bev_merge_uvs()

◆ bev_rebuild_polygon()

◆ bevel_build_cutoff()

static void bevel_build_cutoff ( BevelParams * bp,
BMesh * bm,
BevVert * bv )
static

Builds the vertex mesh when the vertex mesh type is set to "cut off" with a face closing off each incoming edge's profile.

TODO(Hans): Make cutoff VMesh work with outer miter != sharp. This should be possible but there are two problems currently:

  • Miter profiles don't have plane_no filled, so down direction is incorrect.
  • Indexing profile points of miters with (i, 0, k) seems to return zero except for the first and last profile point. TODO(Hans): Use repface / edge arrays for UV interpolation properly.

Definition at line 5585 of file bmesh_bevel.cc.

References bev_create_ngon(), BEVEL_EPSILON, BLI_memarena_alloc(), bm, VMesh::boundstart, NewVert::co, copy_v3_v3(), VMesh::count, create_mesh_bmvert(), cross_v3_v3v3(), dot_v3v3(), Profile::height, BoundVert::index, BoundVert::is_arc_start, BoundVert::is_patch_start, len_squared_v3v3(), madd_v3_v3v3fl(), BevelParams::mat_nr, max_ii(), BevelParams::mem_arena, mesh_vert(), negate_v3(), BoundVert::next, BMVert::no, BoundVert::nv, Profile::plane_no, BoundVert::prev, printf, BoundVert::profile, BevelParams::seg, sqrtf, BevVert::v, NewVert::v, and BevVert::vmesh.

Referenced by build_vmesh().

◆ bevel_build_edge_polygons()

◆ bevel_build_poly()

◆ bevel_build_rings()

◆ bevel_build_trifan()

◆ bevel_edge_order_extend()

static int bevel_edge_order_extend ( BMesh * bm,
BevVert * bv,
int i )
static

Try to extend the bv->edges[] array beyond i by finding more successor edges. This is a possibly exponential-time search, but it is only exponential in the number of "internal faces" at a vertex – i.e., faces that bridge between the edges that naturally form a manifold cap around bv. It is rare to have more than one of these, so unlikely that the exponential time case will be hit in practice. Returns the new index i' where bv->edges[i'] ends the best path found. The path will have the tags of all of its edges set.

Definition at line 6057 of file bmesh_bevel.cc.

References blender::Vector< T, InlineBufferCapacity, Allocator >::append(), bevel_edge_order_extend(), BLI_assert, bm, BM_BEVEL_EDGE_TAG_DISABLE, BM_BEVEL_EDGE_TAG_ENABLE, BM_BEVEL_EDGE_TAG_TEST, BM_ITER_ELEM, BM_LOOPS_OF_EDGE, blender::Vector< T, InlineBufferCapacity, Allocator >::clear(), BMLoop::e, EdgeHalf::e, BevVert::edgecount, BevVert::edges, edges_face_connected_at_vert(), l, BMLoop::next, BMLoop::prev, blender::Vector< T, InlineBufferCapacity, Allocator >::size(), BevVert::v, and BMLoop::v.

Referenced by bevel_edge_order_extend(), and find_bevel_edge_order().

◆ bevel_edges_sharp_boundary()

◆ bevel_extend_edge_data()

static void bevel_extend_edge_data ( BevVert * bv)
static

◆ bevel_extend_edge_data_ex()

◆ bevel_harden_normals()

static void bevel_harden_normals ( BevelParams * bp,
BMesh * bm )
static

Harden normals for bevel.

The desired effect is that the newly created F_EDGE and F_VERT faces appear smoothly shaded with the normals at the boundaries with F_RECON faces matching those recon faces. And at boundaries between F_EDGE and F_VERT faces, the normals should match the F_EDGE ones. Assumes custom loop normals are in use.

Definition at line 2457 of file bmesh_bevel.cc.

References add_v3_v3v3(), bevel_edges_sharp_boundary(), BKE_lnor_space_custom_normal_to_data(), bm, BM_ELEM_CD_GET_VOID_P, BM_elem_flag_test, BM_elem_index_get, BM_ELEM_LONG_TAG, BM_FACES_OF_MESH, BM_ITER_ELEM, BM_ITER_MESH, BM_lnorspace_update(), BM_LOOPS_OF_FACE, BM_mesh_normals_update(), BM_vert_step_fan_loop(), CD_CUSTOMLOOPNORMAL, CustomData_get_offset(), BMLoop::e, ELEM, BMLoop::f, F_EDGE, F_NONE, F_ORIG, F_RECON, F_VERT, get_face_kind(), BevelParams::harden_normals, l, BMesh::ldata, BMesh::lnor_spacearr, MLoopNorSpaceArray::lspacearr, BMFace::no, BMVert::no, norm(), normalize_v3(), BevelParams::offset, BMLoop::prev, and BMLoop::v.

Referenced by BM_mesh_bevel().

◆ bevel_limit_offset()

static void bevel_limit_offset ( BevelParams * bp,
BMesh * bm )
static

Calculate an offset that is the lesser of the current bp.offset and the maximum possible offset before geometry collisions happen. If the offset changes as a result of this, adjust the current edge offset specs to reflect this clamping, and store the new offset in bp.offset.

Definition at line 7619 of file bmesh_bevel.cc.

References BevelParams::affect_type, BEVEL_AFFECT_VERTICES, bm, BM_elem_flag_test, BM_ELEM_TAG, BM_ITER_MESH, BM_VERTS_OF_MESH, BevVert::edgecount, BevVert::edges, find_bevvert(), geometry_collide_offset(), BevelParams::offset, EdgeHalf::offset_l, EdgeHalf::offset_l_spec, EdgeHalf::offset_r, EdgeHalf::offset_r_spec, and vertex_collide_offset().

Referenced by BM_mesh_bevel().

◆ bevel_reattach_wires()

◆ bevel_rebuild_existing_polygons()

static void bevel_rebuild_existing_polygons ( BMesh * bm,
BevelParams * bp,
BMVert * v )
static

◆ bevel_set_weighted_normal_face_strength()

◆ bevel_vert_construct()

◆ bevel_vert_two_edges()

◆ bevvert_is_weld_cross()

static bool bevvert_is_weld_cross ( BevVert * bv)
static

◆ BM_mesh_bevel()

void BM_mesh_bevel ( BMesh * bm,
float offset,
int offset_type,
int profile_type,
int segments,
float profile,
bool affect_type,
bool use_weights,
bool limit_offset,
const MDeformVert * dvert,
int vertex_group,
int mat,
bool loop_slide,
bool mark_seam,
bool mark_sharp,
bool harden_normals,
int face_strength_mode,
int miter_outer,
int miter_inner,
float spread,
const CurveProfile * custom_profile,
int vmesh_method,
int bweight_offset_vert,
int bweight_offset_edge )
  • Currently only bevels BM_ELEM_TAG'd verts and edges.
  • Newly created faces, edges, and verts are BM_ELEM_TAG'd too, the caller needs to ensure these are cleared before calling if its going to use this tag.
  • If limit_offset is set, adjusts offset down if necessary to avoid geometry collisions.
Warning
all tagged edges must be manifold.

Definition at line 7676 of file bmesh_bevel.cc.

References adjust_offsets(), BEVEL_AFFECT_VERTICES, BEVEL_AMT_ABSOLUTE, BEVEL_AMT_PERCENT, bevel_build_edge_polygons(), bevel_extend_edge_data(), BEVEL_FACE_STRENGTH_NONE, bevel_harden_normals(), bevel_limit_offset(), BEVEL_MITER_SHARP, BEVEL_PROFILE_CUSTOM, bevel_reattach_wires(), bevel_rebuild_existing_polygons(), bevel_set_weighted_normal_face_strength(), bevel_vert_construct(), BEVEL_VMESH_CUTOFF, BLI_assert, BLI_ghash_flag_set(), BLI_ghash_free(), BLI_ghash_ptr_new(), BLI_memarena_free(), BLI_memarena_new(), BLI_memarena_use_calloc(), BLI_time_now_seconds(), BevelParams::bm, bm, BM_EDGES_OF_MESH, BM_elem_flag_disable, BM_elem_flag_enable, BM_elem_flag_test, BM_ELEM_LONG_TAG, BM_ELEM_TAG, BM_FACES_OF_MESH, BM_ITER_ELEM, BM_ITER_MESH, BM_ITER_MESH_MUTABLE, BM_LOOPS_OF_FACE, BM_vert_kill(), BM_VERTS_OF_MESH, BMO_edge_flag_test, BMO_vert_flag_test, build_boundary(), build_vmesh(), e, EDGE_OUT, ELEM, F_EDGE, fabsf, find_bevvert(), find_profile_fullness(), get_face_kind(), GHASH_FLAG_ALLOW_DUPES, l, logf, math_layer_info_init(), max_ii(), MEM_SIZE_OPTIMAL, printf, PRO_CIRCLE_R, PRO_LINE_R, PRO_SQUARE_IN_R, PRO_SQUARE_R, regularize_profile_orientation(), set_profile_spacing(), sqrtf, BMesh::use_toolflags, v, and VERT_OUT.

Referenced by bmo_bevel_exec(), and modify_mesh().

◆ boundvert_rep_face()

static BMFace * boundvert_rep_face ( BoundVert * v,
BMFace ** r_fother )
static

Return a good representative face (for materials, etc.) for faces created around/near BoundVert v. Sometimes care about a second choice, if there is one. If r_fother parameter is non-nullptr and there is another, different, possible frep, return the other one in that parameter.

Definition at line 610 of file bmesh_bevel.cc.

References v.

Referenced by bevel_build_poly(), bevel_build_rings(), and build_center_ngon().

◆ build_boundary()

static void build_boundary ( BevelParams * bp,
BevVert * bv,
bool construct )
static

Make a circular list of BoundVerts for bv, each of which has the coordinates of a vertex on the boundary of the beveled vertex bv->v. This may adjust some EdgeHalf widths, and there might have to be a subsequent pass to make the widths as consistent as possible. Doesn't make the actual BMVerts.

For a width consistency pass, we just recalculate the coordinates of the #BoundVerts. If the other ends have been (re)built already, then we copy the offsets from there to match, else we use the ideal (user-specified) widths.

Parameters
constructThe first time through, construct will be true and we are making the #BoundVerts and setting up the BoundVert and EdgeHalf pointers appropriately. Also, if construct, decide on the mesh pattern that will be used inside the boundary.

Definition at line 2974 of file bmesh_bevel.cc.

References add_new_bound_vert(), adjust_bound_vert(), adjust_miter_coords(), adjust_miter_inner_coords(), BevelParams::affect_type, ANGLE_LARGER, ANGLE_SMALLER, BEVEL_AFFECT_VERTICES, BEVEL_MITER_PATCH, BEVEL_MITER_SHARP, BEVEL_VMESH_ADJ, BEVEL_VMESH_CUTOFF, BLI_assert, build_boundary_terminal_edge(), build_boundary_vertex_only(), copy_v3_v3(), VMesh::count, e, BoundVert::ebev, BevVert::edgecount, edges_angle_kind(), BoundVert::efirst, eh_on_plane(), BoundVert::elast, BoundVert::eon, good_offset_on_edge_between(), BoundVert::is_arc_start, EdgeHalf::is_bev, BoundVert::is_patch_start, EdgeHalf::leftv, BevelParams::loop_slide, M_ADJ, M_CUTOFF, M_NONE, M_POLY, BevelParams::mark_seam, BevelParams::mark_sharp, BevelParams::mem_arena, mem_arena, VMesh::mesh_kind, Profile::middle, BevelParams::miter_inner, BevelParams::miter_outer, BoundVert::next, EdgeHalf::next, next_bev(), offset_meet(), offset_on_edge_between(), BoundVert::profile, EdgeHalf::profile_index, BevelParams::seg, EdgeHalf::seg, BevVert::selcount, set_bound_vert_seams(), BoundVert::sinratio, BevVert::v, v, v2, BevVert::vmesh, and BevelParams::vmesh_method.

Referenced by adjust_offsets(), and BM_mesh_bevel().

◆ build_boundary_terminal_edge()

◆ build_boundary_vertex_only()

◆ build_center_ngon()

◆ build_square_in_vmesh()

static void build_square_in_vmesh ( BevelParams * bp,
BMesh * bm,
BevVert * bv,
VMesh * vm1 )
static

Special case of bevel_build_rings when triangle-corner and profile is 0. There is no corner mesh except, if nseg odd, for a center poly. Boundary verts merge with previous ones according to pattern: (i, 0, k) merged with (i+1, 0, ns-k) for k <= ns/2.

Definition at line 4948 of file bmesh_bevel.cc.

References bm, build_center_ngon(), copy_v3_v3(), VMesh::count, create_mesh_bmvert(), BevelParams::mat_nr, mesh_vert(), VMesh::seg, BevVert::v, NewVert::v, and BevVert::vmesh.

Referenced by bevel_build_rings().

◆ build_vmesh()

◆ calculate_profile()

static void calculate_profile ( BevelParams * bp,
BoundVert * bndv,
bool reversed,
bool miter )
static

Calculate the actual coordinate values for bndv's profile. This is only needed if bp->seg > 1. Allocate the space for them if that hasn't been done already. If bp->seg is not a power of 2, also need to calculate the coordinate values for the power of 2 >= bp->seg, because the ADJ pattern needs power-of-2 boundaries during construction.

Definition at line 2150 of file bmesh_bevel.cc.

References BEVEL_PROFILE_SUPERELLIPSE, BEVEL_VMESH_CUTOFF, BLI_memarena_alloc(), calculate_profile_segments(), Profile::end, Profile::height, len_v3v3(), make_unit_square_map(), BevelParams::mem_arena, Profile::middle, mul_v3_m4v3(), PRO_LINE_R, BevelParams::pro_spacing, BevelParams::pro_spacing_miter, Profile::prof_co, Profile::prof_co_2, BoundVert::profile, BevelParams::profile_type, BevelParams::seg, ProfileSpacing::seg_2, Profile::start, Profile::super_r, BevelParams::vmesh_method, ProfileSpacing::xvals, ProfileSpacing::xvals_2, ProfileSpacing::yvals, and ProfileSpacing::yvals_2.

Referenced by calculate_vm_profiles(), and make_cube_corner_adj_vmesh().

◆ calculate_profile_segments()

static void calculate_profile_segments ( const Profile * profile,
const float map[4][4],
const bool use_map,
const bool reversed,
const int ns,
const double * xvals,
const double * yvals,
float * r_prof_co )
static

Helper for calculate_profile that builds the 3D locations for the segments and the higher power of 2 segments.

Definition at line 2093 of file bmesh_bevel.cc.

References add_v3_v3v3(), copy_v3_v3(), float, interp_v3_v3v3(), is_zero_v3(), isect_line_plane_v3(), and mul_v3_m4v3().

Referenced by calculate_profile().

◆ calculate_vm_profiles()

static void calculate_vm_profiles ( BevelParams * bp,
BevVert * bv,
VMesh * vm )
static

Calculate the profiles for all the BoundVerts of VMesh vm.

Note
This should only be called once for each BevVert, after all changes have been made to the profile's parameters.

Definition at line 2683 of file bmesh_bevel.cc.

References BEVEL_PROFILE_CUSTOM, VMesh::boundstart, calculate_profile(), BoundVert::is_arc_start, BoundVert::is_patch_start, BoundVert::is_profile_start, BoundVert::next, BoundVert::profile, BevelParams::profile_type, set_profile_params(), and Profile::special_params.

Referenced by build_vmesh().

◆ check_edge_data_seam_sharp_edges()

static void check_edge_data_seam_sharp_edges ( BevVert * bv,
int flag )
static

◆ choose_rep_face()

static BMFace * choose_rep_face ( BevelParams * bp,
BMFace ** face,
int nfaces )
static

Use a tie-breaking rule to choose a representative face when there are number of choices, face[0], face[1], ..., face[nfaces]. This is needed when there are an odd number of segments, and the center segment (and its continuation into vmesh) can usually arbitrarily be the previous face or the next face. Or, for the center polygon of a corner, all of the faces around the vertex are possibleface_component choices. If we just choose randomly, the resulting UV maps or material assignment can look ugly/inconsistent. Allow for the case when arguments are null.

Definition at line 950 of file bmesh_bevel.cc.

References BLI_array_alloca, BLI_assert, BM_elem_flag_test, BM_elem_index_get, BM_ELEM_SELECT, BM_face_calc_center_bounds(), MathLayerInfo::face_component, float, BMFace::mat_nr, BevelParams::math_layer_info, and VEC_VALUE_LEN.

Referenced by bevel_build_edge_polygons(), bevel_build_rings(), and frep_for_center_poly().

◆ closer_v3_v3v3v3()

static void closer_v3_v3v3v3 ( float r[3],
const float a[3],
const float b[3],
const float v[3] )
static

Copy whichever of a and b is closer to v into r.

Definition at line 4981 of file bmesh_bevel.cc.

References b, copy_v3_v3(), len_squared_v3v3(), and v.

Referenced by square_out_adj_vmesh().

◆ contig_ldata_across_edge()

static bool contig_ldata_across_edge ( BMesh * bm,
BMEdge * e,
BMFace * f1,
BMFace * f2 )
static

◆ contig_ldata_across_loops()

static bool contig_ldata_across_loops ( BMesh * bm,
BMLoop * l1,
BMLoop * l2,
int layer_index )
static

◆ copy_mesh_vert()

static void copy_mesh_vert ( VMesh * vm,
int ito,
int jto,
int kto,
int ifrom,
int jfrom,
int kfrom )
static

Definition at line 509 of file bmesh_bevel.cc.

References NewVert::co, copy_v3_v3(), mesh_vert(), and NewVert::v.

Referenced by bevel_vert_two_edges(), and build_vmesh().

◆ count_bound_vert_seams()

static int count_bound_vert_seams ( BevVert * bv)
static

Definition at line 2650 of file bmesh_bevel.cc.

References BevVert::any_seam, BevVert::edgecount, BevVert::edges, and EdgeHalf::is_seam.

Referenced by bevel_build_rings().

◆ count_ccw_edges_between()

static int count_ccw_edges_between ( EdgeHalf * e1,
EdgeHalf * e2 )
static

Definition at line 573 of file bmesh_bevel.cc.

References count, and e.

Referenced by bev_rebuild_polygon().

◆ create_mesh_bmvert()

static void create_mesh_bmvert ( BMesh * bm,
VMesh * vm,
int i,
int j,
int k,
BMVert * eg )
static

◆ cubic_subdiv()

◆ disable_flag_out_edge()

static void disable_flag_out_edge ( BMesh * bm,
BMEdge * bme )
static

Definition at line 411 of file bmesh_bevel.cc.

References bm, BMO_edge_flag_disable, EDGE_OUT, and BMesh::use_toolflags.

Referenced by bev_rebuild_polygon().

◆ edge_edge_angle_less_than_180()

static bool edge_edge_angle_less_than_180 ( const BMEdge * e1,
const BMEdge * e2,
const BMFace * f )
static

◆ edge_face_angle()

static float edge_face_angle ( EdgeHalf * e)
static

Definition at line 6034 of file bmesh_bevel.cc.

References angle_normalized_v3v3(), e, float, M_PI, and BMVert::no.

Referenced by bevel_vert_construct().

◆ edges_angle_kind()

◆ edges_face_connected_at_vert()

static bool edges_face_connected_at_vert ( BMEdge * bme1,
BMEdge * bme2 )
static

Definition at line 591 of file bmesh_bevel.cc.

References BM_ITER_ELEM, BM_LOOPS_OF_EDGE, BMLoop::e, l, BMLoop::next, and BMLoop::prev.

Referenced by bevel_edge_order_extend().

◆ eh_on_plane()

static bool eh_on_plane ( EdgeHalf * e)
static

Definition at line 2666 of file bmesh_bevel.cc.

References BEVEL_EPSILON_BIG, dot_v3v3(), e, fabsf, and BMVert::no.

Referenced by build_boundary().

◆ fast_bevel_edge_order()

◆ fill_profile_fracs()

static void fill_profile_fracs ( BevelParams * bp,
BoundVert * bndv,
float * frac,
int ns )
static

◆ fill_vmesh_fracs()

static void fill_vmesh_fracs ( VMesh * vm,
float * frac,
int i )
static

Definition at line 3972 of file bmesh_bevel.cc.

References frac(), len_v3v3(), mesh_vert(), and VMesh::seg.

Referenced by interp_vmesh().

◆ find_bevel_edge_order()

◆ find_bevvert()

◆ find_closer_edge()

static BMEdge * find_closer_edge ( float * co,
BMEdge * e1,
BMEdge * e2 )
static

◆ find_edge_half()

static EdgeHalf * find_edge_half ( BevVert * bv,
BMEdge * bme )
static

◆ find_even_superellipse_chords()

static void find_even_superellipse_chords ( int n,
float r,
double * xvals,
double * yvals )
static

Find equidistant points (x0,y0), (x1,y1)... (xn,yn) on the superellipse function in the first quadrant. For special profiles (linear, arc, rectangle) the point can be calculated easily, for any other profile a more expensive search procedure must be used because there is no known closed form for equidistant parametrization. xvals and yvals should be size n+1.

Definition at line 7258 of file bmesh_bevel.cc.

References cos(), double(), find_even_superellipse_chords_general(), M_PI_2, M_SQRT2, PRO_CIRCLE_R, PRO_LINE_R, PRO_SQUARE_IN_R, and PRO_SQUARE_R.

Referenced by set_profile_spacing().

◆ find_even_superellipse_chords_general()

static void find_even_superellipse_chords_general ( int seg,
float r,
double * xvals,
double * yvals )
static

This search procedure to find equidistant points (x,y) in the first superellipse quadrant works for every superellipse exponent but is more expensive than known solutions for special cases. Call the point on superellipse that intersects x=y line mx. For r>=1 use only the range x in [0,mx] and mirror the rest along x=y line, for r<1 use only x in [mx,1]. Points are initially spaced and iteratively repositioned to have the same distance.

Definition at line 7158 of file bmesh_bevel.cc.

References e, find_superellipse_chord_endpoint(), M_SQRT2, pow(), sqrt(), sum(), and superellipse_co().

Referenced by find_even_superellipse_chords().

◆ find_face_internal_boundverts()

static int find_face_internal_boundverts ( const BevVert * bv,
const BMFace * f,
BoundVert * r_internal[3] )
static

Find which BoundVerts of bv are internal to face f. That is, when both the face and the point are projected to 2d, the point is on the boundary of or inside the projected face. There can only be up to three of then, since, including miters, that is the maximum number of BoundVerts that can be between two edges. Return the number of face-internal vertices found.

Definition at line 4753 of file bmesh_bevel.cc.

References BLI_assert, BM_face_point_inside_test(), VMesh::boundstart, BMVert::co, v, and BevVert::vmesh.

Referenced by bevel_build_poly(), build_center_ngon(), and projected_boundary_area().

◆ find_other_end_edge_half()

static EdgeHalf * find_other_end_edge_half ( BevelParams * bp,
EdgeHalf * e,
BevVert ** r_bvother )
static

Find the EdgeHalf representing the other end of e->e.

Returns
other end's BevVert in *r_bvother, if r_bvother is provided. That may not have been constructed yet, in which case return nullptr.

Definition at line 539 of file bmesh_bevel.cc.

References BLI_assert, BMVert::e, e, find_bevvert(), find_edge_half(), BMEdge::v1, and BMEdge::v2.

Referenced by adjust_offsets(), geometry_collide_offset(), next_edgehalf_bev(), and vertex_collide_offset().

◆ find_profile_fullness()

static float find_profile_fullness ( BevelParams * bp)
static

Find the profile's "fullness," which is the fraction of the space it takes up way from the boundvert's centroid to the original vertex for a non-custom profile, or in the case of a custom profile, the average "height" of the profile points along its centerline.

Definition at line 7334 of file bmesh_bevel.cc.

References BEVEL_PROFILE_CUSTOM, CIRCLE_FULLNESS_SEGS, float, PRO_CIRCLE_R, PRO_LINE_R, BevelParams::pro_spacing, BevelParams::pro_super_r, BevelParams::profile, BevelParams::profile_type, BevelParams::seg, ProfileSpacing::xvals, and ProfileSpacing::yvals.

Referenced by BM_mesh_bevel().

◆ find_superellipse_chord_endpoint()

static double find_superellipse_chord_endpoint ( double x0,
double dtarget,
float r,
bool rbig )
static

Definition at line 7090 of file bmesh_bevel.cc.

References e, fabs(), M_SQRT2, pow(), sqrt(), and superellipse_co().

Referenced by find_even_superellipse_chords_general().

◆ flag_out_edge()

static void flag_out_edge ( BMesh * bm,
BMEdge * bme )
static

◆ flag_out_vert()

static void flag_out_vert ( BMesh * bm,
BMVert * bmv )
static

Definition at line 404 of file bmesh_bevel.cc.

References bm, BMO_vert_flag_enable, BMesh::use_toolflags, and VERT_OUT.

Referenced by create_mesh_bmvert().

◆ frep_for_center_poly()

static BMFace * frep_for_center_poly ( BevelParams * bp,
BevVert * bv )
static

Pick a good face from all the faces around bv to use for a representative face, using choose_rep_face. We want to choose from among the faces that would be chosen for a single-segment edge polygon between two successive Boundverts. But the single beveled edge is a special case, where we also want to consider the third face (else can get zero-area UV interpolated face).

If there are math-having custom loop layers, like UV, then don't include faces that would result in zero-area UV polygons if chosen as the rep.

Definition at line 4855 of file bmesh_bevel.cc.

References BLI_array_alloca, choose_rep_face(), BevVert::edgecount, BevVert::edges, EdgeHalf::fnext, EdgeHalf::fprev, MathLayerInfo::has_math_layers, is_bad_uv_poly(), EdgeHalf::is_bev, BevelParams::math_layer_info, and BevVert::selcount.

Referenced by bevel_build_poly(), bevel_build_rings(), and build_center_ngon().

◆ geometry_collide_offset()

static float geometry_collide_offset ( BevelParams * bp,
EdgeHalf * eb )
static

Assume we have a situation like:

a                 d
 \               /
A \             / C
   \ th1    th2/
    b---------c
         B

where edges are A, B, and C, following a face around vertices a, b, c, d. th1 is angle abc and th2 is angle bcd; and the argument EdgeHalf eb is B, going from b to c. In general case, edge offset specs for A, B, C have the form ka*t, kb*t, kc*t where ka, kb, kc are some factors (may be 0) and t is the current bp->offset. We want to calculate t at which the clone of B parallel to it collapses. This can be calculated using trig. Another case of geometry collision that can happen is When B slides along A because A is un-beveled. Then it might collide with a. Similarly for B sliding along C.

Definition at line 7481 of file bmesh_bevel.cc.

References angle_v3v3v3(), BEVEL_AMT_ABSOLUTE, BEVEL_AMT_PERCENT, BM_edge_calc_length(), BM_face_edge_share_loop(), BMVert::co, EdgeHalf::e, ELEM, find_other_end_edge_half(), EdgeHalf::fnext, EdgeHalf::is_bev, EdgeHalf::is_rev, BMLoop::next, EdgeHalf::next, BevelParams::offset, EdgeHalf::offset_l_spec, EdgeHalf::offset_r_spec, BevelParams::offset_type, BMLoop::prev, EdgeHalf::prev, sinf, tanf, BevVert::v, BMLoop::v, BMEdge::v1, and BMEdge::v2.

Referenced by bevel_limit_offset().

◆ get_face_kind()

◆ get_incident_edges()

static void get_incident_edges ( BMFace * f,
BMVert * v,
BMEdge ** r_e1,
BMEdge ** r_e2 )
static

Definition at line 4712 of file bmesh_bevel.cc.

References BM_EDGES_OF_FACE, BM_ITER_ELEM, e, and v.

Referenced by bevel_build_poly(), build_center_ngon(), and projected_boundary_area().

◆ get_profile_point()

static void get_profile_point ( BevelParams * bp,
const Profile * pro,
int i,
int nseg,
float r_co[3] )
static

Find the point on given profile at parameter i which goes from 0 to nseg as the profile moves from pro->start to pro->end. We assume that nseg is either the global seg number or a power of 2 less than or equal to the power of 2 >= seg. In the latter case, we subsample the profile for seg_2, which will not necessarily give equal spaced chords, but is in fact more what is desired by the cubic subdivision method used to make the vmesh pattern.

Definition at line 2064 of file bmesh_bevel.cc.

References BLI_assert, copy_v3_v3(), Profile::end, is_power_of_2_i(), BevelParams::pro_spacing, Profile::prof_co, Profile::prof_co_2, BevelParams::seg, ProfileSpacing::seg_2, and Profile::start.

Referenced by adj_vmesh(), bevel_vert_two_edges(), build_vmesh(), cubic_subdiv(), fill_profile_fracs(), and make_cube_corner_adj_vmesh().

◆ good_offset_on_edge_between()

static bool good_offset_on_edge_between ( EdgeHalf * e1,
EdgeHalf * e2,
EdgeHalf * emid,
BMVert * v )
static

Return true if it will look good to put the meeting point where offset_on_edge_between would put it. This means that neither side sees a reflex angle.

Definition at line 1585 of file bmesh_bevel.cc.

References offset_meet_edge(), and v.

Referenced by build_boundary().

◆ interp_range()

static int interp_range ( const float * frac,
int n,
const float f,
float * r_rest )
static

Definition at line 4018 of file bmesh_bevel.cc.

References frac().

Referenced by interp_vmesh().

◆ interp_vmesh()

◆ is_bad_uv_poly()

static bool is_bad_uv_poly ( BevVert * bv,
BMFace * frep )
static

If we make a poly out of verts around bv, snapping to rep frep, will uv poly have zero area? The uv poly is made by snapping all outside-of-frep vertices to the closest edge in frep. Sometimes this results in a zero or very small area polygon, which translates to a zero or very small area polygon in UV space – not good for interpolating textures.

Definition at line 4834 of file bmesh_bevel.cc.

References BEVEL_EPSILON_BIG, BLI_assert, projected_boundary_area(), and BevVert::vmesh.

Referenced by frep_for_center_poly().

◆ is_canon()

static bool is_canon ( VMesh * vm,
int i,
int j,
int k )
static

◆ is_outside_edge()

static bool is_outside_edge ( EdgeHalf * e,
const float co[3],
BMVert ** ret_closer_v )
static

◆ make_cube_corner_adj_vmesh()

◆ make_cube_corner_square()

static VMesh * make_cube_corner_square ( MemArena * mem_arena,
int nseg )
static

◆ make_cube_corner_square_in()

static VMesh * make_cube_corner_square_in ( MemArena * mem_arena,
int nseg )
static

Special case for cube corner, when r is PRO_SQUARE_IN_R, meaning inward straight sides. We mostly don't want a VMesh at all for this case – just a three-way weld with a triangle in the middle for odd nseg.

Definition at line 4330 of file bmesh_bevel.cc.

References add_new_bound_vert(), b, copy_v3_v3(), VMesh::count, float, M_SQRT2, mem_arena, mesh_vert(), and new_adj_vmesh().

Referenced by make_cube_corner_adj_vmesh().

◆ make_unit_cube_map()

static void make_unit_cube_map ( const float va[3],
const float vb[3],
const float vc[3],
const float vd[3],
float r_mat[4][4] )
static

Like make_unit_square_map, but this one makes a matrix that transforms the (1,1,1) corner of a unit cube into an arbitrary corner with corner vert d and verts around it a, b, c (in CCW order, viewed from d normal dir). The matrix mat is calculated to map: (1,0,0) -> va (0,1,0) -> vb (0,0,1) -> vc (1,1,1) -> vd We want M to make M*A=B where A has the left side above, as columns and B has the right side as columns - both extended into homogeneous coords. So M = B*(Ainverse). Doing Ainverse by hand gives the code below. The cols of M are 1/2{va-vb+vc-vd}, 1/2{-va+vb-vc+vd}, 1/2{-va-vb+vc+vd}, and 1/2{va+vb+vc-vd} and Blender matrices have cols at m[i][*].

Definition at line 2008 of file bmesh_bevel.cc.

References add_v3_v3(), copy_v3_v3(), mul_v3_fl(), and sub_v3_v3().

Referenced by tri_corner_adj_vmesh().

◆ make_unit_square_map()

static bool make_unit_square_map ( const float va[3],
const float vmid[3],
const float vb[3],
float r_mat[4][4] )
static

Fill matrix r_mat so that a point in the sheared parallelogram with corners va, vmid, vb (and the 4th that is implied by it being a parallelogram) is the result of transforming the unit square by multiplication with r_mat. If it can't be done because the parallelogram is degenerate, return false, else return true. Method: Find vo, the origin of the parallelogram with other three points va, vmid, vb. Also find vd, which is in direction normal to parallelogram and 1 unit away from the origin. The quarter circle in first quadrant of unit square will be mapped to the quadrant of a sheared ellipse in the parallelogram, using a matrix. The matrix mat is calculated to map: (0,1,0) -> va (1,1,0) -> vmid (1,0,0) -> vb (0,1,1) -> vd We want M to make M*A=B where A has the left side above, as columns and B has the right side as columns - both extended into homogeneous coords. So M = B*(Ainverse). Doing Ainverse by hand gives the code below.

Definition at line 1951 of file bmesh_bevel.cc.

References add_v3_v3v3(), angle_v3v3(), BEVEL_EPSILON_ANG, cross_v3_v3v3(), fabsf, is_zero_v3(), M_PI, normalize_v3(), sub_v3_v3(), and sub_v3_v3v3().

Referenced by calculate_profile(), and snap_to_pipe_profile().

◆ math_layer_info_init()

◆ mesh_vert()

◆ mesh_vert_canon()

static NewVert * mesh_vert_canon ( VMesh * vm,
int i,
int j,
int k )
static

VMesh verts for vertex i have data for (i, 0 <= j <= ns2, 0 <= k <= ns), where ns2 = floor(nseg / 2). But these overlap data from previous and next i: there are some forced equivalences. Let's call these indices the canonical ones: we will just calculate data for these 0 <= j <= ns2, 0 <= k <= ns2 (for odd ns) 0 <= j < ns2, 0 <= k <= ns2 (for even ns) also (j=ns2, k=ns2) at i=0 (for even ns2) This function returns the canonical one for any i, j, k in [0,n],[0,ns],[0,ns].

Definition at line 3863 of file bmesh_bevel.cc.

References BLI_assert, VMesh::count, mesh_vert(), and VMesh::seg.

Referenced by cubic_subdiv(), interp_vmesh(), and vmesh_copy_equiv_verts().

◆ move_profile_plane()

static void move_profile_plane ( BoundVert * bndv,
BMVert * bmvert )
static

Maybe move the profile plane for bndv->ebev to the plane its profile's start, and the original beveled vert, bmv. This will usually be the plane containing its adjacent non-beveled edges, but sometimes the start and the end are not on those edges.

Currently just used in build_boundary_terminal_edge.

Definition at line 1840 of file bmesh_bevel.cc.

References BEVEL_EPSILON_BIG, BMVert::co, copy_v3_v3(), cross_v3_v3v3(), dot3(), dot_v3v3(), Profile::end, fabsf, is_zero_v3(), normalize_v3(), Profile::plane_no, BoundVert::profile, Profile::proj_dir, Profile::special_params, Profile::start, and sub_v3_v3v3().

Referenced by build_boundary_terminal_edge().

◆ move_weld_profile_planes()

static void move_weld_profile_planes ( BevVert * bv,
BoundVert * bndv1,
BoundVert * bndv2 )
static

Move the profile plane for the two BoundVerts involved in a weld. We want the plane that is most likely to have the intersections of the two edges' profile projections on it. bndv1 and bndv2 are by construction the intersection points of the outside parts of the profiles. The original vertex should form a third point of the desired plane.

Definition at line 1880 of file bmesh_bevel.cc.

References BEVEL_EPSILON, BMVert::co, NewVert::co, copy_v3_v3(), cross_v3_v3v3(), dot_v3v3(), fabsf, is_zero_v3(), normalize_v3(), BoundVert::nv, Profile::plane_no, BoundVert::profile, Profile::proj_dir, Profile::special_params, sub_v3_v3v3(), and BevVert::v.

Referenced by build_vmesh().

◆ nearly_parallel()

static bool nearly_parallel ( const float d1[3],
const float d2[3] )
static

Definition at line 432 of file bmesh_bevel.cc.

References angle_v3v3(), BEVEL_EPSILON_ANG, fabsf, and M_PI.

Referenced by set_profile_params().

◆ nearly_parallel_normalized()

static bool nearly_parallel_normalized ( const float d1[3],
const float d2[3] )
static
Returns
True if d1 and d2 are parallel or nearly parallel.

Definition at line 442 of file bmesh_bevel.cc.

References BEVEL_EPSILON_ANG_DOT, BLI_ASSERT_UNIT_V3, compare_ff(), dot_v3v3(), and fabsf.

Referenced by edges_angle_kind().

◆ new_adj_vmesh()

◆ next_bev()

static EdgeHalf * next_bev ( BevVert * bv,
EdgeHalf * from_e )
static

Definition at line 558 of file bmesh_bevel.cc.

References e, BevVert::edgecount, and BevVert::edges.

Referenced by bevel_build_trifan(), and build_boundary().

◆ next_edgehalf_bev()

static EdgeHalf * next_edgehalf_bev ( BevelParams * bp,
EdgeHalf * start_edge,
bool toward_bv,
BevVert ** r_bv )
static

Helper function to return the next Beveled EdgeHalf along a path.

Parameters
toward_bvWhether the direction to travel points toward or away from the BevVert connected to the current EdgeHalf.
r_bvThe BevVert connected to the EdgeHalf – updated if we're traveling to the other EdgeHalf of an original edge.
Note
This only returns the most parallel edge if it's the most parallel by at least 10 degrees. This is a somewhat arbitrary choice, but it makes sure that consistent orientation paths only continue in obvious ways.

Definition at line 3395 of file bmesh_bevel.cc.

References BEVEL_SMALL_ANG_DOT, BMVert::co, compare_ff(), dot_v3v3(), EdgeHalf::e, find_other_end_edge_half(), EdgeHalf::is_bev, EdgeHalf::next, normalize_v3(), sub_v3_v3v3(), BMEdge::v1, and BMEdge::v2.

Referenced by regularize_profile_orientation().

◆ offset_in_plane()

static void offset_in_plane ( EdgeHalf * e,
const float plane_no[3],
bool left,
float r_co[3] )
static

◆ offset_meet()

static void offset_meet ( BevelParams * bp,
EdgeHalf * e1,
EdgeHalf * e2,
BMVert * v,
BMFace * f,
bool edges_between,
float meetco[3],
const EdgeHalf * e_in_plane )
static

Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco. e1 and e2 share vertex v and face f (may be nullptr) and viewed from the normal side of the bevel vertex, e1 precedes e2 in CCW order. Offset edge is on right of both edges, where e1 enters v and e2 leave it. When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2), but if the offsets are not equal (we allow for because the bevel modifier has edge weights that may lead to different offsets) then the meeting point can be found by intersecting offset lines. If making the meeting point significantly changes the left or right offset from the user spec, record the change in offset_l (or offset_r); later we can tell that a change has happened because the offset will differ from its original value in offset_l_spec (or offset_r_spec).

Parameters
edges_betweenIf this is true, there are edges between e1 and e2 in CCW order so they don't share a common face. We want the meeting point to be on an existing face so it should be dropped onto one of the intermediate faces, if possible.
e_in_planeIf we need to drop from the calculated offset lines to one of the faces, we don't want to drop onto the 'in plane' face, so if this is not null skip this edge's faces.

Definition at line 1334 of file bmesh_bevel.cc.

References add_v3_v3(), add_v3_v3v3(), angle_v3v3(), BEVEL_AMT_ABSOLUTE, BEVEL_AMT_PERCENT, BEVEL_EPSILON_ANG, BEVEL_SMALL_ANG, BM_edge_other_vert(), closest_to_plane_normalized_v3(), BMVert::co, copy_v3_v3(), cosf, cross_v3_v3v3(), dot_v3v3(), e, EdgeHalf::e, ELEM, fabsf, EdgeHalf::fnext, EdgeHalf::fprev, is_outside_edge(), isect_line_line_v3(), M_PI, madd_v3_v3fl(), max_ff(), mid_v3_v3v3(), mul_v3_fl(), negate_v3(), EdgeHalf::next, BMFace::no, BMVert::no, normalize_v3(), EdgeHalf::offset_l, offset_meet_lines_percent_or_absolute(), EdgeHalf::offset_r, BevelParams::offset_type, plane_from_point_normal_v3(), point_between_edges(), EdgeHalf::prev, slide_dist(), sub_v3_v3v3(), v, and zero_v3().

Referenced by build_boundary(), and build_boundary_terminal_edge().

◆ offset_meet_edge()

static bool offset_meet_edge ( EdgeHalf * e1,
EdgeHalf * e2,
BMVert * v,
float meetco[3],
float * r_angle )
static

Calculate the meeting point between e1 and e2 (one of which should have zero offsets), where e1 precedes e2 in CCW order around their common vertex v (viewed from normal side). If r_angle is provided, return the angle between e and meetco in *r_angle. If the angle is 0, or it is 180 degrees or larger, there will be no meeting point; return false in that case, else true.

Definition at line 1535 of file bmesh_bevel.cc.

References angle_normalized_v3v3(), BEVEL_GOOD_ANGLE, BM_edge_other_vert(), BMVert::co, copy_v3_v3(), cross_v3_v3v3(), dot_v3v3(), EdgeHalf::e, fabsf, float, M_PI, madd_v3_v3fl(), BMVert::no, normalize_v3(), EdgeHalf::offset_l, EdgeHalf::offset_r, sinf, sub_v3_v3v3(), and v.

Referenced by good_offset_on_edge_between(), and offset_on_edge_between().

◆ offset_meet_lines_percent_or_absolute()

◆ offset_on_edge_between()

static bool offset_on_edge_between ( BevelParams * bp,
EdgeHalf * e1,
EdgeHalf * e2,
EdgeHalf * emid,
BMVert * v,
float meetco[3],
float * r_sinratio )
static

Calculate the best place for a meeting point for the offsets from edges e1 and e2 on the in-between edge emid. Viewed from the vertex normal side, the CCW order of these edges is e1, emid, e2. Return true if we placed meetco as compromise between where two edges met. If we did, put the ratio of sines of angles in *r_sinratio too. However, if the bp->offset_type is BEVEL_AMT_PERCENT or BEVEL_AMT_ABSOLUTE, we just slide along emid by the specified amount.

Definition at line 1601 of file bmesh_bevel.cc.

References BEVEL_AMT_ABSOLUTE, BEVEL_AMT_PERCENT, BLI_assert, BM_edge_other_vert(), BM_ELEM_CD_GET_FLOAT, BevelParams::bweight_offset_edge, BMVert::co, copy_v3_v3(), EdgeHalf::e, ELEM, interp_v3_v3v3(), EdgeHalf::is_bev, madd_v3_v3v3fl(), mid_v3_v3v3(), normalize_v3(), BevelParams::offset, offset_meet_edge(), EdgeHalf::offset_r, BevelParams::offset_type, sinf, slide_dist(), sub_v3_v3v3(), BevelParams::use_weights, v, and v2.

Referenced by build_boundary().

◆ pipe_adj_vmesh()

static VMesh * pipe_adj_vmesh ( BevelParams * bp,
BevVert * bv,
BoundVert * vpipe )
static

See pipe_test for conditions that make 'pipe'; vpipe is the return value from that. We want to make an ADJ mesh but then snap the vertices to the profile in a plane perpendicular to the pipes.

Definition at line 4650 of file bmesh_bevel.cc.

References adj_vmesh(), BEVEL_PROFILE_CUSTOM, NewVert::co, VMesh::count, ELEM, float, BoundVert::index, interp_v3_v3v3(), is_canon(), max_ii(), mesh_vert(), min_ff(), BoundVert::next, BevelParams::profile_type, VMesh::seg, snap_to_pipe_profile(), and BevVert::vmesh.

Referenced by bevel_build_rings().

◆ pipe_test()

static BoundVert * pipe_test ( BevVert * bv)
static

Do the edges at bv form a "pipe"? Current definition: 3 or 4 beveled edges, 2 in line with each other, with other edges on opposite sides of the pipe if there are 4. Also, the vertex boundary should have 3 or 4 vertices in it, and all of the faces involved should be parallel to the pipe edges. Return the boundary vert whose ebev is one of the pipe edges, and whose next boundary vert has a beveled, non-pipe edge.

Definition at line 3800 of file bmesh_bevel.cc.

References angle_normalized_v3v3(), BEVEL_EPSILON_ANG, BEVEL_EPSILON_BIG, BM_edge_other_vert(), VMesh::boundstart, BMVert::co, VMesh::count, dot_v3v3(), e, EdgeHalf::e, BoundVert::ebev, BevVert::edgecount, BevVert::edges, fabsf, BoundVert::next, BMVert::no, normalize_v3(), BevVert::selcount, sub_v3_v3v3(), BevVert::v, v2, and BevVert::vmesh.

Referenced by build_vmesh().

◆ point_between_edges()

static bool point_between_edges ( const float co[3],
BMVert * v,
BMFace * f,
EdgeHalf * e1,
EdgeHalf * e2 )
static

◆ project_to_edge()

static void project_to_edge ( const BMEdge * e,
const float co_a[3],
const float co_b[3],
float projco[3] )
static

Definition at line 1698 of file bmesh_bevel.cc.

References BLI_assert_msg, BMVert::co, copy_v3_v3(), e, and isect_line_line_v3().

Referenced by set_profile_params().

◆ projected_boundary_area()

static float projected_boundary_area ( BevVert * bv,
BMFace * f )
static

Find where the coordinates of the BndVerts in bv should snap to in face f. Face f should contain vertex bv->v. Project the snapped verts to 2d, then return the area of the resulting polygon. Usually one BndVert is inside the face, sometimes up to 3 (if there are miters), so don't snap those to an edge; all the rest snap to one of the edges of bmf incident on bv->v.

Definition at line 4789 of file bmesh_bevel.cc.

References area_poly_v2(), axis_dominant_v3_to_m3(), BLI_array_alloca, BLI_assert, VMesh::boundstart, closest_to_line_segment_v3(), BMVert::co, VMesh::count, ELEM, find_face_internal_boundverts(), float, get_incident_edges(), len_squared_v3v3(), mul_v2_m3v3(), BMFace::no, BevVert::v, v, BMEdge::v1, BMEdge::v2, and BevVert::vmesh.

Referenced by is_bad_uv_poly().

◆ record_face_kind()

◆ regularize_profile_orientation()

static void regularize_profile_orientation ( BevelParams * bp,
BMEdge * bme )
static

Starting along any beveled edge, travel along the chain / cycle of beveled edges including that edge, marking consistent profile orientations along the way. Orientations are marked by setting whether the BoundVert that contains each profile's information is the side of the profile's start or not.

Definition at line 3480 of file bmesh_bevel.cc.

References NewVert::co, find_bevvert(), find_edge_half(), EdgeHalf::is_bev, BoundVert::is_profile_start, EdgeHalf::leftv, next_edgehalf_bev(), BoundVert::nv, EdgeHalf::rightv, BMEdge::v1, and EdgeHalf::visited_rpo.

Referenced by BM_mesh_bevel().

◆ sabin_gamma()

static float sabin_gamma ( int n)
static

Definition at line 3941 of file bmesh_bevel.cc.

References cos(), M_PI, M_SQRT3, pow(), sqrt(), and y.

Referenced by cubic_subdiv().

◆ set_bound_vert_seams()

static void set_bound_vert_seams ( BevVert * bv,
bool mark_seam,
bool mark_sharp )
static

◆ set_profile_params()

◆ set_profile_spacing()

static void set_profile_spacing ( BevelParams * bp,
ProfileSpacing * pro_spacing,
bool custom )
static

Fills the ProfileSpacing struct with the 2D coordinates for the profile's vertices. The superellipse used for multi-segment profiles does not have a closed-form way to generate evenly spaced points along an arc. We use an expensive search procedure to find the parameter values that lead to bp->seg even chords. We also want spacing for a number of segments that is a power of 2 >= bp->seg (but at least 4). Use doubles because otherwise we cannot come close to float precision for final results.

Parameters
pro_spacingThe struct to fill. Changes depending on whether there needs to be a separate miter profile.

Definition at line 7395 of file bmesh_bevel.cc.

References BKE_curveprofile_init(), BLI_memarena_alloc(), BevelParams::custom_profile, double(), find_even_superellipse_chords(), max_ii(), BevelParams::mem_arena, power_of_2_max_i(), BevelParams::pro_spacing, BevelParams::pro_super_r, BevelParams::seg, ProfileSpacing::seg_2, CurveProfile::segments, CurveProfile::segments_len, CurveProfilePoint::x, ProfileSpacing::xvals, ProfileSpacing::xvals_2, CurveProfilePoint::y, ProfileSpacing::yvals, and ProfileSpacing::yvals_2.

Referenced by BM_mesh_bevel().

◆ slide_dist()

◆ snap_edge_for_center_vmesh_vert()

static BMEdge * snap_edge_for_center_vmesh_vert ( int i,
int n_bndv,
BMEdge * eprev,
BMEdge * enext,
BMFace ** bndv_rep_faces,
BMFace * center_frep,
const bool * frep_beats_next )
static

Definition at line 5231 of file bmesh_bevel.cc.

Referenced by snap_edges_for_vmesh_vert().

◆ snap_edges_for_vmesh_vert()

static void snap_edges_for_vmesh_vert ( int i,
int j,
int k,
int ns,
int ns2,
int n_bndv,
BMEdge * eprev,
BMEdge * enext,
BMEdge * enextnext,
BMFace ** bndv_rep_faces,
BMFace * center_frep,
const bool * frep_beats_next,
BMEdge * r_snap_edges[4] )
static

Fill the r_snap_edges array with the edges to snap to (or NUL, if no snapping) for the adj mesh face with lower left corner at (i, ring j, segment k). The indices of the four corners are (i,j,k), (i,j,k+1), (i,j+1,k+1), (i,j+1,k). The answer will be one of nullptr (don't snap), eprev (the edge between boundvert i and boundvert i-1), or enext (the edge between boundvert i and boundvert i+1). When n is odd, the center column (seg ns2) is ambiguous as to whether it interpolates in the current boundvert's frep [= interpolation face] or the next one's. Similarly, when n is odd, the center row (ring ns2) is ambiguous as to whether it interpolates in the current boundvert's frep or the previous one's. Parameter frep_beats_next should have an array of size n_bndv of booleans that say whether the tie should be broken in favor of the next boundvert's frep (if true) or the current one's. For vertices in the center polygon (when ns is odd), the snapping edge depends on where the boundvert is in relation to the boundvert that has the center face's frep, so the arguments bndv_rep_faces is an array of size n_bndv give the freps for each i, and center_frep is the frep for the center.

NOTE: this function is for edge bevels only, at the moment.

Definition at line 5276 of file bmesh_bevel.cc.

References BLI_assert, ELEM, and snap_edge_for_center_vmesh_vert().

Referenced by bevel_build_rings().

◆ snap_to_pipe_profile()

static void snap_to_pipe_profile ( BoundVert * vpipe,
bool midline,
float co[3] )
static

Snap co to the closest point on the profile for vpipe projected onto the plane containing co with normal in the direction of edge vpipe->ebev. For the square profiles, need to decide whether to snap to just one plane or to the midpoint of the profile; do so if midline is true.

Definition at line 4606 of file bmesh_bevel.cc.

References BEVEL_EPSILON_D, closest_to_line_segment_v3(), closest_to_plane_v3(), BMVert::co, compare_v3v3(), copy_v3_v3(), BMVert::e, e, BoundVert::ebev, Profile::end, invert_m4_m4(), make_unit_square_map(), Profile::middle, mul_v3_m4v3(), plane_from_point_normal_v3(), BoundVert::profile, snap(), snap_to_superellipsoid(), Profile::start, sub_v3_v3v3(), Profile::super_r, BMEdge::v1, and BMEdge::v2.

Referenced by pipe_adj_vmesh().

◆ snap_to_superellipsoid()

static void snap_to_superellipsoid ( float co[3],
const float super_r,
bool midline )
static

Snap a direction co to a superellipsoid with parameter super_r. For square profiles, midline says whether or not to snap to both planes.

Only currently used for the pipe and cube corner special cases.

Definition at line 2213 of file bmesh_bevel.cc.

References b, BEVEL_EPSILON, BLI_assert, ELEM, fabsf, max_ff(), min_ff(), normalize_v3(), powf, PRO_CIRCLE_R, PRO_SQUARE_IN_R, PRO_SQUARE_R, x, y, and z().

Referenced by make_cube_corner_adj_vmesh(), and snap_to_pipe_profile().

◆ square_out_adj_vmesh()

static VMesh * square_out_adj_vmesh ( BevelParams * bp,
BevVert * bv )
static

Special case of VMesh when profile == 1 and there are 3 or more beveled edges. We want the effect of parallel offset lines (n/2 of them) on each side of the center, for even n. Wherever they intersect with each other between two successive beveled edges, those intersections are part of the vmesh rings. We have to move the boundary edges too – the usual method is to make one profile plane between successive BoundVerts, but for the effect we want here, there will be two planes, one on each side of the original edge. At the moment, this is not called for odd number of segments, though code does something if it is.

Definition at line 5003 of file bmesh_bevel.cc.

References add_v3_v3v3(), ANGLE_SMALLER, ANGLE_STRAIGHT, angle_v3v3v3(), BEVEL_SMALL_ANG, VMesh::boundstart, closer_v3_v3v3v3(), closest_to_line_segment_v3(), BMVert::co, NewVert::co, copy_v3_v3(), VMesh::count, EdgeHalf::e, edges_angle_kind(), BoundVert::efirst, BoundVert::elast, float, interp_v3_v3v3(), BoundVert::is_arc_start, BoundVert::is_patch_start, isect_line_line_v3(), BevelParams::mem_arena, MEM_callocN, MEM_freeN(), MEM_mallocN, mesh_vert(), mid_v3_v3v3(), Profile::middle, new_adj_vmesh(), BoundVert::next, BoundVert::nv, BoundVert::prev, BoundVert::profile, VMesh::seg, sinf, sub_v3_v3v3(), BevVert::v, BMEdge::v1, BMEdge::v2, BevVert::vmesh, and vmesh_copy_equiv_verts().

Referenced by bevel_build_rings().

◆ superellipse_co()

static double superellipse_co ( double x,
float r,
bool rbig )
static

Get the coordinate on the superellipse (x^r + y^r = 1), at parameter value x (or, if !rbig, mirrored (y=x)-line). rbig should be true if r > 1.0 and false if <= 1.0. Assume r > 0.0.

Definition at line 2043 of file bmesh_bevel.cc.

References BLI_assert, and pow().

Referenced by find_even_superellipse_chords_general(), and find_superellipse_chord_endpoint().

◆ swap_face_components()

static void swap_face_components ( int * face_component,
int totface,
int c1,
int c2 )
static

In array face_component of total totface elements, swap values c1 and c2 wherever they occur.

Definition at line 799 of file bmesh_bevel.cc.

Referenced by math_layer_info_init().

◆ tri_corner_adj_vmesh()

◆ tri_corner_test()

◆ vertex_collide_offset()

static float vertex_collide_offset ( BevelParams * bp,
EdgeHalf * ea )
static

We have an edge A between vertices a and b, where EdgeHalf ea is the half of A that starts at a. For vertex-only bevels, the new vertices slide from a at a rate ka*t and from b at a rate kb*t. We want to calculate the t at which the two meet.

Definition at line 7597 of file bmesh_bevel.cc.

References BM_edge_calc_length(), EdgeHalf::e, find_other_end_edge_half(), BevelParams::offset, and EdgeHalf::offset_l_spec.

Referenced by bevel_limit_offset().

◆ vmesh_center()

static void vmesh_center ( VMesh * vm,
float r_cent[3] )
static

Definition at line 3915 of file bmesh_bevel.cc.

References add_v3_v3(), copy_v3_v3(), VMesh::count, mesh_vert(), mul_v3_fl(), VMesh::seg, and zero_v3().

Referenced by interp_vmesh().

◆ vmesh_copy_equiv_verts()

◆ weld_cross_attrs_copy()

static void weld_cross_attrs_copy ( BMesh * bm,
BevVert * bv,
VMesh * vm,
int vmindex,
EdgeHalf * e )
static

Copy edge attribute data across the non-beveled crossing edges of a cross weld.

Situation looks like this:

 e->next
   |

----—3----— ----—2----— ----—1----— e ----—0---— | e->prev

where e is the EdgeHalf of one of the beveled edges, e->next and e->prev are EdgeHalfs for the unbeveled edges of the cross and their attributes are to be copied to the edges 01, 12, 23. The vert i is mesh_vert(vm, vmindex, 0, i)->v.

Definition at line 6880 of file bmesh_bevel.cc.

References BLI_assert, bm, BM_edge_exists(), BM_elem_attrs_copy(), BM_elem_flag_disable, BM_elem_flag_enable, BM_elem_flag_test, BM_ELEM_SEAM, BM_ELEM_SMOOTH, e, BevVert::edges, mesh_vert(), and v.

Referenced by bevel_build_edge_polygons().