diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-09-15 19:32:09 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-09-15 19:32:09 +0400 |
commit | 86b474a344c452c47666af82c6a8077bea0635e2 (patch) | |
tree | 6abdc219e5ad7240d75c3c7af3ec5009648cc55a /source/blender | |
parent | 2601aa9cf37bed73b2808536f05506f367d87952 (diff) |
made subsurf object mode conversion faster, though still needs a bit more work
Diffstat (limited to 'source/blender')
19 files changed, 262 insertions, 184 deletions
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index 482a6c4aff4..13219c8bb30 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -65,7 +65,7 @@ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me); /* Copies the given DerivedMesh with verts, faces & edges stored as * custom element data. */ -struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm); +struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm, int faces_from_tessfaces); /* creates a CDDerivedMesh with the same layer stack configuration as the * given DerivedMesh and containing the requested numbers of elements. diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 18fbc1a8fea..530012e7aa9 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -194,7 +194,7 @@ #define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i)) #define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i)) -/*little pointer array macro library. example of usage: +/*little array macro library. example of usage: int *arr = NULL; V_DECLARE(arr); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a59ae7e5424..d37a0329582 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -366,16 +366,7 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target) { DMFaceIter *iter = source->newFaceIter(source); DMLoopIter *liter; - int totloop = 0; - - for (; !iter->done; iter->step(iter)) { - liter = iter->getLoopsIter(iter); - for (; !liter->done; liter->step(liter)) { - totloop++; - } - } - - iter->free(iter); + int totloop = source->numLoopData; dm_add_polys_from_iter(&target->loopData, &target->polyData, source, totloop); @@ -1821,6 +1812,8 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) } CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop); + + dfiter->free(dfiter); } /* new value for useDeform -1 (hack for the gameengine): @@ -1965,7 +1958,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* apply vertex coordinates or build a DerivedMesh as necessary */ if(dm) { if(deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); + DerivedMesh *tdm = CDDM_copy(dm, 0); dm->release(dm); dm = tdm; @@ -2039,7 +2032,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos * DerivedMesh then we need to build one. */ if(dm && deformedVerts) { - finaldm = CDDM_copy(dm); + finaldm = CDDM_copy(dm, 0); dm->release(dm); @@ -2180,7 +2173,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D /* apply vertex coordinates or build a DerivedMesh as necessary */ if(dm) { if(deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); + DerivedMesh *tdm = CDDM_copy(dm, 0); if(!(cage_r && dm == *cage_r)) dm->release(dm); dm = tdm; @@ -2189,7 +2182,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } else if(cage_r && dm == *cage_r) { /* dm may be changed by this modifier, so we need to copy it */ - dm = CDDM_copy(dm); + dm = CDDM_copy(dm, 0); } } else { @@ -2242,7 +2235,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if(cage_r && i == cageIndex) { if(dm && deformedVerts) { - *cage_r = CDDM_copy(dm); + *cage_r = CDDM_copy(dm, 0); CDDM_apply_vert_coords(*cage_r, deformedVerts); } else if(dm) { *cage_r = dm; @@ -2261,7 +2254,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D * then we need to build one. */ if(dm && deformedVerts) { - *final_r = CDDM_copy(dm); + *final_r = CDDM_copy(dm, 0); if(!(cage_r && dm == *cage_r)) dm->release(dm); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 773f0d1eb79..5cc64c9d3e2 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1410,7 +1410,7 @@ DMFaceIter *cdDM_newFaceIter(DerivedMesh *source) return (DMFaceIter*) iter; } -DerivedMesh *CDDM_copy(DerivedMesh *source) +DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces) { CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm"); DerivedMesh *dm = &cddm->dm; @@ -1438,8 +1438,10 @@ DerivedMesh *CDDM_copy(DerivedMesh *source) CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges); CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces); - DM_DupPolys(source, dm); - //CDDM_tessfaces_to_faces(dm); + if (!faces_from_tessfaces) + DM_DupPolys(source, dm); + else + CDDM_tessfaces_to_faces(dm); cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP); cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index c3a3f57cd40..2d330748772 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -432,7 +432,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, clmd->scene= scene; /* nice to pass on later :) */ framenr= (int)scene->r.cfra; cache= clmd->point_cache; - result = CDDM_copy(dm); + result = CDDM_copy(dm, 0); BKE_ptcache_id_from_cloth(&pid, ob, clmd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index bda204409b2..814b85dad2a 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -922,13 +922,29 @@ static void customData_update_offsets(CustomData *data); static CustomDataLayer *customData_add_layer__internal(CustomData *data, int type, int alloctype, void *layerdata, int totelem, const char *name); +void customData_update_typemap(CustomData *data) +{ + int i, lasttype = -1; + + for (i=0; i<CD_NUMTYPES; i++) { + data->typemap[i] = -1; + } + + for (i=0; i<data->totlayer; i++) { + if (data->layers[i].type != lasttype) { + data->typemap[data->layers[i].type] = i; + } + lasttype = data->layers[i].type; + } +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { const LayerTypeInfo *typeInfo; CustomDataLayer *layer, *newlayer; int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0; - + for(i = 0; i < source->totlayer; ++i) { layer = &source->layers[i]; typeInfo = layerType_getInfo(layer->type); @@ -964,6 +980,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, newlayer->active_mask = lastmask; } } + + customData_update_typemap(dest); } void CustomData_copy(const struct CustomData *source, struct CustomData *dest, @@ -1041,11 +1059,12 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, char *nam int CustomData_get_active_layer_index(const CustomData *data, int type) { - int i; + if (!data->totlayer) + return -1; - for(i=0; i < data->totlayer; ++i) - if(data->layers[i].type == type) - return i + data->layers[i].active; + if (data->typemap[type] != -1) { + return data->typemap[type] + data->layers[data->typemap[type]].active; + } return -1; } @@ -1307,6 +1326,7 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype, layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, typeInfo->defaultname); + customData_update_typemap(data); if(layer) return layer->data; @@ -1322,6 +1342,7 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype, layer = customData_add_layer__internal(data, type, alloctype, layerdata, totelem, name); + customData_update_typemap(data); if(layer) return layer->data; @@ -1360,6 +1381,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); + customData_update_typemap(data); return 1; } @@ -1644,7 +1666,7 @@ void *CustomData_get_n(const CustomData *data, int type, int index, int n) int offset; /* get the layer index of the first layer of type */ - layer_index = CustomData_get_layer_index(data, type); + layer_index = data->typemap[type]; if(layer_index < 0) return NULL; offset = layerType_getInfo(type)->size * index; @@ -1996,7 +2018,7 @@ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *l } else if(fdata->layers[i].type == CD_MCOL) CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), totloop); - } + } } void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){ int i; diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 214363b4c79..0024f84d8fb 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -226,7 +226,7 @@ DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Scene *scene, Ob } } - result = CDDM_copy(dm); + result = CDDM_copy(dm, 0); if(result) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index bfd92ff4d9f..35e2989650a 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -268,7 +268,7 @@ void free_dverts(MDeformVert *dvert, int totvert) /* Free any special data from the verts */ for (i=0; i<totvert; i++){ - if (dvert[i].dw) MEM_freeN (dvert[i].dw); + if (dvert[i].dw) BLI_cellalloc_free (dvert[i].dw); } MEM_freeN (dvert); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 6eacf802e63..496cc2b8224 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -2274,7 +2274,7 @@ BM_INLINE EdgeData *edge_get_first(VertUser *vu) DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) { - DerivedMesh *cddm = CDDM_copy(dm); + DerivedMesh *cddm = CDDM_copy(dm, 0); MEdge *medge; V_DECLARE(medge); MLoop *mloop, *ml, *prevl; @@ -2954,7 +2954,7 @@ static void displaceModifier_deformVerts( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); else return; @@ -2973,7 +2973,7 @@ static void displaceModifier_deformVertsEM( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else dm = CDDM_from_BMEditMesh(editData, ob->data); CDDM_apply_vert_coords(dm, vertexCos); @@ -3639,7 +3639,7 @@ static void smoothModifier_deformVerts( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else dm = CDDM_from_mesh(ob->data, ob); CDDM_apply_vert_coords(dm, vertexCos); @@ -3657,7 +3657,7 @@ static void smoothModifier_deformVertsEM( { DerivedMesh *dm; - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else dm = CDDM_from_BMEditMesh(editData, ob->data); CDDM_apply_vert_coords(dm, vertexCos); @@ -4647,7 +4647,7 @@ static void waveModifier_deformVertsEM( if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM)) dm = derivedData; - else if(derivedData) dm = CDDM_copy(derivedData); + else if(derivedData) dm = CDDM_copy(derivedData, 0); else dm = CDDM_from_BMEditMesh(editData, ob->data); if(wmd->flag & MOD_WAVE_NORM) { @@ -5259,7 +5259,7 @@ static void collisionModifier_deformVerts( MVert *tempVert = NULL; /* if possible use/create DerivedMesh */ - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); if(!ob->pd) @@ -5427,7 +5427,7 @@ static void surfaceModifier_deformVerts( surmd->dm->release(surmd->dm); /* if possible use/create DerivedMesh */ - if(derivedData) surmd->dm = CDDM_copy(derivedData); + if(derivedData) surmd->dm = CDDM_copy(derivedData, 0); else surmd->dm = get_original_dm(md->scene, ob, NULL, 0); if(!ob->pd) @@ -5686,7 +5686,7 @@ static void particleSystemModifier_deformVerts( } /* make new dm */ - psmd->dm=CDDM_copy(dm); + psmd->dm=CDDM_copy(dm, 0); CDDM_apply_vert_coords(psmd->dm, vertexCos); CDDM_calc_normals(psmd->dm); @@ -7361,7 +7361,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) { - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); else if(ob->type==OB_LATTICE) dm = NULL; else return; @@ -7386,7 +7386,7 @@ static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, BMEdi if(dataMask) { - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_BMEditMesh(editData, ob->data); else if(ob->type==OB_LATTICE) dm = NULL; else return; @@ -7475,7 +7475,7 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) { - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); else if(ob->type==OB_LATTICE) dm = NULL; else return; @@ -7502,7 +7502,7 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, BME /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) { - if(derivedData) dm = CDDM_copy(derivedData); + if(derivedData) dm = CDDM_copy(derivedData, 0); else if(ob->type==OB_MESH) dm = CDDM_from_BMEditMesh(editData, ob->data); else if(ob->type==OB_LATTICE) dm = NULL; else return; diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index d281fb9bd2a..3026fc9d628 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -598,7 +598,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, BMO_Finish_Op(bm, &op); BMEdit_RecalcTesselation(em); - result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL)); + result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL), 0); BMEdit_Free(em); MEM_freeN(em); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9aaff82de84..47b37c10689 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -606,7 +606,7 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float data->totchildcache= psys->totchildcache; if(psmd->dm) - data->dm= CDDM_copy(psmd->dm); + data->dm= CDDM_copy(psmd->dm, 0); data->totdmvert= psmd->totdmvert; data->totdmedge= psmd->totdmedge; data->totdmface= psmd->totdmface; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 888ba7c9a5e..91de57024e6 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -774,7 +774,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); - smd->coll->dm = CDDM_copy(dm); + smd->coll->dm = CDDM_copy(dm, 0); // rigid movement support Mat4CpyMat4(smd->coll->mat_old, smd->coll->mat); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e93066aafac..73893760f61 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -55,11 +55,11 @@ #include "BLI_blenlib.h" #include "BLI_editVert.h" - #include "BLI_arithb.h" #include "BLI_linklist.h" #include "BLI_memarena.h" #include "BLI_edgehash.h" +#include "PIL_time.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -85,6 +85,10 @@ struct CCGDerivedMesh { struct {int startVert; int startEdge; CCEdge *edge;} *edgeMap; struct {int startVert; int startEdge; int startFace; CCFace *face;} *faceMap; + /*maps final faces to faceMap faces*/ + int *reverseFaceMap; + + EdgeHash *ehash; }; typedef struct CCGDerivedMesh CCGDerivedMesh; @@ -183,7 +187,7 @@ static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) { } } -static int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) { +BM_INLINE int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) { int faceBase = *((int*) CCS_getFaceUserData(ss, f)); int numVerts = CCS_getFaceNumVerts(f); @@ -558,9 +562,12 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, DerivedMesh *dm, MultiresSubsurf *ms) { DerivedMesh *cgdm, *result; + double curt = PIL_check_seconds_timer(); cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); - result = CDDM_copy(cgdm); + result = CDDM_copy(cgdm, 0); + + printf("subsurf conversion time: %.6lf\n", PIL_check_seconds_timer() - curt); cgdm->needsFree = 1; cgdm->release(cgdm); @@ -1282,10 +1289,10 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS); memset(mf, 0, sizeof(*mf)); + if (faceNum >= cgdm->dm.numFaceData) + return; - i = 0; - while(i < lastface && faceNum >= cgdm->faceMap[i + 1].startFace) - ++i; + i = cgdm->reverseFaceMap[faceNum]; f = cgdm->faceMap[i].face; numVerts = CCS_getFaceNumVerts(f); @@ -1456,7 +1463,7 @@ typedef struct cgdm_loopIter { typedef struct cgdm_faceIter { DMFaceIter head; CCGDerivedMesh *cgdm; - MFace mface; + MFace *mface, *mf; cgdm_loopIter liter; EdgeHash *ehash; /*edge map for populating loopiter->eindex*/ @@ -1478,10 +1485,10 @@ void cgdm_faceIterStep(void *self) return; }; - cgdm_getFinalFace((DerivedMesh*)fiter->cgdm, fiter->head.index, &fiter->mface); + fiter->mf++; - fiter->head.flags = fiter->mface.flag; - fiter->head.mat_nr = fiter->mface.mat_nr; + fiter->head.flags = fiter->mface->flag; + fiter->head.mat_nr = fiter->mface->mat_nr; fiter->head.len = 4; } @@ -1511,25 +1518,25 @@ void cgdm_loopIterStep(void *self) switch (i) { case 0: - v1 = liter->fiter->mface.v1; - v2 = liter->fiter->mface.v2; + v1 = liter->fiter->mf->v1; + v2 = liter->fiter->mf->v2; break; case 1: - v1 = liter->fiter->mface.v2; - v2 = liter->fiter->mface.v3; + v1 = liter->fiter->mf->v2; + v2 = liter->fiter->mf->v3; break; case 2: - v1 = liter->fiter->mface.v3; - v2 = liter->fiter->mface.v4; + v1 = liter->fiter->mf->v3; + v2 = liter->fiter->mf->v4; break; case 3: - v1 = liter->fiter->mface.v4; - v2 = liter->fiter->mface.v1; + v1 = liter->fiter->mf->v4; + v2 = liter->fiter->mf->v1; break; } liter->head.vindex = v1; - liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->ehash, v1, v2)); + liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->cgdm->ehash, v1, v2)); liter->lindex += 1; cgdm_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v); @@ -1567,7 +1574,8 @@ DMLoopIter *cgdm_faceIterGetLIter(void *self) void cgdm_faceIterFree(void *vfiter) { cgdm_faceIter *fiter = vfiter; - BLI_edgehash_free(fiter->ehash, NULL); + + MEM_freeN(fiter->mface); MEM_freeN(fiter); } @@ -1579,12 +1587,8 @@ DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm) fiter->cgdm = dm; fiter->liter.cgdm = dm; - fiter->ehash = BLI_edgehash_new(); - - for (i=0; i<totedge; i++) { - cgdm_getFinalEdge(dm, i, &medge); - BLI_edgehash_insert(fiter->ehash, medge.v1, medge.v2, SET_INT_IN_POINTER(i)); - } + fiter->mface = fiter->mf = dm->dupTessFaceArray(dm); + fiter->mf--; fiter->head.free = cgdm_faceIterFree; fiter->head.step = cgdm_faceIterStep; @@ -2547,6 +2551,8 @@ static void cgdm_release(DerivedMesh *dm) { MEM_freeN(cgdm->vertMap); MEM_freeN(cgdm->edgeMap); MEM_freeN(cgdm->faceMap); + MEM_freeN(cgdm->reverseFaceMap); + BLI_edgehash_free(cgdm->ehash, NULL); MEM_freeN(cgdm); } } @@ -2638,14 +2644,14 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, WeightTable wtable = {0}; /* MVert *mvert = NULL; - as yet unused */ MCol *mcol; - MEdge *medge = NULL; + MEdge *medge = NULL, medge2; MFace *mface = NULL; MPoly *mpoly = NULL; DM_from_template(&cgdm->dm, dm, CCS_getNumFinalVerts(ss), CCS_getNumFinalEdges(ss), CCS_getNumFinalFaces(ss), - CCS_getNumFinalFaces(ss)*4+1, + CCS_getNumFinalFaces(ss)*4, CCS_getNumFinalFaces(ss)); DM_add_tessface_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL); DM_add_face_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL); @@ -2738,6 +2744,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, } CCFIter_free(fi); + cgdm->reverseFaceMap = MEM_callocN(sizeof(int)*CCS_getNumFinalFaces(ss), "reverseFaceMap"); + edgeSize = CCS_getEdgeSize(ss); gridSize = CCS_getGridSize(ss); gridFaces = gridSize - 1; @@ -2884,6 +2892,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, *faceOrigIndex = origIndex; *polyOrigIndex = origIndex; + cgdm->reverseFaceMap[faceNum] = index; + faceOrigIndex++; polyOrigIndex++; faceNum++; @@ -2972,6 +2982,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, V_FREE(loopidx); free_ss_weights(&wtable); + cgdm->ehash = BLI_edgehash_new(); + for (i=0; i<cgdm->dm.numEdgeData; i++) { + cgdm_getFinalEdge((DerivedMesh*)cgdm, i, &medge2); + BLI_edgehash_insert(cgdm->ehash, medge2.v1, medge2.v2, SET_INT_IN_POINTER(i)); + } #if 0 for(index = 0; index < totface; ++index) { CCFace *f = cgdm->faceMap[index].face; @@ -3273,7 +3288,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( DerivedMesh *cddm = NULL, *result; if (!CDDM_Check(dm)) { - cddm = CDDM_copy(dm); + cddm = CDDM_copy(dm, 0); dm = cddm; } diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index abbd17c3635..f82004813cb 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -32,6 +32,10 @@ #ifndef BLI_EDGEHASH_H #define BLI_EDGEHASH_H +#include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" +#include "BLI_mempool.h" + struct EdgeHash; struct EdgeHashIterator; typedef struct EdgeHash EdgeHash; @@ -45,22 +49,22 @@ void BLI_edgehash_free (EdgeHash *eh, EdgeHashFreeFP valfreefp); /* Insert edge (v0,v1) into hash with given value, does * not check for duplicates. */ -void BLI_edgehash_insert (EdgeHash *eh, int v0, int v1, void *val); +//void BLI_edgehash_insert (EdgeHash *eh, int v0, int v1, void *val); /* Return value for given edge (v0,v1), or NULL if * if key does not exist in hash. (If need exists * to differentiate between key-value being NULL and * lack of key then see BLI_edgehash_lookup_p(). */ -void* BLI_edgehash_lookup (EdgeHash *eh, int v0, int v1); +//void* BLI_edgehash_lookup (EdgeHash *eh, int v0, int v1); /* Return pointer to value for given edge (v0,v1), * or NULL if key does not exist in hash. */ -void** BLI_edgehash_lookup_p (EdgeHash *eh, int v0, int v1); +//void** BLI_edgehash_lookup_p (EdgeHash *eh, int v0, int v1); /* Return boolean true/false if edge (v0,v1) in hash. */ -int BLI_edgehash_haskey (EdgeHash *eh, int v0, int v1); +//int BLI_edgehash_haskey (EdgeHash *eh, int v0, int v1); /* Return number of keys in hash. */ int BLI_edgehash_size (EdgeHash *eh); @@ -95,5 +99,99 @@ void BLI_edgehashIterator_step (EdgeHashIterator *ehi); /* Determine if an iterator is done. */ int BLI_edgehashIterator_isDone (EdgeHashIterator *ehi); +/**************inlined code************/ +static unsigned int hashsizes[]= { + 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, + 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, + 268435459 +}; + +#define EDGEHASH(v0,v1) ((v0*39)^(v1*31)) + +/***/ + +typedef struct EdgeEntry EdgeEntry; +struct EdgeEntry { + EdgeEntry *next; + int v0, v1; + void *val; +}; + +struct EdgeHash { + EdgeEntry **buckets; + BLI_mempool *epool; + int nbuckets, nentries, cursize; +}; + + +BM_INLINE void BLI_edgehash_insert(EdgeHash *eh, int v0, int v1, void *val) { + unsigned int hash; + EdgeEntry *e= BLI_mempool_alloc(eh->epool); + + if (v1<v0) { + v0 ^= v1; + v1 ^= v0; + v0 ^= v1; + } + hash = EDGEHASH(v0,v1)%eh->nbuckets; + + e->v0 = v0; + e->v1 = v1; + e->val = val; + e->next= eh->buckets[hash]; + eh->buckets[hash]= e; + + if (++eh->nentries>eh->nbuckets*3) { + EdgeEntry *e, **old= eh->buckets; + int i, nold= eh->nbuckets; + + eh->nbuckets= hashsizes[++eh->cursize]; + eh->buckets= MEM_mallocN(eh->nbuckets*sizeof(*eh->buckets), "eh buckets"); + BMEMSET(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); + + for (i=0; i<nold; i++) { + for (e= old[i]; e;) { + EdgeEntry *n= e->next; + + hash= EDGEHASH(e->v0,e->v1)%eh->nbuckets; + e->next= eh->buckets[hash]; + eh->buckets[hash]= e; + + e= n; + } + } + + MEM_freeN(old); + } +} + +BM_INLINE void** BLI_edgehash_lookup_p(EdgeHash *eh, int v0, int v1) { + unsigned int hash; + EdgeEntry *e; + + if (v1<v0) { + v0 ^= v1; + v1 ^= v0; + v0 ^= v1; + } + hash = EDGEHASH(v0,v1)%eh->nbuckets; + for (e= eh->buckets[hash]; e; e= e->next) + if (v0==e->v0 && v1==e->v1) + return &e->val; + + return NULL; +} + +BM_INLINE void* BLI_edgehash_lookup(EdgeHash *eh, int v0, int v1) { + void **value_p = BLI_edgehash_lookup_p(eh,v0,v1); + + return value_p?*value_p:NULL; +} + +BM_INLINE int BLI_edgehash_haskey(EdgeHash *eh, int v0, int v1) { + return BLI_edgehash_lookup_p(eh, v0, v1)!=NULL; +} + #endif diff --git a/source/blender/blenlib/intern/BLI_cellalloc.c b/source/blender/blenlib/intern/BLI_cellalloc.c index 85ef34900c9..f45916f1663 100644 --- a/source/blender/blenlib/intern/BLI_cellalloc.c +++ b/source/blender/blenlib/intern/BLI_cellalloc.c @@ -29,6 +29,10 @@ /* Simple, fast memory allocator that uses many BLI_mempools for allocation. this is meant to be used by lots of relatively small objects. + + this is a temporary and inperfect fix for performance issues caused + by vgroups. it needs to be replaced with something better, preferably + integrated into guardedalloc. */ #include "MEM_guardedalloc.h" @@ -65,6 +69,12 @@ void *BLI_cellalloc_malloc(long size, char *tag) if (!slot) return NULL; + + /*stupid optimization trick. + round up to nearest 16 bytes boundary. + this is to reduce the number of potential + pools. hopefully it'll help.*/ + slot += 16 - (slot & 15); if (slot >= totpool) { void *tmp; @@ -103,7 +113,8 @@ void *BLI_cellalloc_calloc(long size, char *tag) void BLI_cellalloc_free(void *mem) { MemHeader *memh = mem; - + int slot; + if (!memh) return; @@ -113,9 +124,12 @@ void BLI_cellalloc_free(void *mem) return; } - if (memh->size > 0 && memh->size+sizeof(MemHeader) < totpool) { + slot = memh->size + sizeof(MemHeader); + slot += 16 - (slot & 15); + + if (memh->size > 0 && slot < totpool) { BLI_remlink(&active_mem, memh); - BLI_mempool_free(pools[memh->size+sizeof(MemHeader)], memh); + BLI_mempool_free(pools[slot], memh); celltotblock--; } else { printf("Error in BLI_cellalloc: attempt to free corrupted block.\n"); diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index cdc952e7b04..a7b2ae9edeb 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -37,32 +37,6 @@ /***/ -static unsigned int hashsizes[]= { - 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, - 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, - 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, - 268435459 -}; - -#define EDGEHASH(v0,v1) ((v0*39)^(v1*31)) - -/***/ - -typedef struct Entry Entry; -struct Entry { - Entry *next; - int v0, v1; - void *val; -}; - -struct EdgeHash { - Entry **buckets; - BLI_mempool *epool; - int nbuckets, nentries, cursize; -}; - -/***/ - EdgeHash *BLI_edgehash_new(void) { EdgeHash *eh= MEM_callocN(sizeof(*eh), "EdgeHash"); eh->cursize= 0; @@ -70,79 +44,11 @@ EdgeHash *BLI_edgehash_new(void) { eh->nbuckets= hashsizes[eh->cursize]; eh->buckets= MEM_callocN(eh->nbuckets*sizeof(*eh->buckets), "eh buckets 2"); - eh->epool = BLI_mempool_create(sizeof(Entry), 512, 512); + eh->epool = BLI_mempool_create(sizeof(EdgeEntry), 512, 512); return eh; } -void BLI_edgehash_insert(EdgeHash *eh, int v0, int v1, void *val) { - unsigned int hash; - Entry *e= BLI_mempool_alloc(eh->epool); - - if (v1<v0) { - v0 ^= v1; - v1 ^= v0; - v0 ^= v1; - } - hash = EDGEHASH(v0,v1)%eh->nbuckets; - - e->v0 = v0; - e->v1 = v1; - e->val = val; - e->next= eh->buckets[hash]; - eh->buckets[hash]= e; - - if (++eh->nentries>eh->nbuckets*3) { - Entry *e, **old= eh->buckets; - int i, nold= eh->nbuckets; - - eh->nbuckets= hashsizes[++eh->cursize]; - eh->buckets= MEM_mallocN(eh->nbuckets*sizeof(*eh->buckets), "eh buckets"); - memset(eh->buckets, 0, eh->nbuckets*sizeof(*eh->buckets)); - - for (i=0; i<nold; i++) { - for (e= old[i]; e;) { - Entry *n= e->next; - - hash= EDGEHASH(e->v0,e->v1)%eh->nbuckets; - e->next= eh->buckets[hash]; - eh->buckets[hash]= e; - - e= n; - } - } - - MEM_freeN(old); - } -} - -void** BLI_edgehash_lookup_p(EdgeHash *eh, int v0, int v1) { - unsigned int hash; - Entry *e; - - if (v1<v0) { - v0 ^= v1; - v1 ^= v0; - v0 ^= v1; - } - hash = EDGEHASH(v0,v1)%eh->nbuckets; - for (e= eh->buckets[hash]; e; e= e->next) - if (v0==e->v0 && v1==e->v1) - return &e->val; - - return NULL; -} - -void* BLI_edgehash_lookup(EdgeHash *eh, int v0, int v1) { - void **value_p = BLI_edgehash_lookup_p(eh,v0,v1); - - return value_p?*value_p:NULL; -} - -int BLI_edgehash_haskey(EdgeHash *eh, int v0, int v1) { - return BLI_edgehash_lookup_p(eh, v0, v1)!=NULL; -} - int BLI_edgehash_size(EdgeHash *eh) { return eh->nentries; } @@ -151,10 +57,10 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) { int i; for (i=0; i<eh->nbuckets; i++) { - Entry *e; + EdgeEntry *e; for (e= eh->buckets[i]; e; ) { - Entry *n= e->next; + EdgeEntry *n= e->next; if (valfreefp) valfreefp(e->val); BLI_mempool_free(eh->epool, e); @@ -182,7 +88,7 @@ void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { struct EdgeHashIterator { EdgeHash *eh; int curBucket; - Entry *curEntry; + EdgeEntry *curEntry; }; EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3ed39f2611d..851f1bac018 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3243,7 +3243,19 @@ static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts) return; for (i=0; i<count; i++) { + void *tmp; + mdverts[i].dw=newdataadr(fd, mdverts[i].dw); + + /*convert to vgroup allocation system*/ + if (mdverts[i].dw) { + tmp = BLI_cellalloc_malloc(MEM_allocN_len(mdverts[i].dw), "vgroups from readfile.c"); + memcpy(tmp, mdverts[i].dw, MEM_allocN_len(mdverts[i].dw)); + + MEM_freeN(mdverts[i].dw); + mdverts[i].dw = tmp; + } + if (!mdverts[i].dw) mdverts[i].totweight=0; } @@ -3262,6 +3274,8 @@ static void direct_link_mdisps(FileData *fd, int count, MDisps *mdisps) } } +/*this isn't really a public api function, so prototyped here*/ +void customData_update_typemap(CustomData *data); static void direct_link_customdata(FileData *fd, CustomData *data, int count) { int i = 0; @@ -3278,6 +3292,8 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count) i++; } } + + customData_update_typemap(data); } diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 6d5138ff11a..e5b8d59d515 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -915,9 +915,20 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } - VECCOPY(normal, ob->obmat[2]); - VECCOPY(plane, ob->obmat[1]); - result = ORIENTATION_NORMAL; + if (!ob) { + normal[0] = 0.0f; + normal[1] = 0.0f; + normal[2] = 1.0f; + plane[0] = 1.0f; + plane[1] = 0.0f; + plane[2] = 0.0f; + + result = ORIENTATION_NORMAL; + } else { + VECCOPY(normal, ob->obmat[2]); + VECCOPY(plane, ob->obmat[1]); + result = ORIENTATION_NORMAL; + } } return result; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 132cad94a1c..2b8cd90b4d5 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -49,6 +49,7 @@ typedef struct CustomDataLayer { * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ + int typemap[100]; /* maps types to indices of first layer of that type */ int totlayer, maxlayer; /* number of layers, size of layers array */ int totsize, pad; /* in editmode, total size of all data layers */ void *pool; /* for Bmesh: Memory pool for allocation of blocks*/ |