@@ -498,6 +498,55 @@ static int measureUnique(std::vector<int>& used, const std::vector<unsigned int>
498
498
return int (vertices);
499
499
}
500
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
+ }
549
+
501
550
static bool loadMetis ()
502
551
{
503
552
#ifdef _WIN32
@@ -538,7 +587,6 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
538
587
539
588
int depth = 0 ;
540
589
std::vector<unsigned char > locks (vertices.size ());
541
- std::vector<int > parents (vertices.size ());
542
590
543
591
// for cluster connectivity, we need a position-only remap that maps vertices with the same position to the same index
544
592
// it's more efficient to build it once; unfortunately, meshopt_generateVertexRemap doesn't support stride so we need to use *Multi version
@@ -551,23 +599,8 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
551
599
for (size_t i = 0 ; i < clusters.size (); ++i)
552
600
clusters[i].self = bounds (vertices, clusters[i].indices , 0 .f );
553
601
554
- size_t components_initial = 0 ;
555
- size_t xformed_initial = 0 ;
556
- for (size_t i = 0 ; i < clusters.size (); ++i)
557
- {
558
- components_initial += measureComponents (parents, clusters[i].indices , remap);
559
- xformed_initial += measureUnique (parents, clusters[i].indices );
560
- }
561
-
562
602
printf (" ideal lod chain: %.1f levels\n " , log2 (double (indices.size () / 3 ) / double (kClusterSize )));
563
603
564
- printf (" lod 0: %d clusters (%.1f tri/cl, %.1f vtx/cl, %.2f connected), %d triangles\n " ,
565
- int (clusters.size ()),
566
- double (indices.size () / 3 ) / double (clusters.size ()),
567
- double (xformed_initial) / double (clusters.size ()),
568
- double (components_initial) / double (clusters.size ()),
569
- int (indices.size () / 3 ));
570
-
571
604
std::vector<int > pending (clusters.size ());
572
605
for (size_t i = 0 ; i < clusters.size (); ++i)
573
606
pending[i] = int (i);
@@ -576,26 +609,20 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
576
609
while (pending.size () > 1 )
577
610
{
578
611
std::vector<std::vector<int > > groups = partition (clusters, pending, remap);
579
- double avg_group = double (pending.size ()) / double (groups.size ());
612
+
613
+ if (kUseLocks )
614
+ lockBoundary (locks, groups, clusters, remap);
580
615
581
616
pending.clear ();
582
617
583
618
std::vector<int > retry;
584
619
585
620
size_t triangles = 0 ;
586
621
size_t stuck_triangles = 0 ;
587
- int stuck_clusters = 0 ;
588
- int full_clusters = 0 ;
589
- size_t components_lod = 0 ;
590
- size_t xformed_lod = 0 ;
591
- size_t boundary_lod = 0 ;
592
622
593
623
if (dump && depth == atoi (dump))
594
624
dumpObj (vertices, std::vector<unsigned int >());
595
625
596
- if (kUseLocks )
597
- lockBoundary (locks, groups, clusters, remap);
598
-
599
626
// every group needs to be simplified now
600
627
for (size_t i = 0 ; i < groups.size (); ++i)
601
628
{
@@ -621,10 +648,6 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
621
648
std::vector<unsigned int > simplified = simplify (vertices, merged, kUseLocks ? &locks : NULL , target_size, &error);
622
649
if (simplified.size () > merged.size () * kSimplifyThreshold )
623
650
{
624
- #if TRACE
625
- printf (" stuck cluster: simplified %d => %d over threshold\n " , int (merged.size () / 3 ), int (simplified.size () / 3 ));
626
- #endif
627
- stuck_clusters += groups[i].size ();
628
651
stuck_triangles += merged.size () / 3 ;
629
652
for (size_t j = 0 ; j < groups[i].size (); ++j)
630
653
retry.push_back (groups[i][j]);
@@ -661,23 +684,11 @@ void nanite(const std::vector<Vertex>& vertices, const std::vector<unsigned int>
661
684
pending.push_back (int (clusters.size ()) - 1 );
662
685
663
686
triangles += split[j].indices .size () / 3 ;
664
- full_clusters += split[j].indices .size () == kClusterSize * 3 ;
665
- components_lod += measureComponents (parents, split[j].indices , remap);
666
- xformed_lod += measureUnique (parents, split[j].indices );
667
- boundary_lod += kUseLocks ? measureUnique (parents, split[j].indices , &locks) : 0 ;
668
687
}
669
688
}
670
689
671
- double inv_clusters = pending.empty () ? 0 : 1.0 / double (pending.size ());
672
-
690
+ dumpMetrics (depth, clusters, groups, remap, locks, retry);
673
691
depth++;
674
- printf (" lod %d: %d clusters (%.1f%% full, %.1f tri/cl, %.1f vtx/cl, %.2f connected, %.1f boundary, %.1f partition), %d triangles" ,
675
- depth, int (pending.size ()),
676
- double (full_clusters) * inv_clusters * 100 , double (triangles) * inv_clusters, double (xformed_lod) * inv_clusters, double (components_lod) * inv_clusters, double (boundary_lod) * inv_clusters, avg_group,
677
- int (triangles));
678
- if (stuck_clusters)
679
- printf (" ; stuck %d clusters (%d triangles)" , stuck_clusters, int (stuck_triangles));
680
- printf (" \n " );
681
692
682
693
if (kUseRetry )
683
694
{
0 commit comments