예제 #1
0
 /**
  * Gets the parameters from this PickSegment.
  *
  * @param start the Point3d object into which the start point will be copied.
  * @param end the Point3d object into which the end point will be copied.
  */
 public void get(Point3d start, Point3d end) {
   start.x = this.start.x;
   start.y = this.start.y;
   start.z = this.start.z;
   end.x = this.end.x;
   end.y = this.end.y;
   end.z = this.end.z;
 }
예제 #2
0
 private Point3d getEffectiveCoordinates(IAtomContainer atomContainer, int[] atomIndices) {
   Point3d ret = new Point3d(0, 0, 0);
   for (int i : atomIndices) {
     Point3d coord = atomContainer.getAtom(i).getPoint3d();
     ret.x += coord.x;
     ret.y += coord.y;
     ret.z += coord.z;
   }
   ret.x /= atomIndices.length;
   ret.y /= atomIndices.length;
   ret.z /= atomIndices.length;
   return ret;
 }
예제 #3
0
 private Point3d getEffectiveCoordinates(IAtomContainer atomContainer, List<Integer> atomIndices) {
   Point3d ret = new Point3d(0, 0, 0);
   for (Object atomIndice : atomIndices) {
     int atomIndex = (Integer) atomIndice;
     Point3d coord = atomContainer.getAtom(atomIndex).getPoint3d();
     ret.x += coord.x;
     ret.y += coord.y;
     ret.z += coord.z;
   }
   ret.x /= atomIndices.size();
   ret.y /= atomIndices.size();
   ret.z /= atomIndices.size();
   return ret;
 }
예제 #4
0
 public void move() {
   Vector3d velocity = new Vector3d(cameraXP - cameraXN, 0, cameraZP - cameraZN);
   velocity.normalize();
   if (Double.isNaN(velocity.x)) {
     velocity = new Vector3d();
   }
   position.add(velocity);
   if (position.x < -maxX) {
     position.x = -maxX;
   } else if (position.x > maxX) {
     position.x = maxX;
   }
   if (position.z < -maxZ) {
     position.z = -maxZ;
   } else if (position.z > maxZ) {
     position.z = maxZ;
   }
 }
예제 #5
0
  @Override
  void update() {
    int newEditId;
    if ((newEditId = volume.update()) != volumeEditId) {
      for (int i = 0; i < 6; i++) {
        boxLine[i].setCoordinates(0, volume.facePoints[i], 0, 4);
        boxLine[i].setCoordinate(4, volume.facePoints[i][0]);
        imageQuad[i].setCoordinates(0, volume.facePoints[i], 0, 4);
      }

      faceCenter[PLUS_X].set(volume.maxCoord.x, 0.0, 0.0);
      faceCenter[PLUS_Y].set(0.0, volume.maxCoord.y, 0.0);
      faceCenter[PLUS_Z].set(0.0, 0.0, volume.maxCoord.z);
      faceCenter[MINUS_X].set(volume.minCoord.x, 0.0, 0.0);
      faceCenter[MINUS_Y].set(0.0, volume.minCoord.y, 0.0);
      faceCenter[MINUS_Z].set(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;
      volumeEditId = newEditId;
    }
    eyePtChanged();
    for (int i = 0; i < 6; i++) {
      if (boxAttr[i].getValue() == true) {
        boxSwitch[i].setWhichChild(Switch.CHILD_ALL);
      } else {
        boxSwitch[i].setWhichChild(Switch.CHILD_NONE);
      }
      String curImageFile = imageAttr[i].getValue();
      if (curImageFile != imageFile[i]) {
        imageFile[i] = curImageFile;
        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);
        }
      }
    }
  }
