I want to build a 2D mesh with the Python Module Meshpy. Here is a simple Code for an example:
from meshpy.tet import MeshInfo, build
mesh_info = MeshInfo()
mesh_info.set_points([
(0,0,0), (2,0,0), (2,2,0), (0,2,0),
])
mesh_info.set_facets([
[0,1,2,3],
])
mesh = build(mesh_info)
How you can see its just a simple square in 2D. If i want to try to mesh it, Python crashes with the error Code "Exception: All vertices are coplanar (Tol = 1e-08)".
Is there a possibility for creating meshes with Meshpy in 2D or does it only works in 3D?
And if its possible, can i change the size of the mesh?
Related
Is there a chance I can replace coordinates of a pyvista_ndarray by a ndarray?
My objective is to reproject points coordinates of a vtu file (unstructured grid). The current coordinates of the mesh object are in the coordinate reference system EPSG 27672 and I want them in EPSG 4326 (WGS84).
For this, I open the vtu file using the pyvista module :
mesh = pv.read("arg_Tm2__t0002.pvtu")
type(mesh.points)
>pyvista.core.pyvista_ndarray.pyvista_ndarray
As a result, mesh.points gives the 3 spatial coordinates. Then, I use pyproj module to reproject the 3 coordinates into EPSG 4326. By combining the 3 resulting x,y,z numpy.ndarray, I now get a NumPy array with a shape and size similar to mesh.points.
# set the pyproj transformer
crs1 = CRS.from_epsg(27562)
crs2 = CRS.from_epsg(4326)
reproj = Transformer.from_crs(crs1, crs2)
# Reprojection
reproj_dataY,reproj_dataX,altitude = reproj.transform(mesh.points[:,0],mesh.points[:,1],mesh.points[:,2])
reprojData = np.column_stack((reproj_dataX,reproj_dataY,altitude))
#compare objects
print('original Mesh points -> ', mesh.points)
print('original Mesh type: ', type(mesh.points))
print('Reprojected points-> ', reprojData)
print('Reprojected type: ', type(reprojData))
Original Mesh points -> [[958427.33 119680.95 2396.288549 ]
[957754.39 120023.85 2430.1833881 ]
[957256.56 120241.02 2112.22953263]
...
[963366.748527 115096.364632 3054.75408138]
[963401.840285 113351.753238 3024.50286566]
[963497.913738 113339.696062 3048.83674197]]
Original Mesh type: <class 'pyvista.core.pyvista_ndarray.pyvista_ndarray'>
Reprojected points-> [[ 6.96487903 45.9823843 2396.288549 ]
[ 6.95646936 45.98581994 2430.1833881 ]
[ 6.95021969 45.98803333 2112.22953263]
...
[ 7.02498443 45.93857775 3054.75408138]
[ 7.02409542 45.92289079 3024.50286566]
[ 7.02532248 45.92273099 3048.83674197]]
Reprojected type: <class 'numpy.ndarray'>enter code here
Now, It's time to replace the coordinates of the vtu object:
mesh.points = reprojData
Finally, I check the modified mesh: The X bounds and Y bounds have been modified and the ranges are correct. However, the plot shows a line of points instead a nice 3d object. :(.
Do you have any idea what is wrong? Do you see another way to manage reprojection?
The range of values of XY and Z after the transformation are significantly different:
>>>np.array(mesh.bounds).reshape((3,-1)).ptp(axis=1)
array([1.22515302e-01, 7.78657599e-02, 2.47978788e+03])
XY are indeed in degrees and Z still in meter. The visual representation of this data is unrealistic and data should be adapted to do so.
Newbie here!
I have an STL file which is not watertight and the gap is quite big to repair with the close vertex of the trimesh.
I tried with open3d by following this but I have the following error: "ValueError: vector too long"..
Is there any way to make the mesh watertight? I need to calculate the CoM and Inertia matrix but the values would not be correct if my mesh is not watertight/a closed surface.
For the open3d, firstly I uploaded the stl file, I converted it to numpy and then I used the following code:
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(DataNP)
o3d.io.write_point_cloud("testinggggg.ply", pcd)
poisson_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=8, width=0, scale=1.1, linear_fit=False)[0]
bbox = pcd.get_axis_aligned_bounding_box()
p_mesh_crop = poisson_mesh.crop(bbox)
o3d.io.write_triangle_mesh("output_testinggggg.ply", dec_mesh)
Any help is highly appreciated!
I have managed to make the mesh watertight. I will post here in case anyone is having troubles in the future with it.
My mesh was actually made of 2 smaller meshes, so I had to first merge them together and then use the VTK library to clean the mesh and fill the holes. This made my mesh watertight and I could calculate everything I needed.
This is the code:
input1 = vtk.vtkPolyData()
input2 = vtk.vtkPolyData()
input1.DeepCopy(Data1.GetOutput())
input2.DeepCopy(Data2.GetOutput())
# Append the two meshes
appendFilter = vtk.vtkAppendPolyData()
appendFilter.AddInputData(input1)
appendFilter.AddInputData(input2)
appendFilter.Update()
# Remove any duplicate points.
cleanFilter = vtk.vtkCleanPolyData()
cleanFilter.SetInputConnection(appendFilter.GetOutputPort())
cleanFilter.Update()
# newData = cleanFilter
fill = vtk.vtkFillHolesFilter()
fill.SetInputConnection(appendFilter.GetOutputPort())
fill.SetHoleSize(100)
fill.Update()
I am creating an interactive map using ipyleaflet using the following code:
from ipyleaflet import Map, Polygon
polygon = Polygon(
locations=[[(38.844185,-4.804621),(39.241299,-1.899833),(40.74308,-2.205491),(40.34742,-5.17429),(38.844185,-4.804621)],[(39.365192,-1.941078),(40.867912,-1.567062),(41.276688,-4.670904),(39.775406,-4.976737),(39.365192,-1.941078)],[(39.706161,-1.849863),(41.207623,-1.465817),(41.617561,-4.594476),(40.117233,-4.908839),(39.706161,-1.849863)],[(39.702591,-5.033657),(40.101254,-2.077048),(41.602196,-2.389729),(41.204681,-5.413605),(39.702591,-5.033657)]],
color="green",
fill_opacity= 0.5,
fill_color="green"
)
m = Map(center=(38.5531, -4.6914), zoom=6)
m.add_layer(polygon);
m
The ouptut looks like this:
I am wondering how can I make the intersection of the polygons not be fully transparent. Looking at the attributes https://ipyleaflet.readthedocs.io/en/latest/api_reference/polygon.html in the documentation, I don't see any option?
An example of the desired output can be seen in the image below:
You've got bad results because ipyleaflet subtracts ovellaped polygons (you can see it in second example in the documentation link you posted, "Polygon with hole")
You need to add each polygon separately, I changed your code a bit, now it creates and applies polygons in loop:
from ipyleaflet import Map, Polygon
poligons = [[(38.844185,-4.804621),(39.241299,-1.899833),(40.74308,-2.205491),(40.34742,-5.17429),(38.844185,-4.804621)],
[(39.365192,-1.941078),(40.867912,-1.567062),(41.276688,-4.670904),(39.775406,-4.976737),(39.365192,-1.941078)],
[(39.706161,-1.849863),(41.207623,-1.465817),(41.617561,-4.594476),(40.117233,-4.908839),(39.706161,-1.849863)],
[(39.702591,-5.033657),(40.101254,-2.077048),(41.602196,-2.389729),(41.204681,-5.413605),(39.702591,-5.033657)]]
m = Map(center=(38.5531, -4.6914), zoom=6)
for poly in poligons:
polygon = Polygon(
locations= poly,
color="green",
fill_opacity= 0.5,
fill_color="green"
)
m.add_layer(polygon);
m
Result:
I have 6 corner points coordinate of 3d surface like Figure 1. I want to generate and plot 3d surface like Figure 2. I need to find the distance of midpoint of each meshed area from the origin.
Figure 1
Figure 2
Please suggest me, which module will be better for meshing and also for plotting?
PyVista and vtkplotter are very similar and both are built on top of VTK but have pretty different APIs/design choices. For your use, either would be great! Here is the equivalent with PyVista for completeness.
Typically with simple geometries like this, Matplotlib, PyVista, or vtkplotter would all do well. If you start to create more sophisticated meshes and 3D scenes, then that's where PyVista and vtkplotter will excel as they are built for 3D while MPL is really awesome at 2D.
PyVista will especially excel at data management if you start making complex meshes.... shameless plug ;)
import pyvista as pv
import numpy as np
# Define the nodes
pts = np.array([(-5.795555, -4, 1.55291), (-4.829629, -2, 1.294095),
(-5.795555, 1, 1.552914), (-5.536736, -4, 2.51884),
(-4.57081, -2, 2.260021), (-5.536736, 1, 2.51884)])
# Define the quads
faces = np.array([(4,0,3,4,1), (4,1,4,5,2)])
# Instantiate a mesh
mesh = pv.PolyData(pts, faces)
# Create a plotting window and display!
p = pv.Plotter()
# Add the mesh and some labels
p.add_mesh(mesh, show_edges=True)
p.add_point_labels(mesh.points, ["%d"%i for i in range(mesh.n_points)])
# A pretty view position
p.camera_position = [(-11.352247399703748, -3.421477319390501, 9.827830270231935),
(-5.1831825, -1.5, 1.9064675),
(-0.48313206526616853, 0.8593146723923926, -0.16781448484204659)]
# Render it!
p.show()
You can use vedo:
from vedo import *
pts = [(-5.795555, -4, 1.55291), (-4.829629, -2, 1.294095),
(-5.795555, 1, 1.552914), (-5.536736, -4, 2.51884),
(-4.57081, -2, 2.260021), (-5.536736, 1, 2.51884)]
faces = [(0,3,4,1), (1,4,5,2)]
mesh = Mesh([pts, faces]).color('red').alpha(0.3).lineWidth(2)
labels = [Text(i, pos=pts[i], s=.2, c='k') for i in range(len(pts))]
show(mesh, labels)
I don't know what your data looks like, but matplotlib is capable of plotting 3D surfaces based on points with x, y and z coordinates.
See: https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
I had x,y,height vars to build a contour in python.
I created a Triangulation grid using
x,y,height and traing are numpy arrays
tri = Tri.Triangulation(x, y, triang)
then i did a contour using tricontourf
tricontourf(tri,height)
how can i get the output of the tricontourf into a numpy array. I can display the image using pyplot but I dont want to.
when I tried this:
triout = tricontourf(tri,height)
print triout
I got:
<matplotlib.tri.tricontour.TriContourSet instance at 0xa9ab66c>
I need to get the image data and if I could get numpy array its easy for me.
Is it possible to do this?
if its not possible can I do what tricontourf does without matplotlib in python?
You should try this :
cs = tricontourf(tri,height)
for collection in cs.collections:
for path in collection.get_paths():
print path.to_polygons()
as I learned on:
https://github.com/matplotlib/matplotlib/issues/367
(it is better to use path.to_polygons() )