display the number of tri's in object mode status, often requested feature from users who model for realtime/game-engine output,

the total number of faces wasn't so useful and could be especially misleading with ngons.
This commit is contained in:
Campbell Barton
2012-12-27 03:51:45 +00:00
parent 6586fd9c62
commit 1d6c3ccf09
5 changed files with 68 additions and 41 deletions

View File

@@ -83,7 +83,7 @@ void BKE_displist_elem_free(DispList *dl);
DispList *BKE_displist_find_or_create(struct ListBase *lb, int type); DispList *BKE_displist_find_or_create(struct ListBase *lb, int type);
DispList *BKE_displist_find(struct ListBase *lb, int type); DispList *BKE_displist_find(struct ListBase *lb, int type);
void BKE_displist_normals_add(struct ListBase *lb); void BKE_displist_normals_add(struct ListBase *lb);
void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface); void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *tottri);
void BKE_displist_free(struct ListBase *lb); void BKE_displist_free(struct ListBase *lb);
int BKE_displist_has_faces(struct ListBase *lb); int BKE_displist_has_faces(struct ListBase *lb);

View File

@@ -225,29 +225,48 @@ void BKE_displist_normals_add(ListBase *lb)
} }
} }
void BKE_displist_count(ListBase *lb, int *totvert, int *totface) void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri)
{ {
DispList *dl; DispList *dl;
dl = lb->first; for (dl = lb->first; dl; dl = dl->next) {
while (dl) { int vert_tot = 0;
int face_tot = 0;
int tri_tot = 0;
switch (dl->type) { switch (dl->type) {
case DL_SURF: case DL_SURF:
*totvert += dl->nr * dl->parts; {
*totface += (dl->nr - 1) * (dl->parts - 1); vert_tot = dl->nr * dl->parts;
face_tot = (dl->nr - 1) * (dl->parts - 1);
tri_tot = face_tot * 2;
break; break;
}
case DL_INDEX3: case DL_INDEX3:
case DL_INDEX4: {
*totvert += dl->nr; vert_tot = dl->nr;
*totface += dl->parts; face_tot = dl->parts;
tri_tot = face_tot;
break; break;
}
case DL_INDEX4:
{
vert_tot = dl->nr;
face_tot = dl->parts;
tri_tot = face_tot * 2;
break;
}
case DL_POLY: case DL_POLY:
case DL_SEGM: case DL_SEGM:
*totvert += dl->nr * dl->parts; {
vert_tot = dl->nr * dl->parts;
break; break;
}
} }
dl = dl->next; *totvert += vert_tot;
*totface += face_tot;
*tottri += tri_tot;
} }
} }

View File

@@ -262,6 +262,8 @@ void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3]);
MINLINE int max_axis_v3(const float vec[3]); MINLINE int max_axis_v3(const float vec[3]);
MINLINE int min_axis_v3(const float vec[3]); MINLINE int min_axis_v3(const float vec[3]);
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -158,4 +158,24 @@ MINLINE int min_axis_v3(const float vec[3])
((y < z) ? 1 : 2)); ((y < z) ? 1 : 2));
} }
/**
* Simple method to find how many tri's we need when we already know the corner+poly count.
*
* Formula is:
*
* tri = ((corner_count / poly_count) - 2) * poly_count;
*
* Use doubles since this is used for allocating and we
* don't want float precision to give incorrect results.
*
* \param poly_count The number of ngon's/tris (1-2 sided faces will give incorrect results)
* \param corner_count - also known as loops in BMesh/DNA
*/
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
{
const double poly_count_d = (double)poly_count;
const double corner_count_d = (double)corner_count;
return (int)((((corner_count_d / poly_count_d) - 2.0) * poly_count_d) + 0.5);
}
#endif /* __MATH_GEOM_INLINE_C__ */ #endif /* __MATH_GEOM_INLINE_C__ */

View File

@@ -39,6 +39,7 @@
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BKE_anim.h" #include "BKE_anim.h"
#include "BKE_blender.h" #include "BKE_blender.h"
@@ -62,7 +63,7 @@ typedef struct SceneStats {
int totbone, totbonesel; int totbone, totbonesel;
int totobj, totobjsel; int totobj, totobjsel;
int totlamp, totlampsel; int totlamp, totlampsel;
int tottri, totmesh, totcurve; int tottri, totmesh;
char infostr[512]; char infostr[512];
} SceneStats; } SceneStats;
@@ -74,7 +75,7 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
{ {
/* we assume derivedmesh is already built, this strictly does stats now. */ /* we assume derivedmesh is already built, this strictly does stats now. */
DerivedMesh *dm = ob->derivedFinal; DerivedMesh *dm = ob->derivedFinal;
int totvert, totedge, totface; int totvert, totedge, totface, totloop;
stats->totmesh += totob; stats->totmesh += totob;
@@ -82,10 +83,12 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
totvert = dm->getNumVerts(dm); totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm); totedge = dm->getNumEdges(dm);
totface = dm->getNumPolys(dm); totface = dm->getNumPolys(dm);
totloop = dm->getNumLoops(dm);
stats->totvert += totvert * totob; stats->totvert += totvert * totob;
stats->totedge += totedge * totob; stats->totedge += totedge * totob;
stats->totface += totface * totob; stats->totface += totface * totob;
stats->tottri += poly_to_tri_count(totface, totloop) * totob;
if (sel) { if (sel) {
stats->totvertsel += totvert; stats->totvertsel += totvert;
@@ -103,40 +106,23 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
case OB_SURF: case OB_SURF:
case OB_CURVE: case OB_CURVE:
case OB_FONT: case OB_FONT:
{
int tot = 0, totf = 0;
stats->totcurve += totob;
if (ob->disp.first)
BKE_displist_count(&ob->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: case OB_MBALL:
{ {
int tot = 0, totf = 0; int totv = 0, totf = 0, tottri = 0;
BKE_displist_count(&ob->disp, &tot, &totf); if (ob->disp.first)
BKE_displist_count(&ob->disp, &totv, &totf, &tottri);
tot *= totob; totv *= totob;
totf *= totob; totf *= totob;
tottri *= totob;
stats->totvert += tot; stats->totvert += totv;
stats->totface += totf; stats->totface += totf;
stats->tottri += tottri;
if (sel) { if (sel) {
stats->totvertsel += tot; stats->totvertsel += totv;
stats->totfacesel += totf; stats->totfacesel += totf;
} }
break; break;
@@ -389,8 +375,8 @@ static void stats_string(Scene *scene)
stats->totbonesel, stats->totbone, memstr); stats->totbonesel, stats->totbone, memstr);
} }
else { else {
s += sprintf(s, "Verts:%d | Faces:%d | Objects:%d/%d | Lamps:%d/%d%s", s += sprintf(s, "Verts:%d | Faces:%d| Tris:%d | Objects:%d/%d | Lamps:%d/%d%s",
stats->totvert, stats->totface, stats->totobjsel, stats->totobj, stats->totlampsel, stats->totlamp, memstr); stats->totvert, stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel, stats->totlamp, memstr);
} }
if (ob) if (ob)