//
// 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.