move edge split into its own function which can be called by the modifier without...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Dec 2012 12:57:27 +0000 (12:57 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Dec 2012 12:57:27 +0000 (12:57 +0000)
source/blender/bmesh/CMakeLists.txt
source/blender/bmesh/operators/bmo_edgesplit.c
source/blender/bmesh/tools/bmesh_edgesplit.c [new file with mode: 0644]
source/blender/bmesh/tools/bmesh_edgesplit.h [new file with mode: 0644]
source/blender/modifiers/intern/MOD_edgesplit.c

index 2a23658f5d030f646c332edd7f4e5887df573ffe..c41b070324079e239bfd917ce968c2052816e2c7 100644 (file)
@@ -111,6 +111,8 @@ set(SRC
        tools/bmesh_decimate_dissolve.c
        tools/bmesh_decimate_unsubdivide.c
        tools/bmesh_decimate.h
+       tools/bmesh_edgesplit.c
+       tools/bmesh_edgesplit.h
 
        bmesh.h
        bmesh_class.h
index 81728cea9061c0613945d41f544a183c5aa93411..b4b50a60877292954c721497a5da991b87bba489 100644 (file)
 
 /** \file blender/bmesh/operators/bmo_edgesplit.c
  *  \ingroup bmesh
+ *
+ * Just a wrapper around #BM_mesh_edgesplit
  */
 
-#include "MEM_guardedalloc.h"
-
 #include "BLI_utildefines.h"
 
 #include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
 
 #include "intern/bmesh_operators_private.h" /* own include */
 
-/**
- * Remove the BM_ELEM_TAG flag for edges we cant split
- *
- * un-tag edges not connected to other tagged edges,
- * unless they are on a boundary
- */
-static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op)
-{
-       BMOIter siter;
-       BMIter iter;
-       BMEdge *e;
-
-       unsigned char *vtouch;
-       unsigned char *vt;
-
-       BM_mesh_elem_index_ensure(bm, BM_VERT);
-
-       vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
-
-       /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
-       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-
-               /* unrelated to flag assignment in this function - since this is the
-                * only place we loop over all edges, disable tag */
-               BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
-
-               if (e->l == NULL) {
-                       BM_elem_flag_disable(e, BM_ELEM_TAG);
-               }
-               else if (BM_edge_is_boundary(e)) {
-                       vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
-                       vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
-
-                       /* while the boundary verts need to be tagged,
-                        * the edge its self can't be split */
-                       BM_elem_flag_disable(e, BM_ELEM_TAG);
-               }
-       }
-
-       /* single marked edges unconnected to any other marked edges
-        * are illegal, go through and unmark them */
-       BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-               /* lame, but we don't want the count to exceed 255,
-                * so just count to 2, its all we need */
-               unsigned char *vt;
-               vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
-               vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
-       }
-       BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-               if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
-                   vtouch[BM_elem_index_get(e->v2)] == 1)
-               {
-                       BM_elem_flag_disable(e, BM_ELEM_TAG);
-               }
-       }
-
-       MEM_freeN(vtouch);
-}
 
 /* keep this operator fast, its used in a modifier */
 void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
 {
-       BMOIter siter;
-       BMEdge *e;
        const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
 
        BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, FALSE);
@@ -103,63 +44,10 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
        if (use_verts) {
                /* this slows down the operation but its ok because the modifier doesn't use */
                BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, FALSE);
-
-               /* prevent one edge having both verts unflagged
-                * we could alternately disable these edges, either way its a corner case.
-                *
-                * This is needed so we don't split off the edge but then none of its verts which
-                * would leave a duplicate edge.
-                */
-               BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-                       if (UNLIKELY((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE &&
-                                    (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE))))
-                       {
-                               BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
-                               BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
-                       }
-               }
-       }
-
-       bm_edgesplit_validate_seams(bm, op);
-
-       BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
-                       /* this flag gets copied so we can be sure duplicate edges get it too (important) */
-                       BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
-
-                       /* keep splitting until each loop has its own edge */
-                       do {
-                               bmesh_edge_separate(bm, e, e->l);
-                       } while (!BM_edge_is_boundary(e));
-
-                       BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
-                       BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
-               }
        }
 
