代码之家  ›  专栏  ›  技术社区  ›  Stéphane Laurent

如何平滑pyvista。结构网格?

  •  0
  • Stéphane Laurent  · 技术社区  · 4 年前

    下面是一个用Python和PyVista制作的Hopf圆环:

    enter image description here

    import numpy as np
    import pyvista as pv
    
    A = 0.44
    n = 3
    def Gamma(t):
        alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
        beta = t + A*np.sin(2*n*t)
        return np.array([
          np.sin(alpha) * np.cos(beta),
          np.sin(alpha) * np.sin(beta),
          np.cos(alpha)
        ])
    
    def HopfInverse(p, phi):
        return np.array([
          (1+p[2])*np.cos(phi),
          p[0]*np.sin(phi) - p[1]*np.cos(phi), 
          p[0]*np.cos(phi) + p[1]*np.sin(phi),
          (1+p[2])*np.sin(phi)
        ]) / np.sqrt(2*(1+p[2]))
    
    def Stereo(q):
        return 2*q[0:3] / (1-q[3])
    
    def F(t, phi):
        return Stereo(HopfInverse(Gamma(t), phi))
    
    angle = np.linspace(0, 2 * np.pi, 300)
    theta, phi = np.meshgrid(angle, angle)
    x, y, z = F(theta, phi)
    
    # Display the mesh
    grid = pv.StructuredGrid(x, y, z)
    grid.plot(smooth_shading=True)
    

    颜色并非完全平滑:在右下角的叶上,你可以看到一条线,将浅灰色和深灰色分开。如何摆脱这条线?

    0 回复  |  直到 4 年前
        1
  •  1
  •   Andras Deak -- Слава Україні    4 年前

    我认为这里的情况是,在结构化网格的两端交汇处没有连通性信息。解决这个问题的一个方法是把你的网格变成一个 PolyData 使用 extract_geometry() 方法,然后使用 clean 具有更大的容忍度。这将迫使pyvista意识到网格中有一个接缝,其中点加倍,导致点合并,接缝闭合:

    import numpy as np
    import pyvista as pv
    
    A = 0.44
    n = 3
    def Gamma(t):
        alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
        beta = t + A*np.sin(2*n*t)
        return np.array([
          np.sin(alpha) * np.cos(beta),
          np.sin(alpha) * np.sin(beta),
          np.cos(alpha)
        ])
    
    def HopfInverse(p, phi):
        return np.array([
          (1+p[2])*np.cos(phi),
          p[0]*np.sin(phi) - p[1]*np.cos(phi), 
          p[0]*np.cos(phi) + p[1]*np.sin(phi),
          (1+p[2])*np.sin(phi)
        ]) / np.sqrt(2*(1+p[2]))
    
    def Stereo(q):
        return 2*q[0:3] / (1-q[3])
    
    def F(t, phi):
        return Stereo(HopfInverse(Gamma(t), phi))
    
    angle = np.linspace(0, 2 * np.pi, 300)
    theta, phi = np.meshgrid(angle, angle)
    x, y, z = F(theta, phi)
    
    # Display the mesh, show seam
    grid = pv.StructuredGrid(x, y, z)
    grid.plot(smooth_shading=True)
    
    # convert to PolyData and clean to remove the seam
    cleaned_poly = grid.extract_geometry().clean(tolerance=1e-6)
    cleaned_poly.plot(smooth_shading=True)
    

    nice Hopf torus figure with no seam

    你的里程数 tolerance 参数可能会有所不同。

    作为一件琐事,我们可以通过提取原始网格的特征边来可视化原始接缝:

    grid.extract_feature_edges().plot()
    

    Plot showing a circle and a clover-shaped curve at the edges of the toroidal dataset

    这些曲线对应于原始栅格中的开放边:

    >>> grid.extract_surface().n_open_edges
    1196
    

    由于曲面是封闭且防水的,因此它应具有0个开放边:

    >>> cleaned_poly.n_open_edges
    0
    
    推荐文章