def tag_support_surfaces(obj, angle_threshold=0.1):
    """
    Tags faces of the object (or its mesh children) whose normal is close to the +z direction with the "support" tag.

    Args:
    obj (bpy.types.Object): The object to tag (can be any type of object).
    angle_threshold (float): The cosine of the maximum angle deviation from +z to be considered a support surface.
    """

    def process_mesh(mesh_obj):
        up_vector = Vector((0, 0, 1))

        n_poly = len(mesh_obj.data.polygons)
        support_mask = np.zeros(n_poly, dtype=bool)

        for poly in mesh_obj.data.polygons:
            global_normal = butil.global_polygon_normal(mesh_obj, poly)
            if global_normal.dot(up_vector) > 1 - angle_threshold:
                support_mask[poly.index] = True

        if t.Subpart.SupportSurface.value not in tag_system.tag_dict:
            tag_system.tag_dict[t.Subpart.SupportSurface.value] = (
                len(tag_system.tag_dict) + 1
            )

        tag_object(mesh_obj, name=t.Subpart.SupportSurface.value, mask=support_mask)

        print(
            f"Tagged {support_mask.sum()} faces as 'support' in object {mesh_obj.name}"
        )

    def process_object(obj):
        if obj.type == "MESH":
            process_mesh(obj)
        for child in obj.children:
            process_object(child)

    process_object(obj)

    Tags faces of the object (or its mesh children) whose normal is close to the +z direction with the "support" tag.

    Args:
    obj (bpy.types.Object): The object to tag (can be any type of object).
    angle_threshold (float): The cosine of the maximum angle deviation from +z to be considered a support surface.
    
infinigen/core/tagging.py