Changeset 2896


Ignore:
Timestamp:
06/19/07 16:49:22 (12 years ago)
Author:
sorber
Message:

Synchronized access to node array in OverlayNodedObject.

Location:
trunk/loci/visbio/overlays
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/overlays/OverlayNodedObject.java

    r2886 r2896  
    8484 
    8585  // -- Fields -- 
     86 
     87  /** Synchronization object for nodes array */ 
     88  protected Object nodesSync = new Object(); 
    8689 
    8790  /** Node array and associated tracking variables */ 
     
    123126    this.x2 = x2; 
    124127    this.y2 = y2; 
    125     maxNodes = 100; 
    126     nodes = new float[2][maxNodes]; 
    127     Arrays.fill(nodes[0], x1); 
    128     Arrays.fill(nodes[1], y1); 
    129     numNodes = 1; 
     128    synchronized (nodesSync) { 
     129      maxNodes = 100; 
     130      nodes = new float[2][maxNodes]; 
     131      Arrays.fill(nodes[0], x1); 
     132      Arrays.fill(nodes[1], y1); 
     133      numNodes = 1; 
     134    } 
    130135    computeLength(); 
    131136    turnOffHighlighting(); 
     
    136141    super(overlay); 
    137142    x1=x2=y1=y2=0f; 
    138     this.nodes = nodes; 
    139     numNodes = nodes[0].length; 
    140     maxNodes = nodes[0].length; 
     143    synchronized (nodesSync) { 
     144      this.nodes = nodes; 
     145      numNodes = nodes[0].length; 
     146      maxNodes = nodes[0].length; 
     147    } 
    141148    updateBoundingBox(); 
    142149    computeLength(); 
     
    152159 
    153160  /** Returns whether this object is drawable, i.e., is of nonzero 
    154   *  size, area, length, etc.  */ 
     161   *  size, area, length, etc.  */ 
    155162  public boolean hasData() { 
    156     if (isDrawing()) return (numNodes > 0); 
    157     else return (numNodes > 1); 
     163    synchronized (nodesSync) { 
     164      if (isDrawing()) return (numNodes > 0); 
     165      else return (numNodes > 1); 
     166    } 
    158167    // NOTE: Not exactly consistent with the other overlay objects. 
    159168    // You want to see 1-node objects while drawing, but 
     
    173182    SampledSet fieldSet = null; 
    174183    try { 
    175       fieldSet = new Gridded2DSet(domain, 
    176         nodes, maxNodes, null, null, null, false); 
     184      synchronized (nodesSync) { 
     185        fieldSet = new Gridded2DSet(domain, 
     186          nodes, maxNodes, null, null, null, false); 
     187      } 
    177188 
    178189      // I've written !isDrawing() to prevent a manifold dimension mismatch 
     
    215226        System.out.println("fieldSet.getLength = " + fieldSet.getLength()); 
    216227      } 
    217       catch (VisADException exc2) {exc2.printStackTrace();} 
     228      catch (VisADException exc2) { exc2.printStackTrace(); } 
    218229    } 
    219230    catch (RemoteException exc) { exc.printStackTrace(); } 
     
    224235  /** Compute the shortest distance from this object to the given point. */ 
    225236  public double getDistance (double x, double y) { 
    226      double[] distSegWt = MathUtil.getDistSegWt(nodes, (float) x, (float) y); 
    227      return distSegWt[0]; 
     237    synchronized (nodesSync) { 
     238      double[] distSegWt = MathUtil.getDistSegWt(nodes, (float) x, (float) y); 
     239      return distSegWt[0]; 
     240    } 
    228241  } 
    229242 
     
    233246    double minDist = Double.POSITIVE_INFINITY; 
    234247    float[] p = new float[]{x, y}; 
    235     for (int i=0; i<numNodes; i++) { 
    236       float[] c = {nodes[0][i], nodes[1][i]};  
    237       double dist = MathUtil.getDistance(c, p);  
    238       if (dist < minDist) { 
    239         minIndex = i; 
    240         minDist = dist; 
     248 
     249    // check distance to all nodes 
     250    synchronized (nodesSync) { 
     251      for (int i=0; i<numNodes; i++) { 
     252        float[] c = {nodes[0][i], nodes[1][i]};  
     253        double dist = MathUtil.getDistance(c, p);  
     254        if (dist < minDist) { 
     255          minIndex = i; 
     256          minDist = dist; 
     257        } 
    241258      } 
    242259    } 
     
    319336  public float[] getNodeCoords (int index) { 
    320337    float[] retvals = new float[2]; 
    321     if (index < numNodes && index >= 0) { 
    322       retvals[0] = nodes[0][index]; 
    323       retvals[1] = nodes[1][index]; 
    324     } else { 
    325       retvals[0] = -1f; 
    326       retvals[1] = -1f; 
     338    synchronized(nodesSync) { 
     339      if (index < numNodes && index >= 0) { 
     340        retvals[0] = nodes[0][index]; 
     341        retvals[1] = nodes[1][index]; 
     342      } else { 
     343        retvals[0] = -1f; 
     344        retvals[1] = -1f; 
     345      } 
    327346    } 
    328347    return retvals; 
     
    331350  /** Returns the node array */ 
    332351  public float[][] getNodes() { 
    333     float[][] copy = new float[2][numNodes]; 
    334     for (int i=0; i<2; i++) 
    335       System.arraycopy(nodes[i], 0, copy[i], 0, numNodes); 
    336     return copy; 
     352    synchronized(nodesSync) { 
     353      float[][] copy = new float[2][numNodes]; 
     354      for (int i=0; i<2; i++) { 
     355        System.arraycopy(nodes[i], 0, copy[i], 0, numNodes); 
     356      } 
     357      return copy; 
     358    } 
    337359  } 
    338360 
    339361  /** Returns the number of real nodes in the array */ 
    340   public int getNumNodes() { return numNodes; } 
     362  public int getNumNodes() { synchronized(nodesSync) { return numNodes; } } 
    341363 
    342364  /** Returns total number of nodes in array */ 
    343   public int getMaxNodes() { return maxNodes; } 
     365  public int getMaxNodes() { synchronized(nodesSync) { return maxNodes; } } 
    344366 
    345367  /** Gets most recent x-coordinate in node array. */ 
    346368  public float getLastNodeX() { 
    347     return nodes[0][numNodes-1]; 
     369    synchronized (nodesSync) { return nodes[0][numNodes-1]; } 
    348370  } 
    349371 
    350372  /** Gets most recent y-coordinate in node array. */ 
    351373  public float getLastNodeY() { 
    352     return nodes[1][numNodes-1]; 
     374    synchronized(nodesSync) { return nodes[1][numNodes-1]; } 
    353375  } 
    354376 
     
    358380    float dx = x1-this.x1; 
    359381    float dy = y1-this.y1; 
    360     for (int i=0; i<numNodes; i++) { 
    361       nodes[0][i] = nodes[0][i]+dx; 
    362       nodes[1][i] = nodes[1][i]+dy; 
     382    synchronized (nodesSync) { 
     383      for (int i=0; i<numNodes; i++) { 
     384        nodes[0][i] = nodes[0][i]+dx; 
     385        nodes[1][i] = nodes[1][i]+dy; 
     386      } 
    363387    } 
    364388 
     
    370394  /** Sets the node array to that provided--for loading from saved */ 
    371395  public void setNodes(float[][] nodes) { 
    372     this.nodes = nodes; 
    373     numNodes = nodes[0].length; 
    374     maxNodes = numNodes; 
     396    synchronized (nodesSync) { 
     397      this.nodes = nodes; 
     398      numNodes = nodes[0].length; 
     399      maxNodes = numNodes; 
     400    } 
    375401    computeLength(); 
    376402    updateBoundingBox(); 
     
    381407    if (numNodes == 0) return; 
    382408    float xmin, xmax, ymin, ymax; 
    383     xmin = xmax = nodes[0][0]; 
    384     ymin = ymax = nodes[1][0]; 
    385     for (int i=1; i < numNodes; i++) { 
    386       if (nodes[0][i] < xmin) xmin = nodes[0][i]; 
    387       if (nodes[0][i] > xmax) xmax = nodes[0][i]; 
    388       if (nodes[1][i] < ymin) ymin = nodes[1][i]; 
    389       if (nodes[1][i] > ymax) ymax = nodes[1][i]; 
     409    synchronized (nodesSync) { 
     410      xmin = xmax = nodes[0][0]; 
     411      ymin = ymax = nodes[1][0]; 
     412      for (int i=1; i < numNodes; i++) { 
     413        if (nodes[0][i] < xmin) xmin = nodes[0][i]; 
     414        if (nodes[0][i] > xmax) xmax = nodes[0][i]; 
     415        if (nodes[1][i] < ymin) ymin = nodes[1][i]; 
     416        if (nodes[1][i] > ymax) ymax = nodes[1][i]; 
     417      } 
    390418    } 
    391419    this.x1 = xmin; 
     
    412440  /** Computes length of curve */ 
    413441  public void computeLength() { 
    414     if (maxNodes != numNodes) truncateNodeArray(); 
     442    boolean notFull = false; 
     443    synchronized (nodesSync) { 
     444      if (maxNodes != numNodes) notFull = true; 
     445    } 
     446    if (notFull) truncateNodeArray(); 
     447 
    415448    double length = 0; 
    416     for (int i=0; i<numNodes-1; i++) { 
    417       double[] a = {(double) nodes[0][i], (double)nodes[1][i]}; 
    418       double[] b = {(double) nodes[0][i+1], (double) nodes[1][i+1]}; 
    419       length += MathUtil.getDistance(a, b); 
     449    synchronized (nodesSync) { 
     450      for (int i=0; i<numNodes-1; i++) { 
     451        double[] a = {(double) nodes[0][i], (double)nodes[1][i]}; 
     452        double[] b = {(double) nodes[0][i+1], (double) nodes[1][i+1]}; 
     453        length += MathUtil.getDistance(a, b); 
     454      } 
    420455    } 
    421456    this.curveLength = length; 
     
    427462  /** Sets coordinates of an existing node */ 
    428463  public void setNodeCoords(int ndx, float newX, float newY) { 
    429     if (ndx >= 0 && ndx < numNodes) { 
     464    synchronized (nodesSync) { 
    430465      nodes[0][ndx] = newX; 
    431466      nodes[1][ndx] = newY; 
    432     } 
    433     else { 
    434       //TEMP: 
    435       //System.out.println("Out of bounds error. Can't reset node coordinates"); 
    436467    } 
    437468  } 
     
    440471  public void setLastNode(float x, float y) { 
    441472    setNodeCoords(numNodes-1, x, y); 
    442     if (numNodes < maxNodes) { 
    443       Arrays.fill(nodes[0], numNodes, maxNodes, x); 
    444       Arrays.fill(nodes[1], numNodes, maxNodes, y); 
     473    synchronized (nodesSync) { 
     474      if (numNodes < maxNodes) { 
     475        Arrays.fill(nodes[0], numNodes, maxNodes, x); 
     476        Arrays.fill(nodes[1], numNodes, maxNodes, y); 
     477      } 
    445478    } 
    446479  } 
     
    453486  /** Sets next node coordinates. */ 
    454487  public void setNextNode(float x, float y) { 
    455     if (numNodes >= maxNodes) { 
    456       maxNodes *= 2; 
    457       nodes = resizeNodeArray(nodes, maxNodes); 
    458     } 
    459     Arrays.fill(nodes[0], numNodes, maxNodes, x); 
    460     Arrays.fill(nodes[1], numNodes++, maxNodes, y); 
    461     // i.e., set all remaining nodes (as per maxNodes) to next node coords 
     488    synchronized (nodesSync) { 
     489      if (numNodes >= maxNodes) { 
     490        maxNodes *= 2; 
     491        resizeNodeArray(maxNodes); 
     492      } 
     493      Arrays.fill(nodes[0], numNodes, maxNodes, x); 
     494      Arrays.fill(nodes[1], numNodes++, maxNodes, y); 
     495      // i.e., set all remaining nodes (as per maxNodes) to next node coords 
     496    } 
    462497  } 
    463498 
     
    472507   */ 
    473508  public void insertNode(int index, float x, float y) { 
    474     if (index >= 0 && index < numNodes) { 
    475       // if array is full, make some more room. 
    476       if (numNodes >= maxNodes) { // numNodes should never exceed maxNodes but.. 
    477         maxNodes *= 2; 
    478         nodes = resizeNodeArray(nodes, maxNodes); 
    479       } 
    480       for (int j = 0; j < 2; j++) { 
    481         for (int i = numNodes; i > index; i--) { 
    482           // right shift every node right of index by 1 
    483           nodes[j][i] = nodes[j][i-1]; 
     509    synchronized (nodesSync) { 
     510      if (index >= 0 && index < numNodes) { 
     511        // if array is full, make some more room. 
     512        if (numNodes >= maxNodes) { // numNodes should never exceed maxNodes but.. 
     513          maxNodes *= 2; 
     514          resizeNodeArray(maxNodes); 
    484515        } 
    485       } 
    486       nodes[0][index] = x; 
    487       nodes[1][index] = y; 
    488       numNodes++; 
    489     } 
    490     else { 
    491       //System.out.println("index not in range (0, numNodes). " + 
    492       //  "No node inserted"); 
     516        for (int j = 0; j < 2; j++) { 
     517          for (int i = numNodes; i > index; i--) { 
     518            // right shift every node right of index by 1 
     519            nodes[j][i] = nodes[j][i-1]; 
     520          } 
     521        } 
     522        nodes[0][index] = x; 
     523        nodes[1][index] = y; 
     524        numNodes++; 
     525      } 
     526      else { 
     527        //System.out.println("index not in range (0, numNodes). " + 
     528        //  "No node inserted"); 
     529      } 
    493530    } 
    494531  } 
     
    499536    // checks whether i1 + 1 < i2, i.e., is there a non-zero 
    500537    // number of nodes to delete 
    501     if (0 <= i1 && i2 < numNodes && i1 + 1 < i2 ) { 
    502       int victims = i2 - i1 - 1; 
    503       float[][] newNodes = new float[2][maxNodes - victims]; 
    504       System.arraycopy(nodes[0], 0, newNodes[0], 0, i1 + 1); 
    505       System.arraycopy(nodes[1], 0, newNodes[1], 0, i1 + 1); 
    506       System.arraycopy(nodes[0], i2, newNodes[0], i1+1, maxNodes - i2); 
    507       System.arraycopy(nodes[1], i2, newNodes[1], i1+1, maxNodes - i2); 
    508       numNodes -= victims; 
    509       maxNodes -= victims; 
    510       nodes = newNodes; 
    511     } else { 
    512       //System.out.println("deleteBetween(int, int) out of bounds error"); 
     538    synchronized(nodesSync) { 
     539      if (0 <= i1 && i2 < numNodes && i1 + 1 < i2 ) { 
     540        int victims = i2 - i1 - 1; 
     541        float[][] newNodes = new float[2][maxNodes - victims]; 
     542        System.arraycopy(nodes[0], 0, newNodes[0], 0, i1 + 1); 
     543        System.arraycopy(nodes[1], 0, newNodes[1], 0, i1 + 1); 
     544        System.arraycopy(nodes[0], i2, newNodes[0], i1+1, maxNodes - i2); 
     545        System.arraycopy(nodes[1], i2, newNodes[1], i1+1, maxNodes - i2); 
     546        numNodes -= victims; 
     547        maxNodes -= victims; 
     548        nodes = newNodes; 
     549      } else { 
     550        //System.out.println("deleteBetween(int, int) out of bounds error"); 
     551      } 
    513552    } 
    514553  } 
     
    516555  /** Deletes a node from the node array */ 
    517556  public void deleteNode(int index) { 
    518     if (index >=0 && index < numNodes) { 
    519       // built-in truncation 
    520       //System.out.println("OverlayObject.deleteNode(" + index +") called. " + 
    521       //  "numNodes = " + numNodes + ", maxNodes = " + maxNodes); 
    522       float [][] newNodes =  new float[2][numNodes-1]; 
    523       System.arraycopy(nodes[0], 0, newNodes[0], 0, index); 
    524       System.arraycopy(nodes[0], index+1, newNodes[0], index, numNodes-index-1); 
    525       System.arraycopy(nodes[1], 0, newNodes[1], 0, index); 
    526       System.arraycopy(nodes[1], index+1, newNodes[1], index, numNodes-index-1); 
    527       numNodes--; 
    528       maxNodes = numNodes; 
    529       nodes = newNodes; 
     557    synchronized (nodesSync) { 
     558      if (index >=0 && index < numNodes) { 
     559        // built-in truncation 
     560        //System.out.println("OverlayObject.deleteNode(" + index +") called. " + 
     561        //  "numNodes = " + numNodes + ", maxNodes = " + maxNodes); 
     562        float [][] newNodes =  new float[2][numNodes-1]; 
     563        System.arraycopy(nodes[0], 0, newNodes[0], 0, index); 
     564        System.arraycopy(nodes[0], index+1, newNodes[0], index, numNodes-index-1); 
     565        System.arraycopy(nodes[1], 0, newNodes[1], 0, index); 
     566        System.arraycopy(nodes[1], index+1, newNodes[1], index, numNodes-index-1); 
     567        numNodes--; 
     568        maxNodes = numNodes; 
     569        nodes = newNodes; 
     570      } 
    530571    } 
    531572  } 
     
    563604    OverlayFreeform f1 = null, f2 = null; 
    564605 
    565     // compute indices into the node array of this freeform  
    566     int f1Start, f2Start, f1Stop, f2Stop; 
    567     f1Start = 0; 
    568     f1Stop = seg; 
    569     f2Start = seg + 1; 
    570     f2Stop = numNodes - 1; 
    571  
    572     // if the cut point is a node itself, exclude that node from both halves 
    573     if (weight == 0.0) f1Stop = seg - 1; 
    574     else if (weight == 1.0) f2Start = seg + 2; 
    575  
    576     int numNodes1 = f1Stop + 1; 
    577     int numNodes2 = f2Stop - f2Start + 1; 
    578  
    579     // create new object if number of nodes in object > 1 
    580     if (numNodes1 > 1) { 
    581       float[][] f1Nodes = new float[2][numNodes1]; 
    582  
    583       for (int i=0; i<2; i++) { 
    584         System.arraycopy(nodes[i], 0, f1Nodes[i], 0, numNodes1); 
    585       } 
    586  
    587       f1 = new OverlayFreeform(overlay, f1Nodes); 
    588       overlay.addObject(f1); 
    589       f1.setSelected(false); 
    590       f1.setDrawing(false); 
    591     } 
    592  
    593     // create new object if number of nodes in object > 1 
    594     if (numNodes2 > 1) { 
    595       float[][] f2Nodes = new float[2][numNodes2]; 
    596  
    597       for (int i = 0; i<2; i++) { 
    598         System.arraycopy(nodes[i], f2Start, f2Nodes[i], 0, numNodes2); 
    599       } 
    600  
    601       f2 = new OverlayFreeform(overlay, f2Nodes); 
    602       overlay.addObject(f2); 
    603       f2.setSelected(false); 
    604       f2.setDrawing(false); 
    605     } 
     606    synchronized (nodesSync) { 
     607      // compute indices into the node array of this freeform  
     608      int f1Start, f2Start, f1Stop, f2Stop; 
     609      f1Start = 0; 
     610      f1Stop = seg; 
     611      f2Start = seg + 1; 
     612      f2Stop = numNodes - 1; 
     613 
     614      // if the cut point is a node itself, exclude that node from both halves 
     615      if (weight == 0.0) f1Stop = seg - 1; 
     616      else if (weight == 1.0) f2Start = seg + 2; 
     617 
     618      int numNodes1 = f1Stop + 1; 
     619      int numNodes2 = f2Stop - f2Start + 1; 
     620 
     621      // create new object if number of nodes in object > 1 
     622      if (numNodes1 > 1) { 
     623        float[][] f1Nodes = new float[2][numNodes1]; 
     624 
     625        for (int i=0; i<2; i++) { 
     626          System.arraycopy(nodes[i], 0, f1Nodes[i], 0, numNodes1); 
     627        } 
     628 
     629        f1 = new OverlayFreeform(overlay, f1Nodes); 
     630        overlay.addObject(f1); 
     631        f1.setSelected(false); 
     632        f1.setDrawing(false); 
     633      } 
     634 
     635      // create new object if number of nodes in object > 1 
     636      if (numNodes2 > 1) { 
     637        float[][] f2Nodes = new float[2][numNodes2]; 
     638 
     639        for (int i = 0; i<2; i++) { 
     640          System.arraycopy(nodes[i], f2Start, f2Nodes[i], 0, numNodes2); 
     641        } 
     642 
     643        f2 = new OverlayFreeform(overlay, f2Nodes); 
     644        overlay.addObject(f2); 
     645        f2.setSelected(false); 
     646        f2.setDrawing(false); 
     647      } 
     648 
     649    } // end synchronized 
    606650 
    607651    // dispose of original freeform 
     
    620664    // an extension 
    621665    // A: Yes, if extend mode is entered directly from edit mode 
    622     float[][] temp = new float[2][maxNodes]; 
    623     for (int j = 0; j < 2; j++) { 
    624       for (int i = 0; i < maxNodes; i++) { 
    625         temp[j][maxNodes-i-1] = nodes[j][i]; 
    626       } 
    627     } 
    628     nodes = temp; 
     666    synchronized (nodesSync) { 
     667      float[][] temp = new float[2][maxNodes]; 
     668      for (int j = 0; j < 2; j++) { 
     669        for (int i = 0; i < maxNodes; i++) { 
     670          temp[j][maxNodes-i-1] = nodes[j][i]; 
     671        } 
     672      } 
     673      nodes = temp; 
     674    } 
    629675  } 
    630676 
    631677  /** Deletes buffer nodes from the tail of the node array */ 
    632678  public void truncateNodeArray() { 
    633     nodes = resizeNodeArray(nodes, numNodes); 
     679     resizeNodeArray(numNodes); 
    634680  } 
    635681 
    636682  /** Resizes the node array, truncating if necessary. */ 
    637   protected float[][] resizeNodeArray(float[][] a, int newLength) { 
    638     //System.out.println("resizing node array to "+ newLength); // TEMP 
    639     int loopMax = Math.min(a[0].length, newLength); 
    640     float[][] a2 = new float[2][newLength]; 
    641     for (int j=0; j<2; j++) { //manually copy a to a2 
    642       for (int i=0; i<loopMax; i++) { 
    643         a2[j][i] = a[j][i]; 
    644       } 
    645       // case where newLength > a.length: 
    646       // fills rest of new array with nodes co-locational with last node 
    647       for (int i=loopMax; i < a2[0].length; i++) { 
    648         a2[j][i] = a[j][loopMax-1]; 
    649       } 
    650     } 
    651     maxNodes = newLength; 
    652     //System.out.println("resize completed. maxNodes = " + 
    653     //  maxNodes + " numNodes =  " + numNodes); 
    654     return a2; 
     683  // TODO is it possible to use System.arraycopy here? 
     684  protected void resizeNodeArray(int newLength) { 
     685    synchronized (nodesSync) { 
     686      int loopMax = Math.min(nodes[0].length, newLength); 
     687      float[][] a2 = new float[2][newLength]; 
     688      for (int j=0; j<2; j++) { //manually copy nodes to a2 
     689        for (int i=0; i<loopMax; i++) { 
     690          a2[j][i] = nodes[j][i]; 
     691        } 
     692        // case where newLength > a.length: 
     693        // fills rest of new array with nodes co-locational with last node 
     694        for (int i=loopMax; i < a2[0].length; i++) { 
     695          a2[j][i] = nodes[j][loopMax-1]; 
     696        } 
     697      } 
     698      nodes = a2; 
     699      maxNodes = newLength; 
     700    } 
    655701  } 
    656702 
     
    660706  private void printNodes(float[][] nodes) { 
    661707    System.out.println("Printing nodes..."); 
    662     for (int i = 0; i < nodes[0].length; i++){ 
    663       System.out.println(i+":("+nodes[0][i]+","+nodes[1][i]+")"); 
     708    synchronized (nodesSync) { 
     709      for (int i = 0; i < nodes[0].length; i++){ 
     710        System.out.println(i+":("+nodes[0][i]+","+nodes[1][i]+")"); 
     711      } 
    664712    } 
    665713  } 
     
    669717    printNodes(nodes); 
    670718  } 
     719 
     720  /** Prints current thread plus method name if provided */ 
     721  public static void printThread(String methodName) { 
     722    System.out.println(methodName + ": currentThread()= " + 
     723        Thread.currentThread()); 
     724  } 
    671725} 
  • trunk/loci/visbio/overlays/OverlayUtil.java

    r2885 r2896  
    499499    OverlayNodedObject ono = (OverlayNodedObject) obj; 
    500500 
    501     float delta; 
    502     float[][] nodes; 
    503     float[] c; 
    504     int numNodes, hltIndex = 0; 
    505     boolean hlt; 
    506     synchronized (overlay) { 
    507       delta = GLOW_WIDTH * getMultiplier(link); 
    508       nodes = ono.getNodes(); 
    509       numNodes = ono.getNumNodes(); 
    510       hlt = ono.isHighlightNode(); 
    511       if (hlt) hltIndex = ono.getHighlightedNodeIndex(); 
    512       c = ono.getNodeCoords(hltIndex); 
    513     } 
     501    float delta = GLOW_WIDTH * getMultiplier(link); 
     502    float[][] nodes = ono.getNodes(); 
     503    // OverlayNodedObject.printThread("OU.getNodedLayer()"); 
     504    int numNodes = ono.getNumNodes(); 
     505    boolean hlt = ono.isHighlightNode(); 
     506    int hltIndex = 0; 
     507    if (hlt) hltIndex = ono.getHighlightedNodeIndex(); 
     508    float[] c = ono.getNodeCoords(hltIndex); 
    514509 
    515510    // arc and width params 
     
    917912  } 
    918913 
    919   // put this in ObjectUtil or something 
    920914  /** Connects a pair of VisAD-style 2D arrays of points */ 
    921   public static float[][] adjoin(float[][] a, float b[][]) { 
     915  public static float[][] adjoin(float[][] a, float[][] b) { 
    922916    int alen = a[0].length; 
    923917    int blen = b[0].length; 
    924918    float[][] result = new float[a.length][alen + blen]; 
    925     for (int j=0; j<a.length; j++) { 
    926       for (int i=0; i<alen; i++) { 
    927         result[j][i] = a[j][i]; 
    928       } 
    929       for (int i=0; i<blen; i++) { 
    930         result[j][i+alen] = b[j][i]; 
    931       } 
     919    for (int j=0; j<2; j++) { 
     920        System.arraycopy(a[j], 0, result[j], 0, alen); 
     921        System.arraycopy(b[j], 0, result[j], alen, blen); 
    932922    } 
    933923    return result; 
     
    10511041        catch (VisADException ex2) { 
    10521042          System.out.println("OverlayUtil: error making Gridded2DSets: " +  
    1053               "lefth tries produced invalid sets."); 
     1043            "both tries produced invalid sets."); 
    10541044          ex2.printStackTrace(); 
    10551045        } 
  • trunk/loci/visbio/overlays/PolylineTool.java

    r2886 r2896  
    9797    //printMode("mouseDown"); 
    9898 
    99     synchronized (overlay) { 
    100       if (overlay.hasToolChanged()) { 
     99    if (overlay.hasToolChanged()) { 
     100      releaseLine(); 
     101      mode = WAIT; 
     102    } 
     103 
     104    if (mode == WAIT) { 
     105      deselectAll(); 
     106      line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
     107      line.setDrawing(true); 
     108      line.setSelected(true); 
     109      overlay.addObject(line, pos); 
     110      mode = PLACE; 
     111    } 
     112    else if (mode == PLACE) { 
     113      if (line.getNumNodes() > 1) { 
    101114        releaseLine(); 
    102         mode = WAIT; 
    103       } 
    104  
    105       if (mode == WAIT) { 
    106         deselectAll(); 
    107         line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
    108         line.setDrawing(true); 
    109         line.setSelected(true); 
    110         overlay.addObject(line, pos); 
    111         mode = PLACE; 
    112       } 
    113       else if (mode == PLACE) { 
    114         if (line.getNumNodes() > 1) { 
    115           releaseLine(); 
     115      } 
     116      else { 
     117        overlay.removeObject(line); 
     118        unselect(); 
     119      } 
     120      mode = WAIT; 
     121    } 
     122    else if (mode == SELECT) { 
     123      if (!ctl) { 
     124        // which node are you near? 
     125        if (selectedNode == line.getNumNodes() - 1) { 
     126          mode = SELECTED_TAIL; 
     127        } 
     128        else if (selectedNode == 0) { 
     129          // you're near the head node. 
     130          // flip nodes around in case user opts to extend polyline 
     131          line.reverseNodes(); 
     132          selectNode(line, line.getNumNodes() - 1); 
     133          mode = SELECTED_TAIL; 
    116134        } 
    117135        else { 
     136          // you're near some other node 
     137          mode = ADJUST; 
     138        } 
     139        line.setDrawing(true); 
     140      } 
     141      else { // erase 
     142        // if node interior, create two new polylines 
     143        if (selectedNode > 0 && selectedNode < line.getNumNodes() - 1) { 
     144          split(line, selectedNode); 
    118145          overlay.removeObject(line); 
    119146          unselect(); 
     147          mode = WAIT; 
    120148        } 
    121         mode = WAIT; 
    122       } 
    123       else if (mode == SELECT) { 
    124         if (!ctl) { 
    125           // which node are you near? 
    126           if (selectedNode == line.getNumNodes() - 1) { 
    127             mode = SELECTED_TAIL; 
    128           } 
    129           else if (selectedNode == 0) { 
    130             // you're near the head node. 
    131             // flip nodes around in case user opts to extend polyline 
    132             line.reverseNodes(); 
    133             selectNode(line, line.getNumNodes() - 1); 
    134             mode = SELECTED_TAIL; 
    135           } 
    136           else { 
    137             // you're near some other node 
    138             mode = ADJUST; 
    139           } 
    140           line.setDrawing(true); 
     149        else { 
     150          // else delete node 
     151          line.deleteNode(selectedNode); 
     152          releaseLine(); 
     153          mode = WAIT; 
    141154        } 
    142         else { // erase 
    143           // if node interior, create two new polylines 
    144           if (selectedNode > 0 && selectedNode < line.getNumNodes() - 1) { 
    145             split(line, selectedNode); 
    146             overlay.removeObject(line); 
    147             unselect(); 
    148             mode = WAIT; 
    149           } 
    150           else { 
    151             // else delete node 
    152             line.deleteNode(selectedNode); 
    153             releaseLine(); 
    154             mode = WAIT; 
    155           } 
    156         } 
    157       } 
    158       else if (mode == EXTEND || mode == BEG_EXTEND) { 
    159         line.setLastNode(dx, dy); 
    160         mode = PLACE; 
    161       } 
    162       else if (mode == EXTEND_ON_TAIL) { 
    163         line.deleteNode(line.getNumNodes()-1); 
    164         releaseLine(); 
    165         mode = WAIT; 
    166       } 
    167     } // end synchronized (line) 
     155      } 
     156    } 
     157    else if (mode == EXTEND || mode == BEG_EXTEND) { 
     158      line.setLastNode(dx, dy); 
     159      mode = PLACE; 
     160    } 
     161    else if (mode == EXTEND_ON_TAIL) { 
     162      line.deleteNode(line.getNumNodes()-1); 
     163      releaseLine(); 
     164      mode = WAIT; 
     165    } 
    168166 
    169167    overlay.notifyListeners(new TransformEvent(overlay)); 
     
    178176    //printMode("mouseDrag"); 
    179177 
    180     synchronized (overlay) { 
    181       if (overlay.hasToolChanged()) { 
    182         releaseLine(); 
    183         mode = WAIT; 
    184       } 
    185       if (mode == ADJUST) { 
    186         line.setNodeCoords(selectedNode, dx, dy); 
    187         overlay.notifyListeners(new TransformEvent(overlay)); 
    188       } 
    189       else if (mode == SELECTED_TAIL) { 
     178    if (overlay.hasToolChanged()) { 
     179      releaseLine(); 
     180      mode = WAIT; 
     181    } 
     182    if (mode == ADJUST) { 
     183      line.setNodeCoords(selectedNode, dx, dy); 
     184      overlay.notifyListeners(new TransformEvent(overlay)); 
     185    } 
     186    else if (mode == SELECTED_TAIL) { 
     187      mode = ADJUST_TAIL; 
     188      mouseDrag(e, px, py, dx, dy, pos, mods); 
     189    } 
     190    else if (mode == ADJUST_TAIL || mode == CLOSE_LOOP) { 
     191      line.setNodeCoords(selectedNode, dx, dy); 
     192 
     193      // determine if near head 
     194      double dist = getDistanceToNode(0, px, py, display); 
     195 
     196      // if near, highlight head node 
     197      if (dist < THRESH) { 
     198        line.setHighlightNode(selectedNode, CON); 
     199        mode = CLOSE_LOOP; 
     200      } 
     201      else { 
     202        line.setHighlightNode(selectedNode, SEL); 
    190203        mode = ADJUST_TAIL; 
    191         mouseDrag(e, px, py, dx, dy, pos, mods); 
    192       } 
    193       else if (mode == ADJUST_TAIL || mode == CLOSE_LOOP) { 
    194         line.setNodeCoords(selectedNode, dx, dy); 
    195  
    196         // determine if near head 
    197         double dist = getDistanceToNode(0, px, py, display); 
    198  
    199         // if near, highlight head node 
    200         if (dist < THRESH) { 
    201           line.setHighlightNode(selectedNode, CON); 
    202           mode = CLOSE_LOOP; 
    203         } 
    204         else { 
    205           line.setHighlightNode(selectedNode, SEL); 
    206           mode = ADJUST_TAIL; 
    207         } 
    208         overlay.notifyListeners(new TransformEvent(overlay)); 
    209       } 
    210       else if (mode == PLACE || mode == EXTEND || mode == BEG_EXTEND || 
    211         mode == EXTEND_ON_TAIL) 
    212       { 
    213         mouseMoved(e, px, py, dx, dy, pos, mods); 
    214       } 
    215     } // end synchronized (line) 
     204      } 
     205      overlay.notifyListeners(new TransformEvent(overlay)); 
     206    } 
     207    else if (mode == PLACE || mode == EXTEND || mode == BEG_EXTEND || 
     208      mode == EXTEND_ON_TAIL) 
     209    { 
     210      mouseMoved(e, px, py, dx, dy, pos, mods); 
     211    } 
    216212  } 
    217213 
     
    223219    //printMode("mouseUp");//TEMP 
    224220 
    225     synchronized (overlay) { 
    226       if (overlay.hasToolChanged()) { 
    227         releaseLine(); 
    228         mode = WAIT; 
    229       } 
    230       if (mode == ADJUST) { 
    231         line.updateBoundingBox(); 
    232         line.computeLength(); 
    233         line.setDrawing(false); 
    234         mode = SELECT; 
    235       } 
    236       else if (mode == ADJUST_TAIL) { 
    237         line.updateBoundingBox(); 
    238         line.computeLength(); 
    239         line.setDrawing(false); 
    240         mode = SELECT; 
    241       } 
    242       else if (mode == SELECTED_TAIL) { 
    243         line.turnOffHighlighting(); 
    244         mode = PLACE; 
    245       } 
    246       else if (mode == CLOSE_LOOP) { 
    247         float[] c = line.getNodeCoords(0); 
    248         line.setLastNode(c[0], c[1]); 
    249         line.updateBoundingBox(); 
    250         line.computeLength(); 
    251         line.setDrawing(false); 
    252         selectNode(line, line.getNumNodes() - 1); 
    253         mode = SELECT; 
    254       } 
    255       else if (mode == EXTEND_ON_TAIL) { 
    256         mouseDown(e, px, py, dx, dy, pos, mods); 
    257         // basically delete last node and end line 
    258       } 
    259     } // end synchronized (line) 
     221    if (overlay.hasToolChanged()) { 
     222      releaseLine(); 
     223      mode = WAIT; 
     224    } 
     225    if (mode == ADJUST) { 
     226      line.updateBoundingBox(); 
     227      line.computeLength(); 
     228      line.setDrawing(false); 
     229      mode = SELECT; 
     230    } 
     231    else if (mode == ADJUST_TAIL) { 
     232      line.updateBoundingBox(); 
     233      line.computeLength(); 
     234      line.setDrawing(false); 
     235      mode = SELECT; 
     236    } 
     237    else if (mode == SELECTED_TAIL) { 
     238      line.turnOffHighlighting(); 
     239      mode = PLACE; 
     240    } 
     241    else if (mode == CLOSE_LOOP) { 
     242      float[] c = line.getNodeCoords(0); 
     243      line.setLastNode(c[0], c[1]); 
     244      line.updateBoundingBox(); 
     245      line.computeLength(); 
     246      line.setDrawing(false); 
     247      selectNode(line, line.getNumNodes() - 1); 
     248      mode = SELECT; 
     249    } 
     250    else if (mode == EXTEND_ON_TAIL) { 
     251      mouseDown(e, px, py, dx, dy, pos, mods); 
     252      // basically delete last node and end line 
     253    } 
    260254  } 
    261255 
     
    267261    //printMode("mouseMoved"); 
    268262 
    269     synchronized (overlay) { 
    270       if (overlay.hasToolChanged()) { 
    271         releaseLine(); 
     263    if (overlay.hasToolChanged()) { 
     264      releaseLine(); 
     265      mode = WAIT; 
     266    } 
     267    if (mode == WAIT) { 
     268      OverlayObject[] objects = overlay.getObjects(); 
     269      int[] ndxNode =  getNearestNode(display, objects, px, py, THRESH); 
     270 
     271      if (ndxNode != null) { 
     272        int ndx = ndxNode[0]; 
     273        int node = ndxNode[1]; 
     274        //System.out.println("near node " + node + " of object " + obj);//TEMP 
     275        deselectAll(); 
     276        line = (OverlayPolyline) objects[ndx]; 
     277        selectNode(line, node); 
     278        mode = SELECT; 
     279      } 
     280    } 
     281    else if (mode == PLACE) { 
     282      line.setNextNode(dx, dy); 
     283 
     284      // keep track of curve length 
     285      // using frequent updates to curvelength in EXTEND, etc. instead 
     286      float[] c = line.getNodeCoords(line.getNumNodes()-2); 
     287      double[] cdub = {(double) c[0], (double) c[1]}; 
     288      double oldLen = line.getCurveLength(); 
     289      line.setCurveLength(oldLen + MathUtil.getDistance(cdub, 
     290            new double[]{dx, dy})); 
     291 
     292      mode = BEG_EXTEND; 
     293    } 
     294    else if (mode == EXTEND || mode == EXTEND_ON_TAIL) { 
     295      // update curve 
     296      adjustLastNode(line, dx, dy); 
     297 
     298      // determine if near head 
     299      double hdist = getDistanceToNode(0, px, py, display); 
     300 
     301      // determine if near last node placed 
     302      double ldist = 
     303        getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
     304 
     305      // if near ndx, highlight selected node differently 
     306      int flag = -1; 
     307      if (ldist < THRESH) 
     308        if (hdist < ldist) flag = 0; 
     309        else if (hdist > ldist) flag = 1; 
     310        else ; 
     311      else if (hdist < THRESH) flag = 0; 
     312 
     313      if (flag == 0) { 
     314        line.setHighlightNode(0, CON); 
     315        mode = CLOSE_LOOP; 
     316      } 
     317      else if (flag == 1) { 
     318        line.setHighlightNode(line.getNumNodes()-1, SEL); 
     319        mode = EXTEND_ON_TAIL; 
     320      } 
     321      else if (flag == -1) { 
     322        line.turnOffHighlighting(); 
     323        mode = EXTEND; 
     324      } 
     325    } 
     326    else if (mode == BEG_EXTEND) { 
     327      // update curve length 
     328      adjustLastNode(line, dx, dy); 
     329 
     330      // determine if near head 
     331      double hdist = getDistanceToNode(0, px, py, display); 
     332 
     333      // determine if near last node placed 
     334      double ldist = 
     335        getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
     336 
     337      // highlight first or last visible node if near 
     338      if (hdist < THRESH) { 
     339        line.setHighlightNode(line.getNumNodes()-1, CON); 
     340        mode = CLOSE_LOOP; 
     341      } 
     342 
     343      // switch modes if you've dragged far enough from last node placed 
     344      if (ldist > 10.0) { 
     345        mode = EXTEND; 
     346      } 
     347    } 
     348    else if (mode == CLOSE_LOOP) { 
     349      line.setLastNode(dx, dy); 
     350      // determine if near head: 
     351      double dist = getDistanceToNode(0, px, py, display); 
     352 
     353      // if not, turn off highlighting 
     354      if (dist > THRESH) { 
     355        line.turnOffHighlighting(); 
     356        mode = EXTEND; 
     357      } 
     358    } 
     359    else if (mode == SELECT) { 
     360      // get distance btw. pointer and selectedNode 
     361      double dist = getDistanceToNode(selectedNode, px, py, display); 
     362 
     363      double threshold = 2.0; 
     364      if (dist > threshold) { 
     365        line.turnOffHighlighting(); 
     366        unselect(); 
    272367        mode = WAIT; 
    273368      } 
    274       if (mode == WAIT) { 
    275         OverlayObject[] objects = overlay.getObjects(); 
    276         int[] ndxNode =  getNearestNode(display, objects, px, py, THRESH); 
    277  
    278         if (ndxNode != null) { 
    279           int ndx = ndxNode[0]; 
    280           int node = ndxNode[1]; 
    281           //System.out.println("near node " + node + " of object " + obj);//TEMP 
    282           deselectAll(); 
    283           line = (OverlayPolyline) objects[ndx]; 
    284           selectNode(line, node); 
    285           mode = SELECT; 
    286         } 
    287       } 
    288       else if (mode == PLACE) { 
    289         line.setNextNode(dx, dy); 
    290  
    291         // keep track of curve length 
    292         // using frequent updates to curvelength in EXTEND, etc. instead 
    293         float[] c = line.getNodeCoords(line.getNumNodes()-2); 
    294         double[] cdub = {(double) c[0], (double) c[1]}; 
    295         double oldLen = line.getCurveLength(); 
    296         line.setCurveLength(oldLen + MathUtil.getDistance(cdub, 
    297               new double[]{dx, dy})); 
    298  
    299         mode = BEG_EXTEND; 
    300       } 
    301       else if (mode == EXTEND || mode == EXTEND_ON_TAIL) { 
    302         // update curve 
    303         adjustLastNode(line, dx, dy); 
    304  
    305         // determine if near head 
    306         double hdist = getDistanceToNode(0, px, py, display); 
    307  
    308         // determine if near last node placed 
    309         double ldist = 
    310           getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
    311  
    312         // if near ndx, highlight selected node differently 
    313         int flag = -1; 
    314         if (ldist < THRESH) 
    315           if (hdist < ldist) flag = 0; 
    316           else if (hdist > ldist) flag = 1; 
    317           else ; 
    318         else if (hdist < THRESH) flag = 0; 
    319  
    320         if (flag == 0) { 
    321           line.setHighlightNode(0, CON); 
    322           mode = CLOSE_LOOP; 
    323         } 
    324         else if (flag == 1) { 
    325           line.setHighlightNode(line.getNumNodes()-1, SEL); 
    326           mode = EXTEND_ON_TAIL; 
    327         } 
    328         else if (flag == -1) { 
    329           line.turnOffHighlighting(); 
    330           mode = EXTEND; 
    331         } 
    332       } 
    333       else if (mode == BEG_EXTEND) { 
    334         // update curve length 
    335         adjustLastNode(line, dx, dy); 
    336  
    337         // determine if near head 
    338         double hdist = getDistanceToNode(0, px, py, display); 
    339  
    340         // determine if near last node placed 
    341         double ldist = 
    342           getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
    343  
    344         // highlight first or last visible node if near 
    345         if (hdist < THRESH) { 
    346           line.setHighlightNode(line.getNumNodes()-1, CON); 
    347           mode = CLOSE_LOOP; 
    348         } 
    349  
    350         // switch modes if you've dragged far enough from last node placed 
    351         if (ldist > 10.0) { 
    352           mode = EXTEND; 
    353         } 
    354       } 
    355       else if (mode == CLOSE_LOOP) { 
    356         line.setLastNode(dx, dy); 
    357         // determine if near head: 
    358         double dist = getDistanceToNode(0, px, py, display); 
    359  
    360         // if not, turn off highlighting 
    361         if (dist > THRESH) { 
    362           line.turnOffHighlighting(); 
    363           mode = EXTEND; 
    364         } 
    365       } 
    366       else if (mode == SELECT) { 
    367         // get distance btw. pointer and selectedNode 
    368         double dist = getDistanceToNode(selectedNode, px, py, display); 
    369  
    370         double threshold = 2.0; 
    371         if (dist > threshold) { 
    372           line.turnOffHighlighting(); 
    373           unselect(); 
    374           mode = WAIT; 
    375         } 
    376       } 
    377       else if (mode == ADJUST) { 
    378       } 
    379       overlay.notifyListeners(new TransformEvent(overlay)); 
    380     }// end synchronized (line) 
     369    } 
     370    else if (mode == ADJUST) { 
     371    } 
     372    overlay.notifyListeners(new TransformEvent(overlay)); 
    381373  } 
    382374 
Note: See TracChangeset for help on using the changeset viewer.