diff --git a/python/taichi/ui/scene.py b/python/taichi/ui/scene.py index f343f47d89bf2..4544505148dc8 100644 --- a/python/taichi/ui/scene.py +++ b/python/taichi/ui/scene.py @@ -94,9 +94,15 @@ def mesh(self, normals=None, color=(0.5, 0.5, 0.5), per_vertex_color=None, - two_sided=False): + two_sided=False, + vertex_offset: int = 0, + vertex_count: int = None, + index_offset: int = 0, + index_count: int = None): """Declare a mesh inside the scene. - + if you indicate the index_offset and index_count, the normals will also + be sliced by the args, and the shading resultes will not be affected. + (It is equal to make a part of the mesh visible) Args: vertices: a taichi 3D Vector field, where each element indicate the 3D location of a vertex. @@ -112,6 +118,19 @@ def mesh(self, element indicate the RGB color of a vertex. two_sided (bool): whether or not the triangles should be able to be seen from both sides. + vertex_offset: int type(ohterwise float type will be floored to int), + if 'indices' is provided, this means the value added to the vertex + index before indexing into the vertex buffer, else this means the + index of the first vertex to draw. + vertex_count: int type(ohterwise float type will be floored to int), + only avaliable when `indices` is not provided, which is the number + of vertices to draw. + index_offset: int type(ohterwise float type will be floored to int), + only avaliable when `indices` is provided, which is the base index + within the index buffer. + index_count: int type(ohterwise float type will be floored to int), + only avaliable when `indices` is provided, which is the the number + of vertices to draw. """ vbo = get_vbo_field(vertices) copy_vertices_to_vbo(vbo, vertices) @@ -120,18 +139,25 @@ def mesh(self, copy_colors_to_vbo(vbo, per_vertex_color) if normals is None: normals = gen_normals(vertices, indices) + if vertex_count is None: + vertex_count = vertices.shape[0] + if index_count is None: + index_count = indices.shape[0] copy_normals_to_vbo(vbo, normals) vbo_info = get_field_info(vbo) indices_info = get_field_info(indices) self.scene.mesh(vbo_info, has_per_vertex_color, indices_info, color, - two_sided) + two_sided, index_count, index_offset, vertex_count, + vertex_offset) def particles(self, centers, radius, color=(0.5, 0.5, 0.5), - per_vertex_color=None): + per_vertex_color=None, + index_offset: int = 0, + index_count: int = None): """Declare a set of particles within the scene. Args: @@ -141,16 +167,21 @@ def particles(self, values. If `per_vertex_color` is provided, this is ignored. per_vertex_color (Tuple[float]): a taichi 3D vector field, where each element indicate the RGB color of a particle. - two_sided (bool): whether or not the triangles should be able to be - seen from both sides. + index_offset: int type(ohterwise float type will be floored to int), + the index of the first vertex to draw. + index_count: int type(ohterwise float type will be floored to int), + the number of vertices to draw. """ vbo = get_vbo_field(centers) copy_vertices_to_vbo(vbo, centers) has_per_vertex_color = per_vertex_color is not None if has_per_vertex_color: copy_colors_to_vbo(vbo, per_vertex_color) + if index_count is None: + index_count = centers.shape[0] vbo_info = get_field_info(vbo) - self.scene.particles(vbo_info, has_per_vertex_color, color, radius) + self.scene.particles(vbo_info, has_per_vertex_color, color, radius, + index_count, index_offset) def point_light(self, pos, color): # pylint: disable=W0235 """Set a point light in this scene. diff --git a/taichi/python/export_ggui.cpp b/taichi/python/export_ggui.cpp index dfdba39468723..656ef014e93cd 100644 --- a/taichi/python/export_ggui.cpp +++ b/taichi/python/export_ggui.cpp @@ -139,11 +139,20 @@ struct PyScene { bool has_per_vertex_color, FieldInfo indices, py::tuple color, - bool two_sided) { + bool two_sided, + float draw_index_count, + float draw_first_index, + float draw_vertex_count, + float draw_first_vertex) { RenderableInfo renderable_info; renderable_info.vbo = vbo; renderable_info.has_per_vertex_color = has_per_vertex_color; renderable_info.indices = indices; + renderable_info.has_user_customized_draw = true; + renderable_info.draw_index_count = (int)draw_index_count; + 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; MeshInfo info; info.renderable_info = renderable_info; @@ -156,10 +165,15 @@ struct PyScene { void particles(FieldInfo vbo, bool has_per_vertex_color, py::tuple color_, - float radius) { + float radius, + float draw_vertex_count, + float draw_first_vertex) { RenderableInfo renderable_info; renderable_info.vbo = vbo; + renderable_info.has_user_customized_draw = true; renderable_info.has_per_vertex_color = has_per_vertex_color; + renderable_info.draw_vertex_count = (int)draw_vertex_count; + renderable_info.draw_first_vertex = (int)draw_first_vertex; ParticlesInfo info; info.renderable_info = renderable_info; diff --git a/taichi/ui/backends/vulkan/renderable.cpp b/taichi/ui/backends/vulkan/renderable.cpp index a17451899c941..427e96032f187 100644 --- a/taichi/ui/backends/vulkan/renderable.cpp +++ b/taichi/ui/backends/vulkan/renderable.cpp @@ -49,22 +49,45 @@ void Renderable::update_data(const RenderableInfo &info) { } int num_vertices = info.vbo.shape[0]; + int draw_num_vertices = info.draw_vertex_count; + int draw_first_vertices = info.draw_first_vertex % num_vertices; + int num_indices; + int draw_num_indices; + int draw_first_indices; + if (info.indices.valid) { TI_ERROR_IF(info.indices.matrix_cols != 1, "indices must either be a ti.field or a 2D/3D ti.Vector.field"); num_indices = info.indices.shape[0] * info.indices.matrix_rows; + draw_num_indices = info.draw_index_count * info.indices.matrix_rows; + draw_first_indices = + (info.draw_first_index * info.indices.matrix_rows) % num_indices; if (info.indices.dtype != PrimitiveType::i32 && info.indices.dtype != PrimitiveType::u32) { throw std::runtime_error("dtype needs to be 32-bit ints for indices"); } } else { num_indices = 1; + draw_num_indices = 1; + draw_first_indices = 0; } config_.vertices_count = num_vertices; config_.indices_count = num_indices; + if (info.has_user_customized_draw) { + config_.draw_vertex_count = draw_num_vertices; + config_.draw_first_vertex = draw_first_vertices; + config_.draw_index_count = draw_num_indices; + config_.draw_first_index = draw_first_indices; + } else { + config_.draw_vertex_count = num_vertices; + config_.draw_first_vertex = 0; + config_.draw_index_count = num_indices; + config_.draw_first_index = 0; + } + if (num_vertices > config_.max_vertices_count || num_indices > config_.max_indices_count) { free_buffers(); @@ -252,9 +275,11 @@ void Renderable::record_this_frame_commands(CommandList *command_list) { command_list->bind_resources(pipeline_->resource_binder()); if (indexed_) { - command_list->draw_indexed(config_.indices_count, 0, 0); + command_list->draw_indexed(config_.draw_index_count, + config_.draw_first_vertex, + config_.draw_first_index); } else { - command_list->draw(config_.vertices_count, 0); + command_list->draw(config_.draw_vertex_count, config_.draw_first_vertex); } } diff --git a/taichi/ui/backends/vulkan/renderable.h b/taichi/ui/backends/vulkan/renderable.h index e0b873a42172d..71d9ce1f59886 100644 --- a/taichi/ui/backends/vulkan/renderable.h +++ b/taichi/ui/backends/vulkan/renderable.h @@ -29,6 +29,10 @@ struct RenderableConfig { int max_indices_count{0}; int vertices_count{0}; int indices_count{0}; + int draw_vertex_count{0}; + int draw_first_vertex{0}; + int draw_index_count{0}; + int draw_first_index{0}; size_t ubo_size{0}; size_t ssbo_size{0}; bool blending{false}; diff --git a/taichi/ui/backends/vulkan/renderables/circles.cpp b/taichi/ui/backends/vulkan/renderables/circles.cpp index 0b3d5bc466078..8083676d0393c 100644 --- a/taichi/ui/backends/vulkan/renderables/circles.cpp +++ b/taichi/ui/backends/vulkan/renderables/circles.cpp @@ -24,6 +24,10 @@ void Circles::init_circles(AppContext *app_context, 1, vertices_count, 1, + vertices_count, + 0, + 1, + 0, sizeof(UniformBufferObject), 0, true, diff --git a/taichi/ui/backends/vulkan/renderables/lines.cpp b/taichi/ui/backends/vulkan/renderables/lines.cpp index 99d1d4f811fa8..d3035f8af71bd 100644 --- a/taichi/ui/backends/vulkan/renderables/lines.cpp +++ b/taichi/ui/backends/vulkan/renderables/lines.cpp @@ -27,6 +27,10 @@ void Lines::init_lines(AppContext *app_context, indices_count, vertices_count, indices_count, + vertices_count, + 0, + indices_count, + 0, sizeof(UniformBufferObject), 0, true, diff --git a/taichi/ui/backends/vulkan/renderables/mesh.cpp b/taichi/ui/backends/vulkan/renderables/mesh.cpp index 52f7b36210235..5200c11b2cd19 100644 --- a/taichi/ui/backends/vulkan/renderables/mesh.cpp +++ b/taichi/ui/backends/vulkan/renderables/mesh.cpp @@ -51,6 +51,10 @@ void Mesh::init_mesh(AppContext *app_context, indices_count, vertices_count, indices_count, + vertices_count, + 0, + indices_count, + 0, sizeof(UniformBufferObject), 1, true, diff --git a/taichi/ui/backends/vulkan/renderables/particles.cpp b/taichi/ui/backends/vulkan/renderables/particles.cpp index 66918ec3eb945..c5f00ea2b5b36 100644 --- a/taichi/ui/backends/vulkan/renderables/particles.cpp +++ b/taichi/ui/backends/vulkan/renderables/particles.cpp @@ -56,6 +56,10 @@ void Particles::init_particles(AppContext *app_context, 1, vertices_count, 1, + vertices_count, + 0, + 1, + 0, sizeof(UniformBufferObject), 1, true, diff --git a/taichi/ui/backends/vulkan/renderables/set_image.cpp b/taichi/ui/backends/vulkan/renderables/set_image.cpp index ea5da2b9ee977..7054a12560a45 100644 --- a/taichi/ui/backends/vulkan/renderables/set_image.cpp +++ b/taichi/ui/backends/vulkan/renderables/set_image.cpp @@ -116,6 +116,10 @@ void SetImage::init_set_image(AppContext *app_context, 6, 6, 6, + 6, + 0, + 6, + 0, sizeof(UniformBufferObject), 0, false, diff --git a/taichi/ui/backends/vulkan/renderables/triangles.cpp b/taichi/ui/backends/vulkan/renderables/triangles.cpp index c4ac445d13e15..f273a5b8ee94d 100644 --- a/taichi/ui/backends/vulkan/renderables/triangles.cpp +++ b/taichi/ui/backends/vulkan/renderables/triangles.cpp @@ -23,6 +23,10 @@ void Triangles::init_triangles(AppContext *app_context, indices_count, vertices_count, indices_count, + vertices_count, + 0, + indices_count, + 0, sizeof(UniformBufferObject), 0, true, diff --git a/taichi/ui/common/renderable_info.h b/taichi/ui/common/renderable_info.h index 585ff40ec0afc..4752000fd3cb9 100644 --- a/taichi/ui/common/renderable_info.h +++ b/taichi/ui/common/renderable_info.h @@ -11,6 +11,11 @@ struct RenderableInfo { FieldInfo indices; bool has_per_vertex_color{false}; VertexAttributes vbo_attrs{VboHelpers::all()}; + bool has_user_customized_draw{false}; + int draw_vertex_count{0}; + int draw_first_vertex{0}; + int draw_index_count{0}; + int draw_first_index{0}; }; TI_UI_NAMESPACE_END