Got rid of old multires code, brought in multires modifier from

soc-2008-nicholasbishop branch.

Note: any old code with multires_test() or multires_level1_test() can 
just be deleted, not needed by the multires modifier.
This commit is contained in:
2009-01-06 18:59:03 +00:00
parent 02003021a6
commit 25e5765f47
27 changed files with 2317 additions and 1982 deletions

View File

@@ -27,42 +27,58 @@
* ***** END GPL LICENSE BLOCK *****
*/
struct CustomData;
struct EditMesh;
struct Multires;
struct MultiresLevel;
struct DerivedMesh;
struct Mesh;
struct MFace;
struct MultiresModifierData;
struct Object;
/* Level access */
struct MultiresLevel *current_level(struct Multires *mr);
struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
typedef struct MultiresSubsurf {
struct MultiresModifierData *mmd;
struct Mesh *me;
} MultiresSubsurf;
/* Level control */
void multires_add_level(struct Object *ob, struct Mesh *me, const char subdiv_type);
void multires_set_level(struct Object *ob, struct Mesh *me, const int render);
void multires_free_level(struct MultiresLevel *lvl);
typedef struct IndexNode {
struct IndexNode *next, *prev;
int index;
} IndexNode;
void multires_edge_level_update(struct Object *ob, struct Mesh *me);
void create_vert_face_map(ListBase **map, IndexNode **mem, const struct MFace *mface,
const int totvert, const int totface);
void create_vert_edge_map(ListBase **map, IndexNode **mem, const struct MEdge *medge,
const int totvert, const int totedge);
void multires_free(struct Multires *mr);
struct Multires *multires_copy(struct Multires *orig);
void multires_create(struct Object *ob, struct Mesh *me);
/* MultiresDM */
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*));
int *MultiresDM_get_flags(struct DerivedMesh *);
/* CustomData */
void multires_delete_layer(struct Object *ob, struct CustomData *cd, const int type, int n);
void multires_add_layer(struct Object *ob, struct CustomData *cd, const int type, const int n);
void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl);
void multires_to_mcol(struct MultiresColFace *f, MCol mcol[4]);
/* After adding or removing vcolor layers, run this */
void multires_load_cols(struct Mesh *me);
#define MULTIRES_DM_UPDATE_BLOCK 1
#define MULTIRES_DM_UPDATE_ALWAYS 2
/* Private (used in multires-firstlevel.c) */
void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render);
void multires_update_levels(struct Mesh *me, const int render);
void multires_update_first_level(struct Mesh *me, struct EditMesh *em);
void multires_update_customdata(struct MultiresLevel *lvl1, struct EditMesh *em, struct CustomData *src,
struct CustomData *dst, const int type);
void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em,
struct MultiresLevel *lvl, struct CustomData *src,
struct CustomData *dst, const int type);
void multires_force_update(struct Object *ob);
struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, struct DerivedMesh*,
struct Mesh *, int, int);
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,
int updateblock, int simple);
void multiresModifier_setLevel(void *mmd_v, void *ob_v);
int multiresModifier_reshape(struct MultiresModifierData *mmd, struct Object *dst, struct Object *src);
/* Related to the old multires */
struct Multires;
void multires_load_old(struct DerivedMesh *, struct Multires *);
void multires_free(struct Multires*);

View File

@@ -30,6 +30,8 @@
#ifndef BKE_SCULPT_H
#define BKE_SCULPT_H
struct MFace;
struct MVert;
struct NumInput;
struct RadialControl;
struct Scene;
@@ -40,6 +42,13 @@ typedef struct SculptSession {
struct ProjVert *projverts;
struct bglMats *mats;
int multires;
int totvert;
int totface;
struct MVert *mvert;
struct MFace *mface;
float *face_normals;
/* An array of lists; array is sized as
large as the number of verts in the mesh,

View File

@@ -32,6 +32,7 @@ struct Mesh;
struct Object;
struct DerivedMesh;
struct EditMesh;
struct MultiresSubsurf;
struct SubsurfModifierData;
struct DerivedMesh *subsurf_make_derived_from_derived(
@@ -40,6 +41,13 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
int useRenderParams, float (*vertCos)[3],
int isFinalCalc, int editMode);
struct DerivedMesh *subsurf_make_derived_from_derived_with_multires(
struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
struct MultiresSubsurf *ms,
int useRenderParams, float (*vertCos)[3],
int isFinalCalc, int editMode);
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);
#endif

View File

@@ -71,7 +71,6 @@
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BKE_texture.h"
@@ -83,8 +82,6 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
//XXX #include "multires.h"
//
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -1448,6 +1445,9 @@ CustomDataMask get_viewedit_datamask()
if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT)
mask |= CD_MASK_MCOL;
if(G.f & G_SCULPTMODE)
mask |= CD_MASK_MDISPS;
return mask;
#endif
return 0;
@@ -2210,93 +2210,11 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da
return ob->derivedDeform;
}
/* Move to multires Pin level, returns a copy of the original vertex coords. */
float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
{
float *vert_copy= NULL;
if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
MultiresLevel *lvl= NULL;
int i;
/* Make sure all mesh edits are properly stored in the multires data*/
//XXX multires_update_levels(me, 1);
/* Copy the highest level of multires verts */
*orig_lvl= me->mr->current;
//XXX lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
vert_copy= MEM_callocN(sizeof(float)*3*lvl->totvert, "multires vert_copy");
for(i=0; i<lvl->totvert; ++i)
VecCopyf(&vert_copy[i*3], me->mr->verts[i].co);
/* Goto the pin level for multires */
me->mr->newlvl= me->mr->pinlvl;
//XXX multires_set_level(ob, me, 1);
}
return vert_copy;
}
/* Propagate the changes to render level - fails if mesh topology changed */
void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy,
const int orig_lvl, CustomDataMask dataMask)
{
if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
if((*dm)->getNumVerts(*dm) == me->totvert &&
(*dm)->getNumFaces(*dm) == me->totface) {
//XXX MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
DerivedMesh *old= NULL;
MVert *vertdup= NULL;
int i;
/* Copy the verts into the mesh */
vertdup= (*dm)->dupVertArray(*dm);
(*dm)->release(*dm);
for(i=0; i<me->totvert; ++i)
me->mvert[i]= vertdup[i];
/* Free vertdup after use*/
MEM_freeN(vertdup);
/* Go to the render level */
me->mr->newlvl= me->mr->renderlvl;
//XXX multires_set_level(ob, me, 1);
(*dm)= getMeshDerivedMesh(me, ob, NULL);
/* Some of the data in dm is referenced externally, so make a copy */
old= *dm;
(*dm)= CDDM_copy(old);
old->release(old);
if(dataMask & CD_MASK_ORCO)
add_orco_dm(ob, NULL, *dm, NULL);
/* Restore the original verts */
me->mr->newlvl= BLI_countlist(&me->mr->levels);
//XXX multires_set_level(ob, me, 1);
//XXX for(i=0; i<lvl->totvert; ++i)
//XXX VecCopyf(me->mvert[i].co, &vert_copy[i*3]);
}
if(vert_copy)
MEM_freeN(vert_copy);
me->mr->newlvl= orig_lvl;
//XXX multires_set_level(ob, me, 1);
}
}
/* Multires note - if mesh has multires enabled, mesh is first set to the Pin level,
where all modifiers are applied, then if the topology hasn't changed, the changes
from modifiers are propagated up to the Render level. */
DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask)
{
DerivedMesh *final;
Mesh *me= get_mesh(ob);
float *vert_copy= NULL;
int orig_lvl= 0;
vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1);
multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
return final;
}
@@ -2304,13 +2222,8 @@ DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask
DerivedMesh *mesh_create_derived_index_render(Scene *scene, Object *ob, CustomDataMask dataMask, int index)
{
DerivedMesh *final;
Mesh *me= get_mesh(ob);
float *vert_copy= NULL;
int orig_lvl= 0;
vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, index);
multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
return final;
}
@@ -2339,13 +2252,8 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
CustomDataMask dataMask)
{
DerivedMesh *final;
Mesh *me= get_mesh(ob);
float *vert_copy= NULL;
int orig_lvl= 0;
vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(scene, ob, vertCos, NULL, &final, 1, 0, 0, dataMask, -1);
multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
return final;
}

