[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57062] trunk/blender/source/blender: optimize mirror merging, remove array reallocation, replace with fixed size arrays.
Campbell Barton
ideasman42 at gmail.com
Mon May 27 22:11:12 CEST 2013
Revision: 57062
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57062
Author: campbellbarton
Date: 2013-05-27 20:11:12 +0000 (Mon, 27 May 2013)
Log Message:
-----------
optimize mirror merging, remove array reallocation, replace with fixed size arrays.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h
trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
trunk/blender/source/blender/blenlib/BLI_utildefines.h
trunk/blender/source/blender/modifiers/intern/MOD_mirror.c
Modified: trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h 2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h 2013-05-27 20:11:12 UTC (rev 57062)
@@ -61,7 +61,7 @@
DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_tessface);
/* merge verts */
-DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
+DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int tot_vtargetmap);
/* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob);
Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c 2013-05-27 20:11:12 UTC (rev 57062)
@@ -2308,15 +2308,19 @@
}
#if 1
-/* merge verts
+
+/**
+ * Merge Verts
*
- * vtargetmap is a table that maps vertices to target vertices. a value of -1
+ * \param vtargetmap The table that maps vertices to target vertices. a value of -1
* indicates a vertex is a target, and is to be kept.
+ * This array is aligned with 'dm->numVertData'
*
+ * \param tot_vtargetmap The number of non '-1' values in vtargetmap.
+ * (not the size )
+ *
* this frees dm, and returns a new one.
*
- * this is a really horribly written function. ger. - joeedh
- *
* note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
*
* Note: This function is currently only used by the Mirror modifier, so it
@@ -2324,49 +2328,66 @@
* of faces sharing the same set of vertices). If used elsewhere, it may
* be necessary to make this functionality optional.
*/
-DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
+DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int tot_vtargetmap)
{
// #define USE_LOOPS
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
CDDerivedMesh *cddm2 = NULL;
- MVert *mv, *mvert = NULL;
- BLI_array_declare(mvert);
- MEdge *med, *medge = NULL;
- BLI_array_declare(medge);
- MPoly *mp, *mpoly = NULL;
- BLI_array_declare(mpoly);
- MLoop *ml, *mloop = NULL;
- BLI_array_declare(mloop);
- EdgeHash *ehash = BLI_edgehash_new();
- int *newv = NULL, *newe = NULL;
+
+ const int totvert = dm->numVertData;
+ const int totedge = dm->numEdgeData;
+ const int totloop = dm->numLoopData;
+ const int totpoly = dm->numPolyData;
+
+ const int totvert_final = totvert - tot_vtargetmap;
+
+ MVert *mv, *mvert = MEM_mallocN(sizeof(*mvert) * totvert_final, __func__);
+ int *oldv = MEM_mallocN(sizeof(*oldv) * totvert_final, __func__);
+ int *newv = MEM_mallocN(sizeof(*newv) * totvert, __func__);
+ STACK_DECLARE(mvert);
+ STACK_DECLARE(oldv);
+
+ MEdge *med, *medge = MEM_mallocN(sizeof(*medge) * totedge, __func__);
+ int *olde = MEM_mallocN(sizeof(*olde) * totedge, __func__);
+ int *newe = MEM_mallocN(sizeof(*newe) * totedge, __func__);
+ STACK_DECLARE(medge);
+ STACK_DECLARE(olde);
+
+ MLoop *ml, *mloop = MEM_mallocN(sizeof(*mloop) * totloop, __func__);
+ int *oldl = MEM_mallocN(sizeof(*oldl) * totloop, __func__);
#ifdef USE_LOOPS
- int *newl = NULL;
+ int newl = MEM_mallocN(sizeof(*newl) * totloop, __func__);
#endif
- int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
- BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
- int i, j, c, totpoly;
-#ifdef USE_LOOPS
- int totloop;
-#endif
+ STACK_DECLARE(mloop);
+ STACK_DECLARE(oldl);
-#ifdef USE_LOOPS
- totloop = dm->numLoopData;
-#endif
- totpoly = dm->numPolyData;
+ MPoly *mp, *mpoly = MEM_mallocN(sizeof(*medge) * totpoly, __func__);
+ int *oldp = MEM_mallocN(sizeof(*oldp) * totpoly, __func__);
+ STACK_DECLARE(mpoly);
+ STACK_DECLARE(oldp);
+
+ EdgeHash *ehash = BLI_edgehash_new();
+
+ int i, j, c;
- newv = MEM_mallocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
- newe = MEM_mallocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
-#ifdef USE_LOOPS
- newl = MEM_mallocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
-#endif
+ STACK_INIT(oldv);
+ STACK_INIT(olde);
+ STACK_INIT(oldl);
+ STACK_INIT(oldp);
+
+ STACK_INIT(mvert);
+ STACK_INIT(medge);
+ STACK_INIT(mloop);
+ STACK_INIT(mpoly);
+
/* fill newl with destination vertex indices */
mv = cddm->mvert;
c = 0;
- for (i = 0; i < dm->numVertData; i++, mv++) {
+ for (i = 0; i < totvert; i++, mv++) {
if (vtargetmap[i] == -1) {
- BLI_array_append(oldv, i);
+ STACK_PUSH(oldv, i);
+ STACK_PUSH(mvert, *mv);
newv[i] = c++;
- BLI_array_append(mvert, *mv);
}
else {
/* dummy value */
@@ -2375,7 +2396,7 @@
}
/* now link target vertices to destination indices */
- for (i = 0; i < dm->numVertData; i++) {
+ for (i = 0; i < totvert; i++) {
if (vtargetmap[i] != -1) {
newv[i] = newv[vtargetmap[i]];
}
@@ -2389,7 +2410,7 @@
/* now go through and fix edges and faces */
med = cddm->medge;
c = 0;
- for (i = 0; i < dm->numEdgeData; i++, med++) {
+ for (i = 0; i < totedge; i++, med++) {
if (LIKELY(med->v1 != med->v2)) {
const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
@@ -2400,9 +2421,9 @@
newe[i] = GET_INT_FROM_POINTER(*eh_p);
}
else {
- BLI_array_append(olde, i);
+ STACK_PUSH(olde, i);
+ STACK_PUSH(medge, *med);
newe[i] = c;
- BLI_array_append(medge, *med);
BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
c++;
}
@@ -2414,7 +2435,7 @@
mp = cddm->mpoly;
for (i = 0; i < totpoly; i++, mp++) {
- MPoly *mp2;
+ MPoly *mp_new;
ml = cddm->mloop + mp->loopstart;
@@ -2441,10 +2462,10 @@
med = cddm->medge + ml->e;
if (LIKELY(med->v1 != med->v2)) {
#ifdef USE_LOOPS
- newl[j + mp->loopstart] = BLI_array_count(mloop);
+ newl[j + mp->loopstart] = STACK_SIZE(mloop);
#endif
- BLI_array_append(oldl, j + mp->loopstart);
- BLI_array_append(mloop, *ml);
+ STACK_PUSH(oldl, j + mp->loopstart);
+ STACK_PUSH(mloop, *ml);
c++;
}
}
@@ -2452,16 +2473,17 @@
if (UNLIKELY(c == 0)) {
continue;
}
+
+ mp_new = STACK_PUSH_RET_PTR(mpoly);
+ *mp_new = *mp;
+ mp_new->totloop = c;
+ mp_new->loopstart = STACK_SIZE(mloop) - c;
- mp2 = BLI_array_append_r(mpoly, *mp);
- mp2->totloop = c;
- mp2->loopstart = BLI_array_count(mloop) - c;
-
- BLI_array_append(oldp, i);
+ STACK_PUSH(oldp, i);
}
/*create new cddm*/
- cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
+ cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
/*update edge indices and copy customdata*/
med = medge;
@@ -2498,31 +2520,39 @@
}
/*copy over data. CustomData_add_layer can do this, need to look it up.*/
- memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
- memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
- memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
- memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
- BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
-
- if (newv)
- MEM_freeN(newv);
- if (newe)
- MEM_freeN(newe);
+ memcpy(cddm2->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert));
+ memcpy(cddm2->medge, medge, sizeof(MEdge) * STACK_SIZE(medge));
+ memcpy(cddm2->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop));
+ memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
+
+ MEM_freeN(mvert);
+ MEM_freeN(medge);
+ MEM_freeN(mloop);
+ MEM_freeN(mpoly);
+
+ MEM_freeN(newv);
+ MEM_freeN(newe);
#ifdef USE_LOOPS
- if (newl)
- MEM_freeN(newl);
+ MEM_freeN(newl);
#endif
- if (oldv)
- MEM_freeN(oldv);
- if (olde)
- MEM_freeN(olde);
- if (oldl)
- MEM_freeN(oldl);
- if (oldp)
- MEM_freeN(oldp);
- if (ehash)
- BLI_edgehash_free(ehash, NULL);
+ MEM_freeN(oldv);
+ MEM_freeN(olde);
+ MEM_freeN(oldl);
+ MEM_freeN(oldp);
+
+ STACK_FREE(oldv);
+ STACK_FREE(olde);
+ STACK_FREE(oldl);
+ STACK_FREE(oldp);
+
+ STACK_FREE(mvert);
+ STACK_FREE(medge);
+ STACK_FREE(mloop);
+ STACK_FREE(mpoly);
+
+ BLI_edgehash_free(ehash, NULL);
+
/*free old derivedmesh*/
dm->needsFree = 1;
dm->release(dm);
Modified: trunk/blender/source/blender/blenlib/BLI_utildefines.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_utildefines.h 2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenlib/BLI_utildefines.h 2013-05-27 20:11:12 UTC (rev 57062)
@@ -296,6 +296,7 @@
#define STACK_SIZE(stack) ((void)stack, (_##stack##_index))
#define STACK_PUSH(stack, val) (void)((stack)[(_##stack##_index)++] = val)
#define STACK_PUSH_RET(stack) ((void)stack, ((stack)[(_##stack##_index)++]))
+#define STACK_PUSH_RET_PTR(stack) ((void)stack, &((stack)[(_##stack##_index)++]))
#define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
#define STACK_FREE(stack) ((void)stack)
Modified: trunk/blender/source/blender/modifiers/intern/MOD_mirror.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_mirror.c 2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/modifiers/intern/MOD_mirror.c 2013-05-27 20:11:12 UTC (rev 57062)
@@ -99,7 +99,7 @@
{
const float tolerance_sq = mmd->tolerance * mmd->tolerance;
const int do_vtargetmap = !(mmd->flag & MOD_MIR_NO_MERGE);
- int is_vtargetmap = FALSE; /* true when it should be used */
+ int tot_vtargetmap = 0; /* total merge vertices */
DerivedMesh *result;
const int maxVerts = dm->getNumVerts(dm);
@@ -187,7 +187,7 @@
* should be mapped for merging */
if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
*vtmap_a = maxVerts + i;
- is_vtargetmap = TRUE;
+ tot_vtargetmap++;
}
else {
*vtmap_a = -1;
@@ -288,8 +288,8 @@
if (do_vtargetmap) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list