Пример #1
0
def execute(self):
    inputDO = self.GetInputDataObject(0, 0)
    inputSEL = self.GetInputDataObject(1, 0)
    outputDO = self.GetOutputDataObject(0)

    assert inputSEL.GetNumberOfNodes() >= 1

    selectionNode = inputSEL.GetNode(0)
    field_type = selectionNode.GetFieldType()
    if field_type == selectionNode.CELL:
        attributeType = vtk.vtkDataObject.CELL
    elif field_type == selectionNode.POINT:
        attributeType = vtk.vtkDataObject.POINT
    elif field_type == selectionNode.ROW:
        attributeType = vtk.vtkDataObject.ROW
    else:
        raise RuntimeError ("Unsupported field attributeType %r" % field_type)

    # evaluate expression on the inputDO.
    # this is equivalent to executing the Python Calculator on the input dataset
    # to produce a mask array.
    inputs = []
    inputs.append(dsa.WrapDataObject(inputDO))

    query = selectionNode.GetQueryString()

    # get a dictionary for arrays in the dataset attributes. We pass that
    # as the variables in the eval namespace for calculator.compute().
    elocals = calculator.get_arrays(inputs[0].GetAttributes(attributeType))
    if not elocals.has_key("id") and re.search(r'\bid\b', query):
        # add "id" array if the query string refers to id.
        # This is a temporary fix. We should look into
        # accelerating id-based selections in the future.
        elocals["id"] = _create_id_array(inputs[0], attributeType)
    try:
        maskArray = calculator.compute(inputs, query, ns=elocals)
    except:
        from sys import stderr
        print ("Error: Failed to evaluate Expression '%s'. "\
            "The following exception stack should provide additional developer "\
            "specific information. This typically implies a malformed "\
            "expression. Verify that the expression is valid.\n" % query, file=sys.stderr)
        raise

    if not maskarray_is_valid(maskArray):
        raise RuntimeError(
            "Expression '%s' did not produce a valid mask array. The value "\
            "produced is of the type '%s'. This typically implies a malformed "\
            "expression. Verify that the expression is valid." % \
            (query, type(maskArray)))

    # if inverse selection is requested, just logical_not the mask array.
    if selectionNode.GetProperties().Has(selectionNode.INVERSE()) and \
        selectionNode.GetProperties().Get(selectionNode.INVERSE()) == 1:
          maskArray = algos.logical_not(maskArray)

    output = dsa.WrapDataObject(outputDO)
    if self.GetPreserveTopology():
        # when preserving topology, just add the mask array as
        # vtkSignedCharArray to the output. vtkPythonExtractSelection should
        # have already ensured that the input is shallow copied over properly
        # before this method gets called.

        # note: since mask array is a bool-array, we multiply it by int8(1) to
        # make it a type of array that can be represented as vtkSignedCharArray.
        output.GetAttributes(attributeType).append(maskArray * np.int8(1), "vtkInsidedness")
    else:
        # handle extraction.
        # flatnonzero() will give is array of indices where the arrays is
        # non-zero (or non-False in our case). We then pass that to
        # vtkPythonExtractSelection to extract the selected ids.
        nonzero_indices =  algos.flatnonzero(maskArray)
        output.FieldData.append(nonzero_indices, "vtkSelectedIds");
        #print (output.FieldData["vtkSelectedIds"])
        self.ExtractElements(attributeType, inputDO, outputDO)
        del nonzero_indices
    del maskArray
