LRTKレフィクシア株式会社

点群OBJの負の頂点番号でエラーが出るときの5つの変換手順

点群から作成したOBJファイルをアップロードした際に、「頂点番号が不正です」「インデックスが範囲外です」「面データを読み込めません」といったエラーが出ることがあります。ファイルが破損しているように見えても、実際には面や線を定義する行で負の頂点番号が使われており、アップロード先がその記述方法に対応していないだけかもしれません。

OBJでは、正の番号だけでなく、現在の位置からさかのぼって頂点を指定する負の番号も使用できます。負の番号自体が直ちに誤りというわけではありません。しかし、OBJの読み込み機能は利用環境ごとに対応範囲が異なります。正の頂点番号だけを前提とした処理では、仕様上有効な負の番号でもエラーとして扱われることがあります。

この問題を解決するときに、マイナス記号だけを削除してはいけません。負の頂点番号は、単なる負数ではなく、参照行より前に定義された頂点を後ろから数える相対番号です。正の番号へ直すには、その行に到達した時点で定義済みの頂点数を数え、正しい計算式で絶対番号に変換する必要があります。

さらに、面の行には頂点番号だけでなく、テクスチャ座標番号や法線番号が含まれる場合があります。それぞれが別の要素一覧を参照しているため、頂点数だけを使って一括変換すると、テクスチャのずれや陰影の崩れを引き起こします。

この記事では、「点群 OBJ アップロード」でエラーの原因を調べている実務担当者に向けて、負の頂点番号を安全に正の番号へ変換する5つの手順を解説します。変換式だけでなく、元データを壊さないための準備、複合インデックスの扱い、変換後の検証方法、再発防止の運用まで詳しく整理します。

点群OBJで負の頂点番号が使われる仕組み

OBJは、三次元形状をテキスト形式で記述できるファイル形式です。頂点座標、テクスチャ座標、法線、点、線、面などの要素を、行頭の識別子と数値によって表現します。点群をOBJとして保存する場合は頂点情報を中心に構成されますが、点群からメッシュを生成した場合は、頂点を参照する面情報も含まれます。

頂点座標は、一般に行頭の v に続けてX、Y、Zの数値を記述します。最初に定義された頂点が1番、次の頂点が2番というように、正の番号はファイル内での定義順を表します。

たとえば、次のように頂点が定義されているとします。

v 0.0 0.0 0.0

v 1.0 0.0 0.0

v 1.0 1.0 0.0

この3頂点を使って面を作る場合、正の番号では f 1 2 3 と記述できます。f は面を表し、その後ろの数値が頂点番号です。

OBJでは、同じ面を f -3 -2 -1 と記述することもできます。負の番号は、面の行に到達した時点で定義済みの頂点を後ろから数える相対参照です。-1 は直前までに定義された最後の頂点、-2 はその一つ前、-3 はさらに一つ前を表します。

その時点で頂点が100個定義されていれば、-1 は100番、-2 は99番、-3 は98番です。したがって、f -3 -2 -1 は f 98 99 100 と同じ頂点を参照します。

ここで重要なのは、負の番号がファイル全体の末尾から数える番号ではないことです。参照行が現れた時点までに定義済みの要素数が基準になります。ファイルの途中で頂点が追加される構成では、同じ -1 でも行の位置によって対応する正の番号が変わります。

たとえば、頂点を10個定義した直後の -1 は10番ですが、その後に頂点を5個追加した位置の -1 は15番です。すべての面に対してファイル末尾の総頂点数を使うと、前半にある面の参照先が変わってしまいます。

負の番号は、データを生成しながら直前の頂点を参照するときに便利です。頂点番号の累積値を毎回明示しなくても、直近の頂点を使って面を定義できます。しかし、読み込み側が相対参照を処理しない場合には、正しいOBJであってもアップロードエラーの原因になります。

負の頂点番号でアップロードエラーが起きる理由

OBJを読み込む処理は、すべてが同じ構文に対応しているわけではありません。OBJの基本的な頂点と面だけを読み込む簡易的な処理では、面の頂点番号が1以上の正の整数であることを前提としている場合があります。このような環境へ負の番号を含むOBJをアップロードすると、マイナス記号を検出した段階で処理が止まることがあります。

