support multiple GL plots in a figure

This commit is contained in:
wyq 2022-08-23 22:59:15 +08:00
parent 92a17067af
commit 1aab89e515
19 changed files with 8268 additions and 143 deletions

View File

@ -1,13 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-math4-legacy-core:4.0-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-20220805.195458-437.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-20220805.195458-437-javadoc.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-20220805.195458-437-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math4-legacy-core/4.0-SNAPSHOT/commons-math4-legacy-core-4.0-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -100,7 +100,7 @@
<artifactId>freehep-graphicsio-ps</artifactId>
<version>2.4</version>
</dependency>
<!--<dependency>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
<version>2.3.2</version>
@ -109,8 +109,8 @@
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
<version>2.3.2</version>
</dependency>-->
<dependency>
</dependency>
<!--<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all</artifactId>
<version>v2.4.0-rc4</version>
@ -158,7 +158,7 @@
<version>v2.4.0-rc4</version>
</dependency>
<!-- GLUEGEN -->
&lt;!&ndash; GLUEGEN &ndash;&gt;
<dependency>
@ -212,7 +212,7 @@
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-natives-windows-i586</artifactId>
<version>v2.4.0-rc4</version>
</dependency>
</dependency>-->
<dependency>
<groupId>org.joml</groupId>
<artifactId>joml</artifactId>

View File

