news 2026/9/11 3:46:43

Taichi 精选示例实战指南:从物理仿真到稀疏数据结构与 Marching Cubes

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Taichi 精选示例实战指南:从物理仿真到稀疏数据结构与 Marching Cubes

Taichi 精选示例实战指南:从物理仿真到稀疏数据结构与 Marching Cubes

【免费下载链接】taichiProductive, portable, and performant GPU programming in Python.项目地址: https://gitcode.com/GitHub_Trending/ta/taichi

导读

misc/examples.md是 Taichi 仓库维护的一张"旗舰示例"速览页,集中收录了最能体现 Taichi 核心能力的 8 个代表性程序,覆盖可微物理仿真(MPM 弹性体、FEM 有限元、Position Based Fluids 流体)、元胞自动机(Game of Life)、弹簧质点布料、Marching Cubes 网格提取与稀疏数据结构(Sparse Grids)等方向。本文以这些官方示例为主线,结合python/taichi/examples/下的真实源码,逐一拆解每个示例的物理模型、Taichi 语法要点与运行方式,帮助读者在跑通演示的同时,掌握将 Taichi 应用于数值计算与交互式 GPU 编程的方法。读完本文,你将能够使用ti example一键运行/导出/打印这些官方示例,理解自动微分(ti.ad.Tape)、稀疏 SNode 布局、统一粒子网格(PIC/APIC)与 Marching Cubes 查表等关键技术的代码级实现,并在此基础上改写出自己的仿真程序。

一、示例总览与运行方式

1.1 八个旗舰示例一览

misc/examples.md精选的 8 个示例及对应源码路径如下(均在 python/taichi/examples 目录下):

示例源码路径技术主题
MPM 拉格朗日力仿真simulation/mpm_lagrangian_forces.py可微 MPM + 能量最小化(Neo-Hookean)
Sparse Gridsfeatures/sparse/taichi_sparse.py稀疏指针 SNode 与活动块查询
2D Position Based Fluidssimulation/pbf2d.pyPBF 流体约束求解
Conway's Game of Lifesimulation/game_of_life.py元胞自动机 + GUI 交互
FEM 弹性体(128 单元)simulation/fem128.py有限元 +ti.ad.Tape自动微分
3D 布料弹簧质点ggui_examples/mass_spring_3d_ggui.py弹簧-阻尼布料 + GGUI 3D 渲染
Marching Cubesalgorithm/mciso_advanced.py2D/3D 等值面提取 + PLY 导出
3D MPMsimulation/mpm3d.py三维雪花/弹性体 MPM

说明:misc/examples.md中引用的simulation/mass_spring_3d.py在当前仓库中已迁移为 GGUI 版本 ggui_examples/mass_spring_3d_ggui.py,本文以仓库现有源码为准。

1.2 使用ti example命令运行

这些示例统一通过ti example子命令管理。在 python/taichi/_main.py 中可以看到其完整实现:命令首先扫描examples目录下所有*.py文件并建立"示例名 -> 目录"映射(_get_available_examples,python/taichi/_main.py),随后支持交互式选择或直接指定示例名运行。

# 列出全部可用示例,并以交互方式选择运行 ti example # 直接运行指定示例(示例名取源码文件名去掉 .py) ti example mpm88 ti example pbf2d ti example taichi_sparse # 打印示例源码而不运行 ti example game_of_life -p # 带行号、语法高亮的富文本打印 ti example fem128 -P # 将示例源码保存到当前目录 ti example mciso_advanced -s

其中-p/-P/-s三个参数分别对应 python/taichi/_main.py 中定义的--print--pretty-print--save。运行时会通过runpy.run_path(target, run_name="__main__")以模块方式执行目标文件(python/taichi/_main.py),因此示例内的if __name__ == "__main__": main()入口会被正常触发。

ti example之外,仓库还提供了交互式图库ti gallery(python/taichi/_main.py),可以用鼠标在图形界面中挑选并运行示例。也可以直接以 Python 脚本方式运行源码:

python python/taichi/examples/simulation/mpm3d.py python python/taichi/examples/features/sparse/taichi_sparse.py

1.3 运行前的环境说明

  • 示例中ti.init(arch=ti.gpu)会自动选择可用的 GPU 后端(CUDA/Vulkan/Metal 等);无 GPU 时可手动改为ti.init(arch=ti.cpu)运行(如 simulation/game_of_life.py 默认不指定 arch)。
  • GUI 示例依赖 Taichi 内置的ti.GUI(CPU 窗口)或ti.ui.Window(GGUI,3D 渲染),需要图形环境。
  • 硬件相关示例(如ti.cuda)需要对应驱动与后端支持,例如 features/sparse/taichi_sparse.py 明确指定arch=ti.cuda

