diff options
author | Daniel Dunbar <daniel@zuster.org> | 2005-08-22 00:48:45 +0400 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2005-08-22 00:48:45 +0400 |
commit | dd7bcb94bf73d219f29febf6bccccf46448a4811 (patch) | |
tree | c9f3748b9b379ab07b7190a1ee30a575df273be0 | |
parent | 5a381a5a1222e3774df77d8223c3c0ee332260f2 (diff) |
- sillyness... added drawMappedEdges for mesh
- revert to drawLooseEdges instead of general drawEdgesFlag
- ditched TFace edge flags, done dynamically now which also
means don't need to recalc surface on flag changes
- added BLI_edgehash, guess what it does
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 83 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_edgehash.h | 70 | ||||
-rw-r--r-- | source/blender/blenlib/SConscript | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/edgehash.c | 161 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 6 | ||||
-rw-r--r-- | source/blender/src/drawmesh.c | 187 | ||||
-rw-r--r-- | source/blender/src/drawobject.c | 4 | ||||
-rw-r--r-- | source/blender/src/editsima.c | 4 |
11 files changed, 435 insertions, 119 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 9c0d87b0254..65f7fbeb5cb 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -121,8 +121,8 @@ struct DerivedMesh { */ void (*drawEdges)(DerivedMesh *dm, int drawLooseEdges); - /* Draw all edges for which (med->flag&mask)==value */ - void (*drawEdgesFlag)(DerivedMesh *dm, unsigned int mask, unsigned int value); + /* Draw all loose edges (edges w/ no adjoining faces) */ + void (*drawLooseEdges)(DerivedMesh *dm); /* Draw all faces * o Set face normal or vertex normal based on inherited face flag diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index b323377bb84..00d7cf5805a 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -212,7 +212,22 @@ static void meshDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) } glEnd(); } -static void meshDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int value) +static void meshDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) +{ + MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; + Mesh *me= mdm->me; + int i; + + glBegin(GL_LINES); + for (i=0; i<me->totedge; i++) { + if (!setDrawOptions || setDrawOptions(userData, i)) { + glVertex3fv(mdm->verts[me->medge[i].v1].co); + glVertex3fv(mdm->verts[me->medge[i].v2].co); + } + } + glEnd(); +} +static void meshDM_drawLooseEdges(DerivedMesh *dm) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; Mesh *me= mdm->me; @@ -222,7 +237,7 @@ static void meshDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned in glBegin(GL_LINES); for(a=me->totedge; a>0; a--, medge++) { - if (((medge->flag|ME_EDGEMAPPED)&mask)==value) { + if (medge->flag&ME_LOOSEEDGE) { glVertex3fv(mdm->verts[medge->v1].co); glVertex3fv(mdm->verts[medge->v2].co); } @@ -484,11 +499,13 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3] mdm->dm.drawUVEdges = meshDM_drawUVEdges; mdm->dm.drawEdges = meshDM_drawEdges; - mdm->dm.drawEdgesFlag = meshDM_drawEdgesFlag; + mdm->dm.drawLooseEdges = meshDM_drawLooseEdges; mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; mdm->dm.drawFacesColored = meshDM_drawFacesColored; mdm->dm.drawFacesTex = meshDM_drawFacesTex; + + mdm->dm.drawMappedEdges = meshDM_drawMappedEdges; mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; mdm->dm.release = meshDM_release; @@ -1013,18 +1030,17 @@ static void ssDM_drawUVEdges(DerivedMesh *dm) glEnd(); } } -static void ssDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int value) +static void ssDM_drawLooseEdges(DerivedMesh *dm) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; MVert *mvert = dlm->mvert; MEdge *medge= dlm->medge; - int tfaceFlags = (ME_EDGE_TFSEL|ME_EDGE_TFACT|ME_EDGE_TFVISIBLE|ME_EDGE_TFACTFIRST|ME_EDGE_TFACTLAST); int i; glBegin(GL_LINES); for (i=0; i<dlm->totedge; i++, medge++) { - if ((medge->flag&mask)==value) { + if (medge->flag&ME_LOOSEEDGE) { glVertex3fv(mvert[medge->v1].co); glVertex3fv(mvert[medge->v2].co); } @@ -1319,7 +1335,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos) ssdm->dm.drawUVEdges = ssDM_drawUVEdges; ssdm->dm.drawEdges = ssDM_drawEdges; - ssdm->dm.drawEdgesFlag = ssDM_drawEdgesFlag; + ssdm->dm.drawLooseEdges = ssDM_drawLooseEdges; ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid; ssdm->dm.drawFacesColored = ssDM_drawFacesColored; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index db2cfe7c2d2..532317a6520 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -518,7 +518,7 @@ static DispListMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, DispListM *med = *inMED; med->v1 = indexMap[inMED->v1][0]; med->v2 = indexMap[inMED->v2][0]; - if (initFlags) med->flag |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED|ME_EDGE_STEPINDEX; + if (initFlags) med->flag |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGE_STEPINDEX; if (indexMap[inMED->v1][1] || indexMap[inMED->v2][1]) { MEdge *med2 = &dlm->medge[dlm->totedge++]; @@ -687,7 +687,7 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * med->v1 = (int) eed->v1->prev; med->v2 = (int) eed->v2->prev; med->crease = (unsigned char) (eed->crease*255.0f); - med->flag = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED|ME_EDGE_STEPINDEX; + med->flag = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGE_STEPINDEX; if (eed->seam) med->flag |= ME_SEAM; if (!eed->f2) med->flag |= ME_LOOSEEDGE; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 745c64103ba..03986a025ba 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -197,63 +197,27 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface) { unsigned int flags = 0; - int j, N = ccgSubSurf_getEdgeNumFaces(ss, e); + int N = ccgSubSurf_getEdgeNumFaces(ss, e); if (!N) flags |= ME_LOOSEEDGE; if (ssFromEditmesh) { EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e); - flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED; + flags |= ME_EDGEDRAW|ME_EDGERENDER; if (eed->seam) { flags |= ME_SEAM; } } else { int makeFlags = 0, edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e); - if (edgeIdx==-1) { - if (!medge) { - makeFlags = 1; - } - } else if (medge) { // can happen for loose edges on mesh with no medge + if (edgeIdx!=-1) { MEdge *origMed = &medge[edgeIdx]; if (dlm) { flags |= origMed->flag&~ME_EDGE_STEPINDEX; } else { - flags |= (origMed->flag&ME_SEAM); - makeFlags = 1; - } - } else { - makeFlags = 1; - } - - if (makeFlags) { - flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED; - - if (tface) { - for (j=0; j<N; j++) { - CCGFace *f = ccgSubSurf_getEdgeFace(ss, e, j); - int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f); - TFace *tf = &tface[origIdx]; - - if (!(tf->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE; - if (tf->flag&TF_SELECT) flags |= ME_EDGE_TFSEL; - - if (tf->flag&TF_ACTIVE) { - int fN = ccgSubSurf_getFaceNumVerts(ss, f); - int k = ccgSubSurf_getFaceEdgeIndex(ss, f, e); - - flags |= ME_EDGE_TFACT; - - if (k==0) { - flags |= ME_EDGE_TFACTFIRST; - } - else if (k==fN-1) { - flags |= ME_EDGE_TFACTLAST; - } - } - } + flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER; } } } @@ -450,9 +414,32 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i lastIndex = -1; for (index=0; index<totedge; index++) { CCGEdge *e= edgeMap2[index]; - unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, inDLM, medge, tface); int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e); int edgeStart = i; + unsigned int flags = 0; + + if (!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE; + + if (ssFromEditmesh) { + EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e); + + flags |= ME_EDGEDRAW|ME_EDGERENDER; + if (eed->seam) { + flags |= ME_SEAM; + } + } else { + int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e); + + if (edgeIdx!=-1) { + MEdge *origMed = &medge[edgeIdx]; + + if (inDLM) { + flags |= origMed->flag&~ME_EDGE_STEPINDEX; + } else { + flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER; + } + } + } for (x=0; x<edgeSize-1; x++) { MEdge *med = &dlm->medge[i]; @@ -974,25 +961,17 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) { ccgFaceIterator_free(fi); ccgEdgeIterator_free(ei); } -static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int value) { +static void ccgDM_drawLooseEdges(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); int i, edgeSize = ccgSubSurf_getEdgeSize(ss); - MEdge *medge = NULL; - TFace *tface = NULL; - - if (!ccgdm->fromEditmesh) { - medge = ccgdm->dlm?ccgdm->dlm->medge:ccgdm->me->medge; - tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface; - } for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - unsigned int flags = ss_getEdgeFlags(ss, e, ccgdm->fromEditmesh, ccgdm->dlm, medge, tface); - if ((flags&mask)==value) { + if (!ccgSubSurf_getEdgeNumFaces(ss, e)) { glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize-1; i++) { glVertex3fv(edgeData[i].co); @@ -1417,7 +1396,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d ccgdm->dm.drawVerts = ccgDM_drawVerts; ccgdm->dm.drawEdges = ccgDM_drawEdges; - ccgdm->dm.drawEdgesFlag = ccgDM_drawEdgesFlag; + ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges; ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored; ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h new file mode 100644 index 00000000000..33ae8a5d5e2 --- /dev/null +++ b/source/blender/blenlib/BLI_edgehash.h @@ -0,0 +1,70 @@ +/** + * A general unordered 2-int pair hash table ADT + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: none of this file. + * + * Contributor(s): Daniel Dunbar + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_EDGEHASH_H +#define BLI_EDGEHASH_H + +struct EdgeHash; +typedef struct EdgeHash EdgeHash; + +typedef void (*EdgeHashFreeFP)(void *key); + +EdgeHash* BLI_edgehash_new (void); +void BLI_edgehash_free (EdgeHash *eh, EdgeHashFreeFP valfreefp); + + /* Insert edge (v0,v1) into hash with given value, does + * not check for duplicates. + */ +void BLI_edgehash_insert (EdgeHash *eh, int v0, int v1, void *val); + + /* Return value for given edge (v0,v1), or NULL if + * if key does not exist in hash. (If need exists + * to differentiate between key-value being NULL and + * lack of key then see BLI_edgehash_lookup_p(). + */ +void* BLI_edgehash_lookup (EdgeHash *eh, int v0, int v1); + + /* Return pointer to value for given edge (v0,v1), + * or NULL if key does not exist in hash. + */ +void** BLI_edgehash_lookup_p (EdgeHash *eh, int v0, int v1); + + /* Return boolean true/false if edge (v0,v1) in hash. */ +int BLI_edgehash_haskey (EdgeHash *eh, int v0, int v1); + + /* Return number of keys in hash. */ +int BLI_edgehash_size (EdgeHash *eh); + +#endif + diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index a4882587618..379817cc322 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -7,6 +7,7 @@ blenlib_env = library_env.Copy () source_files = ['intern/BLI_dynstr.c', 'intern/BLI_ghash.c', + 'intern/edgehash.c', 'intern/BLI_linklist.c', 'intern/BLI_memarena.c', 'intern/arithb.c', diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c new file mode 100644 index 00000000000..538128a45d5 --- /dev/null +++ b/source/blender/blenlib/intern/edgehash.c @@ -0,0 +1,161 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: none of this file. + * + * Contributor(s): Daniel Dunbar + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * A general (pointer -> pointer) hash table ADT + */ + +#include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" +#include "BLI_edgehash.h" + +/***/ + +static unsigned int hashsizes[]= { + 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, + 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, + 268435459 +}; + +#define EDGEHASH(v0,v1) ((v0*39)^(v1*31)) + +/***/ + +typedef struct Entry Entry; +struct Entry { + Entry *next; + int v0, v1; + void *val; +}; + +struct EdgeHash { + Entry **buckets; + int nbuckets, nentries, cursize; +}; + +/***/ + +EdgeHash *BLI_edgehash_new(void) { + EdgeHash *eh= MEM_mallocN(sizeof(*eh), "EdgeHash"); + eh->cursize= 0; + eh->nentries= 0; + eh->nbuckets= hashsizes[eh->cursize]; + + eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets)); + memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); + + return eh; +} + +void BLI_edgehash_insert(EdgeHash *eh, int v0, int v1, void *val) { + unsigned int hash; + Entry *e= malloc(sizeof(*e)); + + if (v1<v0) v0 ^= v1 ^= v0 ^= v1; + hash = EDGEHASH(v0,v1)%eh->nbuckets; + + e->v0 = v0; + e->v1 = v1; + e->val = val; + e->next= eh->buckets[hash]; + eh->buckets[hash]= e; + + if (++eh->nentries>eh->nbuckets*3) { + Entry *e, **old= eh->buckets; + int i, nold= eh->nbuckets; + + eh->nbuckets= hashsizes[++eh->cursize]; + eh->buckets= malloc(eh->nbuckets*sizeof(*eh->buckets)); + memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); + + for (i=0; i<nold; i++) { + for (e= old[i]; e;) { + Entry *n= e->next; + + hash= EDGEHASH(e->v0,e->v1)%eh->nbuckets; + e->next= eh->buckets[hash]; + eh->buckets[hash]= e; + + e= n; + } + } + + free(old); + } +} + +void** BLI_edgehash_lookup_p(EdgeHash *eh, int v0, int v1) { + unsigned int hash; + Entry *e; + + if (v1<v0) v0 ^= v1 ^= v0 ^= v1; + hash = EDGEHASH(v0,v1)%eh->nbuckets; + for (e= eh->buckets[hash]; e; e= e->next) + if (v0==e->v0 && v1==e->v1) + return &e->val; + + return NULL; +} + +void* BLI_edgehash_lookup(EdgeHash *eh, int v0, int v1) { + void **value_p = BLI_edgehash_lookup_p(eh,v0,v1); + + return value_p?*value_p:NULL; +} + +int BLI_edgehash_haskey(EdgeHash *eh, int v0, int v1) { + return BLI_edgehash_lookup_p(eh, v0, v1)!=NULL; +} + +int BLI_edgehash_size(EdgeHash *eh) { + return eh->nentries; +} + +void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { + int i; + + for (i=0; i<eh->nbuckets; i++) { + Entry *e; + + for (e= eh->buckets[i]; e; ) { + Entry *n= e->next; + + if (valfreefp) valfreefp(e->val); + free(e); + + e= n; + } + } + + free(eh->buckets); + MEM_freeN(eh); +} diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index eb46a146ad3..b240572c4b5 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -83,13 +83,7 @@ typedef struct MSticky { #define ME_FGON (1<<3) // reserve 16 for ME_HIDE #define ME_EDGERENDER (1<<5) -#define ME_EDGEMAPPED (1<<6) #define ME_LOOSEEDGE (1<<7) -#define ME_EDGE_TFSEL (1<<8) -#define ME_EDGE_TFACT (1<<9) -#define ME_EDGE_TFVISIBLE (1<<10) -#define ME_EDGE_TFACTFIRST (1<<11) -#define ME_EDGE_TFACTLAST (1<<12) #define ME_EDGE_STEPINDEX (1<<15) /* puno = vertexnormal (mface) */ diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index c33588d0dff..acf81405547 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -41,6 +41,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_edgehash.h" #include "IMB_imbuf_types.h" @@ -488,7 +489,135 @@ void update_realtime_textures() } } +/***/ + + /* Flags for marked edges */ +enum { + eEdge_Visible = (1<<0), + eEdge_Select = (1<<1), + eEdge_Active = (1<<2), + eEdge_SelectAndActive = (1<<3), + eEdge_ActiveFirst = (1<<4), + eEdge_ActiveLast = (1<<5) +}; + + /* Creates a hash of edges to flags indicating + * adjacent tface select/active/etc flags. + */ +static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags) +{ + int *flags_p; + + if (!BLI_edgehash_haskey(eh, v0, v1)) { + BLI_edgehash_insert(eh, v0, v1, 0); + } + + flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1); + *flags_p |= flags; +} +static EdgeHash *get_marked_edge_info(Mesh *me) +{ + EdgeHash *eh = BLI_edgehash_new(); + int i; + + for (i=0; i<me->totface; i++) { + MFace *mf = &me->mface[i]; + TFace *tf = &me->tface[i]; + + if (mf->v3) { + if (!(tf->flag&TF_HIDE)) { + unsigned int flags = eEdge_Visible; + if (tf->flag&TF_SELECT) flags |= eEdge_Select; + if (tf->flag&TF_ACTIVE) { + flags |= eEdge_Active; + if (tf->flag&TF_SELECT) flags |= eEdge_SelectAndActive; + } + + get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags); + get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags); + if (mf->v4) { + get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags); + get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags); + } else { + get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags); + } + + if (tf->flag&TF_ACTIVE) { + get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, eEdge_ActiveFirst); + get_marked_edge_info__orFlags(eh, mf->v1, mf->v4?mf->v4:mf->v3, eEdge_ActiveLast); + } + } + } + } + return eh; +} + + +static int draw_tfaces3D__setHiddenOpts(void *userData, int index) +{ + struct { Mesh *me; EdgeHash *eh; } *data = userData; + MEdge *med = &data->me->medge[index]; + unsigned int flags = (int) BLI_edgehash_lookup(data->eh, med->v1, med->v2); + + if((G.f & G_DRAWSEAMS) && (med->flag&ME_SEAM)) { + return 0; + } else if(G.f & G_DRAWEDGES){ + if (G.f&G_HIDDENEDGES) { + return 1; + } else { + return (flags & eEdge_Visible); + } + } else { + return (flags & eEdge_Select); + } +} +static int draw_tfaces3D__setSeamOpts(void *userData, int index) +{ + struct { Mesh *me; EdgeHash *eh; } *data = userData; + MEdge *med = &data->me->medge[index]; + unsigned int flags = (int) BLI_edgehash_lookup(data->eh, med->v1, med->v2); + + if (med->flag&ME_SEAM) { + if (G.f&G_HIDDENEDGES) { + return 1; + } else { + return (flags & eEdge_Visible); + } + } else { + return 0; + } +} +static int draw_tfaces3D__setSelectOpts(void *userData, int index) +{ + struct { Mesh *me; EdgeHash *eh; } *data = userData; + MEdge *med = &data->me->medge[index]; + unsigned int flags = (int) BLI_edgehash_lookup(data->eh, med->v1, med->v2); + + return flags & eEdge_Select; +} +static int draw_tfaces3D__setActiveOpts(void *userData, int index) +{ + struct { Mesh *me; EdgeHash *eh; } *data = userData; + MEdge *med = &data->me->medge[index]; + unsigned int flags = (int) BLI_edgehash_lookup(data->eh, med->v1, med->v2); + + if (flags & eEdge_Active) { + if (flags & eEdge_ActiveLast) { + glColor3ub(255, 0, 0); + } else if (flags & eEdge_ActiveFirst) { + glColor3ub(0, 255, 0); + } else if (flags & eEdge_SelectAndActive) { + glColor3ub(255, 255, 0); + } else { + glColor3ub(255, 0, 255); + } + + return 1; + } else { + return 0; + } +} static int draw_tfaces3D__drawFaceOpts(TFace *tface, int matnr) { if (tface && !(tface->flag&TF_HIDE) && (tface->flag&TF_SELECT)) { @@ -499,7 +628,10 @@ static int draw_tfaces3D__drawFaceOpts(TFace *tface, int matnr) } static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm) { - int a; + struct { Mesh *me; EdgeHash *eh; } data; + + data.me = me; + data.eh = get_marked_edge_info(me); glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); @@ -507,30 +639,19 @@ static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm) /* Draw (Hidden) Edges */ BIF_ThemeColor(TH_EDGE_FACESEL); - if((G.f & G_DRAWEDGES)){ - if (G.f&G_HIDDENEDGES) { - dm->drawEdgesFlag(dm, ME_EDGEMAPPED, ME_EDGEMAPPED); - } else { - dm->drawEdgesFlag(dm, ME_EDGE_TFVISIBLE, ME_EDGE_TFVISIBLE); - } - } else { - dm->drawEdgesFlag(dm, ME_EDGE_TFVISIBLE|ME_EDGE_TFSEL, ME_EDGE_TFVISIBLE|ME_EDGE_TFSEL); - } + dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data); + /* Draw Seams */ if(G.f & G_DRAWSEAMS) { BIF_ThemeColor(TH_EDGE_SEAM); glLineWidth(2); - if (G.f&G_HIDDENEDGES) { - dm->drawEdgesFlag(dm, ME_EDGEMAPPED|ME_SEAM, ME_EDGEMAPPED|ME_SEAM); - } else { - dm->drawEdgesFlag(dm, ME_EDGE_TFVISIBLE|ME_SEAM, ME_EDGE_TFVISIBLE|ME_SEAM); - } + dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data); glLineWidth(1); } - /* Draw Selected Faces in transparent purple */ + /* Draw Selected Faces */ if(G.f & G_DRAWFACES) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -544,38 +665,16 @@ static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm) bglPolygonOffset(1.0); /* Draw Stippled Outline for selected faces */ - cpack(0xFFFFFF); + glColor3ub(255, 255, 255); setlinestyle(1); - dm->drawEdgesFlag(dm, ME_EDGE_TFVISIBLE|ME_EDGE_TFSEL, ME_EDGE_TFVISIBLE|ME_EDGE_TFSEL); + dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data); setlinestyle(0); - /* Draw active face */ - for (a=0; a<me->totface; a++) { - TFace *tf = &me->tface[a]; - - if (me->mface[a].v3 && (tf->flag&TF_ACTIVE)) { - if (!(tf->flag&TF_HIDE)) { - glColor3ub(255, 0, 0); - dm->drawEdgesFlag(dm, ME_EDGE_TFACTLAST, ME_EDGE_TFACTLAST); - glColor3ub(0, 255, 0); - dm->drawEdgesFlag(dm, ME_EDGE_TFACTFIRST, ME_EDGE_TFACTFIRST); - - if (tf->flag&TF_SELECT) { - glColor3ub(255, 255, 0); - } else { - glColor3ub(255, 0, 255); - } - - /* Draw remaining edges of active fact that are not first or last */ - dm->drawEdgesFlag(dm, ME_EDGE_TFACT|ME_EDGE_TFACTFIRST|ME_EDGE_TFACTLAST, ME_EDGE_TFACT|0|0); - } - - break; - } - } + dm->drawMappedEdges(dm, draw_tfaces3D__setActiveOpts, &data); bglPolygonOffset(0.0); // resets correctly now, even after calling accumulated offsets -#undef PASSVERT + + BLI_edgehash_free(data.eh, NULL); } static int set_gl_light(Object *ob) @@ -930,7 +1029,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt) } else { BIF_ThemeColor(TH_WIRE); } - dm->drawEdgesFlag(dm, ME_LOOSEEDGE, ME_LOOSEEDGE); + dm->drawLooseEdges(dm); } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 45c165c95ff..10631e74ecc 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -1733,7 +1733,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in } else { BIF_ThemeColor(TH_WIRE); } - dm->drawEdgesFlag(dm, ME_LOOSEEDGE, ME_LOOSEEDGE); + dm->drawLooseEdges(dm); } else if(dt==OB_SHADED) { if( (G.f & G_WEIGHTPAINT)) { @@ -1772,7 +1772,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in } else { BIF_ThemeColor(TH_WIRE); } - dm->drawEdgesFlag(dm, ME_LOOSEEDGE, ME_LOOSEEDGE); + dm->drawLooseEdges(dm); } } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 4c241290d78..6f79f1daae9 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -115,10 +115,6 @@ void object_uvs_changed(Object *ob) void object_tface_flags_changed(Object *ob, int updateButtons) { - if (G.f&G_FACESELECT) { - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - if (updateButtons) allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWIMAGE, 0); |