表示されるエラーは環境によって異なります。「負のインデックスは使用できません」と明示されることもあれば、「面の解析に失敗しました」「頂点参照が不正です」「インデックスが範囲外です」のように、原因を直接示さないこともあります。

負の頂点番号に対応している処理でも、テクスチャ座標番号や法線番号の負数には対応していない場合があります。形状だけのOBJは読み込めるのに、テクスチャや法線を含めると失敗する場合は、面の複合インデックスを確認する必要があります。

OBJの面は、頂点番号だけを記述する形式に限りません。頂点番号とテクスチャ座標番号を組み合わせる形式、頂点番号と法線番号を組み合わせる形式、三種類すべてを組み合わせる形式があります。

f 1 2 3 は頂点番号だけを指定する形式です。

f 1/1 2/2 3/3 は、頂点番号とテクスチャ座標番号を指定します。

f 1//1 2//1 3//1 は、テクスチャ座標を省略し、頂点番号と法線番号を指定します。

f 1/1/1 2/2/1 3/3/1 は、頂点番号、テクスチャ座標番号、法線番号を指定します。

これらの各番号には負の値を使用できますが、三つの欄は別々の要素一覧を参照します。負の頂点番号を扱えても、負の法線番号の処理に失敗すれば、面全体を読み込めないことがあります。

また、元の負の番号が参照可能な範囲を超えている場合もあります。その行までに頂点が10個しかないのに -11 が指定されていれば、正しい頂点へ対応させることができません。正の番号へ変換すると0になり、OBJの通常の1始まりの参照として成立しません。

この場合はアップロード先の非対応ではなく、書き出し途中の中断、頂点行の欠落、面と頂点の統合ミスなど、元ファイル側の問題が疑われます。負の番号を変換する工程では、対応する正の番号を計算するだけでなく、変換結果が有効範囲内にあるかを検査することが必要です。

変換前に確認するOBJの基本構造

負の番号を変換する前に、対象となるOBJにどの種類の行が含まれているかを確認します。OBJでは行頭の識別子によって、数値の意味が変わります。マイナス記号を含む数値がすべて変換対象になるわけではありません。

v は頂点座標です。後ろに続く負の小数は、X、Y、Zの座標値である可能性があります。測量データやローカル座標では、座標値が負になることは珍しくありません。

vt はテクスチャ座標です。ここに記載される数値も座標値であり、負の値が含まれる場合があります。

vn は法線ベクトルです。方向を表す成分には通常、正負の小数が使われます。

p は点を表し、後ろの整数で頂点を参照します。

l は線を表し、頂点番号と、必要に応じてテクスチャ座標番号を参照します。標準的な l の構文では法線番号を指定しません。

f は面を表し、頂点番号、テクスチャ座標番号、法線番号を参照します。

負の頂点番号として変換するのは、点群やポリゴンメッシュで一般的に使われる p、l、f の参照欄にある負の整数です。v -123.45 50.0 8.0 のような頂点座標行を正の数へ変えると、点群の位置や形状そのものが変わってしまいます。

なお、OBJには自由曲線や自由曲面を表す curv、curv2、surf などの要素もあり、それらにも頂点やパラメータ頂点などの参照番号が現れる場合があります。本記事の5手順は、点群やポリゴンメッシュで一般的な p、l、f を主対象とします。自由曲線や自由曲面の要素が含まれている場合は、同じ置換処理へ無理に含めず、各要素の構文に対応した変換処理を使用します。

そのため、ファイル全体からマイナス記号を検索し、すべて削除する方法は使用できません。行の種類と、行内で数値が置かれている位置を判定したうえで変換します。

次に、頂点行と面行の配置を確認します。OBJには、すべての頂点を先に定義し、その後に面をまとめて記述する構成があります。この場合、各面行に到達した時点の頂点数は基本的に同じです。

一方で、頂点を数個追加し、その頂点を使う面を記述してから、さらに頂点を追加する構成もあります。この場合は面行ごとに参照基準が変わるため、ファイルを上から順に処理しなければなりません。

