GerritGroot
Technical User
Hi all,
I've got a problem reading a binary file in Fortran90.
In essence, it may be solved if someone knows how to add
two 2 byte numbers to make a 4 byte one. This would also prevent me
from having to open and close the file again and again.
My compiler doesn't support FORM='BINARY' so I can't use that
The file (extension *.stl) contains triangular surface elements and
their normals. It has the following structure:
# of bytes description
80 Any text such as the creator's name
4 int equal to the number of facets in file
4 float normal x ! FACET 1
4 float normal y
4 float normal z
4 float vertex1 x
4 float vertex1 y
4 float vertex1 z
4 float vertex2 x
4 float vertex2 y
4 float vertex2 z
4 float vertex3 x
4 float vertex3 y
4 float vertex3 z
2 unused (padding to make 50-bytes) ! HERE'S ACTUALLY THE PROBLEM
4 float normal x ! FACET 2
4 float normal y
4 float normal z
4 float vertex1 x
4 float vertex1 y
4 float vertex1 z
4 float vertex2 x
4 float vertex2 y
4 float vertex2 z
4 float vertex3 x
4 float vertex3 y
4 float vertex3 z
2 unused (padding to make 50-bytes)
4 float normal x ! FACET 3
AND SO ON...
I tried something like this:
There must be a better way to do this, without having to open and close the file
again and again and without having to use REC=34.5 which obviously is never going to work.
Thanks in advance,
Gerrit
I've got a problem reading a binary file in Fortran90.
In essence, it may be solved if someone knows how to add
two 2 byte numbers to make a 4 byte one. This would also prevent me
from having to open and close the file again and again.
My compiler doesn't support FORM='BINARY' so I can't use that
The file (extension *.stl) contains triangular surface elements and
their normals. It has the following structure:
# of bytes description
80 Any text such as the creator's name
4 int equal to the number of facets in file
4 float normal x ! FACET 1
4 float normal y
4 float normal z
4 float vertex1 x
4 float vertex1 y
4 float vertex1 z
4 float vertex2 x
4 float vertex2 y
4 float vertex2 z
4 float vertex3 x
4 float vertex3 y
4 float vertex3 z
2 unused (padding to make 50-bytes) ! HERE'S ACTUALLY THE PROBLEM
4 float normal x ! FACET 2
4 float normal y
4 float normal z
4 float vertex1 x
4 float vertex1 y
4 float vertex1 z
4 float vertex2 x
4 float vertex2 y
4 float vertex2 z
4 float vertex3 x
4 float vertex3 y
4 float vertex3 z
2 unused (padding to make 50-bytes)
4 float normal x ! FACET 3
AND SO ON...
I tried something like this:
Code:
PROGRAM HowToDoThis
IMPLICIT NONE
! An included file defines:
INTEGER, PARAMETER :: I1B=SELECTED_INT_KIND(2)
INTEGER, PARAMETER :: I2B=SELECTED_INT_KIND(4)
INTEGER, PARAMETER :: I4B=SELECTED_INT_KIND(9)
INTEGER, PARAMETER :: I8B=SELECTED_INT_KIND(18)
INTEGER, PARAMETER :: R1B=SELECTED_REAL_KIND(r=2)
INTEGER, PARAMETER :: R2B=SELECTED_REAL_KIND(r=4)
INTEGER, PARAMETER :: R4B=SELECTED_REAL_KIND(r=9)
INTEGER, PARAMETER :: R8B=SELECTED_REAL_KIND(r=18)
! Next, I define:
CHARACTER(LEN=80) :: header
INTEGER(KIND=I4B) :: ntri
INTEGER(KIND=I2B) :: padding
REAL(KIND=R4B), DIMENSION(3) :: n,x1,x2,x3
OPEN(UNIT=1,FILE='input.stl',STATUS='OLD',ACCESS='DIRECT',FORM='UNFORMATTED',RECL=80)
READ(1,REC=1)header
CLOSE(1,STATUS='KEEP')
! So far it works fine, but then...
OPEN(UNIT=1,FILE='input.stl',STATUS='OLD',ACCESS='DIRECT',FORM='UNFORMATTED',RECL=4)
! I start with 21, supposing I have to pass 80 bytes from the header, so 20*4 bytes
READ(1,REC=21)ntri
CLOSE(1,STATUS='KEEP')
OPEN(UNIT=1,FILE='input.stl',STATUS='OLD',ACCESS='DIRECT',FORM='UNFORMATTED',RECL=4)
! In fact, the program already breaks down here, although I don't know why
READ(1,REC=22)( n(i),i=1,3,1)
READ(1,REC=25)(x1(i),i=1,3,1)
READ(1,REC=28)(x2(i),i=1,3,1)
READ(1,REC=31)(x2(i),i=1,3,1)
CLOSE(1,STATUS='KEEP')
! Then I'll read the two byte integer
OPEN(UNIT=1,FILE='input.stl',STATUS='OLD',ACCESS='DIRECT',FORM='UNFORMATTED',RECL=2)
READ(1,REC=67)padding
CLOSE(1,STATUS='KEEP')
! (Here I'll write some stuff to an ascii file so n,x1,x2 and x3 are not lost but converted to another format)
! And... ...even though the above doesn't work yet, supposing it will, my problem will
! come here, when I read the second triangular element.
OPEN(UNIT=1,FILE='input.stl',STATUS='OLD',ACCESS='DIRECT',FORM='UNFORMATTED',RECL=4)
READ(1,REC=34.5)( n(i),i=1,3,1)
!...ETC
CLOSE(1,STATUS='KEEP')
END PROGRAM HowToDoThis
There must be a better way to do this, without having to open and close the file
again and again and without having to use REC=34.5 which obviously is never going to work.
Thanks in advance,
Gerrit