# Adding thickness to a surface mesh

**URL:** https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568
**Category:** ParaView Support
**Created:** [February 28, 2021, 4:22pm UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568 "2021-02-28T16:22:19Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![parajan](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/p/6a8cbe/32.png) [@parajan](https://discourse.paraview.org/u/parajan)
#### Post date: [February 28, 2021, 4:22pm UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/1 "2021-02-28T16:22:19Z")

</div>

I have a spherical surface with a scalar field on it, as shown here in 3d and in a cross section:

 ![paraview_problem](https://discourse.paraview.org/uploads/default/original/2X/2/20def4ecb26e0ed47e32a45675d4f7a6cc656be5.png)

I would like to give the surface a thickness, so that it looks more like this (surface has thickness and there should be no artifacts in the cross section):  
 ![target](https://discourse.paraview.org/uploads/default/original/2X/2/2f22f7d99a7d999ccd473d44a4e3e648f0c2928a.png)

What has not worked so far is:

1. **Change line width** : Under Styling \> Line Width. This has no effect on the 3d view. It only changes the width of the line in the cross section. However, the larger line thickness leads to tiny evenly spaced dark artifacts.
2. **Extrusion** : After applying Extract Surface, the Linear Extrusion filter can move the mesh surface in a direction, but it is constant for each element of the mesh. Is it possible to set the extrusion direction as the surface normal?

Is there another way/filter available to achieve this?

I attach the geometry and the paraview state file:  
[sphere\_surface.vtu](https://discourse.paraview.org/uploads/short-url/waEgWk3CbRPhhbuajPwoYjo4aE1.vtu) (706.5 KB)  
[surface\_thickness\_issue.pvsm](https://discourse.paraview.org/uploads/short-url/rxaJ4iEv89EeEPnnAztu0I3FZf7.pvsm) (699.2 KB)

---

<div class="post-metadata">

### Author: ![mwestphal](https://discourse.paraview.org/user_avatar/discourse.paraview.org/mwestphal/32/17_2.png) [@mwestphal](https://discourse.paraview.org/u/mwestphal)
#### Post date: [March 1, 2021, 9:08am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/2 "2021-03-01T09:08:16Z")

</div>

I’m afraid there isn’t, but a NormalExtrusion filter would make sense in ParaView.

You should be able to implement in a python ProgrammableFilter though.

---

<div class="post-metadata">

### Author: ![Kenichiro-Yoshimi](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/k/ecc23a/32.png) [@Kenichiro-Yoshimi](https://discourse.paraview.org/u/Kenichiro-Yoshimi)
#### Post date: [March 1, 2021, 10:40am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/3 "2021-03-01T10:40:30Z")

</div>

Hello,

A simple work around is to use the Delaunay 3D filter if adding thickness to a sphere. See the attached state file:  
[delaunay\_3d.zip](https://discourse.paraview.org/uploads/short-url/9q9IvUlkzaDse1H30ck9Mg0APie.zip) (393.0 KB)

 ![delaunay_3d](https://discourse.paraview.org/uploads/default/original/2X/6/6d429a15dd4642b98c8ad6f0731e241b55d71c40.png)  
But, the cutting surface by the Clip filter with box might not be very sharp as shown in the upper left figure.

---

<div class="post-metadata">

### Author: ![parajan](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/p/6a8cbe/32.png) [@parajan](https://discourse.paraview.org/u/parajan)
#### Post date: [March 1, 2021, 9:44pm UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/4 "2021-03-01T21:44:50Z")

</div>

Very neat. To make the sphere hollow, the trick is to clip a sphere out of it, correct? Is it possible to clip non-standard volumes as well, so one could use the approach for a non-spherical shape?

---

<div class="post-metadata">

### Author: ![Kenichiro-Yoshimi](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/k/ecc23a/32.png) [@Kenichiro-Yoshimi](https://discourse.paraview.org/u/Kenichiro-Yoshimi)
#### Post date: [March 3, 2021, 12:20am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/5 "2021-03-03T00:20:53Z")

</div>

Hello,

For a non-spherical shape, it is needed to use the **Programmable filter** so that the surface of the shape is extruded in each surface normal direction. As the simplest example, the state file is attached:  
[extrusion.zip](https://discourse.paraview.org/uploads/short-url/AfRGHmgeCMIlSxX0eCLXkjFoxKD.zip) (356.1 KB)

And, the figure below shows the result.  
 ![extrusion](https://discourse.paraview.org/uploads/default/original/2X/8/8a44ced06357d46c995abbf6d0a7d6bdced9319e.png)

Here is programmable filter:

- Output Data set Type: vtkUnstructuredGrid
- Script:

```python
import numpy as np

pdi = self.GetInput()
ugo = self.GetOutput()
ugo.Allocate()

scale = 0.2

num_pts = pdi.GetNumberOfPoints()
num_cells = pdi.GetNumberOfCells()
new_pts = pdi.GetPoints()
in_pd = pdi.GetPointData()
out_pd = ugo.GetPointData()
out_pd.CopyAllocate(in_pd);

normals =in_pd.GetArray('Normals')

id_map = {}
for i in range(num_pts):
    point = np.array(pdi.GetPoint(i))
    normal = np.array(normals.GetTuple3(i))

    j = new_pts.InsertNextPoint(point+normal*scale)
    out_pd.CopyData(in_pd, i, i)
    out_pd.CopyData(in_pd, i, j)
    id_map[i] = j

ids = vtk.vtkIdList()
for c_id in range(num_cells):
    pdi.GetCellPoints(c_id, ids)
    new_ids = ids
    for id in range(ids.GetNumberOfIds()):
        extruded_pt_id = id_map[ids.GetId(id)]
        new_ids.InsertNextId(extruded_pt_id)

    ugo.InsertNextCell(vtk.VTK_WEDGE, new_ids)

ugo.SetPoints(new_pts)

```

---

<div class="post-metadata">

### Author: ![mwestphal](https://discourse.paraview.org/user_avatar/discourse.paraview.org/mwestphal/32/17_2.png) [@mwestphal](https://discourse.paraview.org/u/mwestphal)
#### Post date: [March 3, 2021, 8:13am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/6 "2021-03-03T08:13:16Z")

</div>

Nice work @Kenichiro-Yoshimi !

If you feel like it and can write C++, this would be great in VTK.

---

<div class="post-metadata">

### Author: ![parajan](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/p/6a8cbe/32.png) [@parajan](https://discourse.paraview.org/u/parajan)
#### Post date: [March 4, 2021, 4:50am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/7 "2021-03-04T04:50:01Z")

</div>

This is awesome! Let me point out that this also generates good data for the sliced view. The slice edges can be made more accurate by running a loop subdivision beforehand on the surface.

 ![nice_extrusion](https://discourse.paraview.org/uploads/default/original/2X/7/7fdcf4513a2a6e224beabe1a5646085685792240.jpeg)

One issue is that the filter changes the array of normals.

![original_normals](https://discourse.paraview.org/uploads/default/original/2X/0/00e883a5ddca2034a6a1ccb7ccfc5deb2c77561c.png) → ![modified_normals](https://discourse.paraview.org/uploads/default/original/2X/c/c693e7c4a59ea20fa59179c1140d3f895ce079ce.png)

This has two downsides:

1. The parameter “scale” can not be changed after its application (produces an error).
2. The surface rendering looks bad when extruding the surface to the outside (scale=-0.2, since the normals point inwards in the mesh).

What seems to resolve the issue is replacing the line

```auto
new_pts = pdi.GetPoints()

```

with

```auto
in_pts = pdi.GetPoints()
new_pts = vtk.vtkPoints()
new_pts.DeepCopy(in_pts)

```

There might be a better way to do this though.

There is still a problem with the lighting unfortunately due to the new normals.  
 ![new_normals](https://discourse.paraview.org/uploads/default/original/2X/6/6d25153e116848209e3d5d427919d3fd155e4632.png) ![bad_lighting](https://discourse.paraview.org/uploads/default/original/2X/d/dabd548e4f2e78372598439b2c088ade253979f3.png)

Is there a way to separate the old from the new normals (so one can flip only the old ones later, since they are now pointing inside the volume)?

Attached is the state file for the image illustrating the lighting problem:  
[spherical\_extrusion\_v2.pvsm](https://discourse.paraview.org/uploads/short-url/e3h8lE9dFWnQyJo9dGqZ9YIujCM.pvsm) (632.3 KB)

---

<div class="post-metadata">

### Author: ![Kenichiro-Yoshimi](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/k/ecc23a/32.png) [@Kenichiro-Yoshimi](https://discourse.paraview.org/u/Kenichiro-Yoshimi)
#### Post date: [March 4, 2021, 9:30am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/8 "2021-03-04T09:30:46Z")

</div>

Thank you for trying and making several improvements!

The simplest way to avoid the lighting issue might be to remove the array of normals in the Programmable filter script.

```python
out_pd.RemoveArray('Normals')

```

Here is the state file [spherical\_extrusion\_v2\_1.pvsm](https://discourse.paraview.org/uploads/short-url/lCQGr4AfFcCrE5vvWx9hLItF2S9.pvsm) (643.8 KB)

---

<div class="post-metadata">

### Author: ![parajan](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/p/6a8cbe/32.png) [@parajan](https://discourse.paraview.org/u/parajan)
#### Post date: [March 4, 2021, 4:44pm UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/9 "2021-03-04T16:44:51Z")

</div>

Yes, that works to kick out the incorrect surface normals.

After the programmable filter, one can then use this to get the correct normal vectors:

- Clip
- Extract Surface
- GenerateSurfaceNormal

This will also generate normal vectors on the cut surface leading to subtly improved lighting:

 ![success](https://discourse.paraview.org/uploads/default/original/2X/3/32ac851bdbd602c4e5749028fa5df6f5b0564c71.png)

---

<div class="post-metadata">

### Author: ![randomwangran](https://discourse.paraview.org/user_avatar/discourse.paraview.org/randomwangran/32/5929_2.png) [@randomwangran](https://discourse.paraview.org/u/randomwangran)
#### Post date: [March 5, 2021, 6:21pm UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/10 "2021-03-05T18:21:38Z")

</div>

Awsome figure!

I notice that the simulated value is the same along the vector, i.e. pointing to the centre of the ball. What  
s the perspective can this figure offer to readers?

---

<div class="post-metadata">

### Author: ![parajan](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/p/6a8cbe/32.png) [@parajan](https://discourse.paraview.org/u/parajan)
#### Post date: [March 6, 2021, 4:57am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/11 "2021-03-06T04:57:40Z")

</div>

I am simulating a thin shell which can be approximated by its midsurface. The figure is very helpful in showing the actual geometry of the physical problem.

---

<div class="post-metadata">

### Author: ![icebreakersours](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/i/ac91a4/32.png) [@icebreakersours](https://discourse.paraview.org/u/icebreakersours)
#### Post date: [March 7, 2022, 3:31am UTC](https://discourse.paraview.org/t/adding-thickness-to-a-surface-mesh/6568/12 "2022-03-07T03:31:40Z")

</div>

Hello,

I tried reproducing this solution for something I am working on and it doesn’t quite work.

Here’s my pipeline: state.pvd \> ExtractSurface \> Threshold (integer) \> ProgrammableFilter (one proposed here).

Naturally, the programmable filter wasn’t going to work in this situation because there are no normals to operate upon. When I insert the programmable filter one level above, it seems to work (bit tricky to tell right now). However, I only want a subset of the surfaces that are embedded inside a domain to be offset with some thickness.

I tried clipping the domain of interest and then extracting surfaces but that doesn’t seem to work.

Thanks!

Vikas
