add LineRender and PipeRender to plot 3D lines with VBO

This commit is contained in:
wyq 2022-12-25 22:54:51 +08:00
parent 198035e527
commit 6d795bbad3
33 changed files with 1194 additions and 393 deletions

View File

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

View File

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

View File

@ -1,13 +0,0 @@
<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-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-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-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

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

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-numbers-angle:1.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-angle/1.1-SNAPSHOT/commons-numbers-angle-1.1-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-angle/1.1-SNAPSHOT/commons-numbers-angle-1.1-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-angle/1.1-SNAPSHOT/commons-numbers-angle-1.1-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-numbers-complex:1.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-complex/1.1-SNAPSHOT/commons-numbers-complex-1.1-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-complex/1.1-SNAPSHOT/commons-numbers-complex-1.1-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-complex/1.1-SNAPSHOT/commons-numbers-complex-1.1-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-numbers-quaternion:1.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-quaternion/1.1-SNAPSHOT/commons-numbers-quaternion-1.1-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-quaternion/1.1-SNAPSHOT/commons-numbers-quaternion-1.1-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-quaternion/1.1-SNAPSHOT/commons-numbers-quaternion-1.1-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-numbers-rootfinder:1.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-rootfinder/1.1-SNAPSHOT/commons-numbers-rootfinder-1.1-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-rootfinder/1.1-SNAPSHOT/commons-numbers-rootfinder-1.1-SNAPSHOT-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-numbers-rootfinder/1.1-SNAPSHOT/commons-numbers-rootfinder-1.1-SNAPSHOT-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-rng-sampling:1.4">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-rng-sampling/1.4/commons-rng-sampling-1.4.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-rng-sampling/1.4/commons-rng-sampling-1.4-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-rng-sampling/1.4/commons-rng-sampling-1.4-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-cdense:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-cdense/0.41/ejml-cdense-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-cdense/0.41/ejml-cdense-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-cdense/0.41/ejml-cdense-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-core:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-core/0.41/ejml-core-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-core/0.41/ejml-core-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-core/0.41/ejml-core-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-ddense:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-ddense/0.41/ejml-ddense-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-ddense/0.41/ejml-ddense-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-ddense/0.41/ejml-ddense-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-dsparse:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-dsparse/0.41/ejml-dsparse-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-dsparse/0.41/ejml-dsparse-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-dsparse/0.41/ejml-dsparse-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-experimental:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-experimental/0.41/ejml-experimental-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-experimental/0.41/ejml-experimental-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-experimental/0.41/ejml-experimental-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-fdense:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fdense/0.41/ejml-fdense-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fdense/0.41/ejml-fdense-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fdense/0.41/ejml-fdense-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-fsparse:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fsparse/0.41/ejml-fsparse-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fsparse/0.41/ejml-fsparse-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-fsparse/0.41/ejml-fsparse-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-simple:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-simple/0.41/ejml-simple-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-simple/0.41/ejml-simple-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-simple/0.41/ejml-simple-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.ejml:ejml-zdense:0.41">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-zdense/0.41/ejml-zdense-0.41.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-zdense/0.41/ejml-zdense-0.41-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/ejml/ejml-zdense/0.41/ejml-zdense-0.41-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -1048,7 +1048,7 @@ public class GLChart implements GLEventListener {
if (this.containsGLPlot()) {
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.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_STENCIL_BUFFER_BIT);
gl.glShadeModel(GL2.GL_SMOOTH);

View File

@ -0,0 +1,656 @@
package org.meteoinfo.chart.graphic.cylinder;
import org.joml.Vector2f;
import org.joml.Vector3f;
import java.util.ArrayList;
import java.util.List;
public class Cylinder {
private float baseRadius;
private float topRadius;
private float height;
private int sectorCount;
private int stackCount;
private boolean smooth;
private int baseIndex;
private int topIndex;
private List<Vector3f> unitCircleVertices;
private List<Vector3f> vertices;
private List<Vector3f> normals;
private List<Integer> indices;
private List<Integer> lineIndices;
private List<Vector2f> texCoords;
private List<Vector3f> interleavedVertices;
private int interleavedStride;
/**
* Constructor
*
* @param baseRadius The base radius
* @param topRadius The top radius
* @param height The height
* @param sectorCount The sector count
* @param stackCount The stack count
* @param smooth Whether smooth
*/
public Cylinder(float baseRadius, float topRadius, float height, int sectorCount, int stackCount,
boolean smooth) {
this.baseRadius = baseRadius;
this.topRadius = topRadius;
this.height = height;
this.sectorCount = sectorCount;
this.stackCount = stackCount;
this.smooth = smooth;
updateVertices();
}
/**
* Update vertices
*/
public void updateVertices() {
// generate unit circle vertices first
buildUnitCircleVertices();
if (smooth) {
buildVerticesSmooth();
} else {
buildVerticesFlat();
}
}
/**
* Get base radius
* @return Base radius
*/
public float getBaseRadius() {
return baseRadius;
}
/**
* Set base radius
* @param value Base radius
*/
public void setBaseRadius(float value) {
if (this.baseRadius != value) {
this.baseRadius = value;
updateVertices();
}
}
/**
* Get top radius
* @return Top radius
*/
public float getTopRadius() {
return topRadius;
}
/**
* Set top radius
* @param value Top radius
*/
public void setTopRadius(float value) {
if (this.topRadius != value) {
this.topRadius = value;
updateVertices();
}
}
/**
* Get height
* @return Height
*/
public float getHeight() {
return height;
}
/**
* Set height
* @param value Height
*/
public void setHeight(float value) {
if (this.height != value) {
this.height = value;
updateVertices();
}
}
/**
* Get sector count
* @return Sector count
*/
public int getSectorCount() {
return sectorCount;
}
/**
* Set sector count
* @param value Sector count
*/
public void setSectorCount(int value) {
if (this.sectorCount != value) {
this.sectorCount = value;
updateVertices();
}
}
/**
* Get stack count
* @return Stack count
*/
public int getStackCount() {
return stackCount;
}
/**
* Set stack count
* @param value stack count
*/
public void setStackCount(int value) {
if (this.stackCount != value) {
this.stackCount = value;
updateVertices();
}
}
/**
* Get smooth
* @return Smooth
*/
public boolean isSmooth() {
return smooth;
}
/**
* Set smooth
* @param value Smooth
*/
public void setSmooth(boolean value) {
if (this.smooth != value) {
this.smooth = value;
updateVertices();
}
}
/**
* Get vertices
* @return Vertices
*/
public List<Vector3f> getVertices() {
return vertices;
}
/**
* Get normals
* @return Normals
*/
public List<Vector3f> getNormals() {
return normals;
}
/**
* Get texture coordinates
* @return Texture coordinates
*/
public List<Vector2f> getTexCoords() {
return texCoords;
}
/**
* Get indices
* @return Indices
*/
public List<Integer> getIndices() {
return indices;
}
/**
* Get interleaved vertices
* @return Interleaved vertices
*/
public List<Vector3f> getInterleavedVertices() {
return interleavedVertices;
}
/**
* Get interleaved stride
* @return Interleaved stride
*/
public int getInterleavedStride() {
return interleavedStride;
}
/**
* generate interleaved vertices: V/N/T
* stride must be 32 bytes
*/
void buildInterleavedVertices()
{
interleavedVertices = new ArrayList<>();
int i, j;
int count = vertices.size();
for(i = 0; i < count; i++)
{
interleavedVertices.add(vertices.get(i));
interleavedVertices.add(normals.get(i));
//interleavedVertices.add(texCoords.get(j));
//interleavedVertices.add(texCoords.get(j+1));
}
}
/**
* generate 3D vertices of a unit circle on XY place
*/
void buildUnitCircleVertices() {
float sectorStep = (float) (2 * Math.PI / sectorCount);
float sectorAngle; // radian
this.unitCircleVertices = new ArrayList<>();
float x, y, z = 0.f;
for(int i = 0; i <= sectorCount; ++i) {
sectorAngle = i * sectorStep;
x = (float) Math.cos(sectorAngle);
y = (float) Math.sin(sectorAngle);
unitCircleVertices.add(new Vector3f(x, y, z));
}
}
class Vertex {
public float x, y, z, s, t;
}
void clearArrays() {
this.vertices = new ArrayList<>();
this.normals = new ArrayList<>();
this.indices = new ArrayList<>();
this.lineIndices = new ArrayList<>();
this.texCoords = new ArrayList<>();
}
/**
* Add single vertex to array
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
*/
void addVertex(float x, float y, float z)
{
vertices.add(new Vector3f(x, y, z));
}
/**
* Add single normal to array
* @param nx Normal x
* @param ny Normal y
* @param nz Normal z
*/
void addNormal(float nx, float ny, float nz)
{
normals.add(new Vector3f(nx, ny, nz));
}
void addNormal(Vector3f n) {
normals.add(n);
}
/**
* Add single texture coord to array
* @param s
* @param t
*/
void addTexCoord(float s, float t)
{
texCoords.add(new Vector2f(s, t));
}
/**
* Add 3 indices to array
* @param i1 Index 1
* @param i2 Index 2
* @param i3 Index 3
*/
void addIndices(int i1, int i2, int i3) {
indices.add(i1);
indices.add(i2);
indices.add(i3);
}
/**
* build vertices of cylinder with smooth shading
* where v: sector angle (0 <= v <= 360)
*/
void buildVerticesSmooth()
{
// clear memory of prev arrays
clearArrays();
float x, y, z; // vertex position
//float s, t; // texCoord
float radius; // radius for each stack
// get normals for cylinder sides
List<Vector3f> sideNormals = getSideNormals();
// put vertices of side cylinder to array by scaling unit circle
for(int i = 0; i <= stackCount; ++i)
{
z = -(height * 0.5f) + (float)i / stackCount * height; // vertex position z
radius = baseRadius + (float)i / stackCount * (topRadius - baseRadius); // lerp
float t = 1.0f - (float)i / stackCount; // top-to-bottom
for(int j = 0; j <= sectorCount; ++j)
{
Vector3f v = unitCircleVertices.get(j);
addVertex(v.x * radius, v.y * radius, z); // position
Vector3f s = sideNormals.get(j);
addNormal(sideNormals.get(j)); // normal
addTexCoord((float)j / sectorCount, t); // tex coord
}
}
// remember where the base.top vertices start
int baseVertexIndex = vertices.size();
// put vertices of base of cylinder
z = -height * 0.5f;
addVertex(0, 0, z);
addNormal(0, 0, -1);
addTexCoord(0.5f, 0.5f);
for(int i = 0; i < sectorCount; ++i)
{
Vector3f v = unitCircleVertices.get(i);
addVertex(v.x * baseRadius, v.y * baseRadius, z);
addNormal(0, 0, -1);
addTexCoord(-v.x * 0.5f + 0.5f, -v.y * 0.5f + 0.5f); // flip horizontal
}
// remember where the base vertices start
int topVertexIndex = vertices.size();
// put vertices of top of cylinder
z = height * 0.5f;
addVertex(0, 0, z);
addNormal(0, 0, 1);
addTexCoord(0.5f, 0.5f);
for(int i = 0; i < sectorCount; ++i)
{
Vector3f v = unitCircleVertices.get(i);
addVertex(v.x * topRadius, v.y * topRadius, z);
addNormal(0, 0, 1);
addTexCoord(v.x * 0.5f + 0.5f, -v.y * 0.5f + 0.5f);
}
// put indices for sides
int k1, k2;
for(int i = 0; i < stackCount; ++i)
{
k1 = i * (sectorCount + 1); // beginning of current stack
k2 = k1 + sectorCount + 1; // beginning of next stack
for(int j = 0; j < sectorCount; ++j, ++k1, ++k2)
{
// 2 triangles per sector
addIndices(k1, k1 + 1, k2);
addIndices(k2, k1 + 1, k2 + 1);
// vertical lines for all stacks
lineIndices.add(k1);
lineIndices.add(k2);
// horizontal lines
lineIndices.add(k2);
lineIndices.add(k2 + 1);
if(i == 0) {
lineIndices.add(k1);
lineIndices.add(k1 + 1);
}
}
}
// remember where the base indices start
baseIndex = indices.size();
// put indices for base
for(int i = 0, k = baseVertexIndex + 1; i < sectorCount; ++i, ++k) {
if(i < (sectorCount - 1))
addIndices(baseVertexIndex, k + 1, k);
else // last triangle
addIndices(baseVertexIndex, baseVertexIndex + 1, k);
}
// remember where the base indices start
topIndex = indices.size();
for(int i = 0, k = topVertexIndex + 1; i < sectorCount; ++i, ++k) {
if(i < (sectorCount - 1))
addIndices(topVertexIndex, k, k + 1);
else
addIndices(topVertexIndex, k, topVertexIndex + 1);
}
// generate interleaved vertex array as well
buildInterleavedVertices();
}
/**
* generate vertices with flat shading
* each triangle is independent (no shared vertices)
*/
void buildVerticesFlat()
{
// tmp vertex definition (x,y,z,s,t)
List<Vertex> tmpVertices = new ArrayList<>();
int i, j, k; // indices
float x, y, z, s, t, radius;
// put tmp vertices of cylinder side to array by scaling unit circle
//NOTE: start and end vertex positions are same, but texcoords are different
// so, add additional vertex at the end point
for(i = 0; i <= stackCount; ++i) {
z = -(height * 0.5f) + (float)i / stackCount * height; // vertex position z
radius = baseRadius + (float)i / stackCount * (topRadius - baseRadius); // lerp
t = 1.0f - (float)i / stackCount; // top-to-bottom
for(j = 0; j <= sectorCount; ++j) {
Vector3f v = unitCircleVertices.get(j);
s = (float)j / sectorCount;
Vertex vertex = new Vertex();
vertex.x = v.x * radius;
vertex.y = v.y * radius;
vertex.z = z;
vertex.s = s;
vertex.t = t;
tmpVertices.add(vertex);
}
}
// clear memory of prev arrays
clearArrays();
Vertex v1, v2, v3, v4; // 4 vertex positions v1, v2, v3, v4
float[] n; // 1 face normal
int vi1, vi2; // indices
int index = 0;
// v2-v4 <== stack at i+1
// | \ |
// v1-v3 <== stack at i
for(i = 0; i < stackCount; ++i)
{
vi1 = i * (sectorCount + 1); // index of tmpVertices
vi2 = (i + 1) * (sectorCount + 1);
for(j = 0; j < sectorCount; ++j, ++vi1, ++vi2)
{
v1 = tmpVertices.get(vi1);
v2 = tmpVertices.get(vi2);
v3 = tmpVertices.get(vi1 + 1);
v4 = tmpVertices.get(vi2 + 1);
// compute a face normal of v1-v3-v2
n = computeFaceNormal(v1.x, v1.y, v1.z, v3.x, v3.y, v3.z, v2.x, v2.y, v2.z);
// put quad vertices: v1-v2-v3-v4
addVertex(v1.x, v1.y, v1.z);
addVertex(v2.x, v2.y, v2.z);
addVertex(v3.x, v3.y, v3.z);
addVertex(v4.x, v4.y, v4.z);
// put tex coords of quad
addTexCoord(v1.s, v1.t);
addTexCoord(v2.s, v2.t);
addTexCoord(v3.s, v3.t);
addTexCoord(v4.s, v4.t);
// put normal
for(k = 0; k < 4; ++k) // same normals for all 4 vertices
{
addNormal(n[0], n[1], n[2]);
}
// put indices of a quad
addIndices(index, index+2, index+1); // v1-v3-v2
addIndices(index+1, index+2, index+3); // v2-v3-v4
// vertical line per quad: v1-v2
lineIndices.add(index);
lineIndices.add(index+1);
// horizontal line per quad: v2-v4
lineIndices.add(index+1);
lineIndices.add(index+3);
if (i == 0) {
lineIndices.add(index);
lineIndices.add(index+2);
}
index += 4; // for next
}
}
// remember where the base index starts
baseIndex = indices.size();
int baseVertexIndex = vertices.size() / 3;
// put vertices of base of cylinder
z = -height * 0.5f;
addVertex(0, 0, z);
addNormal(0, 0, -1);
addTexCoord(0.5f, 0.5f);
for(i = 0; i < sectorCount; ++i)
{
Vector3f v = unitCircleVertices.get(i);
addVertex(v.x * baseRadius, v.y * baseRadius, z);
addNormal(0, 0, -1);
addTexCoord(-v.x * 0.5f + 0.5f, -v.y * 0.5f + 0.5f); // flip horizontal
}
// put indices for base
for(i = 0, k = baseVertexIndex + 1; i < sectorCount; ++i, ++k)
{
if(i < sectorCount - 1)
addIndices(baseVertexIndex, k + 1, k);
else
addIndices(baseVertexIndex, baseVertexIndex + 1, k);
}
// remember where the top index starts
topIndex = indices.size();
int topVertexIndex = vertices.size() / 3;
// put vertices of top of cylinder
z = height * 0.5f;
addVertex(0, 0, z);
addNormal(0, 0, 1);
addTexCoord(0.5f, 0.5f);
for(i = 0; i < sectorCount; ++i)
{
Vector3f v = unitCircleVertices.get(i);
addVertex(v.x * topRadius, v.y * topRadius, z);
addNormal(0, 0, 1);
addTexCoord(v.x * 0.5f + 0.5f, -v.y * 0.5f + 0.5f);
}
for(i = 0, k = topVertexIndex + 1; i < sectorCount; ++i, ++k)
{
if(i < sectorCount - 1)
addIndices(topVertexIndex, k, k + 1);
else
addIndices(topVertexIndex, k, topVertexIndex + 1);
}
// generate interleaved vertex array as well
buildInterleavedVertices();
}
///////////////////////////////////////////////////////////////////////////////
// generate shared normal vectors of the side of cylinder
///////////////////////////////////////////////////////////////////////////////
List<Vector3f> getSideNormals()
{
float sectorStep = (float) (2 * Math.PI / sectorCount);
float sectorAngle; // radian
// compute the normal vector at 0 degree first
// tanA = (baseRadius-topRadius) / height
float zAngle = (float) Math.atan2(baseRadius - topRadius, height);
float x0 = (float) Math.cos(zAngle); // nx
float y0 = 0; // ny
float z0 = (float) Math.sin(zAngle); // nz
// rotate (x0,y0,z0) per sector angle
List<Vector3f> normals = new ArrayList<>();
for(int i = 0; i <= sectorCount; ++i)
{
sectorAngle = i * sectorStep;
normals.add(new Vector3f((float) (Math.cos(sectorAngle)*x0 - Math.sin(sectorAngle)*y0),
(float) (Math.sin(sectorAngle)*x0 + Math.cos(sectorAngle)*y0), z0));
}
return normals;
}
///////////////////////////////////////////////////////////////////////////////
// return face normal of a triangle v1-v2-v3
// if a triangle has no surface (normal length = 0), then return a zero vector
///////////////////////////////////////////////////////////////////////////////
float[] computeFaceNormal(float x1, float y1, float z1, // v1
float x2, float y2, float z2, // v2
float x3, float y3, float z3) // v3
{
float EPSILON = 0.000001f;
float[] normal = new float[]{0.f, 0.f, 0.f}; // default return value (0,0,0)
float nx, ny, nz;
// find 2 edge vectors: v1-v2, v1-v3
float ex1 = x2 - x1;
float ey1 = y2 - y1;
float ez1 = z2 - z1;
float ex2 = x3 - x1;
float ey2 = y3 - y1;
float ez2 = z3 - z1;
// cross product: e1 x e2
nx = ey1 * ez2 - ez1 * ey2;
ny = ez1 * ex2 - ex1 * ez2;
nz = ex1 * ey2 - ey1 * ex2;
// normalize only if the length is > 0
float length = (float) Math.sqrt(nx * nx + ny * ny + nz * nz);
if(length > EPSILON) {
// normalize
float lengthInv = 1.0f / length;
normal[0] = nx * lengthInv;
normal[1] = ny * lengthInv;
normal[2] = nz * lengthInv;
}
return normal;
}
}

View File

@ -1,18 +1,20 @@
package org.meteoinfo.chart.graphic.pipe;
import org.joml.Vector3f;
import org.meteoinfo.math.Matrix4f;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
/**
* base contour following a path
* ported from C++ code by Song Ho Ahn (song.ahn@gmail.com)
*/
public class Pipe {
private Vector<Vector3f> path;
private Vector<Vector3f> contour;
private Vector<Vector<Vector3f>> contours;
private Vector<Vector<Vector3f>> normals;
private List<Vector3f> path;
private List<Vector3f> contour;
private List<List<Vector3f>> contours;
private List<List<Vector3f>> normals;
/**
* Constructor
@ -26,7 +28,7 @@ public class Pipe {
* @param pathPoints Path points
* @param contourPoints Contour points
*/
public Pipe(Vector<Vector3f> pathPoints, Vector<Vector3f> contourPoints) {
public Pipe(List<Vector3f> pathPoints, List<Vector3f> contourPoints) {
this.path = pathPoints;
this.contour = contourPoints;
generateContours();
@ -38,9 +40,9 @@ public class Pipe {
* @param radius Contour radius
* @param steps Contour steps
*/
public Pipe(Vector<Vector3f> pathPoint, float radius, int steps) {
public Pipe(List<Vector3f> pathPoint, float radius, int steps) {
this.path = pathPoint;
this.contour = new Vector<>();
this.contour = new ArrayList<>();
float x, y, a;
for (int i = 0; i < steps; i++) {
a = (float) (Math.PI * 2 / steps * i);
@ -57,7 +59,7 @@ public class Pipe {
* Get path
* @return Path
*/
public Vector<Vector3f> getPath() {
public List<Vector3f> getPath() {
return this.path;
}
@ -65,7 +67,7 @@ public class Pipe {
* Set path
* @param pathPoints Path points
*/
public void setPath(Vector<Vector3f> pathPoints) {
public void setPath(List<Vector3f> pathPoints) {
this.path = pathPoints;
generateContours();
}
@ -74,7 +76,7 @@ public class Pipe {
* Get contour
* @return Contour
*/
public Vector<Vector3f> getContour() {
public List<Vector3f> getContour() {
return this.contour;
}
@ -83,7 +85,7 @@ public class Pipe {
* @param idx Index
* @return Contour
*/
public Vector<Vector3f> getContour(int idx) {
public List<Vector3f> getContour(int idx) {
return this.contours.get(idx);
}
@ -91,7 +93,7 @@ public class Pipe {
* Set contour
* @param contourPoints Contour points
*/
public void setContour(Vector<Vector3f> contourPoints) {
public void setContour(List<Vector3f> contourPoints) {
this.contour = contourPoints;
generateContours();
}
@ -125,7 +127,7 @@ public class Pipe {
* @param idx Index
* @return Normal
*/
public Vector<Vector3f> getNormal(int idx) {
public List<Vector3f> getNormal(int idx) {
return this.normals.get(idx);
}
@ -152,7 +154,7 @@ public class Pipe {
else
{
// add dummy to match same # of contours/normals and path
Vector<Vector3f> dummy = new Vector<>();
List<Vector3f> dummy = new ArrayList<>();
contours.add(dummy);
normals.add(dummy);
@ -169,8 +171,8 @@ public class Pipe {
void generateContours()
{
// reset
contours = new Vector<>();
normals = new Vector<>();
contours = new ArrayList<>();
normals = new ArrayList<>();
// path must have at least a point
if(path.size() < 1)
@ -223,7 +225,7 @@ public class Pipe {
* @param toIndex To index
* @return Projected contour
*/
Vector<Vector3f> projectContour(int fromIndex, int toIndex)
List<Vector3f> projectContour(int fromIndex, int toIndex)
{
Vector3f dir1, dir2, normal;
Line line = new Line();
@ -238,8 +240,8 @@ public class Pipe {
Plane plane = new Plane(normal, path.get(toIndex));
// project each vertex of contour to the plane
Vector<Vector3f> fromContour = contours.get(fromIndex);
Vector<Vector3f> toContour = new Vector<>();
List<Vector3f> fromContour = contours.get(fromIndex);
List<Vector3f> toContour = new ArrayList<>();
int count = (int)fromContour.size();
for(int i = 0; i < count; ++i)
{
@ -255,13 +257,13 @@ public class Pipe {
* @param pathIndex Path index
* @return Contour normal
*/
Vector<Vector3f> computeContourNormal(int pathIndex)
List<Vector3f> computeContourNormal(int pathIndex)
{
// get current contour and center point
Vector<Vector3f> contour = contours.get(pathIndex);
List<Vector3f> contour = contours.get(pathIndex);
Vector3f center = path.get(pathIndex);
Vector<Vector3f> contourNormal = new Vector<>();
List<Vector3f> contourNormal = new ArrayList<>();
Vector3f normal;
for(int i = 0; i < (int)contour.size(); ++i)
{

View File

@ -5,8 +5,8 @@ import org.meteoinfo.geometry.shape.PointZ;
import org.meteoinfo.geometry.shape.PolylineZShape;
import org.joml.Vector3f;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class PipeShape extends PolylineZShape {
private float radius = 0.05f;
@ -65,7 +65,7 @@ public class PipeShape extends PolylineZShape {
}
void generatePipe() {
Vector<Vector3f> path = new Vector<>();
List<Vector3f> path = new ArrayList<>();
for (PointZ p : (List<PointZ>) this.getPoints()) {
path.add(new Vector3f((float)p.X, (float)p.Y, (float)p.Z));
}
@ -83,7 +83,7 @@ public class PipeShape extends PolylineZShape {
}
this.transform = (Transform) transform.clone();
Vector<Vector3f> path = new Vector<>();
List<Vector3f> path = new ArrayList<>();
for (PointZ p : (List<PointZ>) this.getPoints()) {
path.add(new Vector3f(transform.transform_x((float)p.X), transform.transform_y((float)p.Y),
transform.transform_z((float)p.Z)));

View File

@ -2509,14 +2509,16 @@ public class GLPlot extends Plot {
break;
case POLYLINE_Z:
boolean useRender = true;
ColorBreak cb = graphic.getGraphicN(0).getLegend();
/*ColorBreak cb = graphic.getGraphicN(0).getLegend();
if (cb instanceof StreamlineBreak) {
useRender = false;
if (graphic.getGraphicN(0).getShape() instanceof PipeShape)
useRender = false;
} else if (cb instanceof ColorBreakCollection) {
if (((ColorBreakCollection) cb).get(0) instanceof StreamlineBreak) {
useRender = false;
if (graphic.getGraphicN(0).getShape() instanceof PipeShape)
useRender = false;
}
}
}*/
if (useRender) {
if (graphic.getGraphicN(0).getShape() instanceof PipeShape) {
if (!this.renderMap.containsKey(graphic)) {
@ -2904,10 +2906,10 @@ public class GLPlot extends Plot {
PolylineBreak plb = (PolylineBreak) cbc.get(i);
rgba = plb.getColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < c2.size(); ++j)
{
@ -2925,10 +2927,10 @@ public class GLPlot extends Plot {
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
for(int i = 0; i < count - 1; i++)
{
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -2988,7 +2990,7 @@ public class GLPlot extends Plot {
}
} else {
StreamlineBreak slb = (StreamlineBreak) cb;
int interval = slb.getInterval() * 3;
int interval = slb.getInterval();
float[] rgba = slb.getColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
gl.glLineWidth(slb.getWidth() * this.dpiScale);
@ -3044,10 +3046,10 @@ public class GLPlot extends Plot {
StreamlineBreak plb = (StreamlineBreak) cbc.get(i);
rgba = plb.getColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -3060,7 +3062,7 @@ public class GLPlot extends Plot {
}
//Draw arrow
Vector<Vector3f> path = pipe.getPath();
List<Vector3f> path = pipe.getPath();
StreamlineBreak slb = (StreamlineBreak) cbc.get(0);
int interval = slb.getInterval();
if (slb.getArrowHeadLength() > 0 || slb.getArrowHeadWidth() > 0) {
@ -3084,10 +3086,10 @@ public class GLPlot extends Plot {
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
for(int i = 0; i < count - 1; i++)
{
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -3100,7 +3102,7 @@ public class GLPlot extends Plot {
}
//Draw arrow
Vector<Vector3f> path = pipe.getPath();
List<Vector3f> path = pipe.getPath();
if (slb.getArrowHeadLength() > 0 || slb.getArrowHeadWidth() > 0) {
float[] p2, p1;
Vector3f pp;

View File

@ -2888,10 +2888,10 @@ public class Plot3DGL extends Plot implements GLEventListener {
PolylineBreak plb = (PolylineBreak) cbc.get(i);
rgba = plb.getColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -2909,10 +2909,10 @@ public class Plot3DGL extends Plot implements GLEventListener {
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
for(int i = 0; i < count - 1; i++)
{
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -3028,10 +3028,10 @@ public class Plot3DGL extends Plot implements GLEventListener {
StreamlineBreak plb = (StreamlineBreak) cbc.get(i);
rgba = plb.getColor().getRGBComponents(null);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -3044,7 +3044,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
}
//Draw arrow
Vector<Vector3f> path = pipe.getPath();
List<Vector3f> path = pipe.getPath();
StreamlineBreak slb = (StreamlineBreak) cbc.get(0);
int interval = slb.getInterval();
if (slb.getArrowHeadLength() > 0 || slb.getArrowHeadWidth() > 0) {
@ -3068,10 +3068,10 @@ public class Plot3DGL extends Plot implements GLEventListener {
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
for(int i = 0; i < count - 1; i++)
{
Vector<Vector3f> c1 = pipe.getContour(i);
Vector<Vector3f> c2 = pipe.getContour(i+1);
Vector<Vector3f> n1 = pipe.getNormal(i);
Vector<Vector3f> n2 = pipe.getNormal(i+1);
List<Vector3f> c1 = pipe.getContour(i);
List<Vector3f> c2 = pipe.getContour(i+1);
List<Vector3f> n1 = pipe.getNormal(i);
List<Vector3f> n2 = pipe.getNormal(i+1);
gl.glBegin(GL_TRIANGLE_STRIP);
for(int j = 0; j < (int)c2.size(); ++j)
{
@ -3084,7 +3084,7 @@ public class Plot3DGL extends Plot implements GLEventListener {
}
//Draw arrow
Vector<Vector3f> path = pipe.getPath();
List<Vector3f> path = pipe.getPath();
if (slb.getArrowHeadLength() > 0 || slb.getArrowHeadWidth() > 0) {
float[] p2, p1;
Vector3f pp;

View File

@ -4,7 +4,10 @@ import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.util.GLBuffers;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;
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;
@ -14,6 +17,7 @@ import org.meteoinfo.geometry.shape.PointZ;
import org.meteoinfo.geometry.shape.Polyline;
import org.meteoinfo.geometry.shape.PolylineZ;
import org.meteoinfo.geometry.shape.PolylineZShape;
import org.meteoinfo.math.Matrix4f;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@ -34,6 +38,15 @@ public class LineRender extends JOGLGraphicRender {
private float[] vertexColor;
private float lineWidth = 1.0f;
private List<Integer> linePointNumbers;
private boolean streamline = false;
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
@ -63,6 +76,15 @@ public class LineRender extends JOGLGraphicRender {
this(gl);
this.graphics = graphics;
ColorBreak cb = graphics.getGraphicN(0).getLegend();
PolylineBreak lineBreak;
if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) {
lineBreak = (PolylineBreak) ((ColorBreakCollection) cb).get(0);
} else {
lineBreak = (PolylineBreak) cb;
}
this.streamline = lineBreak instanceof StreamlineBreak;
this.updateVertexColor();
}
@ -129,6 +151,121 @@ public class LineRender extends JOGLGraphicRender {
return vertexData;
}
private void updateConeVertex() {
List<Vector3f> vertexPositionList = new ArrayList<>();
List<Vector3f> vertexNormalList = new ArrayList<>();
List<Vector4f> vertexColorList = new ArrayList<>();
List<Integer> vertexIndices = new ArrayList<>();
for (Graphic graphic : this.graphics.getGraphics()) {
PolylineZShape shape = (PolylineZShape) graphic.getShape();
int pointNum = shape.getPointNum();
List<PointZ> ps = (List<PointZ>) shape.getPoints();
ColorBreak cb = graphic.getLegend();
if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) {
ColorBreakCollection cbc = (ColorBreakCollection) cb;
StreamlineBreak slb = (StreamlineBreak) cbc.get(0);
int interval = slb.getInterval();
Vector3f v1, v2;
for (int i = 1; i < pointNum; i++) {
if (i % interval == 0) {
PointZ p2 = ps.get(i);
PointZ p1 = ps.get(i - 1);
v1 = transform.transform((float) p1.X, (float) p1.Y, (float) p1.Z);
v2 = transform.transform((float) p2.X, (float) p2.Y, (float) p2.Z);
slb = (StreamlineBreak) cbc.get(i);
Cylinder cylinder = new Cylinder(slb.getArrowHeadWidth() * 0.02f,
0, slb.getArrowHeadLength() * 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));
}
float[] color = slb.getColor().getRGBComponents(null);
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);
}
}
}
}
} else {
StreamlineBreak slb = (StreamlineBreak) cb;
int interval = slb.getInterval();
Vector3f v1, v2;
for (int i = 1; i < pointNum; i++) {
if (i % interval == 0) {
PointZ p2 = ps.get(i);
PointZ p1 = ps.get(i - 1);
v1 = transform.transform((float) p1.X, (float) p1.Y, (float) p1.Z);
v2 = transform.transform((float) p2.X, (float) p2.Y, (float) p2.Z);
Cylinder cylinder = new Cylinder(slb.getArrowHeadWidth() * 0.02f,
0, slb.getArrowHeadLength() * 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));
}
float[] color = slb.getColor().getRGBComponents(null);
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();
}
@Override
public void setTransform(Transform transform, boolean alwaysUpdateBuffers) {
boolean updateBuffer = true;
@ -152,6 +289,34 @@ public class LineRender extends JOGLGraphicRender {
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);
if (this.streamline) {
this.updateConeVertex();
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);
}
}
}
@ -193,6 +358,28 @@ public class LineRender extends JOGLGraphicRender {
gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
if (this.streamline) {
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);
}
}
}
}

View File

@ -4,16 +4,19 @@ 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.chart.graphic.pipe.Pipe;
import org.meteoinfo.chart.graphic.pipe.PipeShape;
import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.geometry.legend.BreakTypes;
import org.meteoinfo.geometry.legend.ColorBreak;
import org.meteoinfo.geometry.legend.ColorBreakCollection;
import org.meteoinfo.geometry.legend.*;
import org.meteoinfo.geometry.shape.PointZ;
import org.meteoinfo.geometry.shape.PolylineZShape;
import org.meteoinfo.math.Matrix4f;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@ -33,6 +36,15 @@ public class PipeRender extends JOGLGraphicRender{
private float[] vertexColor;
private int[] vertexIndices;
private List<Integer> linePointNumbers;
private boolean streamline = false;
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
@ -66,6 +78,15 @@ public class PipeRender extends JOGLGraphicRender{
for (Graphic graphic : this.graphics.getGraphics()) {
this.vertexNum += ((PipeShape) graphic.getShape()).getVertexCount();
}
ColorBreak cb = graphics.getGraphicN(0).getLegend();
PolylineBreak lineBreak;
if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) {
lineBreak = (PolylineBreak) ((ColorBreakCollection) cb).get(0);
} else {
lineBreak = (PolylineBreak) cb;
}
this.streamline = lineBreak instanceof StreamlineBreak;
}
void compileShaders() throws Exception {
@ -146,8 +167,8 @@ public class PipeRender extends JOGLGraphicRender{
Pipe pipe = shape.getPipe();
int n = pipe.getContour().size();
for (int j = 0; j < pipe.getContourCount() - 1; j++) {
Vector<Vector3f> c1 = pipe.getContour(j);
Vector<Vector3f> c2 = pipe.getContour(j + 1);
List<Vector3f> c1 = pipe.getContour(j);
List<Vector3f> c2 = pipe.getContour(j + 1);
for (int k = 0; k < n - 1; k++) {
vertexIndices[i++] = b + j * n + k;
vertexIndices[i++] = b + j * n + k + 1;
@ -181,6 +202,121 @@ public class PipeRender extends JOGLGraphicRender{
return vertexNormal;
}
private void updateConeVertex() {
List<Vector3f> vertexPositionList = new ArrayList<>();
List<Vector3f> vertexNormalList = new ArrayList<>();
List<Vector4f> vertexColorList = new ArrayList<>();
List<Integer> vertexIndices = new ArrayList<>();
for (Graphic graphic : this.graphics.getGraphics()) {
PolylineZShape shape = (PolylineZShape) graphic.getShape();
int pointNum = shape.getPointNum();
List<PointZ> ps = (List<PointZ>) shape.getPoints();
ColorBreak cb = graphic.getLegend();
if (cb.getBreakType() == BreakTypes.COLOR_BREAK_COLLECTION) {
ColorBreakCollection cbc = (ColorBreakCollection) cb;
StreamlineBreak slb = (StreamlineBreak) cbc.get(0);
int interval = slb.getInterval();
Vector3f v1, v2;
for (int i = 1; i < pointNum; i++) {
if (i % interval == 0) {
PointZ p2 = ps.get(i);
PointZ p1 = ps.get(i - 1);
v1 = transform.transform((float) p1.X, (float) p1.Y, (float) p1.Z);
v2 = transform.transform((float) p2.X, (float) p2.Y, (float) p2.Z);
slb = (StreamlineBreak) cbc.get(i);
Cylinder cylinder = new Cylinder(slb.getArrowHeadWidth() * 0.02f,
0, slb.getArrowHeadLength() * 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));
}
float[] color = slb.getColor().getRGBComponents(null);
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);
}
}
}
}
} else {
StreamlineBreak slb = (StreamlineBreak) cb;
int interval = slb.getInterval();
Vector3f v1, v2;
for (int i = 1; i < pointNum; i++) {
if (i % interval == 0) {
PointZ p2 = ps.get(i);
PointZ p1 = ps.get(i - 1);
v1 = transform.transform((float) p1.X, (float) p1.Y, (float) p1.Z);
v2 = transform.transform((float) p2.X, (float) p2.Y, (float) p2.Z);
Cylinder cylinder = new Cylinder(slb.getArrowHeadWidth() * 0.02f,
0, slb.getArrowHeadLength() * 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));
}
float[] color = slb.getColor().getRGBComponents(null);
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();
}
@Override
public void setTransform(Transform transform, boolean alwaysUpdateBuffers) {
boolean updateBuffer = true;
@ -220,6 +356,34 @@ public class PipeRender extends JOGLGraphicRender{
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo.get(1));
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * Integer.BYTES, indexBuffer, GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
if (this.streamline) {
this.updateConeVertex();
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);
}
}
}
@ -254,6 +418,28 @@ public class PipeRender extends JOGLGraphicRender{
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
if (this.streamline) {
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);
}
}
}
}

View File

@ -1,4 +1,4 @@
package org.meteoinfo.chart.graphic.pipe;
package org.meteoinfo.math;
import org.joml.Vector3f;

View File

@ -12,51 +12,19 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="meteoinfo-math" />
<orderEntry type="module" module-name="meteoinfo-geometry" />
<orderEntry type="module" module-name="meteoinfo-table" />
<orderEntry type="module" module-name="meteoinfo-image" />
<orderEntry type="module" module-name="meteoinfo-data" />
<orderEntry type="library" name="Maven: org.meteothink:wContour:1.7.1" level="project" />
<orderEntry type="library" name="Maven: com.l2fprod:l2fprod-common-all:6.9.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath:1.0.7" level="project" />
<orderEntry type="library" name="Maven: com.formdev:flatlaf:3.0" level="project" />
<orderEntry type="library" name="Maven: com.formdev:flatlaf-extras:3.0" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-util:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-emf:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-pdf:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphics2d:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-ps:2.4" level="project" />
<orderEntry type="library" name="Maven: com.itextpdf:itextpdf:5.5.13.3" level="project" />
<orderEntry type="module" module-name="meteoinfo-ndarray" />
<orderEntry type="module" module-name="meteoinfo-common" />
<orderEntry type="library" name="Maven: org.ejml:ejml-experimental:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-simple:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ojalgo:ojalgo:52.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.haifengl:smile-interpolation:2.6.0" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp-platform:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.10-1.5.4" level="project" />
<orderEntry type="module" module-name="meteoinfo-ui" />
<orderEntry type="library" name="Maven: org.locationtech.jts:jts-core:1.19.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-imaging:1.0-alpha3" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.imageio:imageio-jpeg:3.9.4" level="project" />
<orderEntry type="module" module-name="meteoinfo-projection" />
<orderEntry type="module" module-name="meteoinfo-dataframe" />
<orderEntry type="library" name="Maven: edu.ucar:netcdfAll:5.5.3" level="project" />
<orderEntry type="library" name="Maven: com.github.albfernandez:juniversalchardet:2.4.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath-font-greek:1.0.7" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath-font-cyrillic:1.0.7" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.formdev:svgSalamander:1.1.3" level="project" />
<orderEntry type="library" name="Maven: org.netbeans:openide-lookup:1.9-patched-1.0" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-tests:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsbase:2.4" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy:4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy:4.0-beta1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-complex:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-angle:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-rootfinder:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-quaternion:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-rng-sampling:1.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy-exception:4.0-beta1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy-core:4.0-beta1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-core:4.0-beta1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-core:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-gamma:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-fraction:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-combinatorics:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-arrays:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-field:1.1" level="project" />
@ -65,15 +33,28 @@
<orderEntry type="library" name="Maven: org.apache.commons:commons-rng-client-api:1.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-statistics-distribution:1.0" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:2.1.0" level="project" />
<orderEntry type="module" module-name="meteoinfo-common" />
<orderEntry type="library" name="Maven: com.google.guava:guava:31.1-jre" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-core:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-ddense:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-dsparse:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-zdense:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-fdense:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-cdense:0.41" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-fsparse:0.41" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.12.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.11.0" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-experimental:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-core:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-ddense:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-dsparse:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-zdense:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-simple:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-fdense:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-cdense:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ejml:ejml-fsparse:0.41.1" level="project" />
<orderEntry type="library" name="Maven: org.ojalgo:ojalgo:52.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.haifengl:smile-interpolation:2.6.0" level="project" />
<orderEntry type="library" name="Maven: com.github.haifengl:smile-math:2.6.0" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp-platform:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-arm:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-arm64:1.5.4" level="project" />
@ -89,6 +70,7 @@
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:macosx-x86_64:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:windows-x86:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:windows-x86_64:1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.10-1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas:0.3.10-1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm:0.3.10-1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm64:0.3.10-1.5.4" level="project" />
@ -104,31 +86,49 @@
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-x86_64:0.3.10-1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86:0.3.10-1.5.4" level="project" />
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86_64:0.3.10-1.5.4" level="project" />
<orderEntry type="module" module-name="meteoinfo-geometry" />
<orderEntry type="module" module-name="meteoinfo-ui" />
<orderEntry type="library" name="Maven: com.toedter:jcalendar:1.4" level="project" />
<orderEntry type="library" name="Maven: org.locationtech.jts:jts-core:1.19.0" level="project" />
<orderEntry type="module" module-name="meteoinfo-table" />
<orderEntry type="module" module-name="meteoinfo-image" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-imaging:1.0-alpha3" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.imageio:imageio-jpeg:3.9.4" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.imageio:imageio-core:3.9.4" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.imageio:imageio-metadata:3.9.4" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.common:common-lang:3.9.4" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.common:common-io:3.9.4" level="project" />
<orderEntry type="library" name="Maven: com.twelvemonkeys.common:common-image:3.9.4" level="project" />
<orderEntry type="module" module-name="meteoinfo-data" />
<orderEntry type="module" module-name="meteoinfo-projection" />
<orderEntry type="library" name="Maven: org.locationtech.proj4j:proj4j:1.2.2" level="project" />
<orderEntry type="library" name="Maven: net.sf.geographiclib:GeographicLib-Java:2.0" level="project" />
<orderEntry type="module" module-name="meteoinfo-dataframe" />
<orderEntry type="library" name="Maven: edu.ucar:netcdfAll:5.5.3" level="project" />
<orderEntry type="library" name="Maven: com.github.albfernandez:juniversalchardet:2.4.0" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.11.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
<orderEntry type="library" name="Maven: org.meteothink:wContour:1.7.1" level="project" />
<orderEntry type="library" name="Maven: com.l2fprod:l2fprod-common-all:6.9.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath:1.0.7" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath-font-greek:1.0.7" level="project" />
<orderEntry type="library" name="Maven: org.scilab.forge:jlatexmath-font-cyrillic:1.0.7" level="project" />
<orderEntry type="library" name="Maven: com.formdev:flatlaf:3.0" level="project" />
<orderEntry type="library" name="Maven: com.formdev:flatlaf-extras:3.0" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.formdev:svgSalamander:1.1.3" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-util:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.netbeans:openide-lookup:1.9-patched-1.0" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-emf:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-io:2.2.2" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-tests:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsbase:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-pdf:2.4" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphics2d:2.4" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-complex:1.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-angle:1.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-rootfinder:1.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-quaternion:1.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-rng-sampling:1.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy-exception:4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-legacy-core:4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-numbers-fraction:1.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.12.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.11.0" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-math4-core:4.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: org.freehep:freehep-graphicsio-ps:2.4" level="project" />
<orderEntry type="library" name="Maven: com.itextpdf:itextpdf:5.5.13.3" level="project" />
</component>
</module>

View File

@ -21,7 +21,7 @@ public class StreamlineBreak extends ArrowLineBreak {
super();
this.arrowHeadWidth = 7;
this.arrowOverhang = 0.5f;
this.interval = 3;
this.interval = 10;
}
/**
@ -30,7 +30,7 @@ public class StreamlineBreak extends ArrowLineBreak {
*/
public StreamlineBreak(PolylineBreak pb) {
super(pb);
this.interval = 3;
this.interval = 10;
}
// </editor-fold>
// <editor-fold desc="Get Set Methods">

View File

@ -1,32 +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\plot">
<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"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\image"/>
<RecentFolder Folder="D:\Working\MIScript\cuace_dust\py\plot"/>
<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\LaSW"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\LaSW\airship"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\streamplot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\plot"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\topology"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\quiver"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot\plot3_pipe_color_1.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"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\MyProgram\java\MeteoInfoDev\toolbox\meteoview3d\mainGUI.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot\plot3_pipe_color_1.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"/>
</RecentFiles>
</File>
<Font>
@ -34,5 +36,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="0,0" MainFormSize="1396,811"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
</MeteoInfo>

View File

@ -703,7 +703,7 @@ def line2arrow(lb, **kwargs):
def line2stream(lb, **kwargs):
"""
Convert linestring break to stream line break.
Convert linestring break to streamline break.
:param lb: (*PolylineBreak*) Linestring break.
:param headwidth: (*float*) Arrow head width. Default is ``width*5``.

View File

@ -693,9 +693,9 @@ public class FrmMain extends javax.swing.JFrame implements IApplication {
jProgressBar_Run.setVisible(false);
jPanel_Status.add(jProgressBar_Run, BorderLayout.WEST);
//Memory progress bar
int maxMemory = (int)(Runtime.getRuntime().maxMemory() / (1024 * 1024 * 1024));
float maxMemory = (float) (Runtime.getRuntime().maxMemory() / (1024. * 1024. * 1024.));
jProgressBar_Memory.setStringPainted(true);
jProgressBar_Memory.setString(String.format("%dG", maxMemory));
jProgressBar_Memory.setString(String.format("%.1fG", maxMemory));
java.util.Timer timer = new java.util.Timer();
timer.schedule(new TimerTask() {
@Override
@ -703,7 +703,7 @@ public class FrmMain extends javax.swing.JFrame implements IApplication {
int ratio = (int) ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) *
100. / Runtime.getRuntime().maxMemory());
jProgressBar_Memory.setValue(ratio);
jProgressBar_Memory.setString(String.format("%d%% / %dG", ratio, maxMemory));
jProgressBar_Memory.setString(String.format("%d%% / %.1fG", ratio, maxMemory));
}
}, 1000,1000);
jPanel_Status.add(jProgressBar_Memory, java.awt.BorderLayout.EAST);