Search in sources :

Example 1 with ItemTriangleMesh

use of uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh in project GDSC-SMLM by aherbert.

the class ImageJ3DResultsViewer method createMesh.

@SuppressWarnings("unused")
private static CustomMesh createMesh(final ImageJ3DResultsViewerSettingsOrBuilder settings, LocalList<Point3f> points, final Point3f[] sphereSize, float transparency, float[] alpha) {
    // Coordinates + color
    int stride = 3 + 3;
    if (alpha != null) {
        // add color alpha
        stride++;
    }
    // Support drawing as points ...
    if (settings.getRendering() == 0) {
        final long arraySize = (long) points.size() * stride;
        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.", arraySize, capacity), 80));
            // @formatter:on
            return null;
        }
        CustomPointMesh mesh;
        if (alpha != null) {
            final TransparentItemPointMesh mesh2 = new TransparentItemPointMesh(points, null, transparency);
            mesh = mesh2;
            mesh2.setItemAlpha(alpha);
        } else {
            mesh = new ItemPointMesh(points, null, transparency);
        }
        mesh.setPointSize(sphereSize[0].x);
        return mesh;
    }
    final Rendering r = Rendering.forNumber(settings.getRendering());
    // Repeated mesh creation is much faster as the normals are cached.
    // There does not appear to be a difference in the speed the image responds
    // to user interaction between indexed or standard triangles.
    // Currently the RepeatedIndexedTriangleMesh computes the normals a different way to
    // the super class to preserve the orientation of the normals. So if the coordinates
    // are modified through the mesh then the appearance will change. For now just use
    // the RepeatedTriangleMesh.
    // TODO - check this. It may not be true if the shading mode is flat...
    // Also the IndexedTriangleMesh has one normal per vertex and this causes a colour fall-off
    // on the triangle plane towards the edges. The TriangleMesh colours the entire surface
    // of each triangle the same which looks 'normal'.
    final List<Point3f> point = Shape3DHelper.createLocalisationObject(r);
    // + normals
    stride += 3;
    final int singlePointSize = point.size();
    final long size = (long) points.size() * singlePointSize;
    final long arraySize = size * stride;
    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 rendering model with fewer vertices.", arraySize, capacity), 80));
        // @formatter:on
        return null;
    }
    if (size > 10000000L) {
        final ExtendedGenericDialog egd = new ExtendedGenericDialog(TITLE);
        egd.addMessage("The results will generate a large mesh of " + size + " vertices.\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 double creaseAngle = (r.isHighResolution()) ? 44 : 0;
    // Used for debugging construction time
    final ImageJTrackProgress progress = null;
    if (alpha != null) {
        final TransparentItemTriangleMesh mesh = new TransparentItemTriangleMesh(point.toArray(new Point3f[singlePointSize]), points.toArray(new Point3f[0]), sphereSize, null, transparency, creaseAngle, progress);
        mesh.setItemAlpha(alpha);
        return mesh;
    }
    return new ItemTriangleMesh(point.toArray(new Point3f[singlePointSize]), points.toArray(new Point3f[0]), sphereSize, null, transparency, creaseAngle, progress);
}
Also used : ItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemPointMesh) TransparentItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemPointMesh) ItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh) TransparentItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemTriangleMesh) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) CustomPointMesh(customnode.CustomPointMesh) TransparentItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemTriangleMesh) Point3f(org.scijava.vecmath.Point3f) Rendering(uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering) ImageJTrackProgress(uk.ac.sussex.gdsc.core.ij.ImageJTrackProgress) TransparentItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemPointMesh)

Example 2 with ItemTriangleMesh

use of uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh in project GDSC-SMLM by aherbert.

the class ImageJ3DResultsViewer method createShape.

