Beispiel #1
0
def display_mesh_face_normals(mesh,
                              display=True,
                              layer=None,
                              scale=1.0,
                              color=(0, 0, 255)):

    guids = compas_rhino.get_objects(
        name='{0}.face.normal.*'.format(mesh.attributes['name']))
    compas_rhino.delete_objects(guids)

    if not display:
        return

    lines = []

    for fkey in mesh.faces():
        normal = mesh.face_normal(fkey)
        start = mesh.face_center(fkey)
        end = [start[axis] + normal[axis] for axis in range(3)]
        name = '{0}.face.normal.{1}'.format(mesh.attributes['name'], fkey)

        lines.append({
            'start': start,
            'end': end,
            'name': name,
            'color': color,
            'arrow': 'end',
        })

    compas_rhino.xdraw_lines(lines, layer=layer, clear=False, redraw=True)
Beispiel #2
0
def move_network(network):
    """Move the entire network.

    Parameters:
        network (compas.datastructures.network.Network): A network object.

    """
    color  = Rhino.ApplicationSettings.AppearanceSettings.FeedbackColor
    origin = {key: network.vertex_coordinates(key) for key in network.vertices()}
    vertex = {key: network.vertex_coordinates(key) for key in network.vertices()}
    edges  = network.edges()
    start  = rhino.pick_point('Point to move from?')

    if not start:
        return

    def OnDynamicDraw(sender, e):
        current = list(e.CurrentPoint)
        vec = [current[i] - start[i] for i in range(3)]
        for key in vertex:
            vertex[key] = [origin[key][i] + vec[i] for i in range(3)]
        for u, v in iter(edges):
            sp = vertex[u]
            ep = vertex[v]
            sp = Point3d(*sp)
            ep = Point3d(*ep)
            e.Display.DrawDottedLine(sp, ep, color)

    guids = rhino.get_objects(name='{0}.*'.format(network.attributes['name']))
    rhino.delete_objects(guids, False)

    gp = Rhino.Input.Custom.GetPoint()
    gp.SetCommandPrompt('Point to move to?')
    gp.DynamicDraw += OnDynamicDraw
    gp.Get()

    if gp.CommandResult() == Rhino.Commands.Result.Success:
        end = list(gp.Point())
        vec = [end[i] - start[i] for i in range(3)]
        for key, attr in network.vertices(True):
            attr['x'] += vec[0]
            attr['y'] += vec[1]
            attr['z'] += vec[2]

    try:
        network.draw()
    except AttributeError:
        # this may result in the network being drawn in a different layer then before
        draw_network(network)
Beispiel #3
0
def draw_mesh_as_faces(mesh,
                       layer=None,
                       clear_layer=False,
                       facecolor=None,
                       redraw=True):

    guids = compas_rhino.get_objects(
        name='{0}.*'.format(mesh.attributes['name']))
    compas_rhino.delete_objects(guids)

    if clear_layer:
        if not layer:
            compas_rhino.clear_current_layer()
        else:
            compas_rhino.clear_layer(layer)

    facecolor = facecolor or {}

    meshes = []

    for fkey in mesh.faces():
        vertices = mesh.face_coordinates(fkey)
        faces = [range(len(vertices))]
        color = facecolor.get(fkey, (255, 255, 255))
        guid = compas_rhino.xdraw_mesh(vertices,
                                       faces,
                                       None,
                                       '{0}.face.{1}'.format(
                                           mesh.attributes['name'], fkey),
                                       layer=layer,
                                       clear=False,
                                       redraw=False)
        compas_rhino.set_mesh_vertex_colors(
            guid, [color for i in range(len(vertices))])
        meshes.append(guid)

    if layer:
        previous = rs.CurrentLayer(layer)

    guid = rs.JoinMeshes(meshes, delete_input=True)

    if layer:
        rs.CurrentLayer(previous)

    rs.ObjectName(guid, '{0}'.format(mesh.attributes['name']))

    rs.EnableRedraw()
    rs.Redraw()
