gpt4 book ai didi

python - 如何使用 vtkOBBTree 和 IntersectWithLine 在 python 中使用 vtk 查找直线和 PolyDataFilter 的交集?

转载 作者:行者123 更新时间:2023-12-01 07:34:26 26 4
gpt4 key购买 nike

我有一个使用 vtkCylinderSource 生成的定向圆柱体,并对其应用了一些转换以获得我想要的方向。下面是创建这个定向圆柱体的代码:

def cylinder_object(startPoint, endPoint, radius, my_color="DarkRed", opacity=1):
colors = vtk.vtkNamedColors()

# Create a cylinder.
# Cylinder height vector is (0,1,0).
# Cylinder center is in the middle of the cylinder
cylinderSource = vtk.vtkCylinderSource()
cylinderSource.SetRadius(radius)
cylinderSource.SetResolution(50)

# Generate a random start and end point
# startPoint = [0] * 3
# endPoint = [0] * 3

rng = vtk.vtkMinimalStandardRandomSequence()
rng.SetSeed(8775070) # For testing.8775070

# Compute a basis
normalizedX = [0] * 3
normalizedY = [0] * 3
normalizedZ = [0] * 3

# The X axis is a vector from start to end
vtk.vtkMath.Subtract(endPoint, startPoint, normalizedX)
length = vtk.vtkMath.Norm(normalizedX)
vtk.vtkMath.Normalize(normalizedX)

# The Z axis is an arbitrary vector cross X
arbitrary = [0] * 3
for i in range(0, 3):
rng.Next()
arbitrary[i] = rng.GetRangeValue(-10, 10)
vtk.vtkMath.Cross(normalizedX, arbitrary, normalizedZ)
vtk.vtkMath.Normalize(normalizedZ)

# The Y axis is Z cross X
vtk.vtkMath.Cross(normalizedZ, normalizedX, normalizedY)
matrix = vtk.vtkMatrix4x4()
# Create the direction cosine matrix
matrix.Identity()
for i in range(0, 3):
matrix.SetElement(i, 0, normalizedX[i])
matrix.SetElement(i, 1, normalizedY[i])
matrix.SetElement(i, 2, normalizedZ[i])
# Apply the transforms
transform = vtk.vtkTransform()
transform.Translate(startPoint) # translate to starting point
transform.Concatenate(matrix) # apply direction cosines
transform.RotateZ(-90.0) # align cylinder to x axis
transform.Scale(1.0, length, 1.0) # scale along the height vector
transform.Translate(0, .5, 0) # translate to start of cylinder

# Transform the polydata
transformPD = vtk.vtkTransformPolyDataFilter()
transformPD.SetTransform(transform)
transformPD.SetInputConnection(cylinderSource.GetOutputPort())

cylinderSource.Update()

# Create a mapper and actor for the arrow
mapper = vtk.vtkPolyDataMapper()
actor = vtk.vtkActor()
if USER_MATRIX:
mapper.SetInputConnection(cylinderSource.GetOutputPort())
actor.SetUserMatrix(transform.GetMatrix())
else:
mapper.SetInputConnection(transformPD.GetOutputPort())
actor.SetMapper(mapper)
actor.GetProperty().SetColor(colors.GetColor3d(my_color))
actor.GetProperty().SetOpacity(opacity)
return actor, transformPD

现在我想用这个定向圆柱体射线转换一条线。不幸的是,使用 vtkCylinderSource 作为 vtkOBBTree 的数据集会产生错误的点。如何将光线转换与 PolyDataFilter 一起使用?

我想出了一个解决方案,将定向圆柱导出到 .STL 文件,然后再次读取该文件以使用 IntersectWithLine 实现光线转换算法。问题是我有数千个这样的定向圆柱体,这种方法(导出和读取)使我的代码非常慢。

def ray_cast(filename, p_source, p_target):
'''

:param filename: STL file to perform ray casting on.
:param p_source: first point
:param p_target: second point
:return: code --> 0 : No intersection.
:return: code --> +1 : p_source lies OUTSIDE the closed surface.
:return; code --> -1 : p_source lies INSIDE closed surface

'''

reader = vtk.vtkSTLReader()
reader.SetFileName(filename)
reader.Update()
mesh = reader.GetOutput()


obbtree = vtk.vtkOBBTree()
obbtree.SetDataSet(mesh)
obbtree.BuildLocator()

pointsVTKIntersection = vtk.vtkPoints()
code = obbtree.IntersectWithLine(p_source, p_target, pointsVTKIntersection, None)
# Extracting data
pointsVTKIntersectionData = pointsVTKIntersection.GetData()
noPointsVTKIntersection = pointsVTKIntersectionData.GetNumberOfTuples()
pointsIntersection = []

for idx in range(noPointsVTKIntersection):
_tup = pointsVTKIntersectionData.GetTuple3(idx)
pointsIntersection.append(_tup)

return code, pointsIntersection, noPointsVTKIntersection

下图显示了使用export-STL方法所需的结果。 (绿色球体是交点) Desired result

我将不胜感激任何建议和帮助..

最佳答案

vedo :

from vedo import *

cyl = Cylinder() # vtkActor

cyl.alpha(0.5).pos(3,3,3).orientation([2,1,1])

p1, p2 = (0,0,0), (4,4,5)

ipts_coords = cyl.intersectWithLine(p1, p2)
print('hit coords are', ipts_coords)

pts = Points(ipts_coords, r=10).color("yellow")
# print(pts.polydata()) # is the vtkPolyData object

origin = Point()
ln = Line(p1,p2)

show(origin, cyl, ln, pts, axes=True)

enter image description here

关于python - 如何使用 vtkOBBTree 和 IntersectWithLine 在 python 中使用 vtk 查找直线和 PolyDataFilter 的交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57058089/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com