Page MenuHome
Paste P1037

Draft of Cutoff vertex mesh method
ActivePublic

Authored by Hans Goudey (HooglyBoogly) on Jul 16 2019, 5:24 PM.
/** Builds the vertex mesh when the vertex mesh type is set to "cut off" with a face closing
* off each incoming edge's profile */
static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
{
int i;
int n_bndv = bv->selcount;
BoundVert *bndv;
float down_direction_avg[3], down_direction[3], prof_len_direction[3], prof_height[3], down_distance[3];
float profile_height, *corner_vertices, last_down_direction[3];
bool build_center_face;
BMVert *bmvert = NULL;
BMEdge **bmedge = NULL;
BMFace **bmface = NULL;
BMFace *repface;
/* Find the locations for the corner vertices at the bottom of the cutoff faces */
corner_vertices = BLI_memarena_alloc(bp->mem_arena, (size_t)(n_bndv * 3));
bndv = bv->vmesh->boundstart;
for (i = 0; i < n_bndv; i++) {
/* Find the direction for the edges for the corner of the the profile planes which
* should be the average of the "down" directions of the two adjaccent profiles */
sub_v3_v3v3(prof_len_direction, bndv->profile.coa, bndv->profile.cob);
/* Cross between the profile plane's normal and the length along the profile is "downward" */
cross_v3_v3v3(down_direction, bndv->profile.plane_no, prof_len_direction);
normalize_v3(down_direction);
mul_v3_fl(down_direction, 0.5f);
copy_v3_v3(down_direction_avg, down_direction);
copy_v3_v3(last_down_direction, down_direction);
/* Reuse the down direction from the previous profile */
if (i != 0) {
add_v3_v3(down_direction_avg, last_down_direction);
}
else {
sub_v3_v3v3(prof_len_direction, bndv->prev->profile.coa, bndv->prev->profile.cob);
cross_v3_v3v3(down_direction, bndv->prev->profile.plane_no, prof_len_direction);
normalize_v3(down_direction);
mul_v3_fl(down_direction_avg, 0.5f);
add_v3_v3(down_direction_avg, down_direction);
}
/* Move down the direction by the transformed height of the profile */
sub_v3_v3v3(prof_height, bndv->profile.midco, bndv->profile.coa);
profile_height = dot_v3v3(down_direction_avg, prof_height);
mul_v3_v3fl(down_distance, down_direction_avg, profile_height);
add_v3_v3v3(&corner_vertices[3 * i], down_distance, bndv->nv.co);
bndv = bndv->next;
}
/* Check if the corner vertices end up in the same location, disable the center face if so */
build_center_face = true;
/* HANS-TODO: There may be a better way to find this case */
if (n_bndv == 3) {
if (len_squared_v3v3(&corner_vertices[0], &corner_vertices[3]) < BEVEL_EPSILON &&
len_squared_v3v3(&corner_vertices[0], &corner_vertices[6]) < BEVEL_EPSILON &&
len_squared_v3v3(&corner_vertices[3], &corner_vertices[6]) < BEVEL_EPSILON) {
build_center_face = false;
}
}
bmvert = BLI_memarena_alloc(bp->mem_arena,
(size_t)(bp->seg + 1 + build_center_face) * sizeof(BMVert));
bndv = bv->vmesh->boundstart;
for (i = 0; i < n_bndv; i++) {
BLI_array_staticdeclare(bmedge, BM_DEFAULT_NGON_STACK_SIZE);
BLI_array_staticdeclare(bmface, BM_DEFAULT_NGON_STACK_SIZE);
/* HANS-TODO: This is probably not a great place for the memory alloc? */
copy_v3_v3(bmvert[0].co, &corner_vertices[3 * i]);
if (build_center_face) {
/* Add the corner vert from the next boundvert to complete the face */
copy_v3_v3(bmvert[1].co, &corner_vertices[3 * (i + 1)]);
}
/* Get profile points and add them to the array of points for the face */
for (int k = 0; k < bp->seg; k++) {
get_profile_point(bp, &bndv->profile, k, bp->seg, bmvert[k + 1 + build_center_face].co);
}
/* Create the profile cutoff face for this boundvert */
repface = boundvert_rep_face(bndv, NULL);
/* HANS-TODO: Fix material argument */
bev_create_ngon(bm, &bmvert, bp->seg + 1 + build_center_face, bmface, repface, bmedge, 0, true);
BLI_array_free(bmedge);
BLI_array_free(bmface);
bndv = bndv->next;
}
/* Create the bottom face if it should be built */
if (build_center_face) {
bmvert = BLI_memarena_alloc(bp->mem_arena, (size_t)n_bndv * sizeof(BMVert));
BLI_array_staticdeclare(bmedge, BM_DEFAULT_NGON_STACK_SIZE);
BLI_array_staticdeclare(bmface, BM_DEFAULT_NGON_STACK_SIZE);
/* The first coordinates in each face vertices array are the coordinates of the bottom corners */
for (i = 0; i < n_bndv; i++) {
/* Add verts from each cutoff face */
copy_v3_v3(bmvert[i].co, &corner_vertices[i]);
}
/* HANS-TODO: get new rep face and interpolate materials */
bev_create_ngon(bm, &bmvert, n_bndv, bmface, repface, bmedge, 0, true);
BLI_array_free(bmedge);
BLI_array_free(bmface);
}
}

Event Timeline