Skip to content

Commit 35f8b13

Browse files
committed
demo: Move all metrics functions to the bottom of the file
This ensures they are more separate from the main processing, making the former easier to read.
1 parent f3e0e9e commit 35f8b13

File tree

1 file changed

+123
-142
lines changed

1 file changed

+123
-142
lines changed

demo/nanite.cpp

Lines changed: 123 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -428,124 +428,7 @@ static std::vector<unsigned int> simplify(const std::vector<Vertex>& vertices, c
428428
return lod;
429429
}
430430

431-
static int follow(std::vector<int>& parents, int index)
432-
{
433-
while (index != parents[index])
434-
{
435-
int parent = parents[index];
436-
parents[index] = parents[parent];
437-
index = parent;
438-
}
439-
440-
return index;
441-
}
442-
443-
static int measureComponents(std::vector<int>& parents, const std::vector<unsigned int>& indices, const std::vector<unsigned int>& remap)
444-
{
445-
assert(parents.size() == remap.size());
446-
447-
for (size_t i = 0; i < indices.size(); ++i)
448-
{
449-
unsigned int v = remap[indices[i]];
450-
parents[v] = v;
451-
}
452-
453-
for (size_t i = 0; i < indices.size(); ++i)
454-
{
455-
int v0 = remap[indices[i]];
456-
int v1 = remap[indices[i + (i % 3 == 2 ? -2 : 1)]];
457-
458-
v0 = follow(parents, v0);
459-
v1 = follow(parents, v1);
460-
461-
parents[v0] = v1;
462-
}
463-
464-
for (size_t i = 0; i < indices.size(); ++i)
465-
{
466-
unsigned int v = remap[indices[i]];
467-
parents[v] = follow(parents, v);
468-
}
469-
470-
int roots = 0;
471-
for (size_t i = 0; i < indices.size(); ++i)
472-
{
473-
unsigned int v = remap[indices[i]];
474-
roots += parents[v] == int(v);
475-
parents[v] = -1; // make sure we only count each root once
476-
}
477-
478-
return roots;
479-
}
480-
481-
static int measureUnique(std::vector<int>& used, const std::vector<unsigned int>& indices, const std::vector<unsigned char>* locks = NULL)
482-
{
483-
for (size_t i = 0; i < indices.size(); ++i)
484-
{
485-
unsigned int v = indices[i];
486-
used[v] = 1;
487-
}
488-
489-
size_t vertices = 0;
490-
491-
for (size_t i = 0; i < indices.size(); ++i)
492-
{
493-
unsigned int v = indices[i];
494-
vertices += used[v] && (!locks || (*locks)[v]);
495-
used[v] = 0;
496-
}
497-
498-
return int(vertices);
499-
}
500-
501-
static void dumpMetrics(int level, const std::vector<Cluster>& queue, const std::vector<std::vector<int> >& groups, const std::vector<unsigned int>& remap, const std::vector<unsigned char>& locks, const std::vector<int>& retry)
502-
{
503-
std::vector<int> parents(remap.size());
504-
505-
int clusters = 0;
506-
int triangles = 0;
507-
int full_clusters = 0;
508-
int components = 0;
509-
int xformed = 0;
510-
int boundary = 0;
511-
512-
for (size_t i = 0; i < groups.size(); ++i)
513-
{
514-
for (size_t j = 0; j < groups[i].size(); ++j)
515-
{
516-
const Cluster& cluster = queue[groups[i][j]];
517-
518-
clusters++;
519-
triangles += int(cluster.indices.size() / 3);
520-
full_clusters += cluster.indices.size() == kClusterSize * 3;
521-
components += measureComponents(parents, cluster.indices, remap);
522-
xformed += measureUnique(parents, cluster.indices);
523-
boundary += kUseLocks ? measureUnique(parents, cluster.indices, &locks) : 0;
524-
}
525-
}
526-
527-
int stuck_clusters = 0;
528-
int stuck_triangles = 0;
529-
530-
for (size_t i = 0; i < retry.size(); ++i)
531-
{
532-
const Cluster& cluster = queue[retry[i]];
533-
534-
stuck_clusters++;
535-
stuck_triangles += int(cluster.indices.size() / 3);
536-
}
537-
538-
double avg_group = double(clusters) / double(groups.size());
539-
double inv_clusters = 1.0 / double(clusters);
540-
541-
printf("lod %d: %d clusters (%.1f%% full, %.1f tri/cl, %.1f vtx/cl, %.2f connected, %.1f boundary, %.1f partition), %d triangles",
542-
level, clusters,
543-
double(full_clusters) * inv_clusters * 100, double(triangles) * inv_clusters, double(xformed) * inv_clusters, double(components) * inv_clusters, double(boundary) * inv_clusters, avg_group,
544-
int(triangles));
545-
if (stuck_clusters)
546-
printf("; stuck %d clusters (%d triangles)", stuck_clusters, stuck_triangles);
547-
printf("\n");
548-
}
431+
static void dumpMetrics(int level, const std::vector<Cluster>& queue, const std::vector<std::vector<int> >& groups, const std::vector<unsigned int>& remap, const std::vector<unsigned char>& locks, const std::vector<int>& retry);
549432