Beispiel #4
0
def display_network_residual_forces(network,
                                    display=True,
                                    layer=None,
                                    clear_layer=False,
                                    scale=1.0,
                                    color=(0, 255, 255),
                                    attr_name='is_anchor'):

    tol = rhino.get_tolerance()
    guids = rhino.get_objects(name='{0}.force:residual.*'.format(network.attributes['name']))
    rhino.delete_objects(guids)

    if not display:
        return

    lines = []

    for key, attr in network.vertices(True):

        if attr[attr_name]:
            continue

        force  = attr['rx'], attr['ry'], attr['rz']
        start  = network.vertex_coordinates(key)
        end    = [start[i] + scale * force[i] for i in range(3)]
        length = distance_point_point(start, end)
        arrow  = 'end'
        name   = '{0}.force:residual.{1}'.format(network.attributes['name'], key)

        if length < tol:
            continue

        lines.append({
            'start' : start,
            'end'   : end,
            'name'  : name,
            'color' : color,
            'arrow' : arrow,
        })

    rhino.xdraw_lines(lines, layer=layer, clear=clear_layer)
Beispiel #5
0
def display_network_applied_loads(network,
                                  display=True,
                                  layer=None,
                                  clear_layer=False,
                                  scale=1.0,
                                  color=(0, 0, 255)):

    tol = rhino.get_tolerance()
    guids = rhino.get_objects(name='{0}.force:load.*'.format(network.attributes['name']))
    rhino.delete_objects(guids)

    if not display:
        return

    lines = []

    for key, attr in network.vertices(True):
        load   = attr['px'], attr['py'], attr['pz']
        end    = network.vertex_coordinates(key)
        start  = [end[i] - scale * load[i] for i in range(3)]
        length = distance_point_point(start, end)
        arrow  = 'end'
        name   = '{0}.force:load.{1}'.format(network.attributes['name'], key)

        if length < tol:
            continue

        lines.append({
            'start': start,
            'end'  : end,
            'name' : name,
            'color': color,
            'arrow': arrow,
        })

    rhino.xdraw_lines(lines, layer=layer, clear=clear_layer)
Beispiel #6
0
def display_network_face_labels(network, attr_name=None, layer=None, color=None, formatter=None):
    """Display labels for the faces of a network.

    Parameters:
        network (compas.datastructures.network.Network): The network object.
        attr_name (str): Optional. The name of the attribute value to display in the label.
            Default is ``None``. If ``None``, the key of the face is displayed.
        layer (str): Optional. The layer to draw in. Default is ``None``.
        color (str, tuple, list, dict): Optional. The color specification. Default is ``None``.
            The following values are supported:

                * str: A HEX color. For example, ``'#ff0000'``.
                * tuple, list: RGB color. For example, ``(255, 0, 0)``.
                * dict: A dictionary of RGB and/or HEX colors.

            If ``None``, the default face color of the network will be used.
        formatter (callable): Optional. A formatting function. Default is ``None``.

    Example:

        .. code-block:: python

            import compas
            from compas.cad import rhino as compas_rhino

            from compas.datastructures.network import Network

            network = Network.from_obj(compas.get_data('lines.obj'))

            compas_rhino.display_network_face_labels(network)


    See Also:
        * :func:`display_network_vertex_labels`
        * :func:`display_network_edge_labels`

    """
    rhino.delete_objects(rhino.get_objects(name="{0}.face.label.*".format(network.attributes['name'])))

    if not attr_name:
        attr_name = 'key'

    colordict = color_to_colordict(color,
                                   network.faces(),
                                   default=network.attributes['color.face'],
                                   colorformat='rgb',
                                   normalize=False)

    if formatter:
        if not callable(formatter):
            raise Exception('The provided formatter is not callable.')
    else:
        formatter = str

    labels = []

    for index, fkey in enumerate(network.faces()):
        if attr_name == 'key':
            value = fkey
        elif attr_name == 'index':
            value = index
        else:
            value = network.facedata[fkey][attr_name]

        labels.append({
            'pos'  : network.face_centroid(fkey),
            'text' : formatter(value),
            'name' : '{0}.face.label.{1}'.format(network.attributes['name'], fkey),
            'color': colordict[fkey]
        })

    rhino.xdraw_labels(
        labels,
        layer=layer,
        clear=False,
        redraw=True
    )
