Search in sources :

Example 1 with Color3f

use of org.scijava.vecmath.Color3f in project TrakEM2 by trakem2.

the class Treeline method generateMesh.

/**
 * Testing for performance, 100 iterations:
 * A: 3307  (current, with clearing of table on the fly)
 * B: 4613  (without clearing table)
 * C: 4012  (without point caching)
 *
 * Although in short runs (10 iterations) A can get very bad:
 * (first run of 10)
 * A: 664
 * B: 611
 * C: 196
 * (second run of 10)
 * A: 286
 * B: 314
 * C: 513  <-- gets worse !?
 *
 * Differences are not so huge in any case.
 */
/*
	static final public void testMeshGenerationPerformance(int n_iterations) {
		// test 3D mesh generation

		Layer la = Display.getFrontLayer();
		java.util.Random rnd = new java.util.Random(67779);
		Node root = new RadiusNode(rnd.nextFloat(), rnd.nextFloat(), la);
		Node parent = root;
		for (int i=0; i<10000; i++) {
			Node child = new RadiusNode(rnd.nextFloat(), rnd.nextFloat(), la);
			parent.add(child, Node.MAX_EDGE_CONFIDENCE);
			if (0 == i % 100) {
				// add a branch of 100 nodes
				Node pa = parent;
				for (int k = 0; k<100; k++) {
					Node ch = new RadiusNode(rnd.nextFloat(), rnd.nextFloat(), la);
					pa.add(ch, Node.MAX_EDGE_CONFIDENCE);
					pa = ch;
				}
			}
			parent = child;
		}

		final AffineTransform at = new AffineTransform(1, 0, 0, 1, 67, 134);

		final ArrayList list = new ArrayList();

		final LinkedList<Node> todo = new LinkedList<Node>();

		final float scale = 0.345f;
		final Calibration cal = la.getParent().getCalibration();
		final float pixelWidthScaled = (float) cal.pixelWidth * scale;
		final float pixelHeightScaled = (float) cal.pixelHeight * scale;
		final int sign = cal.pixelDepth < 0 ? -1 : 1;
		final Map<Node,Point3f> points = new HashMap<Node,Point3f>();

		// A few performance tests are needed:
		// 1 - if the map caching of points helps or recomputing every time is cheaper than lookup
		// 2 - if removing no-longer-needed points from the map helps lookup or overall slows down

		long t0 = System.currentTimeMillis();
		for (int i=0; i<n_iterations; i++) {
			// A -- current method
			points.clear();
			todo.clear();
			todo.add(root);
			list.clear();
			final float[] fps = new float[2];

			boolean go = true;
			while (go) {
				final Node node = todo.removeFirst();
				// Add children to todo list if any
				if (null != node.children) {
					for (final Node nd : node.children) todo.add(nd);
				}
				go = !todo.isEmpty();
				// Get node's 3D coordinate
				Point3f p = points.get(node);
				if (null == p) {
					fps[0] = node.x;
					fps[1] = node.y;
					at.transform(fps, 0, fps, 0, 1);
					p = new Point3f(fps[0] * pixelWidthScaled,
							fps[1] * pixelHeightScaled,
							(float)node.la.getZ() * pixelWidthScaled * sign);
					points.put(node, p);
				}
				if (null != node.parent) {
					// Create a line to the parent
					list.add(points.get(node.parent));
					list.add(p);
					if (go && node.parent != todo.getFirst().parent) {
						// node.parent point no longer needed (last child just processed)
						points.remove(node.parent);
					}
				}
			}
		}
		System.out.println("A: " + (System.currentTimeMillis() - t0));


		t0 = System.currentTimeMillis();
		for (int i=0; i<n_iterations; i++) {

			points.clear();
			todo.clear();
			todo.add(root);
			list.clear();
			final float[] fps = new float[2];

			// Simpler method, not clearing no-longer-used nodes from map
			while (!todo.isEmpty()) {
				final Node node = todo.removeFirst();
				// Add children to todo list if any
				if (null != node.children) {
					for (final Node nd : node.children) todo.add(nd);
				}
				// Get node's 3D coordinate
				Point3f p = points.get(node);
				if (null == p) {
					fps[0] = node.x;
					fps[1] = node.y;
					at.transform(fps, 0, fps, 0, 1);
					p = new Point3f(fps[0] * pixelWidthScaled,
							fps[1] * pixelHeightScaled,
							(float)node.la.getZ() * pixelWidthScaled * sign);
					points.put(node, p);
				}
				if (null != node.parent) {
					// Create a line to the parent
					list.add(points.get(node.parent));
					list.add(p);
				}
			}
		}
		System.out.println("B: " + (System.currentTimeMillis() - t0));

		t0 = System.currentTimeMillis();
		for (int i=0; i<n_iterations; i++) {

			todo.clear();
			todo.add(root);
			list.clear();

			// Simplest method: no caching in a map
			final float[] fp = new float[4];
			while (!todo.isEmpty()) {
				final Node node = todo.removeFirst();
				// Add children to todo list if any
				if (null != node.children) {
					for (final Node nd : node.children) todo.add(nd);
				}
				if (null != node.parent) {
					// Create a line to the parent
					fp[0] = node.x;
					fp[1] = node.y;
					fp[2] = node.parent.x;
					fp[3] = node.parent.y;
					at.transform(fp, 0, fp, 0, 2);
					list.add(new Point3f(fp[2] * pixelWidthScaled,
							     fp[3] * pixelHeightScaled,
							     (float)node.parent.la.getZ() * pixelWidthScaled * sign));
					list.add(new Point3f(fp[0] * pixelWidthScaled,
							     fp[1] * pixelHeightScaled,
							     (float)node.la.getZ() * pixelWidthScaled * sign));
				}
			}
		}
		System.out.println("C: " + (System.currentTimeMillis() - t0));
	}
	*/
