NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Hello SirAttached herewith a modified version of ShadowImageByRefFunctionTypeJ3D and a slightly modified version of ShadowFunctionSetTypeJ3D.
Keep the old jars.Kindly recompile them and just see this time you will be able to see the details you have been looking for. Just confirm me if there any artifact that is coming higher resolution. I have tested in both the programs that you sent me. I am seeing no issues.
Just let me know if there are any. I will again quote the same DISCLAIMER NOTICE:It is pretty much a TEMPORARY (not very TESTED) solution but still very EFFICIENT ;-)
This is something pretty New as Tom Rink Sir says "DISCOVERY BY ACCIDENT" :-) because we are able to generate this type of surface details using geometry only.
But now we are doing it using Textures. It is gonna change our way we were thinking till now in visAD. with regards Ghansham On 05/31/2012 11:30 PM, visad-request@xxxxxxxxxxxxxxxx wrote:
Send visad mailing list submissions to visad@xxxxxxxxxxxxxxxx To subscribe or unsubscribe via the World Wide Web, visit http://mailman.unidata.ucar.edu/mailman/listinfo/visad or, via email, send a message with subject or body 'help' to visad-request@xxxxxxxxxxxxxxxx You can reach the person managing the list at visad-owner@xxxxxxxxxxxxxxxx When replying, please edit your Subject line so it is more specific than "Re: Contents of visad digest..." Today's Topics: 1. Re: Strange rendering depending on axis range (Ghansham Sangar) 2. Re: Strange rendering depending on axis range (Tomas Pluskal) ---------------------------------------------------------------------- Message: 1 Date: Thu, 31 May 2012 11:54:22 +0530 From: Ghansham Sangar<ghansham@xxxxxxxxxxxxxxx> To: visad@xxxxxxxxxxxxxxxx Subject: Re: [visad] Strange rendering depending on axis range Message-ID:<4FC70E96.50701@xxxxxxxxxxxxxxx> Content-Type: text/plain; charset=ISO-8859-1; format=flowed R/Sir I would suggest you to just check with the modified render for the range setting issue. That will be really appreciated. regards Ghansham On 05/31/2012 11:15 AM, visad-request@xxxxxxxxxxxxxxxx wrote:Send visad mailing list submissions to visad@xxxxxxxxxxxxxxxx To subscribe or unsubscribe via the World Wide Web, visit http://mailman.unidata.ucar.edu/mailman/listinfo/visad or, via email, send a message with subject or body 'help' to visad-request@xxxxxxxxxxxxxxxx You can reach the person managing the list at visad-owner@xxxxxxxxxxxxxxxx When replying, please edit your Subject line so it is more specific than "Re: Contents of visad digest..." Today's Topics: 1. Re: Strange rendering depending on axis range (Tomas Pluskal) ---------------------------------------------------------------------- Message: 1 Date: Thu, 31 May 2012 05:44:55 +0000 From: Tomas Pluskal<pluskal@xxxxxxx> To: "visad@xxxxxxxxxxxxxxxx"<visad@xxxxxxxxxxxxxxxx> Subject: Re: [visad] Strange rendering depending on axis range Message-ID:<AFA0F858-9E23-4E74-83B4-E0CA2A4F3766@xxxxxxx> Content-Type: text/plain; charset="windows-1252" Hi Tom, formally setting the ranges to decimal values fixes the problem for me. Just a followup to this issue: setting the range to 44027 - 44028 shows the same problem, despite using decimal values (screenshot is attached). Tomas [cid:71D3DE54-921A-4BAD-8A61-699176429D50@oist.jp] =============================================== Tom?? Pluskal G0 Cell Unit, Okinawa Institute of Science and Technology Graduate University 1919-1 Tancha, Onna-son, Okinawa 904-0495, Japan TEL: +81-98-966-8684 Fax: +81-98-966-2890 -------------- next part -------------- An HTML attachment was scrubbed... URL:<http://mailman.unidata.ucar.edu/mailing_lists/archives/visad/attachments/20120531/11a1504e/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: Screen Shot 2012-05-31 at 2.40.27 PM.png Type: image/png Size: 24416 bytes Desc: Screen Shot 2012-05-31 at 2.40.27 PM.png URL:<http://mailman.unidata.ucar.edu/mailing_lists/archives/visad/attachments/20120531/11a1504e/attachment.png> ------------------------------ _______________________________________________ visad mailing list visad@xxxxxxxxxxxxxxxx For list information, to unsubscribe, visit: http://www.unidata.ucar.edu/mailing_lists/ End of visad Digest, Vol 30, Issue 15 *************************************------------------------------ Message: 2 Date: Thu, 31 May 2012 07:57:17 +0000 From: Tomas Pluskal<pluskal@xxxxxxx> To: "visad@xxxxxxxxxxxxxxxx"<visad@xxxxxxxxxxxxxxxx> Subject: Re: [visad] Strange rendering depending on axis range Message-ID:<8AD72553-F8A3-4297-A693-4720AF715CED@xxxxxxx> Content-Type: text/plain; charset="Windows-1252" Dear Gransham, Please note that this issue only appears with texture set to OFF. When I set textures to ON, I get a nice flat plane (using default renderer) . When I use your modified DisplayRendererJ3D, I also get a nice flat plane. Best regards, Tomas On May 31, 2012, at 3:24 PM, Ghansham Sangar wrote:R/Sir I would suggest you to just check with the modified render for the range setting issue. That will be really appreciated. regards Ghansham=============================================== Tom?? Pluskal G0 Cell Unit, Okinawa Institute of Science and Technology Graduate University 1919-1 Tancha, Onna-son, Okinawa 904-0495, Japan TEL: +81-98-966-8684 Fax: +81-98-966-2890 ------------------------------ _______________________________________________ visad mailing list visad@xxxxxxxxxxxxxxxx For list information, to unsubscribe, visit: http://www.unidata.ucar.edu/mailing_lists/ End of visad Digest, Vol 30, Issue 16 *************************************
// // ShadowFunctionOrSetTypeJ3D.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2009 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.java3d; import visad.*; import visad.util.ThreadManager; import javax.media.j3d.*; import java.util.ArrayList; import java.util.List; import java.util.Vector; import java.rmi.*; import java.awt.image.*; /** The ShadowFunctionOrSetTypeJ3D is an abstract parent for ShadowFunctionTypeJ3D and ShadowSetTypeJ3D.<P> */ public class ShadowFunctionOrSetTypeJ3D extends ShadowTypeJ3D { ShadowRealTupleTypeJ3D Domain; ShadowTypeJ3D Range; // null for ShadowSetTypeJ3D private Vector AccumulationVector = new Vector(); public ShadowFunctionOrSetTypeJ3D(MathType t, DataDisplayLink link, ShadowType parent) throws VisADException, RemoteException { super(t, link, parent); if (this instanceof ShadowFunctionTypeJ3D) { Domain = (ShadowRealTupleTypeJ3D) ((FunctionType) Type).getDomain().buildShadowType(link, this); Range = (ShadowTypeJ3D) ((FunctionType) Type).getRange().buildShadowType(link, this); adaptedShadowType = new ShadowFunctionType(t, link, getAdaptedParent(parent), (ShadowRealTupleType) Domain.getAdaptedShadowType(), Range.getAdaptedShadowType()); } else { Domain = (ShadowRealTupleTypeJ3D) ((SetType) Type).getDomain().buildShadowType(Link, this); Range = null; adaptedShadowType = new ShadowSetType(t, link, getAdaptedParent(parent), (ShadowRealTupleType) Domain.getAdaptedShadowType()); } } public ShadowRealTupleTypeJ3D getDomain() { return Domain; } public ShadowTypeJ3D getRange() { return Range; } /** clear AccumulationVector */ public void preProcess() throws VisADException { AccumulationVector.removeAllElements(); if (this instanceof ShadowFunctionTypeJ3D) { Range.preProcess(); } } /** transform data into a Java3D scene graph; add generated scene graph components as children of group; value_array are inherited valueArray values; default_values are defaults for each display.DisplayRealTypeVector; return true if need post-process */ public boolean doTransform(Object group, Data data, final float[] value_array, final float[] default_values, final DataRenderer renderer) throws VisADException, RemoteException { boolean post = true; // FIXME what value for animation? boolean isAnimation1d = false; boolean isTerminal = adaptedShadowType.getIsTerminal(); ScalarMap timeMap = null; // used in the animation case to get control DataDisplayLink[] link_s = renderer.getLinks(); DataDisplayLink link = link_s[0]; Vector scalarMaps = link.getSelectedMapVector(); // only determine if it's an animation if non-terminal. isTerminal will // only be determined if there are scalar maps - defaults to false if (!isTerminal && !scalarMaps.isEmpty()) { // determine if it's an animation MathType mtype = data.getType(); if (mtype instanceof FunctionType) { int ani_map_idx = 0; FunctionType function = (FunctionType) mtype; RealTupleType functionD = function.getDomain(); for (int kk = 0; kk < scalarMaps.size(); kk++) { ScalarMap scalarMap = (ScalarMap) scalarMaps.elementAt(kk); String scalar_name = scalarMap.getScalarName(); if (scalar_name.equals(((RealType) functionD.getComponent(0)).getName())) { if (((scalarMap.getDisplayScalar()).equals(Display.Animation)) && (functionD.getDimension() == 1)) { isAnimation1d = true; ani_map_idx = kk; } } } // animation domain timeMap = (ScalarMap) scalarMaps.elementAt(ani_map_idx); } } // animation logic if (isAnimation1d){ // analyze data's domain (its a Field) Set domainSet = ((Field) data).getDomainSet(); // create and add switch with nodes for animation images int domainLength = domainSet.getLength(); // num of domain nodes Switch swit = (Switch) makeSwitch(domainLength); AnimationControlJ3D control = (AnimationControlJ3D)timeMap.getControl(); addSwitch(group, swit, control, domainSet, renderer); /*** Old code: // render frames for (int i=0; i<domainLength; i++) { BranchGroup node = (BranchGroup) swit.getChild(i); // not necessary, but perhaps if this is modified // int[] lat_lon_indices = renderer.getLatLonIndices(); BranchGroup branch = (BranchGroup) makeBranch(); recurseRange(branch, ((Field) data).getSample(i), value_array, default_values, renderer); node.addChild(branch); // not necessary, but perhaps if this is modified // renderer.setLatLonIndices(lat_lon_indices); } ****/ //jeffmc:First construct the branches List<BranchGroup> branches = new ArrayList<BranchGroup>(); for (int i=0; i<domainLength; i++) { BranchGroup node = (BranchGroup) swit.getChild(i); BranchGroup branch = (BranchGroup) makeBranch(); branches.add(branch); } ThreadManager threadManager = new ThreadManager("animation rendering"); for (int i=0; i<domainLength; i++) { final BranchGroup branch = (BranchGroup) branches.get(i); final Data sample = ((Field) data).getSample(i); final BranchGroup node = (BranchGroup) swit.getChild(i); threadManager.addRunnable(new ThreadManager.MyRunnable() { public void run() throws Exception { recurseRange(branch, sample, value_array, default_values, renderer); node.addChild(branch); } }); } threadManager.runInParallel(); } else { ShadowFunctionOrSetType shadow = (ShadowFunctionOrSetType)adaptedShadowType; post = shadow.doTransform(group, data, value_array, default_values, renderer, this); } ensureNotEmpty(group); return post; } /** * Get the possibly adjusted texture width. * @param data_width The initial texture width. * @return If <code>DisplayImplJ3D.TEXTURE_NPOT</code> then return * <code>data_width</code>, otherwise return the minimum power of two greater * than <code>data_width</code>. * @see DisplayImplJ3D#TEXTURE_NPOT */ public int textureWidth(int data_width) { if (DisplayImplJ3D.TEXTURE_NPOT) return data_width; // must be a power of 2 in Java3D int texture_width = 1; while (texture_width < data_width) texture_width *= 2; return texture_width; } /** * Get the possibly adjusted texture height. * @param data_height The initial texture height. * @return If <code>DisplayImplJ3D.TEXTURE_NPOT</code> then return * <code>data_height</code>, otherwise return the minimum power of two greater * than <code>data_height</code>. * @see DisplayImplJ3D#TEXTURE_NPOT */ public int textureHeight(int data_height) { if (DisplayImplJ3D.TEXTURE_NPOT) return data_height; // must be a power of 2 in Java3D int texture_height = 1; while (texture_height < data_height) texture_height *= 2; return texture_height; } /** * Get the possibly adjusted texture depth. * @param data_depth The initial texture depth. * @return If <code>DisplayImplJ3D.TEXTURE_NPOT</code> then return * <code>data_depth</code>, otherwise return the minimum power of two greater * than <code>data_depth</code>. * @see DisplayImplJ3D#TEXTURE_NPOT */ public int textureDepth(int data_depth) { if (DisplayImplJ3D.TEXTURE_NPOT) return data_depth; // must be a power of 2 in Java3D int texture_depth = 1; while (texture_depth < data_depth) texture_depth *= 2; return texture_depth; } public void adjustZ(float[] coordinates) { if (display.getDisplayRenderer().getMode2D()) { for (int i=2; i<coordinates.length; i+=3) { coordinates[i] = DisplayImplJ3D.BACK2D; } } } public int getImageComponentType(int buffImgType) { if (buffImgType == BufferedImage.TYPE_4BYTE_ABGR) { return ImageComponent2D.FORMAT_RGBA8; } else if (buffImgType == BufferedImage.TYPE_3BYTE_BGR) { return ImageComponent2D.FORMAT_RGB8; } else if (buffImgType == BufferedImage.TYPE_BYTE_GRAY) { return ImageComponent2D.FORMAT_CHANNEL8; } return ImageComponent2D.FORMAT_RGBA8; } public int getTextureType(int buffImgType) { if (buffImgType == BufferedImage.TYPE_4BYTE_ABGR) { return Texture2D.RGBA; } else if (buffImgType == BufferedImage.TYPE_3BYTE_BGR) { return Texture2D.RGB; } else if (buffImgType == BufferedImage.TYPE_BYTE_GRAY) { return Texture2D.INTENSITY; //-return Texture2D.LUMINANCE; Not sure if this matters? } return Texture2D.RGBA; } public void setTexCoords(float[] texCoords, float ratiow, float ratioh) { setTexCoords(texCoords, ratiow, ratioh, false); } public void setTexCoords(float[] texCoords, float ratiow, float ratioh, boolean yUp) { if (!yUp) { // the default // corner 0 texCoords[0] = 0.0f; texCoords[1] = 1.0f; // corner 1 texCoords[2] = ratiow; texCoords[3] = 1.0f; // corner 2 texCoords[4] = ratiow; texCoords[5] = 1.0f - ratioh; // corner 3 texCoords[6] = 0.0f; texCoords[7] = 1.0f - ratioh; } else { // yUp = true, for imageByReference=true // corner 0 texCoords[0] = 0.0f; texCoords[1] = 0.0f; // corner 1 texCoords[2] = 0.0f; texCoords[3] = ratioh; // corner 2 texCoords[4] = ratiow; texCoords[5] = ratioh; // corner 3 texCoords[6] = ratiow; texCoords[7] = 0.0f; } } public float[] setTex3DCoords(int length, int axis, float ratiow, float ratioh, float ratiod) { // need to flip Y and Z in X and Y views? float[] texCoords = new float[12 * length]; if (axis == 2) { for (int i=0; i<length; i++) { int i12 = i * 12; float depth = 0.0f + (ratiod - 0.0f) * i / (length - 1.0f); // corner 0 texCoords[i12] = 0.0f; texCoords[i12 + 1] = 1.0f; texCoords[i12 + 2] = depth; // corner 1 texCoords[i12 + 3] = ratiow; texCoords[i12 + 4] = 1.0f; texCoords[i12 + 5] = depth; // corner 2 texCoords[i12 + 6] = ratiow; texCoords[i12 + 7] = 1.0f - ratioh; texCoords[i12 + 8] = depth; // corner 3 texCoords[i12 + 9] = 0.0f; texCoords[i12 + 10] = 1.0f - ratioh; texCoords[i12 + 11] = depth; } } else if (axis == 1) { for (int i=0; i<length; i++) { int i12 = i * 12; float height = 1.0f - ratioh * i / (length - 1.0f); // corner 0 texCoords[i12] = 0.0f; texCoords[i12 + 1] = height; texCoords[i12 + 2] = 0.0f; // corner 1 texCoords[i12 + 3] = ratiow; texCoords[i12 + 4] = height; texCoords[i12 + 5] = 0.0f; // corner 2 texCoords[i12 + 6] = ratiow; texCoords[i12 + 7] = height; texCoords[i12 + 8] = ratiod; // corner 3 texCoords[i12 + 9] = 0.0f; texCoords[i12 + 10] = height; texCoords[i12 + 11] = ratiod; } } else if (axis == 0) { for (int i=0; i<length; i++) { int i12 = i * 12; float width = 0.0f + (ratiow - 0.0f) * i / (length - 1.0f); // corner 0 texCoords[i12] = width; texCoords[i12 + 1] = 1.0f; texCoords[i12 + 2] = 0.0f; // corner 1 texCoords[i12 + 3] = width; texCoords[i12 + 4] = 1.0f - ratioh; texCoords[i12 + 5] = 0.0f; // corner 2 texCoords[i12 + 6] = width; texCoords[i12 + 7] = 1.0f - ratioh; texCoords[i12 + 8] = ratiod; // corner 3 texCoords[i12 + 9] = width; texCoords[i12 + 10] = 1.0f; texCoords[i12 + 11] = ratiod; } } return texCoords; } // WLH 17 March 2000 private static float EPS = 0.00f; public float[] setTexStackCoords(int length, int axis, float ratiow, float ratioh, float ratiod) { float[] texCoords = new float[8 * length]; if (axis == 2) { for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f + EPS; texCoords[i8 + 1] = 1.0f - EPS; // corner 1 texCoords[i8 + 2] = ratiow - EPS; texCoords[i8 + 3] = 1.0f - EPS; // corner 2 texCoords[i8 + 4] = ratiow - EPS; texCoords[i8 + 5] = 1.0f - ratioh + EPS; // corner 3 texCoords[i8 + 6] = 0.0f + EPS; texCoords[i8 + 7] = 1.0f - ratioh + EPS; } } else if (axis == 1) { // WLH 23 Feb 2000 - flip Z for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f + EPS; texCoords[i8 + 1] = 1.0f - EPS; // corner 1 texCoords[i8 + 2] = ratiow - EPS; texCoords[i8 + 3] = 1.0f - EPS; // corner 2 texCoords[i8 + 4] = ratiow - EPS; texCoords[i8 + 5] = 1.0f - ratiod + EPS; // corner 3 texCoords[i8 + 6] = 0.0f + EPS; texCoords[i8 + 7] = 1.0f - ratiod + EPS; } } else if (axis == 0) { // WLH 23 Feb 2000 - flip Y and Z for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f + EPS; texCoords[i8 + 1] = 1.0f - EPS; // corner 1 texCoords[i8 + 2] = ratioh - EPS; texCoords[i8 + 3] = 1.0f - EPS; // corner 2 texCoords[i8 + 4] = ratioh - EPS; texCoords[i8 + 5] = 1.0f - ratiod + EPS; // corner 3 texCoords[i8 + 6] = 0.0f + EPS; texCoords[i8 + 7] = 1.0f - ratiod + EPS; } } /* WLH 17 March 2000 if (axis == 2) { for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f; texCoords[i8 + 1] = 1.0f; // corner 1 texCoords[i8 + 2] = ratiow; texCoords[i8 + 3] = 1.0f; // corner 2 texCoords[i8 + 4] = ratiow; texCoords[i8 + 5] = 1.0f - ratioh; // corner 3 texCoords[i8 + 6] = 0.0f; texCoords[i8 + 7] = 1.0f - ratioh; } } else if (axis == 1) { // WLH 23 Feb 2000 - flip Z for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f; texCoords[i8 + 1] = 1.0f; // corner 1 texCoords[i8 + 2] = ratiow; texCoords[i8 + 3] = 1.0f; // corner 2 texCoords[i8 + 4] = ratiow; texCoords[i8 + 5] = 1.0f - ratiod; // corner 3 texCoords[i8 + 6] = 0.0f; texCoords[i8 + 7] = 1.0f - ratiod; } } else if (axis == 0) { // WLH 23 Feb 2000 - flip Y and Z for (int i=0; i<length; i++) { int i8 = i * 8; // corner 0 texCoords[i8] = 0.0f; texCoords[i8 + 1] = 1.0f; // corner 1 texCoords[i8 + 2] = ratioh; texCoords[i8 + 3] = 1.0f; // corner 2 texCoords[i8 + 4] = ratioh; texCoords[i8 + 5] = 1.0f - ratiod; // corner 3 texCoords[i8 + 6] = 0.0f; texCoords[i8 + 7] = 1.0f - ratiod; } } */ return texCoords; } public Vector getTextMaps(int i, int[] textIndices) { if (i < 0) { return ((ShadowTextTypeJ3D) Range).getSelectedMapVector(); } else { ShadowTextTypeJ3D text = (ShadowTextTypeJ3D) ((ShadowTupleTypeJ3D) Range).getComponent(textIndices[i]); return text.getSelectedMapVector(); } } public void textureToGroup(Object group, VisADGeometryArray array, BufferedImage image, GraphicsModeControl mode, float constant_alpha, float[] constant_color, int texture_width, int texture_height) throws VisADException { textureToGroup(group, array, image, mode, constant_alpha, constant_color, texture_width, texture_height, false, false, null, false); } public void textureToGroup(Object group, VisADGeometryArray array, BufferedImage image, GraphicsModeControl mode, float constant_alpha, float[] constant_color, int texture_width, int texture_height, boolean byReference, boolean yUp, VisADImageTile tile, boolean smoothen) throws VisADException { GeometryArray geometry = display.makeGeometry(array); // System.out.println("texture geometry"); // create basic Appearance TransparencyAttributes c_alpha = null; if (constant_alpha == 1.0f) { // constant opaque alpha = NONE c_alpha = null; } else if (constant_alpha == constant_alpha) { // c_alpha = new TransparencyAttributes(mode.getTransparencyMode(), c_alpha = new TransparencyAttributes(TransparencyAttributes.BLENDED, constant_alpha); c_alpha.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE); //REUSE GEOMETRY/COLORBYTE REQUIREMENT } else { c_alpha = new TransparencyAttributes(); c_alpha.setTransparencyMode(TransparencyAttributes.BLENDED); c_alpha.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE); //REUSE GEOMETRY/COLORBYTE REQUIREMENT } ColoringAttributes c_color = null; if (constant_color != null && constant_color.length == 3) { c_color = new ColoringAttributes(); c_color.setColor(constant_color[0], constant_color[1], constant_color[2]); } Appearance appearance = makeAppearance(mode, c_alpha, null, geometry, false); appearance.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE); //REUSE GEOMETRY/COLORBYTE REQUIREMENT // create TextureAttributes TextureAttributes texture_attributes = new TextureAttributes(); // WLH 20 June 2001 if (smoothen) { texture_attributes.setTextureMode(TextureAttributes.MODULATE); } else { texture_attributes.setTextureMode(TextureAttributes.REPLACE); } texture_attributes.setPerspectiveCorrectionMode( TextureAttributes.NICEST); appearance.setTextureAttributes(texture_attributes); // create Texture2D // TextureLoader uses 1st argument = 1 /* System.out.println("Texture.BASE_LEVEL = " + Texture.BASE_LEVEL); // 1 System.out.println("Texture.RGBA = " + Texture.RGBA); // 6 */ Texture2D texture = new Texture2D(Texture.BASE_LEVEL, getTextureType(image.getType()), texture_width, texture_height); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(getImageComponentType(image.getType()), image, byReference, yUp); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); if (byReference) { image2d.setCapability(ImageComponent.ALLOW_IMAGE_WRITE); } texture.setImage(0, image2d); // // from TextureLoader // TextureLoader uses 3 for both setMinFilter and setMagFilter /* System.out.println("Texture.FASTEST = " + Texture.FASTEST); // 0 System.out.println("Texture.NICEST = " + Texture.NICEST); // 1 System.out.println("Texture.BASE_LEVEL_POINT = " + Texture.BASE_LEVEL_POINT); // 2 System.out.println("Texture.BASE_LEVEL_LINEAR = " + Texture.BASE_LEVEL_LINEAR); // 3 */ ///for interpolation: if (smoothen) { texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } else { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } texture.setEnable(true); // end of from TextureLoader // Shape3D shape = new Shape3D(geometry, appearance); shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); //REUSE GEOMETRY/COLORBYTE REQUIREMENT shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE); //REUSE GEOMETRY/COLORBYTE REQUIREMENT // WLH 6 April 2000 // ((Group) group).addChild(shape); BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.addChild(shape); if (((Group) group).numChildren() > 0) { ((Group) group).setChild(branch, 0); } else { ((Group) group).addChild(branch); } if (tile != null) { tile.setImageComponent(image2d); } } public void texture3DToGroup(Object group, VisADGeometryArray arrayX, VisADGeometryArray arrayY, VisADGeometryArray arrayZ, VisADGeometryArray arrayXrev, VisADGeometryArray arrayYrev, VisADGeometryArray arrayZrev, BufferedImage[] images, GraphicsModeControl mode, float constant_alpha, float[] constant_color, int texture_width, int texture_height, int texture_depth, DataRenderer renderer) throws VisADException { GeometryArray geometryX = display.makeGeometry(arrayX); GeometryArray geometryY = display.makeGeometry(arrayY); GeometryArray geometryZ = display.makeGeometry(arrayZ); GeometryArray geometryXrev = display.makeGeometry(arrayXrev); GeometryArray geometryYrev = display.makeGeometry(arrayYrev); GeometryArray geometryZrev = display.makeGeometry(arrayZrev); // System.out.println("texture geometry"); // create basic Appearance TransparencyAttributes c_alpha = null; if (constant_alpha == 1.0f) { // constant opaque alpha = NONE c_alpha = null; } else if (constant_alpha == constant_alpha) { // c_alpha = new TransparencyAttributes(mode.getTransparencyMode(), c_alpha = new TransparencyAttributes(TransparencyAttributes.BLENDED, constant_alpha); } else { c_alpha = new TransparencyAttributes(); c_alpha.setTransparencyMode(TransparencyAttributes.BLENDED); } ColoringAttributes c_color = null; if (constant_color != null && constant_color.length == 3) { c_color = new ColoringAttributes(); c_color.setColor(constant_color[0], constant_color[1], constant_color[2]); } Appearance appearance = makeAppearance(mode, c_alpha, null, geometryX, true); // create TextureAttributes TextureAttributes texture_attributes = new TextureAttributes(); // texture_attributes.setTextureMode(TextureAttributes.REPLACE); texture_attributes.setTextureMode(TextureAttributes.MODULATE); texture_attributes.setPerspectiveCorrectionMode( TextureAttributes.NICEST); appearance.setTextureAttributes(texture_attributes); // create Texture2D // TextureLoader uses 1st argument = 1 /* System.out.println("Texture.BASE_LEVEL = " + Texture.BASE_LEVEL); // 1 System.out.println("Texture.RGBA = " + Texture.RGBA); // 6 */ Texture3D texture = new Texture3D(Texture.BASE_LEVEL, Texture.RGBA, texture_width, texture_height, texture_depth); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent3D image3d = new ImageComponent3D(ImageComponent.FORMAT_RGBA, texture_width, texture_height, texture_depth); image3d.setCapability(ImageComponent.ALLOW_IMAGE_READ); for (int i=0; i<texture_depth; i++) { image3d.set(i, images[i]); images[i] = null; // take out the garbage } texture.setImage(0, image3d); // // from TextureLoader // TextureLoader uses 3 for both setMinFilter and setMagFilter /* System.out.println("Texture.FASTEST = " + Texture.FASTEST); // 0 System.out.println("Texture.NICEST = " + Texture.NICEST); // 1 System.out.println("Texture.BASE_LEVEL_POINT = " + Texture.BASE_LEVEL_POINT); // 2 System.out.println("Texture.BASE_LEVEL_LINEAR = " + Texture.BASE_LEVEL_LINEAR); // 3 */ /* for interpolation: */ texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); /* for sampling: texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); */ texture.setEnable(true); // end of from TextureLoader // OK to share appearance ?? Shape3D shapeX = new Shape3D(geometryX, appearance); shapeX.setCapability(Shape3D.ALLOW_APPEARANCE_READ); Shape3D shapeY = new Shape3D(geometryY, appearance); shapeY.setCapability(Shape3D.ALLOW_APPEARANCE_READ); Shape3D shapeZ = new Shape3D(geometryZ, appearance); shapeZ.setCapability(Shape3D.ALLOW_APPEARANCE_READ); Shape3D shapeXrev = new Shape3D(geometryXrev, appearance); Shape3D shapeYrev = new Shape3D(geometryYrev, appearance); Shape3D shapeZrev = new Shape3D(geometryZrev, appearance); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeX.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeX.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shapeY.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeY.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shapeZ.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeZ.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shapeXrev.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeXrev.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shapeYrev.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeYrev.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shapeZrev.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeZrev.setCapability(Shape3D.ALLOW_APPEARANCE_READ); Switch swit = (Switch) makeSwitch(); swit.addChild(shapeX); swit.addChild(shapeY); swit.addChild(shapeZ); swit.addChild(shapeXrev); swit.addChild(shapeYrev); swit.addChild(shapeZrev); // WLH 6 April 2000 // ((Group) group).addChild(swit); BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.addChild(swit); if (((Group) group).numChildren() > 0) { ((Group) group).setChild(branch, 0); } else { ((Group) group).addChild(branch); } ProjectionControlJ3D control = (ProjectionControlJ3D) display.getProjectionControl(); control.addPair(swit, renderer); } public void textureStackToGroup(Object group, VisADGeometryArray arrayX, VisADGeometryArray arrayY, VisADGeometryArray arrayZ, VisADGeometryArray arrayXrev, VisADGeometryArray arrayYrev, VisADGeometryArray arrayZrev, BufferedImage[] imagesX, BufferedImage[] imagesY, BufferedImage[] imagesZ, GraphicsModeControl mode, float constant_alpha, float[] constant_color, int texture_width, int texture_height, int texture_depth, DataRenderer renderer) throws VisADException { GeometryArray[] geometryX = makeGeometrys(arrayX); GeometryArray[] geometryY = makeGeometrys(arrayY); GeometryArray[] geometryZ = makeGeometrys(arrayZ); /* not needed ?? GeometryArray[] geometryXrev = makeGeometrys(arrayXrev); GeometryArray[] geometryYrev = makeGeometrys(arrayYrev); GeometryArray[] geometryZrev = makeGeometrys(arrayZrev); */ int nx = arrayX.coordinates.length; boolean flipX = (arrayX.coordinates[0] > arrayX.coordinates[nx-3]); int ny = arrayY.coordinates.length; boolean flipY = (arrayY.coordinates[1] > arrayY.coordinates[ny-2]); int nz = arrayZ.coordinates.length; boolean flipZ = (arrayZ.coordinates[2] > arrayZ.coordinates[nz-1]); // System.out.println("flipX = " + flipX + " flipY = " + flipY + // " flipZ = " + flipZ); // create Attributes for Appearances TransparencyAttributes c_alpha = null; if (constant_alpha == 1.0f) { // constant opaque alpha = NONE c_alpha = null; } else if (constant_alpha == constant_alpha) { // c_alpha = new TransparencyAttributes(mode.getTransparencyMode(), c_alpha = new TransparencyAttributes(TransparencyAttributes.BLENDED, constant_alpha); } else { c_alpha = new TransparencyAttributes(); c_alpha.setTransparencyMode(TransparencyAttributes.BLENDED); } ColoringAttributes c_color = null; if (constant_color != null && constant_color.length == 3) { c_color = new ColoringAttributes(); c_color.setColor(constant_color[0], constant_color[1], constant_color[2]); } TextureAttributes texture_attributes = new TextureAttributes(); // WLH 17 March 2000 // texture_attributes.setTextureMode(TextureAttributes.MODULATE); texture_attributes.setTextureMode(TextureAttributes.REPLACE); texture_attributes.setPerspectiveCorrectionMode( TextureAttributes.NICEST); int transparencyMode = mode.getTransparencyMode(); OrderedGroup branchX = new OrderedGroup(); branchX.setCapability(Group.ALLOW_CHILDREN_READ); int data_depth = geometryX.length; Shape3D[] shapeX = new Shape3D[data_depth]; for (int ii=0; ii<data_depth; ii++) { int i = flipX ? data_depth-1-ii : ii; int width = imagesX[i].getWidth(); int height = imagesX[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesX[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryX[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeX[i] = new Shape3D(geometryX[i], appearance); shapeX[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeX[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchX.addChild(shapeX[i]); } OrderedGroup branchXrev = new OrderedGroup(); branchXrev.setCapability(Group.ALLOW_CHILDREN_READ); for (int ii=data_depth-1; ii>=0; ii--) { int i = flipX ? data_depth-1-ii : ii; int width = imagesX[i].getWidth(); int height = imagesX[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesX[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryX[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeX[i] = new Shape3D(geometryX[i], appearance); shapeX[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeX[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchXrev.addChild(shapeX[i]); } shapeX = null; OrderedGroup branchY = new OrderedGroup(); branchY.setCapability(Group.ALLOW_CHILDREN_READ); int data_height = geometryY.length; Shape3D[] shapeY = new Shape3D[data_height]; for (int ii=0; ii<data_height; ii++) { int i = flipY ? data_height-1-ii : ii; int width = imagesY[i].getWidth(); int height = imagesY[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); // flip texture on Y axis ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesY[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryY[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeY[i] = new Shape3D(geometryY[i], appearance); shapeY[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeY[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchY.addChild(shapeY[i]); } OrderedGroup branchYrev = new OrderedGroup(); branchYrev.setCapability(Group.ALLOW_CHILDREN_READ); for (int ii=data_height-1; ii>=0; ii--) { int i = flipY ? data_height-1-ii : ii; int width = imagesY[i].getWidth(); int height = imagesY[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); // flip texture on Y axis ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesY[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryY[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeY[i] = new Shape3D(geometryY[i], appearance); shapeY[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeY[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchYrev.addChild(shapeY[i]); } shapeY = null; OrderedGroup branchZ = new OrderedGroup(); branchZ.setCapability(Group.ALLOW_CHILDREN_READ); int data_width = geometryZ.length; Shape3D[] shapeZ = new Shape3D[data_width]; for (int ii=0; ii<data_width; ii++) { int i = flipZ ? data_width-1-ii : ii; int width = imagesZ[i].getWidth(); int height = imagesZ[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesZ[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryZ[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeZ[i] = new Shape3D(geometryZ[i], appearance); shapeZ[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeZ[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchZ.addChild(shapeZ[i]); } OrderedGroup branchZrev = new OrderedGroup(); branchZrev.setCapability(Group.ALLOW_CHILDREN_READ); for (int ii=data_width-1; ii>=0; ii--) { int i = flipZ ? data_width-1-ii : ii; int width = imagesZ[i].getWidth(); int height = imagesZ[i].getHeight(); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, width, height); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, imagesZ[i]); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); Appearance appearance = makeAppearance(mode, c_alpha, null, geometryZ[i], true); appearance.setTextureAttributes(texture_attributes); // WLH 17 March 2000 if (transparencyMode == TransparencyAttributes.FASTEST) { texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); } else { texture.setBoundaryModeS(Texture.CLAMP); texture.setBoundaryModeT(Texture.CLAMP); texture.setMinFilter(Texture.BASE_LEVEL_LINEAR); texture.setMagFilter(Texture.BASE_LEVEL_LINEAR); } texture.setEnable(true); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); shapeZ[i] = new Shape3D(geometryZ[i], appearance); shapeZ[i].setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeZ[i].setCapability(Shape3D.ALLOW_APPEARANCE_READ); branchZrev.addChild(shapeZ[i]); } shapeZ = null; Switch swit = (Switch) makeSwitch(); swit.addChild(branchX); swit.addChild(branchY); swit.addChild(branchZ); swit.addChild(branchXrev); swit.addChild(branchYrev); swit.addChild(branchZrev); // WLH 6 April 2000 // ((Group) group).addChild(swit); BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.addChild(swit); if (((Group) group).numChildren() > 0) { ((Group) group).setChild(branch, 0); } else { ((Group) group).addChild(branch); } ProjectionControlJ3D control = (ProjectionControlJ3D) display.getProjectionControl(); control.addPair(swit, renderer); } /* GeometryArray[] makeGeometrys(VisADGeometryArray array) throws VisADException { int count = array.vertexCount; int depth = count / 4; int color_length = array.colors.length / count; int tex_length = array.texCoords.length / count; GeometryArray[] geometrys = new GeometryArray[depth]; for (int d=0; d<depth; d++) { int i12 = d * 4 * 3; int i4c = d * 4 * color_length; int i4t = d * 4 * tex_length; VisADQuadArray qarray = new VisADQuadArray(); qarray.vertexCount = 4; qarray.coordinates = new float[12]; qarray.texCoords = new float[tex_length * 4]; qarray.colors = new byte[color_length * 4]; qarray.normals = new float[12]; for (int i=0; i<12; i++) { qarray.coordinates[i] = array.coordinates[i12 + i]; qarray.normals[i] = array.normals[i12 + i]; } for (int i=0; i<4*color_length; i++) { qarray.colors[i] = array.colors[i4c + i]; } for (int i=0; i<4*tex_length; i++) { qarray.texCoords[i] = array.texCoords[i4t + i]; } geometrys[d] = display.makeGeometry(qarray); } return geometrys; } */ public GeometryArray[] makeGeometrys(VisADGeometryArray array) throws VisADException { int count = array.vertexCount; int depth = count / 4; VisADGeometryArray[] qarrays = makeVisADGeometrys(array); GeometryArray[] geometrys = new GeometryArray[depth]; for (int d=0; d<depth; d++) { geometrys[d] = display.makeGeometry(qarrays[d]); } return geometrys; } public VisADGeometryArray[] makeVisADGeometrys(VisADGeometryArray array) throws VisADException { int count = array.vertexCount; int depth = count / 4; int color_length = array.colors.length / count; int tex_length = array.texCoords.length / count; VisADGeometryArray[] geometrys = new VisADGeometryArray[depth]; for (int d=0; d<depth; d++) { int i12 = d * 4 * 3; int i4c = d * 4 * color_length; int i4t = d * 4 * tex_length; VisADQuadArray qarray = new VisADQuadArray(); qarray.vertexCount = 4; qarray.coordinates = new float[12]; qarray.texCoords = new float[tex_length * 4]; qarray.colors = new byte[color_length * 4]; qarray.normals = new float[12]; for (int i=0; i<12; i++) { qarray.coordinates[i] = array.coordinates[i12 + i]; qarray.normals[i] = array.normals[i12 + i]; } for (int i=0; i<4*color_length; i++) { qarray.colors[i] = array.colors[i4c + i]; } for (int i=0; i<4*tex_length; i++) { qarray.texCoords[i] = array.texCoords[i4t + i]; } geometrys[d] = qarray; } return geometrys; } public Object makeSwitch() { Switch swit = new Switch(); swit.setCapability(Switch.ALLOW_SWITCH_READ); swit.setCapability(Switch.ALLOW_SWITCH_WRITE); swit.setCapability(BranchGroup.ALLOW_DETACH); swit.setCapability(Group.ALLOW_CHILDREN_READ); swit.setCapability(Group.ALLOW_CHILDREN_WRITE); return swit; } public Object makeSwitch(int length) throws VisADException { Switch swit = (Switch)makeSwitch(); // -TDR swit.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); for (int i=0; i<length; i++) { BranchGroup node = new BranchGroup(); node.setCapability(BranchGroup.ALLOW_DETACH); node.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); node.setCapability(BranchGroup.ALLOW_CHILDREN_READ); node.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); ensureNotEmpty(node); addToSwitch(swit, node); } return swit; } public Object makeBranch() { BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); return branch; } public void addToGroup(Object group, Object branch) throws VisADException { /* WLH 18 Aug 98 empty BranchGroup or Shape3D may cause NullPointerException from Shape3DRetained.setLive */ ensureNotEmpty((BranchGroup) branch); ((BranchGroup) group).addChild((BranchGroup) branch); } public void addToSwitch(Object swit, Object branch) throws VisADException { /* WLH 18 Aug 98 empty BranchGroup or Shape3D may cause NullPointerException from Shape3DRetained.setLive */ ensureNotEmpty((BranchGroup) branch); ((Switch) swit).addChild((BranchGroup) branch); } public void addSwitch(Object group, Object swit, Control control, Set domain_set, DataRenderer renderer) throws VisADException { ((AVControlJ3D) control).addPair((Switch) swit, domain_set, renderer); ((AVControlJ3D) control).init(); // WLH 06 Feb 06 - fix problem adding a new switch to an existing group // ((Group) group).addChild((Switch) swit); BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.addChild((Switch) swit); ((Group) group).addChild(branch); } public boolean recurseRange(Object group, Data data, float[] value_array, float[] default_values, DataRenderer renderer) throws VisADException, RemoteException { return Range.doTransform(group, data, value_array, default_values, renderer); } public boolean wantIndexed() { /* doesn't seem to matter to memory use return true; */ return false; } /** render accumulated Vector of value_array-s to and add to group; then clear AccumulationVector */ public void postProcess(Object group) throws VisADException { if (((ShadowFunctionOrSetType) adaptedShadowType).getFlat()) { int LevelOfDifficulty = getLevelOfDifficulty(); if (LevelOfDifficulty == LEGAL) { throw new UnimplementedException("terminal LEGAL unimplemented: " + "ShadowFunctionOrSetTypeJ3D.postProcess"); } else { // includes !isTerminal // nothing to do } } else { if (this instanceof ShadowFunctionTypeJ3D) { Range.postProcess(group); } } AccumulationVector.removeAllElements(); } }
// // ShadowImageByRefFunctionTypeJ3D.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2009 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.bom; import visad.*; import visad.data.CachedBufferedByteImage; import visad.java3d.*; import visad.data.mcidas.BaseMapAdapter; import visad.data.mcidas.AreaAdapter; import visad.data.gif.GIFForm; import visad.util.Util; import javax.media.j3d.*; import java.io.*; import java.util.Arrays; import java.util.Enumeration; import java.util.Vector; import java.util.Iterator; import java.util.ArrayList; import java.rmi.*; import java.net.URL; import java.awt.event.*; import javax.swing.*; import java.awt.color.*; import java.awt.image.*; /** The ShadowImageFunctionTypeJ3D class shadows the FunctionType class for ImageRendererJ3D, within a DataDisplayLink, under Java3D.<P> */ public class ShadowImageByRefFunctionTypeJ3D extends ShadowFunctionTypeJ3D { private static final int MISSING1 = Byte.MIN_VALUE; // least byte private VisADImageNode imgNode = null; private VisADImageNode prevImgNode = null; private int prevDataWidth = -1; private int prevDataHeight = -1; private int prevNumImages = -1; //- Ghansham (New variables introduced to preserve scaled values and colorTables) private byte scaled_Bytes[][]; //scaled byte values private float scaled_Floats[][]; //scaled Float Values private float rset_scalarmap_lookup[][]; //GHANSHAM:30AUG2011 create a lookup for rset FlatField range values private byte[][] itable; //For single band private byte[][] fast_table; //For fast_lookup private byte[][][] threeD_itable; //for multiband private float[][] color_values; //special case private boolean first_time; //This variable indicates the first tile of the image. private float topo_samples[]; //------------------------------------------------------------------------------ AnimationControlJ3D animControl = null; private boolean reuse = false; private boolean reuseImages = false; int[] inherited_values = null; ShadowFunctionOrSetType adaptedShadowType = null; int levelOfDifficulty = -1; //REUSE GEOMETRY/COLORBYTE VARIABLES (STARTS HERE) boolean regen_colbytes = false; boolean regen_geom = false; boolean apply_alpha = false; //REUSE GEOMETRY/COLORBYTE VARIABLES (ENDS HERE) public ShadowImageByRefFunctionTypeJ3D(MathType t, DataDisplayLink link, ShadowType parent) throws VisADException, RemoteException { super(t, link, parent); } public ShadowImageByRefFunctionTypeJ3D(MathType t, DataDisplayLink link, ShadowType parent, int[] inherited_values, ShadowFunctionOrSetType adaptedShadowType, int levelOfDifficulty) throws VisADException, RemoteException { super(t, link, parent); this.inherited_values = inherited_values; this.adaptedShadowType = adaptedShadowType; this.levelOfDifficulty = levelOfDifficulty; } //REUSE GEOMETRY/COLORBYTE UTILITY METHODS (STARTS HERE) /*This method returns two things: 1. whether any spatial maps has return true in checkTicks() function 2. Current ZAxis value */ private Object[] findSpatialMapTicksAndCurrZValue(ShadowFunctionOrSetType MyAdaptedShadowType, DisplayImpl display, float default_values[], float value_array[], int valueToScalar[], DataRenderer renderer, DataDisplayLink link, int valueArrayLength) throws VisADException, DisplayException { ShadowRealTupleType Domain = MyAdaptedShadowType.getDomain(); ShadowRealType[] DomainComponents = MyAdaptedShadowType.getDomainComponents(); ShadowRealTupleType domain_reference = Domain.getReference(); ShadowRealType[] DC = DomainComponents; if (domain_reference != null && domain_reference.getMappedDisplayScalar()) { DC = MyAdaptedShadowType.getDomainReferenceComponents(); } int[] tuple_index = new int[3]; DisplayTupleType spatial_tuple = null; boolean spatial_maps_check_ticks = false; for (int i=0; i<DC.length; i++) { Enumeration maps = DC[i].getSelectedMapVector().elements(); ScalarMap map = (ScalarMap) maps.nextElement(); if (map.checkTicks(renderer, link)) { spatial_maps_check_ticks = true; } DisplayRealType real = map.getDisplayScalar(); spatial_tuple = real.getTuple(); if (spatial_tuple == null) { /*throw new DisplayException("texture with bad tuple: " + "ShadowImageFunctionTypeJ3D.doTransform");*/ return null; } tuple_index[i] = real.getTupleIndex(); if (maps.hasMoreElements()) { /*throw new DisplayException("texture with multiple spatial: " + "ShadowImageFunctionTypeJ3D.doTransform");*/ return null; } } // get spatial index not mapped from domain_set tuple_index[2] = 3 - (tuple_index[0] + tuple_index[1]); DisplayRealType real = (DisplayRealType) spatial_tuple.getComponent(tuple_index[2]); int value2_index = display.getDisplayScalarIndex(real); float value2 = default_values[value2_index]; for (int i=0; i<valueArrayLength; i++) { if (inherited_values[i] > 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { value2 = value_array[i]; break; } } tuple_index = null; Object ret_values[] = new Object[2]; ret_values[0] = spatial_maps_check_ticks; ret_values[1] = value2; return ret_values; } /*This method retuns whether any of the rangemap has return true in checkTicks()*/ private boolean findRadianceMapColorControlCheckTicks(ScalarMap cmap, ScalarMap cmaps[], DataRenderer renderer, DataDisplayLink link) { BaseColorControl cc; boolean color_map_changed = false; if (cmap!= null) { cc = (BaseColorControl) cmap.getControl(); color_map_changed = (cmap.checkTicks(renderer, link) || cc.checkTicks(renderer,link)); } else if (cmaps !=null) { for (int i = 0; i < cmaps.length; i++) { cc = (BaseColorControl) cmaps[i].getControl(); if (null != cc) { if (cc.checkTicks(renderer,link) || cmaps[i].checkTicks(renderer, link)) { color_map_changed = true; break; } } else { if (cmaps[i].checkTicks(renderer, link)) { color_map_changed = true; break; } } } } return color_map_changed; } /*This method just applies the texture on the already generated geometry. This is used when only colorbytes are generated and geometry is reused. This does away with buildTexture(Linear/Curve) when geometry is reused */ private void applyTexture(Shape3D shape, VisADImageTile tile, boolean apply_alpha, float constant_alpha) { Appearance app = shape.getAppearance(); if (regen_colbytes) { if (animControl == null) { imgNode.setCurrent(0); } } if (apply_alpha) { TransparencyAttributes transp_attribs = app.getTransparencyAttributes(); if (null == transp_attribs) { transp_attribs = new TransparencyAttributes(); transp_attribs.setTransparencyMode(TransparencyAttributes.BLENDED); transp_attribs.setTransparency(constant_alpha); transp_attribs.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE); app.setTransparencyAttributes(transp_attribs); } else { transp_attribs.setTransparency(constant_alpha); } } } /* This is the real nasty logic that decides following things: 1. Regenerate gometry 2. Regenerate ColorBytes 3. Change in alpha Before doing this it inializes range ScalarMaps, constant_alpha value. It also takes out the terminal ShadowType required in case of animations */ //GHANSHAM:30AUG2011 Changed the signaure of initRegenFlags.. passing the ShadowFunctionOrSetType, constant_lapha, cmap and cmaps private void initRegenFlags(ImageRendererJ3D imgRenderer, ShadowFunctionOrSetType MyAdaptedShadowType, float constant_alpha, ScalarMap cmap, ScalarMap cmaps[], Data data, DisplayImpl display, float default_values[], float[] value_array, int []valueToScalar, int valueArrayLength, //DataDisplayLink link, int curved_size) throws BadMappingException, VisADException { DataDisplayLink link, int curved_size, ScalarMap topo_map) throws BadMappingException, VisADException { /*The nasty logic starts from here Retrieves the curve size, zaxis value, alpha, ff hashcode value from Renderer class. Compares them with current values and does other checks. Finally store the current values for above variables in the renderer class.*/ int last_curve_size = imgRenderer.getLastCurveSize(); float last_zaxis_value = imgRenderer.getLastZAxisValue(); float last_alpha_value = imgRenderer.getLastAlphaValue(); long last_data_hash_code = imgRenderer.getLastDataHashCode(); long current_data_hash_code = data.hashCode(); boolean last_adjust_projection_seam = imgRenderer.getLastAdjustProjectionSeam(); //27FEB2012: Projection Seam Change Bug Fix boolean current_adjust_projection_seam = adaptedShadowType.getAdjustProjectionSeam(); //27FEB2012: Projection Seam Change Bug Fix Object map_ticks_z_value[] = findSpatialMapTicksAndCurrZValue(MyAdaptedShadowType, display, default_values, value_array, valueToScalar, imgRenderer, link, valueArrayLength); if (null == map_ticks_z_value) { return; } float current_zaxis_value = Float.parseFloat(map_ticks_z_value[1].toString()); if ((-1 != last_curve_size) && Float.isNaN(last_zaxis_value) && (-1 == last_data_hash_code)) { //First Time regen_colbytes = true; regen_geom = true; apply_alpha = true; } else { boolean data_hash_code_changed = (current_data_hash_code != last_data_hash_code); if (data_hash_code_changed) { //dataref.setData() regen_colbytes = true; regen_geom = true; apply_alpha =true; } else { boolean spatial_maps_check_ticks = Boolean.parseBoolean(map_ticks_z_value[0].toString()); boolean zaxis_value_changed = (Float.compare(last_zaxis_value, current_zaxis_value) != 0); boolean curve_texture_value_change = (last_curve_size != curved_size); boolean alpha_changed = (Float.compare(constant_alpha, last_alpha_value) != 0); boolean radiancemap_colcontrol_check_ticks = findRadianceMapColorControlCheckTicks(cmap, cmaps, imgRenderer, link); boolean projection_seam_changed = (current_adjust_projection_seam != last_adjust_projection_seam); //27FEB2012: Projection Seam Change Bug Fix if (spatial_maps_check_ticks || zaxis_value_changed || curve_texture_value_change || projection_seam_changed) { //change in geometry 27FEB2012: Projection Seam Change Bug Fix regen_geom = true; } else if (alpha_changed) { //change in alpha value apply_alpha = true; } else if (radiancemap_colcontrol_check_ticks) { //change in Radiance ScalarMaps or ColorTable regen_colbytes = true; regen_geom = (null != topo_map); } else { //Assuming that ff.setSamples() has been called. regen_colbytes = true; regen_geom = (null != topo_map); } } } imgRenderer.setLastCurveSize(curved_size); imgRenderer.setLastZAxisValue(current_zaxis_value); imgRenderer.setLastAlphaValue(constant_alpha); imgRenderer.setLastAdjustProjectionSeam(current_adjust_projection_seam); //27FEB2012: Projection Seam Change Bug Fix imgRenderer.setLastDataHashCode(current_data_hash_code); } //REUSE GEOMETRY/COLORBYTE UTILITY METHODS (ENDS HERE) // transform data into a depiction under group public boolean doTransform(Object group, Data data, float[] value_array, float[] default_values, DataRenderer renderer) throws VisADException, RemoteException { DataDisplayLink link = renderer.getLink(); // return if data is missing or no ScalarMaps if (data.isMissing()) { ((ImageRendererJ3D) renderer).markMissingVisADBranch(); return false; } if (levelOfDifficulty == -1) { levelOfDifficulty = getLevelOfDifficulty(); } if (levelOfDifficulty == NOTHING_MAPPED) return false; if (group instanceof BranchGroup && ((BranchGroup) group).numChildren() > 0) { Node g = ((BranchGroup) group).getChild(0); // WLH 06 Feb 06 - support switch in a branch group. if (g instanceof BranchGroup && ((BranchGroup) g).numChildren() > 0) { reuseImages = true; } } DisplayImpl display = getDisplay(); int cMapCurveSize = (int) default_values[display.getDisplayScalarIndex(Display.CurvedSize)]; int curved_size = (cMapCurveSize > 0) ? cMapCurveSize : display.getGraphicsModeControl().getCurvedSize(); // length of ValueArray int valueArrayLength = display.getValueArrayLength(); // mapping from ValueArray to DisplayScalar int[] valueToScalar = display.getValueToScalar(); //GHANSHAM:30AUG2011 Restrutured the code to extract the constant_alpha, cmap, cmaps and ShadowFunctionType so that they can be passed to initRegenFlags method if (adaptedShadowType == null) { adaptedShadowType = (ShadowFunctionOrSetType) getAdaptedShadowType(); } boolean anyContour = adaptedShadowType.getAnyContour(); boolean anyFlow = adaptedShadowType.getAnyFlow(); boolean anyShape = adaptedShadowType.getAnyShape(); boolean anyText = adaptedShadowType.getAnyText(); if (anyContour || anyFlow || anyShape || anyText) { throw new BadMappingException("no contour, flow, shape or text allowed"); } FlatField imgFlatField = null; Set domain_set = ((Field) data).getDomainSet(); ShadowRealType[] DomainComponents = adaptedShadowType.getDomainComponents(); int numImages = 1; if (!adaptedShadowType.getIsTerminal()) { Vector domain_maps = DomainComponents[0].getSelectedMapVector(); ScalarMap amap = null; if (domain_set.getDimension() == 1 && domain_maps.size() == 1) { ScalarMap map = (ScalarMap) domain_maps.elementAt(0); if (Display.Animation.equals(map.getDisplayScalar())) { amap = map; } } if (amap == null) { throw new BadMappingException("time must be mapped to Animation"); } animControl = (AnimationControlJ3D) amap.getControl(); numImages = domain_set.getLength(); adaptedShadowType = (ShadowFunctionOrSetType) adaptedShadowType.getRange(); DomainComponents = adaptedShadowType.getDomainComponents(); imgFlatField = (FlatField) ((FieldImpl)data).getSample(0); } else { imgFlatField = (FlatField)data; } // check that range is single RealType mapped to RGB only ShadowRealType[] RangeComponents = adaptedShadowType.getRangeComponents(); int rangesize = RangeComponents.length; if (rangesize != 1 && rangesize != 3) { throw new BadMappingException("image values must single or triple"); } ScalarMap cmap = null; ScalarMap[] cmaps = null; int[] permute = {-1, -1, -1}; boolean hasAlpha = false; ScalarMap topo_map = null; if (rangesize == 1) { Vector mvector = RangeComponents[0].getSelectedMapVector(); //Added to allow Range Component Mapping to ZAxis if (mvector.size() != 1 && mvector.size()!= 2) { throw new BadMappingException("image values must be mapped to RGB only or RGB and Axis only"); } ScalarMap scalar_map = null; for (int i = 0; i < mvector.size(); i++) { scalar_map = (ScalarMap) mvector.elementAt(i); DisplayRealType display_scalar = scalar_map.getDisplayScalar(); if (display_scalar.equals(Display.RGB)) { cmap = scalar_map; } else if (display_scalar.equals(Display.RGBA)) { hasAlpha = true; cmap = scalar_map; } else if (display_scalar.equals(Display.ZAxis)) { topo_map = scalar_map; } else { throw new BadMappingException("image values must be mapped to RGB only or RGB and Axis only"); } } /*if (mvector.size() != 1) { throw new BadMappingException("image values must be mapped to RGB only"); } cmap = (ScalarMap) mvector.elementAt(0); if (Display.RGB.equals(cmap.getDisplayScalar())) { } else if (Display.RGBA.equals(cmap.getDisplayScalar())) { hasAlpha = true; } else { throw new BadMappingException("image values must be mapped to RGB or RGBA"); }*/ } else { cmaps = new ScalarMap[3]; for (int i=0; i<3; i++) { Vector mvector = RangeComponents[i].getSelectedMapVector(); if (mvector.size() != 1) { throw new BadMappingException("image values must be mapped to color only"); } cmaps[i] = (ScalarMap) mvector.elementAt(0); if (Display.Red.equals(cmaps[i].getDisplayScalar())) { permute[0] = i; } else if (Display.Green.equals(cmaps[i].getDisplayScalar())) { permute[1] = i; } else if (Display.Blue.equals(cmaps[i].getDisplayScalar())) { permute[2] = i; } else if (Display.RGB.equals(cmaps[i].getDisplayScalar())) { //Inserted by Ghansham for Mapping all the three scalarMaps to Display.RGB (starts here) permute[i] = i; } else { ////Inserted by Ghansham for Mapping all the three scalarMaps to Display.RGB(ends here) throw new BadMappingException("image values must be mapped to Red, Green or Blue only"); } } if (permute[0] < 0 || permute[1] < 0 || permute[2] < 0) { throw new BadMappingException("image values must be mapped to Red, Green or Blue only"); } //Inserted by Ghansham for Checking that all should be mapped to Display.RGB or not even a single one should be mapped to Display.RGB(starts here) //This is to check if there is a single Display.RGB ScalarMap int indx = -1; for (int i = 0; i < 3; i++) { if (cmaps[i].getDisplayScalar().equals(Display.RGB)) { indx = i; break; } } if (indx != -1){ //if there is a even a single Display.RGB ScalarMap, others must also Display.RGB only for (int i = 0; i < 3; i++) { if (i !=indx && !(cmaps[i].getDisplayScalar().equals(Display.RGB))) { throw new BadMappingException("image values must be mapped to (Red, Green, Blue) or (RGB,RGB,RGB) only"); } } } //Inserted by Ghansham for Checking that all should be mapped to Display.RGB or not even a single one should be mapped to Display.RGB(Ends here) } float constant_alpha = default_values[display.getDisplayScalarIndex(Display.Alpha)]; int color_length; ImageRendererJ3D imgRenderer = (ImageRendererJ3D) renderer; int imageType = imgRenderer.getSuggestedBufImageType(); if (imageType == BufferedImage.TYPE_4BYTE_ABGR) { color_length = 4; if (!hasAlpha) { color_length = 3; imageType = BufferedImage.TYPE_3BYTE_BGR; } } else if (imageType == BufferedImage.TYPE_3BYTE_BGR) { color_length = 3; } else if (imageType == BufferedImage.TYPE_USHORT_GRAY) { color_length = 2; } else if (imageType == BufferedImage.TYPE_BYTE_GRAY) { color_length = 1; } else { // we shouldn't ever get here because the renderer validates the // imageType before we get it, but just in case... throw new VisADException("renderer returned unsupported image type"); } if (color_length == 4) constant_alpha = Float.NaN; // WLH 6 May 2003 //REUSE GEOMETRY/COLORBYTE LOGIC (STARTS HERE) regen_colbytes = false; regen_geom = false; apply_alpha = false; //initRegenFlags((ImageRendererJ3D)renderer, adaptedShadowType, constant_alpha, cmap, cmaps, data, display, default_values, value_array, valueToScalar, valueArrayLength, link, curved_size); initRegenFlags((ImageRendererJ3D)renderer, adaptedShadowType, constant_alpha, cmap, cmaps, data, display, default_values, value_array, valueToScalar, valueArrayLength, link, curved_size, topo_map); if(!reuseImages) { regen_geom = true; regen_colbytes = true; apply_alpha = true; } /** System.err.println("Regenerate Color Bytes:" + regen_colbytes); System.err.println("Regenerate Geometry:" + regen_geom); System.err.println("Apply Alpha:" + apply_alpha); System.err.println("ReuseImages:" + reuseImages); */ //REUSE GEOMETRY/COLORBYTE LOGIC (ENDS HERE) prevImgNode = ((ImageRendererJ3D)renderer).getImageNode(); BranchGroup bgImages = null; /*REUSE GEOM/COLBYTE: Replaced reuse with reuseImages. Earlier else part of this decision was never being used. The reason was reuse was always set to false. Compare with your version. Added one extra line in the else part where I extract the bgImages from the switch. Now else part occurs when either reuse_colbytes or regen_geom is true. But when regen_colbytes and regen_geom both are true, then I assume that a new flatfield is set so go with the if part. */ if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE GEOM/COLBYTE:Earlier reuse variable was used. Replaced it with reuseImages. //Added regen_colbytes and regen_geom. //This is used when either its first time or full new data has been with different dims. BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); Switch swit = (Switch) makeSwitch(); imgNode = new VisADImageNode(); bgImages = new BranchGroup(); bgImages.setCapability(BranchGroup.ALLOW_DETACH); bgImages.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); bgImages.setCapability(BranchGroup.ALLOW_CHILDREN_READ); bgImages.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); swit.addChild(bgImages); swit.setWhichChild(0); branch.addChild(swit); imgNode.setBranch(branch); imgNode.setSwitch(swit); ((ImageRendererJ3D)renderer).setImageNode(imgNode); if ( ((BranchGroup) group).numChildren() > 0 ) { ((BranchGroup)group).setChild(branch, 0); } else { ((BranchGroup)group).addChild(branch); /* // make sure group is live. group not empty (above addChild) if (group instanceof BranchGroup) { ((ImageRendererJ3D) renderer).setBranchEarly((BranchGroup) group); } */ } } else { //REUSE GEOM/COLBYTE: If its not the first time. And the dims have not changed but either color bytes or geometry has changed. imgNode = ((ImageRendererJ3D)renderer).getImageNode(); bgImages = (BranchGroup) imgNode.getSwitch().getChild(0); //REUSE GEOM/COLBYTE:Extract the bgImages from the avaialable switch } GraphicsModeControl mode = (GraphicsModeControl) display.getGraphicsModeControl().clone(); // get some precomputed values useful for transform // mapping from ValueArray to MapVector int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); Unit[] dataUnits = null; CoordinateSystem dataCoordinateSystem = null; if (animControl != null) { Switch swit = new SwitchNotify(imgNode, numImages); ((AVControlJ3D) animControl).addPair((Switch) swit, domain_set, renderer); ((AVControlJ3D) animControl).init(); } domain_set = imgFlatField.getDomainSet(); dataUnits = ((Function) imgFlatField).getDomainUnits(); dataCoordinateSystem = ((Function) imgFlatField).getDomainCoordinateSystem(); int domain_length = domain_set.getLength(); int[] lengths = ((GriddedSet) domain_set).getLengths(); int data_width = lengths[0]; int data_height = lengths[1]; imgNode.numImages = numImages; imgNode.data_width = data_width; imgNode.data_height = data_height; int texture_width_max = link.getDisplay().getDisplayRenderer().getTextureWidthMax(); int texture_height_max = link.getDisplay().getDisplayRenderer().getTextureWidthMax(); int texture_width = textureWidth(data_width); int texture_height = textureHeight(data_height); if (reuseImages) { if (prevImgNode.numImages != numImages || prevImgNode.data_width != data_width || prevImgNode.data_height != data_height) { reuseImages = false; } } if (reuseImages) { imgNode.numChildren = prevImgNode.numChildren; imgNode.imageTiles = prevImgNode.imageTiles; } else { Mosaic mosaic = new Mosaic(data_height, texture_height_max, data_width, texture_width_max); for (Iterator iter = mosaic.iterator(); iter.hasNext();) { Tile tile = (Tile) iter.next(); imgNode.addTile(new VisADImageTile(numImages, tile.height, tile.y_start, tile.width, tile.x_start)); } } prevImgNode = imgNode; ShadowRealTupleType Domain = adaptedShadowType.getDomain(); Unit[] domain_units = ((RealTupleType) Domain.getType()).getDefaultUnits(); float[] constant_color = null; // check that domain is only spatial if (!Domain.getAllSpatial() || Domain.getMultipleDisplayScalar()) { throw new BadMappingException("domain must be only spatial"); } // check domain and determine whether it is square or curved texture boolean isTextureMap = adaptedShadowType.getIsTextureMap() && (domain_set instanceof Linear2DSet || (domain_set instanceof LinearNDSet && domain_set.getDimension() == 2)) && //(domain_set.getManifoldDimension() == 2); (domain_set.getManifoldDimension() == 2 && (topo_map == null)); boolean curvedTexture = adaptedShadowType.getCurvedTexture() && !isTextureMap && curved_size > 0 && (domain_set instanceof Gridded2DSet || (domain_set instanceof GriddedSet && domain_set.getDimension() == 2)) && (domain_set.getManifoldDimension() == 2); if (group instanceof BranchGroup) { ((ImageRendererJ3D) renderer).setBranchEarly((BranchGroup) group); } first_time =true; //Ghansham: this variable just indicates to makeColorBytes whether it's the first tile of the image boolean branch_added = false; if (isTextureMap) { // linear texture if (imgNode.getNumTiles() == 1) { VisADImageTile tile = imgNode.getTile(0); if (regen_colbytes) { //REUSE COLBYTES: regenerate only if required makeColorBytesDriver(imgFlatField, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, data_width, data_height, imageType, tile, 0, topo_map != null); } if (regen_geom) { //REUSE : REGEN GEOM regenerate the geometry buildLinearTexture(bgImages, domain_set, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, display, tile); } else { //REUSE Reuse the branch fully along with geometry. Just apply the colorbytes(Buffered Image) BranchGroup Branch_L1 = (BranchGroup) bgImages.getChild(0); Shape3D shape = (Shape3D) Branch_L1.getChild(0); applyTexture(shape, tile, apply_alpha, constant_alpha); } } else { BranchGroup branch = null; //if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE: Make a fresh branch if (!reuseImages) { branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } else { //REUSE the branch branch = (BranchGroup) bgImages.getChild(0); } int branch_tile_indx = 0; //REUSE: to get the branch for a tile in case of multi-tile rendering for (Iterator iter = imgNode.getTileIterator(); iter.hasNext();) { VisADImageTile tile = (VisADImageTile) iter.next(); if (regen_colbytes) { //REUSE COLBYTES: regenerate only if required makeColorBytesDriver(imgFlatField, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, data_width, data_height, imageType, tile, 0, topo_map != null); first_time = false; //Ghansham: setting 'first_time' variable false after the first tile has been generated } if (regen_geom) { //REUSE: Regenerate the geometry float[][] g00 = ((GriddedSet)domain_set).gridToValue( new float[][] {{tile.xStart}, {tile.yStart}}); float[][] g11 = ((GriddedSet)domain_set).gridToValue( new float[][] {{tile.xStart+tile.width-1}, {tile.yStart+tile.height-1}}); double x0 = g00[0][0]; double x1 = g11[0][0]; double y0 = g00[1][0]; double y1 = g11[1][0]; Set dset = new Linear2DSet(x0, x1, tile.width, y0, y1, tile.height); BranchGroup branch1 = null; if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE: Make a fresh branch for each tile branch1 = new BranchGroup(); branch1.setCapability(BranchGroup.ALLOW_DETACH); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } else { //REUSE: Reuse the already built branch for each tile branch1 = (BranchGroup) branch.getChild(branch_tile_indx); } buildLinearTexture(branch1, dset, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, display, tile); if (!reuseImages|| (regen_colbytes && regen_geom)) { branch.addChild(branch1); } g00 = null; g11 = null; dset = null; } else { //REUSE Reuse the branch fully along with geometry. Just apply the colorbytes(Buffered Image) BranchGroup branch1 = (BranchGroup) branch.getChild(branch_tile_indx); BranchGroup branch2 = (BranchGroup) branch1.getChild(0); //Beause we create a branch in textureToGroup Shape3D shape = (Shape3D) branch2.getChild(0); applyTexture(shape, tile, apply_alpha, constant_alpha); } if (0 == branch_tile_indx) { //Add the branch to get rendered as early as possible if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE : Add a new branch if created if (((Group) bgImages).numChildren() > 0) { ((Group) bgImages).setChild(branch, 0); } else { ((Group) bgImages).addChild(branch); } } } branch_tile_indx++; } } } // end if (isTextureMap) else if (curvedTexture) { int[] lens = ((GriddedSet)domain_set).getLengths(); int[] domain_lens = lens; if (imgNode.getNumTiles() == 1) { VisADImageTile tile = imgNode.getTile(0); if (regen_colbytes) { //REUSE COLBYTES: regenerate only if required makeColorBytesDriver(imgFlatField, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, data_width, data_height, imageType, tile, 0, topo_map != null); } if (regen_geom) { //REUSE: REGEN GEOM regenerate buildCurvedTexture(bgImages, domain_set, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, display, curved_size, Domain, dataCoordinateSystem, renderer, adaptedShadowType, new int[] {0,0}, //domain_lens[0], domain_lens[1], null, domain_lens[0], domain_lens[1], tile); domain_lens[0], domain_lens[1], null, domain_lens[0], domain_lens[1], tile, topo_samples, topo_map); } else { //REUSE Reuse the branch fully along with geometry. Just apply the colorbytes(Buffered Image) BranchGroup Branch_L1 = (BranchGroup) bgImages.getChild(0); Shape3D shape = (Shape3D) Branch_L1.getChild(0); applyTexture(shape, tile, apply_alpha, constant_alpha); } } else { float[][] samples = ((GriddedSet)domain_set).getSamples(false); BranchGroup branch = null; if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE: Make a fresh branch branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } else { //REUSE: Reuse already built branch branch = (BranchGroup) bgImages.getChild(0); } int branch_tile_indx = 0; //REUSE: to get the branch for a tile in case of multi-tile rendering for (Iterator iter = imgNode.getTileIterator(); iter.hasNext();) { VisADImageTile tile = (VisADImageTile) iter.next(); if (regen_colbytes) { //REUSE COLBYTES: regenerate only if required makeColorBytesDriver(imgFlatField, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, data_width, data_height, imageType, tile, 0, topo_map != null); first_time = false; //Ghansham: setting 'first_time' variable false after the first tile has been generated } if (regen_geom) { //REUSE REGEN GEOM regenerate geometry BranchGroup branch1 = null; if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE: Make a fresh branch group for each tile branch1 = new BranchGroup(); branch1.setCapability(BranchGroup.ALLOW_DETACH); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch1.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); } else { //REUSE: Reuse the already existing branch for each tile branch1 = (BranchGroup) branch.getChild(branch_tile_indx); } buildCurvedTexture(branch1, null, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, display, curved_size, Domain, dataCoordinateSystem, renderer, adaptedShadowType, new int[] {tile.xStart,tile.yStart}, tile.width, tile.height, samples, domain_lens[0], domain_lens[1], tile, topo_samples, topo_map); if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE: Add newly created branch branch.addChild(branch1); } } else { //REUSE Reuse the branch fully along with geometry. Just apply the colorbytes(Buffered Image) BranchGroup branch1 = (BranchGroup) branch.getChild(branch_tile_indx); BranchGroup branch2 = (BranchGroup) branch1.getChild(0); Shape3D shape = (Shape3D) branch2.getChild(0); applyTexture(shape, tile, apply_alpha, constant_alpha); } if (0 == branch_tile_indx) { //Add the branch to get rendered as early as possible if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE : Add a new branch if created if (((Group) bgImages).numChildren() > 0) { ((Group) bgImages).setChild(branch, 0); } else { ((Group) bgImages).addChild(branch); } } } branch_tile_indx++; } } } // end if (curvedTexture) else { // !isTextureMap && !curvedTexture throw new BadMappingException("must be texture map or curved texture map"); } topo_samples = null; // make sure group is live. group not empty (above addChild) /*if (group instanceof BranchGroup) { ((ImageRendererJ3D) renderer).setBranchEarly((BranchGroup) group); }*/ for (int k=1; k<numImages; k++) { FlatField ff = (FlatField) ((Field)data).getSample(k); CoordinateSystem dcs = ff.getDomainCoordinateSystem(); GriddedSet domSet = (GriddedSet) ff.getDomainSet(); int[] lens = domSet.getLengths(); // if image dimensions, or dataCoordinateSystem not equal to first image, resample to first if (regen_colbytes) { //REUSE COLBYTES: resample the flatfield only if colorbytes need to be regenerated if ( (lens[0] != data_width || lens[1] != data_height) || !(dcs.equals(dataCoordinateSystem))) { ff = (FlatField) ff.resample(imgFlatField.getDomainSet(), Data.NEAREST_NEIGHBOR, Data.NO_ERRORS); } } first_time = true; scaled_Bytes = null; //scaled byte values scaled_Floats = null; //scaled Float Values fast_table = null; rset_scalarmap_lookup = null; //GHANSHAM:30AUG2011 create a lookup for rset FlatField range values itable = null; //For single band threeD_itable = null; //for multiband color_values = null; //special case for (Iterator iter = imgNode.getTileIterator(); iter.hasNext();) { VisADImageTile tile = (VisADImageTile) iter.next(); if(regen_colbytes) { //REUSE COLBYTES: regenerate colobytes only if required makeColorBytesDriver(ff, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, data_width, data_height, imageType, tile, k, false); first_time = false; } //image.bytesChanged(byteData); } } cmaps = null; first_time = true; scaled_Bytes = null; //scaled byte values scaled_Floats = null; //scaled Float Values fast_table = null; rset_scalarmap_lookup = null; //GHANSHAM:30AUG2011 create a lookup for rset FlatField range values itable = null; //For single band threeD_itable = null; //for multiband color_values = null; //special case ensureNotEmpty(bgImages); return false; } // This function calls makeColorBytes function (Ghansham) public void makeColorBytesDriver(Data imgFlatField, ScalarMap cmap, ScalarMap[] cmaps, float constant_alpha, ShadowRealType[] RangeComponents, int color_length, int domain_length, int[] permute, int data_width, int data_height, int imageType, VisADImageTile tile, int image_index, boolean extract_topo) throws VisADException, RemoteException { BufferedImage image = null; byte byteData[] = null; int tile_width = tile.width; int tile_height = tile.height; int xStart = tile.xStart; int yStart = tile.yStart; int texture_width = textureWidth(tile_width); int texture_height = textureHeight(tile_height); if (!reuseImages) { image = createImageByRef(texture_width, texture_height, imageType); tile.setImage(image_index, image); } else { //image = (CachedBufferedByteImage) tile.getImage(0); image = (BufferedImage) tile.getImage(image_index); } java.awt.image.Raster raster = image.getRaster(); DataBuffer db = raster.getDataBuffer(); byteData = ((DataBufferByte)db).getData(); java.util.Arrays.fill(byteData, (byte)0); makeColorBytes(imgFlatField, cmap, cmaps, constant_alpha, RangeComponents, color_length, domain_length, permute, byteData, data_width, data_height, tile_width, tile_height, xStart, yStart, texture_width, texture_height, extract_topo); } /* New version contributed by Ghansham (ISRO) This function scales the flatfield values and the colortable for the first tile only using the first_time variable. Rest of the time it only uses scaled values and color table to generate colorbytes for respective tile. Just see the first_time variable use. That is the only difference between this function and earlier function makeColorBytes(). Some new class variables have been introduced to preserve scaled values and colortable. They are made null after all the tiles for a single image has been generated. At the end of doTransform(), they are made null. */ public void makeColorBytes(Data data, ScalarMap cmap, ScalarMap[] cmaps, float constant_alpha, ShadowRealType[] RangeComponents, int color_length, int domain_length, int[] permute, byte[] byteData, int data_width, int data_height, int tile_width, int tile_height, int xStart, int yStart, int texture_width, int texture_height, boolean extract_topo) throws VisADException, RemoteException { if (cmap != null) { BaseColorControl control = (BaseColorControl) cmap.getControl(); float[][] table = control.getTable(); Set rset = null; boolean is_default_unit = false; if (data instanceof FlatField) { // for fast byte color lookup, need: // 1. range data values are packed in bytes //bytes = ((FlatField) data).grabBytes(); if (first_time) { scaled_Bytes = ((FlatField) data).grabBytes(); } // 2. range set is Linear1DSet Set[] rsets = ((FlatField) data). getRangeSets(); if (rsets != null) rset = rsets[0]; // 3. data Unit equals default Unit RealType rtype = (RealType) RangeComponents[0].getType(); Unit def_unit = rtype.getDefaultUnit(); if (def_unit == null) { is_default_unit = true; } else { Unit[][] data_units = ((FlatField) data).getRangeUnits(); Unit data_unit = (data_units == null) ? null : data_units[0][0]; is_default_unit = def_unit.equals(data_unit); } } if (table != null) { // combine color table RGB components into ints if (first_time) { itable = new byte[table[0].length][4]; // int r, g, b, a = 255; int r, g, b; int c = (int) (255.0 * (1.0f - constant_alpha)); int a = (c < 0) ? 0 : ((c > 255) ? 255 : c); for (int j=0; j<table[0].length; j++) { c = (int) (255.0 * table[0][j]); r = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * table[1][j]); g = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * table[2][j]); b = (c < 0) ? 0 : ((c > 255) ? 255 : c); if (color_length == 4) { c = (int) (255.0 * table[3][j]); a = (c < 0) ? 0 : ((c > 255) ? 255 : c); } itable[j][0] = (byte) r; itable[j][1] = (byte) g; itable[j][2] = (byte) b; itable[j][3] = (byte) a; } } int tblEnd = table[0].length - 1; // get scale for color table int table_scale = table[0].length; if (data instanceof ImageFlatField && scaled_Bytes != null && is_default_unit) { if (ImageFlatField.DEBUG) { System.err.println("ShadowImageFunctionTypeJ3D.doTransform: " + "cmap != null: looking up color values"); } // avoid unpacking floats for ImageFlatFields if (first_time) { scaled_Bytes[0]= cmap.scaleValues(scaled_Bytes[0], table_scale); } // fast lookup from byte values to color bytes byte[] bytes0 = scaled_Bytes[0]; int k =0; int color_length_times_texture_width = texture_width*color_length; for (int y=0; y<tile_height; y++) { int image_col_factor = (y+yStart)*data_width + xStart; k= y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { int i = x + image_col_factor; int j = bytes0[i] & 0xff; // unsigned // clip to table int ndx = j < 0 ? 0 : (j > tblEnd ? tblEnd : j); if (color_length == 4) { byteData[k] = itable[ndx][3]; byteData[k+1] = itable[ndx][2]; byteData[k+2] = itable[ndx][1]; byteData[k+3] = itable[ndx][0]; } if (color_length == 3) { byteData[k] = itable[ndx][2]; byteData[k+1] = itable[ndx][1]; byteData[k+2] = itable[ndx][0]; } if (color_length == 1) { byteData[k] = itable[ndx][0]; } k += color_length; } } } else if (scaled_Bytes != null && scaled_Bytes[0] != null && is_default_unit && rset != null && rset instanceof Linear1DSet) { // fast since FlatField with bytes, data Unit equals default // Unit and range set is Linear1DSet // get "scale and offset" for Linear1DSet if (first_time) { double first = ((Linear1DSet) rset).getFirst(); double step = ((Linear1DSet) rset).getStep(); // get scale and offset for ScalarMap double[] so = new double[2]; double[] da = new double[2]; double[] di = new double[2]; cmap.getScale(so, da, di); double scale = so[0]; double offset = so[1]; // combine scales and offsets for Set, ScalarMap and color table float mult = (float) (table_scale * scale * step); float add = (float) (table_scale * (offset + scale * first)); // build table for fast color lookup fast_table = new byte[256][]; for (int j=0; j<256; j++) { int index = j - 1; if (index >= 0) { // not missing int k = (int) (add + mult * index); // clip to table int ndx = k < 0 ? 0 : (k > tblEnd ? tblEnd : k); fast_table[j] = itable[ndx]; } } } // now do fast lookup from byte values to color bytes byte[] bytes0 = scaled_Bytes[0]; int k = 0; int color_length_times_texture_width = texture_width*color_length; for (int y=0; y<tile_height; y++) { int image_col_factor = (y+yStart)*data_width + xStart; k = y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { int i = x + image_col_factor; int ndx = ((int) bytes0[i]) - MISSING1; if (color_length == 4) { byteData[k] = itable[ndx][3]; byteData[k+1] = itable[ndx][2]; byteData[k+2] = itable[ndx][1]; byteData[k+3] = itable[ndx][0]; } if (color_length == 3) { byteData[k] = itable[ndx][2]; byteData[k+1] = itable[ndx][1]; byteData[k+2] = itable[ndx][0]; } if (color_length == 1) { byteData[k] = itable[ndx][0]; } k+=color_length; } } } else { // medium speed way to build texture colors if (first_time) { scaled_Bytes = null; scaled_Floats = ((Field) data).getFloats(false); topo_samples = new float[scaled_Floats[0].length]; System.arraycopy(scaled_Floats[0], 0, topo_samples, 0, scaled_Floats[0].length); //GHANSHAM:30AUG2011 If rset can be used to create a lookup for range values, create them if (rset instanceof Integer1DSet) { rset_scalarmap_lookup = new float[1][rset.getLength()]; for (int i = 0; i < rset_scalarmap_lookup[0].length; i++) { rset_scalarmap_lookup[0][i] = i; } rset_scalarmap_lookup[0] = cmap.scaleValues(rset_scalarmap_lookup[0], false); } else { scaled_Floats[0] = cmap.scaleValues(scaled_Floats[0]); } } // now do fast lookup from byte values to color bytes float[] values0 = scaled_Floats[0]; int k = 0; int color_length_times_texture_width = texture_width*color_length; int image_col_offset = yStart*data_width + xStart; int image_col_factor = 0; for (int y=0; y<tile_height; y++) { image_col_factor = y*data_width+image_col_offset; k = y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { int i = x + image_col_factor; if (!Float.isNaN(values0[i])) { // not missing int j = 0; //GHANSHAM:30AUG2011 Use the rset lookup to find scaled Range Values if (null != rset_scalarmap_lookup && null != rset_scalarmap_lookup[0]) { j = (int) (table_scale*rset_scalarmap_lookup[0][(int)values0[i]]); } else { j = (int) (table_scale*values0[i]); } // clip to table int ndx = j < 0 ? 0 : (j > tblEnd ? tblEnd : j); if (color_length == 4) { byteData[k] = itable[ndx][3]; byteData[k+1] = itable[ndx][2]; byteData[k+2] = itable[ndx][1]; byteData[k+3] = itable[ndx][0]; } if (color_length == 3) { byteData[k] = itable[ndx][2]; byteData[k+1] = itable[ndx][1]; byteData[k+2] = itable[ndx][0]; } if (color_length == 1) { byteData[k] = itable[ndx][0]; } } k+=color_length; } } } } else { // if (table == null) // slower, more general way to build texture colors if (first_time) { // call lookupValues which will use function since table == null scaled_Bytes = null; itable = null; scaled_Floats = ((Field) data).getFloats(false); scaled_Floats[0] = cmap.scaleValues(scaled_Floats[0]); topo_samples = new float[scaled_Floats[0].length]; System.arraycopy(scaled_Floats[0], 0, topo_samples, 0, scaled_Floats[0].length); color_values = control.lookupValues(scaled_Floats[0]); } // combine color RGB components into bytes // int r, g, b, a = 255; int r, g, b; int c = (int) (255.0 * (1.0f - constant_alpha)); int a = (c < 0) ? 0 : ((c > 255) ? 255 : c); int k = 0; int color_length_times_texture_width = texture_width*color_length; int image_col_offset = yStart*data_width + xStart; int image_col_factor = 0; for (int y=0; y<tile_height; y++) { image_col_factor = y*data_width+image_col_offset; k = y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { int i = x + image_col_factor; if (!Float.isNaN(scaled_Floats[0][i])) { // not missing c = (int) (255.0 * color_values[0][i]); r = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * color_values[1][i]); g = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * color_values[2][i]); b = (c < 0) ? 0 : ((c > 255) ? 255 : c); if (color_length == 4) { c = (int) (255.0 * color_values[3][i]); a = (c < 0) ? 0 : ((c > 255) ? 255 : c); } if (color_length == 4) { byteData[k] = (byte) a; byteData[k+1] = (byte) b; byteData[k+2] = (byte) g; byteData[k+3] = (byte) r; } if (color_length == 3) { byteData[k] = (byte) b; byteData[k+1] = (byte) g; byteData[k+2] = (byte) r; } if (color_length == 1) { byteData[k] = (byte) b; } } k+=color_length; } } } } else if (cmaps != null) { Set rsets[] = null; if (data instanceof ImageFlatField) { if (first_time) { scaled_Bytes = ((FlatField) data).grabBytes(); } } //GHANSHAM:30AUG2011 Extract rsets from RGB FlatField if (data instanceof FlatField) { rsets = ((FlatField) data). getRangeSets(); } boolean isRGBRGBRGB = ((cmaps[0].getDisplayScalar() == Display.RGB) && (cmaps[1].getDisplayScalar() == Display.RGB) && (cmaps[2].getDisplayScalar() == Display.RGB)); int r, g, b, c; int tableEnd = 0; if (first_time) { if (isRGBRGBRGB) { //Inserted by Ghansham (starts here) int map_indx; threeD_itable = new byte[cmaps.length][][]; for (map_indx = 0; map_indx < cmaps.length; map_indx++) { BaseColorControl basecolorcontrol = (BaseColorControl)cmaps[map_indx].getControl(); float color_table[][] = basecolorcontrol.getTable(); threeD_itable[map_indx] = new byte[color_table[0].length][3]; int table_indx; for(table_indx = 0; table_indx < threeD_itable[map_indx].length; table_indx++) { c = (int) (255.0 * color_table[0][table_indx]); r = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * color_table[1][table_indx]); g = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * color_table[2][table_indx]); b = (c < 0) ? 0 : ((c > 255) ? 255 : c); threeD_itable[map_indx][table_indx][0] = (byte) r; threeD_itable[map_indx][table_indx][1] = (byte) g; threeD_itable[map_indx][table_indx][2] = (byte) b; } } } } if (scaled_Bytes != null) { // grab bytes directly from ImageFlatField if (ImageFlatField.DEBUG) { System.err.println("ShadowImageFunctionTypeJ3D.doTransform: " + "cmaps != null: grab bytes directly"); } //Inserted by Ghansham starts here //IFF:Assume that FlatField is of type (element,line)->(R,G,B) with (Display.RGB,Display.RGB,Display.RGB) as mapping if (cmaps[0].getDisplayScalar() == Display.RGB && cmaps[1].getDisplayScalar() == Display.RGB && cmaps[2].getDisplayScalar() == Display.RGB) { int map_indx = 0; for (map_indx = 0; map_indx < cmaps.length; map_indx++) { int table_length = threeD_itable[0].length; int color_indx = permute[map_indx]; if (first_time) { scaled_Bytes[color_indx] = cmaps[color_indx].scaleValues(scaled_Bytes[color_indx], table_length); } int domainLength = scaled_Bytes[color_indx].length; int tblEnd = table_length - 1; int data_indx = 0; int texture_index = 0; int image_col_offset = yStart*data_width + xStart; int image_col_factor = 0; for (int y=0; y<tile_height; y++) { image_col_factor = y*data_width + image_col_offset; for (int x=0; x<tile_width; x++) { data_indx = x + image_col_factor; texture_index = x + y*texture_width; texture_index *= color_length; int j = scaled_Bytes[color_indx][data_indx] & 0xff; // unsigned // clip to table int ndx = j < 0 ? 0 : (j > tblEnd ? tblEnd : j); byteData[texture_index+(color_length-color_indx-1)]=threeD_itable[map_indx][ndx][map_indx]; //Check if this logic works well } } } } else { //Inserted by Ghansham (Ends here) int data_indx = 0; int texture_index = 0; int offset=0; c = 0; if (color_length == 4) { c = (int) (255.0 * (1.0f - constant_alpha)); } //IFF:with (Red,Green,Blue) or (Red,Green,Blue,Alpha) as mapping int color_length_times_texture_width = color_length*texture_width; int image_col_offset = yStart*data_width + xStart; int image_col_factor = 0; for (int y=0; y<tile_height; y++) { image_col_factor = y*data_width + image_col_offset; texture_index = y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { data_indx = x + image_col_factor; if (color_length == 4) { byteData[texture_index] = (byte)c; //a byteData[texture_index+1] = scaled_Bytes[2][data_indx]; //b byteData[texture_index+2] = scaled_Bytes[1][data_indx]; //g byteData[texture_index+3] = scaled_Bytes[0][data_indx]; //r } else { byteData[texture_index] = scaled_Bytes[2][data_indx]; //b byteData[texture_index+1] = scaled_Bytes[1][data_indx]; //g byteData[texture_index+2] = scaled_Bytes[0][data_indx]; //r } texture_index += color_length; } } } } else { if (first_time) { float[][] values = ((Field) data).getFloats(false); scaled_Floats = new float[3][]; for (int i = 0; i < scaled_Floats.length; i++) { //GHANSHAM:30AUG2011 Use the rset lookup to find scaled Range Values if (rsets != null) { if (rsets[permute[i]] instanceof Integer1DSet) { if (null == rset_scalarmap_lookup) { rset_scalarmap_lookup = new float[3][]; } rset_scalarmap_lookup[i] = new float[rsets[permute[i]].getLength()]; for (int j = 0; j < rset_scalarmap_lookup[i].length; j++) { rset_scalarmap_lookup[i][j] = j; } rset_scalarmap_lookup[i] = cmaps[permute[i]].scaleValues(rset_scalarmap_lookup[i], false); scaled_Floats[i] = values[permute[i]]; } else { scaled_Floats[i] = cmaps[permute[i]].scaleValues(values[permute[i]]); } } else { scaled_Floats[i] = cmaps[permute[i]].scaleValues(values[permute[i]]); } } } c = (int) (255.0 * (1.0f - constant_alpha)); int a = (c < 0) ? 0 : ((c > 255) ? 255 : c); int m = 0; //GHANSHAM:30AUG2011 Create tableLengths for each of the tables separately rather than single table_length. More safe int RGB_tableEnd[] = null;; if (isRGBRGBRGB) { RGB_tableEnd = new int[threeD_itable.length]; for (int indx = 0; indx < threeD_itable.length; indx++) { RGB_tableEnd[indx]= threeD_itable[indx].length - 1; } } int k = 0; int color_length_times_texture_width = color_length*texture_width; int image_col_offset = yStart*data_width + xStart; int image_col_factor = 0; for (int y=0; y<tile_height; y++) { image_col_factor = y*data_width + image_col_offset; k = y*color_length_times_texture_width; for (int x=0; x<tile_width; x++) { int i = x + image_col_factor; if (!Float.isNaN(scaled_Floats[0][i]) && !Float.isNaN(scaled_Floats[1][i]) && !Float.isNaN(scaled_Floats[2][i])) { // not missing r=0;g=0;b=0; if (isRGBRGBRGB) { //Inserted by Ghansham (start here) int indx = -1; //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[0] != null) { indx = (int)(RGB_tableEnd[0] * rset_scalarmap_lookup[0][(int)scaled_Floats[0][i]]); } else{ indx = (int)(RGB_tableEnd[0] * scaled_Floats[0][i]); } indx = (indx < 0) ? 0 : ((indx > RGB_tableEnd[0]) ? RGB_tableEnd[0] : indx); r = threeD_itable[0][indx][0]; //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[1] != null) { indx = (int)(RGB_tableEnd[1] * rset_scalarmap_lookup[1][(int)scaled_Floats[1][i]]); } else{ indx = (int)(RGB_tableEnd[1] * scaled_Floats[1][i]); } indx = (indx < 0) ? 0 : ((indx > RGB_tableEnd[1]) ? RGB_tableEnd[1] : indx); g = threeD_itable[1][indx][1]; //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[2] != null) { indx = (int)(RGB_tableEnd[2] * rset_scalarmap_lookup[2][(int)scaled_Floats[2][i]]); } else { indx = (int)(RGB_tableEnd[2] * scaled_Floats[2][i]); } indx = (indx < 0) ? 0 : ((indx > RGB_tableEnd[2]) ? RGB_tableEnd[2] : indx); b = threeD_itable[2][indx][2]; } else { //Inserted by Ghansham (ends here) //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[0] != null) { c=(int) (255.0 * rset_scalarmap_lookup[0][(int)scaled_Floats[0][i]]); } else { c = (int) (255.0 * scaled_Floats[0][i]); } r = (c < 0) ? 0 : ((c > 255) ? 255 : c); //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[1] != null) { c=(int) (255.0 * rset_scalarmap_lookup[1][(int)scaled_Floats[1][i]]); } else { c = (int) (255.0 * scaled_Floats[1][i]); } g = (c < 0) ? 0 : ((c > 255) ? 255 : c); //GHANSHAM:30AUG2011 Use the rset_scalarmap lookup to find scaled Range Values if (rset_scalarmap_lookup != null && rset_scalarmap_lookup[2] != null) { c=(int) (255.0 * rset_scalarmap_lookup[2][(int)scaled_Floats[2][i]]); } else { c = (int) (255.0 * scaled_Floats[2][i]); } b = (c < 0) ? 0 : ((c > 255) ? 255 : c); } if (color_length == 4) { byteData[k] = (byte) a; byteData[k+1] = (byte) b; byteData[k+2] = (byte) g; byteData[k+3] = (byte) r; } if (color_length == 3) { byteData[k] = (byte) b; byteData[k+1] = (byte) g; byteData[k+2] = (byte) r; } if (color_length == 1) { byteData[k] = (byte) b; } } k+=color_length; } } RGB_tableEnd = null; } } else { throw new BadMappingException("cmap == null and cmaps == null ??"); } } public void buildCurvedTexture(Object group, Set domain_set, Unit[] dataUnits, Unit[] domain_units, float[] default_values, ShadowRealType[] DomainComponents, int valueArrayLength, int[] inherited_values, int[] valueToScalar, GraphicsModeControl mode, float constant_alpha, float[] value_array, float[] constant_color, DisplayImpl display, int curved_size, ShadowRealTupleType Domain, CoordinateSystem dataCoordinateSystem, DataRenderer renderer, ShadowFunctionOrSetType adaptedShadowType, int[] start, int lenX, int lenY, float[][] samples, int bigX, int bigY, VisADImageTile tile, float topo_samples[], ScalarMap topo_map) throws VisADException, DisplayException { float[] coordinates = null; float[] texCoords = null; int data_width = 0; int data_height = 0; int texture_width = 1; int texture_height = 1; int[] lengths = null; if (dataCoordinateSystem instanceof CachingCoordinateSystem) { dataCoordinateSystem = ((CachingCoordinateSystem)dataCoordinateSystem).getCachedCoordinateSystem(); } // get domain_set sizes if (domain_set != null) { lengths = ((GriddedSet) domain_set).getLengths(); } else { lengths = new int[] {lenX, lenY}; } data_width = lengths[0]; data_height = lengths[1]; // texture sizes must be powers of two on older graphics cards. texture_width = textureWidth(data_width); texture_height = textureHeight(data_height); // transform for any CoordinateSystem in data (Field) Domain ShadowRealTupleType domain_reference = Domain.getReference(); ShadowRealType[] DC = DomainComponents; if (domain_reference != null && domain_reference.getMappedDisplayScalar()) { RealTupleType ref = (RealTupleType) domain_reference.getType(); renderer.setEarthSpatialData(Domain, domain_reference, ref, ref.getDefaultUnits(), (RealTupleType) Domain.getType(), new CoordinateSystem[] {dataCoordinateSystem}, domain_units); // ShadowRealTypes of DomainReference DC = adaptedShadowType.getDomainReferenceComponents(); } else { RealTupleType ref = (domain_reference == null) ? null : (RealTupleType) domain_reference.getType(); Unit[] ref_units = (ref == null) ? null : ref.getDefaultUnits(); renderer.setEarthSpatialData(Domain, domain_reference, ref, ref_units, (RealTupleType) Domain.getType(), new CoordinateSystem[] {dataCoordinateSystem}, domain_units); } int[] tuple_index = new int[3]; int[] spatial_value_indices = {-1, -1, -1}; ScalarMap[] spatial_maps = new ScalarMap[3]; DisplayTupleType spatial_tuple = null; for (int i=0; i<DC.length; i++) { Enumeration maps = DC[i].getSelectedMapVector().elements(); ScalarMap map = (ScalarMap) maps.nextElement(); DisplayRealType real = map.getDisplayScalar(); spatial_tuple = real.getTuple(); if (spatial_tuple == null) { throw new DisplayException("texture with bad tuple: " + "ShadowImageFunctionTypeJ3D.doTransform"); } // get spatial index tuple_index[i] = real.getTupleIndex(); spatial_value_indices[tuple_index[i]] = map.getValueIndex(); spatial_maps[tuple_index[i]] = map; if (maps.hasMoreElements()) { throw new DisplayException("texture with multiple spatial: " + "ShadowImageFunctionTypeJ3D.doTransform"); } } // end for (int i=0; i<DC.length; i++) // get spatial index not mapped from domain_set tuple_index[2] = 3 - (tuple_index[0] + tuple_index[1]); DisplayRealType real = (DisplayRealType) spatial_tuple.getComponent(tuple_index[2]); int value2_index = display.getDisplayScalarIndex(real); float value2 = default_values[value2_index]; /*for (int i=0; i<valueArrayLength; i++) { if (inherited_values[i] > 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { value2 = value_array[i]; break; } }*/ //To take care of Z mapping of RGB values if (null == topo_samples) { for (int i=0; i<valueArrayLength; i++) { if (inherited_values[i] > 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { value2 = value_array[i]; break; } } } else { spatial_maps[tuple_index[2]] = topo_map; } boolean useLinearTexture = false; double[] scale = null; double[] offset = null; CoordinateSystem coord = null; if (spatial_tuple.equals(Display.DisplaySpatialCartesianTuple)) { // inside 'if (anyFlow) {}' in ShadowType.assembleSpatial() renderer.setEarthSpatialDisplay(null, spatial_tuple, display, spatial_value_indices, default_values, null); } else { coord = spatial_tuple.getCoordinateSystem(); if (coord instanceof CachingCoordinateSystem) { coord = ((CachingCoordinateSystem)coord).getCachedCoordinateSystem(); } if (coord instanceof InverseLinearScaledCS) { InverseLinearScaledCS invCS = (InverseLinearScaledCS)coord; //useLinearTexture = (invCS.getInvertedCoordinateSystem()).equals(dataCoordinateSystem); //To take care of Z mapping of RGB values useLinearTexture = (invCS.getInvertedCoordinateSystem()).equals(dataCoordinateSystem) && (null == topo_samples); scale = invCS.getScale(); offset = invCS.getOffset(); } // inside 'if (anyFlow) {}' in ShadowType.assembleSpatial() renderer.setEarthSpatialDisplay(coord, spatial_tuple, display, spatial_value_indices, default_values, null); } if (useLinearTexture) { float scaleX = (float) scale[0]; float scaleY = (float) scale[1]; float offsetX = (float) offset[0]; float offsetY = (float) offset[1]; float[][] xyCoords = null; if (domain_set != null) { xyCoords = getBounds(domain_set, data_width, data_height, scaleX, offsetX, scaleY, offsetY); } else { //If there is tiling in linear texture domain set is coming null if number of tiles is greater than 1 //Code inserted by Ghansham (starts here) int indx0 = (start[0]) + (start[1])*bigX; int indx1 = (start[0]) + (start[1] + lenY-1)*bigX; int indx2 = (start[0] + lenX -1) + (start[1] + lenY - 1)*bigX; int indx3 = (start[0] + lenX -1 ) + (start[1])*bigX; float x0 = samples[0][indx0]; float y0 = samples[1][indx0]; float x1 = samples[0][indx1]; float y1 = samples[1][indx1]; float x2 = samples[0][indx2]; float y2 = samples[1][indx2]; float x3 = samples[0][indx3]; float y3 = samples[1][indx3]; xyCoords = new float[2][4]; xyCoords[0][0] = (x0 - offsetX)/scaleX; xyCoords[1][0] = (y0 - offsetY)/scaleY; xyCoords[0][1] = (x1 - offsetX)/scaleX; xyCoords[1][1] = (y1 - offsetY)/scaleY; xyCoords[0][2] = (x2 - offsetX)/scaleX; xyCoords[1][2] = (y2 - offsetY)/scaleY; xyCoords[0][3] = (x3 - offsetX)/scaleX; xyCoords[1][3] = (y3 - offsetY)/scaleY; //Code inserted by Ghansham (Ends here) } // create VisADQuadArray that texture is mapped onto coordinates = new float[12]; // corner 0 (-1,1) coordinates[tuple_index[0]] = xyCoords[0][0]; coordinates[tuple_index[1]] = xyCoords[1][0]; coordinates[tuple_index[2]] = value2; // corner 1 (-1,-1) coordinates[3+tuple_index[0]] = xyCoords[0][1]; coordinates[3+tuple_index[1]] = xyCoords[1][1]; coordinates[3 + tuple_index[2]] = value2; // corner 2 (1, -1) coordinates[6+tuple_index[0]] = xyCoords[0][2]; coordinates[6+tuple_index[1]] = xyCoords[1][2]; coordinates[6 + tuple_index[2]] = value2; // corner 3 (1,1) coordinates[9+tuple_index[0]] = xyCoords[0][3]; coordinates[9+tuple_index[1]] = xyCoords[1][3]; coordinates[9 + tuple_index[2]] = value2; // move image back in Java3D 2-D mode adjustZ(coordinates); texCoords = new float[8]; float ratiow = ((float) data_width) / ((float) texture_width); float ratioh = ((float) data_height) / ((float) texture_height); boolean yUp = true; setTexCoords(texCoords, ratiow, ratioh, yUp); VisADQuadArray qarray = new VisADQuadArray(); qarray.vertexCount = 4; qarray.coordinates = coordinates; qarray.texCoords = texCoords; /*REUSE GEOM/COLORBYTES:I have replaced reuse with reuseImages. And here in the else logic I have added a few more lines. The else part of this never got executed because reuse was always false. Now else part gets executed when reuse is true and either regen_geom or regen_colbytes is true. It just applies geometry to the already available texture. When both are true then if part gets executed. */ //if (!reuse) if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE GEOM/COLORBYTES: Earlier reuse variable was used. Replaced it with reuseImages and regeom_colbytes and regen_geom BufferedImage image = tile.getImage(0); textureToGroup(group, qarray, image, mode, constant_alpha, constant_color, texture_width, texture_height, true, true, tile, false); } else { //REUSE GEOM/COLORBYTES: reuse the colorbytes just apply the geometry int num_children = ((BranchGroup) group).numChildren(); if (num_children > 0) { BranchGroup branch1 = (BranchGroup) ((BranchGroup) group).getChild(0); //This the branch group created by textureToGroup Function Shape3D shape = (Shape3D) branch1.getChild(0); shape.setGeometry(((DisplayImplJ3D) display).makeGeometry(qarray)); } if (animControl == null) { imgNode.setCurrent(0); } } } else { // compute size of triangle array to map texture onto int size = (data_width + data_height) / 2; curved_size = Math.max(1, Math.min(curved_size, size / 32)); int nwidth = 2 + (data_width - 1) / curved_size; int nheight = 2 + (data_height - 1) / curved_size; // compute locations of triangle vertices in texture int nn = nwidth * nheight; int[] is = new int[nwidth]; int[] js = new int[nheight]; for (int i=0; i<nwidth; i++) { is[i] = Math.min(i * curved_size, data_width - 1); } for (int j=0; j<nheight; j++) { js[j] = Math.min(j * curved_size, data_height - 1); } // get spatial coordinates at triangle vertices int k = 0; float[][] spline_domain = null; //To take care of Z mapping of RGB values float[] extracted_topo_samples = null; if (null != topo_samples) { extracted_topo_samples = new float[nn]; } if (domain_set == null) { //Ghansham: We generate the indices for the samples directly from 'is' and 'js' array spline_domain = new float[2][nn]; int kk = 0; int ndx = 0; int col_factor = 0; for (int j = 0; j < nheight; j++) { col_factor = (start[1] + js[j]) * bigX; for (int i = 0; i < nwidth; i++) { ndx = (start[0] + is[i]) + col_factor; spline_domain[0][kk] = samples[0][ndx]; spline_domain[1][kk] = samples[1][ndx]; //To take care of Z mapping of RGB values if (null != topo_samples) { extracted_topo_samples[kk] = topo_samples[ndx]; } kk++; } } } else { int[] indices = new int[nn]; //Ghansham:Calculate indices only if there is a single tile in the full image k=0; int col_factor; for (int j=0; j<nheight; j++) { col_factor = data_width * js[j]; for (int i=0; i<nwidth; i++) { indices[k] = is[i] + col_factor; if (null != topo_samples) { extracted_topo_samples[k] = topo_samples[indices[k]]; } k++; } } spline_domain = domain_set.indexToValue(indices); indices = null; } spline_domain = Unit.convertTuple(spline_domain, dataUnits, domain_units, false); if (domain_reference != null && domain_reference.getMappedDisplayScalar()) { RealTupleType ref = (RealTupleType) domain_reference.getType(); spline_domain = CoordinateSystem.transformCoordinates( ref, null, ref.getDefaultUnits(), null, (RealTupleType) Domain.getType(), dataCoordinateSystem, domain_units, null, spline_domain); } float[][] spatial_values = new float[3][]; spatial_values[tuple_index[0]] = spline_domain[0]; spatial_values[tuple_index[1]] = spline_domain[1]; boolean isSpherical = spatial_tuple.equals(Display.DisplaySpatialSphericalTuple); if (isSpherical || topo_samples != null) { spatial_values[tuple_index[2]] = new float[nn]; if (topo_samples != null) { spatial_values[tuple_index[2]] = extracted_topo_samples; } else { Arrays.fill(spatial_values[tuple_index[2]], value2); } } for (int i = 0; i < 3; i++) { if (spatial_maps[i] != null) { spatial_values[i] = spatial_maps[i].scaleValues(spatial_values[i], false); } } if (!spatial_tuple.equals(Display.DisplaySpatialCartesianTuple)) { spatial_values = coord.toReference(spatial_values); } boolean spatial_all_select = true; if (isSpherical || topo_samples != null) { for (int i=0; i<nn; i++) { if (Float.isNaN(spatial_values[0][i]) || Float.isNaN(spatial_values[1][i]) || Float.isNaN(spatial_values[2][i])) { spatial_all_select = false; break; } } } else { if (Float.isNaN(value2)) { spatial_all_select = false; } else { for (int i=0; i<nn; i++) { if (Float.isNaN(spatial_values[0][i]) || Float.isNaN(spatial_values[1][i])) { spatial_all_select = false; break; } } } } VisADTriangleStripArray tarray = new VisADTriangleStripArray(); tarray.stripVertexCounts = new int[nheight - 1]; java.util.Arrays.fill(tarray.stripVertexCounts, 2 * nwidth); int len = (nheight - 1) * (2 * nwidth); tarray.vertexCount = len; tarray.coordinates = new float[3 * len]; tarray.texCoords = new float[2 * len]; /*float temp_normals[] = null; float temp_coords[] = null; int normalLength; int normalLengthX3;*/ float normals[][] = null; if (topo_samples != null) { normals = makeNormals(spatial_values, nwidth, nheight); tarray.normals = new float[3 *len]; } int m = 0; k = 0; int kt = 0; float y_coord = 0f; float y_coord2 = 0f; float x_coord = 0f; boolean use_z_samples = (isSpherical || null != topo_samples); for (int j=0; j<nheight-1; j++) { if (0 ==j){ y_coord = (0.5f + js[j])/texture_height; } else { y_coord = y_coord2; } y_coord2 = (0.5f + js[j+1])/texture_height; for (int i=0; i<nwidth; i++) { tarray.coordinates[k] = spatial_values[0][m]; tarray.coordinates[k+1] = spatial_values[1][m]; tarray.coordinates[k+2] = use_z_samples ? spatial_values[2][m] : value2; tarray.coordinates[k+3] = spatial_values[0][m+nwidth]; tarray.coordinates[k+4] = spatial_values[1][m+nwidth]; tarray.coordinates[k+5] = use_z_samples ? spatial_values[2][m+nwidth]: value2; if (null != topo_samples) { tarray.normals[k] = normals[0][m]; tarray.normals[k+1] = normals[1][m]; tarray.normals[k+2] = normals[2][m]; tarray.normals[k+3] = normals[0][m+nwidth]; tarray.normals[k+4] = normals[1][m+nwidth]; tarray.normals[k+5] = normals[2][m+nwidth]; } x_coord = (0.5f + is[i])/texture_width; tarray.texCoords[kt++] = x_coord; tarray.texCoords[kt++] = y_coord; tarray.texCoords[kt++] = x_coord; tarray.texCoords[kt++] = y_coord2; m += 1; k+=6; } } normals = null; is = null; js = null; extracted_topo_samples = null; spatial_values[0] = null; spatial_values[1] = null; spatial_values[2] = null; spatial_values = null; spline_domain[0] = null; spline_domain[1] = null; spline_domain = null; // do surgery to remove any missing spatial coordinates in texture if (!spatial_all_select) { tarray = (VisADTriangleStripArray) tarray.removeMissing(); } // do surgery along any longitude split (e.g., date line) in texture if (adaptedShadowType.getAdjustProjectionSeam()) { tarray = (VisADTriangleStripArray) tarray.adjustLongitude(renderer); tarray = (VisADTriangleStripArray) tarray.adjustSeam(renderer); } /*REUSE GEOM/COLORBYTES:I have replaced reuse with reuseImages. And here in the else logic I have added a few more lines. The else part of this never got executed because reuse was always false. Now else part gets executed when reuseImages is true or either regen_geom or regen_colbytes is true. It just applies geometry to the already available texture. When both regen_geom or regen_colbytes are true then if part gets executed. */ // add texture as sub-node of group in scene graph //if (!reuse) if (!reuseImages || (regen_colbytes && regen_geom)) { //REUSE GEOM/COLORBYTES: Earlier reuse variable was used. Replaced it with reuseImages and regeom_colbytes and regen_geom BufferedImage image = tile.getImage(0); textureToGroup(group, tarray, image, mode, constant_alpha, constant_color, texture_width, texture_height, true, true, tile, null != topo_samples); } else { //REUSE GEOM/COLORBYTES: Reuse the colorbytes and just apply the geometry int num_children = ((BranchGroup) group).numChildren(); if (num_children > 0) { BranchGroup branch1 = (BranchGroup) ((BranchGroup) group).getChild(0); //This is the branch group created by textureToGroup Function Shape3D shape = (Shape3D) branch1.getChild(0); shape.setGeometry(((DisplayImplJ3D) display).makeGeometry(tarray)); } if (animControl == null) { imgNode.setCurrent(0); } } } tuple_index = null; // System.out.println("end curved texture " + (System.currentTimeMillis() - link.start_time)); } public void buildLinearTexture(Object group, Set domain_set, Unit[] dataUnits, Unit[] domain_units, float[] default_values, ShadowRealType[] DomainComponents, int valueArrayLength, int[] inherited_values, int[] valueToScalar, GraphicsModeControl mode, float constant_alpha, float[] value_array, float[] constant_color, DisplayImpl display, VisADImageTile tile) throws VisADException, DisplayException { float[] coordinates = null; float[] texCoords = null; float[] normals = null; int data_width = 0; int data_height = 0; int texture_width = 1; int texture_height = 1; Linear1DSet X = null; Linear1DSet Y = null; if (domain_set instanceof Linear2DSet) { X = ((Linear2DSet) domain_set).getX(); Y = ((Linear2DSet) domain_set).getY(); } else { X = ((LinearNDSet) domain_set).getLinear1DComponent(0); Y = ((LinearNDSet) domain_set).getLinear1DComponent(1); } float[][] limits = new float[2][2]; limits[0][0] = (float) X.getFirst(); limits[0][1] = (float) X.getLast(); limits[1][0] = (float) Y.getFirst(); limits[1][1] = (float) Y.getLast(); // get domain_set sizes data_width = X.getLength(); data_height = Y.getLength(); // texture sizes must be powers of two on older graphics cards texture_width = textureWidth(data_width); texture_height = textureHeight(data_height); // WLH 27 Jan 2003 float half_width = 0.5f / ((float) (data_width - 1)); float half_height = 0.5f / ((float) (data_height - 1)); half_width = (limits[0][1] - limits[0][0]) * half_width; half_height = (limits[1][1] - limits[1][0]) * half_height; limits[0][0] -= half_width; limits[0][1] += half_width; limits[1][0] -= half_height; limits[1][1] += half_height; // convert values to default units (used in display) limits = Unit.convertTuple(limits, dataUnits, domain_units); int[] tuple_index = new int[3]; if (DomainComponents.length != 2) { throw new DisplayException("texture domain dimension != 2:" + "ShadowFunctionOrSetType.doTransform"); } // find the spatial ScalarMaps for (int i=0; i<DomainComponents.length; i++) { Enumeration maps = DomainComponents[i].getSelectedMapVector().elements(); ScalarMap map = (ScalarMap) maps.nextElement(); // scale values limits[i] = map.scaleValues(limits[i]); DisplayRealType real = map.getDisplayScalar(); DisplayTupleType tuple = real.getTuple(); if (tuple == null || !tuple.equals(Display.DisplaySpatialCartesianTuple)) { throw new DisplayException("texture with bad tuple: " + "ShadowFunctionOrSetType.doTransform"); } // get spatial index tuple_index[i] = real.getTupleIndex(); if (maps.hasMoreElements()) { throw new DisplayException("texture with multiple spatial: " + "ShadowFunctionOrSetType.doTransform"); } } // end for (int i=0; i<DomainComponents.length; i++) // get spatial index not mapped from domain_set tuple_index[2] = 3 - (tuple_index[0] + tuple_index[1]); DisplayRealType real = (DisplayRealType) Display.DisplaySpatialCartesianTuple.getComponent(tuple_index[2]); int value2_index = display.getDisplayScalarIndex(real); float value2 = default_values[value2_index]; for (int i=0; i<valueArrayLength; i++) { if (inherited_values[i] > 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { // value for unmapped spatial dimension value2 = value_array[i]; break; } } // create VisADQuadArray that texture is mapped onto coordinates = new float[12]; // corner 0 coordinates[tuple_index[0]] = limits[0][0]; coordinates[tuple_index[1]] = limits[1][0]; coordinates[tuple_index[2]] = value2; // corner 1 coordinates[3 + tuple_index[0]] = limits[0][0]; coordinates[3 + tuple_index[1]] = limits[1][1]; coordinates[3 + tuple_index[2]] = value2; // corner 2 coordinates[6 + tuple_index[0]] = limits[0][1]; coordinates[6 + tuple_index[1]] = limits[1][1]; coordinates[6 + tuple_index[2]] = value2; // corner 3 coordinates[9 + tuple_index[0]] = limits[0][1]; coordinates[9 + tuple_index[1]] = limits[1][0]; coordinates[9 + tuple_index[2]] = value2; // move image back in Java3D 2-D mode adjustZ(coordinates); texCoords = new float[8]; float ratiow = ((float) data_width) / ((float) texture_width); float ratioh = ((float) data_height) / ((float) texture_height); boolean yUp = true; setTexCoords(texCoords, ratiow, ratioh, yUp); VisADQuadArray qarray = new VisADQuadArray(); qarray.vertexCount = 4; qarray.coordinates = coordinates; qarray.texCoords = texCoords; /*REUSE GEOM/COLORBYTES:I have replaced reuse with reuseImages. And here in the else logic I have added a few more lines. The else part of this never got executed because reuse was always false. Now else part gets executed when reuse is true and either regen_geom or regen_colbytes is true. It just applies geometry to the already available texture. When both are true then if part gets executed. */ // add texture as sub-node of group in scene graph if (!reuseImages|| (regen_colbytes && regen_geom)) { //REUSE GEOM/COLORBYTES: Earlier reuse variable was used. Replaced it with reuseImages and regeom_colbytes and regen_geom BufferedImage image = tile.getImage(0); textureToGroup(group, qarray, image, mode, constant_alpha, constant_color, texture_width, texture_height, true, true, tile, false); } else { int num_children = ((BranchGroup) group).numChildren(); if (num_children > 0) { //REUSE GEOM/COLORBYTES: Reuse the colorbytes and apply geometry BranchGroup branch1 = (BranchGroup) ((BranchGroup) group).getChild(0); //This the branch group created by textureToGroup Function Shape3D shape = (Shape3D) branch1.getChild(0); shape.setGeometry(((DisplayImplJ3D) display).makeGeometry(qarray)); } if (animControl == null) { imgNode.setCurrent(0); } } } //public CachedBufferedByteImage createImageByRef(final int texture_width, final int texture_height, final int imageType) { public BufferedImage createImageByRef(final int texture_width, final int texture_height, final int imageType) { return new BufferedImage(texture_width, texture_height, imageType); } public static float[][] getBounds(Set domain_set, float data_width, float data_height, float scaleX, float offsetX, float scaleY, float offsetY) throws VisADException { float[][] xyCoords = new float[2][4]; float[][] coords0 = ((GriddedSet)domain_set).gridToValue(new float[][] {{0f},{0f}}); float[][] coords1 = ((GriddedSet)domain_set).gridToValue(new float[][] {{0f},{(float)(data_height-1)}}); float[][] coords2 = ((GriddedSet)domain_set).gridToValue(new float[][] {{(data_width-1f)},{(data_height-1f)}}); float[][] coords3 = ((GriddedSet)domain_set).gridToValue(new float[][] {{(data_width-1f)},{0f}}); float x0 = coords0[0][0]; float y0 = coords0[1][0]; float x1 = coords1[0][0]; float y1 = coords1[1][0]; float x2 = coords2[0][0]; float y2 = coords2[1][0]; float x3 = coords3[0][0]; float y3 = coords3[1][0]; xyCoords[0][0] = (x0 - offsetX)/scaleX; xyCoords[1][0] = (y0 - offsetY)/scaleY; xyCoords[0][1] = (x1 - offsetX)/scaleX; xyCoords[1][1] = (y1 - offsetY)/scaleY; xyCoords[0][2] = (x2 - offsetX)/scaleX; xyCoords[1][2] = (y2 - offsetY)/scaleY; xyCoords[0][3] = (x3 - offsetX)/scaleX; xyCoords[1][3] = (y3 - offsetY)/scaleY; return xyCoords; } public float[][] makeNormals(float[][] coordinates, int LengthX, int LengthY) { int Length = LengthX * LengthY; //float[] normals = new float[3 * Length]; float normals[][] = new float[3][Length]; int k = 0; int ki, kj; int LengthX3 = 3 * LengthX; for (int i = 0; i < LengthY; i++) { for (int j = 0; j < LengthX; j++) { /*float c0 = coordinates[k]; float c1 = coordinates[k + 1]; float c2 = coordinates[k + 2];*/ float c0 = coordinates[0][k]; float c1 = coordinates[1][k]; float c2 = coordinates[2][k]; float n0 = 0.0f; float n1 = 0.0f; float n2 = 0.0f; float n, m, m0, m1, m2, q0, q1, q2; for (int ip = -1; ip <= 1; ip += 2) { for (int jp = -1; jp <= 1; jp += 2) { int ii = i + ip; int jj = j + jp; if (0 <= ii && ii < LengthY && 0 <= jj && jj < LengthX) { ki = k + ip * LengthX; kj = k + jp; /*ki = k + ip * LengthX3; kj = k + jp * 3; m0 = (coordinates[kj + 2] - c2) * (coordinates[ki + 1] - c1) - (coordinates[kj + 1] - c1) * (coordinates[ki + 2] - c2); m1 = (coordinates[kj] - c0) * (coordinates[ki + 2] - c2) - (coordinates[kj + 2] - c2) * (coordinates[ki] - c0); m2 = (coordinates[kj + 1] - c1) * (coordinates[ki] - c0) - (coordinates[kj] - c0) * (coordinates[ki + 1] - c1);*/ m0 = (coordinates[2][kj] - c2) * (coordinates[1][ki] - c1) - (coordinates[1][kj] - c1) * (coordinates[2][ki] - c2); m1 = (coordinates[0][kj] - c0) * (coordinates[2][ki] - c2) - (coordinates[2][kj] - c2) * (coordinates[0][ki] - c0); m2 = (coordinates[1][kj] - c1) * (coordinates[0][ki] - c0) - (coordinates[0][kj] - c0) * (coordinates[1][ki] - c1); m = (float) Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2); if (ip == jp) { q0 = m0 / m; q1 = m1 / m; q2 = m2 / m; } else { q0 = -m0 / m; q1 = -m1 / m; q2 = -m2 / m; } if (q0 == q0) { n0 += q0; n1 += q1; n2 += q2; } else { } } } } n = (float) Math.sqrt(n1 * n0 + n1 * n1 + n2 * n2); /*normals[k] = n0 / n; normals[k + 1] = n1 / n; normals[k + 2] = n2 / n;*/ normals[0][k] = n0 / n; normals[1][k] = n1 / n; normals[2][k] = n2 / n; if (normals[0][k] != normals[0][k]) { normals[0][k] = 0.0f; normals[1][k] = 0.0f; normals[2][k] = -1.0f; } /*if (normals[k] != normals[k]) { normals[k] = 0.0f; normals[k + 1] = 0.0f; normals[k + 2] = -1.0f; } k+= 3;*/ k+=1; } // end for (int j=0; j<LengthX; j++) } // end for (int i=0; i<LengthY; i++) return normals; } } class SwitchNotify extends Switch { VisADImageNode imgNode; int numChildren; Switch swit; SwitchNotify(VisADImageNode imgNode, int numChildren) { super(); this.imgNode = imgNode; this.numChildren = numChildren; this.swit = imgNode.getSwitch(); } public int numChildren() { return numChildren; } public void setWhichChild(int index) { if (index == Switch.CHILD_NONE) { swit.setWhichChild(Switch.CHILD_NONE); } else if (index >= 0) { if ( swit.getWhichChild() == Switch.CHILD_NONE) { swit.setWhichChild(0); } imgNode.setCurrent(index); } } } class Mosaic { Tile[][] tiles; ArrayList<Tile> tileList = new ArrayList<Tile>(); int n_x_sub = 1; int n_y_sub = 1; Mosaic(int lenY, int limitY, int lenX, int limitX) { int y_sub_len = limitY; n_y_sub = lenY/y_sub_len; if (n_y_sub == 0) n_y_sub++; if ((lenY - n_y_sub*y_sub_len) > 4) n_y_sub += 1; int[][] y_start_stop = new int[n_y_sub][2]; for (int k = 0; k < n_y_sub-1; k++) { y_start_stop[k][0] = k*y_sub_len - k; y_start_stop[k][1] = ((k+1)*y_sub_len - 1) - k; // check that we don't exceed limit if ( ((y_start_stop[k][1]-y_start_stop[k][0])+1) > limitY) { y_start_stop[k][1] -= 1; //too big, take away gap fill } } int k = n_y_sub-1; y_start_stop[k][0] = k*y_sub_len - k; y_start_stop[k][1] = lenY - 1 - k; int x_sub_len = limitX; n_x_sub = lenX/x_sub_len; if (n_x_sub == 0) n_x_sub++; if ((lenX - n_x_sub*x_sub_len) > 4) n_x_sub += 1; int[][] x_start_stop = new int[n_x_sub][2]; for (k = 0; k < n_x_sub-1; k++) { x_start_stop[k][0] = k*x_sub_len - k; x_start_stop[k][1] = ((k+1)*x_sub_len - 1) - k; // check that we don't exceed limit if ( ((x_start_stop[k][1]-x_start_stop[k][0])+1) > limitX) { x_start_stop[k][1] -= 1; //too big, take away gap fill } } k = n_x_sub-1; x_start_stop[k][0] = k*x_sub_len - k; x_start_stop[k][1] = lenX - 1 - k; tiles = new Tile[n_y_sub][n_x_sub]; for (int j=0; j<n_y_sub; j++) { for (int i=0; i<n_x_sub; i++) { tiles[j][i] = new Tile(y_start_stop[j][0], y_start_stop[j][1], x_start_stop[i][0], x_start_stop[i][1]); tileList.add(tiles[j][i]); } } } Iterator iterator() { return tileList.iterator(); } } class Tile { int y_start; int x_start; int y_stop; int x_stop; int height; int width; Tile(int y_start, int y_stop, int x_start, int x_stop) { this.y_start = y_start; this.y_stop = y_stop; this.x_start = x_start; this.x_stop = x_stop; height = y_stop - y_start + 1; width = x_stop - x_start + 1; } }
visad
archives: