Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doc] Add docs for GGUI's new features #5647

Merged
merged 27 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0e67c33
improve docs about new features of GGUI
Morcki Aug 5, 2022
0eaebbf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 5, 2022
d55c006
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
c20edec
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
d6e00b4
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
550f291
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
730a4de
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
7334da8
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
8fb1b90
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
cb766d9
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
8aae144
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 8, 2022
f3d2e67
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
e3f1752
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 8, 2022
6ad3755
rename wareframe to wireframe
Morcki Aug 8, 2022
d3a7a12
update some docs
Morcki Aug 8, 2022
a48a4e0
update docs
Morcki Aug 9, 2022
a95e28c
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
3f3000b
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
d2e5abe
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
9e94669
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
be5bf12
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
361c059
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
be6490c
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
4e2173e
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
9c120d6
Update docs/lang/articles/visualization/ggui.md
Morcki Aug 9, 2022
a0945ec
rename to
Morcki Aug 10, 2022
093ed9d
update
Morcki Aug 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 264 additions & 0 deletions docs/lang/articles/visualization/ggui.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Note that you need to call `point_light()` for every frame. Similar to the `canv
### 3D Geometries

```python
scene.lines(vertices, width, indices, color, per_vertex_color)
scene.mesh(vertices, indices, normals, color, per_vertex_color)
Morcki marked this conversation as resolved.
Show resolved Hide resolved
scene.particles(vertices, radius, color, per_vertex_color)
```
Expand All @@ -108,6 +109,220 @@ If a mesh has `num` triangles, the `indices` should be a 1D scalar field with a

`normals` is an optional parameter for `scene.mesh()`.

:::example

1. An example of drawing 3d-lines

```python
import taichi as ti

ti.init(arch=ti.cuda)

N = 10

particles_pos = ti.Vector.field(3, dtype=ti.f32, shape = N)
points_pos = ti.Vector.field(3, dtype=ti.f32, shape = N)

@ti.kernel
def init_points_pos(points : ti.template()):
for i in range(points.shape[0]):
points[i] = [i for j in ti.static(range(3))]

init_points_pos(particles_pos)
init_points_pos(points_pos)

window = ti.ui.Window("Test for Drawing 3d-lines", (768, 768))
canvas = window.get_canvas()
scene = ti.ui.Scene()
camera = ti.ui.make_camera()
camera.position(5, 2, 2)

while window.running:
camera.track_user_inputs(window, movement_speed=0.03, hold_key=ti.ui.RMB)
scene.set_camera(camera)
scene.ambient_light((0.8, 0.8, 0.8))
scene.point_light(pos=(0.5, 1.5, 1.5), color=(1, 1, 1))

scene.particles(particles_pos, color = (0.68, 0.26, 0.19), radius = 0.1)
# Draw 3d-lines in the scene
scene.lines(points_pos, color = (0.28, 0.68, 0.99), width = 5.0)
canvas.scene(scene)
window.show()
```

### Advanced 3d Geometries

```python
scene.lines(vertices, width, indices, color, per_vertex_color, vertex_offset, vertex_count, index_offset, index_count)

scene.mesh(vertices, indices, normals, color, per_vertex_color, vertex_offset, vertex_count, index_offset, index_count, show_wireframe)

scene.particles(vertices, radius, color, per_vertex_color, index_offset, index_count)

scene.mesh_instance(vertices, indices, normals, color, per_vertex_color, vertex_offset, vertex_count, index_offset, index_count, show_wireframe)
```

The additional arguments `vertex_offset`, `vertex_count`, `index_offset` and `index_count` control the visible part of the particles and mesh. For the `mesh()` and `mesh_instance()` methods, set whether to show wireframe mode through setting `show_wireframe`.

:::example

1. Example of drawing a part of the mesh/particles

```python
# For particles
# draw the 2-th to 7-th particles
scene.particles(center, radius,
index_offset = 1,
index_count = 6)

