title: How to use vtkOBBTree and IntersectWithLine to find the intersection of a line and a PolyDataFilter in python using vtk?
body: <p>I have an oriented cylinder generated with <code>vtkCylinderSource</code> and some transformations are applied on it to get the orientation that i want. Here is the code for creating this oriented-cylinder:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Now i want to ray cast a line with this oriented cylinder. unfortunately, using the vtkCylinderSource as the dataset for vtkOBBTree produces the wrong points as the result. how can i use ray-casting with a PolyDataFilter?</p>
  
  <p>I came up with a solution where i export my oriented-cylinder to a <code>.stl</code> file and then read it again to implement the ray-casting algorithm using <code>IntersectWithLine</code>. The problem is i have thousands of these oriented-cylinders and this method (exporting and reading) makes my code extremely slow.</p>
  
  <pre><code>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 --&gt; 0 : No intersection.
      :return: code --&gt; +1 : p_source lies OUTSIDE the closed surface.
      :return; code --&gt; -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
  </code></pre>
  
  <p>Below image shows the desired result using export-stl method. (the green spheres are intersection points)
  <a href="https://i.stack.imgur.com/EV8mb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EV8mb.png" alt="Desired result"></a></p>
  
  <p>I would appreciate any suggestion and help..</p>