点群データから作成したOBJをクラウドや3D表示環境へアップロードした際に、「NaNを含む」「座標値が不正」「頂点を読み込めない」といったエラーが発生することがあります。元の点群が画面上では正常に見えていても、OBJへの変換、メッシュ化、軽量化、座標変換などを経た後のファイルに非有限値や構造不整合が混入し、アップロード段階で初めて問題が表面化することがあります。
NaNはNot a Numberを表す特殊な浮動小数点値です。座標計算や変換処理の途中で計算不能な状態が生じたり、欠損値を含むデータを演算したりすると、処理系によってはNaNが生成されます。また、正負の無限大も通常の有限な座標値としては扱えないため、アップロード前にはNaNだけでなく、数値として有限であるかを確認する必要があります。
ただし、OBJの検査ではNaNという文字列だけを探せばよいわけではありません。OBJはテキストで記述される形式で、幾何頂点はv、テクスチャ座標はvt、頂点法線はvn、面はfなどの行で表されます。幾何頂点は基本となるX、Y、Zに加えて、用途によって第4成分の重みwを持つことがあります。また、面などの参照番号には正の絶対インデックスだけでなく負の相対インデックスが使われる場合があります。そのため、単純な列数固定や正の番号だけを前提にした検査では、正常なOBJを異常と判定したり、逆に参照不整合を見逃したりする可能性があります。
点群 OBJ アップロードを安定させるには、利用するアップロード環境が受け付けるOBJの範囲を把握したうえで、非有限値、行構造、座標範囲、参照関係、再読み込み結果を一連で確認することが重要です。
この記事では、点群OBJアップロードでNaN座標エラーを防ぐために実務で確認したい5つの検査方法を、原因の切り分け方から修正後の再確認まで含めて解説します。
点群OBJでNaN座標エラーが発生する理由
OBJは、頂点や面などの幾何情報をテキストで記述できる3Dデータ形式です。ポリゴン形状では、一般にvで幾何頂点を定義し、必要に応じてvtでテクスチャ座標、vnで頂点法線を定義します。面を持つOBJでは、f行からこれらを番号で参照して形状を構成します。点群用途では頂点だけを中心に扱い、面を持たないOBJも考えられます。
典型的な幾何頂点はv 123.456 789.012 35.678のようにX、Y、Zで記述されます。一方、OBJの仕様上は用途によって第4成分のwを持つ幾何頂点もあります。そのため、「v行は必ず数値が3個でなければ異常」と固定してしまうのは適切ではありません。実務では、対象が単純な点群またはポリゴンメッシュなのか、自由曲面などの要素を含むのか、アップロード先がどの記述を受け付けるのかを確認したうえで検査条件を決めます。
NaNは数値演算の結果として生じる特殊値で、通常の有限座標とは異なります。座標変換式で不正な入力を使った場合、欠損値を含む列を計算した場合、正規化できないベクトルを処理した場合など、処理内容によって発生原因は変わります。法線計算でも、処理対象のベクトル長が0になるなど、実装によっては非有限値へつながる可能性があります。
重要なのは、「OBJにNaNという文字があること」と「アップロード側で非有限値として判定されること」を分けて考えることです。エクスポーターによっては非有限値をNaNやnan、inf、Infinityなどの文字列として出力することがありますが、すべての処理系が同じ表記を使うとは限りません。また、アップロード先がどの表記を受理または拒否するかにも実装差があります。
手元の表示環境で読み込めたことも、OBJ全体が正常である保証にはなりません。ビューアーによっては不正な頂点や面を読み飛ばし、残った部分だけを描画する場合があります。逆に、別のアップロード環境では入力検証が厳しく、少数の異常値や参照不整合を理由に処理を停止することがあります。
さらに、NaNを含む幾何頂点だけを削除すれば解決するとは限りません。面、線、点要素などがその頂点を参照していれば、削除後に参照関係を再構成する必要があります。特にOBJでは正の絶対インデックスに加え、現在位置から数える負の相対インデックスが使われる場合もあるため、単純な行削除だけでは参照の意味が変わることがあります。
したがって、NaN検査は文字列検索だけではなく、数値としての有限性、OBJ行の構文、座標範囲、参照インデックス、修正後の再解析まで含めた工程として考えることが重要です。
検査方法1:NaNやInfinityを文字列として検索する
最初に行いたいのが、OBJ内部に非有限値を示す文字列が直接記録されていないかを確認する検査です。OBJはテキスト形式なので、ファイルを検索できる環境であれば、異常候補を比較的短時間で絞り込めます。
検索対象としてはnan、NaN、NANなどを大文字小文字を区別せず確認します。さらに、処理系によってはinf、+inf、-inf、Infinityなどの表記が出力されることもあるため、必要に応じて対象を広げます。ただし、これらの表記はアップロード先によって解釈が異なる可能性があるため、特定の1語が見つからなかっただけで正常と判断しないことが重要です。
たとえばv 102.35 NaN 18.21であれば、Y座標を通常の有限値として扱えません。v NaN NaN NaNのように幾何頂点全体が成立していない場合もあります。また、位置座標だけでなく、vnやvtに非有限値が含まれる可能性もあります。アップロード先が法線やテクスチャ座標まで解析する場合、幾何頂点が正常でも後段でエラーになることがあります。
文字列検索の利点は、大規模なOBJでも明確な異常候補を素早く特定できる点です。該当行番号と前後の記述を記録しておけば、どのデータ種別で異常が発生したかを追跡しやすくなります。
一方、この方法だけでは完全ではありません。空欄、区切り崩れ、数値へ変換できない別の文字列、桁あふれにつながる異常な値、想定外の列構成などは、NaNという文字列の検索だけでは検出できません。
そのため、文字列検索はアップロード前の高速な一次検査と位置付けます。異常が見つかった場合はその場で削除するのではなく、該当行が幾何頂点なのか、法線なのか、テクスチャ座標なのかを確認し、面や線などから参照されているかも調べます。
特に幾何頂点の行を途中から削除すると、正の絶対インデックスを使用する要素では後続頂点の番号関係が変わります。負の相対インデックスを使用している場合も、要素行から見た相対位置が変わることがあります。文字列を見つけた段階では、異常箇所の記録までにとどめ、参照関係を確認してから修正する方が安全です。
検査方法2:すべての数値を有限値として判定する
文字列検索より確実なのが、OBJ内の数値項目を実際に数値として解析し、有限値かどうかを判定する方法です。
この検査では、文字列がNaNかどうかだけを見るのではなく、数値化した結果が有限であるかを確認します。これにより、NaNに加えて正負の無限大も検出できます。継続的に点群OBJをアップロードする業務では、この有限値検査を自動処理の中心に置くと原因を切り分けやすくなります。
単純な点群またはポリゴンメッシュを対象とするなら、まずv行のX、Y、Zを数値化します。3成分のうち一つでも有限値でなければ、その幾何頂点を要確認として記録します。第4成分wを許容する運用であれば、その値についても数値として解析できるか、利用環境の条件に合うかを確認します。
ここで、ゼロ、負数、指数表記をそれだけで異常と判断しないことが重要です。座標が0であることや負であることは、原点や座標系の設定によって普通に起こり得ます。1.0e-6のような指数表記も、アップロード先がその数値表現を解釈でき、値が有限であれば直ちに異常とはいえません。
反対に、非常に大きな有限値は有限値検査には合格しますが、業務上妥当とは限りません。有限性と座標範囲の妥当性は別の検査として扱う必要があります。
vnがある場合は、法線の3成分も有限値か確認します。vtについては使用される成分数がデータや用途によって異なるため、アップロード環境が受け付ける構成に合わせて解析します。自由曲面関連の記述やvpなどを含むOBJを扱う場合は、それらも対象に含めます。
自動検査では、異常の有無だけでなく、行番号、データ種別、何番目の成分か、元の文字列を記録すると原因調査が容易になります。「非有限値が1件ある」だけではなく、「幾何頂点の特定行でZ成分が非有限」と分かれば、元の点群や変換工程へ戻りやすくなります。
また、検査を最初の1件で停止させず、ファイル全体を最後まで走査することが重要です。数百万行の中に非有限値が複数ある場合、1件直して再アップロードし、次の1件で再び失敗するという手戻りを防げます。
有限値判定は、NaN文字列の表記差に依存しにくい点でも有効です。アップロード前の標準検査として、ファイル全体を数値として正しく解釈できるかを確認する運用が適しています。
検査方法3:頂点行の列数と数値形式を検査する
NaNそのものが見つからなくても、OBJの行構造がアップロード先の想定から外れていれば、読み込みエラーになることがあります。3つ目の検査では、vをはじめとする各行が、対象環境で受け付けられる構文になっているかを確認します。
単純な点群やポリゴンメッシュでは、v行から少なくともX、Y、Zを読み取れることを確認します。ただし、標準仕様では幾何頂点に第4成分wを持たせる記述があります。そのため、4つ目の数値があるだけで異常と判定してはいけません。
一方で、実装によっては頂点カラーなどの追加値をv行へ付ける慣習があります。こうした拡張表現を受け付けるかどうかはソフトウェアによって異なります。したがって、検査条件は「OBJなら常に3列」と決めるのではなく、「今回アップロードする環境が何成分まで対応するか」に合わせて設定することが重要です。
座標の不足は明確な確認対象です。たとえばv 123.4 456.7のようにX、Y、Zの3成分を取得できない行は、一般的な3次元幾何頂点として扱えません。また、v 123.4 abc 78.9のように数値へ変換できない文字列が混ざっている場合も、NaN検索とは別に構文異常として検出する必要があります。
区切り文字の崩れや余計な注記も確認します。OBJは空白でトークンを分けるテキスト形式なので、数値の途中に単位記号を付けたり、数値とコメントを独自形式で連結したりすると、読み込み側が想定どおりに解析できない場合があります。
CSVなど別形式を経由してOBJを生成した場合は、小数点と区切り記号の扱いにも注意します。ロケールや変換設定の違いで、元の数値が意図しない列へ分割されると、結果として座標列が欠落したり、余分な列が増えたりする可能性があります。
改行についても、単純に「行が長いから途中で分割してよい」とは考えない方が安全です。OBJには行継続の記述が使われる場合がありますが、任意の位置で改行しただけでは別の行として解釈される可能性があります。ファイル分割や独自のテキスト処理を行った後は、行頭キーワードと各トークンの対応が保たれているかを確認します。
検査結果として、幾何頂点行数、正常に解析できた行数、構造異常行数、法線行数、テクスチャ座標行数などを集計すると異常を見つけやすくなります。想定した頂点数と解析できた頂点数が一致しない場合は、NaNがなくても構造異常や未対応表現が含まれている可能性があります。
この検査の目的は、OBJ仕様で許されるすべての記述を一律に拒否することではありません。アップロード先の対応範囲と照らし合わせ、必要な成分が欠けていないか、未対応の追加成分が混ざっていないか、数値化できない文字列がないかを確認することが重要です。
検査方法4:座標範囲と外れ値から異常頂点を見つける
すべての座標が有限で、行構造も正常でも、空間的に不自然な値が混在していることがあります。4つ目に確認したいのが、点群OBJ全体の座標範囲です。
まずX、Y、Zそれぞれの最小値と最大値を求めます。これにより、点群がどの程度の空間範囲に分布しているかを数値で確認できます。
たとえば数十メートル程度の構造物を対象としているのに、1点だけ本体から極端に離れた位置にある場合、その頂点は確認対象になります。有限値なのでNaN検査には合格しますが、座標系の取り違え、単位変換、桁位置、原点設定、異なるデータの混入などが原因になっている可能性があります。
ここで重要なのは、大きな座標値そのものをNaNと同一視しないことです。値が大きくても有限であればNaNではありません。また、測量座標や地理空間データでは大きな絶対座標を持つ場合があります。数値の大小だけで削除するのではなく、使用している座標系、単位、現場規模、原点の設計と照らして妥当性を判断します。
複数回の計測結果を統合したOBJでは、座標範囲の検査が特に有効です。一部のデータだけ異なる座標系や原点で処理されていると、統合後に大きく離れた場所へ配置されることがあります。
Z方向も個別に確認します。平面表示では異常が目立たなくても、高さだけ極端な値になっている場合があります。上から見た表示だけに頼らず、XYZの各軸を数値で確認することが重要です。
外れ値の判定には、最小値と最大値だけでなく、点群の中心的な分布からどの程度離れているかを見る方法もあります。ただし、長距離の道路、河川、造成地など、実際に広い範囲を持つデータでは遠方点が正しい場合があります。しきい値を全国一律の固定値にするのではなく、対象現場と用途に合わせて設定します。
また、変換工程ごとに座標範囲を記録すると、異常が発生した段階を追いやすくなります。元点群では妥当だった範囲が、座標変換後に突然広がったのであれば、その変換条件を重点的に確認できます。
NaNが検出された場合は、その前後の処理で極端な有限値が発生していないかも確認すると原因調査に役立ちます。特定の演算で値が異常に増大し、その後の工程で非有限値になった可能性もあるためです。
座標範囲の検査は、NaNだけでなく、座標系の取り違え、単位誤り、原点設定ミス、別データの混入を早期に発見するための補助検査として有効です。
検査方法5:頂点番号と面参照を再検証して読み込み試験を行う
5つ目は、NaNを除去または修正した後も含めて、OBJ全体の参照関係が成立しているかを確認する検査です。
OBJでは、点、線、面などの要素が頂点を番号で参照します。正の参照番号は先頭から数える絶対インデックスで、幾何頂点は1から数えます。一方、負の参照番号は要素行の位置からさかのぼって数える相対インデックスとして使われる場合があります。したがって、検査を「1から最大頂点番号までに入っているか」だけで終わらせると、負の参照を正しく評価できません。
面を表すf行では、幾何頂点だけを参照するf 1 2 3のような形式に加え、テクスチャ座標や法線を組み合わせたv/vt/vn形式、法線だけを伴うv//vn形式などがあります。アップロード対象のOBJにvtやvnが含まれる場合は、幾何頂点番号だけでなく、それぞれの参照先が存在するかも確認します。
ゼロインデックスは通常のOBJの参照として扱わないため、0が現れた場合は確認対象です。正の参照は対象リストの範囲内にあるかを確認し、負の参照はその要素行の時点で何番目の頂点、テクスチャ座標、法線を指すのかを解決して、有効な参照になるかを確認します。
NaNを含む幾何頂点を単純に1行削除すると、正の絶対インデックスで後続頂点を参照している要素の意味が変わります。負の相対インデックスを使用している場合も、削除位置と要素行の位置関係によって参照先が変わる可能性があります。そのため、手作業で該当行だけを削除するより、元データで異常点を除外してOBJを書き出し直すか、頂点と参照番号を一貫して再構成できる処理を使う方が安全です。
異常頂点が面に使われていた場合は、頂点の削除だけでなく、その面をどう扱うかも決める必要があります。面を削除するのか、周辺形状を再生成するのかは、元データと用途に応じて判断します。点群OBJで面を持たない場合は、この面再構成は不要ですが、pやlなど別の要素が頂点を参照していないかは確認します。
修正後は、ファイルを別工程で再読み込みします。書き出した直後のOBJを同じ内部データのまま信用するのではなく、完成ファイルからもう一度解析し、頂点数、面数や要素数、非有限値数、構造異常数、参照エラー数、座標範囲を確認します。
この往復確認によって、「書き出し処理は完了したが、完成したOBJを読み直すと一部が欠落する」という状態を発見しやすくなります。アップロード先と同じパーサーを使えない場合でも、別の検証処理でOBJを再解析することで、明確な構造破損を事前に見つけられます。
点群OBJは大容量になることがあり、アップロード後に失敗すると再送や再調査に時間がかかります。参照検証と再読み込みをアップロード前に行うことで、手戻りを減らしやすくなります。
NaNを検出した後に安全に修正する手順
NaNが見つかったときに避けたいのは、原因を確認せず該当値を一律に0へ置き換えることです。
たとえばv 150.2 NaN 30.5のYを単純に0へ変更すると、文字列としては有限値になります。しかし、本来のY座標が不明なまま0を代入しているため、点が全く異なる位置へ移動する可能性があります。エラー表示を消すことと、正しい幾何データに戻すことは別です。
まず、異常値がどの段階で生成されたかを確認します。元点群に欠損があるのか、座標変換で発生したのか、メッシュ化や法線生成で生じたのか、OBJ書き出し時だけ発生したのかを切り分けます。
元データに異常があるなら、可能であれば元点群の段階で除外または再取得し、その後の処理をやり直します。変換工程で発生しているなら、入力座標、変換係数、座標系、単位、欠損値処理などを確認します。OBJ書き出し時だけ発生している場合は、書き出し前の内部データと完成OBJを比較します。
異常頂点を削除する場合は、その頂点を参照する面、線、点要素などの処理も必要です。正の絶対インデックスと負の相対インデックスの両方を考慮し、参照関係が破綻しないように再構成します。
修正後は、文字列検索だけで終了せず、有限値判定、行構造、座標範囲、参照関係、再読み込みをもう一度実行します。修正作業によって別の不整合が生じる可能性があるためです。
また、異常が複数存在する場合は、最初の1件だけ直してアップロードするのではなく、ファイル全体を最後まで走査します。修正前後の異常件数を保存し、たとえば非有限値が3件から0件になったことを確認できれば、作業完了を判断しやすくなります。
点群OBJの品質管理では、「エラー表示が消えた」ではなく、「設定した検査項目を通過した」ことを完了条件にする方が再発を防ぎやすくなります。
大規模な点群OBJでは自動検査を前提にする
数千点程度の小さなOBJであれば、テキストを開いて一部を確認できる場合があります。しかし、実務の点群データは数十万点、数百万点以上になることがあり、目視だけで全件を確認するのは現実的ではありません。
大規模な点群OBJでは、アップロード前検査を自動化することが有効です。
自動検査では、ファイルを先頭から順番に読みながら、行頭キーワードを判定し、幾何頂点数を数え、必要な数値を解析し、有限値を確認し、XYZの最小値と最大値を更新していく方法が考えられます。これらはすべての頂点を同時にメモリへ保持しなくても実行しやすい検査です。
一方、面や線の参照を厳密に検証する場合は、正の絶対インデックスと負の相対インデックスを解決できるよう、各種類の頂点がその時点で何件定義されているかを管理します。fにv/vt/vnが含まれる場合は、幾何頂点、テクスチャ座標、法線を別々に数え、それぞれの参照を検査します。
検査結果として、総行数、幾何頂点数、正常頂点数、非有限値数、構造異常行数、法線数、テクスチャ座標数、面数、参照エラー数、XYZの座標範囲などを保存すると、前回データとの比較にも利用できます。
同じ現場で継続してOBJを書き出す場合、これらの集計値は品質変化の把握に役立ちます。前回と同程度の範囲を処理しているのに頂点数が急減した場合、NaNが0件でも別の工程異常を疑う材料になります。
検査処理とアップロード処理を分離することも重要です。OBJが完成したらすぐ送信するのではなく、未検査、検査済み、アップロード済みと状態を分けて管理すると、旧版や未検査ファイルを誤って送る可能性を減らせます。
大容量OBJの問題箇所を調査するためにファイルを分割する場合は、テキストを任意の行で単純分割しないよう注意します。頂点定義と要素参照の関係が変わるため、分割後の各ファイルで参照番号を再構成できる方法を使う必要があります。
NaNが頻繁に発生する場合は、完成OBJを毎回修正するより上流工程を見直す方が有効です。同じ変換処理で繰り返し非有限値が出るなら、入力データの欠損、座標変換条件、法線計算、メッシュ処理、軽量化処理などのどこで異常が生成されているかを確認します。
点群OBJアップロードを安定させる運用ルール
点群 OBJ アップロードの失敗を減らすには、エラーが出たときだけ担当者が調べる運用より、毎回同じ検査を通す仕組みにする方が安定します。
まず、OBJを書き出す前の元データで欠損値や座標異常がないかを確認します。次にOBJ生成後、非有限値、行構造、座標範囲、参照関係を検査します。その後、完成OBJを一度再読み込みし、想定した件数と範囲で解釈できることを確認してからアップロードします。
この順序を固定すると、異常が混入した工程を追跡しやすくなります。元点群では正常でOBJ生成直後に異常があるなら書き出し工程を確認し、OBJ生成直後は正常で軽量化後に異常が出たなら軽量化工程を重点的に調べられます。
座標の基準もチーム内で統一します。座標系、単位、原点、軸方向などが工程ごとに変わると、NaNではなくても大きな位置ずれが生じます。有限値検査に合格しただけで位置が正しいとは判断せず、座標範囲と現場条件を合わせて確認します。
外部から受け取ったOBJについても、拡張子が同じだから内部構造も同じとは考えないことが重要です。OBJには複数の要素記述があり、正負の参照番号、vtやvnの有無、第4成分w、実装独自の拡張などによって、ソフトウェア間の互換性に差が出る場合があります。
複数人で点群取得、変換、OBJ生成、アップロードを分担する場合は、どの元データから、どの処理条件で、いつ生成したファイルなのかを追跡できるようにします。完成OBJだけを残して元データを失うと、異常値の正しい座標を復元できない場合があります。
アップロード前にはファイル容量だけでなく、頂点数、要素数、座標範囲、非有限値数、参照エラー数を記録する習慣を付けると、品質変化に気付きやすくなります。
点群データでは、一見正常に表示されることと、内部データが正常であることは同じではありません。表示確認と数値・構造検査を分けて実施することが大切です。
まとめ
点群OBJアップロードでNaN座標エラーを防ぐには、アップロード後のエラーメッセージだけを頼りに修正するのではなく、OBJを生成した段階で数値と構造を検査することが重要です。
最初にNaNやInfinityなどの異常候補を文字列として検索すれば、明確な問題を素早く絞り込めます。ただし表記は処理系によって異なる可能性があるため、文字列検索だけで正常判定はしません。
次に、座標や必要な数値を実際に解析し、有限値として成立しているかを確認します。ゼロ、負数、指数表記はそれだけで異常ではありません。有限性と業務上の妥当性を分けて判断します。
行構造の検査では、v行をXYZの3成分だけに固定しないことも重要です。OBJでは用途によって第4成分wを持つことがあり、実装によっては頂点カラーなどの拡張表現もあります。利用するアップロード環境の対応範囲に合わせて、必要成分の不足と未対応成分の混入を確認します。
座標範囲を確認すれば、数値としては有限でも空間的に不自然な頂点を見つけやすくなります。座標系、単位、原点の取り違えもNaNとは別の問題として確認します。
さらに、修正後は面や線などの参照関係を再検証します。OBJの参照番号には1始まりの正の絶対インデックスだけでなく、負の相対インデックスが使われる場合があります。f行にテクスチャ座標や法線の参照が含まれる場合は、それぞれの参照先も確認します。
特に注意したいのは、NaNを単純に0へ置き換えないことです。エラー表示を消しても、点が誤った位置へ移動すれば点群の品質を損ないます。異常が発生した工程を特定し、可能な限り元データに近い段階で修正してからOBJを書き出し直す方が安全です。
大規模な点群を継続的に扱う場合は、文字列検索、有限値判定、行構造、座標範囲、参照関係、再読み込みまでを自動検査に組み込みます。「OBJを書き出せたから完了」ではなく、「定めた検査を通過してからアップロードする」という運用にすると、点群 OBJ アップロードの手戻りを抑えやすくなります。
そして、OBJ化した後のエラー対処だけでなく、現場での計測から点群活用までの流れを整理することも重要です。点群を取得し、位置情報を確認しながら現場データを活用する環境を整えたい場合は、LRTK Phoneを活用した運用も検討してみてください。