C
C Program SRFWRL to convert triangulated or polygonated surface into
C Virtual Reality Modeling Language
C
C Version: 5.40
C Date: 2000, February 11
C
C Coded by: Ludek Klimes
C Department of Geophysics, Charles University Prague,
C Ke Karlovu 3, 121 16 Praha 2, Czech Republic,
C E-mail: klimes@seis.karlov.mff.cuni.cz
C
C References:
C
C VRML (Virtual Reality Modeling Language) version 1.0C
C
C VRML97 (Virtual Reality Modeling Language ISO/IEC 14772)
C
C GOCAD
C
C Persistence of Vision scene description language, version 3.1
C
C.......................................................................
C
C Description of data files:
C
C Input data read from the standard input device (*):
C The data are read by the list directed input (free format) and
C consist of a single string 'SEP':
C 'SEP'...String in apostrophes containing the name of the input
C SEP parameter or history file with the input data.
C No default, 'SEP' must be specified and cannot be blank.
C
C
C Input data file 'SEP':
C File 'SEP' has the form of the SEP
C parameter file. The parameters, which do not differ from their
C defaults, need not be specified in file 'SEP'.
C Data specifying input files:
C VRTX='string'... Name of the file with vertices of the polygons.
C Description of file VRTX
C Default: VRTX='vrtx.out'
C TRGL='string'... Name of the file describing the triangles or
C polygons. Triangles are recommended (and obligatory if
C VRML='GOCAD').
C Description of file TRGL
C Default: TRGL='trgl.out'
C COLORS='string'... Name of the file containing the data describing
C the colour map.
C Description of file COLORS
C Not used if VRML='GOCAD'.
C Default: COLORS='hsv.dat'
C Input/output file:
C WRL='string'... Name of the file to be supplemented with surfaces
C or to be copied to the beginning of the output file.
C If the filename is blank, output file starts from a
C scratch (mostly not reasonable).
C The default name of the output file is equal to WRL.
C It is recommended to specify WRL rather than to use
C the default name.
C Default: WRL='out.wrl'
C WRLOUT='string'... Name of the output file if different from WRL.
C Default: WRLOUT=WRL
C Data specifying the form of the output file:
C VRML='string'... Virtual reality scene description language.
C VRML='VRML1': VRML (Virtual Reality Modeling Language)
C version 1.0.
C VRML='VRML2': VRML97 according to ISO/IEC 14772 standard.
C VRML='GOCAD': GOCAD description of surfaces (TSurf).
C VRML='POV': POV (Persistence Of Vision) scene
C description language, version 3.1.
C Default: VRML='VRML2' (recommended)
C NAME='string'... String containing the GOCAD name of the surface.
C Used only if VRML='GOCAD'. Obligatory parameter, must be
C specified and cannot be blank if VRML='GOCAD'.
C Data specifying the values to be scaled in colours:
C KOLPOS=integer... If zero, all surfaces will have the same colour
C given by parameters R, G, B. If positive, the values in
C KOLPOS-th column of input file VRTX will be colour-coded
C at each vertex on the positive side of each triangle or
C polygon of the surface.
C Not used if VRML='GOCAD'.
C Default: KOLPOS=7
C KOLNEG=integer... If zero, all surfaces will have the same colour
C given by parameters R, G, B. If positive, the values in
C KOLNEG-th column of input file VRTX will be colour-coded
C at each vertex on the negative side of each triangle or
C polygon of the surface.
C Not used if VRML='GOCAD'.
C Default: KOLNEG=7
C PROPERTIES='string'... String containing names of properties
C corresponding to values Z1,Z2,Z3,V1,...,VN (see file
C VRTX) which may be used to control the
C colour of the surface. If the number of names is smaller
C than the number of values, the leftmost values are
C considered. If PROPERTIES=' ', no values are considered
C and GOCAD atom VRTX is used for the vertices (otherwise,
C GOCAD atom PVRTX is used).
C Used only if VRML='GOCAD'.
C Default: PROPERTIES=' '
C Data specifying the colour scale (not used if VRML='GOCAD'):
C VADD=real, VMUL=real, VPER=real, VREF=real, CREF=real, CREF1=real,
C CREF2=real, CREF3=real, etc... Refer to file
C colors.for.
C R=real, G=real, B=real... Float numbers between 0 and 1 specifying
C the colour of the surfaces if KOLPOS=0 or
C KOLNEG=0.
C Defaults: R=1, G=1, B=1 (white)
C TRANSP=real... Transparency of the surfaces (sometimes called
C transmit). Values from 0 to 1.
C Default: TRANSP=0.
C AMBIENT=real... Float number between 0 and 1 specifying the
C intensity of the ambient light. The colour of the ambient
C light is assumed white. Applied to the surfaces only if
C VRML='vrml1'. Otherwise, the ambient light source of
C intensity AMBIENT is prescribed by program
C iniwrl.for.
C Default: AMBIENT=0.20 (default for VRML materials)
C SPECULAR=real... Intensity of the specular reflections from
C glossy surfaces. Values from 0 to 1.
C Default: SPECULAR=0 (default for VRML materials)
C SHININESS=real... Shininess of the surfaces (sometimes called
C transmit). Values from 0 to 1.
C Default: SHININESS=0.20 (default for VRML materials)
C
C
C Input file VRTX with the vertices:
C (1) None to several strings terminated by / (a slash)
C (2) For each vertex data (2.1):
C (2.1) 'NAME',X1,X2,X3,Z1,Z2,Z3,V1,...,VN/
C 'NAME'... Name of the vertex. Not considered. May be blank.
C X1,X2,X3... Coordinates of the vertex.
C Z1,Z2,Z3... Normal to the surface at the vertex.
C V1,...,VN...Optional values which may be used to control the
C colour of the surface.
C /... None to several values terminated by a slash.
C (3) / or end of file.
C
C
C Input file TRGL with the triangles or polygons:
C (1) For each triangle data (1.1), or for each polygon data (1.2):
C (1.1) I1,I2,I3,/
C I1,I2,I3... Indices of 3 vertices of the triangle, right-handed
C with respect to the given surface normals.
C The vertices in file VRTX are indexed by positive integers
C according to their order.
C For polygon, three indices I1,I2,I3 are replaced with more
C ones.
C /... List of vertices is terminated by a slash.
C (1.2) I1,I2,...,IN,/
C I1,I2,...,IN... Indices of N vertices of the polygon.
C The vertices in file VRTX are indexed by positive integers
C according to their order.
C /... List of vertices must be terminated by a slash.
C (2) / or end of file.
C
C=======================================================================
C
C Common block /RAMC/:
INCLUDE 'ram.inc'
C ram.inc
C
INTEGER IRAM(MRAM)
EQUIVALENCE (IRAM,RAM)
C
C.......................................................................
C
C External functions and subroutines:
EXTERNAL LENGTH,RSEP1,RSEP3T,RSEP3I,ERROR,FORM2,COLOR1,COLOR2
INTEGER LENGTH
C
C Filenames and parameters:
CHARACTER*80 FSEP,FVRTX,FTRGL,FCOLS,FIN,FOUT
INTEGER LU1,LU2,IUNDEF,MVRTX,MQ
PARAMETER (LU1=1,LU2=2,IUNDEF=-999999,MVRTX=99,MQ=30)
C MVRTX... Maximum number of vertices of a single polygon.
C
C Other variables:
CHARACTER*(8+8*MQ) FORMAT
CHARACTER*5 VRML
CHARACTER*255 TEXT
LOGICAL LNORM
INTEGER KOLPOS,KOLNEG,KQ,NQ
INTEGER NVRTX,NPLGN,IREF,IRGB,I1,I2,I,N
REAL AMBI,TRANSP,SPEC,SHIN,RED,GREEN,BLUE
REAL OUTMIN(MQ),OUTMAX(MQ),R,G,B,AUX
C LNORM.. Says whether the surface normals are specified.
C
C.......................................................................
C
C Reading main input data:
WRITE(*,'(A)') '+SRFWRL: Enter input filename: '
FSEP=' '
READ (*,*) FSEP
IF(FSEP.EQ.' ') THEN
C SRFWRL-07
CALL ERROR('SRFWRL-07: No input file specified')
C Input file in the form of the SEP (Stanford Exploration Project)
C parameter or history file must be specified.
C There is no default filename.
END IF
WRITE(*,'(A)') '+SRFWRL: Working... '
C
C Reading input and output filenames:
CALL RSEP1(LU1,FSEP)
CALL RSEP3T('VRTX' ,FVRTX,'vrtx.out')
CALL RSEP3T('TRGL' ,FTRGL,'trgl.out')
CALL RSEP3T('COLORS',FCOLS,'hsv.dat' )
CALL RSEP3T('WRL' ,FIN ,'out.wrl' )
CALL RSEP3T('WRLOUT',FOUT ,FIN )
CALL RSEP3T('VRML' ,VRML ,'VRML2' )
CALL LOWER(VRML)
CALL RSEP3I('KOLPOS',KOLPOS,7)
CALL RSEP3I('KOLNEG',KOLNEG,7)
C
C Beginning of the output file:
OPEN(LU2,FILE=FOUT)
CALL WRL1(LU1,LU2,FIN,FOUT,VRML)
C
C Writing the prolog for the GOCAD surface:
IF (VRML.EQ.'gocad') THEN
WRITE(LU2,'(A)')
* 'GOCAD TSurf'
CALL RSEP3T('NAME',TEXT,' ')
IF (TEXT.NE.' ') THEN
I=LENGTH(TEXT)
WRITE(LU2,'(2A)')
* 'HDR name:',TEXT(1:I)
ELSE
C SRFWRL-09
CALL ERROR('SRFWRL-09: No name of GOCAD object')
C Name of the GOCAD object (set of points) must be specified.
END IF
CALL RSEP3T('PROPERTIES',TEXT,' ')
IF (TEXT.NE.' ') THEN
I=LENGTH(TEXT)
WRITE(LU2,'(2A)')
* 'PROPERTIES ',TEXT(1:I)
KOLNEG=4
DO 11 I=1,I-2
IF (TEXT(I:I).NE.' '.AND.TEXT(I+1:I+1).EQ.' ') THEN
KOLNEG=KOLNEG+1
END IF
11 CONTINUE
ELSE
KOLNEG=0
END IF
KOLPOS=KOLNEG
END IF
C
C Reading vertices:
LNORM=.TRUE.
KQ=MAX0(6,KOLPOS,KOLNEG)
IF(VRML.EQ.'gocad') THEN
NQ=KQ
ELSE IF(KOLPOS.EQ.0.AND.KOLNEG.EQ.0) THEN
NQ=6
ELSE IF(KOLPOS.EQ.KOLNEG) THEN
NQ=7
ELSE
NQ=8
END IF
IF(NQ.GT.MQ) THEN
C SRFWRL-10
CALL ERROR('SRFWRL-10: Too small arrays OUTMIN and OUTMAX')
END IF
OPEN(LU1,FILE=FVRTX)
READ(LU1,*) (TEXT,I=1,20)
NVRTX=0
20 CONTINUE
IF(NVRTX+KQ.GT.MRAM) THEN
C SRFWRL-01
CALL ERROR('SRFWRL-01: Too small array RAM')
END IF
TEXT='$'
DO 21 I=NVRTX+2,NVRTX+KQ
RAM(I)=0.
21 CONTINUE
READ(LU1,*,END=29) TEXT,(RAM(I),I=NVRTX+1,NVRTX+KQ)
IF(TEXT.EQ.'$') THEN
GO TO 29
END IF
C Shifting the values to be displayed to the 7th and 8th columns
IF(KOLNEG.GT.0) THEN
AUX=RAM(NVRTX+KOLNEG)
END IF
IF(KOLPOS.GT.0) THEN
RAM(NVRTX+7)=RAM(NVRTX+KOLPOS)
END IF
IF(KOLNEG.GT.0.AND.KOLPOS.NE.KOLNEG) THEN
RAM(NVRTX+8)=AUX
END IF
C Normalizing the normal
AUX=SQRT(RAM(NVRTX+4)**2+RAM(NVRTX+5)**2+RAM(NVRTX+6)**2)
IF(AUX.GT.0.) THEN
AUX=0.999/AUX
RAM(NVRTX+4)=RAM(NVRTX+4)*AUX
RAM(NVRTX+5)=RAM(NVRTX+5)*AUX
RAM(NVRTX+6)=RAM(NVRTX+6)*AUX
ELSE
LNORM=.FALSE.
END IF
IF(NVRTX.EQ.0) THEN
DO 22 I=1,NQ
OUTMIN(I)=RAM(NVRTX+I)
OUTMAX(I)=RAM(NVRTX+I)
22 CONTINUE
ELSE
DO 23 I=1,NQ
OUTMIN(I)=AMIN1(OUTMIN(I),RAM(NVRTX+I))
OUTMAX(I)=AMAX1(OUTMAX(I),RAM(NVRTX+I))
23 CONTINUE
END IF
NVRTX=NVRTX+NQ
GO TO 20
29 CONTINUE
CLOSE(LU1)
IF(NQ.GE.8) THEN
OUTMIN(7)=AMIN1(OUTMIN(7),OUTMIN(8))
OUTMAX(7)=AMAX1(OUTMAX(7),OUTMAX(8))
END IF
C Values to be displayed have been shifted to the 7th or 8th columns
IF(VRML.NE.'gocad') THEN
IF(KOLNEG.NE.0) THEN
IF(KOLPOS.EQ.KOLNEG) THEN
KOLNEG=7
ELSE
KOLNEG=8
END IF
END IF
IF(KOLPOS.NE.0) THEN
KOLPOS=7
END IF
END IF
C
C Reading input parameters for surface appearance:
CALL RSEP3R('AMBIENT' ,AMBI ,0.20)
CALL RSEP3R('TRANSP' ,TRANSP,0.00)
CALL RSEP3R('SPECULAR' ,SPEC ,0.00)
CALL RSEP3R('SHININESS',SHIN ,0.20)
CALL RSEP3R('R' ,RED ,1.)
CALL RSEP3R('G' ,GREEN ,1.)
CALL RSEP3R('B' ,BLUE ,1.)
C
C Determining the colour map:
IF(KOLPOS.GT.0.OR.KOLNEG.GT.0) THEN
CALL COLOR1(LU1,MRAM-NVRTX,IRAM(NVRTX+1),RAM(NVRTX+1),
* 1,OUTMIN(7),OUTMAX(7))
IF (VRML.EQ.'pov') THEN
AUX=0.01/SHININ
WRITE(LU2,'(A)')
* '#default {'
WRITE(LU2,'(A,2(F4.2,A))')
* ' finish { ambient 1.00 specular ',SPEC,
* ' roughness ',AUX,' }'
WRITE(LU2,'(A)')
* ' pigment {'
* ,' color_map {'
CALL COLOR3(MRAM-NVRTX,IRAM(NVRTX+1),RAM(NVRTX+1),1,IREF,IRGB)
I=NVRTX+1+IRAM(NVRTX+1)
IREF=NVRTX+IREF
IRGB=NVRTX+IRGB
DO 57 I2=1,IRAM(NVRTX+2)-IRAM(NVRTX+1)
WRITE(LU2,'(A,F8.6,A,4(F4.2,A))')
* ' [',RAM(I+I2),' rgbt <',
* (RAM(IRGB+I1),',',I1=3*I2-2,3*I2),TRANSP,'>]'
57 CONTINUE
WRITE(LU2,'(A)')
* ' }'
* ,' }'
* ,'}'
WRITE(LU2,'(A,G13.6,A)')
* '#declare CREF = ',RAM(IREF+1),';'
* ,'#declare VREF = ',RAM(IREF+2),';'
* ,'#declare VPER = ',RAM(IREF+3),';'
END IF
END IF
C
C Writing the prolog for the surface:
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)')
* 'DEF SurfaceMaterial Material {'
WRITE(LU2,'(3(A,F4.2))')
* ' diffuseColor ',RED,' ',GREEN,' ',BLUE
* ,' ambientColor ',RED*AMBI,' ',GREEN*AMBI,' ',BLUE*AMBI
* ,' specularColor ',SPEC,' ',SPEC,' ',SPEC
WRITE(LU2,'(A,F4.2)')
* ' shininess ',SHIN
* ,' transparency ',TRANSP
WRITE(LU2,'(A)')
* ' emissiveColor 0.00 0.00 0.00'
* ,'}'
WRITE(LU2,'(A)')
* 'Separator {'
* ,'USE SurfaceMaterial'
IF(LNORM) THEN
WRITE(LU2,'(A)') 'NormalBinding { value PER_VERTEX }'
ELSE
WRITE(LU2,'(A)') 'NormalBinding { value PER_FACE }'
END IF
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)')
* 'Shape {'
* ,' appearance DEF SurfaceAppearance Appearance {'
* ,' material Material {'
WRITE(LU2,'(3(A,F4.2))')
* ' diffuseColor ',RED,' ',GREEN,' ',BLUE
* ,' specularColor ',SPEC,' ',SPEC,' ',SPEC
WRITE(LU2,'(A,F4.2)')
* ' shininess ',SHIN
* ,' transparency ',TRANSP
WRITE(LU2,'(A)')
* ' ambientIntensity 1.00'
* ,' emissiveColor 0.00 0.00 0.00'
* ,' }'
* ,' }'
* ,'}'
* ,'Surface {'
* ,'appearance USE SurfaceAppearance'
ELSE IF (VRML.EQ.'gocad') THEN
CONTINUE
ELSE IF (VRML.EQ.'pov') THEN
WRITE(LU2,'(A,I6,A)')
* '#declare NVRTX =',NVRTX/NQ,';'
WRITE(LU2,'(A)')
* '#declare PTS = array[NVRTX][7]'
* ,'#declare IVRTX = 0;'
* ,'#macro VRTX(X1,X2,X3,Z1,Z2,Z3,V1)'
* ,' #declare PTS[IVRTX][0] = X1;'
* ,' #declare PTS[IVRTX][1] = X2;'
* ,' #declare PTS[IVRTX][2] = X3;'
* ,' #declare PTS[IVRTX][3] = Z1;'
* ,' #declare PTS[IVRTX][4] = Z2;'
* ,' #declare PTS[IVRTX][5] = Z3;'
* ,' #declare PTS[IVRTX][6] = V1;'
* ,' #declare IVRTX = IVRTX + 1;'
* ,'#end'
* ,'#macro TRGL(I1,I2,I3)'
* ,' #local X1=;'
* ,' #local X2=;'
* ,' #local X3=;'
* ,' #local Z1=;'
* ,' #local Z2=;'
* ,' #local Z3=;'
* ,' #local V1=PTS[I1][6]-PTS[I3][6];'
* ,' #local V2=PTS[I2][6]-PTS[I3][6];'
* ,' #local V3= PTS[I3][6];'
* ,' #if (V1=0 & V2=0)'
* ,' #local V1=VPER/999999;'
* ,' #end'
* ,' #local D1=X1-X3;'
* ,' #local D2=X2-X3;'
* ,' #local D11=vdot(D1,D1);'
* ,' #local D12=vdot(D1,D2);'
* ,' #local D22=vdot(D2,D2);'
* ,' #local D =D11*D22-D12*D12;'
* ,' #local G =(D1*(D22*V1-D12*V2)+D2*(-D12*V1+D11*V2))/D;'
* ,' #local GN= vlength(G);'
* ,' #local G0= G*VPER/GN/GN;'
* ,' #local G1= V2*D1-V1*D2;'
* ,' #local G2= vcross(G0,G1);'
* ,' smooth_triangle {'
* ,' X1,Z1,X2,Z2,X3,Z3'
* ,' texture {'
* ,' pigment {'
* ,' gradient x'
* ,' translate ((VREF-V3)/VPER-CREF-100)*x'
* ,' matrix '
* ,' translate X3'
* ,' }'
* ,' }'
* ,' }'
* ,'#end'
ELSE
C SRFWRL-08
CALL ERROR('SRFWRL-08: No valid string in VRML')
C Valid string specifying the form of the output file is:
C VRML='VRML1' or 'VRML2' or 'POV'. Default and recommended
C value is 'VRML2'.
END IF
C
C Writing the vertices:
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') 'Coordinate3 { point ['
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'point ['
END IF
C ------
IF (VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
FORMAT='('
CALL FORM2(3,OUTMIN(1),OUTMAX(1),FORMAT(2:25))
DO 60 I=1,NVRTX,NQ
WRITE(LU2,FORMAT) RAM(I),' ',RAM(I+1),' ',RAM(I+2),','
60 CONTINUE
ELSE IF (VRML.EQ.'gocad') THEN
C Writing the vertices with normals and values:
FORMAT='(A,I0,A,'
FORMAT(5:5)=CHAR(ICHAR('1')+INT(ALOG10(FLOAT(NVRTX/NQ)+0.5)))
IF (KOLNEG.EQ.0) THEN
CALL FORM2(3,OUTMIN(1),OUTMAX(1),FORMAT(9:8+8*3))
DO 62 I=1,NVRTX,NQ
WRITE(LU2,FORMAT) 'VRTX ',I/NQ+1,(' ',RAM(J),J=I,I+2)
62 CONTINUE
ELSE
CALL FORM2(NQ,OUTMIN(1),OUTMAX(1),FORMAT(9:8+8*NQ))
DO 63 I=1,NVRTX,NQ
WRITE(LU2,FORMAT) 'PVRTX ',I/NQ+1,(' ',RAM(J),J=I,I+NQ-1)
63 CONTINUE
END IF
ELSE IF (VRML.EQ.'pov') THEN
C Writing the vertices with normals and values:
IF(KOLNEG.NE.KOLPOS) THEN
C SRFWRL-51
CALL WARN('SRFWRL-51: POV surface sides differently coloured')
C POV scene description language does not allow for different
C colours at the positive and negative side of a surface.
END IF
FORMAT='(A,'
CALL FORM2(3,OUTMIN(1),OUTMAX(1),FORMAT(4:27))
FORMAT(27:38)=',3(F5.3,A),'
CALL FORM2(1,OUTMIN(7),OUTMAX(7),FORMAT(39:46))
DO 65 I=1,NVRTX,NQ
WRITE(LU2,FORMAT) 'VRTX(',(RAM(I1),',',I1=I,I+5),RAM(I+6),')'
65 CONTINUE
END IF
C ------
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') ']'
END IF
C
C Writing the right-handed normals (positive surface side):
IF(LNORM) THEN
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') 'DEF SurfaceNormal Normal { vector ['
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'normalPos Normal { vector ['
END IF
C ------
IF (VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
FORMAT='(3(F5.3,A))'
DO 66 I=4,NVRTX,NQ
WRITE(LU2,FORMAT) RAM(I),' ',RAM(I+1),' ',RAM(I+2),','
66 CONTINUE
END IF
C ------
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') '] }'
END IF
END IF
C
C Writing the left-handed normals (negative surface side):
IF(LNORM) THEN
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') 'Normal { vector ['
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'normalNeg Normal { vector ['
END IF
C ------
IF (VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
DO 67 I=4,NVRTX,NQ
WRITE(LU2,FORMAT) -RAM(I),' ',-RAM(I+1),' ',-RAM(I+2),','
67 CONTINUE
END IF
C ------
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') '] }'
END IF
END IF
C
C Writing the colours of the positive surface side:
IF(KOLPOS.GT.0) THEN
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') 'DEF SurfaceColor Material { diffuseColor ['
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'colorPos DEF SurfaceColor Color { color ['
END IF
C ------
IF (VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
DO 71 I=KOLPOS,NVRTX,NQ
CALL COLOR2(MRAM-NVRTX,IRAM(NVRTX+1),RAM(NVRTX+1),
* 1,RAM(I),R,G,B)
WRITE(LU2,'(3(F4.2,A))') R,' ',G,' ',B,','
71 CONTINUE
END IF
C ------
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') '] }'
END IF
END IF
C
C Writing the colours of the negative surface side:
IF(KOLNEG.GT.0) THEN
IF(KOLNEG.EQ.KOLPOS) THEN
IF (VRML.EQ.'vrml1') THEN
CONTINUE
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'colorNeg USE SurfaceColor'
END IF
ELSE
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') 'Material { diffuseColor ['
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'colorNeg Color { color ['
ELSE IF (VRML.EQ.'pov') THEN
END IF
C ------
IF (VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
DO 72 I=KOLNEG,NVRTX,NQ
CALL COLOR2(MRAM-NVRTX,IRAM(NVRTX+1),RAM(NVRTX+1),
* 1,RAM(I),R,G,B)
WRITE(LU2,'(3(F4.2,A))') R,' ',G,' ',B,','
72 CONTINUE
END IF
C ------
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') '] }'
END IF
END IF
END IF
C
C Reading the polygons (usually triangles):
DO 81 I=1,MRAM
IRAM(I)=0
81 CONTINUE
OPEN(LU1,FILE=FTRGL)
NPLGN=0
82 CONTINUE
IF(NPLGN+MVRTX+1.GT.MRAM) THEN
C SRFWRL-02
CALL ERROR('SRFWRL-02: Too small array RAM')
END IF
IRAM(NPLGN+1)=IUNDEF
READ(LU1,*,END=89) (IRAM(I),I=NPLGN+1,NPLGN+MVRTX+1)
IF(IRAM(NPLGN+1).EQ.IUNDEF) THEN
GO TO 89
END IF
DO 83 I=NPLGN+1,NPLGN+MVRTX+1
IF(IRAM(I).LE.0) THEN
C Number of polygon vertices
N=I-1-NPLGN
GO TO 84
ELSE IF(IRAM(I).GT.NVRTX/NQ) THEN
C SRFWRL-03
WRITE(TEXT,'(A,I6)')'SRFWRL-03: Wrong vertex index:',IRAM(I)
CALL ERROR(TEXT(1:LENGTH(TEXT)))
END IF
83 CONTINUE
C SRFWRL-04
CALL ERROR('SRFWRL-04: Too many vertices in polygons')
84 CONTINUE
IF(N.LT.3) THEN
C SRFWRL-52
CALL WARN('SRFWRL-52: Polygon of less than 3 vertices')
END IF
C Checking vertex indices:
DO 86 I2=NPLGN+1,NPLGN+N
DO 85 I1=I2+1,NPLGN+N
IF(IRAM(I2).EQ.IRAM(I1)) THEN
C SRFWRL-05
WRITE(TEXT,'(A,I6)')
* 'SRFWRL-05: The same vertex twice in a polygon:',IRAM(I2)
CALL ERROR(TEXT(1:LENGTH(TEXT)))
C All vertices of a polygon must be different.
END IF
85 CONTINUE
86 CONTINUE
C Terminating polygon by zero
IF(N.GE.3) THEN
NPLGN=NPLGN+N+1
IRAM(NPLGN)=0
END IF
GO TO 82
89 CONTINUE
CLOSE(LU1)
C
C Writing the polygons (usually triangles):
IF(VRML.EQ.'vrml1') THEN
IF(KOLNEG.GT.0) THEN
WRITE(LU2,'(A)') 'MaterialBinding { value PER_VERTEX }'
ELSE
WRITE(LU2,'(A)') 'MaterialBinding { value OVERALL }'
END IF
WRITE(LU2,'(A)') 'ShapeHints {'
WRITE(LU2,'(A)') ' vertexOrdering CLOCKWISE'
WRITE(LU2,'(A)') ' shapeType SOLID'
WRITE(LU2,'(A)') '}'
WRITE(LU2,'(A)') 'DEF Surface IndexedFaceSet { coordIndex ['
ELSE IF(VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') 'coordIndex ['
END IF
C ------
N=0
IF(VRML.EQ.'vrml1'.OR.VRML.EQ.'vrml2') THEN
FORMAT='(99(I0,A))'
I=INT(ALOG10(FLOAT(NVRTX/NQ)-0.5))+1
FORMAT(6:6)=CHAR(ICHAR('0')+I)
DO 91 I2=1,NPLGN
IF(IRAM(I2).LE.0) THEN
WRITE(LU2,FORMAT)
* (IRAM(I1)-1,', ',I1=N+1,I2-2),IRAM(I2-1)-1,', -1,'
N=I2
END IF
91 CONTINUE
ELSE IF (VRML.EQ.'gocad') THEN
FORMAT='(A,3(A,I0))'
I=INT(ALOG10(FLOAT(NVRTX/NQ)+0.5))+1
FORMAT(9:9)=CHAR(ICHAR('0')+I)
DO 92 I2=1,NPLGN
IF(IRAM(I2).LE.0) THEN
IF(I2-N.GT.4) THEN
C SRFWRL-10
CALL ERROR('SRFWRL-10: More than 3 vertices in polygon')
C In this version of the SRFWRL program, only triangles are
C allowed for GOCAD. Polygons should be divided into
C triangles using program 'trgl.for'.
END IF
WRITE(LU2,FORMAT) 'TRGL',(' ',IRAM(I1),I1=N+1,I2-1)
N=I2
END IF
92 CONTINUE
ELSE IF(VRML.EQ.'pov') THEN
FORMAT='(99(A,I0))'
I=INT(ALOG10(FLOAT(NVRTX/NQ)-0.5))+1
FORMAT(8:8)=CHAR(ICHAR('0')+I)
DO 93 I2=1,NPLGN
IF(IRAM(I2).LE.0) THEN
IF(I2-N.GT.4) THEN
C SRFWRL-06
CALL ERROR('SRFWRL-06: More than 3 vertices in polygon')
C In this version of the SRFWRL program, only triangles are
C allowed for the POV scene description language. Polygons
C should be divided into triangles using program 'trgl.for'.
END IF
WRITE(LU2,FORMAT)
* 'TRGL(',(IRAM(I1)-1,',',I1=N+1,I2-2),IRAM(I2-1)-1,')'
N=I2
END IF
93 CONTINUE
END IF
C ------
IF(VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '] }'
IF(LNORM) THEN
WRITE(LU2,'(A)') 'USE SurfaceNormal'
END IF
IF(KOLPOS.GT.0) THEN
WRITE(LU2,'(A)') 'USE SurfaceColor'
WRITE(LU2,'(A)') 'MaterialBinding { value PER_VERTEX }'
ELSE
WRITE(LU2,'(A)') 'MaterialBinding { value OVERALL }'
END IF
WRITE(LU2,'(A)') 'ShapeHints {'
WRITE(LU2,'(A)') ' vertexOrdering COUNTERCLOCKWISE'
WRITE(LU2,'(A)') ' shapeType SOLID'
WRITE(LU2,'(A)') '}'
WRITE(LU2,'(A)') 'USE Surface'
ELSE IF(VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') ']'
END IF
C
C Writing the trailor for the surface:
IF (VRML.EQ.'vrml1') THEN
WRITE(LU2,'(A)') '}'
ELSE IF (VRML.EQ.'vrml2') THEN
WRITE(LU2,'(A)') '}'
ELSE IF (VRML.EQ.'gocad') THEN
WRITE(LU2,'(A)') 'END'
END IF
CLOSE(LU2)
WRITE(*,'(A)') '+SRFWRL: Done. '
STOP
END
C
C=======================================================================
C
INCLUDE 'error.for'
C error.for
INCLUDE 'sep.for'
C sep.for
INCLUDE 'length.for'
C length.for
INCLUDE 'forms.for'
C forms.for
INCLUDE 'colors.for'
C colors.for
INCLUDE 'wrl.for'
C wrl.for
C
C=======================================================================
C