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:
authorDaniel Dunbar <daniel@zuster.org>2005-07-22 00:30:33 +0400
committerDaniel Dunbar <daniel@zuster.org>2005-07-22 00:30:33 +0400
commit33709bf6e29bf2feb4a8753ad79a4244248ad3ea (patch)
tree7749548dbbc69ecf8a61066885b1abce4f2f4bdf /source/blender
parent9449f0b24fac41b45eeca49f5b84328c1cae03b4 (diff)
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function - added modifier_{new,free] utility function - added ccgSubSurf_getUseAgeCounts to query info - removed subsurf modifier faking (ME_SUBSURF flag is no longer valid). subsurf modifier gets converted on file load although there is obscure linked mesh situation where this can go wrong, will fix shortly. this also means that some places in the code that test/copy subsurf settings are broken for the time being. - shuffled modifier calculation to be simpler. note that all modifiers are currently disabled in editmode (including subsurf). don't worry, will return shortly. - bug fix, build modifier didn't randomize meshes with only verts - cleaned up subsurf_ccg and adapted for future editmode modifier work - added editmesh.derived{Cage,Final}, not used yet - added SubsurfModifierData.{mCache,emCache}, will be used to cache subsurf instead of caching in derivedmesh itself - removed old subsurf buttons - added do_modifiers_buttons to handle modifier events - removed count_object counting of modifier (subsurfed) objects... this would be nice to add back at some point but requires care. probably requires rewrite of counting system. New feature: Incremental Subsurf in Object Mode The previous release introduce incremental subsurf calculation during editmode but it was not turned on during object mode. In general it does not make sense to have it always enabled during object mode because it requires caching a fair amount of information about the mesh which is a waste of memory unless the mesh is often recalculated. However, for mesh's that have subsurfed armatures for example, or that have other modifiers so that the mesh is essentially changing on every frame, it makes a lot of sense to keep the subsurf'd object around and that is what the new incremental subsurf modifier toggle is for. The intent is that the user will enable this option for (a) a mesh that is currently under active editing or (b) a mesh that is heavily updated in the scene, such as a character. I will try to write more about this feature for release, because it has advantages and disadvantages that are not immediately obvious (the first user reaction will be to turn it on for ever object, which is probably not correct).
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_modifier.h34
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h6
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c17
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c135
-rw-r--r--source/blender/blenkernel/intern/modifier.c136
-rw-r--r--source/blender/blenkernel/intern/object.c4
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c451
-rw-r--r--source/blender/blenlib/BLI_editVert.h5
-rw-r--r--source/blender/blenloader/intern/readfile.c69
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h4
-rw-r--r--source/blender/src/butspace.c5
-rw-r--r--source/blender/src/buttons_editing.c7
-rw-r--r--source/blender/src/buttons_object.c49
-rw-r--r--source/blender/src/drawobject.c28
-rw-r--r--source/blender/src/edit.c13
-rw-r--r--source/blender/src/editmesh.c20
19 files changed, 544 insertions, 450 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 406060dfb53..da7c053bb9c 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -156,9 +156,8 @@ DerivedMesh *mesh_create_derived_render(struct Object *ob);
DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, float (*vertCos)[3]);
DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, float (*vertCos)[3]);
-DerivedMesh *editmesh_get_derived(void);
-DerivedMesh *editmesh_get_derived_proxy(void);
DerivedMesh *editmesh_get_derived_cage(int *needsFree_r);
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r);
#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index b0736a1ab72..a09ee20b385 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -61,15 +61,33 @@ typedef enum {
} ModifierTypeFlag;
typedef struct ModifierTypeInfo {
- char name[32], structName[32];
+ /* The user visible name for this modifier */
+ char name[32];
+
+ /* The DNA struct name for the modifier data type, used to
+ * write the DNA data out.
+ */
+ char structName[32];
+
+ /* The size of the modifier data type, used by allocation. */
+ int structSize;
+
ModifierTypeType type;
ModifierTypeFlag flags;
- /* Create new instance data for this modifier type.
+ /* Initialize new instance data for this modifier type, this function
+ * should set modifier variables to their default values.
*
- * This function must be present.
+ * This function is optional.
*/
- struct ModifierData *(*allocData)(void);
+ void (*initData)(struct ModifierData *md);
+
+ /* Free internal modifier data variables, this function should
+ * not free the _md_ variable itself.
+ *
+ * This function is optional.
+ */
+ void (*freeData)(struct ModifierData *md);
/* Return a boolean value indicating if this modifier is able to be calculated
* based on the modifier data. This is *not* regarding the md->flag, that is
@@ -120,7 +138,13 @@ typedef struct ModifierTypeInfo {
ModifierTypeInfo *modifierType_get_info(ModifierType type);
-int modifier_dependsOnTime(struct ModifierData *md);
+ /* Modifier utility calls, do call through type pointer and return
+ * default values if pointer is optional.
+ */
+struct ModifierData* modifier_new (int type);
+void modifier_free (struct ModifierData *md);
+
+int modifier_dependsOnTime (struct ModifierData *md);
#endif
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h
index 5443ab72760..a5200276159 100644
--- a/source/blender/blenkernel/BKE_subsurf.h
+++ b/source/blender/blenkernel/BKE_subsurf.h
@@ -35,10 +35,10 @@ struct Mesh;
struct Object;
struct DerivedMesh;
struct EditMesh;
+struct SubsurfModifierData;
-struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type, struct DerivedMesh *oldDerived);
-struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]);
-struct DerivedMesh *subsurf_make_derived_from_dlm(struct DispListMesh *dlm, int subdivType, int subdivLevels);
+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]);
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 bd935505ea9..6bfc431a209 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -289,8 +289,7 @@ struct _CCGSubSurf {
EHash *fMap; /* map of CCGFaceHDL -> Face */
CCGMeshIFC meshIFC;
- void *meshData;
-
+
CCGAllocatorIFC allocatorIFC;
CCGAllocatorHDL allocator;
@@ -611,7 +610,7 @@ static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss) {
/***/
-CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
+CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
if (!allocatorIFC) {
allocatorIFC = _getStandardAllocatorIFC();
allocator = NULL;
@@ -630,8 +629,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivLevel
ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
ss->meshIFC = *ifc;
- ss->meshData = meshData;
-
+
ss->subdivLevels = subdivLevels;
ss->numGrids = 0;
ss->allowEdgeCreation = 0;
@@ -710,6 +708,15 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
return eCCGError_None;
}
+void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
+{
+ *useAgeCounts_r = ss->useAgeCounts;
+
+ if (vertUserOffset_r) *vertUserOffset_r = ss->vertUserAgeOffset;
+ if (edgeUserOffset_r) *edgeUserOffset_r = ss->edgeUserAgeOffset;
+ if (faceUserOffset_r) *faceUserOffset_r = ss->faceUserAgeOffset;
+}
+
CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) {
if (useAgeCounts) {
if ( (vertUserOffset+4>ss->meshIFC.vertUserSize) ||
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 4f0594a28eb..4c522b1a827 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -37,7 +37,7 @@ typedef enum {
typedef struct _CCGSubSurf CCGSubSurf;
-CCGSubSurf* ccgSubSurf_new (CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
+CCGSubSurf* ccgSubSurf_new (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
void ccgSubSurf_free (CCGSubSurf *ss);
CCGError ccgSubSurf_sync (CCGSubSurf *ss);
@@ -56,7 +56,9 @@ CCGError ccgSubSurf_syncFaceDel (CCGSubSurf *ss, CCGFaceHDL fHDL);
CCGError ccgSubSurf_processSync (CCGSubSurf *ss);
CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels);
+
CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue);
+void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r);
CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index f54b152578a..399f2afb6d4 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1005,11 +1005,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
if (deform_r) *deform_r = NULL;
*final_r = NULL;
- /* Note: useDeform==1 implies ob must be non-NULL */
-
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++) {
@@ -1092,29 +1091,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
}
}
- /* Fake the subsurf modifier */
- {
- int level = useRenderParams?me->subdivr:me->subdiv;
-
- if ((me->flag&ME_SUBSURF) && level) {
- ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Subsurf);
- SubsurfModifierData smd;
-
- smd.levels = me->subdiv;
- smd.renderLevels = me->subdivr;
- smd.subdivType = me->subsurftype;
-
- dm = mti->applyModifier(&smd.modifier, ob, dm, deformedVerts, useRenderParams);
-
- if (deformedVerts) {
- if (deformedVerts!=inputVertexCos) {
- MEM_freeN(deformedVerts);
- }
- deformedVerts = 0;
- }
- }
- }
-
/* 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.
@@ -1152,13 +1128,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
/***/
-static void clear_and_build_mesh_data(Object *ob, int mustBuildForMesh)
+static void clear_mesh_caches(Object *ob)
{
- float min[3], max[3];
Mesh *me= ob->data;
- if(ob->flag&OB_FROMDUPLI) return;
-
/* also serves as signal to remake texspace */
if (me->bb) {
MEM_freeN(me->bb);
@@ -1175,27 +1148,70 @@ static void clear_and_build_mesh_data(Object *ob, int mustBuildForMesh)
ob->derivedDeform->release(ob->derivedDeform);
ob->derivedDeform= NULL;
}
+}
- if (ob==G.obedit) {
- G.editMesh->derived= subsurf_make_derived_from_editmesh(G.editMesh, me->subdiv, me->subsurftype, G.editMesh->derived);
- }
-
- if (ob!=G.obedit || mustBuildForMesh) {
- mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
+static void mesh_build_data(Object *ob)
+{
+ float min[3], max[3];
+ Mesh *me= ob->data;
+
+ if(ob->flag&OB_FROMDUPLI) return;
+
+ clear_mesh_caches(ob);
+
+ mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
- INIT_MINMAX(min, max);
+ INIT_MINMAX(min, max);
- ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
+ ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
- boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
+ boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
- build_particle_system(ob);
+ build_particle_system(ob);
+}
+
+static void editmesh_build_data(void)
+{
+ Mesh *me = G.obedit->data;
+ EditMesh *em = G.editMesh;
+
+ clear_mesh_caches(G.obedit);
+
+ if (em->derivedFinal) {
+ if (em->derivedFinal!=em->derivedCage) {
+ em->derivedFinal->release(em->derivedFinal);
+ }
+ em->derivedFinal = NULL;
+ }
+ if (em->derivedCage) {
+ em->derivedCage->release(em->derivedCage);
+ em->derivedCage = NULL;
+ }
+
+/*
+ if ((me->flag&ME_SUBSURF) && me->subdiv) {
+ em->derivedFinal = subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype, NULL);
+
+ if (me->flag&ME_OPT_EDGES) {
+ em->derivedCage = em->derivedFinal;
+ } else {
+ em->derivedCage = getEditMeshDerivedMesh(em);
+ }
+ } else {
+*/
+ em->derivedFinal = em->derivedCage = getEditMeshDerivedMesh(em);
+/*
}
+*/
}
void makeDispListMesh(Object *ob)
{
- clear_and_build_mesh_data(ob, 0);
+ if (ob==G.obedit) {
+ editmesh_build_data();
+ } else {
+ mesh_build_data(ob);
+ }
}
/***/
@@ -1205,7 +1221,7 @@ DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
Mesh *me = ob->data;
if (!ob->derivedFinal) {
- clear_and_build_mesh_data(ob, 1);
+ mesh_build_data(ob);
}
*needsFree_r = 0;
@@ -1215,7 +1231,7 @@ DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
{
if (!ob->derivedDeform) {
- clear_and_build_mesh_data(ob, 1);
+ mesh_build_data(ob);
}
*needsFree_r = 0;
@@ -1251,40 +1267,23 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3
/***/
-DerivedMesh *editmesh_get_derived_proxy(void)
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r)
{
- return getEditMeshDerivedMesh(G.editMesh);
-}
+ *cageNeedsFree_r = *finalNeedsFree_r = 0;
-DerivedMesh *editmesh_get_derived(void)
-{
- Mesh *me= G.obedit->data;
+ if (!G.editMesh->derivedCage)
+ editmesh_build_data();
- if ((me->flag&ME_SUBSURF) && me->subdiv) {
- if (!G.editMesh->derived) {
- makeDispListMesh(G.obedit);
- }
-
- return G.editMesh->derived;
- }
-
- return NULL;
+ *final_r = G.editMesh->derivedFinal;
+ return G.editMesh->derivedCage;
}
DerivedMesh *editmesh_get_derived_cage(int *needsFree_r)
{
- Mesh *me= G.obedit->data;
- DerivedMesh *dm = NULL;
-
*needsFree_r = 0;
- if (me->flag&ME_OPT_EDGES) {
- dm = editmesh_get_derived();
- }
- if (!dm) {
- *needsFree_r = 1;
- dm = editmesh_get_derived_proxy();
- }
+ if (!G.editMesh->derivedCage)
+ editmesh_build_data();
- return dm;
+ return G.editMesh->derivedCage;
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 709d6f0cd40..044c79711f8 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -21,21 +21,9 @@
#include "BKE_mesh.h"
#include "depsgraph_private.h"
-/***/
+#include "CCGSubSurf.h"
-static void *allocModifierData(int type, int size)
-{
- ModifierData *md = MEM_callocN(size, "md");
- md->type = type;
- md->mode = eModifierMode_RealtimeAndRender;
-
- return md;
-}
-
-static ModifierData *noneModifier_allocData(void)
-{
- return allocModifierData(eModifierType_None, sizeof(ModifierData));
-}
+/***/
static int noneModifier_isDisabled(ModifierData *md)
{
@@ -44,11 +32,6 @@ static int noneModifier_isDisabled(ModifierData *md)
/* Curve */
-static ModifierData *curveModifier_allocData(void)
-{
- return allocModifierData(eModifierType_Curve, sizeof(CurveModifierData));
-}
-
static int curveModifier_isDisabled(ModifierData *md)
{
CurveModifierData *cmd = (CurveModifierData*) md;
@@ -76,11 +59,6 @@ static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vert
/* Lattice */
-static ModifierData *latticeModifier_allocData(void)
-{
- return allocModifierData(eModifierType_Lattice, sizeof(LatticeModifierData));
-}
-
static int latticeModifier_isDisabled(ModifierData *md)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -108,20 +86,26 @@ static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*ve
/* Subsurf */
-static ModifierData *subsurfModifier_allocData(void)
+static void subsurfModifier_initData(ModifierData *md)
{
- SubsurfModifierData *smd = allocModifierData(eModifierType_Subsurf, sizeof(SubsurfModifierData));
-
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
smd->levels = 1;
smd->renderLevels = 2;
-
- return (ModifierData*) smd;
}
+static void subsurfModifier_freeData(ModifierData *md)
+{
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+ if (smd->mCache) {
+ ccgSubSurf_free(smd->mCache);
+ }
+}
+
static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
{
SubsurfModifierData *smd = (SubsurfModifierData*) md;
- int levels = useRenderParams?smd->renderLevels:smd->levels;
Mesh *me = ob->data;
if (dm) {
@@ -137,25 +121,23 @@ static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, Derived
}
dm->release(dm);
- dm = subsurf_make_derived_from_dlm(dlm, smd->subdivType, levels);
+ dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL);
displistmesh_free(dlm);
return dm;
} else {
- return subsurf_make_derived_from_mesh(me, smd->subdivType, levels, vertexCos);
+ return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos);
}
}
/* Build */
-static ModifierData *buildModifier_allocData(void)
+static void buildModifier_initData(ModifierData *md)
{
- BuildModifierData *bmd = allocModifierData(eModifierType_Build, sizeof(BuildModifierData));
+ BuildModifierData *bmd = (BuildModifierData*) md;
bmd->start = 1.0;
bmd->length = 100.0;
-
- return (ModifierData*) bmd;
}
static int buildModifier_dependsOnTime(ModifierData *md)
@@ -354,8 +336,14 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
} else {
ndlm->totvert = totvert*frac;
- ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
- memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
+ if (bmd->randomize) {
+ ndlm->mvert = MEM_dupallocN(mvert);
+ BLI_array_randomize(ndlm->mvert, sizeof(*mvert), totvert, bmd->seed);
+ } else {
+ ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
+ memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
+ }
+
if (vertexCos) {
for (i=0; i<ndlm->totvert; i++) {
VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
@@ -373,14 +361,11 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
/* Mirror */
-static ModifierData *mirrorModifier_allocData(void)
+static void mirrorModifier_initData(ModifierData *md)
{
- MirrorModifierData *mmd = allocModifierData(eModifierType_Mirror, sizeof(MirrorModifierData));
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
- mmd->axis = 0;
mmd->tolerance = 0.001;
-
- return (ModifierData*) mmd;
}
static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
@@ -602,60 +587,61 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
memset(typeArr, 0, sizeof(typeArr));
+ /* Initialize and return the appropriate type info structure,
+ * assumes that modifier has:
+ * name == typeName,
+ * structName == typeName + 'ModifierData'
+ */
+#define INIT_TYPE(typeName) \
+ ( strcpy(typeArr[eModifierType_##typeName].name, #typeName), \
+ strcpy(typeArr[eModifierType_##typeName].structName, #typeName "ModifierData"), \
+ typeArr[eModifierType_##typeName].structSize = sizeof(typeName##ModifierData), \
+ &typeArr[eModifierType_##typeName])
+
mti = &typeArr[eModifierType_None];
strcpy(mti->name, "None");
strcpy(mti->structName, "ModifierData");
+ mti->structSize = sizeof(ModifierData);
mti->type = eModifierType_None;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
- mti->allocData = noneModifier_allocData;
mti->isDisabled = noneModifier_isDisabled;
- mti = &typeArr[eModifierType_Curve];
- strcpy(mti->name, "Curve");
- strcpy(mti->structName, "CurveModifierData");
+ mti = INIT_TYPE(Curve);
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs;
- mti->allocData = curveModifier_allocData;
mti->isDisabled = curveModifier_isDisabled;
mti->updateDepgraph = curveModifier_updateDepgraph;
mti->deformVerts = curveModifier_deformVerts;
- mti = &typeArr[eModifierType_Lattice];
- strcpy(mti->name, "Lattice");
- strcpy(mti->structName, "LatticeModifierData");
+ mti = INIT_TYPE(Lattice);
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs;
- mti->allocData = latticeModifier_allocData;
mti->isDisabled = latticeModifier_isDisabled;
mti->updateDepgraph = latticeModifier_updateDepgraph;
mti->deformVerts = latticeModifier_deformVerts;
- mti = &typeArr[eModifierType_Subsurf];
- strcpy(mti->name, "Subsurf");
- strcpy(mti->structName, "SubsurfModifierData");
+ mti = INIT_TYPE(Subsurf);
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
- mti->allocData = subsurfModifier_allocData;
+ mti->initData = subsurfModifier_initData;
+ mti->freeData = subsurfModifier_freeData;
mti->applyModifier = subsurfModifier_applyModifier;
- mti = &typeArr[eModifierType_Build];
- strcpy(mti->name, "Build");
- strcpy(mti->structName, "BuildModifierData");
+ mti = INIT_TYPE(Build);
mti->type = eModifierTypeType_Nonconstructive;
mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->allocData = buildModifier_allocData;
+ mti->initData = buildModifier_initData;
mti->dependsOnTime = buildModifier_dependsOnTime;
mti->applyModifier = buildModifier_applyModifier;
- mti = &typeArr[eModifierType_Mirror];
- strcpy(mti->name, "Mirror");
- strcpy(mti->structName, "MirrorModifierData");
+ mti = INIT_TYPE(Mirror);
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->allocData = mirrorModifier_allocData;
+ mti->initData = mirrorModifier_initData;
mti->applyModifier = mirrorModifier_applyModifier;
typeArrInit = 0;
+#undef INIT_TYPE
}
if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
@@ -665,6 +651,28 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
}
}
+ModifierData *modifier_new(int type)
+{
+ ModifierTypeInfo *mti = modifierType_get_info(type);
+ ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
+
+ md->type = type;
+ md->mode = eModifierMode_RealtimeAndRender;
+
+ if (mti->initData) mti->initData(md);
+
+ return md;
+}
+
+void modifier_free(ModifierData *md)
+{
+ ModifierTypeInfo *mti = modifierType_get_info(md->type);
+
+ if (mti->freeData) mti->freeData(md);
+
+ MEM_freeN(md);
+}
+
int modifier_dependsOnTime(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_get_info(md->type);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 9b70f2923f7..05a09e8c039 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -95,6 +95,7 @@
#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_mball.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_property.h"
#include "BKE_sca.h"
@@ -177,7 +178,8 @@ static void free_modifiers(ListBase *lb)
while (md=lb->first) {
BLI_remlink(lb, md);
- MEM_freeN(md);
+
+ modifier_free(md);
}
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 39a451094bb..4212efa5af2 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -38,6 +38,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "BKE_bad_level_calls.h"
@@ -58,24 +59,6 @@
#include "CCGSubSurf.h"
-typedef struct _SubSurf {
- CCGSubSurf *subSurf;
-
- int useAging;
- int controlType;
-#define SUBSURF_CONTROLTYPE_MESH 1
-#define SUBSURF_CONTROLTYPE_EDITMESH 2
-
- /* used by editmesh control type */
- EditMesh *em;
-
- /* used by mesh control type */
- Mesh *me;
-
- float (*vertCos)[3];
- DispListMesh *dlm;
-} SubSurf;
-
typedef struct _VertData {
float co[3];
float no[3];
@@ -99,13 +82,25 @@ static void arena_release(CCGAllocatorHDL a) {
BLI_memarena_free(a);
}
-static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
+static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useEdgeCreation, int useFlatSubdiv) {
CCGMeshIFC ifc;
CCGSubSurf *ccgSS;
- CCGAllocatorIFC allocatorIFC, *allocatorIFCp;
- CCGAllocatorHDL allocator;
- if (ss->useAging) {
+ if (prevSS) {
+ int oldUseAging;
+
+ ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
+
+ if (oldUseAging!=useAging) {
+ ccgSubSurf_free(prevSS);
+ } else {
+ ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
+
+ return prevSS;
+ }
+ }
+
+ if (useAging) {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
} else {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
@@ -113,58 +108,31 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
ifc.vertDataSize = sizeof(VertData);
if (useArena) {
+ CCGAllocatorIFC allocatorIFC;
+ CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
+
allocatorIFC.alloc = arena_alloc;
allocatorIFC.realloc = arena_realloc;
allocatorIFC.free = arena_free;
allocatorIFC.release = arena_release;
- allocatorIFCp = &allocatorIFC;
- allocator = BLI_memarena_new((1<<16));
- ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
+ ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
} else {
- ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, NULL, NULL);
+ ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
}
- if (ss->useAging) {
+ if (useAging) {
ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4);
}
+ if (useEdgeCreation) {
+ ccgSubSurf_setAllowEdgeCreation(ccgSS, 1, useFlatSubdiv?subdivLevels:0.0f);
+ }
ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
return ccgSS;
}
-static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAging, int useArena) {
- SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_em");
-
- ss->useAging = useAging;
- ss->controlType = SUBSURF_CONTROLTYPE_EDITMESH;
- ss->subSurf = _getSubSurf(ss, subdivLevels, useArena);
- ss->em = em;
-
- return ss;
-}
-
-static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, float (*vertCos)[3], DispListMesh *dlm) {
- SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_m");
-
- ss->controlType = SUBSURF_CONTROLTYPE_MESH;
- ss->useAging=0;
- ss->subSurf = _getSubSurf(ss, subdivLevels, 1);
- ss->me = me;
- ss->dlm = dlm;
- ss->vertCos = vertCos;
-
- ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1, useFlatSubdiv?subdivLevels:0.0f);
-
- return ss;
-}
-
-static void subSurf_free(SubSurf *ss) {
- ccgSubSurf_free(ss->subSurf);
- MEM_freeN(ss);
-}
-
static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
@@ -216,23 +184,35 @@ 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 *subSurf_createDispListMesh(SubSurf *ssm) {
- CCGSubSurf *ss = ssm->subSurf;
+static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM) {
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
- TFace *tface = ssm->dlm?ssm->dlm->tface:ssm->me->tface;
- MEdge *medge = ssm->dlm?ssm->dlm->medge:ssm->me->medge;
- MFace *mface = ssm->dlm?ssm->dlm->mface:ssm->me->mface;
- MCol *mcol = ssm->dlm?ssm->dlm->mcol:ssm->me->mcol;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
int i, j, k, S, x, y;
int vertBase = 0;
- MFace *mf;
+ TFace *tface = NULL;
+ MEdge *medge = NULL;
+ MFace *mface = NULL;
+ MCol *mcol = NULL;
CCGVertIterator *vi;
CCGEdgeIterator *ei;
CCGFaceIterator *fi;
+ if (!ssFromEditmesh) {
+ if (inDLM) {
+ tface = inDLM->tface;
+ medge = inDLM->medge;
+ mface = inDLM->mface;
+ mcol = inDLM->mcol;
+ } else if (inMe) {
+ tface = inMe->tface;
+ medge = inMe->medge;
+ mface = inMe->mface;
+ mcol = inMe->mcol;
+ }
+ }
+
dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
@@ -240,10 +220,10 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
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");
- if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && tface) {
+ if (!ssFromEditmesh && tface) {
dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
dlm->mcol = NULL;
- } else if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && mcol) {
+ } else if (!ssFromEditmesh && mcol) {
dlm->tface = NULL;
dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
} else {
@@ -316,7 +296,7 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
med->flag = ME_EDGEDRAW;
- if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
+ if (ssFromEditmesh) {
EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
if (ee->seam) {
@@ -380,19 +360,41 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
float edge_data[4][6];
float corner_data[4][6];
float center_data[6] = {0};
- int numDataComponents;
+ int numDataComponents = 0;
TFace *origTFace = NULL;
- MCol *origMCol = NULL;
int mat_nr;
int flag;
- if (ssm->controlType==SUBSURF_CONTROLTYPE_MESH) {
+ if (!ssFromEditmesh) {
int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
- MFace *origMFace = &((MFace*) mface)[origIdx];
- if (tface)
- origTFace = &((TFace*)tface)[origIdx];
- if (mcol)
- origMCol = &mcol[origIdx*4];
+ MFace *origMFace = &mface[origIdx];
+
+ if (tface) {
+ origTFace = &tface[origIdx];
+
+ for (S=0; S<numVerts; S++) {
+ unsigned char *col = (unsigned char*) &origTFace->col[S];
+ corner_data[S][0] = col[0]/255.0f;
+ corner_data[S][1] = col[1]/255.0f;
+ corner_data[S][2] = col[2]/255.0f;
+ corner_data[S][3] = col[3]/255.0f;
+ corner_data[S][4] = origTFace->uv[S][0];
+ corner_data[S][5] = origTFace->uv[S][1];
+ }
+ numDataComponents = 6;
+ } else if (mcol) {
+ MCol *origMCol = &mcol[origIdx*4];
+
+ for (S=0; S<numVerts; S++) {
+ unsigned char *col = (unsigned char*) &origMCol[S];
+ corner_data[S][0] = col[0]/255.0f;
+ corner_data[S][1] = col[1]/255.0f;
+ corner_data[S][2] = col[2]/255.0f;
+ corner_data[S][3] = col[3]/255.0f;
+ }
+ numDataComponents = 4;
+ }
+
mat_nr = origMFace->mat_nr;
flag = origMFace->flag;
} else {
@@ -401,30 +403,6 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
flag = ef->flag;
}
- if (origTFace) {
- for (S=0; S<numVerts; S++) {
- unsigned char *col = (unsigned char*) &origTFace->col[S];
- corner_data[S][0] = col[0]/255.0f;
- corner_data[S][1] = col[1]/255.0f;
- corner_data[S][2] = col[2]/255.0f;
- corner_data[S][3] = col[3]/255.0f;
- corner_data[S][4] = origTFace->uv[S][0];
- corner_data[S][5] = origTFace->uv[S][1];
- }
- numDataComponents = 6;
- } else if (origMCol) {
- for (S=0; S<numVerts; S++) {
- unsigned char *col = (unsigned char*) &origMCol[S];
- corner_data[S][0] = col[0]/255.0f;
- corner_data[S][1] = col[1]/255.0f;
- corner_data[S][2] = col[2]/255.0f;
- corner_data[S][3] = col[3]/255.0f;
- }
- numDataComponents = 4;
- } else {
- numDataComponents = 0;
- }
-
for (S=0; S<numVerts; S++) {
for (k=0; k<numDataComponents; k++) {
edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
@@ -439,7 +417,7 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
int prevS= (S-1+numVerts)%numVerts;
for (y=0; y<gridSize-1; y++) {
for (x=0; x<gridSize-1; x++) {
- mf = &dlm->mface[i];
+ MFace *mf = &dlm->mface[i];
mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
@@ -504,84 +482,89 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
return dlm;
}
-static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
- float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf);
+static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
+ float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
+ CCGVertHDL fVerts[4];
+ MVert *mvert = dlm?dlm->mvert:me->mvert;
+ MEdge *medge = dlm?dlm->medge:me->medge;
+ MFace *mface = dlm?dlm->mface:me->mface;
+ int totvert = dlm?dlm->totvert:me->totvert;
+ int totedge = dlm?dlm->totedge:me->totedge;
+ int totface = dlm?dlm->totface:me->totface;
+ int i;
+
+ ccgSubSurf_initFullSync(ss);
+
+ if (vertexCos) {
+ for (i=0; i<totvert; i++) {
+ ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]);
+ }
+ } else {
+ for (i=0; i<totvert; i++) {
+ ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co);
+ }
+ }
- ccgSubSurf_initFullSync(ss->subSurf);
+ if (medge) {
+ for (i=0; i<totedge; i++) {
+ MEdge *med = &medge[i];
+ float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
- if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
- CCGVertHDL fVerts[4];
- MVert *mvert = ss->dlm?ss->dlm->mvert:ss->me->mvert;
- MEdge *medge = ss->dlm?ss->dlm->medge:ss->me->medge;
- MFace *mface = ss->dlm?ss->dlm->mface:ss->me->mface;
- int totvert = ss->dlm?ss->dlm->totvert:ss->me->totvert;
- int totedge = ss->dlm?ss->dlm->totedge:ss->me->totedge;
- int totface = ss->dlm?ss->dlm->totface:ss->me->totface;
- int i;
+ ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
+ }
+ } else {
+ for (i=0; i<totface; i++) {
+ MFace *mf = &((MFace*) mface)[i];
- if (ss->vertCos) {
- for (i=0; i<totvert; i++) {
- ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->vertCos[i]);
- }
- } else {
- for (i=0; i<totvert; i++) {
- ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, mvert[i].co);
+ if (!mf->v3) {
+ ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
}
}
+ }
- if (medge) {
- for (i=0; i<totedge; i++) {
- MEdge *med = &medge[i];
- float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
+ for (i=0; i<totface; i++) {
+ MFace *mf = &((MFace*) mface)[i];
- ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
- }
- } else {
- for (i=0; i<totface; i++) {
- MFace *mf = &((MFace*) mface)[i];
+ if (mf->v3) {
+ fVerts[0] = (CCGVertHDL) mf->v1;
+ fVerts[1] = (CCGVertHDL) mf->v2;
+ fVerts[2] = (CCGVertHDL) mf->v3;
+ fVerts[3] = (CCGVertHDL) mf->v4;
- if (!mf->v3) {
- ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
- }
- }
+ ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
}
+ }
- for (i=0; i<totface; i++) {
- MFace *mf = &((MFace*) mface)[i];
+ ccgSubSurf_processSync(ss);
+}
- if (mf->v3) {
- fVerts[0] = (CCGVertHDL) mf->v1;
- fVerts[1] = (CCGVertHDL) mf->v2;
- fVerts[2] = (CCGVertHDL) mf->v3;
- fVerts[3] = (CCGVertHDL) mf->v4;
+void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv)
+{
+ float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
+ EditVert *ev, *fVerts[4];
+ EditEdge *ee;
+ EditFace *ef;
- ccgSubSurf_syncFace(ss->subSurf, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
- }
- }
- } else {
- EditVert *ev, *fVerts[4];
- EditEdge *ee;
- EditFace *ef;
+ ccgSubSurf_initFullSync(ss);
- for (ev=ss->em->verts.first; ev; ev=ev->next) {
- ccgSubSurf_syncVert(ss->subSurf, ev, ev->co);
- }
+ for (ev=em->verts.first; ev; ev=ev->next) {
+ ccgSubSurf_syncVert(ss, ev, ev->co);
+ }
- for (ee=ss->em->edges.first; ee; ee=ee->next) {
- ccgSubSurf_syncEdge(ss->subSurf, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
- }
+ for (ee=em->edges.first; ee; ee=ee->next) {
+ ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
+ }
- for (ef=ss->em->faces.first; ef; ef=ef->next) {
- fVerts[0] = ef->v1;
- fVerts[1] = ef->v2;
- fVerts[2] = ef->v3;
- fVerts[3] = ef->v4;
+ for (ef=em->faces.first; ef; ef=ef->next) {
+ fVerts[0] = ef->v1;
+ fVerts[1] = ef->v2;
+ fVerts[2] = ef->v3;
+ fVerts[3] = ef->v4;
- ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
- }
+ ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
}
- ccgSubSurf_processSync(ss->subSurf);
+ ccgSubSurf_processSync(ss);
}
/***/
@@ -589,12 +572,12 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
typedef struct {
DerivedMesh dm;
- SubSurf *ss;
+ CCGSubSurf *ss;
} CCGDerivedMesh;
static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
@@ -641,17 +624,17 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
static int ccgDM_getNumVerts(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- return ccgSubSurf_getNumFinalVerts(ccgdm->ss->subSurf);
+ return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
}
static int ccgDM_getNumFaces(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- return ccgSubSurf_getNumFinalFaces(ccgdm->ss->subSurf);
+ return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
}
static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGVert *v = ccgSubSurf_getVert(ccgdm->ss->subSurf, vert);
- float *co = ccgSubSurf_getVertData(ccgdm->ss->subSurf, v);
+ CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
+ float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
co_r[0] = co[0];
co_r[1] = co[1];
@@ -660,7 +643,7 @@ static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- return subSurf_createDispListMesh(ccgdm->ss);
+ return ss_to_displistmesh(ccgdm->ss, 1, NULL, NULL);
}
static void ccgDM_drawVerts(DerivedMesh *dm) {
@@ -668,11 +651,14 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
}
static void ccgDM_drawEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
+ int useAging;
+
+ ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -682,7 +668,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
if (eed->h!=0)
continue;
- if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+ if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
@@ -695,7 +681,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
glEnd();
}
- if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+ if (useAging && !(G.f&G_BACKBUFSEL)) {
glColor3ub(0, 0, 0);
}
@@ -734,7 +720,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
}
static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -754,7 +740,7 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
}
static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -778,7 +764,7 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
@@ -851,7 +837,7 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
bglBegin(GL_POINTS);
@@ -869,7 +855,7 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void
}
static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGEdge *e = ccgSubSurf_getEdge(ss, edge);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
@@ -884,9 +870,11 @@ static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
}
static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
- int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+ ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -895,7 +883,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
glBegin(GL_LINE_STRIP);
if (!setDrawOptions || setDrawOptions(userData, edge)) {
- if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+ if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
@@ -912,9 +900,11 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
}
static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
- int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+ int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+ ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -926,7 +916,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
for (i=0; i<edgeSize; i++) {
setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
- if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+ if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
@@ -939,7 +929,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
}
static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = ccgdm->ss->subSurf;
+ CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
@@ -970,12 +960,12 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void
static void ccgDM_release(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
- subSurf_free(ccgdm->ss);
+ ccgSubSurf_free(ccgdm->ss);
MEM_freeN(ccgdm);
}
-static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss) {
CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm");
ccgdm->dm.getMinMax = ccgDM_getMinMax;
@@ -1007,44 +997,53 @@ static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
/***/
-DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels, short type, DerivedMesh *oldDerived) {
- CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) oldDerived;
+DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd) {
+ int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
+ CCGSubSurf *ss = _getSubSurf(NULL, smd->levels, G.rt==52, 0, 0, useSimple);
- if (!ccgdm || ccgSubSurf_getSubdivisionLevels(ccgdm->ss->subSurf)!=subdivLevels) {
- if (ccgdm) {
- oldDerived->release(oldDerived);
- }
+ ss_sync_from_editmesh(ss, em, useSimple);
- ccgdm = getCCGDerivedMesh(subSurf_fromEditmesh(em, subdivLevels, G.rt==52, 0));
- }
+ return (DerivedMesh*) getCCGDerivedMesh(ss);
+}
- subSurf_sync(ccgdm->ss, type==ME_SIMPLE_SUBSURF);
+DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]) {
+ int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
- return (DerivedMesh*) ccgdm;
-}
+ /* Do not use cache in render mode. */
+ if (useRenderParams) {
+ CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, 1, useSimple);
-DerivedMesh *subsurf_make_derived_from_dlm(DispListMesh *dlm, int subdivType, int subdivLevels) {
- SubSurf *ss = subSurf_fromMesh(NULL, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, NULL, dlm);
+ ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
- subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
+ dlm = ss_to_displistmesh(ss, 0, me, dlm);
- dlm = subSurf_createDispListMesh(ss);
-
- subSurf_free(ss);
-
- return derivedmesh_from_displistmesh(dlm);
-}
-DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]) {
- SubSurf *ss = subSurf_fromMesh(me, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, vertCos, NULL);
- DispListMesh *dlm;
+ ccgSubSurf_free(ss);
+
+ return derivedmesh_from_displistmesh(dlm);
+ } else {
+ int useEdgeCreation = !(dlm?dlm->medge:me->medge);
+ int useIncremental = useEdgeCreation?0:smd->useIncrementalMesh;
+ CCGSubSurf *ss;
+
+ if (!useIncremental && smd->mCache) {
+ ccgSubSurf_free(smd->mCache);
+ smd->mCache = NULL;
+ }
- subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
+ ss = _getSubSurf(smd->mCache, smd->levels, 0, 1, useEdgeCreation, useSimple);
- dlm = subSurf_createDispListMesh(ss);
-
- subSurf_free(ss);
-
- return derivedmesh_from_displistmesh(dlm);
+ ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
+
+ dlm = ss_to_displistmesh(ss, 0, me, dlm);
+
+ if (useIncremental) {
+ smd->mCache = ss;
+ } else {
+ ccgSubSurf_free(ss);
+ }
+
+ return derivedmesh_from_displistmesh(dlm);
+ }
}
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
@@ -1054,18 +1053,18 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
* calculated vert positions is incorrect for the verts
* on the boundary of the mesh.
*/
- SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL, NULL);
+ CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0, 0);
float edge_sum[3], face_sum[3];
CCGVertIterator *vi;
- subSurf_sync(ss, 0);
+ ss_sync_from_mesh(ss, me, NULL, NULL, 0);
- vi = ccgSubSurf_getVertIterator(ss->subSurf);
+ vi = ccgSubSurf_getVertIterator(ss);
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- int idx = (int) ccgSubSurf_getVertVertHandle(ss->subSurf, v);
- int N = ccgSubSurf_getVertNumEdges(ss->subSurf, v);
- int numFaces = ccgSubSurf_getVertNumFaces(ss->subSurf, v);
+ int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
+ int N = ccgSubSurf_getVertNumEdges(ss, v);
+ int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
float *co;
int i;
@@ -1073,21 +1072,21 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
for (i=0; i<N; i++) {
- CCGEdge *e = ccgSubSurf_getVertEdge(ss->subSurf, v, i);
- VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss->subSurf, e, 1));
+ CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
+ VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
}
for (i=0; i<numFaces; i++) {
- CCGFace *f = ccgSubSurf_getVertFace(ss->subSurf, v, i);
- VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss->subSurf, f));
+ CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
+ VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
}
- co = ccgSubSurf_getVertData(ss->subSurf, v);
+ co = ccgSubSurf_getVertData(ss, v);
positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
}
ccgVertIterator_free(vi);
- subSurf_free(ss);
+ ccgSubSurf_free(ss);
}
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h
index 54d2098ee1a..a5fcf32d76e 100644
--- a/source/blender/blenlib/BLI_editVert.h
+++ b/source/blender/blenlib/BLI_editVert.h
@@ -100,7 +100,10 @@ typedef struct EditMesh
EditEdge *alledges, *curedge;
EditFace *allfaces, *curface;
- struct DerivedMesh *derived;
+ /* DerivedMesh caches... note that derived cage can be equivalent
+ * to derived final, care should be taken on release.
+ */
+ struct DerivedMesh *derivedCage, *derivedFinal;
} EditMesh;
#endif
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8385535ed8b..2b2cb8a1a3d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2112,23 +2112,46 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
/* ************ READ OBJECT ***************** */
-static void lib_link_modifier_data(FileData *fd, Object *ob, ModifierData *md)
+static void lib_link_modifiers(FileData *fd, Object *ob)
{
- if (md->type==eModifierType_Lattice) {
- LatticeModifierData *lmd = (LatticeModifierData*) md;
-
- lmd->object = newlibadr(fd, ob->id.lib, lmd->object);
- }
- else if (md->type==eModifierType_Curve) {
- CurveModifierData *cmd = (CurveModifierData*) md;
+ ModifierData *md;
+
+ for (md=ob->modifiers.first; md; md=md->next) {
+ if (md->type==eModifierType_Lattice) {
+ LatticeModifierData *lmd = (LatticeModifierData*) md;
+
+ lmd->object = newlibadr(fd, ob->id.lib, lmd->object);
+ }
+ else if (md->type==eModifierType_Curve) {
+ CurveModifierData *cmd = (CurveModifierData*) md;
+
+ cmd->object = newlibadr(fd, ob->id.lib, cmd->object);
+ }
+ }
+
+ /* Patch subsurf modifier */
+ if (ob->type==OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (me->flag&ME_SUBSURF) {
+ SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
+
+ smd->levels = me->subdiv;
+ smd->renderLevels = me->subdivr;
+ smd->subdivType = me->subsurftype;
- cmd->object = newlibadr(fd, ob->id.lib, cmd->object);
+ BLI_addtail(&ob->modifiers, smd);
+
+ /* Turn it off, so it won't get saved again with flag,
+ * still could be an issue with lib-linked mesh.
+ */
+ me->flag ^= ME_SUBSURF;
+ }
}
}
static void lib_link_object(FileData *fd, Main *main)
{
- ModifierData *md;
Object *ob;
bSensor *sens;
bController *cont;
@@ -2260,9 +2283,7 @@ static void lib_link_object(FileData *fd, Main *main)
hook->parent= newlibadr(fd, ob->id.lib, hook->parent);
}
- for (md=ob->modifiers.first; md; md= md->next) {
- lib_link_modifier_data(fd, ob, md);
- }
+ lib_link_modifiers(fd, ob);
}
ob= ob->id.next;
}
@@ -2289,6 +2310,21 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
}
+static void direct_link_modifiers(FileData *fd, ListBase *lb)
+{
+ ModifierData *md;
+
+ link_list(fd, lb);
+
+ for (md=lb->first; md; md=md->next) {
+ if (md->type==eModifierType_Subsurf) {
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+ smd->emCache = smd->mCache = 0;
+ }
+ }
+}
+
static void direct_link_object(FileData *fd, Object *ob)
{
PartEff *paf;
@@ -2304,7 +2340,6 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->pose= newdataadr(fd, ob->pose);
direct_link_pose(fd, ob->pose);
- link_list(fd, &ob->modifiers);
link_list(fd, &ob->defbase);
link_list(fd, &ob->nlastrips);
link_list(fd, &ob->constraintChannels);
@@ -2327,8 +2362,7 @@ static void direct_link_object(FileData *fd, Object *ob)
if(paf->type==EFF_BUILD) {
BuildEff *baf = (BuildEff*) paf;
PartEff *next = paf->next;
- ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Build);
- BuildModifierData *bmd = (BuildModifierData*) mti->allocData();
+ BuildModifierData *bmd = (BuildModifierData*) modifier_new(eModifierType_Build);
bmd->start = baf->sfra;
bmd->length = baf->len;
@@ -2408,6 +2442,8 @@ static void direct_link_object(FileData *fd, Object *ob)
}
}
}
+
+ direct_link_modifiers(fd, &ob->modifiers);
ob->bb= NULL;
ob->derivedDeform= NULL;
@@ -4767,7 +4803,6 @@ static void do_versions(FileData *fd, Main *main)
}
}
}
-
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 5ebdd4d5a1a..6d626a5d6a8 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -601,6 +601,10 @@ enum {
#define B_RECALCAL 3411
#define B_RECALC_DEFL 3412
+#define B_MDFR_BUTS 3600
+
+#define B_MDFR_INCREMENTAl 3501
+
/* *********************** */
/* *********************** */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 5eb00c4f21b..8efad895e47 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -36,7 +36,9 @@ typedef struct ModifierData {
typedef struct SubsurfModifierData {
ModifierData modifier;
- short subdivType, levels, renderLevels, pad;
+ short subdivType, levels, renderLevels, useIncrementalMesh;
+
+ void *emCache, *mCache;
} SubsurfModifierData;
typedef struct LatticeModifierData {
diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c
index b0917a1123d..5008fc84e9d 100644
--- a/source/blender/src/butspace.c
+++ b/source/blender/src/butspace.c
@@ -318,9 +318,12 @@ void do_butspace(unsigned short event)
do_uvautocalculationbuts(event);
}
else if(event<=B_EFFECTSBUTS) {
- /*here we put the effects buttons do commands*/
do_effects_panels(event);
}
+ else if(event<=B_MDFR_BUTS) {
+ extern void do_modifier_panels(unsigned short event);
+ do_modifier_panels(event);
+ }
else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too
else if(event>REDRAWVIEW3D) allqueue(event, 0);
}
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index f437752a677..09db99e7bf5 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -656,8 +656,6 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
{
uiBlock *block;
float val;
- /* Hope to support more than two subsurf algorithms */
- char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
@@ -667,12 +665,7 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
uiBlockBeginAlign(block);
- uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButS(block, TOG|BIT|7, B_SUBSURFTYPE, "SubSurf", 10,134,70,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Subdivision Surface");
- uiDefButS(block, MENU, B_SUBSURFTYPE, subsurfmenu, 80,134,84,19, &(me->subsurftype), 0, 0, 0, 0, "Selects type of Subsurf algorithm.");
uiBlockSetCol(block, TH_AUTO);
- uiDefButS(block, NUM, B_SUBSURFTYPE, "Subdiv:", 10, 114,110,19, &me->subdiv, 0, 6, 0, 0, "Defines the level of subdivision to display in real time interactively");
- uiDefButS(block, NUM, B_DIFF, "", 120,114, 44, 19, &me->subdivr, 0, 6, 0, 0, "Defines the level of subdivision to apply during rendering");
uiDefButS(block, TOG|BIT|8, B_SUBSURFTYPE, "Optimal", 10, 94,154,19, &me->flag, 0, 0, 0, 0, "Only draws optimal wireframe");
uiBlockBeginAlign(block);
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 204f580096e..5333bf1a61d 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -1655,23 +1655,46 @@ static void object_softbodies(Object *ob)
static int actModifier = 0;
-static void modifiers_add(void *ob_v, int type)
+void do_modifier_panels(unsigned short event)
{
- Object *ob = ob_v;
- ModifierTypeInfo *mti = modifierType_get_info(type);
-
- if (mti) {
- ModifierData *md = mti->allocData();
-
- BLI_addtail(&ob->modifiers, md);
+ Object *ob = OBACT;
+ ModifierData *md;
+ int i;
- actModifier = BLI_countlist(&ob->modifiers);
+ for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
+ md = md->next;
- allqueue(REDRAWBUTSOBJECT, 0);
+ switch(event) {
+ case B_MDFR_INCREMENTAl:
+ if (md && md->type==eModifierType_Subsurf && ((SubsurfModifierData*)md)->useIncrementalMesh) {
+ if (ob->type==OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (!me->medge) {
+ if (okee("Requires mesh edges, create now?")) {
+ make_edges(me);
+ }
+ }
+ }
+ }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
+ break;
}
}
+static void modifiers_add(void *ob_v, int type)
+{
+ Object *ob = ob_v;
+ BLI_addtail(&ob->modifiers, modifier_new(type));
+
+ actModifier = BLI_countlist(&ob->modifiers);
+
+ allqueue(REDRAWBUTSOBJECT, 0);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+}
+
static uiBlock *modifier_add_menu(void *ob_v)
{
Object *ob = ob_v;
@@ -1707,7 +1730,8 @@ static void modifiers_del(void *ob_v, void *arg2)
if (md) {
BLI_remlink(&ob->modifiers, md);
- MEM_freeN(md);
+
+ modifier_free(md);
}
allqueue(REDRAWBUTSOBJECT, 0);
@@ -1819,7 +1843,8 @@ static void object_panel_modifiers(Object *ob)
char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
uiDefButS(block, NUM, B_MAKEDISP, "Levels:", 550, 320, 150,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
uiDefButS(block, NUM, B_MAKEDISP, "Render Levels:", 550, 300, 150,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
- uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu, 550,280,150,19, &(smd->subdivType), 0, 0, 0, 0, "Selects type of subdivision algorithm.");
+ uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu, 550,280,150,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
+ uiDefButS(block, TOG, B_MDFR_INCREMENTAl, "Incremental", 550, 260,150,19,&smd->useIncrementalMesh, 0, 0, 1, 0, "Use incremental calculation, even outside of mesh mode");
} else if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md;
uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:", 550, 320, 120,19, &lmd->object, "Lattice object to deform with");
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 4c05139227c..20a6bb1df3a 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -1659,16 +1659,9 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em)
}
}
-static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, DerivedMesh *realDM, int dt)
+static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
{
Mesh *me = ob->data;
- DerivedMesh *cageDM;
-
- if(realDM && (me->flag&ME_OPT_EDGES)) {
- cageDM = realDM;
- } else {
- cageDM = baseDM;
- }
if(dt>OB_WIRE) {
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
@@ -1676,11 +1669,7 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, Derived
glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- if (realDM) {
- realDM->drawFacesSolid(realDM, set_gl_material);
- } else {
- baseDM->drawFacesSolid(baseDM, set_gl_material);
- }
+ finalDM->drawFacesSolid(finalDM, set_gl_material);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
@@ -1693,9 +1682,9 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, Derived
glDepthMask(0);
}
else {
- if (realDM && !(me->flag&ME_OPT_EDGES)) {
+ if (cageDM!=finalDM) {
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
- realDM->drawEdges(realDM);
+ finalDM->drawEdges(finalDM);
}
}
@@ -1918,13 +1907,14 @@ static void draw_mesh_object(Base *base, int dt)
int has_alpha= 0;
if(G.obedit && ob->data==G.obedit->data) {
- DerivedMesh *baseDM = editmesh_get_derived_proxy();
- DerivedMesh *realDM = editmesh_get_derived();
+ int cageNeedsFree, finalNeedsFree;
+ DerivedMesh *finalDM, *cageDM = editmesh_get_derived_cage_and_final(&finalDM, &cageNeedsFree, &finalNeedsFree);
if(dt>OB_WIRE) init_gl_materials(ob); // no transp in editmode, the fancy draw over goes bad then
- draw_em_fancy(ob, G.editMesh, baseDM, realDM, dt);
+ draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
- baseDM->release(baseDM);
+ if (cageNeedsFree) cageDM->release(cageDM);
+ if (finalNeedsFree) finalDM->release(finalDM);
}
else {
BoundBox *bb = mesh_get_bb(me);
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index 74437bc771b..8a1d1088834 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -500,16 +500,9 @@ void count_object(Object *ob, int sel)
if(me) {
int totvert, totface;
- /* note; do not make disp or get derived mesh here. spoils dependency order */
- if (me->flag & ME_SUBSURF) {
- /* approximate counts, about right for a mesh entirely made
- * of quads and that is a closed 2-manifold.
- */
- totvert= totface= me->totface*1<<(me->subdiv*2);
- } else {
- totvert= me->totvert;
- totface= me->totface;
- }
+ // XXX fixme for modifier stack
+ totvert= me->totvert;
+ totface= me->totface;
G.totvert+= totvert;
G.totface+= totface;
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 804b77abb80..2e3ca06a9bb 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -451,9 +451,15 @@ void free_editMesh(EditMesh *em)
if(em->edges.first) free_edgelist(&em->edges);
if(em->faces.first) free_facelist(&em->faces);
- if(em->derived) {
- em->derived->release(em->derived);
- em->derived= NULL;
+ if(em->derivedFinal) {
+ if (em->derivedFinal!=em->derivedCage) {
+ em->derivedFinal->release(em->derivedFinal);
+ }
+ em->derivedFinal= NULL;
+ }
+ if(em->derivedCage) {
+ em->derivedCage->release(em->derivedCage);
+ em->derivedCage= NULL;
}
/* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
@@ -699,7 +705,7 @@ void make_editMesh()
}
}
-
+
if(actkey && actkey->totelem!=me->totvert);
else {
unsigned int *mcol;
@@ -779,7 +785,7 @@ void make_editMesh()
MEM_freeN(evlist);
end_editmesh_fastmalloc(); // resets global function pointers
-
+
/* this creates coherent selections. also needed for older files */
EM_selectmode_set();
/* paranoia check to enforce hide rules */
@@ -1388,7 +1394,7 @@ void separate_mesh(void)
emcopy.allverts= NULL;
emcopy.alledges= NULL;
emcopy.allfaces= NULL;
- emcopy.derived= NULL;
+ emcopy.derivedFinal= emcopy.derivedCage= NULL;
free_editMesh(&emcopy);
em->verts= edve;
@@ -1554,7 +1560,7 @@ void separate_mesh_loose(void)
emcopy.allverts= NULL;
emcopy.alledges= NULL;
emcopy.allfaces= NULL;
- emcopy.derived= NULL;
+ emcopy.derivedFinal= emcopy.derivedCage= NULL;
free_editMesh(&emcopy);
em->verts= edve;