Commit 97ba574f authored by Cory Quammen's avatar Cory Quammen
Browse files

Add RegionId assignment mode

By default, the mode is UNSPECIFIED, which matches the previous
behavior of how RegionIds are assigned to different connected
components.

Another option, CELL_COUNT_DESCENDING, has also been implemented. In
this mode, RegionIds are assigned to connected components such that
the lowest RegionId is assigned to the component with the largest
number of cells and other RegionIds are assigned in descending order
of cell count.
parent 783312e1
......@@ -31,6 +31,8 @@
#include "vtkUnstructuredGrid.h"
#include "vtkIdTypeArray.h"
#include <map>
vtkObjectFactoryNewMacro(vtkConnectivityFilter);
// Construct with default extraction mode to extract largest regions.
......@@ -39,6 +41,7 @@ vtkConnectivityFilter::vtkConnectivityFilter()
this->RegionSizes = vtkIdTypeArray::New();
this->ExtractionMode = VTK_EXTRACT_LARGEST_REGION;
this->ColorRegions = 0;
this->RegionIdAssignmentMode = UNSPECIFIED;
this->ScalarConnectivity = 0;
this->ScalarRange[0] = 0.0;
......@@ -350,6 +353,10 @@ int vtkConnectivityFilter::RequestData(
// if coloring regions; send down new scalar data
if ( this->ColorRegions )
{
auto pointRegionIds = vtkIdTypeArray::SafeDownCast(outputPD->GetArray("RegionId"));
auto cellRegionIds = vtkIdTypeArray::SafeDownCast(outputCD->GetArray("RegionId"));
this->OrderRegionIds(this->NewScalars, this->NewCellScalars);
int idx = outputPD->AddArray(this->NewScalars);
outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
idx = outputCD->AddArray(this->NewCellScalars);
......@@ -613,6 +620,57 @@ void vtkConnectivityFilter::TraverseAndMark (vtkDataSet *input)
} //while wave is not empty
}
void vtkConnectivityFilter::OrderRegionIds(vtkIdTypeArray* pointRegionIds, vtkIdTypeArray* cellRegionIds)
{
if (this->ColorRegions)
{
if (this->RegionIdAssignmentMode == CELL_COUNT_DESCENDING)
{
// Use a multimap to handle cases where more than one region has the same number of cells.
std::multimap<vtkIdType, vtkIdType> cellCountToRegionId;
typedef std::multimap<vtkIdType, vtkIdType>::value_type ValueType;
vtkIdType numRegions = this->RegionSizes->GetNumberOfTuples();
for (vtkIdType regionId = 0; regionId < numRegions; ++regionId)
{
ValueType value(this->RegionSizes->GetValue(regionId), regionId);
cellCountToRegionId.insert(value);
}
// Now reverse iterate through the sorted multimap to process the RegionIds
// from largest to smallest and create a map from the old RegionId to the new
// RegionId
std::map<vtkIdType, vtkIdType> oldToNew;
vtkIdType counter = 0;
for (auto iter = cellCountToRegionId.rbegin(); iter != cellCountToRegionId.rend(); ++iter)
{
auto regionCount = iter->first;
auto regionId = iter->second;
// Re-order the region sizes based on the sorting
this->RegionSizes->SetValue(counter, regionCount);
// Create map from old to new RegionId
oldToNew[regionId] = counter++;
}
vtkIdType numPts = pointRegionIds->GetNumberOfTuples();
for (vtkIdType i = 0; i < numPts; ++i)
{
vtkIdType oldValue = pointRegionIds->GetValue(i);
pointRegionIds->SetValue(i, oldToNew[oldValue]);
}
vtkIdType numCells = cellRegionIds->GetNumberOfTuples();
for (vtkIdType i = 0; i < numCells; ++i)
{
vtkIdType oldValue = cellRegionIds->GetValue(i);
cellRegionIds->SetValue(i, oldToNew[oldValue]);
}
}
// else UNSPECIFIED mode
}
}
// Obtain the number of connected regions.
int vtkConnectivityFilter::GetNumberOfExtractedRegions()
{
......
......@@ -180,6 +180,23 @@ public:
vtkBooleanMacro(ColorRegions,vtkTypeBool);
//@}
/**
* Enumeration of the various ways to assign RegionIds when
* the ColorRegions option is on.
*/
enum RegionIdAssignment {
UNSPECIFIED,
CELL_COUNT_DESCENDING
};
//@{
/**
* Set/get mode controlling how RegionIds are assigned.
*/
//@}
vtkSetMacro(RegionIdAssignmentMode, int);
vtkGetMacro(RegionIdAssignmentMode, int);
//@{
/**
* Set/get the desired precision for the output types. See the documentation
......@@ -215,8 +232,12 @@ protected:
vtkTypeBool ScalarConnectivity;
double ScalarRange[2];
int RegionIdAssignmentMode;
void TraverseAndMark(vtkDataSet *input);
void OrderRegionIds(vtkIdTypeArray* pointRegionIds, vtkIdTypeArray* cellRegionIds);
private:
// used to support algorithm execution
vtkFloatArray *CellScalars;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment