Python: how to get volume of subd?

I can see how to get the volumes of meshes, surfaces, and polysurfaces, but I can’t seem to get the volume of subds. How do I do that? I want user to be able to select any of those types and return a volume. In Vbscript, I did it like this (which was annoying but worked) but with python rs syntax, I get an error when a subd is selected:

If Rhino.IsObjectSolid(strObject) Then
If Rhino.IsMesh(strObject) Then
arrMP = Rhino.MeshVolume(strObject)
If IsArray(arrMP) Then
ObjectVolume = CDbl(arrMP(1))

					End If
				Else	
					arrMP = Rhino.SurfaceVolume(strObject)
					If IsArray(arrMP) Then
						ObjectVolume = CDbl(arrMP(0))
						
					End If
				End If

Hi @phcreates,

I am a littie confused, as your post subject says Python but your code is VBScript. RhinoScript has not been updated to support SubD objects.

For Python (or RhinoCommon), convert the SubD to a Brep and then calculate the volume of the Brep.

Hope this helps.

– Dale

Hi Dale,
The code that I posted is old vbscript code that did what I want to do in python (it does get volume of subds - maybe it just considers them meshes?) But I can’t get the same result so far in python. Thanks for the input - I’m really new at python and so far mostly still just trying to figure out the basics. I’ll try the SubD to a Brep & see where it gets me.

Here is where I was in Python, but I get an error when obj is a subd:

def get_volume(obj):

if rs.IsMesh(obj):
    arrMP=rs.MeshVolume(obj)
    Volume = arrMP[1]
else:
    massprop = rs.SurfaceVolume(obj)
    Volume = massprop[0]


return Volume

Hi @phcreates,

The PolysrfFilter filter allows Rhino’s object picker to pick surfaces, polysurfaces, extrusions, and subds. And when used, the returned ObjRef will create a proxy Brep on your behalf, so you don’t need to do any geometric conversion.

For example:

import Rhino
import scriptcontext as sc

def test_volume():
    filter = Rhino.DocObjects.ObjectType.Surface \
        | Rhino.DocObjects.ObjectType.PolysrfFilter \
        | Rhino.DocObjects.ObjectType.Mesh

    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select object for volume calculation", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success: return
    
    obj_type = objref.Object().ObjectType
    brep = objref.Brep()
    mesh = objref.Mesh()
    
    if brep and brep.IsSolid:
        mp = Rhino.Geometry.VolumeMassProperties.Compute(brep, True, False, False, False)
        if mp:
            print("{0} volume = {1}".format(obj_type, mp.Volume))
    elif mesh and mesh.IsSolid:
        mp = Rhino.Geometry.VolumeMassProperties.Compute(mesh, True, False, False, False)
        if mp:
            print("{0} volume = {1}".format(obj_type, mp.Volume))

if __name__ == "__main__":
    test_volume()

– Dale

Thanks that is super helpful!