private Shape3D createLine( Point3f start, Point3f end, Color3f color, boolean isDashed, float lineWidth) { Appearance app = new Appearance(); app.setColoringAttributes(new ColoringAttributes(color, ColoringAttributes.SHADE_FLAT)); if (isDashed) { app.setLineAttributes(new LineAttributes(lineWidth, LineAttributes.PATTERN_DASH, true)); } else { app.setLineAttributes(new LineAttributes(lineWidth, LineAttributes.PATTERN_SOLID, true)); } LineArray lineArr = new LineArray(2, LineArray.COORDINATES); lineArr.setCoordinate(0, start); lineArr.setCoordinate(1, end); Shape3D line = new Shape3D(lineArr, app); return line; }
protected void makeWires() { Wire[] wires = createWireList(); if (wires.length == 0) return; FloatBuffer nioWires = ByteBuffer.allocateDirect(wires.length * 2 * 3 * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); for (int i = 0; i < wires.length; i++) { nioWires.put(wires[i].getCoordinates(grid)); } // Create edge shapes directly, don't make it appear in graph LineArray la = new NioLineArray(wires.length * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); la.setCoordRefBuffer(new J3DBuffer(nioWires)); int colSize = wires.length * 2 * 3; FloatBuffer nioWireColors = ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); float[] colors = getColorForOrder(-2, 0); for (int i = 0; i < colSize; i += 3) nioWireColors.put(colors); la.setColorRefBuffer(new J3DBuffer(nioWireColors)); la.setUserData(new int[] {-2, 0}); Appearance a = new Appearance(); // PolygonAttributes pa = new // PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(2); // pa.setPolygonOffsetFactor(2); // a.setPolygonAttributes(pa); /* * LineAttributes lat = new LineAttributes(); lat.setLineWidth(2.0f); * a.setLineAttributes(lat); */ Shape3D s3d = new Shape3D(la, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(true); // by default, can be changed with actions s3d.setUserData(this); // this object will handle edges addChild(s3d); allEdgeShapes.add(s3d); }
/** * Simple algorithm to add or remove an edge from the selection Ideas: 1. Use one shape per quad * => easy, but can become very fast too big to fit in memory. => pb: flicker when adding / * removing because the scene is detached 2. Use only one shape, modify geometry TODO: pre-create * an empty shape to avoid initial flicker * * @param on * @param p * @param u * @param v * @param groupIdx2 */ protected void toggleSelectedEdge(boolean on, SelectionEdge se) { if (on) { // add the given edge to the list if (edgeSelection.contains(se)) return; // already in edgeSelection.add(se); } else { // remove the given edge from the list if (!edgeSelection.contains(se)) return; // not present edgeSelection.remove(se); if (edgeSelection.size() == 0) { LineArray la = (LineArray) edgeSelectionShape.getGeometry(); la.setValidVertexCount(0); return; } } // Use in-memory arrays instead of NIO because edgeSelection should not // be too big // => faster LineArray la = new LineArray( edgeSelection.size() * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE); double[] coords = new double[edgeSelection.size() * 2 * 3]; float[] colors = new float[edgeSelection.size() * 2 * 3]; for (int i = 0; i < coords.length; i += 6) { SelectionEdge edge = edgeSelection.get(i / 6); edge.updateCoords(grid, coords, i); edge.updateColors(colors, i); } la.setCoordRefDouble(coords); la.setColorRefFloat(colors); la.setCapability(GeometryArray.ALLOW_COUNT_WRITE); // update edgeSelection Shape with the new edgeSelection list if (edgeSelectionShape == null) { Appearance a = new Appearance(); // PolygonAttributes pa = new // PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(1); // above edges // pa.setPolygonOffsetFactor(1); LineAttributes lat = new LineAttributes(); lat.setLineWidth(2.0f); lat.setLineAntialiasingEnable(true); a.setLineAttributes(lat); // a.setPolygonAttributes(pa); edgeSelectionShape = new Shape3D(la, a); edgeSelectionShape.setUserData(this); edgeSelectionShape.setPickable(false); edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); edgeSelectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); BranchGroup bg = new BranchGroup(); bg.addChild(edgeSelectionShape); addChild(bg); } else edgeSelectionShape.setGeometry(la); }
protected void makeGroups() { int totalQuads = 0; int totalInternalEdges = 0; int totalExternalEdges = 0; // loop over each group // loop over each group int[] groupID = provider.getDomainIDs(); for (int g = 0; g < groupID.length; ++g) { LOGGER.finest("generating java3d tree for group number " + groupID[g]); // Set of EdgeLine objects. Overlapping edges on the same line are // merged together HashMap<EdgeLine, EdgeLine> externalEdges = new HashMap<EdgeLine, EdgeLine>(); // Same trick for internal edges. HashMap<EdgeLine, EdgeLine> internalEdges = new HashMap<EdgeLine, EdgeLine>(); FDDomain fdDomain = (FDDomain) provider.getDomain(groupID[g]); baseColor.put(new Integer(g), fdDomain.getColor()); Plate[] plates = domainToPlates(fdDomain); if (plates.length == 0) continue; // Create plates for this group FloatBuffer nioCoords = ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); FloatBuffer nioColors = ByteBuffer.allocateDirect(plates.length * 4 * 3 * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); float[] baseColor = getColorForOrder(g, 0); // System.out.println(baseColor[0]+" "+baseColor[1]+" "+baseColor[2]); for (int np = 0; np < plates.length; ++np) { Plate p = plates[np]; // put coordinates nioCoords.put(p.getCoordinates(grid)); // put colors for the 4 vertices nioColors.put(baseColor); nioColors.put(baseColor); nioColors.put(baseColor); nioColors.put(baseColor); // Merge external edges addEdge(externalEdges, getLine(p, 2, p.min1), p.min2, p.max2); addEdge(externalEdges, getLine(p, 2, p.max1), p.min2, p.max2); addEdge(externalEdges, getLine(p, 1, p.min2), p.min1, p.max1); addEdge(externalEdges, getLine(p, 1, p.max2), p.min1, p.max1); // Merge internal edges for (int i = p.min1 + 1; i < p.max1; ++i) addEdge(internalEdges, getLine(p, 2, i), p.min2, p.max2); for (int j = p.min2 + 1; j < p.max2; ++j) addEdge(internalEdges, getLine(p, 1, j), p.min1, p.max1); } // use by reference array of colors => fast to change! QuadArray qa = new NioQuadArray(plates.length * 4, GeometryArray.COORDINATES | GeometryArray.COLOR_3); qa.setCoordRefBuffer(new J3DBuffer(nioCoords)); qa.setColorRefBuffer(new J3DBuffer(nioColors)); qa.setCapability(GeometryArray.ALLOW_COLOR_WRITE); qa.setCapabilityIsFrequent(GeometryArray.ALLOW_COLOR_WRITE); Appearance a = new Appearance(); PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0); pa.setPolygonOffset(1); pa.setPolygonOffsetFactor(1); a.setPolygonAttributes(pa); Shape3D s3d = new Shape3D(qa, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(true); s3d.setUserData(new BehindShape(s3d, plates, g)); this.addChild(s3d); // Create edge shapes directly, don't make them appear in graph int nInternalEdges = 0; for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nInternalEdges += el.getNumberOfEdges(); } if (nInternalEdges > 0) { DoubleBuffer nioInternalEdges = ByteBuffer.allocateDirect(nInternalEdges * 2 * 3 * 8) .order(ByteOrder.nativeOrder()) .asDoubleBuffer(); // create edge coords for (Iterator<EdgeLine> it = internalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nioInternalEdges.put(el.getCoords(grid)); } LineArray la = new NioLineArray(nInternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); la.setCoordRefBuffer(new J3DBuffer(nioInternalEdges)); int colSize = nInternalEdges * 2 * 3; FloatBuffer nioInternalColors = ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); float[] colors = getColorForOrder(g, 2); for (int i = 0; i < colSize; i += 3) nioInternalColors.put(colors); la.setColorRefBuffer(new J3DBuffer(nioInternalColors)); la.setUserData(new int[] {g, 2}); a = new Appearance(); // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(4); // pa.setPolygonOffsetFactor(4); // a.setPolygonAttributes(pa); // LineAttributes lat = new LineAttributes(); // lat.setLineAntialiasingEnable(true); // a.setLineAttributes(lat); // RenderingAttributes ra = new RenderingAttributes(); // ra.setAlphaTestFunction(RenderingAttributes.GREATER); // ra.setAlphaTestValue(0.5f); // a.setRenderingAttributes(ra); s3d = new Shape3D(la, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(false); // by default, see actions s3d.setUserData(this); // this object will handle edges this.addChild(s3d); allEdgeShapes.add(s3d); } // Now, create external edge int nExternalEdges = 0; for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nExternalEdges += el.getNumberOfEdges(); } if (nExternalEdges > 0) { DoubleBuffer nioExternalEdges = ByteBuffer.allocateDirect(nExternalEdges * 2 * 3 * 8) .order(ByteOrder.nativeOrder()) .asDoubleBuffer(); // create edge coords for (Iterator<EdgeLine> it = externalEdges.keySet().iterator(); it.hasNext(); ) { EdgeLine el = it.next(); nioExternalEdges.put(el.getCoords(grid)); } LineArray la = new NioLineArray(nExternalEdges * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); la.setCoordRefBuffer(new J3DBuffer(nioExternalEdges)); int colSize = nExternalEdges * 2 * 3; FloatBuffer nioExternalColors = ByteBuffer.allocateDirect(colSize * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); float[] colors = getColorForOrder(g, 4); for (int i = 0; i < colSize; i += 3) nioExternalColors.put(colors); la.setColorRefBuffer(new J3DBuffer(nioExternalColors)); la.setUserData(new int[] {g, 4}); a = new Appearance(); // pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, // PolygonAttributes.CULL_NONE, 0); // pa.setPolygonOffset(3); // pa.setPolygonOffsetFactor(3); // a.setPolygonAttributes(pa); s3d = new Shape3D(la, a); PickTool.setCapabilities(s3d, PickTool.INTERSECT_FULL); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); s3d.setCapability(Node.ALLOW_PICKABLE_READ); s3d.setCapability(Node.ALLOW_PICKABLE_WRITE); s3d.setPickable(false); // by default, see actions s3d.setUserData(this); // this object will handle edges this.addChild(s3d); allEdgeShapes.add(s3d); } totalQuads += plates.length; totalInternalEdges += nInternalEdges; totalExternalEdges += nExternalEdges; } System.out.println("Total quads: " + totalQuads); System.out.println("Total Internal Plate edges: " + totalInternalEdges); System.out.println("Total External Plate edges: " + totalExternalEdges); }
public void addLinesAroundRegion(TransformGroup tg) { Color3f x = new Color3f(Color.green.brighter().brighter()); Color3f y = new Color3f(Color.yellow.brighter().brighter()); Color3f z = new Color3f(Color.red.brighter().brighter()); LineArray wireframe = new LineArray(12 * 2, GeometryArray.COORDINATES | GeometryArray.COLOR_3); wireframe.setCapability(LineArray.ALLOW_COLOR_WRITE); wireframe.setCapability(LineArray.ALLOW_COORDINATE_READ); wireframe.setCapability(LineArray.ALLOW_COUNT_READ); ArrayList<Point3f> vx = getVertices(); // Add lines parallel to x wireframe.setCoordinate(0, vx.get(0)); wireframe.setCoordinate(1, vx.get(2)); wireframe.setCoordinate(2, vx.get(1)); wireframe.setCoordinate(3, vx.get(3)); wireframe.setCoordinate(4, vx.get(4)); wireframe.setCoordinate(5, vx.get(6)); wireframe.setCoordinate(6, vx.get(5)); wireframe.setCoordinate(7, vx.get(7)); for (int i = 0; i < 8; i++) wireframe.setColor(i, x); // Add lines parallel to y wireframe.setCoordinate(8, vx.get(0)); wireframe.setCoordinate(9, vx.get(4)); wireframe.setCoordinate(10, vx.get(1)); wireframe.setCoordinate(11, vx.get(5)); wireframe.setCoordinate(12, vx.get(2)); wireframe.setCoordinate(13, vx.get(6)); wireframe.setCoordinate(14, vx.get(3)); wireframe.setCoordinate(15, vx.get(7)); for (int i = 8; i < 16; i++) wireframe.setColor(i, y); // Add lines parallel to z wireframe.setCoordinate(16, vx.get(0)); wireframe.setCoordinate(17, vx.get(1)); wireframe.setCoordinate(18, vx.get(2)); wireframe.setCoordinate(19, vx.get(3)); wireframe.setCoordinate(20, vx.get(4)); wireframe.setCoordinate(21, vx.get(5)); wireframe.setCoordinate(22, vx.get(6)); wireframe.setCoordinate(23, vx.get(7)); for (int i = 16; i < 24; i++) wireframe.setColor(i, z); Shape3D shape = new Shape3D(wireframe); tg.addChild(shape); }
public BranchGroup addTetrahedron(Simplex simplex, Color3f color) { BranchGroup bgTetrahedron = new BranchGroup(); bgTetrahedron.setCapability(BranchGroup.ALLOW_DETACH); javax.vecmath.Point3d[] coords = new javax.vecmath.Point3d[12]; LineArray la = new LineArray(12, LineArray.COORDINATES | LineArray.COLOR_3); Point3d p0 = (Point3d) complex.getPoints().get(simplex.getPoints()[0]); Point3d p1 = (Point3d) complex.getPoints().get(simplex.getPoints()[1]); Point3d p2 = (Point3d) complex.getPoints().get(simplex.getPoints()[2]); Point3d p3 = (Point3d) complex.getPoints().get(simplex.getPoints()[3]); coords[0] = coords[2] = coords[4] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ()); coords[1] = coords[6] = coords[8] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ()); coords[3] = coords[7] = coords[10] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ()); coords[5] = coords[9] = coords[11] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ()); la.setCoordinates(0, coords); Color3f[] colors = new Color3f[12]; for (int i = 0; i < 12; i++) colors[i] = Colors.black; la.setColors(0, colors); javax.vecmath.Point3d[] coordsTr = new javax.vecmath.Point3d[24]; TriangleArray tr = new TriangleArray(24, TriangleArray.COORDINATES | TriangleArray.COLOR_3); coordsTr[0] = coordsTr[3] = coordsTr[6] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ()); coordsTr[1] = coordsTr[4] = coordsTr[9] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ()); coordsTr[2] = coordsTr[7] = coordsTr[10] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ()); coordsTr[5] = coordsTr[8] = coordsTr[11] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ()); coordsTr[12] = coordsTr[15] = coordsTr[18] = new javax.vecmath.Point3d(p0.getX(), p0.getY(), p0.getZ()); coordsTr[14] = coordsTr[17] = coordsTr[21] = new javax.vecmath.Point3d(p1.getX(), p1.getY(), p1.getZ()); coordsTr[13] = coordsTr[20] = coordsTr[23] = new javax.vecmath.Point3d(p2.getX(), p2.getY(), p2.getZ()); coordsTr[16] = coordsTr[19] = coordsTr[22] = new javax.vecmath.Point3d(p3.getX(), p3.getY(), p3.getZ()); tr.setCoordinates(0, coordsTr); Color3f[] colorsTr = new Color3f[24]; for (int i = 0; i < 24; i++) colorsTr[i] = Colors.green; tr.setColors(0, colorsTr); Appearance ap = new Appearance(); ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ); ap.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE); ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ); ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE); // ap.setCapability(Appearance.ALLOW_MATERIAL_READ); // ap.setCapability(Appearance.ALLOW_MATERIAL_WRITE); ap.setLineAttributes(new LineAttributes(2, LineAttributes.PATTERN_SOLID, false)); ap.setMaterial(new Material()); // ap.setTransparencyAttributes(new // TransparencyAttributes(TransparencyAttributes.SCREEN_DOOR, 0.5f)); // LineArray la = cell.getLineArray(); Shape3D shape = new Shape3D(la, ap); Shape3D shapeTr = new Shape3D(tr, ap); shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); simplex.setTetrahedron(shape); // cell.setLineArray(la); simplex.setTriangleArray(tr); simplex.setBgTetrahedron(bgTetrahedron); TransformGroup tgTetrahedron = new TransformGroup(); tgTetrahedron.addChild(shape); tgTetrahedron.addChild(shapeTr); bgTetrahedron.addChild(tgTetrahedron); spin.addChild(bgTetrahedron); return bgTetrahedron; }