简体   繁体   English

如何在vtk中缩放PolyData而不转换它?

[英]How to scale a PolyData in vtk without translating it?

I am using VTK in python to import .stl files. 我在python中使用VTK导入.stl文件。 then what i want to do is to scale down the mesh and making it smaller without changing the orientation matrix. 那么我想做的就是缩小网格并使其更小而不更改方向矩阵。

I tried vtkTransform with a scale tuple but the problem is the scaled polydata is getting rotated. 我尝试使用带有刻度元组的vtkTransform ,但问题是缩放的多数据正在旋转。

Here is the code: 这是代码:

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)

I used my mesh file kidney.stl (yellow one) but what i getting is the scaled and rotated mesh. 我使用了我的网格文件kidney.stl (黄色),但我得到的是缩放和旋转的网格。 i set opacity to 0.75 to see both meshes. 我将不透明度设置为0.75,以查看两个网格。 In the picture below you can see that the green one is completely moved but i want to scale so the green one is completely inside the original yellow mesh. 在下面的图片中,您可以看到绿色的网格已完全移动,但是我要缩放,因此绿色的网格完全在原始的黄色网格内。

以上代码结果

Simple answer (no explanation) can be found here: Scaling 3D models, finding the origin 可以在此处找到简单答案(无解释): 缩放3D模型,找到起点

That is because the scaling transformation is defined simply as multiplying the coordinates by a given factor (see eg https://www.tutorialspoint.com/computer_graphics/3d_transformation.htm ). 那是因为缩放变换被简单地定义为将坐标乘以给定的因子(例如,参见https://www.tutorialspoint.com/computer_graphics/3d_transformation.htm )。 This intrinsically means that it is done with respect to a certain reference point. 从本质上讲,这是相对于某个参考点完成的。 Your transform.Scale() call will use the origin (0,0,0) as this reference point and since your object is apparently not centered around origin, you get the translation (not rotation as you claim btw). 您的transform.Scale()调用将使用原点(0,0,0)作为该参考点,并且由于您的对象显然不在原点中心,因此可以得到平移(而不是声称btw为旋转)。

To get a locally centered scaling, you need to choose a reference point R on your object around which you want to scale (in your case, since you want the scaled object to be inside the original, you want some kind of center - since the object is "almost convex", centroid - average of all points - could be good enough). 要获得局部居中的缩放比例,您需要在要缩放的对象上选择参考点R(在这种情况下,由于您希望缩放后的对象位于原始对象之内,因此您需要某种中心-对象是“几乎是凸的”,质心-所有点的平均值-可能足够好)。 Translate the object by -R to align it with the coordinate system, scale and then translate back by +R. 用-R平移对象以使其与坐标系对齐,缩放,然后再按+ R平移。

Try a little exercise to visualize this: simple 2D example - draw yourself a square made of points with coordinates (2,2), (2,3), (3,3), (3,2) and "scale it by 2" - you get (4,4), (4,6),(6,6), (6,4) - draw it as well. 尝试一下练习以直观地看到这一点:简单的2D示例-自己绘制一个由坐标为(2,2),(2,3),(3,3),(3,2)的点组成的正方形,然后“按2 “-您得到(4,4),(4,6),(6,6),(6,4)-也画出它。 Now try the alternative - first translate by the square's center (2.5,2.5), you get (-0.5,-0.5), (-0.5,0.5), (0.5,0.5), (0.5,-0.5) (draw it), scale by two, you get (-1,-1), (-1, 1), (1,1), (1,-1) (draw) and finally translate back by 2.5: (1.5, 1.5), (1.5,3.5), (3.5,3.5), (3.5, 1.5) and draw - see the difference? 现在尝试替代方法-首先通过正方形的中心(2.5,2.5)进行平移,您会得到(-0.5,-0.5),(-0.5,0.5),(0.5,0.5),(0.5,-0.5)(将其绘制) ,按2的比例缩放,则得到(-1,-1),(-1、1),(1,1),(1,-1)(绘制),最后平移2.5:(1.5,1.5), (1.5,3.5),(3.5,3.5),(3.5、1.5)和平局-看到区别了吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM