LRTKレフィクシア株式会社

点群OBJのNaN・Inf値で読込失敗する原因と4つの除去法

NaN・Inf値で点群OBJの読み込みが失敗する仕組み

点群OBJをアップロードした際に、解析エラー、読込失敗、表示不能などが発生する場合は、OBJファイル内にNaNやInfといった非有限値が含まれている可能性があります。拡張子、ファイル容量、関連ファイルの配置に問題が見当たらないときは、行に記録された数値そのものを確認することが重要です。

NaNは「Not a Number」の略で、実数として扱えない計算結果を表す特殊値です。代表例は0を0で割る演算や、定義域外の演算を処理系が浮動小数点値として返す場合です。Infは正または負の無限大を表します。IEEE 754に沿う浮動小数点処理では、有限の非ゼロ値をゼロで割った場合や、有限の計算結果が表現可能範囲を超えてオーバーフローした場合などにInfが生じ得ます。ただし、言語やライブラリによっては例外を発生させ、NaNやInfを値として返さないこともあります。([Oracle Docs][1])

OBJの幾何頂点は、一般に次のような「v」行で定義されます。

text v 12.345 67.890 3.210

変換処理が非有限値を検査せず文字列化すると、次のような行が出力されることがあります。

text v NaN 67.890 3.210 v 12.345 Inf 3.210 v 12.345 67.890 -Inf

NaNやInfという文字列をテキストファイルへ保存すること自体は可能ですが、OBJの交換データとして互換性が保証される表現ではありません。読み込み側が通常の有限な浮動小数点数だけを想定している場合、数値変換の段階で拒否されます。読み込みに成功したように見えても、境界ボックス、中心座標、縮尺、法線、空間インデックスなどの計算で異常が表面化することがあります。

NaNは演算に入ると後続結果へ伝播しやすく、モデル全体の最小値や最大値が決められない原因になります。ただし、NaNを無視するか伝播させるかは使用する関数や実装によって異なります。Infが含まれる場合も、表示範囲が過大になったり、有限値を前提とする処理が停止したりする可能性があります。

そのため、点群OBJアップロードの失敗を直すときは、該当文字列を消すだけでは不十分です。異常値が含まれる幾何頂点、UV座標、法線、点要素、線要素、面要素の参照関係を確認し、OBJ全体の整合性を保った状態で除去する必要があります。OBJでは「v」「vt」「vn」の各データが別々に番号付けされ、「p」「l」「f」などの要素から参照されます。([Gist][2])

点群OBJでNaN・Inf値を確認すべき場所

最初に確認したいのは、行頭が「v」の幾何頂点です。標準的なOBJではX、Y、Zに加えて任意の重みWを持つ場合があります。点群用途では「v」行だけが大量に並ぶ独自運用も見られますが、OBJ仕様上は点要素を「p」行で定義できます。頂点だけのOBJを点として表示できるか、「p」行が必要か、そもそも点要素に対応するかはアップロード先の実装によって異なります。([Gist][2])

ファイルに「p」「l」「f」や自由曲線・曲面の参照がなく、「v」行を単なる独立点として独自に読み込む環境であれば、異常な頂点行の削除だけで済む場合があります。一方、点要素の「p」、線要素の「l」、面要素の「f」が頂点番号を参照している場合は、途中の「v」行だけを削除すると後続番号がずれます。読み込めても、点の欠落、線の誤接続、細長い面、形状の破綻が生じるため注意が必要です。

次に確認するのが、行頭が「vt」のテクスチャ座標です。UV座標にNaNやInfが含まれていると、対応していない読み込み環境では解析に失敗することがあります。読み込みを継続する環境でも、テクスチャが表示されない、極端に引き伸ばされる、特定面だけ不自然になるなどの症状が出る可能性があります。ただし、症状はレンダラーやインポーターの実装に左右されるため、必ず同じ表示になるとは限りません。

行頭が「vn」の頂点法線も確認します。法線は通常三成分のベクトルです。ゼロ長ベクトルを正規化しようとして0除算が発生した場合や、元座標にNaNが含まれたまま法線を計算した場合に、成分へNaNが入ることがあります。有限値であっても、長さがほぼゼロの法線は有効な向きを示さないため、別途検査が必要です。

自由曲線や自由曲面を含むOBJでは、「vp」のパラメータ空間頂点や曲線・曲面のパラメータにも数値が入ります。一般的な点群OBJでは使用されないことが多いものの、ファイルを汎用的に検査する場合は「v」「vt」「vn」だけに限定しない方が安全です。

幾何頂点の末尾にRGBなどの値を追加する実装もありますが、頂点色は元の正式なOBJ仕様には含まれない慣用的な拡張です。アップロード先によって解釈が異なるため、追加成分にNaNやInfがある場合だけでなく、追加成分そのものが非対応である可能性も考えます。([Paul Bourke][3])

「f」行には、本来、幾何頂点番号、UV番号、法線番号を表す整数が記録されます。「f 1/2/3」のような形式の各番号は別々の配列を参照します。ここにNaNやInfが出ている場合は、座標値の異常ではなく、参照番号の生成処理が破損している状態です。単純な置換では本来の参照先を復元できないため、元データまたは再構築用の対応表が必要です。

検索時は「nan」「+nan」「-nan」「inf」「+inf」「-inf」「infinity」などの表記差を想定します。ただし、文字列の一部として「inf」が含まれるオブジェクト名、マテリアル名、ファイル名まで誤検出しないよう、数値トークンとして検査するのが理想です。テキスト検索は一次確認に使い、最終確認では各数値欄を実際に解析して有限値判定を行います。

NaNが混入する主な原因

NaNが点群OBJに混入する代表的な原因は、計算途中で有効な実数結果を定義できない演算が行われ、その結果を出力処理が除外しなかったことです。点群処理では、座標変換、スケール調整、近傍探索、法線推定、補間、メッシュ生成など多数の数値計算が行われます。どの工程でも、入力値や前提条件が不正であればNaNが生成される可能性があります。

特に注意したいのがゼロ長ベクトルの正規化です。法線や方向ベクトルを求める処理では、各成分をベクトル長で割ります。同じ位置に重複した点がある場合、面を構成する三点が同一点または一直線上にある場合、差分ベクトルや外積の長さがゼロになることがあります。その状態で0を0で割る形になると、IEEE 754型の処理ではNaNになり得ます。実装によっては事前判定で処理を中止したり、既定値を返したりします。

欠損値の引き継ぎも大きな原因です。元の点群形式や表形式データでは、座標、色、反射強度、時刻などの欠損をNaNで保持できる場合があります。元形式では欠損値として意味を持っていても、OBJの数値欄へそのまま書き出すと、受け側では不正値として扱われる可能性があります。

複数の点群を結合するときにも注意が必要です。あるデータには属性があり、別のデータには同じ属性がない場合、処理系が欠けた部分をNaNで補完することがあります。結合後に座標だけを使う予定でも、書き出し設定で追加属性や法線まで出力すると、非有限値がOBJへ残る場合があります。

座標変換パラメータの不備も原因になり得ます。変換行列にNaNが入っている、姿勢値の正規化に失敗している、特異またはほぼ特異な行列の逆行列を求めている、変換元の値が既に非有限であるといった場合です。ただし、座標系の指定を誤っただけで必ずNaNになるわけではなく、単に位置、軸、縮尺が誤った有限値になるケースも多くあります。

点群からメッシュを生成する工程では、孤立点、重複点、局所密度の低い領域、極端に近い点、退化した三角形が計算を不安定にします。近傍点が不足している場所を無理に補間したり、面積ゼロの面から法線を求めたりすると、NaNが生じる可能性が高まります。

重要なのは、NaNを見つけた場所が原因発生箇所とは限らないことです。たとえば「vn」行にNaNが出ていても、原因は法線計算ではなく、入力した「v」座標のNaNかもしれません。工程ごとに有限値数、欠損数、座標範囲を記録し、最初にNaNが現れた段階を特定します。

Inf値が混入する主な原因

Infは、IEEE 754に沿う浮動小数点処理で、有限の非ゼロ値をゼロで割った場合や、計算結果が対象の浮動小数点型で表現できる最大値を超えた場合などに発生し得ます。0を0で割った場合はInfではなくNaNになります。処理系によっては例外やエラーで停止するため、常に文字列のInfが残るわけではありません。([Oracle Docs][1])

非常に小さいがゼロではない値を分母にした場合、結果はまず大きな有限値になります。その値が表現可能範囲を超えたときにオーバーフローしてInfになる可能性があります。したがって、「ゼロに近い値で割れば必ずInfになる」という説明は正確ではありません。分母の大きさ、分子、数値型、丸め方式、例外設定によって結果が変わります。

単位変換や縮尺設定の誤りも確認対象です。メートルからミリメートルへ一度変換した程度で倍精度浮動小数点がInfになることは通常ありません。しかし、同じ倍率を誤って何度も適用する、異常に大きな尺度係数を使う、累乗や反復処理で値を増幅する、単精度の中間値へ落とすといった条件が重なると、オーバーフローへ至る可能性があります。

座標変換では、角度の単位を度とラジアンで取り違える、投影式の適用範囲外を入力する、分母がゼロになる特異点を通るなどの問題が考えられます。ただし、単位や座標系の取り違えは、多くの場合、まず極端だが有限な値として現れます。Infだけを検索するのではなく、妥当範囲を外れた有限値も同時に検出する必要があります。

原点から離れた大きな座標値は、それ自体が直ちにInfを生む原因ではありません。むしろ単精度処理で相対精度が不足し、小さな差分が失われることが主な問題です。その後に退化したベクトルの正規化、ほぼ特異な行列の計算、極端な倍率補正などが続くと、NaNやInfへ発展する場合があります。大きな公共座標を扱うときは、必要に応じてローカル原点へ平行移動し、元の座標へ戻すための変換情報を別途管理します。

書き出し処理の中断や保存領域不足は、通常、Infそのものを生成する原因ではありません。これらは末尾の欠落、不完全な行、ファイルの切断として現れることが一般的です。Infが末尾付近に集中している場合でも、「保存が途中で止まったからInfになった」と断定せず、計算バッファに既にInfがあり、それを最後に書き出したのか、ファイルが単に途中で切れたのかを分けて確認します。

除去法1:テキスト検索で異常な行を特定して修正する

ファイルが比較的小さく、NaNやInfの件数が少ない場合は、OBJをテキストとして開き、異常な行を直接確認する方法が有効です。OBJはテキスト形式で記録されるため内容を目視できます。ただし、数百万行以上の大規模ファイルを一般的なエディターで開くと、メモリ不足や応答停止が起こり得ます。その場合はコマンドライン検索やストリーム処理へ切り替えます。

最初に元ファイルを複製し、作業用コピーで修正します。検索は大文字と小文字を区別せず行いますが、単なる部分一致だけでは名称やコメントを拾う可能性があります。異常文字列が「v」「vt」「vn」「vp」などの数値欄にあるのか、「p」「l」「f」の参照欄にあるのかを確認します。

参照要素を一切持たず、アップロード先が「v」行だけを独立点として扱うことが確認できている場合は、異常な頂点行の削除で直ることがあります。しかし、標準的な点要素「p」が存在する場合や、線「l」、面「f」、曲線、曲面から参照されている場合は、頂点行だけを削除してはいけません。後続の頂点番号が変わるため、すべての参照を更新する必要があります。

メッシュOBJで異常頂点を手作業で除去する場合は、その頂点を参照する面を特定します。該当面を削除し、残す頂点へ新番号を割り当て、面参照を書き換えます。対象が数件でも、負の参照番号や複数のグループが混在すると作業は複雑です。修正対象が少なく見えても、参照行が多い場合はスクリプト処理へ移行した方が安全です。

UV座標にだけNaNやInfがあり、テクスチャを利用しない場合は、アップロード先がUVなしOBJを受け付けることを確認したうえで、「vt」行と面行のUV参照を一括で外す方法があります。一部の「vt」行だけを削除し、面参照を残すと番号がずれます。

法線情報が異常な場合は、形状が正常であれば「vn」行と面行の法線参照を外し、別工程で法線を再計算する方法があります。無効な法線を単純に「0 0 0」へ置換すると、有限値にはなっても有効な方向ベクトルにはなりません。読み込み側が法線を自動生成するか、法線なしOBJに対応するかを事前に確認します。

NaNやInfを機械的に0へ置換する方法は原則として避けます。座標の一成分を0にすると、頂点が座標軸や原点付近へ移動し、長い線、鋭い突起、巨大な三角形が発生する可能性があります。本来値を周辺点から推定できる明確な根拠がない限り、該当点の削除または元データからの再生成を優先します。

除去法2:元の点群データから非有限値を除外して再出力する

