Here is a snippet, using the compas_CGAL interior_straight_skeleton() function, and showing how to write compas geometry into the rhino drawing.
Useful in drawing plans of hipped roofs.
# Draw a 'Straight Skeleton' into an anti-clockwise closed non-intersecting planar polyline
# A straight skeleton describes the plan of ridges and valleys in a hipped roof.
#! python 3
# r: compas, compas_cgal
import rhinoscriptsyntax as rs
import scriptcontext as sc
from compas.geometry import Point, Polygon, Line
from compas_cgal.straight_skeleton_2 import interior_straight_skeleton
import compas_rhino.objects
import compas_rhino.conversions
obj = rs.GetObject("Select a polyline", rs.filter.curve)
poly_points = []
if obj and rs.IsPolyline(obj):
pts = rs.PolylineVertices(obj)
for pt in pts:
poly_points.append(Point(pt.X, pt.Y, pt.Z))
polyg = Polygon(poly_points)
graph = interior_straight_skeleton(polyg)
for edge in graph.edges():
edge_line = graph.edge_line(edge)
rh_ln = compas_rhino.conversions.line_to_rhino(edge_line)
sc.doc.Objects.AddLine(rh_ln)
Straight skeleton extrusion has been added to compas_cgal. Incase you need to model or draw roofscapes:
Here is a rough sketch for generating ‘hipped roof’ forms.
Thanks Petras!
# Draw a hipped roof form - aka an extruded straight skeleton.
# Outputs a mesh and edge lines
# Uses compas_cgal python bindings for CGAL geometry library.
# Thanks Petras Vestartas & ETH Zurich.
#! python 3
# r: compas, compas_cgal
import rhinoscriptsyntax as rs
import scriptcontext as sc
from compas.geometry import Point, Polygon, Line
from compas_cgal.straight_skeleton_2 import interior_straight_skeleton
from compas_cgal.straight_skeleton_2 import extrude
import compas_rhino.objects
import compas_rhino.conversions
def extrude_straight_skeleton():
TOLERANCE = 0.06
obj = rs.GetObject("Select a boundary polyline: ", rs.filter.curve)
poly_points = []
if obj and rs.IsPolyline(obj):
pts = rs.PolylineVertices(obj)
for pt in pts:
poly_points.append(Point(pt.X, pt.Y, pt.Z))
polyg = Polygon(poly_points)
holes_objs = rs.GetObjects("Select any non-overlapping Holes: ", rs.filter.curve)
holes = []
if holes_objs:
for hl in holes_objs:
if rs.IsPolyline(hl):
poly_points = []
pts = rs.PolylineVertices(hl)
for pt in pts:
poly_points.append(Point(pt.X, pt.Y, pt.Z))
poly_hole = Polygon(poly_points)
holes.append(poly_hole)
if len(holes) == 0:
holes = None
mesh, lines = extrude(polyg, holes=holes, angles=22.5)
for line in lines:
rh_ln = compas_rhino.conversions.line_to_rhino(line)
sc.doc.Objects.AddLine(rh_ln)
rh_msh = compas_rhino.conversions.mesh_to_rhino(mesh)
# unites the mesh from cgal into flat planes
rh_msh.Weld(TOLERANCE)
rh_msh.MergeAllCoplanarFaces(TOLERANCE)
sc.doc.Objects.AddMesh(rh_msh)
if __name__ == "__main__" :
extrude_straight_skeleton()
@greenbox Can you post some example on more complex scene to stress test this method?