示例#1
0
// Changes the size of the current point given the zoom and scroll wheel delta value
void utilWheelChangePointSize(ImodView *vi, float zoom, int delta)
{
  int ix, iy, pt;
  Iobj *obj;
  Icont *cont;
  float size;
  imodGetIndex(vi->imod, &ix, &iy, &pt);
  obj = imodObjectGet(vi->imod);
  cont = imodContourGet(vi->imod);
  if (!cont || pt < 0)
    return;
  size = imodPointGetSize(obj, cont, pt);
  if (!size && (!cont->sizes || (cont->sizes && cont->sizes[pt] < 0)))
    return;
  size += delta * utilWheelToPointSizeScaling(zoom);
  size = B3DMAX(0., size);
  vi->undo->contourDataChg();
  imodPointSetSize(cont, pt, size);
  vi->undo->finishUnit();
  imodDraw(vi, IMOD_DRAW_MOD);
}
示例#2
0
/*
 * Analyze spherical points in the given object and convert them to vectors and
 * normals for faster drawing
 */
int VertBufManager::analyzeSpheres(Iobj *obj, int obNum, float zscale, int xybin,
                                   float scrnScale, int quality, int fillType,
                                   int useFillColor, int thickenCont, int checkTime)
{
  RGBTmap colors;
  pair<RGBTmap::iterator,bool> mapret;
  RGBTmap::iterator mapit;
  RGBTindices rInd;
  DrawProps defProps, contProps;
  b3dUInt32 contRGBT;
  VertBufData *vbd = obj->vertBufSphere;
  Icont *cont;
  int handleFlags, nonVboFlags = 0, numRemnant, fullState, skip, numVerts, co, pt;
  int colorType, cumFanInd, cumQuadInd, surfState, contState, stepRes;
  float drawsize;
  int numDefSphVert, numDefSphQuad, numDefSphFan, numTriples,indVert, indQuad, indFan;
  int indQuadDef, indFanDef, irem, match;

  if (fillType > 0)
    handleFlags = (useFillColor ? CHANGED_FCOLOR : CHANGED_COLOR) | CHANGED_TRANS;
  else {
    handleFlags = CHANGED_COLOR | CHANGED_TRANS;
    nonVboFlags = CHANGED_3DWIDTH;
  }
  colorType = useFillColor ? GEN_STORE_FCOLOR : GEN_STORE_COLOR;

  istoreDefaultDrawProps(obj, &defProps);

  // Check if there is a current VBO and it is all still valid 
  // TODO: handle finegrain AND size changes
  //packRGBT(defProps, useFillColor, contRGBT);
  if (vbd && vbd->vbObj && fillType == vbd->fillType && vbd->useFillColor == useFillColor
      && quality == vbd->quality && obj->pdrawsize == vbd->pdrawsize &&
      checkTime == vbd->checkTime && fabs((double)(scrnScale - vbd->scrnScale)) < 1.e-4 &&
      fabs((double)(zscale - vbd->zscale)) < 1.e-4 && 
      (fillType != 0 || thickenCont == vbd->thickenCont)) {
    match = 1;
    if (fillType == 0 && thickenCont)
      match = checkSelectedAreRemnants(vbd, obNum);
    if (match && !Imodv->standalone && obNum == Imodv->imod->cindex.object && 
        vbd->checksum != imodObjectChecksum(obj, obNum))
      match = 0;
    if (match)
      return -1;
  }

  numRemnant = 0;
  cumQuadInd = 0;
  cumFanInd = 0;
  numVerts = 0;
  for (co = 0; co < obj->contsize; co++) {
    cont = &obj->cont[co];
    setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0);
    if (!imodvCheckContourDraw(cont, co, checkTime))
      continue;
    fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, 
                                          cont->surf, &contState, &surfState);

    // Skip a gap without counting it; count one to be excluded or that can't be handled
    if (contProps.gap)
      continue;
    skip = 0;
    if ((fullState & nonVboFlags) || (thickenCont && imodvCheckThickerContour(co)))
      skip = 1;

    // Check for point changes that would need to be handled
    if (!skip && cont->store) {
      if (istoreCountItems(cont->store, colorType, 1) || 
          istoreCountItems(cont->store, GEN_STORE_TRANS, 1))
        skip = 1;
      if (!skip && fillType <= 0 && istoreCountItems(cont->store, GEN_STORE_3DWIDTH, 1))
        skip = 1;
    }
    if (skip) {
      setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 1);
      numRemnant++;
      continue;
    }

    // Loop on the points and determine number of vertices and indices needed for each
    // Since we don't skip point drawing, this doesn't need store changes checked
    rInd.numInds = 0;
    rInd.numFanInds = 0;
    for (pt = 0; pt < cont->psize; pt++) {

      // Only draw zero-size points with scattered point objects
      drawsize = imodPointGetSize(obj, cont, pt) / xybin;
      if (!iobjScat(obj->flags) && !drawsize)
        continue;
      stepRes = sphereResForSize(drawsize);
      numVerts += sphereCounts(2 * stepRes, stepRes, fillType, rInd.numInds,
                               rInd.numFanInds);

      // For a special contour, add to list of RGBT values with the counts if it
      // is not on the list; if it is already on the list increment its count;
      if (fullState & handleFlags) {
        rInd.firstElement = co;
        packRGBT(&contProps, useFillColor, contRGBT);
        mapret = colors.insert(pair<b3dUInt32,RGBTindices>(contRGBT, rInd));
        if (mapret.second == false) {
          mapret.first->second.numInds += rInd.numInds;
          mapret.first->second.numFanInds += rInd.numFanInds;
        }
      } else {
        cumQuadInd += rInd.numInds;
        cumFanInd += rInd.numFanInds;
      }
    }
  }      

  if (!numVerts) {
    vbCleanupSphereVBD(obj);
    return 2;
  }

  // Get parameters for default sphere
  drawsize = obj->pdrawsize / xybin;
  stepRes = sphereResForSize(drawsize);
  numDefSphVert = sphereCounts(2 * stepRes, stepRes, fillType, numDefSphQuad, 
                               numDefSphFan);
  imodTrace('b', "numverts %d cumfan %d cumquad %d def vert %d quad %d fan %d rem %d",
            numVerts, cumFanInd, cumQuadInd, numDefSphVert,numDefSphQuad, numDefSphFan,
            numRemnant);

  vbd = allocateVBDIfNeeded(&obj->vertBufSphere); 
  if (!vbd || drawsize < 0) {
    vbCleanupSphereVBD(obj);
    return 1;
  }
  vbd->numFanIndDefault = cumFanInd;
  vbd->numRemnant = numRemnant;

  // Now allocate whatever pieces are needed in VBD
  // Add up the special set sizes and re-initialize the counts to be starting indexes
  if (allocateSpecialSets(vbd, colors.size(), cumQuadInd, 1) ||
      processMap(vbd, &colors, cumQuadInd, 1, cumFanInd)) {
    vbCleanupSphereVBD(obj);
    return 1;
  }
  vbd->fanIndStart = cumQuadInd;

  // Now allocate temps plus default sphere
  numTriples = (1 + (fillType > 0 ? 1 : 0)) * numVerts;
  if (allocateTempVerts(numTriples) || allocateTempInds(cumFanInd) ||
      allocateDefaultSphere(numDefSphVert, numDefSphQuad + numDefSphFan, fillType)) {
    vbCleanupSphereVBD(obj);
    return 1;
  }
    
  if (genAndBindBuffers(vbd, numTriples, cumFanInd)) {
    vbCleanupSphereVBD(obj);
    return 1;
  }

  // Build the default sphere
  indVert = 0;
  indQuad = 0;
  indFan = numDefSphQuad;
  makeSphere(drawsize, 2 * stepRes, stepRes, mDefSphVerts, mDefSphInds, indVert, indQuad, 
           indFan, fillType, 0., 0., 0.);
  imodTrace('b', "numtriples %d cumquad %d cumfan %d after def vert %d quad %d fan %d", 
            numTriples, cumQuadInd, cumFanInd, indVert, indQuad,
            indFan);
  /*for (pt = 0; pt < indFan; pt++) {
    imodPrintStderr(" %d", mDefSphInds[pt]);
    if ((pt + 1) % 16 == 0 || pt == indFan - 1) imodPrintStderr("\n");
    } */

  // Set the identifiers of this vb data
  vbd->zscale = zscale;
  vbd->fillType = fillType;
  vbd->useFillColor = useFillColor;
  packRGBT(&defProps, useFillColor, vbd->defaultRGBT);
  vbd->checkTime = checkTime;
  vbd->scrnScale = scrnScale;
  vbd->quality = quality;
  vbd->pdrawsize = obj->pdrawsize;
  vbd->thickenCont = thickenCont;
  vbd->checksum = imodObjectChecksum(obj, obNum);

  // Process contours and points in them
  indVert = 0;
  indQuadDef = 0;
  indFanDef = cumQuadInd;
  irem = 0;
  for (co = 0; co < obj->contsize; co++) {
    cont = &obj->cont[co];
    if (!imodvCheckContourDraw(cont, co, checkTime))
      continue;
    fullState = istoreContSurfDrawProps(obj->store, &defProps, &contProps, co, 
                                        cont->surf, &contState, &surfState);
    if (contProps.gap)
      continue;

    // Add marked contours to the remnant list
    if (cont->flags & ICONT_TEMPUSE) {
      setOrClearFlags(&cont->flags, ICONT_TEMPUSE, 0);
      vbd->remnantIndList[irem++] = co;
      continue;
    }

    // Set the starting indices for the contour's quads and fans
    if (fullState & handleFlags) {
      packRGBT(&contProps, useFillColor, contRGBT);
      mapit = colors.find(contRGBT);
      indQuad = mapit->second.numInds;
      indFan = mapit->second.numFanInds;
    } else {
      indQuad = indQuadDef;
      indFan = indFanDef;
    }

    // Loop on the points and make sohere or copy the default
    for (pt = 0; pt < cont->psize; pt++) {

      drawsize = imodPointGetSize(obj, cont, pt);
      if (!iobjScat(obj->flags) && !drawsize)
        continue;
      if (drawsize == obj->pdrawsize) {
        copyDefaultSphere(mDefSphVerts, mDefSphInds, numDefSphVert, numDefSphQuad,
                          numDefSphFan, fillType, mVerts, mInds, indVert, indQuad,
                          indFan,  cont->pts[pt].x, cont->pts[pt].y, 
                          cont->pts[pt].z * zscale);
      } else {
        drawsize /= xybin;
        stepRes = sphereResForSize(drawsize);
        makeSphere(drawsize, 2 * stepRes, stepRes, mVerts, mInds, indVert, indQuad,
                 indFan, fillType, cont->pts[pt].x, cont->pts[pt].y, 
                 cont->pts[pt].z * zscale);
      }
    }

    // Save the new indices back where they came from
    if (fullState & handleFlags) {
      mapit->second.numInds = indQuad;
      mapit->second.numFanInds = indFan;
    } else {
      indQuadDef = indQuad;
      indFanDef = indFan;
    }
  }

  imodTrace('b', "cumfan %d after load vert %d quad %d fan %d  irem %d", 
            cumFanInd, indVert, indQuad, indFan, irem);
  /* for (pt = 0; pt < cumFanInd; pt++) {
    imodPrintStderr(" %d", mInds[pt]);
    if ((pt + 1) % 16 == 0 || pt == cumFanInd - 1) imodPrintStderr("\n");
    } */

  // Transfer to GL
  b3dBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, cumFanInd * sizeof(GLuint), mInds);
  b3dBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  b3dBufferSubData(GL_ARRAY_BUFFER, 0, numTriples * 3 * sizeof(GLfloat), mVerts);
  b3dBindBuffer(GL_ARRAY_BUFFER, 0);

  return 0;
}
示例#3
0
/* DNM 6/17/01: pass the selection size as a parameter so that windows can
   make it zoom-dependent */
