Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draping 2D features on 3D mesh #2288

Open
swiss-knight opened this issue Sep 14, 2024 · 3 comments
Open

Draping 2D features on 3D mesh #2288

swiss-knight opened this issue Sep 14, 2024 · 3 comments

Comments

@swiss-knight
Copy link

swiss-knight commented Sep 14, 2024

Hello,

this is not an issue sensu stricto but it seems that the github Discussion panel is not available in this repo.

I'm simply wondering if it's possible to compute the projection of a 2D feature onto a 3D mesh using trimesh.

The use case which comes to my mind is when one is working with 2D geographical data and want to get those 2D data (points, lines or polygons) "onto" a TIN (given e.g. as ply, stl or obj file...), representing a terrain.

This is only a subset of the question, because in that case we know the projection is done "vertically": (x,y) coordinates of the 2D features do not change during the operation and the normals of the terrain triangles all have a positive z component (i.e. there is no overhang)

Thank you for the nice work done on this package!
Warm Regards.

@Kiord
Copy link

Kiord commented Sep 16, 2024

This is a common practice for texture mapping for instance.
Can you elaborate on the goal of draping those 2D features ? Is it solely for visualization ?

@swiss-knight
Copy link
Author

Hi @Kiord,

No it's not for visualization; I would like the output to be a real 3D geometry.

The main goal is to retrieve the 3rd dimension of some given 2D shapes to actually make those shapes 3 dimensional.

You can think about a set of line features representing a road network which is given in 2 dimensions (e.g. as Shapely LINESTRING objects having (x,y) coordinates), which you want to convert to real 3D lines having (x,y,z) coordinates using an existing terrain model given as a TIN mesh (e.g. as a PLY file), to retrieve the Z-values and make those 2D geometries real 3D geometries (e.g. also a Shapely LINESTRINGs).

An other way of representing the problem at hand would to apply a parallel projection (in the current case, a vertical one) of the 2D shapes "onto" the mesh. This operation is sometimes known as "draping" 2D shapes onto a terrain/mesh.

@Kiord
Copy link

Kiord commented Sep 16, 2024

Thanks for the details, to my knowledge there is no such thing in Trimesh.

You could obtain the Z coordinate of all the features (or at least their control points) by raycasting them along the Z axis.
Something like that : (not tested)

# Make sure to set the ray origins on one side of the mesh
origin_z = mesh.vertices[:, 2].min() - 1 
features_2d_with_low_z  = np.zeros((len(features_2d), 3))
features_2d_with_low_z[:, 2] = origin_z

up_vectors = np.zeros_like(features_2d_with_low_z)
up_vectors[:, 2] = 1

# ray/mesh intersections computation
intersections, ray_indices, face_indices = scan_mesh.ray.intersects_location(features_2d_with_low_z, up_vectors, multiple_hits)

intersections_z = -np.ones(len(features_2d))
intersections_z[ray_indices] = intersections[:, 2]

But if the triangle mesh resolution is higher than the spacing of the 2D features, the now-3D shapes won't exactly lie on 3D surface. An exact solution would require to compute the 2D intersections of the 2D shapes on the XY triangles of the surface mesh. With straight lines only, it should not be so hard.

PS : The 3D ray casting is a bit overkill considering it only solves a 2D point query on 2D triangles...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants