public BranchGroup doTransform() throws VisADException, RemoteException {

    DataDisplayLink[] Links = getLinks();
    if (Links == null || Links.length == 0) {
      return null;
    }

    DataDisplayLink link = Links[0];
    ShadowTypeJ3D type = (ShadowTypeJ3D) link.getShadow();
    boolean doByRef = false;
    if (isByRefUsable(link, type) && ShadowType.byReference) {
      doByRef = true;
      type =
          new ShadowImageByRefFunctionTypeJ3D(
              link.getData().getType(),
              link,
              null,
              ((ShadowFunctionOrSetType) type.getAdaptedShadowType()).getInheritedValues(),
              (ShadowFunctionOrSetType) type.getAdaptedShadowType(),
              type.getLevelOfDifficulty());
    }

    BranchGroup branch = null;
    if ((lastByRef && doByRef) || (!lastByRef && !doByRef)) {
      branch = getBranch();
    }
    lastByRef = doByRef;

    if (branch == null) {
      branch = new BranchGroup();
      branch.setCapability(BranchGroup.ALLOW_DETACH);
      branch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
      branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
      branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
      last_curve_size = -1;
      last_zaxis_value = Float.NaN;
      last_alpha_value = Float.NaN;
      last_data_hash_code = -1;
      adjust_projection_seam = false; // 27FEB2012: Projection Seam Change Bug Fix
    }

    // initialize valueArray to missing
    int valueArrayLength = getDisplay().getValueArrayLength();
    float[] valueArray = new float[valueArrayLength];
    for (int i = 0; i < valueArrayLength; i++) {
      valueArray[i] = Float.NaN;
    }

    Data data;
    try {
      data = link.getData();
    } catch (RemoteException re) {
      if (visad.collab.CollabUtil.isDisconnectException(re)) {
        getDisplay().connectionFailed(this, link);
        removeLink(link);
        return null;
      }
      throw re;
    }

    if (data == null) {
      branch = null;
      addException(new DisplayException("Data is null: DefaultRendererJ3D.doTransform"));
    } else {
      // check MathType of non-null data, to make sure it is a single-band
      // image or a sequence of single-band images
      MathType mtype = link.getType();
      if (!isImageType(mtype)) {
        throw new BadMappingException("must be image or image sequence");
      }
      link.start_time = System.currentTimeMillis();
      link.time_flag = false;
      vbranch = null;
      // transform data into a depiction under branch
      long t1 = System.currentTimeMillis();
      try {
        if (type
            instanceof
            ShadowImageByRefFunctionTypeJ3D) { // GEOMETRY/COLORBYTE REUSE LOGIC Only for ByRef for
                                               // Time being
          if (checkAction()) { // This generally decides whether at all retransformation is required
                               // or not.
            type.doTransform(branch, data, valueArray, link.getDefaultValues(), this);
          }
        } else { // Not byRef (ShadowImageFunctionTypeJ3D)
          type.doTransform(branch, data, valueArray, link.getDefaultValues(), this);
        }
      } catch (RemoteException re) {
        if (visad.collab.CollabUtil.isDisconnectException(re)) {
          getDisplay().connectionFailed(this, link);
          removeLink(link);
          return null;
        }
        throw re;
      }
      long t2 = System.currentTimeMillis();
      // System.err.println("Time taken:" + (t2-t1));
    }
    link.clearData();

    return branch;
  }