Merge topic 'tube-cell-fields'

2bcc9aa70 Fix handling of cell fields in Tube filter

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2911
This commit is contained in:
Kenneth Moreland 2022-11-21 21:42:47 +00:00 committed by Kitware Robot
commit 2ddaa36858
3 changed files with 34 additions and 28 deletions

@ -0,0 +1,19 @@
# Fix handling of cell fields in Tube filter
The `Tube` filter wraps a tube of polygons around poly line cells.
During this process it had a strange (and wrong) handling of cell data.
It assumed that each line had an independent field entry for each
segment of each line. It thus had lots of extra code to find the length
and offsets of the segment data in the cell data.
This is simply not how cell fields work in VTK-m. In VTK-m, each cell
has exactly one entry in the cell field array. Even if a polyline has
100 segments, it only gets one cell field value. This behavior is
consistent with how VTK treats cell field arrays.
The behavior the `Tube` filter was trying to implement was closer to an
"edge" field. However, edge fields are currently not supported in VTK-m.
The proper implementation would be to add edge fields to VTK-m. (This
would also get around some problems with the implementation that was
removed here when mixing polylines with other cell types and degenerate
lines.)

@ -62,14 +62,12 @@ void TestTubeFilters()
ptVar.push_back(1);
ptVar.push_back(2);
cellVar.push_back(100);
cellVar.push_back(101);
//Polyline 2.
ptVar.push_back(10);
ptVar.push_back(11);
ptVar.push_back(12);
cellVar.push_back(110);
cellVar.push_back(111);
//Add some degenerate polylines.
//Polyline 3: (only 1 point)
@ -79,7 +77,6 @@ void TestTubeFilters()
ptVar.push_back(-1);
ptVar.push_back(-1);
cellVar.push_back(-1);
cellVar.push_back(-1);
ds.AddPointField("pointVar", ptVar);
ds.AddCellField("cellVar", cellVar);
@ -117,10 +114,10 @@ void TestTubeFilters()
vtkm::cont::ArrayHandle<vtkm::FloatDefault> cellArr;
output.GetField("cellVar").GetData().AsArrayHandle(cellArr);
VTKM_TEST_ASSERT(cellArr.GetNumberOfValues() == 36, "Wrong number of values in cell field");
std::vector<vtkm::FloatDefault> cellVals = { 100, 100, 100, 100, 100, 100, 101, 101, 101,
101, 101, 101, 100, 100, 100, 101, 101, 101,
110, 110, 110, 110, 110, 110, 111, 111, 111,
111, 111, 111, 110, 110, 110, 111, 111, 111 };
std::vector<vtkm::FloatDefault> cellVals = { 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100,
110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 110 };
portal = cellArr.ReadPortal();
for (vtkm::Id i = 0; i < 36; i++)
VTKM_TEST_ASSERT(portal.Get(i) == cellVals[static_cast<std::size_t>(i)],

@ -48,7 +48,6 @@ public:
FieldOut ptsPerPolyline,
FieldOut ptsPerTube,
FieldOut numTubeConnIds,
FieldOut linesPerPolyline,
FieldOut validCell);
using ExecutionSignature = void(CellShape shapeType,
PointCount numPoints,
@ -58,8 +57,7 @@ public:
_4 ptsPerPolyline,
_5 ptsPerTube,
_6 numTubeConnIds,
_7 linesPerPolyline,
_8 validCell);
_7 validCell);
using InputDomain = _1;
template <typename CellShapeTag, typename PointIndexType, typename InPointsType>
@ -71,7 +69,6 @@ public:
vtkm::Id& ptsPerPolyline,
vtkm::Id& ptsPerTube,
vtkm::Id& numTubeConnIds,
vtkm::Id& linesPerPolyline,
vtkm::Id& validCell) const
{
// We only support polylines that contain 2 or more points.
@ -97,7 +94,6 @@ public:
ptsPerTube = this->NumSides * numNonCoincidentPoints;
// (two tris per segment) X (numSides) X numVertsPerCell
numTubeConnIds = (numNonCoincidentPoints - 1) * 2 * this->NumSides * this->NumVertsPerCell;
linesPerPolyline = numNonCoincidentPoints - 1;
//Capping adds center vertex in middle of cap, plus NumSides triangles for cap.
if (this->Capping)
@ -113,7 +109,6 @@ public:
nonIncidentPtsPerPolyline = 0;
ptsPerTube = 0;
numTubeConnIds = 0;
linesPerPolyline = 0;
}
}
@ -481,24 +476,23 @@ public:
FieldInCell ptsPerPolyline,
FieldInCell tubePointOffsets,
FieldInCell tubeConnOffsets,
FieldInCell segOffset,
WholeArrayOut outConnectivity,
WholeArrayOut outCellSrcIdx);
using ExecutionSignature = void(CellShape shapeType,
InputIndex inCellIndex,
_2 ptsPerPolyline,
_3 tubePointOffset,
_4 tubeConnOffsets,
_5 segOffset,
_6 outConn,
_7 outCellSrcIdx);
_5 outConn,
_6 outCellSrcIdx);
using InputDomain = _1;
template <typename CellShapeTag, typename OutConnType, typename OutCellSrcIdxType>
VTKM_EXEC void operator()(const CellShapeTag& shapeType,
vtkm::Id inCellIndex,
const vtkm::IdComponent& numPoints,
const vtkm::Id& tubePointOffset,
const vtkm::Id& tubeConnOffset,
const vtkm::Id& segOffset,
OutConnType& outConn,
OutCellSrcIdxType& outCellSrcIdx) const
{
@ -517,7 +511,7 @@ public:
outConn.Set(outIdx + 1, tubePtOffset + i * this->NumSides + (j + 1) % this->NumSides);
outConn.Set(outIdx + 2,
tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
outCellSrcIdx.Set(outIdx / 3, segOffset + static_cast<vtkm::Id>(i));
outCellSrcIdx.Set(outIdx / 3, inCellIndex);
outIdx += 3;
//Triangle 2: verts 0,2,3
@ -525,7 +519,7 @@ public:
outConn.Set(outIdx + 1,
tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
outConn.Set(outIdx + 2, tubePtOffset + (i + 1) * this->NumSides + j);
outCellSrcIdx.Set(outIdx / 3, segOffset + static_cast<vtkm::Id>(i));
outCellSrcIdx.Set(outIdx / 3, inCellIndex);
outIdx += 3;
}
}
@ -539,7 +533,7 @@ public:
outConn.Set(outIdx + 0, startCenterPt);
outConn.Set(outIdx + 1, startCenterPt + 1 + j);
outConn.Set(outIdx + 2, startCenterPt + 1 + ((j + 1) % this->NumSides));
outCellSrcIdx.Set(outIdx / 3, segOffset);
outCellSrcIdx.Set(outIdx / 3, inCellIndex);
outIdx += 3;
}
@ -552,7 +546,7 @@ public:
outConn.Set(outIdx + 0, endCenterPt);
outConn.Set(outIdx + 1, endOffsetPt + j);
outConn.Set(outIdx + 2, endOffsetPt + ((j + 1) % this->NumSides));
outCellSrcIdx.Set(outIdx / 3, segOffset + static_cast<vtkm::Id>(numPoints - 2));
outCellSrcIdx.Set(outIdx / 3, inCellIndex);
outIdx += 3;
}
}
@ -622,8 +616,7 @@ public:
}
//Count number of polyline pts, tube pts and tube cells
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, segPerPolyline,
validCell;
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, validCell;
vtkm::cont::ArrayHandle<vtkm::IdComponent> nonIncidentPtsPerPolyline;
CountSegments countSegs(this->Capping, this->NumSides);
vtkm::worklet::DispatcherMapTopology<CountSegments> countInvoker(countSegs);
@ -633,7 +626,6 @@ public:
ptsPerPolyline,
ptsPerTube,
numTubeConnIds,
segPerPolyline,
validCell);
vtkm::Id totalPolylinePts = vtkm::cont::Algorithm::Reduce(ptsPerPolyline, vtkm::Id(0));
@ -645,14 +637,13 @@ public:
vtkm::Id totalTubeCells = totalTubeConnIds / 3;
vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, nonIncidentPolylinePtOffset,
tubePointOffsets, tubeConnOffsets, segOffset;
tubePointOffsets, tubeConnOffsets;
vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylinePtOffset);
vtkm::cont::Algorithm::ScanExclusive(
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(nonIncidentPtsPerPolyline),
nonIncidentPolylinePtOffset);
vtkm::cont::Algorithm::ScanExclusive(ptsPerTube, tubePointOffsets);
vtkm::cont::Algorithm::ScanExclusive(numTubeConnIds, tubeConnOffsets);
vtkm::cont::Algorithm::ScanExclusive(segPerPolyline, segOffset);
//Generate normals at each point on all polylines
NormalsType normals;
@ -686,7 +677,6 @@ public:
nonIncidentPtsPerPolyline,
tubePointOffsets,
tubeConnOffsets,
segOffset,
newConnectivity,
this->OutputCellSourceIndex);
newCells.Fill(totalTubePts, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);