Beispiel #7
0
def draw_network(network,
                 layer=None,
                 clear_layer=False,
                 vertexcolor=None,
                 edgecolor=None,
                 edgelabel=None):
    """Draw a network data structure in Rhino.

    Parameters:
        network (compas.datastructures.network.Network): The network object.
        layer (str): Optional. The layer to draw in. Default is ``None``. If
            ``None``, the currenlt layer is used.
        clear_layer (bool): Optional. Clear the layer if ``True``. Default is ``False``.
        vertexcolor (list, tuple, str, dict): Optional. The color specification
            for the vertices. Default is ``None``.

                * list, tuple: rgb color, with color specs between 0 and 255 (e.g. ``(255, 0, 0)``).
                * str: hex color (e.g. ``'#ff0000'``).
                * dict: dictionary of hex or rgb colors.

        edgecolor (list, tuple, str, dict): Optional. The color specification
            for the edges. Default is ``None``.

                * list, tuple: rgb color, with color specs between 0 and 255 (e.g. ``(255, 0, 0)``).
                * str: hex color (e.g. ``'#ff0000'``).
                * dict: dictionary of hex or rgb color.

    Note:
        * Any network objects with the same name that are already present in the
          model will be deleted by this function.
        * To also clear the entire layer the network will be drawn on, for
          example, if you have a dedicated network layer, use the ``clear_layer`` flag as well.

    See Also:
        * :class:`compas.datastructures.network.Network`
        * :func:`compas_rhino.utilities.drawing.xdraw_lines`
        * :func:`compas_rhino.utilities.drawing.xdraw_points`

    Example:

        .. code-block:: python
            :emphasize-lines: 7

            import compas
            from compas.datastructures.network import Network
            from compas.cad import rhino as compas_rhino

            network = Network.from_obj(compas.get_data('lines.obj'))

            compas_rhino.draw_network(network)

    """
    vertexcolor = color_to_colordict(vertexcolor,
                                     network.vertices(),
                                     default=network.attributes['color.vertex'],
                                     colorformat='rgb',
                                     normalize=False)

    edgecolor = color_to_colordict(edgecolor,
                                   network.edges(),
                                   default=network.attributes['color.edge'],
                                   colorformat='rgb',
                                   normalize=False)

    edgelabel = edgelabel or {}

    points = []
    for key, attr in network.vertices(True):
        points.append({
            'pos'  : network.vertex_coordinates(key),
            'name' : '{0}.vertex.{1}'.format(network.attributes['name'], repr(key)),
            'color': vertexcolor[key]
        })

    lines = []
    for u, v, attr in network.edges(True):
        lines.append({
            'start': network.vertex_coordinates(u),
            'end'  : network.vertex_coordinates(v),
            'name' : '{0}.edge.{1}-{2}'.format(network.attributes['name'], repr(u), repr(v)),
            'color': edgecolor[(u, v)]
        })

    labels = []
    for (u, v), text in edgelabel.items():
        labels.append({
            'pos'  : network.edge_midpoint(u, v),
            'text' : str(text),
            'name' : '{0}.edge.label.{1}-{2}'.format(network.attributes['name'], repr(u), repr(v)),
            'color': edgecolor[(u, v)],
        })

    guids = rhino.get_objects(name='{0}.*'.format(network.attributes['name']))
    rhino.delete_objects(guids)

    rhino.xdraw_points(
        points,
        layer=layer,
        clear=clear_layer,
        redraw=False
    )
    rhino.xdraw_lines(
        lines,
        layer=layer,
        clear=False,
        redraw=False
    )
    rhino.xdraw_labels(
        labels,
        layer=layer,
        clear=False,
        redraw=True
    )
