;===================================================================== ; PV-WAVE ARL ; ; PV-Wave Advanced Rendering Library ; 11/90 D. Carr ; ; (c) Copyright Precision Visuals, Inc., 1990 ; Boulder, Colorado, U.S.A. ; ; All Rights Reserved. ; ; This software is confidential information which is proprietary to ; and a trade secret of Precision Visuals, Inc. Use, duplication or ; disclosure is subject to the terms of an appropriate license ; agreement. ; ------------------------------------------------------------------ ; Use, duplication, or disclosure by the Government is subject to ; restrictions set forth in paragraph (b)(3)(B) of the Rights in ; Technical Data and Computer Software clause in DAR 7-104.9(a). ; ; Contractor : Precision Visuals, Inc., Boulder, Colorado, U.S.A. ; ------------------------------------------------------------------- ; ; PROGRAM OVERVIEW : PROCEDURE Poly_Plot ; ; Poly_Plot renders a list of polygons. This procedure is ; supplied as an alternative to the standard PV-WAVE command ; "Polyshade". This procedure is slower than Polyshade, but ; is more flexible. Polyshade will fail if any vertex of any ; polygon lies outside the plot window. Also, Polyshade can ; only render polygons using light source shading. ; ; Poly_Plot will not fail if one or more polygons have a vertex ; outside the current plot window. Poly_Plot does not render ; polygons with light source shading, but it can plot opaque ; and translucent polygons. Also, the fill color and edge ; color can be specified for each polygon. ; ; Poly_Plot uses a simple back-to-front sorting method to ; determine the polygon plotting order. ; ; ; SEE ALSO : Poly_Norm Poly_Trans Poly_Dev Polyshade Poly_C_Conv ; ; MANDATORY INPUTS : ; ; vertex_list : A (3, n) array containing the 3-D coordinates ; of each vertex. The vertex_list should be in ; DEVICE coordinates. To obtain DEVICE coordinates ; from DATA coordinates use the "Poly_Norm", ; "Poly_Trans", and "Poly_Dev" functions in that ; order. ; ; polygon_list : An array containing the number of sides for ; each polygon and the subscripts into the ; vertex_list array. ; ; The vertex_list and polygon_list are the same ; type of arrays used by the "Polyshade" and ; "Shade_Volume" commands. ; For example, to render two adjacent square poly- ; gons, vertex_list could contain : ; 0.0 0.0 0.0 ; 1.0 0.0 0.0 ; 2.0 0.0 0.0 ; 2.0 1.0 0.0 ; 1.0 1.0 0.0 ; 0.0 1.0 0.0 ; Note that there are only six verticies in the ; vertex_list because two verticies are shared by ; both polygons. The polygon_list would then ; contain : ; 4 The first polygon has 4 sides. ; 0 The first vertex is vertex_list(*, 0). ; 1 The second vertex is vertex_list(*, 1). ; 4 The third vertex is vertex_list(*, 4). ; 5 The fourth vertex is vertex_list(*, 5). ; 4 The second polygon has 4 sides. ; 1 The first vertex is vertex_list(*, 1). ; 2 The second vertex is vertex_list(*, 2). ; 3 The third vertex is vertex_list(*, 3). ; 4 The fourth vertex is vertex_list(*, 4). ; ; pg_num : The total number of polygons to plot. ; ; winx : The X dimension of the current plot window in ; device coordinates. ; NOTE : The winx parameter is ignored if the ; "image" keyword is present. ; ; winy : The Y dimension of the current plot window in ; device coordinates. ; NOTE : The winy parameter is ignored if the ; "image" keyword is present. ; ; fill_colors : The color(s) to fill the polygons with. If ; fill_colors contains fewer than pg_num elements, ; then all polygons will be filled with the color ; specified by the first element in fill_colors. ; Otherwise, each polygon will be filled with the ; corresponding color found in fill_colors(i). ; To prevent polygon fill, set fill_colors to -1 . ; For example, fill_colors could contain : ; 255 Fill the first polygon with color 255. ; 200 Fill the second polygon with color 200. ; -1 Don't fill the third polygon. ; 0 Fill the fourth polygon with color 0. ; ; edge_colors : The color(s) to draw the polygon edges with. ; The edge_colors parameter works in the same manner ; as fill_colors. To suppress the plotting of ; polygon edges set edge_colors to -1 . ; NOTE : Polygon edges are NOT plotted if the ; "image" keyword is present. ; ; poly_opaque : The translucency factor to use for plotting each ; polygon. If poly_opaque contains fewer than ; pg_num elements, then all polygons will be plotted ; with the translucency factor specified by the ; first element in poly_opaque. ; Otherwise, each polygon will be plotted with the ; corresponding translucency factor found in ; poly_opaque(i). To prevent translucency, set ; poly_opaque to -1 . ; A translucency factor of 0 is completely clear. ; The higher the translucency factor, the more ; opaque the polygon is. If the maximum value ; found in "image" is 255 and if the maximum color ; value found in fill_colors is also 255 then a ; translucency factor of 255 would be completely ; opaque. ; NOTE : The "image" keyword must be supplied for ; poly_opaque to take effect. ; ; OPTIONAL PARAMETERS (Keywords) : ; ; image : On input, image is a 2-dimensional array ; containing the image on which to plot the ; polygons. On return, image contains the ; original image with the polygons plotted on it. ; This image may then be displayed using "Tv" or ; other similar commands. ; NOTE : If "image" is NOT supplied then the ; polygons will be plotted immediately as ; generated in the current PV-WAVE window. ; The "image" parameter must be present for ; poly_opaque to have any effect. ; If the "image" parameter is present then ; no polygon edges will be plotted and the ; winx and winy parameters will be ignored. ; ; zclip : If "zclip" is present and non-zero then polygons ; that do not have at least one vertex in front of ; the view point will not be plotted. ; ;===================================================================== ; PRO Poly_Plot, vertex_list, polygon_list, pg_num, winx, winy, $ fill_colors, edge_colors, poly_opaque, image=image, zclip=zclip szv = Size(vertex_list) IF ((szv(0) NE 2) AND (szv(1) NE 3)) THEN BEGIN Print, "Invalid vertex list." STOP ENDIF IF ((Max(polygon_list) GE szv(2)) OR (Min(polygon_list) LT 0)) THEN BEGIN Print, "Invalid polygon list." STOP ENDIF IF (pg_num LE 0) THEN BEGIN Print, "Number of polygons must be >= 1" STOP ENDIF IF (N_Elements(image) GT 0) THEN BEGIN szi = Size(image) IF (szi(0) NE 2) THEN BEGIN Print, "image array not 2-dimensional" STOP ENDIF IF ((szi(1) LT 2) OR (szi(2) LT 2)) THEN BEGIN Print, "image dimensions must be >= 2" STOP ENDIF winx = szi(1) winy = szi(2) ENDIF ELSE BEGIN IF ((winx LE 1) OR (winy LE 1)) THEN BEGIN Print, "Plot window size must be >= 2" STOP ENDIF ENDELSE z_clip = 0 IF (N_Elements(zclip) GT 0) THEN z_clip = zclip IF (N_Elements(fill_colors) GE pg_num) THEN BEGIN f_colors = fill_colors ENDIF ELSE BEGIN f_colors = Intarr(pg_num) f_colors(*) = fill_colors(0) ENDELSE IF (N_Elements(edge_colors) GE pg_num) THEN BEGIN e_colors = edge_colors ENDIF ELSE BEGIN e_colors = Intarr(pg_num) e_colors(*) = edge_colors(0) ENDELSE IF (N_Elements(poly_opaque) GE pg_num) THEN BEGIN p_opaque = poly_opaque ENDIF ELSE BEGIN p_opaque = Intarr(pg_num) p_opaque(*) = poly_opaque(0) ENDELSE L0 = Long(0) L1 = Long(1) distances = Fltarr(pg_num) pg_num1 = Long(pg_num) - L1 pv_idx = L0 col_idx = L0 Print, 'Calculating distances ...' FOR i=L0, pg_num1 DO BEGIN pl = polygon_list(pv_idx) pz = Fltarr(pl, /Nozero) pz(L0:pl-L1) = vertex_list(2, polygon_list(pv_idx+L1:pv_idx+pl)) distances(i) = Min(pz) pv_idx = pv_idx + polygon_list(pv_idx) + L1 ENDFOR Print, 'Sorting distances ...' p_order = Sort(distances) pv_idx = Lonarr(pg_num) Print, 'Arranging polygons ...' FOR i=L1, pg_num1 DO pv_idx(i) = pv_idx(i-L1) + polygon_list(pv_idx(i-L1)) + L1 Print, 'Plotting polygons ...' IF (N_Elements(image) GT 0) THEN BEGIN FOR i=L0, pg_num1 DO BEGIN j = p_order(i) pl = polygon_list(pv_idx(j)) px = Lonarr(pl, /Nozero) py = px pz = px px(L0:pl-L1) = vertex_list(0, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) py(L0:pl-L1) = vertex_list(1, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) pz(L0:pl-L1) = vertex_list(2, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) ind = Where(((px GT 0) AND (px LT winx)) AND $ ((py GT 0) AND (py LT winy))) IF (((ind(0) GE L0) AND ((Max(pz) LE L0) OR (z_clip EQ 0))) AND ((Min(px) NE Max(px)) AND (Min(py) NE Max(py)))) $ THEN BEGIN lox = Min(px) loy = Min(py) px = px - lox py = py - loy hix = Max(px) + 1 hiy = Max(py) + 1 indp = Polyfillv(px, py, hix, hiy) indy = (((indp / hix) > (-loy)) < (winy - loy)) + loy indx = (((indp - (Fix(indp / hix) * hix)) > (-lox)) < (winx - lox)) + lox indp = (indy * winx) + indx IF (p_opaque(j) LT 0) THEN BEGIN IF (f_colors(j) GE 0) THEN image(indp) = f_colors(j) ENDIF ELSE BEGIN IF (f_colors(j) GE 0) THEN image(indp) = (((image(indp) - p_opaque(j)) > 0) + f_colors(j)) < (!D.N_Colors - 1) ENDELSE ENDIF ENDFOR ENDIF ELSE BEGIN FOR i=L0, pg_num1 DO BEGIN j = p_order(i) pl = polygon_list(pv_idx(j)) px = Lonarr(pl, /Nozero) py = px pz = px px(L0:pl-L1) = vertex_list(0, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) py(L0:pl-L1) = vertex_list(1, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) pz(L0:pl-L1) = vertex_list(2, polygon_list(pv_idx(j)+L1:pv_idx(j)+pl)) ind = Where(((px GT 0) AND (px LT winx)) AND $ ((py GT 0) AND (py LT winy))) IF ((ind(0) GE L0) AND ((Max(pz) LE L0) OR (z_clip EQ 0))) THEN BEGIN IF (f_colors(j) GE 0) THEN Polyfill, px, py, Color=f_colors(j), /Device IF (e_colors(j) GE 0) THEN BEGIN Plots, px, py, Color=e_colors(j), /Device Plots, [px(0), px(pl-L1)], [py(0), py(pl-L1)], Color=e_colors(j), /Device ENDIF ENDIF ENDFOR ENDELSE Print, 'Plotting complete ...' RETURN END