安全性を重視するなら、構成を問わず、先頭から一行ずつ読みながら現在の頂点数を更新する方法が適しています。すべての頂点が先に定義されているファイルにも対応でき、途中で頂点が追加されるファイルでも誤変換を防げます。

さらに、頂点、テクスチャ座標、法線の数は別々に数えます。頂点が10万個あっても、テクスチャ座標が8万個、法線が5万個という構成はあり得ます。三つを同じ件数として扱うと、頂点番号は合っていても、テクスチャ座標や法線が範囲外になります。

手順1 元のOBJを複製して変換対象を特定する

最初の手順は、元のOBJを直接編集せず、変換用の複製を作ることです。負の番号の変換は、数万行から数百万行に及ぶ場合があります。途中で計算式や対象範囲を誤ると、多数の面参照が書き換わります。原本を上書きしてしまうと、元の参照関係へ戻すことが難しくなります。

原本、変換作業用、変換後の検証用を分け、役割が分かる名称で保存します。更新日時だけを基準にすると、コピーや移動によって順序が分かりにくくなるため、版を識別できる情報も残します。

複製後は、ファイルが末尾まで正常に保存されているかを確認します。点群OBJは容量が大きくなりやすく、書き出し中の中断や保存領域不足によって、末尾が欠けた状態で残ることがあります。負の番号を正しく変換しても、元ファイルが途中で切れていればアップロードは成功しません。

ファイル末尾が行の途中で終わっていないか、想定していた容量と大きく違わないか、作成処理が正常終了しているかを確認します。可能であれば、頂点数や面数を作成時の記録と照合します。

次に、文字コードと改行形式を確認します。OBJの主要部分は英数字で構成されますが、コメント、オブジェクト名、グループ名、材質名などに日本語が含まれる場合があります。変換処理によって文字コードが変わると、番号変換とは別の読み込みエラーが発生する可能性があります。

一般的な点群やポリゴンメッシュでは、変換対象を特定するときに p、l、f で始まる行を抽出し、その参照欄に負の整数が含まれているかを調べます。座標行や法線行にあるマイナス値は対象外です。単純な全文検索は対象の候補を見つける用途には使えますが、検索件数だけで変換対象数を確定しないようにします。

curv、curv2、surf などが含まれている場合は、点、線、面だけのOBJではありません。その場合は対象要素を処理できる変換機能を用意するか、自由曲線や自由曲面を保持できる環境で正の参照番号を使って再出力します。

たとえば、v -10.0 5.0 2.0 は負の座標値を持つ頂点行であり、修正してはいけません。vn -0.5 0.0 0.5 も法線ベクトルの成分です。一方、f -3 -2 -1 の三つの負数は頂点参照なので変換対象です。

変換前には、ファイル全体の行数、v 行数、vt 行数、vn 行数、p 行数、l 行数、f 行数を記録します。自由曲線や自由曲面を含む場合は、それらの要素数も別に記録します。負の参照を正の番号へ置き換えるだけであれば、通常はこれらの行数が変わる必要はありません。

変換後に行数が減っていれば、読み込み途中で処理が止まった可能性があります。行数が増えていれば、改行の誤処理や重複出力を疑えます。事前に件数を記録しておくことで、アップロード前にファイルの欠落を発見しやすくなります。

手順2 行ごとの頂点数を数えて参照基準を確定する

二つ目の手順では、OBJを先頭から順に読みながら、その時点までに定義された頂点数を数えます。負の頂点番号は、参照行より前に定義された頂点の末尾を基準にするためです。

処理開始時点では、頂点数、テクスチャ座標数、法線数をすべて0にします。v 行を読み込んだら頂点数を1増やします。vt 行を読み込んだらテクスチャ座標数を1増やします。vn 行を読み込んだら法線数を1増やします。

f 行に到達したら、その直前までに数えた値を使って負の参照を変換します。面行そのものは頂点を追加しないため、面を変換した後も頂点数は変わりません。

たとえば、ある面行に到達した時点で頂点が1200個定義されているとします。面が f -3 -2 -1 であれば、参照先は1198番、1199番、1200番です。

