//
// ShadowImageFunctionTypeJ3D.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 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.java3d.*;
import visad.data.mcidas.BaseMapAdapter;
import visad.data.mcidas.AreaAdapter;
import visad.data.gif.GIFForm;

import javax.media.j3d.*;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.Vector;
import java.rmi.*;

import java.net.URL;

import java.awt.event.*;
import javax.swing.*;
import java.awt.image.BufferedImage;

/**
   The ShadowImageFunctionTypeJ3D class shadows the FunctionType class for
   ImageRendererJ3D, within a DataDisplayLink, under Java3D.

*/ public class ShadowImageFunctionTypeJ3D extends ShadowFunctionTypeJ3D { private static final int MISSING1 = Byte.MIN_VALUE; // least byte public ShadowImageFunctionTypeJ3D(MathType t, DataDisplayLink link, ShadowType parent) throws VisADException, RemoteException { super(t, link, parent); } // 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(); //System.out.println("start doTransform " + (System.currentTimeMillis() - link.start_time)); // return if data is missing or no ScalarMaps if (data.isMissing()) { ((ImageRendererJ3D) renderer).markMissingVisADBranch(); return false; } if (getLevelOfDifficulty() == NOTHING_MAPPED) return false; ShadowFunctionOrSetType adaptedShadowType = (ShadowFunctionOrSetType) getAdaptedShadowType(); DisplayImpl display = getDisplay(); GraphicsModeControl mode = (GraphicsModeControl) display.getGraphicsModeControl().clone(); display.setDepthBufferOffset(renderer, mode); // get 'shape' flags 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"); } // get some precomputed values useful for transform // length of ValueArray int valueArrayLength = display.getValueArrayLength(); // mapping from ValueArray to DisplayScalar int[] valueToScalar = display.getValueToScalar(); // mapping from ValueArray to MapVector int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); // array to hold values for various mappings float[][] display_values = new float[valueArrayLength][]; int[] inherited_values = adaptedShadowType.getInheritedValues(); for (int i=0; i 0) { display_values[i] = new float[1]; display_values[i][0] = value_array[i]; } } // analyze data's domain (its a Field) Set domain_set = ((Field) data).getDomainSet(); Unit[] dataUnits = ((Function) data).getDomainUnits(); CoordinateSystem dataCoordinateSystem = ((Function) data).getDomainCoordinateSystem(); float[][] domain_values = null; double[][] domain_doubles = null; ShadowRealTupleType Domain = adaptedShadowType.getDomain(); Unit[] domain_units = ((RealTupleType) Domain.getType()).getDefaultUnits(); int domain_length; int domain_dimension; try { domain_length = domain_set.getLength(); domain_dimension = domain_set.getDimension(); } catch (SetException e) { return false; } // System.err.println ("domain_length:" + domain_length); // ShadowRealTypes of Domain ShadowRealType[] DomainComponents = adaptedShadowType.getDomainComponents(); // check whether this ShadowImageFunctionTypeJ3D is for an // image (terminal - no recursive calls to doTransform) or an // image sequence (non-terminal - recursive calls to doTransform // for each image in the sequence if (adaptedShadowType.getIsTerminal()) { // terminal, so this is an image // System.out.println("start colors " + (System.currentTimeMillis() - link.start_time)); float constant_alpha = Float.NaN; float[] constant_color = null; // 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}; int color_length = 3; if (rangesize == 1) { Vector mvector = RangeComponents[0].getSelectedMapVector(); 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())) { color_length = 3; } else if (Display.RGBA.equals(cmap.getDisplayScalar())) { color_length = 4; } 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 and Blue"); } //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) } constant_alpha = default_values[display.getDisplayScalarIndex(Display.Alpha)]; byte[][] color_bytes; if (cmap != null) { // build texture colors in color_bytes array BaseColorControl control = (BaseColorControl) cmap.getControl(); float[][] table = control.getTable(); byte[][] bytes = null; 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(); // 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 byte[][] 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 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 && bytes != null && is_default_unit) { if (ImageFlatField.DEBUG) { System.err.println("ShadowImageFunctionTypeJ3D.doTransform: " + "cmap != null: looking up color values"); } // avoid unpacking floats for ImageFlatFields color_bytes = new byte[4][domain_length]; bytes[0] = cmap.scaleValues(bytes[0], table_scale); // fast lookup from byte values to color bytes byte[] bytes0 = bytes[0]; for (int i=0; i tblEnd ? tblEnd : j); color_bytes[0][i] = itable[ndx][0]; color_bytes[1][i] = itable[ndx][1]; color_bytes[2][i] = itable[ndx][2]; color_bytes[3][i] = itable[ndx][3]; } } else if (bytes != null && 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 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 byte[][] 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 color_bytes = new byte[4][domain_length]; byte[] bytes0 = bytes[0]; for (int i=0; i tblEnd ? tblEnd : j); color_bytes[0][i] = itable[ndx][0]; color_bytes[1][i] = itable[ndx][1]; color_bytes[2][i] = itable[ndx][2]; color_bytes[3][i] = itable[ndx][3]; } } values = null; // take out the garbage } } else { // if (table == null) // slower, more general way to build texture colors bytes = null; // take out the garbage float[][] values = ((Field) data).getFloats(false); values[0] = cmap.scaleValues(values[0]); // call lookupValues which will use function since table == null float[][] color_values = control.lookupValues(values[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); color_bytes = new byte[4][domain_length]; for (int i=0; i 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); } color_bytes[0][i] = (byte) r; color_bytes[1][i] = (byte) g; color_bytes[2][i] = (byte) b; color_bytes[3][i] = (byte) a; } } // take out the garbage values = null; color_values = null; } } else if (cmaps != null) { byte[][] bytes = null; if (data instanceof ImageFlatField) { bytes = ((ImageFlatField) data).grabBytes(); } if (bytes != null) { // grab bytes directly from ImageFlatField if (ImageFlatField.DEBUG) { System.err.println("ShadowImageFunctionTypeJ3D.doTransform: " + "cmaps != null: grab bytes directly"); } color_bytes = new byte[4][]; if (cmaps[0].getDisplayScalar() == Display.RGB && cmaps[1].getDisplayScalar() == Display.RGB && cmaps[2].getDisplayScalar() == Display.RGB) { //Inserted by Ghansham (starts here) int map_indx = 0; int r, g, b, c; for (map_indx = 0; map_indx < cmaps.length; map_indx++) { BaseColorControl basecolorcontrol = (BaseColorControl)cmaps[map_indx].getControl(); float color_table[][] = basecolorcontrol.getTable(); int itable[][] = new int[color_table[0].length][3]; int table_indx; for (table_indx = 0; table_indx < itable.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); itable[table_indx][0] = (byte) r; itable[table_indx][1] = (byte) g; itable[table_indx][2] = (byte) b; } int table_length = color_table[0].length; int color_indx = permute[map_indx]; byte bytes1[] = cmaps[color_indx].scaleValues(bytes[color_indx], table_length); //Memory Leak. overwritting bytes. it can be avoided if required. ScaleValues function does not have a signature of scaleValues(byte [], factor, boolean). its required, if need to save memory. int domainLength = bytes1.length; int tblEnd = table_length - 1; color_bytes[map_indx] = new byte[domain_length]; int data_indx; for (data_indx = 0; data_indx < domainLength; data_indx++) { int j = bytes1[data_indx] & 0xff; // unsigned // clip to table int ndx = j < 0 ? 0 : (j > tblEnd ? tblEnd : j); color_bytes[map_indx][data_indx] = (byte)itable[ndx][map_indx]; } itable = null; //Taking out the garbage bytes1 = null; //Taking out the garbage } }else { //Inserted by Ghansham (Ends here) color_bytes[0] = cmaps[permute[0]].scaleValues(bytes[permute[0]], 255); color_bytes[1] = cmaps[permute[1]].scaleValues(bytes[permute[1]], 255); color_bytes[2] = cmaps[permute[2]].scaleValues(bytes[permute[2]], 255); } int c = (int) (255.0 * (1.0f - constant_alpha)); color_bytes[3] = new byte[domain_length]; Arrays.fill(color_bytes[3], (byte) c); } else { float[][] values = ((Field) data).getFloats(false); float[][] new_values = new float[3][]; new_values[0] = cmaps[permute[0]].scaleValues(values[permute[0]]); new_values[1] = cmaps[permute[1]].scaleValues(values[permute[1]]); new_values[2] = cmaps[permute[2]].scaleValues(values[permute[2]]); values = new_values; int r, g, b; int c = (int) (255.0 * (1.0f - constant_alpha)); int a = (c < 0) ? 0 : ((c > 255) ? 255 : c); color_bytes = new byte[4][domain_length]; if (cmaps[0].getDisplayScalar() == Display.RGB && cmaps[1].getDisplayScalar() == Display.RGB && cmaps[2].getDisplayScalar() == Display.RGB) { //Inserted by Ghansham (starts here) int map_indx; for (map_indx = 0; map_indx < cmaps.length; map_indx++) { BaseColorControl basecolorcontrol = (BaseColorControl)cmaps[map_indx].getControl(); float color_table[][] = basecolorcontrol.getTable(); int itable[][] = new int[color_table[0].length][3]; int table_indx; for(table_indx = 0; table_indx < itable.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); itable[table_indx][0] = (byte) r; itable[table_indx][1] = (byte) g; itable[table_indx][2] = (byte) b; } int tableEnd = color_table[0].length - 1; for(int data_indx = 0; data_indx < domain_length; data_indx++) { int indx = (int)((float)tableEnd * values[map_indx][data_indx]); // clip to table indx = indx < 0 ? 0 : (indx > tableEnd ? tableEnd : indx); color_bytes[map_indx][data_indx] = (byte)itable[indx][map_indx]; } itable = null; //Take out the garbage } Arrays.fill(color_bytes[3], (byte)a); } else { //Inserted by Ghansham (ends here) for (int i=0; i 255) ? 255 : c); c = (int) (255.0 * values[1][i]); g = (c < 0) ? 0 : ((c > 255) ? 255 : c); c = (int) (255.0 * values[2][i]); b = (c < 0) ? 0 : ((c > 255) ? 255 : c); color_bytes[0][i] = (byte) r; color_bytes[1][i] = (byte) g; color_bytes[2][i] = (byte) b; color_bytes[3][i] = (byte) a; } } } // take out the garbage values = null; } } else { throw new BadMappingException("cmap == null and cmaps == null ??"); } // System.out.println("end colors " + (System.currentTimeMillis() - link.start_time)); // check domain and determine whether it is square or curved texture if (!Domain.getAllSpatial() || Domain.getMultipleDisplayScalar()) { throw new BadMappingException("domain must be only spatial"); } boolean isTextureMap = adaptedShadowType.getIsTextureMap() && (domain_set instanceof Linear2DSet || (domain_set instanceof LinearNDSet && domain_set.getDimension() == 2)) && (domain_set.getManifoldDimension() == 2); // DRM 2003-08-21 //int curved_size = display.getGraphicsModeControl().getCurvedSize(); int cMapCurveSize = (int) default_values[display.getDisplayScalarIndex(Display.CurvedSize)]; int curved_size = (cMapCurveSize > 0) ? cMapCurveSize : display.getGraphicsModeControl().getCurvedSize(); boolean curvedTexture = adaptedShadowType.getCurvedTexture() && !isTextureMap && curved_size > 0 && (domain_set instanceof Gridded2DSet || (domain_set instanceof GriddedSet && domain_set.getDimension() == 2)) && (domain_set.getManifoldDimension() == 2); float[] coordinates = null; float[] texCoords = null; float[] normals = null; byte[] colors = null; int data_width = 0; int data_height = 0; int texture_width = 1; int texture_height = 1; float[] coordinatesX = null; float[] texCoordsX = null; float[] normalsX = null; byte[] colorsX = null; float[] coordinatesY = null; float[] texCoordsY = null; float[] normalsY = null; byte[] colorsY = null; if (color_length == 4) constant_alpha = Float.NaN; // WLH 6 May 2003 if (isTextureMap) { //System.out.println("ShadowImageFunctionType, start texture map: " + (System.currentTimeMillis() - link.start_time)); int[] lens = ((GriddedSet)domain_set).getLengths(); int limit = link.getDisplay().getDisplayRenderer().getTextureWidthMax(); int y_sub_len = lens[1]; int n_y_sub = 1; while( y_sub_len >= limit ) { y_sub_len /= 2; n_y_sub *= 2; } 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; y_start_stop[k][1] = (k+1)*y_sub_len - 1; } int k = n_y_sub-1; y_start_stop[k][0] = k*y_sub_len; y_start_stop[k][1] = lens[1] - 1; int x_sub_len = lens[0]; int n_x_sub = 1; while( x_sub_len >= limit ) { x_sub_len /= 2; n_x_sub *= 2; } 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; x_start_stop[k][1] = (k+1)*x_sub_len - 1; } k = n_x_sub-1; x_start_stop[k][0] = k*x_sub_len; x_start_stop[k][1] = lens[0] - 1; if (n_y_sub == 1 && n_x_sub == 1) { buildLinearTexture(group, domain_set, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, color_bytes, display); } else { 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); int start = 0; int i_total = 0; for (int i=0; i 0) { ((Group) group).setChild(branch, 0); } else { ((Group) group).addChild(branch); } } } // end if (isTextureMap) else if (curvedTexture) { //System.out.println("start curved texture " + (System.currentTimeMillis() - link.start_time)); int[] lens = ((GriddedSet)domain_set).getLengths(); int limit = link.getDisplay().getDisplayRenderer().getTextureWidthMax(); //System.err.println("Texture Limit:" + limit); int y_sub_len = lens[1]; int n_y_sub = 1; while( y_sub_len >= limit ) { y_sub_len /= 2; n_y_sub *= 2; } 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; y_start_stop[k][1] = (k+1)*y_sub_len - 1; } int k = n_y_sub-1; y_start_stop[k][0] = k*y_sub_len; y_start_stop[k][1] = lens[1] - 1; int x_sub_len = lens[0]; int n_x_sub = 1; while( x_sub_len >= limit ) { x_sub_len /= 2; n_x_sub *= 2; } 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; x_start_stop[k][1] = (k+1)*x_sub_len - 1; } k = n_x_sub-1; x_start_stop[k][0] = k*x_sub_len; x_start_stop[k][1] = lens[0] - 1; //System.out.println(" y : "+lens[1]+", x : "+lens[0]); //System.out.println("n_y_sub: "+n_y_sub+", n_x_sub: "+n_x_sub); if (n_y_sub == 1 && n_x_sub == 1) { buildCurvedTexture(group, domain_set, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, color_bytes, display, curved_size, Domain, dataCoordinateSystem, renderer, adaptedShadowType, new int[] {0, 0}, lens[0], lens[1], null, lens[0], lens[1]); } else { float[][] samples = ((GriddedSet)domain_set).getSamples(false); 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); int start = 0; int i_total = 0; for (int i=0; i 0) { // vertical stitch float[][] samplesC = new float[2][4*leny]; byte[][] color_bytesC = new byte[4][4*leny]; int cntv = 0; int startv = x_start_stop[j][0] + i_total*lens[0]; for (int iv=0; iv < leny; iv++) { samplesC[0][cntv] = samples[0][startv-2]; samplesC[0][cntv+1] = samples[0][startv-1]; samplesC[0][cntv+2] = samples[0][startv]; samplesC[0][cntv+3] = samples[0][startv+1]; samplesC[1][cntv] = samples[1][startv-2]; samplesC[1][cntv+1] = samples[1][startv-1]; samplesC[1][cntv+2] = samples[1][startv]; samplesC[1][cntv+3] = samples[1][startv+1]; for (int c=0; c<4; c++) { color_bytesC[c][cntv] = color_bytes[c][startv-2]; color_bytesC[c][cntv+1] = color_bytes[c][startv-1]; color_bytesC[c][cntv+2] = color_bytes[c][startv]; color_bytesC[c][cntv+3] = color_bytes[c][startv+1]; } cntv += 4; startv += lens[0]; } Gridded2DSet gsetv = new Gridded2DSet(domain_set.getType(), samplesC, 4, leny); BranchGroup branchv = new BranchGroup(); branchv.setCapability(BranchGroup.ALLOW_DETACH); branchv.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branchv.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branchv.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); buildCurvedTexture(branchv, gsetv, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, color_bytesC, display, curved_size, Domain, dataCoordinateSystem, renderer, adaptedShadowType, new int[] {x_start_stop[j][0], y_start_stop[i][0]}, lenx, leny, samples, lens[0], lens[1]); branch.addChild(branchv); } if (i > 0) { // horz stitch float[][] samplesC = new float[2][4*lenx]; byte[][] color_bytesC = new byte[4][4*lenx]; int starth = x_start_stop[j][0] + i_total*lens[0]; int cnth = 0; System.arraycopy(samples[0], starth-2*lens[0], samplesC[0], cnth, lenx); System.arraycopy(samples[1], starth-2*lens[0], samplesC[1], cnth, lenx); cnth += lenx; System.arraycopy(samples[0], starth-1*lens[0], samplesC[0], cnth, lenx); System.arraycopy(samples[1], starth-1*lens[0], samplesC[1], cnth, lenx); cnth += lenx; System.arraycopy(samples[0], starth, samplesC[0], cnth, lenx); System.arraycopy(samples[1], starth, samplesC[1], cnth, lenx); cnth += lenx; System.arraycopy(samples[0], starth+1*lens[0], samplesC[0], cnth, lenx); System.arraycopy(samples[1], starth+1*lens[0], samplesC[1], cnth, lenx); cnth = 0; for (int c=0; c<4; c++) { System.arraycopy(color_bytes[c], starth-2*lens[0], color_bytesC[c], cnth, lenx); } cnth += lenx; for (int c=0; c<4; c++) { System.arraycopy(color_bytes[c], starth-1*lens[0], color_bytesC[c], cnth, lenx); } cnth += lenx; for (int c=0; c<4; c++) { System.arraycopy(color_bytes[c], starth, color_bytesC[c], cnth, lenx); } cnth += lenx; for (int c=0; c<4; c++) { System.arraycopy(color_bytes[c], starth+1*lens[0], color_bytesC[c], cnth, lenx); } Gridded2DSet gseth = new Gridded2DSet(domain_set.getType(), samplesC, lenx, 4); BranchGroup branchh = new BranchGroup(); branchh.setCapability(BranchGroup.ALLOW_DETACH); branchh.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); branchh.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branchh.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); buildCurvedTexture(branchh, gseth, dataUnits, domain_units, default_values, DomainComponents, valueArrayLength, inherited_values, valueToScalar, mode, constant_alpha, value_array, constant_color, color_bytesC, display, curved_size, Domain, dataCoordinateSystem, renderer, adaptedShadowType, new int[] {x_start_stop[j][0], y_start_stop[i][0]}, lenx, leny, samples, lens[0], lens[1]); branch.addChild(branchh); } //- tile piece byte[][] color_bytesW = new byte[4][lenx*leny]; int cnt = 0; for (k=0; k 0) { ((Group) group).setChild(branch, 0); } else { ((Group) group).addChild(branch); } } } // end if (curvedTexture) else { // !isTextureMap && !curvedTexture throw new BadMappingException("must be texture map or curved texture map"); } } else { // !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"); } AnimationControlJ3D control = (AnimationControlJ3D) amap.getControl(); // get any usable frames from the old scene graph Switch old_swit = null; BranchGroup[] old_nodes = null; double[] old_times = null; boolean[] old_mark = null; int old_len = 0; boolean reuse = ((ImageRendererJ3D) renderer).getReUseFrames(); 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) { g = ((BranchGroup) g).getChild(0); } if (g instanceof Switch) { old_swit = (Switch) g; old_len = old_swit.numChildren(); if (old_len > 0) { old_nodes = new BranchGroup[old_len]; for (int i=0; i 0) // create frames for new scene graph // Set aset = control.getSet(); // double[][] values = aset.getDoubles(); double[][] values = domain_set.getDoubles(); double[] times = values[0]; int len = times.length; double delta = Math.abs((times[len-1] - times[0]) / (1000.0 * len)); // create new Switch and make live // control.clearSwitches(this); // already done in DataRenderer.doAction Switch swit = null; if (old_swit != null) { swit = old_swit; ((AVControlJ3D) control).addPair((Switch) swit, domain_set, renderer); ((AVControlJ3D) control).init(); } else { swit = (Switch) makeSwitch(); swit.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND); swit.setCapability(BranchGroup.ALLOW_CHILDREN_READ); swit.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); addSwitch(group, swit, control, domain_set, renderer); } // insert old frames into new scene graph, and make // new (blank) VisADBranchGroups for rendering new frames VisADBranchGroup[] nodes = new VisADBranchGroup[len]; boolean[] mark = new boolean[len]; for (int i=0; i 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { value2 = value_array[i]; break; } } float[][] spatial_values = new float[3][]; spatial_values[tuple_index[0]] = spline_domain[0]; spatial_values[tuple_index[1]] = spline_domain[1]; spatial_values[tuple_index[2]] = new float[nn]; Arrays.fill(spatial_values[tuple_index[2]], value2); for (int i=0; i<3; i++) { if (spatial_maps[i] != null) { //-TDR spatial_values[i] = spatial_maps[i].scaleValues(spatial_values[i]); spatial_values[i] = spatial_maps[i].scaleValues(spatial_values[i], false); } } //System.err.println("Spatial Values:" + spatial_values[0].length); 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 { CoordinateSystem coord = spatial_tuple.getCoordinateSystem(); spatial_values = coord.toReference(spatial_values); // float[][] new_spatial_values = coord.toReference(spatial_values); // for (int i=0; i<3; i++) spatial_values[i] = new_spatial_values[i]; // inside 'if (anyFlow) {}' in ShadowType.assembleSpatial() renderer.setEarthSpatialDisplay(coord, spatial_tuple, display, spatial_value_indices, default_values, null); } // break from ShadowFunctionOrSetType coordinates = new float[3 * nn]; k = 0; for (int i=0; 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][1]; coordinates[3 + tuple_index[1]] = limits[1][0]; 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][0]; coordinates[9 + tuple_index[1]] = limits[1][1]; 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); setTexCoords(texCoords, ratiow, ratioh); normals = new float[12]; float n0 = ((coordinates[3+2]-coordinates[0+2]) * (coordinates[6+1]-coordinates[0+1])) - ((coordinates[3+1]-coordinates[0+1]) * (coordinates[6+2]-coordinates[0+2])); float n1 = ((coordinates[3+0]-coordinates[0+0]) * (coordinates[6+2]-coordinates[0+2])) - ((coordinates[3+2]-coordinates[0+2]) * (coordinates[6+0]-coordinates[0+0])); float n2 = ((coordinates[3+1]-coordinates[0+1]) * (coordinates[6+0]-coordinates[0+0])) - ((coordinates[3+0]-coordinates[0+0]) * (coordinates[6+1]-coordinates[0+1])); float nlen = (float) Math.sqrt(n0 * n0 + n1 * n1 + n2 * n2); n0 = n0 / nlen; n1 = n1 / nlen; n2 = n2 / nlen; // corner 0 normals[0] = n0; normals[1] = n1; normals[2] = n2; // corner 1 normals[3] = n0; normals[4] = n1; normals[5] = n2; // corner 2 normals[6] = n0; normals[7] = n1; normals[8] = n2; // corner 3 normals[9] = n0; normals[10] = n1; normals[11] = n2; colors = new byte[12]; for (int i=0; i<12; i++) colors[i] = (byte) 127; VisADQuadArray qarray = new VisADQuadArray(); qarray.vertexCount = 4; qarray.coordinates = coordinates; qarray.texCoords = texCoords; qarray.colors = colors; qarray.normals = normals; // System.out.println("start createImage " + (System.currentTimeMillis() - link.start_time)); // create BufferedImage for texture from color_bytes BufferedImage image = createImage(data_width, data_height, texture_width, texture_height, color_bytes); // System.out.println("start textureToGroup " + (System.currentTimeMillis() - link.start_time)); // add texture as sub-node of group in scene graph textureToGroup(group, qarray, image, mode, constant_alpha, constant_color, texture_width, texture_height); // System.out.println("end texture map " + (System.currentTimeMillis() - link.start_time)); } public BufferedImage createImage(int data_width, int data_height, int texture_width, int texture_height, byte[][] color_bytes) throws VisADException { ShadowFunctionOrSetType adaptedShadowType = (ShadowFunctionOrSetType) getAdaptedShadowType(); return adaptedShadowType.createImage(data_width, data_height, texture_width, texture_height, color_bytes); // BufferedImage image = null; // ColorModel colorModel = ColorModel.getRGBdefault(); // WritableRaster raster = colorModel.createCompatibleWritableRaster( // texture_width, texture_height); // image = new BufferedImage(colorModel, raster, false, null); // int[] intData = ((DataBufferInt)raster.getDataBuffer()).getData(); // int k = 0; // int m = 0; // int r, g, b, a; // for (int j=0; j 0 && !args[0].equals("X")) { areaFile = args[0]; // mapFile = args[0]; } if (args.length == 2) { threeD = (args[1].indexOf("2") >= 0) ? false : true; remap = (args[1].indexOf("2") >= 0) ? false : true; } boolean gif = areaFile.endsWith("gif") || areaFile.endsWith("GIF") || areaFile.endsWith("jpg") || areaFile.endsWith("JPG"); try { if (mapFile.indexOf("://") > 0) { baseMap = new BaseMapAdapter(new URL(mapFile) ); } else { baseMap = new BaseMapAdapter(mapFile); } //--- map data to display ---// if (gif) { display = new DisplayImplJ3D("display", new TwoDDisplayRendererJ3D()); lat_map = new ScalarMap(RealType.getRealType("ImageLine"), Display.YAxis); lon_map = new ScalarMap(RealType.getRealType("ImageElement"), Display.XAxis); } else if (threeD) { display = new DisplayImplJ3D("display"); lat_map = new ScalarMap(RealType.Latitude, Display.Latitude); lon_map = new ScalarMap(RealType.Longitude, Display.Longitude); } else { display = new DisplayImplJ3D("display", new TwoDDisplayRendererJ3D()); lat_map = new ScalarMap(RealType.Latitude, Display.YAxis); lon_map = new ScalarMap(RealType.Longitude, Display.XAxis); } display.addMap(lat_map); display.addMap(lon_map); if (!gif) { lat_map.setRange(-90.0, 90.0); lon_map.setRange(-180.0, 180.0); } DataReference maplines_ref = new DataReferenceImpl("MapLines"); maplines_ref.setData(baseMap.getData()); ConstantMap[] colMap; colMap = new ConstantMap[4]; colMap[0] = new ConstantMap(0., Display.Blue); colMap[1] = new ConstantMap(1., Display.Red); colMap[2] = new ConstantMap(0., Display.Green); colMap[3] = new ConstantMap(1.001, Display.Radius); // map lines above image FlatField imaget = null; if (gif) { GIFForm gif_form = new GIFForm(); imaget = (FlatField) gif_form.open(areaFile); } else { AreaAdapter aa = new AreaAdapter(areaFile); imaget = aa.getData(); } FunctionType ftype = (FunctionType) imaget.getType(); RealTupleType dtype = ftype.getDomain(); RealTupleType rtype = (RealTupleType)ftype.getRange(); if (remap) { int SIZE = 256; RealTupleType lat_lon = ((CoordinateSystem) dtype.getCoordinateSystem()).getReference(); Linear2DSet dset = new Linear2DSet(lat_lon, -4.0, 70.0, SIZE, -150.0, 5.0, SIZE); imaget = (FlatField) imaget.resample(dset, Data.NEAREST_NEIGHBOR, Data.NO_ERRORS); ftype = (FunctionType) imaget.getType(); dtype = ftype.getDomain(); } if (gif) { ScalarMap rmap = new ScalarMap( (RealType) rtype.getComponent(0), Display.Red); display.addMap(rmap); ScalarMap gmap = new ScalarMap( (RealType) rtype.getComponent(1), Display.Green); display.addMap(gmap); ScalarMap bmap = new ScalarMap( (RealType) rtype.getComponent(2), Display.Blue); display.addMap(bmap); } else { // select which band to show... ScalarMap rgbmap = new ScalarMap( (RealType) rtype.getComponent(0), Display.RGBA); display.addMap(rgbmap); BaseColorControl control = (BaseColorControl) rgbmap.getControl(); control.initGreyWedge(); /* test for RGBA */ float[][] table = control.getTable(); for (int i=0; i

Ads help maintain this website.