@SuppressWarnings("unused")
private static Shape3D createShape(Builder settings) {
    final LocalList<Point3f> points = new LocalList<>(1);
    points.push(new Point3f());
    // We try and match the geometry and appearance of the standard mesh.
    // Do this by creating a mesh with a single point and get the Geometry and Appearance.
    GeometryArray ga;
    CustomMesh mesh;
    final float transparency = getTransparency(settings);
    // Support drawing as points ...
    if (settings.getRendering() == 0) {
        mesh = new TransparentItemPointMesh(points, null, transparency);
        ((ItemPointMesh) mesh).setPointSize((float) settings.getPixelSize());
        updateAppearance(mesh, settings);
        // Assume the TransparentItemPointMesh sets COLOR_4
        ga = (GeometryArray) mesh.getGeometry();
    } else {
        final Rendering r = Rendering.forNumber(settings.getRendering());
        final List<Point3f> point = Shape3DHelper.createLocalisationObject(r);
        final Point3f[] vertices = point.toArray(new Point3f[1]);
        // Correct the direction
        ItemTriangleMesh.checkFacets(vertices);
        final double creaseAngle = (r.isHighResolution()) ? 44 : 0;
        mesh = new ItemTriangleMesh(vertices, points.toArray(new Point3f[1]), null, null, transparency, creaseAngle, null);
        updateAppearance(mesh, settings);
        final int nVertices = vertices.length;
        ga = new TriangleArray(nVertices, GeometryArray.COORDINATES | GeometryArray.NORMALS);
        // Copy the coords and normals. We don't require the vertex colours.
        final float[] coords = new float[nVertices * 3];
        final float[] normals = new float[nVertices * 3];
        final GeometryArray gaToCopy = (GeometryArray) mesh.getGeometry();
        gaToCopy.getCoordinates(0, coords);
        gaToCopy.getNormals(0, normals);
        ga.setCoordinates(0, coords);
        ga.setNormals(0, normals);
        ga.setValidVertexCount(nVertices);
    }
    return new Shape3D(ga, mesh.getAppearance());
}
Also used : ItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemPointMesh) TransparentItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemPointMesh) ItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh) TransparentItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemTriangleMesh) IndexedGeometryArray(org.scijava.java3d.IndexedGeometryArray) GeometryArray(org.scijava.java3d.GeometryArray) TriangleArray(org.scijava.java3d.TriangleArray) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) Point3f(org.scijava.vecmath.Point3f) Rendering(uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering) CustomMesh(customnode.CustomMesh) Shape3D(org.scijava.java3d.Shape3D) TransparentItemPointMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemPointMesh)

Example 3 with ItemTriangleMesh

use of uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh in project GDSC-SMLM by aherbert.

the class ImageJ3DResultsViewerDemo method run.

