Search in sources :

Example 1 with IndexedGeometryArray

use of org.scijava.java3d.IndexedGeometryArray in project GDSC-SMLM by aherbert.

the class ItemMesh method reorderFast.

@Override
public void reorderFast(int[] indices) {
    changed = true;
    final int oldSize = size();
    final int size = (indices == null) ? 0 : Math.min(oldSize, indices.length);
    if (size == 0 || indices == null) {
        points = new Point3f[0];
        sizes = new Point3f[0];
        this.setGeometry(null);
        return;
    }
    // From here on we assume the current geometry will not be null
    // as this only happens when the original size is zero. Size has
    // been checked at this point to be the smaller of new and old.
    final GeometryArray ga = (GeometryArray) getGeometry();
    points = reorderPoints(points, indices);
    // Sizes could be null or a single size
    if (sizes != null && sizes.length == points.length) {
        sizes = reorderPoints(sizes, indices);
    }
    // Reorder all things in the geometry: coordinates and colour.
    // The normals, indices, strip counts are are unchanged.
    // int objectSize = vertexCount;
    int countPerObject = vertexCount * 3;
    final float[] oldCoords = new float[oldSize * countPerObject];
    ga.getCoordinates(0, oldCoords);
    final float[] coords = new float[size * countPerObject];
    for (int i = 0; i < size; i++) {
        final int j = indices[i];
        final int ii = i * countPerObject;
        final int jj = j * countPerObject;
        System.arraycopy(oldCoords, jj, coords, ii, countPerObject);
    }
    final float[] colors;
    if (hasColor()) {
        countPerObject = colorUpdater.size();
        final int colorSize = oldSize * countPerObject;
        final float[] oldColors = (colorSize < oldCoords.length) ? oldCoords : new float[colorSize];
        ga.getColors(0, oldColors);
        colors = new float[size * countPerObject];
        for (int i = 0; i < size; i++) {
            final int j = indices[i];
            final int ii = i * countPerObject;
            final int jj = j * countPerObject;
            System.arraycopy(oldColors, jj, colors, ii, countPerObject);
        }
    } else {
        colors = null;
    }
    ga.updateData(new GeometryUpdater() {

        @Override
        public void updateData(Geometry geometry) {
            final GeometryArray ga = (GeometryArray) geometry;
            // We re-use the geometry and just truncate the vertex count
            ga.setCoordinates(0, coords);
            if (colors != null) {
                ga.setColors(0, colors);
            }
            if (size != oldSize) {
                if (isIndexGeometryArray()) {
                    if (isStripGeometryArray()) {
                        int[] indices = new int[indexCount * oldSize];
                        ((IndexedGeometryStripArray) ga).getStripIndexCounts(indices);
                        indices = Arrays.copyOf(indices, indexCount * size);
                        ((IndexedGeometryStripArray) ga).setStripIndexCounts(indices);
                    } else {
                        ((IndexedGeometryArray) ga).setValidIndexCount(size * indexCount);
                    }
                } else if (isStripGeometryArray()) {
                    int[] indices = new int[vertexCount * oldSize];
                    ((GeometryStripArray) ga).getStripVertexCounts(indices);
                    indices = Arrays.copyOf(indices, vertexCount * size);
                    ((GeometryStripArray) ga).setStripVertexCounts(indices);
                } else {
                    ga.setValidVertexCount(size * vertexCount);
                }
            }
        }
    });
}
Also used : GeometryUpdater(org.scijava.java3d.GeometryUpdater) Geometry(org.scijava.java3d.Geometry) GeometryStripArray(org.scijava.java3d.GeometryStripArray) IndexedGeometryStripArray(org.scijava.java3d.IndexedGeometryStripArray) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray)

Example 2 with IndexedGeometryArray

use of org.scijava.java3d.IndexedGeometryArray in project GDSC-SMLM by aherbert.

the class ItemMesh method createGeometry.

/**
 * Creates the geometry.
 *
 * @param coords the coords
 * @param sourceGa the source geometry array
 * @return the geometry array
 */
protected GeometryArray createGeometry(float[] coords, GeometryArray sourceGa) {
    final GeometryArray ga = createGeometryArray(sourceGa, 0);
    ga.setCoordinates(0, coords);
    ga.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
    // Handle normals
    boolean doNormals = hasNormals();
    // Handle colors
    if (hasColor()) {
        ga.setCapability(GeometryArray.ALLOW_COLOR_READ);
        ga.setCapability(GeometryArray.ALLOW_COLOR_WRITE);
        colorUpdater = ArrayColorUpdater.create(vertexCount, hasColor4());
    }
    // Handle indexed array
    if (isIndexGeometryArray()) {
        final IndexedGeometryArray sourceIga = (IndexedGeometryArray) sourceGa;
        final IndexedGeometryArray iga = (IndexedGeometryArray) ga;
        final int objectIndexCount = sourceIga.getValidIndexCount();
        final int[] objectIndices = new int[objectIndexCount];
        final int[] allIndices = new int[objectIndices.length * points.length];
        sourceIga.getCoordinateIndices(0, objectIndices);
        duplicateIndices(objectIndices, allIndices);
        iga.setCoordinateIndices(0, allIndices);
        // Check if we need the color and normal indices
        if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) {
            if (hasNormals()) {
            // Done later
            }
            if (hasColor()) {
            // Update the colour for each vertex as normal
            }
        } else {
            if (hasNormals()) {
                // Use the same index for all vertices for normals
                sourceIga.getNormalIndices(0, objectIndices);
                duplicate(objectIndices, 0, objectIndices.length, points.length, allIndices, 0);
                iga.setNormalIndices(0, allIndices);
                final float[] normals = new float[(MathUtils.max(objectIndices) + 1) * 3];
                sourceIga.getNormals(0, normals);
                iga.setNormals(0, normals);
                doNormals = false;
            }
            if (hasColor()) {
                // Use a single index per item for vertex colour
                for (int i = 0, k = 0; i < points.length; i++) {
                    for (int j = 0; j < objectIndexCount; j++) {
                        allIndices[k++] = i;
                    }
                }
                iga.setColorIndices(0, allIndices);
                // Only have to update a single colour per item
                colorUpdater = ArrayColorUpdater.create(1, hasColor4());
            }
        }
    }
    if (doNormals) {
        final float[] objectNormals = new float[vertexCount * 3];
        sourceGa.getNormals(0, objectNormals);
        final float[] allNormals = new float[objectNormals.length * points.length];
        duplicate(objectNormals, 0, objectNormals.length, points.length, allNormals, 0);
        ga.setNormals(0, allNormals);
    }
    return ga;
}
Also used : IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray)

Example 3 with IndexedGeometryArray

use of org.scijava.java3d.IndexedGeometryArray in project GDSC-SMLM by aherbert.

the class ImageJ3DResultsViewer method createItemMesh.

