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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/BKE_multires.h20
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c212
-rw-r--r--source/blender/blenkernel/intern/customdata.c8
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c95
-rw-r--r--source/blender/blenkernel/intern/multires.c1396
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/editors/object/object_modifier.c13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c10
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c64
15 files changed, 582 insertions, 1276 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 245db7e35ff..3018f89178e 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -228,7 +228,7 @@ typedef struct ModifierTypeInfo {
*
* This function is optional (assumes never disabled if not present).
*/
- int (*isDisabled)(struct ModifierData *md);
+ int (*isDisabled)(struct ModifierData *md, int userRenderParams);
/* Add the appropriate relations to the DEP graph depending on the
* modifier data.
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index a331479cad1..53ead3a5eda 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -39,23 +39,6 @@ typedef struct MultiresSubsurf {
int local_mmd;
} MultiresSubsurf;
-/* MultiresDM */
-struct Object *MultiresDM_get_object(struct DerivedMesh *dm);
-struct Mesh *MultiresDM_get_mesh(struct DerivedMesh *dm);
-struct DerivedMesh *MultiresDM_new(struct MultiresSubsurf *, struct DerivedMesh*, int, int, int);
-void *MultiresDM_get_vertnorm(struct DerivedMesh *);
-void *MultiresDM_get_orco(struct DerivedMesh *);
-struct MVert *MultiresDM_get_subco(struct DerivedMesh *);
-struct ListBase *MultiresDM_get_vert_face_map(struct DerivedMesh *);
-struct ListBase *MultiresDM_get_vert_edge_map(struct DerivedMesh *);
-int *MultiresDM_get_face_offsets(struct DerivedMesh *);
-int MultiresDM_get_totlvl(struct DerivedMesh *);
-int MultiresDM_get_lvl(struct DerivedMesh *);
-void MultiresDM_set_update(struct DerivedMesh *, void (*)(struct DerivedMesh*));
-
-/* The displacements will only be updated when
- the MultiresDM has been marked as modified */
-void MultiresDM_mark_as_modified(struct DerivedMesh *);
void multires_mark_as_modified(struct Object *ob);
void multires_force_update(struct Object *ob);
@@ -64,10 +47,9 @@ struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*
struct Object *, int, int);
struct MultiresModifierData *find_multires_modifier(struct Object *ob);
-int multiresModifier_switch_level(struct Object *, const int);
void multiresModifier_join(struct Object *);
void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);
-void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int distance,
+void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob,
int updateblock, int simple);
int multiresModifier_reshape(struct MultiresModifierData *mmd, struct Object *dst, struct Object *src);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 5a911fcb13b..b715b1531de 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1535,7 +1535,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
md->scene= scene;
if (!(md->mode&eModifierMode_Realtime)) return NULL;
- if (mti->isDisabled && mti->isDisabled(md)) return NULL;
+ if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
if (mti->type==eModifierTypeType_OnlyDeform) {
int numVerts;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 3007564e333..b3e75549028 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1810,215 +1810,3 @@ MFace *CDDM_get_faces(DerivedMesh *dm)
return ((CDDerivedMesh*)dm)->mface;
}
-/* Multires DerivedMesh, extends CDDM */
-typedef struct MultiresDM {
- CDDerivedMesh cddm;
-
- MultiresModifierData *mmd;
- int local_mmd;
-
- int lvl, totlvl;
- float (*orco)[3];
- MVert *subco;
-
- ListBase *vert_face_map, *vert_edge_map;
- IndexNode *vert_face_map_mem, *vert_edge_map_mem;
- int *face_offsets;
-
- Object *ob;
- int modified;
-
- void (*update)(DerivedMesh*);
-} MultiresDM;
-
-static void MultiresDM_release(DerivedMesh *dm)
-{
- MultiresDM *mrdm = (MultiresDM*)dm;
- int mvert_layer;
-
- /* Before freeing, need to update the displacement map */
- if(dm->needsFree && mrdm->modified) {
- /* Check that mmd still exists */
- if(!mrdm->local_mmd && BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0)
- mrdm->mmd = NULL;
- if(mrdm->mmd)
- mrdm->update(dm);
- }
-
- /* If the MVert data is being used as the sculpt undo store, don't free it */
- mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
- if(mvert_layer != -1) {
- CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
- if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts)
- cd->flag |= CD_FLAG_NOFREE;
- }
-
- if(DM_release(dm)) {
- cdDM_free_internal(&mrdm->cddm);
- MEM_freeN(mrdm->subco);
- MEM_freeN(mrdm->orco);
- if(mrdm->vert_face_map)
- MEM_freeN(mrdm->vert_face_map);
- if(mrdm->vert_face_map_mem)
- MEM_freeN(mrdm->vert_face_map_mem);
- if(mrdm->vert_edge_map)
- MEM_freeN(mrdm->vert_edge_map);
- if(mrdm->vert_edge_map_mem)
- MEM_freeN(mrdm->vert_edge_map_mem);
- if(mrdm->face_offsets)
- MEM_freeN(mrdm->face_offsets);
- MEM_freeN(mrdm);
- }
-}
-
-DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
-{
- MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
- CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
- DerivedMesh *dm = NULL;
-
- mrdm->cddm = *cddm;
- MEM_freeN(cddm);
- dm = &mrdm->cddm.dm;
-
- mrdm->mmd = ms->mmd;
- mrdm->ob = ms->ob;
- mrdm->local_mmd = ms->local_mmd;
-
- if(dm) {
- MDisps *disps;
- MVert *mvert;
- int i;
-
- DM_from_template(dm, orig, numVerts, numEdges, numFaces);
- CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
-
- disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
- if(disps)
- CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
-
-
- mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
- mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
- for(i = 0; i < orig->getNumVerts(orig); ++i)
- copy_v3_v3(mrdm->orco[i], mvert[i].co);
- }
- else
- DM_init(dm, numVerts, numEdges, numFaces);
-
- if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
- CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
- if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
- CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
- if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
- CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
-
- CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
- CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
- CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
-
- mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
- mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
- mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
-
- mrdm->lvl = ms->mmd->lvl;
- mrdm->totlvl = ms->mmd->totlvl;
- mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
- mrdm->modified = 0;
-
- dm->release = MultiresDM_release;
-
- return dm;
-}
-
-Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
-{
- return get_mesh(((MultiresDM*)dm)->ob);
-}
-
-Object *MultiresDM_get_object(DerivedMesh *dm)
-{
- return ((MultiresDM*)dm)->ob;
-}
-
-void *MultiresDM_get_orco(DerivedMesh *dm)
-{
- return ((MultiresDM*)dm)->orco;
-
-}
-
-MVert *MultiresDM_get_subco(DerivedMesh *dm)
-{
- return ((MultiresDM*)dm)->subco;
-}
-
-int MultiresDM_get_totlvl(DerivedMesh *dm)
-{
- return ((MultiresDM*)dm)->totlvl;
-}
-
-int MultiresDM_get_lvl(DerivedMesh *dm)
-{
- return ((MultiresDM*)dm)->lvl;
-}
-
-void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
-{
- ((MultiresDM*)dm)->orco = orco;
-}
-
-void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
-{
- ((MultiresDM*)dm)->update = update;
-}
-
-ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
-{
- MultiresDM *mrdm = (MultiresDM*)dm;
- Mesh *me = mrdm->ob->data;
-
- if(!mrdm->vert_face_map)
- create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface,
- me->totvert, me->totface);
-
- return mrdm->vert_face_map;
-}
-
-ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
-{
- MultiresDM *mrdm = (MultiresDM*)dm;
- Mesh *me = mrdm->ob->data;
-
- if(!mrdm->vert_edge_map)
- create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge,
- me->totvert, me->totedge);
-
- return mrdm->vert_edge_map;
-}
-
-int *MultiresDM_get_face_offsets(DerivedMesh *dm)
-{
- MultiresDM *mrdm = (MultiresDM*)dm;
- Mesh *me = mrdm->ob->data;
- int i, accum = 0;
-
- if(!mrdm->face_offsets) {
- int len = (int)pow(2, mrdm->lvl - 2) - 1;
- int area = len * len;
- int t = 1 + len * 3 + area * 3, q = t + len + area;
-
- mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets");
- for(i = 0; i < me->totface; ++i) {
- mrdm->face_offsets[i] = accum;
-
- accum += (me->mface[i].v4 ? q : t);
- }
- }
-
- return mrdm->face_offsets;
-}
-
-void MultiresDM_mark_as_modified(DerivedMesh *dm)
-{
- ((MultiresDM*)dm)->modified = 1;
-}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 7b754025b6c..4844595513f 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -381,6 +381,7 @@ static void layerDefault_origspace_face(void *data, int count)
osf[i] = default_osf;
}
+#if 0
/* Adapted from sculptmode.c */
static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
{
@@ -426,9 +427,12 @@ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, fl
add_v3_v3v3(out, d2[0], d2[1]);
}
+#endif
static void layerSwap_mdisps(void *data, int *ci)
{
+ // XXX
+#if 0
MDisps *s = data;
float (*d)[3] = NULL;
int x, y, st;
@@ -447,11 +451,14 @@ static void layerSwap_mdisps(void *data, int *ci)
if(s->disps)
MEM_freeN(s->disps);
s->disps = d;
+#endif
}
static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
int count, void *dest)
{
+ // XXX
+#if 0
MDisps *d = dest;
MDisps *s = NULL;
int st, stl;
@@ -496,6 +503,7 @@ static void layerInterp_mdisps(void **sources, float *weights, float *sub_weight
copy_v3_v3(d->disps[y * st + x], srcdisp);
}
}
+#endif
}
static void layerCopy_mdisps(const void *source, void *dest, int count)
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 48fb283c404..b35cf917895 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1225,7 +1225,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if ((md->mode & required_mode) != required_mode) continue;
- if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
preTesselatePoint = md;
@@ -1275,7 +1275,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
md->scene= scene;
if ((md->mode & required_mode) != required_mode) continue;
- if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform) continue;
if (!deformedVerts) {
@@ -1330,7 +1330,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
md->scene= scene;
if ((md->mode & required_mode) != required_mode) continue;
- if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
/* need to put all verts in 1 block for curve deform */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index dc548edbb25..e963b2e9fb6 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -1002,7 +1002,7 @@ void lattice_calc_modifiers(Scene *scene, Object *ob)
if (!(md->mode&eModifierMode_Realtime)) continue;
if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
- if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
if (mti->type!=eModifierTypeType_OnlyDeform) continue;
if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 50c907fd1ca..d8c05c30cfe 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -187,7 +187,7 @@ static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)
/***/
-static int noneModifier_isDisabled(ModifierData *md)
+static int noneModifier_isDisabled(ModifierData *md, int userRenderParams)
{
return 1;
}
@@ -222,7 +222,7 @@ static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *m
return dataMask;
}
-static int curveModifier_isDisabled(ModifierData *md)
+static int curveModifier_isDisabled(ModifierData *md, int userRenderParams)
{
CurveModifierData *cmd = (CurveModifierData*) md;
@@ -298,7 +298,7 @@ static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData
return dataMask;
}
-static int latticeModifier_isDisabled(ModifierData *md)
+static int latticeModifier_isDisabled(ModifierData *md, int userRenderParams)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -402,6 +402,13 @@ static void subsurfModifier_freeData(ModifierData *md)
}
}
+static int subsurfModifier_isDisabled(ModifierData *md, int useRenderParams)
+{
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+ return (useRenderParams)? (smd->renderLevels == 0): (smd->levels == 0);
+}
+
static DerivedMesh *subsurfModifier_applyModifier(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
int useRenderParams, int isFinalCalc)
@@ -410,8 +417,13 @@ static DerivedMesh *subsurfModifier_applyModifier(
DerivedMesh *result;
result = subsurf_make_derived_from_derived(derivedData, smd,
- useRenderParams, NULL,
- isFinalCalc, 0);
+ useRenderParams, NULL, isFinalCalc, 0);
+
+ if(useRenderParams || !isFinalCalc) {
+ DerivedMesh *cddm= CDDM_copy(result);
+ result->release(result);
+ result= cddm;
+ }
return result;
}
@@ -3524,7 +3536,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob,
displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
-static int displaceModifier_isDisabled(ModifierData *md)
+static int displaceModifier_isDisabled(ModifierData *md, int useRenderParams)
{
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
@@ -4268,7 +4280,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
}
-static int smoothModifier_isDisabled(ModifierData *md)
+static int smoothModifier_isDisabled(ModifierData *md, int useRenderParams)
{
SmoothModifierData *smd = (SmoothModifierData*) md;
short flag;
@@ -4498,7 +4510,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
}
-static int castModifier_isDisabled(ModifierData *md)
+static int castModifier_isDisabled(ModifierData *md, int useRenderParams)
{
CastModifierData *cmd = (CastModifierData*) md;
short flag;
@@ -5487,7 +5499,7 @@ static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData
return dataMask;
}
-static int armatureModifier_isDisabled(ModifierData *md)
+static int armatureModifier_isDisabled(ModifierData *md, int useRenderParams)
{
ArmatureModifierData *amd = (ArmatureModifierData*) md;
@@ -5610,7 +5622,7 @@ static void hookModifier_freeData(ModifierData *md)
if (hmd->indexar) MEM_freeN(hmd->indexar);
}
-static int hookModifier_isDisabled(ModifierData *md)
+static int hookModifier_isDisabled(ModifierData *md, int useRenderParams)
{
HookModifierData *hmd = (HookModifierData*) md;
@@ -6308,7 +6320,7 @@ static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
tbmd->operation = bmd->operation;
}
-static int booleanModifier_isDisabled(ModifierData *md)
+static int booleanModifier_isDisabled(ModifierData *md, int useRenderParams)
{
BooleanModifierData *bmd = (BooleanModifierData*) md;
@@ -7757,7 +7769,7 @@ static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierDa
return dataMask;
}
-static int meshdeformModifier_isDisabled(ModifierData *md)
+static int meshdeformModifier_isDisabled(ModifierData *md, int useRenderParams)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
@@ -8047,15 +8059,10 @@ static void multiresModifier_initData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
- mmd->lvl = mmd->totlvl = 1;
-}
-
-static void multiresModifier_freeData(ModifierData *md)
-{
- MultiresModifierData *mmd = (MultiresModifierData*)md;
-
- if(mmd->undo_verts)
- MEM_freeN(mmd->undo_verts);
+ mmd->lvl = 0;
+ mmd->sculptlvl = 0;
+ mmd->renderlvl = 0;
+ mmd->totlvl = 0;
}
static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
@@ -8063,37 +8070,35 @@ static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
MultiresModifierData *mmd = (MultiresModifierData*) md;
MultiresModifierData *tmmd = (MultiresModifierData*) target;
- tmmd->totlvl = mmd->totlvl;
tmmd->lvl = mmd->lvl;
+ tmmd->sculptlvl = mmd->sculptlvl;
+ tmmd->renderlvl = mmd->renderlvl;
+ tmmd->totlvl = mmd->totlvl;
}
static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
int useRenderParams, int isFinalCalc)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
- DerivedMesh *final;
+ DerivedMesh *result;
- /* TODO: for now just skip a level1 mesh */
- if(mmd->lvl == 1)
- return dm;
+ result = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
- final = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
- if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
- int i;
- MVert *dst = CDDM_get_verts(final);
- for(i = 0; i < mmd->undo_verts_tot; ++i) {
- copy_v3_v3(dst[i].co, mmd->undo_verts[i].co);
- }
- CDDM_calc_normals(final);
-
- MultiresDM_mark_as_modified(final);
+ if(result == dm)
+ return dm;
- MEM_freeN(mmd->undo_verts);
- mmd->undo_signal = 0;
- mmd->undo_verts = NULL;
+ if(useRenderParams || !isFinalCalc) {
+ DerivedMesh *cddm= CDDM_copy(result);
+ result->release(result);
+ result= cddm;
+ }
+ else if(ob->mode & OB_MODE_SCULPT) {
+ /* would be created on the fly too, just nicer this
+ way on first stroke after e.g. switching levels */
+ result->getPBVH(ob, result);
}
- return final;
+ return result;
}
/* Shrinkwrap */
@@ -8142,7 +8147,7 @@ static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierDa
return dataMask;
}
-static int shrinkwrapModifier_isDisabled(ModifierData *md)
+static int shrinkwrapModifier_isDisabled(ModifierData *md, int useRenderParams)
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
return !smd->target;
@@ -8438,6 +8443,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->initData = subsurfModifier_initData;
mti->copyData = subsurfModifier_copyData;
mti->freeData = subsurfModifier_freeData;
+ mti->isDisabled = subsurfModifier_isDisabled;
mti->applyModifier = subsurfModifier_applyModifier;
mti->applyModifierEM = subsurfModifier_applyModifierEM;
@@ -8770,7 +8776,6 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
mti->initData = multiresModifier_initData;
- mti->freeData = multiresModifier_freeData;
mti->copyData = multiresModifier_copyData;
mti->applyModifier = multiresModifier_applyModifier;
@@ -8920,7 +8925,7 @@ int modifier_couldBeCage(ModifierData *md)
return ( (md->mode & eModifierMode_Realtime) &&
(md->mode & eModifierMode_Editmode) &&
- (!mti->isDisabled || !mti->isDisabled(md)) &&
+ (!mti->isDisabled || !mti->isDisabled(md, 0)) &&
modifier_supportsMapping(md));
}
@@ -8957,7 +8962,7 @@ int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual
if (!(md->mode & eModifierMode_Realtime)) continue;
if (!(md->mode & eModifierMode_Editmode)) continue;
- if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
if (md->mode & eModifierMode_DisableTemporary) continue;
@@ -8999,7 +9004,7 @@ int modifier_isEnabled(ModifierData *md, int required_mode)
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if((md->mode & required_mode) != required_mode) return 0;
- if(mti->isDisabled && mti->isDisabled(md)) return 0;
+ if(mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return 0;
if(md->mode & eModifierMode_DisableTemporary) return 0;
if(required_mode & eModifierMode_Editmode)
if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index fc14afaf07f..2518d4bc3ca 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -40,6 +40,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BKE_btex.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
@@ -50,14 +51,19 @@
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_subsurf.h"
+#include "BKE_utildefines.h"
+
+#include "CCGSubSurf.h"
#include <math.h>
#include <string.h>
/* MULTIRES MODIFIER */
static const int multires_max_levels = 13;
-static const int multires_quad_tot[] = {4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
-static const int multires_side_tot[] = {2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097};
+static const int multires_grid_tot[] = {1, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409};
+static const int multires_side_tot[] = {1, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097};
+
+static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl);
MultiresModifierData *find_multires_modifier(Object *ob)
{
@@ -72,23 +78,32 @@ MultiresModifierData *find_multires_modifier(Object *ob)
}
return mmd;
+}
+static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render)
+{
+ if(render)
+ return mmd->renderlvl;
+ else if(ob->mode == OB_MODE_SCULPT)
+ return mmd->sculptlvl;
+ else
+ return mmd->lvl;
}
-int multiresModifier_switch_level(Object *ob, const int distance)
+static void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
{
- MultiresModifierData *mmd = find_multires_modifier(ob);
-
- if(mmd) {
- mmd->lvl += distance;
- if(mmd->lvl < 1) mmd->lvl = 1;
- else if(mmd->lvl > mmd->totlvl) mmd->lvl = mmd->totlvl;
- /* XXX: DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
- object_handle_update(ob);*/
- return 1;
+ mmd->totlvl = lvl;
+
+ if(ob->mode != OB_MODE_SCULPT) {
+ mmd->lvl = MAX2(mmd->lvl, lvl);
+ CLAMP(mmd->lvl, 0, mmd->totlvl);
}
- else
- return 0;
+
+ mmd->sculptlvl = MAX2(mmd->sculptlvl, lvl);
+ CLAMP(mmd->sculptlvl, 0, mmd->totlvl);
+
+ mmd->renderlvl = MAX2(mmd->renderlvl, lvl);
+ CLAMP(mmd->renderlvl, 0, mmd->totlvl);
}
/* XXX */
@@ -156,6 +171,8 @@ void multiresModifier_join(Object *ob)
/* Returns 0 on success, 1 if the src's totvert doesn't match */
int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src)
{
+ /* XXX */
+#if 0
Mesh *src_me = get_mesh(src);
DerivedMesh *mrdm = dst->derivedFinal;
@@ -172,319 +189,139 @@ int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src
return 0;
}
+#endif
return 1;
}
-static void Mat3FromColVecs(float mat[][3], float v1[3], float v2[3], float v3[3])
+static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3])
{
copy_v3_v3(mat[0], v1);
copy_v3_v3(mat[1], v2);
copy_v3_v3(mat[2], v3);
}
-static DerivedMesh *multires_subdisp_pre(DerivedMesh *mrdm, int distance, int simple)
+static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB)
{
- DerivedMesh *final;
- SubsurfModifierData smd;
-
- memset(&smd, 0, sizeof(SubsurfModifierData));
- smd.levels = distance;
- if(simple)
- smd.subdivType = ME_SIMPLE_SUBSURF;
+ int x, y, j, skip;
- final = NULL; // XXX subsurf_make_derived_from_derived_with_multires(mrdm, &smd, NULL, 0, NULL, 0, 0);
+ if(sizeA > sizeB) {
+ skip = (sizeA-1)/(sizeB-1);
- return final;
-}
+ for(j = 0, y = 0; y < sizeB; y++)
+ for(x = 0; x < sizeB; x++, j++)
+ copy_v3_v3(gridA[y*skip*sizeA + x*skip], gridB[j]);
+ }
+ else {
+ skip = (sizeB-1)/(sizeA-1);
-static void VecAddUf(float a[3], float b[3])
-{
- a[0] += b[0];
- a[1] += b[1];
- a[2] += b[2];
+ for(j = 0, y = 0; y < sizeA; y++)
+ for(x = 0; x < sizeA; x++, j++)
+ copy_v3_v3(gridA[j], gridB[y*skip*sizeB + x*skip]);
+ }
}
-static void multires_subdisp(DerivedMesh *orig, Object *ob, DerivedMesh *final, int lvl, int totlvl,
- int totsubvert, int totsubedge, int totsubface, int addverts)
+static void multires_copy_dm_grid(DMGridData *gridA, DMGridData *gridB, int sizeA, int sizeB)
{
- DerivedMesh *mrdm;
- Mesh *me = ob->data;
- MultiresModifierData mmd_sub;
- MVert *mvs = CDDM_get_verts(final);
- MVert *mvd, *mvd_f1, *mvs_f1, *mvd_f3, *mvd_f4;
- MVert *mvd_f2, *mvs_f2, *mvs_e1, *mvd_e1, *mvs_e2;
- int totvert;
- int slo1 = multires_side_tot[lvl - 1];
- int sll = slo1 / 2;
- int slo2 = multires_side_tot[totlvl - 2];
- int shi2 = multires_side_tot[totlvl - 1];
- int skip = multires_side_tot[totlvl - lvl] - 1;
- int i, j, k;
-
- memset(&mmd_sub, 0, sizeof(MultiresModifierData));
- mmd_sub.lvl = mmd_sub.totlvl = totlvl;
- mrdm = multires_dm_create_from_derived(&mmd_sub, 1, orig, ob, 0, 0);
-
- mvd = CDDM_get_verts(mrdm);
- /* Need to map from ccg to mrdm */
- totvert = mrdm->getNumVerts(mrdm);
-
- if(!addverts) {
- for(i = 0; i < totvert; ++i) {
- float z[3] = {0,0,0};
- copy_v3_v3(mvd[i].co, z);
- }
- }
-
- /* Load base verts */
- for(i = 0; i < me->totvert; ++i)
- VecAddUf(mvd[totvert - me->totvert + i].co, mvs[totvert - me->totvert + i].co);
-
- mvd_f1 = mvd;
- mvs_f1 = mvs;
- mvd_f2 = mvd;
- mvs_f2 = mvs + totvert - totsubvert;
- mvs_e1 = mvs + totsubface * (skip-1) * (skip-1);
-
- for(i = 0; i < me->totface; ++i) {
- const int end = me->mface[i].v4 ? 4 : 3;
- int x, y, x2, y2, mov= 0;
-
- mvd_f1 += 1 + end * (slo2-2); //center+edgecross
- mvd_f3 = mvd_f4 = mvd_f1;
-
- for(j = 0; j < end; ++j) {
- mvd_f1 += (skip/2 - 1) * (slo2 - 2) + (skip/2 - 1);
- /* Update sub faces */
- for(y = 0; y < sll; ++y) {
- for(x = 0; x < sll; ++x) {
- /* Face center */
- VecAddUf(mvd_f1->co, mvs_f1->co);
- mvs_f1 += 1;
-
- /* Now we hold the center of the subface at mvd_f1
- and offset it to the edge cross and face verts */
-
- /* Edge cross */
- for(k = 0; k < 4; ++k) {
- if(k == 0) mov = -1;
- else if(k == 1) mov = slo2 - 2;
- else if(k == 2) mov = 1;
- else if(k == 3) mov = -(slo2 - 2);
-
- for(x2 = 1; x2 < skip/2; ++x2) {
- VecAddUf((mvd_f1 + mov * x2)->co, mvs_f1->co);
- ++mvs_f1;
- }
- }
+ int x, y, j, skip;
- /* Main face verts */
- for(k = 0; k < 4; ++k) {
- int movx= 0, movy= 0;
-
- if(k == 0) { movx = -1; movy = -(slo2 - 2); }
- else if(k == 1) { movx = slo2 - 2; movy = -1; }
- else if(k == 2) { movx = 1; movy = slo2 - 2; }
- else if(k == 3) { movx = -(slo2 - 2); movy = 1; }
-
- for(y2 = 1; y2 < skip/2; ++y2) {
- for(x2 = 1; x2 < skip/2; ++x2) {
- VecAddUf((mvd_f1 + movy * y2 + movx * x2)->co, mvs_f1->co);
- ++mvs_f1;
- }
- }
- }
-
- mvd_f1 += skip;
- }
- mvd_f1 += (skip - 1) * (slo2 - 2) - 1;
- }
- mvd_f1 -= (skip - 1) * (slo2 - 2) - 1 + skip;
- mvd_f1 += (slo2 - 2) * (skip/2-1) + skip/2-1 + 1;
- }
-
- /* update face center verts */
- VecAddUf(mvd_f2->co, mvs_f2->co);
-
- mvd_f2 += 1;
- mvs_f2 += 1;
-
- /* update face edge verts */
- for(j = 0; j < end; ++j) {
- MVert *restore;
-
- /* Super-face edge cross */
- for(k = 0; k < skip-1; ++k) {
- VecAddUf(mvd_f2->co, mvs_e1->co);
- mvd_f2++;
- mvs_e1++;
- }
- for(x = 1; x < sll; ++x) {
- VecAddUf(mvd_f2->co, mvs_f2->co);
- mvd_f2++;
- mvs_f2++;
-
- for(k = 0; k < skip-1; ++k) {
- VecAddUf(mvd_f2->co, mvs_e1->co);
- mvd_f2++;
- mvs_e1++;
- }
- }
-
- restore = mvs_e1;
- for(y = 0; y < sll - 1; ++y) {
- for(x = 0; x < sll; ++x) {
- for(k = 0; k < skip - 1; ++k) {
- VecAddUf(mvd_f3[(skip-1)+(y*skip) + (x*skip+k)*(slo2-2)].co,
- mvs_e1->co);
- ++mvs_e1;
- }
- mvs_e1 += skip-1;
- }
- }
-
- mvs_e1 = restore + skip - 1;
- for(y = 0; y < sll - 1; ++y) {
- for(x = 0; x < sll; ++x) {
- for(k = 0; k < skip - 1; ++k) {
- VecAddUf(mvd_f3[(slo2-2)*(skip-1)+(x*skip)+k + y*skip*(slo2-2)].co,
- mvs_e1->co);
- ++mvs_e1;
- }
- mvs_e1 += skip - 1;
- }
- }
-
- mvd_f3 += (slo2-2)*(slo2-2);
- mvs_e1 -= skip - 1;
- }
+ if(sizeA > sizeB) {
+ skip = (sizeA-1)/(sizeB-1);
- /* update base (2) face verts */
- for(j = 0; j < end; ++j) {
- mvd_f2 += (slo2 - 1) * (skip - 1);
- for(y = 0; y < sll - 1; ++y) {
- for(x = 0; x < sll - 1; ++x) {
- VecAddUf(mvd_f2->co, mvs_f2->co);
- mvd_f2 += skip;
- ++mvs_f2;
- }
- mvd_f2 += (slo2 - 1) * (skip - 1);
- }
- mvd_f2 -= (skip - 1);
- }
+ for(j = 0, y = 0; y < sizeB; y++)
+ for(x = 0; x < sizeB; x++, j++)
+ copy_v3_v3(gridA[y*skip*sizeA + x*skip].co, gridB[j].co);
}
+ else {
+ skip = (sizeB-1)/(sizeA-1);
- /* edges */
- mvd_e1 = mvd + totvert - me->totvert - me->totedge * (shi2-2);
- mvs_e2 = mvs + totvert - me->totvert - me->totedge * (slo1-2);
- for(i = 0; i < me->totedge; ++i) {
- for(j = 0; j < skip - 1; ++j) {
- VecAddUf(mvd_e1->co, mvs_e1->co);
- mvd_e1++;
- mvs_e1++;
- }
- for(j = 0; j < slo1 - 2; j++) {
- VecAddUf(mvd_e1->co, mvs_e2->co);
- mvd_e1++;
- mvs_e2++;
-
- for(k = 0; k < skip - 1; ++k) {
- VecAddUf(mvd_e1->co, mvs_e1->co);
- mvd_e1++;
- mvs_e1++;
- }
- }
+ for(j = 0, y = 0; y < sizeA; y++)
+ for(x = 0; x < sizeA; x++, j++)
+ copy_v3_v3(gridA[j].co, gridB[y*skip*sizeB + x*skip].co);
}
-
- final->needsFree = 1;
- final->release(final);
- mrdm->needsFree = 1;
- MultiresDM_mark_as_modified(mrdm);
- mrdm->release(mrdm);
}
/* direction=1 for delete higher, direction=0 for lower (not implemented yet) */
void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Object *ob, int direction)
{
Mesh *me = get_mesh(ob);
- int distance = mmd->totlvl - mmd->lvl;
- MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ int lvl = multires_get_level(ob, mmd, 0);
+ int levels = mmd->totlvl - lvl;
+ MDisps *mdisps;
+
+ // XXX CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
+ mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS);
multires_force_update(ob);
- if(mdisps && distance > 0 && direction == 1) {
- int skip = multires_side_tot[distance] - 1;
- int st = multires_side_tot[mmd->totlvl - 1];
- int totdisp = multires_quad_tot[mmd->lvl - 1];
- int i, j, x, y;
+ if(mdisps && levels > 0 && direction == 1) {
+ int nsize = multires_side_tot[lvl];
+ int hsize = multires_side_tot[mmd->totlvl];
+ int i;
for(i = 0; i < me->totface; ++i) {
- float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires del disps");
-
- for(j = 0, y = 0; y < st; y += skip) {
- for(x = 0; x < st; x += skip) {
- copy_v3_v3(disps[j], mdisps[i].disps[y * st + x]);
- ++j;
- }
+ MDisps *mdisp= &mdisps[i];
+ float (*disps)[3], (*ndisps)[3], (*hdisps)[3];
+ int nvert = (me->mface[i].v4)? 4: 3;
+ int totdisp = multires_grid_tot[lvl]*nvert;
+ int S;
+
+ disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
+
+ ndisps = disps;
+ hdisps = mdisp->disps;
+
+ for(S = 0; S < nvert; S++) {
+ multires_copy_grid(ndisps, hdisps, nsize, hsize);
+
+ ndisps += nsize*nsize;
+ hdisps += hsize*hsize;
}
- MEM_freeN(mdisps[i].disps);
- mdisps[i].disps = disps;
- mdisps[i].totdisp = totdisp;
+ MEM_freeN(mdisp->disps);
+ mdisp->disps = disps;
+ mdisp->totdisp = totdisp;
}
}
- mmd->totlvl = mmd->lvl;
+ multires_set_tot_level(ob, mmd, lvl);
}
-void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int distance, int updateblock, int simple)
+static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple)
{
- DerivedMesh *final = NULL;
- int totsubvert = 0, totsubface = 0, totsubedge = 0;
- Mesh *me = get_mesh(ob);
- MDisps *mdisps;
- int i;
+ MultiresModifierData mmd;
- if(distance == 0)
- return;
+ memset(&mmd, 0, sizeof(MultiresModifierData));
+ mmd.lvl = lvl;
+ mmd.sculptlvl = lvl;
+ mmd.renderlvl = lvl;
+ mmd.totlvl = totlvl;
+ mmd.simple = simple;
- if(mmd->totlvl > multires_max_levels)
- mmd->totlvl = multires_max_levels;
- if(mmd->lvl > multires_max_levels)
- mmd->lvl = multires_max_levels;
+ return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0);
+}
- multires_force_update(ob);
+static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple)
+{
+ SubsurfModifierData smd;
- mmd->lvl = mmd->totlvl;
- mmd->totlvl += distance;
+ memset(&smd, 0, sizeof(SubsurfModifierData));
+ smd.levels = smd.renderLevels = lvl;
+ smd.flags |= eSubsurfModifierFlag_SubsurfUv;
+ if(simple)
+ smd.subdivType = ME_SIMPLE_SUBSURF;
- mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
- if(!mdisps)
- mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
+ return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0);
+}
- if(mdisps->disps && !updateblock && mmd->totlvl > 2) {
- DerivedMesh *orig, *mrdm;
- MultiresModifierData mmd_sub;
-
- orig = CDDM_from_mesh(me, NULL);
- memset(&mmd_sub, 0, sizeof(MultiresModifierData));
- mmd_sub.lvl = mmd_sub.totlvl = mmd->lvl;
- mmd_sub.simple = simple;
- mrdm = multires_dm_create_from_derived(&mmd_sub, 1, orig, ob, 0, 0);
- totsubvert = mrdm->getNumVerts(mrdm);
- totsubedge = mrdm->getNumEdges(mrdm);
- totsubface = mrdm->getNumFaces(mrdm);
- orig->needsFree = 1;
- orig->release(orig);
-
- final = multires_subdisp_pre(mrdm, distance, simple);
- mrdm->needsFree = 1;
- mrdm->release(mrdm);
- }
+static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
+{
+ int i;
+ /* reallocate displacements to be filled in */
for(i = 0; i < me->totface; ++i) {
- const int totdisp = multires_quad_tot[mmd->totlvl - 1];
+ int nvert = (me->mface[i].v4)? 4: 3;
+ int totdisp = multires_grid_tot[lvl]*nvert;
float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
if(mdisps[i].disps)
@@ -493,732 +330,353 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int dista
mdisps[i].disps = disps;
mdisps[i].totdisp = totdisp;
}
-
-
- if(final) {
- DerivedMesh *orig;
-
- orig = CDDM_from_mesh(me, NULL);
-
- multires_subdisp(orig, ob, final, mmd->lvl, mmd->totlvl, totsubvert, totsubedge, totsubface, 0);
-
- orig->needsFree = 1;
- orig->release(orig);
- }
-
- mmd->lvl = mmd->totlvl;
}
-typedef struct DisplacerEdges {
- /* DerivedMesh index at the start of each edge (using face x/y directions to define the start) */
- int base[4];
- /* 1 if edge moves in the positive x or y direction, -1 otherwise */
- int dir[4];
-} DisplacerEdges;
-
-typedef struct DisplacerSpill {
- /* Index of face (in base mesh), -1 for none */
- int face;
-
- /* Spill flag */
- /* 1 = Negative variable axis */
- /* 2 = Near fixed axis */
- /* 4 = Flip axes */
- int f;
-
- /* Neighboring edges */
- DisplacerEdges edges;
-} DisplacerSpill;
-
-typedef struct MultiresDisplacer {
- Mesh *me;
- MDisps *grid;
- MFace *face;
-
- int dm_first_base_vert_index;
-
- int spacing;
- int sidetot, interior_st, disp_st;
- int sidendx;
- int type;
- int invert;
- MVert *subco;
- int subco_index, face_index;
- float weight;
-
- /* Valence for each corner */
- int valence[4];
-
- /* Neighboring edges for current face */
- DisplacerEdges edges_primary;
-
- /* Neighboring faces */
- DisplacerSpill spill_x, spill_y;
-
- int *face_offsets;
-
- int x, y, ax, ay;
-} MultiresDisplacer;
-
-static int mface_v(MFace *f, int v)
+void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
{
- return v == 0 ? f->v1 : v == 1 ? f->v2 : v == 2 ? f->v3 : v == 3 ? f->v4 : -1;
-}
+ Mesh *me = ob->data;
+ MDisps *mdisps;
+ int lvl= mmd->totlvl;
+ int totlvl= mmd->totlvl+1;
-/* Get the edges (and their directions) */
-static void find_displacer_edges(MultiresDisplacer *d, DerivedMesh *dm, DisplacerEdges *de, MFace *f)
-{
- ListBase *emap = MultiresDM_get_vert_edge_map(dm);
- IndexNode *n;
- int i, end = f->v4 ? 4 : 3;
- int offset = dm->getNumVerts(dm) - d->me->totvert - d->me->totedge * d->interior_st;
+ if(totlvl > multires_max_levels)
+ return;
- for(i = 0; i < end; ++i) {
- int vcur = mface_v(f, i);
- int vnext = mface_v(f, i == end - 1 ? 0 : i + 1);
+ multires_force_update(ob);
- de->dir[i] = 1;
-
- for(n = emap[vcur].first; n; n = n->next) {
- MEdge *e = &d->me->medge[n->index];
-
- if(e->v1 == vnext || e->v2 == vnext) {
- de->base[i] = n->index * d->interior_st;
- if(((i == 0 || i == 1) && e->v1 == vnext) ||
- ((i == 2 || i == 3) && e->v2 == vnext)) {
- de->dir[i] = -1;
- de->base[i] += d->interior_st - 1;
- }
- de->base[i] += offset;
- break;
- }
- }
- }
-}
+ mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ if(!mdisps)
+ mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface);
-/* Returns in out the corners [0-3] that use v1 and v2 */
-static void find_face_corners(MFace *f, int v1, int v2, int out[2])
-{
- int i, end = f->v4 ? 4 : 3;
-
- for(i = 0; i < end; ++i) {
- int corner = mface_v(f, i);
- if(corner == v1)
- out[0] = i;
- if(corner == v2)
- out[1] = i;
- }
-}
+ if(mdisps->disps && !updateblock && totlvl > 1) {
+ /* upsample */
+ DerivedMesh *lowdm, *cddm, *highdm;
+ DMGridData **highGridData, **lowGridData, **subGridData;
+ CCGSubSurf *ss;
+ int i, numGrids, highGridSize, lowGridSize;
+
+ /* create subsurf DM from original mesh at high level */
+ cddm = CDDM_from_mesh(me, NULL);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple);
+
+ /* create multires DM from original mesh at low level */
+ lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
+ cddm->release(cddm);
+
+ /* copy subsurf grids and replace them with low displaced grids */
+ numGrids = highdm->getNumGrids(highdm);
+ highGridSize = highdm->getGridSize(highdm);
+ highGridData = highdm->getGridData(highdm);
+ lowGridSize = lowdm->getGridSize(lowdm);
+ lowGridData = lowdm->getGridData(lowdm);
+
+ subGridData = MEM_callocN(sizeof(float*)*numGrids, "subGridData*");
+
+ for(i = 0; i < numGrids; ++i) {
+ /* backup subsurf grids */
+ subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData");
+ memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize);
+
+ /* overwrite with current displaced grids */
+ multires_copy_dm_grid(highGridData[i], lowGridData[i], highGridSize, lowGridSize);
+ }
-static void multires_displacer_get_spill_faces(MultiresDisplacer *d, DerivedMesh *dm, MFace *mface)
-{
- ListBase *map = MultiresDM_get_vert_face_map(dm);
- IndexNode *n1, *n2;
- int v4 = d->face->v4 ? d->face->v4 : d->face->v1;
- int crn[2], lv;
+ /* low lower level dm no longer needed at this point */
+ lowdm->release(lowdm);
- memset(&d->spill_x, 0, sizeof(DisplacerSpill));
- memset(&d->spill_y, 0, sizeof(DisplacerSpill));
- d->spill_x.face = d->spill_y.face = -1;
+ /* subsurf higher levels again with displaced data */
+ ss= ((CCGDerivedMesh*)highdm)->ss;
+ ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
+ ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
- for(n1 = map[d->face->v3].first; n1; n1 = n1->next) {
- if(n1->index == d->face_index)
- continue;
+ /* reallocate displacements */
+ multires_reallocate_mdisps(me, mdisps, totlvl);
- for(n2 = map[d->face->v2].first; n2; n2 = n2->next) {
- if(n1->index == n2->index)
- d->spill_x.face = n1->index;
- }
- for(n2 = map[v4].first; n2; n2 = n2->next) {
- if(n1->index == n2->index)
- d->spill_y.face = n1->index;
- }
- }
+ /* compute displacements */
+ multiresModifier_disp_run(highdm, me, 1, 0, subGridData, totlvl);
- if(d->spill_x.face != -1) {
- /* Neighbor of v2/v3 found, find flip and orientation */
- find_face_corners(&mface[d->spill_x.face], d->face->v2, d->face->v3, crn);
- lv = mface[d->spill_x.face].v4 ? 3 : 2;
-
- if(crn[0] == 0 && crn[1] == lv)
- d->spill_x.f = 0+2+0;
- else if(crn[0] == lv && crn[1] == 0)
- d->spill_x.f = 1+2+0;
- else if(crn[0] == 1 && crn[1] == 0)
- d->spill_x.f = 1+2+4;
- else if(crn[0] == 0 && crn[1] == 1)
- d->spill_x.f = 0+2+4;
- else if(crn[0] == 2 && crn[1] == 1)
- d->spill_x.f = 1+0+0;
- else if(crn[0] == 1 && crn[1] == 2)
- d->spill_x.f = 0+0+0;
- else if(crn[0] == 3 && crn[1] == 2)
- d->spill_x.f = 0+0+4;
- else if(crn[0] == 2 && crn[1] == 3)
- d->spill_x.f = 1+0+4;
-
- find_displacer_edges(d, dm, &d->spill_x.edges, &mface[d->spill_x.face]);
+ /* free */
+ highdm->release(highdm);
+ for(i = 0; i < numGrids; ++i)
+ MEM_freeN(subGridData[i]);
+ MEM_freeN(subGridData);
}
-
- if(d->spill_y.face != -1) {
- /* Neighbor of v3/v4 found, find flip and orientation */
- find_face_corners(&mface[d->spill_y.face], d->face->v3, v4, crn);
- lv = mface[d->spill_y.face].v4 ? 3 : 2;
-
- if(crn[0] == 1 && crn[1] == 0)
- d->spill_y.f = 1+2+0;
- else if(crn[0] == 0 && crn[1] == 1)
- d->spill_y.f = 0+2+0;
- else if(crn[0] == 2 && crn[1] == 1)
- d->spill_y.f = 1+0+4;
- else if(crn[0] == 1 && crn[1] == 2)
- d->spill_y.f = 0+0+4;
- else if(crn[0] == 3 && crn[1] == 2)
- d->spill_y.f = 0+0+0;
- else if(crn[0] == 2 && crn[1] == 3)
- d->spill_y.f = 1+0+0;
- else if(crn[0] == 0 && crn[1] == lv)
- d->spill_y.f = 0+2+4;
- else if(crn[0] == lv && crn[1] == 0)
- d->spill_y.f = 1+2+4;
-
- find_displacer_edges(d, dm, &d->spill_y.edges, &mface[d->spill_y.face]);
+ else {
+ /* only reallocate, nothing to upsample */
+ multires_reallocate_mdisps(me, mdisps, totlvl);
}
-}
-
-static void find_corner_valences(MultiresDisplacer *d, DerivedMesh *dm)
-{
- int i;
-
- d->valence[3] = -1;
- /* Set the vertex valence for the corners */
- for(i = 0; i < (d->face->v4 ? 4 : 3); ++i)
- d->valence[i] = BLI_countlist(&MultiresDM_get_vert_edge_map(dm)[mface_v(d->face, i)]);
+ multires_set_tot_level(ob, mmd, totlvl);
}
-static void multires_displacer_init(MultiresDisplacer *d, DerivedMesh *dm,
- const int face_index, const int invert)
+static void grid_adjacent_rotate(int rotation, int gridSize, int *x, int *y)
{
- Mesh *me = MultiresDM_get_mesh(dm);
-
- d->me = me;
- d->face = me->mface + face_index;
- d->face_index = face_index;
- d->face_offsets = MultiresDM_get_face_offsets(dm);
- /* Get the multires grid from customdata */
- d->grid = CustomData_get_layer(&me->fdata, CD_MDISPS);
- if(d->grid)
- d->grid += face_index;
-
- d->spacing = pow(2, MultiresDM_get_totlvl(dm) - MultiresDM_get_lvl(dm));
- d->sidetot = multires_side_tot[MultiresDM_get_lvl(dm) - 1];
- d->interior_st = d->sidetot - 2;
- d->disp_st = multires_side_tot[MultiresDM_get_totlvl(dm) - 1];
- d->invert = invert;
-
- multires_displacer_get_spill_faces(d, dm, me->mface);
- find_displacer_edges(d, dm, &d->edges_primary, d->face);
- find_corner_valences(d, dm);
-
- d->dm_first_base_vert_index = dm->getNumVerts(dm) - me->totvert;
-}
+ /* we rotate (rotation * 90°) counterclockwise around center */
+ int nx, ny;
+
+ switch(rotation) {
+ case 0: nx = *x; ny = *y; break;
+ case 1: nx = *y; ny = *x; break;
+ case 2: nx = *x; ny = *y; break; //gridSize - 1 - *x; ny = gridSize - 1 - *y; break;
+ case 3: nx = *y; ny = *x; break;
+ }
-static void multires_displacer_weight(MultiresDisplacer *d, const float w)
-{
- d->weight = w;
+ *x = nx;
+ *y = ny;
}
-static void multires_displacer_anchor(MultiresDisplacer *d, const int type, const int side_index)
+static void grid_adjacent_jump(DMGridAdjacency *adj, int gridSize, int *index, int *x, int *y)
{
- d->sidendx = side_index;
- d->x = d->y = d->sidetot / 2;
- d->type = type;
-
- if(type == 2) {
- if(side_index == 0)
- d->y -= 1;
- else if(side_index == 1)
- d->x += 1;
- else if(side_index == 2)
- d->y += 1;
- else if(side_index == 3)
- d->x -= 1;
- }
- else if(type == 3) {
- if(side_index == 0) {
- d->x -= 1;
- d->y -= 1;
+ if(*x < 0) {
+ if(adj->index[3] == -1) {
+ /* no adjacent grid, clamp */
+ *x = 0;
}
- else if(side_index == 1) {
- d->x += 1;
- d->y -= 1;
+ else {
+ /* jump to adjacent grid */
+ *index = adj->index[3];
+ *x += gridSize;
+ grid_adjacent_rotate(adj->rotation[3], gridSize, x, y);
}
- else if(side_index == 2) {
- d->x += 1;
- d->y += 1;
+ }
+ else if(*x >= gridSize) {
+ if(adj->index[1] == -1) {
+ /* no adjacent grid, take a step back */
+ *x = gridSize - 1;
}
- else if(side_index == 3) {
- d->x -= 1;
- d->y += 1;
+ else {
+ /* jump to adjacent grid */
+ *index = adj->index[1];
+ *x -= gridSize;
+ grid_adjacent_rotate(adj->rotation[1], gridSize, x, y);
}
}
-
- d->ax = d->x;
- d->ay = d->y;
-}
-
-static void multires_displacer_anchor_edge(MultiresDisplacer *d, int v1, int v2, int x)
-{
- d->type = 4;
-
- if(v1 == d->face->v1) {
- d->x = 0;
- d->y = 0;
- if(v2 == d->face->v2)
- d->x += x;
- else if(v2 == d->face->v3) {
- if(x < d->sidetot / 2)
- d->y = x;
- else {
- d->x = x;
- d->y = d->sidetot - 1;
- }
+ else if(*y < 0) {
+ if(adj->index[0] == -1) {
+ /* no adjacent grid, clamp */
+ *y = 0;
}
- else
- d->y += x;
- }
- else if(v1 == d->face->v2) {
- d->x = d->sidetot - 1;
- d->y = 0;
- if(v2 == d->face->v1)
- d->x -= x;
- else
- d->y += x;
- }
- else if(v1 == d->face->v3) {
- d->x = d->sidetot - 1;
- d->y = d->sidetot - 1;
- if(v2 == d->face->v2)
- d->y -= x;
- else if(v2 == d->face->v1) {
- if(x < d->sidetot / 2)
- d->x -= x;
- else {
- d->x = 0;
- d->y -= x;
- }
+ else {
+ /* jump to adjacent grid */
+ *index = adj->index[0];
+ *y += gridSize;
+ grid_adjacent_rotate(adj->rotation[0], gridSize, x, y);
}
- else
- d->x -= x;
}
- else if(v1 == d->face->v4) {
- d->x = 0;
- d->y = d->sidetot - 1;
- if(v2 == d->face->v3)
- d->x += x;
- else
- d->y -= x;
+ else if(*y >= gridSize) {
+ if(adj->index[2] == -1) {
+ /* no adjacent grid, take a step back */
+ *y = gridSize - 1;
+ }
+ else {
+ /* jump to adjacent grid */
+ *index = adj->index[2];
+ *y -= gridSize;
+ grid_adjacent_rotate(adj->rotation[2], gridSize, x, y);
+ }
}
}
-static void multires_displacer_anchor_vert(MultiresDisplacer *d, const int v)
-{
- const int e = d->sidetot - 1;
-
- d->type = 5;
-
- d->x = d->y = 0;
- if(v == d->face->v2)
- d->x = e;
- else if(v == d->face->v3)
- d->x = d->y = e;
- else if(v == d->face->v4)
- d->y = e;
-}
-
-static void multires_displacer_jump(MultiresDisplacer *d)
+static void grid_tangent(DMGridAdjacency *adj, int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3])
{
- if(d->sidendx == 0) {
- d->x -= 1;
- d->y = d->ay;
- }
- else if(d->sidendx == 1) {
- d->x = d->ax;
- d->y -= 1;
- }
- else if(d->sidendx == 2) {
- d->x += 1;
- d->y = d->ay;
- }
- else if(d->sidendx == 3) {
- d->x = d->ax;
- d->y += 1;
+ int jindex = index, jx = x, jy = y;
+
+ if(axis == 0) {
+ if(adj->index[1] == -1 && x == gridSize - 1) {
+ if(adj->index[2] == -1 && y == gridSize - 1)
+ sub_v3_v3v3(t, gridData[index][x + gridSize*(y - 1)].co, gridData[index][x - 1 + gridSize*(y - 1)].co);
+ else
+ sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x - 1 + gridSize*y].co);
+ }
+ else {
+ jx += 1;
+ grid_adjacent_jump(adj, gridSize, &jindex, &jx, &jy);
+ sub_v3_v3v3(t, gridData[jindex][jx + gridSize*jy].co, gridData[index][x + gridSize*y].co);
+ }
}
-}
-
-/* Treating v1 as (0,0) and v3 as (st-1,st-1),
- returns the index of the vertex at (x,y).
- If x or y is >= st, wraps over to the adjacent face,
- or if there is no adjacent face, returns -2. */
-static int multires_index_at_loc(int face_index, int x, int y, MultiresDisplacer *d, DisplacerEdges *de)
-{
- int coord_edge = d->sidetot - 1; /* Max value of x/y at edge of grid */
- int mid = d->sidetot / 2;
- int lim = mid - 1;
- int qtot = lim * lim;
- int base = d->face_offsets[face_index];
-
- /* Edge spillover */
- if(x == d->sidetot || y == d->sidetot) {
- int flags, v_axis, f_axis, lx, ly;
-
- if(x == d->sidetot && d->spill_x.face != -1) {
- flags = d->spill_x.f;
-
- /* Handle triangle seam between v1 and v3 */
- if(!d->me->mface[d->spill_x.face].v4 &&
- ((flags == 2 && y >= mid) || (flags == 3 && y < mid)))
- flags += 2;
-
- v_axis = (flags & 1) ? d->sidetot - 1 - y : y;
- f_axis = (flags & 2) ? 1 : d->sidetot - 2;
- lx = f_axis, ly = v_axis;
-
- if(flags & 4) {
- lx = v_axis;
- ly = f_axis;
+ else if(axis == 1) {
+ if(adj->index[2] == -1 && y == gridSize - 1) {
+ if(adj->index[1] == -1 && x == gridSize - 1) {
+ sub_v3_v3v3(t, gridData[index][x - 1 + gridSize*y].co, gridData[index][x - 1 + gridSize*(y - 1)].co);
}
-
- return multires_index_at_loc(d->spill_x.face, lx, ly, d, &d->spill_x.edges);
- }
- else if(y == d->sidetot && d->spill_y.face != -1) {
- flags = d->spill_y.f;
-
- /* Handle triangle seam between v1 and v3 */
- if(!d->me->mface[d->spill_y.face].v4 &&
- ((flags == 6 && x >= mid) || (flags == 7 && x < mid)))
- flags = ~flags;
-
- v_axis = (flags & 1) ? x : d->sidetot - 1 - x;
- f_axis = (flags & 2) ? 1 : d->sidetot - 2;
- lx = v_axis, ly = f_axis;
-
- if(flags & 4) {
- lx = f_axis;
- ly = v_axis;
+ else {
+ sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x + gridSize*(y - 1)].co);
}
-
- return multires_index_at_loc(d->spill_y.face, lx, ly, d, &d->spill_y.edges);
}
- else
- return -2;
- }
- /* Corners */
- else if(x == 0 && y == 0)
- return d->dm_first_base_vert_index + d->face->v1;
- else if(x == coord_edge && y == 0)
- return d->dm_first_base_vert_index + d->face->v2;
- else if(x == coord_edge && y == coord_edge)
- return d->dm_first_base_vert_index + d->face->v3;
- else if(x == 0 && y == coord_edge)
- return d->dm_first_base_vert_index + d->face->v4;
- /* Edges */
- else if(x == 0) {
- if(d->face->v4)
- return de->base[3] + de->dir[3] * (y - 1);
- else
- return de->base[2] + de->dir[2] * (y - 1);
- }
- else if(y == 0)
- return de->base[0] + de->dir[0] * (x - 1);
- else if(x == d->sidetot - 1)
- return de->base[1] + de->dir[1] * (y - 1);
- else if(y == d->sidetot - 1)
- return de->base[2] + de->dir[2] * (x - 1);
- /* Face center */
- else if(x == mid && y == mid)
- return base;
- /* Cross */
- else if(x == mid && y < mid)
- return base + (mid - y);
- else if(y == mid && x > mid)
- return base + lim + (x - mid);
- else if(x == mid && y > mid)
- return base + lim*2 + (y - mid);
- else if(y == mid && x < mid) {
- if(d->face->v4)
- return base + lim*3 + (mid - x);
- else
- return base + lim*2 + (mid - x);
- }
- /* Quarters */
- else {
- int offset = base + lim * (d->face->v4 ? 4 : 3);
- if(x < mid && y < mid)
- return offset + ((mid - x - 1)*lim + (mid - y));
- else if(x > mid && y < mid)
- return offset + qtot + ((mid - y - 1)*lim + (x - mid));
- else if(x > mid && y > mid)
- return offset + qtot*2 + ((x - mid - 1)*lim + (y - mid));
- else if(x < mid && y > mid)
- return offset + qtot*3 + ((y - mid - 1)*lim + (mid - x));
- }
-
- return -1;
-}
-
-/* Calculate the TS matrix used for applying displacements.
- Uses the undisplaced subdivided mesh's curvature to find a
- smoothly normal and tangents. */
-static void calc_disp_mat(MultiresDisplacer *d, float mat[3][3])
-{
- int u = multires_index_at_loc(d->face_index, d->x + 1, d->y, d, &d->edges_primary);
- int v = multires_index_at_loc(d->face_index, d->x, d->y + 1, d, &d->edges_primary);
- float norm[3], t1[3], t2[3], inv[3][3];
- MVert *base = d->subco + d->subco_index;
-
- //printf("f=%d, x=%d, y=%d, i=%d, u=%d, v=%d ", d->face_index, d->x, d->y, d->subco_index, u, v);
-
- norm[0] = base->no[0] / 32767.0f;
- norm[1] = base->no[1] / 32767.0f;
- norm[2] = base->no[2] / 32767.0f;
-
- /* Special handling for vertices of valence 3 */
- if(d->valence[1] == 3 && d->x == d->sidetot - 1 && d->y == 0)
- u = -1;
- else if(d->valence[2] == 3 && d->x == d->sidetot - 1 && d->y == d->sidetot - 1)
- u = v = -1;
- else if(d->valence[3] == 3 && d->x == 0 && d->y == d->sidetot - 1)
- v = -1;
-
- /* If either u or v is -2, it's on a boundary. In this
- case, back up by one row/column and use the same
- vector as the preceeding sub-edge. */
-
- if(u < 0) {
- u = multires_index_at_loc(d->face_index, d->x - 1, d->y, d, &d->edges_primary);
- sub_v3_v3v3(t1, base->co, d->subco[u].co);
- }
- else
- sub_v3_v3v3(t1, d->subco[u].co, base->co);
-
- if(v < 0) {
- v = multires_index_at_loc(d->face_index, d->x, d->y - 1, d, &d->edges_primary);
- sub_v3_v3v3(t2, base->co, d->subco[v].co);
- }
- else
- sub_v3_v3v3(t2, d->subco[v].co, base->co);
-
- //printf("uu=%d, vv=%d\n", u, v);
-
- normalize_v3(t1);
- normalize_v3(t2);
- Mat3FromColVecs(mat, t1, t2, norm);
-
- if(d->invert) {
- invert_m3_m3(inv, mat);
- copy_m3_m3(mat, inv);
+ else {
+ jy += 1;
+ grid_adjacent_jump(adj, gridSize, &jindex, &jx, &jy);
+ sub_v3_v3v3(t, gridData[jindex][jx + gridSize*jy].co, gridData[index][x + gridSize*y].co);
+ }
}
}
-static void multires_displace(MultiresDisplacer *d, float co[3])
+static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl)
{
- float disp[3], mat[3][3];
- float *data;
- MVert *subco = &d->subco[d->subco_index];
-
- if(!d->grid || !d->grid->disps) return;
-
- data = d->grid->disps[(d->y * d->spacing) * d->disp_st + (d->x * d->spacing)];
-
- if(d->invert)
- sub_v3_v3v3(disp, co, subco->co);
- else
- copy_v3_v3(disp, data);
-
-
- /* Apply ts matrix to displacement */
- calc_disp_mat(d, mat);
- mul_m3_v3(mat, disp);
-
- if(d->invert) {
- copy_v3_v3(data, disp);
-
- }
- else {
- if(d->type == 4 || d->type == 5)
- mul_v3_fl(disp, d->weight);
- add_v3_v3v3(co, co, disp);
- }
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
+ DMGridData **gridData, **subGridData;
+ DMGridAdjacency *gridAdjacency;
+ MFace *mface = me->mface;
+ MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ int i, S, x, y, numGrids, gIndex, gridSize, dGridSize, dSkip;
- if(d->type == 2) {
- if(d->sidendx == 0)
- d->y -= 1;
- else if(d->sidendx == 1)
- d->x += 1;
- else if(d->sidendx == 2)
- d->y += 1;
- else if(d->sidendx == 3)
- d->x -= 1;
- }
- else if(d->type == 3) {
- if(d->sidendx == 0)
- d->y -= 1;
- else if(d->sidendx == 1)
- d->x += 1;
- else if(d->sidendx == 2)
- d->y += 1;
- else if(d->sidendx == 3)
- d->x -= 1;
- }
-}
+ numGrids = dm->getNumGrids(dm);
+ gridSize = dm->getGridSize(dm);
+ gridData = dm->getGridData(dm);
+ gridAdjacency = dm->getGridAdjacency(dm);
+ subGridData = (oldGridData)? oldGridData: gridData;
-static void multiresModifier_disp_run(DerivedMesh *dm, MVert *subco, int invert)
-{
- const int lvl = MultiresDM_get_lvl(dm);
- const int gridFaces = multires_side_tot[lvl - 2] - 1;
- const int edgeSize = multires_side_tot[lvl - 1] - 1;
- MVert *mvert = CDDM_get_verts(dm);
- MEdge *medge = MultiresDM_get_mesh(dm)->medge;
- MFace *mface = MultiresDM_get_mesh(dm)->mface;
- ListBase *map = MultiresDM_get_vert_face_map(dm);
- Mesh *me = MultiresDM_get_mesh(dm);
- MultiresDisplacer d;
- int i, S, x, y;
-
- d.subco = subco;
- d.subco_index = 0;
+ dGridSize = multires_side_tot[totlvl];
+ dSkip = (dGridSize-1)/(gridSize-1);
- for(i = 0; i < me->totface; ++i) {
+ for(gIndex = 0, i = 0; i < me->totface; ++i) {
const int numVerts = mface[i].v4 ? 4 : 3;
-
- /* Center */
- multires_displacer_init(&d, dm, i, invert);
- multires_displacer_anchor(&d, 1, 0);
- multires_displace(&d, mvert->co);
- ++mvert;
- ++d.subco_index;
-
- /* Cross */
- for(S = 0; S < numVerts; ++S) {
- multires_displacer_anchor(&d, 2, S);
- for(x = 1; x < gridFaces; ++x) {
- multires_displace(&d, mvert->co);
- ++mvert;
- ++d.subco_index;
- }
- }
-
- /* Quarters */
- for(S = 0; S < numVerts; S++) {
- multires_displacer_anchor(&d, 3, S);
- for(y = 1; y < gridFaces; y++) {
- for(x = 1; x < gridFaces; x++) {
- multires_displace(&d, mvert->co);
- ++mvert;
- ++d.subco_index;
- }
- multires_displacer_jump(&d);
- }
- }
- }
-
- for(i = 0; i < me->totedge; ++i) {
- const MEdge *e = &medge[i];
- for(x = 1; x < edgeSize; ++x) {
- IndexNode *n1, *n2;
- int numFaces = 0;
- for(n1 = map[e->v1].first; n1; n1 = n1->next) {
- for(n2 = map[e->v2].first; n2; n2 = n2->next) {
- if(n1->index == n2->index)
- ++numFaces;
- }
- }
- multires_displacer_weight(&d, 1.0f / numFaces);
- /* TODO: Better to have these loops outside the x loop */
- for(n1 = map[e->v1].first; n1; n1 = n1->next) {
- for(n2 = map[e->v2].first; n2; n2 = n2->next) {
- if(n1->index == n2->index) {
- multires_displacer_init(&d, dm, n1->index, invert);
- multires_displacer_anchor_edge(&d, e->v1, e->v2, x);
- multires_displace(&d, mvert->co);
+ MDisps *mdisp = &mdisps[i];
+
+ for(S = 0; S < numVerts; ++S, ++gIndex) {
+ DMGridData *grid = gridData[gIndex];
+ DMGridData *subgrid = subGridData[gIndex];
+ DMGridAdjacency *adj = &gridAdjacency[gIndex];
+ float (*dispgrid)[3] = &mdisp->disps[S*dGridSize*dGridSize];
+
+ for(y = 0; y < gridSize; y++) {
+ for(x = 0; x < gridSize; x++) {
+ float *co = grid[x + y*gridSize].co;
+ float *sco = subgrid[x + y*gridSize].co;
+ float *no = subgrid[x + y*gridSize].no;
+ float *data = dispgrid[dGridSize*y*dSkip + x*dSkip];
+ float mat[3][3], tx[3], ty[3], disp[3], d[3];
+
+ /* construct tangent space matrix */
+ grid_tangent(adj, gridSize, gIndex, x, y, 0, subGridData, tx);
+ normalize_v3(tx);
+
+ grid_tangent(adj, gridSize, gIndex, x, y, 1, subGridData, ty);
+ normalize_v3(ty);
+
+ column_vectors_to_mat3(mat, tx, ty, no);
+
+ if(!invert) {
+ /* convert to object space and add */
+ mul_v3_m3v3(disp, mat, data);
+ add_v3_v3v3(co, sco, disp);
+ }
+ else if(!add) {
+ /* convert difference to tangent space */
+ sub_v3_v3v3(disp, co, sco);
+ invert_m3(mat);
+ mul_v3_m3v3(data, mat, disp);
+ }
+ else {
+ /* convert difference to tangent space */
+ invert_m3(mat);
+ mul_v3_m3v3(d, mat, co);
+ add_v3_v3(data, d);
}
}
}
- ++mvert;
- ++d.subco_index;
- }
- }
-
- for(i = 0; i < me->totvert; ++i) {
- IndexNode *n;
- multires_displacer_weight(&d, 1.0f / BLI_countlist(&map[i]));
- for(n = map[i].first; n; n = n->next) {
- multires_displacer_init(&d, dm, n->index, invert);
- multires_displacer_anchor_vert(&d, i);
- multires_displace(&d, mvert->co);
}
- ++mvert;
- ++d.subco_index;
}
- if(!invert)
- CDDM_calc_normals(dm);
+ if(!invert) {
+ ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0);
+ ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0);
+ }
}
static void multiresModifier_update(DerivedMesh *dm)
{
+ CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
Object *ob;
Mesh *me;
MDisps *mdisps;
+ MultiresModifierData *mmd;
- ob = MultiresDM_get_object(dm);
- me = MultiresDM_get_mesh(dm);
+ ob = ccgdm->multires.ob;
+ me = ccgdm->multires.ob->data;
+ mmd = ccgdm->multires.mmd;
+ // XXX CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
if(mdisps) {
- const int lvl = MultiresDM_get_lvl(dm);
- const int totlvl = MultiresDM_get_totlvl(dm);
+ int lvl = ccgdm->multires.lvl;
+ int totlvl = ccgdm->multires.totlvl;
if(lvl < totlvl) {
- /* Propagate disps upwards */
- DerivedMesh *final, *subco_dm, *orig;
- MVert *verts_new = NULL, *cur_lvl_orig_verts = NULL;
- MultiresModifierData mmd;
- int i;
-
- orig = CDDM_from_mesh(me, NULL);
-
- /* Regenerate the current level's vertex coordinates
- (includes older displacements but not new sculpts) */
- mmd.totlvl = totlvl;
- mmd.lvl = lvl;
- subco_dm = multires_dm_create_from_derived(&mmd, 1, orig, ob, 0, 0);
- cur_lvl_orig_verts = CDDM_get_verts(subco_dm);
-
- /* Subtract the original vertex cos from the new vertex cos */
- verts_new = CDDM_get_verts(dm);
- for(i = 0; i < dm->getNumVerts(dm); ++i)
- sub_v3_v3v3(verts_new[i].co, verts_new[i].co, cur_lvl_orig_verts[i].co);
-
- final = multires_subdisp_pre(dm, totlvl - lvl, 0);
-
- multires_subdisp(orig, ob, final, lvl, totlvl, dm->getNumVerts(dm), dm->getNumEdges(dm),
- dm->getNumFaces(dm), 1);
-
- subco_dm->release(subco_dm);
- orig->release(orig);
+ Mesh *me = ob->data;
+ DerivedMesh *lowdm, *cddm, *highdm;
+ DMGridData **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid;
+ CCGSubSurf *ss;
+ int i, j, numGrids, highGridSize, lowGridSize;
+
+ /* create subsurf DM from original mesh at high level */
+ cddm = CDDM_from_mesh(me, NULL);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple);
+
+ /* create multires DM from original mesh and displacements */
+ lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
+ cddm->release(cddm);
+
+ /* gather grid data */
+ numGrids = highdm->getNumGrids(highdm);
+ highGridSize = highdm->getGridSize(highdm);
+ highGridData = highdm->getGridData(highdm);
+ lowGridSize = lowdm->getGridSize(lowdm);
+ lowGridData = lowdm->getGridData(lowdm);
+ gridData = dm->getGridData(dm);
+
+ subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*");
+ diffGrid = MEM_callocN(sizeof(DMGridData)*lowGridSize*lowGridSize, "diff");
+
+ for(i = 0; i < numGrids; ++i) {
+ /* backup subsurf grids */
+ subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData");
+ memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize);
+
+ /* write difference of subsurf and displaced low level into high subsurf */
+ for(j = 0; j < lowGridSize*lowGridSize; ++j)
+ sub_v3_v3v3(diffGrid[j].co, gridData[i][j].co, lowGridData[i][j].co);
+
+ multires_copy_dm_grid(highGridData[i], diffGrid, highGridSize, lowGridSize);
+ }
+
+ /* lower level dm no longer needed at this point */
+ MEM_freeN(diffGrid);
+ lowdm->release(lowdm);
+
+ /* subsurf higher levels again with difference of coordinates */
+ ss= ((CCGDerivedMesh*)highdm)->ss;
+ ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0);
+ ccgSubSurf_updateLevels(ss, lvl, NULL, 0);
+
+ /* add to displacements */
+ multiresModifier_disp_run(highdm, me, 1, 1, subGridData, mmd->totlvl);
+
+ /* free */
+ highdm->release(highdm);
+ for(i = 0; i < numGrids; ++i)
+ MEM_freeN(subGridData[i]);
+ MEM_freeN(subGridData);
+ }
+ else {
+ DerivedMesh *cddm, *subdm;
+
+ cddm = CDDM_from_mesh(me, NULL);
+ subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple);
+ cddm->release(cddm);
+
+ multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl);
+
+ subdm->release(subdm);
}
- else
- multiresModifier_disp_run(dm, MultiresDM_get_subco(dm), 1);
}
}
void multires_mark_as_modified(struct Object *ob)
{
if(ob && ob->derivedFinal) {
- MultiresDM_mark_as_modified(ob->derivedFinal);
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)ob->derivedFinal;
+ ccgdm->multires.modified = 1;
}
}
@@ -1234,24 +692,47 @@ void multires_force_update(Object *ob)
struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob,
int useRenderParams, int isFinalCalc)
{
- SubsurfModifierData smd;
- MultiresSubsurf ms;
+ //Mesh *me= ob->data;
DerivedMesh *result;
- int i;
+ CCGDerivedMesh *ccgdm;
+ DMGridData **gridData, **subGridData;
+ int lvl= multires_get_level(ob, mmd, useRenderParams);
+ int i, gridSize, numGrids;
+
+ if(lvl == 0)
+ return dm;
+
+ result = subsurf_dm_create_local(ob, dm, lvl, 0);
+
+ if(!local_mmd) {
+ ccgdm = (CCGDerivedMesh*)result;
+
+ ccgdm->multires.ob = ob;
+ ccgdm->multires.mmd = mmd;
+ ccgdm->multires.local_mmd = local_mmd;
+ ccgdm->multires.lvl = lvl;
+ ccgdm->multires.totlvl = mmd->totlvl;
+ ccgdm->multires.modified = 0;
+ ccgdm->multires.update = multiresModifier_update;
+ }
- ms.mmd = mmd;
- ms.ob = ob;
- ms.local_mmd = local_mmd;
+ numGrids = result->getNumGrids(result);
+ gridSize = result->getGridSize(result);
+ gridData = result->getGridData(result);
- memset(&smd, 0, sizeof(SubsurfModifierData));
- smd.levels = smd.renderLevels = mmd->lvl - 1;
- smd.flags |= eSubsurfModifierFlag_SubsurfUv;
+ subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*");
- result = NULL; // XXX subsurf_make_derived_from_derived_with_multires(dm, &smd, &ms, useRenderParams, NULL, isFinalCalc, 0);
- for(i = 0; i < result->getNumVerts(result); ++i)
- MultiresDM_get_subco(result)[i] = CDDM_get_verts(result)[i];
- multiresModifier_disp_run(result, MultiresDM_get_subco(result), 0);
- MultiresDM_set_update(result, multiresModifier_update);
+ for(i = 0; i < numGrids; i++) {
+ subGridData[i] = MEM_callocN(sizeof(DMGridData)*gridSize*gridSize, "subGridData");
+ memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
+ }
+
+ // XXX CustomData_external_read(&me->fdata, CD_MASK_MDISPS, me->totface);
+ multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
+
+ for(i = 0; i < numGrids; i++)
+ MEM_freeN(subGridData[i]);
+ MEM_freeN(subGridData);
return result;
}
@@ -1425,9 +906,9 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
MultiresLevel *lvl, *lvl1;
MVert *vsrc, *vdst;
int src, dst;
- int totlvl = MultiresDM_get_totlvl(dm);
- int st = multires_side_tot[totlvl - 2] - 1;
- int extedgelen = multires_side_tot[totlvl - 1] - 2;
+ int totlvl = 2; // XXX MultiresDM_get_totlvl(dm);
+ int st = multires_side_tot[totlvl - 1] - 1;
+ int extedgelen = multires_side_tot[totlvl] - 2;
int *vvmap; // inorder for dst, map to src
int crossedgelen;
int i, j, s, x, totvert, tottri, totquad;
@@ -1454,9 +935,9 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
lvl = lvl1->next;
for(j = 2; j <= mr->level_count; ++j) {
- int base = multires_side_tot[totlvl - j] - 2;
- int skip = multires_side_tot[totlvl - j + 1] - 1;
- int st = multires_side_tot[j - 2] - 1;
+ int base = multires_side_tot[totlvl - j + 1] - 2;
+ int skip = multires_side_tot[totlvl - j + 2] - 1;
+ int st = multires_side_tot[j - 1] - 1;
for(x = 0; x < st; ++x)
vvmap[ldst + base + x * skip] = lsrc + st * i + x;
@@ -1483,7 +964,7 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
/* Face edge cross */
tottri = totquad = 0;
- crossedgelen = multires_side_tot[totlvl - 2] - 2;
+ crossedgelen = multires_side_tot[totlvl - 1] - 2;
dst = 0;
for(i = 0; i < lvl1->totface; ++i) {
int sides = lvl1->faces[i].v[3] ? 4 : 3;
@@ -1492,8 +973,8 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
++dst;
for(j = 3; j <= mr->level_count; ++j) {
- int base = multires_side_tot[totlvl - j] - 2;
- int skip = multires_side_tot[totlvl - j + 1] - 1;
+ int base = multires_side_tot[totlvl - j + 1] - 2;
+ int skip = multires_side_tot[totlvl - j + 2] - 1;
int st = pow(2, j - 2);
int st2 = pow(2, j - 3);
int lsrc = lvl->prev->totvert;
@@ -1541,8 +1022,8 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
int ldst = dst + 1 + sides * (st - 1);
for(s = 0; s < sides; ++s) {
- int st2 = multires_side_tot[totlvl - 2] - 2;
- int st3 = multires_side_tot[totlvl - 3] - 2;
+ int st2 = multires_side_tot[totlvl - 1] - 2;
+ int st3 = multires_side_tot[totlvl - 2] - 2;
int st4 = st3 == 0 ? 1 : (st3 + 1) / 2;
int mid = ldst + st2 * st3 + st3;
int cv = lvl1->faces[j].v[s];
@@ -1583,3 +1064,4 @@ void multires_load_old(DerivedMesh *dm, Multires *mr)
MEM_freeN(vvmap);
}
+
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1fa9090ba45..a9ceb77ad9f 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3922,12 +3922,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
SWITCH_INT(mmd->dynverts[a])
}
}
- else if (md->type==eModifierType_Multires) {
- MultiresModifierData *mmd = (MultiresModifierData*) md;
-
- mmd->undo_verts = newdataadr(fd, mmd->undo_verts);
- mmd->undo_signal = !!mmd->undo_verts;
- }
}
}
@@ -9595,7 +9589,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ToolSettings *ts;
//PTCacheID *pid;
//ListBase pidlist;
- int i, a;
+ int /*i, */a;
for(ob = main->object.first; ob; ob = ob->id.next) {
//BKE_ptcache_ids_from_object(&pidlist, ob);
@@ -9613,6 +9607,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ob->data = me;
if(me && me->id.lib==NULL && me->mr) { /* XXX - library meshes crash on loading most yoFrankie levels, the multires pointer gets invalid - Campbell */
+ // XXX
+#if 0
MultiresLevel *lvl;
ModifierData *md;
MultiresModifierData *mmd;
@@ -9648,7 +9644,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
BLI_insertlinkbefore(&ob->modifiers, md, mmd);
- multiresModifier_subdivide(mmd, ob, me->mr->level_count - 1, 1, 0);
+ for(i = 0; i < me->mr->level_count - 1; ++i)
+ multiresModifier_subdivide(mmd, ob, 1, 0);
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me, NULL);
@@ -9662,6 +9659,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* Remove the old multires */
multires_free(me->mr);
+#endif
me->mr = NULL;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index b2147221f9f..b00cd10c6a7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1214,12 +1214,6 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
}
- else if (md->type==eModifierType_Multires) {
- MultiresModifierData *mmd = (MultiresModifierData*) md;
-
- if(mmd->undo_verts)
- writestruct(wd, DATA, "MVert", mmd->undo_verts_tot, mmd->undo_verts);
- }
}
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index c4304056017..9da7fa94295 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -373,7 +373,7 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
- if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
+ if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return 0;
}
@@ -684,6 +684,13 @@ void OBJECT_OT_modifier_copy(wmOperatorType *ot)
/************* multires delete higher levels operator ****************/
+static int multires_poll(bContext *C)
+{
+ PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
+ ID *id= ptr.id.data;
+ return (ptr.data && id && !id->lib);
+}
+
static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_MultiresModifier);
@@ -702,8 +709,8 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
{
ot->name= "Delete Higher Levels";
ot->idname= "OBJECT_OT_multires_higher_levels_delete";
- ot->poll= ED_operator_object_active;
+ ot->poll= multires_poll;
ot->exec= multires_higher_levels_delete_exec;
/* flags */
@@ -718,7 +725,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
Object *ob= ptr.id.data;
MultiresModifierData *mmd= ptr.data;
- multiresModifier_subdivide(mmd, ob, 1, 0, mmd->simple);
+ multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index c9e351458ad..82893b48af0 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2027,13 +2027,13 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
- //MultiresModifierData *mmd = sculpt_multires_active(ob);
+ MultiresModifierData *mmd = sculpt_multires_active(ob);
if(ob->mode & OB_MODE_SCULPT) {
multires_force_update(ob);
- /*if(mmd && mmd->sculptlvl != mmd->lvl)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);*/
+ if(mmd && mmd->sculptlvl != mmd->lvl)
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* Leave sculptmode */
ob->mode &= ~OB_MODE_SCULPT;
@@ -2044,8 +2044,8 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
/* Enter sculptmode */
ob->mode |= OB_MODE_SCULPT;
- /*if(mmd && mmd->sculptlvl != mmd->lvl)
- DAG_id_flush_update(&ob->id, OB_RECALC_DATA);*/
+ if(mmd && mmd->sculptlvl != mmd->lvl)
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* Create persistent sculpt mode data */
if(!ts->sculpt)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index fe6a5b050e3..d6e7992d435 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -581,12 +581,8 @@ typedef struct ExplodeModifierData {
typedef struct MultiresModifierData {
ModifierData modifier;
- struct MVert *undo_verts; /* Store DerivedMesh vertices for multires undo */
- int undo_verts_tot; /* Length of undo_verts array */
- char undo_signal; /* If true, signals to replace verts with undo verts */
-
- char lvl, totlvl;
- char simple;
+ char lvl, sculptlvl, renderlvl, totlvl;
+ char simple, pad[3];
} MultiresModifierData;
typedef struct FluidsimModifierData {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 93972894ef1..689599c5cdf 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -39,6 +39,7 @@
#include "BKE_animsys.h"
#include "BKE_bmesh.h" /* For BevelModifierData */
+#include "BKE_global.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
#include "WM_api.h"
@@ -335,10 +336,36 @@ static void rna_MultiresModifier_level_range(PointerRNA *ptr, int *min, int *max
{
MultiresModifierData *mmd = (MultiresModifierData*)ptr->data;
- *min = 1;
+ *min = 0;
*max = mmd->totlvl;
}
+/*static int rna_MultiresModifier_external_get(PointerRNA *ptr)
+{
+ Object *ob= (Object*)ptr->id.data;
+ Mesh *me= ob->data;
+
+ return CustomData_external_test(&me->fdata, CD_MDISPS);
+}
+
+static void rna_MultiresModifier_external_set(PointerRNA *ptr, int value)
+{
+ Object *ob= (Object*)ptr->id.data;
+ Mesh *me= ob->data;
+
+ if(CustomData_external_test(&me->fdata, CD_MDISPS) && !value)
+ CustomData_external_remove(&me->fdata, CD_MDISPS, me->totface);
+ else if(!CustomData_external_test(&me->fdata, CD_MDISPS) && value)
+ CustomData_external_add(&me->fdata, CD_MDISPS, me->id.name+2, me->totface);
+}
+
+static int rna_MultiresModifier_external_editable(PointerRNA *ptr)
+{
+ MultiresModifierData *mmd = ptr->data;
+
+ return (G.save_over && mmd->totlvl > 0);
+}*/
+
static void modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value)
{
Object *ob= value.data;
@@ -487,17 +514,15 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna)
rna_def_property_subdivision_common(srna, "subdivType");
- prop= RNA_def_property(srna, "levels", PROP_INT, PROP_NONE);
+ prop= RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "levels");
- RNA_def_property_range(prop, 1, 6);
- RNA_def_property_ui_range(prop, 1, 6, 1, 0);
+ RNA_def_property_ui_range(prop, 0, 6, 1, 0);
RNA_def_property_ui_text(prop, "Levels", "Number of subdivisions to perform.");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_NONE);
+ prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "renderLevels");
- RNA_def_property_range(prop, 1, 6);
- RNA_def_property_ui_range(prop, 1, 6, 1, 0);
+ RNA_def_property_ui_range(prop, 0, 6, 1, 0);
RNA_def_property_ui_text(prop, "Render Levels", "Number of subdivisions to perform when rendering.");
prop= RNA_def_property(srna, "optimal_draw", PROP_BOOLEAN, PROP_NONE);
@@ -523,11 +548,32 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
rna_def_property_subdivision_common(srna, "simple");
- prop= RNA_def_property(srna, "level", PROP_INT, PROP_NONE);
+ prop= RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "lvl");
- RNA_def_property_ui_text(prop, "Level", "");
+ RNA_def_property_ui_text(prop, "Levels", "Number of subdivisions to use in the viewport.");
+ RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "sculpt_levels", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "sculptlvl");
+ RNA_def_property_ui_text(prop, "Sculpt Levels", "Number of subdivisions to use in sculpt mode.");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "render_levels", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "renderlvl");
+ RNA_def_property_ui_text(prop, "Render Levels", "");
+ RNA_def_property_int_funcs(prop, NULL, NULL, "rna_MultiresModifier_level_range");
+
+ prop= RNA_def_property(srna, "total_levels", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "totlvl");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Total Levels", "Number of subdivisions for which displacements are stored.");
+
+ /*prop= RNA_def_property(srna, "external", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_MultiresModifier_external_get", "rna_MultiresModifier_external_set");
+ RNA_def_property_editable_func(prop, "rna_MultiresModifier_external_editable");
+ RNA_def_property_ui_text(prop, "External", "Store multires displacements outside the .blend file, to save memory.");*/
}
static void rna_def_modifier_lattice(BlenderRNA *brna)