# For mesh
# 1. with indices
scene.mesh(vertices, indices,
index_offset = user_defined_first_indices_index,
index_count = user_defined_index_count,
# vertex_offset is set to 0 by default, and it is not necessary
# to assign vertex_offset a value that otherwise you must.
vertex_offset = user_defined_vertex_offset)

# usually used as below:
# draw the 11-th to 111-th mesh vertexes
scene.mesh(vertices, indices,
index_offset = 10,
index_count = 100)

# 2. without indices (similar to the particles' example above)
scene.mesh(vertices,
vertex_offset = user_defined_first_vertex_index,
vertex_count = user_defined_vertex_count)
```
2. An example of drawing part of lines
```python
import taichi as ti

ti.init(arch=ti.cuda)

N = 10

particles_pos = ti.Vector.field(3, dtype=ti.f32, shape = N)
points_pos = ti.Vector.field(3, dtype=ti.f32, shape = N)
points_indices = ti.Vector.field(1, dtype=ti.i32, shape = N)

@ti.kernel
def init_points_pos(points : ti.template()):
for i in range(points.shape[0]):
points[i] = [i for j in range(3)]
# points[i] = [ti.sin(i * 1.0), i * 0.2, ti.cos(i * 1.0)]

@ti.kernel
def init_points_indices(points_indices : ti.template()):
for i in range(N):
points_indices[i][0] = i // 2 + i % 2

init_points_pos(particles_pos)
init_points_pos(points_pos)
init_points_indices(points_indices)

window = ti.ui.Window("Test for Drawing 3d-lines", (768, 768))
canvas = window.get_canvas()
scene = ti.ui.Scene()
camera = ti.ui.make_camera()
camera.position(5, 2, 2)

while window.running:
camera.track_user_inputs(window, movement_speed=0.03, hold_key=ti.ui.RMB)
scene.set_camera(camera)
scene.ambient_light((0.8, 0.8, 0.8))
scene.point_light(pos=(0.5, 1.5, 1.5), color=(1, 1, 1))

scene.particles(particles_pos, color = (0.68, 0.26, 0.19), radius = 0.1)
# Here you will get visible part from the 3rd point with (N - 4) points.
scene.lines(points_pos, color = (0.28, 0.68, 0.99), width = 5.0, vertex_count = N - 4, vertex_offset = 2)
# Using indices to indicate which vertex to use
# scene.lines(points_pos, color = (0.28, 0.68, 0.99), width = 5.0, indices = points_indices)
# Case 1, vertex_count will be changed to N - 2 when drawing.
# scene.lines(points_pos, color = (0.28, 0.68, 0.99), width = 5.0, vertex_count = N - 1, vertex_offset = 0)
# Case 2, vertex_count will be changed to N - 2 when drawing.
# scene.lines(points_pos, color = (0.28, 0.68, 0.99), width = 5.0, vertex_count = N, vertex_offset = 2)
canvas.scene(scene)
window.show()
```

3. Details of mesh instancing
```python
num_instance = 100
m_transforms = ti.Matrix.field(4, 4, dtype = ti.f32, shape = num_instance)


# For example: An object is scaled by 2, rotated by rotMat, and translated by t = [1, 2, 3], then
#
# The ScaleMatrix is:
# 2, 0, 0, 0
# 0, 2, 0, 0
# 0, 0, 2, 0
# 0, 0, 0, 1
#
# The RotationMatrix is:
# https://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
#
# The TranslationMatrix is:
# 1, 0, 0, 1
# 0, 1, 0, 2
# 0, 0, 1, 3
# 0, 0, 0, 1
#
# Let TransformMatrix = TranslationMatrix @ RotationMatrix @ ScaleMatrix, then the final TransformMatrix is:
# 2 * rotMat00, rotMat01, rotMat02, 1
# rotMat10, 2 * rotMat11, rotMat12, 2
# rotMat20, rotMat21, 2 * rotMat22, 3
# 0, 0, 0, 1
...

# Draw mesh instances (from the 1st instance)
scene.mesh_instance(vertices, indices, transforms = m_transforms, instance_offset = 1)
```
4. Example of setting wireframe mode
```python

window = ti.ui.Window("Display Mesh", (1024, 1024), vsync=True)
canvas = window.get_canvas()
scene = ti.ui.Scene()
camera = ti.ui.make_camera()
Morcki marked this conversation as resolved.
Show resolved Hide resolved

# slider_int usage
some_int_type_value = 0
def show_options():
global some_int_type_value

window.GUI.begin("Display Panel", 0.05, 0.1, 0.2, 0.15)
display_mode = window.GUI.slider_int("Value Range", some_int_type_value, 0, 5)
window.GUI.end()

while window.running:

...
# if to show wireframe
scene.mesh_instance(vertices, indices, instance_count = 100 , show_wireframe = True)

canvas.scene(scene)
show_options()
window.show()
```



:::note

If `indices` is not provided, consider using like this:
```python
scene.mesh(vertices, normals, color, per_vertex_color, vertex_offset, vertex_count, wireframe)
```
If `indices` is provided, consider using like this:
```python
scene.mesh(vertices, indices, normals, color, per_vertex_color, vertex_offset, index_offset, index_count, wireframe)
```



:::

### Rendering the scene
Expand All @@ -118,6 +333,55 @@ You can render a scene on a canvas.
canvas.scene(scene)
```

### Fetching Color/Depth information

```python
img = window.get_image_buffer()
window.get_depth_buffer(scene_depth)
depth = window.get_depth_buffer_as_numpy()
```

After rendering the current scene, you can fetch the color and depth information of the current scene using `get_image_buffer()` and `get_depth_buffer_as_numpy()`, which copy the gpu data to a NumPy array(cpu).
`get_depth_buffer()` copies the GPU data to a Taichi field (depend on the `arch` you choose) or copies data from GPU to GPU.
ailzhang marked this conversation as resolved.
Show resolved Hide resolved

:::example

1. Example of fetching color information
Morcki marked this conversation as resolved.
Show resolved Hide resolved
```python
window = ti.ui.Window("Test for getting image buffer from ggui", (768, 768), vsync=True)
video_manager = ti.tools.VideoManager("OutputDir")

while window.running:
render_scene()
img = window.get_image_buffer()
video_manager.write_frame(img)
window.show()

video_manager.make_video(gif=True, mp4=True)
```

2. An example of fetching the depth data
```python
window_shape = (720, 1080)
window = ti.ui.Window("Test for copy depth data", window_shape)
canvas = window.get_canvas()
scene = ti.ui.Scene()
camera = ti.ui.make_camera()

# Get the shape of the window
w, h = window.get_window_shape()
# The field/ndarray stores the depth information, and must be of the ti.f32 data type and have a 2d shape.
# or, in other words, the shape must equal the window's shape
scene_depth = ti.ndarray(ti.f32, shape = (w, h))
# scene_depth = ti.field(ti.f32, shape = (w, h))

while window.running:
render()
canvas.scene(scene)
window.get_depth_buffer(scene_depth)
window.show()
```

## GUI components

The design of GGUI's GUI components follows the [Dear ImGui](https://github.com/ocornut/imgui) APIs.
Expand Down
12 changes: 6 additions & 6 deletions python/taichi/ui/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def mesh(self,
vertex_count: int = None,
index_offset: int = 0,
index_count: int = None,
show_wareframe: bool = False):
show_wireframe: bool = False):
"""Declare a mesh inside the scene.

if you indicate the index_offset and index_count, the normals will also
Expand Down Expand Up @@ -206,7 +206,7 @@ def mesh(self,
index_count (int, optional):
only available when `indices` is provided, which is the the number
of vertices to draw.
show_wareframe (bool, optional):
show_wireframe (bool, optional):
turn on/off WareFrame mode.
"""
vbo = get_vbo_field(vertices)
Expand All @@ -229,7 +229,7 @@ def mesh(self,

self.scene.mesh(vbo_info, has_per_vertex_color, indices_info, color,
two_sided, index_count, index_offset, vertex_count,
vertex_offset, show_wareframe)
vertex_offset, show_wireframe)

