void checkCrop3D(struct data *d) { int fn3, startd3, cropd3; checkCrop(d); // set 2D parameters fn3=d->fn3; /* Check that either fn3 is active */ /* If so, make sure it is divisible by 4 */ if (!fn3) fn3 = d->nv3*2; else { fn3 /=4; fn3 *=4; } fn3 /= 2; startd3 = d->startd3; cropd3 = d->cropd3; if((startd3 < 0) || (startd3 > fn3-2)){ d->startd3=0; fprintf(stderr,"Warning: setting start of crop 3 to 1\n"); } if(cropd3 < 1) { d->cropd3=fn3; fprintf(stderr,"Warning: setting crop 3 to %d \n",d->cropd3); } if(d->startd3 + d->cropd3 > fn3){ d->cropd3 = fn3-d->startd3; fprintf(stderr,"Warning: setting crop 3 to %d \n",d->cropd3); } }
BufferMapper* OverlayPlaneBase::getTTMMapper(BufferMapper& grallocMapper, struct VideoPayloadBuffer *payload) { buffer_handle_t khandle; uint32_t w, h; uint32_t yStride, uvStride; stride_t stride; int srcX, srcY, srcW, srcH; int tmp; DataBuffer *buf; ssize_t index; TTMBufferMapper *mapper; bool ret; if (!payload) { ETRACE("invalid payload buffer"); return 0; } srcX = grallocMapper.getCrop().x; srcY = grallocMapper.getCrop().y; srcW = grallocMapper.getCrop().w; srcH = grallocMapper.getCrop().h; // init ttm buffer if (mUseScaledBuffer) { khandle = payload->scaling_khandle; } else { khandle = payload->rotated_buffer_handle; } index = mTTMBuffers.indexOfKey(khandle); if (index < 0) { VTRACE("unmapped TTM buffer, will map it"); if (mUseScaledBuffer) { w = payload->scaling_width; h = payload->scaling_height; } else { w = payload->rotated_width; h = payload->rotated_height; checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height); } uint32_t format = grallocMapper.getFormat(); // this is for sw decode with tiled buffer in landscape mode if (payload->tiling) format = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; // calculate stride switch (format) { case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_I420: uint32_t yStride_align; yStride_align = DisplayQuery::getOverlayLumaStrideAlignment(grallocMapper.getFormat()); if (yStride_align > 0) { yStride = align_to(align_to(w, 32), yStride_align); } else { yStride = align_to(align_to(w, 32), 64); } uvStride = align_to(yStride >> 1, 64); stride.yuv.yStride = yStride; stride.yuv.uvStride = uvStride; break; case HAL_PIXEL_FORMAT_NV12: yStride = align_to(align_to(w, 32), 64); uvStride = yStride; stride.yuv.yStride = yStride; stride.yuv.uvStride = uvStride; break; case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar: case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled: if (mUseScaledBuffer) { stride.yuv.yStride = payload->scaling_luma_stride; stride.yuv.uvStride = payload->scaling_chroma_u_stride; } else { yStride = align_to(align_to(w, 32), 64); uvStride = yStride; stride.yuv.yStride = yStride; stride.yuv.uvStride = uvStride; } break; case HAL_PIXEL_FORMAT_YUY2: case HAL_PIXEL_FORMAT_UYVY: yStride = align_to((align_to(w, 32) << 1), 64); uvStride = 0; stride.yuv.yStride = yStride; stride.yuv.uvStride = uvStride; break; } DataBuffer buf(khandle); // update buffer buf.setStride(stride); buf.setWidth(w); buf.setHeight(h); buf.setCrop(srcX, srcY, srcW, srcH); buf.setFormat(format); // create buffer mapper bool res = false; do { mapper = new TTMBufferMapper(*mWsbm, buf); if (!mapper) { ETRACE("failed to allocate mapper"); break; } // map ttm buffer ret = mapper->map(); if (!ret) { ETRACE("failed to map"); invalidateTTMBuffers(); ret = mapper->map(); if (!ret) { ETRACE("failed to remap"); break; } } if (mTTMBuffers.size() >= OVERLAY_DATA_BUFFER_COUNT) { invalidateTTMBuffers(); } // add mapper index = mTTMBuffers.add(khandle, mapper); if (index < 0) { ETRACE("failed to add TTMMapper"); break; } // increase mapper refCount since it is added to mTTMBuffers mapper->incRef(); res = true; } while (0); if (!res) { // error handling if (mapper) { mapper->unmap(); delete mapper; mapper = NULL; } return 0; } } else {
void DistanceMapFilter::applyDistanceMapFilter(QString flnm, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops, QList<PathObject> paths, uchar *lut, int chan) { int bpv = 1; if (m_voxelType > 0) bpv = 2; int nbytes = bpv*m_nY*m_nZ; bool trim = (qRound(m_dataSize.x) < m_height || qRound(m_dataSize.y) < m_width || qRound(m_dataSize.z) < m_depth); bool clipPresent = (clipPos.count() > 0); m_cropPresent = false; m_tearPresent = false; m_blendPresent = false; for(int ci=0; ci<m_crops.count(); ci++) { if (crops[ci].cropType() < CropObject::Tear_Tear) m_cropPresent = true; else if (crops[ci].cropType() < CropObject::View_Tear) m_tearPresent = true; else if (m_crops[ci].cropType() > CropObject::Displace_Displace && m_crops[ci].cropType() < CropObject::Glow_Ball) m_blendPresent = true; } m_pathCropPresent = false; m_pathBlendPresent = false; for (int i=0; i<m_paths.count(); i++) { if (m_paths[i].blend()) m_pathBlendPresent = true; if (m_paths[i].crop()) m_pathCropPresent = true; } m_meshLog->moveCursor(QTextCursor::End); int d0 = 0; int d1 = m_nX-1; int d0z = d0 + qRound(m_dataMin.z); int d1z = d1 + qRound(m_dataMin.z); uchar *opacityVol = new uchar[m_nX*m_nY*m_nZ]; uchar *cropped = new uchar[nbytes]; uchar *tmp = new uchar[nbytes]; int i0 = 0; for(int i=d0z; i<=d1z; i++) { m_meshProgress->setValue((int)(100.0*(float)i0/(float)m_nX)); qApp->processEvents(); int iv = qBound(0, i, m_depth-1); uchar *vslice = m_vfm->getSlice(iv); memset(cropped, 0, nbytes); if (!trim) memcpy(tmp, vslice, nbytes); else { int wmin = qRound(m_dataMin.y); int hmin = qRound(m_dataMin.x); if (m_voxelType == 0) { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) tmp[w*m_nZ + h] = vslice[(wmin+w)*m_height + (hmin+h)]; } else { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) ((ushort*)tmp)[w*m_nZ + h] = ((ushort*)vslice)[(wmin+w)*m_height + (hmin+h)]; } } int jk = 0; for(int j=0; j<m_nY; j++) for(int k=0; k<m_nZ; k++) { Vec po = Vec(m_dataMin.x+k, m_dataMin.y+j, iv); bool ok = true; // we don't want to scale before pruning int mop = 0; { Vec pp = po - m_dataMin; int ppi = pp.x/m_pruneLod; int ppj = pp.y/m_pruneLod; int ppk = pp.z/m_pruneLod; ppi = qBound(0, ppi, m_pruneX-1); ppj = qBound(0, ppj, m_pruneY-1); ppk = qBound(0, ppk, m_pruneZ-1); int mopidx = ppk*m_pruneY*m_pruneX + ppj*m_pruneX + ppi; mop = m_pruneData[3*mopidx + chan]; ok = (mop > 0); } po *= m_samplingLevel; if (ok && clipPresent) ok = StaticFunctions::getClip(po, clipPos, clipNormal); if (ok && m_cropPresent) ok = checkCrop(po); if (ok && m_pathCropPresent) ok = checkPathCrop(po); if (ok && m_blendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkBlend(po, v, lut); } if (ok && m_pathBlendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkPathBlend(po, v, lut); } if (ok) cropped[jk] = mop; else cropped[jk] = 0; jk ++; } if (m_voxelType == 0) { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) tmp[j] = 0; } } else { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) ((ushort*)tmp)[j] = 0; } } applyOpacity(iv, cropped, lut, tmp); memcpy(opacityVol + i0*m_nY*m_nZ, tmp, m_nY*m_nZ); i0++; } delete [] tmp; delete [] cropped; m_meshProgress->setValue(100); qApp->processEvents(); //------------ if (m_tearPresent) { uchar *data0 = new uchar[m_nX*m_nY*m_nZ]; memcpy(data0, opacityVol, m_nX*m_nY*m_nZ); applyTear(d0, d1, 0, data0, opacityVol, false); delete [] data0; } typedef uchar PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > ImageType; ImageType::IndexType start; start.Fill(0); ImageType::SizeType size; size[0] = m_nZ; size[1] = m_nY; size[2] = m_nX; ImageType::RegionType region(start, size); ImageType::Pointer image = ImageType::New(); image->SetRegions(region); image->Allocate(); image->FillBuffer(0); uchar *iptr = (uchar*)image->GetBufferPointer(); memcpy(iptr, opacityVol, m_nX*m_nY*m_nZ); typedef itk::Image< float, 3 > OutputImageType; typedef itk::SignedMaurerDistanceMapImageFilter<ImageType, OutputImageType> DistanceMapFilter; DistanceMapFilter::Pointer filter = DistanceMapFilter::New(); filter->SetInput( image ); filter->SetSquaredDistance(0); filter->SetUseImageSpacing(0); filter->SetInsideIsPositive(1); filter->Update(); QFile fp; fp.setFileName(flnm); fp.open(QFile::WriteOnly); uchar vt = 8; fp.write((char*)&vt, 1); fp.write((char*)&m_nX, 4); fp.write((char*)&m_nY, 4); fp.write((char*)&m_nZ, 4); OutputImageType *dimg = filter->GetOutput(); char *tdata = (char*)(dimg->GetBufferPointer()); fp.write(tdata, 4*m_nX*m_nY*m_nZ); fp.close(); m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText("Signed Distance Map data saved in "+flnm); QMessageBox::information(0, "", QString("Signed Distance Map saved in "+flnm)); }
void MeshGenerator::generateMesh(int nSlabs, QStringList volumeFiles, QString flnm, int depth, QGradientStops vstops, int fillValue, bool checkForMore, bool lookInside, Vec voxelScaling, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops, QList<PathObject> paths, uchar *lut, int chan, bool avgColor) { bool saveIntermediate = false; int bpv = 1; if (m_voxelType > 0) bpv = 2; int nbytes = bpv*m_nY*m_nZ; // if (nSlabs > 1) // { // QStringList sl; // sl << "No"; // sl << "Yes"; // bool ok; // QString okstr = QInputDialog::getItem(0, "Save slab files", // "Save slab files in .ply format.\nFiles will not be collated together to create a unified mesh for the whole sample.", // sl, 0, false, &ok); // if (ok && okstr == "Yes") // saveIntermediate = true; // } QGradientStops lutstops; for(int i=0; i<255; i++) { QColor col(lut[4*i+0], lut[4*i+1], lut[4*i+2], lut[4*i+3]); lutstops << QGradientStop((float)i/(float)255.0f, col); } bool trim = (qRound(m_dataSize.x) < m_height || qRound(m_dataSize.y) < m_width || qRound(m_dataSize.z) < m_depth); bool clipPresent = (clipPos.count() > 0); m_cropPresent = false; m_tearPresent = false; m_blendPresent = false; for(int ci=0; ci<m_crops.count(); ci++) { if (crops[ci].cropType() < CropObject::Tear_Tear) m_cropPresent = true; else if (crops[ci].cropType() < CropObject::View_Tear) m_tearPresent = true; else if (m_crops[ci].cropType() > CropObject::Displace_Displace && m_crops[ci].cropType() < CropObject::Glow_Ball) m_blendPresent = true; } m_pathCropPresent = false; m_pathBlendPresent = false; for (int i=0; i<m_paths.count(); i++) { if (m_paths[i].blend()) m_pathBlendPresent = true; if (m_paths[i].crop()) m_pathCropPresent = true; } int nextra = depth; int blockStep = m_nX/nSlabs; //----------------------------- int nvols = volumeFiles.count(); //----------------------------- for (int volnum=0; volnum < nvols; volnum++) { //if (nvols > 1) { m_vfm->setBaseFilename(volumeFiles[volnum]); uchar *vslice = m_vfm->getSlice(0); } m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(QString("\nProcessing file %1 of %2 : %3\n").\ arg(volnum+1).arg(nvols).arg(m_vfm->fileName())); for (int nb=0; nb<nSlabs; nb++) { m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(QString(" Processing slab %1 of %2\n").arg(nb+1).arg(nSlabs)); int d0 = nb*blockStep; int d1 = qMin(m_nX-1, (nb+1)*blockStep); int dlen = d1-d0+1; int d0z = d0 + qRound(m_dataMin.z); int d1z = d1 + qRound(m_dataMin.z); uchar *extData; if (m_voxelType == 0) extData = new uchar[(dlen+2*nextra)*m_nY*m_nZ]; else extData = new uchar[2*(dlen+2*nextra)*m_nY*m_nZ]; // ushort uchar *cropped = new uchar[nbytes]; uchar *tmp = new uchar[nbytes]; int i0 = 0; for(int i=d0z-nextra; i<=d1z+nextra; i++) { m_meshProgress->setValue((int)(100.0*(float)(i0/(float)(dlen+2*nextra)))); qApp->processEvents(); int iv = qBound(0, i, m_depth-1); uchar *vslice = m_vfm->getSlice(iv); memset(cropped, 0, nbytes); if (!trim) memcpy(tmp, vslice, nbytes); else { int wmin = qRound(m_dataMin.y); int hmin = qRound(m_dataMin.x); if (m_voxelType == 0) { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) tmp[w*m_nZ + h] = vslice[(wmin+w)*m_height + (hmin+h)]; } else { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) ((ushort*)tmp)[w*m_nZ + h] = ((ushort*)vslice)[(wmin+w)*m_height + (hmin+h)]; } } int jk = 0; for(int j=0; j<m_nY; j++) for(int k=0; k<m_nZ; k++) { Vec po = Vec(m_dataMin.x+k, m_dataMin.y+j, iv); bool ok = true; // we don't want to scale before pruning // no mop pruning po *= m_samplingLevel; if (ok && clipPresent) ok = StaticFunctions::getClip(po, clipPos, clipNormal); if (ok && m_cropPresent) ok = checkCrop(po); if (ok && m_pathCropPresent) ok = checkPathCrop(po); if (ok && m_blendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkBlend(po, v, lut); } if (ok && m_pathBlendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkPathBlend(po, v, lut); } if (ok) //cropped[jk] = mop; // nop mop pruning cropped[jk] = 255; else cropped[jk] = 0; jk ++; } if (m_voxelType == 0) { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) tmp[j] = 0; } } else { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) ((ushort*)tmp)[j] = 0; } } // tmp now clipped and contains raw data memcpy(extData + bpv*i0*m_nY*m_nZ, tmp, nbytes); i0++; } delete [] tmp; delete [] cropped; m_meshProgress->setValue(100); qApp->processEvents(); //------------ if (m_tearPresent) { uchar *data0 = new uchar[(dlen+2*nextra)*m_nY*m_nZ]; uchar *data1 = extData; memcpy(data0, data1, (dlen+2*nextra)*m_nY*m_nZ); applyTear(d0, d1, nextra, data0, data1, true); delete [] data0; } //------------ //-------------------------------- // ---- set border voxels to fillValue if (fillValue >= 0) { uchar *v = extData; i0 = 0; for(int i=d0z-nextra; i<=d1z+nextra; i++) { int iv = qBound(0, i, m_depth-1); int i0dx = i0*m_nY*m_nZ; if (iv <= qRound(m_dataMin.z) || iv >= qRound(m_dataMax.z)) { if (m_voxelType == 0) memset(v + i0dx, fillValue, m_nY*m_nZ); else { for(int fi=0; fi<m_nY*m_nZ; fi++) ((ushort*)v)[i0*m_nY*m_nZ + fi] = fillValue; } } else { if (m_voxelType == 0) { for(int j=0; j<m_nY; j++) v[i0dx + j*m_nZ] = fillValue; for(int j=0; j<m_nY; j++) v[i0dx + j*m_nZ + m_nZ-1] = fillValue; for(int k=0; k<m_nZ; k++) v[i0dx + k] = fillValue; for(int k=0; k<m_nZ; k++) v[i0dx + (m_nY-1)*m_nZ + k] = fillValue; } else { for(int j=0; j<m_nY; j++) ((ushort*)v)[i0dx + j*m_nZ] = fillValue; for(int j=0; j<m_nY; j++) ((ushort*)v)[i0dx + j*m_nZ + m_nZ-1] = fillValue; for(int k=0; k<m_nZ; k++) ((ushort*)v)[i0dx + k] = fillValue; for(int k=0; k<m_nZ; k++) ((ushort*)v)[i0dx + (m_nY-1)*m_nZ + k] = fillValue; } } i0++; } } //-------------------------------- m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText(" Generating Color ...\n"); for(int ni=0; ni<m_nverts; ni++) { m_meshProgress->setValue((int)(100.0*(float)ni/(float)m_nverts)); qApp->processEvents(); float v[3]; v[0] = m_vlist[ni]->x/voxelScaling.x/m_scaleModel; v[1] = m_vlist[ni]->y/voxelScaling.y/m_scaleModel; v[2] = m_vlist[ni]->z/voxelScaling.z/m_scaleModel; if (v[2] > d0 && v[2] <= d1) { // QMessageBox::information(0, "", QString("%1 %2 %3\n%4 %5 %6\n%7 %8"). \ // arg(v[0]).arg(v[1]).arg(v[2]). \ // arg(m_vlist[ni]->x).arg(m_vlist[ni]->y).arg(m_vlist[ni]->z). \ // arg(d0).arg(d1)); uchar *volData = extData; QColor col; QVector3D pos, normal; pos = QVector3D(v[0], v[1], v[2]-d0 + nextra); normal = QVector3D(-m_vlist[ni]->nx, -m_vlist[ni]->ny, -m_vlist[ni]->nz); col = getVRLutColor(volData, dlen, depth, nextra, pos, normal, lut, lookInside, QVector3D(v[0], v[1], v[2])); if (col.alphaF() > 0) { float r = col.red()/255.0f; float g = col.green()/255.0f; float b = col.blue()/255.0f; float a = col.alphaF(); // tinge with lutcolor QColor col0 = vstops[255*(float)(volnum+1)/(float)nvols].second; float aa = col0.alphaF(); float tr = col0.red()/255.0f; float tg = col0.green()/255.0f; float tb = col0.blue()/255.0f; r = (1.0-aa)*r + aa*a*tr; g = (1.0-aa)*g + aa*a*tg; b = (1.0-aa)*b + aa*a*tb; vcolor[3*ni+0] = (1-a)*vcolor[3*ni+0] + r; vcolor[3*ni+1] = (1-a)*vcolor[3*ni+1] + g; vcolor[3*ni+2] = (1-a)*vcolor[3*ni+2] + b; } } } m_meshProgress->setValue(100); delete [] extData; } // loop over slabs // if (nvols > 1) // save intermediate files // { // QString plyflnm = flnm; // plyflnm.chop(3); // plyflnm += QString("%1.ply").arg((int)volnum, (int)nvols/10+2, 10, QChar('0')); // // for(int ni=0; ni<m_nverts; ni++) // { // m_vlist[ni]->r = 255*vcolor[3*ni+0]; // m_vlist[ni]->g = 255*vcolor[3*ni+1]; // m_vlist[ni]->b = 255*vcolor[3*ni+2]; // } // savePLY(plyflnm); // } }// loop over files for(int ni=0; ni<m_nverts; ni++) { m_vlist[ni]->r = 255*vcolor[3*ni+0]; m_vlist[ni]->g = 255*vcolor[3*ni+1]; m_vlist[ni]->b = 255*vcolor[3*ni+2]; } savePLY(flnm); m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText("Mesh saved in "+flnm); QMessageBox::information(0, "", QString("Mesh saved in "+flnm)); }