// // ShadowFunctionOrSetType.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2000 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 */ /* MEM - memory use reduction strategy: changes marked by MEM_WLH 1. if (isTexture) no assembleSpatial NOT NEEDED but if (isTexture) then domain_values = null, so spatial display_values[i] = null so assembleSpatial does nothing (except construct a SingletonSet spatial_set) 2. byte[][] assembleColor DONE this has a bad space / time tradeoff in makeIso*, so create a boolean in GMC to choose between (Irregular3DSet, Gridded3DSet) and their slower extensions 3. after use, set display_values[i] = null; DONE done in many ShadowType.assemble* - marked by MEM_WLH 4. don't fill arrays that won't get used are there any of these ?? 5. replace getValues() by getFloats(false) already done for getSamples 6. assembleColors first DONE 7. boolean[] range_select 8. in-line byteToFloat and floatToByte DONE VisADCanvasJ2D, Gridded3DSet, Irregular3DSet N. iso-surface computation uses: Irregular3DSet.makeIsosurface: float[len] fieldValues float[3 or 4][len] auxValues (color_values) float[3][nvertex] fieldVertices float[3 or 4][nvertex] auxLevels int[1][npolygons][3 or 4] polyToVert int[1][nvertex][nverts[i]] vertToPoly int[Delan.Tri.length][4] polys int[Delan.NumEdges] globalToVertex float[DomainDimension][Delan.NumEdges] edgeInterp float[3 or 4][Delan.NumEdges] auxInterp Gridded3DSet.makeIsoSurface: start with nvertex_estimate = 4 * npolygons + 100 int[num_cubes] ptFLAG int[xdim_x_ydim_x_zdim] ptAUX int[num_cubes+1] pcube float[1][4 * npolygons] VX float[1][4 * npolygons] VY float[1][4 * npolygons] VZ float[3 or 4][nvet] color_temps float[3 or 4][len] cfloat int[7 * npolygons] Vert_f_Pol int[1][36 * npolygons] Pol_f_Vert number of bytes = 268 (or 284) * npolygons + 24 (or 28) * len isosurf: float[3][len] samples float[3 or 4][nvertex_estimate] tempaux number of bytes = 48 (or 64) * npolygons + 12 * len float[npolygons] NxA, NxB, NyA, NyB, NzA, NzB float[npolygons] Pnx, Pny, Pnz float[nvertex] NX, NY, NZ number of bytes = 84 * npolygons make_normals: none total number of bytes = 36 (or 40) * len + 400 (to 432) * npolygons so if len = 0.5M and npolygons = 0.1M bytes = 20M + 43.2M = 63.2M */ package visad; import java.util.*; import java.text.*; import java.rmi.*; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; import java.awt.image.DataBufferInt; import java.awt.image.DataBuffer; /** The ShadowFunctionOrSetType class is an abstract parent for classes that implement ShadowFunctionType or ShadowSetType.

