Issue #28 Cleaned up True Color code and removed old MultiChannel code. Adding capping index back to indexing.glsl and added no data value to ColorMapParameters that should be used for finding no data values in shader and in java. True color dialog was written but not hooked in yet as need to still think about single resource tied to multiple channels and serializing changes.

Change-Id: I20bff443fe4c9b9330c0a66779218227c48df014

Former-commit-id: fc06265360 [formerly b69d2cad1c] [formerly fc06265360 [formerly b69d2cad1c] [formerly 1b406ecfca [formerly 564b38b30562a371cf0345de572b32ea8f53e82e]]]
Former-commit-id: 1b406ecfca
Former-commit-id: 47cefd1513 [formerly aa9df46a1d]
Former-commit-id: 362d34bee0
This commit is contained in:
Max Schenkelberg 2012-08-20 14:47:14 -05:00
parent 322d74aab7
commit dcbab7d58f
31 changed files with 721 additions and 2023 deletions

View file

@ -187,6 +187,8 @@ public class ColorMapParameters implements Cloneable, ISerializableObject {
private boolean mirror;
private double noDataValue = Double.NaN;
@XmlElement
private PersistedParameters persisted = new PersistedParameters();
@ -1009,4 +1011,20 @@ public class ColorMapParameters implements Cloneable, ISerializableObject {
this.colorMapMax = params.colorMapMax;
}
}
/**
* @return the noDataValue
*/
public double getNoDataValue() {
return noDataValue;
}
/**
* @param noDataValue
* the noDataValue to set
*/
public void setNoDataValue(double noDataValue) {
this.noDataValue = noDataValue;
}
}

View file

@ -124,7 +124,7 @@ public class ImagingSupport {
bulk.toArray(new DrawableImage[bulk.size()]));
}
return rval & skipped;
return rval & !skipped;
}
/**

View file

@ -1,104 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.drawables.ext.colormap;
import java.util.Map;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
import com.raytheon.uf.viz.core.exception.VizException;
/**
* {@link IImagingExtension} used to create and draw multi-channel R,G,B images
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 5, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public interface IMultiChannelImageExtension extends IImagingExtension {
public static enum Channel {
RED, GREEN, BLUE;
}
public static class ChannelData {
public String name;
public ColorMapParameters parameters;
public boolean invert;
public ChannelData(String name, ColorMapParameters params,
boolean invert) {
this.name = name;
this.parameters = params;
}
}
public static interface IMultiChannelImage extends IImage {
public Map<Channel, IImageChannel> getImageMapping();
public void setImageMapping(Map<Channel, IImageChannel> mapping);
}
public static interface IImageChannel extends IColormappedImage {
public void setInverted(boolean inverted);
}
/**
* Construct a true color image, this
*
* @param channelMap
* @return
* @throws VizException
*/
public IMultiChannelImage constructImage(
Map<Channel, IImageChannel> imageMapping) throws VizException;
/**
* Construct a IImageChannel for a IMultiChannelImage
*
* @param callback
* @param inverted
* @return
* @throws VizException
*/
public IImageChannel constructImage(
IColorMapDataRetrievalCallback callback, ChannelData channelData)
throws VizException;
}

View file

