Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/tools/bmesh_bevel.c
| Show First 20 Lines • Show All 1,514 Lines • ▼ Show 20 Lines | static bool good_offset_on_edge_between(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, BMVert *v) | ||||
| return offset_meet_edge(e1, emid, v, meet, &ang) && offset_meet_edge(emid, e2, v, meet, &ang); | return offset_meet_edge(e1, emid, v, meet, &ang) && offset_meet_edge(emid, e2, v, meet, &ang); | ||||
| } | } | ||||
| /** | /** | ||||
| * Calculate the best place for a meeting point for the offsets from edges e1 and e2 on the | * 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, | * 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, | * 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. | * 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. | |||||
| */ | */ | ||||
| static bool 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) | EdgeHalf *e1, | ||||
| EdgeHalf *e2, | |||||
| EdgeHalf *emid, | |||||
| BMVert *v, | |||||
| float meetco[3], | |||||
| float *r_sinratio) | |||||
| { | { | ||||
| bool retval = false; | bool retval = false; | ||||
| BLI_assert(e1->is_bev && e2->is_bev && !emid->is_bev); | BLI_assert(e1->is_bev && e2->is_bev && !emid->is_bev); | ||||
| float ang1, ang2; | float ang1, ang2; | ||||
| float meet1[3], meet2[3]; | float meet1[3], meet2[3]; | ||||
| bool ok1 = offset_meet_edge(e1, emid, v, meet1, &ang1); | bool ok1 = offset_meet_edge(e1, emid, v, meet1, &ang1); | ||||
| bool ok2 = offset_meet_edge(emid, e2, v, meet2, &ang2); | bool ok2 = offset_meet_edge(emid, e2, v, meet2, &ang2); | ||||
| if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { | |||||
| BMVert *v2 = BM_edge_other_vert(emid->e, v); | |||||
| if (bp->offset_type == BEVEL_AMT_PERCENT) { | |||||
| interp_v3_v3v3(meetco, v->co, v2->co, bp->offset / 100.0f); | |||||
| } | |||||
| else { | |||||
| float dir[3]; | |||||
| sub_v3_v3v3(dir, v2->co, v->co); | |||||
| normalize_v3(dir); | |||||
| madd_v3_v3v3fl(meetco, v->co, dir, bp->offset); | |||||
| } | |||||
| if (r_sinratio) { | |||||
| *r_sinratio = (ang1 == 0.0f) ? 1.0f : sinf(ang2) / sinf(ang1); | |||||
| } | |||||
| return true; | |||||
| } | |||||
HooglyBoogly: I guess it's too bad that we still have to run these functions in this special case just to get… | |||||
| if (ok1 && ok2) { | if (ok1 && ok2) { | ||||
| mid_v3_v3v3(meetco, meet1, meet2); | mid_v3_v3v3(meetco, meet1, meet2); | ||||
| if (r_sinratio) { | if (r_sinratio) { | ||||
| /* ang1 should not be 0, but be paranoid. */ | /* ang1 should not be 0, but be paranoid. */ | ||||
| *r_sinratio = (ang1 == 0.0f) ? 1.0f : sinf(ang2) / sinf(ang1); | *r_sinratio = (ang1 == 0.0f) ? 1.0f : sinf(ang2) / sinf(ang1); | ||||
| } | } | ||||
| retval = true; | retval = true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,405 Lines • ▼ Show 20 Lines | do { | ||||
| } | } | ||||
| float r, co[3]; | float r, co[3]; | ||||
| if (in_plane == 0 && not_in_plane == 0) { | if (in_plane == 0 && not_in_plane == 0) { | ||||
| offset_meet(bp, e, e2, bv->v, e->fnext, false, co, NULL); | offset_meet(bp, e, e2, bv->v, e->fnext, false, co, NULL); | ||||
| } | } | ||||
| else if (not_in_plane > 0) { | else if (not_in_plane > 0) { | ||||
| if (bp->loop_slide && not_in_plane == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) { | if (bp->loop_slide && not_in_plane == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) { | ||||
| if (offset_on_edge_between(e, e2, enip, bv->v, co, &r)) { | if (offset_on_edge_between(bp, e, e2, enip, bv->v, co, &r)) { | ||||
| eon = enip; | eon = enip; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| offset_meet(bp, e, e2, bv->v, NULL, true, co, eip); | offset_meet(bp, e, e2, bv->v, NULL, true, co, eip); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* n_in_plane > 0 and n_not_in_plane == 0. */ | /* n_in_plane > 0 and n_not_in_plane == 0. */ | ||||
| if (bp->loop_slide && in_plane == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) { | if (bp->loop_slide && in_plane == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) { | ||||
| if (offset_on_edge_between(e, e2, eip, bv->v, co, &r)) { | if (offset_on_edge_between(bp, e, e2, eip, bv->v, co, &r)) { | ||||
| eon = eip; | eon = eip; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| offset_meet(bp, e, e2, bv->v, e->fnext, true, co, eip); | offset_meet(bp, e, e2, bv->v, e->fnext, true, co, eip); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 4,214 Lines • ▼ Show 20 Lines | static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb) | ||||
| BevVert *bvc = NULL; | BevVert *bvc = NULL; | ||||
| EdgeHalf *ebother = find_other_end_edge_half(bp, eb, &bvc); | EdgeHalf *ebother = find_other_end_edge_half(bp, eb, &bvc); | ||||
| EdgeHalf *ec; | EdgeHalf *ec; | ||||
| BMVert *vd; | BMVert *vd; | ||||
| float kc; | float kc; | ||||
| if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { | if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { | ||||
| if (ea->is_bev && ebother != NULL && ebother->prev->is_bev) { | if (ea->is_bev && ebother != NULL && ebother->prev->is_bev) { | ||||
| if (bp->offset_type == BEVEL_AMT_PERCENT) { | if (bp->offset_type == BEVEL_AMT_PERCENT) { | ||||
| return bp->offset > 50.0f ? 50.0f : 100.f; | return 50.0f; | ||||
| } | } | ||||
| /* This is only right sometimes. The exact answer is very hard to calculate. */ | /* This is only right sometimes. The exact answer is very hard to calculate. */ | ||||
| float blen = BM_edge_calc_length(eb->e); | float blen = BM_edge_calc_length(eb->e); | ||||
| return bp->offset > blen / 2.0f ? blen / 2.0f : blen; | return bp->offset > blen / 2.0f ? blen / 2.0f : blen; | ||||
| } | } | ||||
| return no_collide_offset; | return no_collide_offset; | ||||
| } | } | ||||
| if (ebother != NULL) { | if (ebother != NULL) { | ||||
| ▲ Show 20 Lines • Show All 404 Lines • Show Last 20 Lines | |||||
I guess it's too bad that we still have to run these functions in this special case just to get the angle. But the logic to get the angle is pretty wrapped up in the other logic of offset_meet_edge, so it's probably not worth changing that.