Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.4 KiB

2 years ago
C Copyright(C) 1999-2020 National Technology & Engineering Solutions
C of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
C NTESS, the U.S. Government retains certain rights in this software.
C
C See packages/seacas/LICENSE for details
C=======================================================================
SUBROUTINE SHADEN (NLNKF, LINKF1, XN, YN, ZN, NCOL, LITE, NLIT,
* MINCOL, KDIFF, KSPEC, SPEXP, WXMIN, WYMIN, WXMAX, WYMAX)
C=======================================================================
C --*** SOLIDF *** (DETOUR) Paint face
C -- Written by Amy Gilkey - revised 09/24/85
C --
C --SOLIDF paints the a face of the mesh.
C --
C --Parameters:
C -- NLNKF - IN - the number of nodes per face
C -- LINKF1 - IN - the connectivity for the face
C -- XN, YN, ZN - IN - the nodal coordinates
C -- NCOL - IN - the number of colors
C -- XLN, YLN, ZLN - IN - the light unit vector components
INTEGER LINKF1(NLNKF)
REAL XN(*), YN(*), ZN(*)
REAL LITE(8,*)
REAL KDIFF, KSPEC, SPEXP
REAL XPTS(20), YPTS(20), ZPTS(20)
SAVE LSTCOL
DATA LSTCOL /0/
C... Coordinate System:
C ^ Y
C |
C |
C |
C | X
C Z--------->
XMAX = -1.0e30
YMAX = -1.0e30
XMIN = 1.0e30
YMIN = 1.0e30
DO 100 ILINK = 1, NLNKF
XPTS(ILINK) = XN(LINKF1(ILINK))
YPTS(ILINK) = YN(LINKF1(ILINK))
ZPTS(ILINK) = ZN(LINKF1(ILINK))
XMAX = MAX(XMAX, XPTS(ILINK))
XMIN = MIN(XMIN, XPTS(ILINK))
YMAX = MAX(YMAX, YPTS(ILINK))
YMIN = MIN(YMIN, YPTS(ILINK))
100 CONTINUE
C ... Determine if polygon is in window.
IF (XMAX .LT. WXMIN .OR. XMIN .GT. WXMAX .OR.
* YMAX .LT. WYMIN .OR. YMIN .GT. WYMAX) RETURN
C ... Calculate surface normal
if (nlnkf .eq. 4) then
XMAG = (YPTS(3) - YPTS(1)) * (ZPTS(4) - ZPTS(2)) -
* (ZPTS(3) - ZPTS(1)) * (YPTS(4) - YPTS(2))
YMAG = (ZPTS(3) - ZPTS(1)) * (XPTS(4) - XPTS(2)) -
* (XPTS(3) - XPTS(1)) * (ZPTS(4) - ZPTS(2))
ZMAG = (XPTS(3) - XPTS(1)) * (YPTS(4) - YPTS(2)) -
* (YPTS(3) - YPTS(1)) * (XPTS(4) - XPTS(2))
else
C ... Newells method, "Procedural Elements for Computer Graphics", p209
xmag = (ypts(nlnkf) - ypts(1)) * (zpts(nlnkf) - zpts(1))
ymag = (zpts(nlnkf) - zpts(1)) * (xpts(nlnkf) - xpts(1))
zmag = (xpts(nlnkf) - xpts(1)) * (ypts(nlnkf) - ypts(1))
do 110 i=1, nlnkf-1
j = i + 1
xmag = xmag + (ypts(i) - ypts(j)) * (zpts(i) - zpts(j))
ymag = ymag + (zpts(i) - zpts(j)) * (xpts(i) - xpts(j))
zmag = zmag + (xpts(i) - xpts(j)) * (ypts(i) - ypts(j))
110 continue
end if
C ... If polygon facing away from viewer (-Z), return immediately
if (zmag .lt. 0) return
VMAG = SQRT(XMAG**2 + YMAG**2 + ZMAG**2)
C ... Normalize surface normal
XMAG = XMAG / VMAG
YMAG = YMAG / VMAG
ZMAG = ZMAG / VMAG
C ... Determine dot product of surface normal and light vector.
SMAG = 0.0
DO 120 I = 1, NLIT
SMAG = SMAG + max(0.0, (XMAG * LITE(5,I) + YMAG * LITE(6,I) +
* ZMAG * LITE(7,I)) * LITE(8,I))
120 CONTINUE
C ... Calculate Reflection Vector.
if (SPEXP .GT. 0.0 .and. KSPEC .GT. 0.0) then
RMAG = 0.0
DO 160 I = 1, NLIT
R = xmag * lite(5,i) + ymag*lite(6,i) + zmag*lite(7,i)
x = 2 * xmag * R - lite(5,i)
y = 2 * ymag * R - lite(6,i)
z = 2 * zmag * R - lite(7,i)
C ... Normalize Reflection Vector
vmag = sqrt(x**2 + y**2 + z**2)
x = x / vmag
y = y / vmag
z = z / vmag
C ... NOTE: Sight vector is (0,0,1),
C ... Calculate dot product of Reflect and Sight
C - sight = z, therefore, dot product = z
RMAG = RMAG + max(0.0, Z)**SPEXP * LITE(8,I)
160 CONTINUE
SMAG = KDIFF * SMAG + KSPEC * RMAG
end if
C ... Scale dot product (0 <= |smag| <= 1) to (0 < icol < ncol)
C If smag <= 0, set icol = 1
C maximum color = ncol-1
C minimum color = 1
if (ncol .eq. 1) then
icol = mincol + 1
else
ICOL = MINCOL + min(NCOL-1, max(1, NINT(SMAG * DBLE(NCOL))))
end if
if (lstcol .ne. icol) then
CALL GRCOLR (ICOL)
lstcol = icol
end if
CALL MPD2PG (NLNKF, XPTS, YPTS, 'S')
RETURN
END