# ============================================================================
# CC0 "No Rights Reserved"
# To the extent possible under law, the author(s) have dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. See http://creativecommons.org/publicdomain/zero/1.0/.
# ============================================================================

# Maps an origin-centered cube to a sphere with improved element uniformity.
# Select nodes before using.


import math


# fx calculates the x-coordinate of the surface
def fx(r, s, t):
    return r * math.sqrt(1.0 - s ** 2 / 2.0 - t ** 2 / 2.0 + s ** 2 * t ** 2 / 3.0)


# fy calculates the y-coordinate of the surface
def fy(r, s, t):
    return s * math.sqrt(1.0 - r ** 2 / 2.0 - t ** 2 / 2.0 + r ** 2 * t ** 2 / 3.0)


# fz calculates the z-coordinate of the surface
def fz(r, s, t):
    return t * math.sqrt(1.0 - r ** 2 / 2.0 - s ** 2 / 2.0 + r ** 2 * s ** 2 / 3.0)


for node_id in mw.selected_nodes():
    coord = mw.node(node_id)
    r = coord.x
    s = coord.y
    t = coord.z

    scale = max(abs(r), abs(s), abs(t))

    r /= scale
    s /= scale
    t /= scale

    mw.set_node_x(node_id, scale * fx(r, s, t))
    mw.set_node_y(node_id, scale * fy(r, s, t))
    mw.set_node_z(node_id, scale * fz(r, s, t))
