Changeset 173 for trunk/loci/visbio/view


Ignore:
Timestamp:
02/17/05 15:56:41 (15 years ago)
Author:
curtis
Message:

Volume rendering in v3.00!

Location:
trunk/loci/visbio/view
Files:
3 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/view/DisplayWindow.java

    r155 r173  
    2727import java.awt.event.ActionEvent; 
    2828import java.awt.event.ActionListener; 
    29 import java.util.Vector; 
    3029import javax.swing.JFrame; 
    3130import javax.swing.JPanel; 
     
    6867  /** Handles logic for capturing the display screenshots and movies. */ 
    6968  protected CaptureHandler captureHandler; 
    70  
    71   /** Handles logic for volume rendering. */ 
    72   protected RenderHandler renderHandler; 
    7369 
    7470  /** Handles logic for linking data transforms to the VisAD display. */ 
     
    159155  public CaptureHandler getCaptureHandler() { return captureHandler; } 
    160156 
    161   /** Gets the volume rendering handler. */ 
    162   public RenderHandler getRenderHandler() { return renderHandler; } 
    163  
    164157  /** Gets the transform handler. */ 
    165158  public TransformHandler getTransformHandler() { return transformHandler; } 
     
    218211    viewHandler.saveState(); 
    219212    captureHandler.saveState(); 
    220     if (renderHandler != null) renderHandler.saveState(); 
    221213    transformHandler.saveState(); 
    222214  } 
     
    250242    viewHandler.restoreState(); 
    251243    captureHandler.restoreState(); 
    252     if (renderHandler != null) renderHandler.saveState(); 
    253244    transformHandler.restoreState(); 
    254245  } 
     
    295286    DisplayWindow window = (DisplayWindow) dyn; 
    296287 
    297     boolean renderMatch = 
    298       (renderHandler == null && window.renderHandler == null) || 
    299       (renderHandler != null && renderHandler.matches(window.renderHandler)); 
    300288    return ObjectUtil.objectsEqual(name, window.name) && 
    301289      viewHandler.matches(window.viewHandler) && 
    302       captureHandler.matches(window.captureHandler) && renderMatch && 
     290      captureHandler.matches(window.captureHandler) && 
    303291      transformHandler.matches(window.transformHandler); 
    304292  } 
     
    338326      viewHandler.initState(null); 
    339327      captureHandler.initState(null); 
    340       if (renderHandler != null) renderHandler.initState(null); 
    341328      transformHandler.initState(null); 
    342329    } 
     
    346333      viewHandler.initState(window.viewHandler); 
    347334      captureHandler.initState(window.captureHandler); 
    348       renderHandler.initState(window.renderHandler); 
    349335      transformHandler.initState(window.transformHandler); 
    350336    } 
     
    368354      wm.addWindow(controls.getWindow()); 
    369355 
    370       // lay out handler panels 
    371       Vector handlerPanels = new Vector(); 
    372       handlerPanels.add(captureHandler.getPanel()); 
    373       if (renderHandler != null) handlerPanels.add(renderHandler.getPanel()); 
    374       Object[] handlerPanelArray = new Object[handlerPanels.size()]; 
    375       handlerPanels.copyInto(handlerPanelArray); 
    376  
    377356      // lay out components 
    378357      pane.add(display.getComponent(), BorderLayout.CENTER); 
    379358      controls.setContentPane(FormsUtil.makeColumn(new Object[] { 
    380         viewHandler.getPanel(), FormsUtil.makeRow(handlerPanelArray), 
    381         "Data", transformHandler.getPanel(), sliders}, null, true)); 
     359        viewHandler.getPanel(), FormsUtil.makeRow(new Object[] { 
     360        captureHandler.getPanel()}), "Data", transformHandler.getPanel(), 
     361        sliders}, null, true)); 
    382362      pack(); 
    383363      repack(); 
     
    399379    if (viewHandler == null) viewHandler = new ViewHandler(this); 
    400380    if (captureHandler == null) captureHandler = new CaptureHandler(this); 
    401     if (renderHandler == null) { 
    402       if (threeD) renderHandler = new RenderHandler(this); 
    403     } 
    404381    if (transformHandler == null) { 
    405382      transformHandler = threeD ? 
  • trunk/loci/visbio/view/StackHandler.java

    r155 r173  
    3838  // -- Constants -- 
    3939 
     40  /** Default maximum resolution for images in a stack. */ 
     41  public static final int DEFAULT_STACK_RESOLUTION = 192; 
     42 
    4043  /** Starting FPS for animation for image stacks. */ 
    4144  public static final int STACK_ANIMATION_RATE = 2; 
     45 
     46  /** Minimum length of each volume rendered spatial axis. */ 
     47  public static final int MIN_VOLUME_RESOLUTION = 2; 
     48 
     49  /** Maximum length of each volume rendered spatial axis. */ 
     50  public static final int MAX_VOLUME_RESOLUTION = 160; 
     51 
     52  /** Default length of each volume rendered spatial axis. */ 
     53  public static final int DEFAULT_VOLUME_RESOLUTION = 64; 
    4254 
    4355 
     
    5365  protected Vector thumbnails; 
    5466 
    55   /** Maximum resolution of stack images. */ 
    56   protected int maxResolution; 
     67  /** Resolution of stack images. */ 
     68  protected int stackRes; 
    5769 
    5870 
     
    6476    positions = new Vector(); 
    6577    thumbnails = new Vector(); 
    66     maxResolution = 192; 
     78    stackRes = DEFAULT_STACK_RESOLUTION; 
    6779  } 
    6880 
     
    7183 
    7284  /** Sets maximum resolution per axis of stacked images. */ 
    73   public void setMaximumResolution(int res) { maxResolution = res; } 
     85  public void setStackResolution(int res) { stackRes = res; } 
    7486 
    7587  /** Gets maximum resolution per axis of stacked images. */ 
    76   public int getMaximumResolution() { return maxResolution; } 
     88  public int getStackResolution() { return stackRes; } 
    7789 
    7890 
  • trunk/loci/visbio/view/StackLink.java

    r155 r173  
    3232public class StackLink extends TransformLink { 
    3333 
     34  // -- Constants -- 
     35 
     36  /** Dummy data to avoid "Data is null" status messages. */ 
     37  protected static final Real DUMMY = new Real(0); 
     38 
     39 
    3440  // -- Fields -- 
    3541 
     
    4551  /** Last known dimensional position of the link. */ 
    4652  protected int[] lastPos; 
     53 
     54  /** Data reference for volume rendered cube. */ 
     55  protected DataReferenceImpl volumeRef; 
     56 
     57  /** Whether volume rendering is currently enabled. */ 
     58  protected boolean volume = false; 
     59 
     60  /** Resolution of rendered volumes. */ 
     61  protected int volumeRes = StackHandler.DEFAULT_VOLUME_RESOLUTION; 
    4762 
    4863 
     
    5772    references = new Vector(); 
    5873    renderers = new Vector(); 
     74    try { volumeRef = new DataReferenceImpl(trans.getName() + "_volume"); } 
     75    catch (VisADException exc) { exc.printStackTrace(); } 
    5976 
    6077    int axis = -1; 
     
    143160  /** Gets visibility of the given data transform's yellow bounding box. */ 
    144161  public boolean isBoundingBoxVisible() { return super.isVisible(); } 
     162 
     163  /** Enables or disables volume rendering. */ 
     164  public void setVolumeRendered(boolean volume) { 
     165    if (this.volume == volume) return; 
     166    this.volume = volume; 
     167    doTransform(TransformHandler.MINIMUM_BURN_DELAY); 
     168  } 
     169 
     170  /** Gets status of volume rendering. */ 
     171  public boolean isVolumeRendered() { return volume; } 
     172 
     173  /** Sets maximum resolution per axis of rendered volumes. */ 
     174  public void setVolumeResolution(int res) { 
     175    if (volumeRes == res) return; 
     176    volumeRes = res; 
     177    doTransform(TransformHandler.MINIMUM_BURN_DELAY); 
     178  } 
     179 
     180  /** Gets maximum resolution per axis of rendered volumes. */ 
     181  public int getVolumeResolution() { return volumeRes; } 
    145182 
    146183 
     
    173210        new ConstantMap(3, Display.LineWidth) 
    174211      }); 
     212 
     213      // add volume 
     214      display.addReference(volumeRef); 
    175215    } 
    176216    catch (VisADException exc) { exc.printStackTrace(); } 
     
    265305   * utilizing thumbnails as appropriate. 
    266306   */ 
    267   protected void computeData(boolean thumbs) { 
     307  protected synchronized void computeData(boolean thumbs) { 
    268308    int[] pos = handler.getPos(trans); 
    269309    ThumbnailHandler th = trans.getThumbHandler(); 
     
    273313    DisplayImpl display = handler.getWindow().getDisplay(); 
    274314    VisUtil.setDisplayDisabled(display, true); 
     315    Data[] slices = new Data[len]; 
    275316    for (int s=0; s<len; s++) { 
    276317      if (stackAxis >= 0) pos[stackAxis] = s; 
    277       String current = " (" + (s + 1) + "/" + len + ")"; 
    278318 
    279319      Data thumb = th == null ? null : th.getThumb(pos); 
     
    281321      if (thumbs) setData(thumb, sliceRef); 
    282322      else { 
    283         setMessage("loading full-resolution data" + current); 
    284         Data d = getImageData(pos); 
    285         if (th != null && thumb == null) { 
     323        setMessage("loading full-resolution data (" + 
     324          (s + 1) + "/" + len + ")"); 
     325        slices[s] = getImageData(pos); 
     326        if (th != null && thumb == null && !volume) { 
    286327          // fill in missing thumbnail 
    287           th.setThumb(pos, th.makeThumb(d)); 
     328          th.setThumb(pos, th.makeThumb(slices[s])); 
    288329        } 
    289         setData(d, sliceRef); 
    290       } 
    291     } 
    292     if (!thumbs) { 
    293       setMessage("burning in full-resolution data"); 
     330        if (volume) setData(DUMMY, sliceRef, false); 
     331        else setData(slices[s], sliceRef); 
     332      } 
     333    } 
     334    if (thumbs) setData(DUMMY, volumeRef, false); 
     335    else { 
     336      if (volume) { 
     337        // render slices as a volume 
     338        String res = volumeRes + "x" + volumeRes + "x" + volumeRes; 
     339        setMessage("constructing " + res + " volume"); 
     340        ImageTransform it = (ImageTransform) trans; 
     341        RealType zType = it.getZType(); 
     342        FunctionType imageType = it.getType(); 
     343        try { 
     344          // convert slices to proper type 
     345          for (int i=0; i<len; i++) { 
     346            slices[i] = VisUtil.switchType((FlatField) slices[i], imageType); 
     347          } 
     348          // compile slices into a single volume 
     349          FunctionType volumeType = new FunctionType(zType, imageType); 
     350          Linear1DSet volumeSet = new Linear1DSet(zType, -1, 1, len); 
     351          FieldImpl field = new FieldImpl(volumeType, volumeSet); 
     352          field.setSamples(slices, false); 
     353          // collapse volume 
     354          FlatField collapsed = VisUtil.collapse(field); 
     355          // resample volume 
     356          setData(VisUtil.makeCube(collapsed, volumeRes), volumeRef, false); 
     357          setMessage("rendering " + res + " volume"); 
     358        } 
     359        catch (VisADException exc) { exc.printStackTrace(); } 
     360        catch (RemoteException exc) { exc.printStackTrace(); } 
     361      } 
     362      else { 
     363        // slice data is already set; just display burn-in message 
     364        setData(DUMMY, volumeRef, false); 
     365        setMessage("burning in full-resolution data"); 
     366      } 
    294367      clearWhenDone = true; 
    295368    } 
     
    307380    int[] res = new int[len.length]; 
    308381    boolean same = true; 
    309     int maxRes = ((StackHandler) handler).getMaximumResolution(); 
     382    int maxRes = volume ? volumeRes : 
     383      ((StackHandler) handler).getStackResolution(); 
    310384    for (int i=0; i<len.length; i++) { 
    311385      if (len[i] > maxRes) { 
  • trunk/loci/visbio/view/StackPanel.java

    r155 r173  
    2626import java.awt.event.ActionEvent; 
    2727import javax.swing.*; 
     28import javax.swing.event.ChangeEvent; 
    2829import loci.visbio.data.DataTransform; 
    2930import loci.visbio.util.FormsUtil; 
     
    4142  protected JComboBox stackBox; 
    4243 
     44  /** Dialog box for toggling individual slices. */ 
     45  protected SliceToggler sliceToggler; 
     46 
     47  /** Button for bringing up slice toggler dialog box. */ 
     48  protected JButton toggleSlices; 
     49 
     50  /** Checkbox for choosing whether current slice is visible. */ 
     51  protected JCheckBox sliceVisible; 
     52 
    4353  /** Checkbox for choosing whether current slice is highlighted. */ 
    4454  protected JCheckBox highlight; 
    4555 
    46   /** Dialog box for toggling individual slices. */ 
    47   protected SliceToggler sliceToggler; 
    48  
    49   /** Button for bringing up slice toggler dialog box. */ 
    50   protected JButton toggleSlices; 
    51  
    52   /** Checkbox for choosing whether current slice is visible. */ 
    53   protected JCheckBox sliceVisible; 
     56  /** Checkbox indicating whether volume rendering is enabled. */ 
     57  protected JCheckBox render; 
     58 
     59  /** Spinner for volume rendering resolution. */ 
     60  protected JSpinner renderRes; 
    5461 
    5562 
     
    7077    stackLabel.setEnabled(b); 
    7178    stackBox.setEnabled(b); 
    72     highlight.setEnabled(b); 
    7379    toggleSlices.setEnabled(b); 
    7480    sliceVisible.setEnabled(b); 
     81    highlight.setEnabled(b); 
     82    render.setEnabled(b); 
     83    renderRes.setEnabled(b); 
    7584    if (b) { 
    7685      StackLink link = (StackLink) handler.getLink(trans); 
     
    96105      stackBox.addActionListener(this); 
    97106 
    98       // update "highlight current slice" checkbox 
    99       highlight.setSelected(link.isBoundingBoxVisible()); 
    100  
    101107      // update "current slice visible" checkbox 
    102108      int slice = link.getCurrentSlice(); 
    103109      sliceVisible.setSelected(link.isSliceVisible(slice)); 
     110 
     111      // update "highlight current slice" checkbox 
     112      highlight.setSelected(link.isBoundingBoxVisible()); 
     113 
     114      // update "render as a volume" checkbox and spinner 
     115      render.setSelected(link.isVolumeRendered()); 
     116      renderRes.setValue(new Integer(link.getVolumeResolution())); 
    104117    } 
    105118  } 
     
    113126    if (cmd.equals("stackBox")) { 
    114127      DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
    115       int axis = stackBox.getSelectedIndex() - 1; 
    116       StackLink link = (StackLink) handler.getLink(trans); 
    117       link.setStackAxis(axis); 
     128      StackLink link = (StackLink) handler.getLink(trans); 
     129      link.setStackAxis(stackBox.getSelectedIndex() - 1); 
    118130      handler.rebuild(); 
    119     } 
    120     else if (cmd.equals("highlight")) { 
    121       DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
    122       boolean vis = highlight.isSelected(); 
    123       StackLink link = (StackLink) handler.getLink(trans); 
    124       link.setBoundingBoxVisible(vis); 
    125131    } 
    126132    else if (cmd.equals("toggleSlices")) { 
     
    135141      DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
    136142      StackLink link = (StackLink) handler.getLink(trans); 
    137       int slice = link.getCurrentSlice(); 
    138       boolean vis = sliceVisible.isSelected(); 
    139       link.setSliceVisible(slice, vis); 
     143      link.setSliceVisible(link.getCurrentSlice(), sliceVisible.isSelected()); 
    140144      updateControls(); 
    141145    } 
    142     else { 
    143       if (cmd.equals("transformBox")) updateControls(); 
    144       super.actionPerformed(e); 
    145     } 
     146    else if (cmd.equals("highlight")) { 
     147      DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
     148      StackLink link = (StackLink) handler.getLink(trans); 
     149      link.setBoundingBoxVisible(highlight.isSelected()); 
     150    } 
     151    else if (cmd.equals("render")) { 
     152      DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
     153      StackLink link = (StackLink) handler.getLink(trans); 
     154      link.setVolumeRendered(render.isSelected()); 
     155    } 
     156    else super.actionPerformed(e); 
     157  } 
     158 
     159 
     160  // -- ChangeListener API methods -- 
     161 
     162  /** Handles spinner changes. */ 
     163  public void stateChanged(ChangeEvent e) { 
     164    Object src = e.getSource(); 
     165    if (src == renderRes) { 
     166      DataTransform trans = (DataTransform) transformList.getSelectedValue(); 
     167      StackLink link = (StackLink) handler.getLink(trans); 
     168      link.setVolumeResolution(((Integer) renderRes.getValue()).intValue()); 
     169    } 
     170    else super.stateChanged(e); 
    146171  } 
    147172 
     
    164189    stackLabel.setEnabled(false); 
    165190 
    166     // highlight current slice checkbox 
    167     highlight = new JCheckBox("Highlight current slice"); 
    168     if (!LAFUtil.isMacLookAndFeel()) highlight.setMnemonic('h'); 
    169     highlight.setToolTipText("Toggles yellow highlight around current slice"); 
    170     highlight.setActionCommand("highlight"); 
    171     highlight.addActionListener(this); 
    172     highlight.setEnabled(false); 
    173  
    174191    // slice toggler dialog box 
    175192    sliceToggler = new SliceToggler((StackHandler) handler); 
     
    192209    sliceVisible.setEnabled(false); 
    193210 
     211    // highlight current slice checkbox 
     212    highlight = new JCheckBox("Highlight current slice"); 
     213    if (!LAFUtil.isMacLookAndFeel()) highlight.setMnemonic('h'); 
     214    highlight.setToolTipText("Toggles yellow highlight around current slice"); 
     215    highlight.setActionCommand("highlight"); 
     216    highlight.addActionListener(this); 
     217    highlight.setEnabled(false); 
     218 
     219    // checkbox for toggling volume rendering 
     220    render = new JCheckBox("Render as a volume"); 
     221    render.setActionCommand("render"); 
     222    render.addActionListener(this); 
     223    render.setMnemonic('v'); 
     224 
     225    // slider for adjusting volume resolution 
     226    SpinnerNumberModel renderModel = new SpinnerNumberModel( 
     227      StackHandler.DEFAULT_VOLUME_RESOLUTION, 
     228      StackHandler.MIN_VOLUME_RESOLUTION, 
     229      StackHandler.MAX_VOLUME_RESOLUTION, 16); 
     230    renderRes = new JSpinner(renderModel); 
     231    renderRes.setToolTipText("Adjusts the resolution of the rendering."); 
     232    renderRes.setEnabled(false); 
     233    renderRes.addChangeListener(this); 
     234 
    194235    // lay out components 
    195     return FormsUtil.makeColumn(new Object[] {visible, 
     236    return FormsUtil.makeColumn(new Object[] { 
    196237      FormsUtil.makeRow(stackLabel, stackBox), 
    197       toggleSlices, sliceVisible, highlight}); 
     238      FormsUtil.makeRow(visible, toggleSlices), 
     239      sliceVisible, highlight, FormsUtil.makeRow(render, renderRes)}); 
    198240  } 
    199241 
  • trunk/loci/visbio/view/TransformLink.java

    r155 r173  
    295295 
    296296      // wait until appointed burn-in time (which could change during the wait) 
    297       if (!alive) break; 
    298297      long time; 
    299298      while ((time = System.currentTimeMillis()) < burnTime) { 
     299        if (!alive) break; 
    300300        long wait = burnTime - time; 
    301301        if (wait >= 1000) { 
     
    410410 
    411411  /** Assigns the given data object to the data reference. */ 
    412   protected void setData(Data d) { setData(d, ref); } 
     412  protected void setData(Data d) { setData(d, ref, true); } 
     413 
     414  /** 
     415   * Assigns the given data object to the data reference, 
     416   * switching to the proper types if the flag is set. 
     417   */ 
     418  protected void setData(Data d, boolean autoSwitch) { 
     419    setData(d, ref, autoSwitch); 
     420  } 
    413421 
    414422  /** Assigns the given data object to the given data reference. */ 
    415423  protected void setData(Data d, DataReference dataRef) { 
    416     if (d instanceof FlatField && trans instanceof ImageTransform) { 
     424    setData(d, dataRef, true); 
     425  } 
     426 
     427  /** 
     428   * Assigns the given data object to the given data reference, 
     429   * switching to the proper types if the flag is set. 
     430   */ 
     431  protected void setData(Data d, DataReference dataRef, boolean autoSwitch) { 
     432    if (autoSwitch && d instanceof FlatField && 
     433      trans instanceof ImageTransform) 
     434    { 
    417435      // special case: use ImageTransform's suggested MathType instead 
    418436      FlatField ff = (FlatField) d; 
Note: See TracChangeset for help on using the changeset viewer.