示例#1
0
文件: vapory.py 项目: draustin/otk
def make_circular_spherical_lens(roc1, roc2, thickness, radius, n, *args):
    sag1 = functions.calc_sphere_sag(roc1, radius)
    sag2 = functions.calc_sphere_sag(roc2, radius)

    sections = []
    surface1 = vp.Sphere([0, 0, roc1], abs(roc1))
    if roc1 > 0:
        sections.append(
            vp.Intersection(surface1,
                            vp.Cylinder([0, 0, 0], [0, 0, sag1], radius)))
    elif roc1 < 0:
        sections.append(
            vp.Difference(vp.Cylinder([0, 0, sag1], [0, 0, 0], radius),
                          surface1))

    sections.append(
        vp.Cylinder([0, 0, max(sag1, 0)], [0, 0, thickness + min(sag2, 0)],
                    radius))

    surface2 = vp.Sphere([0, 0, thickness + roc2], abs(roc2))
    if roc2 < 0:
        sections.append(
            vp.Intersection(
                surface2,
                vp.Cylinder([0, 0, thickness + sag2], [0, 0, thickness],
                            radius)))
    elif roc2 > 0:
        sections.append(
            vp.Difference(
                vp.Cylinder([0, 0, thickness], [0, 0, thickness + sag2],
                            radius), surface2))

    lens = vp.Union(*sections, vp.Texture('T_Glass3'), vp.Interior('ior', n),
                    *args)
    return lens
示例#2
0
def _generate_objects(representations):
    objects = []

    for rep in representations:
        if rep['type'] == 'spheres':
            for (x, y, z), r, c in zip(rep['options']['coordinates'],
                                       rep['options']['radii'],
                                       rep['options']['colors']):
                # Generate the shape
                sphere = vp.Sphere( [x,y,z] , r, vp.Texture( vp.Pigment( 'color', hex2rgb(c)) ))
                objects.append(sphere)

        elif rep['type'] == 'points':
            # Render points as small spheres
            for (x, y, z), c, s in zip(rep['options']['coordinates'],
                                    rep['options']['colors'],
                                    rep['options']['sizes']):
                # Point = sphere with a small radius
                sphere = vp.Sphere( [x,y,z] , s * 0.15,
                                    vp.Texture( vp.Pigment( 'color', hex2rgb(c)) ))
                objects.append(sphere)

        elif rep['type'] == 'surface':
            verts = rep['options']['verts']
            faces = rep['options']['faces']
            color = rep['options']['color']
            triangles = verts.take(faces, axis=0)

            for v1, v2, v3 in triangles:
                povt = vp.Triangle(v1.tolist(),
                                   v2.tolist(),
                                   v3.tolist(),
                                   vp.Texture(vp.Pigment('color', hex2rgb(color))))
                objects.append(povt)

        elif rep['type'] == 'cylinders':
            start = rep['options']['startCoords']
            end = rep['options']['endCoords']
            radii = rep['options']['radii']
            colors = rep['options']['colors']

            for s, e, r, c in zip(start, end, radii, colors):
                cylinder = vp.Cylinder(s.tolist(), e.tolist(), r,
                                       vp.Texture(vp.Pigment('color', hex2rgb(c))))
                objects.append(cylinder)

        else:
            print("No support for representation type: %s" % rep['type'])

    return objects
示例#3
0
def PovrayArrow(position, direction, color):
    """
    This function creates the arrow with the library vapory
    (https://pypi.org/project/Vapory/). It helps to process the image.

    :param position: It is the position where the object is going to be ubicated.
    :type position: list
    :param direction: It is the course along which the object moves.
    :type direction: list
    :param color: It is representes by the RGB color model. It is an additive color
    model in which red, green, and blue light are added together in various ways to
    reproduce a broad array of colors.
    :type color: list

    :return: It returns an ``Union()`` of three 3D figures, that represent the
    ``PovrayArrow()``.
    :rtype: ``Union()``
    """
    position = numpy.array(position)
    direction = numpy.array(direction) * 0.9
    base_point_cylinder = position - 0.5 * direction
    cap_point_cone = position + 0.7 * direction
    cap_point_cylinder = base_point_cone = base_point_cylinder + 0.7 * direction

    radius_cylinder = 1 / 20
    base_radius_cone = 1 / 6

    texture = vapory.Texture(vapory.Pigment("color", color),
                             vapory.Finish("roughness", 0, "ambient", 0.2))

    cylinder = vapory.Cylinder(base_point_cylinder, cap_point_cylinder,
                               radius_cylinder, texture)

    cone = vapory.Cone(base_point_cone, base_radius_cone, cap_point_cone, 0.0,
                       texture)

    sphere = vapory.Sphere(
        position,
        2 * radius_cylinder,
        vapory.Texture(vapory.Pigment("color", [0, 0, 0])),
    )

    return vapory.Union(sphere, vapory.Union(cone, cylinder))
