GetMaterialVolume

Hi,
To determine the portion of a window’s glazing surface (total returned surface area GetMaterialArea),
I have to round to compare the solid portion of the glazing with the volume obtained (GetMaterialVolume).
Does rounding to 5 digits seem sufficient to avoid false positives?

Thank you
Sincerely,
christian.stan

Rather than round you can use the ‘almost equals’ node and set the tolerance

add another step of Face.MaterialElementId comparison. but if there’re more than one vitrage solids for whatever reason, both methods would fail.

if that ever happens, go with rays. set origins carefully and cast them inwards/outwards. (by carefully i mean avoid hittin wood/metal or any other material. iirc ray mask is at category level but not material.)

either more face iterations or rays, it’s gettin slower and slower.

alternatively, i suppose if there’s no geometrical modification within the family document. the solid and face indices wouldn’t change at all. then its just two index operators[idx], or two GetItemAtIndex away. quick and dirty but it should work.

Here’s some sample code that filters by face normal and then materials [after @BimAmbit 's suggestion]. This assumes all geometry is a solid type. I think calculating the true glass to solid ratio would be better done using formula inside a family as this does not account for overlapping solids

import clr

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

doc = DocumentManager.Instance.CurrentDBDocument

options = Options()
options.DetailLevel = ViewDetailLevel.Undefined
options.IncludeNonVisibleObjects = False

elem = UnwrapElement(IN[0])

geom = next(iter(elem.get_Geometry(options)))

fo = elem.FacingOrientation

faces = [
    f
    for i in geom.GetInstanceGeometry()
    for f in i.Faces  # Assumes solid
    if hasattr(f, "FaceNormal") and f.FaceNormal.IsAlmostEqualTo(fo)
]

total_area = sum(face.Area for face in faces)

glass_area = sum(
    face.Area
    for face in faces
    if "glass" in doc.GetElement(face.MaterialElementId).Name.lower()
)

OUT = (
    total_area,
    glass_area,
    f"Glass Area: {round(glass_area / total_area * 100, 2)}%"
)