mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
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.)
This commit is contained in:
parent
ef3c4c65c9
commit
2bcc9aa708
19
docs/changelog/tube-cell-fields.md
Normal file
19
docs/changelog/tube-cell-fields.md
Normal file
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user