LRTKレフィクシア株式会社

点群OBJアップロードで頂点・UV・法線の参照ずれを直す5手順

点群OBJアップロードで参照ずれが起きる仕組み

点群から生成したメッシュをOBJ形式でアップロードしたとき、形状は表示されるのにテクスチャだけがずれる、面の明暗が不自然になる、一部の三角形が遠方へ伸びる、特定の面だけ欠けるといった問題が起きることがあります。これらは、OBJファイル内で頂点、UV座標、法線の参照番号が正しく対応していない場合に現れやすい症状です。ただし、巨大座標による数値精度、テクスチャ画像の向き、材質ファイルの参照切れ、非平面多角形の三角形化などでも似た表示になるため、見た目だけで原因を断定しないことが重要です。

OBJはテキスト形式で、三次元座標、テクスチャ座標、頂点法線を別々の配列として記録できます。頂点は一般にv、テクスチャ座標はvt、法線はvnで始まる行に定義され、面はfで始まる行から各配列を参照します。重要なのは、三種類の番号が独立していることです。頂点番号が25であっても、同じ面コーナーが参照するUV番号が40、法線番号が12という構成は仕様上成立します。

たとえば、面の一つのコーナーを25/40/12と記述した場合、25は頂点、40はテクスチャ座標、12は法線の参照番号です。25/25/25のように三つの番号が一致する必要はありません。変換処理や手作業で三種類の配列を同じ番号体系だと思い込み、一括で加算、削除、置換すると、形状、テクスチャ、陰影の対応が崩れます。参照先が存在しない場合や、面行の時点ではまだ定義されていない要素を参照した場合は、読み込みエラー、面の欠落、属性の無視につながる可能性があります。

OBJの正の参照番号は1から始まります。プログラム内部で0始まりの配列を使っている場合、書き出し時に1を加え忘れると、0参照や一つずつずれた参照が発生します。逆に、すでに1始まりへ変換済みの番号へ再度1を加えると、終端側の参照が範囲外になります。番号補正を行うときは、入力が0始まりか1始まりかを推測せず、変換前後の仕様を確認します。

点群OBJという呼び方は実務で使われますが、OBJは一般に点群そのものより、点群から生成した表面メッシュの受け渡しに使われます。点群処理、メッシュ生成、不要要素の削除、UV展開、法線計算、OBJ書き出しという複数工程のどこかで要素を削除または並べ替えると、参照表の更新漏れが最終ファイルへ持ち越されます。そのため、アップロード先だけを疑うのではなく、書き出し前のメッシュ構造までさかのぼって確認する必要があります。

頂点・UV・法線の参照ずれで現れる主な症状

参照ずれは一つの症状だけでは判断しにくいため、形状、テクスチャ、陰影のどこに異常が出ているかを切り分けます。形状そのものが大きく崩れ、離れた位置へ細長い三角形が伸びる場合は、f行の頂点番号が誤っている可能性があります。面が本来とは異なる頂点を結ぶため、座標値が正常でもポリゴンの接続だけが壊れます。ただし、極端に大きな座標値や単位の誤認でも似た表示になるため、座標範囲も併せて確認します。

形状は正しいのに画像だけが別の場所へ貼られる場合は、UV参照を優先して確認します。vtは一般的な画像マッピングでは二つの値で使われますが、OBJの記述としては追加成分を持つ場合もあります。面コーナーが正しいvtを参照していなければ、画像の一部が引き伸ばされる、隣接面と模様がつながらない、同じ領域が繰り返されるといった症状が現れます。画像の上下反転は、画像原点や読み込み側の座標系による場合もあり、参照番号のずれとは分けて扱います。

形状とテクスチャが正しいのに、面ごとに明るさが急変する、凹凸が逆に見える、曲面が角張って見える場合は、法線参照、面の向き、スムージングの扱いを確認します。法線番号が別の方向を参照すると、照明計算が実際の面方向と一致しません。また、頂点の並び順が反転した面と元の法線が混在すると、表裏判定と陰影が食い違うことがあります。

アップロード時に一部の面が消える場合は、参照先が有効範囲を超えている、0が含まれている、斜線の使い方が不正、同じ面内で面コーナーの記述形式がそろっていないといった問題も考えられます。読み込み側が不正な面だけを無視する実装であれば部分欠落として現れ、厳格な実装では最初の不正行で処理が停止することがあります。