最も安全性が高いのは、OBJを書き出す前の元点群へ戻り、NaNやInfを含むレコードを除外してから再出力する方法です。OBJ変換後は元の属性、点ID、時刻、分類、スキャン番号などが失われている場合があります。元データ段階で処理すれば、座標と付随属性の対応を保ちやすくなります。

除外条件では、X、Y、Zの三成分がすべて有限であることを確認します。Wを使う場合はWも検査し、0やほぼ0のWを使って実座標へ変換する処理があるなら、その条件も確認します。法線、UV、色、反射強度などを出力する場合は、それぞれ必要な全成分を有限値判定します。

有限値判定は、文字列の見た目だけでなく数値型へ変換して行います。たとえばPythonの「math.isfinite」は、値がNaNでも正負の無限大でもない場合に真を返します。同等の有限値判定は多くの言語や数値ライブラリに用意されています。([Python documentation][4])

アップロードで利用しない属性に非有限値がある場合は、その属性を出力対象から外す方法があります。ただし、幾何頂点の末尾へ非標準の追加成分として連結されている場合、受け側が行全体を拒否する可能性があります。必要な要素だけを明示して書き出し、非標準拡張の互換性を確認します。

異常点を削除した後は、重複点、孤立点、局所密度の低い点も確認します。NaN点の除去によって周囲との接続を失い、単独で残る点が発生する場合があります。メッシュ生成前であれば、近傍点数、点間距離、局所密度などを基準に追加整理すると、退化面やゼロ長法線を減らせます。

法線計算は、座標の非有限値を除外した後に行います。NaNを含む点を近傍探索へ入れると、周辺の正常点にまで異常な法線が波及する可能性があります。座標検査、外れ値整理、近傍探索、法線推定という順序を固定すると原因を追跡しやすくなります。

座標変換を伴う場合は、変換前と変換後の両方で有限値を検査します。入力が有限でも、変換式、パラメータ、適用範囲の問題で出力がNaNやInfになることがあります。各工程で点数、非有限値数、X・Y・Zの最小値と最大値を記録すると、異常が発生した段階を特定できます。

再出力後は、書き出し完了メッセージだけで正常と判断しません。保存したOBJを再度解析し、非有限値がないこと、必要な要素数が一致すること、参照番号が範囲内であることを確認します。元工程からやり直す方法は手間がかかりますが、参照番号を手作業で直すより再現性が高く、業務成果として継続利用するファイルに適しています。

除去法3:中間データを経由して正常なOBJを書き出す

元の点群処理環境に有限値の除外機能がない場合は、別の中間データまたは変換環境へ読み込み、非有限値を除外してからOBJを書き出し直す方法があります。ただし、中間変換を通すだけで自動的にNaNやInfが消えるとは限りません。読み込み時に拒否する、警告だけで保持する、黙って0へ置換する、該当点を削除するなど、挙動はツールによって異なります。

まず、元OBJを警告付きでも読み込めるかを確認します。読み込み後は、元ファイルと比較して頂点数、点要素数、線数、面数、UV数、法線数がどう変化したかを記録します。「読み込めた」という事実だけでは、異常点が適切に除外されたことを示しません。

点群として利用するだけで、面、UV、法線が不要な場合は、有限な幾何頂点と、必要に応じて点要素「p」だけで再構成します。アップロード先が「v」行だけの独自点群OBJを受け付けるのか、標準的な「p」要素が必要なのかも確認します。点要素自体に非対応で、面を持つモデルだけを受け付けるサービスでは、この方法では読み込めません。

面やテクスチャが必要な場合は、異常頂点を削除した後に面参照を再構築するか、元点群からメッシュを再生成します。既存面を維持したまま頂点だけ削除すると参照関係が壊れます。穴埋めや再メッシュ化を行う場合は、本来存在しない面を作る可能性があるため、元点群や現場記録と比較します。

中間データを経由するときは、座標系、単位、軸方向、原点、左右手系、頂点順序が変わっていないかを確認します。OBJ自体は線形単位や上方向を一意に定義する一般的なメタデータを持たないため、変換ツール側の設定に依存します。修正前後の代表点を比較し、座標値と向きが意図した範囲にあるか確認します。([NVIDIA Docs][5])

頂点の並び順が変わる可能性にも注意します。OBJ単体の表示だけなら問題にならなくても、外部の属性ファイル、点ID、管理台帳が頂点番号に依存している場合は対応関係が失われます。必要であれば旧番号、新番号、元点IDを対応表として保存します。

