/*========================================================================= Program: Visualization Toolkit Module: vtkEuclideanClusterExtraction.h Copyright (c) Kitware, Inc. All rights reserved. See LICENSE file for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkEuclideanClusterExtraction * @brief perform segmentation based on geometric * proximity and optional scalar threshold * * vtkEuclideanClusterExtraction is a filter that extracts points that are in * close geometric proximity, and optionally satisfies a scalar threshold * criterion. (Points extracted in this way are referred to as clusters.) * The filter works in one of five ways: 1) extract the largest cluster in the * dataset; 2) extract specified cluster number(s); 3) extract all clusters * containing specified point ids; 4) extract the cluster closest to a specified * point; or 5) extract all clusters (which can be used for coloring the clusters). * * Note that geometric proximity is defined by setting the Radius instance * variable. This variable defines a local sphere around each point; other * points contained in this sphere are considered "connected" to the * point. Setting this number too large will connect clusters that should not * be; setting it too small will fragment the point cloud into myriad * clusters. To accelerate the geometric proximity operations, a point * locator may be specified. By default, a vtkStaticPointLocator is used, but * any vtkAbstractPointLocator may be specified. * * The behavior of vtkEuclideanClusterExtraction can be modified by turning * on the boolean ivar ScalarConnectivity. If this flag is on, the clustering * algorithm is modified so that points are considered part of a cluster if * they satisfy both the geometric proximity measure, and the points scalar * values falls into the scalar range specified. This use of * ScalarConnectivity is particularly useful for data with intensity or color * information, serving as a simple "connected segmentation" algorithm. For * example, by using a seed point in a known cluster, clustering will pull * out all points "representing" the local structure. * * @sa * vtkConnectivityFilter vtkPolyDataConnectivityFilter */ #ifndef vtkEuclideanClusterExtraction_h #define vtkEuclideanClusterExtraction_h #include "vtkFiltersPointsModule.h" // For export macro #include "vtkPolyDataAlgorithm.h" #define VTK_EXTRACT_POINT_SEEDED_CLUSTERS 1 #define VTK_EXTRACT_SPECIFIED_CLUSTERS 2 #define VTK_EXTRACT_LARGEST_CLUSTER 3 #define VTK_EXTRACT_ALL_CLUSTERS 4 #define VTK_EXTRACT_CLOSEST_POINT_CLUSTER 5 class vtkDataArray; class vtkFloatArray; class vtkIdList; class vtkIdTypeArray; class vtkAbstractPointLocator; class VTKFILTERSPOINTS_EXPORT vtkEuclideanClusterExtraction : public vtkPolyDataAlgorithm { public: vtkTypeMacro(vtkEuclideanClusterExtraction, vtkPolyDataAlgorithm); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Construct with default extraction mode to extract largest clusters. */ static vtkEuclideanClusterExtraction* New(); //@{ /** * Specify the local search radius. */ vtkSetClampMacro(Radius, double, 0.0, VTK_FLOAT_MAX); vtkGetMacro(Radius, double); //@} //@{ /** * Turn on/off connectivity based on scalar value. If on, points are * connected only if the are proximal AND the scalar value of a candidate * point falls in the scalar range specified. Of course input point scalar * data must be provided. */ vtkSetMacro(ScalarConnectivity, bool); vtkGetMacro(ScalarConnectivity, bool); vtkBooleanMacro(ScalarConnectivity, bool); //@} //@{ /** * Set the scalar range used to extract points based on scalar connectivity. */ vtkSetVector2Macro(ScalarRange, double); vtkGetVector2Macro(ScalarRange, double); //@} //@{ /** * Control the extraction of connected surfaces. */ vtkSetClampMacro( ExtractionMode, int, VTK_EXTRACT_POINT_SEEDED_CLUSTERS, VTK_EXTRACT_CLOSEST_POINT_CLUSTER); vtkGetMacro(ExtractionMode, int); void SetExtractionModeToPointSeededClusters() { this->SetExtractionMode(VTK_EXTRACT_POINT_SEEDED_CLUSTERS); } void SetExtractionModeToLargestCluster() { this->SetExtractionMode(VTK_EXTRACT_LARGEST_CLUSTER); } void SetExtractionModeToSpecifiedClusters() { this->SetExtractionMode(VTK_EXTRACT_SPECIFIED_CLUSTERS); } void SetExtractionModeToClosestPointCluster() { this->SetExtractionMode(VTK_EXTRACT_CLOSEST_POINT_CLUSTER); } void SetExtractionModeToAllClusters() { this->SetExtractionMode(VTK_EXTRACT_ALL_CLUSTERS); } const char* GetExtractionModeAsString(); //@} /** * Initialize the list of point ids used to seed clusters. */ void InitializeSeedList(); /** * Add a seed id (point id). Note: ids are 0-offset. */ void AddSeed(vtkIdType id); /** * Delete a seed id.a */ void DeleteSeed(vtkIdType id); /** * Initialize the list of cluster ids to extract. */ void InitializeSpecifiedClusterList(); /** * Add a cluster id to extract. Note: ids are 0-offset. */ void AddSpecifiedCluster(int id); /** * Delete a cluster id to extract. */ void DeleteSpecifiedCluster(int id); //@{ /** * Used to specify the x-y-z point coordinates when extracting the cluster * closest to a specified point. */ vtkSetVector3Macro(ClosestPoint, double); vtkGetVectorMacro(ClosestPoint, double, 3); //@} /** * Obtain the number of connected clusters. This value is valid only after filter execution. */ int GetNumberOfExtractedClusters(); //@{ /** * Turn on/off the coloring of connected clusters. */ vtkSetMacro(ColorClusters, bool); vtkGetMacro(ColorClusters, bool); vtkBooleanMacro(ColorClusters, bool); //@} //@{ /** * Specify a point locator. By default a vtkStaticPointLocator is * used. The locator performs efficient proximity searches near a * specified interpolation position. */ void SetLocator(vtkAbstractPointLocator* locator); vtkGetObjectMacro(Locator, vtkAbstractPointLocator); //@} protected: vtkEuclideanClusterExtraction(); ~vtkEuclideanClusterExtraction() override; double Radius; // connection radius bool ColorClusters; // boolean turns on/off scalar gen for separate clusters int ExtractionMode; // how to extract clusters vtkIdList* Seeds; // id's of points or cells used to seed clusters vtkIdList* SpecifiedClusterIds; // clusters specified for extraction vtkIdTypeArray* ClusterSizes; // size (in cells) of each cluster extracted double ClosestPoint[3]; bool ScalarConnectivity; double ScalarRange[2]; vtkAbstractPointLocator* Locator; // Configure the pipeline int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; int FillInputPortInformation(int port, vtkInformation* info) override; // Internal method for propagating connected waves. void InsertIntoWave(vtkIdList* wave, vtkIdType ptId); void TraverseAndMark(vtkPoints* pts); private: vtkEuclideanClusterExtraction(const vtkEuclideanClusterExtraction&) = delete; void operator=(const vtkEuclideanClusterExtraction&) = delete; // used to support algorithm execution vtkFloatArray* NeighborScalars; vtkIdList* NeighborPointIds; char* Visited; vtkIdType* PointMap; vtkIdTypeArray* NewScalars; vtkIdType ClusterNumber; vtkIdType PointNumber; vtkIdType NumPointsInCluster; vtkDataArray* InScalars; vtkIdList* Wave; vtkIdList* Wave2; vtkIdList* PointIds; }; //@{ /** * Return the method of extraction as a string. */ inline const char* vtkEuclideanClusterExtraction::GetExtractionModeAsString(void) { if (this->ExtractionMode == VTK_EXTRACT_POINT_SEEDED_CLUSTERS) { return "ExtractPointSeededClusters"; } else if (this->ExtractionMode == VTK_EXTRACT_SPECIFIED_CLUSTERS) { return "ExtractSpecifiedClusters"; } else if (this->ExtractionMode == VTK_EXTRACT_ALL_CLUSTERS) { return "ExtractAllClusters"; } else if (this->ExtractionMode == VTK_EXTRACT_CLOSEST_POINT_CLUSTER) { return "ExtractClosestPointCluster"; } else { return "ExtractLargestCluster"; } } //@} #endif