Fix T61469: wrong object statistics when using instances.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 12 Feb 2019 18:17:14 +0000 (19:17 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 12 Feb 2019 18:18:32 +0000 (19:18 +0100)
The new code already loops over all instances, don't need to be counted again.

source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/intern/object_dupli.c
source/blender/editors/space_info/info_stats.c

index 125e40e..dccb8eb 100644 (file)
@@ -65,7 +65,6 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl
 
 struct ListBase *object_duplilist(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob);
 void free_object_duplilist(struct ListBase *lb);
-int count_duplilist(struct Object *ob);
 
 typedef struct DupliObject {
        struct DupliObject *next, *prev;
index 4c10e5a..22402a6 100644 (file)
@@ -1102,28 +1102,3 @@ void free_object_duplilist(ListBase *lb)
        BLI_freelistN(lb);
        MEM_freeN(lb);
 }
-
-int count_duplilist(Object *ob)
-{
-       if (ob->transflag & OB_DUPLI) {
-               if (ob->transflag & OB_DUPLIVERTS) {
-                       if (ob->type == OB_MESH) {
-                               if (ob->transflag & OB_DUPLIVERTS) {
-                                       ParticleSystem *psys = ob->particlesystem.first;
-                                       int pdup = 0;
-
-                                       for (; psys; psys = psys->next)
-                                               pdup += psys->totpart;
-
-                                       if (pdup == 0) {
-                                               Mesh *me = ob->data;
-                                               return me->totvert;
-                                       }
-                                       else
-                                               return pdup;
-                               }
-                       }
-               }
-       }
-       return 1;
-}
index f2da794..16ef587 100644 (file)
@@ -91,7 +91,7 @@ typedef struct SceneStatsFmt {
        char totgpstroke[MAX_INFO_NUM_LEN], totgppoint[MAX_INFO_NUM_LEN];
 } SceneStatsFmt;
 
-static bool stats_mesheval(Mesh *me_eval, int sel, int totob, SceneStats *stats)
+static bool stats_mesheval(Mesh *me_eval, bool is_selected, SceneStats *stats)
 {
        if (me_eval == NULL) {
                return false;
@@ -110,32 +110,37 @@ static bool stats_mesheval(Mesh *me_eval, int sel, int totob, SceneStats *stats)
                totloop = me_eval->totloop;
        }
 
-       stats->totvert += totvert * totob;
-       stats->totedge += totedge * totob;
-       stats->totface += totface * totob;
-       stats->tottri  += poly_to_tri_count(totface, totloop) * totob;
+       stats->totvert += totvert;
+       stats->totedge += totedge;
+       stats->totface += totface;
+       stats->tottri  += poly_to_tri_count(totface, totloop);
 
-       if (sel) {
+       if (is_selected) {
                stats->totvertsel += totvert;
                stats->totfacesel += totface;
        }
        return true;
 }
 
-static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
+static void stats_object(Object *ob, SceneStats *stats)
 {
+       const bool is_selected = (ob->base_flag & BASE_SELECTED) != 0;
+
+       stats->totobj++;
+       if (is_selected) stats->totobjsel++;
+
        switch (ob->type) {
                case OB_MESH:
                {
                        /* we assume evaluated mesh is already built, this strictly does stats now. */
                        Mesh *me_eval = ob->runtime.mesh_eval;
-                       stats_mesheval(me_eval, sel, totob, stats);
+                       stats_mesheval(me_eval, is_selected, stats);
                        break;
                }
                case OB_LAMP:
-                       stats->totlamp += totob;
-                       if (sel) {
-                               stats->totlampsel += totob;
+                       stats->totlamp++;
+                       if (is_selected) {
+                               stats->totlampsel++;
                        }
                        break;
                case OB_SURF:
@@ -143,7 +148,7 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
                case OB_FONT:
                {
                        Mesh *me_eval = ob->runtime.mesh_eval;
-                       if (stats_mesheval(me_eval, sel, totob, stats)) {
+                       if (stats_mesheval(me_eval, is_selected, stats)) {
                                break;
                        }
                        ATTR_FALLTHROUGH;  /* Falltrough to displist. */
@@ -155,15 +160,11 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
                        if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first)
                                BKE_displist_count(&ob->runtime.curve_cache->disp, &totv, &totf, &tottri);
 
-                       totv   *= totob;
-                       totf   *= totob;
-                       tottri *= totob;
-
                        stats->totvert += totv;
                        stats->totface += totf;
                        stats->tottri  += tottri;
 
-                       if (sel) {
+                       if (is_selected) {
                                stats->totvertsel += totv;
                                stats->totfacesel += totf;
                        }
@@ -171,7 +172,7 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
                }
                case OB_GPENCIL:
                {
-                       if (sel) {
+                       if (is_selected) {
                                bGPdata *gpd = (bGPdata *)ob->data;
                                /* GPXX Review if we can move to other place when object change
                                 * maybe to depsgraph evaluation
@@ -313,86 +314,6 @@ static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
        stats->tottri = ob->sculpt->bm->totface;
 }
 
-static void stats_dupli_object_group_count(Collection *collection, int *count)
-{
-       *count += BLI_listbase_count(&collection->gobject);
-
-       for (CollectionChild *child = collection->children.first; child; child = child->next) {
-               stats_dupli_object_group_count(child->collection, count);
-       }
-}
-
-static void stats_dupli_object_group_doit(Collection *collection, SceneStats *stats, ParticleSystem *psys,
-                                          const int totgroup, int *cur)
-{
-       for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
-               int tot = count_particles_mod(psys, totgroup, *cur);
-               stats_object(cob->ob, 0, tot, stats);
-               (*cur)++;
-       }
-
-       for (CollectionChild *child = collection->children.first; child; child = child->next) {
-               stats_dupli_object_group_doit(child->collection, stats, psys, totgroup, cur);
-       }
-}
-
-static void stats_dupli_object(Object *ob, SceneStats *stats)
-{
-       const bool is_selected = (ob->base_flag & BASE_SELECTED) != 0;
-       if (is_selected) stats->totobjsel++;
-
-       if (ob->transflag & OB_DUPLIPARTS) {
-               /* Dupli Particles */
-               ParticleSystem *psys;
-               ParticleSettings *part;
-
-               for (psys = ob->particlesystem.first; psys; psys = psys->next) {
-                       part = psys->part;
-
-                       if (part->draw_as == PART_DRAW_OB && part->dup_ob) {
-                               int tot = count_particles(psys);
-                               stats_object(part->dup_ob, 0, tot, stats);
-                       }
-                       else if (part->draw_as == PART_DRAW_GR && part->dup_group) {
-                               int totgroup = 0, cur = 0;
-
-                               Collection *collection = part->dup_group;
-                               stats_dupli_object_group_count(collection, &totgroup);
-                               stats_dupli_object_group_doit(collection, stats, psys, totgroup, &cur);
-                       }
-               }
-
-               stats_object(ob, is_selected, 1, stats);
-               stats->totobj++;
-       }
-       else if (ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES))) {
-               /* Dupli Verts/Faces */
-               int tot;
-
-               /* metaball dupli-instances are tessellated once */
-               if (ob->type == OB_MBALL) {
-                       tot = 1;
-               }
-               else {
-                       tot = count_duplilist(ob->parent);
-               }
-
-               stats->totobj += tot;
-               stats_object(ob, is_selected, tot, stats);
-       }
-       else if ((ob->transflag & OB_DUPLICOLLECTION) && ob->dup_group) {
-               /* Dupli Group */
-               int tot = count_duplilist(ob);
-               stats->totobj += tot;
-               stats_object(ob, is_selected, tot, stats);
-       }
-       else {
-               /* No Dupli */
-               stats_object(ob, is_selected, 1, stats);
-               stats->totobj++;
-       }
-}
-
 static bool stats_is_object_dynamic_topology_sculpt(Object *ob, const eObjectMode object_mode)
 {
        return (ob &&
@@ -427,7 +348,7 @@ static void stats_update(Depsgraph *depsgraph, ViewLayer *view_layer)
                /* Objects */
                DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob_iter)
                {
-                       stats_dupli_object(ob_iter, &stats);
+                       stats_object(ob_iter, &stats);
                }
                DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
        }