問題の見え方はアップロード先の実装にも左右されます。法線がない場合に自動計算する環境もあれば、ファイル内の法線を優先する環境もあります。四角形以上の面を内部で三角形化する方法も一様ではありません。そのため、ある環境では表示できても別の環境では崩れることがあります。公開前には、表示結果だけでなく、面参照を機械的に検査することが安全です。

手順1 OBJと関連ファイルを退避して構造を確認する

最初の手順は、修正対象のOBJと関連ファイルを複製し、元データを変更しない状態で調査を始めることです。参照番号の修正は単純な文字列置換では済まない場合が多く、誤った一括処理を行うと部分的な不具合がファイル全体へ広がります。元ファイル、作業用ファイル、検証済みファイルを分けて保存します。

材質情報が付属する場合は、MTLファイルとテクスチャ画像も同じ単位で退避します。OBJ内のmtllib、usemtl、MTL内の画像参照、実際の画像ファイル名は相互に関係します。ただし、画像が見つからない問題とUV番号のずれは別問題です。関連ファイルがそろっているかを先に確認し、その後にOBJ内部の参照を調べます。

OBJをテキストとして開き、v、vt、vn、fの各行がどのように並んでいるかを確認します。実務でよく見るファイルは、頂点データをまとめて定義してから面を記述します。一方、負の相対参照を使うファイルなどでは、頂点データと要素が区間ごとに並ぶこともあります。いずれの場合も、面の参照は、その面行までに定義された対応配列を基準に解決します。ファイル末尾の総数だけを使って途中の面を判定すると、相対参照や途中定義を誤って評価するおそれがあります。

面の記述形式も確認します。代表的な形式は、頂点だけのf 1 2 3、頂点とUVのf 1/1 2/2 3/3、頂点と法線のf 1//1 2//2 3//3、三種類すべてのf 1/1/1 2/2/2 3/3/3です。二本の斜線を使う形式では中央のUV番号を省略します。1/0/1のように0を入れるのではなく、UVを持たない場合は1//1と記述します。

次に、問題がファイル全体に出ているか、特定区間だけに出ているかを記録します。最初の面から崩れる場合は、開始番号、区切り、読み込み形式の解釈が原因である可能性があります。途中から崩れる場合は、途中で頂点やUVを削除した後に参照表を更新していない、複数データの結合時に加算量を誤った、特定区間だけ別の変換処理を通ったといった原因が考えられます。

可能であれば、同じ元データからテクスチャなし、法線なし、面数を減らした検証用OBJを書き出します。形状だけのファイルが正常なら、頂点参照の基本部分は大きく崩れていないと判断しやすくなります。次にUV、最後に法線を追加し、どの要素を加えた時点で問題が再現するかを特定します。

手順2 頂点・UV・法線の定義数と面参照を照合する

二つ目の手順では、v、vt、vnの定義数を数え、すべてのf行がその時点で有効な参照を持つか確認します。三種類の定義数が異なること自体は異常ではありません。頂点が10,000件、UVが12,000件、法線が8,000件という構成も成立します。

すべての頂点データが面より前にまとめて定義されている一般的な構成なら、正の頂点番号は1から10,000、UV番号は1から12,000、法線番号は1から8,000の範囲で検査できます。ただし、定義と面が途中で交互に現れる場合は、各f行までに登場したv、vt、vnの件数を別々に保持し、その時点の上限で検証します。

たとえば、次の面があるとします。

text f 120/350/80 121/351/81 122/352/82

この行を読むには、面行までに定義済みの頂点120、121、122、UV350、351、352、法線80、81、82がそれぞれ存在するかを確認します。その時点で頂点が500、UVが300、法線が100なら、UVの350以降は無効です。形状用の頂点番号が有効でも、読み込み側によってはテクスチャ参照だけが無視される場合と、面全体が無視される場合があります。

0参照も確認します。OBJの参照番号で0は先頭要素を意味しません。自作変換処理が0始まりの配列番号をそのまま書き出すと、0/0/0や15/0/8が発生します。UVを使わず法線だけを使うなら15//8とし、UVが必要なら対応する正しい正数または有効な負数へ直します。