二、可微 MPM:拉格朗日力与能量自动微分

2.1 示例定位与物理模型

simulation/mpm_lagrangian_forces.py 演示了 Taichi 最独特的组合能力:MPM(Material Point Method)框架 + 自动微分计算内力。与传统的"先求应力、再插值到网格"的做法不同,该示例直接把总势能(Neo-Hookean 超弹性能量)定义为粒子位置的函数,通过ti.ad.Tape(total_energy)反向传播得到x.grad(即内力F = -∂E/∂x),再把力项注入粒子到网格(P2G)的散射过程。

核心物理参数见 simulation/mpm_lagrangian_forces.py:

dim = 2 quality = 1 # 增大该整数可提升分辨率/质量 n_particle_x = 100 * quality n_particle_y = 8 * quality n_particles = n_particle_x * n_particle_y n_elements = (n_particle_x - 1) * (n_particle_y - 1) * 2 # 三角形单元数 n_grid = 64 * quality dx = 1 / n_grid dt = 1e-4 / quality E = 25000 # 杨氏模量 p_mass = 1 p_vol = 1 mu = 1 # Lamé 第一参数(剪切模量) la = 1 # Lamé 第二参数

quality是一个全局质量开关:将其从 1 调大到 2、4,粒子数、网格数与时间步都会按比例细化,直接获得更精细的仿真结果。

2.2 能量计算与自动微分

示例用needs_grad=True标记位置场与能量场(simulation/mpm_lagrangian_forces.py):

x = ti.Vector.field(dim, dtype=float, shape=n_particles, needs_grad=True) ... total_energy = ti.field(dtype=float, shape=(), needs_grad=True)

compute_total_energy内核遍历三角形单元,计算变形梯度F = currentT @ restT[i].inverse(),再按 Neo-Hookean 公式累加单元能量(simulation/mpm_lagrangian_forces.py):

I1 = (F @ F.transpose()).trace() J = F.determinant() element_energy = 0.5 * mu * (I1 - 2) - mu * ti.log(J) + 0.5 * la * ti.log(J) ** 2 total_energy[None] += E * element_energy * dx * dx

主循环中,每一帧先用ti.ad.Tape(total_energy)包裹前向能量计算,自动完成反向传播(simulation/mpm_lagrangian_forces.py):

with ti.ad.Tape(total_energy): compute_total_energy() p2g() # 此时 x.grad 已携带内力,被 p2g 用于速度散射

p2g内核中可以看到力项- dt * x.grad[p]直接参与 APIC 风格的 affine 散射(simulation/mpm_lagrangian_forces.py):

grid_v[base + I] += weight * (p_mass * v[p] - dt * x.grad[p] + affine @ dpos) grid_m[base + I] += weight * p_mass

随后grid_op完成网格速度归一化、重力施加与碰撞(中心圆 + 边界盒,见 simulation/mpm_lagrangian_forces.py),g2p用双三次样条权重回插速度与仿射矩阵C(simulation/mpm_lagrangian_forces.py),形成完整的 MPM 时间步。

2.3 渲染与交互

渲染部分展示了ti.GUI的矢量绘制能力(simulation/mpm_lagrangian_forces.py):gui.circle绘制中央障碍圆,gui.lines用三角形网格索引vertices绘制线框,gui.circles绘制粒子,gui.line绘制地面。粒子位置通过x.to_numpy()取回 CPU 端,网格边用np.roll技巧构造,展示了 Taichi field 与 NumPy 数组的无缝互转。

三、三维 MPM:雪花/弹性体标准实现

simulation/mpm3d.py 是更广为人知的 MPM 变体——"Taichi 雪花"(MPM88/MPM3D 系列之一),采用经典 MPM 算法(不依赖自动微分),可作为修改和扩展的基线。

文件头部通过注释给出了 2D/3D 多组分辨率与时间步配置(simulation/mpm3d.py):

# dim, n_grid, steps, dt = 2, 128, 20, 2e-4 # dim, n_grid, steps, dt = 2, 256, 32, 1e-4 dim, n_grid, steps, dt = 3, 32, 25, 4e-4 # dim, n_grid, steps, dt = 3, 64, 25, 2e-4 # dim, n_grid, steps, dt = 3, 128, 25, 8e-5