def mesh_instance(self,
vertices,
Expand All @@ -245,7 +245,7 @@ def mesh_instance(self,
vertex_count: int = None,
index_offset: int = 0,
index_count: int = None,
show_wareframe: bool = False):
show_wireframe: bool = False):
"""Declare mesh instances inside the scene.

If transforms is given, then according to the shape of transforms, it will
Expand Down Expand Up @@ -290,7 +290,7 @@ def mesh_instance(self,
index_count (int, optional):
only available when `indices` is provided, which is the the number
of indices to draw.
show_wareframe (bool, optional):
show_wireframe (bool, optional):
turn on/off WareFrame mode.
"""
vbo = get_vbo_field(vertices)
Expand Down Expand Up @@ -319,7 +319,7 @@ def mesh_instance(self,
color, two_sided, transform_info,
instance_count, instance_offset, index_count,
index_offset, vertex_count, vertex_offset,
show_wareframe)
show_wireframe)

def particles(self,
centers,
Expand Down
4 changes: 2 additions & 2 deletions python/taichi/ui/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ def get_depth_buffer_as_numpy(self):
arr_vulkan_layout_to_arr_normal_layout(tmp_depth, depth_numpy_arr)
return depth_numpy_arr

def get_image_buffer(self):
def get_image_buffer_as_numpy(self):
"""Get the window content to numpy array.

Returns:
3d numpy array: [width, height, channels] with (0.0~1.0) float-format color.
"""
return self.window.get_image_buffer()
return self.window.get_image_buffer_as_numpy()

def destroy(self):
"""Destroy this window. The window will be unavailable then.
Expand Down
10 changes: 5 additions & 5 deletions taichi/python/export_ggui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ struct PyScene {
float draw_first_index,
float draw_vertex_count,
float draw_first_vertex,
bool show_wareframe) {
bool show_wireframe) {
RenderableInfo renderable_info;
renderable_info.vbo = vbo;
renderable_info.has_per_vertex_color = has_per_vertex_color;
Expand All @@ -186,7 +186,7 @@ struct PyScene {
renderable_info.draw_first_index = (int)draw_first_index;
renderable_info.draw_vertex_count = (int)draw_vertex_count;
renderable_info.draw_first_vertex = (int)draw_first_vertex;
renderable_info.display_mode = show_wareframe
renderable_info.display_mode = show_wireframe
? taichi::lang::PolygonMode::Line
: taichi::lang::PolygonMode::Fill;

Expand Down Expand Up @@ -231,7 +231,7 @@ struct PyScene {
float draw_first_index,
float draw_vertex_count,
float draw_first_vertex,
bool show_wareframe) {
bool show_wireframe) {
RenderableInfo renderable_info;
renderable_info.vbo = vbo;
renderable_info.has_per_vertex_color = has_per_vertex_color;
Expand All @@ -241,7 +241,7 @@ struct PyScene {
renderable_info.draw_first_index = (int)draw_first_index;
renderable_info.draw_vertex_count = (int)draw_vertex_count;
renderable_info.draw_first_vertex = (int)draw_first_vertex;
renderable_info.display_mode = show_wareframe
renderable_info.display_mode = show_wireframe
? taichi::lang::PolygonMode::Line
: taichi::lang::PolygonMode::Fill;

Expand Down Expand Up @@ -484,7 +484,7 @@ void export_ggui(py::module &m) {
.def("write_image", &PyWindow::write_image)
.def("copy_depth_buffer_to_ndarray",
&PyWindow::copy_depth_buffer_to_ndarray)
.def("get_image_buffer", &PyWindow::get_image_buffer)
.def("get_image_buffer_as_numpy", &PyWindow::get_image_buffer)
.def("is_pressed", &PyWindow::is_pressed)
.def("get_cursor_pos", &PyWindow::py_get_cursor_pos)
.def("is_running", &PyWindow::is_running)
Expand Down