private static ItemMesh createItemMesh(final ImageJ3DResultsViewerSettingsOrBuilder settings, LocalList<Point3f> points, final Point3f[] sphereSize, float transparency, float[] alpha) {
    final Rendering rendering = Rendering.forNumber(settings.getRendering());
    final int colorDepth = (alpha != null) ? 4 : 3;
    final Shape3D shape = Shape3DHelper.createShape(rendering, colorDepth);
    final GeometryArray ga = (GeometryArray) shape.getGeometry();
    final Appearance appearance = shape.getAppearance();
    // Estimate the largest array required for the data.
    // The mesh is created by reference using an array for coords, normals and colors.
    final int singlePointVertexSize = ga.getValidVertexCount();
    int singlePointIndexSize = 0;
    final int stride = Math.max(3, colorDepth);
    if (ga instanceof IndexedGeometryArray) {
        // Indexed arrays may have much larger index array than the vertex array
        singlePointIndexSize = ((IndexedGeometryArray) ga).getIndexCount();
    }
    final int singlePointSize = Math.max(singlePointIndexSize, stride * singlePointVertexSize);
    final long arraySize = (long) points.size() * singlePointSize;
    if (arraySize > CustomContentHelper.MAX_ARRAY_SIZE) {
        final double capacity = (double) arraySize / CustomContentHelper.MAX_ARRAY_SIZE;
        // @formatter:off
        IJ.error(TITLE, TextUtils.wrap(String.format("The results will generate data of %d values. " + "This is amount of data is not supported (%.2fx capacity). " + "Please choose a different dataset with fewer points or " + "different rendering model.", arraySize, capacity), 80));
        // @formatter:on
        return null;
    }
    // Support drawing as points ...
    if (settings.getRendering() == 0) {
        final ItemMesh mesh = new ReferenceItemMesh(points.toArray(new Point3f[0]), ga, appearance, null, null, transparency);
        if (alpha != null) {
            mesh.setItemAlpha(alpha);
        }
        mesh.getAppearance().getPointAttributes().setPointSize(sphereSize[0].x);
        return mesh;
    }
    final int triangles = Shape3DHelper.getNumberOfTriangles(rendering);
    final long size = (long) points.size() * triangles;
    if (size > 10000000L) {
        final ExtendedGenericDialog egd = new ExtendedGenericDialog(TITLE);
        egd.addMessage("The results will generate a large mesh of " + size + " triangles.\nThis may take a long time to render and may run out of memory.");
        egd.setOKLabel("Continue");
        egd.showDialog();
        if (egd.wasCanceled()) {
            return null;
        }
    }
    IJ.showStatus("Creating 3D mesh ...");
    final ItemMesh mesh = new ReferenceItemMesh(points.toArray(new Point3f[0]), ga, appearance, sphereSize, null, transparency);
    if (alpha != null) {
        mesh.setItemAlpha(alpha);
    }
    return mesh;
}
Also used : Point3f(org.scijava.vecmath.Point3f) Rendering(uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering) ReferenceItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ReferenceItemMesh) ItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemMesh) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) ReferenceItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ReferenceItemMesh) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray) Shape3D(org.scijava.java3d.Shape3D) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) Appearance(org.scijava.java3d.Appearance)

Example 4 with IndexedGeometryArray

use of org.scijava.java3d.IndexedGeometryArray in project GDSC-SMLM by aherbert.

the class ReferenceItemMesh method createGeometry.

@Override
protected GeometryArray createGeometry(float[] coords, GeometryArray sourceGa) {
    final GeometryArray ga = createGeometryArray(sourceGa, GeometryArray.BY_REFERENCE);
    ga.setCoordRefFloat(coords);
    ga.setCapability(GeometryArray.ALLOW_REF_DATA_READ);
    ga.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
    // Handle indexed array
    if (isIndexGeometryArray()) {
        final IndexedGeometryArray sourceIga = (IndexedGeometryArray) sourceGa;
        final IndexedGeometryArray iga = (IndexedGeometryArray) ga;
        final int objectIndexCount = sourceIga.getValidIndexCount();
        final int[] objectIndices = new int[objectIndexCount];
        final int[] allIndices = new int[objectIndices.length * points.length];
        sourceIga.getCoordinateIndices(0, objectIndices);
        duplicateIndices(objectIndices, allIndices);
        iga.setCoordinateIndices(0, allIndices);
        // Check if we need the color and normal indices
        if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) {
            // Duplicate the other indices
            if (hasNormals()) {
                sourceIga.getNormalIndices(0, objectIndices);
                duplicateIndices(objectIndices, allIndices);
                iga.setNormalIndices(0, allIndices);
            }
            if (hasColor()) {
                sourceIga.getColorIndices(0, objectIndices);
                duplicateIndices(objectIndices, allIndices);
                iga.setColorIndices(0, allIndices);
            }
        }
    }
    // Handle normals
    if (hasNormals()) {
        final float[] objectNormals = new float[vertexCount * 3];
        sourceGa.getNormals(0, objectNormals);
        final float[] allNormals = new float[objectNormals.length * points.length];
        duplicate(objectNormals, 0, objectNormals.length, points.length, allNormals, 0);
        ga.setNormalRefFloat(allNormals);
    }
    // Handle colors
    if (hasColor()) {
        colorUpdater = ArrayColorUpdater.create(vertexCount, hasColor4());
        ga.setColorRefFloat(new float[colorUpdater.size() * size()]);
    }
    return ga;
}
Also used : IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray)

