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/intern/bmesh_operators.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c179
1 files changed, 135 insertions, 44 deletions
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 4c38ccacb31..e09be79633e 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -64,16 +64,17 @@ static const char *bmo_error_messages[] = {
/* operator slot type information - size of one element of the type given. */
const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
- 0,
- sizeof(int),
- sizeof(int),
- sizeof(float),
- sizeof(void *),
- 0, /* unused */
- 0, /* unused */
- 0, /* unused */
- sizeof(void *), /* pointer buffer */
- sizeof(BMOElemMapping)
+ 0, /* 0: BMO_OP_SLOT_SENTINEL */
+ sizeof(int), /* 1: BMO_OP_SLOT_BOOL */
+ sizeof(int), /* 2: BMO_OP_SLOT_INT */
+ sizeof(float), /* 3: BMO_OP_SLOT_FLT */
+ sizeof(void *), /* 4: BMO_OP_SLOT_PNT */
+ sizeof(void *), /* 5: BMO_OP_SLOT_PNT */
+ 0, /* 6: unused */
+ 0, /* 7: unused */
+ sizeof(float) * 3, /* 8: BMO_OP_SLOT_VEC */
+ sizeof(void *), /* 9: BMO_OP_SLOT_ELEMENT_BUF */
+ sizeof(BMOElemMapping) /* 10: BMO_OP_SLOT_MAPPING */
};
/* Dummy slot so there is something to return when slot name lookup fails */
@@ -450,32 +451,34 @@ 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,
+ int test_for_enabled)
{
BMIter elements;
int count = 0;
BMElemF *ele_f;
+ int test = (test_for_enabled ? oflag : 0);
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))
+ if (BMO_elem_flag_test(bm, ele_f, oflag) == test)
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))
+ if (BMO_elem_flag_test(bm, ele_f, oflag) == test)
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))
+ if (BMO_elem_flag_test(bm, ele_f, oflag) == test)
count++;
}
}
@@ -483,6 +486,17 @@ int BMO_mesh_flag_count(BMesh *bm, const char htype, const short oflag)
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,
@@ -546,7 +560,7 @@ void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slotname
if (!slot->data.ghash) {
slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
- BLI_ghashutil_ptrcmp, "bmesh op");
+ BLI_ghashutil_ptrcmp, "bmesh slot map hash");
}
BLI_ghash_insert(slot->data.ghash, element, mapping);
@@ -675,25 +689,32 @@ 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,
+ int 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);
+
+ if (test_for_enabled)
+ totelement = BM_mesh_enabled_flag_count(bm, htype, hflag, TRUE);
+ else
+ totelement = BM_mesh_disabled_flag_count(bm, htype, hflag, TRUE);
if (totelement) {
+ int test = (test_for_enabled ? hflag : 0);
+
bmo_slot_buffer_alloc(op, slotname, totelement);
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)) {
+ if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+ BM_elem_flag_test(ele, hflag) == test) {
((BMElem **)output->data.p)[i] = ele;
i++;
}
@@ -702,7 +723,8 @@ 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)) {
+ if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+ BM_elem_flag_test(ele, hflag) == test) {
((BMElem **)output->data.p)[i] = ele;
i++;
}
@@ -711,7 +733,8 @@ 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)) {
+ if (!BM_elem_flag_test(ele, BM_ELEM_HIDDEN) &&
+ BM_elem_flag_test(ele, hflag) == test) {
((BMElem **)output->data.p)[i] = ele;
i++;
}
@@ -723,24 +746,75 @@ 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)
+{
+ 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);
+
+ if (output_slot->len == 0) {
+ /* output slot is empty, copy rather than append */
+ BMO_slot_copy(other_op, output_op, other_slot_name, output_slot_name);
+ }
+ else if (other_slot->len != 0) {
+ int elem_size = BMO_OPSLOT_TYPEINFO[output_slot->slottype];
+ int alloc_size = elem_size * (output_slot->len + other_slot->len);
+ /* allocate new buffer */
+ void *buf = BLI_memarena_alloc(output_op->arena, alloc_size);
+
+ /* 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);
+
+ output_slot->data.buf = buf;
+ output_slot->len += other_slot->len;
+ }
+}
+
/**
* \brief BMO_FLAG_TO_SLOT
*
* 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,
+ int 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;
+
+ 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) {
BMHeader *ele;
BMHeader **ele_array;
+ int test = (test_for_enabled ? oflag : 0);
bmo_slot_buffer_alloc(op, slotname, totelement);
@@ -748,7 +822,7 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
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)) {
+ if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag) == test) {
ele_array[i] = ele;
i++;
}
@@ -757,7 +831,7 @@ 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)) {
+ if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag) == test) {
ele_array[i] = ele;
i++;
}
@@ -766,7 +840,7 @@ 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)) {
+ if (BMO_elem_flag_test(bm, (BMElemF *)ele, oflag) == test) {
ele_array[i] = ele;
i++;
}
@@ -778,6 +852,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
*
@@ -1264,8 +1350,8 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *_fmt, va_list vlist)
/* we muck around in here, so dup i */
fmt = ofmt = BLI_strdup(_fmt);
- /* find operator nam */
- i = strcspn(fmt, " \t");
+ /* find operator name */
+ i = strcspn(fmt, " ");
opname = fmt;
if (!opname[i]) noslot = 1;
@@ -1289,17 +1375,15 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *_fmt, va_list vlist)
while (*fmt) {
if (state) {
/* jump past leading whitespac */
- i = strspn(fmt, " \t");
+ i = strspn(fmt, " ");
fmt += i;
/* ignore trailing whitespac */
if (!fmt[i])
break;
- /* find end of slot name. currently this is
- * a little flexible, allowing "slot=%f",
- * "slot %f", "slot%f", and "slot\t%f". */
- i = strcspn(fmt, "= \t%");
+ /* find end of slot name, only "slot=%f", can be used */
+ i = strcspn(fmt, "=");
if (!fmt[i]) {
GOTO_ERROR("could not match end of slot name");
}
@@ -1318,7 +1402,6 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *_fmt, va_list vlist)
else {
switch (*fmt) {
case ' ':
- case '\t':
case '=':
case '%':
break;
@@ -1373,11 +1456,13 @@ 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;
- if (NEXT_CHAR(fmt) == ' ' || NEXT_CHAR(fmt) == '\t' || NEXT_CHAR(fmt) == '\0') {
+ if (NEXT_CHAR(fmt) == ' ' || NEXT_CHAR(fmt) == '\0') {
BMO_slot_float_set(op, slotname, va_arg(vlist, double));
}
else {
@@ -1400,13 +1485,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));
}
}