Ejemplo n.º 1
0
def _get_spheres(ctk_scene, d_args=None):
    """return the ASY string output to draw the spheres

    Arguments:
        ctk_scene {Scene} -- CTK Scene Object with ctk_scene.type == 'spheres'

    Keyword Arguments:
        d_args {dict} -- User defined defaults of the plot (default: {None})
    """
    assert ctk_scene.type == "spheres"
    updated_defaults = update_object_args(d_args,
                                          object_name="Spheres",
                                          allowed_args=["radius", "color"])

    positions = [tuple(pos) for pos in ctk_scene.positions]
    radius = ctk_scene.radius or updated_defaults["radius"]
    color = ctk_scene.color or updated_defaults["color"]
    color = color.replace("#", "")
    if ctk_scene.phiStart or ctk_scene.phiEnd:
        raise NotImplementedError

    # phiStart = ctk_scene.phiStart or 0 # not yet implemented
    # phiEnd = ctk_scene.phiEnd or 2*pi

    return (Environment().from_string(TEMP_SPHERE).render(positions=positions,
                                                          radius=radius,
                                                          color=color))
Ejemplo n.º 2
0
def _get_lines(ctk_scene, d_args=None):
    """return the ASY string output to draw cylinders

    Arguments:
        ctk_scene {Scene} -- CTK Scene Object with ctk_scene.type == 'cylinders'

    Keyword Arguments:
        d_args {dict} -- User defined defaults of the plot (default: {None})
    """
    assert ctk_scene.type == "lines"
    updated_defaults = update_object_args(
        d_args, object_name="Lines", allowed_args=["linewidth", "color"]
    )
    ipos = map(tuple, ctk_scene.positions[0::2])
    fpos = map(tuple, ctk_scene.positions[1::2])
    posPairs = [*zip(ipos, fpos)]

    linewidth = ctk_scene.linewidth or updated_defaults["linewidth"]
    color = ctk_scene.color or updated_defaults["color"]
    color = color.replace("#", "")
    return (
        Environment()
        .from_string(TEMP_LINE)
        .render(posPairs=posPairs, color=color, linewidth=linewidth)
    )
Ejemplo n.º 3
0
def _get_surface(ctk_scene, d_args=None):
    """return the ASY string output to draw cylinders

    Arguments:
        ctk_scene {Scene} -- CTK Scene Object with ctk_scene.type == 'surface'

    Keyword Arguments:
        d_args {dict} -- User defined defaults of the plot (default: {None})
    """
    assert ctk_scene.type == "surface"
    updated_defaults = update_object_args(
        d_args, object_name="Surfaces", allowed_args=["opacity", "color", "edge_width"]
    )
    color = ctk_scene.color or updated_defaults["color"]
    color = color.replace("#", "")
    opacity = ctk_scene.opacity or updated_defaults["opacity"]

    positions = tuple(
        map(lambda x: "{" + f"{x[0]}, {x[1]}, {x[2]}" + "}", ctk_scene.positions)
    )
    num_triangle = len(ctk_scene.positions) / 3.0
    # sanity check the mesh must be triangles
    assert num_triangle.is_integer()

    # # make decision on transparency
    # transparent = if obj_args['opacity'] < 0.99
    #
    # # asymptote just needs the xyz positions
    num_triangle = int(num_triangle)
    pos_xyz = tuple(
        chain.from_iterable(
            [
                (positions[itr * 3], positions[itr * 3 + 1], positions[itr * 3 + 2])
                for itr in range(num_triangle)
            ]
        )
    )
    #
    # # write the data array
    data_array_asy = (
        Environment()
        .from_string(TEMP_SURF)
        .render(positions=pos_xyz, face_color=color, opac=opacity)
    )

    return data_array_asy
Ejemplo n.º 4
0
def _get_line_from_vec(v0, v1, scene_args):
    """
    Draw the line given the two endpoints, some Three.js capabilities still
    don't work well in pythreejs (unable to update linewidth and such)
    LineSegments2 is the only one that has been tested successfully, but
    it cannot handle LineDashedMaterial
    :param v0: list, one endpoint of line
    :param v1: list, other endpoint of line
    :param scene_args: dict, properties of the line (line_width and color)
    :return: pythreejs object that displays the line segment
    """
    obj_args = update_object_args(scene_args, "Lines", ["linewidth", "color"])
    logger.debug(obj_args)
    line = LineSegments2(
        LineSegmentsGeometry(positions=[[v0, v1]]),
        LineMaterial(**obj_args),  # Dashed lines do not work in pythreejs yet
    )
    return line