Example 5 with IndexedGeometryArray

use of org.scijava.java3d.IndexedGeometryArray in project GDSC-SMLM by aherbert.

the class ReferenceItemMesh method reorderFast.

@SuppressWarnings("null")
@Override
public void reorderFast(int[] indices) {
    changed = true;
    final int oldSize = size();
    final int size = (indices == null) ? 0 : Math.min(oldSize, indices.length);
    if (size == 0) {
        points = new Point3f[0];
        sizes = new Point3f[0];
        this.setGeometry(null);
        return;
    }
    // From here on we assume the current geometry will not be null
    // as this only happens when the original size is zero. Size has
    // been checked at this point to be the smaller of new and old.
    final GeometryArray ga = (GeometryArray) getGeometry();
    points = reorderPoints(points, indices);
    // Sizes could be null or a single size
    if (sizes != null && sizes.length == points.length) {
        sizes = reorderPoints(sizes, indices);
    }
    // Reorder all things in the geometry: coordinates and colour.
    // The normals, indices, strip counts are are unchanged.
    int countPerObject = vertexCount * 3;
    final float[] oldCoords = ga.getCoordRefFloat();
    final float[] coords = new float[size * countPerObject];
    for (int i = 0; i < size; i++) {
        final int j = indices[i];
        final int ii = i * countPerObject;
        final int jj = j * countPerObject;
        System.arraycopy(oldCoords, jj, coords, ii, countPerObject);
    }
    final float[] colors;
    if (hasColor()) {
        countPerObject = colorUpdater.size();
        final float[] oldColors = ga.getColorRefFloat();
        colors = new float[size * countPerObject];
        for (int i = 0; i < size; i++) {
            final int j = indices[i];
            final int ii = i * countPerObject;
            final int jj = j * countPerObject;
            System.arraycopy(oldColors, jj, colors, ii, countPerObject);
        }
    } else {
        colors = null;
    }
    ga.updateData(geometry -> {
        final GeometryArray geom = (GeometryArray) geometry;
        // We re-use the geometry and just truncate the vertex count
        geom.setCoordRefFloat(coords);
        if (colors != null) {
            geom.setColorRefFloat(colors);
        }
        if (size != oldSize) {
            if (isIndexGeometryArray()) {
                if (isStripGeometryArray()) {
                    int[] indices2 = new int[indexCount * oldSize];
                    ((IndexedGeometryStripArray) geom).getStripIndexCounts(indices2);
                    indices2 = Arrays.copyOf(indices2, indexCount * size);
                    ((IndexedGeometryStripArray) geom).setStripIndexCounts(indices2);
                } else {
                    ((IndexedGeometryArray) geom).setValidIndexCount(size * indexCount);
                }
            } else if (isStripGeometryArray()) {
                int[] indices2 = new int[vertexCount * oldSize];
                ((GeometryStripArray) geom).getStripVertexCounts(indices2);
                indices2 = Arrays.copyOf(indices2, vertexCount * size);
                ((GeometryStripArray) geom).setStripVertexCounts(indices2);
            } else {
                geom.setValidVertexCount(size * vertexCount);
            }
        }
    });
}
Also used : IndexedGeometryStripArray(org.scijava.java3d.IndexedGeometryStripArray) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray)

Aggregations

GeometryArray (org.scijava.java3d.GeometryArray)5 IndexedGeometryArray (org.scijava.java3d.IndexedGeometryArray)5 IndexedGeometryStripArray (org.scijava.java3d.IndexedGeometryStripArray)2 Appearance (org.scijava.java3d.Appearance)1 Geometry (org.scijava.java3d.Geometry)1 GeometryStripArray (org.scijava.java3d.GeometryStripArray)1 GeometryUpdater (org.scijava.java3d.GeometryUpdater)1 Shape3D (org.scijava.java3d.Shape3D)1 Point3f (org.scijava.vecmath.Point3f)1 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)1 ItemMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemMesh)1 ReferenceItemMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.ReferenceItemMesh)1 Rendering (uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering)1