terrain op• 数据种类:mesh → mesh
• 调用: import fullseye as fs; fs.ledger.mesh_scatter_boulders(V, F, *, density: 'float', d_min: 'float', d_max=None, exponent: 'float' = 3.1, seed: 'int' = 0, region_weights=None, aspect=(1.0, 0.7, 0.5), embed: 'float' = 0.35, subdiv: 'int' = 1, shape: 'str' = 'ellipsoid', orientation: 'str' = 'normal', burial=(0.3, 0.6), max_count=None, hull_points=None, return_info: 'bool' = False)(要直接调用实现,import render3d; render3d.mesh_scatter_boulders(V, F, *, density: 'float', d_min: 'float', d_max=None, exponent: 'float' = 3.1, seed: 'int' = 0, region_weights=None, aspect=(1.0, 0.7, 0.5), embed: 'float' = 0.35, subdiv: 'int' = 1, shape: 'str' = 'ellipsoid', orientation: 'str' = 'normal', burial=(0.3, 0.6), max_count=None, hull_points=None, return_info: 'bool' = False);从台账取用则 ops3d.get("mesh_scatter_boulders"))
在网格上散布半埋的岩块(幂律尺寸,带 seed)→ (V, F)。
(或在 return_info=True 时返回 (V, F, info))。
shape='ellipsoid'(默认,行为不变):icosphere 椭球,半轴为 D/2 × aspect(1 : 0.7 : 0.5,最短轴沿局部表面法线),绕法线旋转并按 embed 下沉(0 = 搁在面上,1 = 中心位于表面)。shape='hull':棱角分明的岩块 —— 在长宽比相同、带 20 % 径向抖动的椭球上取带 seed 的随机点并求凸包(平坦的小面、锐利的棱边,呈现 Itokawa 巨砾的样貌),每块 hull_points 个点(默认随尺寸变化: 10 + 8·log2(D/d_min),10..40)。orientation='random' 给每块一个均匀随机旋转,而不是让其短轴与法线对齐。对于凸包,下沉量
是 sample_boulders 给出的随尺寸变化的 burial 比例(默认岩块高度的 30–60 % 位于表面以下;embed 被忽略)。max_count 通过按同一规律提高 d_min 来限制期望个数(参见 sample_boulders;info['d_min_effective'] 报告实际值)。
位置与尺寸来自 sample_boulders(泊松过程,N(>D) ∝ D^-exponent);岩石放在*按原样传入*的网格上 —— 请传入已位移/ 细分的地形,使岩石落在最终表面上。来自 terrain_region_mask 的 region_weights 让“海”区域保持平滑。岩石作为真实几何体追加,因此与地形经由同一条光栅化器/ 光线投射路径产生自阴影、投射阴影并产生遮挡。info = 采样 dict 加上 faces_per_boulder 和 n_boulders。在 seed 下确定。Fail-closed。
步骤:用 sample_boulders 抽取位置(面上的均匀点)、面法线和直径 D,为每块岩石生成一个小网格并连接在输入网格之后(顶点追加到末尾,面 index 已做偏移)。输入的顶点和面原样保留,因此可以根据 info['faces_per_boulder'] 和原来的面数只切出岩石的面。
• density:每单位面积(网格单位²)中 D ≥ d_min 的岩石期望个数。实际个数由泊松分布决定,也可能为 0 个(此时返回输入的副本)。
• d_min < d_max(None = 10·d_min)、exponent > 0、aspect 为 3 个正元素、embed ∈ [0, 1]、subdiv ∈ [0, 3] (椭球的 icosphere 细分)、hull_points 在 [6, 200] 内。任何一项超出范围都会抛出 ValueError。
• shape='ellipsoid':把半轴为 D/2·aspect 的椭球以最短轴沿法线的朝向放置,并把中心沿法线方向抬高 semi_z·(1 − embed)。
• shape='hull':椭球上随机点的凸包。沿法线方向的高度范围中,burial (默认 0.3〜0.6,岩石越小越深)比例的部分沉到面下。embed 被忽略。
• orientation='random' 为均匀随机旋转(4 元数,即四元数)。'normal' 为绕法线的随机旋转。旋转的随机数使用以 seed + 1 初始化的 generator。
岩石是真实几何体,因此 ambient_occlusion / cast_shadow / shadow_raycast 的光线会正常命中它们。放置的面就是传入的网格本身,因此请在 mesh_displace_spectrum 或 mesh_subdivide 之后 调用(若先调用,岩石会浮在地面上方/埋入地面)。
• 示例数据目录(下载 URL / 许可证) —— 2-D 用 skimage.data(BSD/公有领域)加合成图,3-D 给出真实数据源(Stanford/PDS 等)的下载 URL。
• 算子来历与参考文献 —— 该算子族所依据的研究/方法出处。
• itokawa_regolith_hero — py -3.11 examples_3d/itokawa_regolith_hero.py
mesh 作为输入)mesh_to_voxel · mesh_to_points · to_points · fuse_to_voxel · ambient_occlusion · cast_shadow · supersample_mesh · render_beauty
terrain)mesh_displace_fbm · terrain_region_mask · mesh_edge_lengths · mesh_subdivide · displacement_band_weights · mesh_displace_spectrum · bump_normals_fbm
*Provenance: render3d.py — 3D 算子登记表。本条目由 tools/opdocs.py md 自动生成(请勿手工编辑)。*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.