再出力時は、必要精度に応じた小数桁数を設定します。桁数を減らしすぎると形状や座標精度が失われます。一方、意味のない桁を過剰に出力すると、ファイル容量と解析時間が増えます。指数表記の対応状況もアップロード先ごとに異なるため、試験ファイルで確認します。

中間変換の利点は、非有限値だけでなく、重複点、退化面、無効法線、不要属性をまとめて整理できることです。その一方で、マテリアル、グループ名、頂点順序、精度が失われる可能性があります。変換前後の要素数、座標範囲、ファイル容量、代表点、テクスチャ表示を比較し、意図しない変更がないか確認します。

除去法4:スクリプトで頂点と参照番号を一括再構築する

大規模な点群OBJや、NaN・Infが多数含まれるメッシュOBJでは、スクリプトによる一括処理が現実的です。単純な行削除ではなく、各レコードを構文として解析し、有限なデータだけを残したうえで参照番号を再構築します。

処理の基本は、OBJを先頭から読み込み、「v」「vt」「vn」「vp」、要素行、グループ、マテリアル参照、コメントなどに分類することです。幾何頂点では必要な数値を変換し、全成分が有限であるかを判定します。正常な頂点には新しい番号を割り当て、旧番号と新番号の対応を保存します。異常頂点は出力せず、旧番号を無効として記録します。

「vt」「vn」「vp」も別々に番号付けされるため、必要に応じて個別の対応表を作ります。幾何頂点の新番号をそのままUVや法線へ使うことはできません。OBJ仕様では各種類が独立して1から番号付けされます。([Gist][2])

要素行を処理するときは、「p」「l」「f」を区別します。点要素「p」は頂点参照、線要素「l」は頂点と任意のUV参照、面要素「f」は頂点、UV、法線の組み合わせを持ちます。異常な参照を含む点や線は該当要素を除外し、面では必要頂点が一つでも欠ける場合、原則としてその面を削除します。三角形から一頂点を除いた二点を面として保存することはできません。

面参照には「v」「v/vt」「v//vn」「v/vt/vn」の形式があります。斜線の数と空欄の意味を維持しなければなりません。同一面の中で参照形式が不整合な行は、元仕様上も不正または互換性の低い状態なので、修復規則を決めて処理します。

OBJでは負の番号による相対参照が可能です。「-1」はファイル全体の最後の要素を意味するのではなく、その要素行の位置から見て直前に定義された同種データを参照します。したがって、読み込み時点の「v」「vt」「vn」件数を使って絶対的な旧番号へ解決し、その後で新番号へ置換する必要があります。([Gist][2])

大容量ファイルでは、全行を一度にメモリへ載せない処理を検討します。ただし、正の参照が後段から前段の頂点を指す一般的なメッシュでは、対応表を作ってから要素を書き換える二段階処理が分かりやすくなります。負の参照や行順を厳密に扱う場合は、最初の走査で行位置ごとの定義数も記録します。

処理結果には、入力と出力の頂点数、UV数、法線数、点数、線数、面数、削除件数を記録します。削除率が高い場合は、修復済みOBJをそのまま成果として使うのではなく、変換元工程を見直して再生成する方が安全です。

スクリプト処理後は、NaNやInfが残っていないこと、すべての正の参照が存在範囲内であること、負の参照が残る場合は行位置から正しく解決できることを検証します。さらに、面の頂点数が三以上であること、同じ頂点を重複参照する退化面がないことも確認します。

NaN・Inf値を除去した後に確認する項目

NaNやInfが文字列検索で見つからなくなっても、修正作業が完了したとは限りません。異常値を削除する過程で、OBJ内の参照関係、点数、形状、テクスチャ対応が変化している可能性があります。構文検査、数値検査、表示確認を分けて実施します。

最初に、各数値が有限であることを確認します。「v」「vt」「vn」「vp」や使用している自由曲線・曲面パラメータを数値として読み込み、有限値判定を行います。検索文字列だけでは、大文字小文字や別表記を見落としたり、名称中の文字列を誤検出したりします。

次に、参照番号を確認します。「p」「l」「f」と、利用している曲線・曲面要素が参照する番号が、対応するデータ範囲内にあるかを検証します。頂点番号が正常でも、UV番号や法線番号が存在しない値を指していれば読み込みに失敗する可能性があります。

