- 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).
This commit is contained in:
2005-07-21 20:30:33 +00:00
parent 9449f0b24f
commit 33709bf6e2
19 changed files with 560 additions and 466 deletions

View File

@@ -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(struct Object *ob, float (*vertCos)[3]);
DerivedMesh *mesh_create_derived_no_deform_render(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(int *needsFree_r);
DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r);
#endif #endif

View File

@@ -61,15 +61,33 @@ typedef enum {
} ModifierTypeFlag; } ModifierTypeFlag;
typedef struct ModifierTypeInfo { 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; ModifierTypeType type;
ModifierTypeFlag flags; 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 /* 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 * 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); 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 #endif

View File

@@ -35,10 +35,10 @@ struct Mesh;
struct Object; struct Object;
struct DerivedMesh; struct DerivedMesh;
struct EditMesh; 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_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]); struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]);
struct DerivedMesh *subsurf_make_derived_from_dlm(struct DispListMesh *dlm, int subdivType, int subdivLevels);
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]); void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);

View File

@@ -289,8 +289,7 @@ struct _CCGSubSurf {
EHash *fMap; /* map of CCGFaceHDL -> Face */ EHash *fMap; /* map of CCGFaceHDL -> Face */
CCGMeshIFC meshIFC; CCGMeshIFC meshIFC;
void *meshData;
CCGAllocatorIFC allocatorIFC; CCGAllocatorIFC allocatorIFC;
CCGAllocatorHDL allocator; 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) { if (!allocatorIFC) {
allocatorIFC = _getStandardAllocatorIFC(); allocatorIFC = _getStandardAllocatorIFC();
allocator = NULL; 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->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
ss->meshIFC = *ifc; ss->meshIFC = *ifc;
ss->meshData = meshData;
ss->subdivLevels = subdivLevels; ss->subdivLevels = subdivLevels;
ss->numGrids = 0; ss->numGrids = 0;
ss->allowEdgeCreation = 0; ss->allowEdgeCreation = 0;
@@ -710,6 +708,15 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
return eCCGError_None; 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) { CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) {
if (useAgeCounts) { if (useAgeCounts) {
if ( (vertUserOffset+4>ss->meshIFC.vertUserSize) || if ( (vertUserOffset+4>ss->meshIFC.vertUserSize) ||

View File

@@ -37,7 +37,7 @@ typedef enum {
typedef struct _CCGSubSurf CCGSubSurf; 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); void ccgSubSurf_free (CCGSubSurf *ss);
CCGError ccgSubSurf_sync (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_processSync (CCGSubSurf *ss);
CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels); CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels);
CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue); 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_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset); CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);

View File

@@ -1005,11 +1005,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
if (deform_r) *deform_r = NULL; if (deform_r) *deform_r = NULL;
*final_r = NULL; *final_r = NULL;
/* Note: useDeform==1 implies ob must be non-NULL */
if (useDeform) { if (useDeform) {
mesh_modifier(ob, &deformedVerts); mesh_modifier(ob, &deformedVerts);
// XXX this copy should be done on demand
if (!deformedVerts) { if (!deformedVerts) {
deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos1"); deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos1");
for (a=0; a<numVerts; a++) { 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 /* 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 * these back onto the DerivedMesh. If we have no DerivedMesh then we need to build
* one. * 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; Mesh *me= ob->data;
if(ob->flag&OB_FROMDUPLI) return;
/* also serves as signal to remake texspace */ /* also serves as signal to remake texspace */
if (me->bb) { if (me->bb) {
MEM_freeN(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->release(ob->derivedDeform);
ob->derivedDeform= NULL; ob->derivedDeform= NULL;
} }
}
if (ob==G.obedit) { static void mesh_build_data(Object *ob)
G.editMesh->derived= subsurf_make_derived_from_editmesh(G.editMesh, me->subdiv, me->subsurftype, G.editMesh->derived); {
} 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);
if (ob!=G.obedit || mustBuildForMesh) { INIT_MINMAX(min, max);
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
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) 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; Mesh *me = ob->data;
if (!ob->derivedFinal) { if (!ob->derivedFinal) {
clear_and_build_mesh_data(ob, 1); mesh_build_data(ob);
} }
*needsFree_r = 0; *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) DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
{ {
if (!ob->derivedDeform) { if (!ob->derivedDeform) {
clear_and_build_mesh_data(ob, 1); mesh_build_data(ob);
} }
*needsFree_r = 0; *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) if (!G.editMesh->derivedCage)
{ editmesh_build_data();
Mesh *me= G.obedit->data;
if ((me->flag&ME_SUBSURF) && me->subdiv) { *final_r = G.editMesh->derivedFinal;
if (!G.editMesh->derived) { return G.editMesh->derivedCage;
makeDispListMesh(G.obedit);
}
return G.editMesh->derived;
}
return NULL;
} }
DerivedMesh *editmesh_get_derived_cage(int *needsFree_r) DerivedMesh *editmesh_get_derived_cage(int *needsFree_r)
{ {
Mesh *me= G.obedit->data;
DerivedMesh *dm = NULL;
*needsFree_r = 0; *needsFree_r = 0;
if (me->flag&ME_OPT_EDGES) { if (!G.editMesh->derivedCage)
dm = editmesh_get_derived(); editmesh_build_data();
}
if (!dm) {
*needsFree_r = 1;
dm = editmesh_get_derived_proxy();
}
return dm; return G.editMesh->derivedCage;
} }

View File

@@ -21,22 +21,10 @@
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "depsgraph_private.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) static int noneModifier_isDisabled(ModifierData *md)
{ {
return 1; return 1;
@@ -44,11 +32,6 @@ static int noneModifier_isDisabled(ModifierData *md)
/* Curve */ /* Curve */
static ModifierData *curveModifier_allocData(void)
{
return allocModifierData(eModifierType_Curve, sizeof(CurveModifierData));
}
static int curveModifier_isDisabled(ModifierData *md) static int curveModifier_isDisabled(ModifierData *md)
{ {
CurveModifierData *cmd = (CurveModifierData*) md; CurveModifierData *cmd = (CurveModifierData*) md;
@@ -76,11 +59,6 @@ static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vert
/* Lattice */ /* Lattice */
static ModifierData *latticeModifier_allocData(void)
{
return allocModifierData(eModifierType_Lattice, sizeof(LatticeModifierData));
}
static int latticeModifier_isDisabled(ModifierData *md) static int latticeModifier_isDisabled(ModifierData *md)
{ {
LatticeModifierData *lmd = (LatticeModifierData*) md; LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -108,20 +86,26 @@ static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*ve
/* Subsurf */ /* 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->levels = 1;
smd->renderLevels = 2; 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) static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
{ {
SubsurfModifierData *smd = (SubsurfModifierData*) md; SubsurfModifierData *smd = (SubsurfModifierData*) md;
int levels = useRenderParams?smd->renderLevels:smd->levels;
Mesh *me = ob->data; Mesh *me = ob->data;
if (dm) { if (dm) {
@@ -137,25 +121,23 @@ static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, Derived
} }
dm->release(dm); 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); displistmesh_free(dlm);
return dm; return dm;
} else { } else {
return subsurf_make_derived_from_mesh(me, smd->subdivType, levels, vertexCos); return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos);
} }
} }
/* Build */ /* 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->start = 1.0;
bmd->length = 100.0; bmd->length = 100.0;
return (ModifierData*) bmd;
} }
static int buildModifier_dependsOnTime(ModifierData *md) static int buildModifier_dependsOnTime(ModifierData *md)
@@ -354,8 +336,14 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
} else { } else {
ndlm->totvert = totvert*frac; ndlm->totvert = totvert*frac;
ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert"); if (bmd->randomize) {
memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert); 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) { if (vertexCos) {
for (i=0; i<ndlm->totvert; i++) { for (i=0; i<ndlm->totvert; i++) {
VECCOPY(ndlm->mvert[i].co, vertexCos[i]); VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
@@ -373,14 +361,11 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
/* Mirror */ /* 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; mmd->tolerance = 0.001;
return (ModifierData*) mmd;
} }
static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams) 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)); 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]; mti = &typeArr[eModifierType_None];
strcpy(mti->name, "None"); strcpy(mti->name, "None");
strcpy(mti->structName, "ModifierData"); strcpy(mti->structName, "ModifierData");
mti->structSize = sizeof(ModifierData);
mti->type = eModifierType_None; mti->type = eModifierType_None;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs; mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
mti->allocData = noneModifier_allocData;
mti->isDisabled = noneModifier_isDisabled; mti->isDisabled = noneModifier_isDisabled;
mti = &typeArr[eModifierType_Curve]; mti = INIT_TYPE(Curve);
strcpy(mti->name, "Curve");
strcpy(mti->structName, "CurveModifierData");
mti->type = eModifierTypeType_OnlyDeform; mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs; mti->flags = eModifierTypeFlag_AcceptsCVs;
mti->allocData = curveModifier_allocData;
mti->isDisabled = curveModifier_isDisabled; mti->isDisabled = curveModifier_isDisabled;
mti->updateDepgraph = curveModifier_updateDepgraph; mti->updateDepgraph = curveModifier_updateDepgraph;
mti->deformVerts = curveModifier_deformVerts; mti->deformVerts = curveModifier_deformVerts;
mti = &typeArr[eModifierType_Lattice]; mti = INIT_TYPE(Lattice);
strcpy(mti->name, "Lattice");
strcpy(mti->structName, "LatticeModifierData");
mti->type = eModifierTypeType_OnlyDeform; mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsCVs; mti->flags = eModifierTypeFlag_AcceptsCVs;
mti->allocData = latticeModifier_allocData;
mti->isDisabled = latticeModifier_isDisabled; mti->isDisabled = latticeModifier_isDisabled;
mti->updateDepgraph = latticeModifier_updateDepgraph; mti->updateDepgraph = latticeModifier_updateDepgraph;
mti->deformVerts = latticeModifier_deformVerts; mti->deformVerts = latticeModifier_deformVerts;
mti = &typeArr[eModifierType_Subsurf]; mti = INIT_TYPE(Subsurf);
strcpy(mti->name, "Subsurf");
strcpy(mti->structName, "SubsurfModifierData");
mti->type = eModifierTypeType_Constructive; mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping; mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
mti->allocData = subsurfModifier_allocData; mti->initData = subsurfModifier_initData;
mti->freeData = subsurfModifier_freeData;
mti->applyModifier = subsurfModifier_applyModifier; mti->applyModifier = subsurfModifier_applyModifier;
mti = &typeArr[eModifierType_Build]; mti = INIT_TYPE(Build);
strcpy(mti->name, "Build");
strcpy(mti->structName, "BuildModifierData");
mti->type = eModifierTypeType_Nonconstructive; mti->type = eModifierTypeType_Nonconstructive;
mti->flags = eModifierTypeFlag_AcceptsMesh; mti->flags = eModifierTypeFlag_AcceptsMesh;
mti->allocData = buildModifier_allocData; mti->initData = buildModifier_initData;
mti->dependsOnTime = buildModifier_dependsOnTime; mti->dependsOnTime = buildModifier_dependsOnTime;
mti->applyModifier = buildModifier_applyModifier; mti->applyModifier = buildModifier_applyModifier;
mti = &typeArr[eModifierType_Mirror]; mti = INIT_TYPE(Mirror);
strcpy(mti->name, "Mirror");
strcpy(mti->structName, "MirrorModifierData");
mti->type = eModifierTypeType_Constructive; mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh; mti->flags = eModifierTypeFlag_AcceptsMesh;
mti->allocData = mirrorModifier_allocData; mti->initData = mirrorModifier_initData;
mti->applyModifier = mirrorModifier_applyModifier; mti->applyModifier = mirrorModifier_applyModifier;
typeArrInit = 0; typeArrInit = 0;
#undef INIT_TYPE
} }
if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') { 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) int modifier_dependsOnTime(ModifierData *md)
{ {
ModifierTypeInfo *mti = modifierType_get_info(md->type); ModifierTypeInfo *mti = modifierType_get_info(md->type);

View File

@@ -95,6 +95,7 @@
#include "BKE_library.h" #include "BKE_library.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_mball.h" #include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_property.h" #include "BKE_property.h"
#include "BKE_sca.h" #include "BKE_sca.h"
@@ -177,7 +178,8 @@ static void free_modifiers(ListBase *lb)
while (md=lb->first) { while (md=lb->first) {
BLI_remlink(lb, md); BLI_remlink(lb, md);
MEM_freeN(md);
modifier_free(md);
} }
} }

View File

@@ -38,6 +38,7 @@
#include "DNA_mesh_types.h" #include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "BKE_bad_level_calls.h" #include "BKE_bad_level_calls.h"
@@ -58,24 +59,6 @@
#include "CCGSubSurf.h" #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 { typedef struct _VertData {
float co[3]; float co[3];
float no[3]; float no[3];
@@ -99,13 +82,25 @@ static void arena_release(CCGAllocatorHDL a) {
BLI_memarena_free(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; CCGMeshIFC ifc;
CCGSubSurf *ccgSS; 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; ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
} else { } else {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4; ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
@@ -113,58 +108,31 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
ifc.vertDataSize = sizeof(VertData); ifc.vertDataSize = sizeof(VertData);
if (useArena) { if (useArena) {
CCGAllocatorIFC allocatorIFC;
CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
allocatorIFC.alloc = arena_alloc; allocatorIFC.alloc = arena_alloc;
allocatorIFC.realloc = arena_realloc; allocatorIFC.realloc = arena_realloc;
allocatorIFC.free = arena_free; allocatorIFC.free = arena_free;
allocatorIFC.release = arena_release; 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 { } 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); 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)); ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
return ccgSS; 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) { static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e); CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
CCGVert *v1 = ccgSubSurf_getEdgeVert1(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); return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
} }
} }
static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) { static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM) {
CCGSubSurf *ss = ssm->subSurf;
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm"); 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 edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss); int gridSize = ccgSubSurf_getGridSize(ss);
int edgeIndexBase, edgeBase, faceIndexBase, faceBase; int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
int i, j, k, S, x, y; int i, j, k, S, x, y;
int vertBase = 0; int vertBase = 0;
MFace *mf; TFace *tface = NULL;
MEdge *medge = NULL;
MFace *mface = NULL;
MCol *mcol = NULL;
CCGVertIterator *vi; CCGVertIterator *vi;
CCGEdgeIterator *ei; CCGEdgeIterator *ei;
CCGFaceIterator *fi; 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->totvert = ccgSubSurf_getNumFinalVerts(ss);
dlm->totedge = ccgSubSurf_getNumFinalEdges(ss); dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
dlm->totface = ccgSubSurf_getNumFinalFaces(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->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge"); dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface"); 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->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
dlm->mcol = NULL; dlm->mcol = NULL;
} else if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && mcol) { } else if (!ssFromEditmesh && mcol) {
dlm->tface = NULL; dlm->tface = NULL;
dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol"); dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
} else { } else {
@@ -316,7 +296,7 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
med->flag = ME_EDGEDRAW; med->flag = ME_EDGEDRAW;
if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) { if (ssFromEditmesh) {
EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e); EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
if (ee->seam) { if (ee->seam) {
@@ -380,19 +360,41 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
float edge_data[4][6]; float edge_data[4][6];
float corner_data[4][6]; float corner_data[4][6];
float center_data[6] = {0}; float center_data[6] = {0};
int numDataComponents; int numDataComponents = 0;
TFace *origTFace = NULL; TFace *origTFace = NULL;
MCol *origMCol = NULL;
int mat_nr; int mat_nr;
int flag; int flag;
if (ssm->controlType==SUBSURF_CONTROLTYPE_MESH) { if (!ssFromEditmesh) {
int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f); int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
MFace *origMFace = &((MFace*) mface)[origIdx]; MFace *origMFace = &mface[origIdx];
if (tface)
origTFace = &((TFace*)tface)[origIdx]; if (tface) {
if (mcol) origTFace = &tface[origIdx];
origMCol = &mcol[origIdx*4];
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; mat_nr = origMFace->mat_nr;
flag = origMFace->flag; flag = origMFace->flag;
} else { } else {
@@ -401,30 +403,6 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
flag = ef->flag; 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 (S=0; S<numVerts; S++) {
for (k=0; k<numDataComponents; k++) { for (k=0; k<numDataComponents; k++) {
edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f; 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; int prevS= (S-1+numVerts)%numVerts;
for (y=0; y<gridSize-1; y++) { for (y=0; y<gridSize-1; y++) {
for (x=0; x<gridSize-1; x++) { 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->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
mf->v2 = getFaceIndex(ss, f, S, x+1, 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); mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
@@ -504,84 +482,89 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
return dlm; return dlm;
} }
static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) { static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf); 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->subSurf); ccgSubSurf_initFullSync(ss);
if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) { if (vertexCos) {
CCGVertHDL fVerts[4]; for (i=0; i<totvert; i++) {
MVert *mvert = ss->dlm?ss->dlm->mvert:ss->me->mvert; ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]);
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;
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 (medge) {
for (i=0; i<totedge; i++) {
MEdge *med = &medge[i];
float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
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) {
ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
}
}
}
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;
ccgSubSurf_syncFace(ss->subSurf, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
}
} }
} else { } else {
EditVert *ev, *fVerts[4]; for (i=0; i<totvert; i++) {
EditEdge *ee; ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co);
EditFace *ef;
for (ev=ss->em->verts.first; ev; ev=ev->next) {
ccgSubSurf_syncVert(ss->subSurf, 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 (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;
ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
} }
} }
ccgSubSurf_processSync(ss->subSurf); if (medge) {
for (i=0; i<totedge; i++) {
MEdge *med = &medge[i];
float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
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 (!mf->v3) {
ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
}
}
}
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;
ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
}
}
ccgSubSurf_processSync(ss);
}
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_initFullSync(ss);
for (ev=em->verts.first; ev; ev=ev->next) {
ccgSubSurf_syncVert(ss, ev, ev->co);
}
for (ee=em->edges.first; ee; ee=ee->next) {
ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
}
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, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
}
ccgSubSurf_processSync(ss);
} }
/***/ /***/
@@ -589,12 +572,12 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
typedef struct { typedef struct {
DerivedMesh dm; DerivedMesh dm;
SubSurf *ss; CCGSubSurf *ss;
} CCGDerivedMesh; } CCGDerivedMesh;
static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(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) { static int ccgDM_getNumVerts(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
return ccgSubSurf_getNumFinalVerts(ccgdm->ss->subSurf); return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
} }
static int ccgDM_getNumFaces(DerivedMesh *dm) { static int ccgDM_getNumFaces(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) 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]) { static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGVert *v = ccgSubSurf_getVert(ccgdm->ss->subSurf, vert); CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
float *co = ccgSubSurf_getVertData(ccgdm->ss->subSurf, v); float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
co_r[0] = co[0]; co_r[0] = co[0];
co_r[1] = co[1]; 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) { static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) 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) { static void ccgDM_drawVerts(DerivedMesh *dm) {
@@ -668,11 +651,14 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
} }
static void ccgDM_drawEdges(DerivedMesh *dm) { static void ccgDM_drawEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss); int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss); int gridSize = ccgSubSurf_getGridSize(ss);
int useAging;
ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei); CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -682,7 +668,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
if (eed->h!=0) if (eed->h!=0)
continue; continue;
if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) { if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0); glColor3ub(0, ageCol>0?ageCol:0, 0);
} }
@@ -695,7 +681,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
glEnd(); glEnd();
} }
if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) { if (useAging && !(G.f&G_BACKBUFSEL)) {
glColor3ub(0, 0, 0); glColor3ub(0, 0, 0);
} }
@@ -734,7 +720,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
} }
static void ccgDM_drawMappedEdges(DerivedMesh *dm) { static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss); int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -754,7 +740,7 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
} }
static void ccgDM_drawLooseEdges(DerivedMesh *dm) { static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(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)) { static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(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) { static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
bglBegin(GL_POINTS); bglBegin(GL_POINTS);
@@ -869,7 +855,7 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void
} }
static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) { static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGEdge *e = ccgSubSurf_getEdge(ss, edge); CCGEdge *e = ccgSubSurf_getEdge(ss, edge);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); 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) { static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(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)) { for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei); CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -895,7 +883,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
if (!setDrawOptions || setDrawOptions(userData, edge)) { 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; int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0); 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) { 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; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(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)) { for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei); CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -926,7 +916,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
for (i=0; i<edgeSize; i++) { for (i=0; i<edgeSize; i++) {
setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1)); 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; int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0); 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) { static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss->subSurf; CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(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) { static void ccgDM_release(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
subSurf_free(ccgdm->ss); ccgSubSurf_free(ccgdm->ss);
MEM_freeN(ccgdm); MEM_freeN(ccgdm);
} }
static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) { static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss) {
CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm"); CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm");
ccgdm->dm.getMinMax = ccgDM_getMinMax; 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) { DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) oldDerived; 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) { ss_sync_from_editmesh(ss, em, useSimple);
if (ccgdm) {
oldDerived->release(oldDerived); return (DerivedMesh*) getCCGDerivedMesh(ss);
}
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]) {
int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
/* Do not use cache in render mode. */
if (useRenderParams) {
CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, 1, useSimple);
ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
dlm = ss_to_displistmesh(ss, 0, me, 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;
} }
ccgdm = getCCGDerivedMesh(subSurf_fromEditmesh(em, subdivLevels, G.rt==52, 0)); ss = _getSubSurf(smd->mCache, smd->levels, 0, 1, useEdgeCreation, useSimple);
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);
} }
subSurf_sync(ccgdm->ss, type==ME_SIMPLE_SUBSURF);
return (DerivedMesh*) ccgdm;
}
DerivedMesh *subsurf_make_derived_from_dlm(DispListMesh *dlm, int subdivType, int subdivLevels) {
SubSurf *ss = subSurf_fromMesh(NULL, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, NULL, dlm);
subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
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;
subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
dlm = subSurf_createDispListMesh(ss);
subSurf_free(ss);
return derivedmesh_from_displistmesh(dlm);
} }
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 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 * calculated vert positions is incorrect for the verts
* on the boundary of the mesh. * 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]; float edge_sum[3], face_sum[3];
CCGVertIterator *vi; 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)) { for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi); CCGVert *v = ccgVertIterator_getCurrent(vi);
int idx = (int) ccgSubSurf_getVertVertHandle(ss->subSurf, v); int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
int N = ccgSubSurf_getVertNumEdges(ss->subSurf, v); int N = ccgSubSurf_getVertNumEdges(ss, v);
int numFaces = ccgSubSurf_getVertNumFaces(ss->subSurf, v); int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
float *co; float *co;
int i; 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; face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
for (i=0; i<N; i++) { for (i=0; i<N; i++) {
CCGEdge *e = ccgSubSurf_getVertEdge(ss->subSurf, v, i); CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss->subSurf, e, 1)); VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
} }
for (i=0; i<numFaces; i++) { for (i=0; i<numFaces; i++) {
CCGFace *f = ccgSubSurf_getVertFace(ss->subSurf, v, i); CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss->subSurf, f)); 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][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][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)); positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
} }
ccgVertIterator_free(vi); ccgVertIterator_free(vi);
subSurf_free(ss); ccgSubSurf_free(ss);
} }

