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/blenkernel
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/blenkernel')
-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
9 files changed, 415 insertions, 375 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);
}