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
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')

Thanks @akaszynski!
Should we add this in the geometric_objects module?
Added in #225
Most helpful comment
Added in #225