diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-19 16:35:40 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-08-19 16:35:40 +0400 |
commit | aace6ef551183a3d09635c3103a8e4cba4f9117a (patch) | |
tree | eea82219e48e722e97fb9964f6138f3bac646bfe /source/blender | |
parent | c3041ae7cda20c78040e7deea17530fe5f41029d (diff) |
2.5: Restored statistics in the info header.
Implementation:
* NC_SCENE or NC_OBJECT cause scene->stats to be cleared.
* NC_INFO is sent to tag info headers for redraw.
* In UI scene.statistics() creates scene->stats if it is
NULLd, and then returns the string.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/editors/include/ED_info.h | 32 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_stats.c | 434 | ||||
-rw-r--r-- | source/blender/editors/space_info/space_info.c | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 7 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 11 |
10 files changed, 499 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 2a8fd765386..6dd362d15a8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -155,6 +155,7 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) scen->theDag= NULL; scen->obedit= NULL; scen->toolsettings= MEM_dupallocN(sce->toolsettings); + scen->stats= NULL; ts= scen->toolsettings; if(ts) { @@ -299,6 +300,9 @@ void free_scene(Scene *sce) ntreeFreeTree(sce->nodetree); MEM_freeN(sce->nodetree); } + + if(sce->stats) + MEM_freeN(sce->stats); } Scene *add_scene(char *name) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 779a898bd6a..db811b22460 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4134,6 +4134,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->theDag = NULL; sce->dagisvalid = 0; sce->obedit= NULL; + sce->stats= 0; memset(&sce->sound_handles, 0, sizeof(sce->sound_handles)); diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h new file mode 100644 index 00000000000..d09e174d71d --- /dev/null +++ b/source/blender/editors/include/ED_info.h @@ -0,0 +1,32 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009, Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef ED_INFO_H +#define ED_INFO_H + +/* info_stats.c */ +void ED_info_stats_clear(struct Scene *scene); +char *ED_info_stats_string(struct Scene *scene); + +#endif /* ED_INFO_H */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index a70fbab1aa4..48de2343c97 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -835,9 +835,11 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b // else transopts= ui_translate_buttons(); /* cut string in 2 parts - only for menu entries */ - if(ELEM5(but->type, SLI, NUM, TEX, NUMSLI, NUMABS)==0) { - cpoin= strchr(but->drawstr, '|'); - if(cpoin) *cpoin= 0; + if((but->block->flag & UI_BLOCK_LOOP)) { + if(ELEM5(but->type, SLI, NUM, TEX, NUMSLI, NUMABS)==0) { + cpoin= strchr(but->drawstr, '|'); + if(cpoin) *cpoin= 0; + } } glColor3ubv((unsigned char*)wcol->text); diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c new file mode 100644 index 00000000000..2d14fbc515e --- /dev/null +++ b/source/blender/editors/space_info/info_stats.c @@ -0,0 +1,434 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_particle_types.h" +#include "DNA_scene_types.h" + +#include "BKE_anim.h" +#include "BKE_context.h" +#include "BKE_displist.h" +#include "BKE_DerivedMesh.h" +#include "BKE_key.h" +#include "BKE_mesh.h" +#include "BKE_particle.h" +#include "BKE_utildefines.h" + +#include "ED_armature.h" +#include "ED_mesh.h" + +#include "BLI_editVert.h" + +typedef struct SceneStats { + int totvert, totvertsel; + int totedge, totedgesel; + int totface, totfacesel; + int totbone, totbonesel; + int totobj, totobjsel; + int totmesh, totlamp, totcurve; + + char infostr[512]; +} SceneStats; + +static void stats_object(Object *ob, int sel, int totob, SceneStats *stats) +{ + switch(ob->type) { + case OB_MESH: { + /* we assume derivedmesh is already built, this strictly does stats now. */ + DerivedMesh *dm= ob->derivedFinal; + int totvert, totedge, totface; + + stats->totmesh +=totob; + + if(dm) { + totvert = dm->getNumVerts(dm); + totedge = dm->getNumEdges(dm); + totface = dm->getNumFaces(dm); + + stats->totvert += totvert*totob; + stats->totedge += totedge*totob; + stats->totface += totface*totob; + + if(sel) { + stats->totvertsel += totvert; + stats->totfacesel += totface; + } + } + break; + } + case OB_LAMP: + stats->totlamp += totob; + break; + case OB_SURF: + case OB_CURVE: + case OB_FONT: { + Curve *cu= ob->data; + int tot= 0, totf= 0; + + stats->totcurve += totob; + + if(cu->disp.first) + count_displist(&cu->disp, &tot, &totf); + + tot *= totob; + totf *= totob; + + stats->totvert+= tot; + stats->totface+= totf; + + if(sel) { + stats->totvertsel += tot; + stats->totfacesel += totf; + } + break; + } + case OB_MBALL: { + int tot= 0, totf= 0; + + count_displist(&ob->disp, &tot, &totf); + + tot *= totob; + totf *= totob; + + stats->totvert += tot; + stats->totface += totf; + + if(sel) { + stats->totvertsel += tot; + stats->totfacesel += totf; + } + break; + } + } +} + +static void stats_object_edit(Object *obedit, SceneStats *stats) +{ + if(obedit->type==OB_MESH) { + /* Mesh Edit */ + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); + EditVert *eve; + EditEdge *eed; + EditFace *efa; + + for(eve= em->verts.first; eve; eve=eve->next) { + stats->totvert++; + if(eve->f & SELECT) stats->totvertsel++; + } + for(eed= em->edges.first; eed; eed=eed->next) { + stats->totedge++; + if(eed->f & SELECT) stats->totedgesel++; + } + for(efa= em->faces.first; efa; efa=efa->next) { + stats->totface++; + if(efa->f & SELECT) stats->totfacesel++; + } + + EM_validate_selections(em); + } + else if(obedit->type==OB_ARMATURE){ + /* Armature Edit */ + bArmature *arm= obedit->data; + EditBone *ebo; + + for(ebo=arm->edbo->first; ebo; ebo=ebo->next){ + stats->totbone++; + + if((ebo->flag & BONE_CONNECTED) && ebo->parent) + stats->totvert--; + + if(ebo->flag & BONE_TIPSEL) + stats->totvertsel++; + if(ebo->flag & BONE_ROOTSEL) + stats->totvertsel++; + + if(ebo->flag & BONE_SELECTED) stats->totbonesel++; + + /* if this is a connected child and it's parent is being moved, remove our root */ + if((ebo->flag & BONE_CONNECTED)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL)) + stats->totvertsel--; + + stats->totvert+=2; + } + } + else if ELEM3(obedit->type, OB_CURVE, OB_SURF, OB_FONT) { + /* Curve Edit */ + Curve *cu= obedit->data; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + for(nu=cu->editnurb->first; nu; nu=nu->next) { + if((nu->type & 7)==CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + stats->totvert+=3; + if(bezt->f1) stats->totvertsel++; + if(bezt->f2) stats->totvertsel++; + if(bezt->f3) stats->totvertsel++; + bezt++; + } + } + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + stats->totvert++; + if(bp->f1 & SELECT) stats->totvertsel++; + bp++; + } + } + } + } + else if(obedit->type==OB_MBALL) { + /* MetaBall Edit */ + MetaBall *mball= obedit->data; + MetaElem *ml; + + for(ml= mball->editelems->first; ml; ml=ml->next) { + stats->totvert++; + if(ml->flag & SELECT) stats->totvertsel++; + } + } + else if(obedit->type==OB_LATTICE) { + /* Lattice Edit */ + Lattice *lt= obedit->data; + Lattice *editlatt= lt->editlatt; + BPoint *bp; + int a; + + bp= editlatt->def; + + a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw; + while(a--) { + stats->totvert++; + if(bp->f1 & SELECT) stats->totvertsel++; + bp++; + } + } +} + +static void stats_object_pose(Object *ob, SceneStats *stats) +{ + if(ob->pose) { + bArmature *arm= ob->data; + bPoseChannel *pchan; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + stats->totbone++; + if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) + if(pchan->bone->layer & arm->layer) + stats->totbonesel++; + } + } +} + +static void stats_object_paint(Object *ob, SceneStats *stats) +{ + if(ob->type == OB_MESH) { + Mesh *me= ob->data; + + stats->totface= me->totface; + stats->totvert= me->totvert; + } +} + +static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats) +{ + if(base->flag & SELECT) 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){ + GroupObject *go; + int tot, totgroup=0, cur=0; + + for(go= part->dup_group->gobject.first; go; go=go->next) + totgroup++; + + for(go= part->dup_group->gobject.first; go; go=go->next) { + tot=count_particles_mod(psys,totgroup,cur); + stats_object(go->ob, 0, tot, stats); + cur++; + } + } + } + + stats_object(ob, base->flag & SELECT, 1, stats); + stats->totobj++; + } + else if(ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS|OB_DUPLIFACES))) { + /* Dupli Verts/Faces */ + int tot= count_duplilist(ob->parent); + stats->totobj+=tot; + stats_object(ob, base->flag & SELECT, tot, stats); + } + else if(ob->transflag & OB_DUPLIFRAMES) { + /* Dupli Frames */ + int tot= count_duplilist(ob); + stats->totobj+=tot; + stats_object(ob, base->flag & SELECT, tot, stats); + } + else if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { + /* Dupli Group */ + int tot= count_duplilist(ob); + stats->totobj+=tot; + stats_object(ob, base->flag & SELECT, tot, stats); + } + else { + /* No Dupli */ + stats_object(ob, base->flag & SELECT, 1, stats); + stats->totobj++; + } +} + +/* Statistics displayed in info header. Called regularly on scene changes. */ +static void stats_update(Scene *scene) +{ + SceneStats stats; + Object *ob= (scene->basact)? scene->basact->object: NULL; + Base *base; + + memset(&stats, 0, sizeof(stats)); + + if(scene->obedit) { + /* Edit Mode */ + stats_object_edit(scene->obedit, &stats); + } + else if(ob && (ob->mode & OB_MODE_POSE)) { + /* Pose Mode */ + stats_object_pose(ob, &stats); + } + else if(ob && (ob->flag & (OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))) { + /* Sculpt and Paint Mode */ + stats_object_paint(ob, &stats); + } + else { + /* Objects */ + for(base= scene->base.first; base; base=base->next) + if(scene->lay & base->lay) + stats_dupli_object(base, base->object, &stats); + } + + if(!scene->stats) + scene->stats= MEM_mallocN(sizeof(SceneStats), "SceneStats"); + + *(scene->stats)= stats; +} + +static void stats_string(Scene *scene) +{ + SceneStats *stats= scene->stats; + Object *ob= (scene->basact)? scene->basact->object: NULL; + uintptr_t mem_in_use, mmap_in_use; + char memstr[64]; + char *s; + + mem_in_use= MEM_get_memory_in_use(); + mmap_in_use= MEM_get_mapped_memory_in_use(); + + /* get memory statistics */ + s= memstr + sprintf(memstr, " | Mem:%.2fM", ((mem_in_use-mmap_in_use)>>10)/1024.0); + if(mmap_in_use) + sprintf(s, " (%.2fM)", ((mmap_in_use)>>10)/1024.0); + + s= stats->infostr; + + if(scene->obedit) { + if(ob_get_keyblock(scene->obedit)) + s+= sprintf(s, "(Key) "); + + if(scene->obedit->type==OB_MESH) { + if(scene->toolsettings->selectmode & SCE_SELECT_VERTEX) + s+= sprintf(s, "Ve:%d-%d | Ed:%d-%d | Fa:%d-%d", + stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge, stats->totfacesel, stats->totface); + else if(scene->toolsettings->selectmode & SCE_SELECT_EDGE) + s+= sprintf(s, "Ed:%d-%d | Fa:%d-%d", + stats->totedgesel, stats->totedge, stats->totfacesel, stats->totface); + else + s+= sprintf(s, "Fa:%d-%d", stats->totfacesel, stats->totface); + } + else if(scene->obedit->type==OB_ARMATURE) { + s+= sprintf(s, "Ve:%d-%d | Bo:%d-%d", stats->totvertsel, stats->totvert, stats->totbonesel, stats->totbone); + } + else { + s+= sprintf(s, "Ve:%d-%d", stats->totvertsel, stats->totvert); + } + + strcat(s, memstr); + } + else if(ob && (ob->mode & OB_MODE_POSE)) { + s += sprintf(s, "Bo:%d-%d %s", + stats->totbonesel, stats->totbone, memstr); + } + else { + s += sprintf(s, "Ve:%d | Fa:%d | Ob:%d-%d | La:%d%s", + stats->totvert, stats->totface, stats->totobj, stats->totobjsel, stats->totlamp, memstr); + } + + if(ob) + sprintf(s, " | %s", ob->id.name+2); +} + +void ED_info_stats_clear(Scene *scene) +{ + if(scene->stats) { + MEM_freeN(scene->stats); + scene->stats= NULL; + } +} + +char *ED_info_stats_string(Scene *scene) +{ + if(!scene->stats) + stats_update(scene); + stats_string(scene); + + return scene->stats->infostr; +} + diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index fe5bbf04af1..b6f9cbeabb5 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -1,5 +1,5 @@ /** - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -58,6 +58,7 @@ #include "UI_view2d.h" #include "ED_markers.h" +#include "ED_object.h" #include "info_intern.h" // own include @@ -166,6 +167,9 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn) if(wmn->data==ND_RENDER_RESULT) ED_region_tag_redraw(ar); break; + case NC_INFO: + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 4a3d555ca33..f1a77d78b7b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -47,6 +47,7 @@ struct Text; struct bNodeTree; struct AnimData; struct Editing; +struct SceneStats; typedef struct Base { struct Base *next, *prev; @@ -717,7 +718,6 @@ typedef struct Scene { /* Units */ struct UnitSettings unit; - } Scene; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 88796919c3e..0301932aef3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -62,6 +62,7 @@ EnumPropertyItem prop_mode_items[] ={ #include "BLI_threads.h" +#include "ED_info.h" #include "ED_node.h" #include "RE_pipeline.h" @@ -1823,6 +1824,7 @@ void RNA_def_scene(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + FunctionRNA *func; /* Struct definition */ srna= RNA_def_struct(brna, "Scene", "ID"); @@ -1982,6 +1984,11 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "gm"); RNA_def_property_struct_type(prop, "SceneGameData"); RNA_def_property_ui_text(prop, "Game Data", ""); + + /* Statistics */ + func= RNA_def_function(srna, "statistics", "ED_info_stats_string"); + prop= RNA_def_string(func, "statistics", "", 0, "Statistics", ""); + RNA_def_function_return(func, prop); rna_def_tool_settings(brna); rna_def_unit_settings(brna); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 00e9f6a2fa2..b717df8f61f 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -134,6 +134,7 @@ typedef struct wmNotifier { #define NC_ANIMATION (15<<24) #define NC_CONSOLE (16<<24) #define NC_NODE (17<<24) +#define NC_INFO (18<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f0d9f8c0989..6c34ed6f902 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -52,6 +52,7 @@ #include "BKE_pointcache.h" #include "ED_fileselect.h" +#include "ED_info.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_util.h" @@ -129,7 +130,7 @@ static wmNotifier *wm_notifier_next(wmWindowManager *wm) void wm_event_do_notifiers(bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); - wmNotifier *note; + wmNotifier *note, *next; wmWindow *win; if(wm==NULL) @@ -141,7 +142,9 @@ void wm_event_do_notifiers(bContext *C) CTX_wm_window_set(C, win); - for(note= wm->queue.first; note; note= note->next) { + for(note= wm->queue.first; note; note= next) { + next= note->next; + if(note->category==NC_WM) { if( ELEM(note->data, ND_FILEREAD, ND_FILESAVE)) { wm->file_saved= 1; @@ -174,6 +177,10 @@ void wm_event_do_notifiers(bContext *C) do_anim= 1; } } + if(note->category == NC_SCENE || note->category == NC_OBJECT) { + ED_info_stats_clear(CTX_data_scene(C)); + WM_event_add_notifier(C, NC_INFO, NULL); + } } if(do_anim) { /* depsgraph gets called, might send more notifiers */ |