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/operators/bmo_extrude.c')
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c123
1 files changed, 57 insertions, 66 deletions
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 81cad277bee..627351ead11 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -88,7 +88,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, FALSE);
if (UNLIKELY(f2 == NULL)) {
- BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed; could not create face");
+ BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face");
BLI_array_free(edges);
return;
}
@@ -132,46 +132,36 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
* This function won't crash if its not but won't work right either.
* \a e_b is the new edge.
*
- * \note this function could be exposed as an api call if other areas need it,
- * so far only extrude does.
+ * \note The edge this face comes from needs to be from the first and second verts fo the face.
+ * The caller must ensure this else we will copy from the wrong source.
*/
-static void bm_extrude_copy_face_loop_attributes(BMesh *bm, BMFace *f, BMEdge *e_a, BMEdge *e_b)
+static void bm_extrude_copy_face_loop_attributes(BMesh *bm, BMFace *f)
{
- /* 'a' is the starting edge #e, 'b' is the final edge #newedge */
- BMLoop *l_dst_a = BM_face_edge_share_loop(f, e_a);
- BMLoop *l_dst_b = BM_face_edge_share_loop(f, e_b);
- /* we could only have a face on one-or the other edges,
- * check if either side of the face has an adjacent face */
- BMLoop *l_src_1;
- BMLoop *l_src_2;
-
- /* there is no l_src_b */
-
- /* sanity */
- BLI_assert(l_dst_a->f == l_dst_b->f);
-
- if (l_dst_a != l_dst_a->radial_next) {
- l_src_1 = l_dst_a->radial_next;
- l_src_2 = l_src_1->next;
- }
- else if (l_dst_b != l_dst_b->radial_next) {
- l_src_2 = l_dst_b->radial_next;
- l_src_1 = l_src_2->next;
- }
- else {
- /* no new faces on either edge, nothing to copy from */
+ /* edge we are extruded from */
+ BMLoop *l_first_0 = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_first_1 = l_first_0->next;
+ BMLoop *l_first_2 = l_first_1->next;
+ BMLoop *l_first_3 = l_first_2->next;
+
+ BMLoop *l_other_0;
+ BMLoop *l_other_1;
+
+ if (UNLIKELY(l_first_0 == l_first_0->radial_next)) {
return;
}
- BM_elem_attrs_copy(bm, bm, l_src_1->f, l_dst_a->f);
- BM_elem_flag_disable(f, BM_ELEM_HIDDEN); /* possibly we copy from a hidden face */
+ l_other_0 = BM_edge_other_loop(l_first_0->e, l_first_0);
+ l_other_1 = BM_edge_other_loop(l_first_0->e, l_first_1);
/* copy data */
- BM_elem_attrs_copy(bm, bm, l_src_2, l_dst_a);
- BM_elem_attrs_copy(bm, bm, l_src_2, l_dst_b->next);
+ BM_elem_attrs_copy(bm, bm, l_other_0->f, f);
+ BM_elem_flag_disable(f, BM_ELEM_HIDDEN); /* possibly we copy from a hidden face */
- BM_elem_attrs_copy(bm, bm, l_src_1, l_dst_a->next);
- BM_elem_attrs_copy(bm, bm, l_src_1, l_dst_b);
+ BM_elem_attrs_copy(bm, bm, l_other_0, l_first_0);
+ BM_elem_attrs_copy(bm, bm, l_other_0, l_first_3);
+
+ BM_elem_attrs_copy(bm, bm, l_other_1, l_first_1);
+ BM_elem_attrs_copy(bm, bm, l_other_1, l_first_2);
}
/* Disable the skin root flag on the input vert, assumes that the vert
@@ -188,9 +178,8 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMOperator dupeop;
- BMVert *v1, *v2, *v3, *v4;
- BMEdge *e, *e2;
BMFace *f;
+ BMEdge *e, *e_new;
BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) {
BMO_elem_flag_enable(bm, e, EXT_INPUT);
@@ -203,33 +192,34 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
/* disable root flag on all new skin nodes */
if (CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
- BMO_ITER(v1, &siter, bm, &dupeop, "newout", BM_VERT) {
- bm_extrude_disable_skin_root(bm, v1);
+ BMVert *v;
+ BMO_ITER(v, &siter, bm, &dupeop, "newout", BM_VERT) {
+ bm_extrude_disable_skin_root(bm, v);
}
}
for (e = BMO_iter_new(&siter, bm, &dupeop, "boundarymap", 0); e; e = BMO_iter_step(&siter)) {
- e2 = BMO_iter_map_value(&siter);
- e2 = *(BMEdge **)e2;
+ BMVert *f_verts[4];
+ e_new = *(BMEdge **)BMO_iter_map_value(&siter);
if (e->l && e->v1 != e->l->v) {
- v1 = e->v1;
- v2 = e->v2;
- v3 = e2->v2;
- v4 = e2->v1;
+ f_verts[0] = e->v1;
+ f_verts[1] = e->v2;
+ f_verts[2] = e_new->v2;
+ f_verts[3] = e_new->v1;
}
else {
- v1 = e2->v1;
- v2 = e2->v2;
- v3 = e->v2;
- v4 = e->v1;
+ f_verts[0] = e->v2;
+ f_verts[1] = e->v1;
+ f_verts[2] = e_new->v1;
+ f_verts[3] = e_new->v2;
}
/* not sure what to do about example face, pass NULL for now */
- f = BM_face_create_quad_tri(bm, v1, v2, v3, v4, NULL, FALSE);
- bm_extrude_copy_face_loop_attributes(bm, f, e, e2);
+ f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, FALSE);
+ bm_extrude_copy_face_loop_attributes(bm, f);
if (BMO_elem_flag_test(bm, e, EXT_INPUT))
- e = e2;
+ e = e_new;
BMO_elem_flag_enable(bm, f, EXT_KEEP);
BMO_elem_flag_enable(bm, e, EXT_KEEP);
@@ -270,8 +260,8 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMOperator dupeop, delop;
BMOIter siter;
BMIter iter, fiter, viter;
- BMEdge *e, *newedge;
- BMVert *verts[4], *v, *v2;
+ BMEdge *e, *e_new;
+ BMVert *v, *v2;
BMFace *f;
int found, fwd, delorig = FALSE;
@@ -378,6 +368,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMO_slot_copy(&dupeop, op, "newout", "geomout");
for (e = BMO_iter_new(&siter, bm, &dupeop, "boundarymap", 0); e; e = BMO_iter_step(&siter)) {
+ BMVert *f_verts[4];
/* this should always be wire, so this is mainly a speedup to avoid map lookup */
if (BM_edge_is_wire(e) && BMO_slot_map_contains(bm, op, "exclude", e)) {
@@ -396,37 +387,37 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
continue;
}
- newedge = *(BMEdge **)BMO_iter_map_value(&siter);
+ e_new = *(BMEdge **)BMO_iter_map_value(&siter);
- if (!newedge) {
+ if (!e_new) {
continue;
}
/* orient loop to give same normal as a loop of newedge
* if it exists (will be an extruded face),
* else same normal as a loop of e, if it exists */
- if (!newedge->l)
+ if (!e_new->l)
fwd = !e->l || !(e->l->v == e->v1);
else
- fwd = (newedge->l->v == newedge->v1);
+ fwd = (e_new->l->v == e_new->v1);
if (fwd) {
- verts[0] = e->v1;
- verts[1] = e->v2;
- verts[2] = newedge->v2;
- verts[3] = newedge->v1;
+ f_verts[0] = e->v1;
+ f_verts[1] = e->v2;
+ f_verts[2] = e_new->v2;
+ f_verts[3] = e_new->v1;
}
else {
- verts[3] = e->v1;
- verts[2] = e->v2;
- verts[1] = newedge->v2;
- verts[0] = newedge->v1;
+ f_verts[0] = e->v2;
+ f_verts[1] = e->v1;
+ f_verts[2] = e_new->v1;
+ f_verts[3] = e_new->v2;
}
/* not sure what to do about example face, pass NULL for now */
- f = BM_face_create_quad_tri_v(bm, verts, 4, NULL, FALSE);
- bm_extrude_copy_face_loop_attributes(bm, f, e, newedge);
+ f = BM_face_create_quad_tri_v(bm, f_verts, 4, NULL, FALSE);
+ bm_extrude_copy_face_loop_attributes(bm, f);
}
/* link isolated vert */