Пример #2
0
def execute(self):
    inputDO = self.GetInputDataObject(0, 0)
    inputSEL = self.GetInputDataObject(1, 0)
    outputDO = self.GetOutputDataObject(0)

    assert inputSEL.GetNumberOfNodes() >= 1

    selectionNode = inputSEL.GetNode(0)
    field_type = selectionNode.GetFieldType()
    if field_type == selectionNode.CELL:
        attributeType = vtk.vtkDataObject.CELL
    elif field_type == selectionNode.POINT:
        attributeType = vtk.vtkDataObject.POINT
    elif field_type == selectionNode.ROW:
        attributeType = vtk.vtkDataObject.ROW
    else:
        raise RuntimeError, "Unsupported field attributeType %r" % field_type

    # evaluate expression on the inputDO.
    # this is equivalent to executing the Python Calculator on the input dataset
    # to produce a mask array.
    inputs = []
    inputs.append(dsa.WrapDataObject(inputDO))

    # get a dictionary for arrays in the dataset attributes. We pass that
    # as the variables in the eval namespace for calculator.compute().
    elocals = calculator.get_arrays(inputs[0].GetAttributes(attributeType))
    try:
        maskArray = calculator.compute(inputs,
                                       selectionNode.GetQueryString(),
                                       ns=elocals)
    except:
        from sys import stderr
        print >> stderr, "Error: Failed to evaluate Expression '%s'. "\
            "The following exception stack should provide additional developer "\
            "specific information. This typically implies a malformed "\
            "expression. Verify that the expression is valid.\n" % \
            selectionNode.GetQueryString()
        raise

    if not maskarray_is_valid(maskArray):
        raise RuntimeError,\
            "Expression '%s' did not produce a valid mask array. The value "\
            "produced is of the type '%s'. This typically implies a malformed "\
            "expression. Verify that the expression is valid." % \
            (selectionNode.GetQueryString(), type(maskArray))

    # if inverse selection is requested, just logical_not the mask array.
    if selectionNode.GetProperties().Has(selectionNode.INVERSE()) and \
        selectionNode.GetProperties().Get(selectionNode.INVERSE()) == 1:
        maskArray = algos.logical_not(maskArray)

    output = dsa.WrapDataObject(outputDO)
    if self.GetPreserveTopology():
        # when preserving topology, just add the mask array as
        # vtkSignedCharArray to the output. vtkPythonExtractSelection should
        # have already ensured that the input is shallow copied over properly
        # before this method gets called.

        # note: since mask array is a bool-array, we multiply it by int8(1) to
        # make it a type of array that can be represented as vtkSignedCharArray.
        output.GetAttributes(attributeType).append(maskArray * np.int8(1),
                                                   "vtkInsidedness")
    else:
        # handle extraction.
        # flatnonzero() will give is array of indices where the arrays is
        # non-zero (or non-False in our case). We then pass that to
        # vtkPythonExtractSelection to extract the selected ids.
        nonzero_indices = algos.flatnonzero(maskArray)
        output.FieldData.append(nonzero_indices, "vtkSelectedIds")
        #print output.FieldData["vtkSelectedIds"]
        self.ExtractElements(attributeType, inputDO, outputDO)
        del nonzero_indices
    del maskArray
