forked from bartvdbraak/blender
bmesh operator api:
avoid per vert/edge/face string lookups in BMO_slot_map_* functions --- used in array modifier, subdivide, remove doubles and other tools.
This commit is contained in:
parent
1dd5a89c87
commit
ebaf1306b8
@ -71,7 +71,7 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val);
|
||||
void *BLI_ghash_lookup(GHash *gh, const void *key);
|
||||
int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
|
||||
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
|
||||
int BLI_ghash_haskey(GHash *gh, void *key);
|
||||
int BLI_ghash_haskey(GHash *gh, const void *key);
|
||||
int BLI_ghash_size(GHash *gh);
|
||||
|
||||
/* *** */
|
||||
|
@ -178,7 +178,7 @@ void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int BLI_ghash_haskey(GHash *gh, void *key)
|
||||
int BLI_ghash_haskey(GHash *gh, const void *key)
|
||||
{
|
||||
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
|
||||
Entry *e;
|
||||
|
@ -140,6 +140,10 @@ typedef struct BMOpSlot {
|
||||
#define BMO_SLOT_AS_BUFFER(slot ) ((slot)->data.buf)
|
||||
#define BMO_SLOT_AS_GHASH(slot ) ((slot)->data.ghash)
|
||||
|
||||
#define BMO_ASSERT_SLOT_IN_OP(slot, op) \
|
||||
BLI_assert(((slot >= (op)->slots_in) && (slot < &(op)->slots_in[BMO_OP_MAX_SLOTS])) || \
|
||||
((slot >= (op)->slots_out) && (slot < &(op)->slots_out[BMO_OP_MAX_SLOTS])))
|
||||
|
||||
/* way more than probably needed, compiler complains if limit hit */
|
||||
#define BMO_OP_MAX_SLOTS 16
|
||||
|
||||
@ -385,8 +389,8 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
|
||||
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
|
||||
int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
|
||||
|
||||
void BMO_slot_map_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element, void *data, int len);
|
||||
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
|
||||
const void *element, void *data, int len);
|
||||
|
||||
/* Counts the number of edges with tool flag toolflag around
|
||||
*/
|
||||
|
@ -69,18 +69,16 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor
|
||||
oflags[bm->stackdepth - 1].f ^= oflag;
|
||||
}
|
||||
|
||||
BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
|
||||
const char *slot_name,
|
||||
BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot,
|
||||
void *element, int val)
|
||||
{
|
||||
BMO_slot_map_insert(op, slot_args, slot_name, element, &val, sizeof(int));
|
||||
BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
|
||||
}
|
||||
|
||||
BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
|
||||
const char *slot_name,
|
||||
BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
|
||||
void *element, float val)
|
||||
{
|
||||
BMO_slot_map_insert(op, slot_args, slot_name, element, &val, sizeof(float));
|
||||
BMO_slot_map_insert(op, slot, element, &val, sizeof(float));
|
||||
}
|
||||
|
||||
|
||||
@ -89,63 +87,62 @@ BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot slot_args[BMO
|
||||
* do NOT use these for non-operator-api-allocated memory! instead
|
||||
* use BMO_slot_map_data_get and BMO_slot_map_insert, which copies the data. */
|
||||
|
||||
BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
|
||||
const char *slot_name,
|
||||
void *element, void *val)
|
||||
BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot,
|
||||
const void *element, void *val)
|
||||
{
|
||||
BMO_slot_map_insert(op, slot_args, slot_name, element, &val, sizeof(void *));
|
||||
BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
|
||||
}
|
||||
|
||||
BLI_INLINE int BMO_slot_map_contains(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *element)
|
||||
BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
|
||||
{
|
||||
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
|
||||
|
||||
/* sanity check */
|
||||
if (!slot->data.ghash) return 0;
|
||||
if (UNLIKELY(slot->data.ghash == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BLI_ghash_haskey(slot->data.ghash, element);
|
||||
}
|
||||
|
||||
BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element)
|
||||
BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
|
||||
{
|
||||
BMOElemMapping *mapping;
|
||||
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
|
||||
|
||||
/* sanity check */
|
||||
if (!slot->data.ghash) return NULL;
|
||||
if (UNLIKELY(slot->data.ghash == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mapping = (BMOElemMapping *)BLI_ghash_lookup(slot->data.ghash, element);
|
||||
|
||||
if (!mapping) return NULL;
|
||||
if (!mapping) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapping + 1;
|
||||
}
|
||||
|
||||
BLI_INLINE float BMO_slot_map_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element)
|
||||
BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
|
||||
{
|
||||
float *val = (float *) BMO_slot_map_data_get(slot_args, slot_name, element);
|
||||
float *val = (float *) BMO_slot_map_data_get(slot, element);
|
||||
if (val) return *val;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BLI_INLINE int BMO_slot_map_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element)
|
||||
BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
|
||||
{
|
||||
int *val = (int *) BMO_slot_map_data_get(slot_args, slot_name, element);
|
||||
int *val = (int *) BMO_slot_map_data_get(slot, element);
|
||||
if (val) return *val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element)
|
||||
BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
|
||||
{
|
||||
void **val = (void **) BMO_slot_map_data_get(slot_args, slot_name, element);
|
||||
void **val = (void **) BMO_slot_map_data_get(slot, element);
|
||||
if (val) return *val;
|
||||
|
||||
return NULL;
|
||||
|
@ -592,13 +592,12 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
|
||||
/* inserts a key/value mapping into a mapping slot. note that it copies the
|
||||
* value, it doesn't store a reference to it. */
|
||||
|
||||
void BMO_slot_map_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
|
||||
void *element, void *data, int len)
|
||||
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
|
||||
const void *element, void *data, int len)
|
||||
{
|
||||
BMOElemMapping *mapping;
|
||||
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
|
||||
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
|
||||
BLI_assert(op->slots_in == slot_args || op->slots_out == slot_args);
|
||||
BMO_ASSERT_SLOT_IN_OP(slot, op);
|
||||
|
||||
mapping = (BMOElemMapping *) BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
|
||||
|
||||
@ -610,7 +609,7 @@ void BMO_slot_map_insert(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], c
|
||||
slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
|
||||
}
|
||||
|
||||
BLI_ghash_insert(slot->data.ghash, element, mapping);
|
||||
BLI_ghash_insert(slot->data.ghash, (void *)element, mapping);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -741,7 +741,10 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
|
||||
BMVert *startv;
|
||||
BMVert *endv;
|
||||
EPathNode *node;
|
||||
int i, use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
|
||||
int i;
|
||||
const int use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
|
||||
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
|
||||
|
||||
|
||||
startv = edata[BM_elem_index_get(edge)].ftag ? edge->v2 : edge->v1;
|
||||
endv = edata[BM_elem_index_get(edge)].ftag ? edge->v1 : edge->v2;
|
||||
@ -806,12 +809,13 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
|
||||
continue;
|
||||
}
|
||||
|
||||
if (use_restrict && BMO_slot_map_contains(op->slots_in, "restrict", e)) {
|
||||
int group = BMO_slot_map_int_get(op->slots_in, "restrict", e);
|
||||
|
||||
if (!(group & path->group)) {
|
||||
v2 = NULL;
|
||||
continue;
|
||||
if (use_restrict) {
|
||||
int *group = (int *)BMO_slot_map_data_get(slot_restrict, e);
|
||||
if (group) {
|
||||
if (!(*group & path->group)) {
|
||||
v2 = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -901,6 +905,8 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
|
||||
const short use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
|
||||
int i, j, group = 0;
|
||||
unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
|
||||
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
|
||||
BMOpSlot *slot_face_groupmap_out = BMO_slot_get(op->slots_out, "face_groupmap.out");
|
||||
|
||||
if (!bm->totvert || !bm->totedge)
|
||||
return;
|
||||
@ -932,14 +938,14 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
|
||||
bm->elem_index_dirty &= ~BM_EDGE;
|
||||
|
||||
init_rotsys(bm, edata, vdata);
|
||||
|
||||
|
||||
while (1) {
|
||||
edge = NULL;
|
||||
group = 0;
|
||||
|
||||
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
|
||||
/* if restrict is on, only start on faces in the restrict map */
|
||||
if (use_restrict && !BMO_slot_map_contains(op->slots_in, "restrict", e))
|
||||
if (use_restrict && !BMO_slot_map_contains(slot_restrict, e))
|
||||
continue;
|
||||
|
||||
if (edata[BM_elem_index_get(e)].tag < 2) {
|
||||
@ -948,7 +954,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
|
||||
if (use_restrict) {
|
||||
int i = 0, j = 0, gi = 0;
|
||||
|
||||
group = BMO_slot_map_int_get(op->slots_in, "restrict", e);
|
||||
group = BMO_slot_map_int_get(slot_restrict, e);
|
||||
|
||||
for (i = 0; i < 30; i++) {
|
||||
if (group & (1 << i)) {
|
||||
@ -1055,7 +1061,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
|
||||
if (use_restrict) {
|
||||
BMO_slot_map_int_insert(op, op->slots_out, "face_groupmap.out", f, path->group);
|
||||
BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *tar
|
||||
*
|
||||
* Copy an existing edge from one bmesh to another.
|
||||
*/
|
||||
static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
static BMEdge *copy_edge(BMOperator *op,
|
||||
BMOpSlot *slot_boundarymap_out,
|
||||
BMesh *source_mesh,
|
||||
BMEdge *source_edge, BMesh *target_mesh,
|
||||
GHash *vhash, GHash *ehash)
|
||||
{
|
||||
@ -102,7 +104,7 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
if (rlen < 2) {
|
||||
/* not sure what non-manifold cases of greater then three
|
||||
* radial should do. */
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "boundarymap.out",
|
||||
BMO_slot_map_ptr_insert(op, slot_boundarymap_out,
|
||||
source_edge, target_edge);
|
||||
}
|
||||
|
||||
@ -124,7 +126,9 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
* Copy an existing face from one bmesh to another.
|
||||
*/
|
||||
|
||||
static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
|
||||
static BMFace *copy_face(BMOperator *op,
|
||||
BMOpSlot *slot_facemap_out,
|
||||
BMesh *source_mesh,
|
||||
BMFace *source_face, BMesh *target_mesh,
|
||||
BMVert **vtar, BMEdge **edar, GHash *vhash, GHash *ehash)
|
||||
{
|
||||
@ -151,11 +155,11 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
|
||||
vtar[i] = BLI_ghash_lookup(vhash, source_loop->v);
|
||||
edar[i] = BLI_ghash_lookup(ehash, source_loop->e);
|
||||
}
|
||||
|
||||
|
||||
/* create new face */
|
||||
target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE);
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "facemap.out", source_face, target_face);
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "facemap.out", target_face, source_face);
|
||||
BMO_slot_map_ptr_insert(op, slot_facemap_out, source_face, target_face);
|
||||
BMO_slot_map_ptr_insert(op, slot_facemap_out, target_face, source_face);
|
||||
|
||||
BM_elem_attrs_copy(source_mesh, target_mesh, source_face, target_face);
|
||||
|
||||
@ -181,7 +185,7 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
|
||||
* Internal Copy function.
|
||||
*/
|
||||
|
||||
static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||
static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
|
||||
{
|
||||
|
||||
BMVert *v = NULL, *v2;
|
||||
@ -196,22 +200,26 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||
BMIter viter, eiter, fiter;
|
||||
GHash *vhash, *ehash;
|
||||
|
||||
BMOpSlot *slot_boundarymap_out = BMO_slot_get(op->slots_out, "boundarymap.out");
|
||||
BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
|
||||
BMOpSlot *slot_isovertmap_out = BMO_slot_get(op->slots_out, "isovertmap.out");
|
||||
|
||||
/* initialize pointer hashes */
|
||||
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
|
||||
ehash = BLI_ghash_ptr_new("bmesh dupeops e");
|
||||
|
||||
/* duplicate flagged vertices */
|
||||
BM_ITER_MESH (v, &viter, source, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(source, v, DUPE_INPUT) &&
|
||||
!BMO_elem_flag_test(source, v, DUPE_DONE))
|
||||
BM_ITER_MESH (v, &viter, bm_src, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm_src, v, DUPE_INPUT) &&
|
||||
!BMO_elem_flag_test(bm_src, v, DUPE_DONE))
|
||||
{
|
||||
BMIter iter;
|
||||
int isolated = 1;
|
||||
|
||||
v2 = copy_vertex(source, v, target, vhash);
|
||||
v2 = copy_vertex(bm_src, v, bm_dst, vhash);
|
||||
|
||||
BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
|
||||
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
|
||||
if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
|
||||
isolated = 0;
|
||||
break;
|
||||
}
|
||||
@ -219,7 +227,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||
|
||||
if (isolated) {
|
||||
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
|
||||
if (BMO_elem_flag_test(source, e, DUPE_INPUT)) {
|
||||
if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT)) {
|
||||
isolated = 0;
|
||||
break;
|
||||
}
|
||||
@ -227,49 +235,49 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||
}
|
||||
|
||||
if (isolated) {
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "isovertmap.out", v, v2);
|
||||
BMO_slot_map_ptr_insert(op, slot_isovertmap_out, v, v2);
|
||||
}
|
||||
|
||||
BMO_elem_flag_enable(source, v, DUPE_DONE);
|
||||
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* now we dupe all the edges */
|
||||
BM_ITER_MESH (e, &eiter, source, BM_EDGES_OF_MESH) {
|
||||
if (BMO_elem_flag_test(source, e, DUPE_INPUT) &&
|
||||
!BMO_elem_flag_test(source, e, DUPE_DONE))
|
||||
BM_ITER_MESH (e, &eiter, bm_src, BM_EDGES_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm_src, e, DUPE_INPUT) &&
|
||||
!BMO_elem_flag_test(bm_src, e, DUPE_DONE))
|
||||
{
|
||||
/* make sure that verts are copied */
|
||||
if (!BMO_elem_flag_test(source, e->v1, DUPE_DONE)) {
|
||||
copy_vertex(source, e->v1, target, vhash);
|
||||
BMO_elem_flag_enable(source, e->v1, DUPE_DONE);
|
||||
if (!BMO_elem_flag_test(bm_src, e->v1, DUPE_DONE)) {
|
||||
copy_vertex(bm_src, e->v1, bm_dst, vhash);
|
||||
BMO_elem_flag_enable(bm_src, e->v1, DUPE_DONE);
|
||||
}
|
||||
if (!BMO_elem_flag_test(source, e->v2, DUPE_DONE)) {
|
||||
copy_vertex(source, e->v2, target, vhash);
|
||||
BMO_elem_flag_enable(source, e->v2, DUPE_DONE);
|
||||
if (!BMO_elem_flag_test(bm_src, e->v2, DUPE_DONE)) {
|
||||
copy_vertex(bm_src, e->v2, bm_dst, vhash);
|
||||
BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
|
||||
}
|
||||
/* now copy the actual edge */
|
||||
copy_edge(op, source, e, target, vhash, ehash);
|
||||
BMO_elem_flag_enable(source, e, DUPE_DONE);
|
||||
copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
|
||||
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* first we dupe all flagged faces and their elements from source */
|
||||
BM_ITER_MESH (f, &fiter, source, BM_FACES_OF_MESH) {
|
||||
if (BMO_elem_flag_test(source, f, DUPE_INPUT)) {
|
||||
BM_ITER_MESH (f, &fiter, bm_src, BM_FACES_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm_src, f, DUPE_INPUT)) {
|
||||
/* vertex pass */
|
||||
BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
|
||||
if (!BMO_elem_flag_test(source, v, DUPE_DONE)) {
|
||||
copy_vertex(source, v, target, vhash);
|
||||
BMO_elem_flag_enable(source, v, DUPE_DONE);
|
||||
if (!BMO_elem_flag_test(bm_src, v, DUPE_DONE)) {
|
||||
copy_vertex(bm_src, v, bm_dst, vhash);
|
||||
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* edge pass */
|
||||
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
|
||||
if (!BMO_elem_flag_test(source, e, DUPE_DONE)) {
|
||||
copy_edge(op, source, e, target, vhash, ehash);
|
||||
BMO_elem_flag_enable(source, e, DUPE_DONE);
|
||||
if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
|
||||
copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
|
||||
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,8 +288,8 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||
BLI_array_grow_items(vtar, f->len);
|
||||
BLI_array_grow_items(edar, f->len);
|
||||
|
||||
copy_face(op, source, f, target, vtar, edar, vhash, ehash);
|
||||
BMO_elem_flag_enable(source, f, DUPE_DONE);
|
||||
copy_face(op, slot_facemap_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
|
||||
BMO_elem_flag_enable(bm_src, f, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,8 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
||||
BMVert *v, *v2;
|
||||
BMFace *f;
|
||||
int found, fwd, delorig = FALSE;
|
||||
BMOpSlot *slot_facemap_out;
|
||||
BMOpSlot *slot_edges_exclude;
|
||||
|
||||
/* initialize our sub-operators */
|
||||
BMO_op_init(bm, &dupeop, op->flag, "duplicate");
|
||||
@ -350,8 +352,10 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT))
|
||||
bm->act_face = BMO_slot_map_ptr_get(dupeop.slots_out, "facemap.out", bm->act_face);
|
||||
slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.out");
|
||||
if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT)) {
|
||||
bm->act_face = BMO_slot_map_ptr_get(slot_facemap_out, bm->act_face);
|
||||
}
|
||||
|
||||
if (delorig) {
|
||||
BMO_op_exec(bm, &delop);
|
||||
@ -369,11 +373,12 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
||||
BMO_slot_copy(&dupeop, slots_out, "geom.out",
|
||||
op, slots_out, "geom.out");
|
||||
|
||||
slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude");
|
||||
for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 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(op->slots_in, "edges_exclude", e)) {
|
||||
if (BM_edge_is_wire(e) && BMO_slot_map_contains(slot_edges_exclude, e)) {
|
||||
BMVert *v1 = e->v1, *v2 = e->v2;
|
||||
|
||||
/* The original edge was excluded,
|
||||
|
@ -55,6 +55,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
|
||||
int axis = BMO_slot_int_get(op->slots_in, "axis");
|
||||
int mirroru = BMO_slot_bool_get(op->slots_in, "mirror_u");
|
||||
int mirrorv = BMO_slot_bool_get(op->slots_in, "mirror_v");
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
ototvert = bm->totvert;
|
||||
/* ototedge = bm->totedge; */ /* UNUSED */
|
||||
@ -86,10 +87,12 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
|
||||
|
||||
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
|
||||
|
||||
v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
|
||||
for (i = 0; i < ototvert; i++) {
|
||||
if (fabsf(v->co[axis]) <= dist) {
|
||||
BMO_slot_map_ptr_insert(&weldop, weldop.slots_in, "targetmap", vmap[i], v);
|
||||
BMO_slot_map_ptr_insert(&weldop, slot_targetmap, vmap[i], v);
|
||||
}
|
||||
v = BM_iter_step(&iter);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
#include "intern/bmesh_operators_private.h" /* own include */
|
||||
|
||||
static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
|
||||
static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot *slot_targetmap)
|
||||
{
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
@ -44,7 +44,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
|
||||
int split = FALSE;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
|
||||
v2 = BMO_slot_map_ptr_get(op->slots_in, "targetmap", l->v);
|
||||
v2 = BMO_slot_map_ptr_get(slot_targetmap, l->v);
|
||||
/* ok: if v2 is NULL (e.g. not in the map) then it's
|
||||
* a target vert, otherwise it's a double */
|
||||
if ((v2 && BM_vert_in_face(f, v2)) &&
|
||||
@ -61,8 +61,8 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
|
||||
BMLoop *nl;
|
||||
BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, FALSE);
|
||||
|
||||
remdoubles_splitface(f, bm, op);
|
||||
remdoubles_splitface(f2, bm, op);
|
||||
remdoubles_splitface(f, bm, op, slot_targetmap);
|
||||
remdoubles_splitface(f2, bm, op, slot_targetmap);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,10 +106,11 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
|
||||
BLI_array_declare(loops);
|
||||
BMFace *f, *f2;
|
||||
int a, b;
|
||||
BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap");
|
||||
|
||||
/* mark merge verts for deletion */
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if ((v2 = BMO_slot_map_ptr_get(op->slots_in, "targetmap", v))) {
|
||||
if ((v2 = BMO_slot_map_ptr_get(slot_targetmap, v))) {
|
||||
BMO_elem_flag_enable(bm, v, ELE_DEL);
|
||||
|
||||
/* merge the vertex flags, else we get randomly selected/unselected verts */
|
||||
@ -120,13 +121,13 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
|
||||
/* check if any faces are getting their own corners merged
|
||||
* together, split face if so */
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
remdoubles_splitface(f, bm, op);
|
||||
remdoubles_splitface(f, bm, op, slot_targetmap);
|
||||
}
|
||||
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, e->v1, ELE_DEL) || BMO_elem_flag_test(bm, e->v2, ELE_DEL)) {
|
||||
v = BMO_slot_map_ptr_get(op->slots_in, "targetmap", e->v1);
|
||||
v2 = BMO_slot_map_ptr_get(op->slots_in, "targetmap", e->v2);
|
||||
v = BMO_slot_map_ptr_get(slot_targetmap, e->v1);
|
||||
v2 = BMO_slot_map_ptr_get(slot_targetmap, e->v2);
|
||||
|
||||
if (!v) v = e->v1;
|
||||
if (!v2) v2 = e->v2;
|
||||
@ -174,10 +175,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
|
||||
v = l->v;
|
||||
v2 = l->next->v;
|
||||
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
|
||||
v = BMO_slot_map_ptr_get(op->slots_in, "targetmap", v);
|
||||
v = BMO_slot_map_ptr_get(slot_targetmap, v);
|
||||
}
|
||||
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
|
||||
v2 = BMO_slot_map_ptr_get(op->slots_in, "targetmap", v2);
|
||||
v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
|
||||
}
|
||||
|
||||
e2 = v != v2 ? BM_edge_exists(v, v2) : NULL;
|
||||
@ -207,10 +208,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
|
||||
v2 = loops[1]->v;
|
||||
|
||||
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
|
||||
v = BMO_slot_map_ptr_get(op->slots_in, "targetmap", v);
|
||||
v = BMO_slot_map_ptr_get(slot_targetmap, v);
|
||||
}
|
||||
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
|
||||
v2 = BMO_slot_map_ptr_get(op->slots_in, "targetmap", v2);
|
||||
v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
|
||||
}
|
||||
|
||||
f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE);
|
||||
@ -344,19 +345,22 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
|
||||
BMOIter siter;
|
||||
BMVert *v, *snapv = NULL;
|
||||
float vec[3];
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BMO_slot_vec_get(op->slots_in, "merge_co", vec);
|
||||
|
||||
//BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
|
||||
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
|
||||
|
||||
|
||||
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
|
||||
|
||||
BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
|
||||
if (!snapv) {
|
||||
snapv = v;
|
||||
copy_v3_v3(snapv->co, vec);
|
||||
}
|
||||
else {
|
||||
BMO_slot_map_ptr_insert(&weldop, weldop.slots_in, "targetmap", v, snapv);
|
||||
BMO_slot_map_ptr_insert(&weldop, slot_targetmap, v, snapv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,9 +377,11 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
||||
BLI_array_declare(edges);
|
||||
float min[3], max[3], center[3];
|
||||
int i, tot;
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
|
||||
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
|
||||
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
|
||||
|
||||
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_MARK);
|
||||
|
||||
@ -408,9 +414,9 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
|
||||
copy_v3_v3(edges[i]->v2->co, center);
|
||||
|
||||
if (edges[i]->v1 != edges[0]->v1)
|
||||
BMO_slot_map_ptr_insert(&weldop, weldop.slots_in, "targetmap", edges[i]->v1, edges[0]->v1);
|
||||
BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
|
||||
if (edges[i]->v2 != edges[0]->v1)
|
||||
BMO_slot_map_ptr_insert(&weldop, weldop.slots_in, "targetmap", edges[i]->v2, edges[0]->v1);
|
||||
BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,9 +493,7 @@ void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
|
||||
static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
|
||||
BMOperator *optarget,
|
||||
BMOpSlot optarget_slot_args[BMO_OP_MAX_SLOTS],
|
||||
const char *targetmapname)
|
||||
BMOperator *optarget, BMOpSlot *optarget_slot)
|
||||
{
|
||||
BMVert **verts;
|
||||
int verts_len;
|
||||
@ -550,7 +554,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
|
||||
BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE);
|
||||
BMO_elem_flag_enable(bm, v_check, VERT_TARGET);
|
||||
|
||||
BMO_slot_map_ptr_insert(optarget, optarget_slot_args, targetmapname, v_other, v_check);
|
||||
BMO_slot_map_ptr_insert(optarget, optarget_slot, v_other, v_check);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -561,10 +565,12 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
|
||||
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator weldop;
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
|
||||
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
|
||||
bmesh_find_doubles_common(bm, op,
|
||||
&weldop, weldop.slots_in, "targetmap");
|
||||
&weldop, slot_targetmap);
|
||||
BMO_op_exec(bm, &weldop);
|
||||
BMO_op_finish(bm, &weldop);
|
||||
}
|
||||
@ -572,8 +578,10 @@ void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
void bmo_find_doubles_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOpSlot *slot_targetmap_out;
|
||||
slot_targetmap_out = BMO_slot_get(op->slots_out, "targetmap");
|
||||
bmesh_find_doubles_common(bm, op,
|
||||
op, op->slots_out, "targetmap.out");
|
||||
op, slot_targetmap_out);
|
||||
}
|
||||
|
||||
void bmo_automerge_exec(BMesh *bm, BMOperator *op)
|
||||
|
@ -225,8 +225,9 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
|
||||
BMVert *ev;
|
||||
float percent, percent2 = 0.0f;
|
||||
|
||||
if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1)
|
||||
percent = BMO_slot_map_float_get(params->op->slots_in, "edgepercents", edge);
|
||||
if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) {
|
||||
percent = BMO_slot_map_float_get(params->slot_edgepercents, edge);
|
||||
}
|
||||
else {
|
||||
percent = 1.0f / (float)(totpoint + 1 - curpoint);
|
||||
percent2 = (float)(curpoint + 1) / (float)(totpoint + 1);
|
||||
@ -778,6 +779,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
params.numcuts = numcuts;
|
||||
params.op = op;
|
||||
params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
|
||||
params.slot_custompatterns = BMO_slot_get(op->slots_in, "custompatterns");
|
||||
params.smooth = smooth;
|
||||
params.seed = seed;
|
||||
params.fractal = fractal;
|
||||
@ -837,7 +840,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
|
||||
if (BMO_elem_flag_test(bm, face, FACE_CUSTOMFILL)) {
|
||||
pat = BMO_slot_map_data_get(op->slots_in, "custompatterns", face);
|
||||
pat = BMO_slot_map_data_get(params.slot_custompatterns, face);
|
||||
for (i = 0; i < pat->len; i++) {
|
||||
matched = 1;
|
||||
for (j = 0; j < pat->len; j++) {
|
||||
@ -1159,6 +1162,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
|
||||
params.op = op;
|
||||
params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
|
||||
|
||||
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
|
||||
skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
|
||||
|
@ -39,6 +39,8 @@ typedef struct SubDParams {
|
||||
int seed;
|
||||
int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
|
||||
BMOperator *op;
|
||||
BMOpSlot *slot_edgepercents; /* BMO_slot_get(params->op->slots_in, "edgepercents"); */
|
||||
BMOpSlot *slot_custompatterns; /* BMO_slot_get(params->op->slots_in, "custompatterns"); */
|
||||
float off[3];
|
||||
} SubDParams;
|
||||
|
||||
|
@ -53,6 +53,7 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
|
||||
BLI_array_declare(projectverts);
|
||||
int i;
|
||||
const int use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
|
||||
BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
|
||||
|
||||
for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
|
||||
|
||||
@ -64,9 +65,9 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
BM_face_triangulate(bm, face, projectverts, EDGE_NEW, FACE_NEW, newfaces, use_beauty);
|
||||
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "facemap.out", face, face);
|
||||
BMO_slot_map_ptr_insert(op, slot_facemap_out, face, face);
|
||||
for (i = 0; newfaces[i]; i++) {
|
||||
BMO_slot_map_ptr_insert(op, op->slots_out, "facemap.out", newfaces[i], face);
|
||||
BMO_slot_map_ptr_insert(op, slot_facemap_out, newfaces[i], face);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,10 +308,13 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
|
||||
BMFace *f;
|
||||
ModifierData *md;
|
||||
BMElem *ele;
|
||||
BMOpSlot *slot_edges_exclude;
|
||||
|
||||
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag);
|
||||
|
||||
slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude");
|
||||
|
||||
/* If a mirror modifier with clipping is on, we need to adjust some
|
||||
* of the cases above to handle edges on the line of symmetry.
|
||||
*/
|
||||
@ -350,21 +353,21 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
|
||||
if ((fabsf(co1[0]) < mmd->tolerance) &&
|
||||
(fabsf(co2[0]) < mmd->tolerance))
|
||||
{
|
||||
BMO_slot_map_ptr_insert(&extop, extop.slots_in, "edges_exclude", edge, NULL);
|
||||
BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
|
||||
}
|
||||
}
|
||||
if (mmd->flag & MOD_MIR_AXIS_Y) {
|
||||
if ((fabsf(co1[1]) < mmd->tolerance) &&
|
||||
(fabsf(co2[1]) < mmd->tolerance))
|
||||
{
|
||||
BMO_slot_map_ptr_insert(&extop, extop.slots_in, "edges_exclude", edge, NULL);
|
||||
BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
|
||||
}
|
||||
}
|
||||
if (mmd->flag & MOD_MIR_AXIS_Z) {
|
||||
if ((fabsf(co1[2]) < mmd->tolerance) &&
|
||||
(fabsf(co2[2]) < mmd->tolerance))
|
||||
{
|
||||
BMO_slot_map_ptr_insert(&extop, extop.slots_in, "edges_exclude", edge, NULL);
|
||||
BMO_slot_map_ptr_insert(&extop, slot_edges_exclude, edge, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2868,6 +2871,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
|
||||
float isect = 0.0f;
|
||||
int len = 0, isected, i;
|
||||
short numcuts = 1, mode = RNA_int_get(op->ptr, "type");
|
||||
BMOpSlot *slot_edgepercents;
|
||||
|
||||
/* allocd vars */
|
||||
float (*screen_vert_coords)[2], (*sco)[2], (*mouse_path)[2];
|
||||
@ -2922,6 +2926,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
/* store percentage of edge cut for KNIFE_EXACT here.*/
|
||||
slot_edgepercents = BMO_slot_get(bmop.slots_in, "edgepercents");
|
||||
for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) {
|
||||
int is_cut = FALSE;
|
||||
if (BM_elem_flag_test(be, BM_ELEM_SELECT)) {
|
||||
@ -2934,9 +2939,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
|
||||
|
||||
if (isect != 0.0f) {
|
||||
if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) {
|
||||
BMO_slot_map_float_insert(&bmop, bmop.slots_in,
|
||||
"edgepercents",
|
||||
be, isect);
|
||||
BMO_slot_map_float_insert(&bmop, slot_edgepercents, be, isect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,6 +235,7 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
|
||||
|
||||
BMOIter oiter;
|
||||
BMOperator find_op;
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
|
||||
is_input ? /* ugh */
|
||||
@ -266,15 +267,17 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
|
||||
|
||||
BMO_op_exec(bm, &find_op);
|
||||
|
||||
slot_targetmap = BMO_slot_get(weld_op->slots_in, "targetmap");
|
||||
|
||||
/* add new merge targets to weld operator */
|
||||
BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
|
||||
v2 = BMO_iter_map_value_p(&oiter);
|
||||
/* check in case the target vertex (v2) is already marked
|
||||
* for merging */
|
||||
while ((v3 = BMO_slot_map_ptr_get(weld_op->slots_in, "targetmap", v2))) {
|
||||
while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
|
||||
v2 = v3;
|
||||
}
|
||||
BMO_slot_map_ptr_insert(weld_op, weld_op->slots_in, "targetmap", v, v2);
|
||||
BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
|
||||
}
|
||||
|
||||
BMO_op_finish(bm, &find_op);
|
||||
@ -299,6 +302,7 @@ static void merge_first_last(BMesh *bm,
|
||||
BMOperator find_op;
|
||||
BMOIter oiter;
|
||||
BMVert *v, *v2;
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BMO_op_initf(bm, &find_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
|
||||
"find_doubles verts=%s dist=%f keep_verts=%s",
|
||||
@ -312,9 +316,10 @@ static void merge_first_last(BMesh *bm,
|
||||
BMO_op_exec(bm, &find_op);
|
||||
|
||||
/* add new merge targets to weld operator */
|
||||
slot_targetmap = BMO_slot_get(weld_op->slots_out, "targetmap");
|
||||
BMO_ITER (v, &oiter, find_op.slots_out, "targetmap.out", 0) {
|
||||
v2 = BMO_iter_map_value_p(&oiter);
|
||||
BMO_slot_map_ptr_insert(weld_op, weld_op->slots_in, "targetmap", v, v2);
|
||||
BMO_slot_map_ptr_insert(weld_op, slot_targetmap, v, v2);
|
||||
}
|
||||
|
||||
BMO_op_finish(bm, &find_op);
|
||||
@ -339,6 +344,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
||||
int *indexMap = NULL;
|
||||
DerivedMesh *start_cap = NULL, *end_cap = NULL;
|
||||
MVert *src_mvert;
|
||||
BMOpSlot *slot_targetmap = NULL; /* for weldop */
|
||||
|
||||
/* need to avoid infinite recursion here */
|
||||
if (amd->start_cap && amd->start_cap != ob)
|
||||
@ -426,10 +432,13 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
||||
BMO_push(bm, NULL);
|
||||
bmesh_edit_begin(bm, 0);
|
||||
|
||||
if (amd->flags & MOD_ARR_MERGE)
|
||||
if (amd->flags & MOD_ARR_MERGE) {
|
||||
BMO_op_init(bm, &weld_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
|
||||
"weld_verts");
|
||||
|
||||
slot_targetmap = BMO_slot_get(weld_op.slots_in, "targetmap");
|
||||
}
|
||||
|
||||
BMO_op_initf(bm, &dupe_op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
|
||||
"duplicate geom=%avef");
|
||||
first_dupe_op = dupe_op;
|
||||
@ -485,11 +494,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
||||
|
||||
/* check in case the target vertex (v2) is already marked
|
||||
* for merging */
|
||||
while ((v3 = BMO_slot_map_ptr_get(weld_op.slots_in, "targetmap", v2))) {
|
||||
while ((v3 = BMO_slot_map_ptr_get(slot_targetmap, v2))) {
|
||||
v2 = v3;
|
||||
}
|
||||
|
||||
BMO_slot_map_ptr_insert(&weld_op, weld_op.slots_in, "targetmap", v, v2);
|
||||
BMO_slot_map_ptr_insert(&weld_op, slot_targetmap, v, v2);
|
||||
}
|
||||
|
||||
#undef _E
|
||||
|
@ -1080,17 +1080,20 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
|
||||
BMOperator op;
|
||||
BMIter iter;
|
||||
int i;
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
shortest_edge = BM_face_find_shortest_loop(f)->e;
|
||||
BMO_op_initf(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "weld_verts");
|
||||
|
||||
slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
|
||||
|
||||
/* Note: could probably calculate merges in one go to be
|
||||
* faster */
|
||||
|
||||
v_safe = shortest_edge->v1;
|
||||
v_merge = shortest_edge->v2;
|
||||
mid_v3_v3v3(v_safe->co, v_safe->co, v_merge->co);
|
||||
BMO_slot_map_ptr_insert(&op, op.slots_in, "targetmap", v_merge, v_safe);
|
||||
BMO_slot_map_ptr_insert(&op, slot_targetmap, v_merge, v_safe);
|
||||
BMO_op_exec(bm, &op);
|
||||
BMO_op_finish(bm, &op);
|
||||
|
||||
@ -1216,6 +1219,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
|
||||
BMOIter oiter;
|
||||
BMOperator op;
|
||||
int i, best_order[4];
|
||||
BMOpSlot *slot_targetmap;
|
||||
|
||||
BLI_assert(split_face->len >= 3);
|
||||
|
||||
@ -1281,8 +1285,9 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
|
||||
BM_face_kill(bm, split_face);
|
||||
BMO_op_init(bm, &op, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
|
||||
"weld_verts");
|
||||
slot_targetmap = BMO_slot_get(op.slots_in, "targetmap");
|
||||
for (i = 0; i < 4; i++) {
|
||||
BMO_slot_map_ptr_insert(&op, op.slots_in, "targetmap",
|
||||
BMO_slot_map_ptr_insert(&op, slot_targetmap,
|
||||
verts[i], frame->verts[best_order[i]]);
|
||||
}
|
||||
BMO_op_exec(bm, &op);
|
||||
|
Loading…
Reference in New Issue
Block a user