Beispiel #8
0
def display_network_axial_forces(network,
                                 display=True,
                                 layer=None,
                                 clear_layer=False,
                                 scale=1.0,
                                 attr_name='f',
                                 color_tension=(255, 0, 0),
                                 color_compression=(0, 0, 255)):
    """Display the axial forces in the edges of a network.

    Parameters:
        network (compas.datastructures.network.Network):
            The network object.
        display (bool): Optional.
            If ``True``, display the axial forces.
            If ``False``, don't display the axial forces.
            Default is ``True``.
        layer (str): Optional.
            The layer to draw in. Default is ``None``.
        clear_layer (bool): Optional.
            Flag for clearing the layer.
            Default is ``False``.
        scale (float): Optional.
            The scale of the forces.
            Default is ``1.0``.
        attr_name (str): Optional.
            The name of the edge attribute storing the force value.
            Default is ``'f'``.
        color_tension (tuple): Optional.
            The color to use for tension forces.
            Default is ``(255, 0, 0)``.
        color_compression (tuple): Optional.
            The color to use for compression forces.
            Default is ``(0, 0, 255)``.

    Example:

        .. code-block:: python

            import random
            import compas
            from compas.cad import rhino as compas_rhino

            from compas.datastructures.network import Network

            network = Network.from_obj(compas.get_data('lines.obj'))

            for u, v, attr in network.edges(True):
                attr['f'] = random.choice([-1.0, 1.0]) * random.randint(1, 10)

            compas_rhino.display_network_axial_forces(network)

    See Also:
        * :func:`display_network_reaction_forces`
        * :func:`display_network_residual_forces`
        * :func:`display_network_selfweight`

    """
    tol = rhino.get_tolerance()
    objects = rhino.get_objects(name='{0}.force:axial.*'.format(network.attributes['name']))
    rhino.delete_objects(objects)

    if not display:
        return

    lines = []

    for u, v, attr in network.edges(True):
        start  = network.vertex_coordinates(u)
        end    = network.vertex_coordinates(v)
        force  = attr['f']
        color  = color_tension if force > 0.0 else color_compression
        radius = scale * ((force ** 2) ** 0.5 / 3.14159) ** 0.5
        name   = '{0}.force:axial.{1}-{2}'.format(network.attributes['name'], u, v)

        if radius < tol:
            continue

        lines.append({
            'start' : start,
            'end'   : end,
            'name'  : name,
            'color' : color,
            'radius': radius,
        })

    rhino.xdraw_cylinders(lines, layer=layer, clear=clear_layer)
Beispiel #9
0
def display_mesh_edge_labels(mesh,
                             attr_name=None,
                             layer=None,
                             color=None,
                             formatter=None):
    """Display labels for the edges of a mesh.

    Parameters:
        mesh (compas.datastructures.mesh.Mesh): The mesh object.
        attr_name (str): Optional. The name of the attribute value to display in the label.
            Default is ``None``. If ``None``, the key of the edge is displayed.
        layer (str): Optional. The layer to draw in. Default is ``None``.
        color (str, tuple, list, dict): Optional. The color specification. Default is ``None``.
            The following values are supported:

                * str: A HEX color. For example, ``'#ff0000'``.
                * tuple, list: RGB color. For example, ``(255, 0, 0)``.
                * dict: A dictionary of RGB and/or HEX colors.

            If ``None``, the default edge color of the mesh will be used.
        formatter (callable): Optional. A formatting function. Default is ``None``.

    Example:

        .. code-block:: python

            import compas
            from compas.cad import rhino as compas_rhino

            from compas.datastructures.mesh import Mesh

            mesh = Mesh.from_obj(compas.get_data('faces.obj'))

            compas_rhino.display_mesh_edge_labels(mesh)


    See Also:
        * :func:`display_mesh_vertex_labels`
        * :func:`display_mesh_face_labels`

    """
    compas_rhino.delete_objects(
        compas_rhino.get_objects(
            name="{0}.edge.label.*".format(mesh.attributes['name'])))

    if not attr_name:
        attr_name = 'key'

    colordict = color_to_colordict(color,
                                   mesh.edges(),
                                   default=mesh.attributes['color.edge'],
                                   colorformat='rgb',
                                   normalize=False)
    if formatter:
        if not callable(formatter):
            raise Exception('The provided formatter is not callable.')
    else:
        formatter = str

    labels = []

    for index, (u, v, attr) in enumerate(mesh.edges(True)):

        if attr_name == 'key':
            value = '{0}-{1}'.format(u, v)
        elif attr_name == 'index':
            value = index
        else:
            value = attr[attr_name]

        labels.append({
            'pos':
            mesh.edge_midpoint(u, v),
            'text':
            formatter(value),
            'name':
            '{0}.edge.label.{1}-{2}'.format(mesh.attributes['name'], u, v),
            'color':
            colordict[(u, v)],
        })

    compas_rhino.xdraw_labels(labels, layer=layer, clear=False, redraw=True)
