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
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
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))
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)]))
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
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])])