View File

@@ -42,6 +42,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
@@ -52,6 +53,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_fluidsim.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -64,6 +66,7 @@
#include <string.h>
#include <limits.h>
#include <math.h>
typedef struct {
DerivedMesh dm;
@@ -885,6 +888,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
DerivedMesh *dm = &cddm->dm;
CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
int i, *index, alloctype;
/* this does a referenced copy, the only new layers being ORIGINDEX,
@@ -900,11 +904,11 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
alloctype= CD_REFERENCE;
CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, alloctype,
CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, CD_MASK_MESH, alloctype,
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
mesh->totedge);
CustomData_merge(&mesh->fdata, &dm->faceData, CD_MASK_MESH, alloctype,
CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
mesh->totface);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
@@ -1282,3 +1286,192 @@ MFace *CDDM_get_faces(DerivedMesh *dm)
return ((CDDerivedMesh*)dm)->mface;
}
/* Multires DerivedMesh, extends CDDM */
typedef struct MultiresDM {
CDDerivedMesh cddm;
MultiresModifierData *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;
Mesh *me;
int flags;
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->flags & MULTIRES_DM_UPDATE_BLOCK))
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(cd->data == mrdm->mmd->undo_verts)
cd->flag |= CD_FLAG_NOFREE;
}
if(DM_release(dm)) {
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->me = ms->me;
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)
VecCopyf(mrdm->orco[i], mvert[i].co);
}
else
DM_init(dm, numVerts, numEdges, 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->flags = 0;
dm->release = MultiresDM_release;
return dm;
}
Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
{
return ((MultiresDM*)dm)->me;
}
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;
if(!mrdm->vert_face_map)
create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, mrdm->me->mface,
mrdm->me->totvert, mrdm->me->totface);
return mrdm->vert_face_map;
}
ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
if(!mrdm->vert_edge_map)
create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, mrdm->me->medge,
mrdm->me->totvert, mrdm->me->totedge);
return mrdm->vert_edge_map;
}
int *MultiresDM_get_face_offsets(DerivedMesh *dm)
{
MultiresDM *mrdm = (MultiresDM*)dm;
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) * mrdm->me->totface, "mrdm face offsets");
for(i = 0; i < mrdm->me->totface; ++i) {
mrdm->face_offsets[i] = accum;
accum += (mrdm->me->mface[i].v4 ? q : t);
}
}
return mrdm->face_offsets;
}
int *MultiresDM_get_flags(DerivedMesh *dm)
{
return &((MultiresDM*)dm)->flags;
}

View File

@@ -34,6 +34,7 @@
#include "BKE_customdata.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_mempool.h"
@@ -44,6 +45,7 @@
#include "MEM_guardedalloc.h"
#include <math.h>
#include <string.h>
/* number of layers to add when growing a CustomData object */
@@ -378,6 +380,156 @@ static void layerDefault_origspace_face(void *data, int count)
for(i = 0; i < count; i++)
osf[i] = default_osf;
}
/* Adapted from sculptmode.c */
static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v)
{
int x, y, x2, y2;
const int st_max = st - 1;
float urat, vrat, uopp;
float d[4][3], d2[2][3];
if(u < 0)
u = 0;
else if(u >= st)
u = st_max;
if(v < 0)
v = 0;
else if(v >= st)
v = st_max;
x = floor(u);
y = floor(v);
x2 = x + 1;
y2 = y + 1;
if(x2 >= st) x2 = st_max;
if(y2 >= st) y2 = st_max;
urat = u - x;
vrat = v - y;
uopp = 1 - urat;
VecCopyf(d[0], disps[y * st + x]);
VecCopyf(d[1], disps[y * st + x2]);
VecCopyf(d[2], disps[y2 * st + x]);
VecCopyf(d[3], disps[y2 * st + x2]);
VecMulf(d[0], uopp);
VecMulf(d[1], urat);
VecMulf(d[2], uopp);
VecMulf(d[3], urat);
VecAddf(d2[0], d[0], d[1]);
VecAddf(d2[1], d[2], d[3]);
VecMulf(d2[0], 1 - vrat);
VecMulf(d2[1], vrat);
VecAddf(out, d2[0], d2[1]);
}
static void layerSwap_mdisps(void *data, int *ci)
{
MDisps *s = data;
float (*d)[3] = NULL;
int x, y, st;
if(!(ci[0] == 2 && ci[1] == 3 && ci[2] == 0 && ci[3] == 1)) return;
d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
st = sqrt(s->totdisp);
for(y = 0; y < st; ++y) {
for(x = 0; x < st; ++x) {
VecCopyf(d[(st - y - 1) * st + (st - x - 1)], s->disps[y * st + x]);
}
}
if(s->disps)
MEM_freeN(s->disps);
s->disps = d;
}
static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
int count, void *dest)
{
MDisps *d = dest;
MDisps *s = NULL;
int st, stl;
int i, x, y;
float crn[4][2];
float (*sw)[4] = NULL;
/* Initialize the destination */
for(i = 0; i < d->totdisp; ++i) {
float z[3] = {0,0,0};
VecCopyf(d->disps[i], z);
}
/* For now, some restrictions on the input */
if(count != 1 || !sub_weights) return;
st = sqrt(d->totdisp);
stl = st - 1;
sw = (void*)sub_weights;
for(i = 0; i < 4; ++i) {
crn[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3];
crn[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3];
}
s = sources[0];
for(y = 0; y < st; ++y) {
for(x = 0; x < st; ++x) {
/* One suspects this code could be cleaner. */
float xl = (float)x / (st - 1);
float yl = (float)y / (st - 1);
float mid1[2] = {crn[0][0] * (1 - xl) + crn[1][0] * xl,
crn[0][1] * (1 - xl) + crn[1][1] * xl};
float mid2[2] = {crn[3][0] * (1 - xl) + crn[2][0] * xl,
crn[3][1] * (1 - xl) + crn[2][1] * xl};
float mid3[2] = {mid1[0] * (1 - yl) + mid2[0] * yl,
mid1[1] * (1 - yl) + mid2[1] * yl};
float srcdisp[3];
mdisps_bilinear(srcdisp, s->disps, st, mid3[0], mid3[1]);
VecCopyf(d->disps[y * st + x], srcdisp);
}
}
}
static void layerCopy_mdisps(const void *source, void *dest, int count)
{
int i;
const MDisps *s = source;
MDisps *d = dest;
for(i = 0; i < count; ++i) {
if(s[i].disps) {
d[i].disps = MEM_dupallocN(s[i].disps);
d[i].totdisp = s[i].totdisp;
}
else {
d[i].disps = NULL;
d[i].totdisp = 0;
}
}
}
static void layerFree_mdisps(void *data, int count, int size)
{
int i;
MDisps *d = data;
for(i = 0; i < count; ++i) {
if(d[i].disps)
MEM_freeN(d[i].disps);
d[i].disps = NULL;
d[i].totdisp = 0;
}
}
/* --------- */
static void layerDefault_mloopcol(void *data, int count)
@@ -553,23 +705,26 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"};
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
"CDMloopCol", "CDTangent", "CDMDisps"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
const CustomDataMask CD_MASK_MESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |

View File

@@ -56,7 +56,6 @@
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_subsurf.h"
#include "BKE_displist.h"
#include "BKE_library.h"
@@ -137,8 +136,6 @@ void free_mesh(Mesh *me)
if(me->bb) MEM_freeN(me->bb);
if(me->mselect) MEM_freeN(me->mselect);
if(me->edit_mesh) MEM_freeN(me->edit_mesh);
if(me->mr) multires_free(me->mr);
}
void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
@@ -222,9 +219,6 @@ Mesh *copy_mesh(Mesh *me)
}
}
if(me->mr)
men->mr= multires_copy(me->mr);
men->mselect= NULL;
men->bb= MEM_dupallocN(men->bb);