View File

@@ -100,7 +100,10 @@ typedef struct EditMesh
EditEdge *alledges, *curedge; EditEdge *alledges, *curedge;
EditFace *allfaces, *curface; 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; } EditMesh;
#endif #endif

View File

@@ -2112,23 +2112,46 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
/* ************ READ OBJECT ***************** */ /* ************ 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) { ModifierData *md;
LatticeModifierData *lmd = (LatticeModifierData*) 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;
lmd->object = newlibadr(fd, ob->id.lib, lmd->object); BLI_addtail(&ob->modifiers, smd);
}
else if (md->type==eModifierType_Curve) { /* Turn it off, so it won't get saved again with flag,
CurveModifierData *cmd = (CurveModifierData*) md; * still could be an issue with lib-linked mesh.
*/
cmd->object = newlibadr(fd, ob->id.lib, cmd->object); me->flag ^= ME_SUBSURF;
}
} }
} }
static void lib_link_object(FileData *fd, Main *main) static void lib_link_object(FileData *fd, Main *main)
{ {
ModifierData *md;
Object *ob; Object *ob;
bSensor *sens; bSensor *sens;
bController *cont; bController *cont;
@@ -2260,9 +2283,7 @@ static void lib_link_object(FileData *fd, Main *main)
hook->parent= newlibadr(fd, ob->id.lib, hook->parent); hook->parent= newlibadr(fd, ob->id.lib, hook->parent);
} }
for (md=ob->modifiers.first; md; md= md->next) { lib_link_modifiers(fd, ob);
lib_link_modifier_data(fd, ob, md);
}
} }
ob= ob->id.next; 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) static void direct_link_object(FileData *fd, Object *ob)
{ {
PartEff *paf; PartEff *paf;
@@ -2304,7 +2340,6 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->pose= newdataadr(fd, ob->pose); ob->pose= newdataadr(fd, ob->pose);
direct_link_pose(fd, ob->pose); direct_link_pose(fd, ob->pose);
link_list(fd, &ob->modifiers);
link_list(fd, &ob->defbase); link_list(fd, &ob->defbase);
link_list(fd, &ob->nlastrips); link_list(fd, &ob->nlastrips);
link_list(fd, &ob->constraintChannels); link_list(fd, &ob->constraintChannels);
@@ -2327,8 +2362,7 @@ static void direct_link_object(FileData *fd, Object *ob)
if(paf->type==EFF_BUILD) { if(paf->type==EFF_BUILD) {
BuildEff *baf = (BuildEff*) paf; BuildEff *baf = (BuildEff*) paf;
PartEff *next = paf->next; PartEff *next = paf->next;
ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Build); BuildModifierData *bmd = (BuildModifierData*) modifier_new(eModifierType_Build);
BuildModifierData *bmd = (BuildModifierData*) mti->allocData();
bmd->start = baf->sfra; bmd->start = baf->sfra;
bmd->length = baf->len; 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->bb= NULL;
ob->derivedDeform= 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!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */

View File

@@ -601,6 +601,10 @@ enum {
#define B_RECALCAL 3411 #define B_RECALCAL 3411
#define B_RECALC_DEFL 3412 #define B_RECALC_DEFL 3412
#define B_MDFR_BUTS 3600
#define B_MDFR_INCREMENTAl 3501
/* *********************** */ /* *********************** */
/* *********************** */ /* *********************** */

View File

@@ -36,7 +36,9 @@ typedef struct ModifierData {
typedef struct SubsurfModifierData { typedef struct SubsurfModifierData {
ModifierData modifier; ModifierData modifier;
short subdivType, levels, renderLevels, pad; short subdivType, levels, renderLevels, useIncrementalMesh;
void *emCache, *mCache;
} SubsurfModifierData; } SubsurfModifierData;
typedef struct LatticeModifierData { typedef struct LatticeModifierData {

View File

@@ -318,9 +318,12 @@ void do_butspace(unsigned short event)
do_uvautocalculationbuts(event); do_uvautocalculationbuts(event);
} }
else if(event<=B_EFFECTSBUTS) { else if(event<=B_EFFECTSBUTS) {
/*here we put the effects buttons do commands*/
do_effects_panels(event); 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, 1); // 1=do header too
else if(event>REDRAWVIEW3D) allqueue(event, 0); else if(event>REDRAWVIEW3D) allqueue(event, 0);
} }

View File

@@ -656,8 +656,6 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
{ {
uiBlock *block; uiBlock *block;
float val; 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); 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; 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"); 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); 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); 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"); uiDefButS(block, TOG|BIT|8, B_SUBSURFTYPE, "Optimal", 10, 94,154,19, &me->flag, 0, 0, 0, 0, "Only draws optimal wireframe");
uiBlockBeginAlign(block); uiBlockBeginAlign(block);

View File

@@ -1655,21 +1655,44 @@ static void object_softbodies(Object *ob)
static int actModifier = 0; static int actModifier = 0;
void do_modifier_panels(unsigned short event)
{
Object *ob = OBACT;
ModifierData *md;
int i;
for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
md = md->next;
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) static void modifiers_add(void *ob_v, int type)
{ {
Object *ob = ob_v; Object *ob = ob_v;
ModifierTypeInfo *mti = modifierType_get_info(type); BLI_addtail(&ob->modifiers, modifier_new(type));
if (mti) { actModifier = BLI_countlist(&ob->modifiers);
ModifierData *md = mti->allocData();
BLI_addtail(&ob->modifiers, md);
actModifier = BLI_countlist(&ob->modifiers); allqueue(REDRAWBUTSOBJECT, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSOBJECT, 0);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
} }
static uiBlock *modifier_add_menu(void *ob_v) static uiBlock *modifier_add_menu(void *ob_v)
@@ -1707,7 +1730,8 @@ static void modifiers_del(void *ob_v, void *arg2)
if (md) { if (md) {
BLI_remlink(&ob->modifiers, md); BLI_remlink(&ob->modifiers, md);
MEM_freeN(md);
modifier_free(md);
} }
allqueue(REDRAWBUTSOBJECT, 0); 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"; 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, "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, 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) { } else if (md->type==eModifierType_Lattice) {
LatticeModifierData *lmd = (LatticeModifierData*) md; LatticeModifierData *lmd = (LatticeModifierData*) md;
uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:", 550, 320, 120,19, &lmd->object, "Lattice object to deform with"); uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:", 550, 320, 120,19, &lmd->object, "Lattice object to deform with");

View File

@@ -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; Mesh *me = ob->data;
DerivedMesh *cageDM;
if(realDM && (me->flag&ME_OPT_EDGES)) {
cageDM = realDM;
} else {
cageDM = baseDM;
}
if(dt>OB_WIRE) { if(dt>OB_WIRE) {
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); 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); glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
if (realDM) { finalDM->drawFacesSolid(finalDM, set_gl_material);
realDM->drawFacesSolid(realDM, set_gl_material);
} else {
baseDM->drawFacesSolid(baseDM, set_gl_material);
}
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@@ -1693,9 +1682,9 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, Derived
glDepthMask(0); glDepthMask(0);
} }
else { else {
if (realDM && !(me->flag&ME_OPT_EDGES)) { if (cageDM!=finalDM) {
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); 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; int has_alpha= 0;
if(G.obedit && ob->data==G.obedit->data) { if(G.obedit && ob->data==G.obedit->data) {
DerivedMesh *baseDM = editmesh_get_derived_proxy(); int cageNeedsFree, finalNeedsFree;
DerivedMesh *realDM = editmesh_get_derived(); 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 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 { else {
BoundBox *bb = mesh_get_bb(me); BoundBox *bb = mesh_get_bb(me);

View File

@@ -500,16 +500,9 @@ void count_object(Object *ob, int sel)
if(me) { if(me) {
int totvert, totface; int totvert, totface;
/* note; do not make disp or get derived mesh here. spoils dependency order */ // XXX fixme for modifier stack
if (me->flag & ME_SUBSURF) { totvert= me->totvert;
/* approximate counts, about right for a mesh entirely made totface= me->totface;
* of quads and that is a closed 2-manifold.
*/
totvert= totface= me->totface*1<<(me->subdiv*2);
} else {
totvert= me->totvert;
totface= me->totface;
}
G.totvert+= totvert; G.totvert+= totvert;
G.totface+= totface; G.totface+= totface;

View File

@@ -451,9 +451,15 @@ void free_editMesh(EditMesh *em)
if(em->edges.first) free_edgelist(&em->edges); if(em->edges.first) free_edgelist(&em->edges);
if(em->faces.first) free_facelist(&em->faces); if(em->faces.first) free_facelist(&em->faces);
if(em->derived) { if(em->derivedFinal) {
em->derived->release(em->derived); if (em->derivedFinal!=em->derivedCage) {
em->derived= NULL; 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 */ /* 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); if(actkey && actkey->totelem!=me->totvert);
else { else {
unsigned int *mcol; unsigned int *mcol;
@@ -779,7 +785,7 @@ void make_editMesh()
MEM_freeN(evlist); MEM_freeN(evlist);
end_editmesh_fastmalloc(); // resets global function pointers end_editmesh_fastmalloc(); // resets global function pointers
/* this creates coherent selections. also needed for older files */ /* this creates coherent selections. also needed for older files */
EM_selectmode_set(); EM_selectmode_set();
/* paranoia check to enforce hide rules */ /* paranoia check to enforce hide rules */
@@ -1388,7 +1394,7 @@ void separate_mesh(void)
emcopy.allverts= NULL; emcopy.allverts= NULL;
emcopy.alledges= NULL; emcopy.alledges= NULL;
emcopy.allfaces= NULL; emcopy.allfaces= NULL;
emcopy.derived= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL;
free_editMesh(&emcopy); free_editMesh(&emcopy);
em->verts= edve; em->verts= edve;
@@ -1554,7 +1560,7 @@ void separate_mesh_loose(void)
emcopy.allverts= NULL; emcopy.allverts= NULL;
emcopy.alledges= NULL; emcopy.alledges= NULL;
emcopy.allfaces= NULL; emcopy.allfaces= NULL;
emcopy.derived= NULL; emcopy.derivedFinal= emcopy.derivedCage= NULL;
free_editMesh(&emcopy); free_editMesh(&emcopy);
em->verts= edve; em->verts= edve;