計算の考え方は、現在の要素数に負の番号を加え、さらに1を加える形です。現在の頂点数をN、負の参照番号をI、変換後の正の番号をPとすると、関係は P = N + I + 1 になります。

Nが1200でIが-1なら、Pは1200です。Iが-2なら1199、Iが-3なら1198です。

このとき、ファイル全体の最終頂点数を使わないことが重要です。たとえば、ファイル末尾では頂点が5000個あっても、対象の面行までに1200個しか定義されていなければ、負の参照番号の基準は1200です。5000を使うと、面が本来とは無関係な後半の頂点を参照してしまいます。

OBJの中には、頂点と面が交互に現れるものがあります。最初に100個の頂点があり、その直後に面が記述され、さらに50個の頂点が追加される構成では、前半の面にある -1 は100番、後半の面にある -1 は150番です。

この違いを無視して一括変換すると、構文上は正の番号になっても、面の形状が壊れます。遠く離れた頂点同士が結ばれ、細長い三角形が発生したり、面が点群の外側へ伸びたりすることがあります。

行を数えるときは、v、vt、vn を厳密に区別します。行頭が v であるかどうかを単純な前方一致だけで判定すると、vt や vn まで頂点として数える可能性があります。行頭の識別子を空白で区切り、完全に一致する種類として判定します。

先頭に空白が付いている行にも注意します。判定するときだけ行頭の空白を除き、出力するときには元の書式を維持する方法が適しています。変換対象でないコメントやグループ情報まで整形すると、変換前後の差分が増え、確認が難しくなります。

手順3 負の頂点番号を正の絶対番号へ変換する

三つ目の手順で、負の頂点番号を正の絶対番号へ置き換えます。ここで行うのは、マイナス記号を削除する処理ではなく、同じ頂点を参照し続けるための再計算です。

現在の頂点数が100の場合、-1 は100番、-2 は99番、-100 は1番です。-101 は計算結果が0になるため、有効な頂点を参照できません。

たとえば、現在の頂点数が8で、面が f -4 -3 -2 -1 と記述されている場合、正の番号へ変換すると f 5 6 7 8 になります。四角形を構成する頂点数や並び順は変えません。

変換時に番号を昇順へ並べ替える必要はありません。面に記述された頂点の順序は、輪郭をたどる順序や面の向きに関係します。元が f -1 -3 -2 であれば、対応する正の番号も元の順序のまま記述します。

番号を見やすくする目的で並べ替えると、面が交差したり、表裏が反転したり、別の三角形になったりする可能性があります。今回の目的は参照方法の変換であり、メッシュ形状の修正ではありません。

変換結果は、必ず1以上かつ、その参照行までに定義されている頂点数以下であることを確認します。結果が0以下になる場合は、参照可能な範囲を超えています。現在の頂点数を上回る結果になる場合も、計算方法や入力値に誤りがある可能性があります。

範囲外の番号が見つかったときに、強制的に1へ変更したり、直前の頂点番号を代入したりしてはいけません。読み込みエラーは消えるかもしれませんが、どの頂点を参照すべきかという根拠が失われます。

元ファイルが途中で欠けている可能性、面データと頂点データが異なる版から結合された可能性、書き出し処理が頂点行を省略した可能性を調べます。正しい参照先が判断できない場合は、元データからOBJを再作成するほうが安全です。

点を表す p 行や線を表す l 行でも、負の頂点番号が使われる場合があります。メッシュだけを想定して f 行しか変換しないと、点や線の読み込み時にエラーが残ります。

点群OBJでは、頂点を定義した後に p 行で表示対象を指定していることがあります。対象ファイルの構成を確認し、今回の処理対象として定めた要素の頂点参照を漏れなく処理します。

一方、コメント行、グループ名、オブジェクト名、材質指定などに含まれる負数は、頂点番号とは限りません。行の識別子に応じて変換対象を限定します。

手順4 テクスチャ座標番号と法線番号を個別に変換する

四つ目の手順では、面に含まれるテクスチャ座標番号と法線番号、および線に含まれるテクスチャ座標番号を確認します。頂点番号だけを正にしても、ほかの参照欄に負の番号が残っていれば、アップロードエラーが解消しない場合があります。

標準的な l 行で指定できるのは頂点番号と任意のテクスチャ座標番号です。法線番号を扱う三つ目の欄は、主に f などの対応する要素で使用します。線の変換処理へ面と同じ三欄の規則をそのまま適用しないようにします。

面の各要素は、スラッシュで複数の番号を組み合わせて記述できます。-3/-3/-1 という要素では、最初の -3 が頂点番号、二つ目の -3 がテクスチャ座標番号、三つ目の -1 が法線番号です。

三つの番号を変換するときは、それぞれ異なる現在件数を使います。頂点番号は、その時点までの v 行数を基準にします。テクスチャ座標番号は vt 行数、法線番号は vn 行数を基準にします。

たとえば、対象の面行までに頂点が100個、テクスチャ座標が80個、法線が20個定義されているとします。要素が -1/-1/-1 であれば、正の番号は 100/80/20 です。

三つとも100に変換してはいけません。テクスチャ座標100番と法線100番が存在しなければ範囲外参照になります。読み込み処理が厳格ならエラーになり、範囲外参照を無視する処理ではテクスチャや陰影が欠落する可能性があります。

頂点番号/テクスチャ座標番号 の形式では、二種類の件数を使います。頂点番号//法線番号 の形式では、中央のテクスチャ座標欄が空です。二つのスラッシュが続く状態を維持し、空欄を0で埋めないようにします。

たとえば、-3//-1 は、負の頂点番号と負の法線番号を参照し、テクスチャ座標を指定していない形式です。変換後も 正の頂点番号//正の法線番号 とします。

これを 正の頂点番号/正の法線番号 に変えると、法線番号がテクスチャ座標番号として解釈されます。スラッシュの数は単なる区切り記号ではなく、各番号の役割を示しています。

法線行である vn の数値自体は変更しません。vn -0.25 0.50 -0.75 の負数はベクトルの方向成分です。負の法線番号ではありません。同様に、vt 行に含まれる負の小数も、テクスチャ座標値としてそのまま保持します。

同一の面行で参照形式が混在していないことも確認します。一つの f 行の中で、1/1/1 と 2//1 のように、一部の頂点だけテクスチャ座標番号を省略する記述は、OBJの標準的な構文では不正です。読み込み側の互換性だけに依存して通過させず、元の出力処理を確認する必要があります。

ただし、負の番号を正に変換する工程で、不足しているテクスチャ座標や法線を推測して追加することは避けます。参照番号の正規化と、メッシュ情報の補修は別の作業です。根拠のない番号を補うと、エラーは消えても表示内容の信頼性が下がります。

変換後は、頂点番号、テクスチャ座標番号、法線番号の最大値と最小値を別々に検査します。頂点番号が1から頂点数の範囲にあるか、テクスチャ座標番号が1からテクスチャ座標数の範囲にあるか、法線番号が1から法線数の範囲にあるかを確認します。

省略欄は検査対象の番号として数えません。1//2 の中央は0番ではなく、テクスチャ座標を指定していない空欄です。

手順5 構文検査と試験アップロードで変換結果を確認する

五つ目の手順は、変換後のOBJを検査し、試験アップロードで結果を確認することです。負の番号が正の番号に変わっていても、処理途中で行が欠けたり、別の番号体系を誤って変換したりしていれば、正常なファイルとはいえません。

最初に、変換前後の総行数を比較します。参照番号だけを変更したのであれば、基本的に行数は同じです。改行形式が変わった場合でも論理的な行数は一致する必要があります。

次に、v、vt、vn、p、l、f の件数を種類ごとに比較します。変換作業で頂点や面を追加、削除する必要はないため、主要要素の件数が変わっていれば、変換処理の不具合を疑います。

変換後の参照行に、負の整数が残っていないかを確認します。ただし、ファイル内のマイナス記号をすべてなくす必要はありません。頂点座標、テクスチャ座標、法線ベクトルには負の値が残ります。

本記事の対象範囲では、検査対象は p、l、f の参照欄です。自由曲線や自由曲面の要素を含む場合は、それらを別途処理したうえで、対応する参照欄も検査対象に加えます。コメントに負の番号の説明が残っている場合は、読み込みに影響しないこともありますが、検査結果と区別できるようにします。