View File

@@ -86,6 +86,7 @@
#include "BKE_displist.h"
#include "BKE_fluidsim.h"
#include "BKE_global.h"
#include "BKE_multires.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_material.h"
@@ -6173,7 +6174,6 @@ static void particleSystemModifier_deformVerts(
DerivedMesh *dm = derivedData;
ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
ParticleSystem * psys=0;
Mesh *me;
int needsFree=0;
if(ob->particlesystem.first)
@@ -6181,14 +6181,6 @@ static void particleSystemModifier_deformVerts(
else
return;
/* multires check */
if(ob->type == OB_MESH) {
me= (Mesh*)ob->data;
if(me->mr && me->mr->current != 1)
modifier_setError(md,
"Particles only supported on first multires level.");
}
if(!psys_check_enabled(ob, psys))
return;
@@ -7738,6 +7730,58 @@ static void meshdeformModifier_deformVertsEM(
dm->release(dm);
}
/* Multires */
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);
}
static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
{
MultiresModifierData *mmd = (MultiresModifierData*) md;
MultiresModifierData *tmmd = (MultiresModifierData*) target;
tmmd->totlvl = mmd->totlvl;
tmmd->lvl = mmd->lvl;
}
static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
int useRenderParams, int isFinalCalc)
{
MultiresModifierData *mmd = (MultiresModifierData*)md;
Mesh *me = get_mesh(ob);
DerivedMesh *final;
/* TODO: for now just skip a level1 mesh */
if(mmd->lvl == 1)
return dm;
final = multires_dm_create_from_derived(mmd, dm, me, 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) {
VecCopyf(dst[i].co, mmd->undo_verts[i].co);
}
CDDM_calc_normals(final);
MEM_freeN(mmd->undo_verts);
mmd->undo_signal = 0;
mmd->undo_verts = NULL;
}
return final;
}
/* Shrinkwrap */
@@ -8338,6 +8382,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->foreachObjectLink = simpledeformModifier_foreachObjectLink;
mti->updateDepgraph = simpledeformModifier_updateDepgraph;
mti = INIT_TYPE(Multires);
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;
typeArrInit = 0;
#undef INIT_TYPE
}

View File