負の参照番号は、面行の位置から各配列を後ろ向きに数える相対参照です。-1は、その面行より前に最後に定義された対応要素を指します。頂点、UV、法線では定義件数が異なるため、-1/-1/-1であっても三種類が同じ通し番号を意味するわけではありません。正の絶対番号へ変換する場合は、面行までに定義済みの各配列件数を用いて、頂点、UV、法線を独立に計算します。アップロード先の負数対応が不明な場合は、検証済みの正数へ変換する方法が互換性対策になります。

複数のOBJ断片を結合する場合も、加算量を分けます。前半に頂点1,000件、UV1,500件、法線700件があり、後半の面が正の1/1/1から始まるなら、後半側の頂点には1,000、UVには1,500、法線には700を加えます。三種類へ同じ値を加えると、UVと法線がずれます。なお、負の参照を含む断片は、単純な加算ではなく、各面位置でいったん絶対番号へ解決してから結合する方が安全です。

削除処理の後も同様です。不要な頂点を削除すれば、その後ろの頂点番号を新しい対応表へ変換する必要がありますが、UVや法線を削除していないなら、それらの番号まで同じように変更してはいけません。重複頂点の統合や孤立要素の削除では、頂点用、UV用、法線用の新旧対応表を分けて作り、面コーナーごとに適用します。

定義数と参照範囲の照合は、面数が多いほど目視では困難です。検査処理で各f行を分解し、行ごとの定義済み件数、正負インデックスの解決結果、0の有無、範囲外件数、形式の不一致を集計します。問題行の行番号と面番号を記録しておけば、原因となった変換区間を特定しやすくなります。

手順3 面要素の参照形式を統一して不正な行を直す

三つ目の手順は、f行の形式を整理し、同じ面を構成する各コーナーの記述をそろえることです。OBJファイル全体では、頂点だけの面と、UVや法線を含む面が別々に存在する場合があります。しかし、一つのf行の中で属性の有無が混在すると、互換性が下がり、読み込み側によっては不正な面として扱われます。

たとえば、次の行は面コーナーごとに要素数が異なります。

text f 10/20/5 11/21 12/22/6

一つ目と三つ目は頂点、UV、法線を参照していますが、二つ目には法線がありません。法線を使うなら三つすべてへ有効な法線番号を設定し、使わないなら面全体をv/vt形式へ統一します。欠けた法線番号を推測で補うのではなく、元メッシュから対応を確認するか、面の向きを整えた後で法線を再生成します。

UVを持たず法線だけを持つ面は、中央を空欄にして10//5と記述します。10/ /5のように空白を挟んだり、10/0/5のように0を入れたりすると、正しい省略形式になりません。斜線の前後へ全角空白や制御文字が混ざる場合も解析を妨げるため、ASCIIの斜線と通常の区切り空白へ統一します。

四角形以上の面はOBJで表現できますが、アップロード先が内部で三角形化することがあります。頂点が非平面に近い多角形、凹多角形、自己交差する多角形では、分割結果が環境によって変わり、参照ずれに似た形状崩れが出ることがあります。互換性を優先する場合は、書き出し前に意図した方法で三角形化し、各三角形の頂点、UV、法線の対応を確定させます。

頂点の並び順にも注意します。面のコーナー順を途中で反転すると、幾何学的な面法線の向きが変わります。ファイル内のvnが元の向きのまま残ると、頂点順から求めた表裏と法線方向が矛盾します。参照番号だけを直して陰影が改善しない場合は、コーナー順、面の表裏、法線方向を一組として確認します。

oやg、usemtlなどの行は、通常、v、vt、vnの配列番号を1へ戻す命令ではありません。一つのOBJファイル内では各配列の番号は全体で管理されます。新しいオブジェクトやグループが始まったからといって正の参照を1から再開すると、ファイル先頭側の要素を誤参照します。オブジェクトごとに番号を1から始めたい場合は、別ファイルへ分けるか、結合時に正しく番号を変換します。

不正行を修正するときは、一度に多くの処理を重ねないことも重要です。UVだけが範囲外なら、まずUV参照だけを直して検証します。構文統一、範囲外参照の修正、三角形化、面反転、法線再計算を同時に行うと、どの操作で改善または悪化したか分かりません。処理単位ごとに別ファイルと差分を残します。