예제 #6
0
  public static void transformMesh(final TopLoc_Location loc, double[] src, float[] dst) {
    double[] matrix = new double[16];
    loc.transformation().getValues(matrix);

    Matrix4d m4d = new Matrix4d(matrix);
    Point3d p3d = new Point3d();

    for (int i = 0; i < src.length; i += 3) {
      p3d.x = src[i + 0];
      p3d.y = src[i + 1];
      p3d.z = src[i + 2];
      m4d.transform(p3d);
      dst[i + 0] = (float) p3d.x;
      dst[i + 1] = (float) p3d.y;
      dst[i + 2] = (float) p3d.z;
    }
  }
 /**
  * Places the value of the "home" center around which the View rotates into the Point3d. The
  * default center is (0, 0, 0).
  *
  * @param homeCenter The Point3d
  * @since Version 1.1
  */
 public void getHomeRotationCenter(Point3d homeCenter) {
   homeCenter.x = homeRotCenter.x;
   homeCenter.y = homeRotCenter.y;
   homeCenter.z = homeRotCenter.z;
 }
  /**
   * Procedure required by the CDOInterface. This function is only supposed to be called by the JCFL
   * library
   */
  public void setObjectProperty(String objectType, String propertyType, String propertyValue) {
    logger.debug("objectType: " + objectType);
    logger.debug("propType: " + propertyType);
    logger.debug("property: " + propertyValue);

    if (objectType == null) {
      logger.error("Cannot add property for null object");
      return;
    }
    if (propertyType == null) {
      logger.error("Cannot add property for null property type");
      return;
    }
    if (propertyValue == null) {
      logger.warn("Will not add null property");
      return;
    }

    if (objectType.equals("Molecule")) {
      if (propertyType.equals("id")) {
        currentMolecule.setID(propertyValue);
      } else if (propertyType.equals("inchi")) {
        currentMolecule.setProperty("iupac.nist.chemical.identifier", propertyValue);
      }
    } else if (objectType.equals("PseudoAtom")) {
      if (propertyType.equals("label")) {
        if (!(currentAtom instanceof IPseudoAtom)) {
          currentAtom = builder.newPseudoAtom(currentAtom);
        }
        ((IPseudoAtom) currentAtom).setLabel(propertyValue);
      }
    } else if (objectType.equals("Atom")) {
      if (propertyType.equals("type")) {
        if (propertyValue.equals("R") && !(currentAtom instanceof IPseudoAtom)) {
          currentAtom = builder.newPseudoAtom(currentAtom);
        }
        currentAtom.setSymbol(propertyValue);
      } else if (propertyType.equals("x2")) {
        Point2d coord = currentAtom.getPoint2d();
        if (coord == null) coord = new Point2d();
        coord.x = Double.parseDouble(propertyValue);
        currentAtom.setPoint2d(coord);
      } else if (propertyType.equals("y2")) {
        Point2d coord = currentAtom.getPoint2d();
        if (coord == null) coord = new Point2d();
        coord.y = Double.parseDouble(propertyValue);
        currentAtom.setPoint2d(coord);
      } else if (propertyType.equals("x3")) {
        Point3d coord = currentAtom.getPoint3d();
        if (coord == null) coord = new Point3d();
        coord.x = Double.parseDouble(propertyValue);
        currentAtom.setPoint3d(coord);
      } else if (propertyType.equals("y3")) {
        Point3d coord = currentAtom.getPoint3d();
        if (coord == null) coord = new Point3d();
        coord.y = Double.parseDouble(propertyValue);
        currentAtom.setPoint3d(coord);
      } else if (propertyType.equals("z3")) {
        Point3d coord = currentAtom.getPoint3d();
        if (coord == null) coord = new Point3d();
        coord.z = Double.parseDouble(propertyValue);
        currentAtom.setPoint3d(coord);
      } else if (propertyType.equals("xFract")) {
        Point3d coord = currentAtom.getFractionalPoint3d();
        if (coord == null) coord = new Point3d();
        coord.x = Double.parseDouble(propertyValue);
        currentAtom.setFractionalPoint3d(coord);
      } else if (propertyType.equals("yFract")) {
        Point3d coord = currentAtom.getFractionalPoint3d();
        if (coord == null) coord = new Point3d();
        coord.y = Double.parseDouble(propertyValue);
        currentAtom.setFractionalPoint3d(coord);
      } else if (propertyType.equals("zFract")) {
        Point3d coord = currentAtom.getFractionalPoint3d();
        if (coord == null) coord = new Point3d();
        coord.z = Double.parseDouble(propertyValue);
        currentAtom.setFractionalPoint3d(coord);
      } else if (propertyType.equals("formalCharge")) {
        currentAtom.setFormalCharge(Integer.parseInt(propertyValue));
      } else if (propertyType.equals("charge") || propertyType.equals("partialCharge")) {
        currentAtom.setCharge(Double.parseDouble(propertyValue));
      } else if (propertyType.equals("hydrogenCount")) {
        currentAtom.setHydrogenCount(Integer.parseInt(propertyValue));
      } else if (propertyType.equals("dictRef")) {
        currentAtom.setProperty("org.openscience.cdk.dict", propertyValue);
      } else if (propertyType.equals("atomicNumber")) {
        currentAtom.setAtomicNumber(Integer.parseInt(propertyValue));
      } else if (propertyType.equals("massNumber")) {
        currentAtom.setMassNumber((int) Double.parseDouble(propertyValue));
      } else if (propertyType.equals("id")) {
        logger.debug("id: ", propertyValue);
        currentAtom.setID(propertyValue);
        atomEnumeration.put(propertyValue, numberOfAtoms);
      }
    } else if (objectType.equals("Bond")) {
      if (propertyType.equals("atom1")) {
        bond_a1 = Integer.parseInt(propertyValue);
      } else if (propertyType.equals("atom2")) {
        bond_a2 = Integer.parseInt(propertyValue);
      } else if (propertyType.equals("id")) {
        logger.debug("id: " + propertyValue);
        bond_id = propertyValue;
      } else if (propertyType.equals("order")) {
        try {
          Double order = Double.parseDouble(propertyValue);
          if (order == 1.0) {
            bond_order = IBond.Order.SINGLE;
          } else if (order == 2.0) {
            bond_order = IBond.Order.DOUBLE;
          } else if (order == 3.0) {
            bond_order = IBond.Order.TRIPLE;
          } else if (order == 4.0) {
            bond_order = IBond.Order.QUADRUPLE;
          } else {
            bond_order = IBond.Order.SINGLE;
          }
        } catch (Exception e) {
          logger.error("Cannot convert to double: " + propertyValue);
          bond_order = IBond.Order.SINGLE;
        }
      } else if (propertyType.equals("stereo")) {
        if (propertyValue.equals("H")) {
          bond_stereo = CDKConstants.STEREO_BOND_DOWN;
        } else if (propertyValue.equals("W")) {
          bond_stereo = CDKConstants.STEREO_BOND_UP;
        }
      }
    }
    logger.debug("Object property set...");
  }
