def _get_cylinder(self, start, end, radius): texture = vp.Texture( vp.Pigment('color', [1 / 255. * e for e in (0, 125, 255)])) c1 = vp.Sphere(start, radius, texture) c2 = vp.Sphere(end, radius, texture) c3 = vp.Cylinder(start, end, radius, texture) return vp.Union(c1, c2, c3)
def __init__(self, scale): segments = [] texture = vp.Texture( vp.Pigment('color', [1 / 255. * e for e in (40, 40, 40)])) for i in range(1, 1000): rands = numpy.random.normal(0, .03 * scale, 3) sphere = vp.Sphere(rands, 0.01, texture) segments.append(sphere) self.body = vp.Union() self.body.args = segments
def _get_cylinder(self, start, end, radius): color = (40 / 255., 40 / 255., 40 / 255.) texture = vp.Texture(vp.Pigment('color', color), vp.Finish("ambient", color, "diffuse", 0.0) ) c1 = vp.Sphere(start, radius, texture) c2 = vp.Sphere(end, radius, texture) c3 = vp.Cylinder(start, end, radius, texture) return vp.Union(c1, c2, c3)
def __init__(self): color = (80/255., 80/255., 80/255.) texture = vp.Texture(vp.Pigment('color', color), vp.Finish('ambient', color, 'diffuse', 0)) self.body = vp.Union(self._get_body(texture), self._get_trunk(texture), self._get_Handle(texture)) cos = math.cos(math.pi / 180 * 15) sin = math.sin(math.pi / 180 * 15) self.origin = [0, -(0.14 * cos + .24), -(.2 + 0.14 * sin)] self.body = self.body.add_args(["translate", self.origin]) self.position = [0, 0, 0] self.orientation = 0
def scene(t, objects): print("make scene") # sun = LightSource([1500 , 2500, tree = get_tree(make_tree(3), 0.7 - t / 500., 1 - t / 210.) random.seed() # print("make tree object") tree_list = [] trav((0, 0, 0, 0.07), tree, .05 - (t / 5000.), tree_list, 1 - t / 200., 0) tree = vp.Union() tree.args = tree_list objects.append(tree)
def __init__(self): self.blocks = [] for i in range(-1, 2): block = self._get_block().add_args(["translate", [i * .4, .0, .7]]) self.blocks.append(block) block = self._get_block().add_args( ["translate", [i * .4, .0, -.7]]) self.blocks.append(block) block = self._get_block().add_args(["translate", [i * .4, .2, .7]]) self.blocks.append(block) block = self._get_block().add_args( ["translate", [i * .4, .2, -.7]]) self.blocks.append(block) block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [.7, 0.1, 0.4 * i]]) self.blocks.append(block) block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [-.7, 0.1, 0.4 * i]]) self.blocks.append(block) for i in range(-2, 2): block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [.7, 0, 0.4 * i + .2]]) self.blocks.append(block) block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [-.7, 0, 0.4 * i + .2]]) self.blocks.append(block) block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [.7, 0.2, 0.4 * i + .2]]) self.blocks.append(block) block = self._get_block().add_args( ["rotate", [0, 90, 0], "translate", [-.7, 0.2, 0.4 * i + .2]]) self.blocks.append(block) block = self._get_block().add_args( ["translate", [0.4 * i + .2, 0.1, 0.7]]) self.blocks.append(block) block = self._get_block().add_args( ["translate", [0.4 * i + .2, 0.1, -0.7]]) self.blocks.append(block) color = (75, 71, 0) self.blocks.append( vapory.Box([-.79, 0, -0.79], [.79, 0.29, 0.79], vapory.Texture( vapory.Pigment('color', [0.8 / 255. * e for e in color])), vapory.Finish("ambient", [1 / 255. * e for e in color], "diffuse", 0.0))) self.foundation = vapory.Union() self.foundation.args = self.blocks self.foundation = self.foundation.add_args(["scale", [2, 2, 2]])
def _get_Handle(self, texture): d_deg = 10 elems = [] for i in range(0, 180, d_deg): sin = math.sin(math.pi / 180. * i) cos = math.cos(math.pi / 180. * i) start = [0, 0.14 * cos + .24, +.2 + 0.14 * sin] sin = math.sin(math.pi / 180. * (i + d_deg)) cos = math.cos(math.pi / 180. * (i + d_deg)) end = [0, 0.14 * cos + .24, +.2 + 0.14 * sin] elems.append(self._get_cylinder(start, end, 0.007, texture)) union = vp.Union() union.args = elems return union
def __init__(self): texture = vp.Texture( vp.Pigment('color', [0.15 * e for e in [0.50, 0.50, 0.10]]), vp.Finish("ambient", 1., "diffuse", 0)) cylinder1 = self._get_cylinder([0, 0, 0], [0, -1.15, 0], 0.02, texture) cylinder2 = self._get_cylinder([0, -1.15, 0], [0, -1.2, -0.015], 0.02, texture) #texture = vp.Texture(vp.Pigment('color', [0.15 * e for e in [0.50, 0.50, 0.10]]), # vp.Finish("phong", 0.9, "metallic", 10)) #texture = vp.Texture("Polished_Brass") shovel = Parametric(self._get_parametric_body(), texture, "scale", [0.5, 0.5, 0.5], "rotate", [0, 0, 90], "translate", [0.25, -1.2, -.045]) self.position = [0, 0, 0] self.orientation = 0 self.body = vp.Union(cylinder1, cylinder2, shovel)
def _get_block(self, x, y, z, radius): color = (240 + random.randint(-5, 5), 180 + random.randint(-5, 5), 75 + random.randint(-5, 5)) color = [0.25 * e for e in color] # radius = 0.01 x -= radius y -= radius z -= radius points = [] points.append([x, y, z]) points.append([x, y, -z]) points.append([x, -y, z]) points.append([x, -y, -z]) points.append([-x, y, z]) points.append([-x, y, -z]) points.append([-x, -y, z]) points.append([-x, -y, -z]) links = [] links.append([points[0], points[1]]) links.append([points[0], points[2]]) links.append([points[0], points[4]]) links.append([points[1], points[3]]) links.append([points[1], points[5]]) links.append([points[2], points[3]]) links.append([points[2], points[6]]) links.append([points[3], points[7]]) links.append([points[4], points[5]]) links.append([points[4], points[6]]) links.append([points[5], points[7]]) links.append([points[6], points[7]]) parts = [] for point in points: parts.append(self._get_sphere(point, radius, color)) for link in links: parts.append(self._get_cylinder(link[0], link[1], radius, color)) for i in range(0, 3): p1 = [-x, -y, -z] p2 = [x, y, z] p1[i] -= radius p2[i] += radius parts.append(self._get_box(p1, p2, color)) union = vp.Union() union.args = parts return union
def __init__(self, lim, off): segments = [] for i in range(3*off, min(3 * max(lim, 0), 10)): def add(i0_n, dx): i0 = -random.gauss(i0_n, .4) x0 = -i0 / 12. y0 = -x0 * x0 * 1. + dx x1 = -(i + i0) / 12. - x0 y1 = -(i + i0) * (i + i0) / 100. - y0 x2 = -(i + 1 + i0) / 12. - x0 y2 = -(i + 1 + i0) * (i + 1 + i0) / 100. - y0 segments.append(self._get_cylinder([0, y1, x1], [0, y2, x2], 0.014)) add(0, 0) add(-1.5, 0.05) add(2, -0.05) self.body = vp.Union() self.body.args = segments
def __init__(self, i): segments = [] i = i * 2 def add(i0_n, x): i0 = -random.gauss(i0_n, .2) x0 = i0 / (11. * x) + 1 y0 = -i0 * i0 / 100. x1 = (i + i0) / (11. * x) - x0 y1 = -(i + i0) * (i + i0) / 100. - y0 x2 = (i + 1 + i0) / (11. * x) - x0 y2 = -(i + 1 + i0) * (i + 1 + i0) / 100. - y0 segments.append(self._get_cylinder([0, y1, x1], [0, y2, x2], 0.02)) add(0, 1) add(0, 1.1) add(0, .9) self.body = vp.Union() self.body.args = segments
def __init__(self): def drange(start, stop, step): r = start while r < stop: yield r r += step def func(x): return 1 - 0.5 * (x - 1.1)**2 step = 0.05 segments = [] for x in drange(-6.4, 6.4, step): y = x + step cylinder = self._get_cylinder([0, func(x), x], [0, func(y), y], 0.02) segments.append(cylinder) self.body = vp.Union() self.body.args = segments
def __init__(self, filename=None, ratio=2., lift=0, simple=False): texture = vp.Texture( vp.Pigment('color', [0.1 * e for e in [0.20, 0.20, 0.20]]), vp.Finish("ambient", 1.0, "diffuse", 0.0)) cylinder = vp.Cylinder([0, 0, 0], [0, 2.5, 0], 0.02, texture) texture = vp.Texture( "" if simple else "uv_mapping", vp.Pigment(vp.ImageMap('png', filename, 'once')), vp.Finish("ambient", 1.0)) if filename is not None else vp.Texture( vp.Pigment('color', [0.9 * e for e in [1.0, 1.00, 1.00]]), vp.Finish("ambient", 1.0, "diffuse", 0.0)) sheet = vp.Polygon(5, [0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0], [0, 0, 0], texture, "scale", [ratio * 0.5, 0.5, 0], "translate", [0, 2, 0]) if simple else Parametric( self._get_parametric_body(), texture, "scale", [ratio * 0.5, 0.5, 0], "translate", [0, 2, 0]) # self.flag = vp.Union(cylinder, sheet) self.flag = self.flag.add_args( ["rotate", [0, 90, 0], "translate", [0, lift, 0]])
def _get_trunk(self, texture): c1 = vp.Cone([0, 0, 0], 0.024, [0, .4, 0], 0.014, texture) c2 = vp.Cone([0, .4, 0], 0.014, [0, .48, 0], 0.1, texture) return vp.Union(c1, c2, "rotate", [-45, 0, 0], "translate", [0, .066, -.180])
def _get_cylinder(self, start, end, radius): c1 = vp.Sphere(start, radius, vp.Texture("Brass_Metal")) c2 = vp.Sphere(end, radius, vp.Texture("Brass_Metal")) c3 = vp.Cylinder(start, end, radius, vp.Texture("Brass_Metal")) return vp.Union(c1, c2, c3)
def geometry_to_povray(appearance, geometry, object, transform, properties): if get_property_yes(properties, [geometry, object], "hide"): return [] #analyze appearance tex = get_property(properties, [geometry, object], 'texture') if tex is None: tex_params = [] #pigment pigment = get_property(properties, [geometry, object], 'pigment') if pigment is None: transmit = 1. - appearance.getColor()[3] pigment = vp.Pigment(*[ 'color', list(appearance.getColor())[0:3], 'transmit', get_property(properties, [geometry, object], 'ambient', transmit) ]) tex_params.append(pigment) #finish finish = get_property(properties, [geometry, object], 'finish') if finish is None: finish=vp.Finish(*['ambient',get_property(properties,[geometry,object],'ambient',0.2), \ 'diffuse',get_property(properties,[geometry,object],'diffuse',0.7), \ 'phong',get_property(properties,[geometry,object],'phong',1.), \ 'phong_size',get_property(properties,[geometry,object],'phong_size',50)]) tex_params.append(finish) #normal normal = get_property(properties, [geometry, object], 'normal') if normal is not None: tex_params.append(normal) #texture tex = vp.Texture(*tex_params) #create geometry ret = [] if transform is None: transform = geometry.getCurrentTransform() else: transform = se3.mul(transform, geometry.getCurrentTransform()) if geometry.type() == "GeometricPrimitive": prim = geometry.getGeometricPrimitive() if get_property_yes(properties, [prim, geometry, object], "hide"): return ret if prim.type == "Point": rad = get_property(properties, [prim, geometry, object], "radius") if rad is not None: mesh_param = [se3.apply(transform, prim.properties[0:3]), rad] mesh_param.append(tex) mesh = vp.Sphere(*mesh_param) ret.append(mesh) elif prim.type == "Sphere": mesh_param = [ se3.apply(transform, prim.properties[0:3]), prim.properties[3] ] mesh_param.append(tex) mesh = vp.Sphere(*mesh_param) ret.append(mesh) elif prim.type == "Segment": rad = get_property(properties, [prim, geometry, object], "radius") if rad is not None: mesh_param = [ se3.apply(transform, prim.properties[0:3]), se3.apply(transform, prim.properties[3:6]), rad ] mesh_param.append(tex) mesh = vp.Cylinder(*mesh_param) ret.append(mesh) elif prim.type == "AABB": mesh_param = [ se3.apply(transform, prim.properties[0:3]), se3.apply(transform, prim.properties[3:6]) ] mesh_param.append(tex) mesh = vp.Box(*mesh_param) ret.append(mesh) elif geometry.type() == "Group": for idElem in range(geometry.numElements()): elem = geometry.getElement(idElem) elem.getCurrentTransform() ret += geometry_to_povray(appearance=appearance, geometry=elem, object=object, transform=transform, properties=properties) elif geometry.type() == "TriangleMesh": tm = geometry.getTriangleMesh() if get_property_yes(properties, [geometry, object], "smooth"): vss = [ se3.apply(transform, tuple(tm.vertices[i * 3:i * 3 + 3])) for i in range(len(tm.vertices) // 3) ] iss = [ tuple(tm.indices[i * 3:i * 3 + 3]) for i in range(len(tm.indices) // 3) ] mesh_param = [ vp.VertexVectors(*([len(vss)] + vss)), vp.FaceIndices(*([len(iss)] + iss)) ] mesh_param.append(tex) mesh = vp.Mesh2(*mesh_param) else: vss = [ se3.apply(transform, tuple(tm.vertices[i * 3:i * 3 + 3])) for i in range(len(tm.vertices) // 3) ] iss = [ tuple(tm.indices[i * 3:i * 3 + 3]) for i in range(len(tm.indices) // 3) ] mesh_param = [ vp.Triangle(vss[it[0]], vss[it[1]], vss[it[2]]) for it in iss ] mesh_param.append(tex) mesh = vp.Mesh(*mesh_param) ret.append(mesh) elif geometry.type() == "VolumeGrid": from skimage import measure import numpy as np grid = geometry.getVolumeGrid() volume = np.reshape(np.array(list(grid.values)), tuple(grid.dims)) spacing = [ (b - a) / d for a, b, d in zip(grid.bbox[0:3], grid.bbox[3:6], grid.dims[0:3]) ] vss, iss, nss, _ = measure.marching_cubes_lewiner(volume, level=0., spacing=spacing) vss += np.expand_dims(np.array(grid.bbox[0:3]).T, 0) vss = [vss[it, :].tolist() for it in range(vss.shape[0])] iss = [iss[it, :].tolist() for it in range(iss.shape[0])] nss = [nss[it, :].tolist() for it in range(nss.shape[0])] mesh_param = [ vp.VertexVectors(*([len(vss)] + vss)), vp.NormalVectors(*([len(nss)] + nss)), vp.FaceIndices(*([len(iss)] + iss)) ] mesh_param.append(tex) mesh = vp.Mesh2(*mesh_param) ret.append(mesh) elif geometry.type() == "PointCloud": cloud_param = [] cloud = geometry.getPointCloud() rad = get_property(properties, [cloud, geometry, object], "radius") for id in range(len(cloud.vertices) // 3): cloud_param.append( vp.Sphere(cloud.vertices[id * 3:id * 3 + 3], rad)) cloud_param.append(tex) mesh = vp.Union(*cloud_param) ret.append(mesh) else: print("Geometry (name=%s) type: %s not supported!" % (object.getName(), geometry.type())) return ret
def to_povray(vis, world, properties={}): """Convert a frame in klampt visualization to a povray script (or render to an image) Args: vis: sub-class of GLProgram world: sub-class of WorldModel properties: some additional information that povray can take but does not map to anything in klampt. Note:: Do not modify properties, use the convenience functions that I provide below (after this function). These take the form ``render_to_x`` and ``add_x``. """ #patch on vapory patch_vapory() #camera mat = vis.view.camera.matrix() pos = mat[1] right = mat[0][0:3] up = mat[0][3:6] dir = op.mul(mat[0][6:9], -1) tgt = op.add(mat[1], dir) #scale fovy = vis.view.fov * vis.view.h / vis.view.w fovx = math.atan(vis.view.w * math.tan(fovy * math.pi / 360.) / vis.view.h) * 360. / math.pi right = op.mul(right, -float(vis.view.w) / vis.view.h) #camera camera_params = [ 'orthographic' if vis.view.orthogonal else 'perspective', 'location', [pos[0], pos[1], pos[2]], 'look_at', [tgt[0], tgt[1], tgt[2]], 'right', [right[0], right[1], right[2]], 'up', [up[0], up[1], up[2]], 'angle', fovx, 'sky', get_property(properties, [], "sky", [0., 0., 1.]) ] camera = vp.Camera(*camera_params) #tempfile tempfile = get_property(properties, [], "tempfile", None) tempfile_path = os.path.dirname(tempfile) if tempfile is not None else '.' if not os.path.exists(tempfile_path): os.mkdir(tempfile_path) #objects objects = [] objs = [o for o in properties["visualObjects"] ] if "visualObjects" in properties else [] objs += [world.terrain(i) for i in range(world.numTerrains())] objs += [world.rigidObject(i) for i in range(world.numRigidObjects())] for r in range(world.numRobots()): objs += [ world.robot(r).link(i) for i in range(world.robot(r).numLinks()) ] for obj in objs: transient = get_property(properties, [obj], "transient", default=True) if transient: objects += geometry_to_povray(obj.appearance(), obj.geometry(), obj, None, properties=properties) else: path = tempfile_path + '/' + obj.getName() + '.pov' if not os.path.exists(path): R, t = obj.geometry().getCurrentTransform() obj.geometry().setCurrentTransform([1, 0, 0, 0, 1, 0, 0, 0, 1], [0, 0, 0]) geom = geometry_to_povray(obj.appearance(), obj.geometry(), obj, None, properties=properties) if len(geom) > 1: file_content = vp.Union(*geom) elif len(geom) > 0: file_content = vp.Object(*geom) else: file_content = None if file_content is not None: f = open(path, 'w') f.write(str(file_content)) f.close() obj.geometry().setCurrentTransform(R, t) else: path = None #include if path is not None: R, t = obj.geometry().getCurrentTransform() objects.append( vp.Object('#include "%s"' % path, "matrix", R + t)) #light if "lights" in properties: objects += properties["lights"] #scene gsettings = [] scene = vp.Scene(camera=camera, objects=objects, included=get_property(properties, [], "included", []), global_settings=get_property(properties, [], "global_settings", [])) try: #this works with later version of vapory return \ render_povstring(str(scene), \ outfile=get_property(properties,[],"outfile",None), \ width=vis.view.w,height=vis.view.h, \ quality=get_property(properties,[],"quality",None), \ antialiasing=get_property(properties,[],"antialiasing",0.3), \ remove_temp=get_property(properties,[],"remove_temp",False), \ show_window=get_property(properties,[],"show_window",False), \ tempfile=tempfile, \ includedirs=get_property(properties,[],"includedirs",None), \ output_alpha=get_property(properties,[],"output_alpha",True)) except: #this works with earlier version of vapory return \ render_povstring(str(scene), \ outfile=get_property(properties,[],"outfile",None), \ width=vis.view.w,height=vis.view.h, \ quality=get_property(properties,[],"quality",None), \ antialiasing=get_property(properties,[],"antialiasing",0.3), \ remove_temp=get_property(properties,[],"remove_temp",False))
def __init__(self): cylinder1 = self._get_cylinder([0, 0, 0], [0, .45, 0], 0.02) cylinder2 = self._get_cylinder([0, .45, +0.015], [0, .45, -0.015], 0.04) self.body = vp.Union(cylinder1, cylinder2)
def _get_cylinder(self, start, end, radius, texture): c1 = vp.Sphere(start, radius, texture) c2 = vp.Sphere(end, radius, texture) c3 = vp.Cylinder(start, end, radius, texture) return vp.Union(c1, c2, c3)
def __init__(self, dict_of_angles, crossarm=False, falda=False): width = 0.07 right_pelvis = [width, 0, 0] left_pelvis = [-width, 0, 0] rad = (dict_of_angles["torso"]) * math.pi / 180. neck = [1.5 * width, 0 - 0.6 * math.cos(rad), 0.6 * math.sin(rad)] right_shoulder = [1.5 * width, neck[1], neck[2]] left_shoulder = [- 1.5 * width, neck[1], neck[2]] self.left_shoulder = left_shoulder right_knee = self.get_point(right_pelvis, dict_of_angles["thigh_1"], 0, .5) right_foot = self.get_point(right_knee, dict_of_angles["shin_1"], 0, .5) left_knee = self.get_point(left_pelvis, dict_of_angles["thigh_2"], 0, .5) left_foot = self.get_point(left_knee, dict_of_angles["shin_2"], 0, .5) left_elbow = self.get_point(left_shoulder, dict_of_angles["upper_arm1"], 0, .4) left_elbow = (left_elbow[0] - 0.04, left_elbow[1], left_elbow[2]) left_hand = self.get_point(left_elbow, dict_of_angles["lower_arm1"], 0, .4) right_elbow = self.get_point(right_shoulder, dict_of_angles["upper_arm2"], -0, .4) right_elbow = (right_elbow[0] + 0.04, right_elbow[1], right_elbow[2]) right_hand = self.get_point(right_elbow, dict_of_angles["lower_arm2"], -0, .4) if crossarm: left_hand = (-left_hand[0], left_hand[1], left_hand[2]) self.left_hand = left_hand self.right_hand = right_hand texture = vapory.Texture(vapory.Pigment('color', [0.0 * e for e in [0.20, 0.20, 0.20]]), vapory.Finish('phong', 0.0)) deg = (dict_of_angles["torso"]) self.torso = vapory.Box([-width, 0, -width / 2], [width, 0.6, width / 2], texture, "rotate", [-deg - 180, 0, 0], "translate", [0, 0, 0]) self.lower_left_leg = self.get_rounded_cylinder(left_knee, left_foot, 0.07 / 2, texture) self.upper_left_leg = self.get_rounded_cylinder(left_pelvis, left_knee, 0.07 / 2, texture) self.lower_right_leg = self.get_rounded_cylinder(right_knee, right_foot, 0.07 / 2, texture) self.upper_right_leg = self.get_rounded_cylinder(right_pelvis, right_knee, 0.07 / 2, texture) self.hip = self.get_rounded_cylinder(left_pelvis, right_pelvis, 0.07 / 2, texture) self.left_flank = self.get_rounded_cylinder([-width, 0, 0], [-width, neck[1], neck[2]], 0.07 / 2, texture) self.right_flank = self.get_rounded_cylinder([width, 0, 0], [width, neck[1], neck[2]], 0.07 / 2, texture) self.shoulder = self.get_rounded_cylinder(left_shoulder, right_shoulder, width / 2, texture) self.upper_left_arm = self.get_rounded_cylinder(left_shoulder, left_elbow, width / 2, texture) self.lower_left_arm = self.get_rounded_cylinder(left_elbow, left_hand, width / 2, texture) self.upper_right_arm = self.get_rounded_cylinder(right_shoulder, right_elbow, width / 2, texture) self.lower_right_arm = self.get_rounded_cylinder(right_elbow, right_hand, width / 2, texture) rad = (dict_of_angles["head"]) * math.pi / 180. self.head = vapory.Sphere( [0, neck[1] - (0.35 / 2 + width) * math.cos(rad), neck[2] + (0.35 / 2 + width) * math.sin(rad)], 0.35 / 2, texture) self.body = vapory.Union(self.torso, self.lower_left_leg, self.upper_left_leg, self.lower_right_leg, self.upper_right_leg, self.hip, self.left_flank, self.right_flank, self.shoulder, self.upper_left_arm, self.lower_left_arm, self.upper_right_arm, self.lower_right_arm, self.head) if (falda): falda = vapory.Triangle(left_pelvis, left_knee, right_knee, texture) self.body.args.append(falda) p1 = [0, neck[1] - (2.72 - 2.96), neck[2] + 1.57 - 1.74] p2 = [0, neck[1] - (3.17 - 2.96), neck[2] + 1.60 - 1.74] p3 = [0, neck[1] - (2.72 - 2.96), neck[2] + 1.68 - 1.74] hair = vapory.Triangle(p1, p2, p3, texture) hair = hair.add_args(["rotate", [0 * 180. / math.pi * rad, 0, 0]]) self.body.args.append(hair) p1 = [0, neck[1] - (3.01 - 2.96), neck[2] + 1.62 - 1.74] p2 = [0, neck[1] - (3.26 - 2.96), neck[2] + 1.59 - 1.74] p3 = [0, neck[1] - (3.26 - 2.96), neck[2] + 1.54 - 1.74] hair = vapory.Triangle(p1, p2, p3, texture) hair = hair.add_args(["rotate", [0 * 180. / math.pi * rad, 0, 0]]) self.body.args.append(hair) p1 = [0, neck[1] - (3.26 - 2.96), neck[2] + (1.59 + 1.54) / 2. - 1.74] hair = vapory.Sphere(p1, 0.025, texture) hair = hair.add_args(["rotate", [0 * 180. / math.pi * rad, 0, 0]]) self.body.args.append(hair) # self.body = self.body.add_args(["scale", [0.5, 0.5, 0.5]]) pos = dict_of_angles["pos"] self.body = self.body.add_args(["translate", [0, pos[1], pos[0]]])
def get_rounded_cylinder(self, start, end, radius, texture): cylinder = vapory.Cylinder(start, end, radius, texture) tip_1 = vapory.Sphere(start, radius, texture) tip_2 = vapory.Sphere(end, radius, texture) return vapory.Union(cylinder, tip_1, tip_2)