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);
}
}
}
});
}
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;
}
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;
}
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;
}
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);
}
}
});
}
Aggregations