@@ -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().
20532059struct 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 ;
0 commit comments