Change values of array of selected elements

I have a method of selecting cells and changing the values in that portion of the array to a new integer, but it is quite cumbersome. So, for example, I might have a mesh that has a “Region” cell array with all integer 1 values. I want to select a portion of this and give that selected portion of the “Region” cell array value 2 (or some other pre-defined user integer value).

I’m hoping that either there is a better way in general, or since this method was created a decade ago, that new features may be able to improve this workflow. Currently, I am using two programmable filters to accomplish this. The first is to give each a global ID for when I split up the mesh:

input = self.GetInputDataObject(0,0)
output = self.GetOutputDataObject(0)
numCells = input.GetNumberOfCells()

globalIds = vtk.vtkDoubleArray()
globalIds.SetNumberOfValues(numCells)
globalIds.SetName("GlobalIds")

origMats = input.GetCellData().GetArray("Region")

matIds = vtk.vtkDoubleArray()
matIds.SetNumberOfValues(numCells)
matIds.SetName("Region")

for ii in range(numCells):
	globalIds.InsertValue(ii,ii)
	matIds.InsertValue(ii, int(origMats.GetTuple1(ii)))

output.GetCellData().AddArray(globalIds)
output.GetCellData().AddArray(matIds)

I then have to select a region, then extract that region, and then select that new region plus the original regionIds, and use the next custom filter to change the material:


#Changes material of selected region to 
#the value set here
matID = 2

#Just in case this needs to be done on 
#data formatted differently
array = 'Region'


####################################

def getSelection(sel, obj):
	currentCell = vtk.vtkGenericCell()
	oldPts = sel.GetCellData().GetArray("GlobalIds")
	pointsToChange = []

	for ii in range(sel.GetNumberOfCells()):
		pointsToChange.append(int(oldPts.GetTuple1(ii)))
	
	return pointsToChange

inp1 = self.GetInputDataObject(0,0)
inp2 = self.GetInputDataObject(0,1)
output = self.GetOutputDataObject(0)

num1 = inp1.GetNumberOfCells()
num2 = inp2.GetNumberOfCells()

if num1 > num2:
	toChange= getSelection(inp2, inp1)
	output.DeepCopy(inp1)

else:
	toChange= getSelection(inp1, inp2)
	output.DeepCopy(inp2)
	
oldIds = output.GetCellData().GetArray(array)
for ii in toChange:
	oldIds.SetComponent(ii, 0, float(matID))

As I previously stated, this can become quite cumbersome when it’s necessary to do it over and over. Are there any potential ways to speed up or streamline this workflow?

Thanks!

The Global Point and Cell IDs filter should at least take care of doing what your first Programmable Filter does.

I can’t think of a filter that applies data to a selection as you are doing in the second one, though. There is Annotate Selection, but that produces a new string array with values rather than an integer array.