示例#4
0
    def scene(pack,
              cmap=None,
              rot=0,
              camera_height=0.7,
              camera_dist=1.5,
              angle=None,
              lightstrength=1.1,
              orthographic=False,
              pad=None,
              floater_color=(.6, .6, .6),
              bgcolor=(1, 1, 1),
              box_color=(.5, .5, .5),
              group_indexes=None,
              clip=False):
        """
        Render a 3D scene.

        Requires `vapory` package, which requires the `povray` binary.

        Parameters
        ----------
        cmap : a colormap
        box_color : Color to draw the box. 'None' => don't draw box.
        floater_color : Color for floaters. 'None' => same color as non-floaters (use cmap).
        group_indexes : a list of indexes for each "group" that should remain
                together on the same side of the box.
        clip : clip the spheres at the edge of the box.

        Returns
        -------
        scene : vapory.Scene, which can be rendered using its `.render()` method.
        """
        import vapory
        import numpy as np

        try:
            import matplotlib as mpl
            import matplotlib.cm as mcm
            vmin, vmax = min(pack.diameters), max(pack.diameters)
            sm = mcm.ScalarMappable(norm=mpl.colors.Normalize(vmin, vmax),
                                    cmap=cmap)
            cols = [sm.to_rgba(s) for s in pack.diameters]
        except ImportError:
            if not isinstance(cmap, list):
                raise ValueError(
                    "matplotlib could not be imported, and cmap not recognizeable as a list"
                )
            cols = list(cmap)
        except TypeError:
            if not isinstance(cmap, list):
                raise ValueError(
                    "matplotlib could not convert cmap to a colormap," +
                    " and cmap not recognizeable as a list")
            cols = list(cmap)

        if floater_color is not None:
            ix, _ = pack.backbone()
            ns, = np.nonzero(~ix)
            for n in ns:
                cols[n] = floater_color

        mod_add = .5 if not clip else 0.
        rs = np.remainder(pack.rs + mod_add, 1) - mod_add
        if group_indexes is not None:
            for ix in group_indexes:
                xs = pack.rs[ix, :]
                com = np.mean(xs, axis=0)
                comdiff = (np.remainder(com + mod_add, 1) - mod_add) - com
                rs[ix, :] = xs + comdiff

        if clip:
            spheres = []
            cube = vapory.Box((-.5, -.5, -.5), (.5, .5, .5))
            dxs = [-1., 0.]
            drs = np.array([(dx, dy, dz) for dx in dxs for dy in dxs
                            for dz in dxs])
            maxr = 0

            for xyz, s, col in zip(rs, pack.diameters, cols):
                for dr in drs:
                    r = dr + xyz
                    if np.any(abs(r) - s / 2. > .5):
                        # not in the box
                        continue
                    sphere = vapory.Sphere(r, s / 2.)
                    cutsphere = vapory.Intersection(
                        cube, sphere,
                        vapory.Texture(vapory.Pigment('color', col[:3])))
                    spheres.append(cutsphere)
                    if np.amax(r) > maxr:
                        maxr = np.amax(r)
        else:
            spheres = [
                vapory.Sphere(xyz, s / 2.,
                              vapory.Texture(vapory.Pigment('color', col[:3])))
                for xyz, s, col in zip(rs, pack.diameters, cols)
            ]
            maxr = np.amax(np.amax(np.abs(rs), axis=1) + pack.diameters / 2.)

        extent = (-.5, .5)
        corners = [
            np.array((x, y, z)) for x in extent for y in extent for z in extent
        ]
        pairs = [(c1, c2) for c1 in corners for c2 in corners
                 if np.allclose(np.sum((c1 - c2)**2), 1) and sum(c1 - c2) > 0]

        radius = 0.01
        cyls, caps = [], []
        if box_color is not None:
            col = vapory.Texture(vapory.Pigment('color', box_color))
            cyls = [vapory.Cylinder(c1, c2, 0.01, col) for c1, c2 in pairs]
            caps = [vapory.Sphere(c, radius, col) for c in corners]

        light_locs = [[8., 5., -3.], [-6., 6., -5.], [-6., -7., -4.],
                      [10., -5., 7.]]

        rotlocs = [[
            x * np.cos(rot) - z * np.sin(rot), y,
            z * np.cos(rot) + x * np.sin(rot)
        ] for x, y, z in light_locs]
        lights = [
            # vapory.LightSource( [2,3,5], 'color', [1,1,1] ),
            vapory.LightSource(loc, 'color', [lightstrength] * 3)
            for loc in rotlocs
        ]
        cloc = [
            np.cos(rot) * camera_dist, camera_dist * camera_height,
            np.sin(rot) * camera_dist
        ]
        # mag = sqrt(sum([d**2 for d in cloc]))
        # direction = [-v*2/mag for v in cloc]

        if angle is None:
            if pad is None:
                pad = max(pack.diameters)
            w = sqrt(2) * maxr + pad
            angle = float(np.arctan2(w, 2 * camera_dist)) * 2 * 180 / np.pi
        camera = vapory.Camera('location', cloc, 'look_at', [0, 0, 0], 'angle',
                               angle)
        # vapory.Camera('orthographic', 'location', cloc, 'direction',
        #               direction, 'up', [0,2,0], 'right', [2,0,0])

        return vapory.Scene(camera,
                            objects=(lights + spheres + cyls + caps +
                                     [vapory.Background("color", bgcolor)]))
