finished removedoubles, and inlined a bunch of functions.

This commit is contained in:
Joseph Eagar
2009-09-09 06:28:58 +00:00
parent 287cc0fad8
commit e0a014a45f
13 changed files with 350 additions and 256 deletions

View File

@@ -24,6 +24,7 @@ typedef struct BMEditMesh {
/*this is for undoing failed operations*/
struct BMEditMesh *emcopy;
int emcopyusers;
/*we store tesselations as triplets of three loops,
which each define a triangle.*/

View File

@@ -241,7 +241,7 @@ behaviour, though it may not be the best in practice.
/*little macro so inline keyword works*/
#if defined(_MSC_VER)
#define BM_INLINE //__forceinline
#define BM_INLINE __forceinline
#else
#define BM_INLINE inline
#endif

View File

@@ -2171,6 +2171,43 @@ static DerivedMesh *mirrorModifier_applyModifierEM(
/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
* or edge angle (can be used to achieve autosmoothing)
*/
/*new cddm-based edge split code*/
#if 0
typedef struct VertUser {
int ov, v, done;
ListBase users;
} VertUser;
typedef struct EdgeNode {
struct EdgeNode *next, *prev;
struct EdgeData *edge;
} EdgeNode;
typedef struct EdgeData {
EdgeNode v1list, v2list;
VertUser *v1user, *v2user;
int tag;
int v1, v2;
} EdgeData;
DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
{
DerivedMesh *cddm = CDDM_copy(dm);
EdgeData *etags;
VertUser *vusers;
if (!cddm->numVertData || !cddm->numEdgeData)
return cddm;
etags = MEM_callocN(sizeof(EdgeData)*cddm->numEdgeData, "edgedata tag thingies");
MEM_freeN(etags);
return cddm;
}
#endif
#if 0
#define EDGESPLIT_DEBUG_3
#define EDGESPLIT_DEBUG_2

View File

@@ -275,7 +275,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
Scene *scene, Object *ob, DerivedMesh *dm,
int initFlags)
{
DerivedMesh *cddm = dm; //CDDM_copy(dm); copying shouldn't be necassary here, as all modifiers return CDDM's
DerivedMesh *cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
BMEditMesh *em = CDDM_To_BMesh(cddm, NULL);
BMOperator op, oldop, weldop;
int i, j, indexLen;
@@ -388,9 +388,6 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
MTC_Mat4CpyMat4(final_offset, tmp_mat);
}
//cddm->needsFree = 1;
//cddm->release(cddm);
BMO_Init_Op(&weldop, "weldverts");
BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
oldop = op;
@@ -535,12 +532,9 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
float mtx[4][4], imtx[4][4];
int i, j;
cddm = dm; //CDDM_copy(dm); copying shouldn't be necassary here, as all modifiers return CDDM's
cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
em = CDDM_To_BMesh(dm, NULL);
//cddm->needsFree = 1;
//cddm->release(cddm);
/*convienence variable*/
bm = em->bm;

View File

@@ -32,8 +32,15 @@
#ifndef BLI_GHASH_H
#define BLI_GHASH_H
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "BKE_utildefines.h"
#include "BLI_mempool.h"
#include "BLI_blenlib.h"
typedef unsigned int (*GHashHashFP) (void *key);
typedef int (*GHashCmpFP) (void *a, void *b);
typedef void (*GHashKeyFreeFP) (void *key);
@@ -63,10 +70,10 @@ typedef struct GHashIterator {
GHash* BLI_ghash_new (GHashHashFP hashfp, GHashCmpFP cmpfp);
void BLI_ghash_free (GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
BM_INLINE void BLI_ghash_insert (GHash *gh, void *key, void *val);
BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
BM_INLINE void* BLI_ghash_lookup (GHash *gh, void *key);
BM_INLINE int BLI_ghash_haskey (GHash *gh, void *key);
//BM_INLINE void BLI_ghash_insert (GHash *gh, void *key, void *val);
//BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
//BM_INLINE void* BLI_ghash_lookup (GHash *gh, void *key);
//BM_INLINE int BLI_ghash_haskey (GHash *gh, void *key);
int BLI_ghash_size (GHash *gh);
@@ -139,11 +146,10 @@ int BLI_ghashutil_strcmp (void *a, void *b);
unsigned int BLI_ghashutil_inthash (void *ptr);
int BLI_ghashutil_intcmp(void *a, void *b);
#endif
/*begin of macro-inlined functions*/
extern unsigned int hashsizes[];
#if 0
#define BLI_ghash_insert(gh, _k, _v){\
unsigned int _hash= (gh)->hashfp(_k)%gh->nbuckets;\
Entry *_e= BLI_mempool_alloc((gh)->entrypool);\
@@ -167,3 +173,94 @@ extern unsigned int hashsizes[];
}\
}\
free(_old); } }
#endif
/*---------inlined functions---------*/
BM_INLINE void BLI_ghash_insert(GHash *gh, void *key, void *val) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e= BLI_mempool_alloc(gh->entrypool);
e->key= key;
e->val= val;
e->next= gh->buckets[hash];
gh->buckets[hash]= e;
if (++gh->nentries>gh->nbuckets*3) {
Entry *e, **old= gh->buckets;
int i, nold= gh->nbuckets;
gh->nbuckets= hashsizes[++gh->cursize];
gh->buckets= malloc(gh->nbuckets*sizeof(*gh->buckets));
memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets));
for (i=0; i<nold; i++) {
for (e= old[i]; e;) {
Entry *n= e->next;
hash= gh->hashfp(e->key)%gh->nbuckets;
e->next= gh->buckets[hash];
gh->buckets[hash]= e;
e= n;
}
}
free(old);
}
}
BM_INLINE void* BLI_ghash_lookup(GHash *gh, void *key)
{
if(gh) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
for (e= gh->buckets[hash]; e; e= e->next)
if (gh->cmpfp(key, e->key)==0)
return e->val;
}
return NULL;
}
BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
Entry *p = 0;
for (e= gh->buckets[hash]; e; e= e->next) {
if (gh->cmpfp(key, e->key)==0) {
Entry *n= e->next;
if (keyfreefp) keyfreefp(e->key);
if (valfreefp) valfreefp(e->val);
BLI_mempool_free(gh->entrypool, e);
e= n;
if (p)
p->next = n;
else
gh->buckets[hash] = n;
--gh->nentries;
return 1;
}
p = e;
}
return 0;
}
BM_INLINE int BLI_ghash_haskey(GHash *gh, void *key) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
for (e= gh->buckets[hash]; e; e= e->next)
if (gh->cmpfp(key, e->key)==0)
return 1;
return 0;
}
#endif

View File

@@ -76,93 +76,6 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp) {
#undef BLI_ghash_insert
#endif
BM_INLINE void BLI_ghash_insert(GHash *gh, void *key, void *val) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e= BLI_mempool_alloc(gh->entrypool);
e->key= key;
e->val= val;
e->next= gh->buckets[hash];
gh->buckets[hash]= e;
if (++gh->nentries>gh->nbuckets*3) {
Entry *e, **old= gh->buckets;
int i, nold= gh->nbuckets;
gh->nbuckets= hashsizes[++gh->cursize];
gh->buckets= malloc(gh->nbuckets*sizeof(*gh->buckets));
memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets));
for (i=0; i<nold; i++) {
for (e= old[i]; e;) {
Entry *n= e->next;
hash= gh->hashfp(e->key)%gh->nbuckets;
e->next= gh->buckets[hash];
gh->buckets[hash]= e;
e= n;
}
}
free(old);
}
}
BM_INLINE void* BLI_ghash_lookup(GHash *gh, void *key)
{
if(gh) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
for (e= gh->buckets[hash]; e; e= e->next)
if (gh->cmpfp(key, e->key)==0)
return e->val;
}
return NULL;
}
BM_INLINE int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
Entry *p = 0;
for (e= gh->buckets[hash]; e; e= e->next) {
if (gh->cmpfp(key, e->key)==0) {
Entry *n= e->next;
if (keyfreefp) keyfreefp(e->key);
if (valfreefp) valfreefp(e->val);
BLI_mempool_free(gh->entrypool, e);
e= n;
if (p)
p->next = n;
else
gh->buckets[hash] = n;
--gh->nentries;
return 1;
}
p = e;
}
return 0;
}
BM_INLINE int BLI_ghash_haskey(GHash *gh, void *key) {
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
Entry *e;
for (e= gh->buckets[hash]; e; e= e->next)
if (gh->cmpfp(key, e->key)==0)
return 1;
return 0;
}
int BLI_ghash_size(GHash *gh) {
return gh->nentries;
}