その後、すべての参照番号が有効範囲内にあるかを調べます。0番参照がないか、頂点数を超える番号がないか、テクスチャ座標数や法線数を超える番号がないかを確認します。

面の各要素に含まれる番号の数も確認します。頂点、頂点/テクスチャ座標、頂点//法線、頂点/テクスチャ座標/法線 のいずれかとして一貫して解析できるかを調べます。スラッシュの過不足、同一面内での欄構成の不一致、整数でない参照値があれば構文エラーの原因になります。

構文検査を通過したら、本番データを置き換える前に試験アップロードを行います。変換済みファイルを別名で登録し、元のデータと比較できる状態にします。

アップロードが完了したかだけでなく、表示内容も確認します。負の番号の計算を誤ると、すべて正の整数になっているため構文検査を通過しても、誤った頂点同士が結ばれることがあります。

全体表示では、外形が元の形状と一致しているか、点群やメッシュが異常に広い範囲へ伸びていないかを確認します。局所表示では、面の欠落、長く鋭い三角形、交差面、裏返った面がないかを調べます。

テクスチャを含む場合は、画像が面に正しく対応しているかを確認します。法線を含む場合は、陰影が不自然に反転していないか、面の境界に意図しない段差が出ていないかを見ます。

測量や出来形確認に用いるOBJでは、代表となる頂点の座標も照合します。負の参照番号の変換では、v 行のX、Y、Zを変える必要はありません。変換前後で頂点座標が一致しているかを確認することで、参照番号以外の値を誤って変更していないか判断できます。

アップロード後に位置や縮尺が変わった場合は、負の番号以外の問題も考えます。座標系、単位、原点、軸方向、桁数の丸めなどを切り分けて確認します。

変換結果が正常であることを確認したら、原本、変換済みOBJ、検査結果、アップロード結果をセットで保存します。変換日、使用した規則、異常行の有無も記録すると、同じ形式のOBJを再び処理するときに判断を再現しやすくなります。

負の番号を変換するときに起こりやすい失敗

負の頂点番号の変換では、構文上のエラーを消すことだけに集中すると、形状を壊す危険があります。代表的な失敗を理解しておくと、変換前後の検査項目を決めやすくなります。

一つ目は、マイナス記号だけを削除することです。-1 は最後に定義された頂点を表しますが、単純に 1 へ変えると最初の頂点を参照します。点群の端にある面が原点付近の頂点へ結ばれ、異常に長い面が発生する可能性があります。

二つ目は、ファイル末尾の総頂点数をすべての面に使用することです。面の途中で頂点が追加されるファイルでは、行ごとに現在の頂点数が異なります。前半の面を最終頂点数で計算すると、後半の頂点を誤って参照します。

三つ目は、v、vt、vn を同じ要素数として扱うことです。頂点数、テクスチャ座標数、法線数は一致するとは限りません。複合インデックスでは、それぞれ独立した件数を使います。

四つ目は、負の座標値や法線成分まで変換することです。v、vt、vn 行の負数は、データそのものです。参照番号ではありません。全文に対する一括置換ではなく、行種別と欄の位置を判定する必要があります。

五つ目は、二重スラッシュの空欄を削除することです。1//2 を 1/2 に変えると、法線番号だった2がテクスチャ座標番号として解釈されます。変換時には元の欄構成を保持します。

六つ目は、面の頂点順を並べ替えることです。番号が連続していなくても、記述順には意味があります。昇順へ並べる処理は、面の向きや形状を変える可能性があります。

七つ目は、範囲外の番号を自動的に近い番号へ補正することです。変換結果が0になったから1へ変更する、存在しない番号を直前の番号へ置き換えるといった処理には、正しい参照先を示す根拠がありません。エラー行として記録し、元データを確認します。

八つ目は、アップロード成功だけで変換完了と判断することです。読み込み側が異常な面を無視する場合、エラーを出さずに一部の面を欠落させることがあります。件数、外形、代表座標、テクスチャ、陰影まで確認する必要があります。

