Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrap vtkParametricSuperToroid class #213

Closed
banesullivan opened this issue May 13, 2019 · 4 comments
Closed

wrap vtkParametricSuperToroid class #213

banesullivan opened this issue May 13, 2019 · 4 comments
Assignees
Labels
feature-request Please add this cool feature!

Comments

@banesullivan
Copy link
Member

banesullivan commented May 13, 2019

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

@banesullivan banesullivan changed the title How to plot supertorus or toroid surface wrap vtkParametricSuperToroid class May 14, 2019
@banesullivan banesullivan added the feature-request Please add this cool feature! label May 14, 2019
@wawosz
Copy link

wawosz commented May 20, 2019

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

@akaszynski
Copy link
Member

akaszynski commented May 20, 2019

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

@banesullivan
Copy link
Member Author

Thanks @akaszynski!

Should we add this in the geometric_objects module?

@akaszynski
Copy link
Member

Added in #225

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Please add this cool feature!
Projects
None yet
Development

No branches or pull requests

3 participants