# Converting vtkUnstructuredGrid to vtkPolyData

**URL:** https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508
**Category:** Support
**Tags:** python
**Created:** [October 19, 2023, 2:00pm UTC](https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508 "2023-10-19T14:00:43Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![rexthor](https://discourse.vtk.org/user_avatar/discourse.vtk.org/rexthor/32/6481_2.png) [@rexthor](https://discourse.vtk.org/u/rexthor)
#### Post date: [October 19, 2023, 2:00pm UTC](https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508/1 "2023-10-19T14:00:43Z")

</div>

I have a vtkUnstructuredGrid that is a contiguous mass of connected vtkHexahedrons (it is an appended grouping of vtkUnstructuredGrid). I want to use some algorithms that only work with vtkPolyData (namely I want to delete some cells where a variable is small). The data is very large, and I want to make sure that I am not deep copying.

Right now, this is how the script looks:

```python
# data is a vtkUnstructuredGrid
# data.GetPointData().GetNumberOfArrays() --> 9
# data.GetNumberOfPoints() --> more than 12 million
# I'm not sure if these 'Set' functions make deep or shallow copies ...
pd = vtk.vtkPolyData()
pd.SetPoints(data.GetPoints())
pd.SetPolys(data.GetCells())
for a_idx in range(data.GetPointData().GetNumberOfArrays()):
    pd.GetFieldData().AddArray(data.GetPointData().GetArray(a_idx))

```

---

<div class="post-metadata">

### Author: ![rexthor](https://discourse.vtk.org/user_avatar/discourse.vtk.org/rexthor/32/6481_2.png) [@rexthor](https://discourse.vtk.org/u/rexthor)
#### Post date: [October 19, 2023, 4:29pm UTC](https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508/2 "2023-10-19T16:29:52Z")

</div>

It does occur to me that I can’t add vtkHexahedrons to a vtkPolyData … ultimately I want the faces of the hexahedrons in there … but the above code for sure will not work.

---

<div class="post-metadata">

### Author: ![Charles\_Gueunet](https://discourse.vtk.org/user_avatar/discourse.vtk.org/charles_gueunet/32/239_2.png) [@Charles\_Gueunet](https://discourse.vtk.org/u/Charles_Gueunet)
#### Post date: [October 23, 2023, 7:42am UTC](https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508/3 "2023-10-23T07:42:16Z")

</div>

If you only want the external surface of your mesh, you may want to look at the `vtkGeometryFilter`.  
If you want to all the internal faces, do you need them to stay connected ? do you need them to stay quads ?

---

<div class="post-metadata">

### Author: ![rexthor](https://discourse.vtk.org/user_avatar/discourse.vtk.org/rexthor/32/6481_2.png) [@rexthor](https://discourse.vtk.org/u/rexthor)
#### Post date: [October 23, 2023, 12:31pm UTC](https://discourse.vtk.org/t/converting-vtkunstructuredgrid-to-vtkpolydata/12508/4 "2023-10-23T12:31:21Z")

</div>

Thanks - I hadn’t heard of vtkGeometryFilter, I actually do need the insides of the object - I mostly wanted to convert the thing to vtkPolyData so that I could run vtkCleanPolyData on it. I am beginning to realize that the real answer to my question is “it depends.” In my, very strange, circumstance the code that generated what I needed was:

```python
    # FIXME: hardcoded: Temperature is index 7
    logging.debug("generating vtkCellArray of unique faces")
    CELL_NODE_COUNT = data.GetCell(0).GetNumberOfPoints()
    FACE_NODE_COUNT = data.GetCell(0).GetFace(0).GetNumberOfPoints()
    temp_array = pd.GetPointData().GetAbstractArray(7)
    unique_quads = set()
    ca = vtk.vtkCellArray()

    for c_idx in range(data.GetNumberOfCells()):
        # Skip those cells for which the average nodal temperature is <= T_LOWER_LIMIT
        cell = data.GetCell(c_idx)
        cell_node_temps = [temp_array.GetTuple1(cell.GetPointId(n)) for n in range(CELL_NODE_COUNT)]
        if np.mean(cell_node_temps) <= T_LOWER_LIMIT:
            continue

        # Break cell into faces, and only add unique faces.
        for f_idx in range(data.GetCell(0).GetNumberOfFaces()):
            face = data.GetCell(c_idx).GetFace(f_idx)
            face_ids = [face.GetPointId(x) for x in range(FACE_NODE_COUNT)]
            sorted_ids = tuple(sorted(face_ids))
            reversed_ids = tuple(reversed(sorted(face_ids)))
            sorted_ids = min(sorted_ids, reversed_ids)
            if sorted_ids not in unique_quads:
                unique_quads.add(sorted_ids)
                ca.InsertNextCell(FACE_NODE_COUNT, face_ids)

    pd.SetPolys(ca)

    logging.debug("cleaning final vtkPolyData")
    cpd = vtk.vtkCleanPolyData()
    cpd.SetInputData(pd)
    cpd.Update()
```
