Source code for compas_ghpython.utilities.drawing


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from compas_rhino.utilities.drawing import _face_to_max_quad

from System.Enum import ToObject
from System.Array import CreateInstance
from System.Drawing import Color

import rhinoscriptsyntax as rs
import scriptcontext as sc

from Rhino.Geometry import Point3d
from Rhino.Geometry import Vector3d
from Rhino.Geometry import Line
from Rhino.Geometry import Polyline
from Rhino.Geometry import Brep
from Rhino.Geometry import Cylinder
from Rhino.Geometry import Circle
from Rhino.Geometry import Plane
from Rhino.Geometry import PipeCapMode
from Rhino.Geometry import Curve
from Rhino.Geometry import Sphere
from Rhino.Geometry import Mesh
from Rhino.Geometry import Vector3f
from Rhino.Geometry import Point2f

TOL = sc.doc.ModelAbsoluteTolerance


__all__ = [
    'draw_frame',
    'draw_points',
    'draw_lines',
    'draw_geodesics',
    'draw_polylines',
    'draw_faces',
    'draw_cylinders',
    'draw_pipes',
    'draw_spheres',
    'draw_mesh',
    'draw_network',
    'draw_circles',
]


[docs]def draw_frame(frame): """Draw a frame. """ pt = Point3d(*iter(frame.point)) xaxis = Vector3d(*iter(frame.xaxis)) yaxis = Vector3d(*iter(frame.yaxis)) return Plane(pt, xaxis, yaxis)
[docs]def draw_points(points): """Draw points. Parameters ---------- points : list of dict The point definitions. Returns ------- list of :class:`Rhino.Geometry.Point3d` Notes ----- .. code-block:: python Schema({ 'pos': lambda x: len(x) == 3) }) """ rg_points = [] for p in iter(points): pos = p['pos'] rg_points.append(Point3d(*pos)) return rg_points
[docs]def draw_lines(lines): """Draw lines. Parameters ---------- lines : list of dict The line definitions. Returns ------- list of :class:`Rhino.Geometry.Line` Notes ----- .. code-block:: python Schema({ 'start': lambda x: len(x) == 3), 'end': lambda x: len(x) == 3), }) """ rg_lines = [] for line in iter(lines): sp = line['start'] ep = line['end'] rg_lines.append(Line(Point3d(*sp), Point3d(*ep))) return rg_lines
def draw_geodesics(geodesics): """Draw geodesic lines on specified surfaces. Parameters ---------- geodesics : list of dict The geodesic definitions. Returns ------- list of :class:`Rhino.Geometry.Curve` Notes ----- .. code-block:: python Schema({ 'start': lambda x: len(x) == 3), 'end': lambda x: len(x) == 3), 'srf': str }) """ rg_geodesics = [] for g in iter(geodesics): sp = g['start'] ep = g['end'] srf = g['srf'] curve = srf.ShortPath(Point3d(*sp), Point3d(*ep), TOL) rg_geodesics.append(curve) return rg_geodesics
[docs]def draw_polylines(polylines): """Draw polylines. Parameters ---------- polylines : list of dict The polyline definitions. Returns ------- list of :class:`Rhino.Geometry.Polyline` Notes ----- .. code-block:: python Schema({ 'points': lambda x: all(len(y) == 3 for y in x) }) """ rg_polylines = [] for p in iter(polylines): points = p['points'] poly = Polyline([Point3d(*xyz) for xyz in points]) poly.DeleteShortSegments(TOL) rg_polylines.append(poly) return rg_polylines
[docs]def draw_faces(faces): """Draw polygonal faces as Meshes. Parameters ---------- faces : list of dict The face definitions. Returns ------- list of :class:`Rhino.Geometry.Mesh` Notes ----- .. code-block:: python Schema({ 'points': lambda x: all(len(y) == 3 for y in x), Optional('vertexcolors', default=None): lambda x: all(len(y) == 3 for y in x) }) """ meshes = [] for face in iter(faces): points = face['points'][:] vertexcolors = face.get('vertexcolors') v = len(points) if v < 3: continue if v == 3: mfaces = [[0, 1, 2, 2]] elif v == 4: mfaces = [[0, 1, 2, 3]] else: mfaces = _face_to_max_quad(points, range(v)) if vertexcolors: r, g, b = [sum(component) / v for component in zip(*vertexcolors)] r = int(min(max(0, r), 255)) g = int(min(max(0, g), 255)) b = int(min(max(0, b), 255)) vertexcolors.append((r, g, b)) if vertexcolors: mesh = draw_mesh(points, mfaces, color=vertexcolors) else: mesh = draw_mesh(points, mfaces) meshes.append(mesh) return meshes
[docs]def draw_cylinders(cylinders, cap=False): """Draw cylinders. Parameters ---------- cylinders : list of dict The cylinder definitions. Other Parameters ---------------- cap : bool, optional Default is ``False``. Returns ------- list of :class:`Rhino.Geometry.Cylinder` Notes ----- .. code-block:: python Schema({ 'start': lambda x: len(x) == 3, 'end': lambda x: len(x) == 3, 'radius': And(Or(int, float), lambda x: x > 0) }) """ rg_cylinders = [] for c in iter(cylinders): start = c['start'] end = c['end'] radius = c['radius'] if radius < TOL: continue base = Point3d(*start) normal = Point3d(*end) - base height = normal.Length if height < TOL: continue plane = Plane(base, normal) circle = Circle(plane, radius) cylinder = Cylinder(circle, height) brep = cylinder.ToBrep(cap, cap) if not brep: continue rg_cylinders.append(brep) return rg_cylinders
[docs]def draw_pipes(pipes, cap=2, fit=1.0): """Draw pipes. Parameters ---------- pipes : list of dict The pipe definitions. Other Parameters ---------------- cap : {0, 1, 2}, optional fit : float, optional Returns ------- list of :class:`Rhino.Geometry.Brep` Notes ----- .. code-block:: python Schema({ 'points': lambda x: all(len(y) == 3 for y in x), 'radius': And(Or(int, float), lambda x: x > 0) }) """ abs_tol = TOL ang_tol = sc.doc.ModelAngleToleranceRadians for p in pipes: points = p['points'] radius = p['radius'] params = [0.0, 1.0] cap = ToObject(PipeCapMode, cap) if type(radius) in (int, float): radius = [radius] * 2 radius = [float(r) for r in radius] rail = Curve.CreateControlPointCurve([Point3d(*xyz) for xyz in points]) breps = Brep.CreatePipe(rail, params, radius, 1, cap, fit, abs_tol, ang_tol) for brep in breps: yield brep
[docs]def draw_spheres(spheres): """Draw spheres. Parameters ---------- spheres : list of dict The sphere definitions. Returns ------- list of :class:`Rhino.Geometry.Sphere` Notes ----- .. code-block:: python Schema({ 'pos': lambda x: len(x) == 3, 'radius': And(Or(int, float), lambda x: x > 0) }) """ rg_sheres = [] for s in iter(spheres): pos = s['pos'] radius = s['radius'] rg_sheres.append(Sphere(Point3d(*pos), radius)) return rg_sheres
[docs]def draw_mesh(vertices, faces, color=None, vertex_normals=None, texture_coordinates=None): """Draw mesh in Grasshopper. Parameters ---------- vertices : list of point List of vertex locations. faces : list of list of int List of faces defined as lists of indices into the list of vertices. Other Parameters ---------------- color : tuple, list or :class:`System.Drawing.Color`, optional vertex_normals : bool, optional texture_coordinates Returns ------- list of :class:`Rhino.Geometry.Mesh` """ mesh = Mesh() for a, b, c in vertices: mesh.Vertices.Add(a, b, c) for face in faces: if len(face) < 4: mesh.Faces.AddFace(face[0], face[1], face[2]) else: mesh.Faces.AddFace(face[0], face[1], face[2], face[3]) if vertex_normals: count = len(vertex_normals) normals = CreateInstance(Vector3f, count) for i, normal in enumerate(vertex_normals): normals[i] = Vector3f(normal[0], normal[1], normal[2]) mesh.Normals.SetNormals(normals) if texture_coordinates: count = len(texture_coordinates) tcs = CreateInstance(Point2f, count) for i, tc in enumerate(texture_coordinates): tcs[i] = Point2f(tc[0], tc[1]) mesh.TextureCoordinates.SetTextureCoordinates(tcs) if color: count = len(vertices) colors = CreateInstance(Color, count) for i in range(count): colors[i] = rs.coercecolor(color) mesh.VertexColors.SetColors(colors) return mesh
[docs]def draw_network(network): """Draw a network in Grasshopper. Parameters ---------- network : :class:`compas.datastructures.Network` Returns ------- tuple A list of :class:`Rhino.Geometry.Point3d`. A list of :class:`Rhino.Geometry.Line`. """ points = [] for key in network.nodes(): points.append({ 'pos': network.node_coordinates(key)}) lines = [] for u, v in network.edges(): lines.append({ 'start': network.node_coordinates(u), 'end': network.node_coordinates(v)}) points_rg = draw_points(points) lines_rg = draw_lines(lines) return points_rg, lines_rg
def draw_circles(circles): """Draw circles in Grasshopper. Parameters ---------- circles : list of dict The circle definitions. Returns ------- list of :class:`Rhino.Geometry.Circle` Notes ----- .. code-block:: python Schema({ 'plane': lambda x: len(x[0]) == 3 and len(x[1]) == 3, 'radius': And(Or(int, float), lambda x: x > 0) }) """ rg_circles = [] for c in iter(circles): point, normal = c['plane'] radius = c['radius'] rg_circles.append(Circle(Plane(Point3d(*point), Vector3d(*normal)), radius)) return rg_circles # ============================================================================== # Main # ============================================================================== if __name__ == '__main__': pass