2

我正在尝试在 Fortran 90 中编写一个 STL 二进制文件。该文件具有以下格式

HEADER:一个 80 字节的 ASCII 标头 - TITLE

一个 4 字节的无符号长整数,NO。刻面

每个方面的格式:

法线向量,3 个浮点值,每个 4 字节;

顶点 1 个 XYZ 坐标,3 个浮点值,每个 4 字节;

顶点2个XYZ坐标,3个浮点值,每个4字节;

顶点 3 个 XYZ 坐标,3 个浮点值,每个 4 字节;

一个 2 字节的无符号整数,应该为零;

我正在尝试创建一个未格式化的文件来写入相关信息,但在定义正确的记录长度时遇到了麻烦。假设我有N个方面,我使用以下命令打开并写入信息

open(unit = 1, status = 'replace', iostat = ioerror, format = 'unformatted', access = 'direct', recl = 84 + N * 50, file = 'c:\temp\test.stl')

我可以发出第一个写语句来写出标题信息,然后发出第二个写语句(在 do 循环内)来写出方面信息吗?

如果是这样,每个写入语句我需要的记录号是多少,因为我有不同记录长度的标题和方面信息。

write(1,rec=?), *header information*
do,i=1,N,1
   write(1,rec=?), *facet information*
enddo
4

1 回答 1

2

那很有趣。我已经编写了一个小程序,该程序使用STREAM访问创建了一个非常简单的金字塔。它似乎工作:

program write_stl
    use ISO_FORTRAN_ENV
    implicit none
    integer, parameter :: u = 400
    character(len=*), parameter :: fname = 'pyramid.stl'
    integer :: ios
    integer(kind=4) :: num_facets
    character(len=80) :: title
    real(kind=4), dimension(3) :: top_vertex, front_vertex, left_vertex, right_vertex

    top_vertex = (/0.0, 0.0, 2.0/)
    front_vertex = (/0.0, -1.0, 0.0/)
    left_vertex = (/-1.0, 1.0, 0.0/)
    right_vertex = (/1.0, 1.0, 0.0/)

    open(unit=u, file=fname, access='stream', status='replace', &
        action='write', iostat=ios)
    call check(ios, 'open')

    title = "Testpyramid"
    write(u, iostat=ios) title
    call check(ios, 'write title')
    num_facets = 4
    write(u, iostat=ios) num_facets
    call check(ios, 'write number of facets')
    ! bottom facet
    call write_facet(u, front_vertex, left_vertex, right_vertex)
    call write_facet(u, top_vertex, right_vertex, left_vertex)
    call write_facet(u, top_vertex, left_vertex, front_vertex)
    call write_facet(u, top_vertex, front_vertex, right_vertex)

    close(u, iostat=ios)
    call check(ios, 'close')

contains

    subroutine check(ios, operation)
        implicit none
        integer, intent(in) :: ios
        character(len=*), intent(in) :: operation
        if (ios == 0) return
        write(*, '(A, I0, 2A)') "Encountered error ", ios, " while performing ", operation
        stop 1
    end subroutine check

    subroutine write_facet(u, vertex1, vertex2, vertex3)
        implicit none
        integer, intent(in) :: u
        real(kind=4), dimension(3), intent(in) :: vertex1, vertex2, vertex3
        real(kind=4), dimension(3) :: normal
        integer(kind=2), parameter :: zero = 0

        normal = calc_normal(vertex1, vertex2, vertex3)
        write(u, iostat=ios) normal
        call check(ios, 'write normal')
        write(u, iostat=ios) vertex1
        call check(ios, 'write vertex')
        write(u, iostat=ios) vertex2
        call check(ios, 'write vertex')
        write(u, iostat=ios) vertex3
        call check(ios, 'write vertex')
        write(u, iostat=ios) zero
        call check(ios, 'write zero')
    end subroutine write_facet

    function calc_normal(vec1, vec2, vec3)
        implicit none
        real(kind=4), dimension(3), intent(in) :: vec1, vec2, vec3
        real(kind=4), dimension(3) :: calc_normal
        real(kind=4), dimension(3) :: d1, d2
        d1 = vec2 - vec1
        d2 = vec3 - vec1
        calc_normal(1) = d1(2) * d2(3) - d1(3) * d2(2)
        calc_normal(2) = d1(3) * d2(1) - d1(1) * d2(3)
        calc_normal(3) = d1(1) * d2(2) - d1(2) * d2(1)
        calc_normal = calc_normal / norm(calc_normal)
    end function calc_normal

    function norm(vec)
        implicit none
        real(kind=4), dimension(3), intent(in) :: vec
        real(kind=4) :: norm

        norm = sqrt(vec(1)**2 + vec(2)**2 + vec(3)**2)
    end function norm

end program write_stl
于 2015-12-08T05:18:32.850 回答