@Override
public void run(String arg) {
    if (ImageJ3DViewerUtils.JAVA_3D_VERSION == null) {
        IJ.error(TITLE, "Java 3D is not available");
        return;
    }
    final boolean renderingTest = true;
    if (renderingTest) {
        // Put all the shapes from rendering on a view and see how they look.
        final Image3DUniverse univ = new Image3DUniverse();
        univ.showAttribute(DefaultUniverse.ATTRIBUTE_SCALEBAR, false);
        univ.show();
        final ImageWindow3D w = univ.getWindow();
        GUI.center(w);
        // Test how many vertices a primitive sphere has
        float x = 0;
        final float y = 0;
        final float space = 2.5f;
        for (final Rendering rendering : Rendering.values()) {
            final Shape3D shape = Shape3DHelper.createShape(rendering, 3);
            final Appearance a = shape.getAppearance();
            final ItemMesh mesh = new ReferenceItemMesh(new Point3f[] { new Point3f(x, y, 0) }, (GeometryArray) shape.getGeometry(), a, null, null, 0f);
            ImageJUtils.log("R=%s %s  Vc=%d  V=%d  T=%d", rendering, shape.getGeometry().getClass().getSimpleName(), mesh.getVerticesCountPerItem(), mesh.getVerticesPerItem(), Shape3DHelper.getNumberOfTriangles(rendering));
            if (rendering == Rendering.POINT) {
                a.getPointAttributes().setPointSize(10);
            }
            univ.addCustomMesh(mesh, x + "," + y);
            x += space;
        }
        return;
    }
    final boolean sphereTest = true;
    if (sphereTest) {
        // Sphere test
        // Put lots of spheres on a view and see how they look.
        // Is it worth supporting an ItemTriangleStripMesh so we can control
        // the sphere better than the icosahedron?
        final Image3DUniverse univ = new Image3DUniverse();
        univ.showAttribute(DefaultUniverse.ATTRIBUTE_SCALEBAR, false);
        univ.show();
        final ImageWindow3D w = univ.getWindow();
        GUI.center(w);
        // Test how many vertices a primitive sphere has
        float x = 0;
        float y = 0;
        final float space = 2.5f;
        Appearance app = null;
        for (int d = 0; d < 4; d++) {
            final List<Point3f> points = customnode.MeshMaker.createIcosahedron(d, 1f);
            final Pair<Point3f[], int[]> p = CustomContentHelper.createIndexedObject(points);
            final int v = points.size();
            final int t = v / 3;
            ImageJUtils.log("Icosahedron divisions = %d, V=%d, T=%d, Vi=%d (%.2f), i=%d", d, v, t, p.getKey().length, v / (double) p.getKey().length, p.getValue().length);
            CustomMesh mesh = new ItemTriangleMesh(points.toArray(new Point3f[0]), new Point3f[] { new Point3f(x, y, 0) }, null, null, 0);
            app = mesh.getAppearance();
            univ.addCustomMesh(mesh, x + "," + y + "," + t);
            final float y2 = y + space;
            mesh = new ItemIndexedTriangleMesh(p.getKey(), p.getValue(), new Point3f[] { new Point3f(x, y2, 0) }, null, null, 0);
            univ.addCustomMesh(mesh, x + "," + y2 + "," + t);
            x += space;
        }
        // Avoid null pointer warnings
        if (app == null) {
            throw new NullPointerException();
        }
        // The T=800 sphere looks about the same as the Icosahedron(div=3) T=1280
        // This may be a better super-high resolution option.
        x = 0;
        y += 2 * space;
        app = (Appearance) app.cloneNodeComponent(true);
        // a.getColoringAttributes().setColor(0, 1, 0);
        app.getMaterial().setDiffuseColor(0, 1, 0);
        for (int d = 4; d < 50; d += 4) {
            // This is a triangle strip array so is more space efficient
            final Sphere s = new Sphere(1, Primitive.GENERATE_NORMALS, d);
            final int t = s.getNumTriangles();
            ImageJUtils.log("Sphere divisions = %d, V=%d, T=%d", d, s.getNumVertices(), t);
            final ItemGeometryGroup g = new ItemGeometryGroup(new Point3f[] { new Point3f(x, y, 0) }, (GeometryArray) s.getShape().getGeometry(), app, null, null, null);
            final String name = x + "," + y + "," + t;
            final CustomContent content = new CustomContent(name, true);
            content.getCurrent().display(new ItemGroupNode(g));
            univ.addContent(content);
            x += space;
        }
        return;
    }
    LocalList<Point3f> pointList;
    float scale;
    if (MemoryPeakResults.isMemoryEmpty()) {
        pointList = new LocalList<>();
        int range;
        // 9 points
        range = 1;
        // range = 49; // 99^3 = 970299 points
        for (int x = -range; x <= range; x++) {
            for (int y = -range; y <= range; y++) {
                for (int z = -range; z <= range; z++) {
                    pointList.add(new Point3f(x, y, z));
                }
            }
        }
        scale = 0.25f;
    } else {
        final ImageJ3DResultsViewerSettings.Builder settings = SettingsManager.readImageJ3DResultsViewerSettings(0).toBuilder();
        final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
        gd.addMessage("Select a dataset to display");
        ResultsManager.addInput(gd, settings.getInputOption(), InputSource.MEMORY);
        gd.showDialog();
        if (gd.wasCanceled()) {
            return;
        }
        final String name = ResultsManager.getInputSource(gd);
        settings.setInputOption(name);
        SettingsManager.writeSettings(settings);
        final MemoryPeakResults results = ResultsManager.loadInputResults(name, false, null, null);
        if (MemoryPeakResults.isEmpty(results)) {
            IJ.error(TITLE, "No results could be loaded");
            IJ.showStatus("");
            return;
        }
        pointList = ImageJ3DResultsViewer.getPoints(results, settings);
        if (pointList == null) {
            return;
        }
        scale = 10f;
    }
    final Image3DUniverse univ = new Image3DUniverse();
    univ.showAttribute(DefaultUniverse.ATTRIBUTE_SCALEBAR, false);
    univ.show();
    final ImageWindow3D w = univ.getWindow();
    GUI.center(w);
    final View view = univ.getViewer().getView();
    view.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_GEOMETRY);
    // I am not sure if this is required if objects are sorted.
    // view.setDepthBufferFreezeTransparent(false)
    IJ.showStatus("Creating points ...");
    final Point3f[] points = pointList.toArray(new Point3f[0]);
    final Point3f[] sizes = new Point3f[] { new Point3f(scale, scale, scale) };
    final Appearance appearance = new Appearance();
    final TransparencyAttributes ta = new TransparencyAttributes();
    ta.setTransparency(0.5f);
    ta.setTransparencyMode(TransparencyAttributes.FASTEST);
    appearance.setTransparencyAttributes(ta);
    final ItemGeometryGroup pointGroup = new ItemGeometryGroup(points, null, appearance, sizes, null, null);
    // pointGroup = new OrderedItemGeometryGroup(points, null, appearance, sizes, null, null);
    // // This supports transparency sorting
    // BranchGroup bg = new BranchGroup();
    // bg.addChild(pointGroup);
    // bg.compile();
    // univ.getScene().addChild(bg);
    // // This does not since ContentInstant uses an OrderedPath to show:
    // // the content; the object bounding box, coordinate system and point list
    // final Content c = new Content("Test");
    // final ContentInstant content = c.getCurrent();
    // content.display(new PointGroupNode(pointGroup));
    // univ.addContent(c);
    // This does since ItemGeometryNode uses a Group to show the points as individual shapes
    // and the CustomContentInstant uses a group not an ordered group so show all the adornments.
    IJ.showStatus("Displaying points ...");
    final CustomContent c = new CustomContent("Test", false);
    final ContentInstant content = c.getCurrent();
    content.display(new ItemGroupNode(pointGroup));
    univ.addContent(c);
    IJ.showStatus("Done");
}
Also used : ImageJ3DResultsViewerSettings(uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.ImageJ3DResultsViewerSettings) ItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemMesh) ReferenceItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ReferenceItemMesh) ItemTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh) ItemGroupNode(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemGroupNode) Sphere(org.scijava.java3d.utils.geometry.Sphere) CustomContent(uk.ac.sussex.gdsc.smlm.ij.ij3d.CustomContent) Point3f(org.scijava.vecmath.Point3f) CustomMesh(customnode.CustomMesh) Shape3D(org.scijava.java3d.Shape3D) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) TransparencyAttributes(org.scijava.java3d.TransparencyAttributes) Image3DUniverse(ij3d.Image3DUniverse) ReferenceItemMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ReferenceItemMesh) ContentInstant(ij3d.ContentInstant) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) Appearance(org.scijava.java3d.Appearance) View(org.scijava.java3d.View) ImageWindow3D(ij3d.ImageWindow3D) ItemGeometryGroup(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemGeometryGroup) Rendering(uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering) ItemIndexedTriangleMesh(uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemIndexedTriangleMesh)