-       if (use_verts) {
-               BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-                       if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) {
-                               BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
-                       }
-                       if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) {
-                               BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
-                       }
-               }
-       }
-
-       BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
-               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
-                       if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
-                               BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
-                               bmesh_vert_separate(bm, e->v1, NULL, NULL);
-                       }
-                       if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
-                               BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
-                               bmesh_vert_separate(bm, e->v2, NULL, NULL);
-                       }
-               }
-       }
+       /* this is where everything happens */
+       BM_mesh_edgesplit(bm, use_verts, TRUE);
 
        BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
 }
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
new file mode 100644 (file)
index 0000000..b6a8c79
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_edgesplit.c
+ *  \ingroup bmesh
+ *
+ * Edge-Split.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#include "bmesh_edgesplit.h"  /* own include */
+
+
+/**
+ * Remove the BM_ELEM_TAG flag for edges we cant split
+ *
+ * un-tag edges not connected to other tagged edges,
+ * unless they are on a boundary
+ */
+static void bm_edgesplit_validate_seams(BMesh *bm)
+{
+       BMIter iter;
+       BMEdge *e;
+
+       unsigned char *vtouch;
+       unsigned char *vt;
+
+       BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+       vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__);
+
+       /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */
+       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+
+               /* unrelated to flag assignment in this function - since this is the
+                * only place we loop over all edges, disable tag */
+               BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+
+               if (e->l == NULL) {
+                       BM_elem_flag_disable(e, BM_ELEM_TAG);
+               }
+               else if (BM_edge_is_boundary(e)) {
+                       vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+                       vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+
+                       /* while the boundary verts need to be tagged,
+                        * the edge its self can't be split */
+                       BM_elem_flag_disable(e, BM_ELEM_TAG);
+               }
+       }
+
+       /* single marked edges unconnected to any other marked edges
+        * are illegal, go through and unmark them */
+       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+                       /* lame, but we don't want the count to exceed 255,
+                        * so just count to 2, its all we need */
+                       unsigned char *vt;
+                       vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
+                       vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
+               }
+       }
+       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+                       if (vtouch[BM_elem_index_get(e->v1)] == 1 &&
+                               vtouch[BM_elem_index_get(e->v2)] == 1)
+                       {
+                               BM_elem_flag_disable(e, BM_ELEM_TAG);
+                       }
+               }
+       }
+
+       MEM_freeN(vtouch);
+}
+
+void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only)
+{
+       BMIter iter;
+       BMEdge *e;
+
+
+       if (tag_only == FALSE) {
+               BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, FALSE);
+       }
+
+       if (use_verts) {
+               /* prevent one edge having both verts unflagged
+                * we could alternately disable these edges, either way its a corner case.
+                *
+                * This is needed so we don't split off the edge but then none of its verts which
+                * would leave a duplicate edge.
+                */
+               BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+                               if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) &&
+                                             (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE))))
+                               {
+                                       BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+                                       BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+                               }
+                       }
+               }
+       }
+
+       bm_edgesplit_validate_seams(bm);
+
+       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+                       /* this flag gets copied so we can be sure duplicate edges get it too (important) */
+                       BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+
+                       /* keep splitting until each loop has its own edge */
+                       do {
+                               bmesh_edge_separate(bm, e, e->l);
+                       } while (!BM_edge_is_boundary(e));
+
+                       BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+                       BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+               }
+       }
+
+       if (use_verts) {
+               BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) {
+                               BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+                       }
+                       if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) {
+                               BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+                       }
+               }
+       }
+
+       BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+               if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+                       if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
+                               BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+                               bmesh_vert_separate(bm, e->v1, NULL, NULL);
+                       }
+                       if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
+                               BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+                               bmesh_vert_separate(bm, e->v2, NULL, NULL);
+                       }
+               }
+       }
+}
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h
new file mode 100644 (file)
index 0000000..687fdac
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_EDGESPLIT_H__
+#define __BMESH_EDGESPLIT_H__
+
+/** \file blender/bmesh/tools/bmesh_edgesplit.h
+ *  \ingroup bmesh
+ */
+
+void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only);
+
+#endif /* __BMESH_EDGESPLIT_H__ */
index ec81c5ce6996e886fdb70b667c4a44eee8c95590..5c786626c949d267d29211b08fcdd5dd16445b71 100644 (file)
 
 /** \file blender/modifiers/intern/MOD_edgesplit.c
  *  \ingroup modifiers
+ *
+ * EdgeSplit modifier
+ *
+ * Splits edges in the mesh according to sharpness flag
+ * or edge angle (can be used to achieve autosmoothing)
  */
 
-
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing) */
-
 #include "BLI_utildefines.h"
 #include "BLI_math.h"
 
-#include "MEM_guardedalloc.h"
-
 #include "BKE_cdderivedmesh.h"
 #include "BKE_modifier.h"
-#include "BKE_mesh.h"
 
 #include "bmesh.h"
+#include "tools/bmesh_edgesplit.h"
 
 #include "DNA_object_types.h"
 
-/* EdgeSplit */
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing)
- *
- * note: this code is very close to MOD_bevel.c
- */
-
 #define EDGE_MARK  1
 
 static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob))
@@ -67,7 +59,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
        float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
 
        bm = DM_to_bmesh(dm);
-       BM_mesh_elem_toolflags_ensure(bm);
        
        if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
@@ -81,7 +72,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
                                    /* 2 face edge - check angle*/
                                    (dot_v3v3(l1->f->no, l2->f->no) < threshold))
                                {
-                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                       BM_elem_flag_enable(e, BM_ELEM_TAG);
                                }
                        }
                }
@@ -94,14 +85,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
                            (e->l->next != e->l))
                        {
                                if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) {
-                                       BMO_elem_flag_enable(bm, e, EDGE_MARK);
+                                       BM_elem_flag_enable(e, BM_ELEM_TAG);
                                }
                        }
                }
        }
        
-       BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
-                    "split_edges edges=%fe", EDGE_MARK);
+       BM_mesh_edgesplit(bm, FALSE, TRUE);
 
        /* BM_mesh_validate(bm); */ /* for troubleshooting */