Beispiel #10
0
def draw_mesh(
    mesh,
    layer=None,
    clear_layer=False,
    show_faces=True,
    show_vertices=False,
    show_edges=False,
    show_wireframe=False,
    vertexcolor=None,
    edgecolor=None,
    wireframecolor=None,
    facecolor=None,
):
    """
    Draw a mesh object in Rhino.

    Parameters:
        mesh (compas.datastructures.mesh.Mesh): The mesh object.
        layer (str): Optional. The layer to draw in. Default is ``None``.
        clear_layer (bool): Optional. Clear the drawing layer. Default is ``True``.
        show_faces (bool): Optional. Show the faces. Default is ``True``.
        show_vertices (bool): Optional. Show the vertices. Default is ``True``.
        show_edges (bool): Optional. Show the edges. Default is ``True``.
        vertexcolor (str, tuple, list, dict): Optional. The vertex color specification. Default is ``None``.
        edgecolor (str, tuple, list, dict): Optional. The edge color specification. Default is ``None``.
        facecolor (str, tuple, list, dict): Optional. The face color specification. Default is ``None``.
        redraw (bool): Optional. Redraw instructions. Default is ``True``.

    Note:
        Colors can be specifiedin different ways:

        * str: A hexadecimal color that will be applied to all elements subject to the specification.
        * tuple, list: RGB color that will be applied to all elements subject to the specification.
        * dict: RGB or hex color dict with a specification for some or all of the related elements.

    Important:
        RGB colors should specify color values between 0 and 255.

    """

    vertexcolor = color_to_colordict(vertexcolor,
                                     mesh.vertices(),
                                     default=mesh.attributes['color.vertex'],
                                     colorformat='rgb',
                                     normalize=False)

    edgecolor = color_to_colordict(edgecolor,
                                   mesh.edges(),
                                   default=mesh.attributes['color.edge'],
                                   colorformat='rgb',
                                   normalize=False)

    # facecolor = color_to_colordict(facecolor,
    #                                mesh.faces(),
    #                                default=mesh.attributes['color.face'],
    #                                colorformat='rgb',
    #                                normalize=False)

    guids = compas_rhino.get_objects(
        name='{0}.*'.format(mesh.attributes['name']))
    compas_rhino.delete_objects(guids)

    if clear_layer:
        if not layer:
            compas_rhino.clear_current_layer()
        else:
            compas_rhino.clear_layer(layer)

    if show_faces:
        key_index = {key: index for index, key in enumerate(mesh.vertices())}
        xyz = [mesh.vertex_coordinates(key) for key in mesh.vertices()]
        faces = []
        color = mesh.attributes['color.face']

        for fkey in mesh.face:
            face = mesh.face_vertices(fkey, ordered=True)
            v = len(face)

            if v < 3:
                print('Degenerate face: {0} => {1}'.format(fkey, face))
            elif v == 3:
                faces.append([key_index[k] for k in face + [face[-1]]])
            elif v == 4:
                faces.append([key_index[k] for k in face])
            else:
                c = len(xyz)
                xyz.append(mesh.face_center(fkey))
                for i in range(-1, len(face) - 1):
                    key = face[i]
                    nbr = face[i + 1]
                    vertices = [
                        c, key_index[key], key_index[nbr], key_index[nbr]
                    ]
                    faces.append(vertices)

        compas_rhino.xdraw_mesh(xyz,
                                faces,
                                color,
                                '{0}.mesh'.format(mesh.attributes['name']),
                                layer=layer,
                                clear=False,
                                redraw=False)

    if show_edges:
        lines = []
        color = mesh.attributes['color.edge']
        for u, v in mesh.edges():
            lines.append({
                'start':
                mesh.vertex_coordinates(u),
                'end':
                mesh.vertex_coordinates(v),
                'name':
                '{0}.edge.{1}-{2}'.format(mesh.attributes['name'], repr(u),
                                          repr(v)),
                'color':
                edgecolor.get((u, v), color),
            })
        compas_rhino.xdraw_lines(lines, layer=layer, clear=False, redraw=False)

    if show_wireframe:
        lines = []
        color = mesh.attributes['color.edge']
        for u, v in mesh.wireframe():
            lines.append({
                'start':
                mesh.vertex_coordinates(u),
                'end':
                mesh.vertex_coordinates(v),
                'name':
                '{0}.edge.{1}-{2}'.format(mesh.attributes['name'], repr(u),
                                          repr(v)),
                'color':
                edgecolor.get((u, v), color),
            })
        compas_rhino.xdraw_lines(lines, layer=layer, clear=False, redraw=False)

    if show_vertices:
        points = []
        color = mesh.attributes['color.vertex']
        for key in mesh.vertices():
            points.append({
                'pos':
                mesh.vertex_coordinates(key),
                'name':
                '{0}.vertex.{1}'.format(mesh.attributes['name'], repr(key)),
                'color':
                vertexcolor.get(key, color),
            })
        compas_rhino.xdraw_points(points,
                                  layer=layer,
                                  clear=False,
                                  redraw=False)

    rs.EnableRedraw()
    rs.Redraw()
