Search in sources :

Example 1 with CustomLineMesh

use of customnode.CustomLineMesh in project TrakEM2 by trakem2.

the class Display3D method createMesh.

/**
 * Returns a function that returns a Content object.
 *  Does NOT add the Content to the universe; it merely creates it.
 */
public Callable<Content> createMesh(final ProjectThing pt, final Displayable displ, final int resample) {
    // OBSOLETE
    final double scale = 1.0;
    return new Callable<Content>() {

        @Override
        public Content call() {
            Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
            try {
                // the list 'triangles' is really a list of Point3f, which define a triangle every 3 consecutive points. (TODO most likely Bene Schmid got it wrong: I don't think there's any need to have the points duplicated if they overlap in space but belong to separate triangles.)
                final List<Point3f> triangles;
                // boolean no_culling_ = false;
                final Class<?> c;
                final boolean line_mesh;
                final int line_mesh_mode;
                if (null == displ) {
                    c = null;
                    line_mesh = false;
                    line_mesh_mode = Integer.MAX_VALUE;
                } else {
                    c = displ.getClass();
                    line_mesh = Tree.class.isAssignableFrom(c) || Polyline.class == c;
                    if (Tree.class.isAssignableFrom(c))
                        line_mesh_mode = CustomLineMesh.PAIRWISE;
                    else if (Polyline.class == c)
                        line_mesh_mode = CustomLineMesh.CONTINUOUS;
                    else
                        // disabled
                        line_mesh_mode = Integer.MAX_VALUE;
                }
                List<Point3f> extra_triangles = null;
                List<Color3f> triangle_colors = null, extra_triangle_colors = null;
                int rs = resample;
                if (displ instanceof AreaContainer) {
                    if (// will adjust this.resample, and return it (even if it's a default value)
                    -1 == resample)
                        // will adjust this.resample, and return it (even if it's a default value)
                        rs = Display3D.this.resample = adjustResampling();
                    else
                        rs = Display3D.this.resample;
                }
                if (AreaList.class == c) {
                    triangles = ((AreaList) displ).generateTriangles(scale, rs);
                // triangles = removeNonManifold(triangles);
                } else if (Ball.class == c) {
                    final double[][][] globe = Ball.generateGlobe(12, 12);
                    triangles = ((Ball) displ).generateTriangles(scale, globe);
                } else if (displ instanceof Line3D) {
                    // Pipe and Polyline
                    // adjustResampling();  // fails horribly, needs first to correct mesh-generation code
                    triangles = ((Line3D) displ).generateTriangles(scale, 12, 1);
                } else if (displ instanceof Tree<?>) {
                    // A 3D wire skeleton, using CustomLineMesh
                    final Tree.MeshData skeleton = ((Tree<?>) displ).generateSkeleton(scale, 12, 1);
                    triangles = skeleton.verts;
                    triangle_colors = skeleton.colors;
                    if (displ instanceof Treeline) {
                        final Tree.MeshData tube = ((Treeline) displ).generateMesh(scale, 12);
                        extra_triangles = tube.verts;
                        extra_triangle_colors = tube.colors;
                    } else if (displ instanceof AreaTree) {
                        final Tree.MeshData mesh = ((AreaTree) displ).generateMesh(scale, rs);
                        extra_triangles = mesh.verts;
                        extra_triangle_colors = mesh.colors;
                    }
                    // avoid issues with MultiMesh
                    if (null != extra_triangles && extra_triangles.isEmpty())
                        extra_triangles = null;
                } else if (Connector.class == c) {
                    final Tree.MeshData octopus = ((Connector) displ).generateMesh(scale, 12);
                    triangles = octopus.verts;
                    triangle_colors = octopus.colors;
                } else if (null == displ && pt.getType().equals("profile_list")) {
                    triangles = Profile.generateTriangles(pt, scale);
                // no_culling_ = true;
                } else {
                    Utils.log("Unrecognized type for 3D mesh generation: " + (null != displ ? displ.getClass() : null) + " : " + displ);
                    triangles = null;
                }
                // safety checks
                if (null == triangles) {
                    Utils.log("Some error ocurred: can't create triangles for " + displ);
                    return null;
                }
                if (0 == triangles.size()) {
                    Utils.log2("Skipping empty mesh for " + displ.getTitle());
                    return null;
                }
                if (!line_mesh && 0 != triangles.size() % 3) {
                    Utils.log2("Skipping non-multiple-of-3 vertices list generated for " + displ.getTitle());
                    return null;
                }
                final Color color;
                final float alpha;
                final String title;
                if (null != displ) {
                    color = displ.getColor();
                    alpha = displ.getAlpha();
                    title = makeTitle(displ);
                } else if (pt.getType().equals("profile_list")) {
                    // for profile_list: get from the first (what a kludge; there should be a ZDisplayable ProfileList object)
                    final Object obp = ((ProjectThing) pt.getChildren().get(0)).getObject();
                    if (null == obp)
                        return null;
                    final Displayable di = (Displayable) obp;
                    color = di.getColor();
                    alpha = di.getAlpha();
                    title = makeProfileListTitle(pt);
                } else {
                    title = pt.toString() + " #" + pt.getId();
                    color = null;
                    alpha = 1.0f;
                }
                // Why for all? Above no_culling_ is set to true or false, depending upon type. --> Because with transparencies it looks proper and better when no_culling is true.
                // for ALL
                final boolean no_culling = true;
                Content ct = null;
                try {
                    final Color3f c3 = new Color3f(color);
                    // If it exists, remove and add as new:
                    universe.removeContent(title);
                    final CustomMesh cm;
                    if (line_mesh) {
                        // ct = universe.createContent(new CustomLineMesh(triangles, line_mesh_mode, c3, 0), title);
                        cm = new CustomLineMesh(triangles, line_mesh_mode, c3, 0);
                    } else if (no_culling) {
                        // create a mesh with the same color and zero transparency (that is, full opacity)
                        final CustomTriangleMesh mesh = new CustomTriangleMesh(triangles, c3, 0);
                        // Set mesh properties for double-sided triangles
                        final PolygonAttributes pa = mesh.getAppearance().getPolygonAttributes();
                        pa.setCullFace(PolygonAttributes.CULL_NONE);
                        pa.setBackFaceNormalFlip(true);
                        mesh.setColor(c3);
                        // After setting properties, add to the viewer
                        // ct = universe.createContent(mesh, title);
                        cm = mesh;
                    } else {
                        // ct = universe.createContent(new CustomTriangleMesh(triangles, c3, 0), title);
                        cm = new CustomTriangleMesh(triangles, c3, 0);
                    }
                    if (null != triangle_colors)
                        cm.setColor(triangle_colors);
                    if (null == extra_triangles || 0 == extra_triangles.size()) {
                        ct = universe.createContent(cm, title);
                    } else {
                        final CustomTriangleMesh extra = new CustomTriangleMesh(extra_triangles, c3, 0);
                        if (null != extra_triangle_colors) {
                            // Set mesh properties for double-sided triangles
                            final PolygonAttributes pa = extra.getAppearance().getPolygonAttributes();
                            pa.setCullFace(PolygonAttributes.CULL_NONE);
                            pa.setBackFaceNormalFlip(true);
                            extra.setColor(extra_triangle_colors);
                        }
                        ct = universe.createContent(new CustomMultiMesh(Arrays.asList(new CustomMesh[] { cm, extra })), title);
                    }
                    // Set general content properties
                    ct.setTransparency(1f - alpha);
                    // Default is unlocked (editable) transformation; set it to locked:
                    ct.setLocked(true);
                    // register mesh title
                    synchronized (ht_pt_meshes) {
                        ht_pt_meshes.put(pt, ct.getName());
                    }
                } catch (final Throwable e) {
                    Utils.logAll("Mesh generation failed for \"" + title + "\"  from " + pt);
                    IJError.print(e);
                    e.printStackTrace();
                }
                Utils.log2(pt.toString() + " n points: " + triangles.size());
                return ct;
            } catch (final Exception e) {
                IJError.print(e);
                return null;
            }
        }
    };
}
Also used : Color3f(org.scijava.vecmath.Color3f) Callable(java.util.concurrent.Callable) CustomTriangleMesh(customnode.CustomTriangleMesh) Point3f(org.scijava.vecmath.Point3f) CustomMesh(customnode.CustomMesh) CustomMultiMesh(customnode.CustomMultiMesh) Color(java.awt.Color) PolygonAttributes(org.scijava.java3d.PolygonAttributes) CustomLineMesh(customnode.CustomLineMesh) Content(ij3d.Content)

Aggregations

CustomLineMesh (customnode.CustomLineMesh)1 CustomMesh (customnode.CustomMesh)1 CustomMultiMesh (customnode.CustomMultiMesh)1 CustomTriangleMesh (customnode.CustomTriangleMesh)1 Content (ij3d.Content)1 Color (java.awt.Color)1 Callable (java.util.concurrent.Callable)1 PolygonAttributes (org.scijava.java3d.PolygonAttributes)1 Color3f (org.scijava.vecmath.Color3f)1 Point3f (org.scijava.vecmath.Point3f)1