VTK에는 내가 원하는 Surface of Revolution API가 없습니다.
vtkRotationalExtrusionFilter라는 클래스가 있지만 원하는 결과를 만들어 주지 않았습니다.
그렇게 원하는 API를 찾아봤는데 찾지 못했기 때문에 그 기능을 직접 구현하기로 했습니다.
먼저 회전시킬 곡선(Profile)을 생성합니다.
Profile을 회전 축을 기준으로 Resolution만큼 회전시키면서 곡선들을 만들어 냅니다.
- # create a profile
- circle = vtk.vtkRegularPolygonSource()
- circle.SetCenter((pt1[0] - self._origin[0], pt1[1] - self._origin[1], pt1[2] - self._origin[2]))
- circle.SetNormal((pt1[0] - center[0], pt1[1] - center[1], pt1[2] - center[2]))
- circle.SetRadius(radius)
- circle.SetNumberOfSides(24)
- circle.Update()
- circle_points = circle.GetOutput().GetPoints() # get points from profile
- del circle
- # Setup points and lines
- points = vtk.vtkPoints()
- points.Allocate((self._resolution + 1) * circle_points.GetNumberOfPoints())
- faces = vtk.vtkCellArray()
- faces.SetNumberOfCells(self._resolution * circle_points.GetNumberOfPoints())
- lines = vtk.vtkCellArray()
- num = circle_points.GetNumberOfPoints()
- for idx in range(num):
- points.InsertNextPoint(circle_points.GetPoint(idx))
- if idx < num - 1:
- line = vtk.vtkLine()
- line.GetPointIds().SetId(0, idx)
- line.GetPointIds().SetId(1, idx + 1)
- lines.InsertNextCell(line)
- else:
- line = vtk.vtkLine()
- line.GetPointIds().SetId(0, idx)
- line.GetPointIds().SetId(1, 0)
- lines.InsertNextCell(line)
- appended_polydata = vtk.vtkAppendPolyData()
- polydata = vtk.vtkPolyData()
- polydata.SetPoints(circle_points)
- polydata.SetLines(lines)
- appended_polydata.AddInputData(polydata)
- # 축 벡터 구하기
- vectors = [(center[0] - pt1[0], center[1] - pt1[1], center[2] - pt1[2]),
- (pt2[0] - pt1[0], pt2[1] - pt1[1], pt2[2] - pt1[2])]
- normal = [0, 0, 0]
- vtk.vtkMath.Cross(vectors[0], vectors[1], normal)
- vtk.vtkMath.Normalize(normal)
- # rotate about normal vector
- transform = vtk.vtkTransform()
- transform.Identity()
- transform.RotateWXYZ(angle/self._resolution, normal[0], normal[1], normal[2])
- for idx in range(self._resolution):
- transform_filter = vtk.vtkTransformPolyDataFilter()
- transform_filter.SetInputData(polydata)
- transform_filter.SetTransform(transform)
- transform_filter.Update()
- polydata = transform_filter.GetOutput()
- for idx_ in range(num):
- points.InsertNextPoint(polydata.GetPoint(idx_))
- appended_polydata.AddInputData(polydata)
- appended_polydata.Update()
- for v in range(self._resolution):
- for u in range(circle_points.GetNumberOfPoints()):
- faces.InsertNextCell(4, [v*circle_points.GetNumberOfPoints() + u,
- v*circle_points.GetNumberOfPoints() + (u + 1) % circle_points.GetNumberOfPoints(),
- (v + 1)*circle_points.GetNumberOfPoints() + (u + 1) % circle_points.GetNumberOfPoints(),
- (v + 1)*circle_points.GetNumberOfPoints() + u])
- output = vtk.vtkPolyData()
- output.SetPoints(points)
- output.SetPolys(faces)
댓글
댓글 쓰기