手順4 頂点の並びとUV・法線を再生成して対応を整える

四つ目の手順では、番号の修正だけで整合しない場合に、メッシュ構造を基準としてUVと法線を再生成します。参照ずれが広範囲に及び、新旧番号の対応表が失われている場合、壊れた番号を推測して直すより、正しい形状から属性を作り直した方が再現性を確保しやすくなります。

まず、頂点と面だけで形状が正常かを確認します。UVと法線を一時的に除いた検証用データで、面の接続、穴、重なり、極端に細長い三角形、表裏の混在を確認します。形状自体が崩れているなら、UVや法線を再生成しても直りません。頂点参照と面構造を先に確定します。

形状が正常であれば、必要に応じてUVを再展開します。UV展開では、三次元表面を二次元画像へ対応付け直すため、島の配置や切れ目が変わることがあります。既存のテクスチャ画像をそのまま使うには元UVとの対応が必要です。対応情報が失われている場合、新しいUVだけを作っても既存画像とは一致しないため、元画像から新UVへ焼き直す処理や、新しいテクスチャ生成が必要です。

UVの境界では、同じ三次元頂点を複数のvtが参照することがあります。硬い稜線では、同じ位置の頂点に複数のvnを割り当てることもあります。これはOBJの別インデックス構造で正しく表現できます。したがって、頂点数とUV数、法線数が一致しないことは異常ではありません。重複座標を統合するときは、面コーナーが持つv/vt/vnの組み合わせを保持し、UV境界や法線境界を消さないようにします。

法線は、面ごとに分ける場合と、複数面で共有する場合があります。平面や角をくっきり見せたい部分では、同じ位置でも異なる法線を使うことがあります。曲面を滑らかに見せたい部分では、隣接面の向きを基にした法線を共有させます。すべてを単純平均すると本来の角が丸く見え、すべてを面法線へ分けると曲面が角張って見えます。スムージング境界を保つ条件を決めて再計算します。

法線を再計算する前には、面の向きをそろえます。表裏が混在した状態で隣接面から法線を求めると、期待しない方向になることがあります。閉じた形状では外向き、地表や構造物の片面メッシュでは想定する表示側へ向けます。開いたメッシュでは自動判定が難しい部分もあるため、重要箇所は目視で確認します。

OBJのvnは必ずしも単位長でなければならないわけではありません。そのため、単に長さが1ではないという理由だけで不正と断定しないようにします。ただし、ゼロベクトル、極端に小さい値、数値として解釈できない値は、陰影計算で問題になる可能性があります。書き出し側で正規化する運用を採用する場合は、ゼロ長を除外してから一貫した処理を行います。

内部形式が位置、UV、法線を一つのインデックスでしか持てない場合は、v/vt/vnの組み合わせごとに頂点を展開する実装があります。一方、OBJ自体は三種類の別インデックスを持てるため、OBJへ書き出すためだけに位置頂点を必ず複製する必要はありません。変換先と変換元のデータモデルを確認し、必要な場合だけ展開します。

再生成後は、v、vt、vn、fを同じ確定データから一括で書き出します。古いOBJの面行を残して、新しいUVや法線定義だけを差し替えると、番号対応を再び壊す原因になります。形状、UV、法線の組み合わせが確定した時点で、一つの書き出し処理から生成したファイルへ統一します。

手順5 最小構成で再書き出しして段階的にアップロードする

五つ目の手順は、修正済みデータを最小構成から段階的にアップロードし、どの要素まで正常に処理できるかを確認することです。完成版だけを繰り返し試すと、形状、UV、法線、材質、画像のどこに問題が残っているか判断しにくくなります。

最初は頂点と三角形面だけのOBJを用意します。ここで形状、位置、縮尺、向き、面の欠落を確認します。形状が崩れるなら、頂点番号、面のコーナー順、重複や範囲外参照が残っている可能性があります。形状が正常なら、頂点参照の基本部分は修正できていると判断しやすくなります。

