Skip to content

Commit a757817

Browse files
authored
fix: pass through original point/cell ids in surface extraction (#130)
1 parent 007b907 commit a757817

2 files changed

Lines changed: 50 additions & 43 deletions

File tree

Filters/Geometry/vtkGeometryFilter.cxx

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,44 +2050,67 @@ struct ExtractDS : public ExtractCellBoundaries<TInputIdType>
20502050
// Helper class to record original point and cell ids. This is for copying
20512051
// cell data, and also to produce output arrays indicating where output
20522052
// cells originated from (typically used in picking).
2053+
//
2054+
// Width-relaxed storage: use vtkTypeInt32Array when the id count fits in
2055+
// int32 (count <= 0x7FFFFFFF), otherwise vtkIdTypeArray. This must match
2056+
// the type produced by PassPointIds / PassCellIds so that vtkAppendPolyData
2057+
// (used by PyVista's MultiBlock extract_surface) sees a consistent type
2058+
// across all blocks and does not drop the array via IsSimilar().
20532059
struct IdRecorder
20542060
{
2055-
vtkSmartPointer<vtkIdTypeArray> Ids;
2061+
vtkSmartPointer<vtkDataArray> Ids;
20562062

20572063
IdRecorder(
2058-
vtkTypeBool passThru, const char* name, vtkDataSetAttributes* attrD, vtkIdType allocSize)
2064+
vtkTypeBool passThru, const char* name, vtkDataSetAttributes* attrD, vtkIdType count)
20592065
{
20602066
if (passThru)
20612067
{
2062-
this->Ids.TakeReference(vtkIdTypeArray::New());
2063-
this->Ids->SetName(name);
2064-
this->Ids->SetNumberOfComponents(1);
2065-
this->Ids->Allocate(allocSize);
2068+
if (count <= static_cast<vtkIdType>(0x7FFFFFFF))
2069+
{
2070+
auto* a = vtkTypeInt32Array::New();
2071+
a->SetName(name);
2072+
a->SetNumberOfComponents(1);
2073+
this->Ids.TakeReference(a);
2074+
}
2075+
else
2076+
{
2077+
auto* a = vtkIdTypeArray::New();
2078+
a->SetName(name);
2079+
a->SetNumberOfComponents(1);
2080+
this->Ids.TakeReference(a);
2081+
}
20662082
attrD->AddArray(this->Ids.Get());
20672083
}
20682084
}
2069-
IdRecorder(vtkTypeBool passThru, const char* name, vtkDataSetAttributes* attrD)
2085+
void Insert(vtkIdType destId, vtkIdType origId)
20702086
{
2071-
if (passThru)
2072-
{
2073-
this->Ids.TakeReference(vtkIdTypeArray::New());
2074-
this->Ids->SetName(name);
2075-
this->Ids->SetNumberOfComponents(1);
2076-
attrD->AddArray(this->Ids.Get());
2077-
}
2078-
else
2087+
if (this->Ids.Get() != nullptr)
20792088
{
2080-
this->Ids = nullptr;
2089+
this->Ids->InsertTuple1(destId, static_cast<double>(origId));
20812090
}
20822091
}
2083-
void Insert(vtkIdType destId, vtkIdType origId)
2092+
// Fill [0, count) with identity values using a parallel SMP loop.
2093+
void FillIdentity(vtkIdType count)
20842094
{
2085-
if (this->Ids.Get() != nullptr)
2095+
if (!this->Ids.Get())
2096+
return;
2097+
if (auto* a = vtkTypeInt32Array::SafeDownCast(this->Ids.Get()))
20862098
{
2087-
this->Ids->InsertValue(destId, origId);
2099+
auto* ptr = a->GetPointer(0);
2100+
vtkSMPTools::For(0, count, [ptr](vtkIdType b, vtkIdType e) {
2101+
for (; b < e; ++b)
2102+
ptr[b] = static_cast<vtkTypeInt32>(b);
2103+
});
2104+
}
2105+
else if (auto* a = vtkIdTypeArray::SafeDownCast(this->Ids.Get()))
2106+
{
2107+
auto* ptr = a->GetPointer(0);
2108+
vtkSMPTools::For(0, count, [ptr](vtkIdType b, vtkIdType e) {
2109+
for (; b < e; ++b)
2110+
ptr[b] = b;
2111+
});
20882112
}
20892113
}
2090-
vtkIdType* GetPointer() { return this->Ids->GetPointer(0); }
20912114
vtkTypeBool PassThru() { return this->Ids.Get() != nullptr; }
20922115
void Allocate(vtkIdType num)
20932116
{
@@ -2100,7 +2123,7 @@ struct IdRecorder
21002123
{
21012124
if (this->Ids.Get() != nullptr)
21022125
{
2103-
this->Ids->SetNumberOfValues(num);
2126+
this->Ids->SetNumberOfTuples(num);
21042127
}
21052128
}
21062129
}; // id recorder
@@ -2608,23 +2631,17 @@ int ExecutePolyData(vtkGeometryFilter* self, vtkDataSet* dataSetInput, vtkPolyDa
26082631
}
26092632

26102633
IdRecorder origCellIds(
2611-
self->GetPassThroughCellIds(), self->GetOriginalCellIdsName(), output->GetCellData());
2634+
self->GetPassThroughCellIds(), self->GetOriginalCellIdsName(), output->GetCellData(),
2635+
numCells);
26122636
IdRecorder origPointIds(
2613-
self->GetPassThroughPointIds(), self->GetOriginalPointIdsName(), output->GetPointData());
2637+
self->GetPassThroughPointIds(), self->GetOriginalPointIdsName(), output->GetPointData(),
2638+
numPts);
26142639

