Example #1
0
  private void createAppearance() {
    Appearance app = new Appearance();

    PolygonAttributes pa = new PolygonAttributes();
    pa.setCullFace(PolygonAttributes.CULL_NONE);
    // so can see the ColouredTiles from both sides
    app.setPolygonAttributes(pa);

    setAppearance(app);
  } // end of createAppearance()
Example #2
0
  /**
   * Sets the appearance.
   *
   * @param shape the new appearance
   */
  private void setAppearance(Shape3D shape) {
    Appearance sphereApp = new Appearance();
    TransparencyAttributes sphereTrans = new TransparencyAttributes();
    PolygonAttributes spherePa = new PolygonAttributes();

    spherePa.setCullFace(PolygonAttributes.CULL_NONE);
    sphereApp.setPolygonAttributes(spherePa);
    sphereTrans.setTransparency(0.6f);
    sphereTrans.setTransparencyMode(TransparencyAttributes.NICEST);
    sphereApp.setTransparencyAttributes(sphereTrans);
    shape.setAppearance(sphereApp);
  }
Example #3
0
  /**
   * Simple algorithm to add or remove a quad 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 toggleSelectedQuad(boolean on, SelectionQuad sq) {
    LOGGER.finest("on=" + on + " selectionQuad=" + sq);
    if (on) {
      // add the given quad to the list
      if (selection.contains(sq)) return; // already in
      selection.add(sq);
    } else {
      // remove the given quad from the list
      if (!selection.contains(sq)) return; // not present
      selection.remove(sq);
      if (selection.size() == 0) {
        QuadArray qa = (QuadArray) selectionShape.getGeometry();
        qa.setValidVertexCount(0);
        return;
      }
    }
    // Use in-memory arrays instead of NIO because selection should not be
    // too big
    // => faster
    QuadArray qa =
        new QuadArray(
            selection.size() * 4,
            GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE);
    float[] coords = new float[selection.size() * 4 * 3];
    float[] colors = new float[selection.size() * 4 * 3];

    for (int i = 0; i < coords.length; i += 12) {
      SelectionQuad quad = selection.get(i / 12);
      quad.updateCoords(grid, coords, i);
      quad.updateColors(colors, i);
    }
    qa.setCoordRefFloat(coords);
    qa.setColorRefFloat(colors);
    qa.setCapability(GeometryArray.ALLOW_COUNT_WRITE);
    // update selection Shape with the new selection list
    if (selectionShape == null) {
      Appearance a = new Appearance();
      PolygonAttributes pa =
          new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0);
      pa.setPolygonOffset(0.5f); // between faces and edges
      pa.setPolygonOffsetFactor(0.5f);
      a.setPolygonAttributes(pa);
      selectionShape = new Shape3D(qa, a);
      selectionShape.setUserData(this);
      selectionShape.setPickable(false);
      selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
      selectionShape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
      BranchGroup bg = new BranchGroup();
      bg.addChild(selectionShape);
      addChild(bg);
    } else selectionShape.setGeometry(qa);
  }
  private Appearance Triangle3DAppearance() {
    _appearance = new Appearance();

    PolygonAttributes polyAttrib = new PolygonAttributes();
    polyAttrib.setPolygonMode(PolygonAttributes.POLYGON_FILL);

    _appearance.setCapability(ALLOW_APPEARANCE_READ);
    _appearance.setCapability(ALLOW_APPEARANCE_WRITE);
    _appearance.setPolygonAttributes(polyAttrib);

    PointAttributes pointatt = new PointAttributes(4, true);
    _appearance.setPointAttributes(pointatt);

    LineAttributes lineatt = new LineAttributes(2, LineAttributes.PATTERN_SOLID, false);
    _appearance.setLineAttributes(lineatt);

    return _appearance;
  }
Example #5
0
  /**
   * Method to access appearance for cells in 3D
   *
   * @param initValue no null if appearance has to be changed according to user value. Using this
   *     mechanism to avoid the creation of new Boolean() just for the checking
   */
  public static void setCellAppearanceValues(Object initValue) {
    Color3f userColor = new Color3f(new Color(User.getColor(User.ColorPrefType.INSTANCE_3D)));

    if (cellApp == null) {
      cellApp = new J3DAppearance(TransparencyAttributes.SCREEN_DOOR, 0, null);

      RenderingAttributes ra = new RenderingAttributes();
      ra.setCapability(RenderingAttributes.ALLOW_VISIBLE_READ);
      ra.setCapability(RenderingAttributes.ALLOW_VISIBLE_WRITE);
      ra.setVisible(J3DUtils.is3DCellBndOn());
      cellApp.setRenderingAttributes(ra);

      // Set up the polygon attributes
      PolygonAttributes pa = new PolygonAttributes();
      pa.setCullFace(PolygonAttributes.CULL_NONE);
      pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
      cellApp.setPolygonAttributes(pa);

      //            TextureAttributes texAttr = new TextureAttributes();
      //            texAttr.setTextureMode(TextureAttributes.MODULATE);
      //            //texAttr.setTextureColorTable(pattern);
      //            cellApp.setTextureAttributes(texAttr);

      LineAttributes lineAttr = new LineAttributes();
      lineAttr.setLineAntialiasingEnable(true);
      cellApp.setLineAttributes(lineAttr);

      // ** Data for cells
      ColoringAttributes ca = new ColoringAttributes();
      ca.setCapability(ColoringAttributes.ALLOW_COLOR_WRITE);
      ca.setCapability(ColoringAttributes.ALLOW_COLOR_READ);
      ca.setColor(userColor);
      cellApp.setColoringAttributes(ca);
      cellApp.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ);
      cellApp.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE);
    } else if (initValue == null) // redoing color only when it was changed in GUI
    {
      ColoringAttributes ca = cellApp.getColoringAttributes();
      Color3f curColor = new Color3f();
      ca.getColor(curColor);
      if (!userColor.equals(curColor)) ca.setColor(userColor);
    }
  }
