diff options
author | Daniel Dunbar <daniel@zuster.org> | 2005-07-22 11:37:15 +0400 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2005-07-22 11:37:15 +0400 |
commit | e546e81762b2214eaf2439c04eea4d339901c2b5 (patch) | |
tree | 683f67adc43738e0226e9cc92a6ec96a5cbb7979 /source/blender/blenkernel | |
parent | 5e34b80e1b2e36a3304802a373a1cebec5b25ba3 (diff) |
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 25 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_subsurf.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 375 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 157 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 288 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 384 |
9 files changed, 953 insertions, 300 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 2fd1eed2a3e..080c21c5d5e 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -91,7 +91,10 @@ struct DerivedMesh { /* Draw all vertices as bgl points (no options) */ void (*drawVerts)(DerivedMesh *dm); - /* Draw all edges as lines (no options) */ + /* Draw all edges as lines (no options) + * + * Also called for *final* editmode DerivedMeshes + */ void (*drawEdges)(DerivedMesh *dm); /* Draw mapped edges as lines (no options) */ @@ -106,7 +109,7 @@ struct DerivedMesh { * o Use inherited face material index to call setMaterial * o Only if setMaterial returns true * - * Also called in Editmode + * Also called for *final* editmode DerivedMeshes */ void (*drawFacesSolid)(DerivedMesh *dm, int (*setMaterial)(int)); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index a09ee20b385..e079b2f2e30 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -58,6 +58,7 @@ typedef enum { eModifierTypeFlag_AcceptsMesh = (1<<0), eModifierTypeFlag_AcceptsCVs = (1<<1), eModifierTypeFlag_SupportsMapping = (1<<2), + eModifierTypeFlag_SupportsEditmode = (1<<3), } ModifierTypeFlag; typedef struct ModifierTypeInfo { @@ -112,9 +113,14 @@ typedef struct ModifierTypeInfo { int (*dependsOnTime)(struct ModifierData *md); /* Only for deform types, should apply the deformation - * to the given vertex array. + * to the given vertex array. If the deformer requires information from + * the object it can obtain it from the _derivedData_ argument if non-NULL, + * and otherwise the _ob_ argument. */ - void (*deformVerts)(struct ModifierData *md, struct Object *ob, float (*vertexCos)[3], int numVerts); + void (*deformVerts)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts); + + /* Like deformVerts but called during editmode (for supporting modifiers) */ + void (*deformVertsEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts); /* For non-deform types: apply the modifier and return a new derived * data object (type is dependent on object type). If the _derivedData_ @@ -130,10 +136,23 @@ typedef struct ModifierTypeInfo { * The _useRenderParams_ indicates if the modifier is being applied in * the service of the renderer which may alter quality settings. * + * The _isFinalCalc_ parameter indicates if the modifier is being calculated + * for a final result or for something temporary (like orcos). This is a hack + * at the moment, it is meant so subsurf can know if it is safe to reuse its + * internal cache. + * * The modifier is expected to release (or reuse) the _derivedData_ argument * if non-NULL. The modifier *MAY NOT* share the _vertexCos_ argument. */ - void *(*applyModifier)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams); + void *(*applyModifier)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc); + + /* Like applyModifier but called during editmode (for supporting modifiers). + * + * The derived object that is returned must support the operations that are expected + * from editmode objects. The same qualifications regarding _derivedData_ and _vertexCos_ + * apply as for applyModifier. + */ + void *(*applyModifierEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]); } ModifierTypeInfo; ModifierTypeInfo *modifierType_get_info(ModifierType type); diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index a5200276159..925ef15288f 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -37,8 +37,8 @@ struct DerivedMesh; struct EditMesh; struct SubsurfModifierData; -struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd); -struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]); +struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd, float (*vertexCos)[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 6bfc431a209..ccc214284ac 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -766,9 +766,9 @@ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) { ss->oldEMap = ss->eMap; ss->oldFMap = ss->fMap; - ss->vMap = _ehash_new(ss->oldVMap->numEntries, &ss->allocatorIFC, ss->allocator); - ss->eMap = _ehash_new(ss->oldFMap->numEntries, &ss->allocatorIFC, ss->allocator); - ss->fMap = _ehash_new(ss->oldEMap->numEntries, &ss->allocatorIFC, ss->allocator); + ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); + ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator); ss->numGrids = 0; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a7678ce8056..f0807857248 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -502,7 +502,11 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3] mdm->freeNors = 1; mdm->freeVerts = 1; } else { - mdm->nors = mesh_build_faceNormals(ob); + // XXX this is kinda hacky because we shouldn't really be editing + // the mesh here, however, we can't just call mesh_build_faceNormals(ob) + // because in the case when a key is applied to a mesh the vertex normals + // would never be correctly computed (and renderer makes this assumption. + mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors); mdm->freeNors = 1; } @@ -515,6 +519,7 @@ typedef struct { DerivedMesh dm; EditMesh *em; + float (*vertexCos)[3]; } EditMeshDerivedMesh; static void emDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) @@ -530,12 +535,23 @@ static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void * EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditVert *eve; - bglBegin(GL_POINTS); - for(eve= emdm->em->verts.first; eve; eve= eve->next) { - if(!setDrawOptions || setDrawOptions(userData, eve)) - bglVertex3fv(eve->co); + if (emdm->vertexCos) { + int i; + + bglBegin(GL_POINTS); + for(i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) { + if(!setDrawOptions || setDrawOptions(userData, eve)) + bglVertex3fv(emdm->vertexCos[i]); + } + bglEnd(); + } else { + bglBegin(GL_POINTS); + for(eve= emdm->em->verts.first; eve; eve= eve->next) { + if(!setDrawOptions || setDrawOptions(userData, eve)) + bglVertex3fv(eve->co); + } + bglEnd(); } - bglEnd(); } static void emDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) { @@ -551,57 +567,107 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void * EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditEdge *eed; - glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { - glVertex3fv(eed->v1->co); - glVertex3fv(eed->v2->co); + 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)) { + glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]); + glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]); + } } + glEnd(); + + for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next) + eve->prev = preveve; + } else { + glBegin(GL_LINES); + for(eed= emdm->em->edges.first; eed; eed= eed->next) { + if(!setDrawOptions || setDrawOptions(userData, eed)) { + glVertex3fv(eed->v1->co); + glVertex3fv(eed->v2->co); + } + } + glEnd(); } - glEnd(); +} +static void emDM_drawEdges(DerivedMesh *dm) +{ + emDM_drawMappedEdgesEM(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) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditEdge *eed; - glBegin(GL_LINES); - for(eed= emdm->em->edges.first; eed; eed= eed->next) { - if(!setDrawOptions || setDrawOptions(userData, eed)) { - setDrawInterpOptions(userData, eed, 0.0); - glVertex3fv(eed->v1->co); - setDrawInterpOptions(userData, eed, 1.0); - glVertex3fv(eed->v2->co); + 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); + glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]); + setDrawInterpOptions(userData, eed, 1.0); + glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]); + } } - } - glEnd(); -} -static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) -{ - EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; - EditFace *efa; + glEnd(); - 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(); + for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next) + 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); + glVertex3fv(eed->v1->co); + setDrawInterpOptions(userData, eed, 1.0); + glVertex3fv(eed->v2->co); + } } + glEnd(); } } -static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) +static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditFace *efa; - for (efa= emdm->em->faces.first; efa; efa= efa->next) { - if(efa->h==0) { - if (setMaterial(efa->mat_nr+1)) { + 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 (efa= emdm->em->faces.first; efa; efa= efa->next) { + if(!setDrawOptions || setDrawOptions(userData, efa)) { glNormal3fv(efa->n); 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(); + } + } + + 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); @@ -611,15 +677,64 @@ static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) } } } +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 (efa= emdm->em->faces.first; efa; efa= efa->next) { + if(efa->h==0) { + if (setMaterial(efa->mat_nr+1)) { + glNormal3fv(efa->n); + 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(); + } + } + } + + 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)) { + 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(); + } + } + } + } +} static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; EditVert *eve; + int i; if (emdm->em->verts.first) { - for (eve= emdm->em->verts.first; eve; eve= eve->next) { - DO_MINMAX(eve->co, min_r, max_r); + for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) { + if (emdm->vertexCos) { + DO_MINMAX(emdm->vertexCos[i], min_r, max_r); + } else { + DO_MINMAX(eve->co, min_r, max_r); + } } } else { min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; @@ -638,7 +753,17 @@ static int emDM_getNumFaces(DerivedMesh *dm) return BLI_countlist(&emdm->em->faces); } -static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em) +static void emDM_release(DerivedMesh *dm) +{ + EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; + + if (emdm->vertexCos) + MEM_freeN(emdm->vertexCos); + + MEM_freeN(emdm); +} + +static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3]) { EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm"); @@ -650,6 +775,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em) 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; @@ -657,9 +783,10 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em) emdm->dm.drawFacesSolid = emDM_drawFacesSolid; emdm->dm.drawMappedFacesEM = emDM_drawMappedFacesEM; - emdm->dm.release = (void(*)(DerivedMesh*)) MEM_freeN; + emdm->dm.release = emDM_release; emdm->em = em; + emdm->vertexCos = vertexCos; return (DerivedMesh*) emdm; } @@ -994,13 +1121,27 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm) /***/ +typedef float vec3f[3]; + +static vec3f *mesh_getVertexCos(Mesh *me, int *numVerts_r) +{ + int i, numVerts = *numVerts_r = me->totvert; + float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1"); + + for (i=0; i<numVerts; i++) { + VECCOPY(cos[i], me->mvert[i].co); + } + + return cos; +} + static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform) { Mesh *me = ob->data; ModifierData *md= ob->modifiers.first; float (*deformedVerts)[3]; DerivedMesh *dm; - int a, numVerts = me->totvert; + int numVerts = me->totvert; if (deform_r) *deform_r = NULL; *final_r = NULL; @@ -1008,14 +1149,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM if (useDeform) { mesh_modifier(ob, &deformedVerts); - // XXX this copy should be done on demand - if (!deformedVerts) { - deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos1"); - for (a=0; a<numVerts; a++) { - VECCOPY(deformedVerts[a], me->mvert[a].co); - } - } - /* Apply all leading deforming modifiers */ for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_get_info(md->type); @@ -1024,7 +1157,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM if (mti->isDisabled && mti->isDisabled(md)) continue; if (mti->type==eModifierTypeType_OnlyDeform) { - mti->deformVerts(md, ob, deformedVerts, numVerts); + if (!deformedVerts) deformedVerts = mesh_getVertexCos(me, &numVerts); + mti->deformVerts(md, ob, NULL, deformedVerts, numVerts); } else { break; } @@ -1066,27 +1200,23 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv"); dm->getVertCos(dm, deformedVerts); } else { - numVerts = me->totvert; - deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos2"); - for (a=0; a<numVerts; a++) { - VECCOPY(deformedVerts[a], me->mvert[a].co); - } + deformedVerts = mesh_getVertexCos(me, &numVerts); } } - mti->deformVerts(md, ob, deformedVerts, numVerts); + mti->deformVerts(md, ob, dm, deformedVerts, numVerts); } else { /* There are 4 cases here (have deform? have dm?) but they all are handled * by the modifier apply function, which will also free the DerivedMesh if * it exists. */ - dm = mti->applyModifier(md, ob, dm, deformedVerts, useRenderParams); + dm = mti->applyModifier(md, ob, dm, deformedVerts, useRenderParams, !inputVertexCos); if (deformedVerts) { if (deformedVerts!=inputVertexCos) { MEM_freeN(deformedVerts); } - deformedVerts = 0; + deformedVerts = NULL; } } } @@ -1126,6 +1256,111 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM } } +static vec3f *editmesh_getVertexCos(EditMesh *em, int *numVerts_r) +{ + int i, numVerts = *numVerts_r = BLI_countlist(&em->verts); + float (*cos)[3]; + EditVert *eve; + + cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos"); + for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) { + VECCOPY(cos[i], eve->co); + } + + return cos; +} + +static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r) +{ + Object *ob = G.obedit; + EditMesh *em = G.editMesh; + ModifierData *md= ob->modifiers.first; + float (*deformedVerts)[3] = NULL; + DerivedMesh *dm; + int numVerts; + + if (cage_r) *cage_r = NULL; + *final_r = NULL; + + *cage_r = getEditMeshDerivedMesh(em, NULL); + +// mesh_modifier(ob, &deformedVerts); + + dm = NULL; + for (; md; md=md->next) { + ModifierTypeInfo *mti = modifierType_get_info(md->type); + + if (!(md->mode&1)) continue; + if (mti->isDisabled && mti->isDisabled(md)) continue; + if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue; + + /* How to apply modifier depends on (a) what we already have as + * a result of previous modifiers (could be a DerivedMesh or just + * deformed vertices) and (b) what type the modifier is. + */ + + if (mti->type==eModifierTypeType_OnlyDeform) { + /* No existing verts to deform, need to build them. */ + if (!deformedVerts) { + if (dm) { + /* Deforming a derived mesh, read the vertex locations out of the mesh and + * deform them. Once done with this run of deformers verts will be written back. + */ + numVerts = dm->getNumVerts(dm); + deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv"); + dm->getVertCos(dm, deformedVerts); + } else { + deformedVerts = editmesh_getVertexCos(em, &numVerts); + } + } + + mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts); + } else { + /* There are 4 cases here (have deform? have dm?) but they all are handled + * by the modifier apply function, which will also free the DerivedMesh if + * it exists. + */ + dm = mti->applyModifierEM(md, ob, em, dm, deformedVerts); + + if (deformedVerts) { + MEM_freeN(deformedVerts); + deformedVerts = NULL; + } + } + } + + /* Yay, we are done. If we have a DerivedMesh and deformed vertices need to apply + * these back onto the DerivedMesh. If we have no DerivedMesh then we need to build + * one. + */ + if (dm && deformedVerts) { + DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts or nors were shared + 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); + MEM_freeN(deformedVerts); + } else if (dm) { + *final_r = dm; + } else { + *final_r = getEditMeshDerivedMesh(em, deformedVerts); + } +} + /***/ static void clear_mesh_caches(Object *ob) @@ -1171,6 +1406,8 @@ static void mesh_build_data(Object *ob) static void editmesh_build_data(void) { + float min[3], max[3]; + EditMesh *em = G.editMesh; clear_mesh_caches(G.obedit); @@ -1186,21 +1423,11 @@ static void editmesh_build_data(void) em->derivedCage = NULL; } -/* - if ((me->flag&ME_SUBSURF) && me->subdiv) { - em->derivedFinal = subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype, NULL); + editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal); - if (me->flag&ME_OPT_EDGES) { - em->derivedCage = em->derivedFinal; - } else { - em->derivedCage = getEditMeshDerivedMesh(em); - } - } else { -*/ - em->derivedFinal = em->derivedCage = getEditMeshDerivedMesh(em); -/* - } -*/ + em->derivedFinal->getMinMax(em->derivedFinal, min, max); + + boundbox_set_from_min_max(mesh_get_bb(G.obedit->data), min, max); } void makeDispListMesh(Object *ob) diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 8fbb10d46b9..ada30151d1e 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -717,101 +717,98 @@ void shadeDispList(Object *ob) DerivedMesh *dm= mesh_get_derived_final(ob, &dmNeedsFree); DispListMesh *dlm; MVert *mvert; - + float *vnors, *vn; + int i; + if (need_orco) { orco = mesh_create_orco(ob); } dlm= dm->convertToDispListMesh(dm); - if (dlm && dlm->totvert) { - float *vnors, *vn; - int i; - - dlob= MEM_callocN(sizeof(DispList), "displistshade"); - BLI_addtail(&ob->disp, dlob); - dlob->type= DL_VERTCOL; + dlob= MEM_callocN(sizeof(DispList), "displistshade"); + BLI_addtail(&ob->disp, dlob); + dlob->type= DL_VERTCOL; + + dlob->col1= MEM_mallocN(sizeof(*dlob->col1)*dlm->totface*4, "col1"); + if (me->flag & ME_TWOSIDED) + dlob->col2= MEM_mallocN(sizeof(*dlob->col2)*dlm->totface*4, "col1"); - dlob->col1= MEM_mallocN(sizeof(*dlob->col1)*dlm->totface*4, "col1"); - if (me->flag & ME_TWOSIDED) - dlob->col2= MEM_mallocN(sizeof(*dlob->col2)*dlm->totface*4, "col1"); + /* vertexnormals */ + vn=vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp"); + mvert= dlm->mvert; + a= dlm->totvert; + while(a--) { - /* vertexnormals */ - vn=vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp"); - mvert= dlm->mvert; - a= dlm->totvert; - while(a--) { - - xn= mvert->no[0]; - yn= mvert->no[1]; - zn= mvert->no[2]; + xn= mvert->no[0]; + yn= mvert->no[1]; + zn= mvert->no[2]; + + /* transpose ! */ + vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(vn); + + mvert++; vn+=3; + } + + for (i=0; i<dlm->totface; i++) { + MFace *mf= &dlm->mface[i]; + + if (mf->v3) { + int j, vidx[4], nverts= mf->v4?4:3; + unsigned char *col1base= (unsigned char*) &dlob->col1[i*4]; + unsigned char *col2base= (unsigned char*) (dlob->col2?&dlob->col2[i*4]:NULL); + unsigned char *mcolbase; + float nor[3]; - /* transpose ! */ - vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; - vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; - vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; - Normalise(vn); + if (dlm->tface) { + mcolbase = (unsigned char*) dlm->tface[i].col; + } else if (dlm->mcol) { + mcolbase = (unsigned char*) &dlm->mcol[i*4]; + } else { + mcolbase = NULL; + } + + ma= give_current_material(ob, mf->mat_nr+1); + if(ma==0) ma= &defmaterial; - mvert++; vn+=3; - } - - for (i=0; i<dlm->totface; i++) { - MFace *mf= &dlm->mface[i]; - - if (mf->v3) { - int j, vidx[4], nverts= mf->v4?4:3; - unsigned char *col1base= (unsigned char*) &dlob->col1[i*4]; - unsigned char *col2base= (unsigned char*) (dlob->col2?&dlob->col2[i*4]:NULL); - unsigned char *mcolbase; - float nor[3]; - - if (dlm->tface) { - mcolbase = (unsigned char*) dlm->tface[i].col; - } else if (dlm->mcol) { - mcolbase = (unsigned char*) &dlm->mcol[i*4]; - } else { - mcolbase = NULL; - } + vidx[0]= mf->v1; + vidx[1]= mf->v2; + vidx[2]= mf->v3; + vidx[3]= mf->v4; + + // XXX, should all DLM's have normals? + if (dlm->nors) { + VECCOPY(nor, &dlm->nors[i*3]); + } else { + if (mf->v4) + CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor); + else + CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor); + } - ma= give_current_material(ob, mf->mat_nr+1); - if(ma==0) ma= &defmaterial; + n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2]; + n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2]; + n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2]; + Normalise(n1); + + vn = n1; + for (j=0; j<nverts; j++) { + MVert *mv= &dlm->mvert[vidx[j]]; + unsigned char *col1= &col1base[j*4]; + unsigned char *col2= col2base?&col2base[j*4]:NULL; + unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL; - vidx[0]= mf->v1; - vidx[1]= mf->v2; - vidx[2]= mf->v3; - vidx[3]= mf->v4; - - // XXX, should all DLM's have normals? - if (dlm->nors) { - VECCOPY(nor, &dlm->nors[i*3]); - } else { - if (mf->v4) - CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor); - else - CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor); - } - - n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2]; - n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2]; - n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2]; - Normalise(n1); - - vn = n1; - for (j=0; j<nverts; j++) { - MVert *mv= &dlm->mvert[vidx[j]]; - unsigned char *col1= &col1base[j*4]; - unsigned char *col2= col2base?&col2base[j*4]:NULL; - unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL; - - VECCOPY(vec, mv->co); - Mat4MulVecfl(mat, vec); - if(mf->flag & ME_SMOOTH) vn= vnors+3*vidx[j]; - fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol); - } + VECCOPY(vec, mv->co); + Mat4MulVecfl(mat, vec); + if(mf->flag & ME_SMOOTH) vn= vnors+3*vidx[j]; + fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol); } } - MEM_freeN(vnors); } + MEM_freeN(vnors); displistmesh_free(dlm); if (orco) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 4713f13c9b9..8c2ee133487 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -790,7 +790,12 @@ void make_edges(Mesh *me) else totedge+=1; } - if(totedge==0) return; + if(totedge==0) { + /* flag that mesh has edges */ + me->medge = MEM_callocN(0, "make mesh edges"); + me->totedge = 0; + return; + } ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort"); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index ad52d58a35f..d9bcbc29e9b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1,5 +1,6 @@ #include "string.h" +#include "BLI_blenlib.h" #include "BLI_rand.h" #include "MEM_guardedalloc.h" @@ -9,6 +10,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BLI_editVert.h" #include "BKE_global.h" #include "BKE_utildefines.h" @@ -50,7 +52,14 @@ static void curveModifier_updateDepgraph(ModifierData *md, DagForest *forest, Ob } } -static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts) +static void curveModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts) +{ + CurveModifierData *cmd = (CurveModifierData*) md; + + curve_deform_verts(cmd->object, ob, vertexCos, numVerts); +} + +static void curveModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts) { CurveModifierData *cmd = (CurveModifierData*) md; @@ -77,7 +86,14 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest, } } -static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts) +static void latticeModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts) +{ + LatticeModifierData *lmd = (LatticeModifierData*) md; + + lattice_deform_verts(lmd->object, ob, vertexCos, numVerts); +} + +static void latticeModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts) { LatticeModifierData *lmd = (LatticeModifierData*) md; @@ -101,9 +117,12 @@ static void subsurfModifier_freeData(ModifierData *md) if (smd->mCache) { ccgSubSurf_free(smd->mCache); } + if (smd->emCache) { + ccgSubSurf_free(smd->emCache); + } } -static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams) +static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc) { DerivedMesh *dm = derivedData; SubsurfModifierData *smd = (SubsurfModifierData*) md; @@ -122,12 +141,39 @@ static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *d } dm->release(dm); - dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL); - displistmesh_free(dlm); + dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL, isFinalCalc); + + return dm; + } else { + return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos, isFinalCalc); + } +} + +static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]) +{ + EditMesh *em = editData; + DerivedMesh *dm = derivedData; + SubsurfModifierData *smd = (SubsurfModifierData*) md; + + if (dm) { + DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts were shared + int i; + + if (vertexCos) { + int numVerts = dm->getNumVerts(dm); + + for (i=0; i<numVerts; i++) { + VECCOPY(dlm->mvert[i].co, vertexCos[i]); + } + } + dm->release(dm); + + // XXX, should I worry about reuse of mCache in editmode? + dm = subsurf_make_derived_from_mesh(NULL, dlm, smd, 0, NULL, 1); return dm; } else { - return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos); + return subsurf_make_derived_from_editmesh(em, smd, vertexCos); } } @@ -146,7 +192,7 @@ static int buildModifier_dependsOnTime(ModifierData *md) return 1; } -static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams) +static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc) { DerivedMesh *dm = derivedData; BuildModifierData *bmd = (BuildModifierData*) md; @@ -370,56 +416,20 @@ static void mirrorModifier_initData(ModifierData *md) mmd->tolerance = 0.001; } -static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams) +static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3]) { - 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; - int i, j, totvert, totedge, totface; - int axis = mmd->axis; + int totvert=ndlm->totvert, totedge=ndlm->totedge, totface=ndlm->totface; + int i, axis = mmd->axis; float tolerance = mmd->tolerance; - if (dm) { - dlm = dm->convertToDispListMesh(dm); - - mvert = dlm->mvert; - medge = dlm->medge; - mface = dlm->mface; - tface = dlm->tface; - mcol = dlm->mcol; - totvert = dlm->totvert; - totedge = dlm->totedge; - totface = dlm->totface; - } else { - Mesh *me = ob->data; - - mvert = me->mvert; - medge = me->medge; - mface = me->mface; - tface = me->tface; - mcol = me->mcol; - totvert = me->totvert; - totedge = me->totedge; - totface = me->totface; - } - - ndlm->mvert = MEM_mallocN(sizeof(*mvert)*totvert*2, "mm_mv"); - for (i=0,j=totvert; i<totvert; i++) { - MVert *mv = &mvert[i]; - MVert *nmv = &ndlm->mvert[i]; - - memcpy(nmv, mv, sizeof(*mv)); + for (i=0; i<totvert; i++) { + MVert *mv = &ndlm->mvert[i]; - if (ABS(nmv->co[axis])<=tolerance) { - nmv->co[axis] = 0; - *((int*) nmv->no) = i; + if (ABS(mv->co[axis])<=tolerance) { + mv->co[axis] = 0; + *((int*) mv->no) = i; } else { - MVert *nmvMirror = &ndlm->mvert[j]; + MVert *nmv = &ndlm->mvert[ndlm->totvert]; /* Because the topology result (# of vertices) must stuff the same * if the mesh data is overridden by vertex cos, have to calc sharedness @@ -427,22 +437,17 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de * vertices. */ if (vertexCos) { - VECCOPY(nmv->co, vertexCos[i]); + VECCOPY(mv->co, vertexCos[i]); } - memcpy(nmvMirror, nmv, sizeof(*mv)); - nmvMirror->co[axis] = -nmvMirror->co[axis]; + memcpy(nmv, mv, sizeof(*mv)); + nmv ->co[axis] = -nmv ->co[axis]; - *((int*) nmv->no) = j++; + *((int*) mv->no) = ndlm->totvert++; } } - ndlm->totvert = j; - - if (medge) { - ndlm->medge = MEM_mallocN(sizeof(*medge)*totedge*2, "mm_med"); - memcpy(ndlm->medge, medge, sizeof(*medge)*totedge); - ndlm->totedge = totedge; + if (ndlm->medge) { for (i=0; i<totedge; i++) { MEdge *med = &ndlm->medge[i]; MEdge *nmed = &ndlm->medge[ndlm->totedge]; @@ -458,18 +463,6 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de } } - ndlm->mface = MEM_mallocN(sizeof(*mface)*totface*2, "mm_mf"); - memcpy(ndlm->mface, mface, sizeof(*mface)*totface); - - if (tface) { - ndlm->tface = MEM_mallocN(sizeof(*tface)*totface*2, "mm_tf"); - memcpy(ndlm->tface, tface, sizeof(*tface)*totface); - } else if (mcol) { - ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*totface*2, "mm_mcol"); - memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*totface); - } - - ndlm->totface = totface; for (i=0; i<totface; i++) { MFace *mf = &ndlm->mface[i]; MFace *nmf = &ndlm->mface[ndlm->totface]; @@ -477,14 +470,14 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de MCol *mc=NULL, *nmc=NULL; /* gcc's mother is uninitialized! */ memcpy(nmf, mf, sizeof(*mf)); - if (tface) { + if (ndlm->tface) { ntf = &ndlm->tface[ndlm->totface]; tf = &ndlm->tface[i]; - memcpy(ntf, tf, sizeof(*tface)); - } else if (mcol) { + 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(*mcol)*4); + memcpy(nmc, mc, sizeof(*ndlm->mcol)*4); } /* Map vertices to shared */ @@ -529,11 +522,11 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de if (copyIdx!=-1) { int fromIdx = (copyIdx+2)%4; - if (tface) { + if (ndlm->tface) { tf->col[copyIdx] = ntf->col[fromIdx]; tf->uv[copyIdx][0] = ntf->uv[fromIdx][0]; tf->uv[copyIdx][1] = ntf->uv[fromIdx][1]; - } else if (mcol) { + } else if (ndlm->mcol) { mc[copyIdx] = nmc[fromIdx]; } @@ -547,21 +540,21 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de if (nmf->v1) { SWAP(int, nmf->v1, nmf->v3); - if (tface) { + 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 (mcol) { + } else if (ndlm->mcol) { SWAP(MCol, nmc[0], nmc[2]); } } else { SWAP(int, nmf->v2, nmf->v4); - if (tface) { + 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 (mcol) { + } else if (ndlm->mcol) { SWAP(MCol, nmc[1], nmc[3]); } } @@ -569,6 +562,63 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de ndlm->totface++; } +} + +static void *mirrorModifier_applyModifier(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; + + if (dm) { + dlm = dm->convertToDispListMesh(dm); + + 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; + } 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); + } + + ndlm->mface = MEM_mallocN(sizeof(*mface)*ndlm->totface*2, "mm_mf"); + memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface); + + 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); if (dlm) displistmesh_free(dlm); if (dm) dm->release(dm); @@ -578,6 +628,64 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de return derivedmesh_from_displistmesh(ndlm); } +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); + } else { + MirrorModifierData *mmd = (MirrorModifierData*) md; + DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm"); + int i, axis = mmd->axis; + float tolerance = mmd->tolerance; + EditMesh *em = editData; + EditVert *eve, *preveve; + EditEdge *eed; + EditFace *efa; + + 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); + + 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"); + + for (i=0,eve=em->verts.first; i<ndlm->totvert; i++,eve=eve->next) { + MVert *mv = &ndlm->mvert[i]; + + VECCOPY(mv->co, eve->co); + } + for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) { + MEdge *med = &ndlm->medge[i]; + + med->v1 = (int) eed->v1->prev; + med->v2 = (int) eed->v2->prev; + med->crease = eed->crease; + } + for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) { + MFace *mf = &ndlm->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; + } + + mirrorModifier__doMirror(mmd, ndlm, vertexCos); + + 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); + } +} + /***/ static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES]; @@ -611,24 +719,27 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type) mti = INIT_TYPE(Curve); mti->type = eModifierTypeType_OnlyDeform; - mti->flags = eModifierTypeFlag_AcceptsCVs; + mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode; mti->isDisabled = curveModifier_isDisabled; mti->updateDepgraph = curveModifier_updateDepgraph; mti->deformVerts = curveModifier_deformVerts; + mti->deformVertsEM = curveModifier_deformVertsEM; mti = INIT_TYPE(Lattice); mti->type = eModifierTypeType_OnlyDeform; - mti->flags = eModifierTypeFlag_AcceptsCVs; + mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode; mti->isDisabled = latticeModifier_isDisabled; mti->updateDepgraph = latticeModifier_updateDepgraph; mti->deformVerts = latticeModifier_deformVerts; + mti->deformVertsEM = latticeModifier_deformVertsEM; mti = INIT_TYPE(Subsurf); mti->type = eModifierTypeType_Constructive; - mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping; + mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode; mti->initData = subsurfModifier_initData; mti->freeData = subsurfModifier_freeData; mti->applyModifier = subsurfModifier_applyModifier; + mti->applyModifierEM = subsurfModifier_applyModifierEM; mti = INIT_TYPE(Build); mti->type = eModifierTypeType_Nonconstructive; @@ -639,9 +750,10 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type) mti = INIT_TYPE(Mirror); mti->type = eModifierTypeType_Constructive; - mti->flags = eModifierTypeFlag_AcceptsMesh; + mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode; mti->initData = mirrorModifier_initData; mti->applyModifier = mirrorModifier_applyModifier; + mti->applyModifierEM = mirrorModifier_applyModifierEM; typeArrInit = 0; #undef INIT_TYPE diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 7c5022e3fde..db874df01cd 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -517,7 +517,7 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float MFace *mf = &((MFace*) mface)[i]; if (!mf->v3) { - ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0); + ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f); } } } @@ -538,7 +538,7 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float ccgSubSurf_processSync(ss); } -void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv) +void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], int useFlatSubdiv) { float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss); EditVert *ev, *fVerts[4]; @@ -547,8 +547,16 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv) ccgSubSurf_initFullSync(ss); - for (ev=em->verts.first; ev; ev=ev->next) { - ccgSubSurf_syncVert(ss, ev, ev->co); + if (vertCos) { + int i=0; + + for (ev=em->verts.first; ev; ev=ev->next) { + ccgSubSurf_syncVert(ss, ev, vertCos[i++]); + } + } else { + for (ev=em->verts.first; ev; ev=ev->next) { + ccgSubSurf_syncVert(ss, ev, ev->co); + } } for (ee=em->edges.first; ee; ee=ee->next) { @@ -574,6 +582,9 @@ typedef struct { CCGSubSurf *ss; int fromEditmesh; + + Mesh *me; + DispListMesh *dlm; } CCGDerivedMesh; static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { @@ -599,7 +610,7 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { CCGEdge *e = ccgEdgeIterator_getCurrent(ei); VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - for (i=1; i<edgeSize-1; i++) + for (i=0; i<edgeSize; i++) DO_MINMAX(edgeData[i].co, min_r, max_r); } @@ -610,8 +621,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - for (x=0; x<gridSize; x++) - DO_MINMAX(faceGridData[x].co, min_r, max_r); for (y=0; y<gridSize; y++) for (x=0; x<gridSize; x++) DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r); @@ -632,6 +641,50 @@ static int ccgDM_getNumFaces(DerivedMesh *dm) { return ccgSubSurf_getNumFinalFaces(ccgdm->ss); } +static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + int i; + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; + + i = 0; + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v)); + } + ccgVertIterator_free(vi); + + 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(cos[i++], ccgSubSurf_getEdgeData(ss, e, x)); + } + ccgEdgeIterator_free(ei); + + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); + + VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f)); + for (S=0; S<numVerts; S++) + for (x=1; x<gridSize-1; x++) + VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); + for (S=0; S<numVerts; S++) + for (y=1; y<gridSize-1; y++) + for (x=1; x<gridSize-1; x++) + VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y)); + } + ccgFaceIterator_free(fi); +} static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert); @@ -644,11 +697,52 @@ static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - return ss_to_displistmesh(ccgdm->ss, 1, NULL, NULL); + return ss_to_displistmesh(ccgdm->ss, ccgdm->fromEditmesh, ccgdm->me, ccgdm->dlm); } static void ccgDM_drawVerts(DerivedMesh *dm) { -// CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; + + glBegin(GL_POINTS); + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + glVertex3fv(ccgSubSurf_getVertData(ss, v)); + } + ccgVertIterator_free(vi); + + 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++) + glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); + } + ccgEdgeIterator_free(ei); + + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); + + glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f)); + for (S=0; S<numVerts; S++) + for (x=1; x<gridSize-1; x++) + glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); + for (S=0; S<numVerts; S++) + for (y=1; y<gridSize-1; y++) + for (x=1; x<gridSize-1; x++) + glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); + } + ccgFaceIterator_free(fi); + glEnd(); } static void ccgDM_drawEdges(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; @@ -776,29 +870,30 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); - int isSmooth; + unsigned char flag,mat_nr; if (ccgdm->fromEditmesh) { EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f); - isSmooth = efa->flag&ME_SMOOTH; if (efa->h!=0) continue; - if (!setMaterial(efa->mat_nr+1)) - continue; + + flag = efa->flag; + mat_nr = efa->mat_nr; } else { - // XXX, can't do these correctly, handle info could have been - // free'd if came from a dlm - isSmooth = 0; -// if (!setMaterial(efa->mat_nr+1)) -// continue; + 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)) + continue; - glShadeModel(isSmooth?GL_SMOOTH:GL_FLAT); + glShadeModel((flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT); for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (isSmooth) { + if (flag&ME_SMOOTH) { for (y=0; y<gridSize-1; y++) { glBegin(GL_QUAD_STRIP); for (x=0; x<gridSize; x++) { @@ -843,10 +938,186 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { ccgFaceIterator_free(fi); } static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) { -// CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + unsigned char *cp1, *cp2; + int useTwoSide=1; + + cp1= col1; + if(col2) { + cp2= col2; + } else { + cp2= NULL; + useTwoSide= 0; + } + + glShadeModel(GL_SMOOTH); + if(col1 && col2) + glEnable(GL_CULL_FACE); + + glBegin(GL_QUADS); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + 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++) { + 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; + + glColor3ub(cp1[3], cp1[2], cp1[1]); + glVertex3fv(d); + glColor3ub(cp1[7], cp1[6], cp1[5]); + glVertex3fv(c); + glColor3ub(cp1[11], cp1[10], cp1[9]); + glVertex3fv(b); + glColor3ub(cp1[15], cp1[14], cp1[13]); + glVertex3fv(a); + + if (useTwoSide) { + glColor3ub(cp2[15], cp2[14], cp2[13]); + glVertex3fv(a); + glColor3ub(cp2[11], cp2[10], cp2[9]); + glVertex3fv(b); + glColor3ub(cp2[7], cp2[6], cp2[5]); + glVertex3fv(c); + glColor3ub(cp2[3], cp2[2], cp2[1]); + glVertex3fv(d); + } + + if (cp2) cp2+=16; + cp1+=16; + } + } + } + } + glEnd(); + + ccgFaceIterator_free(fi); } static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) { -// CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + 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; + TFace *tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface; + MCol *mcol = ccgdm->dlm?ccgdm->dlm->mcol:ccgdm->me->mcol; +// float uv[4][2]; +// float col[4][3]; + + glBegin(GL_QUADS); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); + int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f); + MFace *mf = &mface[index]; + TFace *tf = tface?&tface[index]:NULL; + unsigned char *cp= NULL; + + if(tf && ((tf->flag&TF_HIDE) || (tf->mode&TF_INVISIBLE))) continue; + + if (setDrawParams(tf, mf->mat_nr)) { + if (tf) { + cp= (unsigned char *) tf->col; + } else if (mcol) { + cp= (unsigned char *) &mcol[index*4]; + } + } + + for (S=0; S<numVerts; S++) { + 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 *b = &faceGridData[(y+0)*gridSize + x + 1]; + VertData *c = &faceGridData[(y+1)*gridSize + x + 1]; + VertData *d = &faceGridData[(y+1)*gridSize + x]; + + 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]; + float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[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); + } + +// if (tf) glTexCoord2fv(tf->uv[0]); +// if (cp) glColor3ub(cp[3], cp[2], cp[1]); +// if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no); +// glVertex3fv(mvert[mf->v1].co); + +/* + { + float x_v = (float) fx/(gridSize-1); + float y_v = (float) fy/(gridSize-1); + float data[6]; + + for (k=0; k<numDataComponents; k++) { + data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + + (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v; + } +*/ + +// if (cp) glColor3ub(cp[3], cp[2], cp[1]); + if (mf->flag&ME_SMOOTH) glNormal3fv(d->no); + glVertex3fv(d->co); +// if (cp) glColor3ub(cp[7], cp[6], cp[5]); + if (mf->flag&ME_SMOOTH) glNormal3fv(c->no); + glVertex3fv(c->co); +// if (cp) glColor3ub(cp[11], cp[10], cp[9]); + if (mf->flag&ME_SMOOTH) glNormal3fv(b->no); + glVertex3fv(b->co); +// if (cp) glColor3ub(cp[15], cp[14], cp[13]); + if (mf->flag&ME_SMOOTH) glNormal3fv(a->no); + glVertex3fv(a->co); + } + } + } + } + glEnd(); + + ccgFaceIterator_free(fi); +/* + MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; + Mesh *me = mdm->me; + MVert *mvert= mdm->verts; + MFace *mface= me->mface; + TFace *tface = me->tface; + float *nors = mdm->nors; + int a; + + for (a=0; a<me->totface; a++) { + MFace *mf= &mface[a]; + if (tf) glTexCoord2fv(tf->uv[1]); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no); + glVertex3fv(mvert[mf->v2].co); + + if (tf) glTexCoord2fv(tf->uv[2]); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no); + glVertex3fv(mvert[mf->v3].co); + + if(mf->v4) { + if (tf) glTexCoord2fv(tf->uv[3]); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no); + glVertex3fv(mvert[mf->v4].co); + } + glEnd(); + } +*/ } static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) { @@ -974,22 +1245,21 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void static void ccgDM_release(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; - ccgSubSurf_free(ccgdm->ss); + if (ccgdm->dlm) displistmesh_free(ccgdm->dlm); MEM_freeN(ccgdm); } -static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh) { - CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm"); +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, 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.getMappedVertCoEM = ccgDM_getMappedVertCoEM; ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh; - //ccgdm->dm.getVertCos = ccgdm_getVertCos; // XXX fixme - ccgdm->dm.drawVerts = ccgDM_drawVerts; ccgdm->dm.drawEdges = ccgDM_drawEdges; ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; @@ -1008,23 +1278,26 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh) { ccgdm->ss = ss; ccgdm->fromEditmesh = fromEditmesh; + ccgdm->me = me; + ccgdm->dlm = dlm; return ccgdm; } /***/ -DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd) { +DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd, float (*vertCos)[3]) { int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; - CCGSubSurf *ss = _getSubSurf(NULL, smd->levels, G.rt==52, 0, 0, useSimple); - - ss_sync_from_editmesh(ss, em, useSimple); + + smd->emCache = _getSubSurf(smd->emCache, smd->levels, G.rt==52, 0, 0, useSimple); + ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple); - return (DerivedMesh*) getCCGDerivedMesh(ss, 1); + return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, NULL, NULL); } -DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]) { +DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) { int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF; + DispListMesh *ndlm; /* Do not use cache in render mode. */ if (useRenderParams) { @@ -1032,34 +1305,51 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - dlm = ss_to_displistmesh(ss, 0, me, dlm); + ndlm = ss_to_displistmesh(ss, 0, me, dlm); + if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - return derivedmesh_from_displistmesh(dlm); + return derivedmesh_from_displistmesh(ndlm); } else { int useEdgeCreation = !(dlm?dlm->medge:me->medge); - int useIncremental = useEdgeCreation?0:smd->useIncrementalMesh; + int useIncremental = smd->useIncrementalMesh && !useEdgeCreation; CCGSubSurf *ss; - if (!useIncremental && smd->mCache) { - ccgSubSurf_free(smd->mCache); - smd->mCache = NULL; + /* It is quite possible there is a much better place to do this. It + * depends a bit on how rigourously we expect this function to never + * be called in editmode. In semi-theory we could share a single + * cache, but the handles used inside and outside editmode are not + * the same so we would need some way of converting them. Its probably + * not worth the effort. But then why am I even writing this long + * comment that no one will read? Hmmm. - zr + */ + if (smd->emCache) { + ccgSubSurf_free(smd->emCache); + smd->emCache = NULL; } - ss = _getSubSurf(smd->mCache, smd->levels, 0, 1, useEdgeCreation, useSimple); + if (useIncremental && isFinalCalc) { + smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels, G.rt==52, 0, 0, useSimple); - ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); + ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); - dlm = ss_to_displistmesh(ss, 0, me, dlm); - - if (useIncremental) { - smd->mCache = ss; + return (DerivedMesh*) getCCGDerivedMesh(ss, 0, me, dlm); } else { + if (smd->mCache && isFinalCalc) { + ccgSubSurf_free(smd->mCache); + smd->mCache = NULL; + } + + ss = _getSubSurf(NULL, smd->levels, G.rt==52, 1, useEdgeCreation, useSimple); + ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple); + ndlm = ss_to_displistmesh(ss, 0, me, dlm); + + if (dlm) displistmesh_free(dlm); ccgSubSurf_free(ss); - } - return derivedmesh_from_displistmesh(dlm); + return derivedmesh_from_displistmesh(ndlm); + } } } |