Aggregations

Point3f (org.scijava.vecmath.Point3f)3 ItemTriangleMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemTriangleMesh)3 Rendering (uk.ac.sussex.gdsc.smlm.ij.ij3d.Shape3DHelper.Rendering)3 CustomMesh (customnode.CustomMesh)2 Shape3D (org.scijava.java3d.Shape3D)2 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)2 ItemPointMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.ItemPointMesh)2 TransparentItemPointMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemPointMesh)2 TransparentItemTriangleMesh (uk.ac.sussex.gdsc.smlm.ij.ij3d.TransparentItemTriangleMesh)2 CustomPointMesh (customnode.CustomPointMesh)1 ContentInstant (ij3d.ContentInstant)1 Image3DUniverse (ij3d.Image3DUniverse)1 ImageWindow3D (ij3d.ImageWindow3D)1 Appearance (org.scijava.java3d.Appearance)1 GeometryArray (org.scijava.java3d.GeometryArray)1 IndexedGeometryArray (org.scijava.java3d.IndexedGeometryArray)1 TransparencyAttributes (org.scijava.java3d.TransparencyAttributes)1 TriangleArray (org.scijava.java3d.TriangleArray)1 View (org.scijava.java3d.View)1 Sphere (org.scijava.java3d.utils.geometry.Sphere)1