Source code for schrodinger.graphics3d.lines

"""
Maestro 3D lines.

The lines module allows creation and drawing of lines.  Clients draw
using Group instances not through Lines instances.

Control over the vertices, color, and width of the lines are provided.
See the Lines class for more info.

To draw any number of lines that share the same color and width, then
place them in a single Lines instance and add the instance to a Group
instance (LinesGroup can be used and is a synonym). Then invoke the
Group's draw() method.  A set of lines with a different width or color
should be placed into a separate Lines instance.

Copyright Schrodinger, LLC. All Rights Reserved

"""

import schrodinger

from . import common
from .common import Group

# NOTE: LinesGroup is deprecated; use Group class.
LinesGroup = Group

maestro = schrodinger.get_maestro()
try:
    from schrodinger.ui import maestro_ui
except ImportError:
    maestro_ui = None

# Constants used to calculate bounding box:
BOUNDING_BOX_INIT_VALUE = 100000000.0

###############################################################################


[docs]class MaestroLines(common.Primitive): """ Class representing a set of 3D lines to be added to the Workspace. Lines with the same characteristics must be placed (color, width) into a single Lines instance. API Example:: import schrodinger.maestro.maestro as maestro import schrodinger.graphics3d.common as common import schrodinger.graphics3d.lines as lines line_grp = common.Group() st = maestro.workspace_get() color='red' displacement = 1.0 for at in st.atom: segments = [ [(at.x - displacement, at.y, at.z), (at.x + displacement, at.y, at.z)], [(at.x, at.y - displacement, at.z), (at.x, at.y + displacement, at.z)], [(at.x, at.y, at.z - displacement), (at.x, at.y, at.z + displacement)], ] # Add the primatives to the container. line_grp.add(lines.Lines(segments, color=color)) # Hide the markers. line_grp.hide() # Remove the markers line_grp.clear() """
[docs] def __init__(self, segments, color=None, width=1.0): """ Lines constructor requires: segments: List of segments, where each segments is a tuple/list of 2 (x,y,z) coordinates: [(x1, y1, z1), (x1, y2, z2)]. color: One of: Color object (Color class) Color name (string) Tuple of (R, G, B) (each a float in range 0.0-1.0) Optional arguments: width (float): Defaults to 1.0. Lines are always drawn out anti-aliased. So the actual width is determined at rasterization time. Not all widths are supported and if an unsupported width is chosen, the nearest supported with is used. Only width 1 is guaranteed to be supported. """ if width < 0.01: raise ValueError("Must specify a width greater than 0.01") if color is None: raise ValueError("Must specify a color") r, g, b = common.color_arg_to_rgb(color) self._checkSegmentsArgument(segments) # Assume each item is itself a list of 3 (x, y, z) coordinates segment_objs = [] for coord1, coord2 in segments: point1 = maestro_ui.MM_GraphicsVec3d(*coord1) point2 = maestro_ui.MM_GraphicsVec3d(*coord2) obj = maestro_ui.MM_GraphicsLineSegment(point1, point2) segment_objs.append(obj) maestro_objects = [maestro.create_lines(segment_objs, r, g, b, width)] common.Primitive.__init__(self, maestro_objects)
def _checkSegmentsArgument(self, segments): """ Private method to check if the segments are in the correct format """ if not isinstance(segments, list): raise TypeError("Expecting a list for segments argument") elif len(segments) < 1: raise RuntimeError("At least one line segment is required") for segment in segments: try: p1, p2 = segment (x1, y1, z1) = p1 (x2, y2, z2) = p2 except (ValueError, TypeError): raise TypeError("Invalid segment: %s" % segment)