@ -21,6 +21,8 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.meteoinfo.chart.jogl.Plot3DGL;
import org.meteoinfo.chart.plot.MapPlot;
import org.meteoinfo.chart.plot.Plot;
import org.meteoinfo.common.PointF;
@ -34,7 +36,7 @@ import org.meteoinfo.geo.drawing.Draw;
public class Chart {
// <editor-fold desc="Variables">
private List<Plot> plots;
protected List<Plot> plots;
private int currentPlot;
private int rowNum;
private int columnNum;
@ -424,6 +426,21 @@ public class Chart {
// </editor-fold>
// <editor-fold desc="Methods">
/**
* Whether contains 3D GL plot
* @return Boolean
*/
public boolean contains3DGLPlot() {
for (Plot plot : this.plots) {
if (plot instanceof Plot3DGL) {
return true;
}
}
return false;
}
/**
* Draw plot
*
@ -456,7 +473,7 @@ public class Chart {
g.translate(area.getX(), area.getY());
//Draw background
if (this.background != null) {
if (this.background != null && !contains3DGLPlot()) {
g.setColor(background);
g.fill(new Rectangle2D.Double(0, 0, area.getWidth(), area.getHeight()));
}
@ -508,8 +525,12 @@ public class Chart {
if (plot instanceof MapPlot) {
((MapPlot) plot).setAntialias(this.antiAlias);
}
//plot.draw(g, plotArea);
plot.draw(g, area);
if (plot instanceof Plot3DGL) {
Rectangle2D graphArea = plot.getPositionArea();
plot.setGraphArea(graphArea);
} else {
plot.draw(g, area);
}
}
}
@ -868,11 +889,8 @@ public class Chart {
* @param plot Plot
*/
public void setPlot(Plot plot) {
if (plot instanceof MapPlot) {
((MapPlot) plot).setParent(parent);
}
this.plots.clear();
this.plots.add(plot);
clearPlots();
addPlot(plot);
}
/**

View File

@ -78,6 +78,8 @@ import org.freehep.graphics2d.VectorGraphics;
import org.freehep.graphicsio.emf.EMFGraphics2D;
import org.freehep.graphicsio.pdf.PDFGraphics2D;
import org.freehep.graphicsio.ps.PSGraphics2D;
import org.meteoinfo.chart.jogl.EarthPlot3D;
import org.meteoinfo.chart.jogl.Plot3DGL;
import org.meteoinfo.chart.plot.MapPlot;
import org.meteoinfo.chart.plot.Plot;
import org.meteoinfo.chart.plot.XY1DPlot;
@ -86,6 +88,7 @@ import org.meteoinfo.chart.plot.Plot3D;
import org.meteoinfo.chart.plot.PlotType;
import org.meteoinfo.chart.plot3d.Projector;
import org.meteoinfo.common.Extent;
import org.meteoinfo.common.Extent3D;
import org.meteoinfo.common.GenericFileFilter;
import org.meteoinfo.common.PointF;
import org.meteoinfo.data.mapdata.webmap.TileLoadListener;
@ -782,97 +785,185 @@ public class ChartPanel extends JPanel implements IChartPanel{
this.dragMode = true;
int x = e.getX();
int y = e.getY();
Plot plot = selPlot(this.mouseDownPoint.x, this.mouseDownPoint.y);
switch (this.mouseMode) {
case ZOOM_IN:
case SELECT:
this.repaintOld();
if (plot instanceof Plot3DGL) {
this.repaint();
} else {
this.repaintOld();
}
break;
case PAN:
Plot plot = selPlot(e.getX(), e.getY());
if (plot != null) {
Graphics2D g = (Graphics2D) this.getGraphics();
Rectangle2D mapRect = plot.getGraphArea();
g.setClip(mapRect);
g.setColor(Color.white);
int aX = e.getX() - mouseDownPoint.x;
int aY = e.getY() - mouseDownPoint.y;
if (aX > 0) {
if (mapRect.getX() >= 0) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY(), aX, (int) mapRect.getHeight());
} else {
g.fillRect(0, (int) mapRect.getY(), aX, (int) mapRect.getHeight());
if (plot instanceof Plot3DGL) {
Plot3DGL plot3DGL = (Plot3DGL) plot;
Dimension size = e.getComponent().getSize();
float dx = (float) (x - this.mouseLastPos.x) / size.width;
float dy = (float) (this.mouseLastPos.y - y) / size.height;
Extent3D extent = plot3DGL.getDrawExtent();
float rotation = plot3DGL.getAngleY();
if (rotation < 90 || rotation > 270) {
dx = -dx;
dy = -dy;
}
} else if (mapRect.getX() <= this.getWidth()) {
g.fillRect((int) (mapRect.getX() + mapRect.getWidth() + aX), (int) mapRect.getY(), Math.abs(aX), (int) mapRect.getHeight());
extent = extent.shift(extent.getWidth() * dx, extent.getHeight() * dy, 0);
plot3DGL.setDrawExtent(extent);
this.repaint();
} else {
g.fillRect(this.getWidth() + aX, (int) mapRect.getY(), Math.abs(aX), (int) mapRect.getHeight());
}
if (aY > 0) {
if (mapRect.getY() >= 0) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY(), (int) mapRect.getWidth(), aY);
Graphics2D g = (Graphics2D) this.getGraphics();
Rectangle2D mapRect = plot.getGraphArea();
g.setClip(mapRect);
g.setColor(Color.white);
int aX = e.getX() - mouseDownPoint.x;
int aY = e.getY() - mouseDownPoint.y;
if (aX > 0) {
if (mapRect.getX() >= 0) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY(), aX, (int) mapRect.getHeight());
} else {
g.fillRect(0, (int) mapRect.getY(), aX, (int) mapRect.getHeight());
}
} else if (mapRect.getX() <= this.getWidth()) {
g.fillRect((int) (mapRect.getX() + mapRect.getWidth() + aX), (int) mapRect.getY(), Math.abs(aX), (int) mapRect.getHeight());
} else {
g.fillRect((int) mapRect.getX(), 0, (int) mapRect.getWidth(), aY);
g.fillRect(this.getWidth() + aX, (int) mapRect.getY(), Math.abs(aX), (int) mapRect.getHeight());
}
} else if (mapRect.getY() + mapRect.getHeight() <= this.getX() + this.getHeight()) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY() + (int) mapRect.getHeight() + aY, (int) mapRect.getWidth(), Math.abs(aY));
} else {
g.fillRect((int) mapRect.getX(), this.getY() + this.getHeight() + aY, (int) mapRect.getWidth(), Math.abs(aY));
if (aY > 0) {
if (mapRect.getY() >= 0) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY(), (int) mapRect.getWidth(), aY);
} else {
g.fillRect((int) mapRect.getX(), 0, (int) mapRect.getWidth(), aY);
}
} else if (mapRect.getY() + mapRect.getHeight() <= this.getX() + this.getHeight()) {
g.fillRect((int) mapRect.getX(), (int) mapRect.getY() + (int) mapRect.getHeight() + aY, (int) mapRect.getWidth(), Math.abs(aY));
} else {
g.fillRect((int) mapRect.getX(), this.getY() + this.getHeight() + aY, (int) mapRect.getWidth(), Math.abs(aY));
}
int startX = (int) mapRect.getX() + aX;
int startY = (int) mapRect.getY() + aY;
g.drawImage(tempImage, startX, startY, this);
g.setColor(this.getForeground());
g.draw(mapRect);
}
int startX = (int) mapRect.getX() + aX;
int startY = (int) mapRect.getY() + aY;
g.drawImage(tempImage, startX, startY, this);
g.setColor(this.getForeground());
g.draw(mapRect);
}
break;
case ROTATE:
plot = selPlot(this.mouseDownPoint.x, this.mouseDownPoint.y);
if (plot != null && plot.getPlotType() == PlotType.XYZ) {
Plot3D plot3d = (Plot3D) plot;
Projector projector = plot3d.getProjector();
float new_value = 0.0f;
// if (!thread.isAlive() || !data_available) {
if (e.isControlDown()) {
projector.set2D_xTranslation(projector.get2D_xTranslation() + (x - this.mouseLastPos.x));
projector.set2D_yTranslation(projector.get2D_yTranslation() + (y - this.mouseLastPos.y));
} else if (e.isShiftDown()) {
new_value = projector.getY2DScaling() + (y - this.mouseLastPos.y) * 0.5f;
if (new_value > 60.0f) {
new_value = 60.0f;
if (plot != null) {
if (plot instanceof Plot3D) {
Plot3D plot3d = (Plot3D) plot;
Projector projector = plot3d.getProjector();
float new_value = 0.0f;
// if (!thread.isAlive() || !data_available) {
if (e.isControlDown()) {
projector.set2D_xTranslation(projector.get2D_xTranslation() + (x - this.mouseLastPos.x));
projector.set2D_yTranslation(projector.get2D_yTranslation() + (y - this.mouseLastPos.y));
} else if (e.isShiftDown()) {
new_value = projector.getY2DScaling() + (y - this.mouseLastPos.y) * 0.5f;
if (new_value > 60.0f) {
new_value = 60.0f;
}
if (new_value < 2.0f) {
new_value = 2.0f;
}
projector.set2DScaling(new_value);
} else {
new_value = projector.getRotationAngle() + (x - this.mouseLastPos.x);
while (new_value > 360) {
new_value -= 360;
}
while (new_value < 0) {
new_value += 360;
}
projector.setRotationAngle(new_value);
new_value = projector.getElevationAngle() + (y - this.mouseLastPos.y);
if (new_value > 90) {
new_value = 90;
} else if (new_value < 0) {
new_value = 0;
}
projector.setElevationAngle(new_value);
}
if (new_value < 2.0f) {
new_value = 2.0f;
this.repaintNew();
} else if (plot instanceof Plot3DGL) {
Plot3DGL plot3DGL = (Plot3DGL) plot;
if (SwingUtilities.isLeftMouseButton(e)) {
if (e.isShiftDown()) {
Dimension size = e.getComponent().getSize();
float dx = (float) (x - this.mouseLastPos.x) / size.width;
float dy = (float) (this.mouseLastPos.y - y) / size.height;
Extent3D extent = plot3DGL.getDrawExtent();
float rotation = plot3DGL.getAngleY();
if (rotation < 90 || rotation > 270) {
dx = -dx;
dy = -dy;
}
extent = extent.shift(extent.getWidth() * dx, extent.getHeight() * dy, 0);
plot3DGL.setDrawExtent(extent);
} else {
Dimension size = e.getComponent().getSize();
float thetaY = 360.0f * ((float) (x - this.mouseLastPos.x) / size.width);
float thetaX = 180.0f * ((float) (this.mouseLastPos.y - y) / size.height);
if (plot3DGL instanceof EarthPlot3D) {
float scale = plot3DGL.getScale();
thetaY /= scale;
thetaX /= scale;
}
float elevation = plot3DGL.getAngleX() - thetaX;
if (elevation > 0) {
elevation = 0;
}
if (elevation < -180) {
elevation = -180;
}
plot3DGL.setAngleX(elevation);
float rotation = plot3DGL.getAngleY() + thetaY;
if (rotation >= 360) {
rotation -= 360;
}
if (rotation < 0) {
rotation += 360;
}
plot3DGL.setAngleY(rotation);
}
this.repaint();
} else if (SwingUtilities.isRightMouseButton(e)) {
Dimension size = e.getComponent().getSize();
float shift = 360.0f * ((float) (this.mouseLastPos.x - x) / size.width);
if (plot3DGL instanceof EarthPlot3D) {
float scale = plot3DGL.getScale();
shift /= -scale;
}
float head = plot3DGL.getHeadAngle() - shift;
if (head >= 360) {
head -= 360;
} else if (head < 0) {
head += 360;
}
if (head < 1)
head = 0;
else if (head > 359)
head = 0;
plot3DGL.setHeadAngle(head);
if (plot3DGL instanceof EarthPlot3D) {
shift = 180.0f * ((float) (this.mouseLastPos.y - y) / size.height);
float pitch = plot3DGL.getPitchAngle() + shift;
if (pitch > 0) {
pitch = 0;
}
if (pitch < -90) {
pitch = -90;
}
plot3DGL.setPitchAngle(pitch);
}
this.repaint();
}
projector.set2DScaling(new_value);
} else {
new_value = projector.getRotationAngle() + (x - this.mouseLastPos.x);
while (new_value > 360) {
new_value -= 360;
}
while (new_value < 0) {
new_value += 360;
}
projector.setRotationAngle(new_value);
new_value = projector.getElevationAngle() + (y - this.mouseLastPos.y);
if (new_value > 90) {
new_value = 90;
} else if (new_value < 0) {
new_value = 0;
}
projector.setElevationAngle(new_value);
}
this.repaintNew();
//this.paintGraphics();
// if (!model.isExpectDelay()) {
// repaint();
// } else {
// if (!dragged) {
// is_data_available = data_available;
// dragged = true;
// }
// data_available = false;
// repaint();
// }
}
break;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,545 @@
package org.meteoinfo.chart.jogl;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
import org.apache.commons.imaging.ImageReadException;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.meteoinfo.chart.ChartColorBar;
import org.meteoinfo.chart.ChartText;
import org.meteoinfo.chart.ChartText3D;
import org.meteoinfo.chart.graphic.GraphicFactory;
import org.meteoinfo.chart.graphic.MeshGraphic;
import org.meteoinfo.common.*;
import org.meteoinfo.geo.legend.LegendManage;
import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.geometry.legend.LegendScheme;
import org.meteoinfo.geometry.legend.PolygonBreak;
import org.meteoinfo.geometry.shape.Shape;
import org.meteoinfo.geometry.shape.ShapeTypes;
import org.meteoinfo.image.ImageUtil;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.math.ArrayUtil;
import org.meteoinfo.projection.KnownCoordinateSystems;
import org.meteoinfo.projection.ProjectionInfo;
import org.meteoinfo.projection.ProjectionUtil;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
public class EarthGLPlot extends GLPlot {
// <editor-fold desc="Variables">
private float radius = 6371.f;
private MeshGraphic surface;
private Extent3D dataExtent;
// </editor-fold>
// <editor-fold desc="Constructor">
/**
* Constructor
*/
public EarthGLPlot() {
super();
this.projInfo = KnownCoordinateSystems.geographic.world.WGS1984;
//earthSurface(50);
//addGraphic(this.surface);
}
/**
* Initialize angles
*/
public void initAngles() {
this.angleX = -45.f;
this.angleY = 160.f;
this.headAngle = 0.f;
this.pitchAngle = 0.f;
}
// </editor-fold>
// <editor-fold desc="GetSet">
/**
* Get earth radius
* @return Earth radius
*/
public float getRadius() {
return this.radius;
}
/**
* Set earth radius
* @param value Earth radius
*/
public void setRadius(float value) {
this.radius = value;
}
@Override
public void setDrawExtent(Extent3D value) {
this.drawExtent = value;
this.transform.setExtent(this.drawExtent);
}
// </editor-fold>
// <editor-fold desc="Method">
void updateDataExtent() {
xAxis.setMinMaxValue(dataExtent.minX, dataExtent.maxX);
yAxis.setMinMaxValue(dataExtent.minY, dataExtent.maxY);
zAxis.setMinMaxValue(dataExtent.minZ, dataExtent.maxZ);
}
/**
* Add a graphic
* @param graphic The graphic
*/
@Override
public void addGraphic(Graphic graphic) {
if (this.dataExtent == null) {
this.dataExtent = (Extent3D) graphic.getExtent();
} else {
this.dataExtent = this.dataExtent.union((Extent3D) graphic.getExtent());
}
updateDataExtent();
this.graphics.add(SphericalTransform.transform(graphic));
Extent ex = this.graphics.getExtent();
if (!ex.is3D()) {
ex = ex.to3D();
}
this.graphicExtent = (Extent3D) ex;
this.setDrawExtent((Extent3D) this.graphicExtent.clone());
}
/**
* Add a graphic
*
* @param index The index
* @param graphic The graphic
*/
@Override
public void addGraphic(int index, Graphic graphic) {
if (this.dataExtent == null) {
this.dataExtent = (Extent3D) graphic.getExtent();
} else {
this.dataExtent = this.dataExtent.union((Extent3D) graphic.getExtent());
}
updateDataExtent();
this.graphics.add(index, SphericalTransform.transform(graphic));
Extent ex = this.graphics.getExtent();
if (!ex.is3D()) {
ex = ex.to3D();
}
this.graphicExtent = (Extent3D) ex;
this.setDrawExtent((Extent3D) this.graphicExtent.clone());
}
/**
* Add a graphic
*
* @param graphic The graphic
* @param proj The graphic projection
*/
@Override
public void addGraphic(Graphic graphic, ProjectionInfo proj) {
if (! proj.equals(this.projInfo)) {
Graphic nGraphic = ProjectionUtil.projectGraphic(graphic, proj, this.projInfo);
addGraphic(nGraphic);
} else {
addGraphic(graphic);
}
}
/**
* Add a graphic
*
* @param index The index
* @param graphic The graphic
* @param proj The graphic projection
*/
@Override
public void addGraphic(int index, Graphic graphic, ProjectionInfo proj) {
if (! proj.equals(this.projInfo)) {
Graphic nGraphic = ProjectionUtil.projectGraphic(graphic, proj, this.projInfo);
addGraphic(index, nGraphic);
} else {
addGraphic(index, graphic);
}
}
/**
* Set earth surface
* @param n The sphere has n*n faces
*/
public MeshGraphic earthSurface(int n) {
Array lon = ArrayUtil.lineSpace(-180.f, 180.f, n + 1, true);
Array lat = ArrayUtil.lineSpace(-90.f, 90.f, n + 1, true);
lat = lat.flip(0).copy();
Array[] lonlat = ArrayUtil.meshgrid(lon, lat);
lon = lonlat[0];
lat = lonlat[1];
Array alt = ArrayUtil.zeros(lon.getShape(), DataType.FLOAT);
LegendScheme ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POLYGON, Color.cyan, 1);
((PolygonBreak) ls.getLegendBreak(0)).setDrawOutline(false);
((PolygonBreak) ls.getLegendBreak(0)).setOutlineColor(Color.white);
surface = GraphicFactory.surface(lon, lat, alt, ls);
return surface;
}
/**
* Set earth image
* @param imageFile
* @throws IOException
* @throws ImageReadException
*/
public void earthImage(String imageFile) throws IOException, ImageReadException {
BufferedImage image = ImageUtil.imageLoad(imageFile);
if (this.surface == null) {
this.earthSurface(50);
this.addGraphic(this.surface);
}
this.surface.setImage(image);
}
@Override
public void display(GLAutoDrawable drawable) {
final GL2 gl = drawable.getGL().getGL2();
float[] rgba = this.background.getRGBComponents(null);
gl.glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
this.lighting.setPosition(gl);
gl.glPushMatrix();
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glEnable(GL2.GL_BLEND);
gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE_MINUS_SRC_ALPHA);
//gl.glBlendFunc(GL2.GL_SRC_ALPHA, GL2.GL_ONE);
if (this.antialias) {
if (this.sampleBuffers)
gl.glEnable(GL2.GL_MULTISAMPLE);
else {
gl.glEnable(GL2.GL_LINE_SMOOTH);
gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_NICEST);
gl.glEnable(GL2.GL_POINT_SMOOTH);
gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_NICEST);
//gl.glEnable(GL2.GL_POLYGON_SMOOTH);
//gl.glHint(GL2.GL_POLYGON_SMOOTH_HINT, GL2.GL_NICEST);
}
} else {
if (this.sampleBuffers)
gl.glDisable(GL2.GL_MULTISAMPLE);
else {
gl.glDisable(GL2.GL_LINE_SMOOTH);
gl.glHint(GL2.GL_LINE_SMOOTH_HINT, GL2.GL_FASTEST);
gl.glDisable(GL2.GL_POINT_SMOOTH);
gl.glHint(GL2.GL_POINT_SMOOTH_HINT, GL2.GL_FASTEST);
//gl.glDisable(GL2.GL_POLYGON_SMOOTH);
//gl.glHint(GL2.GL_POLYGON_SMOOTH_HINT, GL2.GL_FASTEST);
}
}
//gl.glScalef(scaleX, scaleY, scaleZ);
if (pitchAngle != 0) {
float scale = getScale();
gl.glTranslatef(0, 0, scale);
gl.glRotatef(70.f * (pitchAngle / 90.f), 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0, 0, -scale);
}
gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f);
gl.glRotatef(angleY, 0.0f, 0.0f, 1.0f);
if (headAngle != 0) {
gl.glRotatef(headAngle, 0.0f, 1.0f, 0.0f);
}
this.updateMatrix(gl);
this.setLight(gl);
//Draw graphics
for (int m = 0; m < this.graphics.getNumGraphics(); m++) {
Graphic graphic = this.graphics.get(m);
drawGraphics(gl, graphic);
}
//Draw text
for (int m = 0; m < this.graphics.getNumGraphics(); m++) {
Graphic graphic = this.graphics.get(m);
if (graphic.getNumGraphics() == 1) {
Shape shape = graphic.getGraphicN(0).getShape();
if (shape.getShapeType() == ShapeTypes.TEXT) {
this.drawText(gl, (ChartText3D) shape);
}
} else {
for (int i = 0; i < graphic.getNumGraphics(); i++) {
Shape shape = graphic.getGraphicN(i).getShape();
if (shape.getShapeType() == ShapeTypes.TEXT) {
this.drawText(gl, (ChartText3D) shape);
}
}
}
}
//Stop lighting
if (this.lighting.isEnable()) {
this.lighting.stop(gl);
}
//Draw axis
this.drawAllZAxis(gl);
//Draw legend
gl.glPopMatrix();
this.updateMatrix(gl);
if (!this.legends.isEmpty()) {
ChartColorBar legend = (ChartColorBar) this.legends.get(0);
if (legend.getLegendScheme().getColorMap() == null)
this.drawLegend(gl, legend);
else
this.drawColorbar(gl, legend);
}
//Draw title
this.drawTitle();
gl.glFlush();
//Do screen-shot
if (this.doScreenShot) {
AWTGLReadBufferUtil glReadBufferUtil = new AWTGLReadBufferUtil(drawable.getGLProfile(), false);
this.screenImage = glReadBufferUtil.readPixelsToBufferedImage(drawable.getGL(), true);
this.doScreenShot = false;
}
}
@Override
protected void drawZAxis(GL2 gl, PointF loc) {
float[] rgba;
float x, y, z, v;
int skip = 1;
XAlign xAlign;
YAlign yAlign;
Rectangle2D rect;
float strWidth, strHeight;
//z axis line
rgba = this.zAxis.getLineColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glLineWidth(this.zAxis.getLineWidth() * this.dpiScale);
gl.glBegin(GL2.GL_LINES);
Vector3f xyz = SphericalTransform.transform(loc.X, loc.Y, (float) this.dataExtent.minZ);
x = this.transform.transform_x(xyz.x);
y = this.transform.transform_y(xyz.y);
z = this.transform.transform_z(xyz.z);
gl.glVertex3f(x, y, z);
xyz = SphericalTransform.transform(loc.X, loc.Y, (float) this.dataExtent.maxZ);
x = this.transform.transform_x(xyz.x);
y = this.transform.transform_y(xyz.y);
z = this.transform.transform_z(xyz.z);
gl.glVertex3f(x, y, z);
gl.glEnd();
//z axis ticks
this.zAxis.updateTickLabels();
List<ChartText> tlabs = this.zAxis.getTickLabels();
//float axisLen = this.toScreenLength(x, y, zMin, x, y, zMax);
//skip = getLabelGap(this.zAxis.getTickLabelFont(), tlabs, axisLen);
float x1 = x;
float y1 = y;
float tickLen = this.zAxis.getTickLength() * this.lenScale;
xAlign = XAlign.RIGHT;
yAlign = YAlign.CENTER;
strWidth = 0.0f;
for (int i = 0; i < this.zAxis.getTickValues().length; i += skip) {
v = (float) this.zAxis.getTickValues()[i];
if (v < dataExtent.minZ || v > dataExtent.maxZ) {
continue;
}
xyz = SphericalTransform.transform(loc.X, loc.Y, v);
x = this.transform.transform_x(xyz.x);
y = this.transform.transform_y(xyz.y);
z = this.transform.transform_z(xyz.z);
x1 = x;
y1 = y;
if (x < 0) {
if (y > 0) {
y1 += tickLen;
} else {
x1 -= tickLen;
}
} else {
if (y > 0) {
x1 += tickLen;
} else {
y1 -= tickLen;
}
}
if (i == tlabs.size()) {
break;
}
//Draw tick line
rgba = this.zAxis.getLineColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glLineWidth(this.zAxis.getLineWidth() * this.dpiScale);
gl.glBegin(GL2.GL_LINES);
gl.glVertex3f(x, y, z);
gl.glVertex3f(x1, y1, z);
gl.glEnd();
//Draw tick label
rect = drawString(gl, tlabs.get(i), x1, y1, z, xAlign, yAlign, -this.tickSpace, 0);
if (strWidth < rect.getWidth()) {
strWidth = (float) rect.getWidth();
}
}
//Draw z axis label
ChartText label = this.zAxis.getLabel();
if (label != null) {
v = (float) (dataExtent.minZ + dataExtent.maxZ) / 2;
xyz = SphericalTransform.transform(loc.X, loc.Y, v);
x = this.transform.transform_x(xyz.x);
y = this.transform.transform_y(xyz.y);
z = this.transform.transform_z(xyz.z);
x1 = x;
y1 = y;
if (x < 0) {
if (y > 0) {
y1 += tickLen;
} else {
x1 -= tickLen;
}
} else {
if (y > 0) {
x1 += tickLen;
} else {
y1 -= tickLen;
}
}
float yShift = strWidth + this.tickSpace * 3;
drawString(gl, label, x1, y1, z, XAlign.CENTER, YAlign.BOTTOM, 90.f, 0, yShift);
}
}
protected void drawZAxis(GL2 gl, ZAxisOption zAxisOption) {
Matrix4f mvMatrix = toMatrix(mvmatrix);
gl.glPushMatrix();
float[] rgba;
float v;
int skip = 1;
XAlign xAlign;
YAlign yAlign;
Rectangle2D rect;
float strWidth, strHeight;
PointF loc = zAxisOption.getLocation();
boolean left = zAxisOption.isLeft();
//z axis line
rgba = this.zAxis.getLineColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glLineWidth(this.zAxis.getLineWidth() * this.dpiScale);
gl.glBegin(GL2.GL_LINES);
Vector3f xyz = SphericalTransform.transform(loc.X, loc.Y, (float) this.dataExtent.minZ);
xyz = this.transform.transform(xyz);
gl.glVertex3f(xyz.x, xyz.y, xyz.z);
Vector3f xyz1 = SphericalTransform.transform(loc.X, loc.Y, (float) this.dataExtent.maxZ);
xyz1 = this.transform.transform(xyz1);
gl.glVertex3f(xyz1.x, xyz1.y, xyz1.z);
gl.glEnd();
//Load identity
gl.glLoadIdentity();
this.updateMatrix(gl);
//z axis ticks positions
this.zAxis.updateTickLabels();
List<ChartText> tlabs = this.zAxis.getTickLabels();
float tickLen = this.zAxis.getTickLength() * this.lenScale;
xAlign = XAlign.RIGHT;
yAlign = YAlign.CENTER;
strWidth = 0.0f;
for (int i = 0; i < this.zAxis.getTickValues().length; i += skip) {
v = (float) this.zAxis.getTickValues()[i];
if (v < dataExtent.minZ || v > dataExtent.maxZ) {
continue;
}
xyz = SphericalTransform.transform(loc.X, loc.Y, v);
xyz = this.transform.transform(xyz);
mvMatrix.transformPosition(xyz);
xyz1 = new Vector3f(xyz.x, xyz.y, xyz.z);
float xShift;
if (left) {
xyz1.x -= tickLen;
xAlign = XAlign.RIGHT;
xShift = -this.tickSpace;
} else {
xyz1.x += tickLen;
xAlign = XAlign.LEFT;
xShift = this.tickSpace;
}
if (i == tlabs.size()) {
break;
}
//Draw tick line
rgba = this.zAxis.getLineColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glLineWidth(this.zAxis.getLineWidth() * this.dpiScale);
gl.glBegin(GL2.GL_LINES);
gl.glVertex3f(xyz.x, xyz.y, xyz.z);
gl.glVertex3f(xyz1.x, xyz1.y, xyz1.z);
gl.glEnd();
//Draw tick label
rect = drawString(gl, tlabs.get(i), xyz1.x, xyz1.y, xyz1.z, xAlign, yAlign, xShift, 0);
if (strWidth < rect.getWidth()) {
strWidth = (float) rect.getWidth();
}
}
//Draw z axis label
ChartText label = this.zAxis.getLabel();
if (label != null) {
v = (float) (dataExtent.minZ + dataExtent.maxZ) / 2;
xyz = SphericalTransform.transform(loc.X, loc.Y, v);
xyz = this.transform.transform(xyz);
mvMatrix.transformPosition(xyz);
if (left) {
xyz.x -= tickLen;
float yShift = strWidth + this.tickSpace * 3;
drawString(gl, label, xyz.x, xyz.y, xyz.z, XAlign.CENTER, YAlign.BOTTOM, 90.f, 0, yShift);
} else {
xyz.x += tickLen;
float yShift = -(strWidth + this.tickSpace * 3);
drawString(gl, label, xyz.x, xyz.y, xyz.z, XAlign.CENTER, YAlign.TOP, 90.f, 0, yShift);
}
}
gl.glPopMatrix();
this.updateMatrix(gl);
}
@Override
protected void drawPolygonShape(GL2 gl, Graphic graphic) {
super.drawPolygonShape(gl, graphic);
}
// </editor-fold>
}

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
protected boolean doScreenShot;
protected BufferedImage screenImage;
protected GL2 gl;
protected final GLU glu = new GLU();
protected GLU glu;
protected final GLUT glut = new GLUT();
protected int startList = 2;
protected GraphicCollection3D graphics;
@ -163,7 +163,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
Extent3D extent3D = new Extent3D(-1, 1, -1, 1, -1, 1);
this.drawExtent = (Extent3D) extent3D.clone();
this.transform.setExtent(this.drawExtent);
this.axesExtent = (Extent3D) this.drawExtent.clone();
this.setAxesExtent((Extent3D) this.drawExtent.clone());
}
/**
@ -4276,6 +4276,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
//drawable.getContext().makeCurrent();
GL2 gl = drawable.getGL().getGL2();
this.gl = gl;
this.glu = GLU.createGLU(gl);
//Background
//gl.glClearColor(1f, 1f, 1f, 1.0f);
gl.glEnable(GL2.GL_POINT_SMOOTH);
@ -4381,7 +4382,34 @@ public class Plot3DGL extends Plot implements GLEventListener {
*/
@Override
public Margin getTightInset(Graphics2D g, Rectangle2D positionArea) {
return null;
int left = 2, bottom = 2, right = 2, top = 5;
int space = 2;
if (this.title != null) {
top += this.title.getTrueDimension(g).height + 10;
}
if (!this.legends.isEmpty()) {
ChartLegend legend = this.getLegend();
Dimension dim = legend.getLegendDimension(g, new Dimension((int) positionArea.getWidth(),
(int) positionArea.getHeight()));
switch (legend.getPosition()) {
case UPPER_CENTER_OUTSIDE:
top += dim.height + 10;
break;
case LOWER_CENTER_OUTSIDE:
bottom += dim.height + legend.getYShift() + 10;
break;
case LEFT_OUTSIDE:
left += dim.width + 10;
break;
case RIGHT_OUTSIDE:
right += dim.width + legend.getXShift() + 10;
break;
}
}
return new Margin(left, right, top, bottom);
}
/**

View File

@ -811,8 +811,7 @@ public abstract class AbstractPlot2D extends Plot {
return;
}
Rectangle2D graphArea;
graphArea = this.getPositionArea();
Rectangle2D graphArea = this.getPositionArea();
this.setGraphArea(graphArea);
//Draw title

View File

@ -2278,16 +2278,6 @@ public class Plot3D extends Plot {
}
}
//Get x axis space
//bottom += this.getXAxisHeight(g, space);
//Get y axis space
//left += this.getYAxisWidth(g, space);
//Set right space
// if (this.getXAxis().isVisible()) {
// if (this.getXAxis().isDrawTickLabel()) {
// right += this.getXAxis().getMaxLabelLength(g) / 2;
// }
// }
return new Margin(left, right, top, bottom);
}

View File

@ -1,34 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\contour">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\stats"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\scatter"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\legend"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\polar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\interpolate"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\imshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\particles"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\plot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\contour"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\common_math\optimize\curve_fit_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface\fimplicit3_gyroid.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\subplot_3d_cylinder.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\common_math\optimize\curve_fit_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface\fimplicit3_gyroid.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\plot\plot.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\subplot_3d_cylinder.py"/>
</RecentFiles>
</File>
<Font>
@ -36,5 +34,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,0" MainFormSize="1381,773"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
</MeteoInfo>

View File

@ -13,7 +13,7 @@ from org.meteoinfo.geo.legend import LegendManage
from org.meteoinfo.geo.layer import LayerTypes
from org.meteoinfo.geometry.shape import ShapeTypes
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
from org.meteoinfo.chart.jogl import Plot3DGL, GLForm, JOGLUtil, EarthPlot3D, MapPlot3D
from org.meteoinfo.chart.jogl import Plot3DGL, GLPlot, GLForm, JOGLUtil, EarthPlot3D, MapPlot3D
from org.meteoinfo.math.interpolate import InterpolationMethod
from org.meteoinfo.image import ImageUtil
from org.meteoinfo.common import Extent3D
@ -58,7 +58,8 @@ class Axes3DGL(Axes3D):
position = kwargs.pop('position', None)
outerposition = kwargs.pop('outerposition', None)
if position is None:
position = [0.13, 0.11, 0.71, 0.815]
#position = [0.13, 0.11, 0.71, 0.815]
position = [0, 0, 1, 1]
self.active_outerposition(True)
else:
self.active_outerposition(False)
@ -123,7 +124,8 @@ class Axes3DGL(Axes3D):
:param plot: (*Axes3D*) Plot.
"""
if plot is None:
self._axes = Plot3DGL()
#self._axes = Plot3DGL()
self._axes = GLPlot()
else:
self._axes = plot

View File

@ -6,23 +6,24 @@
# Note: Jython
#-----------------------------------------------------
from org.meteoinfo.chart import ChartPanel, Chart, Location, MouseMode, ChartText
from org.meteoinfo.chart import GLChartPanel, GLChart, Location, MouseMode, ChartText
import plotutil
from ._axes import Axes, PolarAxes
from ._mapaxes import MapAxes
from ._axes3d import Axes3D
from ._axes3dgl import Axes3DGL
from java.awt import Font
__all__ = ['Figure']
class Figure(ChartPanel):
class Figure(GLChartPanel):
"""
top level container for all plot elements
"""
def __init__(self, figsize=None, dpi=None, bgcolor='w'):
def __init__(self, figsize=None, dpi=None, bgcolor='w', **kwargs):
"""
Constructor
@ -30,7 +31,7 @@ class Figure(ChartPanel):
:param bgcolor: (*Color*) Optional, background color of the figure. Default is ``w`` (white).
:param dpi: (*int*) Dots per inch.
"""
chart = Chart()
chart = GLChart()
chart.setBackground(plotutil.getcolor(bgcolor))
if figsize is None:
super(Figure, self).__init__(chart)
@ -396,8 +397,8 @@ class Figure(ChartPanel):
ax = MapAxes(*args, **kwargs)
#self.__set_axesm(ax, **kwargs)
elif axestype == '3d':
ax = Axes3D(*args, **kwargs)
#self.__set_axes3d(ax, **kwargs)
#ax = Axes3D(*args, **kwargs)
ax = Axes3DGL(*args, **kwargs)
else:
ax = Axes(*args, **kwargs)
#self.__set_axes(ax, **kwargs)
@ -749,8 +750,8 @@ class Figure(ChartPanel):
:param symbol: (*boolean*) Set symbol antialias or not.
"""
if b is None:
b = not self.getChart().isAntiAlias()
self.getChart().setAntiAlias(b)
b = not self.getChart().isAntialias()
self.getChart().setAntialias(b)
if not symbol is None:
self.getChart().setSymbolAntialias(symbol)

View File

@ -547,7 +547,7 @@ def windrose(wd, ws, nwdbins=16, wsbins=None, degree=True, colors=None, cmap='ma
return g_axes, bars
def figure(bgcolor='w', figsize=None, newfig=True):
def figure(bgcolor='w', figsize=None, newfig=True, **kwargs):
"""
Creates a figure.
@ -557,7 +557,7 @@ def figure(bgcolor='w', figsize=None, newfig=True):
:param newfig: (*boolean*) Optional, if creates a new figure. Default is ``True`` .
"""
global g_figure
g_figure = Figure(figsize, bgcolor=bgcolor)
g_figure = Figure(figsize, bgcolor=bgcolor, **kwargs)
if not batchmode:
show(newfig)
@ -818,7 +818,7 @@ def axes3d(*args, **kwargs):
def axes3dgl(*args, **kwargs):
"""
Add an 3d axes with JOGL to the figure.
Add a 3d axes with JOGL to the figure.
:returns: The axes.
"""
@ -828,9 +828,9 @@ def axes3dgl(*args, **kwargs):
g_axes = ax
if not batchmode:
if g_figure is None or isinstance(g_figure, Figure):
glfigure(**kwargs)
g_figure.set_axes(ax)
if g_figure is None:
figure(**kwargs)
g_figure.add_axes(ax)
draw_if_interactive()
return ax

View File

@ -24,7 +24,7 @@ import com.formdev.flatlaf.extras.FlatSVGIcon;
import org.meteoinfo.chart.ChartPanel;
import org.meteoinfo.chart.IChartPanel;
import org.meteoinfo.chart.MouseMode;
import org.meteoinfo.chart.jogl.GLChartPanel;
//import org.meteoinfo.chart.jogl.GLChartPanel;
import org.meteoinfo.console.jython.PythonInteractiveInterpreter;
import org.meteoinfo.ui.ButtonTabComponent;
@ -278,9 +278,9 @@ public class FigureDockable extends DefaultSingleCDockable {
* @param cp Chart panel
*/
public void removeFigure(JPanel cp) {
if (cp instanceof GLChartPanel) {
/*if (cp instanceof GLChartPanel) {
((GLChartPanel) cp).animator_stop();
}
}*/
JScrollPane sp = (JScrollPane) cp.getParent().getParent();
if (tabbedPanel.getTabCount() > 0) {
tabbedPanel.remove(sp);