导入偏移量较大的 obj 文件

问题描述

我有一系列 obj 文件,这些文件是由我的专门处理 GIS(地理信息系统)数据的同事通过摄影测量生成的。文件中的前几个数据点类似于:

v 445077.679 4460688.700 61.371 
v 445077.340 4460686.317 61.367 
v 445077.296 4460686.024 61.416 

我相信该文件是有效的,因为我可以在在线查看器中打开这些文件,并且在 http://masc.cs.gmu.edu/wiki/ObjViewer 处使用查看器可以获得我期望看到的内容

Online view using http://masc.cs.gmu.edu/wiki/ObjViewer

当我在 Blender、Unity 或 Unreal Engine 中打开同一个文件时,对象离世界原点很远。我可以通过将原点移动到质心然后重置对象位置来将其居中,但是当我重新调整对象时,我总是看到如下所示的内容

Image from Blender

我做错了什么,或者我的文件有什么问题?

解决方法

这些文件出现问题的原因是大偏移量与 32 位浮点值相结合。在这种情况下,对象都使用相同的地理起源,可能在 0.000N/0.000E 的纬度/经度处

几乎所有的 3D 图形程序都使用 32 位浮点值来存储每个点的位置,而偏移量和 32 位值的组合会导致部分精度丢失。 32 位浮点数的精度约为 7 位十进制数字,因此示例文件中的偏移量 4460688 完全占主导地位,有效地将模型从 1mm 分辨率数据削减到 1m 分辨率数据。长三角形的原因是由于偏移量的不对称,在一个方向上丢失的数据较多。

解决方案是在使用 3D 软件导入对象之前应用一些偏移使对象靠近原点。 我写了一个快速的 python 脚本来帮助解决这个问题:https://gitlab.umich.edu/lsa-ts-rsp/xr-shiftOBJ/-/blob/main/shiftOBJ.py

import re  # regex


def shiftFile(inFileName,outFileName,offset):
    with open(inFileName) as myInFile:
        with open(outFileName,'w') as myOutFile:
            for line in myInFile:
                myOutFile.write(shiftLine(line,offset))


def shiftLine(inLine,offset):
    #if a line is a vertex then apply the shift and drop vertex colors
    lineRegex = re.compile('v (\d+\.\d+) (\d+\.\d+) (\d+\.\d+)')
    m = lineRegex.match(inLine)
    if m and len(m.groups()) >= 3:
        outLine = 'v ' + "{:.3f}".format(float(m.groups()[0]) + offset[0]) + ' ' + "{:.3f}".format(float(m.groups()[1]) + offset[1]) + ' ' + "{:.3f}".format(float(m.groups()[2]) + offset[2]) + '\n'
        return outLine
    else:
        return inLine


if __name__ == '__main__':
    inFile = '/Users/crstock/Documents/Unreal Projects/Olynthos Data/B88DW18.obj'
    outFile = '/Users/crstock/Documents/Unreal Projects/Olynthos Data/B88DW18_shifted.obj'
    offset = [-445070,-4460680,-59.0]
    shiftFile(inFile,outFile,offset)

这会对所有顶点线应用偏移量,而让其他线单独存在。通过对多个输入文件使用相同的偏移值,您可以保持相对偏移,以便相关对象适当地组合在一起。