From eef0cdb1aa361b3d24a3ab12c8309a6dbfced023 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 Nov 2011 20:21:44 +0000 Subject: [PATCH] inline BMIter_Step() and BMIter_New() since the compiler can optimize out the switch statement when BMIter_New() is called with the define (which is common). --- source/blender/bmesh/bmesh_iterators.h | 30 ++- source/blender/bmesh/intern/bmesh_iterators.c | 175 +++--------------- .../bmesh/intern/bmesh_iterators_inline.c | 132 ++++++++++++- 3 files changed, 189 insertions(+), 148 deletions(-) diff --git a/source/blender/bmesh/bmesh_iterators.h b/source/blender/bmesh/bmesh_iterators.h index f90ca2f72d5..c87240b99f2 100644 --- a/source/blender/bmesh/bmesh_iterators.h +++ b/source/blender/bmesh/bmesh_iterators.h @@ -75,8 +75,34 @@ typedef struct BMIter { int htype, count; }BMIter; -void *BMIter_New(struct BMIter *iter, struct BMesh *bm, const char htype, void *data); -void *BMIter_Step(struct BMIter *iter); void *BMIter_AtIndex(struct BMesh *bm, const char htype, void *data, int index); +/* private for bmesh_iterators_inline.c */ +void bmiter__vert_of_mesh_begin(struct BMIter *iter); +void *bmiter__vert_of_mesh_step(struct BMIter *iter); +void bmiter__edge_of_mesh_begin(struct BMIter *iter); +void *bmiter__edge_of_mesh_step(struct BMIter *iter); +void bmiter__face_of_mesh_begin(struct BMIter *iter); +void *bmiter__face_of_mesh_step(struct BMIter *iter); +void bmiter__edge_of_vert_begin(struct BMIter *iter); +void *bmiter__edge_of_vert_step(struct BMIter *iter); +void bmiter__face_of_vert_begin(struct BMIter *iter); +void *bmiter__face_of_vert_step(struct BMIter *iter); +void bmiter__loop_of_vert_begin(struct BMIter *iter); +void *bmiter__loop_of_vert_step(struct BMIter *iter); +void bmiter__loops_of_edge_begin(struct BMIter *iter); +void *bmiter__loops_of_edge_step(struct BMIter *iter); +void bmiter__loops_of_loop_begin(struct BMIter *iter); +void *bmiter__loops_of_loop_step(struct BMIter *iter); +void bmiter__face_of_edge_begin(struct BMIter *iter); +void *bmiter__face_of_edge_step(struct BMIter *iter); +void bmiter__vert_of_face_begin(struct BMIter *iter); +void *bmiter__vert_of_face_step(struct BMIter *iter); +void bmiter__edge_of_face_begin(struct BMIter *iter); +void *bmiter__edge_of_face_step(struct BMIter *iter); +void bmiter__loop_of_face_begin(struct BMIter *iter); +void *bmiter__loop_of_face_step(struct BMIter *iter); + +#include "intern/bmesh_iterators_inline.c" + #endif diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index a037dd9d25f..82870f00422 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -24,6 +24,8 @@ * \ingroup bmesh * * Functions to abstract looping over bmesh data structures. + * + * See: bmesh_iterators_inlin.c too, some functions are here for speed reasons. */ #include @@ -54,18 +56,6 @@ void *BMIter_AtIndex(struct BMesh *bm, const char htype, void *data, int index) return val; } -/* - * BMESH ITERATOR STEP - * - * Calls an iterators step fucntion to return - * the next element. -*/ - -void *BMIter_Step(BMIter *iter) -{ - return iter->step(iter); -} - /* * INIT ITERATOR * @@ -95,41 +85,44 @@ static void init_iterator(BMIter *iter) * When the end of a sequence is * reached, next should always equal NULL * -*/ + * The 'bmiter__' prefix is used because these are used in + * bmesh_iterators_inine.c but should otherwise be seen as + * private. + */ /* * VERT OF MESH CALLBACKS * */ -static void vert_of_mesh_begin(BMIter *iter) +void bmiter__vert_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->vpool, &iter->pooliter); } -static void *vert_of_mesh_step(BMIter *iter) +void *bmiter__vert_of_mesh_step(BMIter *iter) { return BLI_mempool_iterstep(&iter->pooliter); } -static void edge_of_mesh_begin(BMIter *iter) +void bmiter__edge_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->epool, &iter->pooliter); } -static void *edge_of_mesh_step(BMIter *iter) +void *bmiter__edge_of_mesh_step(BMIter *iter) { return BLI_mempool_iterstep(&iter->pooliter); } -static void face_of_mesh_begin(BMIter *iter) +void bmiter__face_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->fpool, &iter->pooliter); } -static void *face_of_mesh_step(BMIter *iter) +void *bmiter__face_of_mesh_step(BMIter *iter) { return BLI_mempool_iterstep(&iter->pooliter); @@ -140,7 +133,7 @@ static void *face_of_mesh_step(BMIter *iter) * */ -static void edge_of_vert_begin(BMIter *iter) +void bmiter__edge_of_vert_begin(BMIter *iter) { init_iterator(iter); if(iter->vdata->e){ @@ -149,7 +142,7 @@ static void edge_of_vert_begin(BMIter *iter) } } -static void *edge_of_vert_step(BMIter *iter) +void *bmiter__edge_of_vert_step(BMIter *iter) { BMEdge *current = iter->nextedge; @@ -166,7 +159,7 @@ static void *edge_of_vert_step(BMIter *iter) * */ -static void face_of_vert_begin(BMIter *iter) +void bmiter__face_of_vert_begin(BMIter *iter) { init_iterator(iter); iter->count = 0; @@ -179,7 +172,7 @@ static void face_of_vert_begin(BMIter *iter) iter->nextloop = iter->firstloop; } } -static void *face_of_vert_step(BMIter *iter) +void *bmiter__face_of_vert_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -206,7 +199,7 @@ static void *face_of_vert_step(BMIter *iter) * */ -static void loop_of_vert_begin(BMIter *iter) +void bmiter__loop_of_vert_begin(BMIter *iter) { init_iterator(iter); iter->count = 0; @@ -219,7 +212,7 @@ static void loop_of_vert_begin(BMIter *iter) iter->nextloop = iter->firstloop; } } -static void *loop_of_vert_step(BMIter *iter) +void *bmiter__loop_of_vert_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -241,7 +234,7 @@ static void *loop_of_vert_step(BMIter *iter) } -static void loops_of_edge_begin(BMIter *iter) +void bmiter__loops_of_edge_begin(BMIter *iter) { BMLoop *l; @@ -253,7 +246,7 @@ static void loops_of_edge_begin(BMIter *iter) iter->firstloop = iter->nextloop = l; } -static void *loops_of_edge_step(BMIter *iter) +void *bmiter__loops_of_edge_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -267,7 +260,7 @@ static void *loops_of_edge_step(BMIter *iter) return NULL; } -static void loops_of_loop_begin(BMIter *iter) +void bmiter__loops_of_loop_begin(BMIter *iter) { BMLoop *l; @@ -283,7 +276,7 @@ static void loops_of_loop_begin(BMIter *iter) iter->nextloop = NULL; } -static void *loops_of_loop_step(BMIter *iter) +void *bmiter__loops_of_loop_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -299,7 +292,7 @@ static void *loops_of_loop_step(BMIter *iter) * */ -static void face_of_edge_begin(BMIter *iter) +void bmiter__face_of_edge_begin(BMIter *iter) { init_iterator(iter); @@ -309,7 +302,7 @@ static void face_of_edge_begin(BMIter *iter) } } -static void *face_of_edge_step(BMIter *iter) +void *bmiter__face_of_edge_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -325,13 +318,13 @@ static void *face_of_edge_step(BMIter *iter) * */ -static void vert_of_face_begin(BMIter *iter) +void bmiter__vert_of_face_begin(BMIter *iter) { init_iterator(iter); iter->firstloop = iter->nextloop = ((BMLoopList*)iter->pdata->loops.first)->first; } -static void *vert_of_face_step(BMIter *iter) +void *bmiter__vert_of_face_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -347,13 +340,13 @@ static void *vert_of_face_step(BMIter *iter) * */ -static void edge_of_face_begin(BMIter *iter) +void bmiter__edge_of_face_begin(BMIter *iter) { init_iterator(iter); iter->firstloop = iter->nextloop = ((BMLoopList*)iter->pdata->loops.first)->first; } -static void *edge_of_face_step(BMIter *iter) +void *bmiter__edge_of_face_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -369,13 +362,13 @@ static void *edge_of_face_step(BMIter *iter) * */ -static void loop_of_face_begin(BMIter *iter) +void bmiter__loop_of_face_begin(BMIter *iter) { init_iterator(iter); iter->firstloop = iter->nextloop = bm_firstfaceloop(iter->pdata); } -static void *loop_of_face_step(BMIter *iter) +void *bmiter__loop_of_face_step(BMIter *iter) { BMLoop *current = iter->nextloop; @@ -384,111 +377,3 @@ static void *loop_of_face_step(BMIter *iter) return current; } - -/* - * BMESH ITERATOR INIT - * - * Takes a bmesh iterator structure and fills - * it with the appropriate function pointers based - * upon its type and then calls BMeshIter_step() - * to return the first element of the iterator. - * -*/ -void *BMIter_New(BMIter *iter, BMesh *bm, const char htype, void *data) -{ - /* int argtype; */ - iter->htype = htype; - iter->bm = bm; - - switch(htype){ - case BM_VERTS_OF_MESH: - iter->begin = vert_of_mesh_begin; - iter->step = vert_of_mesh_step; - break; - case BM_EDGES_OF_MESH: - iter->begin = edge_of_mesh_begin; - iter->step = edge_of_mesh_step; - break; - case BM_FACES_OF_MESH: - iter->begin = face_of_mesh_begin; - iter->step = face_of_mesh_step; - break; - case BM_EDGES_OF_VERT: - if (!data) - return NULL; - - iter->begin = edge_of_vert_begin; - iter->step = edge_of_vert_step; - iter->vdata = data; - break; - case BM_FACES_OF_VERT: - if (!data) - return NULL; - - iter->begin = face_of_vert_begin; - iter->step = face_of_vert_step; - iter->vdata = data; - break; - case BM_LOOPS_OF_VERT: - if (!data) - return NULL; - - iter->begin = loop_of_vert_begin; - iter->step = loop_of_vert_step; - iter->vdata = data; - break; - case BM_FACES_OF_EDGE: - if (!data) - return NULL; - - iter->begin = face_of_edge_begin; - iter->step = face_of_edge_step; - iter->edata = data; - break; - case BM_VERTS_OF_FACE: - if (!data) - return NULL; - - iter->begin = vert_of_face_begin; - iter->step = vert_of_face_step; - iter->pdata = data; - break; - case BM_EDGES_OF_FACE: - if (!data) - return NULL; - - iter->begin = edge_of_face_begin; - iter->step = edge_of_face_step; - iter->pdata = data; - break; - case BM_LOOPS_OF_FACE: - if (!data) - return NULL; - - iter->begin = loop_of_face_begin; - iter->step = loop_of_face_step; - iter->pdata = data; - break; - case BM_LOOPS_OF_LOOP: - if (!data) - return NULL; - - iter->begin = loops_of_loop_begin; - iter->step = loops_of_loop_step; - iter->ldata = data; - break; - case BM_LOOPS_OF_EDGE: - if (!data) - return NULL; - - iter->begin = loops_of_edge_begin; - iter->step = loops_of_edge_step; - iter->edata = data; - break; - default: - break; - } - - iter->begin(iter); - return BMIter_Step(iter); -} diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.c b/source/blender/bmesh/intern/bmesh_iterators_inline.c index 3c69a45713f..6161bc8f314 100644 --- a/source/blender/bmesh/intern/bmesh_iterators_inline.c +++ b/source/blender/bmesh/intern/bmesh_iterators_inline.c @@ -23,12 +23,142 @@ /** \file blender/bmesh/intern/bmesh_iterators_inline.c * \ingroup bmesh * - * TODO + * BMesh inline iterator functions. */ #ifndef BM_ITERATORS_INLINE_C #define BM_ITERATORS_INLINE_C +#include "bmesh.h" + +#ifndef NULL +# define NULL (void *)0 +#endif + +/* inline here optimizes out the switch statement when called with + * constant values (which is very common), nicer for loop-in-loop situations */ + +/* + * BMESH ITERATOR STEP + * + * Calls an iterators step fucntion to return + * the next element. +*/ + +BM_INLINE void *BMIter_Step(BMIter *iter) +{ + return iter->step(iter); +} + + +/* + * BMESH ITERATOR INIT + * + * Takes a bmesh iterator structure and fills + * it with the appropriate function pointers based + * upon its type and then calls BMeshIter_step() + * to return the first element of the iterator. + * +*/ +BM_INLINE void *BMIter_New(BMIter *iter, BMesh *bm, const char htype, void *data) +{ + /* int argtype; */ + iter->htype = htype; + iter->bm = bm; + + /* inlining optimizes out this switch when called with the defined type */ + switch(htype){ + case BM_VERTS_OF_MESH: + iter->begin = bmiter__vert_of_mesh_begin; + iter->step = bmiter__vert_of_mesh_step; + break; + case BM_EDGES_OF_MESH: + iter->begin = bmiter__edge_of_mesh_begin; + iter->step = bmiter__edge_of_mesh_step; + break; + case BM_FACES_OF_MESH: + iter->begin = bmiter__face_of_mesh_begin; + iter->step = bmiter__face_of_mesh_step; + break; + case BM_EDGES_OF_VERT: + if (!data) + return NULL; + + iter->begin = bmiter__edge_of_vert_begin; + iter->step = bmiter__edge_of_vert_step; + iter->vdata = data; + break; + case BM_FACES_OF_VERT: + if (!data) + return NULL; + + iter->begin = bmiter__face_of_vert_begin; + iter->step = bmiter__face_of_vert_step; + iter->vdata = data; + break; + case BM_LOOPS_OF_VERT: + if (!data) + return NULL; + + iter->begin = bmiter__loop_of_vert_begin; + iter->step = bmiter__loop_of_vert_step; + iter->vdata = data; + break; + case BM_FACES_OF_EDGE: + if (!data) + return NULL; + + iter->begin = bmiter__face_of_edge_begin; + iter->step = bmiter__face_of_edge_step; + iter->edata = data; + break; + case BM_VERTS_OF_FACE: + if (!data) + return NULL; + + iter->begin = bmiter__vert_of_face_begin; + iter->step = bmiter__vert_of_face_step; + iter->pdata = data; + break; + case BM_EDGES_OF_FACE: + if (!data) + return NULL; + + iter->begin = bmiter__edge_of_face_begin; + iter->step = bmiter__edge_of_face_step; + iter->pdata = data; + break; + case BM_LOOPS_OF_FACE: + if (!data) + return NULL; + + iter->begin = bmiter__loop_of_face_begin; + iter->step = bmiter__loop_of_face_step; + iter->pdata = data; + break; + case BM_LOOPS_OF_LOOP: + if (!data) + return NULL; + + iter->begin = bmiter__loops_of_loop_begin; + iter->step = bmiter__loops_of_loop_step; + iter->ldata = data; + break; + case BM_LOOPS_OF_EDGE: + if (!data) + return NULL; + + iter->begin = bmiter__loops_of_edge_begin; + iter->step = bmiter__loops_of_edge_step; + iter->edata = data; + break; + default: + break; + } + + iter->begin(iter); + return BMIter_Step(iter); +} #endif