修正前後の頂点数、点要素数、線数、面数、UV数、法線数を比較します。少数の異常値だけを除去したつもりなのに面数が大幅に減っている場合は、対応表や削除条件に問題がある可能性があります。反対に、異常頂点を削除したのに参照要素数が変わっていない場合は、無効参照が残っていないか確認します。

座標範囲も重要です。X、Y、Zの最小値、最大値、中央値、代表的な点間距離を確認し、対象物として妥当な範囲に収まっているかを見ます。NaNやInfがなくても、一点だけ極端に遠い有限値が残ると、表示範囲が広がり、本体が小さな点に見えることがあります。

メッシュでは、重複面、面積がほぼゼロの面、同一頂点を複数回参照する面、極端に細長い面、面の向きも確認します。異常頂点の削除後に退化面が残ると、法線計算、陰影、後続の解析で問題になります。

法線を残した場合は、各成分が有限であることに加え、長さが0または極端に小さくないことを確認します。必要に応じて法線を再計算し、面の向きと整合しているかを表示で確認します。

テクスチャを使用する場合は、UV参照、MTL参照、画像ファイル名、相対配置を確認します。異常UVを削除した際に参照を誤ると、形状は正常でも画像がずれます。代表的な境界や模様が正しい位置に表示されるかを確認します。

最後に、修正済みファイルを新しい名称で保存し、可能なら小さな範囲で試験アップロードします。同じ名称で上書きすると、アップロード先やブラウザのキャッシュ、旧バージョンと混同することがあります。修正版の作成日時、削除件数、変換条件を記録し、結果を比較できるようにします。

修正しても点群OBJをアップロードできない場合の切り分け

NaNやInfを除去しても読み込めない場合は、別の構造エラーまたはサービス側の非対応条件が残っている可能性があります。エラーメッセージがNaNやInfを示していても、それが唯一の原因とは限りません。最初の不備を直すと、次の不備が新たに表示されることがあります。

まず確認したいのは、アップロード先が点要素を受け付けるかです。OBJ仕様には点要素「p」がありますが、すべての3Dビューアやクラウドサービスが点表示へ対応するわけではありません。また、「v」行だけを点群として表示する挙動は実装依存です。面を持つ三次元モデルだけを対象とする環境では、非有限値を除去しても点群OBJを読み込めません。([Gist][2])

次に、参照番号が範囲内にあるかを確認します。頂点が千個しかないのに「f」や「p」が千一番目を参照していれば不正です。UVや法線も別々の範囲で検証します。負の参照は、その行より前に定義済みの要素数から解決します。

数値の区切りも確認します。OBJは行頭のキーワードと、その後の引数を空白で区切るテキスト形式です。小数点にカンマを使う、数値同士が結合する、斜線の前後へ不適切な空白を入れる、修正時に改行を消すと、正常な座標や参照として解釈されない可能性があります。

文字コードと先頭文字も確認します。厳格なパーサーでは、ファイル先頭のBOMや想定外の制御文字によって最初のキーワードを認識できないことがあります。コメントやオブジェクト名に非ASCII文字を使えるかも実装依存です。原因切り分けでは、ASCIIの名称と単純な構成へ一時的に絞ります。

ファイルの末尾が途中で切れていないかも確認します。大容量OBJの保存中に処理が停止すると、最後の要素行が途中までしか書かれないことがあります。これはNaNやInfとは別の問題です。末尾だけを除去して読み込めた場合でも、保存処理全体の完了確認やストレージ空き容量を見直します。

マテリアルやテクスチャを参照している場合は、「mtllib」と「usemtl」、MTL内の画像参照、ファイル名の大文字小文字、相対配置を確認します。欠落を警告で済ませる環境もあれば、アップロード処理全体を失敗させる環境もあります。最小構成の切り分けでは、元ファイルを保管したうえでマテリアル参照を外した複製を試します。

容量、頂点数、面数、処理時間の上限も考慮します。NaNやInfがなくても、解析時のメモリ不足やタイムアウトで失敗する場合があります。範囲を分割した小さなOBJが読み込めるかを試すと、データ構造と処理規模のどちらが原因かを判断しやすくなります。

NaN・Inf値の再発を防ぐ運用方法

