如何在不翻译的情况下在 vtk 中缩放 PolyData?

How to scale a PolyData in vtk without translating it?

我在 python 中使用 VTK 导入 .stl 文件。那么我想做的就是在不改变方向矩阵的情况下缩小网格并使其变小。

我尝试 vtkTransform 使用缩放元组,但问题是缩放的多数据正在旋转。

代码如下:

def scaleSTL(filenameSTL, opacity=0.75, scale=(1,1,1), mesh_color="gold"):
    colors = vtk.vtkNamedColors()

    reader = vtk.vtkSTLReader()
    reader.SetFileName(filenameSTL)
    reader.Update()

    transform = vtk.vtkTransform()
    transform.Scale(scale)

    transformFilter = vtk.vtkTransformPolyDataFilter()
    transformFilter.SetInputConnection(reader.GetOutputPort())
    transformFilter.SetTransform(transform)
    transformFilter.Update()

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(transformFilter.GetOutputPort())

    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(colors.GetColor3d(mesh_color))
    actor.GetProperty().SetOpacity(opacity)

    return actor

def render_scene(my_actor_list):
    renderer = vtk.vtkRenderer()
    for arg in my_actor_list:
        renderer.AddActor(arg)
    namedColors = vtk.vtkNamedColors()
    renderer.SetBackground(namedColors.GetColor3d("SlateGray"))

    window = vtk.vtkRenderWindow()
    window.SetWindowName("Oriented Cylinder")
    window.AddRenderer(renderer)

    interactor = vtk.vtkRenderWindowInteractor()
    interactor.SetRenderWindow(window)

    # Visualize
    window.Render()
    interactor.Start()

if __name__ == "__Main__":

    filename = "400_tri.stl"
    scale01 = (1, 1, 1)
    scale02 = (0.5, 0.5, 0.5)
    my_list = []
    my_list.append(scaleSTL(filename, 0.75, scale01, "Gold"))
    my_list.append(scaleSTL(filename, 0.75, scale02, "DarkGreen"))
    render_scene(my_list)

我使用了我的网格文件 kidney.stl(黄色文件),但我得到的是缩放和旋转的网格。我将不透明度设置为 0.75 以查看两个网格。在下图中,您可以看到绿色的完全移动了,但我想缩放绿色的完全在原来的黄色网格内。

可以在这里找到简单的答案(没有解释):Scaling 3D models, finding the origin

这是因为缩放变换被简单地定义为将坐标乘以给定因子(参见 https://www.tutorialspoint.com/computer_graphics/3d_transformation.htm)。这本质上意味着它是相对于某个参考点完成的。您的 transform.Scale() 调用将使用原点 (0,0,0) 作为参考点,并且由于您的对象显然不以原点为中心,因此您会得到平移(不是您声称的旋转)。

要获得局部居中缩放,您需要在要围绕其缩放的对象上选择一个参考点 R(在您的情况下,由于您希望缩放后的对象位于原始对象内部,因此您需要某种中心 - 因为对象是 "almost convex",质心 - 所有点的平均值 - 可能就足够了)。通过 -R 平移对象以使其与坐标系对齐,缩放然后通过 +R 平移回来。

尝试一个小练习来形象化:简单的二维示例 - 给自己画一个由坐标为 (2,2)、(2,3)、(3,3)、(3,2) 和"scale it by 2" - 你得到 (4,4), (4,6),(6,6), (6,4) - 也绘制它。现在尝试替代方案 - 首先通过正方形的中心 (2.5,2.5) 平移,你得到 (-0.5,-0.5), (-0.5,0.5), (0.5,0.5), (0.5,-0.5) (画出来) , 按二缩放,你得到 (-1,-1), (-1, 1), (1,1), (1,-1) (draw) 最后平移 2.5: (1.5, 1.5), (1.5,3.5), (3.5,3.5), (3.5, 1.5) 和绘制 - 看出区别了吗?