Пример #3
0
def extract_selection_vtp(poly_in, query=None, l_cell_idx = None, field_type="CELL", inverse_selection=False, verbose=False):
	"""Returns a vtk polydata object as a subselection of an input polydata object
	Some words about indexes : 
	Cells
		- CellId              = index (of CellData and Polys (=connectivity and offset arrays)) = PK
		- vtkOriginalCellIds  = index of original vtp (never changed, even after consecutive selections)
		- SelectionCellIds    = index of previous selection(changes every selection step, allows you to go 1 level up)
		- vertexIndices       = related point indices (=redundant = same as connectivity) = FK
	Points  
		- PointId             = index (of PointData and Points) = PK
		- vtkOriginalPointIds = index of original vtp (never changed, even after consecutive selections) 
		- SelectionPointIds   = index of previous selection(changes every selection step, allows you to go 1 level up)
		
	naming chosen as to comply with the paraview naming
		
	"""
	a_ix_cell = np.array([])
	a_ix_point = np.array([])
	wdo_in  = dsa.WrapDataObject(poly_in)
	wdo_out = dsa.WrapDataObject(vtk.vtkPolyData()) 
	   
	if query:
		attributeType =  set_attributetype(field_type)
		if verbose: print(wdo_in.GetAttributes(attributeType))
		# d_attr_data = get_arrays(inputs[0].GetAttributes(attributeType))
		attribs = wdo_in.GetAttributes(attributeType)
		
		d_attr_data = {key:attribs[key] for key in attribs.keys()} #dict : key = 'attributename' , value = array of data 
		if not "id" in d_attr_data.keys() and re.search(r'\bid\b', query): # add "id" array if the query string refers to id.
			d_attr_data["id"] = _create_id_array(wdo_in, attributeType)
		try:
			maskArray = compute(wdo_in, query, ns=d_attr_data)   # SELECTION :returns boolean mask 
		except:
			print ("Error: Failed to evaluate Expression '%s'. "\
				"The following exception stack should provide additional developer "\
				"specific information. This typically implies a malformed "\
				"expression. Verify that the expression is valid.\n", query)
			raise
			
		if not maskarray_is_valid(maskArray):
			raise RuntimeError("Expression '%s' did not produce a valid mask array. The value "\
				"produced is of the type '{0}'. This typically implies a malformed "\
				"expression. Verify that the expression is valid. {1}".format(query, type(maskArray)))
		
		if inverse_selection:
			maskArray = algos.logical_not(maskArray)

		
		nonzero_indices =  algos.flatnonzero(maskArray)  # returns indices of boolean mask 

		if field_type=="CELL":
			a_ix_cell = np.array(nonzero_indices)
		else:
			print("only cell based selections are supported right now.")
			return
	else:
		a_ix_cell = np.array(l_cell_idx)
	
	if not isinstance(a_ix_cell,np.ndarray) or a_ix_cell.size == 0:
		print('warning : nothing selected.  An empty VTP will be created')
	
	if field_type=="CELL":
	
		#STEP1 : Replace CellData
		nb_arrays = wdo_in.GetCellData().GetNumberOfArrays()
		if verbose:print("{0} arrays are present in {1}Data".format(nb_arrays,field_type))
		
		
		for i in range(nb_arrays):
			
			vtk_array        = wdo_in.GetAttributes(vtk.vtkDataObject.CELL).GetArray(i)
			attr_name        = wdo_in.GetAttributes(vtk.vtkDataObject.CELL).GetArrayName(i)
			if attr_name=="SelectionCellIds":
				continue
			
			if a_ix_cell.size==0:
				vtk_array_select = np.array([])
			else:
				vtk_array_select = vtk_array[a_ix_cell]
			
			if attr_name=="vertexIndices":
				a_vtkOriginalPointIds = vtk_array_select.__array__()  #not stored in output_poly, only used further down
				continue
		   
			if verbose:print("{0}),{1},{2} ==> {3}".format(i, attr_name, vtk_array.size, vtk_array_select.size))
			
			# wdo_out.GetAttributes(vtk.vtkDataObject.CELL).append(vtk_array_select,attr_name)
			wdo_out.GetAttributes(vtk.vtkDataObject.CELL).append(vtk_array_select,attr_name)
			if verbose:print(wdo_out.GetAttributes(vtk.vtkDataObject.CELL)[attr_name],"compared to input : \n", wdo_in.GetAttributes(vtk.vtkDataObject.CELL)[attr_name])
					
		wdo_out.GetAttributes(vtk.vtkDataObject.CELL).append(a_ix_cell,"SelectionCellIds")  #backup selectionIds to easily refer to the selection 1 level up
		if isinstance(wdo_out.CellData['vtkOriginalCellIds'], dsa.VTKNoneArray):  # at first selection, this column is newly added
			wdo_out.GetAttributes(vtk.vtkDataObject.CELL).append(a_ix_cell,"vtkOriginalCellIds") 
		
		#STEP2 : Get points to be selected based on the cell selection
		a_ix_point = np.unique(a_vtkOriginalPointIds) #unique gives 1D SORTED ascending array
		d_oldPointId_newPointID = { old:new for new,old in enumerate(a_ix_point) }  
		
		#STEP3 : Copy PointData
		nb_arrays = wdo_in.GetPointData().GetNumberOfArrays()
		if verbose:print("{0} arrays are present in CellData".format(nb_arrays))
		for i in range(nb_arrays):
			vtk_array        = wdo_in.GetAttributes(vtk.vtkDataObject.POINT).GetArray(i)
			attr_name        = wdo_in.GetAttributes(vtk.vtkDataObject.POINT).GetArrayName(i)
			if attr_name == "SelectionPointIds":
				continue
				
			if a_ix_point.size==0:
				vtk_array_select = np.array([])
			else:   
				vtk_array_select = vtk_array[a_ix_point]
			if verbose:print("{0}),{1},{2} ==> {3}".format(i, attr_name, vtk_array.size, vtk_array_select.size))

			wdo_out.GetAttributes(vtk.vtkDataObject.POINT).append(vtk_array_select,attr_name)   
			
		wdo_out.GetAttributes(vtk.vtkDataObject.POINT).append(a_ix_point,"SelectionPointIds")  #backup original ids as extra column
		if isinstance(wdo_out.PointData['vtkOriginalPointIds'], dsa.VTKNoneArray): # at first selection, this column is newly added
			wdo_out.GetAttributes(vtk.vtkDataObject.POINT).append(a_ix_point,"vtkOriginalPointIds")
		
		#STEP4: Copy Points
		if a_ix_point.size!=0: wdo_out.Points = wdo_in.Points[a_ix_point]

		#STEP5: Construct Polygons (Cells) 
		#wdo_out.Polygons    = wdo_in.Polygons[a_ix_point] => not supported by wrapper, so use native VTK
		vtkCellArray = vtk.vtkCellArray()
		vertexIndices_new = []
		for p1,p2,p3 in a_vtkOriginalPointIds:
			l_new_triangle = [d_oldPointId_newPointID[p1],d_oldPointId_newPointID[p2],d_oldPointId_newPointID[p3]]
			vtkCellArray.InsertNextCell (3, l_new_triangle) 
			vertexIndices_new.append(l_new_triangle)
			
		wdo_out.VTKObject.SetPolys(vtkCellArray)
		
		#STEP6: update CellData vertexIndices
		wdo_out.GetAttributes(vtk.vtkDataObject.CELL).append(np.array(vertexIndices_new),"vertexIndices")
		

	return wdo_out.VTKObject
