Struggling with GH Definitions – Design Principles or Best Practices?

Any favorite strategies or rules of thumb on how people select geometry?

FWIW: I’m a big fan of ‘Pipeline’ components, combined with filtering to select the ‘right’ objects for GH scripts. In RH8, there are now a nice set of ‘Filtering’ components which work quite well for us when combined with UserText tags applied to objects in Rhino:

By ‘tagging’ objects in RH you can then usually control their selection in GH reasonably well. Though of course it would be nice if the ‘tags’ where a bit more user-friendly, as discussed previously


However for sub-face selection on Polysurfaces, the best workaround we’ve found (since you cannot ‘tag’ sub-faces using the existing Rhino UI tools - though it is possible with custom scripts) is to use Materials as a proxy for the ‘tag’, and then filter / sort based on the Material’s name over in Grasshopper. You can easily apply different materials to different sub-faces of a single Polysurface, and so in this way determine ‘which is which’ within GH:

You get the added benefit of ‘seeing’ which faces have which ‘tags’ applied as well.

I’m not 100% sure if this something that can be achieved with the ‘standard’ GH components? We just created a small utility component to pull that data in though, which has worked quite well for our needs.

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

from Grasshopper import DataTree
from Grasshopper.Kernel.Data import GH_Path
from System import Object

def get_brep_face_data(_brep_guid):
    # type: (GUID) -> tuple[list[BrepFace], list[str]]
    brep_faces_, material_names_ = [], []

    brep = rs.coercebrep(_brep_guid)
    if not brep:
        msg = "Failed to coerce Brep from GUID: {}".format(_brep_guid)
        raise Exception(msg)

    for face in brep.Faces:
        # -- Add the BrepFace geometry to the output set
        brep_faces_.append(face)

        # -- Get the BrepFace's Material Name and add to the output
        compo_index = Rhino.Geometry.ComponentIndex(
            Rhino.Geometry.ComponentIndexType.BrepFace, face.FaceIndex
        )
        brep_obj = Rhino.RhinoDoc.ActiveDoc.Objects.FindId(_brep_guid)
        mat_name = Rhino.DocObjects.RhinoObject.GetMaterial(brep_obj, compo_index).Name
        material_names_.append(mat_name)

    return brep_faces_, material_names_

def run(_brep_guids):
    # type: () -> tuple[DataTree[Rhino.Geometry.BrepFace], DataTree[str]]
    subface_geo_ = DataTree[Object]()
    mat_names_ = DataTree[Object]()

    try:
        sc.doc = Rhino.RhinoDoc.ActiveDoc
        for i, brep_guid in enumerate(_brep_guids):
            faces, mats = get_brep_face_data(brep_guid)
            subface_geo_.AddRange(faces, GH_Path(i))
            mat_names_.AddRange(mats, GH_Path(i))
    finally:
        sc.doc = ghdoc

    return subface_geo_, mat_names_

if _brep_guids:
    surface_subface_, material_names_ = run(_brep_guids)

@ed.p.may

Example Files:

1 Like