550433
static bool loadMetis()
551434
{
@@ -581,10 +464,6 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
581464

582465
static const char* dump = getenv("DUMP");
583466

584-
#ifndef NDEBUG
585-
std::vector<std::pair<int, int> > dag_debug;
586-
#endif
587-
588467
int depth = 0;
589468
std::vector<unsigned char> locks(vertices.size());
590469

@@ -669,13 +548,6 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
669548
clusters[groups[i][j]].parent = groupb;
670549
}
671550

672-
#ifndef NDEBUG
673-
// record DAG edges for validation during the cut
674-
for (size_t j = 0; j < groups[i].size(); ++j)
675-
for (size_t k = 0; k < split.size(); ++k)
676-
dag_debug.push_back(std::make_pair(groups[i][j], int(clusters.size()) + int(k)));
677-
#endif
678-
679551
for (size_t j = 0; j < split.size(); ++j)
680552
{
681553
split[j].self = groupb;
@@ -730,19 +602,6 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
730602
if (boundsError(clusters[i].self, maxx, maxy, maxz, proj, znear) <= threshold && boundsError(clusters[i].parent, maxx, maxy, maxz, proj, znear) > threshold)
731603
cut.insert(cut.end(), clusters[i].indices.begin(), clusters[i].indices.end());
732604

733-
#ifndef NDEBUG
734-
for (size_t i = 0; i < dag_debug.size(); ++i)
735-
{
736-
int j = dag_debug[i].first, k = dag_debug[i].second;
737-
float ej = boundsError(clusters[j].self, maxx, maxy, maxz, proj, znear);
738-
float ejp = boundsError(clusters[j].parent, maxx, maxy, maxz, proj, znear);
739-
float ek = boundsError(clusters[k].self, maxx, maxy, maxz, proj, znear);
740-
741-
assert(ej <= ek);
742-
assert(ejp >= ej);
743-
}
744-
#endif
745-
746605
printf("cut (%.3f): %d triangles\n", threshold, int(cut.size() / 3));
747606

748607
if (dump && -1 == atoi(dump))
@@ -754,3 +613,125 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
754613
dumpObj("cluster", clusters[i].indices);
755614
}
756615
}
616+
617+
// What follows is code that is helpful for collecting metrics, visualizing cuts, etc.
618+
// This code is not used in the actual clustering implementation and can be ignored.
619+
620+
static int follow(std::vector<int>& parents, int index)
621+
{
622+
while (index != parents[index])
623+
{
624+
int parent = parents[index];
625+
parents[index] = parents[parent];
626+
index = parent;
627+
}
628+
629+
return index;
630+
}
631+
632+
static int measureComponents(std::vector<int>& parents, const std::vector<unsigned int>& indices, const std::vector<unsigned int>& remap)
633+
{
634+
assert(parents.size() == remap.size());
635+
636+
for (size_t i = 0; i < indices.size(); ++i)
637+
{
638+
unsigned int v = remap[indices[i]];
639+
parents[v] = v;
640+
}
641+
642+
for (size_t i = 0; i < indices.size(); ++i)
643+
{
644+
int v0 = remap[indices[i]];
645+
int v1 = remap[indices[i + (i % 3 == 2 ? -2 : 1)]];
646+
647+
v0 = follow(parents, v0);
648+
v1 = follow(parents, v1);
649+
650+
parents[v0] = v1;
651+
}
652+
653+
for (size_t i = 0; i < indices.size(); ++i)
654+
{
655+
unsigned int v = remap[indices[i]];
656+
parents[v] = follow(parents, v);
657+
}
658+
659+
int roots = 0;
660+
for (size_t i = 0; i < indices.size(); ++i)
661+
{
662+
unsigned int v = remap[indices[i]];
663+
roots += parents[v] == int(v);
664+
parents[v] = -1; // make sure we only count each root once
665+
}
666+
667+
return roots;
668+
}
669+
670+
static int measureUnique(std::vector<int>& used, const std::vector<unsigned int>& indices, const std::vector<unsigned char>* locks = NULL)
671+
{
672+
for (size_t i = 0; i < indices.size(); ++i)
673+
{
674+
unsigned int v = indices[i];
675+
used[v] = 1;
676+
}
677+
678+
size_t vertices = 0;
679+
680+
for (size_t i = 0; i < indices.size(); ++i)
681+
{
682+
unsigned int v = indices[i];
683+
vertices += used[v] && (!locks || (*locks)[v]);
684+
used[v] = 0;
685+
}
686+
687+
return int(vertices);
688+
}
689+
690+
static void dumpMetrics(int level, const std::vector<Cluster>& queue, const std::vector<std::vector<int> >& groups, const std::vector<unsigned int>& remap, const std::vector<unsigned char>& locks, const std::vector<int>& retry)
691+
{
692+
std::vector<int> parents(remap.size());
693+
694+
int clusters = 0;
695+
int triangles = 0;
696+
int full_clusters = 0;
697+
int components = 0;
698+
int xformed = 0;
699+
int boundary = 0;
700+
701+
for (size_t i = 0; i < groups.size(); ++i)
702+
{
703+
for (size_t j = 0; j < groups[i].size(); ++j)
704+
{
705+
const Cluster& cluster = queue[groups[i][j]];
706+
707+
clusters++;
708+
triangles += int(cluster.indices.size() / 3);
709+
full_clusters += cluster.indices.size() == kClusterSize * 3;
710+
components += measureComponents(parents, cluster.indices, remap);
711+
xformed += measureUnique(parents, cluster.indices);
712+
boundary += kUseLocks ? measureUnique(parents, cluster.indices, &locks) : 0;
713+
}
714+
}
715+
716+
int stuck_clusters = 0;
717+
int stuck_triangles = 0;
718+
719+
for (size_t i = 0; i < retry.size(); ++i)
720+
{
721+
const Cluster& cluster = queue[retry[i]];
722+
723+
stuck_clusters++;
724+
stuck_triangles += int(cluster.indices.size() / 3);
725+
}
726+
727+
double avg_group = double(clusters) / double(groups.size());
728+
double inv_clusters = 1.0 / double(clusters);
729+
730+
printf("lod %d: %d clusters (%.1f%% full, %.1f tri/cl, %.1f vtx/cl, %.2f connected, %.1f boundary, %.1f partition), %d triangles",
731+
level, clusters,
732+
double(full_clusters) * inv_clusters * 100, double(triangles) * inv_clusters, double(xformed) * inv_clusters, double(components) * inv_clusters, double(boundary) * inv_clusters, avg_group,
733+
int(triangles));
734+
if (stuck_clusters)
735+
printf("; stuck %d clusters (%d triangles)", stuck_clusters, stuck_triangles);
736+
printf("\n");
737+
}

0 commit comments

Comments
 (0)