Commit: 451031f1904c27ceac0b1660fcd52e2b0aaf3a81
Author: Julian Eisel
Date:   Thu Jun 9 00:22:32 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rB451031f1904c27ceac0b1660fcd52e2b0aaf3a81

Use new, fast and simple array iterator instead of recursive iterator

Group positioning needs to be fixed after this, will check soon.

===================================================================

M       source/blender/blenkernel/BKE_layer.h
M       source/blender/blenkernel/intern/layer.c
M       source/blender/editors/space_layers/layers_draw.c
M       source/blender/editors/space_layers/layers_intern.h
M       source/blender/editors/space_layers/layers_ops.c
M       source/blender/editors/space_layers/layers_util.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_layer.h 
b/source/blender/blenkernel/BKE_layer.h
index e6896cf..81cd051 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -58,8 +58,12 @@ void BKE_layertree_delete(LayerTree *ltree);
 bool BKE_layertree_iterate(const LayerTree *ltree, LayerTreeIterFunc foreach, 
void *customdata, const bool inverse);
 int  BKE_layertree_get_totitems(const LayerTree *ltree);
 
-#define BKE_LAYERTREE_ITER_START(ltree, idx_name, litem_name) \
-       for (int idx_name = 0; idx_name < BKE_layertree_get_totitems(ltree); 
idx_name++) { \
+/**
+ * Macro to iterate over all layer items of a tree.
+ * Don't call #BKE_layeritem_remove inside, it will mess up iteration.
+ */
+#define BKE_LAYERTREE_ITER_START(ltree, start_at, idx_name, litem_name) \
+       for (int idx_name = start_at; idx_name < 
BKE_layertree_get_totitems(ltree); idx_name++) { \
                LayerTreeItem *litem_name = ltree->items_all[idx_name];
 #define BKE_LAYERTREE_ITER_END } (void)0
 
diff --git a/source/blender/blenkernel/intern/layer.c 
b/source/blender/blenkernel/intern/layer.c
index c12ea80..4b346c7 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -63,7 +63,7 @@ LayerTree *BKE_layertree_new(const eLayerTree_Type type)
 
 void BKE_layertree_delete(LayerTree *ltree)
 {
-       BKE_LAYERTREE_ITER_START(ltree, i, litem)
+       BKE_LAYERTREE_ITER_START(ltree, 0, i, litem)
        {
                /* layeritem_free does all we need in this case. No 
un-registering needed */
                layeritem_free(litem);
diff --git a/source/blender/editors/space_layers/layers_draw.c 
b/source/blender/editors/space_layers/layers_draw.c
index d08a79b..29498a9 100644
--- a/source/blender/editors/space_layers/layers_draw.c
+++ b/source/blender/editors/space_layers/layers_draw.c
@@ -66,40 +66,28 @@ static int layer_tile_indent_level_get(const LayerTreeItem 
*litem)
        return indent_level;
 }
 
-typedef struct TileDrawInfo {
-       const bContext *C;
-       ARegion *ar;
-       SpaceLayers *slayer;
-       uiBlock *block;
-       uiStyle *style;
-
-       float size_y;
-       int idx;
-} TileDrawInfo;
-
-static bool layer_tile_draw_cb(LayerTreeItem *litem, void *userdata)
+/**
+ * Draw the tile for \a litem.
+ * \return the height of the drawn tile.
+ */
+static float layer_tile_draw(
+        LayerTreeItem *litem,
+        const bContext *C, ARegion *ar, SpaceLayers *slayer, uiBlock *block, 
uiStyle *style,
+        float ofs_y, int idx)
 {
-       if (!litem->draw)
-               return true; /* skip this item, but continue iterating */
-
-       TileDrawInfo *drawinfo = userdata;
-       View2D *v2d = &drawinfo->ar->v2d;
-       LayerTile *tile = BLI_ghash_lookup(drawinfo->slayer->tiles, litem);
+       LayerTile *tile = BLI_ghash_lookup(slayer->tiles, litem);
        const bool expanded = litem->draw_settings && (tile->flag & 
LAYERTILE_EXPANDED);
 
        const float pad_x = 4.0f * UI_DPI_FAC;
        const float header_y = LAYERTILE_HEADER_HEIGHT;
 
        const float ofs_x = layer_tile_indent_level_get(litem) * 
LAYERITEM_INDENT_SIZE;
-       const float ofs_y = drawinfo->size_y;
-       const rctf rect = {-v2d->cur.xmin + ofs_x, drawinfo->ar->winx,
-                          -v2d->cur.ymin - ofs_y - header_y, -v2d->cur.ymin - 
ofs_y};
+       const rctf rect = {-ar->v2d.cur.xmin + ofs_x, ar->winx,
+                          -ar->v2d.cur.ymin - ofs_y - header_y, 
-ar->v2d.cur.ymin - ofs_y};
        int size_y = 0;
        int tile_size_y = 0;
 
        /* draw item itself */
-       uiBlock *block = drawinfo->block;
-
        if (tile->flag & LAYERTILE_RENAME) {
                uiBut *but = uiDefBut(
                        block, UI_BTYPE_TEXT, 1, "", rect.xmin, rect.ymin,
@@ -109,18 +97,18 @@ static bool layer_tile_draw_cb(LayerTreeItem *litem, void 
*userdata)
                UI_but_flag_disable(but, UI_BUT_UNDO);
 
                /* returns false if button got removed */
-               if (UI_but_active_only(drawinfo->C, drawinfo->ar, block, but) 
== false) {
+               if (UI_but_active_only(C, ar, block, but) == false) {
                        tile->flag &= ~LAYERTILE_RENAME;
                        /* Yuk! Sending notifier during draw. Need to
                         * do that so item uses regular drawing again. */
-                       WM_event_add_notifier(drawinfo->C, NC_SPACE | 
ND_SPACE_LAYERS, NULL);
+                       WM_event_add_notifier(C, NC_SPACE | ND_SPACE_LAYERS, 
NULL);
                }
        }
        else {
                uiLayout *layout = UI_block_layout(
                        block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
-                       rect.xmin, rect.ymax, BLI_rctf_size_y(&rect), 0, 0, 
drawinfo->style);
-               litem->draw(drawinfo->C, litem, layout);
+                       rect.xmin, rect.ymax, BLI_rctf_size_y(&rect), 0, 0, 
style);
+               litem->draw(C, litem, layout);
                uiItemL(layout, "", 0); /* XXX without this editing last item 
causes crashes */
                UI_block_layout_resolve(block, NULL, NULL);
        }
@@ -129,15 +117,15 @@ static bool layer_tile_draw_cb(LayerTreeItem *litem, void 
*userdata)
        if (expanded) {
                uiLayout *layout = UI_block_layout(
                        block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
-                       rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), 0, 0, 
drawinfo->style);
-               litem->draw_settings(drawinfo->C, litem, layout);
+                       rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), 0, 0, 
style);
+               litem->draw_settings(C, litem, layout);
 
                UI_block_layout_resolve(block, NULL, &size_y);
-               tile_size_y = -(size_y + drawinfo->size_y + v2d->cur.ymin);
+               tile_size_y = -(ofs_y + size_y + ar->v2d.cur.ymin);
        }
 
        /* draw background */
-       if (drawinfo->idx % 2) {
+       if (idx % 2) {
                UI_ThemeColorShade(TH_BACK, 10);
                fdrawbox_filled(0, rect.ymax - tile_size_y, rect.xmax, 
rect.ymax);
        }
@@ -148,12 +136,11 @@ static bool layer_tile_draw_cb(LayerTreeItem *litem, void 
*userdata)
                UI_draw_roundbox(rect.xmin + pad_x, rect.ymin, rect.xmax - 
pad_x, rect.ymax, 5.0f);
        }
 
-       drawinfo->size_y += tile_size_y;
-       drawinfo->idx++;
+       idx++;
        /* set tile height */
        tile->tot_height = tile_size_y;
 
-       return true;
+       return tile_size_y;
 }
 
 void layers_tiles_draw(const bContext *C, ARegion *ar)
@@ -161,16 +148,25 @@ void layers_tiles_draw(const bContext *C, ARegion *ar)
        SpaceLayers *slayer = CTX_wm_space_layers(C);
 
        uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
-       TileDrawInfo drawinfo = {C, ar, slayer, block, UI_style_get_dpi()};
+       uiStyle *style = UI_style_get_dpi();
 
        /* draw tiles */
-       BKE_layertree_iterate(slayer->act_tree, layer_tile_draw_cb, &drawinfo, 
true);
+       int idx = 0;
+       float ofs_y = 0.0f;
+       BKE_LAYERTREE_ITER_START(slayer->act_tree, 0, i, litem)
+       {
+               if (litem->draw) {
+                       ofs_y += layer_tile_draw(litem, C, ar, slayer, block, 
style, ofs_y, idx);
+                       idx++;
+               }
+       }
+       BKE_LAYERTREE_ITER_END;
 
        /* fill remaining space with empty boxes */
-       const float tot_fill_tiles = (-ar->v2d.cur.ymin - drawinfo.size_y) / 
LAYERTILE_HEADER_HEIGHT + 1;
+       const float tot_fill_tiles = (-ar->v2d.cur.ymin - ofs_y) / 
LAYERTILE_HEADER_HEIGHT + 1;
        for (int i = 0; i < tot_fill_tiles; i++) {
-               if ((i + drawinfo.idx) % 2) {
-                       const float pos[2] = {0, -ar->v2d.cur.ymin - 
drawinfo.size_y - (LAYERTILE_HEADER_HEIGHT * (i + 1))};
+               if ((i + idx) % 2) {
+                       const float pos[2] = {0, -ar->v2d.cur.ymin - ofs_y - 
(LAYERTILE_HEADER_HEIGHT * (i + 1))};
                        UI_ThemeColorShade(TH_BACK, 10);
                        fdrawbox_filled(pos[0], pos[1], pos[0] + ar->winx, 
pos[1] + LAYERTILE_HEADER_HEIGHT);
                }
@@ -180,7 +176,7 @@ void layers_tiles_draw(const bContext *C, ARegion *ar)
        UI_block_draw(C, block);
 
        /* update size of tot-rect (extents of data/viewable area) */
-       UI_view2d_totRect_set(&ar->v2d, ar->winx - 
BLI_rcti_size_x(&ar->v2d.vert), drawinfo.size_y);
+       UI_view2d_totRect_set(&ar->v2d, ar->winx - 
BLI_rcti_size_x(&ar->v2d.vert), ofs_y);
 }
 
 
diff --git a/source/blender/editors/space_layers/layers_intern.h 
b/source/blender/editors/space_layers/layers_intern.h
index f5a46d6..dc5d029 100644
--- a/source/blender/editors/space_layers/layers_intern.h
+++ b/source/blender/editors/space_layers/layers_intern.h
@@ -61,10 +61,8 @@ void       layers_data_refresh(const struct Scene *scene, 
struct SpaceLayers *sl
 void       layers_tilehash_delete(SpaceLayers *slayer);
 LayerTile *layers_tile_add(const struct SpaceLayers *slayer, struct 
LayerTreeItem *litem);
 void       layers_tile_remove(const struct SpaceLayers *slayer, LayerTile 
*tile, const bool remove_children);
-LayerTile *layers_tile_find_at_coordinate(
-        struct SpaceLayers *slayer, struct ARegion *ar, const int co[2],
-        int *r_tile_idx);
-bool layers_any_selected(struct SpaceLayers *slayer, const struct LayerTree 
*ltree);
+LayerTile *layers_tile_find_at_coordinate(struct SpaceLayers *slayer, struct 
ARegion *ar, const int co[2]);
+bool layers_any_selected(struct SpaceLayers *slayer);
 
 /* layers_ops.c */
 void layers_operatortypes(void);
diff --git a/source/blender/editors/space_layers/layers_ops.c 
b/source/blender/editors/space_layers/layers_ops.c
index 4d7c1c6..f6d78f1 100644
--- a/source/blender/editors/space_layers/layers_ops.c
+++ b/source/blender/editors/space_layers/layers_ops.c
@@ -192,23 +192,6 @@ static void LAYERS_OT_remove(wmOperatorType *ot)
                                "Type", "Method used for deleting layers");
 }
 
-typedef struct {
-       SpaceLayers *slayer;
-       LayerTreeItem *group;
-} GroupAddSelectedData;
-
-static bool layer_group_add_selected_cb(LayerTreeItem *litem, void *customdata)
-{
-       GroupAddSelectedData *gadata = customdata;
-       LayerTile *tile = BLI_ghash_lookup(gadata->slayer->tiles, litem);
-
-       if (tile->flag & LAYERTILE_SELECTED) {
-               BKE_layeritem_group_assign(gadata->group, litem);
-       }
-
-       return true;
-}
-
 static int layer_group_add_invoke(bContext *C, wmOperator *UNUSED(op), const 
wmEvent *UNUSED(event))
 {
        Scene *scene = CTX_data_scene(C);
@@ -218,8 +201,14 @@ static int layer_group_add_invoke(bContext *C, wmOperator 
*UNUSED(op), const wmE
        layers_tile_add(slayer, new_group);
 
        /* Add selected items to group */
-       GroupAddSelectedData gadata = {slayer, new_group};
-       BKE_layertree_iterate(slayer->act_tree, layer_group_add_selected_cb, 
&gadata, true);
+       BKE_LAYERTREE_ITER_START(slayer->act_tree, 0, i, litem)
+       {
+               LayerTile *tile = BLI_ghash_lookup(slayer->tiles, litem);
+               if (tile->flag & LAYERTILE_SELECTED) {
+                       BKE_layeritem_group_assign(new_group, litem);
+               }
+       }
+       BKE_LAYERTREE_ITER_END;
 
        WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
        return OPERATOR_FINISHED;
@@ -244,7 +233,7 @@ static int layer_rename_invoke(

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to