Blender  V3.3
Classes | Macros | Typedefs | Enumerations | Functions
bmesh_bevel.c File Reference
#include "MEM_guardedalloc.h"
#include "DNA_curveprofile_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BKE_curveprofile.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "eigen_capi.h"
#include "bmesh.h"
#include "bmesh_bevel.h"
#include "./intern/bmesh_private.h"

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 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
 

Typedefs

typedef struct NewVert NewVert
 
typedef struct EdgeHalf EdgeHalf
 
typedef struct Profile Profile
 
typedef struct ProfileSpacing ProfileSpacing
 
typedef struct MathLayerInfo MathLayerInfo
 
typedef struct BoundVert BoundVert
 
typedef struct VMesh VMesh
 
typedef struct BevVert BevVert
 
typedef enum AngleKind AngleKind
 
typedef struct BevelParams BevelParams
 

Enumerations

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, bool neg)
 
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. More...
 
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 struct 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 float smoothresh, const struct CurveProfile *custom_profile, const int vmesh_method)
 

Detailed Description

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

Definition in file bmesh_bevel.c.

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 2265 of file bmesh_bevel.c.

◆ BEVEL_EPSILON

#define BEVEL_EPSILON   1e-6f

Definition at line 40 of file bmesh_bevel.c.

◆ BEVEL_EPSILON_ANG

#define BEVEL_EPSILON_ANG   DEG2RADF(2.0f)

Definition at line 44 of file bmesh_bevel.c.

◆ 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 49 of file bmesh_bevel.c.

◆ BEVEL_EPSILON_BIG

#define BEVEL_EPSILON_BIG   1e-4f

Definition at line 42 of file bmesh_bevel.c.

◆ BEVEL_EPSILON_BIG_SQ

#define BEVEL_EPSILON_BIG_SQ   1e-8f

Definition at line 43 of file bmesh_bevel.c.

◆ BEVEL_EPSILON_D

#define BEVEL_EPSILON_D   1e-6

Definition at line 39 of file bmesh_bevel.c.

◆ BEVEL_EPSILON_SQ

#define BEVEL_EPSILON_SQ   1e-12f

Definition at line 41 of file bmesh_bevel.c.

◆ BEVEL_GOOD_ANGLE

#define BEVEL_GOOD_ANGLE   0.1f

Definition at line 1509 of file bmesh_bevel.c.

◆ BEVEL_MATCH_SPEC_WEIGHT

#define BEVEL_MATCH_SPEC_WEIGHT   0.2

Definition at line 52 of file bmesh_bevel.c.

◆ BEVEL_MAX_ADJUST_PCT

#define BEVEL_MAX_ADJUST_PCT   10.0f

Definition at line 50 of file bmesh_bevel.c.

◆ BEVEL_MAX_AUTO_ADJUST_PCT

#define BEVEL_MAX_AUTO_ADJUST_PCT   300.0f

Definition at line 51 of file bmesh_bevel.c.

◆ BEVEL_SMALL_ANG

#define BEVEL_SMALL_ANG   DEG2RADF(10.0f)

Definition at line 45 of file bmesh_bevel.c.

◆ 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 47 of file bmesh_bevel.c.

◆ BM_BEVEL_EDGE_TAG_DISABLE

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

Definition at line 6070 of file bmesh_bevel.c.

◆ BM_BEVEL_EDGE_TAG_ENABLE

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

Definition at line 6069 of file bmesh_bevel.c.

◆ BM_BEVEL_EDGE_TAG_TEST

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

Definition at line 6071 of file bmesh_bevel.c.

◆ BM_ELEM_LONG_TAG

#define BM_ELEM_LONG_TAG   (1 << 6)

Definition at line 378 of file bmesh_bevel.c.

◆ CIRCLE_FULLNESS_SEGS

#define CIRCLE_FULLNESS_SEGS   11

◆ EDGE_OUT

#define EDGE_OUT   4

Definition at line 381 of file bmesh_bevel.c.

◆ PRO_CIRCLE_R

#define PRO_CIRCLE_R   2.0f

