mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
add QuiverRender to plot 3D quivers with VBO
This commit is contained in:
parent
6d795bbad3
commit
80475bba09
@ -5869,7 +5869,7 @@ public class GraphicFactory {
|
||||
wa.v = v;
|
||||
wa.w = w;
|
||||
wa.scale = scale;
|
||||
wa.setHeadWith(headWidth);
|
||||
wa.setHeadWidth(headWidth);
|
||||
wa.setHeadLength(headLength);
|
||||
wa.setPoint(aPoint);
|
||||
if (cdata == null) {
|
||||
|
||||
@ -2508,46 +2508,39 @@ public class GLPlot extends Plot {
|
||||
}
|
||||
break;
|
||||
case POLYLINE_Z:
|
||||
boolean useRender = true;
|
||||
/*ColorBreak cb = graphic.getGraphicN(0).getLegend();
|
||||
if (cb instanceof StreamlineBreak) {
|
||||
if (graphic.getGraphicN(0).getShape() instanceof PipeShape)
|
||||
useRender = false;
|
||||
} else if (cb instanceof ColorBreakCollection) {
|
||||
if (((ColorBreakCollection) cb).get(0) instanceof StreamlineBreak) {
|
||||
if (graphic.getGraphicN(0).getShape() instanceof PipeShape)
|
||||
useRender = false;
|
||||
}
|
||||
}*/
|
||||
if (useRender) {
|
||||
if (graphic.getGraphicN(0).getShape() instanceof PipeShape) {
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new PipeRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
PipeRender pipeRender = (PipeRender) renderMap.get(graphic);
|
||||
pipeRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
pipeRender.setOrthographic(this.orthographic);
|
||||
pipeRender.setLighting(this.lighting);
|
||||
pipeRender.updateMatrix();
|
||||
pipeRender.draw();
|
||||
} else {
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new LineRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
LineRender lineRender = (LineRender) renderMap.get(graphic);
|
||||
lineRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
lineRender.setOrthographic(this.orthographic);
|
||||
lineRender.setLighting(this.lighting);
|
||||
lineRender.updateMatrix();
|
||||
lineRender.draw();
|
||||
if (graphic.getGraphicN(0).getShape() instanceof PipeShape) {
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new PipeRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
PipeRender pipeRender = (PipeRender) renderMap.get(graphic);
|
||||
pipeRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
pipeRender.setOrthographic(this.orthographic);
|
||||
pipeRender.setLighting(this.lighting);
|
||||
pipeRender.updateMatrix();
|
||||
pipeRender.draw();
|
||||
} else {
|
||||
for (int i = 0; i < graphic.getNumGraphics(); i++) {
|
||||
Graphic gg = graphic.getGraphicN(i);
|
||||
this.drawGraphic(gl, gg);
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new LineRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
LineRender lineRender = (LineRender) renderMap.get(graphic);
|
||||
lineRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
lineRender.setOrthographic(this.orthographic);
|
||||
lineRender.setLighting(this.lighting);
|
||||
lineRender.updateMatrix();
|
||||
lineRender.draw();
|
||||
}
|
||||
break;
|
||||
case WIND_ARROW:
|
||||
if (!this.renderMap.containsKey(graphic)) {
|
||||
renderMap.put(graphic, new QuiverRender(gl, (GraphicCollection3D) graphic));
|
||||
}
|
||||
QuiverRender quiverRender = (QuiverRender) renderMap.get(graphic);
|
||||
quiverRender.setTransform(this.transform, this.alwaysUpdateBuffers);
|
||||
quiverRender.setOrthographic(this.orthographic);
|
||||
quiverRender.setLighting(this.lighting);
|
||||
quiverRender.updateMatrix();
|
||||
quiverRender.draw();
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < graphic.getNumGraphics(); i++) {
|
||||
Graphic gg = graphic.getGraphicN(i);
|
||||
@ -3745,7 +3738,7 @@ public class GLPlot extends Plot {
|
||||
//float coneHgt = coneFractionAxially * norm_of_v;
|
||||
//float coneRadius = coneFractionRadially * norm_of_v;
|
||||
float coneRadius = shape.getHeadLength() * 0.02f;
|
||||
float coneHgt = shape.getHeadWith() * 0.02f;
|
||||
float coneHgt = shape.getHeadWidth() * 0.02f;
|
||||
|
||||
// Set location of arrowhead to be at the startpoint of the line
|
||||
float[] vConeLocation = {x2, y2, z2};
|
||||
|
||||
@ -3727,7 +3727,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
|
||||
//float coneHgt = coneFractionAxially * norm_of_v;
|
||||
//float coneRadius = coneFractionRadially * norm_of_v;
|
||||
float coneRadius = shape.getHeadLength() * 0.02f;
|
||||
float coneHgt = shape.getHeadWith() * 0.02f;
|
||||
float coneHgt = shape.getHeadWidth() * 0.02f;
|
||||
|
||||
// Set location of arrowhead to be at the startpoint of the line
|
||||
float[] vConeLocation = {x2, y2, z2};
|
||||
|
||||
@ -0,0 +1,268 @@
|
||||
package org.meteoinfo.chart.render.jogl;
|
||||
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2;
|
||||
import com.jogamp.opengl.util.GLBuffers;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
import org.meteoinfo.chart.graphic.GraphicCollection3D;
|
||||
import org.meteoinfo.chart.graphic.cylinder.Cylinder;
|
||||
import org.meteoinfo.chart.jogl.Program;
|
||||
import org.meteoinfo.chart.jogl.Transform;
|
||||
import org.meteoinfo.chart.jogl.Utils;
|
||||
import org.meteoinfo.geometry.graphic.Graphic;
|
||||
import org.meteoinfo.geometry.legend.*;
|
||||
import org.meteoinfo.geometry.shape.PointZ;
|
||||
import org.meteoinfo.geometry.shape.PolylineZShape;
|
||||
import org.meteoinfo.geometry.shape.WindArrow3D;
|
||||
import org.meteoinfo.math.Matrix4f;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuiverRender extends JOGLGraphicRender {
|
||||
|
||||
private GraphicCollection3D graphics;
|
||||
private Program program;
|
||||
private IntBuffer vbo;
|
||||
private int quiverNumber;
|
||||
private float lineWidth;
|
||||
private float[] vertexPosition;
|
||||
private float[] vertexColor;
|
||||
private int sizePosition;
|
||||
private int sizeColor;
|
||||
private IntBuffer vboCone;
|
||||
private float[] coneVertexPosition;
|
||||
private float[] coneVertexNormal;
|
||||
private float[] coneVertexColor;
|
||||
private int[] coneVertexIndices;
|
||||
private int sizeConePosition;
|
||||
private int sizeConeNormal;
|
||||
private int sizeConeColor;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param gl The JOGL GL2 object
|
||||
*/
|
||||
public QuiverRender(GL2 gl) {
|
||||
super(gl);
|
||||
|
||||
if (useShader) {
|
||||
try {
|
||||
this.compileShaders();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param gl The JOGL GL2 object
|
||||
* @param graphics The quiver graphics
|
||||
*/
|
||||
public QuiverRender(GL2 gl, GraphicCollection3D graphics) {
|
||||
this(gl);
|
||||
|
||||
this.graphics = graphics;
|
||||
this.quiverNumber = graphics.getNumGraphics();
|
||||
PointBreak pb = (PointBreak) graphics.getGraphicN(0).getLegend();
|
||||
this.lineWidth = pb.getOutlineSize();
|
||||
}
|
||||
|
||||
private void updateVertexArrays() {
|
||||
vertexPosition = new float[quiverNumber * 6];
|
||||
vertexColor = new float[quiverNumber * 8];
|
||||
List<Vector3f> vertexPositionList = new ArrayList<>();
|
||||
List<Vector3f> vertexNormalList = new ArrayList<>();
|
||||
List<Vector4f> vertexColorList = new ArrayList<>();
|
||||
List<Integer> vertexIndices = new ArrayList<>();
|
||||
for (int i = 0, pi = 0, ci = 0; i < quiverNumber; i++, pi+=6, ci+=8) {
|
||||
Graphic graphic = graphics.getGraphicN(i);
|
||||
WindArrow3D shape = (WindArrow3D) graphic.getShape();
|
||||
PointBreak pb = (PointBreak) graphic.getLegend();
|
||||
PointZ sp = (PointZ) shape.getPoint();
|
||||
PointZ ep = (PointZ) shape.getEndPoint();
|
||||
|
||||
Vector3f v1 = transform.transform((float) sp.X, (float) sp.Y, (float) sp.Z);
|
||||
Vector3f v2 = transform.transform((float) ep.X, (float) ep.Y, (float) ep.Z);
|
||||
float[] color = pb.getColor().getRGBComponents(null);
|
||||
vertexPosition[pi] = v1.x;
|
||||
vertexPosition[pi + 1] = v1.y;
|
||||
vertexPosition[pi + 2] = v1.z;
|
||||
vertexPosition[pi + 3] = v2.x;
|
||||
vertexPosition[pi + 4] = v2.y;
|
||||
vertexPosition[pi + 5] = v2.z;
|
||||
System.arraycopy(color, 0, vertexColor, ci, 4);
|
||||
System.arraycopy(color, 0, vertexColor, ci + 4, 4);
|
||||
|
||||
Cylinder cylinder = new Cylinder(shape.getHeadWidth() * 0.02f,
|
||||
0, shape.getHeadLength() * 0.02f, 8, 1, true);
|
||||
Matrix4f matrix = new Matrix4f();
|
||||
matrix.lookAt(v2.sub(v1, new Vector3f()));
|
||||
matrix.translate(v2);
|
||||
List<Vector3f> vertices = cylinder.getVertices();
|
||||
int n = vertices.size();
|
||||
int nAdded = vertexPositionList.size();
|
||||
for (Vector3f v : vertices) {
|
||||
vertexPositionList.add(matrix.mul(v));
|
||||
}
|
||||
List<Vector3f> normals = cylinder.getNormals();
|
||||
for (Vector3f v : normals) {
|
||||
vertexNormalList.add(matrix.mul(v));
|
||||
}
|
||||
for (int j = 0; j < n; j++) {
|
||||
vertexColorList.add(new Vector4f(color));
|
||||
}
|
||||
if (nAdded == 0) {
|
||||
vertexIndices.addAll(cylinder.getIndices());
|
||||
} else {
|
||||
for (int idx : cylinder.getIndices()) {
|
||||
vertexIndices.add(idx + nAdded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int n = vertexPositionList.size();
|
||||
this.coneVertexPosition = new float[n * 3];
|
||||
this.coneVertexNormal = new float[n * 3];
|
||||
this.coneVertexColor = new float[n * 4];
|
||||
Vector3f v;
|
||||
Vector4f v4;
|
||||
for (int i = 0, j = 0, k = 0; i < n; i++, j+=3, k+=4) {
|
||||
v = vertexPositionList.get(i);
|
||||
coneVertexPosition[j] = v.x;
|
||||
coneVertexPosition[j + 1] = v.y;
|
||||
coneVertexPosition[j + 2] = v.z;
|
||||
v = vertexNormalList.get(i);
|
||||
coneVertexNormal[j] = v.x;
|
||||
coneVertexNormal[j + 1] = v.y;
|
||||
coneVertexNormal[j + 2] = v.z;
|
||||
v4 = vertexColorList.get(i);
|
||||
coneVertexColor[k] = v4.x;
|
||||
coneVertexColor[k + 1] = v4.y;
|
||||
coneVertexColor[k + 2] = v4.z;
|
||||
coneVertexColor[k + 3] = v4.w;
|
||||
}
|
||||
coneVertexIndices = vertexIndices.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
|
||||
void compileShaders() throws Exception {
|
||||
String vertexShaderCode = Utils.loadResource("/shaders/surface/vertex.vert");
|
||||
String fragmentShaderCode = Utils.loadResource("/shaders/surface/surface.frag");
|
||||
program = new Program("surface", vertexShaderCode, fragmentShaderCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(Transform transform, boolean alwaysUpdateBuffers) {
|
||||
boolean updateBuffer = true;
|
||||
if (!alwaysUpdateBuffers && this.transform != null && this.transform.equals(transform))
|
||||
updateBuffer = false;
|
||||
|
||||
super.setTransform((Transform) transform.clone());
|
||||
|
||||
if (updateBuffer) {
|
||||
this.updateVertexArrays();
|
||||
|
||||
FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexPosition);
|
||||
sizePosition = vertexBuffer.capacity() * Float.BYTES;
|
||||
|
||||
FloatBuffer colorBuffer = GLBuffers.newDirectFloatBuffer(vertexColor);
|
||||
sizeColor = colorBuffer.capacity() * Float.BYTES;
|
||||
int totalSize = sizePosition + sizeColor;
|
||||
|
||||
vbo = GLBuffers.newDirectIntBuffer(1);
|
||||
gl.glGenBuffers(1, vbo);
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0));
|
||||
gl.glBufferData(GL.GL_ARRAY_BUFFER, totalSize, null, GL.GL_STATIC_DRAW);
|
||||
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, sizePosition, vertexBuffer);
|
||||
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizePosition, sizeColor, colorBuffer);
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
FloatBuffer coneVertexBuffer = GLBuffers.newDirectFloatBuffer(coneVertexPosition);
|
||||
sizeConePosition = coneVertexBuffer.capacity() * Float.BYTES;
|
||||
FloatBuffer coneNormalBuffer = GLBuffers.newDirectFloatBuffer(coneVertexNormal);
|
||||
sizeConeNormal = coneNormalBuffer.capacity() * Float.BYTES;
|
||||
FloatBuffer coneColorBuffer = GLBuffers.newDirectFloatBuffer(coneVertexColor);
|
||||
sizeConeColor = coneColorBuffer.capacity() * Float.BYTES;
|
||||
|
||||
vboCone = GLBuffers.newDirectIntBuffer(2);
|
||||
gl.glGenBuffers(2, vboCone);
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboCone.get(0));
|
||||
gl.glBufferData(GL.GL_ARRAY_BUFFER, sizeConePosition + sizeConeNormal + sizeConeColor,
|
||||
null, GL.GL_STATIC_DRAW);
|
||||
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, sizeConePosition, coneVertexBuffer);
|
||||
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizeConePosition, sizeConeNormal, coneNormalBuffer);
|
||||
gl.glBufferSubData(GL.GL_ARRAY_BUFFER, sizeConePosition + sizeConeNormal, sizeConeColor,
|
||||
coneColorBuffer);
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
IntBuffer coneIndexBuffer = GLBuffers.newDirectIntBuffer(coneVertexIndices);
|
||||
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vboCone.get(1));
|
||||
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, coneIndexBuffer.capacity() * Integer.BYTES,
|
||||
coneIndexBuffer, GL.GL_STATIC_DRAW);
|
||||
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setUniforms() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (useShader) { // not working now
|
||||
program.use(gl);
|
||||
setUniforms();
|
||||
|
||||
gl.glUseProgram(0);
|
||||
} else {
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo.get(0));
|
||||
|
||||
// enable vertex arrays
|
||||
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
|
||||
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
|
||||
gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
|
||||
gl.glColorPointer(4, GL.GL_FLOAT, 0, sizePosition);
|
||||
|
||||
boolean lightEnabled = this.lighting.isEnable();
|
||||
if (lightEnabled) {
|
||||
this.lighting.stop(gl);
|
||||
}
|
||||
gl.glLineWidth(this.lineWidth * this.dpiScale);
|
||||
gl.glDrawArrays(GL.GL_LINES, 0, quiverNumber);
|
||||
if (lightEnabled) {
|
||||
this.lighting.start(gl);
|
||||
}
|
||||
|
||||
// draw wind arrow
|
||||
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
|
||||
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboCone.get(0));
|
||||
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vboCone.get(1));
|
||||
|
||||
// enable vertex arrays
|
||||
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
|
||||
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
|
||||
gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
|
||||
gl.glNormalPointer(GL.GL_FLOAT, 0, sizeConePosition);
|
||||
gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
|
||||
gl.glColorPointer(4, GL.GL_FLOAT, 0, sizeConePosition + sizeConeNormal);
|
||||
|
||||
gl.glDrawElements(GL2.GL_TRIANGLES, coneVertexIndices.length, GL.GL_UNSIGNED_INT, 0);
|
||||
|
||||
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
|
||||
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
|
||||
|
||||
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
|
||||
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ public class WindArrow3D extends PointZShape {
|
||||
public double v;
|
||||
public double w;
|
||||
public float scale = 1;
|
||||
private float headWith = 1;
|
||||
private float headWidth = 1;
|
||||
private float headLength = 2.5f;
|
||||
|
||||
// </editor-fold>
|
||||
@ -40,16 +40,16 @@ public class WindArrow3D extends PointZShape {
|
||||
* Get head width
|
||||
* @return Head width
|
||||
*/
|
||||
public float getHeadWith() {
|
||||
return this.headWith;
|
||||
public float getHeadWidth() {
|
||||
return this.headWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set head width
|
||||
* @param value Head width
|
||||
*/
|
||||
public void setHeadWith(float value) {
|
||||
this.headWith = value;
|
||||
public void setHeadWidth(float value) {
|
||||
this.headWidth = value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math\optimize"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\common_math"/>
|
||||
<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\meteo\calc"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
|
||||
<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\3d\jogl\streamplot"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamslice"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\topology"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\airship"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\city"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_pipe_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver\quiver3_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver\quiver3_2.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar\bar_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contourfsclice_1.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot\streamplot_pipe_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver\quiver3_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver\quiver3_2.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar\bar_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\contour\contourfsclice_1.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -36,5 +36,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1362,763"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -337,7 +337,7 @@ class Axes3DGL(Axes3D):
|
||||
"""
|
||||
self._axes.addZAxis(x, y, left)
|
||||
|
||||
def bar(self, x, y, z, width=0.8, bottom=None, cylinder=False, **kwargs):
|
||||
def bar(self, *args, **kwargs):
|
||||
"""
|
||||
Make a 3D bar plot of x, y and z, where x, y and z are sequence like objects of the same lengths.
|
||||
|
||||
@ -347,7 +347,7 @@ class Axes3DGL(Axes3D):
|
||||
:param width: (*float*) Bar width.
|
||||
:param cylinder: (*bool*) Is cylinder bar or rectangle bar.
|
||||
:param bottom: (*bool*) Color of the points. Or z values.
|
||||
:param color: (*Color*) Optional, the color of the bar faces.
|
||||
:param facecolor: (*Color*) Optional, the color of the bar faces.
|
||||
:param edgecolor: (*Color*) Optional, the color of the bar edge. Default is black color.
|
||||
Edge line will not be plotted if ``edgecolor`` is ``None``.
|
||||
:param linewidth: (*int*) Optional, width of bar edge.
|
||||
@ -362,16 +362,41 @@ class Axes3DGL(Axes3D):
|
||||
"""
|
||||
#Add data series
|
||||
label = kwargs.pop('label', 'S_0')
|
||||
xdata = plotutil.getplotdata(x)
|
||||
ydata = plotutil.getplotdata(y)
|
||||
zdata = plotutil.getplotdata(z)
|
||||
if len(args) == 1:
|
||||
z = np.asarray(args[0])
|
||||
if z.ndim == 1:
|
||||
nx, = z.shape
|
||||
y = np.array([0] * nx)
|
||||
x = np.arange(nx)
|
||||
else:
|
||||
ny, nx = z.shape
|
||||
x = np.arange(nx)
|
||||
y = np.arange(ny)
|
||||
x, y = np.meshgrid(x, y)
|
||||
elif len(args) == 2:
|
||||
x = np.asarray(args[0])
|
||||
z = np.asarray(args[1])
|
||||
nx, = x.shape
|
||||
y = np.array([0] * nx)
|
||||
else:
|
||||
x = np.asarray(args[0])
|
||||
y = np.asarray(args[1])
|
||||
z = np.asarray(args[2])
|
||||
|
||||
xdata = x._array
|
||||
ydata = y._array
|
||||
zdata = z._array
|
||||
|
||||
autowidth = False
|
||||
width = kwargs.pop('width', 0.8)
|
||||
width = np.asarray(width)
|
||||
|
||||
bottom = kwargs.pop('bottom', None)
|
||||
if not bottom is None:
|
||||
bottom = plotutil.getplotdata(bottom)
|
||||
|
||||
cylinder = kwargs.pop('cylinder', False)
|
||||
|
||||
#Set plot data styles
|
||||
fcobj = kwargs.pop('color', None)
|
||||
if fcobj is None:
|
||||
|
||||
Binary file not shown.
@ -241,7 +241,7 @@ def bar(x, height, width=0.8, bottom=None, align='center', data=None, **kwargs):
|
||||
return r
|
||||
|
||||
@_copy_docstring_and_deprecators(Axes3D.bar)
|
||||
def bar3(x, y, z, width=0.8, bottom=None, cylinder=False, **kwargs):
|
||||
def bar3(*args, **kwargs):
|
||||
global g_axes
|
||||
if g_axes is None:
|
||||
g_axes = axes3d()
|
||||
@ -249,7 +249,7 @@ def bar3(x, y, z, width=0.8, bottom=None, cylinder=False, **kwargs):
|
||||
if not isinstance(g_axes, Axes3D):
|
||||
g_axes = axes3d()
|
||||
|
||||
r = g_axes.bar(x, y, z, width, bottom, cylinder, **kwargs)
|
||||
r = g_axes.bar(*args, **kwargs)
|
||||
draw_if_interactive()
|
||||
return r
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user