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