Finding intersection points between .stl (CAD drawing) file and 3D plot (matplotlib)?

1.8k views Asked by At

I am trying to find intersection points between 3d object .stl file (that I imported to python using numpy-stl) and 3d plot(that I generated using matplotlib). The 3d object is a cad drawing and 3d plot is a bunch of curves in 3d. I can plot them on the same figure but I have no idea how I can find intersection points between the trajectory and the drawing. My idea was to convert the curve into .stl using save() function from the numpy-stl module after plotting it and show them together on a cad application like freeCAD together and find intersection using the application's functionality. But it does not work as simple because the plots are point based and .stl is triangle based. If anyone has any advice on how to approach this problem, please let me know!!

Here is the code to plot both .stl object and the 3d plot. This is what I have so far.

#allInitialE is 1D list, allX, allY, allZ are all 2D lists

from stl import mesh
from numpy import *
from mpl_toolkits import mplot3d
from matplotlib import pyplot as plt

fig = plt.figure()
ax = plt.axes(projection = '3d')       
your_mesh = mesh.Mesh.from_file('fileName.stl')
your_mesh.translate([0,7,0])
ax.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))
ax.view_init(azim = -90, elev = 0)

maxE = max(allInitialE)

ax.set_xlabel('x axis (m)')   # y and z are flipped to make it easier for me to visualize
ax.set_ylabel('z axix (m)')
ax.set_zlabel('y axix (m)')
plt.title('Particle Trajectory')
for k in range(numParticles):  #iterate through each of the particles' xyz data 
    e = allInitialE[k]
    if e < maxE/3:
        ax.plot3D(allX[k], allZ[k], allY[k], 'g-')
    elif e < maxE/2:
        ax.plot3D(allX[k], allZ[k], allY[k], 'b-')
    else:
        ax.plot3D(allX[k], allZ[k], allY[k], 'r-')

plt.show()

1 idea: Is there any way to convert .stl object to a set of plane functions? If so, I could make the plots into lines and find intersection between the plane and the line?

2nd idea: Or, since .stl are vector based, I can use vector calculation? i.e. see if a vector on a curve (line segment) has a common point as a triangle on a .stl object (triangle is defined by three vectors).

Please give me any idea you may have! Thank you so much.

2

There are 2 answers

0
ferdymercury On

Another way might be to use VTK. You can convert your numpy-stl object (obj) to a vtkPolyData

import vedo
import vtk
import itertools
obj = your_mesh
verts = list(itertools.chain(*(obj.vectors)))
faces = [[i*3, i*3+1, i*3+2] for i in range(len(verts)//3)]
vpoly = vedo.Mesh([verts, faces]).clean().polydata()

Then you could use vtkCutter https://discourse.vtk.org/t/get-intersection-of-polydata-line-and-a-plane/3894/3 or vtkIntersectionPolyDataFilter VTK check polydata point objects for intersection

Concerning your 1st idea, yes, you can convert your STL file into a set of triangles, just check out:

your_mesh.vectors

which is an array of triangle 3D vertices. From those you can construct a plane, and then calculate intersection between segment and plane.

Concerning the 2nd idea, you could do that only if your trajectory crosses exactly to a vertex, otherwise it would not detect the intersection. (Or you would need to give it a margin).

0
Sara S On

I found a way using pyoctree, which has a function to find intersection between line segments and mesh. Here is the link: https://pypi.org/project/pyoctree/

I was able to use rayIntersection() to do what I wanted to do, really quick. This Intersection between line and triangle in 3D also helped, but the calculation was very slow when it dealt with 60K+ points in a curve.