Mapping texture image on a 3D surface

Hi,
i’m new with plotly and i’m using it for a 3D mesh generator. I would like to know if it’s possible to map a texture (taken from a 2D image) into a 3D surface through a correspondence matrix (For each vertex in 3D assing a 2D point into the image, from which i can take the texture data (RGB)). I’ve did something like this with the function ‘plot_mesh’ from the toolbox graph on matlab and now i need to do the same thing in python but i don’t find anything like this, someone can help me?
Thanks in advance

@barloccia This notebook illustrates how you can map a 2d image onto a surface:
https://plot.ly/~empet/14172/mapping-an-image-on-a-surface/
Unlike matlab you cannot map a multicolor (rgb) image because plotly can color a surface only using a colormap.

1 Like

The link does not work anymore

The notebook illustrating how to map a graycolor onto a surface has been removed because meanwhile
it was developed a method to map a color image: https://github.com/empet/Texture-mapping-with-Plotly.
But if you need the simplest case, let me know, and I’ll repost the removed notebook.

1 Like

I have the following and want to render the texture of the satellite image to this hight profile. I have tried the linked method, but it did not work.

@Klegi Without giving details about the mapped image on your surface, that seems to be a rough (unsmooth) surface, it’s hard to have an opinion, just by looking at the posted image.
If the mapped image has a low resolution then the result is not as expected.
What I see is an image with dark colors that probably doesn’t allow to distinguish details.
To fix such a drawback you should add lighting and lightposition in the go.Surface definition, having respectively the following attributes (but changing the assigned values according to your needs)

lighting=dict(ambient=0.18,
              diffuse=1,
              fresnel=0.1,
                        specular=1,
                        roughness=0.05,
                        facenormalsepsilon=1e-8,
                        vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
                   y=200,
                   z=1000)

Here are more details. The upper image shows the height profile dem_np. The lower is the satellite image that should be the texture of the height like in google earth. Dem is a (541, 901, 1) and land_np is (541, 901, 3) numpy array. I will make the satellite image a bit shinier in preprocessing in the future.

fig = go.Figure(data=[go.Surface(z=dem_np, x=x, y=y[::-1], surfacecolor=land_np[...,0], lighting=lighting, lightposition=lightposition)])
fig.update_layout(scene=dict(
    zaxis=dict(nticks=4, range=[np.min(dem_np), np.max(dem_np)]),
    aspectratio=dict(x=1, y=1, z=0.2)
))

Edit - solved:
I have solved my problem with the github link you provided above. Thank you!
And I have found a bug in it. I changed the image2zvals function as the colorscale did not support numpy types. So I adapted the line before the return statement to
pl_colorscale = [[float(sv), f'rgb{int(color[0]), int(color[1]), int(color[2])}'] for sv, color in zip(scale, colors)]