Definition at line 146 of file bmesh_bevel.c.

◆ PRO_LINE_R

#define PRO_LINE_R   1.0f

Definition at line 147 of file bmesh_bevel.c.

◆ PRO_SQUARE_IN_R

#define PRO_SQUARE_IN_R   0.0f

Definition at line 148 of file bmesh_bevel.c.

◆ PRO_SQUARE_R

#define PRO_SQUARE_R   1e4f

Definition at line 145 of file bmesh_bevel.c.

◆ VEC_VALUE_LEN

#define VEC_VALUE_LEN   6

◆ VERT_OUT

#define VERT_OUT   8

Definition at line 382 of file bmesh_bevel.c.

Typedef Documentation

◆ AngleKind

typedef enum AngleKind AngleKind

Helper for keeping track of angle kind.

◆ BevelParams

typedef struct BevelParams BevelParams

Bevel parameters and state.

◆ BevVert

typedef struct BevVert BevVert

◆ BoundVert

typedef struct BoundVert BoundVert

An element in a cyclic boundary of a Vertex Mesh (VMesh), placed on each side of beveled edges where each profile starts, or on each side of a miter.

◆ EdgeHalf

typedef struct EdgeHalf EdgeHalf

◆ MathLayerInfo

typedef struct MathLayerInfo MathLayerInfo

If the mesh has custom data Loop layers that 'have math' we use this data to help decide which face to use as representative when there is an ambiguous choice as to which face to use, which happens when there is an odd number of segments.

The face_compent field of the following will only be set if there are an odd number of segments. The it uses BMFace indices to index into it, so will only be valid as long BMFaces are not added or deleted in the BMesh. "Connected Component" here means connected in UV space: i.e., one face is directly connected to another if they share an edge and all of Loop UV custom layers are contiguous across that edge.

◆ NewVert

typedef struct NewVert NewVert

◆ Profile

typedef struct Profile Profile

Profile specification: The profile is a path defined with start, middle, and end control points projected onto a plane (plane_no is normal, plane_co is a point on it) via lines in a given direction (proj_dir).

Many interesting profiles are in family of superellipses: (abs(x/a))^r + abs(y/b))^r = 1 r==2 => ellipse; r==1 => line; r < 1 => concave; r > 1 => bulging out. Special cases: let r==0 mean straight-inward, and r==4 mean straight outward.

After the parameters are all set, the actual profile points are calculated and pointed to by prof_co. We also may need profile points for a higher resolution number of segments for the subdivision while making the ADJ vertex mesh pattern, and that goes in prof_co_2.

◆ ProfileSpacing

The un-transformed 2D storage of profile vertex locations. Also, for non-custom profiles this serves as a cache for the results of the expensive calculation of u parameter values to get even spacing on superellipse for current BevelParams seg and pro_super_r.

◆ VMesh

typedef struct VMesh VMesh

Data for the mesh structure replacing a vertex.

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 295 of file bmesh_bevel.c.

◆ 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 281 of file bmesh_bevel.c.

Function Documentation

◆ add_new_bound_vert()

static BoundVert* add_new_bound_vert ( MemArena mem_arena,
VMesh vm,
const float  co[3] 
)
static

◆ adj_vmesh()

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

◆ adjust_bound_vert()

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

◆ adjust_miter_coords()

static void adjust_miter_coords ( BevelParams bp,
BevVert bv,
EdgeHalf emiter 
)
static

◆ adjust_miter_inner_coords()

static void adjust_miter_inner_coords ( BevelParams bp,
BevVert bv,
EdgeHalf emiter 
)
static

◆ 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 3694 of file bmesh_bevel.c.

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, NULL, 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 3532 of file bmesh_bevel.c.

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, 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 3932 of file bmesh_bevel.c.

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

Referenced by cubic_subdiv().

◆ bev_ccw_test()

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

Definition at line 1899 of file bmesh_bevel.c.

References Freestyle::a, usdtokens::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-NULL, else from facerep. If edge_arr is non-NULL, then for interpolation purposes only, the corresponding elements of vert_arr are snapped to any non-NULL 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 663 of file bmesh_bevel.c.

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, NULL, 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()

static void bev_merge_edge_uvs ( BMesh bm,
BMEdge bme,
BMVert v 
)
static

◆ bev_merge_end_uvs()

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

Definition at line 6867 of file bmesh_bevel.c.

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

Referenced by bevel_build_edge_polygons().

◆ bev_merge_uvs()

static void bev_merge_uvs ( BMesh bm,
BMVert v 
)
static

◆ bev_rebuild_polygon()

static bool bev_rebuild_polygon ( BMesh bm,
BevelParams bp,
BMFace f 
)
static

◆ 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 5590 of file bmesh_bevel.c.

References bev_create_ngon(), BEVEL_EPSILON, BLI_array_free, BLI_array_staticdeclare, BLI_memarena_alloc(), bm, BM_DEFAULT_NGON_STACK_SIZE, 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(), blender::math::length(), madd_v3_v3v3fl(), BevelParams::mat_nr, max_ii(), BevelParams::mem_arena, mesh_vert(), negate_v3(), BoundVert::next, BMVert::no, NULL, BoundVert::nv, Profile::plane_no, BoundVert::prev, BoundVert::profile, BevelParams::seg, sqrtf, NewVert::v, BevVert::v, and BevVert::vmesh.

Referenced by build_vmesh().

◆ bevel_build_edge_polygons()

static void bevel_build_edge_polygons ( BMesh bm,
BevelParams bp,
BMEdge bme 
)
static

◆ bevel_build_poly()

static BMFace* bevel_build_poly ( BevelParams bp,
BMesh bm,
BevVert bv 
)
static

◆ bevel_build_rings()

static void bevel_build_rings ( BevelParams bp,
BMesh bm,
BevVert bv,
BoundVert vpipe 
)
static

◆ bevel_build_trifan()

static void bevel_build_trifan ( BevelParams bp,
BMesh bm,
BevVert bv 
)
static

◆ 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 6082 of file bmesh_bevel.c.

References BLI_array_append, BLI_array_clear, BLI_array_free, BLI_array_len, BLI_array_staticdeclare, BLI_assert, bm, BM_BEVEL_EDGE_TAG_DISABLE, BM_BEVEL_EDGE_TAG_ENABLE, BM_BEVEL_EDGE_TAG_TEST, BM_DEFAULT_NGON_STACK_SIZE, BM_ITER_ELEM, BM_LOOPS_OF_EDGE, BMLoop::e, EdgeHalf::e, BevVert::edgecount, BevVert::edges, edges_face_connected_at_vert(), if(), l, BMLoop::next, NULL, BMLoop::prev, BMLoop::v, and BevVert::v.

Referenced by find_bevel_edge_order().

◆ bevel_edges_sharp_boundary()

static void bevel_edges_sharp_boundary ( BMesh bm,
BevelParams bp 
)
static

◆ bevel_extend_edge_data()

static void bevel_extend_edge_data ( BevVert bv)
static

◆ bevel_harden_normals()

static void bevel_harden_normals ( BevelParams bp,
BMesh bm 
)
static

◆ 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 7647 of file bmesh_bevel.c.

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(), 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()

static void bevel_reattach_wires ( BMesh bm,
BevelParams bp,
BMVert v 
)
static

◆ bevel_rebuild_existing_polygons()

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

◆ bevel_set_weighted_normal_face_strength()

static void bevel_set_weighted_normal_face_strength ( BMesh bm,
BevelParams bp 
)
static

◆ bevel_vert_construct()

static BevVert* bevel_vert_construct ( BMesh bm,
BevelParams bp,
BMVert v 
)
static

◆ bevel_vert_two_edges()

static void bevel_vert_two_edges ( BevelParams bp,
BMesh bm,
BevVert bv 
)
static

◆ 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 struct 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,
float  smoothresh,
const struct CurveProfile custom_profile,
int  vmesh_method 
)
  • 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 7704 of file bmesh_bevel.c.