单步substep内核按"P2G 散射 -> 网格更新/碰撞 -> G2P 回插"三阶段组织(simulation/mpm3d.py):

  • P2G:按stress = -dt * 4 * E * p_vol * (F_J[p] - 1) / dx**2计算应力并构造 affine 矩阵,用ti.static(ti.grouped(ti.ndrange(*neighbour)))静态展开 3×3×3 邻域;
  • 网格阶段:F_grid_v[I] /= F_grid_m[I]归一化速度,施加重力并用ti.select(cond, 0, F_grid_v[I])处理边界碰撞;
  • G2P:回插速度与仿射矩阵new_C += 4 * weight * g_v.outer_product(dpos) / dx**2,并更新形变梯度雅可比F_J[p] *= 1 + dt * new_C.trace()

ti.loop_config(block_dim=n_grid)用于针对该网格规模设置 CUDA block 维度,是调优 GPU 内核吞吐量时可参考的实用 API。该示例默认将结果导出为 PLY(文件顶部的export_file变量,设为/tmp/mpm3d.ply即可写盘),可与 features/io/export_ply.py 中的 PLY 导出工具链配合使用。

四、Sparse Grids:稀疏指针 SNode 实战

features/sparse/taichi_sparse.py 是理解 Taichi **稀疏数据结构(SNode)**的必读示例:它用旋转的 Taichi Logo 逐帧激活一个 512×512 的稀疏网格,并可视化活动块(active block)的层级结构。

4.1 三层 pointer + dense 布局

核心布局构造见 features/sparse/taichi_sparse.py:

