void Tick::drawTick(int tickstep, Vec wv0, Vec wv1, float ox, float oy, int axis, float sclx, float scly, GLdouble* OModel, GLdouble *OProj, GLint *Oviewport) { int i, nvox, nsteps; float dlen, perpx, perpy; Vec step; float xc0, yc0, xc1, yc1; float *ticx, *ticy; Vec dataMin, dataMax, dataSize; Global::bounds(dataMin, dataMax); dataSize = dataMax - dataMin + Vec(1,1,1); nvox = dataSize[axis]; if (tickstep == 0) { // just get the end points when // we don't want to plot any ticks GLdouble tx,ty,tz; gluProject((GLdouble)wv0.x, (GLdouble)wv0.y, (GLdouble)wv0.z, OModel, OProj, Oviewport, &tx, &ty, &tz); xc0 = tx; yc0 = ty; gluProject((GLdouble)wv1.x, (GLdouble)wv1.y, (GLdouble)wv1.z, OModel, OProj, Oviewport, &tx, &ty, &tz); xc1 = tx; yc1 = ty; perpx = (yc1-yc0); perpy = -(xc1-xc0); dlen = sqrt(perpx*perpx + perpy*perpy); perpx/=dlen; perpy/=dlen; perpx*=200*sclx; perpy*=200*sclx; if (perpx*(xc0-ox) + perpy*(yc0-oy) < 0) { perpx = -perpx; perpy = -perpy; } } else { // get tick marker positions nsteps = nvox/tickstep; if (nvox%tickstep == 0) nsteps += 1; else nsteps += 2; if (nsteps < 2) nsteps = 2; ticx = new float[nsteps]; ticy = new float[nsteps]; step = tickstep*(wv1-wv0)/nvox; for (i=0; i<nsteps; i++) { Vec w; GLdouble tx,ty,tz; w = wv0 + i*step; if (i == nsteps-1) w = wv1; gluProject((GLdouble)w.x, (GLdouble)w.y, (GLdouble)w.z, OModel, OProj, Oviewport, &tx, &ty, &tz); ticx[i] = tx; ticy[i] = ty; } xc0 = ticx[0]; yc0 = ticy[0]; xc1 = ticx[nsteps-1]; yc1 = ticy[nsteps-1]; perpx = (yc1-yc0); perpy = -(xc1-xc0); dlen = sqrt(perpx*perpx + perpy*perpy); perpx/=dlen; perpy/=dlen; perpx*=200*sclx; perpy*=200*sclx; if (perpx*(xc0-ox) + perpy*(yc0-oy) < 0) { perpx = -perpx; perpy = -perpy; } glBegin(GL_LINES); for (i=0; i<nsteps; i++) { float x, y; x = ticx[i]; y = ticy[i]; glVertex2f(x, y); if (i == 0 || i == nsteps-1) glVertex2f(x+1.5*perpx, y+1.5*perpy); else glVertex2f(x+perpx, y+perpy); } if (tickstep < (dataMax[axis]-dataMin[axis])) { glVertex2f(xc0+perpx*2.8, yc0+perpy*2.8); glVertex2f(xc1+perpx*2.8, yc1+perpy*2.8); } glEnd(); delete [] ticx; delete [] ticy; } //--- if (tickstep > 0) -------- float x, y, angle; bool angleFixed = false; // find rotation angle for text x = perpx; y = perpy; dlen = sqrt(x*x+y*y); x/=dlen; y/=dlen; angle = atan2(-x, y); angle *= 180.0/3.1415926535; if (perpy < 0) { angle = 180+angle; angleFixed = true; } QString str; int len; float width; float pshift = 0.2; if (tickstep > 0) pshift = 1.5; if (axis == 0) str = Tick::labelX(); else if (axis == 1) str = Tick::labelY(); else if (axis == 2) str = Tick::labelZ(); if (Tick::drawText(str, xc0, xc1, yc0, yc1, perpx, perpy, angle, angleFixed, pshift, 12)) pshift += 1.9; int flip = 1; if (perpx < 0) flip = -1; if (tickstep > 0) { str = QString("%1").arg(dataMin[axis]); x = xc0; y = yc0; x += perpx*2; y += perpy*2; float fangle = angle; if (angleFixed) fangle = angle-flip*90; else fangle = angle+flip*90; float fscl = 120.0/Global::dpi(); QFont font = QFont(); font.setPointSize(10*fscl); StaticFunctions::renderRotatedText(x, y, str, font, Qt::transparent, Tick::m_textColor, fangle, false); // (0,0) is top left str = QString("%1").arg(dataMax[axis]); x = xc1; y = yc1; x += perpx*2; y += perpy*2; fangle = angle; if (angleFixed) fangle = angle-flip*90; else fangle = angle+flip*90; StaticFunctions::renderRotatedText(x, y, str, font, Qt::transparent, Tick::m_textColor, fangle, false); // (0,0) is top left } VolumeInformation pvlInfo = VolumeInformation::volumeInformation(); if (pvlInfo.voxelUnit > 0) { str = QString("<- %1 %2 ->").\ arg(nvox*pvlInfo.voxelSize[axis], 0, 'f', Global::floatPrecision()). \ arg(pvlInfo.voxelUnitStringShort()); if (Tick::drawText(str, xc0, xc1, yc0, yc1, perpx, perpy, angle, angleFixed, pshift, 11)) pshift += 1.3; } if (tickstep > 0 && tickstep < (dataMax[axis]-dataMin[axis])) { if (pvlInfo.voxelUnit > 0) str = QString("ticks at %1 voxels (%2 %3)"). \ arg(tickstep). \ arg(tickstep*pvlInfo.voxelSize[axis], 0, 'f', Global::floatPrecision()). \ arg(pvlInfo.voxelUnitStringShort()); else str = QString("ticks at %1 voxels").arg(tickstep); Tick::drawText(str, xc0, xc1, yc0, yc1, perpx, perpy, angle, angleFixed, pshift, 10); } }
void VolumeOperations::getVolume(Vec bmin, Vec bmax, int tag) { QProgressDialog progress("Calculating Volume", QString(), 0, 100, 0); progress.setMinimumDuration(0); int ds = bmin.z; int ws = bmin.y; int hs = bmin.x; int de = bmax.z; int we = bmax.y; int he = bmax.x; uchar *lut = Global::lut(); uchar *tagColors = Global::tagColors(); qint64 nvoxels = 0; for(qint64 d=ds; d<=de; d++) { progress.setValue(90*(d-ds)/((de-ds+1))); if (d%10 == 0) qApp->processEvents(); for(qint64 w=ws; w<=we; w++) for(qint64 h=hs; h<=he; h++) { bool clipped = false; for(int i=0; i<m_cPos.count(); i++) { Vec p = Vec(h, w, d) - m_cPos[i]; if (m_cNorm[i]*p > 0) { clipped = true; break; } } if (!clipped) { qint64 idx = d*m_width*m_height + w*m_height + h; int val = m_volData[idx]; if (m_volDataUS) val = m_volDataUS[idx]; uchar mtag = m_maskData[idx]; bool opaque = (lut[4*val+3]*tagColors[4*mtag+3] > 0); if (tag > -1) opaque &= (mtag == tag); if (opaque) nvoxels ++; } } } progress.setValue(100); VolumeInformation pvlInfo; pvlInfo = VolumeInformation::volumeInformation(); Vec voxelSize = pvlInfo.voxelSize; float voxvol = nvoxels*voxelSize.x*voxelSize.y*voxelSize.z; QString mesg; mesg += QString("Visible Voxels : %1\n").arg(nvoxels); mesg += QString("Voxel Size : %1, %2, %3 %4\n").\ arg(voxelSize.x).arg(voxelSize.y).arg(voxelSize.z). arg(pvlInfo.voxelUnitStringShort()); mesg += QString("Volume : %1 %2^3\n"). \ arg(voxvol).\ arg(pvlInfo.voxelUnitStringShort()); QMessageBox::information(0, "", mesg); }
void ScaleBarObject::draw(float pixelGLRatio, int screenWidth, int screenHeight, int viewWidth, int viewHeight, bool grabsMouse) { VolumeInformation pvlInfo = VolumeInformation::volumeInformation(); QString str; bool horizontal = m_type; float slen = voxels(); if (pvlInfo.voxelUnit > 0) { float avg = (pvlInfo.voxelSize[0] + pvlInfo.voxelSize[1] + pvlInfo.voxelSize[2])/3.0f; str = QString("%1 %2"). \ arg(slen, 0, 'f', Global::floatPrecision()). \ arg(pvlInfo.voxelUnitStringShort()); slen /= avg; } else str = QString("%1 voxels").arg(slen); slen = slen/pixelGLRatio; Vec s0 = Vec(m_pos.x()*viewWidth, m_pos.y()*viewHeight, 1); Vec s1 = s0; if (horizontal) { slen *= (float)viewWidth/(float)screenWidth; s0 -= Vec(slen/2, 0, 0); s1 += Vec(slen/2, 0, 0); } else { slen *= (float)viewHeight/(float)screenHeight; s0 -= Vec(0, slen/2, 0); s1 += Vec(0, slen/2, 0); } glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // back to front glColor4f(0, 0, 0, 0.8f); if (grabsMouse) { glColor4f(0.5f, 0, 0, 0.8f); glBegin(GL_QUADS); if (horizontal) { glVertex2f(s0.x-5, s0.y-10); glVertex2f(s1.x+5, s0.y-10); glVertex2f(s1.x+5, s0.y+10); glVertex2f(s0.x-5, s0.y+10); } else { glVertex2f(s0.x-10, s0.y-5); glVertex2f(s0.x-10, s1.y+5); glVertex2f(s0.x+10, s1.y+5); glVertex2f(s0.x+10, s0.y-5); } glEnd(); } glDisable(GL_BLEND); glColor3f(1,1,1); glLineWidth(10); glBegin(GL_LINES); glVertex3fv(s0); glVertex3fv(s1); glEnd(); glColor3f(0.5,0.5,0.5); glLineWidth(2); glBegin(GL_LINES); if (horizontal) { glVertex2f(s0.x+slen/2, s0.y-3); glVertex2f(s0.x+slen/2, s1.y+3); } else { glVertex2f(s1.x-3, (s1.y+s0.y)/2); glVertex2f(s0.x+3, (s1.y+s0.y)/2); } glEnd(); glColor3f(0,0,0); glLineWidth(2); glBegin(GL_LINES); if (horizontal) { glVertex2f(s0.x+1, s0.y); glVertex2f(s1.x-1, s1.y); } else { glVertex2f(s0.x, s0.y+1); glVertex2f(s1.x, s1.y-1); } glEnd(); glLineWidth(1); glColor3f(1,1,1); { Vec w0 = Vec(m_pos.x()*screenWidth, (1-m_pos.y())*screenHeight,1); Vec w1 = w0; if (horizontal) { w0 -= Vec(slen/2, 0, 0); w1 += Vec(slen/2, 0, 0); } else { w0 -= Vec(0, slen/2, 0); w1 += Vec(0, slen/2, 0); } QFont tfont = QFont("Helvetica", 12); tfont.setStyleStrategy(QFont::PreferAntialias); QFontMetrics metric(tfont); int mde = metric.descent(); int fht = metric.height()+2; int fwd = metric.width(str)+2; QImage bImage = QImage(fwd, fht, QImage::Format_ARGB32); bImage.fill(0); QPainter bpainter(&bImage); Vec bgcolor = Global::backgroundColor(); bpainter.setBackgroundMode(Qt::OpaqueMode); bpainter.setBackground(QColor(bgcolor.z*255, bgcolor.y*255, bgcolor.x*255)); float bgintensity = (0.3*bgcolor.x + 0.5*bgcolor.y + 0.2*bgcolor.z); QColor penColor(Qt::white); if (bgintensity > 0.5) penColor = Qt::black; bpainter.setPen(penColor); bpainter.setFont(tfont); bpainter.drawText(1, fht-mde, str); QImage cImage = bImage.mirrored(); if (!horizontal) { QMatrix matrix; matrix.rotate(90); cImage = cImage.transformed(matrix); } int x,y; if (horizontal) { x = (w0.x+w1.x)/2 - cImage.width()/2; y = w0.y-3-cImage.height(); if (!m_textpos) y = w0.y+6; } else { x = w1.x+3; if (!m_textpos) x = w1.x-5-cImage.width(); y = (w0.y+w1.y)/2 - cImage.height()/2; } glWindowPos2i(x,y); const uchar *bits = cImage.bits(); glDrawPixels(cImage.width(), cImage.height(), GL_RGBA, GL_UNSIGNED_BYTE, bits); } }