Ejemplo n.º 1
0
def paintArrow(img: ti.template(),
               orig,
               dir,
               color=1,
               width=3,
               max_size=12,
               min_scale=0.4):
    res = ts.vec(*img.shape)
    I = orig * res
    D = dir * res
    J = I + D
    DL = ts.length(D)
    S = min(max_size, DL * min_scale)
    DS = D / (DL + 1e-4) * S
    SW = S + width
    D1 = ti.Matrix.rotation2d(+math.pi * 3 / 4) @ DS
    D2 = ti.Matrix.rotation2d(-math.pi * 3 / 4) @ DS
    bmin, bmax = ti.floor(max(0,
                              min(I, J) - SW)), ti.ceil(
                                  min(res - 1,
                                      max(I, J) + SW))
    for P in ti.grouped(ti.ndrange((bmin.x, bmax.x), (bmin.y, bmax.y))):
        c0 = ts.smoothstep(abs(sdLine(I, J, P)), width, width / 2)
        c1 = ts.smoothstep(abs(sdLine(J, J + D1, P)), width, width / 2)
        c2 = ts.smoothstep(abs(sdLine(J, J + D2, P)), width, width / 2)
        ti.atomic_max(img[P], max(c0, c1, c2) * color)
Ejemplo n.º 2
0
def paint():
    for i, j in img:
        ii = min(max(1, i * N // res), N - 2)
        jj = min(max(1, j * N // res), N - 2)
        if img_field == 0:  # density
            img[i, j] = Q[ii, jj][0]
        elif img_field == 1:  # numerical schlieren
            img[i,
                j] = ti.sqrt(((Q[ii + 1, jj][0] - Q[ii - 1, jj][0]) / h)**2 +
                             ((Q[ii, jj + 1][0] - Q[ii, jj - 1][0]) / h)**2)
        elif img_field == 2:  # vorticity
            img[i, j] = (Q[ii + 1, jj][2] - Q[ii - 1, jj][2]) / h - (
                Q[ii, jj + 1][1] - Q[ii, jj - 1][1]) / h
        elif img_field == 3:  # velocity magnitude
            img[i, j] = ti.sqrt(Q[ii, jj][1]**2 + Q[ii, jj][2]**2)

    max = -1.0e10
    min = 1.0e10
    for i, j in img:
        ti.atomic_max(max, img[i, j])
        ti.atomic_min(min, img[i, j])

    for i, j in img:
        if use_fixed_caxis:
            min = fixed_caxis[0]
            max = fixed_caxis[1]
        img[i, j] = (img[i, j] - min) / (max - min)
def checkStatic():
    static[None] = 1
    maxvn2[None] = 0.0
    for i in ti.static(range(n_nodes)):
        v2dn2 = v2d[i].dot(v2d[i])
        ti.atomic_max(maxvn2[None], v2dn2)
        if v2dn2 >= staticEpsilon * staticEpsilon:
            static[None] = 0
Ejemplo n.º 4
0
 def compute_max_grid_velocity(self, grid_v: ti.template()) -> ti.f32:
     max_velocity = 0.0
     for I in ti.grouped(grid_v):
         v = grid_v[I]
         v_max = 0.0
         for i in ti.static(range(self.dim)):
             v_max = max(v_max, abs(v[i]))
         ti.atomic_max(max_velocity, v_max)
     return max_velocity
Ejemplo n.º 5
0
 def compute_max_velocity(self) -> ti.f32:
     max_velocity = 0.0
     for p in self.v:
         v = self.v[p]
         v_max = 0.0
         for i in ti.static(range(self.dim)):
             v_max = max(v_max, abs(v[i]))
         ti.atomic_max(max_velocity, v_max)
     return max_velocity
Ejemplo n.º 6
0
    def foo():
        # Parallel max
        for i in range(1000):
            ti.atomic_max(f[0], 1.12 * i)

        # Serial max
        for _ in range(1):
            for i in range(1000):
                f[1] = ti.max(1.12 * i, f[1])
Ejemplo n.º 7
0
 def func():
     for i in x:
         x[i] = y[None]
     x[0] = z[None]
     x[1] += z[None]
     x[2] -= z[None]
     x[3] *= z[None]
     x[4] //= z[None]
     x[5] %= z[None]
     x[6] &= z[None]
     x[7] |= z[None]
     x[8] ^= z[None]
     ti.atomic_min(x[10], z[None])
     ti.atomic_max(x[11], z[None])
Ejemplo n.º 8
0
 def iou_kernel(self)->ti.float64:
     ma = ti.cast(0., self.dtype)
     mb = ti.cast(0., self.dtype)
     I = ti.cast(0., self.dtype)
     Ua = ti.cast(0., self.dtype)
     Ub = ti.cast(0., self.dtype)
     for i in ti.grouped(self.grid_mass):
         ti.atomic_max(ma, self.grid_mass[i])
         ti.atomic_max(mb, self.target_density[i])
         I += self.grid_mass[i]  * self.target_density[i]
         Ua += self.grid_mass[i]
         Ub += self.target_density[i]
     I = I/ma/mb
     U = Ua/ma + Ub/mb
     return I/(U - I)
Ejemplo n.º 9
0
 def func():
     for i in x:
         x[i] = y[None]
     if ti.static(rhs_is_mat):
         x[0] = z[None]
     else:
         x[0].fill(z[None])
     x[1] += z[None]
     x[2] -= z[None]
     x[3] *= z[None]
     x[4] /= z[None]
     x[5] //= z[None]
     x[6] %= z[None]
     ti.atomic_min(x[7], z[None])
     ti.atomic_max(x[8], z[None])
Ejemplo n.º 10
0
    def updateCorrectedPressure(self):
        # predict density, max density error, correction pressure
        for pa_idx in self.predicted_position:
            if self.particle_is_fluid[pa_idx] == 1:
                pos_a = self.predicted_position[pa_idx]  # position
                vel_a = self.predicted_velocity[pa_idx]  # velocity

                # using two different method to predict density and
                # choose the one which is closer to reference density
                predicted_density = self.particle_density[pa_idx]

                for nb_idx in range(self.particle_num_neighbors[pa_idx]):
                    pb_idx = self.particle_neighbors[pa_idx, nb_idx]

                    pos_b = self.predicted_position[pb_idx]
                    vel_b = self.predicted_velocity[pb_idx]

                    x_ab = pos_a - pos_b
                    v_ab = vel_a - vel_b

                    if self.particle_is_fluid[nb_idx] == 1:
                        predicted_density += self.rho_dt(v_ab, x_ab) * self.dt

                # only handle positive error (thus incompressible)
                density_error = max(predicted_density - self.rho_0, 0)

                self.predicted_density[pa_idx] = predicted_density
                self.corrected_pressure[
                    pa_idx] += self.delta * density_error  # ref to PCISPH equation (9),(10)

                err = abs(density_error)

                # update max density error
                self.max_density_error[None] = ti.atomic_max(
                    err, self.max_density_error[None])
Ejemplo n.º 11
0
    def do_render(self, scene):
        a = scene.camera.untrans_pos(self.a)
        b = scene.camera.untrans_pos(self.b)
        c = scene.camera.untrans_pos(self.c)
        A = scene.uncook_coor(a)
        B = scene.uncook_coor(b)
        C = scene.uncook_coor(c)
        B_A = B - A
        C_B = C - B
        A_C = A - C
        ilB_A = 1 / ts.length(B_A)
        ilC_B = 1 / ts.length(C_B)
        ilA_C = 1 / ts.length(A_C)
        B_A *= ilB_A
        C_B *= ilC_B
        A_C *= ilA_C
        BxA = ts.cross(B, A) * ilB_A
        CxB = ts.cross(C, B) * ilC_B
        AxC = ts.cross(A, C) * ilA_C
        normal = ts.normalize(ts.cross(a - c, a - b))
        light_dir = scene.camera.untrans_dir(scene.light_dir[None])
        pos = (a + b + c) * (1 / 3)
        dir = ts.vec3(0.0)
        color = scene.opt.render_func(pos, normal, dir, light_dir)
        color = scene.opt.pre_process(color)

        W = 0.4
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            AB = ts.cross(X, B_A) + BxA
            BC = ts.cross(X, C_B) + CxB
            CA = ts.cross(X, A_C) + AxC
            udf = max(AB, BC, CA)
            if udf < 0:
                scene.img[X] = color
            elif udf < W:
                t = ts.smoothstep(udf, W, 0)
                ti.atomic_max(scene.img[X], t * color)
Ejemplo n.º 12
0
def compute_dist(t: ti.int32):
    for bs, i in ti.ndrange(BATCH_SIZE, particle_num):
        if material[i] == 0:
            dist = 0.0
            for j in ti.static(range(3)):
                dist += (F_pos[bs, t, i][j] - target_centers[bs][j])**2
            dist_sqr = ti.sqrt(dist)
            ti.atomic_min(min_dist[bs], dist_sqr)
            ti.atomic_max(max_height[bs], F_pos[bs, t, i][1])
            ti.atomic_max(max_left[bs], F_pos[bs, t, i][0])
            ti.atomic_max(max_right[bs], F_pos[bs, t, i][2])
Ejemplo n.º 13
0
def render_cylinder(model, camera, v1, v2, radius, c1, c2):
    scene = model.scene
    a = camera.untrans_pos(v1)
    b = camera.untrans_pos(v2)
    A = camera.uncook(a)
    B = camera.uncook(b)
    bx = int(ti.ceil(camera.fx * radius / min(a.z, b.z)))
    by = int(ti.ceil(camera.fy * radius / min(a.z, b.z)))

    M, N = ti.floor(min(A, B)), ti.ceil(max(A, B))
    M.x -= bx
    N.x += bx
    M.y -= by
    N.y += by
    M.x, N.x = min(max(M.x, 0),
                   camera.img.shape[0]), min(max(N.x, 0), camera.img.shape[1])
    M.y, N.y = min(max(M.y, 0),
                   camera.img.shape[0]), min(max(N.y, 0), camera.img.shape[1])
    if (M.x < N.x and M.y < N.y):
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            t = ti.dot(X - A, B - A) / (B - A).norm_sqr()
            if t < 0 or t > 1:
                continue
            proj = a * (1 - t) + b * t
            W = ti.cast(ti.Vector([X.x, X.y, proj.z]), ti.f32)
            w = cook_coord(camera, W)
            dw = w - proj
            dw2 = dw.norm_sqr()
            if dw2 > radius**2:
                continue
            dz = ti.sqrt(radius**2 - dw2)
            n = ti.Vector([dw.x, dw.y, -dz])
            zindex = 1 / (proj.z - dz)

            if zindex >= ti.atomic_max(camera.zbuf[X], zindex):
                basecolor = c1 if t < 0.5 else c2
                normal = ts.normalize(n)
                view = ts.normalize(a + n)
                color = get_ambient(camera, normal, view) * basecolor
                for light in ti.static(scene.lights):
                    light_color = scene.opt.render_func(a + n, normal, \
                        view, light, basecolor)
                    color += light_color
                camera.img[X] = color
                camera.nbuf[X] = normal
Ejemplo n.º 14
0
def render_line(camera, p1, p2):
    scene = camera.scene
    a = camera.untrans_pos(p1)
    b = camera.untrans_pos(p2)
    A = camera.uncook(a)
    B = camera.uncook(b)
    # dda algorithm
    step = abs((B - A)).max()
    delta = (B - A) / step
    dz = (b.z - a.z) / step
    # needs to do screen clipping
    for i in range(step):
        X = int(A + i * delta)
        if X.x < 0 or X.x >= camera.res[0] or X.y < 0 or X.y >= camera.res[1]:
            continue
        zindex = 1 / (a.z + i * dz)
        if zindex >= ti.atomic_max(camera.zbuf[X], zindex):
            camera.img[X] = ts.vec3(0, 0.7, 0)
Ejemplo n.º 15
0
    def do_render(self):
        model = self.model
        scene = model.scene
        L2W = model.L2W
        a = scene.camera.untrans_pos(L2W @ self.vertex(0).pos)
        b = scene.camera.untrans_pos(L2W @ self.vertex(1).pos)
        c = scene.camera.untrans_pos(L2W @ self.vertex(2).pos)
        A = scene.uncook_coor(a)
        B = scene.uncook_coor(b)
        C = scene.uncook_coor(c)
        B_A = B - A
        C_B = C - B
        A_C = A - C
        ilB_A = 1 / ts.length(B_A)
        ilC_B = 1 / ts.length(C_B)
        ilA_C = 1 / ts.length(A_C)
        B_A *= ilB_A
        C_B *= ilC_B
        A_C *= ilA_C
        BxA = ts.cross(B, A) * ilB_A
        CxB = ts.cross(C, B) * ilC_B
        AxC = ts.cross(A, C) * ilA_C
        normal = ts.normalize(ts.cross(a - c, a - b))
        light_dir = scene.camera.untrans_dir(scene.light_dir[None])
        pos = (a + b + c) / 3
        color = scene.opt.render_func(pos, normal, ts.vec3(0.0), light_dir)
        color = scene.opt.pre_process(color)

        Ak = 1 / (ts.cross(A, C_B) + CxB)
        Bk = 1 / (ts.cross(B, A_C) + AxC)
        Ck = 1 / (ts.cross(C, B_A) + BxA)

        W = 1
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            AB = ts.cross(X, B_A) + BxA
            BC = ts.cross(X, C_B) + CxB
            CA = ts.cross(X, A_C) + AxC
            if AB <= 0 and BC <= 0 and CA <= 0:
                zindex = pos.z  #(Ak * a.z * BC + Bk * b.z * CA + Ck * c.z * AB)
                zstep = zindex - ti.atomic_max(scene.zbuf[X], zindex)
                if zstep >= 0:
                    scene.img[X] = color
Ejemplo n.º 16
0
def render_particle(model, camera, vertex, radius, basecolor):
    scene = model.scene
    a = camera.untrans_pos(vertex)
    A = camera.uncook(a)

    bx = camera.fx * radius / a.z
    by = camera.fy * radius / a.z
    M = A
    N = A
    M.x -= bx
    N.x += bx
    M.y -= by
    N.y += by

    M.x, N.x = min(max(M.x, 0),
                   camera.img.shape[0]), min(max(N.x, 0), camera.img.shape[1])
    M.y, N.y = min(max(M.y, 0),
                   camera.img.shape[0]), min(max(N.y, 0), camera.img.shape[1])
    if (M.x < N.x and M.y < N.y):
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            W = ti.cast(ti.Vector([X.x, X.y, a.z]), ti.f32)
            w = cook_coord(camera, W)
            dw = w - a
            dw2 = dw.norm_sqr()

            if dw2 > radius**2:
                continue
            dz = ti.sqrt(radius**2 - dw2)
            n = ti.Vector([dw.x, dw.y, -dz])
            zindex = 1 / (a.z - dz)
            if zindex >= ti.atomic_max(camera.zbuf[X], zindex):
                normal = ts.normalize(n)
                view = ts.normalize(a + n)
                color = get_ambient(camera, normal, view) * basecolor
                for light in ti.static(scene.lights):
                    light_color = scene.opt.render_func(
                        a + n, normal, view, light, basecolor)
                    color += light_color
                camera.img[X] = color
                camera.nbuf[X] = normal
Ejemplo n.º 17
0
def render_particle(model, camera, index):
    scene = model.scene
    L2W = model.L2W
    a = model.pos[index]
    r = model.radius[index]
    a = camera.untrans_pos(L2W @ a)
    A = camera.uncook(a)

    rad = camera.uncook(ts.vec3(r, r, a.z), False)

    M = int(ti.floor(A - rad))
    N = int(ti.ceil(A + rad))
    M = ts.clamp(M, 0, ti.Vector(camera.res))
    N = ts.clamp(N, 0, ti.Vector(camera.res))

    for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
        pos = camera.cook(float(ts.vec3(X, a.z)))
        dp = pos - a
        dp2 = dp.norm_sqr()

        if dp2 > r**2:
            continue

        dz = ti.sqrt(r**2 - dp2)
        zindex = 1 / (a.z - dz)

        if zindex < ti.atomic_max(camera.fb['idepth'][X], zindex):
            continue

        n = ts.vec3(dp.xy, -dz)
        normal = ts.normalize(n)
        view = ts.normalize(a + n)
        color = ts.vec3(1.0)

        color = model.colorize(pos, normal, color)
        camera.fb['img'][X] = color
        camera.fb['normal'][X] = normal
Ejemplo n.º 18
0
 def atomic_depth(self, X, depth):
     idepth = self.idepth_fixp(1 / depth)
     return idepth < ti.atomic_max(self['idepth'][X], idepth)
Ejemplo n.º 19
0
 def test0():
     for I in x:
         x[I] = 0
     x[1] = ti.cast(1, ti.u64) << 63
     for I in x:
         ti.atomic_max(x[0], x[I])
Ejemplo n.º 20
0
def render_triangle(model, camera, face):
    scene = model.scene
    L2W = model.L2W
    posa, posb, posc = model.pos[face[0, 0]], model.pos[face[1, 0]], model.pos[
        face[2, 0]]
    texa, texb, texc = model.tex[face[0, 1]], model.tex[face[1, 1]], model.tex[
        face[2, 1]]
    nrma, nrmb, nrmc = model.nrm[face[0, 2]], model.nrm[face[1, 2]], model.nrm[
        face[2, 2]]
    posa = camera.untrans_pos(L2W @ posa)
    posb = camera.untrans_pos(L2W @ posb)
    posc = camera.untrans_pos(L2W @ posc)
    nrma = camera.untrans_dir(L2W.matrix @ nrma)
    nrmb = camera.untrans_dir(L2W.matrix @ nrmb)
    nrmc = camera.untrans_dir(L2W.matrix @ nrmc)

    pos_center = (posa + posb + posc) / 3
    if ti.static(camera.type == camera.ORTHO):
        pos_center = ts.vec3(0.0, 0.0, 1.0)

    dpab = posa - posb
    dpac = posa - posc
    dtab = texa - texb
    dtac = texa - texc

    normal = ts.cross(dpab, dpac)
    tan, bitan = compute_tangent(-dpab, -dpac, -dtab, -dtac)

    # NOTE: the normal computation indicates that a front-facing face should
    # be COUNTER-CLOCKWISE, i.e., glFrontFace(GL_CCW);
    # this is to be compatible with obj model loading.
    if ts.dot(pos_center, normal) <= 0:

        clra = model.vertex_shader(posa, texa, nrma, tan, bitan)
        clrb = model.vertex_shader(posb, texb, nrmb, tan, bitan)
        clrc = model.vertex_shader(posc, texc, nrmc, tan, bitan)

        A = camera.uncook(posa)
        B = camera.uncook(posb)
        C = camera.uncook(posc)
        scr_norm = 1 / ts.cross(A - C, B - A)
        B_A = (B - A) * scr_norm
        C_B = (C - B) * scr_norm
        A_C = (A - C) * scr_norm

        # screen space bounding box
        M = int(ti.floor(min(A, B, C) - 1))
        N = int(ti.ceil(max(A, B, C) + 1))
        M = ts.clamp(M, 0, ti.Vector(camera.res))
        N = ts.clamp(N, 0, ti.Vector(camera.res))
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            # barycentric coordinates using the area method
            X_A = X - A
            w_C = ts.cross(B_A, X_A)
            w_B = ts.cross(A_C, X_A)
            w_A = 1 - w_C - w_B
            # draw
            eps = ti.get_rel_eps() * 0.2
            is_inside = w_A >= -eps and w_B >= -eps and w_C >= -eps
            if not is_inside:
                continue
            zindex = 1 / (posa.z * w_A + posb.z * w_B + posc.z * w_C)
            if zindex < ti.atomic_max(camera.fb['idepth'][X], zindex):
                continue

            clr = [
                a * w_A + b * w_B + c * w_C
                for a, b, c in zip(clra, clrb, clrc)
            ]
            camera.fb.update(X, model.pixel_shader(*clr))
Ejemplo n.º 21
0
def render_triangle(model, camera, face):
    scene = model.scene
    L2W = model.L2W
    _1 = ti.static(min(1, model.faces.m - 1))
    _2 = ti.static(min(2, model.faces.m - 1))
    ia, ib, ic = model.vi[face[0, 0]], model.vi[face[1, 0]], model.vi[face[2,
                                                                           0]]
    ta, tb, tc = model.vt[face[0, _1]], model.vt[face[1,
                                                      _1]], model.vt[face[2,
                                                                          _1]]
    na, nb, nc = model.vn[face[0, _2]], model.vn[face[1,
                                                      _2]], model.vn[face[2,
                                                                          _2]]
    a = camera.untrans_pos(L2W @ ia)
    b = camera.untrans_pos(L2W @ ib)
    c = camera.untrans_pos(L2W @ ic)

    # NOTE: the normal computation indicates that # a front-facing face should
    # be COUNTER-CLOCKWISE, i.e., glFrontFace(GL_CCW);
    # this is to be compatible with obj model loading.
    normal = ts.normalize(ts.cross(a - b, a - c))
    pos = (a + b + c) / 3
    view_pos = (a + b + c) / 3
    if ti.static(camera.type == camera.ORTHO):
        view_pos = ts.vec3(0.0, 0.0, 1.0)
    if ts.dot(view_pos, normal) <= 0:
        # shading
        color = ts.vec3(0.0)
        for light in ti.static(scene.lights):
            color += scene.opt.render_func(pos, normal, ts.vec3(0.0), light)
        color = scene.opt.pre_process(color)
        A = camera.uncook(a)
        B = camera.uncook(b)
        C = camera.uncook(c)
        scr_norm = 1 / ts.cross(A - C, B - A)
        B_A = (B - A) * scr_norm
        C_B = (C - B) * scr_norm
        A_C = (A - C) * scr_norm

        W = 1
        # screen space bounding box
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        M.x, N.x = min(max(M.x, 0),
                       camera.img.shape[0]), min(max(N.x, 0),
                                                 camera.img.shape[1])
        M.y, N.y = min(max(M.y, 0),
                       camera.img.shape[0]), min(max(N.y, 0),
                                                 camera.img.shape[1])
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            # barycentric coordinates using the area method
            X_A = X - A
            w_C = ts.cross(B_A, X_A)
            w_B = ts.cross(A_C, X_A)
            w_A = 1 - w_C - w_B
            # draw
            in_screen = w_A >= 0 and w_B >= 0 and w_C >= 0 and 0 < X[
                0] < camera.img.shape[0] and 0 < X[1] < camera.img.shape[1]
            if not in_screen:
                continue
            zindex = 1 / (a.z * w_A + b.z * w_B + c.z * w_C)
            if zindex < ti.atomic_max(camera.zbuf[X], zindex):
                continue

            coor = (ta * w_A + tb * w_B + tc * w_C)
            camera.img[X] = color * model.texSample(coor)
Ejemplo n.º 22
0
 def func():
     a = -1000
     for i in range(10):
         ti.atomic_max(a, i)
     A[None] = a
Ejemplo n.º 23
0
 def func():
     for i in range(n):
         # this is an expr with side effect, make sure it's not optimized out.
         ti.atomic_max(c[None], i * step)