References adjust_offsets(), BevelParams::affect_type, 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(), bm, BevelParams::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, BevelParams::face_hash, BevelParams::face_strength_mode, find_bevvert(), find_profile_fullness(), ProfileSpacing::fullness, get_face_kind(), GHASH_FLAG_ALLOW_DUPES, BevelParams::harden_normals, l, logf, math_layer_info_init(), max_ii(), BevelParams::mem_arena, MEM_SIZE_OPTIMAL, BevelParams::miter_inner, BevelParams::miter_outer, NULL, offset, BevelParams::offset, BevelParams::offset_adjust, PIL_check_seconds_timer(), PRO_CIRCLE_R, PRO_LINE_R, BevelParams::pro_spacing, BevelParams::pro_spacing_miter, PRO_SQUARE_IN_R, PRO_SQUARE_R, BevelParams::pro_super_r, BevelParams::profile_type, regularize_profile_orientation(), BevelParams::seg, set_profile_spacing(), sqrtf, BMesh::use_toolflags, v, BevelParams::vert_hash, VERT_OUT, and BevelParams::vmesh_method.

Referenced by bmo_bevel_exec(), and modifyMesh().

◆ 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-NULL and there is another, different, possible frep, return the other one in that parameter.

Definition at line 599 of file bmesh_bevel.c.

References NULL, and 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 2977 of file bmesh_bevel.c.

References add_new_bound_vert(), adjust_bound_vert(), BevelParams::affect_type, ANGLE_LARGER, ANGLE_SMALLER, BEVEL_AFFECT_VERTICES, BEVEL_MITER_PATCH, BEVEL_MITER_SHARP, BLI_assert, build_boundary_terminal_edge(), build_boundary_vertex_only(), copy_v3_v3(), e, BoundVert::ebev, BevVert::edgecount, edges_angle_kind(), BoundVert::efirst, eh_on_plane(), BoundVert::elast, BoundVert::eon, good_offset_on_edge_between(), EdgeHalf::is_bev, EdgeHalf::leftv, BevelParams::loop_slide, BevelParams::mem_arena, mem_arena, BevelParams::miter_inner, BevelParams::miter_outer, EdgeHalf::next, next_bev(), NULL, offset_meet(), offset_on_edge_between(), r, BevelParams::seg, BevVert::selcount, v, BevVert::v, v1, v2, and BevVert::vmesh.

Referenced by adjust_offsets(), and BM_mesh_bevel().

◆ build_boundary_terminal_edge()

static void build_boundary_terminal_edge ( BevelParams bp,
BevVert bv,
EdgeHalf efirst,
const bool  construct 
)
static

◆ build_boundary_vertex_only()

static void build_boundary_vertex_only ( BevelParams bp,
BevVert bv,
bool  construct 
)
static

◆ build_center_ngon()

static void build_center_ngon ( BevelParams bp,
BMesh bm,
BevVert bv,
int  mat_nr 
)
static

◆ 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 4955 of file bmesh_bevel.c.

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

Referenced by bevel_build_rings().

◆ build_vmesh()

static void build_vmesh ( BevelParams bp,
BMesh bm,
BevVert bv 
)
static

◆ 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 2132 of file bmesh_bevel.c.

References BEVEL_PROFILE_SUPERELLIPSE, BEVEL_VMESH_CUTOFF, BLI_memarena_alloc(), calculate_profile_segments(), Profile::end, Profile::height, if(), len_v3v3(), make_unit_square_map(), map, BevelParams::mem_arena, Profile::middle, mul_v3_m4v3(), NULL, 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 2075 of file bmesh_bevel.c.

References add_v3_v3v3(), copy_v3_v3(), Profile::end, float(), interp_v3_v3v3(), is_zero_v3(), isect_line_plane_v3(), map, mul_v3_m4v3(), Profile::plane_co, Profile::plane_no, Profile::proj_dir, and Profile::start.

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 2686 of file bmesh_bevel.c.

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,
bool  neg 
)
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 937 of file bmesh_bevel.c.

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, NULL, 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 4988 of file bmesh_bevel.c.