block1 = ti.root.pointer(ti.ij, n // 64) # 第一层指针:64×64 个块 block2 = block1.pointer(ti.ij, 4) # 第二层指针:每块再细分 4×4 block3 = block2.pointer(ti.ij, 4) # 第三层指针 block3.dense(ti.ij, 4).place(x) # 最内层 dense 4×4,实际存放数据

这样x实际被组织成 3 层指针 + 1 层稠密的结构:n = 512,则块大小为64 × 4 × 4 × 4 = 512,形成经典的多分辨率稀疏金字塔。pointer节点按需分配、未激活时零内存占用,这是稀疏网格(如体素场景)节省显存的关键机制。

4.2 激活、旋转与活动块可视化

activate内核逐帧读取旋转矩阵ti.math.rotation2d(ti.sin(t))变换坐标,命中 Logo 像素的位置置 1(features/sparse/taichi_sparse.py),其中taichi_logo来自 python/taichi/examples/patterns.py,是一个返回布尔结果的 SDF 风格符号距离函数。

paint内核则演示了三个稀疏 API 的组合(features/sparse/taichi_sparse.py):

  • ti.rescale_index(x, block, [i, j]):把数据坐标缩放到指定块层的索引;
  • ti.is_active(block, idx):查询某层块是否已激活;
  • 三层结果叠加后映射为灰度,img[scatter(i), scatter(j)] = 1 - t / 4输出可视化图。

主循环中block1.deactivate_all()每帧清空全部活动块再重新激活(features/sparse/taichi_sparse.py),直观展示"活动块随 Logo 旋转动态分配/回收"的过程。这种"按需激活 + 层级查询"的模式正是 python/taichi/examples/features/sparse 目录下taichi_dynamic.py(动态长度数组)、taichi_bitmasked.py(位掩码稀疏)等进阶示例的共同基础。

五、Position Based Fluids:2D 流体约束求解

simulation/pbf2d.py 实现了 Macklin & Müller 2013 年的 PBF(Position Based Fluids)算法(文件头标注了论文出处与原作者 Ye Kuang),用纯位置投影的方式求解不可压缩约束,无需显式压力项。

5.1 领域构建与邻居查找

示例为 60×20 的粒子网格构建了统一空间哈希网格(simulation/pbf2d.py):

ti.root.dense(ti.i, num_particles).place(old_positions, positions, velocities) grid_snode = ti.root.dense(ti.ij, grid_size) grid_snode.place(grid_num_particles) grid_snode.dense(ti.k, max_num_particles_per_cell).place(grid2particles)

其中grid2particles是一个dense(ti.k, 100)的"每格粒子索引表",配合ti.atomic_add(grid_num_particles[cell], 1)(simulation/pbf2d.py)实现并行无冲突的格子填充。prologue内核随后遍历 3×3 邻域格子,把距离小于neighbor_radius的粒子写入particle_neighbors,并统计每粒子邻居数(simulation/pbf2d.py)。

5.2 约束求解三阶段

substep内核按 PBF 论文公式逐步求解(simulation/pbf2d.py):

  1. 用 Spiky 核梯度与 Poly6 核计算密度约束density_constraint = (mass * density_constraint / rho0) - 1.0,并累加sum_gradient_sqr,得到拉格朗日乘子lambdas[p_i] = -density_constraint / (sum_gradient_sqr + lambda_epsilon)(对应论文 Eq. 8-11);
  2. compute_scorr(论文 Eq. 13 的人工压力项,代码中以x*x*x*x实现 4 次幂)修正位置增量pos_delta_i += (lambda_i + lambda_j + scorr_ij) * spiky_gradient(pos_ji, h_)(Eq. 12, 14);
  3. 应用位置增量并除以rho0

epilogue内核把新位置约束回边界并反推速度velocities[i] = (positions[i] - old_positions[i]) / time_delta(simulation/pbf2d.py)。值得注意的细节:confine_position_to_boundary在钳制位置时混入epsilon * ti.random()随机抖动,避免粒子粘连(simulation/pbf2d.py)。

5.3 交互与性能统计

主循环中右侧挡板通过move_board内核做正弦往复运动(b[0] += -ti.sin(...) * vel_strength * time_delta,见 simulation/pbf2d.py),用于演示流体与动态边界的交互。示例还提供print_stats(simulation/pbf2d.py),每 20 帧打印一次"每格粒子数 / 每粒子邻居数"的平均值与最大值,可作为验证空间哈希与邻居查找性能的观测指标。

六、FEM 弹性体:128 单元有限元 + 自动微分

simulation/fem128.py 把有限元(FEM)与自动微分结合:不手写刚度矩阵,而是直接对总势能U求梯度得到节点力。

6.1 网格与材料参数

代码顶部定义材料与几何参数(simulation/fem128.py):

N = 12 dt = 5e-5 dx = 1 / N rho = 4e1 NF = 2 * N**2 # 三角形面片数 NV = (N + 1) ** 2 # 顶点数 E, nu = 4e4, 0.2 # 杨氏模量、泊松比 mu, lam = E / 2 / (1 + nu), E * nu / (1 + nu) / (1 - 2 * nu) # Lamé 参数 ball_pos, ball_radius = ti.Vector([0.5, 0.0]), 0.31 damping = 14.5

init_mesh内核把 12×12 网格切成三角形(f2v记录每面三个顶点索引),init_pos计算每面的初始形状矩阵B(其逆矩阵用于后续变形梯度计算,见 simulation/fem128.py 与 simulation/fem128.py)。

6.2 势能计算与时间积分

update_U内核先对每面计算变形梯度F[i] = D_i @ B[i],再累加 Neo-Hookean 势能(simulation/fem128.py):

log_J_i = ti.log(F_i.determinant()) phi_i = mu / 2 * ((F_i.transpose() @ F_i).trace() - 2) phi_i -= mu * log_J_i phi_i += lam / 2 * log_J_i**2 phi[i] = phi_i U[None] += V[i] * phi_i

时间积分在advance内核中完成(simulation/fem128.py):加速度来自-pos.grad[i] / (rho * dx**2)(即势能梯度 = 内力),叠加重力与鼠标吸引/排斥力,速度乘以ti.exp(-dt * damping)实现阻尼,随后处理球体碰撞(disp2 <= ball_radius**2时投影速度)与矩形边界。

主循环每帧执行 50 次"自动微分 + 积分"(simulation/fem128.py):

for i in range(50): with ti.ad.Tape(loss=U): update_U() advance()

交互方式(simulation/fem128.py):WASD/方向键控制重力方向,鼠标左键吸引、右键排斥,R复位。渲染用gui.triangles按势能密度着色(paint_phi,红-灰渐变),直观呈现应力分布。

七、3D 布料:弹簧质点 + GGUI 场景渲染

ggui_examples/mass_spring_3d_ggui.py 将 128×128 质点的布料模型接入 Taichi GGUI(Vulkan 图形界面),展示弹簧-阻尼系统与 3D 场景 API 的组合用法。

7.1 弹簧布局与力模型

示例在每帧初始化时对每个质点周围 4×4(含对角线距离 ≤ 2)的邻域建立弹簧(spring_offsets),并可通过bending_springs开关切换到 3×3 邻域的弯曲弹簧模式(ggui_examples/mass_spring_3d_ggui.py)。核心参数见 ggui_examples/mass_spring_3d_ggui.py:

n = 128 quad_size = 1.0 / n dt = 4e-2 / n substeps = int(1 / 60 // dt) gravity = ti.Vector([0, -9.8, 0]) spring_Y = 3e4 # 弹簧刚度 dashpot_damping = 1e4 # 阻尼器 drag_damping = 1 # 空气阻力 ball_radius = 0.3

substep内核实现三类力:重力、弹簧力-spring_Y * d * (current_dist / original_dist - 1)(以当前/原始长度比驱动)与阻尼力-v_ij.dot(d) * d * dashpot_damping * quad_size,最后对撞到中心球的质点做速度投影(ggui_examples/mass_spring_3d_ggui.py)。

7.2 GGUI 场景搭建

渲染层展示了 GGUI 的完整流程(ggui_examples/mass_spring_3d_ggui.py):

window = ti.ui.Window("Taichi Cloth Simulation on GGUI", (768, 768), vsync=True) canvas = window.get_canvas() scene = window.get_scene() camera = ti.ui.Camera() ... camera.position(0.0, 0.0, 3) camera.lookat(0.0, 0.0, 0) scene.set_camera(camera) scene.point_light(pos=(0, 1, 2), color=(1, 1, 1)) scene.ambient_light((0.5, 0.5, 0.5)) scene.mesh(vertices, indices=indices, per_vertex_color=colors, two_sided=True) scene.particles(ball_center, radius=ball_radius * 0.95, color=(0.5, 0.42, 0.8)) canvas.scene(scene) window.show()

其中indicesinitialize_mesh_indices生成每 6 个索引一组的两三角形面片(ggui_examples/mass_spring_3d_ggui.py),colors按棋盘格模式给顶点着色。运行 1.5 秒后布料自动复位(current_t > 1.5触发initialize_mass_points()),适合循环展示。该示例与 ggui_examples 目录下的mpm3d_ggui.pystable_fluid_ggui.py等一起构成了 GGUI 3D 应用的参考集。

八、Marching Cubes:等值面提取与 PLY 导出

algorithm/mciso_advanced.py 用@ti.data_oriented类封装了一个可复用的 MCISO 提取器,支持 2D(Marching Squares)与 3D(Marching Cubes)两种维度,并演示pointer稀疏加速。

8.1 查表结构与数据布局

MCISO类内置两张查找表:et2(2D,16 种角点组合)与et3(3D,256 种组合,对应标准 15 条边编号,注释中给出了表来源链接,见 algorithm/mciso_advanced.py),并通过ti.Vector.field(dim, int, et.shape[:2])+from_numpy载入 Taichi 场(algorithm/mciso_advanced.py)。

标量场m与梯度场g的布局支持稠密/稀疏两种模式(algorithm/mciso_advanced.py):

if self.use_sparse: ti.root.pointer(indices, self.N // self.blk_size).dense(indices, self.blk_size).place(self.m) ti.root.dense(indices, self.N).place(self.g) else: ti.root.dense(indices, self.N).place(self.m) ti.root.dense(indices, self.N).place(self.g)

use_sparse = blk_size is not None,实例化时传入blk_size即可启用稀疏模式——这与第四节 Sparse Grids 的pointer用法一脉相承。

8.2 梯度计算与并行 March

compute_grad用中心差分计算归一化梯度(r[i] = self.m[I + d] - self.m[I - d],见 algorithm/mciso_advanced.py)。核心的march内核逐体素(2D 逐像素)按位拼接角点状态得到查表索引idx,再对每个命中边用线性插值求交:

p = (1 - self.m[i, j]) / (self.m[i + 1, j] - self.m[i, j]) R = [i + p, j]

并使用n = ti.atomic_add(r_n, 1)(algorithm/mciso_advanced.py)在并行内核内原子分配输出缓冲槽位,最终返回写入的顶点数r_n

8.3 交互、渲染与导出

MCISO_Example.main提供实时交互(algorithm/mciso_advanced.py):鼠标拖动通过touch内核写入高斯混合标量场,每次移动重新march;2D 模式渲染梯度场灰度图与等值线,3D 模式绘制三角面片,并按空格键用ti.tools.PLYWriter把网格写入mciso_output.plyti.deactivate_all_snodes()(稀疏模式下)或self.m.fill(0)(稠密模式)负责每帧重置场数据。三维网格提取(如从 SDF/体素场重建表面)通常还需要法线、UV 等附加属性,可参考 features/io/export_mesh.py 的完整导出链。

九、Game of Life:100 行元胞自动机与 GUI 交互

simulation/game_of_life.py 是入门 Taichi 的最简交互示例:约 100 行实现 Conway 生命游戏,文件头注释致敬了 Conway(1937–2020)。

9.1 规则实现

游戏在 64×64 的alive场上进行(simulation/game_of_life.py):

n = 64 cell_size = 8 alive = ti.field(int, shape=(n, n)) count = ti.field(int, shape=(n, n))

get_count通过 8 个方向累加邻居存活数,边界外视为 0;calc_ruleti.static展开规则表B, S = [3], [2, 3](重生/存活规则,simulation/game_of_life.py)。run内核分成两个独立循环:先算邻居计数、再更新状态,避免就地更新带来的竞争(simulation/game_of_life.py)。把B, S改成其他组合(如[2], [0],注释中已给出)即可切换到其他元胞自动机规则。

9.2 GUI 交互与图像放大

主循环演示了ti.GUI的事件系统(simulation/game_of_life.py):

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": alive.fill(0) if gui.is_pressed(gui.LMB, gui.RMB): mx, my = gui.get_cursor_pos() alive[int(mx * n), int(my * n)] = gui.is_pressed(gui.LMB) paused = True

交互操作包括:空格暂停/继续、r清空重来、鼠标左键画存活细胞、右键画死细胞;窗口帧率通过gui.fps_limit = 15限制。显示时用ti.tools.imresize(alive, img_size)把 64×64 整数场放大到 512×512 再转 uint8 输出(simulation/game_of_life.py),这是ti.tools图像工具的一个典型用法。

十、延伸学习路径

以上 8 个示例覆盖了 Taichi 的主要能力象限,仓库中还有大量同主题姊妹示例可继续研读:

  • 更多 MPM/流体:simulation/mpm88.py、simulation/mpm128.py、simulation/stable_fluid.py、simulation/eulerfluid2d.py,以及带自动微分的 simulation/ad_gravity.py;
  • 稀疏进阶:features/sparse/taichi_dynamic.py、features/sparse/taichi_bitmasked.py、features/sparse/explicit_activation.py;
  • 自动微分:autodiff 目录下的simple_derivative.pyjacobian.pyregression.pyminimization.py
  • GGUI 3D:ggui_examples 目录下的mpm3d_ggui.pystable_fluid_ggui.pyfractal3d_ggui.pymass_spring_game_ggui.py
  • 渲染:rendering 目录下的cornell_box.pysdf_renderer.pyrasterizer.pytaichi_ngp.py
  • 图模式(Graph):graph 目录下的mpm88_graph.pystable_fluid_graph.py,展示ti.graph的 AOT 化调用方式;
  • IO:features/io 目录下的export_videos.pyexport_ply.pyexport_mesh.py,可学习如何把仿真结果导出为视频与网格文件。

运行上述任一示例只需ti example <示例名>,或在 python/taichi/examples 目录中直接阅读源码。建议按照"Game of Life(入门)→ Sparse Grids(数据结构)→ PBF2D / MPM3D(数值仿真)→ fem128 / mpm_lagrangian_forces(自动微分)→ mciso_advanced(网格提取)→ mass_spring_3d_ggui(3D 渲染)"的顺序逐步深入,即可系统掌握 Taichi 从基础语法到高级特性的完整技术栈。

【免费下载链接】taichiProductive, portable, and performant GPU programming in Python.项目地址: https://gitcode.com/GitHub_Trending/ta/taichi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 3:46:38

Java八种基本数据类型详解与应用实践

1. Java八种基本类型深度解析Java作为一门强类型语言&#xff0c;其基本数据类型&#xff08;Primitive Types&#xff09;是构成所有Java程序的基石。这八种基本类型可以分为三类&#xff1a;六种数字类型&#xff08;4种整数型2种浮点型&#xff09;、1种字符型和1种布尔型。…

作者头像 李华
网站建设 2026/9/11 3:46:30

基于SSM+MySQL的停车场管理系统:计费状态与并发控制实战解析

简介&#xff1a;基于SSMMySQL的停车场管理系统设计与实现资料包&#xff0c;专为毕业设计、课程设计及Java Web学习者打造&#xff0c;覆盖车辆进出管理、停车位监控、收费计费、统计报表等核心业务。资源内含项目全套源码、设计文档、部署说明和视频演示&#xff0c;共1223个…

作者头像 李华
网站建设 2026/9/11 3:46:25

全端云SaaS平台:一站式解决门店多渠道管理与数字化升级

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华