Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/tools/bmesh_bevel.c')
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c121
1 files changed, 87 insertions, 34 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 34317866b39..2ef93618e2a 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -525,23 +525,28 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v)
BMLoop *l;
float uv[2];
int n;
- int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ int i;
- if (cd_loop_uv_offset == -1)
- return;
+ for (i = 0; i < num_of_uv_layers; i++) {
+ int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i);
- n = 0;
- zero_v2(uv);
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
- n++;
- }
- if (n > 1) {
- mul_v2_fl(uv, 1.0f / (float)n);
+ if (cd_loop_uv_offset == -1)
+ return;
+
+ n = 0;
+ zero_v2(uv);
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uv);
+ add_v2_v2(uv, luv->uv);
+ n++;
+ }
+ if (n > 1) {
+ mul_v2_fl(uv, 1.0f / (float)n);
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ copy_v2_v2(luv->uv, uv);
+ }
}
}
}
@@ -787,7 +792,7 @@ static void offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2,
* be on emid if that does a better job of keeping offsets at the user spec.
* Viewed from the vertex normal side, the CCW order of the edges is e1, emid, e2.
* The offset lines may not meet exactly: the lines may be angled so that they can't meet.
- * In that case, pick the the offset_on_edge_between. */
+ * In that case, pick the offset_on_edge_between. */
static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
BMVert *v, float meetco[3])
{
@@ -1387,7 +1392,7 @@ static void set_bound_vert_seams(BevVert *bv)
}
/* Make a circular list of BoundVerts for bv, each of which has the coordinates
- * of a vertex on the the boundary of the beveled vertex bv->v.
+ * 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.
* The first time through, construct will be true and we are making the BoundVerts
@@ -1474,7 +1479,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
return;
}
- lastd = bp->vertex_only ? bv->offset : e->offset_l;
+ lastd = e->offset_l;
do {
if (e->is_bev) {
/* handle only left side of beveled edge e here: next iteration should do right side */
@@ -1557,9 +1562,10 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
/* None of e->prev, e, e->next are beveled.
* could either leave alone or add slide points to make
* one polygon around bv->v. For now, we choose latter.
+ * For vertex bevel, we use e->offset_l as slide distance.
* Could slide to make an even bevel plane but for now will
* just use last distance a meet point moved from bv->v. */
- slide_dist(e, bv->v, lastd, co);
+ slide_dist(e, bv->v, bp->vertex_only ? e->offset_l : lastd, co);
if (construct) {
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = v->elast = e;
@@ -2229,7 +2235,6 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
BoundVert *bndv;
int i, j, k, ns2;
float co[3], coc[3];
- float w;
if (r == PRO_SQUARE_R)
return make_cube_corner_straight(mem_arena, nseg);
@@ -2262,10 +2267,8 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
bndv = bndv->next;
}
/* center vertex */
- w = (float)(1.0 / M_SQRT3);
- co[0] = w;
- co[1] = w;
- co[2] = w;
+ copy_v3_fl(co, M_SQRT1_3);
+
if (nseg > 2) {
if (r > 1.5f)
mul_v3_fl(co, 1.4f);
@@ -2712,23 +2715,60 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv)
}
}
-/* Special case: there is no vmesh pattern because this has only two boundary verts,
- * and there are no faces in the original mesh at the original vertex.
- * Since there will be no rebuilt face to make the edge between the boundary verts,
+/* Special case: vertex bevel with only two boundary verts.
+ * Want to make a curved edge if seg > 0.
+ * If there are no faces in the original mesh at the original vertex,
+ * there will be no rebuilt face to make the edge between the boundary verts,
* we have to make it here. */
-static void bevel_build_one_wire(BMesh *bm, BevVert *bv)
+static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
{
VMesh *vm = bv->vmesh;
BMVert *v1, *v2;
BMEdge *e_eg;
+ Profile *pro;
+ float co[3];
+ BoundVert *bndv;
+ int ns, k;
- BLI_assert(vm->count == 2);
+ BLI_assert(vm->count == 2 && bp->vertex_only);
v1 = mesh_vert(vm, 0, 0, 0)->v;
v2 = mesh_vert(vm, 1, 0, 0)->v;
- e_eg = bv->edges[0].e;
- BLI_assert(v1 != NULL && v2 != NULL && e_eg != NULL);
- BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+
+ ns = vm->seg;
+ if (ns > 1) {
+ /* Set up profile parameters */
+ bndv = vm->boundstart;
+ pro = &bndv->profile;
+ pro->super_r = bp->pro_super_r;
+ copy_v3_v3(pro->coa, v1->co);
+ copy_v3_v3(pro->cob, v2->co);
+ copy_v3_v3(pro->midco, bv->v->co);
+ /* don't use projection */
+ zero_v3(pro->plane_co);
+ zero_v3(pro->plane_no);
+ zero_v3(pro->proj_dir);
+ calculate_profile(bp, bndv);
+ for (k = 1; k < ns; k++) {
+ get_profile_point(bp, pro, k, ns, co);
+ copy_v3_v3(mesh_vert(vm, 0, 0, k)->co, co);
+ create_mesh_bmvert(bm, vm, 0, 0, k, bv->v);
+ }
+ copy_v3_v3(mesh_vert(vm, 0, 0, ns)->co, v2->co);
+ for (k = 1; k < ns; k++)
+ copy_mesh_vert(vm, 1, 0, ns - k, 0, 0, k);
+ }
+
+ if (BM_vert_face_count(bv->v) == 0) {
+ e_eg = bv->edges[0].e;
+ BLI_assert(e_eg != NULL);
+ for (k = 0; k < ns; k++) {
+ v1 = mesh_vert(vm, 0, 0, k)->v;
+ v2 = mesh_vert(vm, 0, 0, k + 1)->v;
+ BLI_assert(v1 != NULL && v2 != NULL);
+ BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+ }
+ }
}
/* Given that the boundary is built, now make the actual BMVerts
@@ -2814,8 +2854,8 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
switch (vm->mesh_kind) {
case M_NONE:
- if (n == 2 && BM_vert_face_count(bv->v) == 0)
- bevel_build_one_wire(bm, bv);
+ if (n == 2 && bp->vertex_only)
+ bevel_vert_two_edges(bp, bm, bv);
break;
case M_POLY:
bevel_build_poly(bp, bm, bv);
@@ -2898,8 +2938,9 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
nwire++;
/* If edge beveling, exclude wire edges from edges array.
* Mark this edge as "chosen" so loop below won't choose it. */
- if (!bp->vertex_only)
+ if (!bp->vertex_only) {
BM_BEVEL_EDGE_TAG_ENABLE(bme);
+ }
}
}
if (!first_bme)
@@ -3081,6 +3122,18 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
e->offset_r_spec *= weight;
}
}
+ else if (bp->vertex_only) {
+ /* Weight has already been applied to bv->offset, if present.
+ * Transfer to e->offset_[lr]_spec and treat percent as special case */
+ if (bp->offset_type == BEVEL_AMT_PERCENT) {
+ v2 = BM_edge_other_vert(e->e, bv->v);
+ e->offset_l_spec = BM_edge_calc_length(e->e) * bv->offset / 100.0f;
+ }
+ else {
+ e->offset_l_spec = bv->offset;
+ }
+ e->offset_r_spec = e->offset_l_spec;
+ }
else {
e->offset_l_spec = e->offset_r_spec = 0.0f;
}
@@ -3159,7 +3212,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BLI_array_append(vv_fix, bmv);
}
}
- else if (vm->mesh_kind == M_ADJ && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
+ else if ((vm->mesh_kind == M_ADJ || bp->vertex_only) && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
BLI_assert(v->prev == vend);
i = vend->index;
for (k = vm->seg - 1; k > 0; k--) {