diff options
Diffstat (limited to 'source')
25 files changed, 1157 insertions, 1164 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 99d438743fa..9c0d87b0254 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -48,9 +48,6 @@ struct MVert; struct Object; struct EditMesh; -struct EditVert; -struct EditEdge; -struct EditFace; struct DispListMesh; struct ModifierData; @@ -68,19 +65,19 @@ struct DerivedMesh { * coordinate and normal. For historical reasons the normal can be * passed as a float or short array, only one should be non-NULL. */ - void (*foreachMappedVertEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditVert *vert, float *co, float *no_f, short *no_s), void *userData); + void (*foreachMappedVert)(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData); /* Iterate over each mapped vertex in the derived mesh, calling the * given function with the original vert and the mapped edge's new * coordinates. */ - void (*foreachMappedEdgeEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditEdge *edge, float *v0co, float *v1co), void *userData); + void (*foreachMappedEdge)(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData); /* Iterate over each mapped face in the derived mesh, calling the * given function with the original face and the mapped face's (or * faces') center and normal. */ - void (*foreachMappedFaceCenterEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditFace *face, float *cent, float *no), void *userData); + void (*foreachMappedFaceCenter)(DerivedMesh *dm, void (*func)(void *userData, int index, float *cent, float *no), void *userData); /* Convert to new DispListMesh, should be free'd by caller. * @@ -91,18 +88,6 @@ struct DerivedMesh { */ struct DispListMesh* (*convertToDispListMesh)(DerivedMesh *dm, int allowShared); - /* Convert to new DispListMesh, should be free'd by caller. - * - * Additionally, allocate and return map arrays. Each map array should be - * have a length corresponding to the returned DLMs totvert, totedge, and - * totface fields respectively. - * - * Each index in the array should give the EditMesh element from which the - * element at the same index in the DLMs vert, edge, or face array was - * derived (which may be null). - */ - struct DispListMesh* (*convertToDispListMeshMapped)(DerivedMesh *dm, int allowShared, struct EditVert ***vertMap_r, struct EditEdge ***edgeMap_r, struct EditFace ***faceMap_r); - /* Iterate over all vertex points, calling DO_MINMAX with given args. * * Also called in Editmode @@ -158,33 +143,40 @@ struct DerivedMesh { /* Draw all faces uses TFace * o Drawing options too complicated to enumerate, look at code. */ - void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)); + void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(TFace *tf, int matnr)); + + /* Draw mapped faces (no color, or texture) + * o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true + * + * If drawSmooth is set to true then vertex normals should be set and glShadeModel + * called with GL_SMOOTH. Otherwise the face normal should be set and glShadeModel + * called with GL_FLAT. + * + * The setDrawOptions is allowed to not set drawSmooth (for example, when lighting + * is disabled), in which case the implementation should draw as smooth shaded. + */ + void (*drawMappedFaces)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData); /* Draw mapped edges as lines * o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true */ - void (*drawMappedEdgesEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditEdge *eed), void *userData); + void (*drawMappedEdges)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData); /* Draw mapped edges as lines with interpolation values * o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t) returns true * * NOTE: This routine is optional! */ - void (*drawMappedEdgesInterpEM)(DerivedMesh *dm, - int (*setDrawOptions)(void *userData, struct EditEdge *eed), - void (*setDrawInterpOptions)(void *userData, struct EditEdge *eed, float t), + void (*drawMappedEdgesInterp)(DerivedMesh *dm, + int (*setDrawOptions)(void *userData, int index), + void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData); - /* Draw all faces - * o Only if !setDrawOptions or setDrawOptions(userData, mapped-face) returns true - */ - void (*drawMappedFacesEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData); - void (*release)(DerivedMesh *dm); }; /* Internal function, just temporarily exposed */ -DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap); +DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3]); DerivedMesh *mesh_get_derived_final(struct Object *ob, int *needsFree_r); DerivedMesh *mesh_get_derived_deform(struct Object *ob, int *needsFree_r); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7c28297194e..f3d878d5341 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -43,6 +43,7 @@ struct MDeformVert; struct Mesh; struct MFace; struct MVert; +struct MCol; struct Object; struct TFace; struct VecNor; @@ -61,9 +62,7 @@ void boundbox_mesh(struct Mesh *me, float *loc, float *size); void tex_space_mesh(struct Mesh *me); float *mesh_create_orco_render(struct Object *ob); float *mesh_create_orco(struct Object *ob); -void test_index_mface(struct MFace *mface, int nr); -void test_index_face(struct MFace *mface, struct TFace *tface, int nr); -void flipnorm_mesh(struct Mesh *me); +void test_index_face(struct MFace *mface, struct MCol *mc, struct TFace *tface, int nr); struct Mesh *get_mesh(struct Object *ob); void set_mesh(struct Object *ob, struct Mesh *me); void mball_to_mesh(struct ListBase *lb, struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index dbcc2dd3e17..2289fb027eb 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -35,13 +35,10 @@ struct Mesh; struct Object; struct DerivedMesh; struct EditMesh; -struct EditVert; -struct EditEdge; -struct EditFace; struct SubsurfModifierData; struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd, float (*vertexCos)[3]); -struct DerivedMesh *subsurf_make_derived_from_dlm_em(struct DispListMesh *dlm, struct SubsurfModifierData *smd, float (*vertCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap); +struct DerivedMesh *subsurf_make_derived_from_dlm_em(struct DispListMesh *dlm, struct SubsurfModifierData *smd, float (*vertCos)[3]); struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc); void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]); diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 2ed7d60e57e..75099157fd7 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -693,6 +693,10 @@ CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation, return eCCGError_None; } +void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r) { + if (allowEdgeCreation_r) *allowEdgeCreation_r = ss->allowEdgeCreation; + if (defaultCreaseValue_r) *defaultCreaseValue_r = ss->defaultCreaseValue; +} CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels) { if (subdivisionLevels<=0) { @@ -850,9 +854,9 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) { return eCCGError_None; } -CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData) { +CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r) { void **prevp; - CCGVert *v; + CCGVert *v = NULL; if (ss->syncState==eSyncState_Partial) { v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); @@ -902,12 +906,13 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData) { } } + if (v_r) *v_r = v; return eCCGError_None; } -CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease) { +CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r) { void **prevp; - CCGEdge *e, *eNew; + CCGEdge *e = NULL, *eNew; if (ss->syncState==eSyncState_Partial) { e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); @@ -955,12 +960,13 @@ CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0 } } + if (e_r) *e_r = e; return eCCGError_None; } -CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs) { +CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r) { void **prevp; - CCGFace *f, *fNew; + CCGFace *f = NULL, *fNew; int j, k, topologyChanged = 0; if (numVerts>ss->lenTempArrays) { @@ -1065,6 +1071,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV } } + if (f_r) *f_r = f; return eCCGError_None; } diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 547580bca6e..f6469866d32 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -5,6 +5,10 @@ typedef void* CCGVertHDL; typedef void* CCGEdgeHDL; typedef void* CCGFaceHDL; +typedef struct _CCGVert CCGVert; +typedef struct _CCGEdge CCGEdge; +typedef struct _CCGFace CCGFace; + typedef struct _CCGMeshIFC CCGMeshIFC; struct _CCGMeshIFC { int vertUserSize, edgeUserSize, faceUserSize; @@ -45,9 +49,9 @@ CCGError ccgSubSurf_sync (CCGSubSurf *ss); CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss); CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss); -CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData); -CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease); -CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs); +CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r); +CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r); +CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r); CCGError ccgSubSurf_syncVertDel (CCGSubSurf *ss, CCGVertHDL vHDL); CCGError ccgSubSurf_syncEdgeDel (CCGSubSurf *ss, CCGEdgeHDL eHDL); @@ -58,16 +62,15 @@ CCGError ccgSubSurf_processSync (CCGSubSurf *ss); CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels); CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue); +void ccgSubSurf_getAllowEdgeCreation (CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r); + void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r); CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset); + CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset); /***/ -typedef struct _CCGVert CCGVert; -typedef struct _CCGEdge CCGEdge; -typedef struct _CCGFace CCGFace; - int ccgSubSurf_getNumVerts (CCGSubSurf *ss); int ccgSubSurf_getNumEdges (CCGSubSurf *ss); int ccgSubSurf_getNumFaces (CCGSubSurf *ss); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index eda5e3ff485..d2d17c322de 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -466,7 +466,6 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch glShadeModel(GL_FLAT); glDisable(GL_CULL_FACE); } - static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; @@ -526,6 +525,54 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, glEnd(); } } +static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) +{ + MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; + Mesh *me = mdm->me; + MVert *mvert= mdm->verts; + MFace *mface= me->mface; + float *nors= mdm->nors; + int a, glmode, shademodel; + + glShadeModel(shademodel = GL_SMOOTH); + glBegin(glmode = GL_QUADS); + for (a=0; a<me->totface; a++) { + MFace *mf= &mface[a]; + int drawSmooth = 1; + + if (mf->v3 && setDrawOptions(userData, a, &drawSmooth)) { + int newmode = mf->v4?GL_QUADS:GL_TRIANGLES; + int newshademodel = drawSmooth?GL_SMOOTH:GL_FLAT; + + if (newmode!=glmode || newshademodel!=shademodel) { + glEnd(); + glShadeModel(shademodel = newshademodel); + glBegin(glmode = newmode); + } + + if (shademodel==GL_FLAT) { + glNormal3fv(&nors[a*3]); + + glVertex3fv(mvert[mf->v1].co); + glVertex3fv(mvert[mf->v2].co); + glVertex3fv(mvert[mf->v3].co); + if(mf->v4) glVertex3fv(mvert[mf->v4].co); + } else { + glNormal3sv(mvert[mf->v1].no); + glVertex3fv(mvert[mf->v1].co); + glNormal3sv(mvert[mf->v2].no); + glVertex3fv(mvert[mf->v2].co); + glNormal3sv(mvert[mf->v3].no); + glVertex3fv(mvert[mf->v3].co); + if(mf->v4) { + glNormal3sv(mvert[mf->v4].no); + glVertex3fv(mvert[mf->v4].co); + } + } + } + } + glEnd(); +} static int meshDM_getNumVerts(DerivedMesh *dm) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; @@ -573,6 +620,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3] mdm->dm.drawFacesSolid = meshDM_drawFacesSolid; mdm->dm.drawFacesColored = meshDM_drawFacesColored; mdm->dm.drawFacesTex = meshDM_drawFacesTex; + mdm->dm.drawMappedFaces = meshDM_drawMappedFaces; mdm->dm.release = meshDM_release; @@ -616,58 +664,55 @@ typedef struct { float (*faceNos)[3]; } EditMeshDerivedMesh; -static void emDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) +static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditVert *eve; + int i; - if (emdm->vertexCos) { - int i; - - for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { - func(userData, eve, emdm->vertexCos[i], emdm->vertexNos[i], NULL); - } - } else { - for (eve= emdm->em->verts.first; eve; eve=eve->next) { - func(userData, eve, eve->co, eve->no, NULL); + for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { + if (emdm->vertexCos) { + func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL); + } else { + func(userData, i, eve->co, eve->no, NULL); } } } -static void emDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) +static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditEdge *eed; + int i; if (emdm->vertexCos) { EditVert *eve, *preveve; - int i; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; - for(eed= emdm->em->edges.first; eed; eed= eed->next) - func(userData, eed, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]); + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) + func(userData, i, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]); for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next) eve->prev = preveve; } else { - for(eed= emdm->em->edges.first; eed; eed= eed->next) - func(userData, eed, eed->v1->co, eed->v2->co); + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) + func(userData, i, eed->v1->co, eed->v2->co); } } -static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) +static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditEdge *eed; + int i; if (emdm->vertexCos) { EditVert *eve, *preveve; - int i; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]); glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]); } @@ -678,8 +723,8 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void * eve->prev = preveve; } else { glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { + for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { glVertex3fv(eed->v1->co); glVertex3fv(eed->v2->co); } @@ -689,26 +734,26 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void * } static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) { - emDM_drawMappedEdgesEM(dm, NULL, NULL); + emDM_drawMappedEdges(dm, NULL, NULL); } -static void emDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) +static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditEdge *eed; + int i; if (emdm->vertexCos) { EditVert *eve, *preveve; - int i; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { - setDrawInterpOptions(userData, eed, 0.0); + for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { + setDrawInterpOptions(userData, i, 0.0); glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]); - setDrawInterpOptions(userData, eed, 1.0); + setDrawInterpOptions(userData, i, 1.0); glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]); } } @@ -718,11 +763,11 @@ static void emDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)( eve->prev = preveve; } else { glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { - setDrawInterpOptions(userData, eed, 0.0); + for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, i)) { + setDrawInterpOptions(userData, i, 0.0); glVertex3fv(eed->v1->co); - setDrawInterpOptions(userData, eed, 1.0); + setDrawInterpOptions(userData, i, 1.0); glVertex3fv(eed->v2->co); } } @@ -749,22 +794,22 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[ VecMulf(cent, 0.33333333333f); } } -static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) +static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditVert *eve, *preveve; EditFace *efa; float cent[3]; - int i=0; // gcc! + int i; if (emdm->vertexCos) { for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; } - for(efa= emdm->em->faces.first; efa; efa= efa->next) { + for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { emDM__calcFaceCent(efa, cent, emdm->vertexCos); - func(userData, efa, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n); + func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n); } if (emdm->vertexCos) { @@ -772,85 +817,75 @@ static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *u eve->prev = preveve; } } -static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) +static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditFace *efa; + int i; if (emdm->vertexCos) { EditVert *eve, *preveve; - int i; + int drawSmooth = 1; for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - if(!setDrawOptions || setDrawOptions(userData, efa)) { - glNormal3fv(emdm->faceNos[i]); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]); - glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]); - glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]); - if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]); - glEnd(); - } - } + if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) { + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); - for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next) - eve->prev = preveve; - } else { - for (efa= emdm->em->faces.first; efa; efa= efa->next) { - if(!setDrawOptions || setDrawOptions(userData, efa)) { glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); - glVertex3fv(efa->v1->co); - glVertex3fv(efa->v2->co); - glVertex3fv(efa->v3->co); - if(efa->v4) glVertex3fv(efa->v4->co); - glEnd(); - } - } - } -} -static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditFace *efa; - - if (emdm->vertexCos) { - EditVert *eve, *preveve; - int i; - - for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next) - eve->prev = (EditVert*) i++; - - for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { - if(efa->h==0) { - if (setMaterial(efa->mat_nr+1)) { + if (drawSmooth) { glNormal3fv(emdm->faceNos[i]); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]); glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]); glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]); if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]); - glEnd(); + } else { + glNormal3fv(emdm->vertexNos[(int) efa->v1->prev]); + glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]); + glNormal3fv(emdm->vertexNos[(int) efa->v2->prev]); + glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]); + glNormal3fv(emdm->vertexNos[(int) efa->v3->prev]); + glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]); + if(efa->v4) { + glNormal3fv(emdm->vertexNos[(int) efa->v4->prev]); + glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]); + } } + glEnd(); } } for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next) eve->prev = preveve; } else { - for (efa= emdm->em->faces.first; efa; efa= efa->next) { - if(efa->h==0) { - if (setMaterial(efa->mat_nr+1)) { + int drawSmooth = 1; + + for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) { + if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) { + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + if (drawSmooth) { glNormal3fv(efa->n); - glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); glVertex3fv(efa->v1->co); glVertex3fv(efa->v2->co); glVertex3fv(efa->v3->co); if(efa->v4) glVertex3fv(efa->v4->co); - glEnd(); + } else { + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + if(efa->v4) { + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } } + glEnd(); } } } @@ -908,16 +943,14 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3]) emdm->dm.getNumVerts = emDM_getNumVerts; emdm->dm.getNumFaces = emDM_getNumFaces; - emdm->dm.foreachMappedVertEM = emDM_foreachMappedVertEM; - emdm->dm.foreachMappedEdgeEM = emDM_foreachMappedEdgeEM; - emdm->dm.foreachMappedFaceCenterEM = emDM_foreachMappedFaceCenterEM; + emdm->dm.foreachMappedVert = emDM_foreachMappedVert; + emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge; + emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter; emdm->dm.drawEdges = emDM_drawEdges; - emdm->dm.drawMappedEdgesEM = emDM_drawMappedEdgesEM; - emdm->dm.drawMappedEdgesInterpEM = emDM_drawMappedEdgesInterpEM; - - emdm->dm.drawFacesSolid = emDM_drawFacesSolid; - emdm->dm.drawMappedFacesEM = emDM_drawMappedFacesEM; + emdm->dm.drawMappedEdges = emDM_drawMappedEdges; + emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp; + emdm->dm.drawMappedFaces = emDM_drawMappedFaces; emdm->dm.release = emDM_release; @@ -979,120 +1012,92 @@ typedef struct { DerivedMesh dm; DispListMesh *dlm; - - EditVert **vertMap; - EditEdge **edgeMap; - EditFace **faceMap; } SSDerivedMesh; -static void ssDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) +static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; - int i; + int i, index=-1; - if (ssdm->vertMap) { - for (i=0; i<dlm->totvert; i++) { - if (ssdm->vertMap[i]) { - func(userData, ssdm->vertMap[i], dlm->mvert[i].co, NULL, dlm->mvert[i].no); - } + for (i=0; i<dlm->totvert; i++) { + MVert *mv = &dlm->mvert[i]; + + if (mv->flag&ME_VERT_STEPINDEX) index++; + + if (index!=-1) { + func(userData, index, mv->co, NULL, mv->no); } } } -static void ssDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) +static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; - int i; + int i, index=-1; - if (ssdm->edgeMap) { - for (i=0; i<dlm->totedge; i++) { - if (ssdm->edgeMap[i]) { - MEdge *med = &dlm->medge[i]; + for (i=0; i<dlm->totedge; i++) { + MEdge *med = &dlm->medge[i]; - func(userData, ssdm->edgeMap[i], dlm->mvert[med->v1].co, dlm->mvert[med->v2].co); - } + if (med->flag&ME_EDGE_STEPINDEX) index++; + + if (index!=-1) { + func(userData, index, dlm->mvert[med->v1].co, dlm->mvert[med->v2].co); } } } -static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) +static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; - int i; + int i, index=-1; - if (ssdm->edgeMap) { - glBegin(GL_LINES); - for(i=0; i<dlm->totedge; i++) { - if(ssdm->edgeMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->edgeMap[i]))) { - MEdge *med = &dlm->medge[i]; + glBegin(GL_LINES); + for(i=0; i<dlm->totedge; i++) { + MEdge *med = &dlm->medge[i]; - glVertex3fv(dlm->mvert[med->v1].co); - glVertex3fv(dlm->mvert[med->v2].co); - } + if (med->flag&ME_EDGE_STEPINDEX) index++; + + if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { + glVertex3fv(dlm->mvert[med->v1].co); + glVertex3fv(dlm->mvert[med->v2].co); } - glEnd(); } + glEnd(); } -static void ssDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) +static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; - int i; + int i, index=-1; - if (ssdm->faceMap) { - for (i=0; i<dlm->totface; i++) { - if(ssdm->faceMap[i]) { - MFace *mf = &dlm->mface[i]; + for (i=0; i<dlm->totface; i++) { + MFace *mf = &dlm->mface[i]; - if (mf->v3) { - float cent[3]; - float no[3]; + if (mf->flag&ME_FACE_STEPINDEX) index++; - VECCOPY(cent, dlm->mvert[mf->v1].co); - VecAddf(cent, cent, dlm->mvert[mf->v2].co); - VecAddf(cent, cent, dlm->mvert[mf->v3].co); + if(index!=-1 && mf->v3) { + float cent[3]; + float no[3]; - if (mf->v4) { - CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no); - VecAddf(cent, cent, dlm->mvert[mf->v4].co); - VecMulf(cent, 0.25f); - } else { - CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no); - VecMulf(cent, 0.33333333333f); - } + VECCOPY(cent, dlm->mvert[mf->v1].co); + VecAddf(cent, cent, dlm->mvert[mf->v2].co); + VecAddf(cent, cent, dlm->mvert[mf->v3].co); - func(userData, ssdm->faceMap[i], cent, no); - } + if (mf->v4) { + CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no); + VecAddf(cent, cent, dlm->mvert[mf->v4].co); + VecMulf(cent, 0.25f); + } else { + CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no); + VecMulf(cent, 0.33333333333f); } - } - } -} -static void ssDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) -{ - SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; - DispListMesh *dlm = ssdm->dlm; - int i; - if (ssdm->faceMap) { - for (i=0; i<dlm->totface; i++) { - if(ssdm->faceMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->faceMap[i]))) { - MFace *mf = &dlm->mface[i]; - - if (mf->v3) { - glBegin(mf->v3?GL_QUADS:GL_TRIANGLES); - glVertex3fv(dlm->mvert[mf->v1].co); - glVertex3fv(dlm->mvert[mf->v2].co); - glVertex3fv(dlm->mvert[mf->v3].co); - if(mf->v4) glVertex3fv(dlm->mvert[mf->v4].co); - glEnd(); - } - } + func(userData, index, cent, no); } } } - static void ssDM_drawVerts(DerivedMesh *dm) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; @@ -1146,6 +1151,7 @@ static void ssDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; DispListMesh *dlm = ssdm->dlm; MVert *mvert = dlm->mvert; + int tfaceFlags = (ME_EDGE_TFSEL|ME_EDGE_TFACT|ME_EDGE_TFVISIBLE|ME_EDGE_TFACTFIRST|ME_EDGE_TFACTLAST); int i; if (dlm->medge) { @@ -1159,6 +1165,78 @@ static void ssDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int } } glEnd(); + } else if ((mask&tfaceFlags) && dlm->tface) { + MFace *mface = dlm->mface; + TFace *tface = dlm->tface; + + glBegin(GL_LINES); + for(i=0; i<dlm->totface; i++, mface++, tface++) { + if (mface->v3) { + unsigned int flags = ME_EDGEDRAW|ME_EDGEMAPPED; + unsigned int flag0, flag1, flag2, flag3; + + if (tface->flag&TF_SELECT) flags |= ME_EDGE_TFSEL; + if (!(tface->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE; + + if (tface->flag&TF_ACTIVE) { + flags |= ME_EDGE_TFACT; + flag0 = flag1 = flag2 = flag3 = flags; + + flag0 |= ME_EDGE_TFACTFIRST; + flag3 |= ME_EDGE_TFACTLAST; + } else { + flag0 = flag1 = flag2 = flag3 = flags; + } + + if (mask&ME_SEAM) { + if (tface->unwrap&TF_SEAM1) flag0 |= ME_SEAM; + if (tface->unwrap&TF_SEAM2) flag1 |= ME_SEAM; + if (tface->unwrap&TF_SEAM3) flag2 |= ME_SEAM; + if (tface->unwrap&TF_SEAM4) flag3 |= ME_SEAM; + } + + if ((flag0&mask)==value) { + glVertex3fv(mvert[mface->v1].co); + glVertex3fv(mvert[mface->v2].co); + } + + if ((flag1&mask)==value) { + glVertex3fv(mvert[mface->v2].co); + glVertex3fv(mvert[mface->v3].co); + } + + if (mface->v4) { + if ((flag2&mask)==value) { + glVertex3fv(mvert[mface->v3].co); + glVertex3fv(mvert[mface->v4].co); + } + + if ((flag3&mask)==value) { + glVertex3fv(mvert[mface->v4].co); + glVertex3fv(mvert[mface->v1].co); + } + } else { + if ((flag3&mask)==value) { + glVertex3fv(mvert[mface->v3].co); + glVertex3fv(mvert[mface->v1].co); + } + } + } + } + glEnd(); + } else { + MFace *mface = dlm->mface; + + glBegin(GL_LINES); + for(i=0; i<dlm->totface; i++, mface++) { + if (!mface->v3) { + if (((ME_EDGEDRAW|ME_LOOSEEDGE|ME_EDGEMAPPED)&mask)==value) { + glVertex3fv(mvert[mface->v1].co); + glVertex3fv(mvert[mface->v2].co); + } + } + } + glEnd(); } } static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) @@ -1366,7 +1444,56 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i glEnd(); } } +static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + MVert *mvert= dlm->mvert; + MFace *mface= dlm->mface; + float *nors = dlm->nors; + int i, glmode, shademodel, index=-1; + + glShadeModel(shademodel = GL_SMOOTH); + glBegin(glmode=GL_QUADS); + for (i=0; i<dlm->totface; i++) { + MFace *mf = &mface[i]; + int drawSmooth = 1; + + if (mf->flag&ME_FACE_STEPINDEX) index++; + if (index!=-1 && mf->v3 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) { + int newmode = mf->v4?GL_QUADS:GL_TRIANGLES; + int newshademodel = drawSmooth?GL_SMOOTH:GL_FLAT; + + if (newmode!=glmode || newshademodel!=shademodel) { + glEnd(); + glShadeModel(shademodel = newshademodel); + glBegin(glmode = newmode); + } + + if (shademodel==GL_FLAT) { + glNormal3fv(&nors[i*3]); + + glVertex3fv(mvert[mf->v1].co); + glVertex3fv(mvert[mf->v2].co); + glVertex3fv(mvert[mf->v3].co); + if(mf->v4) glVertex3fv(mvert[mf->v4].co); + } else { + glNormal3sv(mvert[mf->v1].no); + glVertex3fv(mvert[mf->v1].co); + glNormal3sv(mvert[mf->v2].no); + glVertex3fv(mvert[mf->v2].co); + glNormal3sv(mvert[mf->v3].no); + glVertex3fv(mvert[mf->v3].co); + if(mf->v4) { + glNormal3sv(mvert[mf->v4].no); + glVertex3fv(mvert[mf->v4].co); + } + } + } + } + glEnd(); +} static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; @@ -1417,38 +1544,16 @@ static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared } } -static DispListMesh *ssDM_convertToDispListMeshMapped(DerivedMesh *dm, int allowShared, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) -{ - SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; - - // We should never get here if the appropriate ssdm fields weren't given. - - *vertMap_r = MEM_dupallocN(ssdm->vertMap); - *edgeMap_r = MEM_dupallocN(ssdm->edgeMap); - *faceMap_r = MEM_dupallocN(ssdm->faceMap); - - if (allowShared) { - return displistmesh_copyShared(ssdm->dlm); - } else { - return displistmesh_copy(ssdm->dlm); - } -} - static void ssDM_release(DerivedMesh *dm) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; displistmesh_free(ssdm->dlm); - if (ssdm->vertMap) { - MEM_freeN(ssdm->vertMap); - MEM_freeN(ssdm->edgeMap); - MEM_freeN(ssdm->faceMap); - } MEM_freeN(dm); } -DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) +DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3]) { SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm"); @@ -1457,7 +1562,6 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos) ssdm->dm.getNumVerts = ssDM_getNumVerts; ssdm->dm.getNumFaces = ssDM_getNumFaces; ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh; - ssdm->dm.convertToDispListMeshMapped = ssDM_convertToDispListMeshMapped; ssdm->dm.getVertCos = ssDM_getVertCos; @@ -1470,24 +1574,20 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos) ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid; ssdm->dm.drawFacesColored = ssDM_drawFacesColored; ssdm->dm.drawFacesTex = ssDM_drawFacesTex; + ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces; /* EM functions */ - ssdm->dm.foreachMappedVertEM = ssDM_foreachMappedVertEM; - ssdm->dm.foreachMappedEdgeEM = ssDM_foreachMappedEdgeEM; - ssdm->dm.foreachMappedFaceCenterEM = ssDM_foreachMappedFaceCenterEM; + ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert; + ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge; + ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter; - ssdm->dm.drawMappedEdgesEM = ssDM_drawMappedEdgesEM; - ssdm->dm.drawMappedEdgesInterpEM = NULL; // no way to implement this one + ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges; + ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one - ssdm->dm.drawMappedFacesEM = ssDM_drawMappedFacesEM; - ssdm->dm.release = ssDM_release; ssdm->dlm = dlm; - ssdm->vertMap = vertMap; - ssdm->edgeMap = edgeMap; - ssdm->faceMap = faceMap; if (vertexCos) { int i; @@ -1642,7 +1742,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM dm->release(dm); - *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL); + *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts); } else if (dm) { *final_r = dm; } else { @@ -1739,13 +1839,10 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) if (cage_r && i==cageIndex) { if (dm && deformedVerts) { DispListMesh *dlm; - EditVert **vertMap; - EditEdge **edgeMap; - EditFace **faceMap; - dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap); + dlm = dm->convertToDispListMesh(dm, 0); - *cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts, vertMap, edgeMap, faceMap); + *cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts); } else if (dm) { *cage_r = dm; } else { @@ -1763,7 +1860,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) if (!cage_r || dm!=*cage_r) dm->release(dm); - *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL); + *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts); MEM_freeN(deformedVerts); } else if (dm) { *final_r = dm; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 4ee8fc2640f..c2aa614dc71 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -137,7 +137,7 @@ DispListMesh *displistmesh_copy(DispListMesh *odlm) if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors); if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol); if (odlm->tface) ndlm->tface= MEM_dupallocN(odlm->tface); - + return ndlm; } diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 5ecbafa9e80..85b3b3a7954 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -649,7 +649,7 @@ static void read_videoscape_mesh(char *str) } mface->edcode= 3; - test_index_mface(mface, poly); + test_index_face(mface, NULL, NULL, poly); mface++; } @@ -823,7 +823,7 @@ static void read_radiogour(char *str) } mface->edcode= 3; - test_index_mface(mface, poly); + test_index_face(mface, NULL, NULL, poly); mface++; } @@ -2128,7 +2128,7 @@ static void displist_to_mesh(DispList *dlfirst) mface->v4= p3; mface->mat_nr= colnr; - test_index_mface(mface, 4); + test_index_face(mface, NULL, NULL, 4); mface++; @@ -2161,7 +2161,7 @@ static void displist_to_mesh(DispList *dlfirst) mface->v2= startve+a*dl->nr+1; mface->v3= startve+a*dl->nr+2; mface->mat_nr= colnr; - test_index_mface(mface, 3); + test_index_face(mface, NULL, NULL, 3); mface++; } else { @@ -2170,7 +2170,7 @@ static void displist_to_mesh(DispList *dlfirst) mface->v3= startve+a*dl->nr+2; mface->v4= startve+a*dl->nr+3; mface->mat_nr= colnr; - test_index_mface(mface, 4); + test_index_face(mface, NULL, NULL, 4); mface++; } } @@ -2196,7 +2196,7 @@ static void displist_to_mesh(DispList *dlfirst) else mface->v2= startve+a+1; mface->mat_nr= colnr; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); mface++; } @@ -2226,7 +2226,7 @@ static void displist_to_mesh(DispList *dlfirst) if (mface->v2>maxvertidx) mface->v2= maxvertidx; if (mface->v3>maxvertidx) mface->v3= maxvertidx; - test_index_mface(mface, 3); + test_index_face(mface, NULL, NULL, 3); mface++; idata+= 3; } @@ -2248,7 +2248,7 @@ static void displist_to_mesh(DispList *dlfirst) mface->v1= startve+a; mface->v2= startve+a+1; mface->mat_nr= colnr; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); mface++; } startve += dl->nr; @@ -4328,7 +4328,7 @@ static void dxf_read_polyline(int noob) { mface->edcode= 3; mface->mat_nr= 0; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); } } @@ -4445,9 +4445,9 @@ static void dxf_read_polyline(int noob) { if(vids[3] && vids[3]!=vids[0]) { mface->v4= vids[3]-1; - test_index_mface(mface, 4); + test_index_face(mface, NULL, NULL, 4); } - else test_index_mface(mface, 3); + else test_index_face(mface, NULL, NULL, 3); mface->edcode= 3; mface->mat_nr= 0; @@ -4786,7 +4786,7 @@ static void dxf_read_3dface(int noob) mface->edcode= 3; mface->mat_nr= 0; - test_index_mface(mface, nverts); + test_index_face(mface, NULL, NULL, nverts); hasbumped=1; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 2dea698db80..e1c1f337bb6 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -488,25 +488,12 @@ float *mesh_create_orco(Object *ob) return make_orco_mesh_internal(ob, 0); } -/** rotates the vertices of a face in case v[2] or v[3] (vertex index) - * is = 0. - * Helaas, the MFace structure has no pointer to its - * texture face, therefore, texture can not be fixed inside - * this function. - * - * see also blender/src/editmesh.c, fix_faceindices() - - * THIS FUNCTION WILL BE DINOSOURCE. For the moment, another hack - is added to fix texture coordinates / vertex colors: - - void test_index_face(MFace *mface, TFace *tface, int nr) - */ - -void test_index_mface(MFace *mface, int nr) + /* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0. */ +#define UVSWAP(t, s) { SWAP(float, t[0], s[0]); SWAP(float, t[1], s[1]); } +void test_index_face(MFace *mface, MCol *mc, TFace *tface, int nr) { int a; - /* first test if the face is legal */ if(mface->v3 && mface->v3==mface->v4) { @@ -533,82 +520,19 @@ void test_index_mface(MFace *mface, int nr) if(mface->v3==0) { SWAP(int, mface->v1, mface->v2); SWAP(int, mface->v2, mface->v3); - - a= mface->edcode; - mface->edcode= 0; - if(a & ME_V1V2) mface->edcode |= ME_V3V1; - if(a & ME_V2V3) mface->edcode |= ME_V1V2; - if(a & ME_V3V1) mface->edcode |= ME_V2V3; - } - } - else if(nr==4) { - if(mface->v3==0 || mface->v4==0) { - SWAP(int, mface->v1, mface->v3); - SWAP(int, mface->v2, mface->v4); - a= mface->edcode; - mface->edcode= 0; - if(a & ME_V1V2) mface->edcode |= ME_V3V4; - if(a & ME_V2V3) mface->edcode |= ME_V2V3; - if(a & ME_V3V4) mface->edcode |= ME_V1V2; - if(a & ME_V4V1) mface->edcode |= ME_V4V1; - } - } -} - -/** This function should die as soon as there is another mesh - structure. Functionality is the same as - - void test_index_mface() - - but it fixes texture coordinates as well. -*/ - -#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float)); -void test_index_face(MFace *mface, TFace *tface, int nr) -{ - int a; - float tmpuv[2]; - unsigned int tmpcol; - - /* first test if the face is legal */ - - if(mface->v3 && mface->v3==mface->v4) { - mface->v4= 0; - nr--; - } - if(mface->v2 && mface->v2==mface->v3) { - mface->v3= mface->v4; - mface->v4= 0; - nr--; - } - if(mface->v1==mface->v2) { - mface->v2= mface->v3; - mface->v3= mface->v4; - mface->v4= 0; - nr--; - } + if (tface) { + UVSWAP(tface->uv[0], tface->uv[1]); + UVSWAP(tface->uv[1], tface->uv[2]); + SWAP(unsigned int, tface->col[0], tface->col[1]); + SWAP(unsigned int, tface->col[1], tface->col[2]); + } - /* prevent a zero at wrong index location */ - if(nr==2) { - if(mface->v2==0) SWAP(int, mface->v1, mface->v2); - } - else if(nr==3) { - if(mface->v3==0) { - SWAP(int, mface->v1, mface->v2); - SWAP(int, mface->v2, mface->v3); - /* rotate face UV coordinates, too */ - UVCOPY(tmpuv, tface->uv[0]); - UVCOPY(tface->uv[0], tface->uv[1]); - UVCOPY(tface->uv[1], tface->uv[2]); - UVCOPY(tface->uv[2], tmpuv); - /* same with vertex colours */ - tmpcol = tface->col[0]; - tface->col[0] = tface->col[1]; - tface->col[1] = tface->col[2]; - tface->col[2] = tmpcol; + if (mc) { + SWAP(MCol, mc[0], mc[1]); + SWAP(MCol, mc[1], mc[2]); + } - a= mface->edcode; mface->edcode= 0; if(a & ME_V1V2) mface->edcode |= ME_V3V1; @@ -620,20 +544,19 @@ void test_index_face(MFace *mface, TFace *tface, int nr) if(mface->v3==0 || mface->v4==0) { SWAP(int, mface->v1, mface->v3); SWAP(int, mface->v2, mface->v4); - /* swap UV coordinates */ - UVCOPY(tmpuv, tface->uv[0]); - UVCOPY(tface->uv[0], tface->uv[2]); - UVCOPY(tface->uv[2], tmpuv); - UVCOPY(tmpuv, tface->uv[1]); - UVCOPY(tface->uv[1], tface->uv[3]); - UVCOPY(tface->uv[3], tmpuv); - /* swap vertex colours */ - tmpcol = tface->col[0]; - tface->col[0] = tface->col[2]; - tface->col[2] = tmpcol; - tmpcol = tface->col[1]; - tface->col[1] = tface->col[3]; - tface->col[3] = tmpcol; + + + if (tface) { + UVSWAP(tface->uv[0], tface->uv[2]); + UVSWAP(tface->uv[1], tface->uv[3]); + SWAP(unsigned int, tface->col[0], tface->col[2]); + SWAP(unsigned int, tface->col[1], tface->col[3]); + } + + if (mc) { + SWAP(MCol, mc[0], mc[2]); + SWAP(MCol, mc[1], mc[3]); + } a= mface->edcode; mface->edcode= 0; @@ -645,39 +568,6 @@ void test_index_face(MFace *mface, TFace *tface, int nr) } } -void flipnorm_mesh(Mesh *me) -{ - MFace *mface; - MVert *mvert; - int a; - - mvert= me->mvert; - a= me->totvert; - while(a--) { - mvert->no[0]= -mvert->no[0]; - mvert->no[1]= -mvert->no[1]; - mvert->no[2]= -mvert->no[2]; - mvert++; - } - - mface= me->mface; - a= me->totface; - while(a--) { - if(mface->v3) { - if(mface->v4) { - SWAP(int, mface->v4, mface->v1); - SWAP(int, mface->v3, mface->v2); - test_index_mface(mface, 4); - } - else { - SWAP(int, mface->v3, mface->v1); - test_index_mface(mface, 3); - } - } - mface++; - } -} - Mesh *get_mesh(Object *ob) { @@ -942,7 +832,7 @@ void nurbs_to_mesh(Object *ob) mface->v1= startvert+ofs+b-1; mface->v2= startvert+ofs+b; mface->edcode= ME_V1V2; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); mface++; } } @@ -968,7 +858,7 @@ void nurbs_to_mesh(Object *ob) if(b==dl->nr-1) mface->v2= startvert+ofs; else mface->v2= startvert+ofs+b+1; mface->edcode= ME_V1V2; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); mface++; } } @@ -994,7 +884,7 @@ void nurbs_to_mesh(Object *ob) mface->v4= 0; mface->edcode= ME_V1V2+ME_V2V3; - test_index_mface(mface, 3); + test_index_face(mface, NULL, NULL, 3); mface++; index+= 3; @@ -1043,7 +933,7 @@ void nurbs_to_mesh(Object *ob) mface->v4= p2; mface->mat_nr= (unsigned char)dl->col; mface->edcode= ME_V1V2+ME_V2V3; - test_index_mface(mface, 4); + test_index_face(mface, NULL, NULL, 4); mface++; p4= p3; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 04e8b16c6bc..a7b3f2b9bb6 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -202,12 +202,9 @@ static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void SubsurfModifierData *smd = (SubsurfModifierData*) md; if (dm) { - EditVert **vertMap; - EditEdge **edgeMap; - EditFace **faceMap; - DispListMesh *dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap); + DispListMesh *dlm = dm->convertToDispListMesh(dm, 0); - dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos, vertMap, edgeMap, faceMap); + dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos); return dm; } else { @@ -452,7 +449,7 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *der mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); - return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); + return derivedmesh_from_displistmesh(ndlm, NULL); } /* Mirror */ @@ -473,307 +470,257 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target) tmmd->tolerance = mmd->tolerance; } -static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) +static DispListMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *inDLM, float (*vertexCos)[3], int initFlags) { - int totvert=ndlm->totvert, totedge=ndlm->totedge, totface=ndlm->totface; int i, axis = mmd->axis; float tolerance = mmd->tolerance; - EditVert **vMapOut; - EditEdge **eMapOut; - EditFace **fMapOut; - - if (vertMap) { - *vertMap_r = vMapOut = MEM_mallocN(sizeof(*vMapOut)*totvert*2, "vmap"); - *edgeMap_r = eMapOut = MEM_mallocN(sizeof(*eMapOut)*totedge*2, "emap"); - *faceMap_r = fMapOut = MEM_mallocN(sizeof(*fMapOut)*totface*2, "fmap"); - } else { - *vertMap_r = vMapOut = NULL; - *edgeMap_r = eMapOut = NULL; - *faceMap_r = fMapOut = NULL; - } + DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "mirror_dlm"); + int (*indexMap)[2]; + + dlm->totvert = dlm->totedge = dlm->totface = 0; + indexMap = MEM_mallocN(sizeof(*indexMap)*inDLM->totvert, "indexmap"); + dlm->mvert = MEM_callocN(sizeof(*dlm->mvert)*inDLM->totvert*2, "dlm_mvert"); + dlm->mface = MEM_callocN(sizeof(*dlm->mface)*inDLM->totface*2, "dlm_mface"); + + if (inDLM->medge) dlm->medge = MEM_callocN(sizeof(*dlm->medge)*inDLM->totedge*2, "dlm_medge"); + if (inDLM->tface) dlm->tface = MEM_callocN(sizeof(*dlm->tface)*inDLM->totface*2, "dlm_tface"); + if (inDLM->mcol) dlm->mcol = MEM_callocN(sizeof(*dlm->mcol)*inDLM->totface*4*2, "dlm_mcol"); - for (i=0; i<totvert; i++) { - MVert *mv = &ndlm->mvert[i]; - int isShared = ABS(mv->co[axis])<=tolerance; + for (i=0; i<inDLM->totvert; i++) { + MVert *inMV = &inDLM->mvert[i]; + MVert *mv = &dlm->mvert[dlm->totvert++]; + int isShared = ABS(inMV->co[axis])<=tolerance; - /* Because the topology result (# of vertices) must stuff the same + /* Because the topology result (# of vertices) must be the same * if the mesh data is overridden by vertex cos, have to calc sharedness - * based on original coordinates. Only write new cos for non-shared - * vertices. This is why we test before copy. + * based on original coordinates. This is why we test before copy. */ + *mv = *inMV; if (vertexCos) { VECCOPY(mv->co, vertexCos[i]); } + if (initFlags) mv->flag |= ME_VERT_STEPINDEX; - if (vMapOut) vMapOut[i] = vertMap[i]; + indexMap[i][0] = dlm->totvert-1; + indexMap[i][1] = !isShared; if (isShared) { mv->co[axis] = 0; - *((int*) mv->no) = i; } else { - MVert *nmv = &ndlm->mvert[ndlm->totvert]; + MVert *mv2 = &dlm->mvert[dlm->totvert++]; - memcpy(nmv, mv, sizeof(*mv)); - nmv ->co[axis] = -nmv ->co[axis]; - - if (vMapOut) vMapOut[ndlm->totvert] = vertMap[i]; - - *((int*) mv->no) = ndlm->totvert++; + *mv2 = *mv; + mv2->co[axis] = -mv2->co[axis]; + mv2->flag &= ~ME_VERT_STEPINDEX; } } - if (ndlm->medge) { - for (i=0; i<totedge; i++) { - MEdge *med = &ndlm->medge[i]; - MEdge *nmed = &ndlm->medge[ndlm->totedge]; - - memcpy(nmed, med, sizeof(*med)); + for (i=0; i<inDLM->totedge; i++) { + MEdge *inMED = &inDLM->medge[i]; + MEdge *med = &dlm->medge[dlm->totedge++]; - nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no); - nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no); + *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 (eMapOut) eMapOut[i] = edgeMap[i]; + if (indexMap[inMED->v1][1] || indexMap[inMED->v2][2]) { + MEdge *med2 = &dlm->medge[dlm->totedge++]; - if (nmed->v1!=med->v1 || nmed->v2!=med->v2) { - if (eMapOut) eMapOut[ndlm->totedge] = edgeMap[i]; - - ndlm->totedge++; - } + *med2 = *med; + med2->v1 = med->v1+indexMap[inMED->v1][1]; + med2->v2 = med->v2+indexMap[inMED->v2][1]; + med2->flag &= ~ME_EDGE_STEPINDEX; } } - for (i=0; i<totface; i++) { - MFace *mf = &ndlm->mface[i]; - MFace *nmf = &ndlm->mface[ndlm->totface]; - TFace *tf=NULL, *ntf=NULL; /* gcc's mother is uninitialized! */ - MCol *mc=NULL, *nmc=NULL; - - memcpy(nmf, mf, sizeof(*mf)); - if (ndlm->tface) { - ntf = &ndlm->tface[ndlm->totface]; - tf = &ndlm->tface[i]; - memcpy(ntf, tf, sizeof(*ndlm->tface)); - } else if (ndlm->mcol) { - nmc = &ndlm->mcol[ndlm->totface*4]; - mc = &ndlm->mcol[i*4]; - memcpy(nmc, mc, sizeof(*ndlm->mcol)*4); - } - - /* Map vertices to shared */ - - nmf->v1 = *((int*) ndlm->mvert[nmf->v1].no); - nmf->v2 = *((int*) ndlm->mvert[nmf->v2].no); - if (nmf->v3) { - nmf->v3 = *((int*) ndlm->mvert[nmf->v3].no); - if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no); + for (i=0; i<inDLM->totface; i++) { + MFace *inMF = &inDLM->mface[i]; + MFace *mf = &dlm->mface[dlm->totface++]; + + *mf = *inMF; + mf->v1 = indexMap[inMF->v1][0]; + mf->v2 = indexMap[inMF->v2][0]; + mf->v3 = indexMap[inMF->v3][0]; + mf->v4 = indexMap[inMF->v4][0]; + if (initFlags) mf->flag |= ME_FACE_STEPINDEX; + + if (inDLM->tface) { + TFace *inTF = &inDLM->tface[i]; + TFace *tf = &dlm->tface[dlm->totface-1]; + + *tf = *inTF; + } else if (inDLM->mcol) { + MCol *inMC = &inDLM->mcol[i*4]; + MCol *mc = &dlm->mcol[(dlm->totface-1)*4]; + + mc[0] = inMC[0]; + mc[1] = inMC[1]; + mc[2] = inMC[2]; + mc[3] = inMC[3]; } + + if (indexMap[inMF->v1][1] || indexMap[inMF->v2][1] || (mf->v3 && indexMap[inMF->v3][1]) || (mf->v4 && indexMap[inMF->v4][1])) { + MFace *mf2 = &dlm->mface[dlm->totface++]; + TFace *tf = NULL; + MCol *mc = NULL; + + *mf2 = *mf; + mf2->v1 = indexMap[inMF->v1][0] + indexMap[inMF->v1][1]; + mf2->v2 = indexMap[inMF->v2][0] + indexMap[inMF->v2][1]; + mf2->v3 = indexMap[inMF->v3][0] + (inMF->v3?indexMap[inMF->v3][1]:0); + mf2->v4 = indexMap[inMF->v4][0] + (inMF->v4?indexMap[inMF->v4][1]:0); + mf2->flag &= ~ME_FACE_STEPINDEX; + + if (inDLM->tface) { + TFace *inTF = &inDLM->tface[i]; + tf = &dlm->tface[dlm->totface-1]; + + *tf = *inTF; + } else if (inDLM->mcol) { + MCol *inMC = &inDLM->mcol[i*4]; + mc = &dlm->mcol[(dlm->totface-1)*4]; + + mc[0] = inMC[0]; + mc[1] = inMC[1]; + mc[2] = inMC[2]; + mc[3] = inMC[3]; + } - if (fMapOut) fMapOut[i] = faceMap[i]; - - /* If all vertices shared don't duplicate face */ - if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4) - continue; - - if (fMapOut) fMapOut[ndlm->totface] = faceMap[i]; - - if (nmf->v3) { - /* Need to flip face normal, pick which verts to flip - * in order to prevent nmf->v3==0 or nmf->v4==0 - */ - if (nmf->v1) { - SWAP(int, nmf->v1, nmf->v3); - - if (ndlm->tface) { - SWAP(unsigned int, ntf->col[0], ntf->col[2]); - SWAP(float, ntf->uv[0][0], ntf->uv[2][0]); - SWAP(float, ntf->uv[0][1], ntf->uv[2][1]); - } else if (ndlm->mcol) { - SWAP(MCol, nmc[0], nmc[2]); - } - } else { - if (nmf->v4) { - SWAP(int, nmf->v2, nmf->v4); - - if (ndlm->tface) { - SWAP(unsigned int, ntf->col[1], ntf->col[3]); - SWAP(float, ntf->uv[1][0], ntf->uv[3][0]); - SWAP(float, ntf->uv[1][1], ntf->uv[3][1]); - } else if (ndlm->mcol) { - SWAP(MCol, nmc[1], nmc[3]); - } - } else { - SWAP(int, nmf->v2, nmf->v3); - - if (ndlm->tface) { - SWAP(unsigned int, ntf->col[1], ntf->col[2]); - SWAP(float, ntf->uv[1][0], ntf->uv[2][0]); - SWAP(float, ntf->uv[1][1], ntf->uv[2][1]); - } else if (ndlm->mcol) { - SWAP(MCol, nmc[1], nmc[2]); - } + if (mf2->v3) { + /* Flip face normal */ + SWAP(int, mf2->v1, mf2->v3); + if (tf) { + SWAP(unsigned int, tf->col[0], tf->col[2]); + SWAP(float, tf->uv[0][0], tf->uv[2][0]); + SWAP(float, tf->uv[0][1], tf->uv[2][1]); + } else if (mc) { + SWAP(MCol, mc[0], mc[2]); } + + test_index_face(mf2, mc, tf, inMF->v4?4:3); } } - - ndlm->totface++; } + + MEM_freeN(indexMap); + + return dlm; } -static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc, int needsMaps) +static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc) { DerivedMesh *dm = derivedData; MirrorModifierData *mmd = (MirrorModifierData*) md; - DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*dlm), "mm_dlm"); - MVert *mvert; - MEdge *medge; - MFace *mface; - TFace *tface; - MCol *mcol; - EditVert **vertMapOut, **vertMap = NULL; - EditEdge **edgeMapOut, **edgeMap = NULL; - EditFace **faceMapOut, **faceMap = NULL; + DispListMesh *outDLM, *inDLM; if (dm) { - if (needsMaps) { - dlm = dm->convertToDispListMeshMapped(dm, 1, &vertMap, &edgeMap, &faceMap); - } else { - dlm = dm->convertToDispListMesh(dm, 1); - } - - mvert = dlm->mvert; - medge = dlm->medge; - mface = dlm->mface; - tface = dlm->tface; - mcol = dlm->mcol; - ndlm->totvert = dlm->totvert; - ndlm->totedge = dlm->totedge; - ndlm->totface = dlm->totface; + inDLM = dm->convertToDispListMesh(dm, 1); } else { Mesh *me = ob->data; - mvert = me->mvert; - medge = me->medge; - mface = me->mface; - tface = me->tface; - mcol = me->mcol; - ndlm->totvert = me->totvert; - ndlm->totedge = me->totedge; - ndlm->totface = me->totface; - } - - ndlm->mvert = MEM_mallocN(sizeof(*mvert)*ndlm->totvert*2, "mm_mv"); - memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert); - - if (medge) { - ndlm->medge = MEM_mallocN(sizeof(*medge)*ndlm->totedge*2, "mm_med"); - memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge); + inDLM = MEM_callocN(sizeof(*inDLM), "inDLM"); + inDLM->dontFreeVerts = inDLM->dontFreeOther = 1; + inDLM->mvert = me->mvert; + inDLM->medge = me->medge; + inDLM->mface = me->mface; + inDLM->tface = me->tface; + inDLM->mcol = me->mcol; + inDLM->totvert = me->totvert; + inDLM->totedge = me->totedge; + inDLM->totface = me->totface; } - ndlm->mface = MEM_mallocN(sizeof(*mface)*ndlm->totface*2, "mm_mf"); - memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface); + outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, dm?0:1); - if (tface) { - ndlm->tface = MEM_mallocN(sizeof(*tface)*ndlm->totface*2, "mm_tf"); - memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface); - } else if (mcol) { - ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*ndlm->totface*2, "mm_mcol"); - memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface); - } - - mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut); - - if (dlm) { - displistmesh_free(dlm); - if (needsMaps) { - MEM_freeN(vertMap); - MEM_freeN(edgeMap); - MEM_freeN(faceMap); - } - } - - mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); + displistmesh_free(inDLM); + + mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors); - return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut); + return derivedmesh_from_displistmesh(outDLM, NULL); } static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc) { - return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 0); + return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1); } static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]) { if (derivedData) { - return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 1); + return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1); } else { MirrorModifierData *mmd = (MirrorModifierData*) md; - DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm"); + DispListMesh *outDLM, *inDLM = MEM_callocN(sizeof(*inDLM), "mm_dlm"); EditMesh *em = editData; EditVert *eve, *preveve; EditEdge *eed; EditFace *efa; - EditVert **vertMapOut, **vertMap; - EditEdge **edgeMapOut, **edgeMap; - EditFace **faceMapOut, **faceMap; int i; for (i=0,eve=em->verts.first; eve; eve= eve->next) eve->prev = (EditVert*) i++; - ndlm->totvert = BLI_countlist(&em->verts); - ndlm->totedge = BLI_countlist(&em->edges); - ndlm->totface = BLI_countlist(&em->faces); + inDLM->totvert = BLI_countlist(&em->verts); + inDLM->totedge = BLI_countlist(&em->edges); + inDLM->totface = BLI_countlist(&em->faces); - vertMap = MEM_mallocN(sizeof(*vertMap)*ndlm->totvert, "mm_vmap"); - edgeMap = MEM_mallocN(sizeof(*edgeMap)*ndlm->totedge, "mm_emap"); - faceMap = MEM_mallocN(sizeof(*faceMap)*ndlm->totface, "mm_fmap"); + inDLM->mvert = MEM_mallocN(sizeof(*inDLM->mvert)*inDLM->totvert*2, "mm_mv"); + inDLM->medge = MEM_mallocN(sizeof(*inDLM->medge)*inDLM->totedge*2, "mm_med"); + inDLM->mface = MEM_mallocN(sizeof(*inDLM->mface)*inDLM->totface*2, "mm_mf"); - ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert*2, "mm_mv"); - ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*ndlm->totedge*2, "mm_med"); - ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface*2, "mm_mf"); + /* Need to be able to mark loose edges */ + for (eed=em->edges.first; eed; eed=eed->next) { + eed->f2 = 0; + } + for (efa=em->faces.first; efa; efa=efa->next) { + efa->e1->f2 = 1; + efa->e2->f2 = 1; + efa->e3->f2 = 1; + efa->e4->f2 = 1; + } - for (i=0,eve=em->verts.first; i<ndlm->totvert; i++,eve=eve->next) { - MVert *mv = &ndlm->mvert[i]; + for (i=0,eve=em->verts.first; i<inDLM->totvert; i++,eve=eve->next) { + MVert *mv = &inDLM->mvert[i]; VECCOPY(mv->co, eve->co); - - vertMap[i] = eve; + mv->mat_nr = 0; + mv->flag = ME_VERT_STEPINDEX; } - for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) { - MEdge *med = &ndlm->medge[i]; + for (i=0,eed=em->edges.first; i<inDLM->totedge; i++,eed=eed->next) { + MEdge *med = &inDLM->medge[i]; med->v1 = (int) eed->v1->prev; med->v2 = (int) eed->v2->prev; med->crease = (unsigned char) (eed->crease*255.0f); - - edgeMap[i] = eed; + med->flag = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED|ME_EDGE_STEPINDEX; + + if (eed->seam) med->flag |= ME_SEAM; + if (!eed->f2) med->flag |= ME_LOOSEEDGE; } - for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) { - MFace *mf = &ndlm->mface[i]; + for (i=0,efa=em->faces.first; i<inDLM->totface; i++,efa=efa->next) { + MFace *mf = &inDLM->mface[i]; mf->v1 = (int) efa->v1->prev; mf->v2 = (int) efa->v2->prev; mf->v3 = (int) efa->v3->prev; mf->v4 = efa->v4?(int) efa->v4->prev:0; mf->mat_nr = efa->mat_nr; - mf->flag = efa->flag; + mf->flag = efa->flag|ME_FACE_STEPINDEX; + mf->edcode = 0; - test_index_mface(mf, efa->v4?4:3); - - faceMap[i] = efa; + test_index_face(mf, NULL, NULL, efa->v4?4:3); } - mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut); + outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, 0); + + displistmesh_free(inDLM); for (preveve=NULL, eve=em->verts.first; eve; preveve=eve, eve= eve->next) eve->prev = preveve; - mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); - - MEM_freeN(faceMap); - MEM_freeN(edgeMap); - MEM_freeN(vertMap); + mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors); - return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut); + return derivedmesh_from_displistmesh(outDLM, NULL); } } @@ -895,7 +842,7 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void * mf->v1 = tri[0]; mf->v2 = tri[1]; mf->v3 = tri[2]; - test_index_mface(mf, 3); + test_index_face(mface, NULL, NULL, 3); } } else { @@ -918,7 +865,7 @@ exit: if (ndlm) { mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); - return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); + return derivedmesh_from_displistmesh(ndlm, NULL); } else { return NULL; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e16ade4b7cc..f324a046c5f 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -68,9 +68,9 @@ typedef struct _VertData { typedef struct CCGDerivedMesh CCGDerivedMesh; -static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v); -static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e); -static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f); +static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v); +static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e); +static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f); /// @@ -113,9 +113,9 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin } if (useAging) { - ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; + ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12; } else { - ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4; + ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; } ifc.vertDataSize = sizeof(VertData); @@ -134,7 +134,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin } if (useAging) { - ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4); + ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8); } if (useEdgeCreation) { ccgSubSurf_setAllowEdgeCreation(ccgSS, 1, useFlatSubdiv?subdivLevels:0.0f); @@ -197,9 +197,9 @@ 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, MEdge *medge, TFace *tface) +static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface) { - unsigned int flags = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED; + unsigned int flags = 0; int j, N = ccgSubSurf_getEdgeNumFaces(ss, e); if (!N) flags |= ME_LOOSEEDGE; @@ -207,40 +207,53 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme if (ssFromEditmesh) { EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e); + flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED; if (eed->seam) { flags |= ME_SEAM; } } else { - int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e); + int makeFlags = 0, edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e); - /* Edges created by lib have handle of -1 */ - if (edgeIdx!=-1 && medge) { + if (edgeIdx==-1) { + if (!medge) { + makeFlags = 1; + } + } else { MEdge *origMed = &medge[edgeIdx]; - flags |= (origMed->flag&ME_SEAM); + if (dlm) { + flags |= origMed->flag&~ME_EDGE_STEPINDEX; + } else { + flags |= (origMed->flag&ME_SEAM); + 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 (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_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); + if (tf->flag&TF_ACTIVE) { + int fN = ccgSubSurf_getFaceNumVerts(ss, f); + int k = ccgSubSurf_getFaceEdgeIndex(ss, f, e); - flags |= ME_EDGE_TFACT; + flags |= ME_EDGE_TFACT; - if (k==0) { - flags |= ME_EDGE_TFACTFIRST; + if (k==0) { + flags |= ME_EDGE_TFACTFIRST; + } + else if (k==fN-1) { + flags |= ME_EDGE_TFACTLAST; + } } - else if (k==fN-1) { - flags |= ME_EDGE_TFACTLAST; - } } } } @@ -249,12 +262,12 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme return flags; } -static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) { +static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM) { DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm"); int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); - int edgeIndexBase, edgeBase, faceBase; - int i, j, k, S, x, y; + int edgeBase, faceBase; + int i, j, k, S, x, y, index, lastIndex; int vertBase = 0; TFace *tface = NULL; MEdge *medge = NULL; @@ -263,9 +276,55 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i CCGVertIterator *vi; CCGEdgeIterator *ei; CCGFaceIterator *fi; - EditVert **vertMap = NULL; - EditEdge **edgeMap = NULL; - EditFace **faceMap = NULL; + CCGFace **faceMap2; + CCGEdge **edgeMap2; + CCGVert **vertMap2; + int totvert, totedge, totface, useEdgeCreation; + + ccgSubSurf_getAllowEdgeCreation(ss, &useEdgeCreation, NULL); + + totvert = ccgSubSurf_getNumVerts(ss); + vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + + if (ssFromEditmesh) { + vertMap2[ccgDM_getVertMapIndex(ccgdm,ss,v)] = v; + } else { + vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v; + } + } + ccgVertIterator_free(vi); + + totedge = ccgSubSurf_getNumEdges(ss); + edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap"); + ei = ccgSubSurf_getEdgeIterator(ss); + for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + + if (useEdgeCreation) { + edgeMap2[i] = e; + } else if (ssFromEditmesh) { + edgeMap2[ccgDM_getEdgeMapIndex(ccgdm,ss,e)] = e; + } else { + edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e; + } + } + + totface = ccgSubSurf_getNumFaces(ss); + faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap"); + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + + if (ssFromEditmesh) { + faceMap2[ccgDM_getFaceMapIndex(ccgdm,ss,f)] = f; + } else { + faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f; + } + } + ccgFaceIterator_free(fi); if (!ssFromEditmesh) { if (inDLM) { @@ -285,12 +344,6 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i dlm->totedge = ccgSubSurf_getNumFinalEdges(ss); dlm->totface = ccgSubSurf_getNumFinalFaces(ss); - if (vertMap_r) { - *vertMap_r = vertMap = MEM_callocN(dlm->totvert*sizeof(*vertMap), "vmap"); - *edgeMap_r = edgeMap = MEM_callocN(dlm->totedge*sizeof(*edgeMap), "emap"); - *faceMap_r = faceMap = MEM_callocN(dlm->totface*sizeof(*faceMap), "fmap"); - } - dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert"); dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge"); dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface"); @@ -305,39 +358,17 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i dlm->mcol = NULL; } - // load vertices - - vertBase = i = 0; - vi = ccgSubSurf_getVertIterator(ss); - for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); - VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v)); - if (vertMap) { - vertMap[i] = ccgDM_getVertHandle(ccgdm, v); - } - *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++; - } - ccgVertIterator_free(vi); - - edgeIndexBase = edgeBase = i; - ei = ccgSubSurf_getEdgeIterator(ss); - for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - int x; - - for (x=1; x<edgeSize-1; x++) { - VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x)); - } - - *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase; - edgeBase += edgeSize-2; - } - ccgEdgeIterator_free(ei); + /* Load vertices... we do in this funny order because + * all "added" vertices" are required to appear first + * in the displist (before STEPINDEX flags start). Also + * note that the vertex with index 0 is always a face + * center vert, this is relied upon to ensure we don't + * need to do silly test_index_face calls. + */ - faceBase = i; - fi = ccgSubSurf_getFaceIterator(ss); - for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + faceBase = i = 0; + for (index=0; index<totface; index++) { + CCGFace *f = faceMap2[index]; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f)); @@ -359,34 +390,37 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase; faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2)); } - ccgFaceIterator_free(fi); - - // load edges - i=0; - ei = ccgSubSurf_getEdgeIterator(ss); - for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, medge, tface); + edgeBase = i; + for (index=0; index<totedge; index++) { + CCGEdge *e= edgeMap2[index]; + int x; - for (x=0; x<edgeSize-1; x++) { - MEdge *med = &dlm->medge[i]; - med->v1 = getEdgeIndex(ss, e, x, edgeSize); - med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); - med->flag = flags; + for (x=1; x<edgeSize-1; x++) { + VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x)); + } - if (edgeMap) { - edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e); - } + *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase; + edgeBase += edgeSize-2; + } - i++; - } + vertBase = i; + lastIndex = -1; + for (index=0; index<totvert; index++) { + CCGVert *v = vertMap2[index]; + int mapIndex = ccgDM_getVertMapIndex(ccgdm, ss, v); + VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v)); + if (mapIndex!=lastIndex) + dlm->mvert[i].flag = ME_VERT_STEPINDEX; + *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++; + lastIndex = mapIndex; } - ccgEdgeIterator_free(ei); - fi = ccgSubSurf_getFaceIterator(ss); - for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + // load edges + + i = 0; + for (index=0; index<totface; index++) { + CCGFace *f = faceMap2[index]; int numVerts = ccgSubSurf_getFaceNumVerts(ss, f); for (k=0; k<numVerts; k++) { @@ -417,14 +451,35 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i } } } - ccgFaceIterator_free(fi); + + lastIndex = -1; + for (index=0; index<totedge; index++) { + CCGEdge *e= edgeMap2[index]; + unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, inDLM, medge, tface); + int edgeStart = i; + + for (x=0; x<edgeSize-1; x++) { + MEdge *med = &dlm->medge[i]; + med->v1 = getEdgeIndex(ss, e, x, edgeSize); + med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); + med->flag = flags; + i++; + } + + if (!useEdgeCreation) { + int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e); + if (mapIndex!=lastIndex) + dlm->medge[edgeStart].flag |= ME_EDGE_STEPINDEX; + lastIndex = mapIndex; + } + } // load faces - i = 0; - fi = ccgSubSurf_getFaceIterator(ss); - for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + i=0; + lastIndex = -1; + for (index=0; index<totface; index++) { + CCGFace *f = faceMap2[index]; int numVerts = ccgSubSurf_getFaceNumVerts(ss, f); float edge_data[4][6]; float corner_data[4][6]; @@ -433,6 +488,7 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i TFace *origTFace = NULL; int mat_nr; int flag; + int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f); if (!ssFromEditmesh) { int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f); @@ -488,26 +544,28 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i for (y=0; y<gridSize-1; y++) { for (x=0; x<gridSize-1; x++) { MFace *mf = &dlm->mface[i]; - mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize); - mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize); - mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize); - mf->v4 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize); + mf->v1 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize); + mf->v2 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize); + mf->v3 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize); + mf->v4 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize); mf->mat_nr = mat_nr; - mf->flag = flag; + mf->flag = flag&~ME_FACE_STEPINDEX; mf->edcode = 0; - if (faceMap) { - faceMap[i] = ccgDM_getFaceHandle(ccgdm, f); + if (S==0 && x==0 && y==0) { + if (mapIndex!=lastIndex) + mf->flag |= ME_FACE_STEPINDEX; + lastIndex = mapIndex; } if (x+1==gridSize-1) - mf->edcode|= ME_V2V3; + mf->edcode|= ME_V3V4; if (y+1==gridSize-1) - mf->edcode|= ME_V1V2; + mf->edcode|= ME_V2V3; for (j=0; j<4; j++) { - int fx = x + (j==1||j==2); - int fy = y + (j==0||j==1); + int fx = x + (j==2||j==3); + int fy = y + (j==1||j==2); float x_v = (float) fx/(gridSize-1); float y_v = (float) fy/(gridSize-1); float data[6]; @@ -550,7 +608,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i } } } - ccgFaceIterator_free(fi); + + MEM_freeN(faceMap2); + MEM_freeN(edgeMap2); + MEM_freeN(vertMap2); mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors); @@ -566,47 +627,53 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float int totvert = dlm?dlm->totvert:me->totvert; int totedge = dlm?dlm->totedge:me->totedge; int totface = dlm?dlm->totface:me->totface; - int i; + int i, index; ccgSubSurf_initFullSync(ss); - if (vertexCos) { - for (i=0; i<totvert; i++) { - ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]); - } - } else { - for (i=0; i<totvert; i++) { - ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co); - } + for (i=0,index=-1; i<totvert; i++) { + CCGVert *v; + ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, &v); + + if (!dlm || (mvert[i].flag&ME_VERT_STEPINDEX)) index++; + ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = index; } if (medge) { - for (i=0; i<totedge; i++) { + for (i=0, index=-1; i<totedge; i++) { MEdge *med = &medge[i]; + CCGEdge *e; float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f; - ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease); + ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease, &e); + + if (!dlm || (med->flag&ME_EDGE_STEPINDEX)) index++; + ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = index; } } else { for (i=0; i<totface; i++) { MFace *mf = &((MFace*) mface)[i]; if (!mf->v3) { - ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f); + ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f, NULL); } } } - for (i=0; i<totface; i++) { + for (i=0, index=-1; i<totface; i++) { MFace *mf = &((MFace*) mface)[i]; + if (!dlm || (mf->flag&ME_FACE_STEPINDEX)) index++; + if (mf->v3) { + CCGFace *f; fVerts[0] = (CCGVertHDL) mf->v1; fVerts[1] = (CCGVertHDL) mf->v2; fVerts[2] = (CCGVertHDL) mf->v3; fVerts[3] = (CCGVertHDL) mf->v4; - ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts); + ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts, &f); + ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = index; } } @@ -619,32 +686,40 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in EditVert *ev, *fVerts[4]; EditEdge *ee; EditFace *ef; + int i; ccgSubSurf_initFullSync(ss); if (vertCos) { - int i=0; - - for (ev=em->verts.first; ev; ev=ev->next) { - ccgSubSurf_syncVert(ss, ev, vertCos[i++]); + for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) { + CCGVert *v; + ccgSubSurf_syncVert(ss, ev, vertCos[i], &v); + ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i; } } else { - for (ev=em->verts.first; ev; ev=ev->next) { - ccgSubSurf_syncVert(ss, ev, ev->co); + for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) { + CCGVert *v; + ccgSubSurf_syncVert(ss, ev, ev->co, &v); + ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i; } } - for (ee=em->edges.first; ee; ee=ee->next) { - ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor); + for (i=0,ee=em->edges.first; ee; i++,ee=ee->next) { + CCGEdge *e; + ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor, &e); + ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = i; } - for (ef=em->faces.first; ef; ef=ef->next) { + for (i=0,ef=em->faces.first; ef; i++,ef=ef->next) { + CCGFace *f; + fVerts[0] = ef->v1; fVerts[1] = ef->v2; fVerts[2] = ef->v3; fVerts[3] = ef->v4; - ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts); + ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts, &f); + ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = i; } ccgSubSurf_processSync(ss); @@ -660,38 +735,18 @@ struct CCGDerivedMesh { Mesh *me; DispListMesh *dlm; - - EditVert **vertMap; - EditEdge **edgeMap; - EditFace **faceMap; }; -static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v) { - if (ccgdm->vertMap) { - int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v); - - return ccgdm->vertMap[index]; - } else { - return ccgSubSurf_getVertVertHandle(ccgdm->ss, v); - } +static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) { + return ((int*) ccgSubSurf_getVertUserData(ss, v))[1]; } -static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e) { - if (ccgdm->vertMap) { - int index = (int) ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e); - return ccgdm->edgeMap[index]; - } else { - return ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e); - } +static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) { + return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1]; } -static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f) { - if (ccgdm->vertMap) { - int index = (int) ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f); - return ccgdm->faceMap[index]; - } else { - return ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f); - } +static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) { + return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1]; } static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { @@ -792,20 +847,22 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { } ccgFaceIterator_free(fi); } -static void ccgDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) { +static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss); for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { CCGVert *v = ccgVertIterator_getCurrent(vi); VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v); + int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v); - func(userData, ccgDM_getVertHandle(ccgdm, v), vd->co, vd->no, NULL); + if (index!=-1) + func(userData, index, vd->co, vd->no, NULL); } ccgVertIterator_free(vi); } -static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) { +static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); @@ -813,11 +870,13 @@ static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userDa for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e); - for (i=0; i<edgeSize-1; i++) - func(userData, edge, edgeData[i].co, edgeData[i+1].co); + if (index!=-1) { + for (i=0; i<edgeSize-1; i++) + func(userData, index, edgeData[i].co, edgeData[i+1].co); + } } ccgEdgeIterator_free(ei); @@ -825,12 +884,7 @@ static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userDa static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, NULL, NULL, NULL); -} -static DispListMesh *ccgDM_convertToDispListMeshMapped(DerivedMesh *dm, int allowShared, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) { - CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - - return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, vertMap_r, edgeMap_r, faceMap_r); + return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm); } static void ccgDM_drawVerts(DerivedMesh *dm) { @@ -892,11 +946,6 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - if (ccgdm->fromEditmesh) { - EditEdge *eed = ccgDM_getEdgeHandle(ccgdm, e); - if (eed && eed->h!=0) - continue; - } if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e)) continue; @@ -922,12 +971,6 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) { CCGFace *f = ccgFaceIterator_getCurrent(fi); int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); - if (ccgdm->fromEditmesh) { - EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); - if (efa && efa->h!=0) - continue; - } - for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); @@ -970,7 +1013,7 @@ static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int 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, medge, tface); + unsigned int flags = ss_getEdgeFlags(ss, e, ccgdm->fromEditmesh, ccgdm->dlm, medge, tface); if ((flags&mask)==value) { glBegin(GL_LINE_STRIP); @@ -984,39 +1027,29 @@ static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int ccgEdgeIterator_free(ei); } + + /* Only used by non-editmesh types */ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); int gridSize = ccgSubSurf_getGridSize(ss); + MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface; for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); - unsigned char flag,mat_nr; - - if (ccgdm->fromEditmesh || ccgdm->vertMap) { - EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); - if (efa && efa->h!=0) - continue; - - flag = efa->flag; - mat_nr = efa->mat_nr; - } else { - int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f); - MFace *mf = (ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface) + index; - flag = mf->flag; - mat_nr = mf->mat_nr; - } - - if (!setMaterial(mat_nr+1)) + int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f); + MFace *mf = &mface[index]; + + if (!setMaterial(mf->mat_nr+1)) continue; - glShadeModel((flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT); + glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT); for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (flag&ME_SMOOTH) { + if (mf->flag&ME_SMOOTH) { for (y=0; y<gridSize-1; y++) { glBegin(GL_QUAD_STRIP); for (x=0; x<gridSize; x++) { @@ -1159,10 +1192,10 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); for (y=0; y<gridSize-1; y++) { for (x=0; x<gridSize-1; x++) { - VertData *a = &faceGridData[(y+0)*gridSize + x]; + VertData *a = &faceGridData[(y+0)*gridSize + x + 0]; VertData *b = &faceGridData[(y+0)*gridSize + x + 1]; VertData *c = &faceGridData[(y+1)*gridSize + x + 1]; - VertData *d = &faceGridData[(y+1)*gridSize + x]; + VertData *d = &faceGridData[(y+1)*gridSize + x + 0]; if (!(mf->flag&ME_SMOOTH)) { float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2]; @@ -1243,8 +1276,68 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, } */ } +static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) { + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + int i, gridSize = ccgSubSurf_getGridSize(ss); + + for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); + int drawSmooth = 1, index = ccgDM_getFaceMapIndex(ccgdm, ss, f); -static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) { + if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) { + for (S=0; S<numVerts; S++) { + VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + if (drawSmooth) { + glShadeModel(GL_SMOOTH); + for (y=0; y<gridSize-1; y++) { + glBegin(GL_QUAD_STRIP); + for (x=0; x<gridSize; x++) { + VertData *a = &faceGridData[(y+0)*gridSize + x]; + VertData *b = &faceGridData[(y+1)*gridSize + x]; + + glNormal3fv(a->no); + glVertex3fv(a->co); + glNormal3fv(b->no); + glVertex3fv(b->co); + } + glEnd(); + } + } else { + glShadeModel(GL_FLAT); + glBegin(GL_QUADS); + for (y=0; y<gridSize-1; y++) { + for (x=0; x<gridSize-1; x++) { + float *a = faceGridData[(y+0)*gridSize + x].co; + float *b = faceGridData[(y+0)*gridSize + x + 1].co; + float *c = faceGridData[(y+1)*gridSize + x + 1].co; + float *d = faceGridData[(y+1)*gridSize + x].co; + float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; + float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; + float no[3]; + + no[0] = b_dY*a_cZ - b_dZ*a_cY; + no[1] = b_dZ*a_cX - b_dX*a_cZ; + no[2] = b_dX*a_cY - b_dY*a_cX; + glNormal3fv(no); + + glVertex3fv(d); + glVertex3fv(c); + glVertex3fv(b); + glVertex3fv(a); + } + } + glEnd(); + } + } + } + } + + ccgFaceIterator_free(fi); +} +static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); @@ -1254,11 +1347,11 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e); glBegin(GL_LINE_STRIP); - if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) { + if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { if (useAging && !(G.f&G_BACKBUFSEL)) { int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; glColor3ub(0, ageCol>0?ageCol:0, 0); @@ -1274,7 +1367,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void ccgEdgeIterator_free(ei); } -static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) { +static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); @@ -1284,13 +1377,13 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions) for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e); glBegin(GL_LINE_STRIP); - if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) { + if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { for (i=0; i<edgeSize; i++) { - setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1)); + setDrawInterpOptions(userData, index, (float) i/(edgeSize-1)); if (useAging && !(G.f&G_BACKBUFSEL)) { int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; @@ -1302,50 +1395,23 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions) } glEnd(); } -} -static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) { - CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - - for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); - EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); - if (efa && (!setDrawOptions || setDrawOptions(userData, efa))) { - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); - - for (S=0; S<numVerts; S++) { - VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - - for (y=0; y<gridSize-1; y++) { - glBegin(GL_QUAD_STRIP); - for (x=0; x<gridSize; x++) { - glVertex3fv(faceGridData[(y+0)*gridSize + x].co); - glVertex3fv(faceGridData[(y+1)*gridSize + x].co); - } - glEnd(); - } - } - } - } - ccgFaceIterator_free(fi); + ccgEdgeIterator_free(ei); } -static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) { +static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); - EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); + int index = ccgDM_getFaceMapIndex(ccgdm, ss, f); - if (efa) { + if (index!=-1) { /* Face center data normal isn't updated atm. */ VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); - func(userData, efa, vd->co, vd->no); + func(userData, index, vd->co, vd->no); } } @@ -1356,39 +1422,33 @@ static void ccgDM_release(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; if (ccgdm->dlm) displistmesh_free(ccgdm->dlm); - if (ccgdm->vertMap) { - MEM_freeN(ccgdm->vertMap); - MEM_freeN(ccgdm->edgeMap); - MEM_freeN(ccgdm->faceMap); - } MEM_freeN(ccgdm); } -static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm, EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) { +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm) { CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); ccgdm->dm.getMinMax = ccgDM_getMinMax; ccgdm->dm.getNumVerts = ccgDM_getNumVerts; ccgdm->dm.getNumFaces = ccgDM_getNumFaces; ccgdm->dm.getVertCos = ccgdm_getVertCos; - ccgdm->dm.foreachMappedVertEM = ccgDM_foreachMappedVertEM; - ccgdm->dm.foreachMappedEdgeEM = ccgDM_foreachMappedEdgeEM; - ccgdm->dm.foreachMappedFaceCenterEM = ccgDM_foreachMappedFaceCenterEM; + ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert; + ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge; + ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter; ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh; - ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped; - + ccgdm->dm.drawVerts = ccgDM_drawVerts; ccgdm->dm.drawEdges = ccgDM_drawEdges; ccgdm->dm.drawEdgesFlag = ccgDM_drawEdgesFlag; ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored; ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; + ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; - ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM; - ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM; - ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM; - + ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; + ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; + ccgdm->dm.release = ccgDM_release; ccgdm->ss = ss; @@ -1396,9 +1456,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d ccgdm->drawInteriorEdges = drawInteriorEdges; ccgdm->me = me; ccgdm->dlm = dlm; - ccgdm->vertMap = vertMap; - ccgdm->edgeMap = edgeMap; - ccgdm->faceMap = faceMap; return ccgdm; } @@ -1413,10 +1470,10 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierDat smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple); ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL, NULL, NULL, NULL); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL); } -DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) { +DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3]) { int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr; int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges); @@ -1425,7 +1482,7 @@ DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifier ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm, vertMap, edgeMap, faceMap); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm); } DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) { @@ -1439,12 +1496,12 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL); + ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); + return derivedmesh_from_displistmesh(ndlm, NULL); } else { int useEdgeCreation = !(dlm?dlm->medge:me->medge); int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental) && !useEdgeCreation; @@ -1469,7 +1526,7 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL); + return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm); } else { if (smd->mCache && isFinalCalc) { ccgSubSurf_free(smd->mCache); @@ -1479,12 +1536,12 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss = _getSubSurf(NULL, smd->levels, 0, 1, useEdgeCreation, useSimple); ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL); + ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); + return derivedmesh_from_displistmesh(ndlm, NULL); } } } diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index 21fc7f73886..44b1cc53669 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -91,6 +91,13 @@ extern void flip_editnormals(void); /* ******************* editmesh_mods.c */ +extern void EM_init_index_arrays(int forVert, int forEdge, int forFace); +extern void EM_free_index_arrays(void); + +extern struct EditVert *EM_get_vert_for_index(int index); +extern struct EditEdge *EM_get_edge_for_index(int index); +extern struct EditFace *EM_get_face_for_index(int index); + extern void EM_select_face_fgon(struct EditFace *efa, int sel); extern int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax); diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 76dc57cd70d..decb52ec1fc 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -75,6 +75,7 @@ typedef struct MSticky { #define ME_SPHERETEST 2 #define ME_SPHERETEMP 4 #define ME_HIDE 16 +#define ME_VERT_STEPINDEX (1<<7) /* medge->flag (1=SELECT)*/ #define ME_EDGEDRAW (1<<1) @@ -89,6 +90,7 @@ typedef struct MSticky { #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) */ #define ME_FLIPV1 1 @@ -107,9 +109,9 @@ typedef struct MSticky { #define ME_V4V1 8 /* flag (mface) */ -#define ME_SMOOTH 1 -#define ME_FACE_SEL 2 - /* flag ME_HIDE is used here too */ - +#define ME_SMOOTH 1 +#define ME_FACE_SEL 2 + /* flag ME_HIDE==16 is used here too */ +#define ME_FACE_STEPINDEX (1<<7) #endif diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index fc2961364f0..6e11883b16c 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -2612,9 +2612,9 @@ static void mface_from_data( MFace * mf, TFace * tf, MCol * col, return; } - test_index_face( mf, tf, i ); + test_index_face(mf, NULL, tf, i ); } else { - test_index_mface( mf, i ); + test_index_face(mf, NULL, NULL, i ); } mf->mat_nr = from->mat_nr; diff --git a/source/blender/radiosity/intern/source/radpostprocess.c b/source/blender/radiosity/intern/source/radpostprocess.c index 12a7408a399..a722d881200 100644 --- a/source/blender/radiosity/intern/source/radpostprocess.c +++ b/source/blender/radiosity/intern/source/radpostprocess.c @@ -981,7 +981,7 @@ void rad_addmesh(void) if(face->v4) mface->v4= *((unsigned int *)face->v4+3); mface->edcode= 3; - test_index_mface(mface, face->v4 ? 4 : 3); + test_index_face(mface, NULL, NULL, face->v4 ? 4 : 3); mface->mat_nr= face->matindex; if (face->tface) { diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c index 2578c1b1216..4097c76dd11 100644 --- a/source/blender/src/booleanops.c +++ b/source/blender/src/booleanops.c @@ -772,9 +772,9 @@ ConvertCSGDescriptorsToMeshObject( ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0); } - test_index_face(mface, tface, 3); + test_index_face(mface, NULL, tface, 3); } else { - test_index_mface(mface, 3); + test_index_face(mface, NULL, NULL, 3); } fi_insert_pos++; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3ad4742730c..ef35971cfa1 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2434,6 +2434,7 @@ void do_meshbuts(unsigned short event) me->totedge= 1; } else make_edges(me); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWBUTSEDIT, 0); break; case B_DELEDGES: @@ -2475,11 +2476,6 @@ void do_meshbuts(unsigned short event) if(G.obedit) { flip_editnormals(); } - else { - flipnorm_mesh( get_mesh(ob) ); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } - allqueue(REDRAWVIEW3D, 0); break; diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 8193809ca18..11081fc43b8 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -185,7 +185,7 @@ void image_changed(SpaceImage *sima, int dotile) if(sima->mode==SI_TEXTURE) { if(G.f & G_FACESELECT) { - me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); + me= get_mesh(OBACT); if(me && me->tface) { tface= me->tface; a= me->totface; @@ -211,7 +211,8 @@ void image_changed(SpaceImage *sima, int dotile) } tface++; } - allqueue(REDRAWVIEW3D, 0); + + object_uvs_changed(OBACT); allqueue(REDRAWBUTSEDIT, 0); } } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 2f0547b137e..8acaf622988 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -896,9 +896,10 @@ static void drawlattice(Object *ob) /* ***************** ******************** */ -static void mesh_foreachScreenVert__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s) +static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData; + EditVert *eve = EM_get_vert_for_index(index); short s[2]; if (eve->h==0) { @@ -908,7 +909,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, EditVert *eve, float view3d_project_short_noclip(curarea, co, s, data->mat); } - data->func(data->userData, eve, s[0], s[1], (int) eve->prev); + data->func(data->userData, eve, s[0], s[1], index); } } void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts) @@ -916,8 +917,6 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } data; int dmNeedsFree; DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree); - EditVert *eve, *preveve; - int index; data.func = func; data.userData = userData; @@ -925,22 +924,19 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i view3d_get_object_project_mat(curarea, G.obedit, data.mat); - for (index=0,eve=G.editMesh->verts.first; eve; index++,eve= eve->next) - eve->prev = (EditVert*) index; - - dm->foreachMappedVertEM(dm, mesh_foreachScreenVert__mapFunc, &data); - - for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next) - eve->prev = preveve; + EM_init_index_arrays(1, 0, 0); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + EM_free_index_arrays(); if (dmNeedsFree) { dm->release(dm); } } -static void mesh_foreachScreenEdge__mapFunc(void *userData, EditEdge *eed, float *v0co, float *v1co) +static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co) { struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData; + EditEdge *eed = EM_get_edge_for_index(index); short s[2][2]; if (eed->h==0) { @@ -958,7 +954,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, EditEdge *eed, float } } - data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], (int) eed->prev); + data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index); } } void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts) @@ -966,8 +962,6 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } data; int dmNeedsFree; DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree); - EditEdge *eed, *preveed; - int index; data.func = func; data.userData = userData; @@ -975,28 +969,25 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, view3d_get_object_project_mat(curarea, G.obedit, data.mat); - for (index=0,eed=G.editMesh->edges.first; eed; index++,eed= eed->next) - eed->prev = (EditEdge*) index; - - dm->foreachMappedEdgeEM(dm, mesh_foreachScreenEdge__mapFunc, &data); - - for (preveed=NULL, eed=G.editMesh->edges.first; eed; preveed=eed, eed= eed->next) - eed->prev = preveed; + EM_init_index_arrays(0, 1, 0); + dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); + EM_free_index_arrays(); if (dmNeedsFree) { dm->release(dm); } } -static void mesh_foreachScreenFace__mapFunc(void *userData, EditFace *efa, float *cent, float *no) +static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no) { struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } *data = userData; + EditFace *efa = EM_get_face_for_index(index); short s[2]; - if (efa && efa->fgonf!=EM_FGON) { + if (efa && efa->h==0 && efa->fgonf!=EM_FGON) { view3d_project_short(curarea, cent, s, data->mat); - data->func(data->userData, efa, s[0], s[1], (int) efa->prev); + data->func(data->userData, efa, s[0], s[1], index); } } void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData) @@ -1004,21 +995,15 @@ void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, i struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } data; int dmNeedsFree; DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree); - EditFace *efa, *prevefa; - int index = 0; data.func = func; data.userData = userData; view3d_get_object_project_mat(curarea, G.obedit, data.mat); - for (index=0,efa=G.editMesh->faces.first; efa; index++,efa= efa->next) - efa->prev = (EditFace*) index; - - dm->foreachMappedFaceCenterEM(dm, mesh_foreachScreenFace__mapFunc, &data); - - for (prevefa=NULL, efa=G.editMesh->faces.first; efa; prevefa=efa, efa= efa->next) - efa->prev = prevefa; + EM_init_index_arrays(0, 0, 1); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + EM_free_index_arrays(); if (dmNeedsFree) { dm->release(dm); @@ -1118,8 +1103,10 @@ static unsigned char *calc_weightpaint_colors(Object *ob) * logic!!! */ -static void draw_dm_face_normals__mapFunc(void *userData, EditFace *efa, float *cent, float *no) +static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no) { + EditFace *efa = EM_get_face_for_index(index); + if (efa->h==0 && efa->fgonf!=EM_FGON) { glVertex3fv(cent); glVertex3f( cent[0] + no[0]*G.scene->editbutsize, @@ -1129,12 +1116,13 @@ static void draw_dm_face_normals__mapFunc(void *userData, EditFace *efa, float * } static void draw_dm_face_normals(DerivedMesh *dm) { glBegin(GL_LINES); - dm->foreachMappedFaceCenterEM(dm, draw_dm_face_normals__mapFunc, 0); + dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, 0); glEnd(); } -static void draw_dm_face_centers__mapFunc(void *userData, EditFace *efa, float *cent, float *no) +static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *no) { + EditFace *efa = EM_get_face_for_index(index); int sel = *((int*) userData); if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) { @@ -1144,12 +1132,14 @@ static void draw_dm_face_centers__mapFunc(void *userData, EditFace *efa, float * static void draw_dm_face_centers(DerivedMesh *dm, int sel) { bglBegin(GL_POINTS); - dm->foreachMappedFaceCenterEM(dm, draw_dm_face_centers__mapFunc, &sel); + dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel); bglEnd(); } -static void draw_dm_vert_normals__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s) +static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { + EditVert *eve = EM_get_vert_for_index(index); + if (eve->h==0) { glVertex3fv(co); @@ -1166,13 +1156,14 @@ static void draw_dm_vert_normals__mapFunc(void *userData, EditVert *eve, float * } static void draw_dm_vert_normals(DerivedMesh *dm) { glBegin(GL_LINES); - dm->foreachMappedVertEM(dm, draw_dm_vert_normals__mapFunc, NULL); + dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, NULL); glEnd(); } /* Draw verts with color set based on selection */ -static void draw_dm_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s) +static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { + EditVert *eve = EM_get_vert_for_index(index); int sel = *((int*) userData); if (eve->h==0 && (eve->f&SELECT)==sel) { @@ -1182,13 +1173,14 @@ static void draw_dm_verts__mapFunc(void *userData, EditVert *eve, float *co, flo static void draw_dm_verts(DerivedMesh *dm, int sel) { bglBegin(GL_POINTS); - dm->foreachMappedVertEM(dm, draw_dm_verts__mapFunc, &sel); + dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &sel); bglEnd(); } /* Draw edges with color set based on selection */ -static int draw_dm_edges_sel__setDrawOptions(void *userData, EditEdge *eed) +static int draw_dm_edges_sel__setDrawOptions(void *userData, int index) { + EditEdge *eed = EM_get_edge_for_index(index); unsigned char **cols = userData; if (eed->h==0) { @@ -1203,26 +1195,27 @@ static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned unsigned char *cols[2]; cols[0] = baseCol; cols[1] = selCol; - dm->drawMappedEdgesEM(dm, draw_dm_edges_sel__setDrawOptions, cols); + dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, cols); } /* Draw edges */ -static int draw_dm_edges__setDrawOptions(void *userData, EditEdge *eed) +static int draw_dm_edges__setDrawOptions(void *userData, int index) { - return eed->h==0; + return EM_get_edge_for_index(index)->h==0; } static void draw_dm_edges(DerivedMesh *dm) { - dm->drawMappedEdgesEM(dm, draw_dm_edges__setDrawOptions, NULL); + dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, NULL); } /* Draw edges with color interpolated based on selection */ -static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, EditEdge *eed) +static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index) { - return (eed->h==0); + return EM_get_edge_for_index(index)->h==0; } -static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, EditEdge *eed, float t) +static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t) { + EditEdge *eed = EM_get_edge_for_index(index); unsigned char **cols = userData; unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0]; unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0]; @@ -1237,26 +1230,30 @@ static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, un unsigned char *cols[2]; cols[0] = baseCol; cols[1] = selCol; - dm->drawMappedEdgesInterpEM(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); + dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols); } /* Draw only seam edges */ -static int draw_dm_edges_seams__setDrawOptions(void *userData, EditEdge *eed) +static int draw_dm_edges_seams__setDrawOptions(void *userData, int index) { + EditEdge *eed = EM_get_edge_for_index(index); + return (eed->h==0 && eed->seam); } static void draw_dm_edges_seams(DerivedMesh *dm) { - dm->drawMappedEdgesEM(dm, draw_dm_edges_seams__setDrawOptions, NULL); + dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL); } /* Draw faces with color set based on selection */ -static int draw_dm_faces_sel__setDrawOptions(void *userData, EditFace *efa) +static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r) { + EditFace *efa = EM_get_face_for_index(index); unsigned char **cols = userData; if (efa->h==0) { glColor4ubv(cols[(efa->f&SELECT)?1:0]); + *drawSmooth_r = (efa->flag&ME_SMOOTH); return 1; } else { return 0; @@ -1267,11 +1264,13 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned unsigned char *cols[2]; cols[0] = baseCol; cols[1] = selCol; - dm->drawMappedFacesEM(dm, draw_dm_faces_sel__setDrawOptions, cols); + dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, cols); } -static int draw_dm_creases__setDrawOptions(void *userData, EditEdge *eed) +static int draw_dm_creases__setDrawOptions(void *userData, int index) { + EditEdge *eed = EM_get_edge_for_index(index); + if (eed->h==0 && eed->crease!=0.0) { BIF_ThemeColorShade((eed->f&SELECT)?TH_EDGE_SELECT:TH_WIRE, 120*eed->crease); return 1; @@ -1279,11 +1278,10 @@ static int draw_dm_creases__setDrawOptions(void *userData, EditEdge *eed) return 0; } } - static void draw_dm_creases(DerivedMesh *dm) { glLineWidth(3.0); - dm->drawMappedEdgesEM(dm, draw_dm_creases__setDrawOptions, NULL); + dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, NULL); glLineWidth(1.0); } @@ -1382,7 +1380,7 @@ static void draw_em_fancy_edges(DerivedMesh *cageDM) draw_dm_edges_sel(cageDM, wire, sel); } else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) { - if(cageDM->drawMappedEdgesInterpEM && (G.scene->selectmode & SCE_SELECT_VERTEX)) { + if(cageDM->drawMappedEdgesInterp && (G.scene->selectmode & SCE_SELECT_VERTEX)) { glShadeModel(GL_SMOOTH); draw_dm_edges_sel_interp(cageDM, wire, sel); glShadeModel(GL_FLAT); @@ -1552,17 +1550,31 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em) } } +static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth_r) +{ + EditFace *efa = EM_get_face_for_index(index); + + if (efa->h==0) { + set_gl_material(efa->mat_nr); + *drawSmooth_r = efa->flag&ME_SMOOTH; + return 1; + } else { + return 0; + } +} static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt) { Mesh *me = ob->data; + EM_init_index_arrays(1, 1, 1); + if(dt>OB_WIRE) { glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); glEnable(GL_LIGHTING); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawFacesSolid(finalDM, set_gl_material); + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL); glFrontFace(GL_CCW); glDisable(GL_LIGHTING); @@ -1635,6 +1647,8 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived glDepthMask(1); bglPolygonOffset(0.0); } + + EM_free_index_arrays(); } /* Mesh drawing routines */ @@ -1729,7 +1743,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->tface) { tface_to_mcol(me); baseDM->drawFacesColored(baseDM, me->flag&ME_TWOSIDED, (unsigned char*) me->mcol, 0); - MEM_freeN(me->mcol); + MEM_freeN(me->mcol); me->mcol= 0; } else { @@ -3756,36 +3770,34 @@ void draw_object_ext(Base *base) /* ***************** BACKBUF SEL (BBS) ********* */ -static void bbs_mesh_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s) +static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { + int offset = (int) userData; + EditVert *eve = EM_get_vert_for_index(index); + if (eve->h==0) { - set_framebuffer_index_color((int) eve->prev); + set_framebuffer_index_color(offset+index); bglVertex3fv(co); } } static int bbs_mesh_verts(DerivedMesh *dm, int offset) { - EditVert *eve, *preveve; - - for (eve=G.editMesh->verts.first; eve; eve= eve->next) - eve->prev = (EditVert*) offset++; - glPointSize( BIF_GetThemeValuef(TH_VERTEX_SIZE) ); bglBegin(GL_POINTS); - dm->foreachMappedVertEM(dm, bbs_mesh_verts__mapFunc, NULL); + dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*) offset); bglEnd(); glPointSize(1.0); - for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next) - eve->prev = preveve; - - return offset; + return offset + G.totvert; // XXX is G variable reliable? } -static int bbs_mesh_wire__setDrawOptions(void *userData, EditEdge *eed) +static int bbs_mesh_wire__setDrawOptions(void *userData, int index) { + int offset = (int) userData; + EditEdge *eed = EM_get_edge_for_index(index); + if (eed->h==0) { - set_framebuffer_index_color((int) eed->vn); + set_framebuffer_index_color(offset+index); return 1; } else { return 0; @@ -3793,21 +3805,16 @@ static int bbs_mesh_wire__setDrawOptions(void *userData, EditEdge *eed) } static int bbs_mesh_wire(DerivedMesh *dm, int offset) { - EditEdge *eed; - - for(eed= G.editMesh->edges.first; eed; eed= eed->next) - eed->vn= (EditVert*) offset++; + dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*) offset); - dm->drawMappedEdgesEM(dm, bbs_mesh_wire__setDrawOptions, NULL); - - return offset; + return offset + G.totedge; // XXX is G variable reliable? } -static int bbs_mesh_solid__setSolidDrawOptions(void *userData, EditFace *efa) +static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) { - if (efa->h==0) { + if (EM_get_face_for_index(index)->h==0) { if (userData) { - set_framebuffer_index_color((int) efa->prev); + set_framebuffer_index_color(index+1); } return 1; } else { @@ -3815,10 +3822,12 @@ static int bbs_mesh_solid__setSolidDrawOptions(void *userData, EditFace *efa) } } -static void bbs_mesh_solid__drawCenter(void *userData, EditFace *efa, float *cent, float *no) +static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *no) { + EditFace *efa = EM_get_face_for_index(index); + if (efa->h==0 && efa->fgonf!=EM_FGON) { - set_framebuffer_index_color((int) efa->prev); + set_framebuffer_index_color(index+1); bglVertex3fv(cent); } @@ -3830,64 +3839,43 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol) cpack(0); if (facecol) { - EditFace *efa, *prevefa; - int a, b; - - // tuck original indices in efa->prev - for(b=1, efa= G.editMesh->faces.first; efa; efa= efa->next, b++) - efa->prev= (EditFace *)(b); - a = b; - - dm->drawMappedFacesEM(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 1); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 1); if(G.scene->selectmode & SCE_SELECT_FACE) { glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedFaceCenterEM(dm, bbs_mesh_solid__drawCenter, NULL); + dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, NULL); bglEnd(); } - for (prevefa= NULL, efa= G.editMesh->faces.first; efa; prevefa= efa, efa= efa->next) - efa->prev= prevefa; - return a; + return 1+G.totface; } else { - dm->drawMappedFacesEM(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0); + dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0); return 1; } } +static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r) +{ + Mesh *me = userData; + MFace *mf = &me->mface[index]; + + if (!me->tface || !(me->tface[index].flag&TF_HIDE)) { + set_framebuffer_index_color(index+1); + return 1; + } else { + return 0; + } +} static void bbs_mesh_solid(Object *ob) { - Mesh *me= ob->data; - MFace *mface= me->mface; - TFace *tface= me->tface; - float co[3]; - int a, glmode, dmNeedsFree; - DerivedMesh *dm = mesh_get_derived_deform(ob, &dmNeedsFree); + int dmNeedsFree; + DerivedMesh *dm = mesh_get_derived_final(ob, &dmNeedsFree); glColor3ub(0, 0, 0); - - glBegin(glmode=GL_QUADS); - for(a=0; a<me->totface; a++, mface++, tface++) { - if(mface->v3 && (!me->tface || !(tface->flag&TF_HIDE))) { - int newmode = mface->v4?GL_QUADS:GL_TRIANGLES; - - set_framebuffer_index_color(a+1); - - if (newmode!=glmode) { - glEnd(); - glBegin(glmode=newmode); - } - - glVertex3fv( (dm->getVertCo(dm, mface->v1, co),co) ); - glVertex3fv( (dm->getVertCo(dm, mface->v2, co),co) ); - glVertex3fv( (dm->getVertCo(dm, mface->v3, co),co) ); - if(mface->v4) glVertex3fv( (dm->getVertCo(dm, mface->v4, co),co) ); - } - } - glEnd(); - + dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, ob->data); + if (dmNeedsFree) { dm->release(dm); } @@ -3907,6 +3895,8 @@ void draw_object_backbufsel(Object *ob) int dmNeedsFree; DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree); + EM_init_index_arrays(1, 1, 1); + em_solidoffs= bbs_mesh_solid_EM(dm, G.scene->selectmode & SCE_SELECT_FACE); bglPolygonOffset(1.0); @@ -3923,6 +3913,8 @@ void draw_object_backbufsel(Object *ob) if (dmNeedsFree) { dm->release(dm); } + + EM_free_index_arrays(); } else bbs_mesh_solid(ob); diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index 015dac2c9b7..ca6be579bb1 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -344,9 +344,11 @@ int get_border(rcti *rect, short col) if (G.obedit) { if ELEM4(G.obedit->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) { circle_selectCB(&obedit_selectionCB); - return 0; } } + else if (G.f&G_FACESELECT) { + circle_selectCB(&obedit_selectionCB); + } return 0; case SPACE_IMAGE: // brush select in UV editor diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index aef790fa439..4d850a6e14d 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -363,6 +363,7 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed if(example) { efa->mat_nr= example->mat_nr; efa->tf= example->tf; + efa->tf.flag &= ~TF_ACTIVE; efa->flag= example->flag; } else { @@ -803,7 +804,7 @@ void make_editMesh() } if(mface->flag & ME_HIDE) efa->h= 1; } - else { + else if (tface) { if( tface->flag & TF_HIDE) efa->h= 1; else if( tface->flag & TF_SELECT) { @@ -841,96 +842,6 @@ void make_editMesh() waitcursor(0); } -/** Rotates MFace and UVFace vertices in case the last - * vertex index is = 0. - * This function is a hack and may only be called in the - * conversion from EditMesh to Mesh data. - * This function is similar to test_index_mface in - * blenkernel/intern/mesh.c. - * To not clutter the blenkernel code with more bad level - * calls/structures, this function resides here. - */ - -static void fix_faceindices(MFace *mface, EditFace *efa, int nr) -{ - int a; - float tmpuv[2]; - unsigned int tmpcol; - - /* first test if the face is legal */ - - if(mface->v3 && mface->v3==mface->v4) { - mface->v4= 0; - nr--; - } - if(mface->v2 && mface->v2==mface->v3) { - mface->v3= mface->v4; - mface->v4= 0; - nr--; - } - if(mface->v1==mface->v2) { - mface->v2= mface->v3; - mface->v3= mface->v4; - mface->v4= 0; - nr--; - } - - /* prevent a zero index value at the wrong location */ - if(nr==2) { - if(mface->v2==0) SWAP(int, mface->v1, mface->v2); - } - else if(nr==3) { - if(mface->v3==0) { - SWAP(int, mface->v1, mface->v2); - SWAP(int, mface->v2, mface->v3); - /* rotate face UV coordinates, too */ - UVCOPY(tmpuv, efa->tf.uv[0]); - UVCOPY(efa->tf.uv[0], efa->tf.uv[1]); - UVCOPY(efa->tf.uv[1], efa->tf.uv[2]); - UVCOPY(efa->tf.uv[2], tmpuv); - /* same with vertex colours */ - tmpcol = efa->tf.col[0]; - efa->tf.col[0] = efa->tf.col[1]; - efa->tf.col[1] = efa->tf.col[2]; - efa->tf.col[2] = tmpcol; - - - a= mface->edcode; - mface->edcode= 0; - if(a & ME_V1V2) mface->edcode |= ME_V3V1; - if(a & ME_V2V3) mface->edcode |= ME_V1V2; - if(a & ME_V3V1) mface->edcode |= ME_V2V3; - } - } - else if(nr==4) { - if(mface->v3==0 || mface->v4==0) { - SWAP(int, mface->v1, mface->v3); - SWAP(int, mface->v2, mface->v4); - /* swap UV coordinates */ - UVCOPY(tmpuv, efa->tf.uv[0]); - UVCOPY(efa->tf.uv[0], efa->tf.uv[2]); - UVCOPY(efa->tf.uv[2], tmpuv); - UVCOPY(tmpuv, efa->tf.uv[1]); - UVCOPY(efa->tf.uv[1], efa->tf.uv[3]); - UVCOPY(efa->tf.uv[3], tmpuv); - /* swap vertex colours */ - tmpcol = efa->tf.col[0]; - efa->tf.col[0] = efa->tf.col[2]; - efa->tf.col[2] = tmpcol; - tmpcol = efa->tf.col[1]; - efa->tf.col[1] = efa->tf.col[3]; - efa->tf.col[3] = tmpcol; - - a= mface->edcode; - mface->edcode= 0; - if(a & ME_V1V2) mface->edcode |= ME_V3V4; - if(a & ME_V2V3) mface->edcode |= ME_V2V3; - if(a & ME_V3V4) mface->edcode |= ME_V1V2; - if(a & ME_V4V1) mface->edcode |= ME_V4V1; - } - } -} - /* makes Mesh out of editmesh */ void load_editMesh(void) { @@ -1117,8 +1028,7 @@ void load_editMesh(void) /* no index '0' at location 3 or 4 */ - if(efa->v4) fix_faceindices(mface, efa, 4); - else fix_faceindices(mface, efa, 3); + test_index_face(mface, NULL, &efa->tf, efa->v4?4:3); i++; efa= efa->next; @@ -1132,7 +1042,7 @@ void load_editMesh(void) mface= &((MFace *) me->mface)[i]; mface->v1= (unsigned int) eed->v1->vn; mface->v2= (unsigned int) eed->v2->vn; - test_index_mface(mface, 2); + test_index_face(mface, NULL, NULL, 2); mface->edcode= ME_V1V2; i++; } @@ -1865,4 +1775,60 @@ void undo_push_mesh(char *name) /* *************** END UNDO *************/ +static EditVert **g_em_vert_array = NULL; +static EditEdge **g_em_edge_array = NULL; +static EditFace **g_em_face_array = NULL; + +void EM_init_index_arrays(int forVert, int forEdge, int forFace) +{ + EditVert *eve; + EditEdge *eed; + EditFace *efa; + int i; + + if (forVert) { + g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*G.totvert, "em_v_arr"); + + for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next) + g_em_vert_array[i] = eve; + } + + if (forEdge) { + g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*G.totedge, "em_e_arr"); + + for (i=0,eed=G.editMesh->edges.first; eed; i++,eed=eed->next) + g_em_edge_array[i] = eed; + } + + if (forFace) { + g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*G.totface, "em_f_arr"); + + for (i=0,efa=G.editMesh->faces.first; efa; i++,efa=efa->next) + g_em_face_array[i] = efa; + } +} + +void EM_free_index_arrays(void) +{ + if (g_em_vert_array) MEM_freeN(g_em_vert_array); + if (g_em_edge_array) MEM_freeN(g_em_edge_array); + if (g_em_face_array) MEM_freeN(g_em_face_array); + g_em_vert_array = NULL; + g_em_edge_array = NULL; + g_em_face_array = NULL; +} + +EditVert *EM_get_vert_for_index(int index) +{ + return g_em_vert_array?g_em_vert_array[index]:NULL; +} +EditEdge *EM_get_edge_for_index(int index) +{ + return g_em_edge_array?g_em_edge_array[index]:NULL; +} + +EditFace *EM_get_face_for_index(int index) +{ + return g_em_face_array?g_em_face_array[index]:NULL; +} diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 650271ac73c..11aabb263cd 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -405,7 +405,12 @@ int EM_init_backbuf_circle(short xs, short ys, short rads) short xmin, ymin, xmax, ymax, xc, yc; int radsq; - if(G.obedit==NULL || G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0; + /* method in use for face selecting too */ + if(G.obedit==NULL) { + if(G.f & G_FACESELECT); + else return 0; + } + else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0; if(em_vertoffs==0) return 0; xmin= xs-rads; xmax= xs+rads; @@ -651,39 +656,45 @@ static EditFace *findnearestface(short *dist) } /* for interactivity, frontbuffer draw in current window */ -static void draw_dm_mapped_vert__mapFunc(void *theVert, EditVert *eve, float *co, float *no_f, short *no_s) +static void draw_dm_mapped_vert__mapFunc(void *theVert, int index, float *co, float *no_f, short *no_s) { - if (eve==theVert) { + if (EM_get_vert_for_index(index)==theVert) { bglVertex3fv(co); } } static void draw_dm_mapped_vert(DerivedMesh *dm, EditVert *eve) { + EM_init_index_arrays(1, 0, 0); bglBegin(GL_POINTS); - dm->foreachMappedVertEM(dm, draw_dm_mapped_vert__mapFunc, eve); + dm->foreachMappedVert(dm, draw_dm_mapped_vert__mapFunc, eve); bglEnd(); + EM_free_index_arrays(); } -static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, EditEdge *eed) +static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, int index) { - return theEdge==eed; + return EM_get_edge_for_index(index)==theEdge; } static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed) { - dm->drawMappedEdgesEM(dm, draw_dm_mapped_edge__setDrawOptions, eed); + EM_init_index_arrays(0, 1, 0); + dm->drawMappedEdges(dm, draw_dm_mapped_edge__setDrawOptions, eed); + EM_free_index_arrays(); } -static void draw_dm_mapped_face_center__mapFunc(void *theFace, EditFace *efa, float *cent, float *no) +static void draw_dm_mapped_face_center__mapFunc(void *theFace, int index, float *cent, float *no) { - if (efa==theFace) { + if (EM_get_face_for_index(index)==theFace) { bglVertex3fv(cent); } } static void draw_dm_mapped_face_center(DerivedMesh *dm, EditFace *efa) { + EM_init_index_arrays(0, 0, 1); bglBegin(GL_POINTS); - dm->foreachMappedFaceCenterEM(dm, draw_dm_mapped_face_center__mapFunc, efa); + dm->foreachMappedFaceCenter(dm, draw_dm_mapped_face_center__mapFunc, efa); bglEnd(); + EM_free_index_arrays(); } static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index c35803103ee..f0c62fac817 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -1348,7 +1348,7 @@ static void facecopy(EditFace *source,EditFace *target) } target->mat_nr = source->mat_nr; - target->tf.flag = source->tf.flag; + target->tf.flag = source->tf.flag&~TF_ACTIVE; target->tf.transp = source->tf.transp; target->tf.mode = source->tf.mode; target->tf.tile = source->tf.tile; diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index ce9ffad1bf0..c9e2a09c957 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -147,6 +147,20 @@ void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select) } } +void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select) +{ + TFace *tface = me->tface; + int a; + + if (tface) { + for(a=1; a<=me->totface; a++, tface++) { + if(EM_check_backbuf(a)) { + tface->flag = select?(tface->flag|TF_SELECT):(tface->flag&~TF_SELECT); + } + } + } +} + void arrows_move_cursor(unsigned short event) { short mval[2]; @@ -502,30 +516,22 @@ static void do_lasso_select_armature(short mcords[][2], short moves, short selec static void do_lasso_select_facemode(short mcords[][2], short moves, short select) { Mesh *me; - TFace *tface; rcti rect; - int a; me= get_mesh(OBACT); if(me==NULL || me->tface==NULL) return; if(me->totface==0) return; - tface= me->tface; em_vertoffs= me->totface+1; // max index array lasso_select_boundbox(&rect, mcords, moves); EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - for(a=1; a<=me->totface; a++, tface++) { - if(EM_check_backbuf(a)) { - tface->flag = select?(tface->flag|TF_SELECT):(tface->flag&~TF_SELECT); - } - } + EM_backbuf_checkAndSelectTFaces(me, select); EM_free_backbuf(); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWIMAGE, 0); + object_tface_flags_changed(OBACT, 0); } static void do_lasso_select(short mcords[][2], short moves, short select) @@ -1728,7 +1734,23 @@ static void mesh_selectionCB(int selecting, Object *editobj, short *mval, float struct { short select, mval[2]; float radius; } data; EditMesh *em = G.editMesh; int bbsel; - + + if(!G.obedit && (G.f&G_FACESELECT)) { + Mesh *me = get_mesh(OBACT); + + if (me) { + em_vertoffs= me->totface+1; // max index array + + bbsel= EM_init_backbuf_circle(mval[0], mval[1], (short)(rad+1.0)); + EM_backbuf_checkAndSelectTFaces(me, selecting==LEFTMOUSE); + EM_free_backbuf(); + + object_tface_flags_changed(OBACT, 0); + } + + return; + } + bbsel= EM_init_backbuf_circle(mval[0], mval[1], (short)(rad+1.0)); data.select = (selecting==LEFTMOUSE); diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 65a2387fd83..044373d10f7 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -293,6 +293,8 @@ void vpaint_undo() *from= temp; to++; from++; } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); if(me->tface) mcol_to_tface(me, 1); } @@ -325,6 +327,8 @@ void clear_vpaint() to++; } BIF_undo_push("Clear vertex colors"); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); if(me->tface) mcol_to_tface(me, 1); } @@ -1282,6 +1286,7 @@ void vertex_paint() mcol_to_tface(me, 0); } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); scrarea_do_windraw(curarea); if(Gvp.flag & (VP_AREA|VP_SOFT)) { |