References Freestyle::a, usdtokens::b(), copy_v3_v3(), len_squared_v3v3(), r, 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 498 of file bmesh_bevel.c.

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 2653 of file bmesh_bevel.c.

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 562 of file bmesh_bevel.c.

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()

static VMesh* cubic_subdiv ( BevelParams bp,
VMesh vm_in 
)
static

◆ disable_flag_out_edge()

static void disable_flag_out_edge ( BMesh bm,
BMEdge bme 
)
static

Definition at line 400 of file bmesh_bevel.c.

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 6059 of file bmesh_bevel.c.

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

Referenced by bevel_vert_construct().

◆ edges_angle_kind()

static AngleKind edges_angle_kind ( EdgeHalf e1,
EdgeHalf e2,
BMVert v 
)
static

◆ edges_face_connected_at_vert()

static bool edges_face_connected_at_vert ( BMEdge bme1,
BMEdge bme2 
)
static

Definition at line 580 of file bmesh_bevel.c.

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 2669 of file bmesh_bevel.c.

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

Referenced by build_boundary().

◆ fast_bevel_edge_order()

static bool fast_bevel_edge_order ( BevVert bv)
static

◆ 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 3973 of file bmesh_bevel.c.

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

Referenced by interp_vmesh().

◆ find_bevel_edge_order()

static void find_bevel_edge_order ( BMesh bm,
BevVert bv,
BMEdge first_bme 
)
static

◆ find_bevvert()

static BevVert* find_bevvert ( BevelParams bp,
BMVert bmv 
)
static

◆ 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 7286 of file bmesh_bevel.c.

References KDL::cos(), double(), find_even_superellipse_chords_general(), M_PI_2, M_SQRT2, PRO_CIRCLE_R, PRO_LINE_R, PRO_SQUARE_IN_R, PRO_SQUARE_R, r, and KDL::sin().

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 7186 of file bmesh_bevel.c.

References e, find_superellipse_chord_endpoint(), M_SQRT2, pow(), r, 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.c.

References BLI_assert, BM_face_point_inside_test(), VMesh::boundstart, BMVert::co, NULL, 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 NULL.

Definition at line 528 of file bmesh_bevel.c.

References BLI_assert, BMVert::e, e, find_bevvert(), find_edge_half(), NULL, 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 7362 of file bmesh_bevel.c.

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 7118 of file bmesh_bevel.c.

References e, fabs(), M_SQRT2, pow(), r, 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 393 of file bmesh_bevel.c.

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.c.

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, NULL, 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 7509 of file bmesh_bevel.c.

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, usdtokens::g(), EdgeHalf::is_bev, EdgeHalf::is_rev, BMLoop::next, EdgeHalf::next, NULL, BevelParams::offset, EdgeHalf::offset_l_spec, EdgeHalf::offset_r_spec, BevelParams::offset_type, BMLoop::prev, EdgeHalf::prev, sinf, t, tanf, BMLoop::v, BevVert::v, BMEdge::v1, and BMEdge::v2.

Referenced by bevel_limit_offset().

◆ get_face_kind()

static FKind get_face_kind ( BevelParams bp,
BMFace f 
)
static

◆ 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.c.

References BM_EDGES_OF_FACE, BM_ITER_ELEM, e, NULL, 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 2046 of file bmesh_bevel.c.

References BLI_assert, copy_v3_v3(), Profile::end, is_power_of_2_i(), NULL, 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 1569 of file bmesh_bevel.c.

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 4019 of file bmesh_bevel.c.

References CCL_NAMESPACE_BEGIN::frac().

Referenced by interp_vmesh().

◆ interp_vmesh()

static VMesh* interp_vmesh ( BevelParams bp,
VMesh vm_in,
int  nseg 
)
static

◆ 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.c.

References blender::compositor::area(), BEVEL_EPSILON_BIG, BLI_assert, NULL, 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()

static VMesh* make_cube_corner_adj_vmesh ( BevelParams bp)
static

◆ 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 4331 of file bmesh_bevel.c.

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

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 1990 of file bmesh_bevel.c.

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 1933 of file bmesh_bevel.c.

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()

static void math_layer_info_init ( BevelParams bp,
BMesh bm 
)
static

