diff --git a/src/main/java/net/imagej/mesh/Mesh.java b/src/main/java/net/imagej/mesh/Mesh.java index 681c013..ddb1ab8 100644 --- a/src/main/java/net/imagej/mesh/Mesh.java +++ b/src/main/java/net/imagej/mesh/Mesh.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -85,9 +85,25 @@ */ public interface Mesh { - /** The mesh's collection of vertices. */ - Vertices vertices(); + /** + * The mesh's collection of vertices. + */ + Vertices vertices(); + + /** + * The mesh's collection of triangles. + */ + Triangles triangles(); + + /** + * Return a copy of the mesh. + */ + default Mesh copy() { + Mesh c = this.createVariable(); + c.vertices().set(vertices().copy()); + c.triangles().set(triangles().copy()); + return c; + } - /** The mesh's collection of triangles. */ - Triangles triangles(); + Mesh createVariable(); } diff --git a/src/main/java/net/imagej/mesh/Meshes.java b/src/main/java/net/imagej/mesh/Meshes.java index a370167..896cdc4 100644 --- a/src/main/java/net/imagej/mesh/Meshes.java +++ b/src/main/java/net/imagej/mesh/Meshes.java @@ -50,7 +50,7 @@ public class Meshes { */ public static RealPoint center(final Mesh m) { RealPoint p = new RealPoint(0, 0, 0); - for (final Vertex v: m.vertices()) { + for (final Vertex v : m.vertices()) { p.move(v); } for (int d = 0; d < 3; d++) { @@ -63,7 +63,7 @@ public static float[] boundingBox(final net.imagej.mesh.Mesh mesh) { final float[] boundingBox = new float[]{Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY}; - for (final Vertex v: mesh.vertices()) { + for (final Vertex v : mesh.vertices()) { final float x = v.xf(), y = v.yf(), z = v.zf(); if (x < boundingBox[0]) boundingBox[0] = x; if (y < boundingBox[1]) boundingBox[1] = y; @@ -85,7 +85,7 @@ public static void copy(final net.imagej.mesh.Mesh src, final net.imagej.mesh.Mesh dest) { final Map vIndexMap = new HashMap<>(); // Copy the vertices, keeping track when indices change. - for (final Vertex v: src.vertices()) { + for (final Vertex v : src.vertices()) { long srcIndex = v.index(); long destIndex = dest.vertices().add(// v.x(), v.y(), v.z(), // @@ -103,7 +103,7 @@ public static void copy(final net.imagej.mesh.Mesh src, } } // Copy the triangles, taking care to use destination indices. - for (final Triangle tri: src.triangles()) { + for (final Triangle tri : src.triangles()) { final long v0src = tri.vertex0(); final long v1src = tri.vertex1(); final long v2src = tri.vertex2(); @@ -125,7 +125,7 @@ public static void calculateNormals(net.imagej.mesh.Mesh src, net.imagej.mesh.Me // Compute the triangle normals. HashMap triNormals = new HashMap<>(); - for (final Triangle tri: src.triangles()) { + for (final Triangle tri : src.triangles()) { final int v0 = (int) tri.vertex0(); final int v1 = (int) tri.vertex1(); final int v2 = (int) tri.vertex2(); @@ -159,9 +159,9 @@ public static void calculateNormals(net.imagej.mesh.Mesh src, net.imagej.mesh.Me // Next, compute the normals per vertex based on face normals HashMap vNormals = new HashMap<>();// Note: these are cumulative until normalized by vNbrCount float[] cumNormal, triNormal; - for (final Triangle tri: src.triangles()) { + for (final Triangle tri : src.triangles()) { triNormal = triNormals.get(tri.index()); - for (long idx: new long[]{tri.vertex0(), tri.vertex1(), tri.vertex2()}) { + for (long idx : new long[]{tri.vertex0(), tri.vertex1(), tri.vertex2()}) { cumNormal = vNormals.getOrDefault(idx, new float[]{0, 0, 0}); cumNormal[0] += triNormal[0]; cumNormal[1] += triNormal[1]; @@ -175,7 +175,7 @@ public static void calculateNormals(net.imagej.mesh.Mesh src, net.imagej.mesh.Me float[] vNormal; double vNormalMag; // Copy the vertices, keeping track when indices change. - for (final Vertex v: src.vertices()) { + for (final Vertex v : src.vertices()) { long srcIndex = v.index(); vNormal = vNormals.get(v.index()); vNormalMag = Math.sqrt(Math.pow(vNormal[0], 2) + Math.pow(vNormal[1], 2) + Math.pow(vNormal[2], 2)); @@ -195,7 +195,7 @@ public static void calculateNormals(net.imagej.mesh.Mesh src, net.imagej.mesh.Me } } // Copy the triangles, taking care to use destination indices. - for (final Triangle tri: src.triangles()) { + for (final Triangle tri : src.triangles()) { final long v0src = tri.vertex0(); final long v1src = tri.vertex1(); final long v2src = tri.vertex2(); diff --git a/src/main/java/net/imagej/mesh/Triangle.java b/src/main/java/net/imagej/mesh/Triangle.java index ae1af4c..187f46c 100644 --- a/src/main/java/net/imagej/mesh/Triangle.java +++ b/src/main/java/net/imagej/mesh/Triangle.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -38,166 +38,222 @@ */ public interface Triangle { - /** - * The mesh to which the triangle belongs. - * - * @see Mesh#triangles() - */ - Mesh mesh(); - - /** Index into the mesh's list of triangles. */ - long index(); - - /** Index of first vertex in the triangle. */ - default long vertex0() { - return mesh().triangles().vertex0(index()); - } - - /** Index of second vertex in the triangle. */ - default long vertex1() { - return mesh().triangles().vertex1(index()); - } - - /** Index of third vertex in the triangle. */ - default long vertex2() { - return mesh().triangles().vertex2(index()); - } - - /** X coordinate of triangle's first vertex, as a float. */ - default float v0xf() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().xf(vIndex); - } - - /** Y coordinate of triangle's first vertex, as a float. */ - default float v0yf() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().yf(vIndex); - } - - /** Z coordinate of triangle's first vertex, as a float. */ - default float v0zf() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().zf(vIndex); - } - - /** X coordinate of triangle's second vertex, as a float. */ - default float v1xf() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().xf(vIndex); - } - - /** Y coordinate of triangle's second vertex, as a float. */ - default float v1yf() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().yf(vIndex); - } - - /** Z coordinate of triangle's second vertex, as a float. */ - default float v1zf() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().zf(vIndex); - } - - /** X coordinate of triangle's third vertex, as a float. */ - default float v2xf() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().xf(vIndex); - } - - /** Y coordinate of triangle's third vertex, as a float. */ - default float v2yf() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().yf(vIndex); - } - - /** Z coordinate of triangle's third vertex, as a float. */ - default float v2zf() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().zf(vIndex); - } - - /** X coordinate of triangle's normal, as a float. */ - default float nxf() { - return mesh().triangles().nxf(index()); - } - - /** Y coordinate of triangle's normal, as a float. */ - default float nyf() { - return mesh().triangles().nyf(index()); - } - - /** Z coordinate of triangle's normal, as a float. */ - default float nzf() { - return mesh().triangles().nzf(index()); - } - - /** X coordinate of triangle's first vertex, as a double. */ - default double v0x() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().x(vIndex); - } - - /** Y coordinate of triangle's first vertex, as a double. */ - default double v0y() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().y(vIndex); - } - - /** Z coordinate of triangle's first vertex, as a double. */ - default double v0z() { - final long vIndex = mesh().triangles().vertex0(index()); - return mesh().vertices().z(vIndex); - } - - /** X coordinate of triangle's second vertex, as a double. */ - default double v1x() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().x(vIndex); - } - - /** Y coordinate of triangle's second vertex, as a double. */ - default double v1y() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().y(vIndex); - } - - /** Z coordinate of triangle's second vertex, as a double. */ - default double v1z() { - final long vIndex = mesh().triangles().vertex1(index()); - return mesh().vertices().z(vIndex); - } - - /** X coordinate of triangle's third vertex, as a double. */ - default double v2x() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().x(vIndex); - } - - /** Y coordinate of triangle's third vertex, as a double. */ - default double v2y() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().y(vIndex); - } - - /** Z coordinate of triangle's third vertex, as a double. */ - default double v2z() { - final long vIndex = mesh().triangles().vertex2(index()); - return mesh().vertices().z(vIndex); - } - - /** X coordinate of triangle's normal, as a double. */ - default double nx() { - return mesh().triangles().nx(index()); - } - - /** Y coordinate of triangle's normal, as a double. */ - default double ny() { - return mesh().triangles().ny(index()); - } - - /** Z coordinate of triangle's normal, as a double. */ - default double nz() { - return mesh().triangles().nz(index()); - } + /** + * The mesh to which the triangle belongs. + * + * @see Mesh#triangles() + */ + Mesh mesh(); + + /** + * Index into the mesh's list of triangles. + */ + long index(); + + /** + * Index of first vertex in the triangle. + */ + default long vertex0() { + return mesh().triangles().vertex0(index()); + } + + /** + * Index of second vertex in the triangle. + */ + default long vertex1() { + return mesh().triangles().vertex1(index()); + } + + /** + * Index of third vertex in the triangle. + */ + default long vertex2() { + return mesh().triangles().vertex2(index()); + } + + /** + * X coordinate of triangle's first vertex, as a float. + */ + default float v0xf() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().xf(vIndex); + } + + /** + * Y coordinate of triangle's first vertex, as a float. + */ + default float v0yf() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().yf(vIndex); + } + + /** + * Z coordinate of triangle's first vertex, as a float. + */ + default float v0zf() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().zf(vIndex); + } + + /** + * X coordinate of triangle's second vertex, as a float. + */ + default float v1xf() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().xf(vIndex); + } + + /** + * Y coordinate of triangle's second vertex, as a float. + */ + default float v1yf() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().yf(vIndex); + } + + /** + * Z coordinate of triangle's second vertex, as a float. + */ + default float v1zf() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().zf(vIndex); + } + + /** + * X coordinate of triangle's third vertex, as a float. + */ + default float v2xf() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().xf(vIndex); + } + + /** + * Y coordinate of triangle's third vertex, as a float. + */ + default float v2yf() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().yf(vIndex); + } + + /** + * Z coordinate of triangle's third vertex, as a float. + */ + default float v2zf() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().zf(vIndex); + } + + /** + * X coordinate of triangle's normal, as a float. + */ + default float nxf() { + return mesh().triangles().nxf(index()); + } + + /** + * Y coordinate of triangle's normal, as a float. + */ + default float nyf() { + return mesh().triangles().nyf(index()); + } + + /** + * Z coordinate of triangle's normal, as a float. + */ + default float nzf() { + return mesh().triangles().nzf(index()); + } + + /** + * X coordinate of triangle's first vertex, as a double. + */ + default double v0x() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().x(vIndex); + } + + /** + * Y coordinate of triangle's first vertex, as a double. + */ + default double v0y() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().y(vIndex); + } + + /** + * Z coordinate of triangle's first vertex, as a double. + */ + default double v0z() { + final long vIndex = mesh().triangles().vertex0(index()); + return mesh().vertices().z(vIndex); + } + + /** + * X coordinate of triangle's second vertex, as a double. + */ + default double v1x() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().x(vIndex); + } + + /** + * Y coordinate of triangle's second vertex, as a double. + */ + default double v1y() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().y(vIndex); + } + + /** + * Z coordinate of triangle's second vertex, as a double. + */ + default double v1z() { + final long vIndex = mesh().triangles().vertex1(index()); + return mesh().vertices().z(vIndex); + } + + /** + * X coordinate of triangle's third vertex, as a double. + */ + default double v2x() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().x(vIndex); + } + + /** + * Y coordinate of triangle's third vertex, as a double. + */ + default double v2y() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().y(vIndex); + } + + /** + * Z coordinate of triangle's third vertex, as a double. + */ + default double v2z() { + final long vIndex = mesh().triangles().vertex2(index()); + return mesh().vertices().z(vIndex); + } + + /** + * X coordinate of triangle's normal, as a double. + */ + default double nx() { + return mesh().triangles().nx(index()); + } + + /** + * Y coordinate of triangle's normal, as a double. + */ + default double ny() { + return mesh().triangles().ny(index()); + } + + /** + * Z coordinate of triangle's normal, as a double. + */ + default double nz() { + return mesh().triangles().nz(index()); + } } diff --git a/src/main/java/net/imagej/mesh/Triangles.java b/src/main/java/net/imagej/mesh/Triangles.java index c7c3961..fb929e9 100644 --- a/src/main/java/net/imagej/mesh/Triangles.java +++ b/src/main/java/net/imagej/mesh/Triangles.java @@ -361,4 +361,21 @@ public Triangle next() { } }; } + + default Triangles copy() { + Triangles tris = this.createVariable(); + Iterator i = this.iterator(); + while (i.hasNext()) { + tris.add(i.next()); + } + return tris; + } + + default void add(Triangle next) { + add(next.vertex0(), next.vertex1(), next.vertex2(), next.nx(), next.ny(), next.nz()); + } + + Triangles createVariable(); + + void set(Triangles copy); } diff --git a/src/main/java/net/imagej/mesh/Vertex.java b/src/main/java/net/imagej/mesh/Vertex.java index a7810b4..729b3f0 100644 --- a/src/main/java/net/imagej/mesh/Vertex.java +++ b/src/main/java/net/imagej/mesh/Vertex.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -40,142 +40,176 @@ */ public interface Vertex extends RealLocalizable { - /** - * The mesh to which the vertex belongs. - * - * @see Mesh#vertices() - */ - Mesh mesh(); - - /** Index into the mesh's list of vertices. */ - long index(); - - /** X position of vertex, as a float. */ - default float xf() { - return mesh().vertices().xf(index()); - } - - /** Y position of vertex, as a float. */ - default float yf() { - return mesh().vertices().yf(index()); - } - - /** Z position of vertex, as a float. */ - default float zf() { - return mesh().vertices().zf(index()); - } - - /** X coordinate of vertex normal, as a float. */ - default float nxf() { - return mesh().vertices().nxf(index()); - } - - /** Y coordinate of vertex normal, as a float. */ - default float nyf() { - return mesh().vertices().nyf(index()); - } - - /** Z coordinate of vertex normal, as a float. */ - default float nzf() { - return mesh().vertices().nzf(index()); - } - - /** U value of vertex texture coordinate, as a float. */ - default float uf() { - return mesh().vertices().uf(index()); - } - - /** V value of vertex texture coordinate, as a float. */ - default float vf() { - return mesh().vertices().vf(index()); - } - - /** X position of vertex, as a double. */ - default double x() { - return mesh().vertices().x(index()); - } - - /** Y position of vertex, as a double. */ - default double y() { - return mesh().vertices().y(index()); - } - - /** Z position of vertex, as a double. */ - default double z() { - return mesh().vertices().z(index()); - } - - /** X coordinate of vertex normal, as a double. */ - default double nx() { - return mesh().vertices().nx(index()); - } - - /** Y coordinate of vertex normal, as a double. */ - default double ny() { - return mesh().vertices().ny(index()); - } - - /** Z coordinate of vertex normal, as a double. */ - default double nz() { - return mesh().vertices().nz(index()); - } - - /** U value of vertex texture coordinate, as a double. */ - default double u() { - return mesh().vertices().u(index()); - } - - /** V value of vertex texture coordinate, as a double. */ - default double v() { - return mesh().vertices().v(index()); - } - - // -- RealLocalizable methods -- - - @Override - default void localize(final float[] position) { - position[0] = xf(); - position[1] = yf(); - position[2] = zf(); - } - - @Override - default void localize(final double[] position) { - position[0] = x(); - position[1] = y(); - position[2] = z(); - } - - @Override - default float getFloatPosition(final int d) { - switch (d) { - case 0: - return xf(); - case 1: - return yf(); - case 2: - return zf(); - } - throw new IndexOutOfBoundsException("" + d); - } - - @Override - default double getDoublePosition(final int d) { - switch (d) { - case 0: - return x(); - case 1: - return y(); - case 2: - return z(); - } - throw new IndexOutOfBoundsException("" + d); - } - - // -- EuclideanSpace methods -- - - @Override - default int numDimensions() { - return 3; - } + /** + * The mesh to which the vertex belongs. + * + * @see Mesh#vertices() + */ + Mesh mesh(); + + /** + * Index into the mesh's list of vertices. + */ + long index(); + + /** + * X position of vertex, as a float. + */ + default float xf() { + return mesh().vertices().xf(index()); + } + + /** + * Y position of vertex, as a float. + */ + default float yf() { + return mesh().vertices().yf(index()); + } + + /** + * Z position of vertex, as a float. + */ + default float zf() { + return mesh().vertices().zf(index()); + } + + /** + * X coordinate of vertex normal, as a float. + */ + default float nxf() { + return mesh().vertices().nxf(index()); + } + + /** + * Y coordinate of vertex normal, as a float. + */ + default float nyf() { + return mesh().vertices().nyf(index()); + } + + /** + * Z coordinate of vertex normal, as a float. + */ + default float nzf() { + return mesh().vertices().nzf(index()); + } + + /** + * U value of vertex texture coordinate, as a float. + */ + default float uf() { + return mesh().vertices().uf(index()); + } + + /** + * V value of vertex texture coordinate, as a float. + */ + default float vf() { + return mesh().vertices().vf(index()); + } + + /** + * X position of vertex, as a double. + */ + default double x() { + return mesh().vertices().x(index()); + } + + /** + * Y position of vertex, as a double. + */ + default double y() { + return mesh().vertices().y(index()); + } + + /** + * Z position of vertex, as a double. + */ + default double z() { + return mesh().vertices().z(index()); + } + + /** + * X coordinate of vertex normal, as a double. + */ + default double nx() { + return mesh().vertices().nx(index()); + } + + /** + * Y coordinate of vertex normal, as a double. + */ + default double ny() { + return mesh().vertices().ny(index()); + } + + /** + * Z coordinate of vertex normal, as a double. + */ + default double nz() { + return mesh().vertices().nz(index()); + } + + /** + * U value of vertex texture coordinate, as a double. + */ + default double u() { + return mesh().vertices().u(index()); + } + + /** + * V value of vertex texture coordinate, as a double. + */ + default double v() { + return mesh().vertices().v(index()); + } + + // -- RealLocalizable methods -- + + @Override + default void localize(final float[] position) { + position[0] = xf(); + position[1] = yf(); + position[2] = zf(); + } + + @Override + default void localize(final double[] position) { + position[0] = x(); + position[1] = y(); + position[2] = z(); + } + + @Override + default float getFloatPosition(final int d) { + switch (d) { + case 0: + return xf(); + case 1: + return yf(); + case 2: + return zf(); + } + throw new IndexOutOfBoundsException("" + d); + } + + @Override + default double getDoublePosition(final int d) { + switch (d) { + case 0: + return x(); + case 1: + return y(); + case 2: + return z(); + } + throw new IndexOutOfBoundsException("" + d); + } + + // -- EuclideanSpace methods -- + + @Override + default int numDimensions() { + return 3; + } } diff --git a/src/main/java/net/imagej/mesh/Vertices.java b/src/main/java/net/imagej/mesh/Vertices.java index 0fb250e..3fffb50 100644 --- a/src/main/java/net/imagej/mesh/Vertices.java +++ b/src/main/java/net/imagej/mesh/Vertices.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -39,306 +39,356 @@ */ public interface Vertices extends Iterable { - /** The mesh to which the collection of vertices belongs. */ - Mesh mesh(); - - /** Number of vertices in the collection. */ - long size(); - - /** X position of a vertex, as a float. */ - float xf(long vIndex); - - /** Y position of a vertex, as a float. */ - float yf(long vIndex); - - /** Z position of a vertex, as a float. */ - float zf(long vIndex); - - /** X coordinate of vertex normal, as a float. */ - float nxf(long vIndex); - - /** Y coordinate of vertex normal, as a float. */ - float nyf(long vIndex); - - /** Z coordinate of vertex normal, as a float. */ - float nzf(long vIndex); - - /** U value of vertex texture coordinate, as a float. */ - float uf(long vIndex); - - /** V value of vertex texture coordinate, as a float. */ - float vf(long vIndex); - - /** - * Adds a vertex. - * - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - * @return Index of newly added vertex. - */ - long addf(float x, float y, float z, // - float nx, float ny, float nz, // - float u, float v); - - /** - * Overwrites a vertex's position, normal and texture coordinates. - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - */ - void setf(long vIndex, float x, float y, float z, // - float nx, float ny, float nz, // - float u, float v); - - /** - * Overwrites a vertex's position. - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - */ - void setPositionf(long vIndex, float x, float y, float z); - - /** - * Overwrites a vertex's normal. - * - * @param vIndex Index of vertex to overwrite. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - */ - void setNormalf(long vIndex, float nx, float ny, float nz); - - /** - * Overwrites a vertex's texture coordinates. - * - * @param vIndex Index of vertex to overwrite. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - */ - void setTexturef(long vIndex, float u, float v); - - /** - * Adds a vertex. - * - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - * @return Index of newly added vertex. - */ - default long addf(final float x, final float y, final float z) { - return addf(x, y, z, 0, 0, 0, 0, 0); - } - - /** - * Overwrites the position of a vertex, sets normal and texture coordinates - * to {@code 0} - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - */ - default void setf(final long vIndex, // - final float x, final float y, final float z) - { - setf(vIndex, x, y, z, 0, 0, 0, 0, 0); - } - - /** X position of a vertex, as a double. */ - default double x(final long vIndex) { - return xf(vIndex); - } - - /** Y position of a vertex, as a double. */ - default double y(final long vIndex) { - return yf(vIndex); - } - - /** Z position of a vertex, as a double. */ - default double z(final long vIndex) { - return zf(vIndex); - } - - /** X coordinate of vertex normal, as a double. */ - default double nx(final long vIndex) { - return nxf(vIndex); - } - - /** Y coordinate of vertex normal, as a double. */ - default double ny(final long vIndex) { - return nyf(vIndex); - } - - /** Z coordinate of vertex normal, as a double. */ - default double nz(final long vIndex) { - return nzf(vIndex); - } - - /** U value of vertex texture coordinate, as a double. */ - default double u(long vIndex) { - return uf(vIndex); - } - - /** V value of vertex texture coordinate, as a double. */ - default double v(long vIndex) { - return vf(vIndex); - } - - /** - * Adds a vertex. - * - * @param x X coordinate of the vertex. - * @param y Y coordinate of the vertex. - * @param z Z coordinate of the vertex. - * @return Index of newly added vertex. - */ - default long add(final double x, final double y, final double z) { - return addf((float) x, (float) y, (float) z); - } - - /** - * Adds a vertex. - * - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - * @return Index of newly added vertex. - */ - default long add(double x, double y, double z, // - double nx, double ny, double nz, // - double u, double v) - { - return addf((float) x, (float) y, (float) z, // - (float) nx, (float) ny, (float) nz, // - (float) u, (float) v); - } - - /** - * Overwrites the position of a vertex, sets normal and texture coordinates - * to {@code 0} - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - */ - default void set(final long vIndex, final double x, final double y, - final double z) - { - set(vIndex, x, y, z, 0, 0, 0, 0, 0); - } - - /** - * Overwrites a vertex's position, normal and texture coordinates. - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - */ - default void set(final long vIndex, final double x, final double y, - final double z, // - final double nx, final double ny, final double nz, // - final double u, final double v) - { - setf(vIndex, (float) x, (float) y, (float) z, // - (float) nx, (float) ny, (float) nz, // - (float) u, (float) v); - } - - /** - * Overwrites a vertex's position. - * - * @param vIndex Index of vertex to overwrite. - * @param x X position of the vertex. - * @param y Y position of the vertex. - * @param z Z position of the vertex. - */ - default void setPosition(final long vIndex, final double x, final double y, - final double z) - { - setPositionf(vIndex, (float) x, (float) y, (float) z); - } - - /** - * Overwrites a vertex's normal. - * - * @param vIndex Index of vertex to overwrite. - * @param nx X coordinate of the vertex's normal. - * @param ny Y coordinate of the vertex's normal. - * @param nz Z coordinate of the vertex's normal. - */ - default void setNormal(final long vIndex, final double nx, final double ny, - final double nz) - { - setNormalf(vIndex, (float) nx, (float) ny, (float) nz); - } - - /** - * Overwrites a vertex's texture coordinates. - * - * @param vIndex Index of vertex to overwrite. - * @param u U value of vertex texture coordinate. - * @param v V value of vertex texture coordinate. - */ - default void setTexture(final long vIndex, final double u, final double v) - { - setTexturef(vIndex, (float) u, (float) v); - } - - - // -- Iterable methods -- - - @Override - default Iterator iterator() { - return new Iterator() { - - private long index = -1; - - private Vertex vertex = new Vertex() { - - @Override - public Mesh mesh() { return Vertices.this.mesh(); } - - @Override - public long index() { return index; } - }; - - @Override - public boolean hasNext() { - return index + 1 < size(); - } - - @Override - public Vertex next() { - index++; - return vertex; - } - }; - } + /** + * The mesh to which the collection of vertices belongs. + */ + Mesh mesh(); + + /** + * Number of vertices in the collection. + */ + long size(); + + /** + * X position of a vertex, as a float. + */ + float xf(long vIndex); + + /** + * Y position of a vertex, as a float. + */ + float yf(long vIndex); + + /** + * Z position of a vertex, as a float. + */ + float zf(long vIndex); + + /** + * X coordinate of vertex normal, as a float. + */ + float nxf(long vIndex); + + /** + * Y coordinate of vertex normal, as a float. + */ + float nyf(long vIndex); + + /** + * Z coordinate of vertex normal, as a float. + */ + float nzf(long vIndex); + + /** + * U value of vertex texture coordinate, as a float. + */ + float uf(long vIndex); + + /** + * V value of vertex texture coordinate, as a float. + */ + float vf(long vIndex); + + /** + * Adds a vertex. + * + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + * @return Index of newly added vertex. + */ + long addf(float x, float y, float z, // + float nx, float ny, float nz, // + float u, float v); + + /** + * Overwrites a vertex's position, normal and texture coordinates. + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + */ + void setf(long vIndex, float x, float y, float z, // + float nx, float ny, float nz, // + float u, float v); + + /** + * Overwrites a vertex's position. + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + */ + void setPositionf(long vIndex, float x, float y, float z); + + /** + * Overwrites a vertex's normal. + * + * @param vIndex Index of vertex to overwrite. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + */ + void setNormalf(long vIndex, float nx, float ny, float nz); + + /** + * Overwrites a vertex's texture coordinates. + * + * @param vIndex Index of vertex to overwrite. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + */ + void setTexturef(long vIndex, float u, float v); + + /** + * Adds a vertex. + * + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + * @return Index of newly added vertex. + */ + default long addf(final float x, final float y, final float z) { + return addf(x, y, z, 0, 0, 0, 0, 0); + } + + /** + * Overwrites the position of a vertex, sets normal and texture coordinates + * to {@code 0} + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + */ + default void setf(final long vIndex, // + final float x, final float y, final float z) { + setf(vIndex, x, y, z, 0, 0, 0, 0, 0); + } + + /** + * X position of a vertex, as a double. + */ + default double x(final long vIndex) { + return xf(vIndex); + } + + /** + * Y position of a vertex, as a double. + */ + default double y(final long vIndex) { + return yf(vIndex); + } + + /** + * Z position of a vertex, as a double. + */ + default double z(final long vIndex) { + return zf(vIndex); + } + + /** + * X coordinate of vertex normal, as a double. + */ + default double nx(final long vIndex) { + return nxf(vIndex); + } + + /** + * Y coordinate of vertex normal, as a double. + */ + default double ny(final long vIndex) { + return nyf(vIndex); + } + + /** + * Z coordinate of vertex normal, as a double. + */ + default double nz(final long vIndex) { + return nzf(vIndex); + } + + /** + * U value of vertex texture coordinate, as a double. + */ + default double u(long vIndex) { + return uf(vIndex); + } + + /** + * V value of vertex texture coordinate, as a double. + */ + default double v(long vIndex) { + return vf(vIndex); + } + + /** + * Adds a vertex. + * + * @param x X coordinate of the vertex. + * @param y Y coordinate of the vertex. + * @param z Z coordinate of the vertex. + * @return Index of newly added vertex. + */ + default long add(final double x, final double y, final double z) { + return addf((float) x, (float) y, (float) z); + } + + /** + * Adds a vertex. + * + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + * @return Index of newly added vertex. + */ + default long add(double x, double y, double z, // + double nx, double ny, double nz, // + double u, double v) { + return addf((float) x, (float) y, (float) z, // + (float) nx, (float) ny, (float) nz, // + (float) u, (float) v); + } + + /** + * Overwrites the position of a vertex, sets normal and texture coordinates + * to {@code 0} + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + */ + default void set(final long vIndex, final double x, final double y, + final double z) { + set(vIndex, x, y, z, 0, 0, 0, 0, 0); + } + + /** + * Overwrites a vertex's position, normal and texture coordinates. + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + */ + default void set(final long vIndex, final double x, final double y, + final double z, // + final double nx, final double ny, final double nz, // + final double u, final double v) { + setf(vIndex, (float) x, (float) y, (float) z, // + (float) nx, (float) ny, (float) nz, // + (float) u, (float) v); + } + + /** + * Overwrites a vertex's position. + * + * @param vIndex Index of vertex to overwrite. + * @param x X position of the vertex. + * @param y Y position of the vertex. + * @param z Z position of the vertex. + */ + default void setPosition(final long vIndex, final double x, final double y, + final double z) { + setPositionf(vIndex, (float) x, (float) y, (float) z); + } + + /** + * Overwrites a vertex's normal. + * + * @param vIndex Index of vertex to overwrite. + * @param nx X coordinate of the vertex's normal. + * @param ny Y coordinate of the vertex's normal. + * @param nz Z coordinate of the vertex's normal. + */ + default void setNormal(final long vIndex, final double nx, final double ny, + final double nz) { + setNormalf(vIndex, (float) nx, (float) ny, (float) nz); + } + + /** + * Overwrites a vertex's texture coordinates. + * + * @param vIndex Index of vertex to overwrite. + * @param u U value of vertex texture coordinate. + * @param v V value of vertex texture coordinate. + */ + default void setTexture(final long vIndex, final double u, final double v) { + setTexturef(vIndex, (float) u, (float) v); + } + + + // -- Iterable methods -- + + @Override + default Iterator iterator() { + return new Iterator() { + + private long index = -1; + + private Vertex vertex = new Vertex() { + + @Override + public Mesh mesh() { + return Vertices.this.mesh(); + } + + @Override + public long index() { + return index; + } + }; + + @Override + public boolean hasNext() { + return index + 1 < size(); + } + + @Override + public Vertex next() { + index++; + return vertex; + } + }; + } + + default Vertices copy() { + Vertices v = this.createVariable(); + Iterator vtx = iterator(); + while (vtx.hasNext()) { + v.add(vtx.next()); + } + return v; + } + + default void add(Vertex vtx) { + add(vtx.x(), vtx.y(), vtx.z(), vtx.nx(), vtx.ny(), vtx.nz(), vtx.u(), vtx.v()); + } + + Vertices createVariable(); + + void set(Vertices copy); } diff --git a/src/main/java/net/imagej/mesh/naive/NaiveDoubleMesh.java b/src/main/java/net/imagej/mesh/naive/NaiveDoubleMesh.java index f0c6d92..893f806 100644 --- a/src/main/java/net/imagej/mesh/naive/NaiveDoubleMesh.java +++ b/src/main/java/net/imagej/mesh/naive/NaiveDoubleMesh.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,332 +31,372 @@ package net.imagej.mesh.naive; import net.imagej.mesh.Mesh; - +import net.imagej.mesh.Triangle; +import net.imagej.mesh.Vertex; import org.scijava.util.DoubleArray; import org.scijava.util.IntArray; +import java.util.Iterator; + public class NaiveDoubleMesh implements Mesh { - private final Vertices vertices; - private final Triangles triangles; - - public NaiveDoubleMesh() { - vertices = new Vertices(); - triangles = new Triangles(); - } - - @Override - public Vertices vertices() { - return vertices; - } - - @Override - public Triangles triangles() { - return triangles; - } - - // -- Inner classes -- - - public class Vertices implements net.imagej.mesh.Vertices { - - private final DoubleArray xs, ys, zs; - private final DoubleArray nxs, nys, nzs; - private final DoubleArray us, vs; - - public Vertices() { - xs = new DoubleArray(); - ys = new DoubleArray(); - zs = new DoubleArray(); - nxs = new DoubleArray(); - nys = new DoubleArray(); - nzs = new DoubleArray(); - us = new DoubleArray(); - vs = new DoubleArray(); - } - - @Override - public Mesh mesh() { - return NaiveDoubleMesh.this; - } - - @Override - public long size() { - return xs.size(); - } - - @Override - public double x(long vIndex) { - return xs.get(safeIndex(vIndex)); - } - - @Override - public double y(long vIndex) { - return ys.get(safeIndex(vIndex)); - } - - @Override - public double z(long vIndex) { - return zs.get(safeIndex(vIndex)); - } - - @Override - public double nx(long vIndex) { - return nxs.get(safeIndex(vIndex)); - } - - @Override - public double ny(long vIndex) { - return nys.get(safeIndex(vIndex)); - } - - @Override - public double nz(long vIndex) { - return nzs.get(safeIndex(vIndex)); - } - - @Override - public double u(long vIndex) { - return us.get(safeIndex(vIndex)); - } - - @Override - public double v(long vIndex) { - return vs.get(safeIndex(vIndex)); - } - - @Override - public long add(double x, double y, double z, double nx, double ny, double nz, - double u, double v) - { - final int index = xs.size(); - xs.add(x); - ys.add(y); - zs.add(z); - nxs.add(nx); - nys.add(ny); - nzs.add(nz); - us.add(u); - vs.add(v); - return index; - } - - @Override - public void set(long vIndex, double x, double y, double z, double nx, double ny, - double nz, double u, double v) - { - final int index = safeIndex(vIndex); - xs.set(index, x); - ys.set(index, y); - zs.set(index, z); - nxs.set(index, nx); - nys.set(index, ny); - nzs.set(index, nz); - us.set(index, u); - vs.set(index, v); - } - - @Override - public void setPosition(final long vIndex, final double x, - final double y, final double z) - { - final int index = safeIndex(vIndex); - xs.set(index, x); - ys.set(index, y); - zs.set(index, z); - } - - @Override - public void setNormal(final long vIndex, final double nx, - final double ny, final double nz) - { - final int index = safeIndex(vIndex); - nxs.set(index, nx); - nys.set(index, ny); - nzs.set(index, nz); - } - - @Override - public void setTexture(final long vIndex, final double u, - final double v) - { - final int index = safeIndex(vIndex); - us.set(index, u); - vs.set(index, v); - } - - private int safeIndex(final long index) { - if (index > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Index too large: " + index); - } - return (int) index; - } - - @Override - public float xf(long vIndex) { - return (float) x(vIndex); - } - - @Override - public float yf(long vIndex) { - return (float) y(vIndex); - } - - @Override - public float zf(long vIndex) { - return (float) z(vIndex); - } - - @Override - public float nxf(long vIndex) { - return (float) nx(vIndex); - } - - @Override - public float nyf(long vIndex) { - return (float) ny(vIndex); - } - - @Override - public float nzf(long vIndex) { - return (float) nz(vIndex); - } - - @Override - public float uf(long vIndex) { - return (float) u(vIndex); - } - - @Override - public float vf(long vIndex) { - return (float) v(vIndex); - } - - @Override - public long addf(float x, float y, float z, float nx, float ny, float nz, - float u, float v) - { - return add(x, y, z, nx, ny, nz, u, v); - } - - @Override - public void setf(long vIndex, float x, float y, float z, float nx, float ny, - float nz, float u, float v) - { - set(vIndex, x, y, z, nx, ny, nz, u, v); - } - - @Override - public void setPositionf(final long vIndex, final float x, - final float y, final float z) - { - setPosition(vIndex, x, y, z); - } - - @Override - public void setNormalf(final long vIndex, final float nx, - final float ny, final float nz) - { - setNormal(vIndex, nx, ny, nz); - } - - @Override - public void setTexturef(final long vIndex, final float u, final float v) - { - setTexture(vIndex, u, v); - } - } - - public class Triangles implements net.imagej.mesh.Triangles { - - private final IntArray v0s, v1s, v2s; - private final DoubleArray nxs, nys, nzs; - - public Triangles() { - v0s = new IntArray(); - v1s = new IntArray(); - v2s = new IntArray(); - nxs = new DoubleArray(); - nys = new DoubleArray(); - nzs = new DoubleArray(); - } - - @Override - public Mesh mesh() { - return NaiveDoubleMesh.this; - } - - @Override - public long size() { - return v1s.size(); - } - - @Override - public long vertex0(long tIndex) { - return v0s.get(safeIndex(tIndex)); - } - - @Override - public long vertex1(long tIndex) { - return v1s.get(safeIndex(tIndex)); - } - - @Override - public long vertex2(long tIndex) { - return v2s.get(safeIndex(tIndex)); - } - - @Override - public double nx(long tIndex) { - return nxs.get(safeIndex(tIndex)); - } - - @Override - public double ny(long tIndex) { - return nys.get(safeIndex(tIndex)); - } - - @Override - public double nz(long tIndex) { - return nzs.get(safeIndex(tIndex)); - } - - @Override - public long add(long v0, long v1, long v2, double nx, double ny, double nz) { - final int index = v0s.size(); - v0s.add(safeIndex(v0)); - v1s.add(safeIndex(v1)); - v2s.add(safeIndex(v2)); - nxs.add(nx); - nys.add(ny); - nzs.add(nz); - return index; - } - - private int safeIndex(final long index) { - if (index > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Index too large: " + index); - } - return (int) index; - } - - @Override - public float nxf(long tIndex) { - return (float) nx(tIndex); - } - - @Override - public float nyf(long tIndex) { - return (float) ny(tIndex); - } - - @Override - public float nzf(long tIndex) { - return (float) nz(tIndex); - } - - @Override - public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { - return add(v0, v1, v2, nx, ny, nz); - } - } + private final Vertices vertices; + private final Triangles triangles; + + public NaiveDoubleMesh() { + vertices = new Vertices(); + triangles = new Triangles(); + } + + @Override + public Vertices vertices() { + return vertices; + } + + @Override + public Triangles triangles() { + return triangles; + } + + @Override + public Mesh createVariable() { + return new NaiveDoubleMesh(); + } + + // -- Inner classes -- + + public class Vertices implements net.imagej.mesh.Vertices { + + private final DoubleArray xs, ys, zs; + private final DoubleArray nxs, nys, nzs; + private final DoubleArray us, vs; + + public Vertices() { + xs = new DoubleArray(); + ys = new DoubleArray(); + zs = new DoubleArray(); + nxs = new DoubleArray(); + nys = new DoubleArray(); + nzs = new DoubleArray(); + us = new DoubleArray(); + vs = new DoubleArray(); + } + + @Override + public Mesh mesh() { + return NaiveDoubleMesh.this; + } + + @Override + public long size() { + return xs.size(); + } + + @Override + public double x(long vIndex) { + return xs.get(safeIndex(vIndex)); + } + + @Override + public double y(long vIndex) { + return ys.get(safeIndex(vIndex)); + } + + @Override + public double z(long vIndex) { + return zs.get(safeIndex(vIndex)); + } + + @Override + public double nx(long vIndex) { + return nxs.get(safeIndex(vIndex)); + } + + @Override + public double ny(long vIndex) { + return nys.get(safeIndex(vIndex)); + } + + @Override + public double nz(long vIndex) { + return nzs.get(safeIndex(vIndex)); + } + + @Override + public double u(long vIndex) { + return us.get(safeIndex(vIndex)); + } + + @Override + public double v(long vIndex) { + return vs.get(safeIndex(vIndex)); + } + + @Override + public long add(double x, double y, double z, double nx, double ny, double nz, + double u, double v) { + final int index = xs.size(); + xs.add(x); + ys.add(y); + zs.add(z); + nxs.add(nx); + nys.add(ny); + nzs.add(nz); + us.add(u); + vs.add(v); + return index; + } + + @Override + public void set(long vIndex, double x, double y, double z, double nx, double ny, + double nz, double u, double v) { + final int index = safeIndex(vIndex); + xs.set(index, x); + ys.set(index, y); + zs.set(index, z); + nxs.set(index, nx); + nys.set(index, ny); + nzs.set(index, nz); + us.set(index, u); + vs.set(index, v); + } + + @Override + public void setPosition(final long vIndex, final double x, + final double y, final double z) { + final int index = safeIndex(vIndex); + xs.set(index, x); + ys.set(index, y); + zs.set(index, z); + } + + @Override + public void setNormal(final long vIndex, final double nx, + final double ny, final double nz) { + final int index = safeIndex(vIndex); + nxs.set(index, nx); + nys.set(index, ny); + nzs.set(index, nz); + } + + @Override + public void setTexture(final long vIndex, final double u, + final double v) { + final int index = safeIndex(vIndex); + us.set(index, u); + vs.set(index, v); + } + + @Override + public net.imagej.mesh.Vertices createVariable() { + return new Vertices(); + } + + @Override + public void set(net.imagej.mesh.Vertices copy) { + xs.clear(); + ys.clear(); + zs.clear(); + nxs.clear(); + nys.clear(); + nzs.clear(); + us.clear(); + vs.clear(); + + Iterator i = copy.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + private int safeIndex(final long index) { + if (index > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Index too large: " + index); + } + return (int) index; + } + + @Override + public float xf(long vIndex) { + return (float) x(vIndex); + } + + @Override + public float yf(long vIndex) { + return (float) y(vIndex); + } + + @Override + public float zf(long vIndex) { + return (float) z(vIndex); + } + + @Override + public float nxf(long vIndex) { + return (float) nx(vIndex); + } + + @Override + public float nyf(long vIndex) { + return (float) ny(vIndex); + } + + @Override + public float nzf(long vIndex) { + return (float) nz(vIndex); + } + + @Override + public float uf(long vIndex) { + return (float) u(vIndex); + } + + @Override + public float vf(long vIndex) { + return (float) v(vIndex); + } + + @Override + public long addf(float x, float y, float z, float nx, float ny, float nz, + float u, float v) { + return add(x, y, z, nx, ny, nz, u, v); + } + + @Override + public void setf(long vIndex, float x, float y, float z, float nx, float ny, + float nz, float u, float v) { + set(vIndex, x, y, z, nx, ny, nz, u, v); + } + + @Override + public void setPositionf(final long vIndex, final float x, + final float y, final float z) { + setPosition(vIndex, x, y, z); + } + + @Override + public void setNormalf(final long vIndex, final float nx, + final float ny, final float nz) { + setNormal(vIndex, nx, ny, nz); + } + + @Override + public void setTexturef(final long vIndex, final float u, final float v) { + setTexture(vIndex, u, v); + } + } + + public class Triangles implements net.imagej.mesh.Triangles { + + private final IntArray v0s, v1s, v2s; + private final DoubleArray nxs, nys, nzs; + + public Triangles() { + v0s = new IntArray(); + v1s = new IntArray(); + v2s = new IntArray(); + nxs = new DoubleArray(); + nys = new DoubleArray(); + nzs = new DoubleArray(); + } + + @Override + public Mesh mesh() { + return NaiveDoubleMesh.this; + } + + @Override + public long size() { + return v1s.size(); + } + + @Override + public long vertex0(long tIndex) { + return v0s.get(safeIndex(tIndex)); + } + + @Override + public long vertex1(long tIndex) { + return v1s.get(safeIndex(tIndex)); + } + + @Override + public long vertex2(long tIndex) { + return v2s.get(safeIndex(tIndex)); + } + + @Override + public double nx(long tIndex) { + return nxs.get(safeIndex(tIndex)); + } + + @Override + public double ny(long tIndex) { + return nys.get(safeIndex(tIndex)); + } + + @Override + public double nz(long tIndex) { + return nzs.get(safeIndex(tIndex)); + } + + @Override + public long add(long v0, long v1, long v2, double nx, double ny, double nz) { + final int index = v0s.size(); + v0s.add(safeIndex(v0)); + v1s.add(safeIndex(v1)); + v2s.add(safeIndex(v2)); + nxs.add(nx); + nys.add(ny); + nzs.add(nz); + return index; + } + + @Override + public net.imagej.mesh.Triangles createVariable() { + return new Triangles(); + } + + @Override + public void set(net.imagej.mesh.Triangles copy) { + v0s.clear(); + v1s.clear(); + v2s.clear(); + nxs.clear(); + nys.clear(); + nzs.clear(); + + Iterator i = copy.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + private int safeIndex(final long index) { + if (index > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Index too large: " + index); + } + return (int) index; + } + + @Override + public float nxf(long tIndex) { + return (float) nx(tIndex); + } + + @Override + public float nyf(long tIndex) { + return (float) ny(tIndex); + } + + @Override + public float nzf(long tIndex) { + return (float) nz(tIndex); + } + + @Override + public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { + return add(v0, v1, v2, nx, ny, nz); + } + } } diff --git a/src/main/java/net/imagej/mesh/naive/NaiveFloatMesh.java b/src/main/java/net/imagej/mesh/naive/NaiveFloatMesh.java index 8cdac77..fed73b7 100644 --- a/src/main/java/net/imagej/mesh/naive/NaiveFloatMesh.java +++ b/src/main/java/net/imagej/mesh/naive/NaiveFloatMesh.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,238 +31,283 @@ package net.imagej.mesh.naive; import net.imagej.mesh.Mesh; - +import net.imagej.mesh.Triangle; +import net.imagej.mesh.Vertex; import org.scijava.util.FloatArray; import org.scijava.util.IntArray; +import java.util.Iterator; + public class NaiveFloatMesh implements Mesh { - private final Vertices vertices; - private final Triangles triangles; - - public NaiveFloatMesh() { - vertices = new Vertices(); - triangles = new Triangles(); - } - - @Override - public Vertices vertices() { - return vertices; - } - - @Override - public Triangles triangles() { - return triangles; - } - - // -- Inner classes -- - - public class Vertices implements net.imagej.mesh.Vertices { - - private final FloatArray xs, ys, zs; - private final FloatArray nxs, nys, nzs; - private final FloatArray us, vs; - - public Vertices() { - xs = new FloatArray(); - ys = new FloatArray(); - zs = new FloatArray(); - nxs = new FloatArray(); - nys = new FloatArray(); - nzs = new FloatArray(); - us = new FloatArray(); - vs = new FloatArray(); - } - - @Override - public Mesh mesh() { - return NaiveFloatMesh.this; - } - - @Override - public long size() { - return xs.size(); - } - - @Override - public float xf(long vIndex) { - return xs.get(safeIndex(vIndex)); - } - - @Override - public float yf(long vIndex) { - return ys.get(safeIndex(vIndex)); - } - - @Override - public float zf(long vIndex) { - return zs.get(safeIndex(vIndex)); - } - - @Override - public float nxf(long vIndex) { - return nxs.get(safeIndex(vIndex)); - } - - @Override - public float nyf(long vIndex) { - return nys.get(safeIndex(vIndex)); - } - - @Override - public float nzf(long vIndex) { - return nzs.get(safeIndex(vIndex)); - } - - @Override - public float uf(long vIndex) { - return us.get(safeIndex(vIndex)); - } - - @Override - public float vf(long vIndex) { - return vs.get(safeIndex(vIndex)); - } - - @Override - public long addf(float x, float y, float z, float nx, float ny, float nz, - float u, float v) - { - final int index = xs.size(); - xs.add(x); - ys.add(y); - zs.add(z); - nxs.add(nx); - nys.add(ny); - nzs.add(nz); - us.add(u); - vs.add(v); - return index; - } - - @Override - public void setf(long vIndex, float x, float y, float z, float nx, float ny, - float nz, float u, float v) - { - final int index = safeIndex(vIndex); - xs.set(index, x); - ys.set(index, y); - zs.set(index, z); - nxs.set(index, nx); - nys.set(index, ny); - nzs.set(index, nz); - us.set(index, u); - vs.set(index, v); - } - - @Override - public void setPositionf(final long vIndex, final float x, - final float y, final float z) - { - final int index = safeIndex(vIndex); - xs.set(index, x); - ys.set(index, y); - zs.set(index, z); - - } - - @Override - public void setNormalf(final long vIndex, final float nx, - final float ny, final float nz) - { - final int index = safeIndex(vIndex); - nxs.set(index, nx); - nys.set(index, ny); - nzs.set(index, nz); - } - - @Override - public void setTexturef(final long vIndex, final float u, final float v) - { - final int index = safeIndex(vIndex); - us.set(index, u); - vs.set(index, v); - } - - private int safeIndex(final long index) { - if (index > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Index too large: " + index); - } - return (int) index; - } - } - - public class Triangles implements net.imagej.mesh.Triangles { - - private final IntArray v0s, v1s, v2s; - private final FloatArray nxs, nys, nzs; - - public Triangles() { - v0s = new IntArray(); - v1s = new IntArray(); - v2s = new IntArray(); - nxs = new FloatArray(); - nys = new FloatArray(); - nzs = new FloatArray(); - } - - @Override - public Mesh mesh() { - return NaiveFloatMesh.this; - } - - @Override - public long size() { - return v1s.size(); - } - - @Override - public long vertex0(long tIndex) { - return v0s.get(safeIndex(tIndex)); - } - - @Override - public long vertex1(long tIndex) { - return v1s.get(safeIndex(tIndex)); - } - - @Override - public long vertex2(long tIndex) { - return v2s.get(safeIndex(tIndex)); - } - - @Override - public float nxf(long tIndex) { - return nxs.get(safeIndex(tIndex)); - } - - @Override - public float nyf(long tIndex) { - return nys.get(safeIndex(tIndex)); - } - - @Override - public float nzf(long tIndex) { - return nzs.get(safeIndex(tIndex)); - } - - @Override - public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { - final int index = v0s.size(); - v0s.add(safeIndex(v0)); - v1s.add(safeIndex(v1)); - v2s.add(safeIndex(v2)); - nxs.add(nx); - nys.add(ny); - nzs.add(nz); - return index; - } - - private int safeIndex(final long index) { - if (index > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Index too large: " + index); - } - return (int) index; - } - } + private final Vertices vertices; + private final Triangles triangles; + + public NaiveFloatMesh() { + vertices = new Vertices(); + triangles = new Triangles(); + } + + @Override + public Vertices vertices() { + return vertices; + } + + @Override + public Triangles triangles() { + return triangles; + } + + @Override + public Mesh createVariable() { + return new NaiveFloatMesh(); + } + + // -- Inner classes -- + + public class Vertices implements net.imagej.mesh.Vertices { + + private final FloatArray xs, ys, zs; + private final FloatArray nxs, nys, nzs; + private final FloatArray us, vs; + + public Vertices() { + xs = new FloatArray(); + ys = new FloatArray(); + zs = new FloatArray(); + nxs = new FloatArray(); + nys = new FloatArray(); + nzs = new FloatArray(); + us = new FloatArray(); + vs = new FloatArray(); + } + + @Override + public Mesh mesh() { + return NaiveFloatMesh.this; + } + + @Override + public long size() { + return xs.size(); + } + + @Override + public float xf(long vIndex) { + return xs.get(safeIndex(vIndex)); + } + + @Override + public float yf(long vIndex) { + return ys.get(safeIndex(vIndex)); + } + + @Override + public float zf(long vIndex) { + return zs.get(safeIndex(vIndex)); + } + + @Override + public float nxf(long vIndex) { + return nxs.get(safeIndex(vIndex)); + } + + @Override + public float nyf(long vIndex) { + return nys.get(safeIndex(vIndex)); + } + + @Override + public float nzf(long vIndex) { + return nzs.get(safeIndex(vIndex)); + } + + @Override + public float uf(long vIndex) { + return us.get(safeIndex(vIndex)); + } + + @Override + public float vf(long vIndex) { + return vs.get(safeIndex(vIndex)); + } + + @Override + public long addf(float x, float y, float z, float nx, float ny, float nz, + float u, float v) { + final int index = xs.size(); + xs.add(x); + ys.add(y); + zs.add(z); + nxs.add(nx); + nys.add(ny); + nzs.add(nz); + us.add(u); + vs.add(v); + return index; + } + + @Override + public void setf(long vIndex, float x, float y, float z, float nx, float ny, + float nz, float u, float v) { + final int index = safeIndex(vIndex); + xs.set(index, x); + ys.set(index, y); + zs.set(index, z); + nxs.set(index, nx); + nys.set(index, ny); + nzs.set(index, nz); + us.set(index, u); + vs.set(index, v); + } + + @Override + public void setPositionf(final long vIndex, final float x, + final float y, final float z) { + final int index = safeIndex(vIndex); + xs.set(index, x); + ys.set(index, y); + zs.set(index, z); + + } + + @Override + public void setNormalf(final long vIndex, final float nx, + final float ny, final float nz) { + final int index = safeIndex(vIndex); + nxs.set(index, nx); + nys.set(index, ny); + nzs.set(index, nz); + } + + @Override + public void setTexturef(final long vIndex, final float u, final float v) { + final int index = safeIndex(vIndex); + us.set(index, u); + vs.set(index, v); + } + + @Override + public net.imagej.mesh.Vertices createVariable() { + return new Vertices(); + } + + @Override + public void set(net.imagej.mesh.Vertices copy) { + xs.clear(); + ys.clear(); + zs.clear(); + nxs.clear(); + nys.clear(); + nzs.clear(); + us.clear(); + vs.clear(); + + Iterator i = copy.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + private int safeIndex(final long index) { + if (index > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Index too large: " + index); + } + return (int) index; + } + } + + public class Triangles implements net.imagej.mesh.Triangles { + + private final IntArray v0s, v1s, v2s; + private final FloatArray nxs, nys, nzs; + + public Triangles() { + v0s = new IntArray(); + v1s = new IntArray(); + v2s = new IntArray(); + nxs = new FloatArray(); + nys = new FloatArray(); + nzs = new FloatArray(); + } + + @Override + public Mesh mesh() { + return NaiveFloatMesh.this; + } + + @Override + public long size() { + return v1s.size(); + } + + @Override + public long vertex0(long tIndex) { + return v0s.get(safeIndex(tIndex)); + } + + @Override + public long vertex1(long tIndex) { + return v1s.get(safeIndex(tIndex)); + } + + @Override + public long vertex2(long tIndex) { + return v2s.get(safeIndex(tIndex)); + } + + @Override + public float nxf(long tIndex) { + return nxs.get(safeIndex(tIndex)); + } + + @Override + public float nyf(long tIndex) { + return nys.get(safeIndex(tIndex)); + } + + @Override + public float nzf(long tIndex) { + return nzs.get(safeIndex(tIndex)); + } + + @Override + public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { + final int index = v0s.size(); + v0s.add(safeIndex(v0)); + v1s.add(safeIndex(v1)); + v2s.add(safeIndex(v2)); + nxs.add(nx); + nys.add(ny); + nzs.add(nz); + return index; + } + + @Override + public net.imagej.mesh.Triangles createVariable() { + return new Triangles(); + } + + @Override + public void set(net.imagej.mesh.Triangles copy) { + v0s.clear(); + v1s.clear(); + v2s.clear(); + nxs.clear(); + nys.clear(); + nzs.clear(); + + Iterator i = copy.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + private int safeIndex(final long index) { + if (index > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Index too large: " + index); + } + return (int) index; + } + } } diff --git a/src/main/java/net/imagej/mesh/nio/BufferMesh.java b/src/main/java/net/imagej/mesh/nio/BufferMesh.java index bf50fa2..5cfc6d3 100644 --- a/src/main/java/net/imagej/mesh/nio/BufferMesh.java +++ b/src/main/java/net/imagej/mesh/nio/BufferMesh.java @@ -7,13 +7,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -30,14 +30,13 @@ package net.imagej.mesh.nio; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.function.Function; - import net.imagej.mesh.Mesh; +import net.imagej.mesh.Triangle; +import net.imagej.mesh.Vertex; + +import java.nio.*; +import java.util.Iterator; +import java.util.function.Function; /** * Mesh implemented using {@link java.nio.Buffer} objects. @@ -46,303 +45,383 @@ */ public class BufferMesh implements Mesh { - private final Vertices vertices; - private final Triangles triangles; - - public BufferMesh(final int vertexMax, final int triangleMax) { - this(vertexMax, triangleMax, true); - } - - public BufferMesh(final int vertexMax, final int triangleMax, - final boolean direct) - { - this(vertexMax, triangleMax, // - direct ? ByteBuffer::allocateDirect : ByteBuffer::allocate); - } - - public BufferMesh(final int vertexMax, final int triangleMax, - final Function creator) - { - this(floats(create(creator, vertexMax * 12)), // - floats(create(creator, vertexMax * 12)), // - floats(create(creator, vertexMax * 8)), // - ints(create(creator, triangleMax * 12)), // - floats(create(creator, triangleMax * 12))); - } - - public BufferMesh(final FloatBuffer verts, final FloatBuffer vNormals, - final FloatBuffer texCoords, final IntBuffer indices, - final FloatBuffer tNormals) - { - vertices = new Vertices(verts, vNormals, texCoords); - triangles = new Triangles(indices, tNormals); - } - - @Override - public Vertices vertices() { - return vertices; - } - - @Override - public Triangles triangles() { - return triangles; - } - - // -- Inner classes -- - - public class Vertices implements net.imagej.mesh.Vertices { - - private static final int V_STRIDE = 3; - private static final int N_STRIDE = 3; - private static final int T_STRIDE = 2; - - private FloatBuffer verts; - private FloatBuffer normals; - private FloatBuffer texCoords; - - public Vertices(final FloatBuffer verts, final FloatBuffer normals, - final FloatBuffer texCoords) - { - this.verts = verts; - this.normals = normals; - this.texCoords = texCoords; - } - - public FloatBuffer verts() { - return verts; - } - - public FloatBuffer normals() { - return normals; - } - - public FloatBuffer texCoords() { - return texCoords; - } - - @Override - public Mesh mesh() { - return BufferMesh.this; - } - - @Override - public long size() { - return verts.limit() / V_STRIDE; - } - - @Override - public float xf(long vIndex) { - return verts.get(safeIndex(vIndex, V_STRIDE, 0)); - } - - @Override - public float yf(long vIndex) { - return verts.get(safeIndex(vIndex, V_STRIDE, 1)); - } - - @Override - public float zf(long vIndex) { - return verts.get(safeIndex(vIndex, V_STRIDE, 2)); - } - - @Override - public float nxf(long vIndex) { - return normals.get(safeIndex(vIndex, N_STRIDE, 0)); - } - - @Override - public float nyf(long vIndex) { - return normals.get(safeIndex(vIndex, N_STRIDE, 1)); - } - - @Override - public float nzf(long vIndex) { - return normals.get(safeIndex(vIndex, N_STRIDE, 2)); - } - - @Override - public float uf(long vIndex) { - return texCoords.get(safeIndex(vIndex, T_STRIDE, 0)); - } - - @Override - public float vf(long vIndex) { - return texCoords.get(safeIndex(vIndex, T_STRIDE, 1)); - } - - @Override - public long addf(float x, float y, float z, float nx, float ny, float nz, - float u, float v) - { - final long index = size(); - grow(verts, V_STRIDE); - verts.put(x); - verts.put(y); - verts.put(z); - grow(normals, N_STRIDE); - normals.put(nx); - normals.put(ny); - normals.put(nz); - grow(texCoords, T_STRIDE); - texCoords.put(u); - texCoords.put(v); - return index; - } - - @Override - public void setf(long vIndex, float x, float y, float z, // - float nx, float ny, float nz, // - float u, float v) - { - verts.put(safeIndex(vIndex, V_STRIDE, 0), x); - verts.put(safeIndex(vIndex, V_STRIDE, 1), y); - verts.put(safeIndex(vIndex, V_STRIDE, 2), z); - normals.put(safeIndex(vIndex, N_STRIDE, 0), nx); - normals.put(safeIndex(vIndex, N_STRIDE, 1), ny); - normals.put(safeIndex(vIndex, N_STRIDE, 2), nz); - texCoords.put(safeIndex(vIndex, T_STRIDE, 0), u); - texCoords.put(safeIndex(vIndex, T_STRIDE, 1), v); - } - - @Override - public void setPositionf(final long vIndex, final float x, - final float y, final float z) - { - verts.put(safeIndex(vIndex, V_STRIDE, 0), x); - verts.put(safeIndex(vIndex, V_STRIDE, 1), y); - verts.put(safeIndex(vIndex, V_STRIDE, 2), z); - } - - @Override - public void setNormalf(final long vIndex, final float nx, - final float ny, final float nz) - { - normals.put(safeIndex(vIndex, N_STRIDE, 0), nx); - normals.put(safeIndex(vIndex, N_STRIDE, 1), ny); - normals.put(safeIndex(vIndex, N_STRIDE, 2), nz); - } - - @Override - public void setTexturef(final long vIndex, final float u, final float v) - { - texCoords.put(safeIndex(vIndex, T_STRIDE, 0), u); - texCoords.put(safeIndex(vIndex, T_STRIDE, 1), v); - } - } - - public class Triangles implements net.imagej.mesh.Triangles { - - private static final int I_STRIDE = 3; - private static final int N_STRIDE = 3; - - private IntBuffer indices; - private FloatBuffer normals; - - public Triangles(final IntBuffer indices, final FloatBuffer normals) { - this.indices = indices; - this.normals = normals; - } - - public IntBuffer indices() { - return indices; - } - - public FloatBuffer normals() { - return normals; - } - - @Override - public Mesh mesh() { - return BufferMesh.this; - } - - @Override - public long size() { - return indices.limit() / I_STRIDE; - } - - @Override - public long vertex0(long tIndex) { - return indices.get(safeIndex(tIndex, I_STRIDE, 0)); - } - - @Override - public long vertex1(long tIndex) { - return indices.get(safeIndex(tIndex, I_STRIDE, 1)); - } - - @Override - public long vertex2(long tIndex) { - return indices.get(safeIndex(tIndex, I_STRIDE, 2)); - } - - @Override - public float nxf(long tIndex) { - return normals.get(safeIndex(tIndex, N_STRIDE, 0)); - } - - @Override - public float nyf(long tIndex) { - return normals.get(safeIndex(tIndex, N_STRIDE, 1)); - } - - @Override - public float nzf(long tIndex) { - return normals.get(safeIndex(tIndex, N_STRIDE, 2)); - } - - @Override - public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { - final long index = size(); - grow(indices, I_STRIDE); - indices.put(safeInt(v0)); - indices.put(safeInt(v1)); - indices.put(safeInt(v2)); - grow(normals, N_STRIDE); - normals.put(nx); - normals.put(ny); - normals.put(nz); - return index; - } - } - - private static int safeIndex(final long index, final int span, - final int offset) - { - return safeInt(span * index + offset); - } - - private static int safeInt(final long value) { - if (value > Integer.MAX_VALUE) { - throw new IndexOutOfBoundsException("Value too large: " + value); - } - return (int) value; - } - - private static ByteBuffer create(final Function creator, - final int length) - { - return creator.apply(length).order(ByteOrder.nativeOrder()); - } - - private static FloatBuffer floats(final ByteBuffer bytes) { - final FloatBuffer floats = bytes.asFloatBuffer(); - // NB: The limit must be set _after_ casting to float, - // or else the casted buffer will have a capacity of 0! - floats.limit(0); - return floats; - } - - private static IntBuffer ints(final ByteBuffer bytes) { - final IntBuffer ints = bytes.asIntBuffer(); - // NB: The limit must be set _after_ casting to int, - // or else the casted buffer will have a capacity of 0! - ints.limit(0); - return ints; - } - - /** Expands the buffer limit in anticipation of {@code put} operations. */ - private static void grow(final Buffer buffer, final int step) { - buffer.limit(buffer.limit() + step); - } + private final Vertices vertices; + private final Triangles triangles; + + public BufferMesh(final int vertexMax, final int triangleMax) { + this(vertexMax, triangleMax, true); + } + + public BufferMesh(final int vertexMax, final int triangleMax, + final boolean direct) { + this(vertexMax, triangleMax, // + direct ? ByteBuffer::allocateDirect : ByteBuffer::allocate); + } + + public BufferMesh(final int vertexMax, final int triangleMax, + final Function creator) { + this(floats(create(creator, vertexMax * 12)), // + floats(create(creator, vertexMax * 12)), // + floats(create(creator, vertexMax * 8)), // + ints(create(creator, triangleMax * 12)), // + floats(create(creator, triangleMax * 12))); + } + + public BufferMesh(final FloatBuffer verts, final FloatBuffer vNormals, + final FloatBuffer texCoords, final IntBuffer indices, + final FloatBuffer tNormals) { + vertices = new Vertices(verts, vNormals, texCoords); + triangles = new Triangles(indices, tNormals); + } + + @Override + public Vertices vertices() { + return vertices; + } + + @Override + public Triangles triangles() { + return triangles; + } + + @Override + public Mesh createVariable() { + return new BufferMesh(0, 0); + } + + // -- Inner classes -- + + public class Vertices implements net.imagej.mesh.Vertices { + + private static final int V_STRIDE = 3; + private static final int N_STRIDE = 3; + private static final int T_STRIDE = 2; + + private FloatBuffer verts; + private FloatBuffer normals; + private FloatBuffer texCoords; + + public Vertices(final FloatBuffer verts, final FloatBuffer normals, + final FloatBuffer texCoords) { + this.verts = verts; + this.normals = normals; + this.texCoords = texCoords; + } + + public FloatBuffer verts() { + return verts; + } + + public FloatBuffer normals() { + return normals; + } + + public FloatBuffer texCoords() { + return texCoords; + } + + @Override + public Mesh mesh() { + return BufferMesh.this; + } + + @Override + public long size() { + return verts.limit() / V_STRIDE; + } + + @Override + public float xf(long vIndex) { + return verts.get(safeIndex(vIndex, V_STRIDE, 0)); + } + + @Override + public float yf(long vIndex) { + return verts.get(safeIndex(vIndex, V_STRIDE, 1)); + } + + @Override + public float zf(long vIndex) { + return verts.get(safeIndex(vIndex, V_STRIDE, 2)); + } + + @Override + public float nxf(long vIndex) { + return normals.get(safeIndex(vIndex, N_STRIDE, 0)); + } + + @Override + public float nyf(long vIndex) { + return normals.get(safeIndex(vIndex, N_STRIDE, 1)); + } + + @Override + public float nzf(long vIndex) { + return normals.get(safeIndex(vIndex, N_STRIDE, 2)); + } + + @Override + public float uf(long vIndex) { + return texCoords.get(safeIndex(vIndex, T_STRIDE, 0)); + } + + @Override + public float vf(long vIndex) { + return texCoords.get(safeIndex(vIndex, T_STRIDE, 1)); + } + + @Override + public long addf(float x, float y, float z, float nx, float ny, float nz, + float u, float v) { + final long index = size(); + grow(verts, V_STRIDE); + verts.put(x); + verts.put(y); + verts.put(z); + grow(normals, N_STRIDE); + normals.put(nx); + normals.put(ny); + normals.put(nz); + grow(texCoords, T_STRIDE); + texCoords.put(u); + texCoords.put(v); + return index; + } + + @Override + public void setf(long vIndex, float x, float y, float z, // + float nx, float ny, float nz, // + float u, float v) { + verts.put(safeIndex(vIndex, V_STRIDE, 0), x); + verts.put(safeIndex(vIndex, V_STRIDE, 1), y); + verts.put(safeIndex(vIndex, V_STRIDE, 2), z); + normals.put(safeIndex(vIndex, N_STRIDE, 0), nx); + normals.put(safeIndex(vIndex, N_STRIDE, 1), ny); + normals.put(safeIndex(vIndex, N_STRIDE, 2), nz); + texCoords.put(safeIndex(vIndex, T_STRIDE, 0), u); + texCoords.put(safeIndex(vIndex, T_STRIDE, 1), v); + } + + @Override + public void setPositionf(final long vIndex, final float x, + final float y, final float z) { + verts.put(safeIndex(vIndex, V_STRIDE, 0), x); + verts.put(safeIndex(vIndex, V_STRIDE, 1), y); + verts.put(safeIndex(vIndex, V_STRIDE, 2), z); + } + + @Override + public void setNormalf(final long vIndex, final float nx, + final float ny, final float nz) { + normals.put(safeIndex(vIndex, N_STRIDE, 0), nx); + normals.put(safeIndex(vIndex, N_STRIDE, 1), ny); + normals.put(safeIndex(vIndex, N_STRIDE, 2), nz); + } + + @Override + public void setTexturef(final long vIndex, final float u, final float v) { + texCoords.put(safeIndex(vIndex, T_STRIDE, 0), u); + texCoords.put(safeIndex(vIndex, T_STRIDE, 1), v); + } + + @Override + public net.imagej.mesh.Vertices createVariable() { + return new Vertices(null, null, null); + } + + @Override + public void set(net.imagej.mesh.Vertices source) { + if (source instanceof net.imagej.mesh.nio.BufferMesh.Vertices) { + set(source, ((Vertices) source).isDirect()); + } else { + set(source, true);// Direct by default + } + } + + public void set(net.imagej.mesh.Vertices source, boolean isDirect) { + if (isDirect) { + verts = floats(ByteBuffer.allocateDirect((int) (source.size() * V_STRIDE * 4))); + normals = floats(ByteBuffer.allocateDirect((int) (source.size() * N_STRIDE * 4))); + texCoords = floats(ByteBuffer.allocateDirect((int) (source.size() * T_STRIDE * 4))); + } else { + verts = floats(ByteBuffer.allocate((int) (source.size() * V_STRIDE * 4))); + normals = floats(ByteBuffer.allocate((int) (source.size() * N_STRIDE * 4))); + texCoords = floats(ByteBuffer.allocate((int) (source.size() * T_STRIDE * 4))); + } + + Iterator i = source.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + public boolean isDirect() { + return verts.isDirect(); + } + + @Override + public Vertices copy() { + Vertices c = (Vertices) createVariable(); + c.set(this); + return c; + } + } + + public class Triangles implements net.imagej.mesh.Triangles { + + private static final int I_STRIDE = 3; + private static final int N_STRIDE = 3; + + private IntBuffer indices; + private FloatBuffer normals; + + public Triangles(final IntBuffer indices, final FloatBuffer normals) { + this.indices = indices; + this.normals = normals; + } + + public IntBuffer indices() { + return indices; + } + + public FloatBuffer normals() { + return normals; + } + + @Override + public Mesh mesh() { + return BufferMesh.this; + } + + @Override + public long size() { + return indices.limit() / I_STRIDE; + } + + @Override + public long vertex0(long tIndex) { + return indices.get(safeIndex(tIndex, I_STRIDE, 0)); + } + + @Override + public long vertex1(long tIndex) { + return indices.get(safeIndex(tIndex, I_STRIDE, 1)); + } + + @Override + public long vertex2(long tIndex) { + return indices.get(safeIndex(tIndex, I_STRIDE, 2)); + } + + @Override + public float nxf(long tIndex) { + return normals.get(safeIndex(tIndex, N_STRIDE, 0)); + } + + @Override + public float nyf(long tIndex) { + return normals.get(safeIndex(tIndex, N_STRIDE, 1)); + } + + @Override + public float nzf(long tIndex) { + return normals.get(safeIndex(tIndex, N_STRIDE, 2)); + } + + @Override + public long addf(long v0, long v1, long v2, float nx, float ny, float nz) { + final long index = size(); + grow(indices, I_STRIDE); + indices.put(safeInt(v0)); + indices.put(safeInt(v1)); + indices.put(safeInt(v2)); + grow(normals, N_STRIDE); + normals.put(nx); + normals.put(ny); + normals.put(nz); + return index; + } + + @Override + public net.imagej.mesh.Triangles createVariable() { + return new Triangles(null, null); + } + + + @Override + public void set(net.imagej.mesh.Triangles source) { + if (source instanceof Triangles) { + set(source, ((Triangles) source).isDirect()); + } else { + set(source, true); + } + } + + public void set(net.imagej.mesh.Triangles source, boolean isDirect) { + if (isDirect) { + indices = ints(ByteBuffer.allocateDirect((int) (source.size() * I_STRIDE * 4))); + normals = floats(ByteBuffer.allocateDirect((int) (source.size() * N_STRIDE * 4))); + } else { + indices = ints(ByteBuffer.allocate((int) (source.size() * I_STRIDE * 4))); + normals = floats(ByteBuffer.allocate((int) (source.size() * N_STRIDE * 4))); + } + + Iterator i = source.iterator(); + while (i.hasNext()) { + add(i.next()); + } + } + + public boolean isDirect() { + return indices.isDirect(); + } + + @Override + public Triangles copy() { + Triangles c = (Triangles) createVariable(); + c.set(this); + return c; + } + + } + + private static int safeIndex(final long index, final int span, + final int offset) { + return safeInt(span * index + offset); + } + + private static int safeInt(final long value) { + if (value > Integer.MAX_VALUE) { + throw new IndexOutOfBoundsException("Value too large: " + value); + } + return (int) value; + } + + private static ByteBuffer create(final Function creator, + final int length) { + return creator.apply(length).order(ByteOrder.nativeOrder()); + } + + private static FloatBuffer floats(final ByteBuffer bytes) { + final FloatBuffer floats = bytes.asFloatBuffer(); + // NB: The limit must be set _after_ casting to float, + // or else the casted buffer will have a capacity of 0! + floats.limit(0); + return floats; + } + + private static IntBuffer ints(final ByteBuffer bytes) { + final IntBuffer ints = bytes.asIntBuffer(); + // NB: The limit must be set _after_ casting to int, + // or else the casted buffer will have a capacity of 0! + ints.limit(0); + return ints; + } + + /** + * Expands the buffer limit in anticipation of {@code put} operations. + */ + private static void grow(final Buffer buffer, final int step) { + buffer.limit(buffer.limit() + step); + } } diff --git a/src/test/java/net/imagej/mesh/AbstractMeshTest.java b/src/test/java/net/imagej/mesh/AbstractMeshTest.java index b81a403..1b664b2 100644 --- a/src/test/java/net/imagej/mesh/AbstractMeshTest.java +++ b/src/test/java/net/imagej/mesh/AbstractMeshTest.java @@ -144,7 +144,12 @@ public void testMesh() throws Exception { t2v0x, t2v0y, t2v0z, // t3nx, t3ny, t3nz); - + // Test copying + Mesh duplicate = mesh.copy(); + assertEquals(mesh.vertices().size(), duplicate.vertices().size()); + assertEquals(mesh.triangles().size(), duplicate.triangles().size()); + assertEquals(mesh.triangles().vertex0(t1), duplicate.triangles().vertex0(t1)); + assertEquals(mesh.triangles().vertex2(t2), duplicate.triangles().vertex2(t2)); } @Test @@ -153,13 +158,13 @@ public void testTriangleNormal() throws URISyntaxException, IOException { Mesh inputMesh = new NaiveDoubleMesh(); inputMesh.vertices().add(1, 1, 1); inputMesh.vertices().add(1, -1, 1); - inputMesh.vertices().add(1,0,-1); + inputMesh.vertices().add(1, 0, -1); inputMesh.triangles().add(0, 1, 2, 1, 0, 0); Mesh lazyInputMesh = new NaiveDoubleMesh(); lazyInputMesh.vertices().add(1, 1, 1); lazyInputMesh.vertices().add(1, -1, 1); - lazyInputMesh.vertices().add(1,0,-1); + lazyInputMesh.vertices().add(1, 0, -1); lazyInputMesh.triangles().add(0, 1, 2); Mesh outMesh = new BufferMesh((int) inputMesh.vertices().size(), (int) inputMesh.triangles().size()); @@ -167,14 +172,14 @@ public void testTriangleNormal() throws URISyntaxException, IOException { for (int idx = 0; idx < inputMesh.triangles().size(); idx++) { // calculateNormals test - assertTriangleNormal(inputMesh,0, outMesh.triangles().nx(idx), outMesh.triangles().ny(idx), outMesh.triangles().nz(idx)); + assertTriangleNormal(inputMesh, 0, outMesh.triangles().nx(idx), outMesh.triangles().ny(idx), outMesh.triangles().nz(idx)); // Add triangles automatic normals calc test - assertTriangleNormal(inputMesh,0, lazyInputMesh.triangles().nx(idx), lazyInputMesh.triangles().ny(idx), lazyInputMesh.triangles().nz(idx)); + assertTriangleNormal(inputMesh, 0, lazyInputMesh.triangles().nx(idx), lazyInputMesh.triangles().ny(idx), lazyInputMesh.triangles().nz(idx)); } } private void assertTriangleNormal(Mesh mesh, long tIndex, // - double nx, double ny, double nz) { + double nx, double ny, double nz) { // We know that our normal calculation does normalization, let's pre-normalize input normals double mx = mesh.triangles().nx(tIndex); double my = mesh.triangles().ny(tIndex);