# Possible VTK 9.6.0rc2 regression with ghost cell rendering

**URL:** https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251
**Category:** Development
**Created:** [January 21, 2026, 7:11pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251 "2026-01-21T19:11:56Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 21, 2026, 7:11pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/1 "2026-01-21T19:11:57Z")

</div>

[ugrid.vtu](https://discourse.vtk.org/uploads/short-url/rDAf7Mz1w6qdPvkOu5mAWlHyE8O.vtu) (4.4 KB)

I have attached an UnstructuredGrid mesh file with a `'vtkGhostType'` cell array. The top “row” of cells in the dataset are masked.

Using the code below with `vtk==9.5.20250802.dev0`, we get :

 ![ghost-cells-aug02](https://discourse.vtk.org/uploads/default/original/2X/0/00c2cff0f40800ed63d1edbcf6d13dbbe91988b0.jpeg)

But with `vtk==9.5.20250809.dev0`, we get this instead, where the interface between the ghost cells and the rest of grid is no longer present, and we can see “inside” the mesh.

 ![ghost-cells-aug09](https://discourse.vtk.org/uploads/default/original/2X/5/5ad2022895a2824aa052b935d791e5cf33558491.jpeg)

I tried looking at the diff [Kitware/VTK@6ac70ce…5cda859](https://github.com/Kitware/VTK/compare/6ac70ce2dc4520624d3bc398097aa8e264302368...5cda859050d00a943eb1007d995fc6fdf37eec24) between the Aug 2 timestamp [Kitware/VTK@6ac70ce](https://github.com/Kitware/VTK/commit/6ac70ce2dc4520624d3bc398097aa8e264302368) and the aug 9 timestamp [Kitware/VTK@5cda859](https://github.com/Kitware/VTK/commit/5cda859050d00a943eb1007d995fc6fdf37eec24) but nothing is jumping out in terms of changes to ghost cells affecting unstructured grids… Haven’t yet bisected to a specific commit.

Is this change intentional? Or is this a bug/regression with VTK 9.6?

```py
import vtk

# Read VTU file
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName('ugrid.vtu')
reader.Update()
data = reader.GetOutput()

# Mapper
mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(data)

# Actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)

# Make grid white with black lines
prop = actor.GetProperty()
prop.EdgeVisibilityOn()
prop.SetEdgeColor(0.0, 0.0, 0.0)
prop.SetLineWidth(1.0)
prop.SetColor(1.0, 1.0, 1.0)
mapper.SetScalarVisibility(False)

# Renderer
renderer = vtk.vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(0.1, 0.1, 0.1)

# Camera
camera = renderer.GetActiveCamera()
camera.SetPosition(1, 1, 1)
camera.SetViewUp(0, 0, 1)
renderer.ResetCamera()

# Render window
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(renderer)
render_window.SetSize(800, 600)

# Interactor
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(render_window)

# Start
render_window.Render()
interactor.Start()

```

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 21, 2026, 8:04pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/2 "2026-01-21T20:04:48Z")

</div>

Furthermore, this particular mesh can be converted to ExplicitStructuredGrid.

If we insert this code after reading the file:

```py
alg = vtk.vtkUnstructuredGridToExplicitStructuredGrid()
alg.SetInputData(data)
alg.SetInputArrayToProcess(0, 0, 0, 1, 'BLOCK_I')
alg.SetInputArrayToProcess(1, 0, 0, 1, 'BLOCK_J')
alg.SetInputArrayToProcess(2, 0, 0, 1, 'BLOCK_K')
alg.Update()
data = alg.GetOutput()

```

And re-run the full example for both vtk versions mentioned above, we get the first image both times. This indicates that ghost cell rendering is now inconsistent across mesh types, and to me suggests that there is indeed a regression with how ghost cells are rendered for UnstructuredGrid types.

---

<div class="post-metadata">

### Author: ![akaszynski](https://discourse.vtk.org/user_avatar/discourse.vtk.org/akaszynski/32/10751_2.png) [@akaszynski](https://discourse.vtk.org/u/akaszynski)
#### Post date: [January 22, 2026, 6:01am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/3 "2026-01-22T06:01:40Z")

</div>

Thanks to @user27182’s hints (2 Aug - 9 Aug) I was able to bisect with:

```bash
git bisect start
git bisect good 6ac70ce2dc4520624d3bc398097aa8e264302368
git bisect bad 5cda859050d00a943eb1007d995fc6fdf37eec24

```

Offending commit is [29253f532082f2804ce39afe3bcd8b45794c2714](https://github.com/kitware/vtk/commit/29253f532082f2804ce39afe3bcd8b45794c2714).

---

<div class="post-metadata">

### Author: ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)
#### Post date: [January 22, 2026, 8:35am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/4 "2026-01-22T08:35:56Z")

</div>

[https://gitlab.kitware.com/vtk/vtk/-/merge\_requests/12224](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/12224)

@spyridon97 @pieper

---

<div class="post-metadata">

### Author: ![spyridon97](https://discourse.vtk.org/user_avatar/discourse.vtk.org/spyridon97/32/7069_2.png) [@spyridon97](https://discourse.vtk.org/u/spyridon97)
#### Post date: [January 22, 2026, 1:23pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/5 "2026-01-22T13:23:50Z")

</div>

This happens because `vtkGeometryFilter` has `RemoveGhostInterfaces` on by default. And the rational behind it is that you don’t wanna see the interface cells by default unless you are doing something special and you need them, e.g. the ghost cell generator needs them, or you want to do some post processing on them, and then remove the ghost cells.

TLDR: we know it’s different, the question is, why is it a problem? IMHO it’s more correct

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 22, 2026, 3:34pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/6 "2026-01-22T15:34:31Z")

</div>

Indeed it’s fine if `vtkGeometryFilter` filter enables this by default, because users are free to configure the filter themselves and use it as they need. It may be “more correct” as you say for a default case, but there are two issues:

1. its use in the rendering pipeline does not appear to be configurable by users
2. it is applied inconsistently, since the ghost cell interface is removed for rendering `vtkUnstructuredGrid` when there are hidden cells, but not for `vtkExplicitUnstructuredGrid` ( and likely `vtkImageData` and `vtkStructuredGrid` too based on downstream testing)

For item (1), it seems this breaking change is acknowledged by @mwestphal here: [https://gitlab.kitware.com/vtk/vtk/-/merge\_requests/12224#note\_1695253](https://gitlab.kitware.com/vtk/vtk/-/merge_requests/12224#note_1695253), so I guess this is already mentioned in the release notes, and is fine. But the lack of consistency with item (2) still seems like a bug to me.

For downstream users, I guess the workaround or “fix” is to call `vtkGeometryFilter` manually _before_ rendering, with `RemoveGhostInterfacesOff`?

---

<div class="post-metadata">

### Author: ![mwestphal](https://discourse.vtk.org/user_avatar/discourse.vtk.org/mwestphal/32/19_2.png) [@mwestphal](https://discourse.vtk.org/u/mwestphal)
#### Post date: [January 22, 2026, 3:37pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/7 "2026-01-22T15:37:44Z")

</div>

My comment is that note was not about behavior but about API.

---

<div class="post-metadata">

### Author: ![spyridon97](https://discourse.vtk.org/user_avatar/discourse.vtk.org/spyridon97/32/7069_2.png) [@spyridon97](https://discourse.vtk.org/u/spyridon97)
#### Post date: [January 22, 2026, 3:41pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/8 "2026-01-22T15:41:32Z")

</div>

Are you sure RemoveGhostInterfaces does not behave correctly for vtkimageData and the rest you mentioned? RemoveGhostInterfaces is used in both ExtractDS and ExtractStructured in vtkGeometryFilter.

Making the parameter configurable via vtkDataSetMapper API is something that can be discussed.

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 22, 2026, 4:33pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/9 "2026-01-22T16:33:41Z")

</div>

Making this configurable would be nice for downstream users. I can confirm that only `vtkUnstructuredGrid` has this “remove ghost cells interface” behavior in `vtk==9.6.0rc2`, here’s a reproducer:

```py
import vtk

def render_dataset(dataset):
    # Mapper
    mapper = vtk.vtkDataSetMapper()
    mapper.SetInputData(dataset)

    # Actor
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    # Make grid white with black lines
    prop = actor.GetProperty()
    prop.EdgeVisibilityOn()
    prop.SetEdgeColor(0.0, 0.0, 0.0)
    prop.SetLineWidth(1.0)
    prop.SetColor(1.0, 1.0, 1.0)
    mapper.SetScalarVisibility(False)

    # Renderer
    renderer = vtk.vtkRenderer()
    renderer.AddActor(actor)
    renderer.SetBackground(0.1, 0.1, 0.1)

    # Camera
    camera = renderer.GetActiveCamera()
    camera.SetPosition(1, 1, 1)
    camera.SetViewUp(0, 0, 1)
    renderer.ResetCamera()

    # Render window
    render_window = vtk.vtkRenderWindow()
    render_window.AddRenderer(renderer)
    render_window.SetSize(800, 600)

    # Interactor
    interactor = vtk.vtkRenderWindowInteractor()
    interactor.SetRenderWindow(render_window)

    # Start
    render_window.Render()
    interactor.Start()

def create_image_data():
    # Create data with 3x3x3 cells
    dataset = vtk.vtkImageData()
    dataset.SetDimensions(4, 4, 4)
    return dataset

def add_ghost_cell_data(data):
    ghost_array = vtk.vtkUnsignedCharArray()
    ghost_array.SetName(vtk.vtkDataSetAttributes.GhostArrayName())
    ghost_array.SetNumberOfTuples(data.GetNumberOfCells())

    # Bottom layer: first 18 cells are visible
    for i in range(18):
        ghost_array.SetValue(i, 0)

    # Top layer: next 9 cells are hidden
    for i in range(18, 27):
        ghost_array.SetValue(i, vtk.vtkDataSetAttributes.HIDDENCELL)

    data.GetCellData().AddArray(ghost_array)
    data.GetCellData().SetActiveScalars(vtk.vtkDataSetAttributes.GhostArrayName())

def image_data_to_structured_grid(data):
    alg = vtk.vtkImageToStructuredGrid()
    alg.SetInputData(data)
    alg.Update()
    return alg.GetOutput()

def image_data_to_unstructured_grid(data):
    alg = vtk.vtkAppendFilter()
    alg.AddInputData(data)
    alg.Update()
    return alg.GetOutput()

def image_data_to_explicit_structured_grid(data):
    ugrid = image_data_to_unstructured_grid(data)
    
    # Create BLOCK_I/J/K cell arrays
    dims = data.GetDimensions()
    ni, nj, nk = dims[0] - 1, dims[1] - 1, dims[2] - 1
    n_cells = ugrid.GetNumberOfCells()

    arr_i = vtk.vtkIntArray()
    arr_i.SetName("BLOCK_I")
    arr_i.SetNumberOfTuples(n_cells)

    arr_j = vtk.vtkIntArray()
    arr_j.SetName("BLOCK_J")
    arr_j.SetNumberOfTuples(n_cells)

    arr_k = vtk.vtkIntArray()
    arr_k.SetName("BLOCK_K")
    arr_k.SetNumberOfTuples(n_cells)

    cid = 0
    for k in range(nk):
        for j in range(nj):
            for i in range(ni):
                arr_i.SetValue(cid, i)
                arr_j.SetValue(cid, j)
                arr_k.SetValue(cid, k)
                cid += 1

    cd = ugrid.GetCellData()
    cd.AddArray(arr_i)
    cd.AddArray(arr_j)
    cd.AddArray(arr_k)
    
    # Convert to explicit grid
    alg = vtk.vtkUnstructuredGridToExplicitStructuredGrid()
    alg.SetInputData(ugrid)
    alg.SetInputArrayToProcess(0, 0, 0, 1, 'BLOCK_I')
    alg.SetInputArrayToProcess(1, 0, 0, 1, 'BLOCK_J')
    alg.SetInputArrayToProcess(2, 0, 0, 1, 'BLOCK_K')
    alg.Update()
    return alg.GetOutput()

image_data = create_image_data()
assert isinstance(image_data, vtk.vtkImageData)
add_ghost_cell_data(image_data)
render_dataset(image_data)

structured_grid = image_data_to_structured_grid(create_image_data())
assert isinstance(structured_grid, vtk.vtkStructuredGrid)
add_ghost_cell_data(structured_grid)
render_dataset(structured_grid)

unstructured_grid = image_data_to_unstructured_grid(create_image_data())
assert isinstance(unstructured_grid, vtk.vtkUnstructuredGrid)
add_ghost_cell_data(unstructured_grid)
render_dataset(unstructured_grid)

explicit_structured_grid = image_data_to_explicit_structured_grid(create_image_data())
assert isinstance(explicit_structured_grid, vtk.vtkExplicitStructuredGrid)
add_ghost_cell_data(explicit_structured_grid)
render_dataset(explicit_structured_grid)

```

`vtkImageData`:

 ![vtkImageData](https://discourse.vtk.org/uploads/default/original/2X/f/f9bb515d51eb59e650023ac96963b70b49610ec0.jpeg)

`vtkStructuredGrid`:

 ![vtkStructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/1/149e90e5ad50b33b2be309a45c4d958aeb602d33.jpeg)

`vtkUnstructuredGrid`:

 ![vtkUnstructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/d/d329f05563ca907c047d05370f7d9d06cb1e6ea7.jpeg)

`vtkExplicitStructuredGrid`:

 ![vtkExplicitStructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/8/8971a59fb4f99c4510f8f741dd5f77cd15d282f3.jpeg)

EDIT: Add example for `vtkExplicitStructuredGrid `

---

<div class="post-metadata">

### Author: ![akaszynski](https://discourse.vtk.org/user_avatar/discourse.vtk.org/akaszynski/32/10751_2.png) [@akaszynski](https://discourse.vtk.org/u/akaszynski)
#### Post date: [January 22, 2026, 9:40pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/10 "2026-01-22T21:40:55Z")

</div>

I’m fine with either behavior, but it’s the inconsistency that has me disagreeing with the current implementation. We can document this within PyVista, but I’m curious if this will be “fixed” or made consistent for this upcoming release of VTK.

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 23, 2026, 12:19am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/11 "2026-01-23T00:19:11Z")

</div>

I also think this change is fine if it’s applied consistently. It sounds like downstream users can already include `vtkGeometryFilter` explicitly in their own pipelines as a pre-rendering step to control this behavior if they wish to, so there is a workaround available.

But as it is with 9.6.0rc2, the use a of pre-rendering step with `vtkGeometryFilter` (and possibly with mesh type conversions) will be _necessary_ for downstream users in order to ensure consistent output for cases where ghost cells are used/present.

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 23, 2026, 5:24am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/12 "2026-01-23T05:24:16Z")

</div>

Please correct me if this information is outdated or if I am mistaken, but I read this VTK blog post on ghosting and blanking:  
[https://www.kitware.com/ghost-and-blanking-visibility-changes/](https://www.kitware.com/ghost-and-blanking-visibility-changes/)  
and I think I need to clarify some terminology.

The examples given above in this discussion are using blank, or hidden cells:

> **vtkDataSetAttribute::HIDDENCELL** specifies that this cell is not part of the model, it is only used to maintain the connectivity of the grid. This is a blank cell.

This is in contrast to ghost, or duplicate cells:

> **vtkDataSetAttribute::DUPLICATECELL** specifies that this cell is present on multiple processors. This is a ghost cell.

And so I think the title of this discussion “regression with ghost cell rendering” may be misleading, and should perhaps be “regression with blank cell rendering” instead.

Based on these definitions, I would agree that interfaces with a proper ghost cell (i.e. `DUPLICATECELL`) should _not_ be rendered by default, since we don’t want to see the interface between two blocks of a composite dataset, for example.

In contrast, the boundary between a visible cell and a blank cell (i.e. `HIDDENCELL`) corresponds to an actual boundary of the model, and not an artificial interface between duplicated data. It therefore seems correct to me that this interface should be rendered by default.

To me, this again suggests that there is regression with how `vtkUnstructuredGrid` is rendered, and all example plots in this discussion should be rendered as a “closed” surface.

---

<div class="post-metadata">

### Author: ![spyridon97](https://discourse.vtk.org/user_avatar/discourse.vtk.org/spyridon97/32/7069_2.png) [@spyridon97](https://discourse.vtk.org/u/spyridon97)
#### Post date: [January 23, 2026, 1:44pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/13 "2026-01-23T13:44:42Z")

</div>

So the gist of the problem is that the interfaces of hidden cells in unstructured grids should not be removed even if RemoveGhostInterfaces is requested because this should only happen for ghost cells and not hidden cells. And this is the case for all the structured dataset types, right?

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 26, 2026, 7:02am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/14 "2026-01-26T07:02:34Z")

</div>

> So the gist of the problem is that the interfaces of hidden cells in unstructured grids should not be removed even if RemoveGhostInterfaces is requested because this should only happen for ghost cells and not hidden cells. And this is the case for all the structured dataset types, right?

Based on the description from the linked blog post, this is my understanding of the expected behavior, yes. But the term “ghost cells” appears to be overloaded, sometimes meaning _only_ `DUPLICATECELL` (like the blog post), or _any_ cell masked by the `vtkGhostType` array. For example, in the actual code, these methods both include `HIDDENCELL` cells as part of the “ghost cells” definition:

- `UnstructuredGrid::RemoveGhostCells` removes `HIDDENCELL`, `DUPLICATECELL`, and `REFINEDCELL`:

> <https://github.com/Kitware/VTK/blob/5420b4a0729b13527701707673bbfc08cdbde070/Common/DataModel/vtkUnstructuredGrid.cxx#L40-L41>

- `vtkExtractGhostCells` uses a threshold filter to extract _all_ masked cells from the `vtkGhostType` array (including `HIDDENCELL`, `DUPLICATECELL`, and `REFINEDCELL`):

> <https://github.com/Kitware/VTK/blob/5420b4a0729b13527701707673bbfc08cdbde070/Filters/General/vtkExtractGhostCells.cxx#L60-L61>

The `RemoveGhostInterfaces` option for `vtkGeometryFilter` is a bit different, and seems to suggest that any ghost cells that are not duplicate cells are _always_ removed, even if `RemoveGhostInterfaces` is False.

> <https://github.com/Kitware/VTK/blob/5420b4a0729b13527701707673bbfc08cdbde070/Filters/Geometry/vtkGeometryFilter.cxx#L1430-L1436>

Maybe the issue is that `vtkUnstructuredGrid` doesn’t explicitly support cell blanking? E.g. in the docs, we can see that [vtkDataSet::HasAnyBlankCells](https://vtk.org/doc/nightly/html/classvtkDataSet.html#a781ed428f065c45d407b75cd4b2152df) is only implemented by:  
[vtkCartesianGrid](https://vtk.org/doc/nightly/html/classvtkCartesianGrid.html#a1faa0d03ee9fcb6436a226fc11f4ecc9), [vtkExplicitStructuredGrid](https://vtk.org/doc/nightly/html/classvtkExplicitStructuredGrid.html#ad9be38bc7ccf20fc10c9b846ef5be2db), and [vtkStructuredGrid](https://vtk.org/doc/nightly/html/classvtkStructuredGrid.html#a7fab14a884ed694470de5d93af6421c9), and so maybe users should only expect cell blanking to work (and render correctly) with those data types?

Further complicating things, it looks like the numpy interface supports masking using ghost arrays with `HIDDENCELL` for _any_ dataset, so presumably this should include `vtkUnstructuredGrid`?

> <https://github.com/Kitware/VTK/blob/5420b4a0729b13527701707673bbfc08cdbde070/Wrapping/Python/vtkmodules/numpy_interface/algorithms.py#L126-L131>

It would be nice to get clarity from VTK devs on what’s supported by VTK and what the expected behavior should be.

- Is cell blanking supported by `vtkUnstructuredGrid` or not?
- Should users expect `vtkImageData` with hidden cells to render the same as a similar dataset that has type `vtkUnstructuredGrid` ?
- Is the issue highlighted by this topic with `vtkUnstructuredGrid` rendering considered a bug or not?

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 26, 2026, 7:41am UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/15 "2026-01-26T07:41:40Z")

</div>

For completeness, here’s an updated example that also includes `vtkRectilinearGrid` and generates renderings for both `HIDDENCELL` and `DUPLICATECELL` ghost cell values.

> ****
>
> ```auto
> import vtk
> 
> # -----------------------------------------------------------------------------
> # Rendering
> # -----------------------------------------------------------------------------
> 
> def render_dataset(dataset, title):
> mapper = vtk.vtkDataSetMapper()
> mapper.SetInputData(dataset)
> mapper.SetScalarVisibility(False)
> 
> actor = vtk.vtkActor()
> actor.SetMapper(mapper)
> 
> prop = actor.GetProperty()
> prop.EdgeVisibilityOn()
> prop.SetEdgeColor(0.0, 0.0, 0.0)
> prop.SetLineWidth(1.0)
> prop.SetColor(1.0, 1.0, 1.0)
> 
> text = vtk.vtkTextActor()
> text.SetInput(title)
> tprop = text.GetTextProperty()
> tprop.SetFontSize(18)
> tprop.SetColor(1.0, 1.0, 1.0)
> text.SetPosition(10, 10)
> 
> renderer = vtk.vtkRenderer()
> renderer.AddActor(actor)
> renderer.AddViewProp(text)
> renderer.SetBackground(0.1, 0.1, 0.1)
> 
> # Camera
> camera = renderer.GetActiveCamera()
> camera.SetPosition(1, 1, 1)
> camera.SetViewUp(0, 0, 1)
> renderer.ResetCamera()
> 
> window = vtk.vtkRenderWindow()
> window.AddRenderer(renderer)
> window.SetSize(800, 600)
> 
> interactor = vtk.vtkRenderWindowInteractor()
> interactor.SetRenderWindow(window)
> 
> window.Render()
>     
> w2i = vtk.vtkWindowToImageFilter()
> w2i.SetInput(window)
> w2i.Update()
> 
> writer = vtk.vtkPNGWriter()
> filename = f"{title}.png"
> writer.SetFileName(filename)
> writer.SetInputConnection(w2i.GetOutputPort())
> writer.Write()
> 
> # -----------------------------------------------------------------------------
> # Base dataset
> # -----------------------------------------------------------------------------
> 
> def create_image_data():
> data = vtk.vtkImageData()
> data.SetDimensions(4, 4, 4) # 3×3×3 cells
> return data
> 
> # -----------------------------------------------------------------------------
> # Conversions
> # -----------------------------------------------------------------------------
> 
> def image_data_to_rectilinear_grid(data):
> dims = data.GetDimensions()
> spacing = data.GetSpacing()
> origin = data.GetOrigin()
> nx, ny, nz = dims
> 
> x = vtk.vtkDoubleArray()
> x.SetNumberOfValues(nx)
> for i in range(nx):
> x.SetValue(i, origin[0] + i * spacing[0])
> 
> y = vtk.vtkDoubleArray()
> y.SetNumberOfValues(ny)
> for j in range(ny):
> y.SetValue(j, origin[1] + j * spacing[1])
> 
> z = vtk.vtkDoubleArray()
> z.SetNumberOfValues(nz)
> for k in range(nz):
> z.SetValue(k, origin[2] + k * spacing[2])
> 
> rgrid = vtk.vtkRectilinearGrid()
> rgrid.SetDimensions(nx, ny, nz)
> rgrid.SetXCoordinates(x)
> rgrid.SetYCoordinates(y)
> rgrid.SetZCoordinates(z)
> 
> rgrid.GetPointData().ShallowCopy(data.GetPointData())
> rgrid.GetCellData().ShallowCopy(data.GetCellData())
> 
> return rgrid
> 
> def image_data_to_structured_grid(data):
> alg = vtk.vtkImageToStructuredGrid()
> alg.SetInputData(data)
> alg.Update()
> return alg.GetOutput()
> 
> def image_data_to_unstructured_grid(data):
> alg = vtk.vtkAppendFilter()
> alg.AddInputData(data)
> alg.Update()
> return alg.GetOutput()
> 
> def image_data_to_explicit_structured_grid(data):
> ugrid = image_data_to_unstructured_grid(data)
> 
> dims = data.GetDimensions()
> ni, nj, nk = dims[0] - 1, dims[1] - 1, dims[2] - 1
> n_cells = ugrid.GetNumberOfCells()
> 
> arr_i = vtk.vtkIntArray()
> arr_i.SetName("BLOCK_I")
> arr_i.SetNumberOfTuples(n_cells)
> 
> arr_j = vtk.vtkIntArray()
> arr_j.SetName("BLOCK_J")
> arr_j.SetNumberOfTuples(n_cells)
> 
> arr_k = vtk.vtkIntArray()
> arr_k.SetName("BLOCK_K")
> arr_k.SetNumberOfTuples(n_cells)
> 
> cid = 0
> for k in range(nk):
> for j in range(nj):
> for i in range(ni):
> arr_i.SetValue(cid, i)
> arr_j.SetValue(cid, j)
> arr_k.SetValue(cid, k)
> cid += 1
> 
> cd = ugrid.GetCellData()
> cd.AddArray(arr_i)
> cd.AddArray(arr_j)
> cd.AddArray(arr_k)
> 
> alg = vtk.vtkUnstructuredGridToExplicitStructuredGrid()
> alg.SetInputData(ugrid)
> alg.SetInputArrayToProcess(0, 0, 0, 1, "BLOCK_I")
> alg.SetInputArrayToProcess(1, 0, 0, 1, "BLOCK_J")
> alg.SetInputArrayToProcess(2, 0, 0, 1, "BLOCK_K")
> alg.Update()
> 
> return alg.GetOutput()
> 
> # -----------------------------------------------------------------------------
> # Ghost cell injection
> # -----------------------------------------------------------------------------
> 
> def add_ghost_cell_data(data, ghost_flag):
> ghost = vtk.vtkUnsignedCharArray()
> ghost.SetName(vtk.vtkDataSetAttributes.GhostArrayName())
> ghost.SetNumberOfTuples(data.GetNumberOfCells())
> 
> # Bottom layer visible
> for i in range(18):
> ghost.SetValue(i, 0)
> 
> # Top layer ghosted
> for i in range(18, 27):
> ghost.SetValue(i, ghost_flag)
> 
> cd = data.GetCellData()
> cd.AddArray(ghost)
> cd.SetActiveScalars(vtk.vtkDataSetAttributes.GhostArrayName())
> 
> # -----------------------------------------------------------------------------
> # Test matrix
> # -----------------------------------------------------------------------------
> 
> MESH_FACTORIES = {
> "ImageData": create_image_data,
> "RectilinearGrid": lambda: image_data_to_rectilinear_grid(create_image_data()),
> "StructuredGrid": lambda: image_data_to_structured_grid(create_image_data()),
> "UnstructuredGrid": lambda: image_data_to_unstructured_grid(create_image_data()),
> "ExplicitStructuredGrid": lambda: image_data_to_explicit_structured_grid(create_image_data()),
> }
> 
> GHOST_TYPES = {
> "HIDDENCELL": vtk.vtkDataSetAttributes.HIDDENCELL,
> "DUPLICATECELL": vtk.vtkDataSetAttributes.DUPLICATECELL,
> }
> 
> # -----------------------------------------------------------------------------
> # Run all renders
> # -----------------------------------------------------------------------------
> 
> for mesh_name, factory in MESH_FACTORIES.items():
> for ghost_name, ghost_flag in GHOST_TYPES.items():
> dataset = factory()
> add_ghost_cell_data(dataset, ghost_flag)
> 
> title = f"{vtk. __version__ } - {mesh_name} - {ghost_name}"
> render_dataset(dataset, title)
> 
> ```

I ran this code with `vtk==9.5.2` and `vtk==9.6.0rc2`. Here’s the generated renderings with the `HIDDENCELL` case on the left, and the `DUPLICATECELL` case on the right.

| Mesh Type | vtk 9.5.2 | vtk 9.6.0 |
| --- | --- | --- |
| ImageData | ![9.5.2 - ImageData](https://discourse.vtk.org/uploads/default/original/2X/1/1b50e209dee8f1d6bcf9f2f8626fbe4d44c70b29.png) | ![9.6.0 - ImageData](https://discourse.vtk.org/uploads/default/original/2X/f/fb2eb79d4fa1179fc8e4cbabd6d619e13ab5bf4f.png) |
| RectilinearGrid | ![9.5.2 - RectilinearGrid](https://discourse.vtk.org/uploads/default/original/2X/6/6327fecd4da00aa8660518fc807738ed2dc92b19.png) | ![9.6.0 - RectilinearGrid](https://discourse.vtk.org/uploads/default/original/2X/c/c14f6e02241da9f6640e85692d7533f83b991cb0.png) |
| StructuredGrid | ![9.5.2 - StructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/a/a78fd0376f7f5a2203312e8bf2489943a1d77d54.png) | ![9.6.0 - StructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/f/fcf5728ff2b14387169b72209e30e75e9c8cc7cc.png) |
| ExplicitStructuredGrid | ![9.5.2 - ExplicitStructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/9/978ea8a2859c65aa713e6b980f2b6b078369df65.png) | ![9.6.0 - ExplicitStructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/e/e70062365e007ed2357bf1c503b8e1f42d84ec86.png) |
| UnstructuredGrid | ![9.5.2 - UnstructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/1/11491a99cf405b8a3bd4f8942eaf78dca09ca7f9.png) | ![9.6.0 - UnstructuredGrid](https://discourse.vtk.org/uploads/default/original/2X/d/d0bd841da199f8c8c5176a538663bef801e08141.png) |

We can make the following observations:

- Renderings for `vtkImageData`, `vtkRectilinearGrid`, `vtkStructured` are identical across versions.
- Renderings for `vtkExplicitStructuredGrid` with `HIDDENCELL` is identical across versions, but with `DUPLICATECELL`, the duplicate cells themselves are now removed, but the interface is _not_ removed.
- Renderings for `vtkUntructuredGrid` have both changed. Both `HIDDENCELL` and `DUPLICATECELL` cells are completely removed, _and_ the interface is removed in both cases.

Whereas in 9.5.2 we had consistent renderings across all mesh types for both `HIDDENCELL` and `DUPLICATECELL` values, we now have _two_ different renderings for the `HIDDENCELL` case, and _three_ different renderings for the `DUPLICATECELL` case. Seems to me like the ghost cell interfaces are not handled correctly and/or consistently by `vtkGeometryFilter`. Should I open an issue in GitLab to track this?

---

<div class="post-metadata">

### Author: ![spyridon97](https://discourse.vtk.org/user_avatar/discourse.vtk.org/spyridon97/32/7069_2.png) [@spyridon97](https://discourse.vtk.org/u/spyridon97)
#### Post date: [January 26, 2026, 3:55pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/16 "2026-01-26T15:55:11Z")

</div>

Yes, please open an issue cause that’s a lot of information.

---

<div class="post-metadata">

### Author: ![user27182](https://discourse.vtk.org/user_avatar/discourse.vtk.org/user27182/32/10104_2.png) [@user27182](https://discourse.vtk.org/u/user27182)
#### Post date: [January 26, 2026, 8:26pm UTC](https://discourse.vtk.org/t/possible-vtk-9-6-0rc2-regression-with-ghost-cell-rendering/16251/17 "2026-01-26T20:26:22Z")

</div>

[https://gitlab.kitware.com/vtk/vtk/-/issues/19922](https://gitlab.kitware.com/vtk/vtk/-/issues/19922)