Пример #4
0
def execute(self):
    inputDO = self.GetInputDataObject(0, 0)
    inputSEL = self.GetInputDataObject(1, 0)
    outputDO = self.GetOutputDataObject(0)

    assert inputSEL.GetNumberOfNodes() >= 1

    selectionNode = inputSEL.GetNode(0)
    field_type = selectionNode.GetFieldType()
    if field_type == selectionNode.CELL:
        attributeType = vtk.vtkDataObject.CELL
    elif field_type == selectionNode.POINT:
        attributeType = vtk.vtkDataObject.POINT
    elif field_type == selectionNode.ROW:
        attributeType = vtk.vtkDataObject.ROW
    else:
        raise RuntimeError("Unsupported field attributeType %r" % field_type)

    # evaluate expression on the inputDO.
    # this is equivalent to executing the Python Calculator on the input dataset
    # to produce a mask array.
    inputs = []
    inputs.append(dsa.WrapDataObject(inputDO))

    query = selectionNode.GetQueryString()

    # get a dictionary for arrays in the dataset attributes. We pass that
    # as the variables in the eval namespace for calculator.compute().
    elocals = calculator.get_arrays(inputs[0].GetAttributes(attributeType))
    if ("id" not in elocals) and re.search(r'\bid\b', query):
        # add "id" array if the query string refers to id.
        # This is a temporary fix. We should look into
        # accelerating id-based selections in the future.
        elocals["id"] = _create_id_array(inputs[0], attributeType)
    try:
        maskArray = calculator.compute(inputs, query, ns=elocals)
    except:
        from sys import stderr
        print ("Error: Failed to evaluate Expression '%s'. "\
            "The following exception stack should provide additional developer "\
            "specific information. This typically implies a malformed "\
            "expression. Verify that the expression is valid.\n" % query, file=stderr)
        raise

    if not maskarray_is_valid(maskArray):
        raise RuntimeError(
            "Expression '%s' did not produce a valid mask array. The value "\
            "produced is of the type '%s'. This typically implies a malformed "\
            "expression. Verify that the expression is valid." % \
            (query, type(maskArray)))

    # if inverse selection is requested, just logical_not the mask array.
    if selectionNode.GetProperties().Has(selectionNode.INVERSE()) and \
        selectionNode.GetProperties().Get(selectionNode.INVERSE()) == 1:
        maskArray = algos.logical_not(maskArray)

    output = dsa.WrapDataObject(outputDO)
    if self.GetPreserveTopology():
        # when preserving topology, just add the mask array as
        # vtkSignedCharArray to the output. vtkPythonExtractSelection should
        # have already ensured that the input is shallow copied over properly
        # before this method gets called.

        # Note: we must force the data type to VTK_SIGNED_CHAR or the array will
        # be ignored by the freeze selection operation
        from vtk.util.numpy_support import numpy_to_vtk
        if type(maskArray
                ) is not vtk.numpy_interface.dataset_adapter.VTKNoneArray:
            insidedness = numpy_to_vtk(maskArray,
                                       deep=1,
                                       array_type=vtk.VTK_SIGNED_CHAR)
            insidedness.SetName("vtkInsidedness")
            output.GetAttributes(attributeType).VTKObject.AddArray(insidedness)
    else:
        # handle extraction.
        # flatnonzero() will give is array of indices where the arrays is
        # non-zero (or non-False in our case). We then pass that to
        # vtkPythonExtractSelection to extract the selected ids.
        nonzero_indices = algos.flatnonzero(maskArray)
        output.FieldData.append(nonzero_indices, "vtkSelectedIds")
        #print (output.FieldData["vtkSelectedIds"])
        self.ExtractElements(attributeType, inputDO, outputDO)
        del nonzero_indices
    del maskArray