Beispiel #11
0
def draw_volmesh(volmesh,
                 name=None,
                 layer=None,
                 clear=True,
                 redraw=True,
                 show_faces=True,
                 show_vertices=True,
                 show_edges=True,
                 vertex_color=None,
                 edge_color=None,
                 face_color=None):
    """"""
    # set default options
    if not isinstance(vertex_color, dict):
        vertex_color = {}
    if not isinstance(edge_color, dict):
        edge_color = {}
    if not isinstance(face_color, dict):
        face_color = {}
    if name:
        volmesh.attributes['name'] = name
    name = volmesh.setdefault('name', name)
    if layer:
        volmesh.attributes['layer'] = layer
    layer = volmesh.setdefault('layer', layer)
    # delete all relevant objects by name
    objects = rhino.get_objects(name='{0}.mesh'.format(name))
    objects += rhino.get_objects(name='{0}.vertex.*'.format(name))
    objects += rhino.get_objects(name='{0}.edge.*'.format(name))
    rhino.delete_objects(objects)
    # clear the layer if requested
    if clear:
        rhino.clear_layers([layer])
    # draw the requested components
    if show_faces:
        faces = []
        color = volmesh.attributes['color.face']
        for vertices in volmesh.faces():
            points = [
                volmesh.vertex_coordinates(vkey)
                for vkey in vertices + [vertices[0]]
            ]
            faces.append({
                'points': points,
                'name': '',
                'color': color,
            })
        rhino.xdraw_faces(faces, layer=layer, clear=False, redraw=False)
    if show_edges:
        lines = []
        color = volmesh.attributes['color.edge']
        for u, v in volmesh.edges_iter():
            lines.append({
                'start': volmesh.vertex_coordinates(u),
                'end': volmesh.vertex_coordinates(v),
                'name': '{0}.edge.{1}-{2}'.format(name, u, v),
                'color': edge_color.get((u, v), color),
            })
        rhino.xdraw_lines(lines, layer=layer, clear=False, redraw=False)
    if show_vertices:
        points = []
        color = volmesh.attributes['color.vertex']
        for key in volmesh.vertices_iter():
            points.append({
                'pos': volmesh.vertex_coordinates(key),
                'name': '{0}.vertex.{1}'.format(name, key),
                'color': vertex_color.get(key, color),
            })
        rhino.xdraw_points(points, layer=layer, clear=False, redraw=False)
    # redraw if requested
    if redraw:
        rs.Redraw()