非破壊編集
先に 選択 で範囲を囲み、ツールレール ✎ 編集 で適用します。
| 操作 | 内容 | ショートカット |
|---|---|---|
| 非表示 | 選択点を表示から除く。書き出し・集計には含まれる | ⌘⇧H / Ctrl+⇧H |
| 削除 | 選択点を成果物から除く。書き出し・集計から除外される | Del / ⌫ |
| 分類 | classification を変更(0〜255) | — |
| 色 | 色を上書き | — |
非表示と削除の違いが要点です。非表示は「今は見たくない」、削除は「成果物に含めない」。 どちらも .copc.laz は一切変更せず、⌘Z で戻せます。
原本を書き換えない仕組み
編集の「真実」は原本でも GPU の属性でもなく、Command ログです。 hide / delete / reclassify / colorOverride が、選択の述語とあわせて追記されていきます。 GPU に載る属性は、毎回このログから再構築されます。
これが効くのは LOD があるからです。カメラが離れれば点は捨てられ、寄れば再ロードされます。 編集を GPU の属性に直接書き込む設計だと、捨てて戻ってきた点から編集が消えます。 ログから再構築する形なら戻ってきます(「退避後の再構築が同値」は回帰テストで固定してあります)。
ログなので、後から出た編集が勝ちます。hide と delete には強弱があり、 同じ点に両方かかっていれば delete が優先されます。
Undo / Redo
⌘Z で戻し、⌘⇧Z(Windows は Ctrl+Y も)でやり直します。
Undo はユーザーごとです。 協働中でも、⌘Z が戻すのは自分が出した編集だけで、 他人の編集は残ります。ログの途中にある自分の 1 件だけが消え、 Redo は元の位置へ戻すので後勝ちの関係も壊れません。Google Docs や Figma と同じ挙動です。 自分の編集が無いときは ⌘Z とボタンが無効になります。
「編集をクリア」だけは例外で、全員分を消します(誰かのクリアを他人が ⌘Z で戻せると 状態が読めなくなるため、Undo の対象外)。協働中は件数付きの確認ダイアログが出ます。
束(Batch)で丸ごと戻す
⌘Z は1操作ずつ戻しますが、**AI の1ターンが出した編集はまとめて1つの束(Batch)**になっていて、 束単位でも戻せます。同じ指示から複数ターンに分かれた場合は runId で上位にまとめられます (人間の操作は当面束になりません。1件ずつの ⌘Z のままです)。
await oniyanma.execute('listBatches')
// → [{ id, kind: 'aiTurn', status: 'applied', counts: { ops, entries }, … }, …]
await oniyanma.execute('revertBatch', { id })
// 機械が呼ぶと確認ゲートがかかる(束が already applied か・戻せる件数を先に返す)戻るのは基本的に編集ログ(op)だけです。 その束の中で所見を起票・更新していた場合、 そちらは戻りません(版の中間状態を保存していないため)。戻していない件数は返り値で 申告されるので、「本当に全部戻ったか」を確認できます。→ 確認ゲート(ドライラン)
例外は検出インポート(kind:'import')の束です。 新規作成しかしない束なので、revertBatch で取り込んだ所見ごと安全に取り下げられます (既存の所見を更新する human / ai / macro 束は、更新前の値を保存していないため対象外のままです)。
他人が作った束は戻せません。 束の来歴(発行したクライアント)と、いま操作している クライアントが一致しないと not-owner になります。per-user undo と同じ規律です。
発行者(来歴)
各編集には誰が出したかが記録されます。
| 発行者 | どこから |
|---|---|
human | UI のボタン・ショートカット・⌘K パレット |
ai | アプリ内 AI コンソール(モデル名と指示文の冒頭も記録) |
api | window.oniyanma.execute / MCP 経由 |
編集パネルには「編集 12 件(うち AI/API 発行 3 件)」のように出ます。 getState().editsByActor からも取れます。
これがあるので、「AI に任せた範囲」と「人が判断した範囲」を後から分けられます。
機械から呼ぶときの確認ゲート
hideSelection / deleteSelection / reclassifySelection / colorSelection / clearEdits は、 機械(ai / api)が confirm 無しで呼ぶと実行されず、影響件数だけを返します。
await oniyanma.execute('deleteSelection')
// → { preview: true, command: 'deleteSelection',
// wouldAffect: { points: 128340, note: 'resident(表示中 LOD サンプル)基準の件数' },
// note: '未実行です。…confirm:true を付けて再実行してください' }
await oniyanma.execute('deleteSelection', { confirm: true }) // 実行される人間の UI 操作は自分の結果を見ているので、このゲートを通りません。 → 確認ゲート(ドライラン)
保存
編集はデータセット単位で localStorage に自動保存され、リロードしても残ります。 別の端末へ持っていく、あるいは成果物として渡すなら、サイドカー (<dataset>.oniyanma.json)に書き出します。→ 保存と書き出し
コマンド
hideSelection · deleteSelection · reclassifySelection · colorSelection · undo · redo · clearEdits · listBatches · getBatch · revertBatch