def simple_advection(scale): n = 256 * 2**int((math.log(scale, 2)) // 2) x = ti.Vector.field(3, dtype=ti.f32, shape=(n, n)) new_x = ti.Vector.field(3, dtype=ti.f32, shape=(n, n)) v = ti.Vector.field(2, dtype=ti.f32, shape=(n, n)) dx = 1 / n inv_dx = 1 / dx dt = 0.01 stagger = ti.Vector([0.5, 0.5]) @ti.func def Vector2(x, y): return ti.Vector([x, y]) @ti.kernel def init(): for i, j in v: v[i, j] = ti.Vector([j / n - 0.5, 0.5 - i / n]) for i, j in ti.ndrange(n * 4, n * 4): ret = ti.taichi_logo(ti.Vector([i, j]) / (n * 4)) x[i // 4, j // 4][0] += ret / 16 x[i // 4, j // 4][1] += ret / 16 x[i // 4, j // 4][2] += ret / 16 @ti.func def vec(x, y): return ti.Vector([x, y]) @ti.func def clamp(p): for d in ti.static(range(p.n)): p[d] = min(1 - 1e-4 - dx + stagger[d] * dx, max(p[d], stagger[d] * dx)) return p @ti.func def sample_bilinear(x, p): p = clamp(p) p_grid = p * inv_dx - stagger I = ti.cast(ti.floor(p_grid), ti.i32) f = p_grid - I g = 1 - f return x[I] * (g[0] * g[1]) + x[I + vec(1, 0)] * (f[0] * g[1]) + x[ I + vec(0, 1)] * (g[0] * f[1]) + x[I + vec(1, 1)] * (f[0] * f[1]) @ti.func def velocity(p): return sample_bilinear(v, p) @ti.func def sample_min(x, p): p = clamp(p) p_grid = p * inv_dx - stagger I = ti.cast(ti.floor(p_grid), ti.i32) return min(x[I], x[I + vec(1, 0)], x[I + vec(0, 1)], x[I + vec(1, 1)]) @ti.func def sample_max(x, p): p = clamp(p) p_grid = p * inv_dx - stagger I = ti.cast(ti.floor(p_grid), ti.i32) return max(x[I], x[I + vec(1, 0)], x[I + vec(0, 1)], x[I + vec(1, 1)]) @ti.func def backtrace(I, dt): # RK3 p = (I + stagger) * dx v1 = velocity(p) p1 = p - 0.5 * dt * v1 v2 = velocity(p1) p2 = p - 0.75 * dt * v2 v3 = velocity(p2) p -= dt * (2 / 9 * v1 + 1 / 3 * v2 + 4 / 9 * v3) return p @ti.func def semi_lagrangian(x, new_x, dt): for I in ti.grouped(x): new_x[I] = sample_bilinear(x, backtrace(I, dt)) @ti.kernel def advect(): semi_lagrangian(x(0), new_x(0), dt) semi_lagrangian(x(1), new_x(1), dt) semi_lagrangian(x(2), new_x(2), dt) for I in ti.grouped(x): x[I] = new_x[I] init() def task(): for i in range(10): advect() ti.benchmark(task, repeat=100) visualize = False if visualize: gui = ti.GUI('Advection schemes', (n, n)) for i in range(10): for _ in range(10): advect() gui.set_image(x.to_numpy()) gui.show()
# initialization init_v[None] = [0, 0] for i in range(n_particles): F[0, i] = [[1, 0], [0, 1]] for i in range(N): for j in range(N): x[0, i * N + j] = [dx * (i * 0.7 + 10), dx * (j * 0.7 + 25)] set_v() losses = [] img_count = 0 gui = ti.GUI("Simple Differentiable MPM Solver", (640, 640), 0xAAAAAA) for i in range(30): grid_v_in.fill(0) grid_m_in.fill(0) x_avg[None] = [0, 0] with ti.Tape(loss=loss): set_v() for s in range(steps - 1): substep(s) compute_x_avg() compute_loss() l = loss[None]
gravitational_force = ti.Vector([0.0, 0.0]) for i in ti.static(range(n_gravitation)): # instead of this one r = x[t - 1] - ti.Vector(gravitation_position[i]) len_r = ti.max(r.norm(), 1e-1) gravitational_force += K * gravitation[t, i] / (len_r * len_r * len_r) * r v[t] = v[t - 1] * math.exp(-dt * damping) + dt * gravitational_force x[t] = x[t - 1] + dt * v[t] @ti.kernel def compute_loss(t: ti.i32): ti.atomic_add(loss[None], dt * (x[t] - goal[t]).norm_sqr()) gui = ti.GUI("Electric", (512, 512), background_color=0x3C733F) def forward(visualize=False, output=None): interval = vis_interval if output: interval = output_vis_interval os.makedirs('electric/{}/'.format(output), exist_ok=True) for t in range(1, steps): nn1(t) nn2(t) advance(t) compute_loss(t) if (t + 1) % interval == 0 and visualize:
self.block.deactivate_all() num_triangles = len(triangles) self.voxelize_triangles(num_triangles, triangles) if __name__ == '__main__': n = 256 vox = Voxelizer((n, n, n), 1.0 / n) # triangle = np.array([[0.1, 0.1, 0.1, 0.6, 0.2, 0.1, 0.5, 0.7, # 0.7]]).astype(np.float32) triangles = np.fromfile('triangles.npy', dtype=np.float32) triangles = np.reshape(triangles, (len(triangles) // 9, 9)) * 0.306 + 0.501 offsets = [0.0, 0.0, 0.0] for i in range(9): triangles[:, i] += offsets[i % 3] print(triangles.shape) print(triangles.max()) print(triangles.min()) vox.voxelize(triangles) voxels = vox.voxels.to_numpy().astype(np.float32) import os os.makedirs('outputs', exist_ok=True) gui = ti.GUI('cross section', (n, n)) for i in range(n): gui.set_image(voxels[:, :, i]) gui.show(f'outputs/{i:04d}.png')
min_val = sample_min(x, source_pos) max_val = sample_max(x, source_pos) if new_x[I] < min_val or new_x[I] > max_val: new_x[I] = sample_bilinear(x, source_pos) @ti.kernel def advect(): if use_mc: maccormick(x, dt) else: semi_lagrangian(x, new_x, dt) for I in ti.grouped(x): x[I] = new_x[I] paint() gui = ti.GUI('Advection schemes', (512, 512)) while True: while gui.get_event(ti.GUI.PRESS): if gui.event.key in [ti.GUI.ESCAPE, ti.GUI.EXIT]: exit(0) if gui.event.key == ti.GUI.SPACE: pause = not pause if not pause: for i in range(1): advect() gui.set_image(x.to_numpy()) gui.show()
def advance_no_toi(t: ti.i32): for i in range(n_objects): new_v = v[t - 1, i] if x[t - 1, i][1] < ground_height and new_v[1] < 0: new_v[1] = -new_v[1] v[t, i] = new_v x[t, i] = x[t - 1, i] + dt * new_v @ti.kernel def compute_loss(t: ti.i32): # loss[None] = (x[t, 0] - ti.Vector(goal)).norm() loss[None] = x[t, 0][1] gui = ti.GUI("Rigid Body", (1024, 1024), background_color=0xFFFFFF) def forward(output=None, visualize=True): interval = vis_interval total_steps = steps if output: interval = output_vis_interval # os.makedirs('rigid_body/{}/'.format(output), exist_ok=True) total_steps *= 2 for t in range(1, total_steps): if use_toi: advance_toi(t) else: advance_no_toi(t)
import taichi_three as t3 import numpy as np ti.init(ti.cpu) scene = t3.Scene() cornell = t3.readobj('assets/cornell.obj') cube = t3.readobj('assets/plane.obj') model = t3.Model(t3.Mesh.from_obj(cornell)) scene.add_model(model) light = t3.PointLight(pos=[0.0, 3.9, 0.0], color=15.0) scene.add_light(light) camera = t3.Camera() camera.ctl = t3.CameraCtl(pos=[0, 2, 6], target=[0, 2, 0]) scene.add_camera_d(camera) original = t3.FrameBuffer(camera) mapped = t3.ImgUnaryOp(original, lambda x: 1 - ti.exp(-x)) scene.add_buffer(mapped) #light.L2W[None] = t3.translate(0, 3.9, 0) gui_ldr = ti.GUI('LDR', camera.res) gui_hdr = ti.GUI('HDR', camera.res) while gui_ldr.running and gui_hdr.running: gui_hdr.get_event(None) camera.from_mouse(gui_hdr) scene.render() gui_ldr.set_image(original.img) gui_ldr.show() gui_hdr.set_image(mapped.img) gui_hdr.show()
import taichi as ti x, y = 0.5, 0.5 delta = 0.01 radius = 8 gui = ti.GUI("Keyboard", res=(400, 400)) while gui.running: while gui.get_event(ti.GUI.PRESS, ti.GUI.MOTION): if gui.event.key == ti.GUI.ESCAPE: gui.running = False elif gui.event.key == ti.GUI.RMB: x, y = gui.event.pos elif gui.event.key == ti.GUI.WHEEL: x, y = gui.event.pos dt = gui.event.delta # delta is 2-dim vector (dx, dy) # dt[0] denotes the horizontal direction, and dt[1] denotes the vertical direction if dt[1] > 0: radius += 10 elif dt[1] < 0: radius = max(8, radius - 10) if gui.is_pressed(ti.GUI.LEFT, 'a'): x -= delta if gui.is_pressed(ti.GUI.RIGHT, 'd'): x += delta if gui.is_pressed(ti.GUI.UP, 'w'): y += delta if gui.is_pressed(ti.GUI.DOWN, 's'):
for i in pos: acc = ts.vec(0, -1, 0) vel[i] += acc * dt for i in pos: for j in range(N): if i != j: interact(i, j) for i in pos: for j in ti.static(range(3)): if vel[i][j] < 0 and pos[i][j] < -1 + radius[i]: vel[i][j] *= -0.8 if vel[i][j] > 0 and pos[i][j] > 1 - radius[i]: vel[i][j] *= -0.8 for i in pos: pos[i] += vel[i] * dt init() gui = ti.GUI('Ball', scene.res) while gui.running: gui.running = not gui.get_event(ti.GUI.ESCAPE) for i in range(4): substep() scene.camera.from_mouse(gui, dis=4) scene.render() gui.set_image(scene.img) gui.show()
args = parse_args() with_gui = args.show write_to_disk = args.out_dir is not None # Try to run on GPU ti.init(arch=ti.cuda, kernel_profiler=True, use_unified_memory=False, device_memory_GB=20) max_num_particles = 235000000 if with_gui: gui = ti.GUI("MLS-MPM", res=1024, background_color=0x112F41, show_gui=False) if write_to_disk: # output_dir = create_output_folder(args.out_dir) output_dir = args.out_dir os.makedirs(f'{output_dir}/particles') os.makedirs(f'{output_dir}/previews') print("Writing 2D vis and binary particle data to folder", output_dir) else: output_dir = None def load_mesh(fn, scale, offset): if isinstance(scale, (int, float)): scale = (scale, scale, scale)
x[xi] = x[0] v[xi] = r * initvel + v[0] inv_m[xi] = 0.5 + ti.random() color[xi] = colorinit @ti.kernel def render(): for p in ti.grouped(img): img[p] = 1e-6 / (p / res - ti.Vector([sun.x, sun.y])).norm(1e-4)**3 for i in x: p = int(ti.Vector([x[i].x, x[i].y]) * res) img[p] += color[i] inv_m[0] = 0 x[0].x = +0.5 x[0].y = -0.01 v[0].x = +0.6 v[0].y = +0.4 color[0] = 1 gui = ti.GUI('Comet', res) while gui.running: gui.running = not gui.get_event(gui.ESCAPE) generate() for s in range(steps): substep() render() gui.set_image(img) gui.show()
import taichi as ti ti.cfg.arch = ti.cuda # Run on GPU by default n = 320 pixels = ti.var(dt=ti.f32, shape=(n * 2, n)) @ti.func def complex_sqr(z): return ti.Vector([z[0] * z[0] - z[1] * z[1], z[1] * z[0] * 2]) @ti.kernel def paint(t: ti.f32): for i, j in pixels: # Parallized over all pixels c = ti.Vector([-0.8, ti.sin(t) * 0.2]) z = ti.Vector([float(i) / n - 1, float(j) / n - 0.5]) * 2 iterations = 0 while z.norm() < 20 and iterations < 50: z = complex_sqr(z) + c iterations += 1 pixels[i, j] = 1 - iterations * 0.02 gui = ti.GUI("Fractal", (n * 2, n)) for i in range(1000000): paint(i * 0.03) gui.set_image(pixels) gui.show()
self.v[i] = [-offset[1], offset[0]] self.v[i] *= 1.5 / offset.norm() @ti.func def gravity(self, pos): offset = -(pos - self.center[None]) return offset / offset.norm()**3 @ti.kernel def integrate(self): for i in range(self.n): self.v[i] += self.dt * self.gravity(self.x[i]) self.x[i] += self.dt * self.v[i] solar = SolarSystem(9, 0.0005) solar.center[None] = [0.5, 0.5] solar.initialize() gui = ti.GUI("Solar System", background_color=0x25A6D9) while True: if gui.get_event(): if gui.event.key == gui.SPACE and gui.event.type == gui.PRESS: solar.initialize() for i in range(10): solar.integrate() gui.circle([0.5, 0.5], radius=20, color=0x8C274C) gui.circles(solar.x.to_numpy(), radius=5, color=0xFFFFFF) gui.show()
count[i, j] = get_count(i, j) for i, j in alive: alive[i, j] = calc_rule(alive[i, j], count[i, j]) @ti.kernel def init(): for i, j in alive: if ti.random() > 0.8: alive[i, j] = 1 else: alive[i, j] = 0 gui = ti.GUI('Game of Life', (img_size, img_size)) gui.fps_limit = 15 print('[Hint] Press `r` to reset') print('[Hint] Press SPACE to pause') print('[Hint] Click LMB, RMB and drag to add alive / dead cells') init() paused = False while gui.running: for e in gui.get_events(gui.PRESS, gui.MOTION): if e.key == gui.ESCAPE: gui.running = False elif e.key == gui.SPACE: paused = not paused elif e.key == 'r':
# semi-implicit time integration for i in range(self.n): self.v[i] += self.dt * self.gravity(self.x[i]) self.x[i] += self.dt * self.v[i] def render(self, gui): # render the simulation scene on the GUI gui.circle([0.5, 0.5], radius=10, color=0xffaa88) gui.circles(solar.x.to_numpy(), radius=3, color=0xffffff) solar = SolarSystem(8, 0.0001) solar.center[None] = [0.5, 0.5] solar.initialize() gui = ti.GUI("Solar System", background_color=0x0071a) while gui.running: # GUI event processing if gui.get_event(gui.PRESS): if gui.event.key == gui.SPACE: solar.initialize() elif gui.event.key == gui.ESCAPE: gui.running = False for i in range(10): solar.integrate() solar.render(gui) gui.show()
J[i] = 1 def T(a): if dim == 2: return a phi, theta = np.radians(28), np.radians(32) a = a - 0.5 x, y, z = a[:, 0], a[:, 1], a[:, 2] c, s = np.cos(phi), np.sin(phi) C, S = np.cos(theta), np.sin(theta) x, z = x * c + z * s, z * c - x * s u, v = x, y * C + z * S return np.array([u, v]).swapaxes(0, 1) + 0.5 init() gui = ti.GUI('MPM3D', background_color=0x112F41) while gui.running and not gui.get_event(gui.ESCAPE): for s in range(15): substep() pos = x.to_numpy() if export_file: writer = ti.PLYWriter(num_vertices=n_particles) writer.add_vertex_pos(pos[:, 0], pos[:, 1], pos[:, 2]) writer.export_frame(gui.frame, export_file) gui.circles(T(pos), radius=2, color=0x66ccff) gui.show()
mesh = t3.MeshGrid((128, 128)) model = t3.Model(t3.QuadToTri(mesh)) scene.add_model(model) camera = t3.Camera() camera.ctl = t3.CameraCtl(pos=[1.1, 1.6, 1.6]) scene.add_camera(camera) light = t3.Light([0.4, -1.5, -0.8], 0.9) scene.add_light(light) ambient = t3.AmbientLight(0.1) scene.add_light(ambient) @ti.func def Z(xy, t): return 0.1 * ti.sin(10 * xy.norm() - t3.tau * t) @ti.kernel def deform_mesh(t: float): for i, j in mesh.pos: mesh.pos[i, j].y = Z(mesh.pos[i, j].xZ, t) gui = ti.GUI('Meshgrid', camera.res) while gui.running: gui.get_event(None) gui.running = not gui.is_pressed(ti.GUI.ESCAPE) camera.from_mouse(gui) deform_mesh(t3.get_time()) scene.render() gui.set_image(camera.img) gui.show()
model.faces[a * 4 + 1] = [a, d, c] model.faces[a * 4 + 2] = [a, b, c] model.faces[a * 4 + 3] = [a, c, d] for i in ti.grouped(x): j = i.dot(tl.vec(N, 1)) model.vt[j] = tl.D.yx + i.xY / N @ti.kernel def update_display(): for i in ti.grouped(x): j = i.dot(tl.vec(N, 1)) model.vi[j] = x[i] init() init_display() with ti.GUI('Mass Spring') as gui: while gui.running and not gui.get_event(gui.ESCAPE): if not gui.is_pressed(gui.SPACE): for i in range(steps): substep() update_display() camera.from_mouse(gui) scene.render() gui.set_image(camera.img) gui.show()
new_v += weight * g_v new_C += 4 * inv_dx * weight * ti.outer_product(g_v, dpos) v[p], C[p] = new_v, new_C x[p] += dt * v[p] # advection import random group_size = n_particles // 3 for i in range(n_particles): x[i] = [ random.random() * 0.2 + 0.3 + 0.10 * (i // group_size), random.random() * 0.2 + 0.05 + 0.32 * (i // group_size) ] material[i] = i // group_size # 0: fluid 1: jelly 2: snow v[i] = [0, 0] F[i] = [[1, 0], [0, 1]] Jp[i] = 1 import numpy as np import os gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41) for frame in range(20000): for s in range(int(2e-3 // dt)): substep() colors = np.array([0x068587, 0xED553B, 0xEEEEF0], dtype=np.uint32) gui.circles(x.to_numpy(), radius=1.5, color=colors[material.to_numpy()]) # gui.show() # Change to gui.show(f'{frame:06d}.png') to write images to disk path = 'result' if not os.path.exists(path): os.makedirs(path) gui.show('{}/'.format(path) + f'{frame:06d}.png')
prolongate(l) for i in range(pre_and_post_smoothing << l): smooth(l, 1) smooth(l, 0) @ti.kernel def paint(): kk = N_tot * 3 // 8 for i, j in pixels: ii = int(i * N / N_gui) + N_ext jj = int(j * N / N_gui) + N_ext pixels[i, j] = x[ii, jj, kk] / N_tot gui = ti.GUI("mgpcg", res=(N_gui, N_gui)) init() sum[None] = 0.0 reduce(r[0], r[0]) initial_rTr = sum[None] # r = b - Ax = b since x = 0 # p = r = r + 0 p if use_multigrid: apply_preconditioner() else: z[0].copy_from(r[0]) update_p()
if pixels[i + 1, j] > level: case_id |= 2 if pixels[i + 1, j + 1] > level: case_id |= 4 if pixels[i, j + 1] > level: case_id |= 8 for k in range(2): if edge_table[case_id, k][0] == -1: break n = ti.atomic_add(n_edges, 1) for l in ti.static(range(2)): vertex_id = edge_table[case_id, k][l] edge_coords[n, l] = ti.Vector([i, j ]) + get_vertex(vertex_id) + 0.5 return n_edges level = 0.2 gui = ti.GUI('Marching squares') while gui.running and not gui.get_event(gui.ESCAPE): touch(*gui.get_cursor_pos(), 0.05) n_edges = march(level) edge_coords_np = edge_coords.to_numpy()[:n_edges] / N gui.set_image(ti.imresize(pixels, *gui.res) / level) gui.lines(edge_coords_np[:, 0], edge_coords_np[:, 1], color=0xff66cc, radius=1.5) gui.show()
for i in range(n_xs): for j in range(n_ys): new_particle(0.52 + i * 0.02, 0.00 + bottom_y + j * 0.02) if i > 0: conn_particle(i * n_ys + j, (i - 1) * n_ys + (j + 0)) if j > 0: conn_particle(i * n_ys + j, (i - 0) * n_ys + (j - 1)) if i > 0 and j > 0: conn_particle(i * n_ys + j, (i - 1) * n_ys + (j - 1)) conn_particle((i - 0) * n_ys + (j - 1), (i - 1) * n_ys + (j - 0)) init() gui = ti.GUI('Mass Spring System', res=(512, 512), background_color=0xdddddd) while True: for e in gui.get_events(ti.GUI.PRESS): if e.key in [ti.GUI.ESCAPE, ti.GUI.EXIT]: exit() elif e.key == gui.SPACE: paused[None] = not paused[None] elif e.key == ti.GUI.LMB: # new_particle(e.pos[0], e.pos[1]) hit_particle(e.pos[0], e.pos[1]) elif e.key == 'c': init() elif e.key == 's': if gui.is_pressed('Shift'): spring_stiffness[None] /= 1.1
import taichi as ti import numpy as np import utils from engine.mpm_solver import MPMSolver write_to_disk = False ti.init(arch=ti.cuda) # Try to run on GPU gui = ti.GUI("Taichi Elements", res=512, background_color=0x112F41) mpm = MPMSolver(res=(256, 256)) mpm.set_gravity([0, 0]) mpm.add_ellipsoid(center=[0.25, 0.45], radius=0.07, velocity=[1, 0], color=0xAAAAFF, material=MPMSolver.material_snow) mpm.add_ellipsoid(center=[0.55, 0.52], radius=0.07, velocity=[-1, 0], color=0xFFAAAA, material=MPMSolver.material_snow) for frame in range(500): mpm.step(8e-3) particles = mpm.particle_info() gui.circles(particles['position'], radius=1.5, color=particles['color']) gui.show(f'{frame:06d}.png' if write_to_disk else None)
def run(self): gui = ti.GUI("Multigrid Preconditioned Conjugate Gradients", res=(self.N_gui, self.N_gui)) self.init() self.reduce(self.r[0], self.r[0]) initial_rTr = self.sum[None] # self.r = b - Ax = b since self.x = 0 # self.p = self.r = self.r + 0 self.p if self.use_multigrid: self.apply_preconditioner() else: self.z[0].copy_from(self.r[0]) self.update_p() self.reduce(self.z[0], self.r[0]) old_zTr = self.sum[None] # CG for i in range(400): # self.alpha = rTr / pTAp self.compute_Ap() self.reduce(self.p, self.Ap) pAp = self.sum[None] self.alpha[None] = old_zTr / pAp # self.x = self.x + self.alpha self.p self.update_x() # self.r = self.r - self.alpha self.Ap self.update_r() # check for convergence self.reduce(self.r[0], self.r[0]) rTr = self.sum[None] if rTr < initial_rTr * 1.0e-12: break # self.z = M^-1 self.r if self.use_multigrid: self.apply_preconditioner() else: self.z[0].copy_from(self.r[0]) # self.beta = new_rTr / old_rTr self.reduce(self.z[0], self.r[0]) new_zTr = self.sum[None] self.beta[None] = new_zTr / old_zTr # self.p = self.z + self.beta self.p self.update_p() old_zTr = new_zTr print(f'iter {i}, residual={rTr}') self.paint() gui.set_image(self.pixels) gui.show() ti.profiler_print()
import taichi as ti import os, sys prefix = sys.argv[1] if len(sys.argv) >= 1 else '' images = [] frames = 0 while True: file = f'{prefix}{frames + 1:04d}.png' if not os.path.exists(file): break print('Loading', file) images.append(ti.imread(file)) frames += 1 res = images[0].shape[:2] gui = ti.GUI('imseqshow', res) while gui.running: gui.set_image(images[gui.frame % frames]) gui.show()
b = parent_geo_center + which * child_geo_size child_geo_center = parent_geo_center + (which - 0.5) * child_geo_size gui.rect(a, b, radius=1, color=0xff0000) render_tree(gui, child, child_geo_center, child_geo_size) if 'cmap' in kDisplay: import matplotlib.cm as cm cmap = cm.get_cmap('magma') print('[Hint] Press `r` to add 512 random particles') print('[Hint] Press `t` to add 512 random particles with angular velocity') print('[Hint] Drag with mouse left button to add a series of particles') print('[Hint] Drag with mouse middle button to add zero-mass particles') print('[Hint] Click mouse right button to add a single particle') gui = ti.GUI('Tree-code', kResolution) while gui.running: for e in gui.get_events(gui.PRESS): if e.key == gui.ESCAPE: gui.running = False elif e.key == gui.RMB: add_particle_at(*gui.get_cursor_pos(), 1.0) elif e.key in 'rt': if particle_table_len[None] + 512 < kMaxParticles: for i in range(512): add_random_particles(e.key == 't') if gui.is_pressed(gui.MMB, gui.LMB): add_particle_at(*gui.get_cursor_pos(), gui.is_pressed(gui.LMB)) if kUseTree: build_tree()
break if f[0] < 0: sign = -1.0 else: sign = 1.0 return ret @ti.kernel def render(): for i, j in img: o = ti.Vector([i / N, j / N]) img[i, j] += sample(o) gui = ti.GUI('SDF 2D') frame = 1 light_pos[None] = [0.5, 0.85] while True: while gui.get_event(ti.GUI.PRESS): if gui.event.key == ti.GUI.LMB: light_pos[None] = [gui.event.pos[0], gui.event.pos[1]] frame = 1 img.fill(0) elif gui.event.key == ti.GUI.ESCAPE: exit() render() gui.set_image(img.to_numpy() / frame) gui.show() frame += 1
import numpy as np import tina ti.init(ti.gpu) scene = tina.PTScene(smoothing=True) roughness = tina.Param(float, initial=0.2) metallic = tina.Param(float, initial=1.0) scene.add_object(tina.MeshModel('assets/sphere.obj'), tina.PBR(metallic=metallic, roughness=roughness)) pars = tina.SimpleParticles() scene.add_object(pars, tina.Lamp(color=32)) gui = ti.GUI('path', scene.res) roughness.make_slider(gui, 'roughness', 0, 1, 0.01) metallic.make_slider(gui, 'metallic', 0, 1, 0.01) pars.set_particles(np.array([ [0, 0, 5], ])) scene.update() while gui.running: if scene.input(gui): scene.clear() scene.render(nsteps=6) gui.set_image(scene.img) gui.show()
@ti.kernel def init_mesh(): for i, j in ti.ndrange(N, N): k = (i * N + j) * 2 a = i * (N + 1) + j b = a + 1 c = a + N + 2 d = a + N + 1 f2v[k + 0] = [a, b, c] f2v[k + 1] = [c, d, a] init_mesh() init_pos() gui = ti.GUI('FEM99') while gui.running: for e in gui.get_events(): if e.key == gui.ESCAPE: gui.running = False elif e.key == 'r': init_pos() for i in range(30): with ti.Tape(loss=U): update_U() advance() gui.circles(pos.to_numpy(), radius=2, color=0xffaa33) gui.circle(ball_pos, radius=ball_radius * 512, color=0x666666) gui.show()
substep(n) Position_update(n) #print(x.to_numpy()[0:n] - old_x.to_numpy()[0:n]) collision_check(n) #print(x.to_numpy()[0:n]) #add constraints for i in range(pbd_num_iters): constraint_neighbors.fill(-1) find_constraint(n) #print("This is ", i , "th iteration.") stretch_constraint(n) apply_position_deltas(n) collision_check(n) updata_velosity(n) gui = ti.GUI('Mass Spring System', res=(640, 640), background_color=0xdddddd) def CheckRepeatMesh(i,j,k,lists): if [i,j,k] in lists: return False elif [i,k,j] in lists: return False elif [j,i,k] in lists: return False elif [j,k,i] in lists: return False elif [k,j,i] in lists: return False elif [j,i,j] in lists: return Fakse else: