Pyvista: wrap vtkParametricSuperToroid class

Created on 13 May 2019  路  4Comments  路  Source: pyvista/pyvista

See stack overflow question: https://stackoverflow.com/questions/55895808/how-to-plot-supertorus-or-toroid-surface-in-vtki

We'll need to make sure this person knows we've change the name of the software

this is related to efforts in #202 and #42

feature-request

Most helpful comment

Added in #225

All 4 comments

I am the author of stack overflow question (https://stackoverflow.com/questions/55895808/how-to-plot-supertorus-or-toroid-surface-in-vtki) and I am interested in using parametric surfaces with PyVista (former vtki). Because vtkParametricSuperToroid class is not wrapped within PyVista, I found another solution and used vista.StructuredGrid class to define supertoroidal surfaces. I created a function supertorus and used it to plot supertoroidal surfaces with PyVista vista.add_mesh(). However, I believe that wrapping vtkParametricSuperToroid class within PyVista will be more efficient.

import pyvista
import numpy as np

def supertorus(yScale, xScale, Height, InternalRadius, Vertical, Horizontal):
    #  initial range for values used in parametric equation
    n = 100
    u = np.linspace(-np.pi, np.pi, n)
    t = np.linspace(-np.pi, np.pi, n)
    u, t = np.meshgrid(u, t)

    # a1: Y Scale <0, 2>
    a1 = yScale
    # a2: X Scale <0, 2>
    a2 = xScale
    # a3: Height <0, 5>
    a3 = Height
    # a4: Internal radius <0, 5>
    a4 = InternalRadius
    # e1: Vertical squareness <0.25, 1>
    e1 = Vertical
    # e2: Horizontal squareness <0.25, 1>
    e2 = Horizontal

    # Definition of parametric equation for supertorus
    x = a1 * (a4 + np.sign(np.cos(u)) * np.abs(np.cos(u)) ** e1) *\
        np.sign(np.cos(t)) * np.abs(np.cos(t)) ** e2
    y = a2 * (a4 + np.sign(np.cos(u)) * np.abs(np.cos(u)) ** e1) *\
        np.sign(np.sin(t)) * np.abs(np.sin(t)) ** e2
    z = a3 * np.sign(np.sin(u)) * np.abs(np.sin(u)) ** e1

    grid = pyvista.StructuredGrid(x, y, z)
    return grid

I'll be adding this to pyvista soon. For the moment, use the code below:

import vtk
import pyvista
from math import pi

def SuperToroid(ring_radius=1.0, cross_section_radius=0.5,
                x_radius=1.0, y_radius=1.0, z_radius=1.0, n_1=1.0,
                n_2=1.0, min_u=0, max_u=2*pi, min_v=0.0, max_v=2*pi,
                u_res=100, v_res=100, w_res=100, join_u=False,
                join_v=False, twist_u=False, twist_v=False,
                clockwise=True):
    """Construct a supertoroid and return a mesh.

    Essentially a supertoroid is a torus with the sine and cosine
    terms raised to a power. A supertoroid is a versatile primitive
    that is controlled by four parameters r0, r1, n1 and n2. r0, r1
    determine the type of torus whilst the value of n1 determines the
    shape of the torus ring and n2 determines the shape of the cross
    section of the ring. It is the different values of these powers
    which give rise to a family of 3D shapes that are all basically
    toroidal in shape.

    Parameters
    ----------
    ring_radius : float
        The radius from the center to the middle of the ring of the
        supertoroid.

    cross_section_radius = 0.5
        The radius of the cross section of ring of the supertoroid.

    x_radius : float, optional
        Radius in the x direction.

    y_radius : float, optional
        Radius in the y direction.

    z_radius : float, optional
        Radius in the z direction.

    n_1 : float
        Controls shape of torus ring.

    n_2 = 1
        Controls shape of cross section of the ring.

    min_u : float, optional
        The minimum u-value.

    max_u : float, optional
        The maximum u-value.

    min_v : float, optional
        The minimum v-value.

    max_v : float, optional
        The maximum v-value.

    u_res : int, optional
        Resol

    join_u : bool, optional
        Joins the first triangle strip to the last one with a twist in
        the u direction.

    join_v : bool, optional
        joins the first triangle strip to the last one with a twist in
        the v direction.

    twist_u : bool, optional
        Joins the first triangle strip to the last one with a twist in
        the u direction.

    twist_v : bool, optional
        Joins the first triangle strip to the last one with a twist in
        the v direction.

    clockwise : bool
        Determines the ordering of the vertices forming the triangle
        strips.

    Notes
    -----
    Care needs to be taken specifying the bounds correctly. You may
    need to carefully adjust MinimumU, MinimumV, MaximumU, MaximumV.

    Examples
    --------
    Create default supertorid
    >>> import pyvista
    >>> mesh = pyvista.SuperToroid()
    >>> mesh.plot(color='w')

    Alternative supertorid
    >>> mesh = pyvista.SuperToroid(n_1=1, n_2=2)
    """
    # create parametric supertorus
    supertorus = vtk.vtkParametricSuperToroid()
    supertorus.SetMinimumU(min_u)
    supertorus.SetMaximumU(max_u)
    supertorus.SetMinimumV(min_v)
    supertorus.SetMaximumV(max_v)
    supertorus.SetJoinU(join_u)
    supertorus.SetJoinV(join_v)
    supertorus.SetTwistU(twist_u)
    supertorus.SetTwistV(twist_v)
    supertorus.SetClockwiseOrdering(clockwise)
    supertorus.SetRingRadius(ring_radius)
    supertorus.SetCrossSectionRadius(cross_section_radius)
    supertorus.SetXRadius(x_radius)
    supertorus.SetYRadius(y_radius)
    supertorus.SetZRadius(z_radius)
    supertorus.SetN1(n_1)
    supertorus.SetN2(n_2)

    # convert to a mesh
    para_source = vtk.vtkParametricFunctionSource()
    para_source.SetParametricFunction(supertorus)
    para_source.SetUResolution(u_res)
    para_source.SetVResolution(v_res)
    para_source.SetWResolution(w_res)
    para_source.Update()
    return pyvista.wrap(para_source.GetOutput())


SuperToroid().plot(color='w')

tmp

Thanks @akaszynski!

Should we add this in the geometric_objects module?

Added in #225

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KeunwooPark picture KeunwooPark  路  4Comments

tinebryder picture tinebryder  路  4Comments

banesullivan picture banesullivan  路  3Comments

wangfudong picture wangfudong  路  3Comments

tkoyama010 picture tkoyama010  路  3Comments