View File

@@ -253,25 +253,25 @@ void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotn
/*counts number of elements inside a slot array.*/
int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, char *slotname);
int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, char *slotname);
/*inserts a key/value mapping into a mapping slot. note that it copies the
value, it doesn't store a reference to it.*/
BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname,
void *element, void *data, int len);
//BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname,
//void *element, void *data, int len);
/*inserts a key/float mapping pair into a mapping slot.*/
BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
void *element, float val);
//BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
//void *element, float val);
//returns 1 if the specified pointer is in the map.
BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, char *slotname, void *element);
//BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, char *slotname, void *element);
/*returns a point to the value of a specific key.*/
BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, char *slotname, void *element);
//BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, char *slotname, void *element);
/*returns the float part of a key/float pair.*/
BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, char *slotname, void *element);
//BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, char *slotname, void *element);
/*flags all elements in a mapping. note that the mapping must only have
bmesh elements in it.*/
@@ -282,10 +282,10 @@ void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
do NOT use these for non-operator-api-allocated memory! instead
use BMO_Get_MapData and BMO_Insert_Mapping, which copies the data.*/
BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *key, void *val);
BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *key);
//BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
//void *key, void *val);
//BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
//void *key);
/*this part of the API is used to iterate over element buffer or
mapping slots.
@@ -350,4 +350,97 @@ float BMO_IterMapValf(BMOIter *iter);
ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
for ( ; ele; ele=BMO_IterStep(iter))
/******************* Inlined Functions********************/
typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
/*mappings map elements to data, which
follows the mapping struct in memory.*/
typedef struct element_mapping {
BMHeader *element;
int len;
} element_mapping;
extern const int BMOP_OPSLOT_TYPEINFO[];
BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname,
void *element, void *data, int len) {
element_mapping *mapping;
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return;
mapping = BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
mapping->element = element;
mapping->len = len;
memcpy(mapping+1, data, len);
if (!slot->data.ghash) {
slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
BLI_ghashutil_ptrcmp);
}
BLI_ghash_insert(slot->data.ghash, element, mapping);
}
BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
void *element, float val)
{
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(float));
}
BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *element, void *val)
{
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(void*));
}
BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, char *slotname, void *element)
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return 0;
if (!slot->data.ghash) return 0;
return BLI_ghash_haskey(slot->data.ghash, element);
}
BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
element_mapping *mapping;
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return NULL;
if (!slot->data.ghash) return NULL;
mapping = BLI_ghash_lookup(slot->data.ghash, element);
if (!mapping) return NULL;
return mapping + 1;
}
BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
float *val = BMO_Get_MapData(bm, op, slotname, element);
if (val) return *val;
return 0.0f;
}
BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
void **val = BMO_Get_MapData(bm, op, slotname, element);
if (val) return *val;
return NULL;
}
#endif /* _BMESH_OPERATOR_H */

View File

