void SoVolumeMetrics::calculateVolumeMetris() { SoXipDataImage* maskData = inputVolume.getValue(); if (!maskData || !maskData->get()) { SoDebugError::postInfo(__FILE__, "input volume data is NULL"); return; } SbXipImage* mask = maskData->get(); SbMatrix matMask = mask->getModelMatrix(); SbXipImageDimensions maskDimension = mask->getDimStored(); //decompose the model matrix SbVec3f colVector, rowVector, norVector, volPosition; colVector[0] = matMask[0][0]; colVector[1] = matMask[0][1]; colVector[2] = matMask[0][2]; rowVector[0] = matMask[1][0]; rowVector[1] = matMask[1][1]; rowVector[2] = matMask[1][2]; norVector[0] = matMask[2][0]; norVector[1] = matMask[2][1]; norVector[2] = matMask[2][2]; volPosition[0] = matMask[3][0]; volPosition[1] = matMask[3][1]; volPosition[2] = matMask[3][2]; float valSpacing[3]; valSpacing[0] = colVector.length() / (float)maskDimension[0]; valSpacing[1] = rowVector.length() / (float)maskDimension[1]; valSpacing[2] = norVector.length() / (float)maskDimension[2]; double volumeFactor = 0.001*valSpacing[0]*valSpacing[1]*valSpacing[2]; unsigned long volume=0, recist=0, who=0; int nSize = maskDimension[0] * maskDimension[1]; unsigned char* pMask = (unsigned char*)mask->refBufferPtr(); for (int k = 0; k < maskDimension[2]; k++) { unsigned char* pSlice = pMask + k * nSize; for (int j = 0; j < nSize; j++) { if (pSlice[j] != 0) volume++; } } _volume = (double)volume * volumeFactor; mask->unrefBufferPtr(); }
void SoXipImageAttributes::evaluate() { SoXipDataImage *imgData = image.getValue(); if (imgData) { SbXipImage *img = imgData->get(); if (img) { SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(img->getModelMatrix())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(img->getBitsStored())); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(img->getDimStored()[0])); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(img->getDimStored()[1])); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(img->getDimStored()[2])); SbMatrix modelMat = img->getModelMatrix(); SbVec3f t, s; SbRotation r, so; modelMat.getTransform(t, r, s, so); modelMat.multVecMatrix(SbVec3f(0.5, 0.5, 0.5), t); // scale MPR model matrix always to max. individual dimension by default float maxScale = s[0] > s[1] ? s[0] : s[1] > s[2] ? s[1] : s[2]; // modelMat.setTransform(t, r, SbVec3f(maxScale, maxScale, maxScale), so); // when using get/setTransform, the rotation is derived from normal vector // but for gantry tilt, we need to compute normal from row and column vector SbVec3f rot[3]; rot[0] = SbVec3f(modelMat[0][0], modelMat[0][1], modelMat[0][2]); rot[1] = SbVec3f(modelMat[1][0], modelMat[1][1], modelMat[1][2]); rot[2] = rot[0].cross(rot[1]); rot[0].normalize(); rot[1].normalize(); rot[2].normalize(); rot[0] *= maxScale; rot[1] *= maxScale; rot[2] *= maxScale; modelMat = SbMatrix( rot[0][0], rot[0][1], rot[0][2], 0, rot[1][0], rot[1][1], rot[1][2], 0, rot[2][0], rot[2][1], rot[2][2], 0, t[0], t[1], t[2], 1); // update engine outputs SbMatrix tmp = SbMatrix::identity(); // flip default viewing direction tmp.setRotate(SbRotation(SbVec3f(1, 0, 0), M_PI)); SbMatrix defOrient = tmp * modelMat; // adjust so plane falls onto original plane defOrient.getTransform(t, r, s, so); SbVec3f object; modelMat = img->getModelMatrix(); modelMat.inverse().multVecMatrix(t, object); object[0] = int(object[0] * img->getDimStored()[0] + 0.5); object[1] = int(object[1] * img->getDimStored()[1] + 0.5); object[2] = int(object[2] * img->getDimStored()[2] + 0.5); object[0] /= img->getDimStored()[0]; object[1] /= img->getDimStored()[1]; object[2] /= img->getDimStored()[2]; modelMat.multVecMatrix(object, t); defOrient.setTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(defOrient)); SbMatrix ortho1, ortho2, ortho3; int which = XipGeomUtils::orthoOrientations(defOrient, ortho1, ortho2, ortho3); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(which)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(ortho1)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(ortho2)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(ortho3)); defOrient.getTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(t)); return; } } SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(0)); SbMatrix rot1, rot2; SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(SbMatrix::identity())); rot1.setRotate(SbRotation(SbVec3f(1, 0, 0), -M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(rot1)); rot2.setRotate(SbRotation(SbVec3f(0, 1, 0), M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(rot2 * rot1)); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(SbVec3f(0.5, 0.5, 0.5))); }
void SoXipComposeVec6::evaluate() { SO_ENGINE_OUTPUT(outVOI, SoMFInt32, setNum(6)); // intersection of plane and volume SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(0, xmin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(1, xmax.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(2, ymin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(3, ymax.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(4, zmin.getValue()) ); SO_ENGINE_OUTPUT(outVOI, SoMFInt32, set1Value(5, zmax.getValue()) ); // Reset outputs SO_ENGINE_OUTPUT( numSlices, SoSFShort, setValue(0) ); SO_ENGINE_OUTPUT( output, SoXipSFDataImage, setValue(0) ); SoXipDataImage* imageData = image.getValue(); if( mImageData != imageData ) { mImageData = image.getValue(); // Reset previous outputs mOutputs.setNum(0); if( mImageData ) { SbXipImage* image = mImageData->get(); if( !image ) return ; // Initialize outputs unsigned int numSlices = image->getDimStored()[2]; mOutputs.setNum( numSlices ); for( unsigned int i = 0; i < numSlices; ++ i ) mOutputs.set1Value( i, 0 ); } } if( imageData ) { SbXipImage* image = mImageData->get(); if( !image ) return ; SbXipImageDimensions dimensions = image->getDimStored(); SbXipImageDimensions sliceDimensions = dimensions; sliceDimensions[2] = 1; int sliceIndex = this->sliceIndex.getValue(); if( sliceIndex < 0 || sliceIndex >= dimensions[2] ) return ; if( mOutputs[sliceIndex] == 0 ) { // Compute the model matrix of the selected frame SbMatrix sliceModelMatrix = image->getModelMatrix(); sliceModelMatrix[2][0] /= dimensions[2]; sliceModelMatrix[2][1] /= dimensions[2]; sliceModelMatrix[2][2] /= dimensions[2]; sliceModelMatrix[3][0] += sliceIndex * sliceModelMatrix[2][0]; sliceModelMatrix[3][1] += sliceIndex * sliceModelMatrix[2][1]; sliceModelMatrix[3][2] += sliceIndex * sliceModelMatrix[2][2]; // Pointer to the selected slice char* imagePtr = (char *) image->refBufferPtr(); unsigned int cellSize; switch( image->getType() ) { case SbXipImage::UNSIGNED_BYTE: cellSize = sizeof(unsigned char); break ; case SbXipImage::BYTE: cellSize = sizeof(char); break ; case SbXipImage::UNSIGNED_SHORT: cellSize = sizeof(unsigned short); break ; case SbXipImage::SHORT: cellSize = sizeof(short); break ; case SbXipImage::UNSIGNED_INT: cellSize = sizeof(unsigned int); break ; case SbXipImage::INT: cellSize = sizeof(int); break ; case SbXipImage::FLOAT: cellSize = sizeof(float); break ; case SbXipImage::DOUBLE: cellSize = sizeof(double); break ; } void* slicePtr = imagePtr + cellSize * image->getComponents() * dimensions[0] * dimensions[1] * sliceIndex; SbXipImage* slice = new SbXipImage( sliceDimensions, image->getType(), image->getBitsStored(), slicePtr, image->getComponents(), image->getComponentType(), image->getComponentLayoutType(), sliceModelMatrix, image->getLineAlignment() ); image->unrefBufferPtr(); SoXipDataImage* output = new SoXipDataImage(); output->ref(); output->set( slice ); output->addRef( imageData ); mOutputs.set1Value( sliceIndex, output ); } SO_ENGINE_OUTPUT( output, SoXipSFDataImage, setValue(mOutputs[sliceIndex]) ); } }
void SoXipCPUMprRender::readyBuffers(SoState *state) { SbXipImageDimensions dim(0, 0, 0); SoXipDataImage *imgData = 0; SbXipImage *image = 0; // Volume imgData = volume.getValue(); dim = SbXipImageDimensions(0,0,0); if (imgData && (image = imgData->get())) { // If data has changed, update MPR if (imgData->getDataId() != mVolDataId) { mVolDataId = imgData->getDataId(); mUpdateFlag |= UPDATE_MPR; } if (mVolDataType != image->getType() || mVolBitsUsed != image->getBitsStored()) { mVolDataType = image->getType(); mVolBitsUsed = image->getBitsStored(); mMPRSize = SbVec2s(-1, -1); // force buffer resizing } mVolBuf = image->refBufferPtr(); dim = imgData->get()->getDimAllocated(); // If dimensions have changed, update Cache if (dim != mVolDim) { mVolDim = dim; mUpdateFlag |= UPDATE_MPRCACHE; } } else { mVolBuf = 0; mVolDim = dim; mVolDataId = 0; } // Transfer function LUT imgData = (SoXipDataImage *) SoXipLutElement::get(state); if (imgData && (image = imgData->get()) && image->getType() == SbXipImage::FLOAT && image->getComponentLayoutType() == SbXipImage::RGBA) { // If there was no LUT before, resize buffers if (!mLutBuf) mMPRSize = SbVec2s(-1, -1); mLutSize = image->getDimStored()[0]; mLutBuf = (float*) image->refBufferPtr(); // If data has changed, update MPR if (imgData->getDataId() != mLutDataId) { mLutDataId = imgData->getDataId(); mUpdateFlag |= UPDATE_MPR; } } else { // If there was a LUT before, force resizing if (mLutBuf) mMPRSize = SbVec2s(-1, -1); mLutBuf = 0; mLutSize = 0; mLutDataId = 0; } }