Ejemplo n.º 5
0
def _get_surface_from_positions(positions, d_args, draw_edges=False):
    # get defaults
    obj_args = update_object_args(d_args, "Surfaces", ["color", "opacity"])
    num_triangle = len(positions) / 3.0
    assert num_triangle.is_integer()
    # make decision on transparency
    if obj_args["opacity"] > 0.99:
        transparent = False
    else:
        transparent = True

    num_triangle = int(num_triangle)
    index_list = [[itr * 3, itr * 3 + 1, itr * 3 + 2]
                  for itr in range(num_triangle)]
    # Vertex ositions as a list of lists
    surf_vertices = BufferAttribute(array=positions, normalized=False)
    # Indices
    surf_indices = BufferAttribute(array=np.array(index_list,
                                                  dtype=np.uint16).ravel(),
                                   normalized=False)
    geometry = BufferGeometry(attributes={
        "position": surf_vertices,
        "index": surf_indices
    })
    new_surface = Mesh(
        geometry=geometry,
        material=MeshLambertMaterial(
            color=obj_args["color"],
            side="DoubleSide",
            transparent=transparent,
            opacity=obj_args["opacity"],
        ),
    )
    if draw_edges == True:
        edges = EdgesGeometry(geometry)
        edges_lines = LineSegments(edges,
                                   LineBasicMaterial(color=obj_args["color"]))
        return new_surface, edges_lines
    else:
        return new_surface, None
Ejemplo n.º 6
0
def _get_cylinders(ctk_scene, d_args=None):
    """return the ASY string output to draw cylinders

    Arguments:
        ctk_scene {Scene} -- CTK Scene Object with ctk_scene.type == 'cylinders'

    Keyword Arguments:
        d_args {dict} -- User defined defaults of the plot (default: {None})
    """
    assert ctk_scene.type == "cylinders"
    updated_defaults = update_object_args(d_args,
                                          object_name="Cylinders",
                                          allowed_args=["radius", "color"])

    posPairs = [[tuple(ipos), tuple(fpos)]
                for ipos, fpos in ctk_scene.positionPairs]
    radius = ctk_scene.radius or updated_defaults["radius"]
    color = ctk_scene.color or updated_defaults["color"]
    color = color.replace("#", "")
    return (Environment().from_string(TEMP_CYLINDER).render(posPairs=posPairs,
                                                            color=color,
                                                            radius=radius))
Ejemplo n.º 7
0
def _get_cylinder_from_vec(v0, v1, d_args=None):
    """
    Draw the cylinder given the two endpoints.

    :param v0: list, one endpoint of line
    :param v1: list, other endpoint of line
    :param d_args: dict, properties of the line (line_width and color)
    :return: Mesh, pythreejs object that displays the cylinders
    """
    obj_args = update_object_args(d_args, "Cylinders", ["radius", "color"])
    v0 = np.array(v0)
    v1 = np.array(v1)
    vec = v1 - v0
    mid_point = (v0 + v1) / 2.0
    rot_vec = np.cross([0, 1, 0], vec)
    rot_vec_len = np.linalg.norm(rot_vec)
    rot_vec = rot_vec / rot_vec_len
    rot_arg = np.arccos(np.dot([0, 1, 0], vec) / np.linalg.norm(vec))
    new_bond = Mesh(
        geometry=CylinderBufferGeometry(
            radiusTop=obj_args["radius"],
            radiusBottom=obj_args["radius"],
            height=np.linalg.norm(v1 - v0),
            radialSegments=12,
            heightSegments=10,
        ),
        material=MeshLambertMaterial(color=obj_args["color"]),
        position=tuple(mid_point),
    )
    rot = R.from_rotvec(rot_arg * rot_vec)
    quat = tuple(rot.as_quat())
    if any(isnan(itr_q) for itr_q in quat):
        new_bond.quaternion = (0, 0, 0, 0)
    else:
        new_bond.quaternion = quat

    return new_bond