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:
authorCampbell Barton <ideasman42@gmail.com>2015-05-22 03:56:54 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-05-22 04:00:14 +0300
commit476feb622cd440e378533eddb063e00dc4e2a906 (patch)
tree254627fcc5ee2a1e533e04552de08e2c5be8720b /source/blender/bmesh/operators/bmo_extrude.c
parenta9347303688336af5c320348a311c76049ba9ca4 (diff)
BMesh: extrude region didnt copy edge flags
Newly created edges around regions wouldn't get the edge flags from surrounding geometry.
Diffstat (limited to 'source/blender/bmesh/operators/bmo_extrude.c')
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index aa92c3054cd..435b9e60949 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -39,6 +39,8 @@
#include "intern/bmesh_operators_private.h" /* own include */
+#define USE_EDGE_REGION_FLAGS
+
enum {
EXT_INPUT = 1,
EXT_KEEP = 2,
@@ -287,6 +289,39 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EXT_KEEP);
}
+#ifdef USE_EDGE_REGION_FLAGS
+/**
+ * When create an edge for an extruded face region
+ * check surrounding edge flags before creating a new edge.
+ */
+static bool bm_extrude_region_edge_flag(const BMVert *v, char r_e_hflag[2])
+{
+ BMEdge *e_iter;
+ const char hflag_enable = BM_ELEM_SEAM;
+ const char hflag_disable = BM_ELEM_SMOOTH;
+ bool ok = false;
+
+ r_e_hflag[0] = 0x0;
+ r_e_hflag[1] = 0xff;
+
+ /* clear flags on both disks */
+ e_iter = v->e;
+ do {
+ if (e_iter->l && !BM_edge_is_boundary(e_iter)) {
+ r_e_hflag[0] |= e_iter->head.hflag;
+ r_e_hflag[1] &= e_iter->head.hflag;
+ ok = true;
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != v->e);
+
+ if (ok) {
+ r_e_hflag[0] &= hflag_enable;
+ r_e_hflag[1] = hflag_disable & ~r_e_hflag[1];
+ }
+ return ok;
+}
+#endif /* USE_EDGE_REGION_FLAGS */
+
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
{
BMOperator dupeop, delop;
@@ -413,6 +448,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude");
for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) {
BMVert *f_verts[4];
+#ifdef USE_EDGE_REGION_FLAGS
+ BMEdge *f_edges[4];
+#endif
/* 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(slot_edges_exclude, e)) {
@@ -465,8 +503,38 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
f_verts[3] = e_new->v2;
}
- /* not sure what to do about example face, pass NULL for now */
+#ifdef USE_EDGE_REGION_FLAGS
+ /* handle new edges */
+ f_edges[0] = e;
+ f_edges[2] = e_new;
+
+ f_edges[1] = BM_edge_exists(f_verts[1], f_verts[2]);
+ if (f_edges[1] == NULL) {
+ char e_hflag[2];
+ bool e_hflag_ok = bm_extrude_region_edge_flag(f_verts[2], e_hflag);
+ f_edges[1] = BM_edge_create(bm, f_verts[1], f_verts[2], NULL, BM_CREATE_NOP);
+ if (e_hflag_ok) {
+ BM_elem_flag_enable(f_edges[1], e_hflag[0]);
+ BM_elem_flag_disable(f_edges[1], e_hflag[1]);
+ }
+ }
+
+ f_edges[3] = BM_edge_exists(f_verts[3], f_verts[0]);
+ if (f_edges[3] == NULL) {
+ char e_hflag[2];
+ bool e_hflag_ok = bm_extrude_region_edge_flag(f_verts[3], e_hflag);
+ f_edges[3] = BM_edge_create(bm, f_verts[3], f_verts[0], NULL, BM_CREATE_NOP);
+ if (e_hflag_ok) {
+ BM_elem_flag_enable(f_edges[3], e_hflag[0]);
+ BM_elem_flag_disable(f_edges[3], e_hflag[1]);
+ }
+ }
+
+ f = BM_face_create(bm, f_verts, f_edges, 4, NULL, BM_CREATE_NOP);
+#else
f = BM_face_create_verts(bm, f_verts, 4, NULL, BM_CREATE_NOP, true);
+#endif
+
bm_extrude_copy_face_loop_attributes(bm, f);
}