Skip to content

Commit

Permalink
simple wireframe model
Browse files Browse the repository at this point in the history
  • Loading branch information
archibate committed Oct 27, 2020
1 parent ef9a19c commit 9cd1148
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ Notable changes:
* Set up multi-material ID system, use `t3.objunpackmtls` to separate OBJ by their material.
* Add a variety of nodes, including `t3.GaussianBlur`, `t3.ImgBinaryOp`, `t3.SuperSampling2x2`...
* Support `t3.DynamicMesh` for mesh with dynamic number of face.
* Add `taichi_three.mciso` module, with `MCISO` and `Voxelizer`.
* Support `t3.Skybox` as model and background sampler.
* Support `t3.ModelGroup` for grouped transformations.
* Add `t3.WireframeModel` and `t3.PolyToEdge`.

Minor fixes:
* Make camera buffer update less ad-hoc.
Expand Down
5 changes: 4 additions & 1 deletion examples/mciso_mpm3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,13 @@ def init():
scene = t3.Scene()
mesh = t3.DynamicMesh(n_faces=mciso.N_res, n_pos=mciso.N_res, n_nrm=mciso.N_res)
model = t3.Model(mesh)
#model.material = t3.MaterialVisualizeNormal()
#model.material = t3.Material(t3.IdealRT(specular=t3.Constant(1.0)))
scene.add_model(model)
camera = t3.Camera()
scene.add_camera(camera)
#skybox = t3.Skybox('assets/skybox.jpg')
#scene.add_model(skybox)
#scene.add_light(skybox)
scene.add_light(t3.Light([0.4, -1.5, -1.8], 0.8))
scene.add_light(t3.AmbientLight(0.22))

Expand Down
23 changes: 23 additions & 0 deletions examples/wireframe_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import taichi as ti
import taichi_three as t3
import numpy as np

ti.init(ti.cpu)

scene = t3.Scene()
model = t3.WireframeModel(t3.PolyToEdge(t3.Mesh.from_obj('assets/monkey.obj')))
scene.add_model(model)
camera = t3.Camera(res=(600, 400))
camera.ctl = t3.CameraCtl(pos=[0, 1, 1.8])
scene.add_camera(camera)
light = t3.Light([0.4, -1.5, -1.8])
scene.add_light(light)

gui = ti.GUI('Wireframe', camera.res)
while gui.running:
gui.get_event(None)
gui.running = not gui.is_pressed(ti.GUI.ESCAPE)
camera.from_mouse(gui)
scene.render()
gui.set_image(camera.img)
gui.show()
29 changes: 29 additions & 0 deletions taichi_three/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,35 @@ def render_triangle(model, camera, face):
camera.fb.update(X, dict(img=color))


@ti.func
def render_line(model, camera, face, w0=0, w1=1):
posa, posb = face.pos # Position
texa, texb = face.tex # TexCoord
nrma, nrmb = face.nrm # Normal

clra = [posa, texa, nrma]
clrb = [posb, texb, nrmb]

A = camera.uncook(posa)
B = camera.uncook(posb)

M = int(ti.floor(min(A, B) - 1))
N = int(ti.ceil(max(A, B) + 1))
M = ts.clamp(M, 0, ti.Vector(camera.fb.res))
N = ts.clamp(N, 0, ti.Vector(camera.fb.res))

B_A = (B - A).normalized()

for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
udf = abs((X - A).cross(B_A))
if udf >= w1:
continue

strength = ts.smoothstep(udf, w1, w0)
color = ts.vec3(strength)
camera.img[X] += color


@ti.func
def render_particle(model, camera, index):
scene = model.scene
Expand Down
51 changes: 51 additions & 0 deletions taichi_three/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,27 @@ def intersect(self, orig, dir):
return hit, orig, dir, clr


@ti.data_oriented
class WireframeModel(ModelBase):
def __init__(self, mesh):
super().__init__()
self.mesh = mesh

from .shading import Material, CookTorrance
self.material = Material(CookTorrance())

@ti.func
def render(self, camera):
self.mesh.before_rendering()
for i in ti.grouped(ti.ndrange(*self.mesh.shape)):
for j in ti.static(ti.grouped(ti.ndrange(*self.mesh.static_shape))):
face = self.mesh.get_face(i, j)
# L2C = W2C @ L2W, Local to Camera, i.e. ModelView in OpenGL
cs_face = TransformedFace(self.L2C[None], face)
render_line(self, camera, cs_face)



@ti.data_oriented
class ModelGroup(ModelBase):
def __init__(self, models=None):
Expand Down Expand Up @@ -333,4 +354,34 @@ def get_face(self, i, j: ti.template()):
tex = [face.tex[i] for i in [0, 2, 3]],
nrm = [face.nrm[i] for i in [0, 2, 3]],
)
return ret


@ti.data_oriented
class PolyToEdge:
def __init__(self, mesh, N=3):
self.mesh = mesh
self.N = N

@property
def shape(self):
return self.mesh.shape

@property
def static_shape(self):
return [self.N, *self.mesh.static_shape]

def before_rendering(self):
self.mesh.before_rendering()

@ti.func
def get_face(self, i, j: ti.template()):
face = self.mesh.get_face(i, ts.vec(*[j[_] for _ in range(1, j.n)]))
ret = DataOriented()
r = ti.static([j.x, (j.x + 1) % self.N])
ret.__dict__.update(
pos = [face.pos[i] for i in r],
tex = [face.tex[i] for i in r],
nrm = [face.nrm[i] for i in r],
)
return ret

0 comments on commit 9cd1148

Please sign in to comment.