Example #6
0
  @Override
  protected Appearance createAppearance() {
    Appearance appearance = new Appearance();
    appearance.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
    appearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ);

    LineAttributes lineAttrib = new LineAttributes();
    lineAttrib.setCapability(LineAttributes.ALLOW_ANTIALIASING_WRITE);
    lineAttrib.setCapability(LineAttributes.ALLOW_PATTERN_WRITE);
    lineAttrib.setCapability(LineAttributes.ALLOW_WIDTH_WRITE);
    lineAttrib.setLineWidth(linewidth);
    lineAttrib.setLinePattern(pattern);
    appearance.setLineAttributes(lineAttrib);

    PolygonAttributes polyAttrib = new PolygonAttributes();
    polyAttrib.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
    polyAttrib.setPolygonMode(PolygonAttributes.POLYGON_FILL);
    polyAttrib.setCullFace(PolygonAttributes.CULL_NONE);
    polyAttrib.setBackFaceNormalFlip(true);
    appearance.setPolygonAttributes(polyAttrib);

    ColoringAttributes colorAttrib = new ColoringAttributes();
    colorAttrib.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
    colorAttrib.setColor(color);
    appearance.setColoringAttributes(colorAttrib);

    TransparencyAttributes tr = new TransparencyAttributes();
    int mode = transparency == 0f ? TransparencyAttributes.NONE : TransparencyAttributes.FASTEST;
    tr.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
    tr.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
    tr.setTransparencyMode(mode);
    tr.setTransparency(transparency);
    appearance.setTransparencyAttributes(tr);

    Material material = new Material();
    material.setCapability(Material.ALLOW_COMPONENT_WRITE);
    material.setAmbientColor(0.1f, 0.1f, 0.1f);
    material.setSpecularColor(0.1f, 0.1f, 0.1f);
    material.setDiffuseColor(0.1f, 0.1f, 0.1f);
    appearance.setMaterial(material);
    return appearance;
  }
Example #7
0
  @Override
  protected Appearance createAppearance() {
    final Appearance appearance = new Appearance();
    appearance.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
    appearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ);

    final PointAttributes pointAttrib = new PointAttributes();
    pointAttrib.setCapability(PointAttributes.ALLOW_ANTIALIASING_WRITE);
    pointAttrib.setCapability(PointAttributes.ALLOW_SIZE_WRITE);
    pointAttrib.setPointSize(pointsize);
    appearance.setPointAttributes(pointAttrib);

    final PolygonAttributes polyAttrib = new PolygonAttributes();
    polyAttrib.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
    polyAttrib.setPolygonMode(PolygonAttributes.POLYGON_FILL);
    polyAttrib.setCullFace(PolygonAttributes.CULL_BACK);
    polyAttrib.setBackFaceNormalFlip(false);
    appearance.setPolygonAttributes(polyAttrib);

    final ColoringAttributes colorAttrib = new ColoringAttributes();
    colorAttrib.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
    colorAttrib.setColor(color);
    appearance.setColoringAttributes(colorAttrib);

    final TransparencyAttributes tr = new TransparencyAttributes();
    final int mode =
        transparency == 0f ? TransparencyAttributes.NONE : TransparencyAttributes.FASTEST;
    tr.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
    tr.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
    tr.setTransparencyMode(mode);
    tr.setTransparency(transparency);
    appearance.setTransparencyAttributes(tr);

    final Material material = new Material();
    material.setCapability(Material.ALLOW_COMPONENT_WRITE);
    material.setAmbientColor(0.1f, 0.1f, 0.1f);
    material.setSpecularColor(0.1f, 0.1f, 0.1f);
    material.setDiffuseColor(0.1f, 0.1f, 0.1f);
    appearance.setMaterial(material);
    return appearance;
  }
