pts ファイル読み込みを実装してみる（点群表示機能を自作してみる その７）

[「点群表示機能を自作してみる」](https://qiita.com/yumimatoba14/items/a89b01145b3af4ce9451)のその７です。
pts ファイルを読み込んでみます。 データは[静岡県が公開している掛川城][掛川城OpenData_link]を用います。

[CloudCompare_home]: https://www.danielgm.net/cc/
[掛川城OpenData_link]: https://www.geospatial.jp/ckan/dataset/kakegawacastle

# 出来上がり図

[GitHub](https://github.com/yumimatoba14/DirectXMfc.git) の以下のリビジョンを参照してください。
> Revision: b176d997a3b183311b1ad3a956efea0caa9a1ebe
> Message:
> changed interface of D3DExclusiveLodPointListObject in order to draw points repeatedly.
> added test codes to draw points.



点サイズ0.001m
![掛川城_0.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/90428671-16c0-5fa9-1afa-1915d87685b5.png)

点サイズ0.02m
![掛川城_0.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/5ef1228e-1b09-e826-6103-64afa3a5f5a5.png)

遠景だと点サイズの違いはほぼ判りません。

別の場所で
点サイズ0.001m
![掛川城2_0.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/2bd16404-f76b-94c4-3a7e-c72729072e39.png)

点サイズ0.02m
![掛川城2_0.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/5220249c-434b-db54-0ce4-1c5c347ba8cc.png)

こちらの場所だと近くの地面が透けるかどうかで違いが出ています。

室内はもっと違いが出ます。
点サイズ0.001m
![掛川城3_0.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/2ec356a2-9c08-62a4-6a77-65965274bebe.png)

点サイズ0.02m
![掛川城3_0.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/bea1cf89-92f9-b23c-0f99-ed5835fe2d46.png)

どうも室内・近景をどのようにきれいに表示するかが、今回の実装の課題(今現在の弱点)ということになりそうです。

# 説明
## 元データ取得
静岡県の[掛川城オープンデータ化プロジェクト ][掛川城OpenData_link] より LAS ファイルをダウンロードできます。 おおよそ2億点のモデルのようです。

このモデルの取得や LAS ファイルについては以下の記事を参考にさせていただきました。

https://qiita.com/nokonoko_1203/items/63e00d279cf7efb5521d

## pts ファイル作成
LAS ファイルを自分で読み込むこともちょっと考えましたが、本筋ではないのでおとなしく [CloudCompare][CloudCompare_home] を用いて変換することにしました。

LAS ファイルは様々なスカラーフィールド(SF)を持っているようです。これらは CloudCompare でエクスポートするときに邪魔なので、 Intensity 以外読み込まないようにします。 (下図)
![CC_OpenLAS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/85e1e464-f2ef-3ce3-d2dc-2f4cb966476d.png)

DB Tree でファイルを選択し、 File → Save メニューを実行します。

![CC_SavePTS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124939/88710527-99af-8c65-a449-67f2b43aeeb5.png)

CloudCompare では PTS ファイルのエクスポート機能があるというよりは、テキストファイルの書き出し機能で PTS ファイル様式で書くこともできる、ということのようです。
「order」を PTS にし、「number of points (seprate line)」にチェックを入れます。
LAS ファイルのスカラープロパティを読み込んでいると SF(s) の位置にそれらが書かれてしまい PTS ファイルの書式から変わってしまいます。 LAS ファイルから読み込んでしまっている場合は消します。

## プログラムでの読み込み
DirectXMfc.exe に File → 開く メニューを追加しました。 フィルタで pts ファイルを選択してファイルを選択してください。 その後、読み込んだ結果のファイル(ビューファイル)を作成する場所を指定してください。
一度作った bin ファイルは、開くメニューで選択することですぐに表示できます。 今回のモデルでは 3GB 程度のファイルができますが、 HDD に保存してもまあまあ サクサク開けているように思われます。(満足)

## 描画設定
描画設定メニューを追加し、点のサイズを変更できるようにしました。 通常は3次元空間中のサイズ、負の値を入れると、スクリーン上でのサイズになります。(-4 を指定すると4ドット相当で描画します。)

ついでに透視投影の Near Z、Far Z も変更可能にしています。
異常値を設定した場合のエラー処理・メンテナンス処理はしていないのでご注意ください。

## その他の修正
以下の修正も行っています。

* レスポンス改善のため1フレーム中で描画する点数を2百万点から百万点に変更。
    * MultiPointListSampleModel2::OnDrawTo() の maxDrawnPointCountPerFrame の個数が該当します。
    * この関数ではその他一範囲(D3DExclusiveLodPointListObject)あたりの描画点数にも上限を加えています。これは優先的に描画する範囲をコントロールする目的です。(簡易的な実装ですが。)

# 所感
ここまで作ったものについて振り返ってみます。

## 良かったところ
* 思ったよりきれいに描画された。 特に遠景がきれい。
* プログレッシブモードが想像していたよりきびきび動く。
    * HDD からの読み込みでも思ったより動いていました。(ファイルサイズが3GB程度なのでファイルキャッシュが効いているのでしょう。10億点のデータで遅いなあと思ったことも事実なので工夫の余地はありそう。)

## イマイチだったところ
* その6までのコードでは領域分割のパラメータが100万点の板に特化していた。
    * 修正済みですが、もうちょっと調整の余地がありそう。 最も粗いレイヤの点数が600点とかのところがあったりして、ちょっと少なすぎる感じ。
* 1フレーム目で描画する点が少なすぎて、回転中は近くが真っ黒に見える。
    * 遠景はそれなりに描画されて見えます。 そのため余計に「遠くはいいからもっと近くを描いてよ」という気になります。
    * 但し近くだけを描くと、特にマウスホイールでの前進後退時に描画範囲が大きく変わってどちら向きにどう移動してるか分からなくなることがありました。 ということで「遠くも近くも描いてよ」ということになるようです。(無茶ですね。) これも要検討課題です。
* 3D長で点サイズを指定していれば近くの点は大きく描画されるので透けにくいのですが、限界はあるようです。
    * 点のサイズが大きすぎると、そこだけ画像を引き延ばしたような描画になって結局何が何だか分からなくなります。 端的に言うと「解像度が粗い画像」状態です。
    * プログレッシブモードの最初のフレームでは点が間引かれていてスカスカだし。
* データ作成が遅い。
    * 原因はほぼ Win32 の CreateFile をバッファリングなしで直接使ってしまっているところ。一部は D3DWin32FileStreamBuf を使うことで解消してますが、まだ直しきれていません。
        * Win32 のファイル API にもバッファリング位あるものと思ってました。 ファイルのキャッシュとちょっと誤解していたかもしれません。 失敗。
    * あとはシングルスレッドで動いているところも原因か。

# 参考資料・リンク
* [掛川城オープンデータ化プロジェクト ][掛川城OpenData_link]
* [CloudCompare][CloudCompare_home]
    * LAS ファイルを PTS に変換するのに使用しました。
    * このツールも表示はプログレッシブ表示しています。