@@ -20,16 +20,6 @@ static void clear_flag_layer(BMesh *bm);
static int bmesh_name_to_slotcode(BMOpDefine *def, char *name);
static int bmesh_opname_to_opcode(char *opname);
typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
/*mappings map elements to data, which
follows the mapping struct in memory.*/
typedef struct element_mapping {
BMHeader *element;
int len;
} element_mapping;
/*operator slot type information - size of one element of the type given.*/
const int BMOP_OPSLOT_TYPEINFO[] = {
0,
@@ -422,6 +412,17 @@ int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, char *slotname)
return slot->len;
}
int BMO_CountSlotMap(BMesh *bm, BMOperator *op, char *slotname)
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*check if its actually a buffer*/
if( !(slot->slottype == BMOP_OPSLOT_MAPPING) )
return 0;
return slot->data.ghash ? BLI_ghash_size(slot->data.ghash) : 0;
}
#if 0
void *BMO_Grow_Array(BMesh *bm, BMOperator *op, int slotcode, int totadd) {
BMOpSlot *slot = &op->slots[slotcode];
@@ -455,28 +456,6 @@ void *BMO_Grow_Array(BMesh *bm, BMOperator *op, int slotcode, int totadd) {
}
#endif
BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname,
void *element, void *data, int len) {
element_mapping *mapping;
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return;
mapping = BLI_memarena_alloc(op->arena, sizeof(*mapping) + len);
mapping->element = element;
mapping->len = len;
memcpy(mapping+1, data, len);
if (!slot->data.ghash) {
slot->data.ghash = BLI_ghash_new(BLI_ghashutil_ptrhash,
BLI_ghashutil_ptrcmp);
}
BLI_ghash_insert(slot->data.ghash, element, mapping);
}
void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
char *slotname, int flag)
{
@@ -494,64 +473,6 @@ void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
}
}
BM_INLINE void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
void *element, float val)
{
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(float));
}
BM_INLINE void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *element, void *val)
{
BMO_Insert_Mapping(bm, op, slotname, element, &val, sizeof(void*));
}
BM_INLINE int BMO_InMap(BMesh *bm, BMOperator *op, char *slotname, void *element)
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return 0;
if (!slot->data.ghash) return 0;
return BLI_ghash_haskey(slot->data.ghash, element);
}
BM_INLINE void *BMO_Get_MapData(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
element_mapping *mapping;
BMOpSlot *slot = BMO_GetSlot(op, slotname);
/*sanity check*/
if (slot->slottype != BMOP_OPSLOT_MAPPING) return NULL;
if (!slot->data.ghash) return NULL;
mapping = BLI_ghash_lookup(slot->data.ghash, element);
if (!mapping) return NULL;
return mapping + 1;
}
BM_INLINE float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
float *val = BMO_Get_MapData(bm, op, slotname, element);
if (val) return *val;
return 0.0f;
}
BM_INLINE void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
void *element)
{
void **val = BMO_Get_MapData(bm, op, slotname, element);
if (val) return *val;
return NULL;
}
static void *alloc_slot_buffer(BMOperator *op, char *slotname, int len){
int slotcode = bmesh_name_to_slotcode(opdefines[op->type], slotname);

View File

@@ -73,12 +73,11 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
vt[i] = v;
BMINDEX_SET(v, i);
/*transfer flags*/
v->head.flag = MEFlags_To_BMFlags(mvert->flag, BM_VERT);
/*this is necassary for selection counts to work properly*/
if(v->head.flag & BM_SELECT) BM_Select_Vert(bm, v, 1);
/*transfer flags*/
v->head.flag = MEFlags_To_BMFlags(mvert->flag, BM_VERT);
v->bweight = (float)mvert->bweight / 255.0f;
/*Copy Custom Data*/
@@ -103,11 +102,11 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
e->crease = (float)medge->crease / 255.0f;
e->bweight = (float)medge->bweight / 255.0f;
/*transfer flags*/
e->head.flag = MEFlags_To_BMFlags(medge->flag, BM_EDGE);
/*this is necassary for selection counts to work properly*/
if (e->head.flag & BM_SELECT) BM_Select(bm, e, 1);
/*transfer flags*/
e->head.flag = MEFlags_To_BMFlags(medge->flag, BM_EDGE);
}
if (!me->totpoly) {
@@ -145,12 +144,12 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
f = BM_Make_Ngon(bm, v1, v2, fedges, mpoly->totloop, 0);
/*transfer flags*/
f->head.flag = MEFlags_To_BMFlags(mpoly->flag, BM_FACE);
/*this is necassary for selection counts to work properly*/
if (f->head.flag & BM_SELECT) BM_Select(bm, f, 1);
/*transfer flags*/
f->head.flag = MEFlags_To_BMFlags(mpoly->flag, BM_FACE);
f->mat_nr = mpoly->mat_nr;
if (i == me->act_face) bm->act_face = f;

View File

@@ -166,6 +166,9 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
}
}
if (V_COUNT(loops) < 3)
continue;
v = loops[0]->v;
v2 = loops[1]->v;

