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

import java.awt.Font;
import java.awt.image.BufferedImage;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.ArrayList;

import visad.util.HersheyFont;

/**
 * The ShadowType hierarchy shadows the MathType hierarchy, within a
 * DataDisplayLink.
 * 

*/ public abstract class ShadowType extends Object implements java.io.Serializable { /** possible values for LevelOfDifficulty */ public static final int NOTHING_MAPPED = 6; public static final int SIMPLE_TUPLE = 5; public static final int SIMPLE_ANIMATE_FIELD = 4; public static final int SIMPLE_FIELD = 3; public static final int NESTED = 2; public static final int LEGAL = 1; /** Image ByReference flags **/ public static final String PROP_IMAGE_BY_REF = "visad.java3d.imageByRef"; /** Property to create a texture for a single value color filled contour */ public static final String PROP_CONTOURFILL_SINGLE_VALUE_AS_TEXTURE = "visad.contourFillSingleValueAsTexture"; public static final boolean byReference; public static final boolean yUp; static { byReference = Boolean.parseBoolean(System.getProperty(PROP_IMAGE_BY_REF, "false")); if (byReference) { yUp = true; } else { yUp = false; } //System.err.println("IMAGE_BY_REF:" + byReference); } /** basic information about this ShadowType */ MathType Type; // MathType being shadowed transient DataDisplayLink Link; transient DisplayImpl display; transient private Data data; // from Link.getData() private ShadowType Parent; /** information calculated by constructors */ /** * count of occurences of DisplayRealType-s ShadowScalarType: set for mappings * to DisplayRealType-s ShadowTupleType (incl ShadowRealTupleType): set to sum * for ShadowScalarType & ShadowRealTupleType components ShadowRealTupleType: * add contribution from Reference */ int[] DisplayIndices; /** * ValueIndices is like DisplayIndices, but distinguishes different * ScalarMap-s of non-Single DisplayRealTypes */ int[] ValueIndices; /** * MultipleSpatialDisplayScalar is true if any RealType component is mapped to * multiple spatial DisplayRealType-s */ boolean MultipleSpatialDisplayScalar; /** * MultipleDisplayScalar is true if any RealType component is mapped to * multiple DisplayRealType-s, or if any RealTupleType component and its * Reference are both mapped */ boolean MultipleDisplayScalar; /** * MappedDisplayScalar is true if any RealType component is mapped to any * DisplayRealType-s, including via a RealTupleType.Reference */ boolean MappedDisplayScalar; /** information calculated by checkIndices & testIndices */ boolean isTerminal; int LevelOfDifficulty; boolean isTextureMap; boolean curvedTexture; boolean isTexture3D; boolean isLinearContour3D; boolean adjustProjectionSeam; /** * Dtype and Rtype used only with ShadowSetType and Flat ShadowFunctionType */ int Dtype; // Domain Type: D0, D1, D2, D3, D4 or Dbad int Rtype; // Range Type: R0, R1, R2, R3, R4 or Rbad /** possible values for Dtype */ static final int D0 = 0; // (Unmapped)* static final int D1 = 1; // allSpatial + (SpatialOffset, IsoContour, Flow, // Text, Shape, ShapeScale, Color, Alpha, Range, // Unmapped)* static final int D2 = 2; // (SpatialOffset, Spatial, Color, Alpha, // Range, Unmapped)* static final int D3 = 3; // (Color, Alpha, Range, Unmapped)* static final int D4 = 4; // (Animation, Value)* static final int Dbad = 5; /** possible values for Rtype */ static final int R0 = 0; // (Unmapped)* static final int R1 = 1; // (Color, Alpha, Range, Unmapped)* static final int R2 = 2; // (Spatial, SpatialOffset, Color, Alpha, // Range, Unmapped)* static final int R3 = 3; // (IsoContour, Flow, Text, Shape, ShapeScale Color, // Alpha, Range, Unmapped)* static final int R4 = 4; // (Spatial, SpatialOffset, IsoContour, Flow, // Text, Shape, ShapeScale, Color, Alpha, Range, // Unmapped)* static final int Rbad = 5; /** spatial DisplayTupleType at terminal nodes */ DisplayTupleType spatialTuple = null; /** number of spatial DisplayRealType components at terminal nodes */ int spatialDimension; /** flags for any IsoContour or Flow at terminal nodes */ boolean anyContour; boolean anyFlow; boolean anyShape; boolean anyText; /** streamline flags */ boolean streamline1; boolean streamline2; float streamlineDensity1; float streamlineDensity2; float arrowScale1; float arrowScale2; float stepFactor1; float stepFactor2; float packingFactor1; float packingFactor2; float cntrWeight1; float cntrWeight2; int n_pass1; int n_pass2; float reduction1; float reduction2; // --------------------- /** trajectory flags */ public boolean trajectory1 = false; public boolean trajectory2 = false; protected ArrayList flowInfoList = new ArrayList(); /** makeContour, manifoldDimension == 2 */ int[] cnt = { 0 }; ProjectionControl p_cntrl = null; ContourControl c_cntrl = null; // ------------------------------------- /** * makeContour, manifoldDimension == 3. Needed for case of missing final * spatial coords */ float[][] spatial_offset_values = null; /** * used by getComponents to record RealTupleTypes with coordinate transforms */ int[] refToComponent; ShadowRealTupleType[] componentWithRef; int[] componentIndex; public ShadowType(MathType type, DataDisplayLink link, ShadowType parent) throws VisADException, RemoteException { Type = type; Link = link; display = link.getDisplay(); Parent = parent; data = link.getData(); DisplayIndices = zeroIndices(display.getDisplayScalarCount()); ValueIndices = zeroIndices(display.getValueArrayLength()); isTerminal = false; isTextureMap = false; curvedTexture = false; isTexture3D = false; isLinearContour3D = false; adjustProjectionSeam = true; LevelOfDifficulty = NOTHING_MAPPED; MultipleSpatialDisplayScalar = false; MultipleDisplayScalar = false; MappedDisplayScalar = false; p_cntrl = display.getProjectionControl(); } public DataDisplayLink getLink() { return Link; } public int getLevelOfDifficulty() { return LevelOfDifficulty; } public boolean getIsTerminal() { return isTerminal; } public boolean getIsTextureMap() { return isTextureMap; } public boolean getCurvedTexture() { return curvedTexture; } public boolean getIsTexture3D() { return isTexture3D; } public boolean getIsLinearContour3D() { return isLinearContour3D; } public int[] getRefToComponent() { return refToComponent; } public ShadowRealTupleType[] getComponentWithRef() { return componentWithRef; } public int[] getComponentIndex() { return componentIndex; } public boolean getAdjustProjectionSeam() { return adjustProjectionSeam; } public ShadowRealType[] getComponents(ShadowType type, boolean doRef) throws VisADException { if (type == null) return null; if (doRef) { refToComponent = null; componentWithRef = null; componentIndex = null; } ShadowRealType[] reals; if (type instanceof ShadowRealType) { ShadowRealType[] r = { (ShadowRealType) type }; return r; } else if (type instanceof ShadowRealTupleType) { int n = ((ShadowRealTupleType) type).getDimension(); reals = new ShadowRealType[n]; for (int i = 0; i < n; i++) { reals[i] = (ShadowRealType) ((ShadowRealTupleType) type) .getComponent(i); } if (doRef) { ShadowRealTupleType ref = ((ShadowRealTupleType) type).getReference(); if (ref != null && ref.getMappedDisplayScalar()) { refToComponent = new int[1]; componentWithRef = new ShadowRealTupleType[1]; componentIndex = new int[1]; refToComponent[0] = 0; componentWithRef[0] = (ShadowRealTupleType) type; componentIndex[0] = 0; } } } else if (type instanceof ShadowTupleType) { int m = ((ShadowTupleType) type).getDimension(); int n = 0; int nref = 0; for (int i = 0; i < m; i++) { ShadowType component = ((ShadowTupleType) type).getComponent(i); if (component instanceof ShadowRealType) { n++; } else if (component instanceof ShadowRealTupleType) { n += getComponents(component, false).length; if (doRef) { ShadowRealTupleType ref = ((ShadowRealTupleType) component) .getReference(); if (ref != null && ref.getMappedDisplayScalar()) nref++; } } } reals = new ShadowRealType[n]; int j = 0; if (nref == 0) doRef = false; if (doRef) { refToComponent = new int[nref]; componentWithRef = new ShadowRealTupleType[nref]; componentIndex = new int[nref]; } int rj = 0; for (int i = 0; i < m; i++) { ShadowType component = ((ShadowTupleType) type).getComponent(i); if (component instanceof ShadowRealType || component instanceof ShadowRealTupleType) { /* * WLH 17 April 99 ShadowRealType[] r = getComponents(component, * false); for (int k=0; k 0) isTerminal = true; if (display_indices[i] > 1 && real.isSingle()) { throw new BadMappingException("Single " + "DisplayRealType " + real.getName() + " occurs more than once: " + "ShadowType.testIndices"); } } // test whether DisplayRealType-s from multiple // spatial DisplayTupleType-s occur spatialTuple = null; spatialDimension = 0; for (int i = 0; i < display_indices.length; i++) { if (display_indices[i] > 0) { DisplayRealType real = (DisplayRealType) display.getDisplayScalar(i); DisplayTupleType rtuple = real.getTuple(); if (rtuple != null) { if (rtuple.equals(Display.DisplaySpatialCartesianTuple) || (rtuple.getCoordinateSystem() != null && rtuple .getCoordinateSystem().getReference().equals( Display.DisplaySpatialCartesianTuple))) { if (spatialTuple != null && !spatialTuple.equals(rtuple)) { throw new BadMappingException("DisplayRealType-s occur from " + "multiple spatial DisplayTupleType-s: " + "ShadowType.testIndices"); } spatialTuple = rtuple; spatialDimension++; } } } } if (isTerminal) { if (levelOfDifficulty == LEGAL) { LevelOfDifficulty = LEGAL; } else { LevelOfDifficulty = NESTED; } } else { // this is not illegal but also not a terminal node // (no DisplayRealType-s mapped) LevelOfDifficulty = NOTHING_MAPPED; } /* * System.out.println("testIndices: LevelOfDifficulty = " + * LevelOfDifficulty + " isTerminal = " + isTerminal + " Type = " + * Type.prettyString()); */ return LevelOfDifficulty; } /* * DEPRECATE THIS, no longer needed because SetTypes, Flat FieldTypes and Flat * TupleTypes are terminals: this defines the default logic for ShadowTextType * and ShadowMissingType - which may occur as a Field Range and are treated as * unmapped */ /** * scans ShadowType tree to determine display feasibility and precompute * useful information for Data transform; indices & display_indices are counts * (at leaves) of numbers of occurrences of RealTypes and DisplayRealTypes; * isTransform flags for (Animation, Range, Value) re-transform; * levelOfDifficulty passed down and up call chain */ public int checkIndices(int[] indices, int[] display_indices, int[] value_indices, boolean[] isTransform, int levelOfDifficulty) throws VisADException, RemoteException { adjustProjectionSeam = checkAdjustProjectionSeam(); LevelOfDifficulty = testIndices(indices, display_indices, levelOfDifficulty); return LevelOfDifficulty; } public DisplayImpl getDisplay() { return display; } public MathType getType() { return Type; } public boolean getMultipleDisplayScalar() { return MultipleDisplayScalar; } public boolean getMultipleSpatialDisplayScalar() { return MultipleSpatialDisplayScalar; } public boolean getMappedDisplayScalar() { return MappedDisplayScalar; } public int[] getDisplayIndices() { int[] ii = new int[DisplayIndices.length]; for (int i = 0; i < DisplayIndices.length; i++) ii[i] = DisplayIndices[i]; return ii; } public int[] getValueIndices() { int[] ii = new int[ValueIndices.length]; for (int i = 0; i < ValueIndices.length; i++) ii[i] = ValueIndices[i]; return ii; } public ArrayList getFlowInfo() { return this.flowInfoList; } /** * return true if DisplayIndices include multiple Animation, SelectValue and * SelectRange */ boolean testTransform() { int count = 0; for (int i = 0; i < DisplayIndices.length; i++) { if (DisplayIndices[i] == 0) continue; DisplayRealType real = (DisplayRealType) display.getDisplayScalar(i); if (real.equals(Display.Animation) || real.equals(Display.SelectValue) || real.equals(Display.SelectRange)) { count++; if (count > 1) return true; } } return false; } /** * mark Control-s as needing re-Transform; default for ShadowTextType and * ShadowMissingType */ void markTransform(boolean[] isTransform) { } /** * helpers for doTransform; they are in ShadowType because they are * independent of graphics library */ /** map values to display_values according to ScalarMap-s in reals */ public static void mapValues(float[][] display_values, double[][] values, ShadowRealType[] reals) throws VisADException { int n = values.length; if (n != reals.length) { throw new DisplayException("lengths don't match " + n + " != " + reals.length + ": " + "ShadowType.mapValues"); } for (int i = 0; i < n; i++) { Enumeration maps = reals[i].getSelectedMapVector().elements(); while (maps.hasMoreElements()) { ScalarMap map = (ScalarMap) maps.nextElement(); int value_index = map.getValueIndex(); /* * double[] range = map.getRange(); System.out.println(map.getScalar() + * " -> " + map.getDisplayScalar() + " : " + range[0] + " " + range[1] + * " value_index = " + value_index); */ // MEM display_values[value_index] = map.scaleValues(values[i]); /* * int m = values[i].length; for (int j=0; j 1) doCopy = true; Enumeration maps = reals[i].getSelectedMapVector().elements(); while (maps.hasMoreElements()) { ScalarMap map = (ScalarMap) maps.nextElement(); int value_index = map.getValueIndex(); /* * double[] range = map.getRange(); System.out.println(map.getScalar() + * " -> " + map.getDisplayScalar() + " : " + range[0] + " " + range[1] + * " value_index = " + value_index); */ // MEM display_values[value_index] = map.scaleValues(values[i], doCopy); /* * int m = values[i].length; for (int j=0; j 0) { float[][] new_s_values = new float[len][flen - nan]; byte[][] new_c_values = color_values; if (clen > 0) new_c_values = new byte[clen][flen - nan]; int c = 0; for (int i = 0; i < flen; i++) { if (f[i] == f[i]) { for (int j = 0; j < len; j++) { new_s_values[j][c] = spatial_values[j][i]; } for (int j = 0; j < clen; j++) { new_c_values[j][c] = color_values[j][i]; } c++; } } spatial_values = new_s_values; color_values = new_c_values; } } // set coordinates and colors // MEM SampledSet.setGeometryArray(array, spatial_values, 4, color_values); return array; } /* CTR: 13 Oct 1998 - END CHANGES */ /** * collect and transform Shape DisplayRealType values from display_values; * offset by spatial_values, colored by color_values and selected by * range_select */ public VisADGeometryArray[] assembleShape(float[][] display_values, int valueArrayLength, int[] valueToMap, Vector MapVector, int[] valueToScalar, DisplayImpl display, float[] default_values, int[] inherited_values, float[][] spatial_values, byte[][] color_values, boolean[][] range_select, int index, ShadowType shadow_api) throws VisADException, RemoteException { if (spatial_values[0] == null) return null; int total_length = 0; Vector array_vector = new Vector(); float x = spatial_values[0][0]; float y = spatial_values[1][0]; float z = spatial_values[2][0]; byte r = 0; byte g = 0; byte b = 0; byte a = 0; int color_length = 0; if (color_values != null) { color_length = color_values.length; r = color_values[0][0]; g = color_values[1][0]; b = color_values[2][0]; if (color_length > 3) a = color_values[3][0]; } float[] scales = null; for (int i = 0; i < valueArrayLength; i++) { if (display_values[i] != null) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); if (real.equals(Display.ShapeScale)) { if (index < 0) { scales = display_values[i]; display_values[i] = null; // MEM_WLH 27 March 99 } else { if (display_values[i].length == 1) { scales = new float[] { display_values[i][0] }; } else { scales = new float[] { display_values[i][index] }; } } } } } if (scales == null) { int default_index = display.getDisplayScalarIndex(Display.ShapeScale); float default_scale = default_values[default_index]; scales = new float[] { default_scale }; } float[] values = null; ShapeControl control = null; for (int j = 0; j < valueArrayLength; j++) { if (display_values[j] != null) { int displayScalarIndex = valueToScalar[j]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); if (real.equals(Display.Shape)) { if (index < 0) { values = display_values[j]; display_values[j] = null; // MEM_WLH 27 March 99 } else { if (display_values[j].length == 1) { values = new float[] { display_values[j][0] }; } else { values = new float[] { display_values[j][index] }; } } control = (ShapeControl) ((ScalarMap) MapVector .elementAt(valueToMap[j])).getControl(); if (values == null || control == null) continue; // make len maximum of lengths of color_values, // spatial_values & scales int len = values.length; if (color_values != null) { if (color_values[0].length > len) len = color_values[0].length; } if (spatial_values[0].length > len) len = spatial_values[0].length; if (scales.length > len) len = scales.length; // expand values if necessary if (values.length < len) { float[] new_values = new float[len]; for (int i = 0; i < len; i++) new_values[i] = values[0]; values = new_values; } // WLH 31 May 2000 float cscale = control.getScale(); VisADGeometryArray[] arrays = control.getShapes(values); for (int i = 0; i < arrays.length; i++) { if (range_select[0] != null) { if (range_select[0].length == 1) { if (!range_select[0][0]) arrays[i] = null; } else { if (!range_select[0][i]) arrays[i] = null; } } VisADGeometryArray array = arrays[i]; if (array != null) { if (spatial_values[0].length > 1) { x = spatial_values[0][i]; y = spatial_values[1][i]; z = spatial_values[2][i]; } int npts = array.coordinates.length / 3; // offset shape location by spatial values float scale = (scales.length == 1) ? scales[0] : scales[i]; // WLH 31 May 2000 scale *= cscale; for (int k = 0; k < array.coordinates.length; k += 3) { array.coordinates[k] = x + scale * array.coordinates[k]; array.coordinates[k + 1] = y + scale * array.coordinates[k + 1]; array.coordinates[k + 2] = z + scale * array.coordinates[k + 2]; } if (array.colors == null && color_values != null) { array.colors = new byte[color_length * npts]; if (color_values[0].length > 1) { r = color_values[0][i]; g = color_values[1][i]; b = color_values[2][i]; if (color_length > 3) a = color_values[3][i]; } for (int k = 0; k < array.colors.length; k += color_length) { array.colors[k] = r; array.colors[k + 1] = g; array.colors[k + 2] = b; if (color_length > 3) array.colors[k + 3] = a; } } } } // end for (int i=0; i 0 && allSpatial && domain_set != null // spatialManifoldDimension spatialDimensions[1] = domain_set.getManifoldDimension(); } // // need a spatial Set for shape (e.g., contour) // or spatialManifoldDimension < 3 // NOTE - 3-D volume rendering may eventually need a spatial Set // boolean set_needed = domain_set != null && (set_for_shape || spatialDimensions[1] < 3); boolean[] missing_checked = { false, false, false }; for (int i = 0; i < 3; i++) { if (spatial_values[i] == null) { // fill any null spatial value arrays with default values // MEM spatial_values[i] = new float[len]; int default_index = display .getDisplayScalarIndex(((DisplayRealType) spatial_tuple .getComponent(i))); float default_value = default_values[default_index]; java.util.Arrays.fill(spatial_values[i], default_value); missing_checked[i] = true; } else if (spatial_values[i].length == 1) { // check solitary spatial value array for missing float v = spatial_values[i][0]; missing_checked[i] = true; if (v != v || Float.isInfinite(v)) { // missing with length = 1, so nothing to render range_select[0] = new boolean[1]; range_select[0][0] = false; return null; } if (len > 1) { // expand solitary spatial value array // MEM spatial_values[i] = new float[len]; for (int j = 0; j < len; j++) spatial_values[i][j] = v; } } } // end for (int i=0; i<3; i++) // first equalize lengths of flow*_values and spatial_values boolean anyFlow = false; int[] flen = { 0, 0 }; float[][][] ff_values = { flow1_values, flow2_values }; for (int k = 0; k < 2; k++) { for (int i = 0; i < 3; i++) { if (ff_values[k][i] != null) { anyFlow = true; flen[k] = Math.max(flen[k], ff_values[k][i].length); } } } len = Math.max(len, Math.max(flen[0], flen[1])); fillOut(spatial_values, len); if (flen[0] > 0) fillOut(flow1_values, len); if (flen[1] > 0) fillOut(flow2_values, len); boolean spatial_flow = anyFlow; for (int i = 0; i < 3; i++) { if (ranges[i] == ranges[i]) { if (spatial_units[i] == null) { spatial_flow = false; break; } for (int j = 0; j < 3; j++) { if (ranges[j] == ranges[j]) { if (spatial_units[j] == null) { spatial_flow = false; break; } if (!Unit.canConvert(spatial_units[i], spatial_units[j])) { spatial_flow = false; break; } } } } } // System.out.println("spatial_flow = " + spatial_flow); boolean[] spatial_flows = new boolean[] {spatial_flow,spatial_flow}; if (spatial_flow) { for (int i = 0; i < valueArrayLength; i++) { if (display_values[i] != null) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); DisplayTupleType tuple = real.getTuple(); if (tuple != null) { if (tuple.equals(Display.DisplayFlow1SphericalTuple) || tuple.equals(Display.DisplayFlow2SphericalTuple)) { int index = tuple.equals(Display.DisplayFlow1SphericalTuple) ? 0 : 1; spatial_flows[index] = false; display_values[i] = null; } } } } // adjust flow for spatial setRange scaling double max_range = -1.0; for (int i = 0; i < 3; i++) { if (ranges[i] == ranges[i]) { double ar = Math.abs(ranges[i]); if (ar > max_range) max_range = ar; } } for (int i = 0; i < 3; i++) { if (ranges[i] == ranges[i]) { ranges[i] = ranges[i] / max_range; } else { ranges[i] = 1.0; } } for (int k = 0; k < 2; k++) { if (!(renderer.getRealVectorTypes(k) instanceof EarthVectorType) && spatial_flows[k]) { if (ff_values[k][0] != null || ff_values[k][1] != null || ff_values[k][2] != null) { for (int j = 0; j < len; j++) { float old_speed = 0.0f; float new_speed = 0.0f; for (int i = 0; i < 3; i++) { if (ff_values[k][i] != null) { old_speed += ff_values[k][i][j] * ff_values[k][i][j]; ff_values[k][i][j] *= ranges[i]; new_speed += ff_values[k][i][j] * ff_values[k][i][j]; } } // but don't change vector magnitude ?? float ratio = (float) Math.sqrt(old_speed / new_speed); // BMF 2009-03-04: flow values cannot be NaN if (Float.isNaN(ratio)) ratio = 0f; for (int i = 0; i < 3; i++) { if (ff_values[k][i] != null) { ff_values[k][i][j] *= ratio; } } } } // end if (ff_values[k][0] != null || ...) } // end if (!(renderer.getRealVectorTypes(k) instanceof // EarthVectorType)) } // end for (int k=0; k<2; k++) } // end if (spatial_flow) // adjust Flow values for coordinate transform if (spatial_tuple.equals(Display.DisplaySpatialCartesianTuple)) { // if (anyFlow) { WLH 4 March 2000 renderer.setEarthSpatialDisplay(null, spatial_tuple, display, spatial_value_indices, default_values, ranges); // } WLH 4 March 2000 } else { // transform tuple_values to DisplaySpatialCartesianTuple CoordinateSystem coord = spatial_tuple.getCoordinateSystem(); float[][][] vector_ends = new float[2][][]; // WLH 4 March 2000 renderer.setEarthSpatialDisplay(coord, spatial_tuple, display, spatial_value_indices, default_values, ranges); if (spatial_flow) { if (anyFlow) { // WLH 4 March 2000 // renderer.setEarthSpatialDisplay(coord, spatial_tuple, display, // spatial_value_indices, default_values, ranges); // compute and transform 'end points' of flow vectors for (int k = 0; k < 2; k++) { if (!(renderer.getRealVectorTypes(k) instanceof EarthVectorType) && spatial_flows[k]) { if (flen[k] > 0) { vector_ends[k] = new float[3][len]; for (int i = 0; i < 3; i++) { if (ff_values[k][i] != null) { for (int j = 0; j < len; j++) { vector_ends[k][i][j] = spatial_values[i][j] + flowScale[k] * ff_values[k][i][j]; } } else { // (ff_values[k][i] == null) for (int j = 0; j < len; j++) { vector_ends[k][i][j] = spatial_values[i][j]; } } } // end for (int i=0; i<3; i++) vector_ends[k] = coord.toReference(vector_ends[k]); } // end if (flen[k] > 0) } // end if (!(renderer.getRealVectorTypes(k) instanceof // EarthVectorType)) } // end for (int k=0; k<2; k++) } } // end if (spatial_flow) // transform spatial_values float[][] new_spatial_values = coord.toReference(spatial_values); /* * System.out.println("in length = " + spatial_values[0].length + * " out length = " + new_spatial_values[0].length); if * (spatial_values[0].length == 5329) { // System.out.println(domain_set); * // 73 73 for (int i=0; i 0) { for (int i = 0; i < 3; i++) { for (int j = 0; j < len; j++) { vector_ends[k][i][j] = (vector_ends[k][i][j] - spatial_values[i][j]) / flowScale[k]; } ff_values[k][i] = vector_ends[k][i]; } } } // end if (!(renderer.getRealVectorTypes(k) instanceof // EarthVectorType)) } // end for (int k=0; k<2; k++) } } // end if (spatial_flow) missing_checked = new boolean[] { false, false, false }; } // end if (!spatial_tuple.equals(Display.DisplaySpatialCartesianTuple)) // calculate if need to swap rows and cols in contour line labels swap[0] = false; if (allSpatial && spatialDimensions[1] == 2 && len > 1) { // find the axis most nearly parallel to first grid direction // i.e., vector from first sample (0) to second sample (1) float simax = 0.0f; float max = -1.0f; int imax = -1; for (int i = 0; i < 3; i++) { float sdiff = spatial_values[i][1] - spatial_values[i][0]; float diff = Math.abs(sdiff); if (diff > max) { simax = sdiff; max = diff; imax = i; } } // set ll = number of samples along a side of fastest factor of // Gridded2DSet // i.e., "stride" // WLH 6 April 2001 // int ll = len; int ll = len - 1; if (domain_set != null && domain_set instanceof Gridded2DSet) { ll = ((Gridded2DSet) domain_set).getLength(0); if (ll > (len - 1)) ll = len - 1; // WLH 6 April 2001 } // find the axis most nearly parallel to second grid direction // i.e., vector from first sample (0) to second sample (1) float sjmax = 0.0f; max = -1.0f; int jmax = -1; for (int i = 0; i < 3; i++) { if (i != imax) { // WLH 6 April 2001 // float sdiff = spatial_values[i][ll-1] - spatial_values[i][0]; float sdiff = spatial_values[i][ll] - spatial_values[i][0]; float diff = Math.abs(sdiff); if (diff > max) { sjmax = sdiff; max = diff; jmax = i; } } } // end for (int i=0; i<3; i++) /*-TDR, debug System.out.println("imax: "+imax+" jmax: "+jmax); System.out.println("simax: "+simax+" sjmax: "+sjmax); */ if (imax == 0) { swap[0] = true; swap[1] = (simax < 0.0f); swap[2] = (sjmax < 0.0f); } else if (imax == 1) { /*-TDR, (4-18-01): wrong grid dimension swapped swap[1] = (sjmax < 0.0f); swap[2] = (simax < 0.0f); */ swap[2] = (sjmax < 0.0f); swap[1] = (simax < 0.0f); } else { // imax == 2 if (jmax == 1) { swap[0] = true; swap[1] = (simax < 0.0f); swap[2] = (sjmax < 0.0f); } else { /*-TDR, (4-18-01) Untested: should probably be same as change above swap[1] = (sjmax < 0.0f); swap[2] = (simax < 0.0f); */ swap[2] = (sjmax < 0.0f); swap[1] = (simax < 0.0f); } } /*-TDR, debug System.out.println("swap[0]: "+swap[0]+" swap[1]: "+swap[1]+ " swap[2]: "+swap[2]); */ } // assemble SpatialOffsets int offset_len = len; for (int i = 0; i < valueArrayLength; i++) { if (display_values[i] != null) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); DisplayTupleType tuple = real.getTuple(); if (Display.DisplaySpatialOffsetTuple.equals(tuple)) { int tuple_index = real.getTupleIndex(); if (offset_values[tuple_index] == null) { offset_values[tuple_index] = display_values[i]; } else { int leno = offset_values[tuple_index].length; int lend = display_values[i].length; if (leno > lend) { // assume lend == 1 float[] off; if (offset_copy[tuple_index]) { off = offset_values[tuple_index]; } else { off = new float[leno]; offset_copy[tuple_index] = true; } for (int j = 0; j < leno; j++) { off[j] = offset_values[tuple_index][j] + display_values[i][0]; } offset_values[tuple_index] = off; off = null; } else if (leno < lend) { // assume leno == 1 float[] off = new float[lend]; for (int j = 0; j < lend; j++) { off[j] = offset_values[tuple_index][0] + display_values[i][j]; } offset_values[tuple_index] = off; off = null; offset_copy[tuple_index] = true; } else { float[] off; if (offset_copy[tuple_index]) { off = offset_values[tuple_index]; } else { off = new float[leno]; offset_copy[tuple_index] = true; } for (int j = 0; j < leno; j++) { off[j] = offset_values[tuple_index][j] + display_values[i][j]; } offset_values[tuple_index] = off; off = null; } } display_values[i] = null; // MEM_WLH 27 March 99 offset_len = Math.max(offset_len, offset_values[tuple_index].length); } // end if (Display.DisplaySpatialOffsetTuple.equals(tuple)) } // end if (display_values[i] != null) } // end for (int i=0; i len) { // assume len == 1 for (int i = 0; i < 3; i++) { float[] s = new float[offset_len]; for (int k = 0; k < offset_len; k++) s[k] = spatial_values[i][0]; spatial_values[i] = s; s = null; } len = offset_len; } // add any spatial offsets to spatial values for (int i = 0; i < 3; i++) { if (offset_values[i] != null) { int leno = offset_values[i].length; if (leno < len) { // assume leno == 1 for (int k = 0; k < offset_len; k++) { spatial_values[i][k] += offset_values[i][0]; } } else { // assume leno == len for (int k = 0; k < offset_len; k++) { spatial_values[i][k] += offset_values[i][k]; } } offset_values[i] = null; missing_checked[i] = missing_checked[i] && offset_missing_checked[i]; } if (!missing_checked[i]) { for (int j = 0; j < len; j++) { if (spatial_values[i][j] != spatial_values[i][j] || Float.isInfinite(spatial_values[i][j])) { if (range_select[0] == null) { range_select[0] = new boolean[len]; for (int k = 0; k < len; k++) range_select[0][k] = true; } else if (range_select[0].length < len) { // assume range_select[0].length == 1 boolean[] r = new boolean[len]; for (int k = 0; k < len; k++) r[k] = range_select[0][0]; range_select[0] = r; } range_select[0][j] = false; spatial_values[i][j] = Float.NaN; } } } } // end for (int i=0; i<3; i++) spatial_offset_values = offset_values; if (set_needed) { try { if (spatialDimension == 0) { double[] values = new double[3]; for (int i = 0; i < 3; i++) values[i] = spatial_values[i][0]; RealTuple tuple = new RealTuple(Display.DisplaySpatialCartesianTuple, values); return new SingletonSet(tuple); } else { SetType type = new SetType(Display.DisplaySpatialCartesianTuple); // MEM // WLH 5 April 2000 // return domain_set.makeSpatial(type, spatial_values); return shadow_api.makeSpatialSet(domain_set, type, spatial_values); } } catch (VisADException e) { return null; } } else { return null; } } // WLH 5 April 2000 public Set makeSpatialSet(Set domain_set, SetType type, float[][] spatial_values) throws VisADException { return domain_set.makeSpatial(type, spatial_values); } private static void fillOut(float[][] values, int flen) { for (int i = 0; i < values.length; i++) { if (values[i] != null) { int len = values[i].length; if (len < flen) { // assume len == 1 float[] s = new float[flen]; float v = values[i][0]; for (int k = 0; k < flen; k++) s[k] = v; values[i] = s; } } } } /** * assemble Flow components; Flow components are 'single', so no compositing * is required */ public void assembleFlow(float[][] flow1_values, float[][] flow2_values, float[] flowScale, float[] arrowScale, float[][] display_values, int valueArrayLength, int[] valueToScalar, DisplayImpl display, float[] default_values, boolean[][] range_select, DataRenderer renderer, ShadowType shadow_api) throws VisADException, RemoteException { int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); int[] flen = { 0, 0 }; float[][][] ff_values = { flow1_values, flow2_values }; DisplayTupleType[] flow_tuple = { Display.DisplayFlow1Tuple, Display.DisplayFlow2Tuple }; DisplayTupleType[] actual_tuple = { null, null }; boolean anyFlow = false; /* * WLH 15 April 2000 ScalarMap[][] maps = new ScalarMap[2][3]; */ for (int i = 0; i < valueArrayLength; i++) { if (display_values[i] != null) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); DisplayTupleType tuple = real.getTuple(); for (int k = 0; k < 2; k++) { if (tuple != null && (tuple.equals(flow_tuple[k]) || (tuple.getCoordinateSystem() != null && tuple .getCoordinateSystem().getReference().equals(flow_tuple[k])))) { if (actual_tuple[k] != null && !actual_tuple[k].equals(tuple)) { throw new DisplayException("multiple flow " + k + " display tuples: " + "ShadowType.assembleFlow"); } actual_tuple[k] = tuple; ScalarMap map = (ScalarMap) MapVector.elementAt(valueToMap[i]); FlowControl control = (FlowControl) map.getControl(); flowScale[k] = control.getFlowScale(); arrowScale[k] = control.getArrowScale(); int flow_index = real.getTupleIndex(); ff_values[k][flow_index] = display_values[i]; flen[k] = Math.max(flen[k], display_values[i].length); // if not DisplayFlow*SphericalTuple, null out values if (actual_tuple[k].equals(flow_tuple[k])) { display_values[i] = null; // MEM_WLH 27 March 99 } /* * WLH 15 April 2000 maps[k][flow_index] = map; */ anyFlow = true; if (k == 0) { streamline1 = control.streamlinesEnabled(); streamlineDensity1 = control.getStreamlineDensity(); arrowScale1 = control.getArrowScale(); stepFactor1 = control.getStepFactor(); packingFactor1 = control.getStreamlinePacking(); float[] pp = control.getStreamlineSmoothing(); cntrWeight1 = pp[0]; n_pass1 = (int) pp[1]; reduction1 = control.getStreamlineReduction(); trajectory1 = control.trajectoryEnabled(); if (trajectory1) { ff_values[k][flow_index] = map.inverseScaleValues(ff_values[k][flow_index], true); flowScale[k] = 1f; } } if (k == 1) { streamline2 = control.streamlinesEnabled(); streamlineDensity2 = control.getStreamlineDensity(); arrowScale2 = control.getArrowScale(); stepFactor2 = control.getStepFactor(); packingFactor2 = control.getStreamlinePacking(); float[] pp = control.getStreamlineSmoothing(); cntrWeight2 = pp[0]; n_pass2 = (int) pp[1]; reduction2 = control.getStreamlineReduction(); trajectory2 = control.trajectoryEnabled(); if (trajectory2) { ff_values[k][flow_index] = map.inverseScaleValues(ff_values[k][flow_index], true); flowScale[k] = 1f; } } } } } } /* * WLH 15 April 2000 if (anyFlow) renderer.setFlowDisplay(maps, flowScale); */ // // TO_DO // this should all happen in flow rendering method // for (int k = 0; k < 2; k++) { boolean[] missing_checked = { false, false, false }; if (flen[k] > 0) { for (int i = 0; i < 3; i++) { if (ff_values[k][i] == null) { // fill any null flow value arrays with default values // MEM ff_values[k][i] = new float[flen[k]]; int default_index = display .getDisplayScalarIndex(((DisplayRealType) flow_tuple[k] .getComponent(i))); float default_value = default_values[default_index]; for (int j = 0; j < flen[k]; j++) { ff_values[k][i][j] = default_value; } missing_checked[i] = true; } else if (ff_values[k][i].length == 1) { // check solitary spatial value array for missing float v = ff_values[k][i][0]; missing_checked[i] = true; if (v != v) { // missing with length = 1, so nothing to render range_select[0] = new boolean[1]; range_select[0][0] = false; return; } if (flen[k] > 1) { // expand solitary flow value array ff_values[k][i] = new float[flen[k]]; for (int j = 0; j < flen[k]; j++) { ff_values[k][i][j] = v; } } } // end if (ff_values[k][i].length == 1) } // end for (int i=0; i<3; i++) } // end if (flen[k] > 0) if (actual_tuple[k] != null && !actual_tuple[k].equals(flow_tuple[k])) { missing_checked = new boolean[] { false, false, false }; // transform tuple_values to flow_tuple[k] CoordinateSystem coord = actual_tuple[k].getCoordinateSystem(); float[][] new_ff_values = coord.toReference(ff_values[k]); for (int i = 0; i < 3; i++) ff_values[k][i] = new_ff_values[i]; } if (flen[k] > 0) { for (int i = 0; i < 3; i++) { if (!missing_checked[i]) { for (int j = 0; j < flen[k]; j++) { if (ff_values[k][i][j] != ff_values[k][i][j]) { if (range_select[0] == null) { range_select[0] = new boolean[flen[k]]; for (int m = 0; m < flen[k]; m++) range_select[0][m] = true; } else if (range_select[0].length < flen[k]) { // assume range_select[0].length == 1 boolean[] r = new boolean[flen[k]]; for (int m = 0; m < flen[k]; m++) r[m] = range_select[0][0]; range_select[0] = r; } range_select[0][j] = false; ff_values[k][i][j] = 0.0f; } } // end for (int j=0; j 0) } // end for (int k=0; k<2; k++) // end of 'this should all happen in flow rendering method' } public static final float METERS_PER_DEGREE = 111137.0f; public static float[][] adjustFlowToEarth(int which, float[][] flow_values, float[][] spatial_values, float flowScale, DataRenderer renderer) throws VisADException { return adjustFlowToEarth(which, flow_values, spatial_values, flowScale, renderer, false); } public static float[][] adjustFlowToEarth(int which, float[][] flow_values, float[][] spatial_values, float flowScale, DataRenderer renderer, boolean force) throws VisADException { return adjustFlowToEarth(which, flow_values, spatial_values, flowScale, renderer, force, false, 3600f); } public static float[][] adjustFlowToEarth(int which, float[][] flow_values, float[][] spatial_values, float flowScale, DataRenderer renderer, boolean force, boolean isTraj, float timeStep) throws VisADException { // System.out.println("adjustFlowToEarth " + renderer.getDisplay().getName() // + " " + renderer.getRealVectorTypes(which)); // IDV // Move this down into the check for shouldAdjust //if (!(renderer.getRealVectorTypes(which) instanceof EarthVectorType) && !force) { // only do this for EarthVectorType // return flow_values; //} FlowControl fcontrol = null; DisplayImpl display = null; boolean shouldAdjust = true; DataDisplayLink link = renderer.getLinks()[0]; if (link != null && !force) { display = link.getDisplay(); if (display != null) { if (which == 0) { fcontrol = (FlowControl) display.getControl(Flow1Control.class); } else if (which == 1) { fcontrol = (FlowControl) display.getControl(Flow2Control.class); } if (fcontrol == null) { throw new VisADException( "adjustFlowToEarth: Unable to get FlowControl"); } shouldAdjust = fcontrol.getAdjustFlowToEarth(); // add one more check Vector maps = link.getSelectedMapVector(); boolean haveSpeedDir = false; for (int i = 0; i < maps.size(); i++) { ScalarMap map = (ScalarMap) maps.get(i); DisplayRealType displayType = map.getDisplayScalar(); if ((which == 0 && (displayType.equals(Display.Flow1Azimuth) || displayType.equals(Display.Flow1Radial) || displayType.equals(Display.Flow1Elevation))) || (which == 1 && (displayType.equals(Display.Flow2Azimuth) || displayType.equals(Display.Flow2Radial) || displayType.equals(Display.Flow2Elevation)))) { haveSpeedDir = true; break; } } if (!(renderer.getRealVectorTypes(which) instanceof EarthVectorType) && !haveSpeedDir ) { shouldAdjust = false; } } } if (!shouldAdjust) return flow_values; int flen = flow_values[0].length; // get flow_values maximum float scale = 0.0f; for (int j = 0; j < flen; j++) { if (Math.abs(flow_values[0][j]) > scale) { scale = (float) Math.abs(flow_values[0][j]); } if (Math.abs(flow_values[1][j]) > scale) { scale = (float) Math.abs(flow_values[1][j]); } if (Math.abs(flow_values[2][j]) > scale) { scale = (float) Math.abs(flow_values[2][j]); } } float inv_scale = 1.0f / scale; if (inv_scale != inv_scale) inv_scale = 1.0f; /* * System.out.println("spatial_values = " + spatial_values[0][0] + " " + * spatial_values[1][0] + " " + spatial_values[2][0]); */ // convert spatial DisplayRealType values to earth coordinates float[][] base_spatial_locs = new float[3][]; // WLH 9 Dec 99 float[][] earth_locs = renderer.spatialToEarth(spatial_values, base_spatial_locs); if (earth_locs == null) return flow_values; int elen = earth_locs.length; // 2 or 3 /* * System.out.println("earth_locs = " + earth_locs[0][0] + " " + * earth_locs[1][0]); */ // convert earth coordinate Units to (radian, radian, meter) boolean other_meters = false; Unit[] earth_units = renderer.getEarthUnits(); if (earth_units != null) { if (Unit.canConvert(earth_units[0], CommonUnit.radian)) { earth_locs[0] = CommonUnit.radian.toThis(earth_locs[0], earth_units[0]); } if (Unit.canConvert(earth_units[1], CommonUnit.radian)) { earth_locs[1] = CommonUnit.radian.toThis(earth_locs[1], earth_units[1]); } if (elen == 3 && earth_units.length == 3 && Unit.canConvert(earth_units[2], CommonUnit.meter)) { other_meters = true; earth_locs[2] = CommonUnit.meter.toThis(earth_locs[2], earth_units[2]); } } /* * System.out.println("radian earth_locs = " + earth_locs[0][0] + " " + * earth_locs[1][0]); */ // add scaled flow vector to earth location if (elen == 3) { // assume meters even if other_meters == false float factor_lat = (float) (inv_scale * 1000.0f * Data.DEGREES_TO_RADIANS / METERS_PER_DEGREE); float factor_vert = inv_scale * 1000.0f; if (!isTraj) { for (int j = 0; j < flen; j++) { earth_locs[2][j] += factor_vert * flow_values[2][j]; earth_locs[1][j] += factor_lat * flow_values[0][j] / ((float) Math.cos(earth_locs[0][j])); earth_locs[0][j] += factor_lat * flow_values[1][j]; } } else { for (int j = 0; j < flen; j++) { earth_locs[2][j] += flow_values[2][j] * timeStep; earth_locs[1][j] += ((flow_values[0][j] * timeStep * (1f/METERS_PER_DEGREE)) / ((float)Math.cos(earth_locs[0][j])) ) * Data.DEGREES_TO_RADIANS; earth_locs[0][j] += flow_values[1][j] * timeStep * (1f/METERS_PER_DEGREE) * Data.DEGREES_TO_RADIANS; } } } else { float factor_lat = 0.00001f * inv_scale * (0.5f * renderer.getLatLonRange()); for (int j = 0; j < flen; j++) { earth_locs[1][j] += factor_lat * flow_values[0][j] / ((float) Math.cos(earth_locs[0][j])); earth_locs[0][j] += factor_lat * flow_values[1][j]; } } /* * System.out.println("flow earth_locs = " + earth_locs[0][0] + " " + * earth_locs[1][0]); */ // convert earth coordinate Units from (radian, radian, meter) if (earth_units != null) { if (Unit.canConvert(earth_units[0], CommonUnit.radian)) { earth_locs[0] = CommonUnit.radian.toThat(earth_locs[0], earth_units[0]); } if (Unit.canConvert(earth_units[1], CommonUnit.radian)) { earth_locs[1] = CommonUnit.radian.toThat(earth_locs[1], earth_units[1]); } if (elen == 3 && earth_units.length == 3 && Unit.canConvert(earth_units[2], CommonUnit.meter)) { earth_locs[2] = CommonUnit.meter.toThat(earth_locs[2], earth_units[2]); } } /* * System.out.println("degree earth_locs = " + earth_locs[0][0] + " " + * earth_locs[1][0]); */ // convert earth coordinates to spatial DisplayRealType values if (elen == 3) { earth_locs = renderer.earthToSpatial(earth_locs, null, base_spatial_locs); } else { // apply vertical flow in earthToSpatial float factor_vert = 0.00001f * inv_scale; float[] vert = new float[flen]; for (int j = 0; j < flen; j++) { vert[j] = factor_vert * flow_values[2][j]; } earth_locs = renderer.earthToSpatial(earth_locs, vert, base_spatial_locs); for (int i=0; i 2 || cnt_flow2_maps > 2) { throw new BadMappingException("Streamlines: Flow tuple dimension must be two"); } if (flow_dim0 == -1 || flow_dim1 == -1) { throw new BadMappingException("Streamlines: Flow tuple dimension must be two"); } // - 2004-01-14 ------------------------------------------------------ if (range_select[0] != null) { if ((range_select[0].length == 1) && (!range_select[0][0])) return null; for (int ii = 0; ii < range_select[0].length; ii++) { if (!range_select[0][ii]) { flow_values[0][ii] = Float.NaN; flow_values[1][ii] = Float.NaN; // -TDR, 2004-01-15 flow_values[2][ii] = Float.NaN; } } } DataRenderer renderer = getLink().getRenderer(); flow_values = adjustFlowToEarth(which, flow_values, spatial_values, flowScale, renderer); /*- start make streamline vertices System.out.println("----start streamlines----------"); */ float density = 1; float arrowScale = 1; float stepFactor = 2; float packingFactor = 1; float cntrWeight = 3; int n_pass = 0; float reduction = 1f; int[] numl = new int[1]; int[][] n_verts = new int[1][]; float[][][] vr = new float[1][][]; float[][][] vc = new float[1][][]; int nr; int nc; if (which == 0) density = streamlineDensity1; if (which == 1) density = streamlineDensity2; if (which == 0) arrowScale = arrowScale1; if (which == 1) arrowScale = arrowScale2; if (which == 0) stepFactor = stepFactor1; if (which == 1) stepFactor = stepFactor2; if (which == 0) packingFactor = packingFactor1; if (which == 1) packingFactor = packingFactor2; if (which == 0) cntrWeight = cntrWeight1; if (which == 1) cntrWeight = cntrWeight2; if (which == 0) n_pass = n_pass1; if (which == 1) n_pass = n_pass2; if (which == 0) reduction = reduction1; if (which == 1) reduction = reduction2; if (spatialManifoldDimension == 2) { nc = ((Gridded3DSet) spatial_set).LengthX; nr = ((Gridded3DSet) spatial_set).LengthY; Gridded2DSet gset = new Gridded2DSet( RealTupleType.Generic2D, new float[][] { spatial_values[flow_dim0], spatial_values[flow_dim1] }, nc, nr, null, null, null, false, false); Stream2D.stream(flow_values[flow_dim0], flow_values[flow_dim1], nr, nc, density, stepFactor, arrowScale, vr, vc, n_verts, numl, gset, packingFactor, cntrWeight, n_pass, reduction); } else { throw new VisADException( "only manifoldDimension==2 supported for streamlimes"); } VisADLineArray[] arrays = new VisADLineArray[numl[0]]; Integer2DSet grid_set = new Integer2DSet(nc, nr); for (int kk = 0; kk < arrays.length; kk++) { arrays[kk] = new VisADLineArray(); float[][] grid = new float[2][n_verts[0][kk]]; System.arraycopy(vr[0][kk], 0, grid[1], 0, n_verts[0][kk]); System.arraycopy(vc[0][kk], 0, grid[0], 0, n_verts[0][kk]); float[][] spatial_set_vals = ((Gridded3DSet) spatial_set) .gridToValue(grid); byte[][] intrp_color_values = null; if (color_values != null) { int len = color_values.length; intrp_color_values = new byte[len][n_verts[0][kk]]; int[] indices = grid_set.valueToIndex(grid); for (int cc = 0; cc < n_verts[0][kk]; cc++) { if (indices[cc] >= 0) { intrp_color_values[0][cc] = color_values[0][indices[cc]]; intrp_color_values[1][cc] = color_values[1][indices[cc]]; intrp_color_values[2][cc] = color_values[2][indices[cc]]; if (len > 3) { intrp_color_values[3][cc] = color_values[3][indices[cc]]; } } else { intrp_color_values[0][cc] = (byte) 255; intrp_color_values[1][cc] = 0; intrp_color_values[2][cc] = 0; if (len > 3) { intrp_color_values[3][cc] = color_values[3][indices[cc]]; } } } } Gridded3DSet.setGeometryArray(arrays[kk], spatial_set_vals, 4, intrp_color_values); arrays[kk] = (VisADLineArray) arrays[kk].removeMissing(); } return arrays; } private static void testFlow(String id, float[][] flow_values) { int flen = flow_values[0].length; for (int i = 0; i < flen; i++) { if (flow_values[0][i] != flow_values[0][i] || flow_values[1][i] != flow_values[1][i] || flow_values[2][i] != flow_values[2][i] || Float.isInfinite(flow_values[0][i]) || Float.isInfinite(flow_values[1][i]) || Float.isInfinite(flow_values[2][i])) { // System.out.println(id + " " + i + " " + flow_values[0][i] + " " + // flow_values[1][i] + " " + flow_values[2][i]); flow_values[0][i] = 0.0f; flow_values[1][i] = 0.0f; flow_values[2][i] = 0.0f; } } } public void makeTrajFlow(int which, float[][] flow_values, Data data, float flowScale, float[][] spatial_values, Set spatial_set, int spatialManifoldDimension, byte[][] color_values, boolean[][] range_select, GraphicsModeControl mode, float constant_alpha, float[] constant_color, int valueArrayLength, int[] valueToMap, Vector MapVector, ArrayList flowInfoList) throws VisADException, RemoteException { // incoming spatial_set will be null (see assembleSpatial), so create from spatial_values. if (spatialManifoldDimension == 3) { SetType stype = new SetType(Display.DisplaySpatialCartesianTuple); Set domain_set = ((FlatField)data).getDomainSet(); spatial_set = domain_set.makeSpatial(stype, spatial_values); } Unit[] flowUnits = new Unit[3]; Unit[][] dataUnits = ((FlatField)data).getRangeUnits(); float[][] rangeValues = ((Field)data).getFloats(false); if (flow_values[0] == null) return; if (spatial_values[0] == null) return; VisADLineArray array = new VisADLineArray(); int len = spatial_values[0].length; int flen = flow_values[0].length; int rlen = 0; // number of non-missing values if (range_select[0] == null) { rlen = len; } else { for (int j = 0; j < range_select[0].length; j++) { if (range_select[0][j]) rlen++; } } if (rlen == 0) return; DataRenderer renderer = getLink().getRenderer(); FunctionType ftype = (FunctionType) Type; RealTupleType rtt = ftype.getFlatRange(); RealType[] range_reals = rtt.getRealComponents(); for (int k = 0; k < range_reals.length; k++) { for (int i = 0; i < valueArrayLength; i++) { ScalarMap map = (ScalarMap) MapVector.elementAt(valueToMap[i]); DisplayRealType dreal = map.getDisplayScalar(); ScalarType scalar = map.getScalar(); if (!scalar.equals(range_reals[k])) continue; if ( dreal.equals(Display.Flow1Elevation) || dreal.equals(Display.Flow2Elevation) || dreal.equals(Display.Flow1Azimuth) || dreal.equals(Display.Flow2Azimuth) || dreal.equals(Display.Flow1Radial) || dreal.equals(Display.Flow2Radial) ) { throw new VisADException("Elevation, Azimuth, Radial not supported for Trajectory"); } if (dreal.equals(Display.Flow1X) || dreal.equals(Display.Flow2X)) { flowUnits[0] = dataUnits[k][0]; } if (dreal.equals(Display.Flow1Y) || dreal.equals(Display.Flow2Y)) { flowUnits[1] = dataUnits[k][0]; } if (dreal.equals(Display.Flow1Z) || dreal.equals(Display.Flow2Z)) { flowUnits[2] = dataUnits[k][0]; } } } byte[][] trajColors = makeTrajColor(rangeValues, valueArrayLength, valueToMap, MapVector); FlowInfo flwInfo = new FlowInfo(); flwInfo.flow_values = flow_values; flwInfo.flow_units = flowUnits; flwInfo.flowScale = flowScale; flwInfo.spatial_values = spatial_values; flwInfo.spatial_set = spatial_set; flwInfo.spatialManifoldDimension = spatialManifoldDimension; flwInfo.color_values = color_values; flwInfo.range_select = range_select; flwInfo.mode = mode; flwInfo.constant_alpha = constant_alpha; flwInfo.constant_color = constant_color; flwInfo.renderer = renderer; flwInfo.which = which; flwInfo.trajColors = trajColors; flowInfoList.add(flwInfo); return; } /* TODO: How, or should this be integrated with assembleColor? */ public byte[][] makeTrajColor(float[][] rangeValues, int valueArrayLength, int[] valueToMap, Vector MapVector) throws VisADException, RemoteException { FunctionType ftype = (FunctionType) Type; RealTupleType rtt = ftype.getFlatRange(); RealType[] range_reals = rtt.getRealComponents(); ScalarMap colorMap = null; int rngIdxClr = -1; int cnt = 0; for (int k = 0; k < range_reals.length; k++) { for (int i = 0; i < valueArrayLength; i++) { ScalarMap map = (ScalarMap) MapVector.elementAt(valueToMap[i]); DisplayRealType dreal = map.getDisplayScalar(); ScalarType scalar = map.getScalar(); if (!scalar.equals(range_reals[k])) continue; if (dreal.equals(Display.RGB) || dreal.equals(Display.RGBA)) { colorMap = map; if (rngIdxClr < 0) { rngIdxClr = k; } cnt++; } } } byte[][] color_values = null; if (colorMap == null) { return null; } if (cnt > 1) { System.out.println("Trajectory: more than one range type for color. Can only use the first found"); } float[] dspVals = colorMap.scaleValues(rangeValues[rngIdxClr]); float[][] fltClrs = ((BaseColorControl)colorMap.getControl()).lookupValues(dspVals); int clrDim = fltClrs.length; color_values = new byte[clrDim][fltClrs[0].length]; for (int d=0; d 3) a = color_values[3][0]; } int n = text_values.length; // CTR 22 Jan 2001 if (n > spatial_values[0].length) n = spatial_values[0].length; VisADGeometryArray[] as = new VisADGeometryArray[n]; // abcd 5 February 2001 // boolean center = text_control.getCenter(); TextControl.Justification justification = text_control.getJustification(); // abcd 19 March 2003 TextControl.Justification verticalJustification = text_control .getVerticalJustification(); double size = text_control.getSize(); Font font = text_control.getFont(); HersheyFont hfont = text_control.getHersheyFont(); // SL 22 June 2003 double rotation = text_control.getRotation(); double characterRotation = text_control.getCharacterRotation(); double scale = text_control.getScale(); double[] offset = text_control.getOffset(); // WLH 31 May 2000 boolean sphere = text_control.getSphere(); float[][] spatial_sphere = null; if (sphere) { spatial_sphere = Display.DisplaySphericalCoordSys .fromReference(spatial_values); } double[] start = new double[3]; double[] base = new double[] { size * FONT_SCALE, 0.0, 0.0 }; double[] up = new double[] { 0.0, size * FONT_SCALE, 0.0 }; // abcd 2 February 2001 // This cannot be moved outside the for loop rotateVectors(base, up, text_control.getRotation()); int k = 0; for (int i = 0; i < n; i++) { if (range_select[0] == null || range_select[0].length == 1 || range_select[0][i]) { /* * System.out.println("makeText, i = " + i + " text = " + text_values[i] * + " spatial_values = " + spatial_values[0][i] + " " + * spatial_values[1][i] + " " + spatial_values[2][i]); */ if (sphere) { double size_in_radians = (size * FONT_SCALE) / spatial_sphere[2][i]; double size_in_degrees = size_in_radians * Data.RADIANS_TO_DEGREES; double lon_size_in_degrees = size_in_degrees / Math.cos(Data.DEGREES_TO_RADIANS * spatial_sphere[0][i]); start = new double[] { spatial_sphere[0][i], spatial_sphere[1][i], spatial_sphere[2][i] }; base = new double[] { 0.0, lon_size_in_degrees, 0.0 }; up = new double[] { size_in_degrees, 0.0, 0.0 }; // abcd 2 February 2001 // This cannot be moved outside the for loop rotateVectors(base, up, text_control.getRotation()); if (font != null) { as[k] = PlotText.render_font(text_values[i], font, start, base, up, justification, verticalJustification, characterRotation, scale, offset); } else if (hfont != null) { as[k] = PlotText.render_font(text_values[i], hfont, start, base, up, justification, verticalJustification, characterRotation, scale, offset); } else { as[k] = PlotText.render_label(text_values[i], start, base, up, justification, verticalJustification, characterRotation, scale, offset); } int len = (as[k] == null) ? 0 : as[k].coordinates.length; if (len > 0) { float[] coordinates = as[k].coordinates; float[][] cs = new float[3][len / 3]; int m = 0; for (int j = 0; j < len / 3; j++) { cs[0][j] = coordinates[m++]; cs[1][j] = coordinates[m++]; cs[2][j] = coordinates[m++]; } cs = Display.DisplaySphericalCoordSys.toReference(cs); m = 0; for (int j = 0; j < len / 3; j++) { coordinates[m++] = cs[0][j]; coordinates[m++] = cs[1][j]; coordinates[m++] = cs[2][j]; } as[k].coordinates = coordinates; // not necessary if (font != null) { float[] normals = as[k].normals; for (int j3 = 0; j3 < len; j3 += 3) { float c = (float) Math.sqrt(coordinates[j3 + 0] * coordinates[j3 + 0] + coordinates[j3 + 1] * coordinates[j3 + 1] + coordinates[j3 + 2] * coordinates[j3 + 2]); float cinv = (c == 0.0f) ? 1.0f : 1.0f / c; normals[j3 + 0] = cinv * coordinates[j3 + 0]; normals[j3 + 1] = cinv * coordinates[j3 + 1]; normals[j3 + 2] = cinv * coordinates[j3 + 2]; } as[k].normals = normals; // not necessary } } } else { // !sphere start = new double[] { spatial_values[0][i], spatial_values[1][i], spatial_values[2][i] }; if (font != null) { as[k] = PlotText.render_font(text_values[i], font, start, base, up, justification, verticalJustification, characterRotation, scale, offset); } else if (hfont != null) { as[k] = PlotText.render_font(text_values[i], hfont, start, base, up, justification, verticalJustification, characterRotation, scale, offset); } else { as[k] = PlotText.render_label(text_values[i], start, base, up, justification, verticalJustification, characterRotation, scale, offset); } } int len = (as[k] == null) ? 0 : as[k].coordinates.length; int numPts = len / 3; if (len > 0 && color_values != null) { byte[] colors = new byte[numPts * color_length]; if (color_values[0].length > 1) { r = color_values[0][k]; g = color_values[1][k]; b = color_values[2][k]; if (color_length > 3) a = color_values[3][k]; } for (int j = 0; j < colors.length; j += color_length) { colors[j] = r; colors[j + 1] = g; colors[j + 2] = b; if (color_length > 3) colors[j + 3] = a; } as[k].colors = colors; } k++; } } // end for (int i=0; i 0) { rgba_values[index][0] = rgba_singles[index] / rgba_single_counts[index]; } else { // nothing mapped to this color component, so use default int default_index = getDefaultColorIndex(display, index); /* * WLH 7 Feb 98 int default_index = index == 0 ? * display.getDisplayScalarIndex(Display.Red) : (index == 1 ? * display.getDisplayScalarIndex(Display.Green) : (index == 2 ? * display.getDisplayScalarIndex(Display.Blue) : * display.getDisplayScalarIndex(Display.Alpha) ) ); */ rgba_values[index][0] = default_values[default_index]; } } } else { colorSum(4, rgba_values, rgba_value_counts, rgba_singles, rgba_single_counts, display, Display.DisplayRGBTuple, default_values); // equalize all rgba_values[index] to same length // and fill with default values equalizeAndDefault(rgba_values, display, Display.DisplayRGBTuple, default_values); } // test for any missing values int big_len = rgba_values[0].length; for (int i = 0; i < 4; i++) { int len = rgba_values[i].length; for (int j = 0; j < len; j++) { if (rgba_values[i][j] != rgba_values[i][j]) { if (range_select[0] == null) { range_select[0] = new boolean[big_len]; for (int k = 0; k < big_len; k++) range_select[0][k] = true; } if (len > 1) { range_select[0][j] = false; rgba_values[i][j] = 0.0f; } else { for (int k = 0; k < big_len; k++) range_select[0][k] = false; // leave any single color value missing - // this will prevent anything from being rendered // MEM_WLH rgba_values[i][j] = 0.0f; single_missing[i] = true; } } } // end for (int j=0; j 255) ? 255 : k; b[i][j] = (byte) ((k < 128) ? k : k - 256); } } } return b; } public static final float byteToFloat(byte b) { return (b < 0) ? (((float) b) + 256.0f) / 255.0f : ((float) b) / 255.0f; // // no 255.0f divide: // return ((b < 0) ? ((float) b) + 256.0f : ((float) b)); } public static final byte floatToByte(float f) { /* * int k = (int) (f 255.0); k = (k < 0) ? 0 : (k > 255) ? 255 : k; return * (byte) ((k < 128) ? k : k - 256); */ int k = (int) (f * 255.0); return (byte) ((k < 0) ? 0 : ((k > 255) ? -1 : ((k < 128) ? k : k - 256))); // // no 255.0f multiply: // return ((byte) ( ((int) f) < 0 ? 0 : ((int) f) > 255 ? -1 : // ((int) f) < 128 ? ((byte) f) : ((byte) (f - 256.0f)) )); } static void colorSum(int nindex, float[][] tuple_values, float[] tuple_value_counts, float[] tuple_singles, float[] tuple_single_counts, DisplayImpl display, DisplayTupleType tuple, float[] default_values) throws VisADException { for (int index = nindex - 1; index >= 0; index--) { if (tuple_values[index] == null) { if (tuple_single_counts[index] > 0) { tuple_values[index] = new float[1]; tuple_values[index][0] = tuple_singles[index]; tuple_value_counts[index] = tuple_single_counts[index]; } } else { // (tuple_values[index] != null) // DRM: 2003-09-19 allow for setting by ConstantMap // int cm = display.getGraphicsModeControl().getColorMode(); int cm = (int) default_values[display .getDisplayScalarIndex(Display.ColorMode)]; /* * DRM: 2005-09-25 default_values now has default from GMC int cm = * (colorMode >= 0) ? colorMode : * display.getGraphicsModeControl().getColorMode(); */ float inv_count = cm == GraphicsModeControl.SUM_COLOR_MODE ? 1.0f : 1.0f / (tuple_value_counts[index] + tuple_single_counts[index]); float[] t_values = tuple_values[index]; for (int j = 0; j < t_values.length; j++) { if (t_values[j] == t_values[j]) { t_values[j] = inv_count * (t_values[j] + tuple_singles[index]); } } } } // end for (int index=0; index t_len) { if (t_len != 1) { throw new DisplayException( "bad length: ShadowType.equalizeAndDefault"); } float[] t = new float[len]; float v = tuple_values[index][0]; for (int i = 0; i < len; i++) t[i] = v; tuple_values[index] = t; } } } /** * composite tuple_values into rgba_values and rgba_value_counts, for index = * 0, 1, 2 */ static void colorComposite(float[][] rgba_values, float[] rgba_value_counts, float[][] tuple_values) throws VisADException { for (int index = 0; index < 3; index++) { singleComposite(index, rgba_values, rgba_value_counts, tuple_values[index]); // FREE tuple_values[index] = null; } } /** * composite values into rgba_values[index] and rgba_value_counts[index] */ static void singleComposite(int index, float[][] rgba_values, float[] rgba_value_counts, float[] values) throws VisADException { if (values == null) return; if (rgba_values[index] == null) { rgba_values[index] = values; rgba_value_counts[index] = 1.0f; } else { rgba_value_counts[index]++; int rgba_len = rgba_values[index].length; int values_len = values.length; if (rgba_len == values_len) { for (int j = 0; j < rgba_len; j++) { rgba_values[index][j] += values[j]; } } else if (values_len == 1) { for (int j = 0; j < rgba_len; j++) { rgba_values[index][j] += values[0]; } } else if (rgba_len == 1) { for (int j = 0; j < rgba_len; j++) { values[j] += rgba_values[index][0]; } rgba_values[index] = values; } else { throw new DisplayException("bad length: ShadowType.singleComposite"); } } } /** * return a composite of SelectRange DisplayRealType values from * display_values, as 0.0 for select and Double.Nan for no select (these * values can be added to other DisplayRealType values) */ public boolean[][] assembleSelect(float[][] display_values, int domain_length, int valueArrayLength, int[] valueToScalar, DisplayImpl display, ShadowType shadow_api) throws VisADException { int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); boolean[][] range_select = new boolean[1][]; boolean anySelect = false; for (int i = 0; i < valueArrayLength; i++) { float[] values = display_values[i]; if (values != null) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); if (real.equals(Display.SelectRange)) { if (range_select[0] == null) { // MEM range_select[0] = new boolean[domain_length]; for (int j = 0; j < domain_length; j++) { range_select[0][j] = true; } } RangeControl control = (RangeControl) ((ScalarMap) MapVector .elementAt(valueToMap[i])).getControl(); float[] range = control.getRange(); // System.out.println("range = " + range[0] + " " + range[1]); if (values.length == 1) { if (values[0] < range[0] || range[1] < values[0]) { for (int j = 0; j < domain_length; j++) { range_select[0][j] = false; } anySelect = true; } } else { for (int j = 0; j < values.length; j++) { if (values[j] < range[0] || range[1] < values[j]) { range_select[0][j] = false; anySelect = true; /* * System.out.println("range = " + range[0] + " " + range[1] + * " values[" + j + "] = " + values[j]); */ } } } // FREE display_values[i] = null; // MEM_WLH 27 March 99 } // end if (real.equals(Display.SelectRange)) } // end if (values != null) } // end for (int i=0; i 0.5f); float mergeArrays = default_values[display .getDisplayScalarIndex(Display.MergeGeometries)]; mode.setMergeGeometries(mergeArrays > 0.5f); float[][] flow1_values = new float[3][]; float[][] flow2_values = new float[3][]; float[] flowScale = new float[2]; float[] arrowScale = new float[2]; boolean[][] range_select = new boolean[1][]; shadow_api.assembleFlow(flow1_values, flow2_values, flowScale, arrowScale, display_values, valueArrayLength, valueToScalar, display, default_values, range_select, renderer, shadow_api); if (range_select[0] != null && !range_select[0][0]) { // data not selected return false; } boolean[] swap = { false, false, false }; int[] spatialDimensions = new int[2]; float[][] spatial_values = new float[3][]; shadow_api.assembleSpatial(spatial_values, display_values, valueArrayLength, valueToScalar, display, default_values, inherited_values, null, false, false, spatialDimensions, range_select, flow1_values, flow2_values, flowScale, swap, renderer, shadow_api); if (range_select[0] != null && !range_select[0][0]) { // data not selected return false; } boolean[] single_missing = { false, false, false, false }; byte[][] color_values = shadow_api.assembleColor(display_values, valueArrayLength, valueToScalar, display, default_values, range_select, single_missing, shadow_api); if (range_select[0] != null && !range_select[0][0]) { // data not selected return false; } int LevelOfDifficulty = getLevelOfDifficulty(); if (LevelOfDifficulty == SIMPLE_TUPLE) { // only manage Spatial, Color and Alpha here // i.e., the 'dots' if (single_missing[0] || single_missing[1] || single_missing[2]) { // System.out.println("single missing alpha"); // a single missing color value, so render nothing return false; } // put single color in appearance /* * ColoringAttributes constant_color = new ColoringAttributes(); * constant_color.setColor(byteToFloat(color_values[0][0]), * byteToFloat(color_values[1][0]), byteToFloat(color_values[2][0])); */ float[] constant_color = new float[] { byteToFloat(color_values[0][0]), byteToFloat(color_values[1][0]), byteToFloat(color_values[2][0]) }; float constant_alpha = Float.NaN; VisADGeometryArray array; boolean anyShapeCreated = false; int[] valueToMap = display.getValueToMap(); Vector MapVector = display.getMapVector(); VisADGeometryArray[] arrays = shadow_api.assembleShape(display_values, valueArrayLength, valueToMap, MapVector, valueToScalar, display, default_values, inherited_values, spatial_values, color_values, range_select, -1, shadow_api); if (arrays != null) { for (int i = 0; i < arrays.length; i++) { array = arrays[i]; if (array != null) { shadow_api.addToGroup(group, array, mode, constant_alpha, constant_color); /* * WLH 25 June 2000 if (renderer.getIsDirectManipulation()) { * renderer.setSpatialValues(spatial_values); } */ } } anyShapeCreated = true; } boolean anyTextCreated = false; if (text_value != null && text_control != null) { String[] text_values = { text_value }; array = shadow_api.makeText(text_values, text_control, spatial_values, color_values, range_select); shadow_api.addTextToGroup(group, array, mode, constant_alpha, constant_color); anyTextCreated = true; } boolean anyFlowCreated = false; // try Flow1 arrays = shadow_api.makeFlow(0, flow1_values, flowScale[0], arrowScale[0], spatial_values, color_values, range_select); if (arrays != null) { for (int i = 0; i < arrays.length; i++) { if (arrays[i] != null) { shadow_api.addToGroup(group, arrays[i], mode, constant_alpha, constant_color); } } anyFlowCreated = true; } // try Flow2 arrays = shadow_api.makeFlow(1, flow2_values, flowScale[1], arrowScale[1], spatial_values, color_values, range_select); if (arrays != null) { for (int i = 0; i < arrays.length; i++) { if (arrays[i] != null) { shadow_api.addToGroup(group, arrays[i], mode, constant_alpha, constant_color); } } anyFlowCreated = true; } if (!anyFlowCreated && !anyTextCreated && !anyShapeCreated) { array = makePointGeometry(spatial_values, null); if (array != null && array.vertexCount > 0) { shadow_api.addToGroup(group, array, mode, constant_alpha, constant_color); /* * WLH 25 June 2000 if (renderer.getIsDirectManipulation()) { * renderer.setSpatialValues(spatial_values); } */ } } // WLH 25 June 2000 if (renderer.getIsDirectManipulation()) { renderer.setSpatialValues(spatial_values); } return false; } else { // if (!(LevelOfDifficulty == SIMPLE_TUPLE)) // must be LevelOfDifficulty == LEGAL // add values to value_array according to SelectedMapVector-s // of RealType-s in components (including Reference) // // accumulate Vector of value_array-s at this ShadowTypeJ3D, // to be rendered in a post-process to scanning data throw new UnimplementedException("terminal LEGAL unimplemented: " + "ShadowType.terminalTupleOrReal"); } } public boolean makeContour(int valueArrayLength, int[] valueToScalar, float[][] display_values, int[] inherited_values, Vector MapVector, int[] valueToMap, int domain_length, boolean[][] range_select, int spatialManifoldDimension, Set spatial_set, byte[][] color_values, boolean indexed, Object group, GraphicsModeControl mode, boolean[] swap, float constant_alpha, float[] constant_color, ShadowType shadow_api, ShadowRealTupleType Domain, ShadowRealType[] DomainReferenceComponents, Set domain_set, Unit[] domain_units, CoordinateSystem dataCoordinateSystem) throws VisADException { boolean anyContourCreated = false; // WLH 4 May 2001 DataRenderer renderer = getLink().getRenderer(); double[] matrix = p_cntrl.getMatrix(); double scale = Double.NaN; double[] scale_a = new double[3]; MouseBehavior mouse = display.getMouseBehavior(); if (mouse != null) { double[] rot_a = new double[3]; double[] trans_a = new double[3]; mouse.instance_unmake_matrix(rot_a, scale_a, trans_a, matrix); scale = scale_a[0]; } /* * try { System.out.println("makeContour " + * getLink().getThingReference().getName()); } catch (RemoteException e) { } */ boolean isLinearContour3D = getIsLinearContour3D() && spatial_set instanceof Linear3DSet; ScalarMap[] spatial_maps = { null, null, null }; int[] permute = { -1, -1, -1 }; if (isLinearContour3D) { RealType[] reals = ((SetType) spatial_set.getType()).getDomain() .getRealComponents(); for (int i = 0; i < valueArrayLength; i++) { ScalarMap map = (ScalarMap) MapVector.elementAt(valueToMap[i]); ScalarType sc = map.getScalar(); RealType real = (sc instanceof RealType) ? (RealType) sc : null; DisplayRealType dreal = map.getDisplayScalar(); DisplayTupleType tuple = dreal.getTuple(); if (tuple != null && tuple.equals(Display.DisplaySpatialCartesianTuple)) { int tuple_index = dreal.getTupleIndex(); for (int j = 0; j < reals.length; j++) { if (real.equals(reals[j])) { permute[j] = tuple_index; spatial_maps[j] = map; break; } } } } } ShadowRealTupleType domain_reference = null; CoordinateSystem coord_sys = null; boolean sphericalDisplayCS = false; if (spatialTuple != null) coord_sys = spatialTuple.getCoordinateSystem(); if (coord_sys != null) { sphericalDisplayCS = coord_sys instanceof SphericalCoordinateSystem; } domain_reference = Domain.getReference(); boolean singleValueAsTexture = Boolean.parseBoolean(System.getProperty(PROP_CONTOURFILL_SINGLE_VALUE_AS_TEXTURE, "false")); for (int i = 0; i < valueArrayLength; i++) { int displayScalarIndex = valueToScalar[i]; DisplayRealType real = display.getDisplayScalar(displayScalarIndex); if (real.equals(Display.IsoContour) && display_values[i] != null && display_values[i].length == domain_length && inherited_values[i] == 0) { // non-inherited IsoContour, so generate contours VisADGeometryArray array = null; ContourControl control = (ContourControl) ((ScalarMap) MapVector .elementAt(valueToMap[i])).getControl(); c_cntrl = control; boolean[] bvalues = new boolean[2]; float[] fvalues = new float[5]; control.getMainContours(bvalues, fvalues); boolean doContour = bvalues[0]; boolean doLabels = bvalues[1]; float isoLvl = fvalues[0]; if (scale != scale) scale = ContourControl.getInitScale(); double label_size = control.getLabelSize(); if (spatialManifoldDimension == 3 || spatialManifoldDimension == 2) { anyContourCreated = true; } if (doContour) { if (range_select[0] != null) { int len = range_select[0].length; if (len == 1 || display_values[i].length == 1) break; // WLH 30 July 99 int dlen = display_values[i].length; float[] temp = display_values[i]; display_values[i] = new float[dlen]; System.arraycopy(temp, 0, display_values[i], 0, dlen); for (int j = 0; j < len; j++) { if (!range_select[0][j]) { display_values[i][j] = Float.NaN; } } } if (spatialManifoldDimension == 3) { if (isoLvl == isoLvl) { // not NaN if (spatial_set != null) { if (isLinearContour3D) { array = ((Linear3DSet) spatial_set).makeLinearIsoSurface( isoLvl, display_values[i], color_values, indexed, spatial_maps, permute); } else { array = spatial_set.makeIsoSurface(isoLvl, display_values[i], color_values, indexed); } // WLH 4 May 2001 if (array != null && getAdjustProjectionSeam()) { try { array = array.adjustLongitude(renderer); array = array.adjustSeam(renderer); } catch (Exception e) { } } // add all data to group shadow_api.addToGroup(group, array, mode, constant_alpha, constant_color); array = null; } else if (coord_sys != null) { // missing spatials set as result // of transform (coord_sys) array = ((Gridded3DSet) domain_set) .makeIsoSurfaceMissingSpatial(isoLvl, display_values[i], color_values, indexed, Domain, domain_reference, domain_units, dataCoordinateSystem, coord_sys, DomainReferenceComponents, spatialTuple, spatial_offset_values); if (array != null) { array = array.removeMissing(); } shadow_api.addToGroup(group, array, mode, constant_alpha, constant_color); array = null; } } // anyContourCreated = true; } else if (spatialManifoldDimension == 2) { if (spatial_set != null) { float[] lowhibase = new float[3]; boolean[] doStyle = { false }; float[] levs = control.getLevels(lowhibase, doStyle); boolean fill = control.contourFilled(); ScalarMap[] smap = new ScalarMap[2]; // changed to 2 to pass // IsoContour Map to Set ScalarType sc = ((ScalarMap) MapVector.elementAt(valueToMap[i])) .getScalar(); if (fill) { for (int kk = 0; kk < MapVector.size(); kk++) { ScalarMap sm = (ScalarMap) MapVector.elementAt(kk); if (sm != null) { if (sm.getScalar().equals(sc) && (sm.getDisplayScalar().equals(Display.RGB) || sm .getDisplayScalar().equals(Display.RGBA))) { smap[0] = sm; } } } if (smap[0] == null) { throw new DisplayException( "IsoContour color-fill is enabled, so " + sc + " must also be mapped to Display.RGB"); } } // BMF 2006-10-04 get the IsoContour ScalarMap for (int kk = 0; kk < MapVector.size(); kk++) { ScalarMap sm = (ScalarMap) MapVector.elementAt(kk); if (sm != null) { if (sm.getScalar().equals(sc) && sm.getDisplayScalar().equals(Display.IsoContour)) { smap[1] = sm; } } } float maxValue = Float.NEGATIVE_INFINITY; float minValue = Float.POSITIVE_INFINITY; boolean haveSingleValue = false; // if the singleValueAsTexture is true, loop over the values visad.util.Trace.call1("ShadowType:isSingleValue"); if (fill && singleValueAsTexture) { int dlen = display_values[i].length; for (int j = 0; j < dlen; j++) { if (display_values[i][j] > maxValue) maxValue = display_values[i][j]; if (display_values[i][j] < minValue) minValue = display_values[i][j]; } haveSingleValue = (maxValue != Float.NEGATIVE_INFINITY && minValue !=Float.POSITIVE_INFINITY && maxValue == minValue); } visad.util.Trace.call2("ShadowType:isSingleValue"); // if we are filling and we have a single value, don't try // to contour and return false; if (haveSingleValue && singleValueAsTexture) return false; visad.util.Trace.call1("ShadowType:makeIsoLines"); VisADGeometryArray[][] array_s = spatial_set.makeIsoLines(levs, lowhibase[0], lowhibase[1], lowhibase[2], display_values[i], color_values, swap, doStyle[0], fill, smap, scale_a, label_size, sphericalDisplayCS); visad.util.Trace.call2("ShadowType:makeIsoLines"); // even though no contours were created, we at least tried // so have to return true. if (array_s == null) return anyContourCreated; boolean adjust = getAdjustProjectionSeam(); // make necessary adjustments for (int j = 0; j < array_s.length; j++) { if (array_s[j] != null) { for (int k=0; k< array_s[j].length; k++) { VisADGeometryArray arr = array_s[j][k]; if (arr != null) { if (adjust) { arr = arr.adjustLongitude(renderer); arr = arr.adjustSeam(renderer); } arr = arr.removeMissing(); } array_s[j][k] = arr; } } } VisADGeometryArray[] uBasicLines = array_s[0]; VisADGeometryArray[] fillLines = array_s[1]; VisADGeometryArray[] labelLines = null; VisADGeometryArray[] sBasicLines = null; if (array_s != null) { // set'em if you got em switch (array_s.length) { case 4: sBasicLines = array_s[3]; case 3: labelLines = array_s[2]; } //if (array_s.length > 0 && uBasicLines.length > 0) { if (array_s.length > 0) { // label mode, forcing labels to have solid J3D line style GraphicsModeControl labelMode = (GraphicsModeControl) mode.clone(); labelMode.setLineStyle(GraphicsModeControl.SOLID_STYLE, false); // mode for dashed lines rendered with J3D line style GraphicsModeControl styledMode = (GraphicsModeControl) mode.clone(); styledMode.setLineStyle(control.getDashedStyle(), false); if (fill) { // BMF set offset to make labels more clear. // FIXME: There may be a better value to use here labelMode.setPolygonOffsetFactor(10f, false); labelMode.setPolygonOffset(1f, false); // make adjustment for basic lines if (uBasicLines != null) { for (VisADGeometryArray arr : uBasicLines) { if (arr == null) continue; shadow_api.adjustZ(arr.coordinates); } } // there may not be unstyled lines if (sBasicLines != null) { for (VisADGeometryArray arr : sBasicLines) { if (arr == null) continue; shadow_api.adjustZ(arr.coordinates); } } } // add unstyled lines if (uBasicLines != null) { for (VisADGeometryArray arr : uBasicLines) { if (arr == null) continue; shadow_api.addToGroup(group, arr, mode, constant_alpha, constant_color); } } array_s[0] = null; uBasicLines = null; // add styled lines if (sBasicLines != null) { for (VisADGeometryArray arr : sBasicLines) { if (arr == null) continue; shadow_api.addToGroup(group, arr, styledMode, constant_alpha, constant_color); } sBasicLines = null; array_s[3] = null; } if (doLabels && labelLines != null) { shadow_api.addLabelsToGroup(group, labelLines, labelMode, control, p_cntrl, cnt, constant_alpha, constant_color); labelLines = null; array_s[2] = null; } else if (!doLabels && fillLines != null) { // fill in contour lines in place of labels shadow_api.addToGroup(group, fillLines[0], mode, constant_alpha, constant_color); if (fillLines.length == 2) { //- styled lines available shadow_api.addToGroup(group, fillLines[1], styledMode, constant_alpha, constant_color); fillLines[1] = null; } fillLines[0] = null; array_s[1] = null; } array_s = null; } } } // end if (spatial_set != null) // anyContourCreated = true; } // end if (spatialManifoldDimension == 2) } // end if (bvalues[CONTOUR]) } // end if (real.equals(Display.IsoContour) && not inherited) } // end for (int i=0; i

Ads help maintain this website.