/**
 * Returns a list of two lists: the {@code List<Point3f>} and the corresponding {@code List<Color3f>}.
 */
public MeshData generateMesh(final double scale_, int parallels) {
    // Construct a mesh made of straight tubes for each edge, and balls of the same ending diameter on the nodes.
    // 
    // TODO:
    // With some cleverness, such meshes could be welded together by merging the nearest vertices on the ball
    // surfaces, or by cleaving the surface where the diameter of the tube cuts it.
    // A tougher problem is where tubes cut each other, but perhaps if the resulting mesh is still non-manifold, it's ok.
    final float scale = (float) scale_;
    if (parallels < 3)
        parallels = 3;
    // Simple ball-and-stick model
    // first test: just the nodes as icosahedrons with 1 subdivision
    final Calibration cal = layer_set.getCalibration();
    final float pixelWidthScaled = (float) cal.pixelWidth * scale;
    final float pixelHeightScaled = (float) cal.pixelHeight * scale;
    final int sign = cal.pixelDepth < 0 ? -1 : 1;
    final List<Point3f> ico = M.createIcosahedron(1, 1);
    final List<Point3f> ps = new ArrayList<Point3f>();
    // A plane made of as many edges as parallels, with radius 1
    // Perpendicular vector of the plane is 0,0,1
    final List<Point3f> plane = new ArrayList<Point3f>();
    final double inc_rads = (Math.PI * 2) / parallels;
    double angle = 0;
    for (int i = 0; i < parallels; i++) {
        plane.add(new Point3f((float) Math.cos(angle), (float) Math.sin(angle), 0));
        angle += inc_rads;
    }
    final Vector3f vplane = new Vector3f(0, 0, 1);
    final Transform3D t = new Transform3D();
    final AxisAngle4f aa = new AxisAngle4f();
    final List<Color3f> colors = new ArrayList<Color3f>();
    final Color3f cf = new Color3f(this.color);
    final HashMap<Color, Color3f> cached_colors = new HashMap<Color, Color3f>();
    cached_colors.put(this.color, cf);
    for (final Set<Node<Float>> nodes : node_layer_map.values()) {
        for (final Node<Float> nd : nodes) {
            Point2D.Double po = transformPoint(nd.x, nd.y);
            final float x = (float) po.x * pixelWidthScaled;
            final float y = (float) po.y * pixelHeightScaled;
            final float z = (float) nd.la.getZ() * pixelWidthScaled * sign;
            // TODO r is not transformed by the AffineTransform
            final float r = ((RadiusNode) nd).r * pixelWidthScaled;
            for (final Point3f vert : ico) {
                final Point3f v = new Point3f(vert);
                v.x = v.x * r + x;
                v.y = v.y * r + y;
                v.z = v.z * r + z;
                ps.add(v);
            }
            int n_verts = ico.size();
            // Check if a 3D volume representation is necessary for this segment
            if (null != nd.parent && (0 != nd.parent.getData() || 0 != nd.getData())) {
                po = null;
                // parent:
                final Point2D.Double pp = transformPoint(nd.parent.x, nd.parent.y);
                final float parx = (float) pp.x * pixelWidthScaled;
                final float pary = (float) pp.y * pixelWidthScaled;
                final float parz = (float) nd.parent.la.getZ() * pixelWidthScaled * sign;
                // TODO r is not transformed by the AffineTransform
                final float parr = ((RadiusNode) nd.parent).r * pixelWidthScaled;
                // the vector perpendicular to the plane is 0,0,1
                // the vector from parent to child is:
                final Vector3f vpc = new Vector3f(x - parx, y - pary, z - parz);
                if (x == parx && y == pary) {
                    aa.set(0, 0, 1, 0);
                } else {
                    final Vector3f cross = new Vector3f();
                    cross.cross(vpc, vplane);
                    // not needed?
                    cross.normalize();
                    aa.set(cross.x, cross.y, cross.z, -vplane.angle(vpc));
                }
                t.set(aa);
                final List<Point3f> parent_verts = transform(t, plane, parx, pary, parz, parr);
                final List<Point3f> child_verts = transform(t, plane, x, y, z, r);
                for (int i = 1; i < parallels; i++) {
                    addTriangles(ps, parent_verts, child_verts, i - 1, i);
                    n_verts += 6;
                }
                // faces from last to first:
                addTriangles(ps, parent_verts, child_verts, parallels - 1, 0);
                n_verts += 6;
            }
            // Colors for each segment:
            Color3f c;
            if (null == nd.color) {
                c = cf;
            } else {
                c = cached_colors.get(nd.color);
                if (null == c) {
                    c = new Color3f(nd.color);
                    cached_colors.put(nd.color, c);
                }
            }
            while (n_verts > 0) {
                n_verts--;
                colors.add(c);
            }
        }
    }
    return new MeshData(ps, colors);
}
Also used : HashMap(java.util.HashMap) Transform3D(org.scijava.java3d.Transform3D) Color3f(org.scijava.vecmath.Color3f) Color(java.awt.Color) ArrayList(java.util.ArrayList) Calibration(ij.measure.Calibration) Point(java.awt.Point) Point3f(org.scijava.vecmath.Point3f) Point2D(java.awt.geom.Point2D) Vector3f(org.scijava.vecmath.Vector3f) AxisAngle4f(org.scijava.vecmath.AxisAngle4f)