26152640
// vtkPolyData points are not culled
26162641
if (origPointIds.PassThru())
26172642
{
26182643
origPointIds.SetNumberOfValues(numPts);
2619-
vtkIdType* origPointIdsPtr = origPointIds.GetPointer();
2620-
vtkSMPTools::For(0, numPts,
2621-
[&origPointIdsPtr](vtkIdType pId, vtkIdType endPId)
2622-
{
2623-
for (; pId < endPId; ++pId)
2624-
{
2625-
origPointIdsPtr[pId] = pId;
2626-
}
2627-
});
2644+
origPointIds.FillIdentity(numPts);
26282645
}
26292646

26302647
// Special case when data is just passed through
@@ -2637,15 +2654,7 @@ int ExecutePolyData(vtkGeometryFilter* self, vtkDataSet* dataSetInput, vtkPolyDa
26372654
if (origCellIds.PassThru())
26382655
{
26392656
origCellIds.SetNumberOfValues(numCells);
2640-
vtkIdType* origCellIdsPtr = origCellIds.GetPointer();
2641-
vtkSMPTools::For(0, numCells,
2642-
[&origCellIdsPtr](vtkIdType cId, vtkIdType endCId)
2643-
{
2644-
for (; cId < endCId; ++cId)
2645-
{
2646-
origCellIdsPtr[cId] = cId;
2647-
}
2648-
});
2657+
origCellIds.FillIdentity(numCells);
26492658
}
26502659

26512660
return 1;

tests/pyvista/deselect.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
# These FAIL on fvtk but PASS on stock 9.6.2 on the same machine. Tracking
2121
# issues filed on pyvista/fvtk; fix each, then delete its line here.
2222
tests/core/test_pointset.py::test_delaunay_3d # vtkDelaunay3D degenerate/under-populated output (#114)
23-
tests/core/test_dataobject_filters.py::test_extract_surface_datasets[True-geometry] # vtkOriginalPointIds not passed through (#115)
24-
tests/core/test_dataobject_filters.py::test_extract_surface_datasets[True-None] # vtkOriginalPointIds not passed through (#115)
2523
tests/core/test_dataobject.py::test_save_compression # XML writer compression weaker than stock (#117)
2624
tests/core/test_helpers.py::test_to_from_trimesh_points_faces # regular_faces not zero-copy (#118)
2725
tests/plotting/test_texture.py::test_skybox_example # vtkSkybox not overridden to vtkOpenGLSkybox (#120)

0 commit comments

Comments
 (0)