次に、vtとUV参照を追加し、確認用の格子画像または本来のテクスチャで表示を確認します。模様の連続性、継ぎ目、上下左右の向き、面ごとの引き伸ばしを見ます。ここで崩れる場合は、UV参照、画像原点、材質と画像の関連付けを切り分けます。UV値は用途によって0から1の外側を取ることもあるため、範囲外という言葉だけで不正と決めず、アップロード先の繰り返しやクランプの扱いも確認します。

最後に法線を追加します。照明方向を変えながら、表裏、陰影の連続性、角の見え方を確認します。法線追加後に面が消える場合は、法線番号の範囲外、0参照、面コーナー形式の不一致を疑います。面は残るが陰影がおかしい場合は、法線方向、ゼロまたは極端に小さい法線、頂点順との矛盾、スムージング境界を確認します。

大規模データでは、全体の前に問題箇所を含む小さなOBJで検証します。切り出し時には、使用する頂点、UV、法線を抽出し、面コーナーの対応を保ったまま番号を振り直します。元ファイルの番号を残して定義だけ減らすと、新たな範囲外参照が発生します。負の参照を残す場合も、切り出し後の行位置で意味が変わらないか確認します。

再書き出しでは、文字コード、改行、数値表記も安定した形式へそろえます。座標値とUV値は小数点を用いた一貫した表記にし、面番号には整数だけを使います。不要な制御文字、全角の区切り、地域設定に依存した小数点以外の記号が混じらないようにします。コメントは#から始め、独自の説明文字列を命令行として挿入しないようにします。

アップロード後に正常に見えたファイルは、検証済み版として固定します。形状のみ、UV追加、法線追加、材質追加という段階で保存しておけば、再発時にも問題の境界を短時間で特定できます。検証途中のファイルを同じ名前で上書きし続ける運用は避けます。

修正後に確認したい表示とデータの整合性

参照ずれが直ったように見えても、公開前には複数の観点で整合性を確認します。最初に面数を確認し、修正前後で意図せず面が減っていないか、三角形化によって想定どおり増えているかを調べます。不正面を削除して表示だけ整えた場合、必要な部位が欠けたままになっている可能性があります。

次に、全体形状と局所形状を確認します。位置や縮尺が正しくても、細部で面が交差する、穴が開く、隣接面が離れることがあります。点群由来のメッシュは微細な三角形が多く、遠景では異常が見えにくいため、境界、薄い部材、急な段差、穴の周辺を拡大します。

テクスチャは、文字、境界線、角、色の切り替わりなど、対応を判断しやすい箇所で照合します。単色に近い面では誤ったUVでも見た目で分からないことがあります。複数箇所を確認し、必要であれば番号付きの格子画像を一時的に使います。

法線は、照明方向を変えたときの見え方で確認します。片面表示では裏向き面が消えるため表裏の混在を発見しやすい一方、両面表示では誤りが隠れることがあります。表示できることと、面の向きや法線が整合していることは同じではありません。

さらに、OBJ内の参照を再検査します。正の番号が面行時点の定義済み件数を超えていないか、0がないか、負数が各配列で正しく解決できるか、同じ面内の形式がそろっているかを確認します。見た目が正常でも、未使用区間や別環境で問題になる記述が残っていることがあります。

参照ずれを再発させない書き出しと受け渡しのルール

参照ずれは、修正方法だけでなく再発防止の運用が重要です。最も効果的なのは、頂点、UV、法線の番号管理を一つの書き出し工程へ集約することです。複数の担当者や処理が同じOBJを順番に直接編集すると、どの工程で番号が変わったか追跡しにくくなります。

変換処理では、元データの要素を削除、統合、並べ替えするたびに、新旧番号の対応表を作ります。頂点用、UV用、法線用の対応表は分けて保持します。面を書き出す時点で三種類を面コーナーごとに適用し、面行までに存在しない要素、0、解決不能な負数を参照していないか検証します。

複数データを結合する場合は、単純なテキスト連結を避けます。各OBJを構造として読み込み、正負の参照を解決し、頂点、UV、法線の累計数に応じて新しい番号へ変換してからまとめます。材質名やオブジェクト名が重複する場合もあるため、必要に応じて一意な名前へ整理します。ただし、名称変更と番号変換は別の処理として記録します。

