mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +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(1);
|
||||||
ptVar.push_back(2);
|
ptVar.push_back(2);
|
||||||
cellVar.push_back(100);
|
cellVar.push_back(100);
|
||||||
cellVar.push_back(101);
|
|
||||||
|
|
||||||
//Polyline 2.
|
//Polyline 2.
|
||||||
ptVar.push_back(10);
|
ptVar.push_back(10);
|
||||||
ptVar.push_back(11);
|
ptVar.push_back(11);
|
||||||
ptVar.push_back(12);
|
ptVar.push_back(12);
|
||||||
cellVar.push_back(110);
|
cellVar.push_back(110);
|
||||||
cellVar.push_back(111);
|
|
||||||
|
|
||||||
//Add some degenerate polylines.
|
//Add some degenerate polylines.
|
||||||
//Polyline 3: (only 1 point)
|
//Polyline 3: (only 1 point)
|
||||||
@ -79,7 +77,6 @@ void TestTubeFilters()
|
|||||||
ptVar.push_back(-1);
|
ptVar.push_back(-1);
|
||||||
ptVar.push_back(-1);
|
ptVar.push_back(-1);
|
||||||
cellVar.push_back(-1);
|
cellVar.push_back(-1);
|
||||||
cellVar.push_back(-1);
|
|
||||||
|
|
||||||
ds.AddPointField("pointVar", ptVar);
|
ds.AddPointField("pointVar", ptVar);
|
||||||
ds.AddCellField("cellVar", cellVar);
|
ds.AddCellField("cellVar", cellVar);
|
||||||
@ -117,10 +114,10 @@ void TestTubeFilters()
|
|||||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> cellArr;
|
vtkm::cont::ArrayHandle<vtkm::FloatDefault> cellArr;
|
||||||
output.GetField("cellVar").GetData().AsArrayHandle(cellArr);
|
output.GetField("cellVar").GetData().AsArrayHandle(cellArr);
|
||||||
VTKM_TEST_ASSERT(cellArr.GetNumberOfValues() == 36, "Wrong number of values in cell field");
|
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,
|
std::vector<vtkm::FloatDefault> cellVals = { 100, 100, 100, 100, 100, 100, 100, 100, 100,
|
||||||
101, 101, 101, 100, 100, 100, 101, 101, 101,
|
100, 100, 100, 100, 100, 100, 100, 100, 100,
|
||||||
110, 110, 110, 110, 110, 110, 111, 111, 111,
|
110, 110, 110, 110, 110, 110, 110, 110, 110,
|
||||||
111, 111, 111, 110, 110, 110, 111, 111, 111 };
|
110, 110, 110, 110, 110, 110, 110, 110, 110 };
|
||||||
portal = cellArr.ReadPortal();
|
portal = cellArr.ReadPortal();
|
||||||
for (vtkm::Id i = 0; i < 36; i++)
|
for (vtkm::Id i = 0; i < 36; i++)
|
||||||
VTKM_TEST_ASSERT(portal.Get(i) == cellVals[static_cast<std::size_t>(i)],
|
VTKM_TEST_ASSERT(portal.Get(i) == cellVals[static_cast<std::size_t>(i)],
|
||||||
|
@ -48,7 +48,6 @@ public:
|
|||||||
FieldOut ptsPerPolyline,
|
FieldOut ptsPerPolyline,
|
||||||
FieldOut ptsPerTube,
|
FieldOut ptsPerTube,
|
||||||
FieldOut numTubeConnIds,
|
FieldOut numTubeConnIds,
|
||||||
FieldOut linesPerPolyline,
|
|
||||||
FieldOut validCell);
|
FieldOut validCell);
|
||||||
using ExecutionSignature = void(CellShape shapeType,
|
using ExecutionSignature = void(CellShape shapeType,
|
||||||
PointCount numPoints,
|
PointCount numPoints,
|
||||||
@ -58,8 +57,7 @@ public:
|
|||||||
_4 ptsPerPolyline,
|
_4 ptsPerPolyline,
|
||||||
_5 ptsPerTube,
|
_5 ptsPerTube,
|
||||||
_6 numTubeConnIds,
|
_6 numTubeConnIds,
|
||||||
_7 linesPerPolyline,
|
_7 validCell);
|
||||||
_8 validCell);
|
|
||||||
using InputDomain = _1;
|
using InputDomain = _1;
|
||||||
|
|
||||||
template <typename CellShapeTag, typename PointIndexType, typename InPointsType>
|
template <typename CellShapeTag, typename PointIndexType, typename InPointsType>
|
||||||
@ -71,7 +69,6 @@ public:
|
|||||||
vtkm::Id& ptsPerPolyline,
|
vtkm::Id& ptsPerPolyline,
|
||||||
vtkm::Id& ptsPerTube,
|
vtkm::Id& ptsPerTube,
|
||||||
vtkm::Id& numTubeConnIds,
|
vtkm::Id& numTubeConnIds,
|
||||||
vtkm::Id& linesPerPolyline,
|
|
||||||
vtkm::Id& validCell) const
|
vtkm::Id& validCell) const
|
||||||
{
|
{
|
||||||
// We only support polylines that contain 2 or more points.
|
// We only support polylines that contain 2 or more points.
|
||||||
@ -97,7 +94,6 @@ public:
|
|||||||
ptsPerTube = this->NumSides * numNonCoincidentPoints;
|
ptsPerTube = this->NumSides * numNonCoincidentPoints;
|
||||||
// (two tris per segment) X (numSides) X numVertsPerCell
|
// (two tris per segment) X (numSides) X numVertsPerCell
|
||||||
numTubeConnIds = (numNonCoincidentPoints - 1) * 2 * this->NumSides * this->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.
|
//Capping adds center vertex in middle of cap, plus NumSides triangles for cap.
|
||||||
if (this->Capping)
|
if (this->Capping)
|
||||||
@ -113,7 +109,6 @@ public:
|
|||||||
nonIncidentPtsPerPolyline = 0;
|
nonIncidentPtsPerPolyline = 0;
|
||||||
ptsPerTube = 0;
|
ptsPerTube = 0;
|
||||||
numTubeConnIds = 0;
|
numTubeConnIds = 0;
|
||||||
linesPerPolyline = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,24 +476,23 @@ public:
|
|||||||
FieldInCell ptsPerPolyline,
|
FieldInCell ptsPerPolyline,
|
||||||
FieldInCell tubePointOffsets,
|
FieldInCell tubePointOffsets,
|
||||||
FieldInCell tubeConnOffsets,
|
FieldInCell tubeConnOffsets,
|
||||||
FieldInCell segOffset,
|
|
||||||
WholeArrayOut outConnectivity,
|
WholeArrayOut outConnectivity,
|
||||||
WholeArrayOut outCellSrcIdx);
|
WholeArrayOut outCellSrcIdx);
|
||||||
using ExecutionSignature = void(CellShape shapeType,
|
using ExecutionSignature = void(CellShape shapeType,
|
||||||
|
InputIndex inCellIndex,
|
||||||
_2 ptsPerPolyline,
|
_2 ptsPerPolyline,
|
||||||
_3 tubePointOffset,
|
_3 tubePointOffset,
|
||||||
_4 tubeConnOffsets,
|
_4 tubeConnOffsets,
|
||||||
_5 segOffset,
|
_5 outConn,
|
||||||
_6 outConn,
|
_6 outCellSrcIdx);
|
||||||
_7 outCellSrcIdx);
|
|
||||||
using InputDomain = _1;
|
using InputDomain = _1;
|
||||||
|
|
||||||
template <typename CellShapeTag, typename OutConnType, typename OutCellSrcIdxType>
|
template <typename CellShapeTag, typename OutConnType, typename OutCellSrcIdxType>
|
||||||
VTKM_EXEC void operator()(const CellShapeTag& shapeType,
|
VTKM_EXEC void operator()(const CellShapeTag& shapeType,
|
||||||
|
vtkm::Id inCellIndex,
|
||||||
const vtkm::IdComponent& numPoints,
|
const vtkm::IdComponent& numPoints,
|
||||||
const vtkm::Id& tubePointOffset,
|
const vtkm::Id& tubePointOffset,
|
||||||
const vtkm::Id& tubeConnOffset,
|
const vtkm::Id& tubeConnOffset,
|
||||||
const vtkm::Id& segOffset,
|
|
||||||
OutConnType& outConn,
|
OutConnType& outConn,
|
||||||
OutCellSrcIdxType& outCellSrcIdx) const
|
OutCellSrcIdxType& outCellSrcIdx) const
|
||||||
{
|
{
|
||||||
@ -517,7 +511,7 @@ public:
|
|||||||
outConn.Set(outIdx + 1, tubePtOffset + i * this->NumSides + (j + 1) % this->NumSides);
|
outConn.Set(outIdx + 1, tubePtOffset + i * this->NumSides + (j + 1) % this->NumSides);
|
||||||
outConn.Set(outIdx + 2,
|
outConn.Set(outIdx + 2,
|
||||||
tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
|
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;
|
outIdx += 3;
|
||||||
|
|
||||||
//Triangle 2: verts 0,2,3
|
//Triangle 2: verts 0,2,3
|
||||||
@ -525,7 +519,7 @@ public:
|
|||||||
outConn.Set(outIdx + 1,
|
outConn.Set(outIdx + 1,
|
||||||
tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
|
tubePtOffset + (i + 1) * this->NumSides + (j + 1) % this->NumSides);
|
||||||
outConn.Set(outIdx + 2, tubePtOffset + (i + 1) * this->NumSides + j);
|
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;
|
outIdx += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,7 +533,7 @@ public:
|
|||||||
outConn.Set(outIdx + 0, startCenterPt);
|
outConn.Set(outIdx + 0, startCenterPt);
|
||||||
outConn.Set(outIdx + 1, startCenterPt + 1 + j);
|
outConn.Set(outIdx + 1, startCenterPt + 1 + j);
|
||||||
outConn.Set(outIdx + 2, startCenterPt + 1 + ((j + 1) % this->NumSides));
|
outConn.Set(outIdx + 2, startCenterPt + 1 + ((j + 1) % this->NumSides));
|
||||||
outCellSrcIdx.Set(outIdx / 3, segOffset);
|
outCellSrcIdx.Set(outIdx / 3, inCellIndex);
|
||||||
outIdx += 3;
|
outIdx += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +546,7 @@ public:
|
|||||||
outConn.Set(outIdx + 0, endCenterPt);
|
outConn.Set(outIdx + 0, endCenterPt);
|
||||||
outConn.Set(outIdx + 1, endOffsetPt + j);
|
outConn.Set(outIdx + 1, endOffsetPt + j);
|
||||||
outConn.Set(outIdx + 2, endOffsetPt + ((j + 1) % this->NumSides));
|
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;
|
outIdx += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,8 +616,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Count number of polyline pts, tube pts and tube cells
|
//Count number of polyline pts, tube pts and tube cells
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, segPerPolyline,
|
vtkm::cont::ArrayHandle<vtkm::Id> ptsPerPolyline, ptsPerTube, numTubeConnIds, validCell;
|
||||||
validCell;
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> nonIncidentPtsPerPolyline;
|
vtkm::cont::ArrayHandle<vtkm::IdComponent> nonIncidentPtsPerPolyline;
|
||||||
CountSegments countSegs(this->Capping, this->NumSides);
|
CountSegments countSegs(this->Capping, this->NumSides);
|
||||||
vtkm::worklet::DispatcherMapTopology<CountSegments> countInvoker(countSegs);
|
vtkm::worklet::DispatcherMapTopology<CountSegments> countInvoker(countSegs);
|
||||||
@ -633,7 +626,6 @@ public:
|
|||||||
ptsPerPolyline,
|
ptsPerPolyline,
|
||||||
ptsPerTube,
|
ptsPerTube,
|
||||||
numTubeConnIds,
|
numTubeConnIds,
|
||||||
segPerPolyline,
|
|
||||||
validCell);
|
validCell);
|
||||||
|
|
||||||
vtkm::Id totalPolylinePts = vtkm::cont::Algorithm::Reduce(ptsPerPolyline, vtkm::Id(0));
|
vtkm::Id totalPolylinePts = vtkm::cont::Algorithm::Reduce(ptsPerPolyline, vtkm::Id(0));
|
||||||
@ -645,14 +637,13 @@ public:
|
|||||||
vtkm::Id totalTubeCells = totalTubeConnIds / 3;
|
vtkm::Id totalTubeCells = totalTubeConnIds / 3;
|
||||||
|
|
||||||
vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, nonIncidentPolylinePtOffset,
|
vtkm::cont::ArrayHandle<vtkm::Id> polylinePtOffset, nonIncidentPolylinePtOffset,
|
||||||
tubePointOffsets, tubeConnOffsets, segOffset;
|
tubePointOffsets, tubeConnOffsets;
|
||||||
vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylinePtOffset);
|
vtkm::cont::Algorithm::ScanExclusive(ptsPerPolyline, polylinePtOffset);
|
||||||
vtkm::cont::Algorithm::ScanExclusive(
|
vtkm::cont::Algorithm::ScanExclusive(
|
||||||
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(nonIncidentPtsPerPolyline),
|
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(nonIncidentPtsPerPolyline),
|
||||||
nonIncidentPolylinePtOffset);
|
nonIncidentPolylinePtOffset);
|
||||||
vtkm::cont::Algorithm::ScanExclusive(ptsPerTube, tubePointOffsets);
|
vtkm::cont::Algorithm::ScanExclusive(ptsPerTube, tubePointOffsets);
|
||||||
vtkm::cont::Algorithm::ScanExclusive(numTubeConnIds, tubeConnOffsets);
|
vtkm::cont::Algorithm::ScanExclusive(numTubeConnIds, tubeConnOffsets);
|
||||||
vtkm::cont::Algorithm::ScanExclusive(segPerPolyline, segOffset);
|
|
||||||
|
|
||||||
//Generate normals at each point on all polylines
|
//Generate normals at each point on all polylines
|
||||||
NormalsType normals;
|
NormalsType normals;
|
||||||
@ -686,7 +677,6 @@ public:
|
|||||||
nonIncidentPtsPerPolyline,
|
nonIncidentPtsPerPolyline,
|
||||||
tubePointOffsets,
|
tubePointOffsets,
|
||||||
tubeConnOffsets,
|
tubeConnOffsets,
|
||||||
segOffset,
|
|
||||||
newConnectivity,
|
newConnectivity,
|
||||||
this->OutputCellSourceIndex);
|
this->OutputCellSourceIndex);
|
||||||
newCells.Fill(totalTubePts, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);
|
newCells.Fill(totalTubePts, vtkm::CELL_SHAPE_TRIANGLE, 3, newConnectivity);
|
||||||
|
Loading…
Reference in New Issue
Block a user