@@ -1,411 +0,0 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*
* Deals with the first-level data in multires (edge flags, weights, and UVs)
*
* multires.h
*
*/
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
//XXX #include "BIF_editmesh.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BLI_editVert.h"
#include "MEM_guardedalloc.h"
#include <string.h>
MDeformVert *subdivide_dverts(MDeformVert *src, MultiresLevel *lvl);
MTFace *subdivide_mtfaces(MTFace *src, MultiresLevel *lvl);
void multires_update_edge_flags(Mesh *me, EditMesh *em);
void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease);
/*********** Generic ***********/
CustomDataMask cdmask(const int type)
{
if(type == CD_MDEFORMVERT)
return CD_MASK_MDEFORMVERT;
else if(type == CD_MTFACE)
return CD_MASK_MTFACE;
return -1;
}
char type_ok(const int type)
{
return (type == CD_MDEFORMVERT) || (type == CD_MTFACE);
}
/* Copy vdata or fdata from Mesh or EditMesh to Multires. */
void multires_update_customdata(MultiresLevel *lvl1, EditMesh *em, CustomData *src, CustomData *dst, const int type)
{
if(src && dst && type_ok(type)) {
const int tot= (type == CD_MDEFORMVERT ? lvl1->totvert : lvl1->totface);
int i;
CustomData_free(dst, tot);
if(CustomData_has_layer(src, type)) {
if(em) {
EditVert *eve= em->verts.first;
EditFace *efa= em->faces.first;
CustomData_copy(src, dst, cdmask(type), CD_CALLOC, tot);
for(i=0; i<tot; ++i) {
if(type == CD_MDEFORMVERT) {
CustomData_from_em_block(&em->vdata, dst, eve->data, i);
eve= eve->next;
}
else if(type == CD_MTFACE) {
CustomData_from_em_block(&em->fdata, dst, efa->data, i);
efa= efa->next;
}
}
}
else
CustomData_copy(src, dst, cdmask(type), CD_DUPLICATE, tot);
}
}
}
/* Uses subdivide_dverts or subdivide_mtfaces to subdivide src to match lvl_end. Does not free src. */
void *subdivide_customdata_to_level(void *src, MultiresLevel *lvl_start,
MultiresLevel *lvl_end, const int type)
{
if(src && lvl_start && lvl_end && type_ok(type)) {
MultiresLevel *lvl;
void *cr_data= NULL, *pr_data= NULL;
pr_data= src;
for(lvl= lvl_start; lvl && lvl != lvl_end; lvl= lvl->next) {
if(type == CD_MDEFORMVERT)
cr_data= subdivide_dverts(pr_data, lvl);
else if(type == CD_MTFACE)
cr_data= subdivide_mtfaces(pr_data, lvl);
/* Free previous subdivision level's data */
if(lvl != lvl_start) {
if(type == CD_MDEFORMVERT)
free_dverts(pr_data, lvl->totvert);
else if(type == CD_MTFACE)
MEM_freeN(pr_data);
}
pr_data= cr_data;
cr_data= NULL;
}
return pr_data;
}
return NULL;
}
/* Directly copy src into dst (handles both Mesh and EditMesh) */
void customdata_to_mesh(Mesh *me, EditMesh *em, CustomData *src, CustomData *dst, const int tot, const int type)
{
if(me && me->mr && src && dst && type_ok(type)) {
if(em) {
int i;
EditVert *eve= em->verts.first;
EditFace *efa= em->faces.first;
CustomData_copy(src, dst, cdmask(type), CD_CALLOC, 0);
for(i=0; i<tot; ++i) {
if(type == CD_MDEFORMVERT) {
CustomData_to_em_block(src, dst, i, &eve->data);
eve= eve->next;
}
else if(type == CD_MTFACE) {
CustomData_to_em_block(src, dst, i, &efa->data);
efa= efa->next;
}
}
} else {
CustomData_merge(src, dst, cdmask(type), CD_DUPLICATE, tot);
}
}
}
/* Subdivide vdata or fdata from Multires into either Mesh or EditMesh. */
void multires_customdata_to_mesh(Mesh *me, EditMesh *em, MultiresLevel *lvl, CustomData *src,
CustomData *dst, const int type)
{
if(me && me->mr && lvl && src && dst && type_ok(type) &&
CustomData_has_layer(src, type)) {
const int tot= (type == CD_MDEFORMVERT ? lvl->totvert : lvl->totface);
if(lvl == me->mr->levels.first) {
customdata_to_mesh(me, em, src, dst, tot, type);
}
else {
CustomData cdf;
const int count = CustomData_number_of_layers(src, type);
int i;
/* Construct a new CustomData containing the subdivided data */
CustomData_copy(src, &cdf, cdmask(type), CD_ASSIGN, tot);
for(i=0; i<count; ++i) {
void *layer= CustomData_get_layer_n(&cdf, type, i);
CustomData_set_layer_n(&cdf, type, i,
subdivide_customdata_to_level(layer, me->mr->levels.first, lvl, type));
}
customdata_to_mesh(me, em, &cdf, dst, tot, type);
CustomData_free(&cdf, tot);
}
}
}
/* Subdivide the first-level customdata up to cr_lvl, then delete the original data */
void multires_del_lower_customdata(Multires *mr, MultiresLevel *cr_lvl)
{
MultiresLevel *lvl1= mr->levels.first;
MDeformVert *dverts= NULL;
CustomData cdf;
int i;
/* dverts */
dverts= subdivide_customdata_to_level(CustomData_get(&mr->vdata, 0, CD_MDEFORMVERT),
lvl1, cr_lvl, CD_MDEFORMVERT);
if(dverts) {
CustomData_free_layers(&mr->vdata, CD_MDEFORMVERT, lvl1->totvert);
CustomData_add_layer(&mr->vdata, CD_MDEFORMVERT, CD_ASSIGN, dverts, cr_lvl->totvert);
}
/* mtfaces */
CustomData_copy(&mr->fdata, &cdf, CD_MASK_MTFACE, CD_ASSIGN, cr_lvl->totface);
for(i=0; i<CustomData_number_of_layers(&mr->fdata, CD_MTFACE); ++i) {
MTFace *mtfaces=
subdivide_customdata_to_level(CustomData_get_layer_n(&mr->fdata, CD_MTFACE, i),
lvl1, cr_lvl, CD_MTFACE);
if(mtfaces)
CustomData_set_layer_n(&cdf, CD_MTFACE, i, mtfaces);
}
CustomData_free(&mr->fdata, lvl1->totface);
mr->fdata= cdf;
}
/* Update all special first-level data, if the first-level is active */
void multires_update_first_level(Mesh *me, EditMesh *em)
{
if(me && me->mr && me->mr->current == 1) {
multires_update_customdata(me->mr->levels.first, em, em ? &em->vdata : &me->vdata,
&me->mr->vdata, CD_MDEFORMVERT);
multires_update_customdata(me->mr->levels.first, em, em ? &em->fdata : &me->fdata,
&me->mr->fdata, CD_MTFACE);
multires_update_edge_flags(me, em);
}
}
/*********** Multires.edge_flags ***********/
void multires_update_edge_flags(Mesh *me, EditMesh *em)
{
MultiresLevel *lvl= me->mr->levels.first;
EditEdge *eed= NULL;
int i;
if(em) eed= em->edges.first;
for(i=0; i<lvl->totedge; ++i) {
if(em) {
me->mr->edge_flags[i]= 0;
eed_to_medge_flag(eed, &me->mr->edge_flags[i], &me->mr->edge_creases[i]);
eed= eed->next;
}
else {
me->mr->edge_flags[i]= me->medge[i].flag;
me->mr->edge_creases[i]= me->medge[i].crease;
}
}
}
/*********** Multires.vdata ***********/
/* MDeformVert */
/* Add each weight from in to out. Scale each weight by w. */
void multires_add_dvert(MDeformVert *out, const MDeformVert *in, const float w)
{
if(out && in) {
int i, j;
char found;
for(i=0; i<in->totweight; ++i) {
found= 0;
for(j=0; j<out->totweight; ++j) {
if(out->dw[j].def_nr==in->dw[i].def_nr) {
out->dw[j].weight += in->dw[i].weight * w;
found= 1;
}
}
if(!found) {
MDeformWeight *newdw= MEM_callocN(sizeof(MDeformWeight)*(out->totweight+1),
"multires dvert");
if(out->dw) {
memcpy(newdw, out->dw, sizeof(MDeformWeight)*out->totweight);
MEM_freeN(out->dw);
}
out->dw= newdw;
out->dw[out->totweight].weight= in->dw[i].weight * w;
out->dw[out->totweight].def_nr= in->dw[i].def_nr;
++out->totweight;
}
}
}
}
/* Takes an input array of dverts and subdivides them (linear) using the topology of lvl */
MDeformVert *subdivide_dverts(MDeformVert *src, MultiresLevel *lvl)
{
if(lvl && lvl->next) {
MDeformVert *out = MEM_callocN(sizeof(MDeformVert)*lvl->next->totvert, "dvert prop array");
int i, j;
/* Copy lower level */
for(i=0; i<lvl->totvert; ++i)
multires_add_dvert(&out[i], &src[i], 1);
/* Edge verts */
for(i=0; i<lvl->totedge; ++i) {
for(j=0; j<2; ++j)
multires_add_dvert(&out[lvl->totvert+i], &src[lvl->edges[i].v[j]],0.5);
}
/* Face verts */
for(i=0; i<lvl->totface; ++i) {
for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j)
multires_add_dvert(&out[lvl->totvert + lvl->totedge + i],
&src[lvl->faces[i].v[j]],
lvl->faces[i].v[3]?0.25:(1.0f/3.0f));
}
return out;
}
return NULL;
}
/*********** Multires.fdata ***********/
/* MTFace */
void multires_uv_avg2(float out[2], const float a[2], const float b[2])
{
int i;
for(i=0; i<2; ++i)
out[i] = (a[i] + b[i]) / 2.0f;
}
/* Takes an input array of mtfaces and subdivides them (linear) using the topology of lvl */
MTFace *subdivide_mtfaces(MTFace *src, MultiresLevel *lvl)
{
if(lvl && lvl->next) {
MTFace *out= MEM_callocN(sizeof(MultiresColFace)*lvl->next->totface,"Multirescolfaces");
int i, j, curf;
for(i=0, curf=0; i<lvl->totface; ++i) {
const char sides= lvl->faces[i].v[3]?4:3;
float cntr[2]= {0, 0};
/* Find average uv coord of the current face */
for(j=0; j<sides; ++j) {
cntr[0]+= src[i].uv[j][0];
cntr[1]+= src[i].uv[j][1];
}
cntr[0]/= sides;
cntr[1]/= sides;
for(j=0; j<sides; ++j, ++curf) {
out[curf]= src[i];
multires_uv_avg2(out[curf].uv[0], src[i].uv[j], src[i].uv[j==0?sides-1:j-1]);
out[curf].uv[1][0]= src[i].uv[j][0];
out[curf].uv[1][1]= src[i].uv[j][1];
multires_uv_avg2(out[curf].uv[2], src[i].uv[j], src[i].uv[j==sides-1?0:j+1]);
out[curf].uv[3][0]= cntr[0];
out[curf].uv[3][1]= cntr[1];
}
}
return out;
}
return NULL;
}
void multires_delete_layer(Object *ob, CustomData *cd, const int type, int n)
{
Mesh *me= ob->data;
if(me && me->mr && cd) {
MultiresLevel *lvl1= me->mr->levels.first;
multires_update_levels(me, 0);
CustomData_set_layer_active(cd, type, n);
CustomData_free_layer_active(cd, type, lvl1->totface);
multires_level_to_mesh(ob, me, 0);
}
}
void multires_add_layer(Object *ob, CustomData *cd, const int type, const int n)
{
Mesh *me= ob->data;
if(me && me->mr && cd) {
multires_update_levels(me, 0);
if(CustomData_has_layer(cd, type))
CustomData_add_layer(cd, type, CD_DUPLICATE, CustomData_get_layer(cd, type),
current_level(me->mr)->totface);
else
CustomData_add_layer(cd, type, CD_DEFAULT, NULL, current_level(me->mr)->totface);
CustomData_set_layer_active(cd, type, n);
multires_level_to_mesh(ob, me, 0);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -707,7 +707,6 @@ void sculptsession_free(Scene *sce)
}
}
/* Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1 */
void sculpt_reset_curve(SculptData *sd)
{
CurveMap *cm = NULL;
@@ -719,21 +718,15 @@ void sculpt_reset_curve(SculptData *sd)
if(cm->curve)
MEM_freeN(cm->curve);
cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points");
cm->curve= MEM_callocN(3*sizeof(CurveMapPoint), "curve points");
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
cm->totpoint= 6;
cm->totpoint= 3;
cm->curve[0].x= 0;
cm->curve[0].y= 1;
cm->curve[1].x= 0.1;
cm->curve[1].y= 0.97553;
cm->curve[2].x= 0.3;
cm->curve[2].y= 0.79389;
cm->curve[3].x= 0.9;
cm->curve[3].y= 0.02447;
cm->curve[4].x= 0.7;
cm->curve[4].y= 0.20611;
cm->curve[5].x= 1;
cm->curve[5].y= 0;
cm->curve[1].x= 0.33;
cm->curve[1].y= 0.33;
cm->curve[2].x= 1;
cm->curve[2].y= 0;
curvemapping_changed(sd->cumap, 0);
}

View File

