diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_subsurf.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 309 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 106 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 182 | ||||
-rw-r--r-- | source/blender/src/editmesh_mods.c | 19 |
6 files changed, 502 insertions, 135 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 6350332fd66..1158f89dde0 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -74,6 +74,18 @@ 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 @@ -137,9 +149,6 @@ struct DerivedMesh { */ void (*drawMappedVertsEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData); - /* Draw single mapped edge as lines (no options) */ - void (*drawMappedEdgeEM)(DerivedMesh *dm, void *edge); - /* Draw mapped edges as lines * o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true */ @@ -179,7 +188,7 @@ struct DerivedMesh { }; /* Internal function, just temporarily exposed */ -DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm); +DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap); 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_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 925ef15288f..dbcc2dd3e17 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -35,9 +35,13 @@ 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_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/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index b26d40f60fe..25ec8d6e3a4 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -140,11 +140,8 @@ static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3]) { MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; - float *co = mdm->verts[index].co; - co_r[0] = co[0]; - co_r[1] = co[1]; - co_r[2] = co[2]; + VECCOPY(co_r, mdm->verts[index].co); } static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) @@ -479,9 +476,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3] mdm->verts = MEM_mallocN(sizeof(*mdm->verts)*me->totvert, "deformedVerts"); for (i=0; i<me->totvert; i++) { - mdm->verts[i].co[0] = vertCos[i][0]; - mdm->verts[i].co[1] = vertCos[i][1]; - mdm->verts[i].co[2] = vertCos[i][2]; + VECCOPY(mdm->verts[i].co, vertCos[i]); } mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors); mdm->freeNors = 1; @@ -519,18 +514,14 @@ static void emDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) { if (eve==vert) { - co_r[0] = emdm->vertexCos[i][0]; - co_r[1] = emdm->vertexCos[i][1]; - co_r[2] = emdm->vertexCos[i][2]; + VECCOPY(co_r, emdm->vertexCos[i]); break; } } } else { EditVert *eve = vert; - co_r[0] = eve->co[0]; - co_r[1] = eve->co[1]; - co_r[2] = eve->co[2]; + VECCOPY(co_r, eve->co); } } static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) @@ -556,15 +547,6 @@ static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void * bglEnd(); } } -static void emDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) -{ - EditEdge *eed = edge; - - glBegin(GL_LINES); - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); - glEnd(); -} static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; @@ -656,13 +638,9 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[ } if (efa->v4) { - cent[0] *= 0.25f; - cent[1] *= 0.25f; - cent[2] *= 0.25f; + VecMulf(cent, 0.25f); } else { - cent[0] *= 0.33333333333f; - cent[1] *= 0.33333333333f; - cent[2] *= 0.33333333333f; + VecMulf(cent, 0.33333333333f); } } static void emDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData) @@ -892,7 +870,6 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3]) emdm->dm.drawMappedVertsEM = emDM_drawMappedVertsEM; emdm->dm.drawEdges = emDM_drawEdges; - emdm->dm.drawMappedEdgeEM = emDM_drawMappedEdgeEM; emdm->dm.drawMappedEdgesEM = emDM_drawMappedEdgesEM; emdm->dm.drawMappedEdgesInterpEM = emDM_drawMappedEdgesInterpEM; @@ -963,8 +940,183 @@ typedef struct { DerivedMesh dm; DispListMesh *dlm; + + EditVert **vertMap; + EditEdge **edgeMap; + EditFace **faceMap; } SSDerivedMesh; +static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + + if (ssdm->vertMap) { + int i; + + for (i=0; i<dlm->totvert; i++) { + if (ssdm->vertMap[i]==vert) { + VECCOPY(co_r, dlm->mvert[i].co); + break; + } + } + } +} +static void ssDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + + if (ssdm->vertMap) { + int i; + + bglBegin(GL_POINTS); + for (i=0; i<dlm->totvert; i++) { + if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) { + bglVertex3fv(dlm->mvert[i].co); + } + } + bglEnd(); + } +} +static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + int i; + + 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]; + + glVertex3fv(dlm->mvert[med->v1].co); + glVertex3fv(dlm->mvert[med->v2].co); + } + } + glEnd(); + } +} + +static void ssDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + int i; + + if (ssdm->faceMap) { + bglBegin(GL_POINTS); + 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) { + float cent[3]; + + VECCOPY(cent, dlm->mvert[mf->v1].co); + VecAddf(cent, cent, dlm->mvert[mf->v2].co); + VecAddf(cent, cent, dlm->mvert[mf->v3].co); + + if (mf->v4) { + VecAddf(cent, cent, dlm->mvert[mf->v4].co); + VecMulf(cent, 0.25f); + } else { + VecMulf(cent, 0.33333333333f); + } + + bglVertex3fv(cent); + } + } + } + bglEnd(); + } +} +static void ssDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + int i; + + if (ssdm->faceMap) { + glBegin(GL_LINES); + 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) { + float cent[3]; + float no[3]; + + VECCOPY(cent, dlm->mvert[mf->v1].co); + VecAddf(cent, cent, dlm->mvert[mf->v2].co); + VecAddf(cent, cent, dlm->mvert[mf->v3].co); + + 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); + } + + glVertex3fv(cent); + glVertex3f( cent[0] + length*no[0], + cent[1] + length*no[1], + cent[2] + length*no[2]); + } + } + } + glEnd(); + } +} +static void ssDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData) +{ + SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; + DispListMesh *dlm = ssdm->dlm; + int i; + + if (ssdm->vertMap) { + glBegin(GL_LINES); + for (i=0; i<dlm->totvert; i++) { + if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) { + float *co = dlm->mvert[i].co; + short *no = dlm->mvert[i].no; + + glVertex3fv(co); + glVertex3f( co[0] + length*no[0]/32767.0, + co[1] + length*no[1]/32767.0, + co[2] + length*no[2]/32767.0); + } + } + glEnd(); + } +} +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(); + } + } + } + } +} + static void ssDM_drawMappedEdges(DerivedMesh *dm) { SSDerivedMesh *ssdm = (SSDerivedMesh*) dm; @@ -1251,16 +1403,38 @@ 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) +DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) { SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm"); @@ -1269,6 +1443,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm) 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; @@ -1282,9 +1457,41 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm) ssdm->dm.drawFacesColored = ssDM_drawFacesColored; ssdm->dm.drawFacesTex = ssDM_drawFacesTex; + /* EM functions */ + + ssdm->dm.getMappedVertCoEM = ssDM_getMappedVertCoEM; + ssdm->dm.drawMappedVertsEM = ssDM_drawMappedVertsEM; + + ssdm->dm.drawMappedEdgesEM = ssDM_drawMappedEdgesEM; + ssdm->dm.drawMappedEdgesInterpEM = NULL; // no way to implement this one + + ssdm->dm.drawMappedVertNormalsEM = ssDM_drawMappedVertNormalsEM; + ssdm->dm.drawMappedFaceNormalsEM = ssDM_drawMappedFaceNormalsEM; + ssdm->dm.drawMappedFaceCentersEM = ssDM_drawMappedFaceCentersEM; + + 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; + + for (i=0; i<dlm->totvert; i++) { + VECCOPY(dlm->mvert[i].co, vertexCos[i]); + } + + if (dlm->nors && !dlm->dontFreeNors) { + MEM_freeN(dlm->nors); + dlm->nors = 0; + } + + mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors); + } return (DerivedMesh*) ssdm; } @@ -1417,24 +1624,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM */ if (dm && deformedVerts) { DispListMesh *dlm = dm->convertToDispListMesh(dm, 0); - int i; - - /* XXX, would like to avoid the conversion to a DLM here if possible. - * Requires adding a DerivedMesh.updateVertCos method. - */ - for (i=0; i<numVerts; i++) { - VECCOPY(dlm->mvert[i].co, deformedVerts[i]); - } dm->release(dm); - if (dlm->nors && !dlm->dontFreeNors) { - MEM_freeN(dlm->nors); - dlm->nors = 0; - } - - mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors); - *final_r = derivedmesh_from_displistmesh(dlm); + *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL); } else if (dm) { *final_r = dm; } else { @@ -1526,8 +1719,14 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) if (cage_r && i==cageIndex) { if (dm && deformedVerts) { - // XXX this is not right, need to convert the dm - *cage_r = dm; + DispListMesh *dlm; + EditVert **vertMap; + EditEdge **edgeMap; + EditFace **faceMap; + + dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap); + + *cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts, vertMap, edgeMap, faceMap); } else if (dm) { *cage_r = dm; } else { @@ -1542,24 +1741,10 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) */ if (dm && deformedVerts) { DispListMesh *dlm = dm->convertToDispListMesh(dm, 0); - int i; - - /* XXX, would like to avoid the conversion to a DLM here if possible. - * Requires adding a DerivedMesh.updateVertCos method. - */ - for (i=0; i<numVerts; i++) { - VECCOPY(dlm->mvert[i].co, deformedVerts[i]); - } if (!cage_r || dm!=*cage_r) dm->release(dm); - if (dlm->nors && !dlm->dontFreeNors) { - MEM_freeN(dlm->nors); - dlm->nors = 0; - } - - mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors); - *final_r = derivedmesh_from_displistmesh(dlm); + *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL); MEM_freeN(deformedVerts); } else if (dm) { *final_r = dm; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index a1786ed8898..6f9e2f861b2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -189,7 +189,14 @@ static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void SubsurfModifierData *smd = (SubsurfModifierData*) md; if (dm) { - return subsurfModifier_applyModifier(md, ob, dm, vertexCos, 0, 1); + EditVert **vertMap; + EditEdge **edgeMap; + EditFace **faceMap; + DispListMesh *dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap); + + dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos, vertMap, edgeMap, faceMap); + + return dm; } else { return subsurf_make_derived_from_editmesh(em, smd, vertexCos); } @@ -432,7 +439,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); + return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); } /* Mirror */ @@ -453,25 +460,40 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target) tmmd->tolerance = mmd->tolerance; } -static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3]) +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) { 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; + } for (i=0; i<totvert; i++) { MVert *mv = &ndlm->mvert[i]; int isShared = ABS(mv->co[axis])<=tolerance; - /* Because the topology result (# of vertices) must stuff 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. - */ + /* Because the topology result (# of vertices) must stuff 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. + */ if (vertexCos) { VECCOPY(mv->co, vertexCos[i]); } + if (vMapOut) vMapOut[i] = vertMap[i]; + if (isShared) { mv->co[axis] = 0; *((int*) mv->no) = i; @@ -481,6 +503,8 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm memcpy(nmv, mv, sizeof(*mv)); nmv ->co[axis] = -nmv ->co[axis]; + if (vMapOut) vMapOut[ndlm->totvert] = vertMap[i]; + *((int*) mv->no) = ndlm->totvert++; } } @@ -495,7 +519,11 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no); nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no); + if (eMapOut) eMapOut[i] = edgeMap[i]; + if (nmed->v1!=med->v1 || nmed->v2!=med->v2) { + if (eMapOut) eMapOut[ndlm->totedge] = edgeMap[i]; + ndlm->totedge++; } } @@ -505,7 +533,7 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm 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; /* gcc's mother is uninitialized! */ + MCol *mc=NULL, *nmc=NULL; memcpy(nmf, mf, sizeof(*mf)); if (ndlm->tface) { @@ -527,10 +555,14 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no); } + 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 @@ -574,7 +606,7 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm } } -static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc) +static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc, int needsMaps) { DerivedMesh *dm = derivedData; MirrorModifierData *mmd = (MirrorModifierData*) md; @@ -584,9 +616,16 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de MFace *mface; TFace *tface; MCol *mcol; + EditVert **vertMapOut, **vertMap = NULL; + EditEdge **edgeMapOut, **edgeMap = NULL; + EditFace **faceMapOut, **faceMap = NULL; if (dm) { - dlm = dm->convertToDispListMesh(dm, 1); + if (needsMaps) { + dlm = dm->convertToDispListMeshMapped(dm, 1, &vertMap, &edgeMap, &faceMap); + } else { + dlm = dm->convertToDispListMesh(dm, 1); + } mvert = dlm->mvert; medge = dlm->medge; @@ -628,19 +667,31 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface); } - mirrorModifier__doMirror(mmd, ndlm, vertexCos); + mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut); - if (dlm) displistmesh_free(dlm); + 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); - return derivedmesh_from_displistmesh(ndlm); + return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut); +} + +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); } static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]) { if (derivedData) { - return mirrorModifier_applyModifier(md, ob, derivedData, vertexCos, 0, 1); + return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 1); } else { MirrorModifierData *mmd = (MirrorModifierData*) md; DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm"); @@ -648,6 +699,9 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * 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) @@ -657,6 +711,10 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * ndlm->totedge = BLI_countlist(&em->edges); ndlm->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"); + 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"); @@ -665,6 +723,8 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * MVert *mv = &ndlm->mvert[i]; VECCOPY(mv->co, eve->co); + + vertMap[i] = eve; } for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) { MEdge *med = &ndlm->medge[i]; @@ -672,6 +732,8 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * med->v1 = (int) eed->v1->prev; med->v2 = (int) eed->v2->prev; med->crease = (unsigned char) (eed->crease*255.0f); + + edgeMap[i] = eed; } for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) { MFace *mf = &ndlm->mface[i]; @@ -683,16 +745,22 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void * mf->flag = efa->flag; test_index_mface(mf, efa->v4?4:3); + + faceMap[i] = efa; } - mirrorModifier__doMirror(mmd, ndlm, vertexCos); + mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut); 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); - return derivedmesh_from_displistmesh(ndlm); + MEM_freeN(faceMap); + MEM_freeN(edgeMap); + MEM_freeN(vertMap); + + return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut); } } @@ -837,7 +905,7 @@ exit: if (ndlm) { mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors); - return derivedmesh_from_displistmesh(ndlm); + return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); } else { return NULL; } @@ -1008,7 +1076,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti = INIT_TYPE(Mirror); mti->type = eModifierTypeType_Constructive; - mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode; + mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode; mti->initData = mirrorModifier_initData; mti->copyData = mirrorModifier_copyData; mti->applyModifier = mirrorModifier_applyModifier; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 316b7425988..c28c0b20b73 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -66,6 +66,12 @@ typedef struct _VertData { float no[3]; } 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 void *arena_alloc(CCGAllocatorHDL a, int numBytes) { @@ -190,7 +196,7 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1); } } -static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM) { +static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) { DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm"); int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSize = ccgSubSurf_getGridSize(ss); @@ -204,7 +210,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh CCGVertIterator *vi; CCGEdgeIterator *ei; CCGFaceIterator *fi; - + EditVert **vertMap = NULL; + EditEdge **edgeMap = NULL; + EditFace **faceMap = NULL; + if (!ssFromEditmesh) { if (inDLM) { tface = inDLM->tface; @@ -223,6 +232,12 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh 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"); @@ -244,6 +259,9 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh 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); @@ -303,9 +321,9 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh med->flag = ME_EDGEDRAW; if (ssFromEditmesh) { - EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e); + EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e); - if (ee->seam) { + if (eed->seam) { med->flag|= ME_SEAM; } } else { @@ -319,6 +337,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh } } + if (edgeMap) { + edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e); + } + i++; } } @@ -434,6 +456,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh mf->flag = flag; mf->edcode = 0; + if (faceMap) { + faceMap[i] = ccgDM_getFaceHandle(ccgdm, f); + } + if (x+1==gridSize-1) mf->edcode|= ME_V2V3; if (y+1==gridSize-1) @@ -585,7 +611,7 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in /***/ -typedef struct { +struct CCGDerivedMesh { DerivedMesh dm; CCGSubSurf *ss; @@ -593,7 +619,39 @@ typedef struct { Mesh *me; DispListMesh *dlm; -} CCGDerivedMesh; + + 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 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 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 void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; @@ -695,17 +753,47 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { } static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert); - float *co = ccgSubSurf_getVertData(ccgdm->ss, v); - co_r[0] = co[0]; - co_r[1] = co[1]; - co_r[2] = co[2]; + /* The vert handle is an index into the vmap in this case, have + * to search for it. + */ + if (ccgdm->vertMap) { + CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss); + + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v); + + if (ccgdm->vertMap[index]==vert) { + float *co = ccgSubSurf_getVertData(ccgdm->ss, v); + + co_r[0] = co[0]; + co_r[1] = co[1]; + co_r[2] = co[2]; + + break; + } + } + + ccgVertIterator_free(vi); + } else { + CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert); + float *co = ccgSubSurf_getVertData(ccgdm->ss, v); + + co_r[0] = co[0]; + co_r[1] = co[1]; + co_r[2] = co[2]; + } } static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - return ss_to_displistmesh(ccgdm->ss, ccgdm->fromEditmesh, ccgdm->me, ccgdm->dlm); + return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, 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->me, ccgdm->dlm, vertMap_r, edgeMap_r, faceMap_r); } static void ccgDM_drawVerts(DerivedMesh *dm) { @@ -768,7 +856,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) { VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); if (ccgdm->fromEditmesh) { - EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e); + EditEdge *eed = ccgDM_getEdgeHandle(ccgdm, e); if (eed->h!=0) continue; } @@ -795,7 +883,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) { int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); if (ccgdm->fromEditmesh) { - EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f); + EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); if (efa->h!=0) continue; } @@ -880,8 +968,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); unsigned char flag,mat_nr; - if (ccgdm->fromEditmesh) { - EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f); + if (ccgdm->fromEditmesh || ccgdm->vertMap) { + EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); if (efa->h!=0) continue; @@ -1136,7 +1224,7 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void bglBegin(GL_POINTS); for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { CCGVert *v = ccgVertIterator_getCurrent(vi); - EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v); + EditVert *vert = ccgDM_getVertHandle(ccgdm, v); if (!setDrawOptions || setDrawOptions(userData, vert)) { bglVertex3fv(ccgSubSurf_getVertData(ss, v)); @@ -1154,7 +1242,7 @@ static void ccgDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*s glBegin(GL_LINES); for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { CCGVert *v = ccgVertIterator_getCurrent(vi); - EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v); + EditVert *vert = ccgDM_getVertHandle(ccgdm, v); if (!setDrawOptions || setDrawOptions(userData, vert)) { VertData *vd = ccgSubSurf_getVertData(ss, v); @@ -1169,21 +1257,6 @@ static void ccgDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*s ccgVertIterator_free(vi); } -static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) { - CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); - CCGEdge *e = ccgSubSurf_getEdge(ss, edge); - VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int i, edgeSize = ccgSubSurf_getEdgeSize(ss); - - glBegin(GL_LINE_STRIP); - for (i=0; i<edgeSize; i++) - glVertex3fv(edgeData[i].co); - glEnd(); - - ccgEdgeIterator_free(ei); -} static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; @@ -1194,7 +1267,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e); + EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); @@ -1224,7 +1297,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions) for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e); + EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); glBegin(GL_LINE_STRIP); @@ -1251,7 +1324,7 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); - EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f); + EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); if (!setDrawOptions || setDrawOptions(userData, efa)) { int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); @@ -1281,7 +1354,7 @@ static void ccgDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*s glBegin(GL_LINES); for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); - EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f); + EditFace *efa = ccgDM_getFaceHandle(ccgdm, f); if (!setDrawOptions || setDrawOptions(userData, efa)) { /* Face center data normal isn't updated atm. */ VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); @@ -1301,11 +1374,16 @@ 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, Mesh *me, DispListMesh *dlm) { +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh *me, DispListMesh *dlm, EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) { CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); ccgdm->dm.getMinMax = ccgDM_getMinMax; @@ -1314,6 +1392,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh ccgdm->dm.getVertCos = ccgdm_getVertCos; ccgdm->dm.getMappedVertCoEM = ccgDM_getMappedVertCoEM; ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh; + ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped; ccgdm->dm.drawVerts = ccgDM_drawVerts; ccgdm->dm.drawEdges = ccgDM_drawEdges; @@ -1325,7 +1404,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh ccgdm->dm.drawMappedVertsEM = ccgDM_drawMappedVertsEM; ccgdm->dm.drawMappedVertNormalsEM = ccgDM_drawMappedVertNormalsEM; - ccgdm->dm.drawMappedEdgeEM = ccgDM_drawMappedEdgeEM; ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM; ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM; ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM; @@ -1337,6 +1415,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh ccgdm->fromEditmesh = fromEditmesh; ccgdm->me = me; ccgdm->dlm = dlm; + ccgdm->vertMap = vertMap; + ccgdm->edgeMap = edgeMap; + ccgdm->faceMap = faceMap; return ccgdm; } @@ -1350,7 +1431,18 @@ 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, NULL, NULL); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, NULL, NULL, NULL, NULL, NULL); +} + +DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) { + int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; + int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr; + + smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple); + + ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple); + + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, NULL, dlm, vertMap, edgeMap, faceMap); } DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) { @@ -1363,12 +1455,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, 0, me, dlm); + ndlm = ss_to_displistmesh(ss, NULL, 0, me, dlm, NULL, NULL, NULL); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - return derivedmesh_from_displistmesh(ndlm); + return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); } else { int useEdgeCreation = !(dlm?dlm->medge:me->medge); int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental) && !useEdgeCreation; @@ -1393,7 +1485,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, me, dlm); + return (DerivedMesh*) getCCGDerivedMesh(ss, 0, me, dlm, NULL, NULL, NULL); } else { if (smd->mCache && isFinalCalc) { ccgSubSurf_free(smd->mCache); @@ -1402,12 +1494,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, 0, me, dlm); + ndlm = ss_to_displistmesh(ss, NULL, 0, me, dlm, NULL, NULL, NULL); if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - return derivedmesh_from_displistmesh(ndlm); + return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL); } } } diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 4623d171f55..dcc43167369 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -675,6 +675,15 @@ static EditFace *findnearestface(short *dist) } /* for interactivity, frontbuffer draw in current window */ +static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, EditEdge *eed) +{ + return theEdge==eed; +} +static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed) +{ + dm->drawMappedEdgesEM(dm, draw_dm_mapped_edge__setDrawOptions, eed); +} + static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) { int dmNeedsFree; @@ -706,11 +715,11 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) if(efa->fgonf==0) { BIF_ThemeColor((efa->f & SELECT)?TH_EDGE_SELECT:TH_WIRE); - dm->drawMappedEdgeEM(dm, efa->e1); - dm->drawMappedEdgeEM(dm, efa->e2); - dm->drawMappedEdgeEM(dm, efa->e3); + draw_dm_mapped_edge(dm, efa->e1); + draw_dm_mapped_edge(dm, efa->e2); + draw_dm_mapped_edge(dm, efa->e3); if (efa->e4) { - dm->drawMappedEdgeEM(dm, efa->e4); + draw_dm_mapped_edge(dm, efa->e4); } } } @@ -731,7 +740,7 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa) if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) { BIF_ThemeColor((eed->f & SELECT)?TH_EDGE_SELECT:TH_WIRE); - dm->drawMappedEdgeEM(dm, eed); + draw_dm_mapped_edge(dm, eed); } if(G.scene->selectmode & SCE_SELECT_VERTEX) { float co[3]; |