finished removedoubles, and inlined a bunch of functions.
This commit is contained in:
@@ -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.*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user