Source code for compas_blender.artists.networkartist


# from __future__ import annotations

from functools import partial

import compas_blender

from compas_blender.artists._artist import BaseArtist
from compas.utilities import color_to_colordict

colordict = partial(color_to_colordict, colorformat='rgb', normalize=True)


__all__ = [
    'NetworkArtist',
]


[docs]class NetworkArtist(BaseArtist): """Artist for COMPAS network objects. Parameters ---------- network : :class:`compas.datastructures.Network` A COMPAS network. settings : dict, optional A dict with custom visualisation settings. Attributes ---------- network : :class:`compas.datastructures.Network` The COMPAS network associated with the artist. settings : dict Default settings for color, scale, tolerance, ... """
[docs] def __init__(self, network): super().__init__() self._nodecollection = None self._edgecollection = None self._pathcollection = None self._object_node = {} self._object_edge = {} self._object_path = {} self.color_nodes = (1.0, 1.0, 1.0) self.color_edges = (0.0, 0.0, 0.0) self.show_nodes = True, self.show_edges = True, self.show_nodelabels = False, self.show_edgelabels = False self.network = network
@property def nodecollection(self): path = f"{self.network.name}::Nodes" if not self._nodecollection: self._nodecollection = compas_blender.create_collections_from_path(path)[1] return self._nodecollection @property def edgecollection(self): path = f"{self.network.name}::Edges" if not self._edgecollection: self._edgecollection = compas_blender.create_collections_from_path(path)[1] return self._edgecollection @property def pathcollection(self): path = f"{self.network.name}::Paths" if not self._pathcollection: self._pathcollection = compas_blender.create_collections_from_path(path)[1] return self._pathcollection @property def object_node(self): if not self._object_node: self._object_node = {} return self._object_node @object_node.setter def object_node(self, values): self._object_node = dict(values) @property def object_edge(self): if not self._object_edge: self._object_edge = {} return self._object_edge @object_edge.setter def object_edge(self, values): self._object_edge = dict(values) @property def object_path(self): if not self._object_path: self._object_path = {} return self._object_path @object_path.setter def object_path(self, values): self._object_path = dict(values)
[docs] def clear(self): objects = list(self.object_node) objects += list(self.object_edge) objects += list(self.object_path) compas_blender.delete_objects(objects, purge_data=True) self._object_node = {} self._object_edge = {} self._object_path = {}
[docs] def draw(self): """Draw the network. Returns ------- list of :class:`bpy.types.Object` The created Blender objects. """ self.clear() if self.show_nodes: self.draw_nodes() if self.show_edges: self.draw_edges() return self.objects
[docs] def draw_nodes(self, nodes=None, color=None): """Draw a selection of nodes. Parameters ---------- nodes : list of int, optional A list of node identifiers. Default is ``None``, in which case all nodes are drawn. color : rgb-tuple or dict of rgb-tuples The color specififcation for the nodes. Returns ------- list of :class:`bpy.types.Object` """ nodes = nodes or list(self.network.nodes()) node_color = colordict(color, nodes, default=self.color_nodes) points = [] for node in nodes: points.append({ 'pos': self.network.node_coordinates(node), 'name': f"{self.network.name}.node.{node}", 'color': node_color[node], 'radius': 0.05}) objects = compas_blender.draw_points(points, self.nodecollection) self.object_node = zip(objects, nodes) return objects
[docs] def draw_edges(self, edges=None, color=None): """Draw a selection of edges. Parameters ---------- edges : list A list of edge keys (as uv pairs) identifying which edges to draw. The default is ``None``, in which case all edges are drawn. color : rgb-tuple or dict of rgb-tuples The color specififcation for the edges. Returns ------- list of :class:`bpy.types.Object` """ edges = edges or list(self.network.edges()) edge_color = colordict(color, edges, default=self.color_edges) lines = [] for edge in edges: lines.append({ 'start': self.network.node_coordinates(edge[0]), 'end': self.network.node_coordinates(edge[1]), 'color': edge_color[edge], 'name': f"{self.network.name}.edge.{edge[0]}-{edge[1]}", 'width': 0.02}) objects = compas_blender.draw_lines(lines, self.edgecollection) self.object_edge = zip(objects, edges) return objects
# ============================================================================== # Main # ============================================================================== if __name__ == "__main__": pass