示例#5
0
def _generate_objects(representations):
    objects = []

    for rep in representations:
        if rep['rep_type'] == 'spheres':
            for i, (x, y, z) in enumerate(rep['options']['coordinates']):
                r = rep['options']['radii'][i]
                c = rep['options']['colors'][i]
                # Generate the shape
                sphere = vp.Sphere([x, y, z], r,
                                   vp.Texture(vp.Pigment('color', hex2rgb(c))))
                objects.append(sphere)

        elif rep['rep_type'] == 'points':
            # Render points as small spheres
            for i, (x, y, z) in enumerate(rep['options']['coordinates']):
                c = rep['options']['colors'][i]
                s = rep['options']['sizes'][i]
                if not 'alpha' in rep['options']:
                    t = 1.0
                else:
                    t = rep['options']['alpha'][i]

                # Point = sphere with a small radius
                sphere = vp.Sphere([x, y, z], s * 0.15,
                                   vp.Texture(
                                       vp.Pigment('color', 'rgbf',
                                                  hex2rgb(c) + (1 - t, ))),
                                   vp.Interior('ior', 1.0))
                objects.append(sphere)

        elif rep['rep_type'] == 'surface':
            verts = rep['options']['verts']
            faces = rep['options']['faces']
            color = rep['options']['color']
            triangles = verts.take(faces, axis=0)

            for v1, v2, v3 in triangles:
                povt = vp.Triangle(
                    v1.tolist(), v2.tolist(), v3.tolist(),
                    vp.Texture(vp.Pigment('color', hex2rgb(color))))
                objects.append(povt)

        elif rep['rep_type'] == 'cylinders':
            start = rep['options']['startCoords']
            end = rep['options']['endCoords']
            colors = rep['options']['colors']

            for i, (s, e) in enumerate(zip(start, end)):
                r = rep['options']['radii'][i]
                c = rep['options']['colors'][i]
                t = _get_transparency(rep['options'], i)

                cylinder = vp.Cylinder(
                    s.tolist(), e.tolist(), r,
                    vp.Texture(
                        vp.Pigment('color', 'rgbf',
                                   hex2rgb(c) + (1 - t, ))))
                objects.append(cylinder)

        elif rep['rep_type'] == 'lines':
            start = rep['options']['startCoords']
            end = rep['options']['endCoords']
            colors = rep['options']['startColors']

            for i, (s, e) in enumerate(zip(start, end)):
                #r = rep['options']['radii'][i]
                r = 0.02
                c = colors[i]
                t = _get_transparency(rep['options'], i)

                cylinder = vp.Cylinder(
                    s.tolist(), e.tolist(), r,
                    vp.Texture(
                        vp.Pigment('color', 'rgbf',
                                   hex2rgb(c) + (1 - t, ))))
                objects.append(cylinder)

        else:
            raise ValueError("No support for representation rep_type: %s" %
                             rep['rep_type'])

    return objects
