Project Breps on closest surfaces chosen from a group

Hello,
in an attempt to create a simple HoneyBee model for environmental analysis, and having exported Rooms, Windows from Revit to GH/Rhino using Speckle, I obtain the following:

  • a group of objects/breps representing a building’s windows (say called “obj_list”) - in blue
  • a group of vertical surfaces (say called “srf_list”) that represent the simplified walls for the environmental model - these are faces of closed breps that the honeybee plugin correctly recognises as thermal zones - in yellow.

I have asked ChatGPT (actually GrasshopperGPT) to create a python script to project each of these objects as flat surfaces onto the “srf_list”, perhaps fitting planes on those “srf_list” and looking for the closest planes to each of the center points from “obj_list”.

GrasshopperGPT stated it created a script that:

  • Converts GUIDs to Rhino Geometry objects.
  • Calculates the center point of each object’s bounding box.
  • Extracts planes from the vertical surfaces.
  • Finds the closest plane to each center point.
  • Projects the objects onto these planes.

However, the script created randomly placed and oriented objects, as per following image:

I am attaching the script GPT created, which I implemented using a GHPython component.

import Rhino.Geometry as rg
import scriptcontext as sc

def convert_guid_to_geometry(guid):
    """ Convert a Guid to a Rhino Geometry object. """
    rhino_object = sc.doc.Objects.Find(guid)
    return rhino_object.Geometry if rhino_object else None

def get_center_point(brep):
    """ Get the center point of a brep's bounding box. """
    bbox = brep.GetBoundingBox(True)
    return bbox.Center

def get_planes_from_surfaces(surfaces):
    """ Extract planes from a list of surfaces. """
    planes = []
    for surface in surfaces:
        if isinstance(surface, rg.Surface) or isinstance(surface, rg.Brep):
            surface_to_use = surface if isinstance(surface, rg.Surface) else surface.Faces[0]
            plane = surface_to_use.TryGetPlane()[1]
            if plane:
                planes.append(plane)
    return planes

def find_closest_plane(point, planes):
    """ Find the closest plane to a given point. """
    min_distance = float('inf')
    closest_plane = None
    for plane in planes:
        distance = rg.Point3d.DistanceTo(plane.ClosestPoint(point), point)
        if distance < min_distance:
            min_distance = distance
            closest_plane = plane
    return closest_plane

def project_to_closest_plane(objects, planes):
    projected_objects = []
    for obj in objects:
        center_point = get_center_point(obj)
        closest_plane = find_closest_plane(center_point, planes)
        if closest_plane:
            # Project the object onto the plane
            transform = rg.Transform.PlaneToPlane(rg.Plane.WorldXY, closest_plane)
            projected_obj = obj.Duplicate()
            projected_obj.Transform(transform)
            projected_objects.append(projected_obj)
    return projected_objects

# Assuming 'obj_list' and 'srf_list' are your input lists of Guids
obj_list = [convert_guid_to_geometry(obj) for obj in obj_list]
srf_list = [convert_guid_to_geometry(srf) for srf in srf_list]

planes = get_planes_from_surfaces(srf_list)
projected = project_to_closest_plane(obj_list, planes)

Anyone??

No chance to solve without any Data and setup of your problem.
How should someone try to find the error without any data (rhino and/or gh).

@flokart fair enough! I am attaching a GH definition with internalised geometry and a description of what I regard as the necessary steps


AB__Project_Breps_SRFs__v01.gh (592.3 KB)