mesh_subdivide — 3D terrain op

Datenarten: meshmesh

Aufruf: import fullseye as fs; fs.ledger.mesh_subdivide(V, F, *, levels: 'int' = 1, target_edge=None, max_faces: 'int' = 4000000) (die Implementierung direkt: import render3d; render3d.mesh_subdivide(V, F, *, levels: 'int' = 1, target_edge=None, max_faces: 'int' = 4000000); aus dem Register: ops3d.get("mesh_subdivide"))

Verwendung

Verfeinert ein Dreiecksnetz → `(V, F): gleichmäßige Mittelpunktunterteilung (levels` Durchgänge).

> Die ausführliche Beschreibung unten ist der Originaltext — Zusammenfassung und Überschriften sind übersetzt.

×4 faces each) or adaptive tessellation to a target edge length (`target_edge`:

median edge = target, edge segments ≤ 1.5×target, in-face Delaunay edges < 2×target).

The geometry is *unchanged* — every new vertex lies on an old facet, so surface area

and enclosed volume are preserved exactly (tests pin this) and nothing is ever

decimated; only the facet size changes, so a later :func:mesh_displace_spectrum can

carry short wavelengths without aliasing.

Adaptive mode cuts each edge into `n = round(length / target_edge)` (≥ 1) segments

— a per-*edge* count, hence conforming across neighbours (no T-junctions) — and fills

each face with a **hexagonal lattice at spacing `target_edge` in the face plane**,

triangulated by a per-face 2-D Delaunay (Qhull). The interior therefore has edges

≈ `target_edge` *whatever the shape of the source face* (the Gaskell Itokawa faces

have a median longest/shortest edge ratio of 1.83, so a per-face lattice pattern

inherits that anisotropy; repeated midpoint bisection additionally leaves a factor-2

spread `(target/2, target]`). Measured on the Itokawa model (edge p5/median/p95 =

2.6/4.7/7.2 m, target 1.5 m): see `examples_3d/itokawa_regolith_hero.py` — the test

pins p95/p5 ≤ 1.5 on a graded plane. `max_faces` (default

`MAX_SUBDIVIDE_FACES`) is a memory guard: if the plan would exceed it the call

raises `ValueError` (fail-closed) rather than silently under-refining.

Deterministic. Fail-closed: degenerate mesh, `levels < 0`, non-positive

`target_edge / caps → ValueError`.

2 つのモードがあり、`target_edge` の有無で切り替わる。

• `target_edge=None(一様): 全辺を中点で割る細分を levels` 回繰り返す(面数は

1 回ごとに 4 倍)。`levels=0 は入力をそのまま返す。各回の前に 面数×4 > max_faces`

なら `ValueError`。

• `target_edge 指定(適応): 辺ごとに分割数 n = round(長さ / target_edge)`

(最小 1)を決め、隣接面で共有するので T 字接合は出ない。分割数は内部上限 64 に

無言でクランプ されるため、`target_edge` の 64 倍を超える長さの辺は目標に届かない。

どの辺も分割不要なら入力のコピーを返す。面数の見積り

`Σ(3 辺の分割数の和 + 平均分割数²)max_faces` を超えると計算前に

`ValueErrorlevels` はこのモードでは使わない。

返り値 `(V (N',3) float64, F (M',3) int64)`。新頂点は必ず元の面の上に置くので面積と

体積は変わらない(平滑化ではない)。適応モードは面ごとに 2-D Delaunay(scipy Qhull)を

使うので、極端に細長い面では品質が落ちる。細分後に `mesh_edge_lengths` で辺長分布を

確かめ、`mesh_displace_spectrum` へ渡す。

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

itokawa_regolith_heropy -3.11 examples_3d/itokawa_regolith_hero.py

Typkompatible Folge-Operatoren (nehmen mesh als Eingabe)

mesh_to_voxel · mesh_to_points · to_points · fuse_to_voxel · ambient_occlusion · cast_shadow · supersample_mesh · render_beauty

Gleiche Kategorie (terrain)

mesh_displace_fbm · terrain_region_mask · mesh_scatter_boulders · mesh_edge_lengths · displacement_band_weights · mesh_displace_spectrum · bump_normals_fbm


*Provenance: render3d.py — 3D Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.