Geodesic Sphere with UI

You can go and put this in your self as a python button straight away.

The geo sphere contains a perfect flat horizontal edge loop on the XZ plane, this means that you can take only half the sphere as a nice dome with a flat border edge.

from maya import mel
from maya.OpenMaya import *
from maya import cmds


def makegeosphere(in_divisions, in_radius):
    if in_divisions == 1 :
        return cmds.polyPlatonicSolid(r=in_radius,st=2,cuv=4,ch=False)
    elif in_divisions >= 2:
        out_obj = cmds.polyPlatonicSolid(r=in_radius,st=1,cuv=4,ch=False)
        out_obj = cmds.ls(out_obj,l=True)[0]
        cmds.xform(out_obj,ro=[0,0,31.717])
        cmds.makeIdentity(out_obj,apply=True)
        if in_divisions > 2:
            #linear smooth gives instant right topology, but deforms
            #the lines to be curved so we can't have nice domes
            #AND is actually (although by 5 to -1 milisecond on 6 divisions) slower than this method
            for i in range(3,in_divisions,1):
                nf = cmds.polyEvaluate(out_obj,face=True)
                cmds.polySmooth(out_obj, mth=0, dv=1, c=0, ch=False)
                nvtx = cmds.polyEvaluate(out_obj,vertex=True)
                cmds.select('%s.vtx[%s:%s]'%(out_obj, nvtx-nf, nvtx))
                mel.eval('DeleteVertex;')
                cmds.polyTriangulate(out_obj)
        li = MSelectionList()
        MGlobal.getSelectionListByName(out_obj, li)
        path = MDagPath()
        li.getDagPath(0, path)
        iter = MItMeshVertex(path)
        mesh = MFnMesh(path)
        while not iter.isDone():            
            #defaults to object space
            point = iter.position()
            mesh.setPoint( iter.index(), MPoint( MVector(point).normal()*in_radius ) )
            iter.next()
        cmds.select(out_obj)
        return out_obj

w = cmds.window(title='GeoSphere Creator')
cmds.columnLayout()
cmds.rowLayout(nc=2)
ds = cmds.intSliderGrp(label='Divisions', field=True, fieldMinValue=1, minValue=1, maxValue=10, value=4, cw3=[42,42,136], width=220)
rs = cmds.floatSliderGrp(label='Radius', field=True, fieldMinValue=0.001, minValue=0.001, value=1.0, cw3=[42,42,136], width=220)
cmds.setParent('..')
cmds.rowLayout(nc=2)
cmds.button('Confirm', w=220, c='makegeosphere( cmds.intSliderGrp("%s",q=True,v=True), cmds.floatSliderGrp("%s",q=True,v=True) ); cmds.deleteUI("%s")'%(ds, rs, w))
cmds.button('Cancel', w=220, c='cmds.deleteUI("%s")'%w)
cmds.showWindow(w)

It basically creates a platonic solid, smoothes it and then sets every vertex at the given radius from the origin again.

It uses exponential smooth, which can be set to actually only subdivide but it also adds points in the center of every face. Hence we have to delete this points and triangulate the mesh making it more difficult than linear smooth, but that just messes things up and adds minor deformation to the end result.

Leave a Reply

Your email address will not be published. Required fields are marked *