예제 #9
0
  @Override
  boolean intersect(
      PickShape pickShape,
      PickInfo pickInfo,
      int flags,
      Point3d iPnt,
      GeometryRetained geom,
      int geomIndex) {

    Point3d pnts[] = new Point3d[4];
    double sdist[] = new double[1];
    double minDist = Double.MAX_VALUE;
    double x = 0, y = 0, z = 0;
    int[] vtxIndexArr = new int[4];

    int i =
        ((vertexFormat & GeometryArray.BY_REFERENCE) == 0 ? initialVertexIndex : initialCoordIndex);
    pnts[0] = new Point3d();
    pnts[1] = new Point3d();
    pnts[2] = new Point3d();
    pnts[3] = new Point3d();

    switch (pickShape.getPickType()) {
      case PickShape.PICKRAY:
        PickRay pickRay = (PickRay) pickShape;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectRay(pnts, pickRay, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKSEGMENT:
        PickSegment pickSegment = (PickSegment) pickShape;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectSegment(pnts, pickSegment.start, pickSegment.end, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKBOUNDINGBOX:
        BoundingBox bbox = (BoundingBox) ((PickBounds) pickShape).bounds;
        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectBoundingBox(pnts, bbox, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKBOUNDINGSPHERE:
        BoundingSphere bsphere = (BoundingSphere) ((PickBounds) pickShape).bounds;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectBoundingSphere(pnts, bsphere, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKBOUNDINGPOLYTOPE:
        BoundingPolytope bpolytope = (BoundingPolytope) ((PickBounds) pickShape).bounds;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectBoundingPolytope(pnts, bpolytope, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKCYLINDER:
        PickCylinder pickCylinder = (PickCylinder) pickShape;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectCylinder(pnts, pickCylinder, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKCONE:
        PickCone pickCone = (PickCone) pickShape;

        while (i < validVertexCount) {
          for (int j = 0; j < 4; j++) {
            vtxIndexArr[j] = i;
            getVertexData(i++, pnts[j]);
          }
          if (intersectCone(pnts, pickCone, sdist, iPnt)) {
            if (flags == 0) {
              return true;
            }
            if (sdist[0] < minDist) {
              minDist = sdist[0];
              x = iPnt.x;
              y = iPnt.y;
              z = iPnt.z;
              if ((flags & PickInfo.CLOSEST_GEOM_INFO) != 0) {
                storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
              }
            }
            if ((flags & PickInfo.ALL_GEOM_INFO) != 0) {
              storeInterestData(pickInfo, flags, geom, geomIndex, vtxIndexArr, iPnt, sdist[0]);
            }
          }
        }
        break;
      case PickShape.PICKPOINT:
        // Should not happen since API already check for this
        throw new IllegalArgumentException(J3dI18N.getString("QuadArrayRetained0"));
      default:
        throw new RuntimeException("PickShape not supported for intersection ");
    }

    if (minDist < Double.MAX_VALUE) {
      iPnt.x = x;
      iPnt.y = y;
      iPnt.z = z;
      return true;
    }
    return false;
  }
예제 #10
0
  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);
  }