@@ -48,6 +48,7 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
@@ -471,7 +472,7 @@ static void calc_ss_weights(int gridFaces,
static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
int drawInteriorEdges, int useSubsurfUv,
DerivedMesh *dm)
DerivedMesh *dm, MultiresSubsurf *ms)
{
DerivedMesh *result;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -524,14 +525,21 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
}
ccgFaceIterator_free(fi);
if(dm) {
result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
} else {
result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
if(ms) {
result = MultiresDM_new(ms, dm, ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
}
else {
if(dm) {
result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
} else {
result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss));
}
}
// load verts
@@ -557,11 +565,12 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
++mvert;
++origIndex;
i++;
for(S = 0; S < numVerts; S++) {
int prevS = (S - 1 + numVerts) % numVerts;
int nextS = (S + 1) % numVerts;
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
for(x = 1; x < gridFaces; x++) {
float w[4];
w[prevS] = weight[x][0][0];
@@ -571,6 +580,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
VecCopyf(mvert->co,
ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
*origIndex = ORIGINDEX_NONE;
++mvert;
++origIndex;
@@ -582,6 +592,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
int prevS = (S - 1 + numVerts) % numVerts;
int nextS = (S + 1) % numVerts;
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
for(y = 1; y < gridFaces; y++) {
for(x = 1; x < gridFaces; x++) {
float w[4];
@@ -2565,9 +2576,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/***/
struct DerivedMesh *subsurf_make_derived_from_derived(
struct DerivedMesh *subsurf_make_derived_from_derived_with_multires(
struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
struct MultiresSubsurf *ms,
int useRenderParams, float (*vertCos)[3],
int isFinalCalc, int editMode)
{
@@ -2599,7 +2611,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
useSubsurfUv, dm);
useSubsurfUv, dm, ms);
ccgSubSurf_free(ss);
@@ -2630,7 +2642,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
useSubsurfUv, dm);
useSubsurfUv, dm, ms);
/*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
drawInteriorEdges,
@@ -2650,7 +2662,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
useSubsurfUv, dm);*/
result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
useSubsurfUv, dm);
useSubsurfUv, dm, ms);
ccgSubSurf_free(ss);
@@ -2659,6 +2671,15 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
}
}
struct DerivedMesh *subsurf_make_derived_from_derived(
struct DerivedMesh *dm,
struct SubsurfModifierData *smd,
int useRenderParams, float (*vertCos)[3],
int isFinalCalc, int editMode)
{
return subsurf_make_derived_from_derived_with_multires(dm, smd, NULL, useRenderParams, vertCos, isFinalCalc, editMode);
}
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
{
/* Finds the subsurf limit positions for the verts in a mesh

View File

@@ -125,6 +125,7 @@
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_node.h" // for tree type defines
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -2803,6 +2804,19 @@ static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts)
}
}
static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps)
{
if(mdisps) {
int i;
for(i = 0; i < count; ++i) {
mdisps[i].disps = newdataadr(fd, mdisps[i].disps);
if(!mdisps[i].disps)
mdisps[i].totdisp = 0;
}
}
}
static void direct_link_customdata(FileData *fd, CustomData *data, int count)
{
int i = 0;
@@ -2814,6 +2828,8 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
if (CustomData_verify_versions(data, i)) {
layer->data = newdataadr(fd, layer->data);
if(layer->type == CD_MDISPS)
direct_link_mdisps(fd, count, layer->data);
i++;
}
}
@@ -2866,11 +2882,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
direct_link_dverts(fd, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT));
direct_link_customdata(fd, &mesh->mr->fdata, lvl->totface);
if(mesh->mr->edge_flags)
mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
if(mesh->mr->edge_creases)
mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
if(!mesh->mr->edge_flags)
mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
if(!mesh->mr->edge_creases)
@@ -2883,9 +2894,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
lvl->faces= newdataadr(fd, lvl->faces);
lvl->edges= newdataadr(fd, lvl->edges);
lvl->colfaces= newdataadr(fd, lvl->colfaces);
lvl->edge_boundary_states= NULL;
lvl->vert_face_map = lvl->vert_edge_map = NULL;
lvl->map_mem= NULL;
}
}
@@ -3273,6 +3281,12 @@ 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;
}
}
}
@@ -8491,8 +8505,78 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
strcpy(tx->nodetree->id.name, "NTTexture Nodetree");
}
}
/* TODO: should be moved into one of the version blocks once this branch moves to trunk and we can
bump the version (or sub-version.) */
{
Object *ob;
int i;
for(ob = main->object.first; ob; ob = ob->id.next) {
if(ob->type == OB_MESH) {
Mesh *me = newlibadr(fd, lib, ob->data);
void *olddata = ob->data;
ob->data = me;
if(me && me->mr) {
MultiresLevel *lvl;
ModifierData *md;
MultiresModifierData *mmd;
DerivedMesh *dm, *orig;
/* Load original level into the mesh */
lvl = me->mr->levels.first;
CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert);
CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge);
CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface);
me->totvert = lvl->totvert;
me->totedge = lvl->totedge;
me->totface = lvl->totface;
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert);
for(i = 0; i < me->totedge; ++i) {
me->medge[i].v1 = lvl->edges[i].v[0];
me->medge[i].v2 = lvl->edges[i].v[1];
}
for(i = 0; i < me->totface; ++i) {
me->mface[i].v1 = lvl->faces[i].v[0];
me->mface[i].v2 = lvl->faces[i].v[1];
me->mface[i].v3 = lvl->faces[i].v[2];
me->mface[i].v4 = lvl->faces[i].v[3];
}
/* Add a multires modifier to the object */
md = ob->modifiers.first;
while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
md = md->next;
mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
BLI_insertlinkbefore(&ob->modifiers, md, mmd);
multiresModifier_subdivide(mmd, ob, me->mr->level_count - 1, 1, 0);
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me, NULL);
dm = multires_dm_create_from_derived(mmd, orig, me, 0, 0);
multires_load_old(dm, me->mr);
*MultiresDM_get_flags(dm) |= MULTIRES_DM_UPDATE_ALWAYS;
dm->release(dm);
orig->release(orig);
/* Remove the old multires */
multires_free(me->mr);
me->mr = NULL;
}
ob->data = olddata;
}
}
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */

View File