@ -1,313 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.core.rsc.capabilities;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.Channel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.ChannelData;
/**
* Capability for multi channel imagery
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class MultiChannelCapability extends AbstractCapability {
@XmlAccessorType(XmlAccessType.NONE)
public static class ChannelSerializable {
@XmlAttribute
private String name;
@XmlAttribute
private Channel channel;
@XmlAttribute
private boolean invert;
@XmlElement
private float dataMin;
@XmlElement
private float dataMax;
@XmlElement
private float cmapMin;
@XmlElement
private float cmapMax;
public ChannelSerializable() {
}
public ChannelSerializable(Channel channel, ChannelData channelData) {
this.channel = channel;
this.name = channelData.name;
this.invert = channelData.invert;
ColorMapParameters params = channelData.parameters;
this.dataMin = params.getDataMin();
this.dataMax = params.getDataMax();
this.cmapMin = params.getColorMapMin();
this.cmapMax = params.getColorMapMax();
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the channel
*/
public Channel getChannel() {
return channel;
}
/**
* @param channel
* the channel to set
*/
public void setChannel(Channel channel) {
this.channel = channel;
}
/**
* @return the dataMin
*/
public float getDataMin() {
return dataMin;
}
/**
* @param dataMin
* the dataMin to set
*/
public void setDataMin(float dataMin) {
this.dataMin = dataMin;
}
/**
* @return the dataMax
*/
public float getDataMax() {
return dataMax;
}
/**
* @param dataMax
* the dataMax to set
*/
public void setDataMax(float dataMax) {
this.dataMax = dataMax;
}
/**
* @return the cmapMin
*/
public float getCmapMin() {
return cmapMin;
}
/**
* @param cmapMin
* the cmapMin to set
*/
public void setCmapMin(float cmapMin) {
this.cmapMin = cmapMin;
}
/**
* @return the cmapMax
*/
public float getCmapMax() {
return cmapMax;
}
/**
* @param cmapMax
* the cmapMax to set
*/
public void setCmapMax(float cmapMax) {
this.cmapMax = cmapMax;
}
/**
* @return the invert
*/
public boolean isInvert() {
return invert;
}
/**
* @param invert
* the invert to set
*/
public void setInvert(boolean invert) {
this.invert = invert;
}
}
public static class Marshaller extends
XmlAdapter<ChannelSerializable[], HashMap<Channel, ChannelData>> {
/*
* (non-Javadoc)
*
* @see
* javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang
* .Object)
*/
@Override
public HashMap<Channel, ChannelData> unmarshal(ChannelSerializable[] v)
throws Exception {
HashMap<Channel, ChannelData> channelMap = new HashMap<Channel, ChannelData>();
for (ChannelSerializable cs : v) {
ColorMapParameters params = new ColorMapParameters();
params.setDataMin(cs.dataMin);
params.setDataMax(cs.dataMax);
params.setColorMapMin(cs.cmapMin);
params.setColorMapMax(cs.cmapMax);
channelMap.put(cs.channel, new ChannelData(cs.name, params,
cs.invert));
}
return channelMap;
}
/*
* (non-Javadoc)
*
* @see
* javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object
* )
*/
@Override
public ChannelSerializable[] marshal(HashMap<Channel, ChannelData> v)
throws Exception {
ChannelSerializable[] serializable = new ChannelSerializable[v
.size()];
int i = 0;
for (Entry<Channel, ChannelData> entry : v.entrySet()) {
ChannelSerializable cs = new ChannelSerializable(
entry.getKey(), entry.getValue());
serializable[i++] = cs;
}
return serializable;
}
}
@XmlJavaTypeAdapter(value = Marshaller.class)
private HashMap<Channel, ChannelData> channelMap = new HashMap<Channel, ChannelData>();
private String[] names;
/**
* @return the names
*/
public String[] getNames() {
return names;
}
/**
* @param names
* the names to set
*/
public void setNames(String[] names) {
this.names = names;
}
/**
* @return the channelMap
*/
public Map<Channel, ChannelData> getChannelMap() {
return channelMap;
}
/**
* @param channelMap
* the channelMap to set
*/
public void setChannelMap(HashMap<Channel, ChannelData> channelMap) {
if (channelMap == null) {
channelMap = new HashMap<Channel, ChannelData>();
}
this.channelMap = channelMap;
capabilityChanged();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability#
* capabilityChanged()
*/
@Override
public void capabilityChanged() {
super.capabilityChanged();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability#clone()
*/
@Override
public AbstractCapability clone() {
MultiChannelCapability cap = new MultiChannelCapability();
cap.channelMap = new HashMap<Channel, ChannelData>(channelMap);
return cap;
}
}

View file

@ -123,7 +123,7 @@ public class Tile {
* @param y
* @return
*/
public boolean contains(double x, double y) {
public boolean crsContains(double x, double y) {
Envelope env = tileGeometry.getEnvelope();
return env.getMinimum(0) <= x && env.getMaximum(0) >= x
&& env.getMinimum(1) <= y && env.getMaximum(1) >= y;
@ -135,8 +135,22 @@ public class Tile {
* @param c
* @return
*/
public boolean contains(Coordinate c) {
return contains(c.x, c.y);
public boolean crsContains(Coordinate c) {
return crsContains(c.x, c.y);
}
/**
* Checks to see if the x/y coordinate is contained by the Tile's grid
* envelope
*
* @param gridX
* @param gridY
* @return
*/
public boolean gridContains(int gridX, int gridY) {
GridEnvelope ge = tileGeometry.getGridRange();
return ge.getLow(0) <= gridX && ge.getHigh(0) >= gridX
&& ge.getLow(1) <= gridY && ge.getHigh(1) >= gridY;
}
/*

View file

@ -225,11 +225,14 @@ public class TileLevel {
* @return
*/
public Tile getTile(double x, double y) {
int xIdx = (int) x / tileSize;
int yIdx = (int) y / tileSize;
double xIdx = x / tileSize;
double yIdx = y / tileSize;
if (xIdx >= 0 && yIdx >= 0 && xIdx < getNumXTiles()
&& yIdx < getNumYTiles()) {
return tiles[yIdx][xIdx];
Tile tile = getTile((int) xIdx, (int) yIdx);
if (tile.gridContains((int) x, (int) y)) {
return tile;
}
}
return null;
}

View file

@ -14,15 +14,20 @@ uniform sampler2D trueColorTexture;
uniform int height;
uniform int width;
uniform float noDataValue;
uniform float alphaStep;
uniform int checkAlpha;
float getIndex(sampler2D rawTex, float cmapMin, float cmapMax, float naturalMin, float naturalMax, int isFloat) {
vec4 textureValue = texture2D(rawTex, gl_TexCoord[0].st);
float naturalVal = textureValue.r;
if ( isFloat == 0 ) {
naturalVal = ((naturalVal * (naturalMax - naturalMin)) + naturalMin);
}
float index = findIndex(naturalVal, cmapMin, cmapMax);
if (index < 0.0 || index > 1.0) {
index = -1.0;
float index = 0.0;
if (naturalVal != noDataValue && naturalVal == naturalVal) {
index = findIndex(naturalVal, cmapMin, cmapMax);
}
return index;
}
@ -39,11 +44,6 @@ void main(void)
float a = curVal.a;
float index = getIndex(rawTex, cmapMin, cmapMax, naturalMin, naturalMax, isFloat);
if ( index < 0.0 ) {
index = a = 0.0;
} else {
a = 1.0;
}
if ( band == 0 && index > r ) {
r = index;
} else if ( band == 1 && index > g ) {
@ -51,6 +51,11 @@ void main(void)
} else if ( band == 2 && index > b ) {
b = index;
}
a = a + alphaStep;
if (checkAlpha == 1 && a < 1.0) {
a = 0.0;
}
gl_FragColor = vec4(r,g,b,a);
}

View file

@ -19,6 +19,9 @@
**/
package com.raytheon.uf.viz.truecolor.gl.extension;
import java.util.IdentityHashMap;
import java.util.Map;
import javax.media.opengl.GL;
import com.raytheon.uf.viz.core.DrawableImage;
@ -61,6 +64,20 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
private Channel renderingChannel;
private Map<ColorMapParameters, Object> parameters = new IdentityHashMap<ColorMapParameters, Object>();
/**
* Alpha value to add to current alpha. When all 3 passes occur, alpha
* should be >= 1.0
*/
private float alphaStep;
/**
* Flag if alpha check should be performed in shader. Alpha vals less than
* one will be set to 0
*/
private boolean checkAlpha;
/*
* (non-Javadoc)
*
@ -102,6 +119,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
if (image instanceof GLTrueColorImage) {
GLTrueColorImage trueColorImage = (GLTrueColorImage) image;
if (trueColorImage.isRepaint()) {
parameters.clear();
writeToImage = trueColorImage;
GLOffscreenRenderingExtension extension = target
.getExtension(GLOffscreenRenderingExtension.class);
@ -109,28 +127,33 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
extension.renderOffscreen(trueColorImage,
trueColorImage.getImageExtent());
boolean allPainted = true;
int channels = trueColorImage.getNumberOfChannels();
// Calculate our alpha step, ensure channels * alphaStep >=
// 1.0
alphaStep = 1.0f / (channels - 0.1f);
int i = 1;
for (Channel channel : Channel.values()) {
renderingChannel = channel;
DrawableImage[] imagesToDraw = trueColorImage
.getImages(channel);
if (imagesToDraw != null && imagesToDraw.length > 0) {
// Perform alpha check on last pass
checkAlpha = i == channels;
// Make sure images are staged before we mosaic them
ImagingSupport.prepareImages(target, imagesToDraw);
// Each image needs to draw separately due to gl
// issues when
// zoomed in very far, rendered parts near the
// corners don't
// show all the pixels for each image. Pushing and
// popping
// GL_TEXTURE_BIT before/after each render fixes
// this issue
// issues when zoomed in very far, rendered parts
// near the corners don't show all the pixels for
// each image. Pushing and popping GL_TEXTURE_BIT
// before/after each render fixes this issue
for (DrawableImage di : imagesToDraw) {
allPainted &= drawRasters(paintProps, di);
}
// Need to set repaint based on if drawing
// completed.
trueColorImage.setRepaint(allPainted == false);
++i;
}
}
} finally {
@ -140,6 +163,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
writeToImage = null;
}
trueColorImage.setImageParameters(parameters.keySet());
target.drawRasters(paintProps,
new DrawableImage(trueColorImage.getWrappedImage(),
imageCoverage));
@ -190,6 +214,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
GLColormappedImage cmapImage = (GLColormappedImage) image;
ColorMapParameters colorMapParameters = cmapImage
.getColorMapParameters();
parameters.put(colorMapParameters, null);
int textureType = cmapImage.getTextureType();
// Set the band image data
@ -200,6 +225,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
program.setUniform("cmapMax", colorMapParameters.getColorMapMax());
program.setUniform("isFloat", textureType == GL.GL_FLOAT
|| textureType == GL.GL_HALF_FLOAT_ARB ? 1 : 0);
program.setUniform("noDataValue", colorMapParameters.getNoDataValue());
// Set the composite image data
program.setUniform("trueColorTexture", 1);
@ -208,6 +234,21 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
// Set the band we are rendering to
program.setUniform("band", renderingChannel.ordinal());
program.setUniform("checkAlpha", checkAlpha);
program.setUniform("alphaStep", alphaStep);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.ext.AbstractGLImagingExtension#enableBlending
* (javax.media.opengl.GL)
*/
@Override
protected void enableBlending(GL gl) {
// Do not enable blending for this extension as it messes with alpha
// values between passes
}
}

View file

@ -22,12 +22,16 @@ package com.raytheon.uf.viz.truecolor.gl.image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IColorMapParametersListener;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
@ -53,7 +57,7 @@ import com.raytheon.viz.core.gl.images.GLImage;
*/
public class GLTrueColorImage extends GLDelegateImage<GLImage> implements
ITrueColorImage {
ITrueColorImage, IColorMapParametersListener {
private static class RGBCallback implements IRenderedImageCallback {
private int[] bounds;
@ -77,6 +81,9 @@ public class GLTrueColorImage extends GLDelegateImage<GLImage> implements
private Map<Channel, DrawableImage[]> channelMap = new HashMap<Channel, DrawableImage[]>();
/* Identity set used to track color map parameters currently listening on */
private Map<ColorMapParameters, Object> listening = new IdentityHashMap<ColorMapParameters, Object>();
/**
* @param extensionClass
*/
@ -121,12 +128,15 @@ public class GLTrueColorImage extends GLDelegateImage<GLImage> implements
}
}
/**
* Get the images for the specified channel
/*
* (non-Javadoc)
*
* @param channel
* @return
* @see com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.
* ITrueColorImage
* #getImages(com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension
* .Channel)
*/
@Override
public DrawableImage[] getImages(Channel channel) {
return channelMap.get(channel);
}
@ -177,4 +187,62 @@ public class GLTrueColorImage extends GLDelegateImage<GLImage> implements
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColorMapParametersListener#
* colorMapChanged()
*/
@Override
public void colorMapChanged() {
// Repaint image on colormap change events
repaint = true;
}
/**
* Sets the ColorMapParameters it's images are using. We add ourselves as
* listeners so we can repaint on changes
*
* @param parameters
*/
public void setImageParameters(Collection<ColorMapParameters> parameters) {
boolean same = false;
if (parameters.size() == listening.size()) {
same = true;
for (ColorMapParameters params : parameters) {
same &= listening.containsKey(params);
if (!same) {
break;
}
}
}
if (!same) {
// Current image parameters list different from passed in, set up
// listeners on new set and remove from current set
for (ColorMapParameters params : listening.keySet()) {
params.removeListener(this);
}
listening.clear();
for (ColorMapParameters params : parameters) {
params.addListener(this);
listening.put(params, null);
}
}
}
/**
* Returns the number of channels the image is currently using
*
* @return
*/
public int getNumberOfChannels() {
int channels = 0;
for (Channel c : Channel.values()) {
DrawableImage[] images = getImages(c);
if (images != null && images.length > 0) {
++channels;
}
}
return channels;
}
}

View file

@ -5,7 +5,7 @@ Bundle-SymbolicName: com.raytheon.uf.viz.truecolor;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.truecolor.Activator
Bundle-Vendor: RAYTHEON
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core, com.raytheon.viz.ui
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
com.raytheon.uf.viz.core;bundle-version="1.12.1174",

View file

@ -1 +1,2 @@
com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroupData
com.raytheon.uf.viz.truecolor.rsc.ChannelResource

View file

@ -28,4 +28,14 @@
renderingOrderId="IMAGE_COUNTRY"
resourceType="PLAN_VIEW"/>
</extension>
<extension
point="com.raytheon.viz.ui.contextualMenu">
<!-- Enable when dialog is ready
<contextualMenu
actionClass="com.raytheon.uf.viz.truecolor.ui.TrueColorDialogAction"
capabilityClass="com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup"
name="TrueColorImaging"
sortID="25"/>
-->
</extension>
</plugin>

View file

@ -55,6 +55,8 @@ public interface ITrueColorImagingExtension extends IImagingExtension {
public void setImages(Channel channel, DrawableImage... images);
public DrawableImage[] getImages(Channel channel);
public void setSize(int[] bounds);
public void setImageExtent(IExtent extent);

View file

@ -0,0 +1,153 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
* Object that represents a resource bound to a {@link Channel}
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 16, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class ChannelResource {
@XmlElement
protected AbstractResourceData resourceData;
protected Set<Channel> channels = new HashSet<Channel>();
@XmlAttribute
protected String channelName;
/**
* @return the resourceData
*/
public AbstractResourceData getResourceData() {
return resourceData;
}
/**
* @param resourceData
* the resourceData to set
*/
public void setResourceData(AbstractResourceData resourceData) {
this.resourceData = resourceData;
}
/**
* @return the channel
*/
@XmlElement(name = "channel")
public Channel[] getChannels() {
return channels.toArray(new Channel[channels.size()]);
}
/**
* @param channel
* the channel to set
*/
public void setChannels(Channel[] channels) {
if (channels == null) {
channels = new Channel[0];
}
this.channels = new HashSet<Channel>(Arrays.asList(channels));
}
/**
* @return the channelName
*/
public String getChannelName() {
return channelName;
}
/**
* @param channelName
* the channelName to set
*/
public void setChannelName(String channelName) {
this.channelName = channelName;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((channelName == null) ? 0 : channelName.hashCode());
result = prime * result
+ ((resourceData == null) ? 0 : resourceData.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ChannelResource other = (ChannelResource) obj;
if (channelName == null) {
if (other.channelName != null)
return false;
} else if (!channelName.equals(other.channelName))
return false;
if (resourceData == null) {
if (other.resourceData != null)
return false;
} else if (!resourceData.equals(other.resourceData))
return false;
return true;
}
}

View file

@ -19,7 +19,12 @@
**/
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.swt.graphics.Rectangle;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@ -30,6 +35,7 @@ import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.IDescriptor.FramesInfo;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ResourcePair;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension.ImageProvider;
@ -71,6 +77,75 @@ public class TrueColorResourceGroup extends
AbstractVizResource<TrueColorResourceGroupData, IDescriptor> implements
IResourceGroup, IResourceDataChanged {
public static class DisplayedChannelResource {
private String displayName;
public AbstractVizResource<?, ?> resource;
public ChannelResource channel;
private DisplayedChannelResource(ChannelResource cr,
AbstractVizResource<?, ?> resource) {
this.channel = cr;
this.resource = resource;
this.displayName = cr.getChannelName();
if (displayName == null) {
displayName = resource.getName();
}
}
/**
* Returns the display name of the channel
*
* @return
*/
public String getDisplayName() {
return displayName;
}
/**
* Checks if the resource is bound to the specified {@link Channel}
*
* @param channel
* @return
*/
public boolean isChannel(Channel channel) {
return this.channel.channels.contains(channel);
}
/**
* Removes a channel from being assigned to the resource
*
* @param channel
*/
public void removeChannel(Channel channel) {
this.channel.channels.remove(channel);
}
/**
* Adds a channel to be assigned to the resource
*
* @param channel
*/
public void addChannel(Channel channel) {
this.channel.channels.add(channel);
}
/**
* Set the channels to be used by the channel resource
*
* @param channels
*/
public void setChannels(Channel[] channels) {
channel.setChannels(channels);
}
}
private static final String DEFAULT_NAME = "RGB Composite";
private List<DisplayedChannelResource> displayedResources;
private ITrueColorImage image;
private boolean timeAgnostic = true;
@ -124,11 +199,18 @@ public class TrueColorResourceGroup extends
image.setSize(new int[] { rect.width, rect.height });
image.setImageExtent(extent);
FramesInfo fi = paintProps.getFramesInfo();
for (Channel c : Channel.values()) {
ResourcePair rp = resourceData.getResource(c);
if (rp != null) {
image.setImages(c, getImages(rp, target, paintProps));
List<DrawableImage> images = new ArrayList<DrawableImage>();
for (DisplayedChannelResource dcr : displayedResources) {
if (dcr.isChannel(c)) {
paintProps.setDataTime(fi.getTimeForResource(dcr.resource));
images.addAll(dcr.resource
.getCapability(ImagingCapability.class)
.getProvider().getImages(target, paintProps));
}
}
image.setImages(c, images.toArray(new DrawableImage[images.size()]));
}
Coordinate ul = new Coordinate(extent.getMinX(), extent.getMaxY());
@ -139,17 +221,6 @@ public class TrueColorResourceGroup extends
target.drawRaster(image, new PixelCoverage(ul, ur, lr, ll), paintProps);
}
private DrawableImage[] getImages(ResourcePair rp, IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
paintProps.setDataTime(paintProps.getFramesInfo().getTimeForResource(
rp.getResource()));
ImagingCapability imaging = rp.getResource().getCapability(
ImagingCapability.class);
Collection<DrawableImage> images = imaging.getProvider().getImages(
target, paintProps);
return images.toArray(new DrawableImage[images.size()]);
}
/*
* (non-Javadoc)
*
@ -172,30 +243,56 @@ public class TrueColorResourceGroup extends
// We will name the composite
getCapability(GroupNamingCapability.class);
// Initialize them
for (ResourcePair rp : getResourceList()) {
AbstractVizResource<?, ?> resource = rp.getResource();
resource.init(target);
// Check resource for required capabilities
String error = null;
if (resource.hasCapability(ImagingCapability.class)) {
ImagingCapability imaging = resource
.getCapability(ImagingCapability.class);
if (imaging.getProvider() != null) {
if (resource.hasCapability(ColorMapCapability.class) == false) {
error = "does not have ColorMapCapability";
displayedResources = new ArrayList<DisplayedChannelResource>();
ResourceList resources = getResourceList();
// Make sure multiple resources are not assinged to same channel
Set<Channel> usedChannels = new HashSet<Channel>();
for (ChannelResource cr : resourceData.getChannelResources()) {
for (ResourcePair rp : resources) {
if (cr.getResourceData() == rp.getResourceData()) {
DisplayedChannelResource displayedResource = new DisplayedChannelResource(
cr, rp.getResource());
AbstractVizResource<?, ?> resource = rp.getResource();
resource.init(target);
// Check resource for required capabilities
String error = null;
if (resource.hasCapability(ImagingCapability.class)) {
ImagingCapability imaging = resource
.getCapability(ImagingCapability.class);
if (imaging.getProvider() != null) {
if (resource
.hasCapability(ColorMapCapability.class) == false) {
error = "does not have ColorMapCapability";
}
} else {
error = "does not have image provider set on the ImagingCapability";
}
} else {
error = "does not have the ImagingCapability";
}
} else {
error = "does not have image provider set on the ImagingCapability";
if (error != null) {
Activator.statusHandler.handle(Priority.PROBLEM,
displayedResource.getDisplayName()
+ " resource in true color composite "
+ error);
resources.remove(rp);
} else {
resource.getResourceData().addChangeListener(this);
// Force channels unique to a single resource
for (Channel c : usedChannels) {
if (displayedResource.isChannel(c)) {
// Notify with INFO message?
displayedResource.removeChannel(c);
}
}
usedChannels
.addAll(Arrays.asList(displayedResource.channel
.getChannels()));
displayedResources.add(displayedResource);
}
break;
}
} else {
error = "does not have the ImagingCapability";
}
if (error != null) {
Activator.statusHandler.handle(Priority.PROBLEM,
resourceData.getCompositeName(rp)
+ " resource in true color composite " + error);
resourceData.removeResource(rp);
}
}
@ -203,16 +300,59 @@ public class TrueColorResourceGroup extends
.getExtension(ITrueColorImagingExtension.class);
image = ext.initializeRaster(new int[] { 0, 0 }, null);
resourceData.addChangeListener(this);
// Set initial ImagingCapability parameters
resourceChanged(ChangeType.CAPABILITY,
getCapability(ImagingCapability.class));
// Every resource has to be time agnostic for us to be as well
timeAgnostic = true;
for (ResourcePair rp : getResourceList()) {
// If any resource is not time agnostic, neither are we
timeAgnostic &= rp.getResource().isTimeAgnostic();
for (DisplayedChannelResource dr : displayedResources) {
timeAgnostic &= dr.resource.isTimeAgnostic();
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getName()
*/
@Override
public String getName() {
String name = resourceData.getGroupName();
if (name != null) {
name += " ";
}
if (image != null) {
String productNames = "";
boolean first = true;
for (Channel c : Channel.values()) {
DrawableImage[] images = image.getImages(c);
if (images != null && images.length > 0) {
name += c.name().substring(0, 1);
if (!first) {
productNames += "/";
}
for (DisplayedChannelResource rsc : displayedResources) {
if (rsc.isChannel(c)) {
productNames += rsc.getDisplayName();
break;
}
}
first = false;
}
}
if (first == true) {
name += DEFAULT_NAME;
} else {
name += ": " + productNames;
}
} else {
name += DEFAULT_NAME;
}
return name;
}
/*
* (non-Javadoc)
*
@ -245,6 +385,10 @@ public class TrueColorResourceGroup extends
image.setInterpolated(imaging.isInterpolationState());
}
}
issueRefresh();
}
public Collection<DisplayedChannelResource> getChannelResources() {
return displayedResources;
}
}

View file

@ -19,19 +19,22 @@
**/
package com.raytheon.uf.viz.truecolor.rsc;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.viz.core.drawables.IDescriptor;
import com.raytheon.uf.viz.core.drawables.ResourcePair;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractNameGenerator;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IResourceGroup;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.ResourceList;
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
* {@link TrueColorResourceGroup} resource data. Contains a red/blue/green
@ -51,7 +54,7 @@ import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channe
* @author mschenke
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class TrueColorResourceGroupData extends AbstractResourceData implements
IResourceGroup {
@ -60,23 +63,8 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
@XmlElement
private String groupName;
@XmlElement
private AbstractResourceData redChannelResource;
@XmlElement
private AbstractResourceData greenChannelResource;
@XmlElement
private AbstractResourceData blueChannelResource;
public TrueColorResourceGroupData() {
nameGenerator = new AbstractNameGenerator() {
@Override
public String getName(AbstractVizResource<?, ?> resource) {
return groupName;
}
};
}
@XmlElement(name = "channelResource")
private List<ChannelResource> channelResources;
/*
* (non-Javadoc)
@ -87,81 +75,25 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
public ResourceList getResourceList() {
if (resourceList == null) {
resourceList = new ResourceList();
// Initialize the resource list, if any of the resources equal each
// other, replace with reference instead of copy to save memory
if (redChannelResource != null) {
addResource(redChannelResource);
}
if (greenChannelResource != null) {
if (greenChannelResource.equals(redChannelResource)) {
greenChannelResource = redChannelResource;
} else {
addResource(greenChannelResource);
}
}
if (blueChannelResource != null) {
if (blueChannelResource.equals(redChannelResource)) {
blueChannelResource = redChannelResource;
} else if (blueChannelResource.equals(greenChannelResource)) {
blueChannelResource = greenChannelResource;
} else {
addResource(blueChannelResource);
// Removes duplicate resources
List<ChannelResource> added = new ArrayList<ChannelResource>(
channelResources.size());
for (ChannelResource resource : channelResources) {
if (addResource(resource.getResourceData())) {
added.add(resource);
}
channelResources = added;
}
}
return resourceList;
}
private void addResource(AbstractResourceData resourceData) {
private boolean addResource(AbstractResourceData resourceData) {
ResourcePair rp = new ResourcePair();
rp.setResourceData(resourceData);
rp.setLoadProperties(new LoadProperties());
rp.setProperties(new ResourceProperties());
resourceList.add(rp);
}
/**
* Removes a resource from the resource data
*
* @param rp
*/
public void removeResource(ResourcePair rp) {
resourceList.remove(rp);
if (rp.getResourceData() == redChannelResource) {
redChannelResource = null;
}
if (rp.getResourceData() == greenChannelResource) {
greenChannelResource = null;
}
if (rp.getResourceData() == blueChannelResource) {
blueChannelResource = null;
}
}
/**
* Get the composite name of the resource pair (Red, Red/Green, Blue, etc)
*
* @param rp
* @return
*/
public String getCompositeName(ResourcePair rp) {
String name = "";
if (rp.getResourceData() == redChannelResource) {
name += "Red";
}
if (rp.getResourceData() == greenChannelResource) {
if (name.isEmpty() == false) {
name += "/";
}
name += "Green";
}
if (rp.getResourceData() == blueChannelResource) {
if (name.isEmpty() == false) {
name += "/";
}
name += "Blue";
}
return name;
return resourceList.add(rp);
}
/*
@ -190,33 +122,6 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
// Nothing to update, updates will be handled by sub resources
}
/**
* Get the resource pair associated with the {@link Channel}
*
* @param channel
* @return
*/
public ResourcePair getResource(Channel channel) {
AbstractResourceData toCheckFor = null;
switch (channel) {
case RED:
toCheckFor = redChannelResource;
break;
case GREEN:
toCheckFor = greenChannelResource;
break;
case BLUE:
toCheckFor = blueChannelResource;
break;
}
for (ResourcePair rp : getResourceList()) {
if (rp.getResourceData() == toCheckFor) {
return rp;
}
}
return null;
}
/**
* @return the groupName
*/
@ -233,49 +138,18 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
}
/**
* @return the redChannelResource
* @return the channelResources
*/
public AbstractResourceData getRedChannelResource() {
return redChannelResource;
public List<ChannelResource> getChannelResources() {
return channelResources;
}
/**
* @param redChannelResource
* the redChannelResource to set
* @param channelResources
* the channelResources to set
*/
public void setRedChannelResource(AbstractResourceData redChannelResource) {
this.redChannelResource = redChannelResource;
}
/**
* @return the greenChannelResource
*/
public AbstractResourceData getGreenChannelResource() {
return greenChannelResource;
}
/**
* @param greenChannelResource
* the greenChannelResource to set
*/
public void setGreenChannelResource(
AbstractResourceData greenChannelResource) {
this.greenChannelResource = greenChannelResource;
}
/**
* @return the blueChannelResource
*/
public AbstractResourceData getBlueChannelResource() {
return blueChannelResource;
}
/**
* @param blueChannelResource
* the blueChannelResource to set
*/
public void setBlueChannelResource(AbstractResourceData blueChannelResource) {
this.blueChannelResource = blueChannelResource;
public void setChannelResources(List<ChannelResource> channelResources) {
this.channelResources = channelResources;
}
/*
@ -292,26 +166,16 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
if (getClass() != obj.getClass())
return false;
TrueColorResourceGroupData other = (TrueColorResourceGroupData) obj;
if (blueChannelResource == null) {
if (other.blueChannelResource != null)
if (channelResources == null) {
if (other.channelResources != null)
return false;
} else if (!blueChannelResource.equals(other.blueChannelResource))
return false;
if (greenChannelResource == null) {
if (other.greenChannelResource != null)
return false;
} else if (!greenChannelResource.equals(other.greenChannelResource))
} else if (!channelResources.equals(other.channelResources))
return false;
if (groupName == null) {
if (other.groupName != null)
return false;
} else if (!groupName.equals(other.groupName))
return false;
if (redChannelResource == null) {
if (other.redChannelResource != null)
return false;
} else if (!redChannelResource.equals(other.redChannelResource))
return false;
return true;
}

View file

@ -17,9 +17,12 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.ui.dialogs;
package com.raytheon.uf.viz.truecolor.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -33,17 +36,22 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.Channel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.ChannelData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability;
import com.raytheon.uf.viz.core.rsc.IDisposeListener;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
import com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup;
import com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup.DisplayedChannelResource;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
import com.raytheon.viz.ui.dialogs.ColorMapSliderComp;
/**
* Dialog for manipulating multi channel capability
* Dialog for modifying true color attributes on a dialog
*
* TODO: Update sliders when combo changes
*
* <pre>
*
@ -51,7 +59,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 3, 2012 mschenke Initial creation
* Aug 16, 2012 mschenke Initial creation
*
* </pre>
*
@ -59,29 +67,52 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability;
* @version 1.0
*/
public class MultiChannelDialog extends CaveSWTDialog {
public class TrueColorDialog extends CaveSWTDialog implements IDisposeListener {
private static final String DISABLED = "Disabled";
private AbstractVizResource<?, ?> resource;
private MultiChannelCapability capability;
private String[] items;
protected TrueColorResourceGroup resource;
private List<ColorMapSliderComp> sliderComps;
public MultiChannelDialog(Shell parent, AbstractVizResource<?, ?> resource,
MultiChannelCapability capability) {
super(parent);
this.capability = capability;
private Map<String, DisplayedChannelResource> resourceMap;
private Map<Channel, DisplayedChannelResource> resourceChannelMap;
private Map<DisplayedChannelResource, Channel[]> originalChannelMap;
/**
* Creates the TrueColorDialog as a window of the parent Shell
*
* @param parent
* @param resource
*/
public TrueColorDialog(Shell parent, TrueColorResourceGroup resource) {
super(parent, SWT.DIALOG_TRIM);
this.resource = resource;
String[] names = capability.getNames();
this.items = new String[names.length + 1];
System.arraycopy(names, 0, items, 1, names.length);
items[0] = DISABLED;
this.sliderComps = new ArrayList<ColorMapSliderComp>();
setText("Channel Options");
this.resourceMap = new LinkedHashMap<String, DisplayedChannelResource>();
this.resourceChannelMap = new HashMap<Channel, DisplayedChannelResource>();
this.originalChannelMap = new HashMap<DisplayedChannelResource, Channel[]>();
setText("Composite Options");
populateItemMap(resource.getChannelResources());
resource.registerListener(this);
}
/**
* @param channelResources
*/
private void populateItemMap(
Collection<DisplayedChannelResource> channelResources) {
resourceMap.put(DISABLED, null);
for (DisplayedChannelResource rsc : channelResources) {
Channel[] channels = rsc.channel.getChannels();
resourceMap.put(rsc.getDisplayName(), rsc);
originalChannelMap.put(rsc, channels);
for (Channel c : channels) {
resourceChannelMap.put(c, rsc);
}
}
}
/*
@ -93,9 +124,8 @@ public class MultiChannelDialog extends CaveSWTDialog {
*/
@Override
protected void initializeComponents(Shell shell) {
Map<Channel, ChannelData> channelMap = capability.getChannelMap();
for (Channel c : Channel.values()) {
addGroup(shell, c, channelMap.get(c));
addGroup(shell, c, resourceChannelMap.get(c));
}
Composite buttonComp = new Composite(shell, SWT.NONE);
@ -129,17 +159,23 @@ public class MultiChannelDialog extends CaveSWTDialog {
b.setLayoutData(gd);
}
private void addGroup(Composite parent, Channel channel,
final ChannelData data) {
/**
* @param shell
* @param c
* @param displayedChannelResource
*/
private void addGroup(Composite parent, final Channel channel,
DisplayedChannelResource displayedResource) {
ColorMapParameters params = null;
if (data != null) {
params = data.parameters;
if (displayedResource != null) {
params = displayedResource.resource.getCapability(
ColorMapCapability.class).getColorMapParameters();
} else {
params = new ColorMapParameters();
}
Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
group.setLayout(new GridLayout(4, false));
group.setLayout(new GridLayout(2, false));
group.setText(channel + ":");
group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
final ColorMapSliderComp cmapSlider = new ColorMapSliderComp(group,
@ -147,53 +183,32 @@ public class MultiChannelDialog extends CaveSWTDialog {
cmapSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
sliderComps.add(cmapSlider);
final Button invertBtn = new Button(group, SWT.CHECK);
invertBtn.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
* .swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
data.invert = invertBtn.getSelection();
resource.issueRefresh();
}
});
if (data != null) {
invertBtn.setSelection(data.invert);
}
Label label = new Label(group, SWT.NONE);
label.setText("Invert");
final Combo options = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
options.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
options.setItems(items);
if (data == null) {
options.setItems(resourceMap.keySet().toArray(
new String[resourceMap.size()]));
if (displayedResource == null) {
options.setText(DISABLED);
enable(group, false);
} else {
if (data.name == null) {
options.setText(DISABLED);
enable(cmapSlider, false);
} else {
options.setText(data.name);
}
options.setText(displayedResource.getDisplayName());
options.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (DISABLED.equals(options.getText())) {
enable(cmapSlider, false);
data.name = null;
} else {
enable(cmapSlider, true);
data.name = options.getText();
DisplayedChannelResource channelResource = resourceMap
.get(options.getText());
enable(cmapSlider, channelResource != null);
DisplayedChannelResource oldResource = resourceChannelMap
.put(channel, channelResource);
if (oldResource != null) {
oldResource.removeChannel(channel);
}
capability.capabilityChanged();
if (channelResource != null) {
channelResource.addChannel(channel);
// TODO: Update slider?
}
resource.issueRefresh();
}
});
}
@ -203,10 +218,37 @@ public class MultiChannelDialog extends CaveSWTDialog {
for (ColorMapSliderComp cmapSlider : sliderComps) {
cmapSlider.restore();
}
for (DisplayedChannelResource rsc : originalChannelMap.keySet()) {
rsc.setChannels(originalChannelMap.get(rsc));
}
close();
}
private void okPressed() {
close();
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.IDisposeListener#disposed(com.raytheon.uf
* .viz.core.rsc.AbstractVizResource)
*/
@Override
public void disposed(AbstractVizResource<?, ?> rsc) {
close();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed()
*/
@Override
protected void disposed() {
super.disposed();
resource.unregisterListener(this);
}
}

View file

@ -17,7 +17,10 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.ui.cmenu;
package com.raytheon.uf.viz.truecolor.ui;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
@ -25,14 +28,11 @@ import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IDisposeListener;
import com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability;
import com.raytheon.viz.ui.dialogs.MultiChannelDialog;
import com.raytheon.uf.viz.truecolor.rsc.TrueColorResourceGroup;
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
/**
* Right click action that opens a dialog for modifying resources with
* MultiChannelCapability
* TODO Add Description
*
* <pre>
*
@ -40,7 +40,7 @@ import com.raytheon.viz.ui.dialogs.MultiChannelDialog;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 3, 2012 mschenke Initial creation
* Aug 16, 2012 mschenke Initial creation
*
* </pre>
*
@ -48,7 +48,9 @@ import com.raytheon.viz.ui.dialogs.MultiChannelDialog;
* @version 1.0
*/
public class MultiChannelImagingAction extends AbstractRightClickAction {
public class TrueColorDialogAction extends AbstractRightClickAction {
private static Map<TrueColorResourceGroup, TrueColorDialog> dialogMap = new HashMap<TrueColorResourceGroup, TrueColorDialog>();
/*
* (non-Javadoc)
@ -57,7 +59,7 @@ public class MultiChannelImagingAction extends AbstractRightClickAction {
*/
@Override
public String getText() {
return "Channel Options...";
return "Composite Options...";
}
/*
@ -67,26 +69,22 @@ public class MultiChannelImagingAction extends AbstractRightClickAction {
*/
@Override
public void run() {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
final AbstractVizResource<?, ?> rsc = getSelectedRsc();
MultiChannelCapability cap = rsc
.getCapability(MultiChannelCapability.class);
final MultiChannelDialog dialog = new MultiChannelDialog(shell, rsc,
cap);
final IDisposeListener listener = new IDisposeListener() {
@Override
public void disposed(AbstractVizResource<?, ?> rsc) {
dialog.close();
}
};
rsc.registerListener(listener);
dialog.addListener(SWT.Dispose, new Listener() {
@Override
public void handleEvent(Event event) {
rsc.unregisterListener(listener);
}
});
TrueColorResourceGroup resource = (TrueColorResourceGroup) getSelectedRsc();
TrueColorDialog dialog = dialogMap.get(resource);
if (dialog == null) {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
dialog = new TrueColorDialog(shell, resource);
final TrueColorDialog toRemove = dialog;
dialogMap.put(resource, dialog);
dialog.addListener(SWT.Close, new Listener() {
@Override
public void handleEvent(Event event) {
dialogMap.remove(toRemove.resource);
}
});
}
dialog.open();
}
}

View file

@ -36,7 +36,7 @@ void main(void) {
}
} else {
float naturalValue = ((rawValue * (naturalMax - naturalMin)) + naturalMin);
index = capIndex(findIndex(naturalValue, cmapMin, cmapMax));
index = findIndex(naturalValue, cmapMin, cmapMax);
}
// Lookup color in colorMap for index

View file

@ -96,9 +96,9 @@ float findFloatIndexLog(float rawValue, float cmapMin, float cmapMax, int mirror
}
/**
* Given a raw data value linearly determine the index into cmapMin/cmapMax.
* Index is not capped and may be outsite of 0-1
* Given a raw data value linearly determine the index(0-1) into cmapMin/cmapMax
*/
float findIndex(float rawValue, float cmapMin, float cmapMax) {
return ((rawValue - cmapMin) / abs(cmapMax-cmapMin));
float index = ((rawValue - cmapMin) / abs(cmapMax-cmapMin));
return capIndex(index);
}

View file

@ -1,70 +0,0 @@
#include <colorUtil>
#include <indexing>
uniform float alpha;
uniform float brightness;
uniform float contrast;
uniform sampler2D rawTexR;
uniform float naturalMinR;
uniform float naturalMaxR;
uniform float cmapMinR;
uniform float cmapMaxR;
uniform int isFloatR;
uniform int invertR;
uniform int applyR;
uniform sampler2D rawTexG;
uniform float naturalMinG;
uniform float naturalMaxG;
uniform float cmapMinG;
uniform float cmapMaxG;
uniform int isFloatG;
uniform int invertG;
uniform int applyG;
uniform sampler2D rawTexB;
uniform float naturalMinB;
uniform float naturalMaxB;
uniform float cmapMinB;
uniform float cmapMaxB;
uniform int isFloatB;
uniform int invertB;
uniform int applyB;
float getIndex(sampler2D rawTex, float cmapMin, float cmapMax, float naturalMin, float naturalMax, int isFloat) {
vec4 textureValue = texture2D(rawTex, gl_TexCoord[0].st);
float naturalVal = textureValue.r;
if ( isFloat == 0 ) {
naturalVal = ((naturalVal * (naturalMax - naturalMin)) + naturalMin);
}
return findIndex(naturalVal, cmapMin, cmapMax);
}
void main(void) {
float r = 0.0;
float g = 0.0;
float b = 0.0;
if ( applyR != 0 ) {
r = getIndex(rawTexR, cmapMinR, cmapMaxR, naturalMinR, naturalMaxR, isFloatR);
if ( invertR != 0 ) {
r = 1.0 - r;
}
}
if ( applyG != 0 ) {
g = getIndex(rawTexG, cmapMinG, cmapMaxG, naturalMinG, naturalMaxG, isFloatG);
if ( invertG != 0 ) {
g = 1.0 - g;
}
}
if ( applyB != 0 ) {
b = getIndex(rawTexB, cmapMinB, cmapMaxB, naturalMinB, naturalMaxB, isFloatB);
if ( invertB != 0 ) {
b = 1.0 - b;
}
}
gl_FragColor = applyContrastAlphaBrightness(vec4(r,g,b,alpha), alpha, brightness, contrast);
}

View file

@ -53,9 +53,6 @@
<graphicsExtension
class="com.raytheon.viz.core.gl.internal.ext.GLDefaultImagingExtension">
</graphicsExtension>
<graphicsExtension
class="com.raytheon.viz.core.gl.internal.ext.GLMultiChannelImageExtension">
</graphicsExtension>
<graphicsExtension
class="com.raytheon.viz.core.gl.internal.ext.mosaic.GLMosaicImageExtension">
</graphicsExtension>

View file

@ -91,7 +91,7 @@ public abstract class AbstractGLImagingExtension extends
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
rval = drawRastersInternal(paintProps, images);
gl.glPolygonMode(GL.GL_BACK, GL.GL_LINE);
gl.glDisable(GL.GL_BLEND);
disableBlending(gl);
} finally {
target.popGLState();
}
@ -159,14 +159,7 @@ public abstract class AbstractGLImagingExtension extends
program.startShader();
}
gl.glTexEnvi(GL.GL_TEXTURE_ENV,
GL.GL_TEXTURE_ENV_MODE, GL.GL_ADD);
gl.glEnable(GL.GL_BLEND);
gl.glTexEnvi(GL.GL_TEXTURE_ENV,
GL.GL_TEXTURE_ENV_MODE, GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA,
GL.GL_ONE_MINUS_SRC_ALPHA);
enableBlending(gl);
gl.glColor4f(0.0f, 0.0f, 0.0f,
paintProps.getAlpha());
}
@ -311,6 +304,27 @@ public abstract class AbstractGLImagingExtension extends
return PaintStatus.ERROR;
}
/**
* Function to enable blending for images
*
* @param gl
*/
protected void enableBlending(GL gl) {
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_ADD);
gl.glEnable(GL.GL_BLEND);
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
}
/**
* Function to disable blending for images
*
* @param gl
*/
protected void disableBlending(GL gl) {
gl.glDisable(GL.GL_BLEND);
}
/**
* Setup anything that is required pre image rendering. Object returned is a
* state object and will be passed in to postImageRender. If the image

View file

@ -209,7 +209,10 @@ public class GLShaderProgram {
* @param value
*/
private void setUniformInternal(String uniformName, Object value) {
if (value instanceof Float) {
if (value instanceof Double) {
gl.glUniform1f(getUniformLocation(uniformName),
((Double) value).floatValue());
} else if (value instanceof Float) {
gl.glUniform1f(getUniformLocation(uniformName), (Float) value);
} else if (value instanceof Integer) {
gl.glUniform1i(getUniformLocation(uniformName), (Integer) value);

View file

@ -1,113 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.core.gl.images;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.ChannelData;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.IImageChannel;
import com.raytheon.viz.core.gl.internal.ext.GLMultiChannelImageExtension;
/**
* GL implementation of {@link IImageChannel}
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 9, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class GLImageChannel extends GLDelegateImage<GLColormappedImage>
implements IImageChannel {
private ChannelData channelData;
/**
* @param target
* @param image
* @param extensionClass
*/
public GLImageChannel(GLColormappedImage image, ChannelData channelData) {
super(image, GLMultiChannelImageExtension.class);
this.channelData = channelData;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.IColormappedImage#getColorMapParameters
* ()
*/
@Override
public ColorMapParameters getColorMapParameters() {
return image.getColorMapParameters();
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.IColormappedImage#setColorMapParameters
* (com.raytheon.uf.viz.core.drawables.ColorMapParameters)
*/
@Override
public void setColorMapParameters(ColorMapParameters params) {
image.setColorMapParameters(params);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getValue(int,
* int)
*/
@Override
public double getValue(int x, int y) {
return image.getValue(x, y);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension
* .IChannelImage#setInvert(boolean)
*/
@Override
public void setInverted(boolean inverted) {
channelData.invert = inverted;
}
/**
* @return the invert
*/
public boolean isInverted() {
return channelData.invert;
}
}

View file

@ -1,262 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.core.gl.images;
import java.util.Map;
import javax.media.opengl.GL;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.Channel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.IImageChannel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.IMultiChannelImage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.gl.IGLTarget;
import com.raytheon.viz.core.gl.internal.ext.GLMultiChannelImageExtension;
import com.sun.opengl.util.texture.TextureCoords;
/**
* GL implementation of a multi channel image
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 19, 2011 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class GLMultiChannelImage extends AbstractGLImage implements
IMultiChannelImage {
private Map<Channel, IImageChannel> channelMap;
/**
* @param target
* @param extensionClass
*/
public GLMultiChannelImage(IGLTarget target,
Map<Channel, IImageChannel> channelMap) {
super(GLMultiChannelImageExtension.class);
this.channelMap = channelMap;
}
/**
* Get the first IColormappedImage in the map
*
* @return first image in the map or null if none
*/
private IColormappedImage getFirstImage() {
if (channelMap != null) {
for (IColormappedImage image : channelMap.values()) {
if (image != null) {
return image;
}
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.images.AbstractGLImage#setInterpolated(boolean)
*/
@Override
public void setInterpolated(boolean isInterpolated) {
super.setInterpolated(isInterpolated);
for (IColormappedImage image : channelMap.values()) {
((AbstractGLImage) image).setInterpolated(isInterpolated);
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IImage#getWidth()
*/
@Override
public int getWidth() {
IColormappedImage image = getFirstImage();
if (image != null) {
return image.getWidth();
}
return 0;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IImage#getHeight()
*/
@Override
public int getHeight() {
IColormappedImage image = getFirstImage();
if (image != null) {
return image.getHeight();
}
return 0;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension
* .IMultiChannelImage#getImageMapping()
*/
@Override
public Map<Channel, IImageChannel> getImageMapping() {
return channelMap;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension
* .IMultiChannelImage#setImageMapping(java.util.Map)
*/
@Override
public void setImageMapping(Map<Channel, IImageChannel> mapping) {
this.channelMap = mapping;
// Set ourselves as unloaded since we are updating the mapping
setStatus(Status.UNLOADED);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getTextureCoords()
*/
@Override
public TextureCoords getTextureCoords() {
return new TextureCoords(0, 1, 1, 0);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getTextureid()
*/
@Override
public int getTextureid() {
// We do not have a single textureid specifically
return 0;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.images.AbstractGLImage#getTextureStorageType()
*/
@Override
public int getTextureStorageType() {
AbstractGLImage image = (AbstractGLImage) getFirstImage();
return image.getTextureStorageType();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#stage()
*/
@Override
public boolean stageTexture() throws VizException {
boolean rval = false;
if (channelMap.size() > 0) {
rval = true;
for (IColormappedImage image : channelMap.values()) {
AbstractGLImage glImage = (AbstractGLImage) image;
glImage.stage();
if (glImage.getStatus() == Status.FAILED) {
rval = false;
}
}
}
return rval;
}
@Override
public void loadTexture(GL gl) throws VizException {
if (channelMap.size() > 0) {
Status status = Status.LOADED;
for (IColormappedImage image : channelMap.values()) {
AbstractGLImage glImage = (AbstractGLImage) image;
glImage.loadTexture(gl);
if (glImage.getStatus() == Status.FAILED) {
status = Status.FAILED;
}
}
setStatus(status);
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#dispose()
*/
@Override
public void dispose() {
for (IColormappedImage image : channelMap.values()) {
((AbstractGLImage) image).dispose();
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#bind()
*/
@Override
public boolean bind(GL gl) {
return true;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#bind(int)
*/
@Override
public boolean bind(GL gl, int texture) {
return true;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#usaAsFrameBuffer()
*/
@Override
public void usaAsFrameBuffer() throws VizException {
throw new VizException(
"Using a GLMultiChannelImage as a frame buffer is not supported");
}
}

View file

@ -1,184 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.core.gl.internal.ext;
import java.util.Map;
import javax.media.opengl.GL;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.gl.glsl.AbstractGLSLImagingExtension;
import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
import com.raytheon.viz.core.gl.images.GLImageChannel;
import com.raytheon.viz.core.gl.images.GLMultiChannelImage;
/**
* GL implementation of {@link IMultiChannelImageExtension}
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 19, 2011 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class GLMultiChannelImageExtension extends AbstractGLSLImagingExtension
implements IMultiChannelImageExtension {
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension
* #constructImage(java.util.Map)
*/
@Override
public IMultiChannelImage constructImage(
Map<Channel, IImageChannel> imageMapping) throws VizException {
return new GLMultiChannelImage(target, imageMapping);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension
* #
* constructImage(com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback
* , com.raytheon.uf.viz.core.drawables.ColorMapParameters)
*/
@Override
public IImageChannel constructImage(
IColorMapDataRetrievalCallback callback, ChannelData channelData)
throws VizException {
return new GLImageChannel(target.getExtension(
GLColormappedImageExtension.class).initializeRaster(callback,
channelData.parameters), channelData);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.ext.AbstractGLImagingExtension#getShaderProgramName
* ()
*/
@Override
public String getShaderProgramName() {
return "multichannel";
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.ext.AbstractGLImagingExtension#loadShaderData
* (com.raytheon.viz.core.gl.glsl.GLShaderProgram,
* com.raytheon.uf.viz.core.drawables.IImage,
* com.raytheon.uf.viz.core.drawables.PaintProperties)
*/
@Override
public void loadShaderData(GLShaderProgram program, IImage image,
PaintProperties paintProps) throws VizException {
GLMultiChannelImage glImage = null;
if (image instanceof GLMultiChannelImage == false) {
throw new VizException(
"Cannot apply glsl multichannel shader to non gl multichannel image");
}
glImage = (GLMultiChannelImage) image;
Map<Channel, IImageChannel> channelMap = glImage.getImageMapping();
program.setUniform("brightness", glImage.getBrightness());
program.setUniform("contrast", glImage.getContrast());
program.setUniform("alpha", paintProps.getAlpha());
for (Channel c : Channel.values()) {
String suffix = "";
int texture = -1;
int texNum = -1;
switch (c) {
case RED:
suffix = "R";
texture = GL.GL_TEXTURE0;
texNum = 0;
break;
case GREEN:
suffix = "G";
texture = GL.GL_TEXTURE1;
texNum = 1;
break;
case BLUE:
suffix = "B";
texture = GL.GL_TEXTURE2;
texNum = 2;
break;
}
boolean applied = false;
IColormappedImage ci = channelMap.get(c);
if (ci != null) {
if (ci instanceof GLImageChannel == false) {
throw new VizException(
"Cannot apply glsl multichannel shader to non gl colormapped image");
}
GLImageChannel glCMImage = (GLImageChannel) ci;
if (glCMImage.bind(target.getGl(), texture)) {
int textureType = glCMImage.getWrappedImage()
.getTextureType();
ColorMapParameters colorMapParameters = ci
.getColorMapParameters();
program.setUniform("rawTex" + suffix, texNum);
program.setUniform("naturalMin" + suffix,
colorMapParameters.getDataMin());
program.setUniform("naturalMax" + suffix,
colorMapParameters.getDataMax());
program.setUniform("cmapMin" + suffix,
colorMapParameters.getColorMapMin());
program.setUniform("cmapMax" + suffix,
colorMapParameters.getColorMapMax());
program.setUniform("isFloat" + suffix,
textureType == GL.GL_FLOAT
|| textureType == GL.GL_HALF_FLOAT_ARB ? 1
: 0);
program.setUniform("invert" + suffix,
glCMImage.isInverted());
applied = true;
}
}
program.setUniform("apply" + suffix, applied ? 1 : 0);
}
}
}

View file

@ -31,11 +31,6 @@
class="com.raytheon.viz.satellite.rsc.SatBlendedResource"
name="satBlendedResource"
renderingOrderId="IMAGE_COUNTRY"/>
<resource
class="com.raytheon.viz.satellite.rsc.SatTrueColorResource"
name="Satellite True Color"
renderingOrderId="IMAGE_COUNTRY"
resourceType="PLAN_VIEW"/>
</extension>
<extension
point="com.raytheon.uf.viz.core.scriptTemplate">

View file

@ -1,489 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.satellite.rsc;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.geotools.coverage.grid.GridGeometry2D;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.HDF5Util;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.RasterMode;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.RecordFactory;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IColorMapParametersListener;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.IRenderable;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.Channel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.ChannelData;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.IImageChannel;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IMultiChannelImageExtension.IMultiChannelImage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
import com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability;
import com.raytheon.uf.viz.core.rsc.hdf5.ImageTile;
import com.vividsolutions.jts.geom.Coordinate;
/**
* True color satellite resource
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class SatTrueColorResource
extends
AbstractPluginDataObjectResource<SatTrueColorResourceData, IMapDescriptor>
implements IColorMapParametersListener {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(SatTrueColorResource.class);
private static final String NAME = "Sat True Color";
private static class SatelliteDataRetriever implements
IColorMapDataRetrievalCallback {
private SatelliteRecord record;
private boolean signed;
public SatelliteDataRetriever(SatelliteRecord record, boolean signed) {
this.record = record;
this.signed = signed;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback#
* getColorMapData()
*/
@Override
public ColorMapData getColorMapData() throws VizException {
ColorMapDataType dataType = signed ? ColorMapDataType.SIGNED_BYTE
: ColorMapDataType.BYTE;
IDataStore ds = DataStoreFactory.getDataStore(HDF5Util
.findHDF5Location(record));
try {
ISpatialObject so = record.getSpatialObject();
ByteBuffer bb = ByteBuffer.wrap(((ByteDataRecord) ds.retrieve(
record.getDataURI(), "Data", Request.ALL))
.getByteData());
return new ColorMapData(bb,
new int[] { so.getNx(), so.getNy() }, dataType);
} catch (Exception e) {
throw new VizException("Error requesting record data", e);
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((record == null) ? 0 : record.hashCode());
result = prime * result + (signed ? 1231 : 1237);
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SatelliteDataRetriever other = (SatelliteDataRetriever) obj;
if (record == null) {
if (other.record != null)
return false;
} else if (!record.equals(other.record))
return false;
if (signed != other.signed)
return false;
return true;
}
}
private class SatTrueColorRenderable implements IRenderable {
private SatelliteRecord baseRecord;
private IMultiChannelImage image;
private ImageTile tile;
private Map<String, SatelliteDataRetriever> recordMap = new HashMap<String, SatelliteDataRetriever>();
public SatTrueColorRenderable(SatelliteRecord[] records)
throws VizException {
for (SatelliteRecord record : records) {
addRecord(record);
}
image = multiExt
.constructImage(createImageMapping(this,
getCapability(MultiChannelCapability.class)
.getChannelMap()));
ImagingCapability ic = getCapability(ImagingCapability.class);
image.setBrightness(ic.getBrightness());
image.setContrast(ic.getContrast());
image.setInterpolated(ic.isInterpolationState());
}
public void addRecord(SatelliteRecord record) throws VizException {
if (tile == null) {
baseRecord = record;
tile = constructCoverage(record);
}
Map<String, Object> mapping = RecordFactory.getInstance()
.loadMapFromUri(record.getDataURI());
String key = String.valueOf(mapping.get(resourceData
.getUniqueField()));
recordMap.put(key, new SatelliteDataRetriever(record, false));
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.drawables.IRenderable#paint(com.raytheon
* .uf.viz.core.IGraphicsTarget,
* com.raytheon.uf.viz.core.drawables.PaintProperties)
*/
@Override
public void paint(IGraphicsTarget target, PaintProperties paintProps)
throws VizException {
target.drawRasters(paintProps, new DrawableImage(image,
tile.coverage, RasterMode.ASYNCHRONOUS));
}
public void dispose() {
if (image != null) {
image.dispose();
image = null;
}
if (tile != null) {
tile.dispose();
tile = null;
}
recordMap.clear();
baseRecord = null;
}
}
private IMultiChannelImageExtension multiExt;
private IMapMeshExtension meshExt;
/**
* @param resourceData
* @param loadProperties
*/
protected SatTrueColorResource(SatTrueColorResourceData resourceData,
LoadProperties loadProperties, Collection<SatelliteRecord> records) {
super(resourceData, loadProperties);
String[] rgb = resourceData.getRedGreenBlue();
MultiChannelCapability mcc = getCapability(MultiChannelCapability.class);
mcc.setNames(rgb);
Map<Channel, ChannelData> channelMap = mcc.getChannelMap();
// Process new entries
Channel[] channels = Channel.values();
for (int i = 0; i < channels.length; ++i) {
Channel c = channels[i];
ChannelData cd = channelMap.get(c);
if (cd == null) {
cd = new ChannelData(i < rgb.length ? rgb[i] : null,
newParams(), false);
channelMap.put(c, cd);
} else {
if (cd.name == null) {
cd.name = i < rgb.length ? rgb[i] : null;
}
if (cd.parameters == null) {
cd.parameters = newParams();
}
}
cd.parameters.addListener(this);
}
getCapability(ImagingCapability.class);
resourceData.fireChangeListeners(ChangeType.DATA_UPDATE,
records.toArray(new SatelliteRecord[records.size()]));
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal(com.raytheon
* .uf.viz.core.IGraphicsTarget)
*/
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
// Grab extensions that will be used
multiExt = target.getExtension(IMultiChannelImageExtension.class);
meshExt = target.getExtension(IMapMeshExtension.class);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getName()
*/
@Override
public String getName() {
Map<Channel, ChannelData> channelMap = getCapability(
MultiChannelCapability.class).getChannelMap();
String components = "";
if (channelMap != null) {
int i = 0;
for (Channel c : Channel.values()) {
ChannelData cd = channelMap.get(c);
if (cd != null && cd.name != null) {
if (i > 0) {
components += ",";
}
components += c.name().charAt(0);
++i;
}
}
}
return NAME + " (" + components + ")";
}
/**
* @param record
* @return
*/
private ImageTile constructCoverage(SatelliteRecord record)
throws VizException {
GridGeometry2D geom = MapUtil
.getGridGeometry(record.getSpatialObject());
ImageTile tile = new ImageTile();
tile.setGridGeometry(geom);
tile.coverage = new PixelCoverage(new Coordinate(), 0, 0);
tile.coverage.setMesh(meshExt.constructMesh(geom, descriptor));
return tile;
}
private Map<Channel, IImageChannel> createImageMapping(
SatTrueColorRenderable renderable,
Map<Channel, ChannelData> channelMap) {
Map<Channel, IImageChannel> newMapping = new HashMap<Channel, IImageChannel>();
for (Entry<Channel, ChannelData> entry : channelMap.entrySet()) {
IColorMapDataRetrievalCallback callback = renderable.recordMap
.get(entry.getValue().name);
if (callback != null) {
try {
IImageChannel imageChannel = multiExt.constructImage(
callback, entry.getValue());
newMapping.put(entry.getKey(), imageChannel);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
}
return newMapping;
}
private ColorMapParameters newParams() {
ColorMapParameters params = new ColorMapParameters();
params.setDataMin(0);
params.setDataMax(255);
params.setColorMapMin(0);
params.setColorMapMax(255);
return params;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource#
* capabilityChanged(com.raytheon.uf.viz.core.drawables.IRenderable,
* com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability)
*/
@Override
protected void capabilityChanged(IRenderable renderable,
AbstractCapability capability) {
SatTrueColorRenderable stcr = (SatTrueColorRenderable) renderable;
if (stcr.image != null) {
if (capability instanceof ImagingCapability) {
ImagingCapability ic = (ImagingCapability) capability;
stcr.image.setBrightness(ic.getBrightness());
stcr.image.setContrast(ic.getContrast());
stcr.image.setInterpolated(ic.isInterpolationState());
} else if (capability instanceof MultiChannelCapability) {
MultiChannelCapability mcc = (MultiChannelCapability) capability;
final Map<Channel, IImageChannel> currMapping = stcr.image
.getImageMapping();
stcr.image.setImageMapping(createImageMapping(stcr,
mcc.getChannelMap()));
// Dispose old mapping
VizApp.runAsync(new Runnable() {
@Override
public void run() {
for (IColormappedImage img : currMapping.values()) {
if (img != null) {
img.dispose();
}
}
}
});
}
issueRefresh();
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource#
* disposeRenderable(com.raytheon.uf.viz.core.drawables.IRenderable)
*/
@Override
protected void disposeRenderable(IRenderable renderable) {
((SatTrueColorRenderable) renderable).dispose();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource#
* projectRenderable(com.raytheon.uf.viz.core.drawables.IRenderable,
* org.opengis.referencing.crs.CoordinateReferenceSystem)
*/
@Override
protected boolean projectRenderable(IRenderable renderable,
CoordinateReferenceSystem crs) throws VizException {
SatTrueColorRenderable stcr = (SatTrueColorRenderable) renderable;
ImageTile newTile = constructCoverage(stcr.baseRecord);
ImageTile oldTile = stcr.tile;
stcr.tile = newTile;
if (oldTile != null) {
oldTile.dispose();
}
return true;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource#
* constructRenderable(java.util.List)
*/
@Override
protected IRenderable constructRenderable(List<PluginDataObject> records)
throws VizException {
SatelliteRecord[] satRecords = new SatelliteRecord[records.size()];
for (int i = 0; i < satRecords.length; ++i) {
satRecords[i] = (SatelliteRecord) records.get(i);
}
return new SatTrueColorRenderable(satRecords);
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractPluginDataObjectResource#
* updateRenderable(com.raytheon.uf.viz.core.drawables.IRenderable,
* com.raytheon.uf.common.dataplugin.PluginDataObject)
*/
@Override
protected boolean updateRenderable(IRenderable renderable,
PluginDataObject pdo) {
try {
SatTrueColorRenderable stcr = (SatTrueColorRenderable) renderable;
stcr.addRecord((SatelliteRecord) pdo);
capabilityChanged(stcr, getCapability(MultiChannelCapability.class));
return true;
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM,
"Error updating satellite renderable with new data", e);
}
return false;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColorMapParametersListener#
* colorMapChanged()
*/
@Override
public void colorMapChanged() {
issueRefresh();
}
}

View file

@ -1,134 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.satellite.rsc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
/**
* Satellite true color resource data. The field used to differentiate
* red/green/blue bands should not be added to the resource data's metadata map.
* The resource data itself will do that by adding an IN entry for the unique
* field for each item in redGreenBlue object
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@XmlAccessorType(XmlAccessType.NONE)
public class SatTrueColorResourceData extends AbstractRequestableResourceData {
@XmlElement
private String uniqueField;
@XmlElement
private String[] redGreenBlue;
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData#
* constructResource(com.raytheon.uf.viz.core.rsc.LoadProperties,
* com.raytheon.uf.common.dataplugin.PluginDataObject[])
*/
@Override
protected AbstractVizResource<?, ?> constructResource(
LoadProperties loadProperties, PluginDataObject[] objects)
throws VizException {
List<SatelliteRecord> records = new ArrayList<SatelliteRecord>(
objects.length);
for (PluginDataObject pdo : objects) {
records.add((SatelliteRecord) pdo);
}
return new SatTrueColorResource(this, loadProperties, records);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData#getMetadataMap
* ()
*/
@Override
public HashMap<String, RequestConstraint> getMetadataMap() {
HashMap<String, RequestConstraint> mdm = new HashMap<String, RequestConstraint>(
super.getMetadataMap());
RequestConstraint constraint = new RequestConstraint("",
ConstraintType.IN);
constraint.setConstraintValueList(redGreenBlue);
mdm.put(uniqueField, constraint);
return mdm;
}
/**
* @return the uniqueField
*/
public String getUniqueField() {
return uniqueField;
}
/**
* @param uniqueField
* the uniqueField to set
*/
public void setUniqueField(String uniqueField) {
this.uniqueField = uniqueField;
}
/**
* @return the redGreenBlue
*/
public String[] getRedGreenBlue() {
return redGreenBlue;
}
/**
* @param redGreenBlue
* the redGreenBlue to set
*/
public void setRedGreenBlue(String[] redGreenBlue) {
this.redGreenBlue = redGreenBlue;
}
}

View file

@ -64,11 +64,6 @@
name="ColorEditDialog"
sortID="20">
</contextualMenu>
<contextualMenu
actionClass="com.raytheon.viz.ui.cmenu.MultiChannelImagingAction"
capabilityClass="com.raytheon.uf.viz.core.rsc.capabilities.MultiChannelCapability"
name="MultiChannelImaging"
sortID="25"/>
<contextualMenu
actionClass="com.raytheon.viz.ui.cmenu.RightClickSeparator"
name="100-------------"