remove BM_ITER, BM_ITER_INDEX macros, use ELEM or MESH variants only (the maceros...
[blender-staging.git] / source / blender / bmesh / intern / bmesh_operators.c
index 58c38def33f4980c117c84a5ec72a8e694dbee22..dce491efe72a4aab3487953bf54af6f535578248 100644 (file)
@@ -274,8 +274,7 @@ void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op, const char *src,
                }
 
                if (!dest_slot->data.ghash) {
-                       dest_slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
-                                                                                                 BLI_ghashutil_ptrcmp, "bmesh operator 2");
+                       dest_slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh operator 2");
                }
 
                BLI_ghashIterator_init(&it, source_slot->data.ghash);
@@ -451,39 +450,50 @@ void BMO_slot_vec_get(BMOperator *op, const char *slotname, float r_vec[3])
 /*
  * BMO_COUNTFLAG
  *
- * Counts the number of elements of a certain type that
- * have a specific flag set.
+ * Counts the number of elements of a certain type that have a
+ * specific flag enabled (or disabled if test_for_enabled is false).
  *
  */
 
-int BMO_mesh_flag_count(BMesh *bm, const char htype, const short oflag)
+static int bmo_mesh_flag_count(BMesh *bm, const char htype, const short oflag,
+                               const short test_for_enabled)
 {
-       BMIter elements;
+       const char iter_types[3] = {BM_VERTS_OF_MESH,
+                                   BM_EDGES_OF_MESH,
+                                   BM_FACES_OF_MESH};
+
+       const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
+
+       BMIter iter;
        int count = 0;
        BMElemF *ele_f;
+       int i;
 
-       if (htype & BM_VERT) {
-               for (ele_f = BM_iter_new(&elements, bm, BM_VERTS_OF_MESH, bm); ele_f; ele_f = BM_iter_step(&elements)) {
-                       if (BMO_elem_flag_test(bm, ele_f, oflag))
-                               count++;
-               }
-       }
-       if (htype & BM_EDGE) {
-               for (ele_f = BM_iter_new(&elements, bm, BM_EDGES_OF_MESH, bm); ele_f; ele_f = BM_iter_step(&elements)) {
-                       if (BMO_elem_flag_test(bm, ele_f, oflag))
-                               count++;
-               }
-       }
-       if (htype & BM_FACE) {
-               for (ele_f = BM_iter_new(&elements, bm, BM_FACES_OF_MESH, bm); ele_f; ele_f = BM_iter_step(&elements)) {
-                       if (BMO_elem_flag_test(bm, ele_f, oflag))
-                               count++;
+       BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
+
+       for (i = 0; i < 3; i++) {
+               if (htype & flag_types[i]) {
+                       BM_ITER_MESH (ele_f, &iter, bm, iter_types[i]) {
+                               if (BMO_elem_flag_test_bool(bm, ele_f, oflag) == test_for_enabled)
+                                       count++;
+                       }
                }
        }
 
        return count;
 }
 
+
+int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag)
+{
+       return bmo_mesh_flag_count(bm, htype, oflag, TRUE);
+}
+
+int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag)
+{
+       return bmo_mesh_flag_count(bm, htype, oflag, FALSE);
+}
+
 void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char htype, const short oflag)
 {
        const char iter_types[3] = {BM_VERTS_OF_MESH,
@@ -498,7 +508,7 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty
 
        for (i = 0; i < 3; i++) {
                if (htype & flag_types[i]) {
-                       BM_ITER(ele, &iter, bm, iter_types[i], NULL) {
+                       BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
                                BMO_elem_flag_disable(bm, ele, oflag);
                        }
                }
@@ -546,8 +556,7 @@ void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slotname
        memcpy(mapping + 1, data, len);
 
        if (!slot->data.ghash) {
-               slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
-                                                BLI_ghashutil_ptrcmp, "bmesh slot map hash");
+               slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh slot map hash");
        }
 
        BLI_ghash_insert(slot->data.ghash, element, mapping);
@@ -638,8 +647,6 @@ static void *bmo_slot_buffer_alloc(BMOperator *op, const char *slotname, int len
  */
 static void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slotname, const char htype)
 {
-       BMIter elements;
-       BMHeader *e;
        BMOpSlot *output = BMO_slot_get(op, slotname);
        int totelement = 0, i = 0;
        
@@ -648,25 +655,30 @@ static void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot
        if (htype & BM_FACE) totelement += bm->totface;
 
        if (totelement) {
+               BMIter iter;
+               BMHeader *ele;
+
                bmo_slot_buffer_alloc(op, slotname, totelement);
 
+               /* TODO - collapse these loops into one */
+
                if (htype & BM_VERT) {
-                       for (e = BM_iter_new(&elements, bm, BM_VERTS_OF_MESH, bm); e; e = BM_iter_step(&elements)) {
-                               ((BMHeader **)output->data.p)[i] = e;
+                       BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+                               ((BMHeader **)output->data.p)[i] = ele;
                                i++;
                        }
                }
 
                if (htype & BM_EDGE) {
-                       for (e = BM_iter_new(&elements, bm, BM_EDGES_OF_MESH, bm); e; e = BM_iter_step(&elements)) {
-                               ((BMHeader **)output->data.p)[i] = e;
+                       BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+                               ((BMHeader **)output->data.p)[i] = ele;
                                i++;
                        }
                }
 
                if (htype & BM_FACE) {
-                       for (e = BM_iter_new(&elements, bm, BM_FACES_OF_MESH, bm); e; e = BM_iter_step(&elements)) {
-                               ((BMHeader **)output->data.p)[i] = e;
+                       BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+                               ((BMHeader **)output->data.p)[i] = ele;
                                i++;
                        }
                }
@@ -676,25 +688,36 @@ static void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot
 /**
  * \brief BMO_HEADERFLAG_TO_SLOT
  *
- * Copies elements of a certain type, which have a certain header flag set
- * into a slot for an operator.
+ * Copies elements of a certain type, which have a certain header flag
+ * enabled/disabled into a slot for an operator.
  */
-void BMO_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
-                                const char htype, const char hflag)
+static void bmo_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
+                                       const char htype, const char hflag,
+                                       const short test_for_enabled)
 {
-       BMIter elements;
-       BMElem *ele;
        BMOpSlot *output = BMO_slot_get(op, slotname);
        int totelement = 0, i = 0;
-       
-       totelement = BM_mesh_count_flag(bm, htype, hflag, TRUE);
+
+       BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
+
+       if (test_for_enabled)
+               totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, TRUE);
+       else
+               totelement = BM_mesh_elem_hflag_count_disabled(bm, htype, hflag, TRUE);
 
        if (totelement) {
+               BMIter iter;
+               BMElem *ele;
+
                bmo_slot_buffer_alloc(op, slotname, totelement);
 
+               /* TODO - collapse these loops into one */
+
                if (htype & BM_VERT) {
-                       for (ele = BM_iter_new(&elements, bm, BM_VERTS_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) && BM_elem_flag_test(ele, hflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+                                   BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
+                               {
                                        ((BMElem **)output->data.p)[i] = ele;
                                        i++;
                                }
@@ -702,8 +725,10 @@ void BMO_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
                }
 
                if (htype & BM_EDGE) {
-                       for (ele = BM_iter_new(&elements, bm, BM_EDGES_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) && BM_elem_flag_test(ele, hflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+                                   BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
+                               {
                                        ((BMElem **)output->data.p)[i] = ele;
                                        i++;
                                }
@@ -711,8 +736,10 @@ void BMO_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
                }
 
                if (htype & BM_FACE) {
-                       for (ele = BM_iter_new(&elements, bm, BM_FACES_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) && BM_elem_flag_test(ele, hflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+                               if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+                                   BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
+                               {
                                        ((BMElem **)output->data.p)[i] = ele;
                                        i++;
                                }
@@ -724,17 +751,29 @@ void BMO_slot_buffer_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
        }
 }
 
+void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op, const char *slotname,
+                                        const char htype, const char hflag)
+{
+       bmo_slot_buffer_from_hflag(bm, op, slotname, htype, hflag, TRUE);
+}
+
+void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op, const char *slotname,
+                                         const char htype, const char hflag)
+{
+       bmo_slot_buffer_from_hflag(bm, op, slotname, htype, hflag, FALSE);
+}
+
 /**
  * Copies the values from another slot to the end of the output slot.
  */
 void BMO_slot_buffer_append(BMOperator *output_op, const char *output_slot_name,
-                                                       BMOperator *other_op, const char *other_slot_name)
+                            BMOperator *other_op, const char *other_slot_name)
 {
        BMOpSlot *output_slot = BMO_slot_get(output_op, output_slot_name);
        BMOpSlot *other_slot = BMO_slot_get(other_op, other_slot_name);
 
        BLI_assert(output_slot->slottype == BMO_OP_SLOT_ELEMENT_BUF &&
-                          other_slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
+                  other_slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
 
        if (output_slot->len == 0) {
                /* output slot is empty, copy rather than append */
@@ -748,8 +787,7 @@ void BMO_slot_buffer_append(BMOperator *output_op, const char *output_slot_name,
 
                /* copy slot data */
                memcpy(buf, output_slot->data.buf, elem_size * output_slot->len);
-               memcpy(((char*)buf) + elem_size * output_slot->len,
-                          other_slot->data.buf, elem_size * other_slot->len);
+               memcpy(((char *)buf) + elem_size * output_slot->len, other_slot->data.buf, elem_size * other_slot->len);
 
                output_slot->data.buf = buf;
                output_slot->len += other_slot->len;
@@ -762,16 +800,24 @@ void BMO_slot_buffer_append(BMOperator *output_op, const char *output_slot_name,
  * Copies elements of a certain type, which have a certain flag set
  * into an output slot for an operator.
  */
-void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
-                               const char htype, const short oflag)
+static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
+                                      const char htype, const short oflag,
+                                      const short test_for_enabled)
 {
-       BMIter elements;
        BMOpSlot *slot = BMO_slot_get(op, slotname);
-       int totelement = BMO_mesh_flag_count(bm, htype, oflag), i = 0;
+       int totelement, i = 0;
+
+       BLI_assert(ELEM(TRUE, FALSE, test_for_enabled));
+
+       if (test_for_enabled)
+               totelement = BMO_mesh_enabled_flag_count(bm, htype, oflag);
+       else
+               totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag);
 
        BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
 
        if (totelement) {
+               BMIter iter;
                BMHeader *ele;
                BMHeader **ele_array;
 
@@ -779,9 +825,11 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
 
                ele_array = (BMHeader **)slot->data.p;
 
+               /* TODO - collapse these loops into one */
+
                if (htype & BM_VERT) {
-                       for (ele = BM_iter_new(&elements, bm, BM_VERTS_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+                               if (BMO_elem_flag_test_bool(bm, (BMElemF *)ele, oflag) == test_for_enabled) {
                                        ele_array[i] = ele;
                                        i++;
                                }
@@ -789,8 +837,8 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
                }
 
                if (htype & BM_EDGE) {
-                       for (ele = BM_iter_new(&elements, bm, BM_EDGES_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+                               if (BMO_elem_flag_test_bool(bm, (BMElemF *)ele, oflag) == test_for_enabled) {
                                        ele_array[i] = ele;
                                        i++;
                                }
@@ -798,8 +846,8 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
                }
 
                if (htype & BM_FACE) {
-                       for (ele = BM_iter_new(&elements, bm, BM_FACES_OF_MESH, bm); ele; ele = BM_iter_step(&elements)) {
-                               if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag)) {
+                       BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+                               if (BMO_elem_flag_test_bool(bm, (BMElemF *)ele, oflag) == test_for_enabled) {
                                        ele_array[i] = ele;
                                        i++;
                                }
@@ -811,6 +859,18 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
        }
 }
 
+void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, const char *slotname,
+                                       const char htype, const short oflag)
+{
+       bmo_slot_buffer_from_flag(bm, op, slotname, htype, oflag, TRUE);
+}
+
+void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op, const char *slotname,
+                                        const char htype, const short oflag)
+{
+       bmo_slot_buffer_from_flag(bm, op, slotname, htype, oflag, FALSE);
+}
+
 /**
  * \brief BMO_FLAG_BUFFER
  *
@@ -975,19 +1035,19 @@ static void bmo_flag_layer_alloc(BMesh *bm)
        bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0);
        
        /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
-       for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, old_totflags_size);
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, old_totflags_size);
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, old_totflags_size);
@@ -1020,19 +1080,19 @@ static void bmo_flag_layer_free(BMesh *bm)
        bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, BLI_MEMPOOL_SYSMALLOC);
        
        /* now go through and memcpy all the flag */
-       for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, new_totflags_size);
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, new_totflags_size);
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
                oldflags = ele->oflags;
                ele->oflags = BLI_mempool_calloc(newpool);
                memcpy(ele->oflags, oldflags, new_totflags_size);
@@ -1055,15 +1115,15 @@ static void bmo_flag_layer_clear(BMesh *bm)
        const int totflags_offset = bm->totflags - 1;
 
        /* now go through and memcpy all the flag */
-       for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
                memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
                memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
                BM_elem_index_set(ele, i); /* set_inline */
        }
-       for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, bm), i = 0; ele; ele = BM_iter_step(&iter), i++) {
+       BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
                memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer));
                BM_elem_index_set(ele, i); /* set_inline */
        }
@@ -1403,7 +1463,9 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *_fmt, va_list vlist)
                                        state = 1;
                                        break;
                                case 'f':
+                               case 'F':
                                case 'h':
+                               case 'H':
                                case 'a':
                                        type = *fmt;
 
@@ -1430,13 +1492,19 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *_fmt, va_list vlist)
                                                }
 
                                                if (type == 'h') {
-                                                       BMO_slot_buffer_from_hflag(bm, op, slotname, htype, va_arg(vlist, int));
+                                                       BMO_slot_buffer_from_enabled_hflag(bm, op, slotname, htype, va_arg(vlist, int));
+                                               }
+                                               else if (type == 'H') {
+                                                       BMO_slot_buffer_from_disabled_hflag(bm, op, slotname, htype, va_arg(vlist, int));
                                                }
                                                else if (type == 'a') {
                                                        BMO_slot_buffer_from_all(bm, op, slotname, htype);
                                                }
-                                               else {
-                                                       BMO_slot_buffer_from_flag(bm, op, slotname, htype, va_arg(vlist, int));
+                                               else if (type == 'f') {
+                                                       BMO_slot_buffer_from_enabled_flag(bm, op, slotname, htype, va_arg(vlist, int));
+                                               }
+                                               else if (type == 'F') {
+                                                       BMO_slot_buffer_from_disabled_flag(bm, op, slotname, htype, va_arg(vlist, int));
                                                }
                                        }