Hi everyone,
I am trying to create a lofted surface between 4 circles using GH-Python in Grasshopper. However, instead of a single continuous loft between the circles, the script is currently creating individual lofts for each circle, as shown in the first image.
I would like to achieve a result similar to the second image, where all the circles are smoothly connected into a single lofted surface.
Here is my code:
import Rhino
import Rhino.Geometry as rg
import System
import System.Collections.Generic as sg
import ghpythonlib.treehelpers as th # ✅ Convert Data Tree to Python List
# Convert DataTree to list of point lists
points_list = th.tree_to_list(points_list)
print(f"🔍 Number of point lists: {len(points_list)}")
# Create curves from point lists
curves = []
for i, points in enumerate(points_list):
real_points = []
for p in points:
if isinstance(p, rg.Curve):
print(f"✅ List {i} is already a curve - keeping it.")
curves.append(p)
break
if isinstance(p, rg.Point3d):
real_points.append(p)
elif isinstance(p, System.Guid):
obj = Rhino.RhinoDoc.ActiveDoc.Objects.Find(p)
if obj and hasattr(obj.Geometry, "Location"):
real_points.append(obj.Geometry.Location)
elif isinstance(obj.Geometry, rg.Point):
real_points.append(obj.Geometry.Location)
print(f"🔍 List {i}: {len(real_points)} points converted.")
if len(real_points) < 3:
print(f"⚠️ Skipping - List {i} is too short for a circle.")
continue
if real_points[0].DistanceTo(real_points[-1]) > 0.01:
real_points.append(real_points[0])
point_list = sg.List[rg.Point3d]()
for p in real_points:
point_list.Add(rg.Point3d(p.X, p.Y, p.Z))
nurbs_curve = rg.PolylineCurve(point_list)
curves.append(nurbs_curve)
print(f"✅ {len(curves)} curves created.")
if len(curves) < 2:
raise ValueError(f"❌ Only {len(curves)} curves found. Need at least 2 for Loft!")
# Move curves to different heights
moved_curves = []
for i, curve in enumerate(curves):
translation = rg.Transform.Translation(0, 0, i * height)
moved_curve = curve.DuplicateCurve()
moved_curve.Transform(translation)
moved_curves.append(moved_curve)
print("✅ All circles moved to their respective heights!")
# Ensure all curves are in a single list
flat_curves = list(moved_curves)
print(f"🔍 Number of curves in flat_curves: {len(flat_curves)}")
for i, curve in enumerate(flat_curves):
print(f" - Curve {i}: Type {type(curve).__name__}, Start Point {curve.PointAtStart}, Length {curve.GetLength()}")
# **Perform Loft**
loft = rg.Brep.CreateFromLoft(
flat_curves,
rg.Point3d.Unset,
rg.Point3d.Unset,
rg.LoftType.Normal, # Try switching between Tight / Loose / Normal
False
if loft and len(loft) > 0:
loft_surface = loft[0]
print("✅ Loft surface successfully created!")
else:
loft_surface = None
print("❌ Loft failed! Check if curves are correct.")
# Output
a = loft_surface # Lofted surface
b = moved_curves # Transformed circles
Python - omer livni, eden maman.gh (43.9 KB)
Thanks in advance for any insights!