Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/tools/bmesh_bevel.c
| Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| #define BEVEL_EPSILON 1e-6f | #define BEVEL_EPSILON 1e-6f | ||||
| #define BEVEL_EPSILON_SQ 1e-12f | #define BEVEL_EPSILON_SQ 1e-12f | ||||
| #define BEVEL_EPSILON_BIG 1e-4f | #define BEVEL_EPSILON_BIG 1e-4f | ||||
| #define BEVEL_EPSILON_BIG_SQ 1e-8f | #define BEVEL_EPSILON_BIG_SQ 1e-8f | ||||
| #define BEVEL_EPSILON_ANG DEG2RADF(2.0f) | #define BEVEL_EPSILON_ANG DEG2RADF(2.0f) | ||||
| #define BEVEL_SMALL_ANG DEG2RADF(10.0f) | #define BEVEL_SMALL_ANG DEG2RADF(10.0f) | ||||
| /** Difference in dot products that corresponds to 10 degree difference between vectors. */ | /** Difference in dot products that corresponds to 10 degree difference between vectors. */ | ||||
| #define BEVEL_SMALL_ANG_DOT 1 - cosf(BEVEL_SMALL_ANG) | #define BEVEL_SMALL_ANG_DOT 1 - cosf(BEVEL_SMALL_ANG) | ||||
| /** Difference in dot products that corresponds to 2.0 degree difference between vectors. */ | |||||
| #define BEVEL_EPSILON_ANG_DOT 1 - cosf(BEVEL_EPSILON_ANG) | |||||
| #define BEVEL_MAX_ADJUST_PCT 10.0f | #define BEVEL_MAX_ADJUST_PCT 10.0f | ||||
| #define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f | #define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f | ||||
| #define BEVEL_MATCH_SPEC_WEIGHT 0.2 | #define BEVEL_MATCH_SPEC_WEIGHT 0.2 | ||||
| //#define DEBUG_CUSTOM_PROFILE_CUTOFF | //#define DEBUG_CUSTOM_PROFILE_CUTOFF | ||||
| /* Happens far too often, uncomment for development. */ | /* Happens far too often, uncomment for development. */ | ||||
| // #define BEVEL_ASSERT_PROJECT | // #define BEVEL_ASSERT_PROJECT | ||||
| ▲ Show 20 Lines • Show All 357 Lines • ▼ Show 20 Lines | |||||
| /* Are d1 and d2 parallel or nearly so? */ | /* Are d1 and d2 parallel or nearly so? */ | ||||
| static bool nearly_parallel(const float d1[3], const float d2[3]) | static bool nearly_parallel(const float d1[3], const float d2[3]) | ||||
| { | { | ||||
| float ang = angle_v3v3(d1, d2); | float ang = angle_v3v3(d1, d2); | ||||
| return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_ANG); | return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - (float)M_PI) < BEVEL_EPSILON_ANG); | ||||
| } | } | ||||
| static bool nearly_parallel_normalized(const float d1[3], const float d2[3]) | |||||
| { | |||||
| BLI_ASSERT_UNIT_V3(d1); | |||||
| BLI_ASSERT_UNIT_V3(d2); | |||||
| const float direction_dot = dot_v3v3(d1, d2); | |||||
| return compare_ff(fabsf(direction_dot), 1.0f, BEVEL_EPSILON_ANG_DOT); | |||||
| } | |||||
| /* Make a new BoundVert of the given kind, inserting it at the end of the circular linked | /* Make a new BoundVert of the given kind, inserting it at the end of the circular linked | ||||
| * list with entry point bv->boundstart, and return it. */ | * list with entry point bv->boundstart, and return it. */ | ||||
| static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) | static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) | ||||
| { | { | ||||
| BoundVert *ans = (BoundVert *)BLI_memarena_alloc(mem_arena, sizeof(BoundVert)); | BoundVert *ans = (BoundVert *)BLI_memarena_alloc(mem_arena, sizeof(BoundVert)); | ||||
| copy_v3_v3(ans->nv.co, co); | copy_v3_v3(ans->nv.co, co); | ||||
| if (!vm->boundstart) { | if (!vm->boundstart) { | ||||
| ▲ Show 20 Lines • Show All 648 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| BMVert *v1 = BM_edge_other_vert(e1->e, v); | BMVert *v1 = BM_edge_other_vert(e1->e, v); | ||||
| BMVert *v2 = BM_edge_other_vert(e2->e, v); | BMVert *v2 = BM_edge_other_vert(e2->e, v); | ||||
| float dir1[3], dir2[3]; | float dir1[3], dir2[3]; | ||||
| sub_v3_v3v3(dir1, v->co, v1->co); | sub_v3_v3v3(dir1, v->co, v1->co); | ||||
| sub_v3_v3v3(dir2, v->co, v2->co); | sub_v3_v3v3(dir2, v->co, v2->co); | ||||
| normalize_v3(dir1); | normalize_v3(dir1); | ||||
| normalize_v3(dir2); | normalize_v3(dir2); | ||||
| /* First check for in-line edges using a simpler test. */ | |||||
| if (nearly_parallel_normalized(dir1, dir2)) { | |||||
| return ANGLE_STRAIGHT; | |||||
| } | |||||
| /* Angles are in [0,pi]. Need to compare cross product with normal to see if they are reflex. */ | /* Angles are in [0,pi]. Need to compare cross product with normal to see if they are reflex. */ | ||||
| float cross[3]; | float cross[3]; | ||||
| cross_v3_v3v3(cross, dir1, dir2); | cross_v3_v3v3(cross, dir1, dir2); | ||||
| normalize_v3(cross); | normalize_v3(cross); | ||||
| float *no; | float *no; | ||||
| if (e1->fnext) { | if (e1->fnext) { | ||||
| no = e1->fnext->no; | no = e1->fnext->no; | ||||
| } | } | ||||
| else if (e2->fprev) { | else if (e2->fprev) { | ||||
| no = e2->fprev->no; | no = e2->fprev->no; | ||||
| } | } | ||||
| else { | else { | ||||
| no = v->no; | no = v->no; | ||||
| } | } | ||||
| float dot = dot_v3v3(cross, no); | |||||
| if (fabsf(dot) < BEVEL_EPSILON_BIG) { | if (dot_v3v3(cross, no) < 0.0f) { | ||||
| return ANGLE_STRAIGHT; | |||||
| } | |||||
| if (dot < 0.0f) { | |||||
| return ANGLE_LARGER; | return ANGLE_LARGER; | ||||
| } | } | ||||
| return ANGLE_SMALLER; | return ANGLE_SMALLER; | ||||
| } | } | ||||
| /* co should be approximately on the plane between e1 and e2, which share common vert v and common | /* co should be approximately on the plane between e1 and e2, which share common vert v and common | ||||
| * face f (which cannot be NULL). Is it between those edges, sweeping CCW? */ | * face f (which cannot be NULL). Is it between those edges, sweeping CCW? */ | ||||
| static bool point_between_edges( | static bool point_between_edges( | ||||
| ▲ Show 20 Lines • Show All 6,508 Lines • Show Last 20 Lines | |||||