Example 2 with Color3f

use of org.scijava.vecmath.Color3f in project TrakEM2 by trakem2.

the class Display3DGUI method randomizeColors.

public static final void randomizeColors(final Image3DUniverse univ) {
    final ArrayList<Content> cs = new ArrayList<Content>(getOrderedContents(univ));
    for (int i = 0; i < cs.size(); ++i) {
        if (i < colors.length) {
            cs.get(i).setColor(new Color3f(colors[i]));
        } else {
            cs.get(i).setColor(new Color3f((float) Math.random(), (float) Math.random(), (float) Math.random()));
        }
    }
    // Update the color bars if something is selected:
    final Content content = univ.getSelected();
    if (null != content)
        univ.fireContentChanged(content);
}
Also used : Content(ij3d.Content) Color3f(org.scijava.vecmath.Color3f) ArrayList(java.util.ArrayList)

Example 3 with Color3f

use of org.scijava.vecmath.Color3f in project TrakEM2 by trakem2.

the class Display3DGUI method newPanelColors.

private static final JPanel newPanelColors(final Image3DUniverse univ) {
    final JPanel p = new JPanel();
    p.setBackground(Color.white);
    final GridBagLayout gb = new GridBagLayout();
    final GridBagConstraints c = new GridBagConstraints();
    c.anchor = GridBagConstraints.NORTHWEST;
    c.fill = GridBagConstraints.HORIZONTAL;
    p.setLayout(gb);
    final String[] labels = new String[] { "Red", "Green", "Blue" };
    final JScrollBar[] sliders = new JScrollBar[3];
    final JTextField[] typers = new JTextField[3];
    for (int i = 0; i < 3; ++i) {
        final JScrollBar slider = new JScrollBar(JScrollBar.HORIZONTAL, 255, 1, 0, 256);
        sliders[i] = slider;
        final JTextField typer = new IntegerField(255, 3);
        typers[i] = typer;
        final int k = i;
        slider.addAdjustmentListener(new AdjustmentListener() {

            @Override
            public void adjustmentValueChanged(final AdjustmentEvent e) {
                final Content content = univ.getSelected();
                if (null == content) {
                    Utils.log("Nothing selected!");
                    return;
                }
                Color3f color = content.getColor();
                // default to yellow
                if (null == color)
                    color = new Color3f(1, 1, 0);
                final float[] co = new float[3];
                color.get(co);
                co[k] = e.getValue() / 255.0f;
                content.setColor(new Color3f(co));
                typer.setText(Integer.toString(e.getValue()));
            }
        });
        typer.addKeyListener(new SliderTyperLink(univ, slider, typer));
        final JLabel l = new JLabel(labels[i]);
        // Layout
        c.gridx = 0;
        c.gridy = i;
        gb.setConstraints(l, c);
        p.add(l);
        c.gridx = 1;
        c.weightx = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        gb.setConstraints(slider, c);
        p.add(slider);
        c.gridx = 2;
        c.weightx = 0;
        c.fill = GridBagConstraints.NONE;
        gb.setConstraints(typer, c);
        p.add(typer);
    }
    // Alpha slider
    c.gridx = 0;
    c.gridy += 1;
    final JLabel aL = new JLabel("Alpha:");
    gb.setConstraints(aL, c);
    p.add(aL);
    c.gridx = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 1;
    final JScrollBar alphaSlider = new JScrollBar(JScrollBar.HORIZONTAL, 255, 1, 0, 256);
    gb.setConstraints(alphaSlider, c);
    p.add(alphaSlider);
    c.gridx = 2;
    c.fill = GridBagConstraints.NONE;
    c.weightx = 0;
    final JTextField alphaTyper = new IntegerField(255, 3);
    gb.setConstraints(alphaTyper, c);
    p.add(alphaTyper);
    alphaSlider.addAdjustmentListener(new AdjustmentListener() {

        @Override
        public void adjustmentValueChanged(final AdjustmentEvent e) {
            final Content content = univ.getSelected();
            if (null == content) {
                Utils.log("Nothing selected!");
                return;
            }
            final float alpha = e.getValue() / 255.0f;
            content.setTransparency(1 - alpha);
            alphaTyper.setText(Integer.toString(e.getValue()));
        }
    });
    alphaTyper.addKeyListener(new SliderTyperLink(univ, alphaSlider, alphaTyper));
    // Button to colorize randomly
    c.gridx = 0;
    c.gridy += 1;
    c.gridwidth = 3;
    c.weightx = 1;
    c.insets = new Insets(15, 4, 4, 4);
    final JButton r = new JButton("Assign random colors to all");
    r.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(final ActionEvent e) {
            randomizeColors(univ);
        }
    });
    gb.setConstraints(r, c);
    p.add(r);
    addTitledLineBorder(p, "Colors");
    univ.addUniverseListener(new UniverseListener() {

        @Override
        public void universeClosed() {
        }

        @Override
        public void transformationUpdated(final View arg0) {
        }

        @Override
        public void transformationStarted(final View arg0) {
        }

        @Override
        public void transformationFinished(final View arg0) {
        }

        @Override
        public void contentSelected(final Content arg0) {
            if (null == arg0) {
                return;
            }
            Color3f color = arg0.getColor();
            // default to yellow
            if (null == color)
                color = new Color3f(1, 1, 0);
            final float[] co = new float[3];
            color.get(co);
            for (int i = 0; i < 3; ++i) {
                // Disallow the slider from firing an event when its value is adjusted
                sliders[i].setValueIsAdjusting(true);
                final int val = (int) (co[i] * 255);
                typers[i].setText(Integer.toString(val));
                sliders[i].setValue(val);
            }
            // After all are set, re-enable, which triggers events (the color will be set three times...)
            for (int i = 0; i < 3; ++i) {
                sliders[i].setValueIsAdjusting(false);
            }
            // Alpha slider:
            alphaSlider.setValueIsAdjusting(true);
            final int alpha = (int) ((1 - arg0.getTransparency()) * 255);
            alphaTyper.setText(Integer.toString(alpha));
            alphaSlider.setValue(alpha);
            alphaSlider.setValueIsAdjusting(false);
        }

        @Override
        public void contentRemoved(final Content arg0) {
        }

        @Override
        public void contentChanged(final Content arg0) {
            if (arg0 == univ.getSelected()) {
                contentSelected(arg0);
            }
        }

        @Override
        public void contentAdded(final Content arg0) {
        }

        @Override
        public void canvasResized() {
        }
    });
    return p;
}
Also used : JPanel(javax.swing.JPanel) GridBagConstraints(java.awt.GridBagConstraints) Insets(java.awt.Insets) GridBagLayout(java.awt.GridBagLayout) ActionEvent(java.awt.event.ActionEvent) AdjustmentEvent(java.awt.event.AdjustmentEvent) Color3f(org.scijava.vecmath.Color3f) JButton(javax.swing.JButton) JLabel(javax.swing.JLabel) IntegerField(ini.trakem2.utils.IntegerField) JTextField(javax.swing.JTextField) UniverseListener(ij3d.UniverseListener) View(org.scijava.java3d.View) JScrollBar(javax.swing.JScrollBar) ActionListener(java.awt.event.ActionListener) Content(ij3d.Content) AdjustmentListener(java.awt.event.AdjustmentListener)