*/ public abstract class ShadowFunctionOrSetType extends ShadowType { ShadowRealTupleType Domain; ShadowType Range; // null for ShadowSetType /** RangeComponents is an array of ShadowRealType-s that are ShadowRealType components of Range or ShadowRealType components of ShadowRealTupleType components of Range; a non-ShadowRealType and non-ShadowTupleType Range is marked by null; components of a ShadowTupleType Range that are neither ShadowRealType nor ShadowRealTupleType are ignored */ ShadowRealType[] RangeComponents; // null for ShadowSetType ShadowRealType[] DomainComponents; ShadowRealType[] DomainReferenceComponents; /** true if range is ShadowRealType or Flat ShadowTupleType not the same as FunctionType.Flat; also true for ShadowSetType */ boolean Flat; /** value_indices from parent */ int[] inherited_values; /** this constructor is a bit of a kludge to get around single inheritance problems */ public ShadowFunctionOrSetType(MathType t, DataDisplayLink link, ShadowType parent, ShadowRealTupleType domain, ShadowType range) throws VisADException, RemoteException { super(t, link, parent); Domain = domain; Range = range; if (this instanceof ShadowFunctionType) { Flat = (Range instanceof ShadowRealType) || (Range instanceof ShadowTextType) || (Range instanceof ShadowTupleType && ((ShadowTupleType) Range).isFlat()); MultipleSpatialDisplayScalar = Domain.getMultipleSpatialDisplayScalar() || Range.getMultipleSpatialDisplayScalar(); MultipleDisplayScalar = Domain.getMultipleDisplayScalar() || Range.getMultipleDisplayScalar(); MappedDisplayScalar = Domain.getMappedDisplayScalar() || Range.getMappedDisplayScalar(); RangeComponents = getComponents(Range, true); } else if (this instanceof ShadowSetType) { Flat = true; MultipleDisplayScalar = Domain.getMultipleDisplayScalar(); MappedDisplayScalar = Domain.getMappedDisplayScalar(); RangeComponents = null; } else { throw new DisplayException("ShadowFunctionOrSetType: must be " + "ShadowFunctionType or ShadowSetType"); } DomainComponents = getComponents(Domain, false); DomainReferenceComponents = getComponents(Domain.getReference(), false); } public boolean getFlat() { return Flat; } public ShadowRealType[] getRangeComponents() { return RangeComponents; } public ShadowRealType[] getDomainComponents() { return DomainComponents; } public ShadowRealType[] getDomainReferenceComponents() { return DomainReferenceComponents; } /** used by FlatField.computeRanges */ int[] getRangeDisplayIndices() throws VisADException { if (!(this instanceof ShadowFunctionType)) { throw new DisplayException("ShadowFunctionOrSetType.getRangeDisplay" + "Indices: must be ShadowFunctionType"); } int n = RangeComponents.length; int[] indices = new int[n]; for (int i=0; i 0) { throw new BadMappingException("Animation and SelectValue may only occur " + "in 1-D Function domain: " + "ShadowFunctionOrSetType.checkIndices"); } else { // eventually ShadowType.testTransform is used to mark Animation, // Value or Range as isTransform when multiple occur in Domain; // however, temporary hack in Renderer.isTransformControl requires // multiple occurence of Animation and Value to throw an Exception if (avCount > 1) { throw new BadMappingException("only one Animation and SelectValue may " + "occur Set domain: " + "ShadowFunctionOrSetType.checkIndices"); } } } if (Flat || this instanceof ShadowSetType) { if (this instanceof ShadowFunctionType) { if (Range instanceof ShadowTupleType) { local_indices = ((ShadowTupleType) Range).sumIndices(local_indices); local_display_indices = ((ShadowTupleType) Range).sumDisplayIndices(local_display_indices); local_value_indices = ((ShadowTupleType) Range).sumValueIndices(local_value_indices); } else if (Range instanceof ShadowScalarType) { ((ShadowScalarType) Range).incrementIndices(local_indices); local_display_indices = addIndices(local_display_indices, ((ShadowScalarType) Range).getDisplayIndices()); local_value_indices = addIndices(local_value_indices, ((ShadowScalarType) Range).getValueIndices()); } // test legality of Animation and SelectValue in Range if (checkAnimationOrValue(Range.getDisplayIndices()) > 0) { throw new BadMappingException("Animation and SelectValue may not " + "occur in Function range: " + "ShadowFunctionOrSetType.checkIndices"); } } // end if (this instanceof ShadowFunctionType) anyContour = checkContour(local_display_indices); anyFlow = checkFlow(local_display_indices); anyShape = checkShape(local_display_indices); anyText = checkText(local_display_indices); LevelOfDifficulty = testIndices(local_indices, local_display_indices, levelOfDifficulty); /* System.out.println("ShadowFunctionOrSetType.checkIndices 1:" + " LevelOfDifficulty = " + LevelOfDifficulty + " isTerminal = " + isTerminal + " Type = " + Type.prettyString()); */ // compute Domain type if (!Domain.getMappedDisplayScalar()) { Dtype = D0; } else if (Domain.getAllSpatial() && checkR4(Domain.getDisplayIndices())) { Dtype = D1; } else if (checkR1D3(Domain.getDisplayIndices())) { Dtype = D3; } else if (checkR2D2(Domain.getDisplayIndices())) { Dtype = D2; } else if (checkAnimationOrValue(Domain.getDisplayIndices()) > 0) { Dtype = D4; } else { Dtype = Dbad; } if (this instanceof ShadowFunctionType) { // compute Range type if (!Range.getMappedDisplayScalar()) { Rtype = R0; } else if (checkR1D3(Range.getDisplayIndices())) { Rtype = R1; } else if (checkR2D2(Range.getDisplayIndices())) { Rtype = R2; } else if (checkR3(Range.getDisplayIndices())) { Rtype = R3; } else if (checkR4(Range.getDisplayIndices())) { Rtype = R4; } else { Rtype = Rbad; } } else { // this instanceof ShadowSetType Rtype = R0; // implicit - Set has no range } if (LevelOfDifficulty == NESTED) { if (Dtype != Dbad && Rtype != Rbad) { if (Dtype == D4) { LevelOfDifficulty = SIMPLE_ANIMATE_FIELD; } else { LevelOfDifficulty = SIMPLE_FIELD; } } else { LevelOfDifficulty = LEGAL; } } /* System.out.println("ShadowFunctionOrSetType.checkIndices 2:" + " LevelOfDifficulty = " + LevelOfDifficulty + " Dtype = " + Dtype + " Rtype = " + Rtype); */ if (this instanceof ShadowFunctionType) { // test for texture mapping // WLH 30 April 99 isTextureMap = !getMultipleDisplayScalar() && getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD && ((FunctionType) getType()).getReal() && // ?? Domain.getDimension() == 2 && Domain.getAllSpatial() && !Domain.getSpatialReference() && Display.DisplaySpatialCartesianTuple.equals( Domain.getDisplaySpatialTuple() ) && checkColorAlphaRange(Range.getDisplayIndices()) && checkAny(Range.getDisplayIndices()) && display.getGraphicsModeControl().getTextureEnable() && !display.getGraphicsModeControl().getPointMode(); curvedTexture = getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD && Domain.getDimension() == 2 && Domain.getAllSpatial() && checkSpatialOffsetColorAlphaRange(Domain.getDisplayIndices()) && checkSpatialOffsetColorAlphaRange(Range.getDisplayIndices()) && checkAny(Range.getDisplayIndices()) && display.getGraphicsModeControl().getTextureEnable() && !display.getGraphicsModeControl().getPointMode(); // WLH 15 March 2000 // isTexture3D = !getMultipleDisplayScalar() && isTexture3D = getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD && ((FunctionType) getType()).getReal() && // ?? Domain.getDimension() == 3 && Domain.getAllSpatial() && // WLH 1 April 2000 // !Domain.getMultipleDisplayScalar() && // WLH 15 March 2000 checkSpatialRange(Domain.getDisplayIndices()) && // WLH 1 April 2000 !Domain.getSpatialReference() && Display.DisplaySpatialCartesianTuple.equals( Domain.getDisplaySpatialTuple() ) && checkColorAlphaRange(Range.getDisplayIndices()) && checkAny(Range.getDisplayIndices()) && display.getGraphicsModeControl().getTextureEnable() && !display.getGraphicsModeControl().getPointMode(); // note GgraphicsModeControl.setTextureEnable(false) disables this isLinearContour3D = getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD && ((FunctionType) getType()).getReal() && // ?? Domain.getDimension() == 3 && Domain.getAllSpatial() && !Domain.getMultipleDisplayScalar() && !Domain.getSpatialReference() && Display.DisplaySpatialCartesianTuple.equals( Domain.getDisplaySpatialTuple() ) && checkContourColorAlphaRange(Range.getDisplayIndices()) && checkContour(Range.getDisplayIndices()); /* System.out.println("checkIndices.isTextureMap = " + isTextureMap + " " + !getMultipleDisplayScalar() + " " + (getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD) + " " + ((FunctionType) getType()).getReal() + " " + (Domain.getDimension() == 2) + " " + Domain.getAllSpatial() + " " + !Domain.getSpatialReference() + " " + Display.DisplaySpatialCartesianTuple.equals( Domain.getDisplaySpatialTuple() ) + " " + checkColorAlphaRange(Range.getDisplayIndices()) + " " + checkAny(Range.getDisplayIndices()) + " " + display.getGraphicsModeControl().getTextureEnable() + " " + !display.getGraphicsModeControl().getPointMode() ); System.out.println("checkIndices.curvedTexture = " + curvedTexture + " " + (getLevelOfDifficulty() == ShadowType.SIMPLE_FIELD) + " " + (Domain.getDimension() == 2) + " " + Domain.getAllSpatial() + " " + checkSpatialOffsetColorAlphaRange(Domain.getDisplayIndices()) + " " + checkSpatialOffsetColorAlphaRange(Range.getDisplayIndices()) + " " + checkAny(Range.getDisplayIndices()) + " " + display.getGraphicsModeControl().getTextureEnable() + " " + !display.getGraphicsModeControl().getPointMode() ); */ } } else { // !Flat && this instanceof ShadowFunctionType if (levelOfDifficulty == NESTED) { if (!checkNested(Domain.getDisplayIndices())) { levelOfDifficulty = LEGAL; } } LevelOfDifficulty = Range.checkIndices(local_indices, local_display_indices, local_value_indices, isTransform, levelOfDifficulty); /* System.out.println("ShadowFunctionOrSetType.checkIndices 3:" + " LevelOfDifficulty = " + LevelOfDifficulty); */ } return LevelOfDifficulty; } public ShadowRealTupleType getDomain() { return Domain; } public ShadowType getRange() { return Range; } /** mark Control-s as needing re-Transform */ void markTransform(boolean[] isTransform) { if (Range != null) Range.markTransform(isTransform); } /** transform data into a (Java3D or Java2D) scene graph; add generated scene graph components as children of group; group is Group (Java3D) or VisADGroup (Java2D); value_array are inherited valueArray values; default_values are defaults for each display.DisplayRealTypeVector; return true if need post-process */ public boolean doTransform(Object group, Data data, float[] value_array, float[] default_values, DataRenderer renderer, ShadowType shadow_api) throws VisADException, RemoteException { // return if data is missing or no ScalarMaps if (data.isMissing()) return false; if (LevelOfDifficulty == NOTHING_MAPPED) return false; // if transform has taken more than 500 milliseconds and there is // a flag requesting re-transform, throw a DisplayInterruptException DataDisplayLink link = renderer.getLink(); // System.out.println("\nstart doTransform " + (System.currentTimeMillis() - link.start_time)); if (link != null) { boolean time_flag = false; if (link.time_flag) { time_flag = true; } else { if (500 < System.currentTimeMillis() - link.start_time) { link.time_flag = true; time_flag = true; } } if (time_flag) { if (link.peekTicks()) { throw new DisplayInterruptException("please wait . . ."); } Enumeration maps = link.getSelectedMapVector().elements(); while(maps.hasMoreElements()) { ScalarMap map = (ScalarMap) maps.nextElement(); if (map.peekTicks(renderer, link)) { throw new DisplayInterruptException("please wait . . ."); } } } } // end if (link != null) // get 'shape' flags boolean anyContour = getAnyContour(); boolean anyFlow = getAnyFlow(); boolean anyShape = getAnyShape(); boolean anyText = getAnyText(); boolean indexed = shadow_api.wantIndexed(); // 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][]; // get values inherited from parent; // assume these do not include SelectRange, SelectValue // or Animation values - see temporary hack in // DataRenderer.isTransformControl /* not needed - over-write inherited_values? need to copy? int[] inherited_values = ((ShadowFunctionOrSetType) adaptedShadowType).getInheritedValues(); */ for (int i=0; i 0) { display_values[i] = new float[1]; display_values[i][0] = value_array[i]; } } // check for only contours and only disabled contours if (getIsTerminal() && anyContour && !anyFlow && !anyShape && !anyText) { // WLH 13 March 99 boolean any_enabled = false; for (int i=0; i 0.99 && renderer.isLegalTextureMap() && (domain_set instanceof Linear2DSet || (domain_set instanceof LinearNDSet && domain_set.getDimension() == 2)); int curved_size = display.getGraphicsModeControl().getCurvedSize(); boolean curvedTexture = getCurvedTexture() && !isTextureMap && curved_size > 0 && getIsTerminal() && // implied by getCurvedTexture()? shadow_api.allowCurvedTexture() && default_values[alpha_index] > 0.99 && renderer.isLegalTextureMap() && (domain_set instanceof Gridded2DSet || (domain_set instanceof GriddedSet && domain_set.getDimension() == 2)); boolean domainOnlySpatial = Domain.getAllSpatial() && !Domain.getMultipleDisplayScalar(); boolean isTexture3D = getIsTexture3D() && // default_values[alpha_index] > 0.99 && renderer.isLegalTextureMap() && (domain_set instanceof Linear3DSet || (domain_set instanceof LinearNDSet && domain_set.getDimension() == 3)); // WLH 1 April 2000 boolean range3D = isTexture3D && anyRange(Domain.getDisplayIndices()); boolean isLinearContour3D = getIsLinearContour3D() && domain_set instanceof Linear3DSet && shadow_api.allowLinearContour(); /* System.out.println("doTransform.isTextureMap = " + isTextureMap + " " + getIsTextureMap() + " " + // (default_values[alpha_index] > 0.99) + " " + renderer.isLegalTextureMap() + " " + (domain_set instanceof Linear2DSet) + " " + (domain_set instanceof LinearNDSet) + " " + (domain_set.getDimension() == 2)); System.out.println("doTransform.curvedTexture = " + curvedTexture + " " + getCurvedTexture() + " " + !isTextureMap + " " + (curved_size > 0) + " " + getIsTerminal() + " " + shadow_api.allowCurvedTexture() + " " + (default_values[alpha_index] > 0.99) + " " + renderer.isLegalTextureMap() + " " + (domain_set instanceof Gridded2DSet) + " " + (domain_set instanceof GriddedSet) + " " + (domain_set.getDimension() == 2) ); */ float[] coordinates = null; float[] texCoords = null; float[] normals = null; byte[] colors = null; int data_width = 0; int data_height = 0; int data_depth = 0; int texture_width = 1; int texture_height = 1; int texture_depth = 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; float[] coordinatesZ = null; float[] texCoordsZ = null; float[] normalsZ = null; byte[] colorsZ = null; int[] volume_tuple_index = null; // System.out.println("test isTextureMap " + (System.currentTimeMillis() - link.start_time)); if (isTextureMap) { Linear1DSet X = null; Linear1DSet Y = null; if (domain_set instanceof Linear2DSet) { X = ((Linear2DSet) domain_set).getX(); Y = ((Linear2DSet) domain_set).getY(); } else { X = ((LinearNDSet) domain_set).getLinear1DComponent(0); Y = ((LinearNDSet) domain_set).getLinear1DComponent(1); } float[][] limits = new float[2][2]; limits[0][0] = (float) X.getFirst(); limits[0][1] = (float) X.getLast(); limits[1][0] = (float) Y.getFirst(); limits[1][1] = (float) Y.getLast(); // convert values to default units (used in display) limits = Unit.convertTuple(limits, dataUnits, domain_units); // get domain_set sizes data_width = X.getLength(); data_height = Y.getLength(); texture_width = shadow_api.textureWidth(data_width); texture_height = shadow_api.textureHeight(data_height); int[] tuple_index = new int[3]; if (DomainComponents.length != 2) { throw new DisplayException("texture domain dimension != 2:" + "ShadowFunctionOrSetType.doTransform"); } for (int i=0; i 0 && real.equals(display.getDisplayScalar(valueToScalar[i])) ) { value2 = value_array[i]; break; } } 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 shadow_api.adjustZ(coordinates); texCoords = new float[8]; float ratiow = ((float) data_width) / ((float) texture_width); float ratioh = ((float) data_height) / ((float) texture_height); shadow_api.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; /* for (int i=0; i < 4; i++) { System.out.println("i = " + i + " texCoords = " + texCoords[2 * i] + " " + texCoords[2 * i + 1]); System.out.println(" coordinates = " + coordinates[3 * i] + " " + coordinates[3 * i + 1] + " " + coordinates[3 * i + 2]); System.out.println(" normals = " + normals[3 * i] + " " + normals[3 * i + 1] + " " + normals[3 * i + 2]); } */ } else if (isTexture3D) { Linear1DSet X = null; Linear1DSet Y = null; Linear1DSet Z = null; if (domain_set instanceof Linear3DSet) { X = ((Linear3DSet) domain_set).getX(); Y = ((Linear3DSet) domain_set).getY(); Z = ((Linear3DSet) domain_set).getZ(); } else { X = ((LinearNDSet) domain_set).getLinear1DComponent(0); Y = ((LinearNDSet) domain_set).getLinear1DComponent(1); Z = ((LinearNDSet) domain_set).getLinear1DComponent(2); } float[][] limits = new float[3][2]; limits[0][0] = (float) X.getFirst(); limits[0][1] = (float) X.getLast(); limits[1][0] = (float) Y.getFirst(); limits[1][1] = (float) Y.getLast(); limits[2][0] = (float) Z.getFirst(); limits[2][1] = (float) Z.getLast(); // convert values to default units (used in display) limits = Unit.convertTuple(limits, dataUnits, domain_units); // get domain_set sizes data_width = X.getLength(); data_height = Y.getLength(); data_depth = Z.getLength(); texture_width = shadow_api.textureWidth(data_width); texture_height = shadow_api.textureHeight(data_height); texture_depth = shadow_api.textureDepth(data_depth); int[] tuple_index = new int[3]; if (DomainComponents.length != 3) { throw new DisplayException("texture3D domain dimension != 3:" + "ShadowFunctionOrSetType.doTransform"); } for (int i=0; i 0.999999f) { */ if (color_values[3][0] == -1) { // = 255 unsigned constant_alpha = 0.0f; // constant_alpha = 1.0f; WLH 26 May 99 // remove alpha from color_values byte[][] c = new byte[3][]; c[0] = color_values[0]; c[1] = color_values[1]; c[2] = color_values[2]; color_values = c; } else { // not opaque /* TransparencyAttributes with constant alpha seems to have broken from The Java 3D API Specification: p. 118 transparency = 1 - alpha, p. 116 transparency 0.0 = opaque, 1.0 = clear */ /* broken alpha - put it back when alpha fixed constant_alpha = new TransparencyAttributes(TransparencyAttributes.NICEST, 1.0f - byteToFloat(color_values[3][0])); so expand constant alpha to variable alpha and note no alpha in Java2D: */ byte v = color_values[3][0]; color_values[3] = new byte[color_values[0].length]; for (int i=0; i 1) { int len = range_select[0].length; /* can be misleading because of the way transparency composites float alpha = default_values[display.getDisplayScalarIndex(Display.Alpha)]; // System.out.println("alpha = " + alpha); if (constant_alpha == constant_alpha) { alpha = 1.0f - constant_alpha; // System.out.println("constant_alpha = " + alpha); } if (color_values.length < 4) { byte[][] c = new byte[4][]; c[0] = color_values[0]; c[1] = color_values[1]; c[2] = color_values[2]; c[3] = new byte[len]; for (int i=0; i 1) { int len = range_select[0].length; /* can be misleading because of the way transparency composites WLH 15 March 2000 */ float alpha = default_values[display.getDisplayScalarIndex(Display.Alpha)]; if (constant_alpha == constant_alpha) { alpha = 1.0f - constant_alpha; } if (color_values.length < 4) { byte[][] c = new byte[4][]; c[0] = color_values[0]; c[1] = color_values[1]; c[2] = color_values[2]; c[3] = new byte[len]; for (int i=0; i 0) { shadow_api.addToGroup(group, array, mode, constant_alpha, constant_color); // System.out.println("array.makeGeometry"); // FREE array = null; /* WLH 25 June 2000 if (renderer.getIsDirectManipulation()) { renderer.setSpatialValues(spatial_values); } */ } } // end if (!anyContourCreated && !anyFlowCreated && // !anyTextCreated && !anyShapeCreated) // WLH 25 June 2000 if (renderer.getIsDirectManipulation()) { renderer.setSpatialValues(spatial_values); } // System.out.println("end doTransform " + (System.currentTimeMillis() - link.start_time)); return false; } // end if (LevelOfDifficulty == SIMPLE_FIELD) else if (LevelOfDifficulty == SIMPLE_ANIMATE_FIELD) { Control control = null; Object swit = null; int index = -1; for (int i=0; i 1) { sp[0][0] = spatial_values[0][i]; sp[1][0] = spatial_values[1][i]; sp[2][0] = spatial_values[2][i]; } else { sp[0][0] = spatial_values[0][0]; sp[1][0] = spatial_values[1][0]; sp[2][0] = spatial_values[2][0]; } byte[][] co = new byte[3][1]; if (color_values == null) { co[0][0] = floatToByte(constant_color[0]); co[1][0] = floatToByte(constant_color[1]); co[2][0] = floatToByte(constant_color[2]); } else if (color_values[0].length > 1) { co[0][0] = color_values[0][i]; co[1][0] = color_values[1][i]; co[2][0] = color_values[2][i]; } else { co[0][0] = color_values[0][0]; co[1][0] = color_values[1][0]; co[2][0] = color_values[2][0]; } boolean[][] ra = {{true}}; boolean anyShapeCreated = false; VisADGeometryArray[] arrays = shadow_api.assembleShape(display_values, valueArrayLength, valueToMap, MapVector, valueToScalar, display, default_values, inherited_values, sp, co, ra, i, shadow_api); if (arrays != null) { for (int j=0; j 1) { te[0] = text_values[i]; } else { te[0] = text_values[0]; } array = shadow_api.makeText(te, text_control, spatial_values, co, ra); if (array != null) { shadow_api.addToGroup(branch, array, mode, constant_alpha, constant_color); array = null; anyTextCreated = true; } } boolean anyFlowCreated = false; if (anyFlow) { if (flow1_values != null && flow1_values[0] != null) { // try Flow1 float[][] f1 = new float[3][1]; if (flow1_values[0].length > 1) { f1[0][0] = flow1_values[0][i]; f1[1][0] = flow1_values[1][i]; f1[2][0] = flow1_values[2][i]; } else { f1[0][0] = flow1_values[0][0]; f1[1][0] = flow1_values[1][0]; f1[2][0] = flow1_values[2][0]; } arrays = shadow_api.makeFlow(0, f1, flowScale[0], sp, co, ra); if (arrays != null) { for (int j=0; j 1) { f2[0][0] = flow2_values[0][i]; f2[1][0] = flow2_values[1][i]; f2[2][0] = flow2_values[2][i]; } else { f2[0][0] = flow2_values[0][0]; f2[1][0] = flow2_values[1][0]; f2[2][0] = flow2_values[2][0]; } arrays = shadow_api.makeFlow(1, f2, flowScale[1], sp, co, ra); if (arrays != null) { for (int j=0; j 3) { ColorModel colorModel = ColorModel.getRGBdefault(); WritableRaster raster = colorModel.createCompatibleWritableRaster(texture_width, texture_height); image = new BufferedImage(colorModel, raster, false, null); // WLH 1 Nov 2000 int[] intData = null; DataBuffer db = raster.getDataBuffer(); if (!(db instanceof DataBufferInt)) { intData = new int[texture_width * texture_height]; } else { intData = ((DataBufferInt) db).getData(); } // int[] intData = ((DataBufferInt)raster.getDataBuffer()).getData(); int k = 0; int m = 0; int r, g, b, a; for (int j=0; j 3) { ColorModel colorModel = ColorModel.getRGBdefault(); WritableRaster raster = colorModel.createCompatibleWritableRaster(texture_width, texture_height); images[d] = new BufferedImage(colorModel, raster, false, null); /* WLH 23 Feb 2000 if (axis == 1) { images[(data_depth-1) - d] = new BufferedImage(colorModel, raster, false, null); } else { images[d] = new BufferedImage(colorModel, raster, false, null); } */ // WLH 1 Nov 2000 int[] intData = null; DataBuffer db = raster.getDataBuffer(); if (!(db instanceof DataBufferInt)) { intData = new int[texture_width * texture_height]; } else { intData = ((DataBufferInt) db).getData(); } // int[] intData = ((DataBufferInt)raster.getDataBuffer()).getData(); // int k = d * data_width * data_height; int kk = d * kdepth; int m = 0; int r, g, b, a; for (int j=0; j