<div dir="ltr">Hey,<div><br></div><div>I was writing a custom point cloud filtering algorithm and came across the vtkPointCloudFilter class,</div><div>which looks like a convenient base for this kind of filter. However, in my opinion it behaves strangely<br></div><div>when it comes to the handling of data arrays bundled with the points. The documentation says that</div><div>"The filter copies point attributes from input to output consistent with the filtering operation", and</div><div>indeed it does, but while copying it changes the type of the attribute arrays, everything becomes a</div><div>float! Here is a small example that uses vtkRadiusOutlierRemoval (derived from vtkPointCloudFilter).</div><div>I create several points with an unsigned char attribute, and pass it through the filter.</div><div><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">#include <iostream><br></font></div><div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">#include <vtkPoints.h></font></div><div><font face="monospace, monospace">#include <vtkPolyData.h></font></div><div><font face="monospace, monospace">#include <vtkPointData.h></font></div><div><font face="monospace, monospace">#include <vtkSmartPointer.h></font></div><div><font face="monospace, monospace">#include <vtkUnsignedCharArray.h></font></div><div><font face="monospace, monospace">#include <vtkRadiusOutlierRemoval.h></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">int main(int argc, const char** argv)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  const double pt1[3] = { 0, 0, 0};</font></div><div><font face="monospace, monospace">  const double pt2[3] = { 1, 0, 0};</font></div><div><font face="monospace, monospace">  const double pt3[3] = { 2, 0, 0};</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  auto points = vtkSmartPointer<vtkPoints>::New();</font></div><div><font face="monospace, monospace">  points->SetDataTypeToDouble();</font></div><div><font face="monospace, monospace">  points->InsertNextPoint(pt1);</font></div><div><font face="monospace, monospace">  points->InsertNextPoint(pt2);</font></div><div><font face="monospace, monospace">  points->InsertNextPoint(pt3);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  auto labels = vtkSmartPointer<vtkUnsignedCharArray>::New();</font></div><div><font face="monospace, monospace">  labels->SetName("label");</font></div><div><font face="monospace, monospace">  labels->SetNumberOfComponents(1);</font></div><div><font face="monospace, monospace">  labels->InsertNextValue(1);</font></div><div><font face="monospace, monospace">  labels->InsertNextValue(2);</font></div><div><font face="monospace, monospace">  labels->InsertNextValue(3);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  auto poly_data = vtkSmartPointer<vtkPolyData>::New();</font></div><div><font face="monospace, monospace">  poly_data->SetPoints(points);</font></div><div><font face="monospace, monospace">  poly_data->GetPointData()->AddArray(labels);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  auto outlier_removal = vtkSmartPointer<vtkRadiusOutlierRemoval>::New();</font></div><div><font face="monospace, monospace">  outlier_removal->SetInputData(poly_data);</font></div><div><font face="monospace, monospace">  outlier_removal->SetRadius(1.5);</font></div><div><font face="monospace, monospace">  outlier_removal->SetNumberOfNeighbors(2);</font></div><div><font face="monospace, monospace">  outlier_removal->Update();</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  auto output = outlier_removal->GetOutputDataObject(0);</font></div><div><font face="monospace, monospace">  auto attributes = output->GetAttributes(0);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  std::cout << "Output attributes: " << attributes->GetArrayName(0) << ", type: " << attributes->GetArray(0)->GetDataTypeAsString() << std::endl;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return 0;</font></div><div><font face="monospace, monospace">}</font></div></div><div><br></div><div><br></div><div>This example prints</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Output attributes: label, type: float</blockquote><div><br></div><div>So what happens is that the "label" attribute, that was originally of type unsigned char, becomes a</div><div>float attribute in the output of the filter.</div><div><br></div><div>It this behavior a bug or a feature? Or maybe I am missing a flag somewhere which controls this</div><div>behavior?</div><div><br></div><div>Cheers,</div><div>Sergey</div><div><br></div><div> </div></div>