示例#6
0
    def scene(pack,
              cmap=None,
              rot=0,
              camera_height=0.7,
              camera_dist=1.5,
              angle=None,
              lightstrength=1.1,
              orthographic=False,
              pad=None,
              floatercolor=(.6, .6, .6)):
        """
        Render a scene.
        
        Requires `vapory` package, which requires the `povray` binary.
        
        Parameters
        ----------
        cmap : a colormap 
        
        Returns
        -------
        scene : vapory.Scene, which can be rendered using its `.render()` method.
        """
        import vapory
        import numpy as np

        try:
            import matplotlib as mpl
            import matplotlib.cm as mcm
            vmin, vmax = min(pack.sigmas), max(pack.sigmas)
            sm = mcm.ScalarMappable(norm=mpl.colors.Normalize(vmin, vmax),
                                    cmap=cmap)
            cols = [sm.to_rgba(s) for s in pack.sigmas]
        except ImportError:
            if not isinstance(cmap, list):
                raise ValueError(
                    "matplotlib could not be imported, and cmap not recognizeable as a list"
                )
            cols = list(cmap)
        except TypeError:
            if not isinstance(cmap, list):
                raise ValueError(
                    "matplotlib could not convert cmap to a colormap, and cmap not recognizeable as a list"
                )
            cols = list(cmap)

        if floatercolor is not None:
            ix, _ = pack.backbone()
            ns, = np.nonzero(~ix)
            for n in ns:
                cols[n] = floatercolor
        rs = np.remainder(pack.rs + .5, 1) - .5
        spheres = [
            vapory.Sphere(xyz, s / 2.,
                          vapory.Texture(vapory.Pigment('color', col[:3])))
            for xyz, s, col in zip(rs, pack.sigmas, cols)
        ]

        extent = (-.5, .5)
        corners = [
            np.array((x, y, z)) for x in extent for y in extent for z in extent
        ]
        pairs = [(c1, c2) for c1 in corners for c2 in corners
                 if np.allclose(np.sum((c1 - c2)**2), 1) and sum(c1 - c2) > 0]

        radius = 0.01
        col = vapory.Texture(vapory.Pigment('color', [.5, .5, .5]))
        cyls = [vapory.Cylinder(c1, c2, 0.01, col) for c1, c2 in pairs]
        caps = [vapory.Sphere(c, radius, col) for c in corners]

        light_locs = [[8., 5., -3.], [-6., 6., -5.], [-6., -7., -4.],
                      [10., -5., 7.]]
        rotlocs = [[
            x * np.cos(rot) - z * np.sin(rot), y,
            z * np.cos(rot) + x * np.sin(rot)
        ] for x, y, z in light_locs]
        lights = [
            #vapory.LightSource( [2,3,5], 'color', [1,1,1] ),
            vapory.LightSource(loc, 'color', [lightstrength] * 3)
            for loc in rotlocs
        ]
        cloc = [
            np.cos(rot) * camera_dist, camera_dist * camera_height,
            np.sin(rot) * camera_dist
        ]
        mag = sqrt(sum([d**2 for d in cloc]))
        direction = [-v * 2 / mag for v in cloc]

        if angle is None:
            if pad is None: pad = max(pack.sigmas)
            w = sqrt(2) + pad
            angle = float(np.arctan2(w, 2 * camera_dist)) * 2 * 180 / np.pi
        camera = vapory.Camera('location', cloc, 'look_at', [0, 0, 0], 'angle',
                               angle)
        # vapory.Camera('orthographic', 'location', cloc, 'direction', direction, 'up', [0,2,0], 'right', [2,0,0])

        return vapory.Scene(camera,
                            objects=lights + spheres + cyls + caps +
                            [vapory.Background("color", [1, 1, 1])])