如何使用Fortran从* .obj文件读取面部信息

问题描述 投票:-2回答:1

问题

现代Fortran如何以* .obj格式导航条目之间带有双斜杠的文件?目标是提取顶点索引(第一项),而忽略顶点法线索引(第二项)。

示例

例如,对于此摘录,

f 297//763 298//763 296//763
f 296//764 298//764 295//764
f 384//765 385//765 382//765
f 384//766 382//766 383//766

目标是创建一个像这样的数组:

face ( 1 ) = [297, 298, 296]
face ( 2 ) = [296, 298, 295]
face ( 3 ) = [384, 385, 382]
face ( 4 ) = [384, 382, 383]

为要采用更丰富的格式的答案加分,例如

f a//b//c  d//e//f g//h//i j//k//l

其他帖子

[How to get Wavefront .obj file with 3 faces (traingle)的答案指向已删除的博客。这篇文章[How to read numeric data from a string in FORTRAN不相关。

参考

*。obj格式的三个参考:Object Files (.obj)B1. Object Files (.obj)Wavefront .obj file

io fortran special-characters gfortran cad
1个回答
1
投票

如注释中所建议,我们可以使用/等用空格替换sed。我们也可以在Fortran中一一扫描每个字符(请参见下文)。然后,我们将所有整数读入vals,然后选择所需的部分作为vals( 1:6:2 )。通过将1:6:2更改为1:12:3等,可以对f a//b//c d//e//f ...使用类似的方法。

[test.f90]
program main
    implicit none
    character(100) buf
    integer vals(10), ios, i

    open(10, file="test.dat", status="old")
    do
        read(10, "(a)", iostat=ios) buf
        if (ios /= 0) exit

        do i = 1, len(buf)
            if (buf(i:i) == "/") buf(i:i) = " "   !! replace "/" by " "
        enddo

        read(buf(2:), *) vals( 1:6 )  !! read all items
        print *, vals( 1:6:2 )  !! select items 1, 3, 5
    enddo
    close(10)
end

[test.dat]
f 297//763 298//763 296//763
f 296//764 298//764 295//764
f 384//765 385//765 382//765
f 384//766 382//766 383//766

$ gfortran test.f90 && ./a.out
     297         298         296
     296         298         295
     384         385         382
     384         382         383

只是为了好玩,这是Python中的类似代码,由于replace()split()而缩短了代码。如果我们有一些类似的例程,我想上面的代码也可能会变得更短。

dat = []
for line in open("test.dat").readlines():
    dat.append( line[1:] .replace("/", " ") .split() [::2] )

import numpy as np
face = np.array(dat, dtype=int)
print(face)

$ python test.py
[[297 298 296]
 [296 298 295]
 [384 385 382]
 [384 382 383]]
© www.soinside.com 2019 - 2024. All rights reserved.