九つ目は、変換と同時に頂点削減や面の再構成を行うことです。複数の変更を一度に行うと、問題が起きた際に原因を切り分けられません。負の番号の正規化は、座標や面構成を変えない独立した工程として実施します。

十個目は、すべての参照要素を p、l、f と決めつけることです。点群やポリゴンメッシュではこの三種類が中心ですが、OBJには自由曲線や自由曲面の要素もあります。未知の行を無視して一部だけ変換すると、負の参照が残る可能性があるため、行種別の一覧を先に確認します。

大容量の点群OBJを安全に変換する方法

点群から生成したOBJは、頂点数や面数が多く、ファイル容量が大きくなりやすい特徴があります。ファイル全体を一度に読み込み、すべての文字列をメモリ上で置換する方法では、処理環境によってはメモリ不足や停止が発生します。

負の番号の変換は、ファイルを先頭から一行ずつ読み込む逐次処理に適しています。現在の頂点数、テクスチャ座標数、法線数を保持し、読み込んだ行を判定して、必要な場合だけ変換したうえで別ファイルへ書き出します。

この方法では、全頂点の座標値をメモリに保持する必要はありません。変換に必要なのは、その時点までに定義された各要素の件数だからです。大容量OBJでも、使用するメモリを抑えながら処理できます。

ただし、変換後の検査に必要な情報は記録します。総行数、要素別の行数、変換した参照数、範囲外だった参照数、最大番号、最小番号などを集計すると、処理結果を確認しやすくなります。

異常を検出した場合は、行番号だけでなく、元の行、現在の要素数、変換対象となった番号、計算結果を記録します。「変換できませんでした」という結果だけでは、原因を調べるために巨大なファイルを再度検索しなければなりません。

保存領域にも余裕が必要です。原本と変換済みファイルを同時に保持するため、少なくとも両方を保存できる空き領域を確保します。負の番号が大きな正の番号へ変わると、文字数が増えて変換後の容量が少し大きくなる場合があります。

保存領域が途中で不足すると、変換済みファイルの末尾が欠ける可能性があります。処理が終了したという表示だけでなく、出力ファイルを正常に閉じられたか、末尾まで書き込まれたか、行数が一致するかを確認します。

処理速度を上げるためにファイルを複数範囲へ分割し、同時に変換する方法には注意が必要です。後半の範囲にある負の番号を変換するには、分割位置までに定義された頂点数、テクスチャ座標数、法線数が必要です。

単純に行数で分割すると、各範囲の初期値が分からず、負の番号を誤変換する可能性があります。並列処理する場合は、事前に各分割位置までの累積件数を計算する必要があります。

また、後半の面が前半で定義された頂点を参照している場合、ファイルを別々のOBJとして分割すると参照関係が失われます。今回の目的が負の番号の正規化だけであれば、元の一体構造を保ったまま逐次処理するほうが分かりやすく、安全です。

負の頂点番号によるエラーを再発させない運用

負の頂点番号を一度変換しても、同じ出力条件でOBJを作成し続ければ、次のアップロードでも同様のエラーが起こります。安定した運用にするには、アップロード直前の修正だけでなく、OBJを書き出す工程を見直すことが重要です。

書き出し時に正の絶対番号を使用できる場合は、アップロード先の対応範囲に合わせて設定します。ただし、設定名や出力仕様は処理環境によって異なります。設定画面だけで判断せず、出力されたOBJの参照行を実際に確認します。

エクスポート条件は、拡張子だけでなく、内部構成まで記録します。座標系、単位、頂点色、面、テクスチャ座標、法線、材質情報、相対参照の有無を整理すると、同じOBJでも何が違うのかを比較しやすくなります。

受け渡し前の検査では、負の参照の有無に加えて、0番参照、範囲外参照、頂点数、面数、関連ファイルの有無を確認します。負の番号がなくても、存在しない正の番号を参照していればアップロードエラーになります。

原本と変換済みファイルを明確に分ける運用も必要です。原本を上書きすると、別のアップロード先では負の番号を含む元形式が必要になった場合や、変換規則を変更する場合に戻れません。