Example 4 with Color3f

use of org.scijava.vecmath.Color3f in project TrakEM2 by trakem2.

the class Display3D method addFatPoint.

/**
 * Expects uncalibrated wx,wy,wz, (i.e. pixel values), to be calibrated by @param ls calibration.
 */
public static final Future<Content> addFatPoint(final String title, final LayerSet ls, final double wx, final double wy, final double wz, final double wr, final Color color) {
    final Display3D d3d = Display3D.get(ls);
    d3d.universe.removeContent(title);
    final Content ct = d3d.universe.createContent(new CustomTriangleMesh(d3d.createFatPoint(wx, wy, wz, wr, ls.getCalibrationCopy()), new Color3f(color), 0), title);
    ct.setLocked(true);
    return d3d.addContent(ct);
}
Also used : Content(ij3d.Content) Color3f(org.scijava.vecmath.Color3f) CustomTriangleMesh(customnode.CustomTriangleMesh)

Example 5 with Color3f

use of org.scijava.vecmath.Color3f 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

Color3f (org.scijava.vecmath.Color3f)9 Content (ij3d.Content)5 ArrayList (java.util.ArrayList)5 Point3f (org.scijava.vecmath.Point3f)5 Color (java.awt.Color)4 HashMap (java.util.HashMap)4 Point (java.awt.Point)3 CustomTriangleMesh (customnode.CustomTriangleMesh)2 Calibration (ij.measure.Calibration)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 TreeMap (java.util.TreeMap)2 CustomLineMesh (customnode.CustomLineMesh)1 CustomMesh (customnode.CustomMesh)1 CustomMultiMesh (customnode.CustomMultiMesh)1 ImagePlus (ij.ImagePlus)1 Plot (ij.gui.Plot)1 DirectoryChooser (ij.io.DirectoryChooser)1 FileSaver (ij.io.FileSaver)1 ByteProcessor (ij.process.ByteProcessor)1