Source code for ladybug_rhino.fromgeometry

"""Functions to translate from Ladybug geometries to Rhino geometries."""
from __future__ import division

from .config import tolerance
from .color import color_to_color, gray

try:
    import Rhino.Geometry as rg
except ImportError as e:
    raise ImportError('Failed to import Rhino Geometry.\n{}'.format(e))

try:
    from ladybug_geometry.geometry2d import LineSegment2D, Polygon2D
except ImportError as e:
    raise ImportError('Failed to import ladybug_geometry.\n{}'.format(e))


"""____________2D GEOMETRY TRANSLATORS____________"""


[docs]def from_vector2d(vector): """Rhino Vector3d from ladybug Vector2D.""" return rg.Vector3d(vector.x, vector.y, 0)
[docs]def from_point2d(point, z=0): """Rhino Point3d from ladybug Point2D.""" return rg.Point3d(point.x, point.y, z)
[docs]def from_ray2d(ray, z=0): """Rhino Ray3d from ladybug Ray2D.""" return rg.Ray3d(from_point2d(ray.p, z), from_vector2d(ray.v))
[docs]def from_linesegment2d(line, z=0): """Rhino LineCurve from ladybug LineSegment2D.""" return rg.LineCurve(from_point2d(line.p1, z), from_point2d(line.p2, z))
[docs]def from_arc2d(arc, z=0): """Rhino Arc from ladybug Arc2D.""" if arc.is_circle: return rg.Circle(from_point2d(arc.c, z), arc.r) else: pts = (arc.p1, arc.midpoint, arc.p2) return rg.Arc(*(from_point2d(pt, z) for pt in pts))
[docs]def from_polygon2d(polygon, z=0): """Rhino closed PolyLineCurve from ladybug Polygon2D.""" return rg.PolylineCurve( [from_point2d(pt, z) for pt in polygon.vertices] + [from_point2d(polygon[0], z)])
[docs]def from_polyline2d(polyline, z=0): """Rhino closed PolyLineCurve from ladybug Polyline2D.""" rhino_pts = [from_point2d(pt, z) for pt in polyline.vertices] if polyline.interpolated: return rg.Curve.CreateInterpolatedCurve( rhino_pts, 3, rg.CurveKnotStyle.UniformPeriodic) else: return rg.PolylineCurve(rhino_pts)
[docs]def from_mesh2d(mesh, z=0): """Rhino Mesh from ladybug Mesh2D.""" pt_function = _get_point2d_function(z) return _translate_mesh(mesh, pt_function)
def _get_point2d_function(z_val): def point2d_function(pt): return from_point2d(pt, z_val) return point2d_function """____________3D GEOMETRY TRANSLATORS____________"""
[docs]def from_vector3d(vector): """Rhino Vector3d from ladybug Vector3D.""" return rg.Vector3d(vector.x, vector.y, vector.z)
[docs]def from_point3d(point): """Rhino Point3d from ladybug Point3D.""" return rg.Point3d(point.x, point.y, point.z)
[docs]def from_ray3d(ray): """Rhino Ray3d from ladybug Ray3D.""" return rg.Ray3d(from_point3d(ray.p), from_vector3d(ray.v))
[docs]def from_linesegment3d(line): """Rhino LineCurve from ladybug LineSegment3D.""" return rg.LineCurve(from_point3d(line.p1), from_point3d(line.p2))
[docs]def from_plane(pl): """Rhino Plane from ladybug Plane.""" return rg.Plane(from_point3d(pl.o), from_vector3d(pl.x), from_vector3d(pl.y))
[docs]def from_arc3d(arc): """Rhino Arc from ladybug Arc3D.""" if arc.is_circle: return rg.Circle(from_plane(arc.plane), from_point3d(arc.c), arc.radius) else: pts = (arc.p1, arc.midpoint, arc.p2) return rg.Arc(*(from_point3d(pt) for pt in pts))
[docs]def from_polyline3d(polyline): """Rhino closed PolyLineCurve from ladybug Polyline3D.""" rhino_pts = [from_point3d(pt) for pt in polyline.vertices] if polyline.interpolated: return rg.Curve.CreateInterpolatedCurve( rhino_pts, 3, rg.CurveKnotStyle.UniformPeriodic) else: return rg.PolylineCurve(rhino_pts)
[docs]def from_mesh3d(mesh): """Rhino Mesh from ladybug Mesh3D.""" return _translate_mesh(mesh, from_point3d)
[docs]def from_face3d(face): """Rhino Brep from ladybug Face3D.""" segs = [from_linesegment3d(seg) for seg in face.boundary_segments] try: brep = rg.Brep.CreatePlanarBreps(segs, tolerance)[0] except TypeError: # not planar in Rhino model tolerance; maybe from another model print('Brep not planar in Rhino model tolerance. Ignoring tolerance.') try: brep = rg.Brep.CreatePlanarBreps(segs, 1e6)[0] except TypeError: # it must be a zero-area geometry return None if face.has_holes: for hole in face.hole_segments: trim_crvs = [from_linesegment3d(seg) for seg in hole] brep.Loops.AddPlanarFaceLoop(0, rg.BrepLoopType.Inner, trim_crvs) return brep
[docs]def from_polyface3d(polyface): """Rhino Brep from ladybug Polyface3D.""" rh_faces = [from_face3d(face) for face in polyface.faces] brep = rg.Brep.JoinBreps(rh_faces, tolerance) if len(brep) == 1: return brep[0]
[docs]def from_sphere(sphere): """Rhino Sphere from ladybug Sphere.""" return rg.Sphere(from_point3d(sphere.center), sphere.radius)
[docs]def from_cone(cone): """Rhino Cone from ladybug Cone.""" plane = rg.Plane(from_point3d(cone.vertex), from_vector3d(cone.axis.normalize())) return rg.Cone(plane, cone.height, cone.radius)
[docs]def from_cylinder(cylinder): """Rhino Cone from ladybug Cone.""" return rg.Cylinder(from_arc3d(cylinder.base_bottom), cylinder.height)
"""________ADDITIONAL 3D GEOMETRY TRANSLATORS________"""
[docs]def from_polyline2d_to_joined_polyline(polylines, z=0): """Rhino PolylineCurve made by joining list of Polyline2D. Args: polylines: An array of Ladybug Polyline2D or LineSegment2D to be joined into a polyline. This can also be an array with a single Polygon2D. z: A number for the Z-coordinate. (Default: 0). Returns: A Rhino brep constructed from the polygon and the offset distance. If offset is unsuccessful, just the polyline will be returned. """ line_crv = [] for pl in polylines: if isinstance(pl, Polygon2D): return from_polygon2d(pl) if isinstance(pl, LineSegment2D): line_crv.append(from_linesegment2d(pl)) else: line_crv.append(from_polyline2d(pl)) return rg.Curve.JoinCurves(line_crv)[0]
[docs]def from_polyline2d_to_offset_brep(polylines, offset, z=0): """Rhino Brep made by offsetting a joined list of Polyline2D inward. Args: polylines: An array of Ladybug Polyline2D or LineSegment2D to be joined and translated to an offset Brep. This can also be an array with a single Polygon2D. offset: A number for the distance to offset the Polygon inward. z: A number for the Z-coordinate. (Default: 0). Returns: A Rhino brep constructed from the polygon and the offset distance. If offset is unsuccessful, just the polyline will be returned. """ curve = from_polyline2d_to_joined_polyline(polylines, z) crv_style = rg.CurveOffsetCornerStyle.Sharp all_curves = [curve] off_curves = curve.Offset(rg.Plane.WorldXY, -offset, tolerance, crv_style) if off_curves is not None: all_curves.extend(off_curves) offset_brep = rg.Brep.CreatePlanarBreps(all_curves) if len(offset_brep) == 1: if offset_brep[0].Loops.Count == 2: return offset_brep[0] return curve
[docs]def from_face3d_to_wireframe(face): """Rhino PolyLineCurves from ladybug Face3D. Args: face: A Ladybug Face3D object to be translated to a wireframe. Returns: A list of Rhino polyline curves for the boundary and holes in the face. """ boundary = [_polyline_points(face.boundary)] if face.has_holes: return boundary + [_polyline_points(tup) for tup in face.holes] return boundary
[docs]def from_polyface3d_to_wireframe(polyface): """Rhino PolyLineCurve from ladybug Polyface3D.""" return [f for face in polyface.faces for f in from_face3d_to_wireframe(face)]
[docs]def from_mesh3d_to_wireframe(mesh): """Rhino PolyLineCurves from ladybug Mesh3D. Args: mesh: A Ladybug Mesh3D object to be translated to a wireframe. Returns: A list of Rhino polyline curves for the mesh edges. """ line_curves = [] for edge in mesh.face_edges: line_curves.append(from_polyline3d(edge)) return line_curves
[docs]def from_face3d_to_solid(face, offset): """Rhino Solid Brep from a ladybug Face3D and an offset from the base face. Args: face: Ladybug geometry Face3D object. offset: Number for the offset distance from the base face. """ srf_brep = from_face3d(face) return rg.Brep.CreateFromOffsetFace( srf_brep.Faces[0], offset, tolerance, False, True)
[docs]def from_face3ds_to_joined_brep(faces): """A list of joined Breps from an array of ladybug Face3D.""" return rg.Brep.JoinBreps([from_face3d(face) for face in faces], tolerance)
[docs]def from_face3ds_to_colored_mesh(faces, color): """Colored Rhino mesh from an array of ladybug Face3D and ladybug Color. This is used in workflows such as coloring Model geometry with results. """ joined_mesh = rg.Mesh() for face in faces: try: joined_mesh.Append(from_mesh3d(face.triangulated_mesh3d)) except Exception: pass # failed to create a Rhino Mesh from the Face3D joined_mesh.VertexColors.CreateMonotoneMesh(color_to_color(color)) return joined_mesh
[docs]def from_mesh3ds_to_colored_mesh(meshes, color): """Colored Rhino mesh from an array of ladybug Mesh3D and ladybug Color. This is used in workflows such as coloring Model geometry with results. """ joined_mesh = rg.Mesh() for mesh in meshes: try: joined_mesh.Append(from_mesh3d(mesh)) except Exception: pass # failed to create a Rhino Mesh from the Mesh3d joined_mesh.VertexColors.CreateMonotoneMesh(color_to_color(color)) return joined_mesh
[docs]def from_mesh2d_to_outline(mesh, z=0): """Rhino Polylines from the faces of ladybug Mesh2D.""" pt_function = _get_point2d_function(z) verts = [pt_function(pt) for pt in mesh.vertices] face_plines = [] for face in mesh.faces: outline = [verts[f] for f in face] + [verts[face[0]]] face_plines.append(rg.PolylineCurve(outline)) return face_plines
[docs]def from_mesh3d_to_outline(mesh): """Rhino Mesh and Polylines from the ladybug Mesh3D. Returns: A tuple with two items - a Rhino Mesh first followed by outline curves of the Mesh. """ rh_mesh = from_mesh3d(mesh) return rh_mesh, rh_mesh.GetNakedEdges()
"""________________EXTRA HELPER FUNCTIONS________________""" def _translate_mesh(mesh, pt_function): """Translates both 2D and 3D meshes to Rhino""" rhino_mesh = rg.Mesh() if mesh.is_color_by_face: # Mesh is constructed face-by-face _f_num = 0 for face in mesh.faces: for pt in tuple(mesh[i] for i in face): rhino_mesh.Vertices.Add(pt_function(pt)) if len(face) == 4: rhino_mesh.Faces.AddFace( _f_num, _f_num + 1, _f_num + 2, _f_num + 3) _f_num += 4 else: rhino_mesh.Faces.AddFace(_f_num, _f_num + 1, _f_num + 2) _f_num += 3 if mesh.colors is not None: rhino_mesh.VertexColors.CreateMonotoneMesh(gray()) _f_num = 0 for i, face in enumerate(mesh.faces): col = color_to_color(mesh.colors[i]) rhino_mesh.VertexColors[_f_num] = col rhino_mesh.VertexColors[_f_num + 1] = col rhino_mesh.VertexColors[_f_num + 2] = col if len(face) == 4: rhino_mesh.VertexColors[_f_num + 3] = col _f_num += 4 else: _f_num += 3 else: # Mesh is constructed vertex-by-vertex for pt in mesh.vertices: rhino_mesh.Vertices.Add(pt_function(pt)) for face in mesh.faces: rhino_mesh.Faces.AddFace(*face) if mesh.colors is not None: rhino_mesh.VertexColors.CreateMonotoneMesh(gray()) for i, col in enumerate(mesh.colors): rhino_mesh.VertexColors[i] = color_to_color(col) return rhino_mesh def _polyline_points(tup): """Convert a tuple of Ladybug Geometry points to a Rhino Polyline.""" return rg.PolylineCurve([from_point3d(pt) for pt in tup] + [from_point3d(tup[0])])