Example #8
0
  /**
   * Method to access appearance of axes in 3D
   *
   * @param initValue false if appearance has to be changed according to user value
   */
  public static void setAxisAppearanceValues(Object initValue) {
    int[] colors = J3DUtils.get3DColorAxes();

    for (int i = 0; i < axisApps.length; i++) {
      Color userColor = new Color(colors[i]);

      if (axisApps[i] == null) {
        axisApps[i] = new J3DAppearance(TransparencyAttributes.NONE, 0.5f, userColor);

        // Turn off face culling so we can see the back side of the labels
        // (since we're not using font extrusion)
        PolygonAttributes polygonAttributes = new PolygonAttributes();
        polygonAttributes.setCullFace(PolygonAttributes.CULL_NONE);

        // Make the axis lines 2 pixels wide
        LineAttributes lineAttributes = new LineAttributes();
        lineAttributes.setLineWidth(3.0f);

        ColoringAttributes colorAttrib = new ColoringAttributes();
        colorAttrib.setColor(new Color3f(userColor));
        colorAttrib.setCapability(ColoringAttributes.ALLOW_COLOR_READ);
        colorAttrib.setCapability(ColoringAttributes.ALLOW_COLOR_WRITE);
        axisApps[i].setColoringAttributes(colorAttrib);
        axisApps[i].setPolygonAttributes(polygonAttributes);
        axisApps[i].setLineAttributes(lineAttributes);
        axisApps[i].setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ);
        axisApps[i].setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE);

        RenderingAttributes ra = new RenderingAttributes();
        ra.setCapability(RenderingAttributes.ALLOW_VISIBLE_READ);
        ra.setCapability(RenderingAttributes.ALLOW_VISIBLE_WRITE);
        ra.setVisible(J3DUtils.is3DAxesOn());
        axisApps[i].setRenderingAttributes(ra);
      } else if (initValue == null) // redoing color only when it was changed in GUI
      axisApps[i].set3DColor(null, userColor);
    }
  }
Example #9
0
  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 Annotations(View view, Context context, Volume vol) {
    super(view, context, vol);
    viewPtAttr = (CoordAttr) context.getAttr("Vol Ref Pt");
    perspectiveAttr = (ToggleAttr) context.getAttr("Perspective");
    boxAttr[PLUS_X] = (ToggleAttr) context.getAttr("Plus X Box");
    boxAttr[PLUS_Y] = (ToggleAttr) context.getAttr("Plus Y Box");
    boxAttr[PLUS_Z] = (ToggleAttr) context.getAttr("Plus Z Box");
    boxAttr[MINUS_X] = (ToggleAttr) context.getAttr("Minus X Box");
    boxAttr[MINUS_Y] = (ToggleAttr) context.getAttr("Minus Y Box");
    boxAttr[MINUS_Z] = (ToggleAttr) context.getAttr("Minus Z Box");
    imageAttr[PLUS_X] = (StringAttr) context.getAttr("Plus X Image");
    imageAttr[PLUS_Y] = (StringAttr) context.getAttr("Plus Y Image");
    imageAttr[PLUS_Z] = (StringAttr) context.getAttr("Plus Z Image");
    imageAttr[MINUS_X] = (StringAttr) context.getAttr("Minus X Image");
    imageAttr[MINUS_Y] = (StringAttr) context.getAttr("Minus Y Image");
    imageAttr[MINUS_Z] = (StringAttr) context.getAttr("Minus Z Image");

    volume = vol;
    frontRoot = new BranchGroup();
    frontRoot.setCapability(BranchGroup.ALLOW_DETACH);
    frontRoot.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);
    backRoot = new BranchGroup();
    backRoot.setCapability(BranchGroup.ALLOW_DETACH);
    backRoot.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);

    int stripLength[] = new int[1];
    stripLength[0] = 5;

    ColoringAttributes ca = new ColoringAttributes(1.0f, 0.0f, 0.0f, ColoringAttributes.SHADE_FLAT);
    Appearance boxAppearance = new Appearance();
    boxAppearance.setColoringAttributes(ca);

    TexCoord2f[] texCoords = new TexCoord2f[4];
    texCoords[0] = new TexCoord2f(0.0f, 0.0f);
    texCoords[1] = new TexCoord2f(1.0f, 0.0f);
    texCoords[2] = new TexCoord2f(1.0f, 1.0f);
    texCoords[3] = new TexCoord2f(0.0f, 1.0f);

    TransparencyAttributes ta = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f);
    TextureAttributes texAttr = new TextureAttributes();
    texAttr.setTextureMode(TextureAttributes.MODULATE);
    PolygonAttributes pa = new PolygonAttributes();
    pa.setCullFace(PolygonAttributes.CULL_NONE);
    RenderingAttributes ra = new RenderingAttributes();
    ra.setDepthBufferEnable(false);

    for (int i = 0; i < 6; i++) {
      faceGroup[i] = new SharedGroup();
      frontAnnotations.addChild(new Link(faceGroup[i]));
      backAnnotations.addChild(new Link(faceGroup[i]));
      boxLine[i] = new LineStripArray(5, GeometryArray.COORDINATES, stripLength);
      boxLine[i].setCoordinates(0, volume.facePoints[i], 0, 4);
      boxLine[i].setCoordinate(4, volume.facePoints[i][0]);
      boxLine[i].setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
      Shape3D box = new Shape3D(boxLine[i], boxAppearance);
      boxSwitch[i] = new Switch();
      boxSwitch[i].setCapability(Switch.ALLOW_SWITCH_WRITE);
      boxSwitch[i].addChild(box);
      if (boxAttr[i].getValue() == true) {
        boxSwitch[i].setWhichChild(Switch.CHILD_ALL);
      } else {
        boxSwitch[i].setWhichChild(Switch.CHILD_NONE);
      }
      faceGroup[i].addChild(boxSwitch[i]);
      imageQuad[i] =
          new QuadArray(4, GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2);
      imageQuad[i].setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
      imageQuad[i].setCoordinates(0, volume.facePoints[i], 0, 4);
      imageQuad[i].setTextureCoordinates(0, 0, texCoords, 0, 4);
      imageAppearance[i] = new Appearance();
      imageAppearance[i].setTransparencyAttributes(ta);
      imageAppearance[i].setPolygonAttributes(pa);
      imageAppearance[i].setRenderingAttributes(ra);
      imageAppearance[i].setTextureAttributes(texAttr);
      imageAppearance[i].setCapability(Appearance.ALLOW_TEXTURE_WRITE);
      imageSwitch[i] = new Switch();
      imageSwitch[i].setCapability(Switch.ALLOW_SWITCH_WRITE);
      imageFile[i] = imageAttr[i].getValue();
      if (imageFile[i].length() > 0) {
        try {
          URL imageURL = new URL(context.getCodeBase().toString() + imageFile[i]);
          imageTexture[i] = new TextureLoader(imageURL, null).getTexture();
        } catch (Exception e) {
          System.err.println("Error " + e + " loading image:" + imageFile[i] + ".");
        }
      }
      imageAppearance[i].setTexture(imageTexture[i]);
      if (imageTexture[i] != null) {
        imageSwitch[i].setWhichChild(Switch.CHILD_ALL);
      } else {
        imageSwitch[i].setWhichChild(Switch.CHILD_NONE);
      }
      Shape3D imageShape = new Shape3D(imageQuad[i], imageAppearance[i]);
      imageSwitch[i].addChild(imageShape);
      faceGroup[i].addChild(imageSwitch[i]);
    }
    frontAnnotations.setCapability(Switch.ALLOW_SWITCH_WRITE);
    backAnnotations.setCapability(Switch.ALLOW_SWITCH_WRITE);

    faceNormal[PLUS_X] = new Vector3d(1.0, 0.0, 0.0);
    faceCenter[PLUS_X] = new Point3d(volume.maxCoord.x, 0.0, 0.0);
    faceNormal[PLUS_Y] = new Vector3d(0.0, 1.0, 0.0);
    faceCenter[PLUS_Y] = new Point3d(0.0, volume.maxCoord.y, 0.0);
    faceNormal[PLUS_Z] = new Vector3d(0.0, 0.0, 1.0);
    faceCenter[PLUS_Z] = new Point3d(0.0, 0.0, volume.maxCoord.z);
    faceNormal[MINUS_X] = new Vector3d(-1.0, 0.0, 0.0);
    faceCenter[MINUS_X] = new Point3d(volume.minCoord.x, 0.0, 0.0);
    faceNormal[MINUS_Y] = new Vector3d(0.0, -1.0, 0.0);
    faceCenter[MINUS_Y] = new Point3d(0.0, volume.minCoord.y, 0.0);
    faceNormal[MINUS_Z] = new Vector3d(0.0, 0.0, -1.0);
    faceCenter[MINUS_Z] = new Point3d(0.0, 0.0, volume.minCoord.z);
    volCenter.x = (volume.maxCoord.x + volume.minCoord.x) / 2;
    volCenter.y = (volume.maxCoord.y + volume.minCoord.y) / 2;
    volCenter.z = (volume.maxCoord.z + volume.minCoord.z) / 2;

    frontRoot.addChild(frontAnnotations);
    backRoot.addChild(backAnnotations);
  }