From 9fa17cdbbaf09abadc61b3bfa9581fd762c1da2f Mon Sep 17 00:00:00 2001
From: Will Schroeder <will.schroeder@kitware.com>
Date: Fri, 14 Apr 2023 10:09:27 -0400
Subject: [PATCH] Extended test to process cell data

The test now tests processing of both cell and point scalar data.
---
 Filters/Core/Testing/Python/TestPackLabels.py | 55 ++++++++++++++++++-
 Filters/Core/vtkPackLabels.cxx                | 21 +++++--
 2 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/Filters/Core/Testing/Python/TestPackLabels.py b/Filters/Core/Testing/Python/TestPackLabels.py
index e46aeed054d..1049572cba9 100755
--- a/Filters/Core/Testing/Python/TestPackLabels.py
+++ b/Filters/Core/Testing/Python/TestPackLabels.py
@@ -40,9 +40,9 @@ scalars.SetTuple1(24,0)
 
 # Print out data as constructed
 if debugPrint:
+    print("Input to pack labels:")
     for i in range(0,numVoxels):
         print(i,scalars.GetTuple1(i))
-    print("\n")
 
 # Pack the labels. This should automatically pack into unsigned char.
 pack = vtk.vtkPackLabels()
@@ -53,15 +53,15 @@ pack.Update()
 labels = pack.GetLabels()
 numLabels = labels.GetNumberOfTuples()
 if debugPrint:
-    print("Number of labels: ",labels.GetNumberOfTuples())
+    print("\nNumber of resulting labels: ",labels.GetNumberOfTuples())
     for i in range(0,numLabels):
         print("Label: ", labels.GetTuple1(i))
-    print("\n")
 
 # Look at the resulting volume
 outScalars = pack.GetOutput().GetPointData().GetScalars()
 dataType = outScalars.GetDataType()
 if debugPrint:
+    print("\nPoint scalars: ")
     for i in range(0,numVoxels):
         print(i,outScalars.GetTuple1(i))
 
@@ -72,3 +72,52 @@ assert(labels.GetTuple1(0) == 0)
 assert(labels.GetTuple1(numLabels-1) == 123)
 assert(outScalars.GetTuple1(0) == 1)
 assert(outScalars.GetTuple1(numVoxels-1) == 0)
+
+# Now test sorting of packed labels by frequency count,
+# and make sure that packing works for cell data as well.
+numVoxelCells = (xDim-1) * (yDim-1) * (zDim-1)
+
+cellScalars = vtk.vtkShortArray()
+cellScalars.SetName("cellScalars")
+cellScalars.SetNumberOfTuples(numVoxelCells)
+cellScalars.Fill(0)
+cellScalars.SetTuple1(7,1)
+cellScalars.SetTuple1(6,2)
+cellScalars.SetTuple1(5,2)
+cellScalars.SetTuple1(3,3)
+cellScalars.SetTuple1(2,3)
+cellScalars.SetTuple1(1,3)
+
+image.GetCellData().SetScalars(cellScalars)
+
+if debugPrint:
+    print("\nCell scalars input to pack labels:")
+    for i in range(0,numVoxelCells):
+        print(i,cellScalars.GetTuple1(i))
+
+pack.SetInputArrayToProcess(0,0,0,vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS,"cellScalars")
+pack.SortByLabelCount()
+pack.Update()
+outCellScalars = pack.GetOutput().GetCellData().GetScalars()
+dataType = outCellScalars.GetDataType()
+
+labels = pack.GetLabels()
+counts = pack.GetLabelsCount()
+numLabels = labels.GetNumberOfTuples()
+
+if debugPrint:
+    print("\nNumber of sorted cell labels with counts: ",labels.GetNumberOfTuples())
+    for i in range(0,numLabels):
+        print("Label: ", labels.GetTuple1(i), ", count: ", counts.GetTuple1(i))
+
+if debugPrint:
+    print("\nOutput cell scalars:")
+    for i in range(0,numVoxelCells):
+        print(i,outCellScalars.GetTuple1(i))
+
+assert(dataType == VTK_UCHAR)
+assert(numLabels == 4)
+assert(counts.GetTuple1(0) == 3)
+assert(counts.GetTuple1(3) == 1)
+assert(labels.GetTuple1(0) == 3)
+assert(labels.GetTuple1(3) == 1)
diff --git a/Filters/Core/vtkPackLabels.cxx b/Filters/Core/vtkPackLabels.cxx
index 87664c00f91..2197956ba67 100644
--- a/Filters/Core/vtkPackLabels.cxx
+++ b/Filters/Core/vtkPackLabels.cxx
@@ -158,7 +158,7 @@ struct MapLabels
 {
   template <typename Array0T, typename Array1T>
   void operator()(Array0T* inScalars, Array1T* outScalars, vtkDataArray* labelsArray,
-    unsigned long maxLabels, unsigned long backgroundValue)
+    vtkIdType maxLabels, unsigned long backgroundValue)
   {
     vtkIdType numScalars = inScalars->GetNumberOfTuples();
     using T0 = vtk::GetAPIType<Array0T>;
@@ -245,7 +245,7 @@ vtkPackLabels::vtkPackLabels()
 //------------------------------------------------------------------------------
 // Find all the labels in the input.
 int vtkPackLabels::RequestData(
-  vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+  vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
 {
   vtkDebugMacro(<< "Executing Pack Labels");
 
@@ -259,7 +259,8 @@ int vtkPackLabels::RequestData(
 
   // Copy the input scalar data to the output. The temporary sortScalars
   // and labels array must be the same type as the input scalars.
-  vtkDataArray* inScalars = input->GetPointData()->GetScalars();
+  vtkDataArray* inScalars = this->GetInputArrayToProcess(0, inputVector);
+  int fieldAssociation = this->GetInputArrayAssociation(0, inputVector);
   if (!inScalars)
   {
     vtkErrorMacro("No input scalars");
@@ -318,7 +319,7 @@ int vtkPackLabels::RequestData(
       outScalars.TakeReference(vtkDataArray::CreateDataArray(VTK_UNSIGNED_LONG));
     }
   }
-  unsigned long maxLabels = GetMaxLabels(outScalars->GetDataType());
+  vtkIdType maxLabels = GetMaxLabels(outScalars->GetDataType());
   if (N > maxLabels)
   {
     vtkWarningMacro(
@@ -357,8 +358,16 @@ int vtkPackLabels::RequestData(
     output->GetFieldData()->PassData(input->GetFieldData());
   }
 
-  // Replace scalar array with packed array.
-  output->GetPointData()->SetScalars(outScalars);
+  // Replace scalar array with packed array. Depending on whether the
+  // data origin is from point or cell data, update appropriately.
+  if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
+  {
+    output->GetPointData()->SetScalars(outScalars);
+  }
+  else
+  {
+    output->GetCellData()->SetScalars(outScalars);
+  }
 
   return 1;
 }
-- 
GitLab