@@ -852,7 +852,7 @@ static void write_constraint_channels(WriteData *wd, ListBase *chanbase)
}
static void write_modifiers(WriteData *wd, ListBase *modbase)
static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
{
ModifierData *md;
@@ -903,10 +903,16 @@ 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 && write_undo)
writestruct(wd, DATA, "MVert", mmd->undo_verts_tot, mmd->undo_verts);
}
}
}
static void write_objects(WriteData *wd, ListBase *idbase)
static void write_objects(WriteData *wd, ListBase *idbase, int write_undo)
{
Object *ob;
@@ -940,7 +946,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "BulletSoftBody", 1, ob->bsoft);
write_particlesystems(wd, &ob->particlesystem);
write_modifiers(wd, &ob->modifiers);
write_modifiers(wd, &ob->modifiers, write_undo);
}
ob= ob->id.next;
}
@@ -1138,7 +1144,7 @@ static void write_curves(WriteData *wd, ListBase *idbase)
static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist)
{
if (dvlist) {
int i;
int i;
/* Write the dvert list */
writestruct(wd, DATA, "MDeformVert", count, dvlist);
@@ -1151,6 +1157,19 @@ static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist)
}
}
static void write_mdisps(WriteData *wd, int count, MDisps *mdlist)
{
if(mdlist) {
int i;
writestruct(wd, DATA, "MDisps", count, mdlist);
for(i = 0; i < count; ++i) {
if(mdlist[i].disps)
writedata(wd, DATA, sizeof(float)*3*mdlist[i].totdisp, mdlist[i].disps);
}
}
}
static void write_customdata(WriteData *wd, int count, CustomData *data, int partial_type, int partial_count)
{
int i;
@@ -1166,6 +1185,9 @@ static void write_customdata(WriteData *wd, int count, CustomData *data, int par
/* layer types that allocate own memory need special handling */
write_dverts(wd, count, layer->data);
}
else if (layer->type == CD_MDISPS) {
write_mdisps(wd, count, layer->data);
}
else {
CustomData_file_write_info(layer->type, &structname, &structnum);
if (structnum) {
@@ -1186,7 +1208,6 @@ static void write_customdata(WriteData *wd, int count, CustomData *data, int par
static void write_meshs(WriteData *wd, ListBase *idbase)
{
Mesh *mesh;
MultiresLevel *lvl;
mesh= idbase->first;
while(mesh) {
@@ -1212,29 +1233,6 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
write_customdata(wd, mesh->totface, &mesh->fdata, -1, 0);
}
/* Multires data */
writestruct(wd, DATA, "Multires", 1, mesh->mr);
if(mesh->mr) {
lvl= mesh->mr->levels.first;
if(lvl) {
write_customdata(wd, lvl->totvert, &mesh->mr->vdata, -1, 0);
write_customdata(wd, lvl->totface, &mesh->mr->fdata, -1, 0);
writedata(wd, DATA, sizeof(short)*lvl->totedge, mesh->mr->edge_flags);
writedata(wd, DATA, sizeof(char)*lvl->totedge, mesh->mr->edge_creases);
}
for(; lvl; lvl= lvl->next) {
writestruct(wd, DATA, "MultiresLevel", 1, lvl);
writestruct(wd, DATA, "MultiresFace", lvl->totface, lvl->faces);
writestruct(wd, DATA, "MultiresEdge", lvl->totedge, lvl->edges);
writestruct(wd, DATA, "MultiresColFace", lvl->totface, lvl->colfaces);
}
lvl= mesh->mr->levels.last;
if(lvl)
writestruct(wd, DATA, "MVert", lvl->totvert, mesh->mr->verts);
}
/* PMV data */
if(mesh->pv) {
writestruct(wd, DATA, "PartialVisibility", 1, mesh->pv);
@@ -2098,7 +2096,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
write_groups (wd, &mainvar->group);
write_armatures(wd, &mainvar->armature);
write_actions (wd, &mainvar->action);
write_objects (wd, &mainvar->object);
write_objects (wd, &mainvar->object, (current != NULL));
write_materials(wd, &mainvar->mat);
write_textures (wd, &mainvar->tex);
write_meshs (wd, &mainvar->mesh);

View File

@@ -1,59 +0,0 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef MULTIRES_H
#define MULTIRES_H
struct CustomData;
struct EditMesh;
struct Object;
struct MDeformVert;
struct Mesh;
struct MultiresLevel;
struct Multires;
struct uiBlock;
/* For canceling operations that don't work with multires on or on a non-base level */
int multires_test();
int multires_level1_test();
void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned short cy);
void multires_make(void *ob, void *me);
void multires_delete(void *ob, void *me);
void multires_level_to_editmesh(struct Object *ob, struct Mesh *me, const int render);
void multires_finish_mesh_update(struct Object *ob);
void multires_subdivide(void *ob, void *me);
void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me);
void multires_set_level_cb(void *ob, void *me);
void multires_edge_level_update_cb(void *ob, void *me);
int multires_modifier_warning();
#endif

View File

@@ -56,7 +56,6 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -628,14 +627,8 @@ static void make_tfaces(Object *ob)
Mesh *me= ob->data;
if(!me->mtface) {
if(me->mr) {
multires_add_layer(ob, &me->mr->fdata, CD_MTFACE,
CustomData_number_of_layers(&me->fdata, CD_MTFACE));
}
else {
me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
NULL, me->totface);
}
me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT,
NULL, me->totface);
}
}

View File

@@ -66,7 +66,6 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_softbody.h"
@@ -97,7 +96,6 @@ static void waitcursor() {}
static void error() {}
static int pupmenu() {return 0;}
static void key_to_mesh() {}
static int multires_test() {return 0;}
static void adduplicate() {}
@@ -1443,7 +1441,6 @@ void separate_mesh(Scene *scene, Object *obedit)
ListBase edve, eded, edvl;
if(obedit==NULL) return;
if(multires_test()) return;
waitcursor(1);
@@ -1572,8 +1569,6 @@ void separate_material(Scene *scene, Object *obedit)
EditMesh *em;
unsigned char curr_mat;
if(multires_test()) return;
me= obedit->data;
em= me->edit_mesh;
if(me->key) {
@@ -1620,7 +1615,6 @@ void separate_mesh_loose(Scene *scene, Object *obedit)
return;
}
if(multires_test()) return;
waitcursor(1);
/* we are going to abuse the system as follows:
@@ -1830,11 +1824,6 @@ typedef struct EditSelectionC{
int index;
}EditSelectionC;
typedef struct EM_MultiresUndo {
int users;
Multires *mr;
} EM_MultiresUndo;
typedef struct UndoMesh {
EditVertC *verts;
EditEdgeC *edges;
@@ -1845,7 +1834,6 @@ typedef struct UndoMesh {
RetopoPaintData *retopo_paint_data;
char retopo_mode;
CustomData vdata, edata, fdata;
EM_MultiresUndo *mru;
} UndoMesh;
/* for callbacks */
@@ -1865,14 +1853,6 @@ static void free_undoMesh(void *umv)
CustomData_free(&um->vdata, um->totvert);
CustomData_free(&um->edata, um->totedge);
CustomData_free(&um->fdata, um->totface);
if(um->mru) {
--um->mru->users;
if(um->mru->users==0) {
multires_free(um->mru->mr);
um->mru->mr= NULL;
MEM_freeN(um->mru);
}
}
MEM_freeN(um);
}
@@ -1973,25 +1953,6 @@ static void *editMesh_to_undoMesh(void *emv)
// XXX um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
// um->retopo_mode= scene->toolsettings->retopo_mode;
{
Multires *mr= NULL; // XXX old-style multires
UndoMesh *prev= NULL; // XXX undo_editmode_get_prev(obedit);
um->mru= NULL;
if(mr) {
if(prev && prev->mru && prev->mru->mr && prev->mru->mr->current == mr->current) {
um->mru= prev->mru;
++um->mru->users;
}
else {
um->mru= MEM_callocN(sizeof(EM_MultiresUndo), "EM_MultiresUndo");
um->mru->users= 1;
um->mru->mr= multires_copy(mr);
}
}
}
return um;
}
@@ -2101,12 +2062,6 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
// retopo_paint_view_update(G.vd);
// }
{
Mesh *me= NULL; // XXX;
multires_free(me->mr);
me->mr= NULL;
if(um->mru && um->mru->mr) me->mr= multires_copy(um->mru->mr);
}
}
static void *getEditMesh(bContext *C)

View File