書き出し条件も固定します。面を三角形化するか、法線を出力するか、UVがない面を許容するか、負の参照を使用するか、複数オブジェクトを一ファイルへまとめるかをルール化します。担当者ごとに設定が異なると、同じ元データでも異なる構造のOBJが生成されます。アップロード先の仕様が不明な場合は、三角形面、正の参照、面内で統一した記述という互換性を重視した構成で検証します。

ファイルの受け渡しでは、OBJだけでなく、MTL、テクスチャ画像、書き出し条件、座標系、単位、作成日、元データの版を同じ単位で管理します。参照ずれと直接関係しない情報もありますが、表示不具合を切り分けるために役立ちます。同名ファイルの上書きで履歴を失わないよう、版番号や作成日時を管理します。

自動検査を導入できる場合は、アップロード前に実行します。検査項目には、面行時点の各定義数、正負参照の解決結果、0参照、面内形式の不一致、三頂点未満の面、同じ頂点を重複参照する面、数値として解釈できない行、ゼロ長に近い法線などを含めます。合否だけでなく問題行と理由を出力すると、修正作業を標準化できます。

点群OBJアップロード前の実務チェック

実務では、参照番号だけを確認してもアップロード後の品質を保証できません。元の点群からメッシュ化した段階で、不要な孤立面、極端なノイズ、自己交差、非常に細い三角形が残っていないかを確認します。形状編集をOBJ書き出し後に行うと参照更新が必要になるため、可能な限り形状を確定してからUV展開と法線計算を行い、最後にOBJを書き出します。

座標値が大きいデータでは、表示側の数値精度や原点処理によって形状が揺らぐことがあります。これは参照番号のずれとは別問題です。細長い面が見えたときは、面番号だけでなく、座標の桁、単位、原点からの距離も確認します。複数原因が同時に存在すれば、参照を修正しても見た目が完全には直らない場合があります。

ファイル容量が大きい場合は、検証用に範囲を分割します。ただし、分割処理が新たな参照ずれを生まないよう、使用要素の抽出、正負参照の解決、番号の振り直しを一体で行います。面行だけを抜き出しても参照先が不足し、すべての定義を残したままでは容量削減効果が小さくなります。

アップロード先の対応条件も事前に確認します。OBJの基本構造を扱えても、負の参照、多角形面、複数材質、自由曲面、非常に長い行などの対応範囲は異なります。特定環境だけで使える拡張記述を避け、頂点、UV、法線、三角形面を明確に記録した構成へ寄せると、環境差による不具合を減らせます。

検証時には、修正前後の画面だけでなく、ファイル構造の差分も残します。どの参照を変更したか、UVを再生成したか、法線を再計算したか、三角形化を行ったかを記録します。これにより、同じ元データを再処理するときに手順を再現しやすくなります。

公開用データは検証用データと分けて管理します。検証中に使用した格子画像、法線なしのOBJ、部分切り出しファイルを誤って公開しないよう、保存場所と命名ルールを分けます。最終版には、検査を通過したOBJと必要な関連ファイルだけをまとめ、アップロード後の表示まで確認して完了とします。

まとめ

点群OBJアップロードで頂点、UV、法線の参照がずれる問題は、三種類の番号を同じ配列として扱うこと、0始まりと1始まりを混同すること、要素の削除や結合後に面参照を更新しないこと、面内の記述形式が不統一であることなどから発生します。形状が崩れる場合は頂点参照、画像がずれる場合はUV参照、陰影や表裏がおかしい場合は法線参照を優先して確認します。

修正は、元ファイルと関連データを退避し、各面行までの定義数を基準に正負の参照を照合し、f行の形式を統一し、必要に応じてUVと法線を再生成し、最小構成から段階的にアップロードする順で進めます。広範囲に参照が壊れている場合は、番号を推測して直すより、正常なメッシュを基準に属性を作り直して一括で再書き出す方が安全です。

再発防止には、頂点、UV、法線の対応表を別々に管理し、書き出し時に0参照、範囲外参照、解決不能な負数、面内形式の不一致を自動検査する運用が有効です。点群からメッシュ、テクスチャ、OBJアップロードまでの工程を標準化すれば、担当者や処理環境が変わっても品質を保ちやすくなります。

現場で取得する三次元データと位置情報の管理を効率化し、後工程で扱いやすいデータ作成につなげたい場合は、LRTK Phoneの活用も検討してください。

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

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