◆ mesh_vert()

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

◆ 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 3864 of file bmesh_bevel.c.

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 1823 of file bmesh_bevel.c.

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 1862 of file bmesh_bevel.c.

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 421 of file bmesh_bevel.c.

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 431 of file bmesh_bevel.c.

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

Referenced by edges_angle_kind().

◆ new_adj_vmesh()

static VMesh* new_adj_vmesh ( MemArena mem_arena,
int  count,
int  seg,
BoundVert bounds 
)
static

◆ next_bev()

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

Definition at line 547 of file bmesh_bevel.c.

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

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 3396 of file bmesh_bevel.c.

References BEVEL_SMALL_ANG_DOT, BMVert::co, compare_ff(), dot_v3v3(), EdgeHalf::e, find_other_end_edge_half(), blender::nodes::node_geo_extrude_mesh_cc::new_edge(), EdgeHalf::next, normalize_v3(), NULL, sub_v3_v3v3(), BMEdge::v1, MEdge::v1, BMEdge::v2, and MEdge::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 NULL) 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 1318 of file bmesh_bevel.c.

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, BMVert::no, BMFace::no, normalize_v3(), NULL, 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 1519 of file bmesh_bevel.c.

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()

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

◆ 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 1585 of file bmesh_bevel.c.

References BEVEL_AMT_ABSOLUTE, BEVEL_AMT_PERCENT, BLI_assert, BevelParams::bm, BM_edge_other_vert(), BM_elem_float_data_get(), CD_BWEIGHT, BMVert::co, copy_v3_v3(), EdgeHalf::e, BMesh::edata, 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.c.

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 3801 of file bmesh_bevel.c.

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, BMVert::no, normalize_v3(), NULL, BevVert::selcount, sub_v3_v3v3(), BevVert::v, v1, 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 1681 of file bmesh_bevel.c.

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.c.

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

Referenced by is_bad_uv_poly().

◆ record_face_kind()

static void record_face_kind ( BevelParams bp,
BMFace f,
FKind  fkind 
)
static

◆ 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 3481 of file bmesh_bevel.c.

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 3942 of file bmesh_bevel.c.

References KDL::cos(), M_PI, M_SQRT3, pow(), sqrt(), x, 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()

static void set_profile_params ( BevelParams bp,
BevVert bv,
BoundVert bndv 
)
static

◆ 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 7423 of file bmesh_bevel.c.

References BKE_curveprofile_init(), BLI_memarena_alloc(), BevelParams::custom_profile, double(), find_even_superellipse_chords(), max_ii(), BevelParams::mem_arena, NULL, 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()

static void slide_dist ( EdgeHalf e,
BMVert v,
float  d,
float  r_slideco[3] 
)
static

◆ 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 5237 of file bmesh_bevel.c.

References NULL.

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 NULL (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 bools 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 5282 of file bmesh_bevel.c.

References BLI_assert, NULL, 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.c.

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 2195 of file bmesh_bevel.c.

References Freestyle::a, usdtokens::b(), BEVEL_EPSILON, BLI_assert, Freestyle::c, ELEM, fabsf, max_ff(), min_ff(), normalize_v3(), powf, PRO_CIRCLE_R, PRO_SQUARE_IN_R, PRO_SQUARE_R, 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 5010 of file bmesh_bevel.c.

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 2025 of file bmesh_bevel.c.

References BLI_assert, pow(), r, and x.

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 787 of file bmesh_bevel.c.

Referenced by math_layer_info_init().

◆ tri_corner_adj_vmesh()

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

◆ tri_corner_test()

static int tri_corner_test ( BevelParams bp,
BevVert bv 
)
static

◆ 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 7625 of file bmesh_bevel.c.

References BM_edge_calc_length(), EdgeHalf::e, find_other_end_edge_half(), NULL, 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 3916 of file bmesh_bevel.c.

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()

static void vmesh_copy_equiv_verts ( VMesh vm)
static

◆ 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 6908 of file bmesh_bevel.c.

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(), NULL, and v.

Referenced by bevel_build_edge_polygons().