@@ -58,7 +58,6 @@
#include "BIF_retopo.h"
#include "ED_mesh.h"
#include "ED_multires.h"
#include "ED_view3d.h"
#include "mesh_intern.h"
@@ -138,8 +137,6 @@ void add_click_mesh(Scene *scene, Object *obedit, EditMesh *em)
float min[3], max[3];
int done= 0;
if(multires_test()) return;
INIT_MINMAX(min, max);
for(v1= em->verts.first;v1; v1=v1->next) {
@@ -610,8 +607,6 @@ void addedgeface_mesh(EditMesh *em)
EditFace *efa;
short amount=0;
if(multires_test()) return;
/* how many selected ? */
if(em->selectmode & SCE_SELECT_EDGE) {
/* in edge mode finding selected vertices means flushing down edge codes... */
@@ -741,8 +736,6 @@ void addedgeface_mesh(EditMesh *em)
void adduplicate_mesh(Scene *scene, Object *obedit, EditMesh *em)
{
if(multires_test()) return;
waitcursor(1);
adduplicateflag(em, SELECT);
@@ -1250,8 +1243,6 @@ void add_primitiveMesh(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em,
/* this function also comes from an info window */
// XXX if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
if (obedit && obedit->type==OB_MESH && multires_test()) return;
/* if editmode exists for other type, it exits */
check_editmode(OB_MESH);

View File

@@ -79,7 +79,6 @@ editmesh_mods.c, UI level access, no geometry changes
#include "RNA_access.h"
#include "RNA_define.h"
#include "ED_multires.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
@@ -3346,8 +3345,6 @@ void editmesh_mark_seam(EditMesh *em, int clear)
{
EditEdge *eed;
// XXX if(multires_level1_test()) return;
/* auto-enable seams drawing */
if(clear==0) {
if(!(G.f & G_DRAWSEAMS)) {
@@ -3391,8 +3388,6 @@ void editmesh_mark_sharp(EditMesh *em, int set)
}
#endif
// XXX if(multires_level1_test()) return;
if(set) {
eed= em->edges.first;
while(eed) {

View File

@@ -78,7 +78,6 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "BMF_Api.h"
#include "ED_multires.h"
#include "ED_mesh.h"
#include "ED_view3d.h"
@@ -143,8 +142,6 @@ void convert_to_triface(EditMesh *em, int direction)
EditFace *efa, *efan, *next;
float fac;
if(multires_test()) return;
efa= em->faces.last;
while(efa) {
next= efa->prev;
@@ -196,8 +193,6 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit) /
struct facesort *vlsortblock, *vsb, *vsb1;
int a, b, test, amount;
if(multires_test()) return 0;
/* flag 128 is cleared, count */
@@ -499,8 +494,6 @@ void xsortvert_flag(bContext *C, int flag)
ListBase tbase;
int i, amount;
if(multires_test()) return;
em_setup_viewcontext(C, &vc);
amount = BLI_countlist(&vc.em->verts);
@@ -540,8 +533,6 @@ void hashvert_flag(EditMesh *em, int flag)
ListBase tbase;
int amount, a, b;
if(multires_test()) return;
/* count */
eve= em->verts.first;
amount= 0;
@@ -600,8 +591,6 @@ void extrude_mesh(Object *obedit, EditMesh *em)
float nor[3]= {0.0, 0.0, 0.0};
short nr, transmode= 0;
if(multires_test()) return;
if(em->selectmode & SCE_SELECT_VERTEX) {
if(G.totvertsel==0) nr= 0;
else if(G.totvertsel==1) nr= 4;
@@ -673,8 +662,6 @@ void extrude_mesh(Object *obedit, EditMesh *em)
void split_mesh(EditMesh *em)
{
if(multires_test()) return;
if(okee(" Split ")==0) return;
waitcursor(1);
@@ -698,8 +685,6 @@ void extrude_repeat_mesh(View3D *v3d, Object *obedit, EditMesh *em, int steps, f
float dvec[3], tmat[3][3], bmat[3][3], nor[3]= {0.0, 0.0, 0.0};
short a;
if(multires_test()) return;
/* dvec */
dvec[0]= v3d->persinv[2][0];
dvec[1]= v3d->persinv[2][1];
@@ -737,8 +722,6 @@ void spin_mesh(View3D *v3d, Object *obedit, EditMesh *em, int steps, float degr,
float phi;
short a,ok;
if(multires_test()) return;
/* imat and center and size */
Mat3CpyMat4(bmat, obedit->obmat);
Mat3Inv(imat,bmat);
@@ -821,8 +804,6 @@ void screw_mesh(Object *obedit, EditMesh *em, int steps, int turns)
EditEdge *eed;
float dvec[3], nor[3];
if(multires_test()) return;
/* clear flags */
eve= em->verts.first;
while(eve) {
@@ -933,8 +914,6 @@ void delete_mesh(Object *obedit, EditMesh *em)
int count;
char *str="Erase";
if(multires_test()) return;
event= pupmenu("Erase %t|Vertices%x10|Edges%x1|Faces%x2|All%x3|Edges & Faces%x4|Only Faces%x5|Edge Loop%x6");
if(event<1) return;
@@ -1078,8 +1057,6 @@ void fill_mesh(EditMesh *em)
short ok;
if(em==NULL) return;
if(multires_test()) return;
waitcursor(1);
/* copy all selected vertices */
@@ -2372,8 +2349,6 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float rad, int beaut
ModifierData *md= obedit->modifiers.first;
int ctrl= 0; // XXX
if(multires_test()) return;
//Set faces f1 to 0 cause we need it later
for(ef=em->faces.first;ef;ef = ef->next) ef->f1 = 0;
for(eve=em->verts.first; eve; eve=eve->next) {
@@ -2930,8 +2905,6 @@ void beauty_fill(EditMesh *em)
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
int totedge, ok, notbeauty=8, onedone, vindex[4];
if(multires_test()) return;
/* - all selected edges with two faces
* - find the faces: store them in edges (using datablock)
* - per edge: - test convex
@@ -3238,9 +3211,6 @@ void join_triangles(EditMesh *em)
float limit = 0.0f; // XXX scene->toolsettings->jointrilimit;
int i, ok, totedge=0, totseledge=0, complexedges, vindex[4];
/*test for multi-resolution data*/
if(multires_test()) return;
/*if we take a long time on very dense meshes we want waitcursor to display*/
waitcursor(1);
@@ -5586,8 +5556,6 @@ int collapseEdges(EditMesh *em)
mergecount = 0;
if(multires_test()) return 0;
build_edgecollection(em, &allcollections);
groupcount = BLI_countlist(&allcollections);
@@ -5646,8 +5614,6 @@ int merge_firstlast(EditMesh *em, int first, int uvmerge)
EditVert *eve,*mergevert;
EditSelection *ese;
if(multires_test()) return 0;
/* do sanity check in mergemenu in edit.c ?*/
if(first == 0){
ese = em->selected.last;
@@ -5681,8 +5647,6 @@ int merge_target(EditMesh *em, int target, int uvmerge)
{
EditVert *eve;
if(multires_test()) return 0;
if(target) snap_sel_to_curs();
else snap_to_center();

View File

@@ -98,7 +98,6 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -2285,9 +2284,6 @@ void ED_object_exit_editmode(bContext *C, int flag)
if(freedata) obedit= NULL;
scene->obedit= obedit; // XXX for context
if(ob->type==OB_MESH && get_mesh(ob)->mr)
multires_edge_level_update(ob, get_mesh(ob));
/* also flush ob recalc, doesn't take much overhead, but used for particles */
DAG_object_flush_update(scene, ob, OB_RECALC_OB|OB_RECALC_DATA);

View File

@@ -74,7 +74,8 @@ typedef struct CustomData {
#define CD_MLOOPUV 16
#define CD_MLOOPCOL 17
#define CD_TANGENT 18
#define CD_NUMTYPES 19
#define CD_MDISPS 19
#define CD_NUMTYPES 20
/* fake type, derivedmesh wants CustomDataMask for weightpaint too, is not stored */
#define CD_WEIGHTPAINT 30
@@ -98,6 +99,7 @@ typedef struct CustomData {
#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
#define CD_MASK_TANGENT (1 << CD_TANGENT)
#define CD_MASK_MDISPS (1 << CD_MDISPS)
/* derivedmesh wants CustomDataMask for weightpaint too, is not customdata though */
#define CD_MASK_WEIGHTPAINT (1 << CD_WEIGHTPAINT)

View File

@@ -117,7 +117,14 @@ typedef struct OrigSpaceFace {
float uv[4][2];
} OrigSpaceFace;
/* Multiresolution modeling */
typedef struct MDisps {
/* Strange bug in SDNA: if disps pointer comes first, it fails to see totdisp */
int totdisp;
char pad[4];
float (*disps)[3];
} MDisps;
/** Multires structs kept for compatibility with old files **/
typedef struct MultiresCol {
float a, r, g, b;
} MultiresCol;
@@ -143,15 +150,9 @@ typedef struct MultiresLevel {
MultiresColFace *colfaces;
MultiresEdge *edges;
/* Temporary connectivity data */
char *edge_boundary_states;
struct ListBase *vert_edge_map;
struct ListBase *vert_face_map;
struct MultiresMapNode *map_mem;
unsigned int totvert, totface, totedge, pad;
/* Kept for compatibility with older files */
/* Kept for compatibility with even older files */
MVert *verts;
} MultiresLevel;
@@ -169,6 +170,8 @@ typedef struct Multires {
char *edge_creases;
} Multires;
/** End Multires **/
typedef struct PartialVisibility {
unsigned int *vert_map; /* vert_map[Old Index]= New Index */
int *edge_map; /* edge_map[Old Index]= New Index, -1= hidden */
@@ -266,7 +269,4 @@ typedef struct PartialVisibility {
#define TF_PIN3 64
#define TF_PIN4 128
/* multires->flag */
#define MULTIRES_NO_RENDER 1
#endif

View File

@@ -39,6 +39,7 @@ typedef enum ModifierType {
eModifierType_Fluidsim,
eModifierType_Mask,
eModifierType_SimpleDeform,
eModifierType_Multires,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -517,6 +518,17 @@ typedef struct ExplodeModifierData {
float protect;
} 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;
} MultiresModifierData;
typedef struct FluidsimModifierData {
ModifierData modifier;

View File

@@ -30,10 +30,194 @@
#include "rna_internal.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#ifdef RNA_RUNTIME
#endif
static float rna_IK_Min_X_get(PointerRNA *ptr)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
return pchan->limitmin[0];
}
static float rna_IK_Min_Y_get(PointerRNA *ptr)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
return pchan->limitmin[1];
}
static float rna_IK_Min_Z_get(PointerRNA *ptr)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
return pchan->limitmin[2];
}
static void rna_IK_Min_X_set(PointerRNA *ptr, float value)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
pchan->limitmin[0] = value;
}
static void rna_IK_Min_Y_set(PointerRNA *ptr, float value)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
pchan->limitmin[1] = value;
}
static void rna_IK_Min_Z_set(PointerRNA *ptr, float value)
{
bPoseChannel *pchan= (bPoseChannel*)ptr->id.data;
pchan->limitmin[2] = value;
}
#else
/* users shouldn't be editing pose channel data directly -- better to set ipos and let blender calc pose_channel stuff */
/* it's going to be weird for users to find IK flags and other such here, instead of in bone where they would expect them
-- is there any way to put a doc in bone, pointing them here? */
static void RNA_def_pose_channel(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_iklimit_items[] = {
{BONE_IK_NO_XDOF, "IKNOXDOF", "No X DoF", "Prevent motion around X axis."},
{BONE_IK_NO_YDOF, "IKNOYDOF", "No Y DoF", "Prevent motion around Y axis."},
{BONE_IK_NO_ZDOF, "IKNOZDOF", "No Z DoF", "Prevent motion around Z axis."},
{BONE_IK_XLIMIT, "IKXLIMIT", "X Limit", "Limit motion around X axis."},
{BONE_IK_YLIMIT, "IKYLIMIT", "Y Limit", "Limit motion around Y axis."},
{BONE_IK_ZLIMIT, "IKZLIMIT", "Z Limit", "Limit motion around Z axis."},
{0, NULL, NULL, NULL}};
srna= RNA_def_struct(brna, "bPoseChannel", NULL);
RNA_def_struct_ui_text(srna, "Pose Channel", "Member of the 'Pose' type.");
/* cosntraints (collection) */
prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "constraints", NULL);
RNA_def_property_struct_type(prop, "bConstraint");
RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel.");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "ikflag", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_iklimit_items);
RNA_def_property_ui_text(prop, "IK Limits", "");
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "selectflag", BONE_SELECTED);
RNA_def_property_ui_text(prop, "Selected", "");
prop= RNA_def_property(srna, "protected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "protectflag", POSE_LOCKED);
RNA_def_property_ui_text(prop, "Protected", "Protect channel from being transformed.");
prop= RNA_def_property(srna, "action_group_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "agrp_index");
RNA_def_property_ui_text(prop, "Action Group Index", "Action Group this pose channel belogs to (0=no group).");
prop= RNA_def_property(srna, "path_start_frame", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pathsf");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation Start Frame", "Starting frame of range of frames to use for Bone Path calculations.");
prop= RNA_def_property(srna, "path_end_frame", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pathef");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation End Frame", "End frame of range of frames to use for Bone Path calculations.");
prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Bone");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Bone", "Bone associated with this Pose Channel.");
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "bPoseChannel");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent of this pose channel.");
prop= RNA_def_property(srna, "child", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "bPoseChannel");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Child of this pose channel.");
prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "chan_mat");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");
/* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */
prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "pose_mat");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel.");
prop= RNA_def_property(srna, "constraint_inverse_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "constinv");
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position.");
prop= RNA_def_property(srna, "pose_head", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Head Position", "Location of head of the channel's bone.");
prop= RNA_def_property(srna, "pose_tail", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Tail Position", "Location of tail of the channel's bone.");
prop= RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmin");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Min_X_get", "rna_IK_Min_X_set", NULL);
RNA_def_property_ui_text(prop, "IK Minimum Limit X", "Minimum X angle for IK Limit");
prop= RNA_def_property(srna, "ik_min_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmin");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Min_Y_get", "rna_IK_Min_Y_set", NULL);
RNA_def_property_ui_text(prop, "IK Minimum Limit Y", "Minimum Y angle for IK Limit");
prop= RNA_def_property(srna, "ik_min_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmin");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Min_Z_get", "rna_IK_Min_Z_set", NULL);
RNA_def_property_ui_text(prop, "IK Minimum Limit Z", "Minimum Z angle for IK Limit");
prop= RNA_def_property(srna, "ik_max_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmax");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Max_X_get", "rna_IK_Max_X_set", NULL);
RNA_def_property_ui_text(prop, "IK Maximum Limit X", "Maximum X angle for IK Limit");
prop= RNA_def_property(srna, "ik_max_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmax");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Max_Y_get", "rna_IK_Max_Y_set", NULL);
RNA_def_property_ui_text(prop, "IK Maximum Limit Y", "Maximum Y angle for IK Limit");
prop= RNA_def_property(srna, "ik_max_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limitmax");
RNA_def_property_range(prop, -180.0f, 180.0f);
RNA_def_property_float_funcs(prop, "rna_IK_Max_Z_get", "rna_IK_Max_Z_set", NULL);
RNA_def_property_ui_text(prop, "IK Maximum Limit Z", "Maximum Z angle for IK Limit");
// float limitmin[3], limitmax[3]; /* DOF constraint */
// float stiffness[3]; /* DOF stiffness */
// float ikstretch;
// float *path; /* totpath x 3 x float */
// struct Object *custom; /* draws custom object instead of this channel */
};
void RNA_def_action(BlenderRNA *brna)
{
@@ -45,3 +229,5 @@ void RNA_def_action(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Action", "DOC_BROKEN");
}
#endif

View File

@@ -505,7 +505,6 @@ typedef struct LampRen {
#define R_LAMPHALO 8
#define R_GLOB_NOPUNOFLIP 16
#define R_NEED_TANGENT 32
#define R_SKIP_MULTIRES 64
#define R_BAKE_TRACE 128
#define R_BAKING 256

View File

@@ -99,7 +99,6 @@
#include "IMB_imbuf_types.h"
#include "envmap.h"
//XXX #include "multires.h"
#include "occlusion.h"
#include "render_types.h"
#include "rendercore.h"
@@ -3077,13 +3076,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if(need_orco)
mask |= CD_MASK_ORCO;
if(me->mr) {
if(re->flag & R_SKIP_MULTIRES)
me->mr->flag |= MULTIRES_NO_RENDER;
else
me->mr->flag &= ~MULTIRES_NO_RENDER;
}
dm= mesh_create_derived_render(re->scene, ob, mask);
if(dm==NULL) return; /* in case duplicated object fails? */
@@ -5432,8 +5424,6 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
re->flag |= R_GLOB_NOPUNOFLIP;
re->flag |= R_BAKING;
re->excludeob= actob;
if(type == RE_BAKE_LIGHT)
re->flag |= R_SKIP_MULTIRES;
if(actob)
re->flag |= R_BAKE_TRACE;