float imod_obj_nearest(ImodView *vi, Iobj *obj, Iindex *index, Ipoint *pnt,
                       float selsize, int ctime, Imat *mat)
{
    
  Icont *cont;
  int i, pindex;
  float distance = -1.;
  float temp_distance;
  int cz = (int)floor(pnt->z + 0.5);
  int twod = 0;
  double rad, delz;
  Ipoint scale, pntrot, ptsrot;
    
  /* Ignore Z value if 2d image. */
  twod = (!(vi->dim & 4));
    
  scale.x = scale.y = 1.;
  scale.z = ((vi->imod->zscale > 0. ? vi->imod->zscale : 1.) * vi->zbin) /
    vi->xybin;

  if (mat)
    imodMatTransform3D(mat, pnt, &pntrot);

  for (i = 0; i < obj->contsize; i++){
        
    cont = &(obj->cont[i]);

  /* Don't report points not in our time. DNM - unless time is 0*/
    if ((ctime) && (obj->flags & IMOD_OBJFLAG_TIME) && (cont->time) &&
        (cont->time != ctime))
      continue;
    if (!cont->psize)
      continue;
        
    if (mat) {
      
      // If a matrix is supplied, rotate each point and test with rotated pnt
      for (pindex = 0; pindex < cont->psize; pindex++) {
        imodMatTransform3D(mat, &cont->pts[pindex], &ptsrot);
        if ((fabs((double)(pntrot.x - ptsrot.x)) < selsize) &&
            (fabs((double)(pntrot.y - ptsrot.y)) < selsize)) {
          delz = 0.5;

          // get radius of point and maximum Z difference that will work
          // Assume points are visible on too many sections in slicer
          if (obj->pdrawsize || cont->sizes) {
            rad = imodPointGetSize(obj, cont, pindex);
            if (rad > 1.)
              delz = sqrt(rad * rad - 1.);
          }
          if (fabs((double)(ptsrot.z - pntrot.z)) <= delz) {

            temp_distance = imodPoint3DScaleDistance(&pntrot, &ptsrot, &scale);
                        
            if (distance < 0. || distance > temp_distance){
              distance = temp_distance;
              index->contour = i;
              index->point   = pindex;
            }
          }
        }
      }

    } else if ((obj->pdrawsize || cont->sizes) && !twod) {

      // If there could be 3D points, then allow attachment to any point
      // that should be visible on the plane
      for(pindex = 0; pindex < cont->psize; pindex++){
        
        if ((fabs((double)(pnt->x - cont->pts[pindex].x)) < selsize) &&
            (fabs((double)(pnt->y - cont->pts[pindex].y)) < selsize)) {
            
          // get radius of point and maximum Z difference that will work
          rad = imodPointGetSize(obj, cont, pindex) / vi->xybin;
          delz = 0.5;
          if (rad > 1.)
            delz = sqrt(rad * rad - 1.) / scale.z;

          if (fabs((double)(cont->pts[pindex].z - cz)) <= delz) {

            temp_distance = imodPoint3DScaleDistance(&(cont->pts[pindex]),
                                                     pnt, &scale);
                        
            if (distance < 0. || distance > temp_distance){
              distance = temp_distance;
              index->contour = i;
              index->point   = pindex;
            }
          }
        }
      }    

    } else {

      // Skip contour if not wild and Z does not match
      if (!twod && !(cont->flags & ICONT_WILD) && 
          ( cz != (int)floor(cont->pts->z + 0.5)))
        continue;

      for(pindex = 0; pindex < cont->psize; pindex++){
        
        if ((twod || cz == (int)floor(cont->pts[pindex].z + 0.5)) &&
            (fabs((double)(pnt->x - cont->pts[pindex].x)) < selsize) &&
            (fabs((double)(pnt->y - cont->pts[pindex].y)) < selsize)) {
            
          temp_distance = imod_distance( &(cont->pts[pindex].x),
                                         &(cont->pts[pindex].y),
                                         pnt);
          if (distance < 0. || distance > temp_distance){
            distance = temp_distance;
            index->contour = i;
            index->point   = pindex;
          }
        }
      }
    }
  }
  return(distance);
}