View File

@@ -2622,3 +2622,60 @@ void MESH_OT_merge(wmOperatorType *ot)
RNA_def_enum_funcs(prop, merge_type_itemf);
RNA_def_boolean(ot->srna, "uvs", 1, "UVs", "Move UVs according to merge.");
}
static int removedoublesflag_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
BMOperator bmop;
char msg[100];
int count;
EDBM_InitOpf(em, &bmop, op, "finddoubles verts=%hv dist=%f",
BM_SELECT, RNA_float_get(op->ptr, "mergedist"));
BMO_Exec_Op(em->bm, &bmop);
count = BMO_CountSlotMap(em->bm, &bmop, "targetmapout");
if (!EDBM_CallOpf(em, op, "weldverts targetmap=%s", &bmop, "targetmapout")) {
BMO_Finish_Op(em->bm, &bmop);
return OPERATOR_CANCELLED;
}
if (!EDBM_FinishOp(em, &bmop, op, 1))
return OPERATOR_CANCELLED;
/*we need a better way of reporting this, since this doesn't work
with the last operator panel correctly.
if(count)
{
sprintf(msg, "Removed %d vertices", count);
BKE_report(op->reports, RPT_INFO, msg);
}
*/
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
void MESH_OT_remove_doubles(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove Doubles";
ot->idname= "MESH_OT_remove_doubles";
/* api callbacks */
ot->exec= removedoublesflag_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_float(ot->srna, "mergedist", 0.0001, 0.0001, 100.0,
"Merge Distance",
"Minimum distance between elements to merge.", 0.00001, 10.0);
}

View File

@@ -156,8 +156,10 @@ int EDBM_InitOpf(BMEditMesh *em, BMOperator *bmop, wmOperator *op, char *fmt, ..
va_end(list);
return 0;
}
em->emcopy = BMEdit_Copy(em);
if (!em->emcopy)
em->emcopy = BMEdit_Copy(em);
em->emcopyusers++;
va_end(list);
}
@@ -178,11 +180,20 @@ int EDBM_FinishOp(BMEditMesh *em, BMOperator *bmop, wmOperator *op, int report)
*em = *emcopy;
MEM_freeN(emcopy);
em->emcopyusers = 0;
em->emcopy = NULL;
return 0;
} else {
BMEdit_Free(em->emcopy);
MEM_freeN(em->emcopy);
em->emcopy = NULL;
em->emcopyusers--;
if (em->emcopyusers < 0) {
printf("warning: em->emcopyusers was less then zero.\n");
}
if (em->emcopyusers <= 0) {
BMEdit_Free(em->emcopy);
MEM_freeN(em->emcopy);
em->emcopy = NULL;
}
}
return 1;
@@ -203,7 +214,9 @@ int EDBM_CallOpf(BMEditMesh *em, wmOperator *op, char *fmt, ...)
return 0;
}
em->emcopy = BMEdit_Copy(em);
if (!em->emcopy)
em->emcopy = BMEdit_Copy(em);
em->emcopyusers++;
BMO_Exec_Op(bm, &bmop);
@@ -224,7 +237,9 @@ int EDBM_CallOpfSilent(BMEditMesh *em, char *fmt, ...)
return 0;
}
em->emcopy = BMEdit_Copy(em);
if (!em->emcopy)
em->emcopy = BMEdit_Copy(em);
em->emcopyusers++;
BMO_Exec_Op(bm, &bmop);

View File

@@ -484,42 +484,6 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit) /
return a; /* amount */
}
static int removedoublesflag_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
char msg[100];
int cnt = removedoublesflag(em,1,0,scene->toolsettings->doublimit);
if(cnt)
{
sprintf(msg, "Removed %d vertices", cnt);
BKE_report(op->reports, RPT_INFO, msg);
}
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_FINISHED;
}
void MESH_OT_remove_doubles(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove Doubles";
ot->idname= "MESH_OT_remove_doubles";
/* api callbacks */
ot->exec= removedoublesflag_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
// XXX is this needed?
/* called from buttons */
static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y, int index)