変換済みファイルには、参照番号を正規化したことが分かる版情報を付けます。ただし、OBJ内部のオブジェクト名や材質名を不用意に変更すると、関連情報との対応が切れる場合があります。ファイル名と処理記録を中心に管理し、内部記述の変更は必要最小限にします。

複数人が関わる業務では、どの工程で何を変更したかを区別します。負の番号の正規化、座標変換、単位変換、頂点削減、面の再構成、法線再計算を一括して「OBJ修正」と記録すると、後から形状や位置の変化を追跡できません。

負の番号の変換は、原則として座標値、頂点順、面数を変えない処理です。この性質を利用し、変換前後で変わってよい項目と、変わってはいけない項目を定めます。

変わってよいのは、参照欄の負の整数が対応する正の整数になることと、それに伴うファイル容量の小さな変化です。変わってはいけないのは、頂点座標、頂点数、面数、面の頂点順、テクスチャ座標値、法線ベクトルなどです。

取得、点群処理、メッシュ化、OBJ出力、アップロードの担当者が分かれている場合は、どの工程で負の番号が生成されたかを確認します。上流の出力条件を統一できれば、アップロード担当者が毎回変換する必要がなくなります。

アップロード先の読み込み仕様が変わる可能性もあるため、過去に成功した条件だけを固定的に使わず、代表的な小規模データで定期的に確認します。負の番号を正にすれば必ず解決するとは限らず、文字コード、改行、ファイル欠損、範囲外参照、単位、座標系など、別の原因が併存することもあります。

エラーが出たときは、最初に負の番号の有無を確認し、次に参照範囲、要素件数、ファイルの完全性を順番に調べる手順を共有します。確認順序を標準化することで、担当者ごとの経験差を抑え、原因を短時間で切り分けやすくなります。

まとめ

点群OBJの負の頂点番号は、参照行より前に定義された頂点を後ろから数える相対参照です。-1 はその時点で最後に定義された頂点、-2 はその一つ前を表します。負の番号自体は直ちに誤りではありませんが、アップロード先が相対参照に対応していない場合は、頂点番号や面データのエラーとして処理されることがあります。

安全に変換するには、まず原本を複製し、ファイルが末尾まで保存されていることと、変換対象となる参照行を確認します。次に、OBJを先頭から順に読み、v、vt、vn の件数を別々に数えます。

負の頂点番号は、現在の頂点数に負の番号を加え、さらに1を加えて正の番号へ変換します。テクスチャ座標番号と法線番号には、それぞれ現在の vt 件数と vn 件数を使用します。

標準的な線要素の l では、頂点番号と任意のテクスチャ座標番号を扱います。面と同じ法線番号の欄があると仮定して変換しないことが重要です。また、同一の面行で参照欄の構成が混在している場合は、負の番号の変換だけで済ませず、元の出力処理を確認します。

変換後は、負の参照が残っていないか、0番や範囲外の参照がないか、変換前後で頂点数や面数が一致しているかを確認します。そのうえで試験アップロードを行い、全体形状、局所的な面、テクスチャ、陰影、代表座標を比較します。

マイナス記号を削除するだけの修正や、ファイル全体の最終頂点数を一律に使う方法では、エラーが消えても形状を壊す可能性があります。負の番号が現れた行の位置と、その時点までの要素数を基準にすることが重要です。

大容量の点群OBJでは、一行ずつ読み込んで別ファイルへ書き出す逐次処理が適しています。異常が見つかった場合は、行番号、元の参照、現在の要素数、計算結果を記録し、根拠のない補正を行わないようにします。

なお、本記事の5手順は、点群やポリゴンメッシュで一般的な p、l、f を主対象としています。curv、curv2、surf などの自由曲線や自由曲面を含むOBJでは、各要素の構文に対応した処理が別途必要です。

点群取得からOBJの作成、アップロード、共有までを安定させるには、変換作業だけでなく、書き出し条件と検査手順を標準化することが欠かせません。現場で取得した位置情報付きの点群を、その後の確認や共有まで効率よく扱う方法を検討する際は、LRTK Phoneの活用へつなげて考えると、点群データの作成から運用までの流れを整理しやすくなります。

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

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