NaNやInfの問題は、アップロード直前に発見して修正するより、点群処理の各工程で検出した方が効率的です。取得、読込、結合、座標変換、ノイズ除去、法線推定、メッシュ生成、OBJ出力という流れの中で、どの段階から非有限値が発生したかを追跡できる運用を整えます。

点群を取得または受領した直後に、点数、座標範囲、欠損数、非有限値数を記録します。この時点で異常値がなければ、後の処理工程で発生した可能性が高いと判断できます。取得直後からNaNがある場合は、センサー入力、欠損値の保存方法、エクスポート設定を確認します。

複数データを結合する前にも同じ検査を実施します。一つのファイルだけに異常値がある状態で結合すると、原因ファイルを特定しにくくなります。個別検査、結合、結合直後の再検査を標準手順にします。

座標変換では、入力と出力の両方を記録します。代表点を数点選び、変換前後の座標、単位、軸方向を比較します。変換後の最小値や最大値が想定範囲を外れた場合や非有限値が一件でも発生した場合は、OBJ出力へ進まず停止する仕組みが有効です。

法線やメッシュを生成する前には、重複点、孤立点、極端に近い点、局所密度の低い領域を整理します。計算の前提を満たさない点を減らすことで、ゼロ長ベクトル、退化面、不安定な正規化を防ぎやすくなります。法線生成後にも非有限値とゼロ長法線を検査します。

OBJを書き出した後は自動検査を実行します。非有限値がないこと、必要な要素数がゼロでないこと、すべての参照が有効であること、座標範囲が想定内であることを確認します。検査に合格したファイルだけをアップロード対象にすると、手作業による見落としを減らせます。

ファイル名と作業履歴も整理します。取得直後、座標変換後、非有限値除去後、軽量化後、アップロード用などを区別し、どの設定で作成したかを記録します。同じ名称で上書きし続けると、問題再発時に正常だった段階へ戻れません。

変換設定を担当者ごとに変えないことも重要です。単位、座標系、軸方向、法線生成、欠損値の扱い、出力属性、桁数を標準化し、確認項目を共通化します。作業者の経験だけに依存せず、同じ入力に対して同じ検査結果が得られる運用にすることで、NaNやInfの再発を抑えられます。

まとめ

点群OBJのアップロードで読込失敗が発生した場合は、幾何頂点、UV座標、法線、パラメータ空間頂点などにNaNやInfが含まれていないかを確認します。NaNは0を0で割る演算などの無効演算や欠損値の引き継ぎで生じ、Infは有限の非ゼロ値のゼロ除算やオーバーフローなどで生じ得ます。ただし、実際の挙動は数値型、言語、ライブラリの例外処理によって異なります。

参照要素を持たず、アップロード先が「v」行だけを独立点として扱う場合は、異常頂点行の削除で修正できることがあります。一方、「p」「l」「f」や曲線・曲面から参照されているOBJでは、データ行だけを削除すると番号がずれます。元点群から有限値だけを再出力するか、旧番号と新番号の対応を作って参照を再構築する必要があります。

除去方法は、少数の異常行をテキストで確認する方法、元データから有限値だけを再出力する方法、中間データを経由して正常化する方法、スクリプトでデータと参照番号を一括再構築する方法の四つに整理できます。データ量、点要素や面の有無、外部属性との連携状況に応じて、整合性を維持できる方法を選びます。

修正後は、NaNやInfが消えたことだけでなく、座標範囲、要素数、参照番号、法線、UV、退化面、外れ値も確認します。非有限値を0へ一括置換すると、不自然な突起や巨大な面が発生する可能性があるため、根拠のある補間ができない場合は削除または元データからの再生成を優先します。

点群OBJを継続的に扱う場合は、取得後、座標変換後、メッシュ生成後、OBJ出力後の各段階で有限値検査を自動化することが有効です。LRTK PhoneとLRTKクラウドを含む取得・確認・共有の運用へつなげる場合も、OBJの対応要素、ファイル上限、変換条件を事前に確認し、検査済みデータだけをアップロードする流れを整えます。LRTKクラウドは点群データの保存、閲覧、共有に対応しています。([Lefixea Irtk][6])

現場を3Dで残して、あとから測る。
実際の画面と動画で使い方を確認できます。

LRTK Phoneの使い方・実例を見る
資料請求導入相談
現場をスマホで3DスキャンLRTK Phone実例を見る