Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h17
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c309
-rw-r--r--source/blender/blenkernel/intern/modifier.c106
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c182
-rw-r--r--source/blender/src/editmesh_mods.c19
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];