diff --git a/src/GLSL/fibers.fs b/src/GLSL/fibers.fs index d190cda9..fa45908d 100755 --- a/src/GLSL/fibers.fs +++ b/src/GLSL/fibers.fs @@ -12,6 +12,7 @@ uniform bool isDistcoloring; varying vec4 myColor; + float lookupTex() { vec3 v = VaryingTexCoord0.xyz; diff --git a/src/dataset/Anatomy.cpp b/src/dataset/Anatomy.cpp index 2ffcae0b..69b86eb6 100755 --- a/src/dataset/Anatomy.cpp +++ b/src/dataset/Anatomy.cpp @@ -699,11 +699,11 @@ bool Anatomy::load( nifti_image *pHeader, nifti_image *pBody ) } if( pHeader->sto_xyz.m[1][1] < 0.0 ) { - m_originalSagOrientation = ORIENTATION_ANT_TO_POST; + m_originalSagOrientation = ORIENTATION_POST_TO_ANT; } else { - m_originalSagOrientation = ORIENTATION_POST_TO_ANT; + m_originalSagOrientation = ORIENTATION_ANT_TO_POST; } } else if( pHeader->qform_code > 0 ) @@ -718,16 +718,16 @@ bool Anatomy::load( nifti_image *pHeader, nifti_image *pBody ) } if( pHeader->qto_xyz.m[1][1] < 0.0 ) { - m_originalSagOrientation = ORIENTATION_ANT_TO_POST; + m_originalSagOrientation = ORIENTATION_POST_TO_ANT; } else { - m_originalSagOrientation = ORIENTATION_POST_TO_ANT; + m_originalSagOrientation = ORIENTATION_ANT_TO_POST; } } // Check the data type. - if( pHeader->datatype == 2 ) + if( pHeader->datatype == 2 || (pHeader->datatype == 16 && pHeader->dim[4] == 3)) { if( pHeader->dim[4] == 1 ) { @@ -981,17 +981,27 @@ bool Anatomy::load( nifti_image *pHeader, nifti_image *pBody ) case RGB: { - unsigned char* pData = (unsigned char*)pBody->data; - - m_floatDataset.resize( datasetSize * 3 ); - - for( int i(0); i < datasetSize; ++i ) - { - m_floatDataset[i * 3] = (float)pData[i] / 255.0f; - m_floatDataset[i * 3 + 1] = (float)pData[datasetSize + i] / 255.0f; - m_floatDataset[i * 3 + 2] = (float)pData[(2 * datasetSize) + i] / 255.0f; - } - + m_floatDataset.resize( datasetSize * 3 ); + if(pHeader->datatype == 2) + { + unsigned char* pData = (unsigned char*)pBody->data; + for( int i(0); i < datasetSize; ++i ) + { + m_floatDataset[i * 3] = (float)pData[i] / 255.0f; + m_floatDataset[i * 3 + 1] = (float)pData[datasetSize + i] / 255.0f; + m_floatDataset[i * 3 + 2] = (float)pData[(2 * datasetSize) + i] / 255.0f; + } + } + else + { + float* pData = (float*)pBody->data; + for( int i(0); i < datasetSize; ++i ) + { + m_floatDataset[i * 3] = (float)pData[i]; + m_floatDataset[i * 3 + 1] = (float)pData[datasetSize + i]; + m_floatDataset[i * 3 + 2] = (float)pData[(2 * datasetSize) + i]; + } + } flag = true; break; } @@ -1028,7 +1038,7 @@ bool Anatomy::load( nifti_image *pHeader, nifti_image *pBody ) flipAxisInternal( X_AXIS, false ); DatasetManager::getInstance()->setFlippedXOnLoad(true); } - if( m_originalSagOrientation == ORIENTATION_ANT_TO_POST ) + if( m_originalSagOrientation == ORIENTATION_POST_TO_ANT ) { flipAxisInternal( Y_AXIS, false ); DatasetManager::getInstance()->setFlippedYOnLoad(true); diff --git a/src/dataset/Fibers.cpp b/src/dataset/Fibers.cpp index d7e35e23..b79688e1 100755 --- a/src/dataset/Fibers.cpp +++ b/src/dataset/Fibers.cpp @@ -194,9 +194,23 @@ bool Fibers::load( const wxString &filename ) /* OcTree points classification */ m_pOctree = new Octree( 2, m_pointArray, m_countPoints ); + //Global properties for opacity rendering computeGLobalProperties(); + if(DatasetManager::getInstance()->getFlippedXOnLoad()) + { + flipAxis(X_AXIS); + std::cout << "flipX save\n"; + } + + if(DatasetManager::getInstance()->getFlippedYOnLoad()) + { + flipAxis(Y_AXIS); + std::cout << "flipY save\n"; + } + + return res; } @@ -1964,13 +1978,13 @@ void Fibers::fitToAnat(bool saving) if(DatasetManager::getInstance()->getFlippedXOnLoad()) { flipAxis(X_AXIS); - std::cout << "flipX \n"; + std::cout << "flipX save\n"; } - if(DatasetManager::getInstance()->getFlippedXOnLoad()) + if(DatasetManager::getInstance()->getFlippedYOnLoad()) { flipAxis(Y_AXIS); - std::cout << "flipY \n"; + std::cout << "flipY save\n"; } } @@ -2047,13 +2061,13 @@ void Fibers::fitToAnat(bool saving) if(DatasetManager::getInstance()->getFlippedXOnLoad()) { flipAxis(X_AXIS); - std::cout << "flipX \n"; + std::cout << "flipX not saving\n"; } - if(DatasetManager::getInstance()->getFlippedXOnLoad()) + if(DatasetManager::getInstance()->getFlippedYOnLoad()) { flipAxis(Y_AXIS); - std::cout << "flipY \n"; + std::cout << "flipY not saving\n"; } } @@ -3759,9 +3773,9 @@ void Fibers::setFibersLength() { // The values are in pixel, we need to set them in millimeters using the spacing // specified in the anatomy file ( m_datasetHelper->xVoxel... ). - dx = ( currentFiberPoints[i].x - currentFiberPoints[i - 1].x ) * voxelX; - dy = ( currentFiberPoints[i].y - currentFiberPoints[i - 1].y ) * voxelY; - dz = ( currentFiberPoints[i].z - currentFiberPoints[i - 1].z ) * voxelZ; + dx = ( currentFiberPoints[i].x - currentFiberPoints[i - 1].x ); + dy = ( currentFiberPoints[i].y - currentFiberPoints[i - 1].y ); + dz = ( currentFiberPoints[i].z - currentFiberPoints[i - 1].z ); FArray currentVector( dx, dy, dz ); m_length[j] += ( float )currentVector.norm(); } diff --git a/src/dataset/Fibers.h b/src/dataset/Fibers.h index 2678cc3d..da89b3e9 100755 --- a/src/dataset/Fibers.h +++ b/src/dataset/Fibers.h @@ -111,7 +111,7 @@ class Fibers : public DatasetInfo void setLocalGlobal(bool value); void setUsingEndpts(bool value); - void flipAxis( AxisType i_axe ); + void flipAxis( AxisType i_axe); void fitToAnat( bool saving); int getFibersCount() const { return m_countLines; } diff --git a/src/dataset/FibersGroup.h b/src/dataset/FibersGroup.h index 1bfbf8a0..ea0757f5 100644 --- a/src/dataset/FibersGroup.h +++ b/src/dataset/FibersGroup.h @@ -66,7 +66,7 @@ class FibersGroup : public DatasetInfo bool load( wxString filename ) { return false; }; void draw() {}; void smooth() {}; - void flipAxis( AxisType i_axe ) {}; + void flipAxis( AxisType i_axe) {}; void drawVectors() {}; void generateTexture() {}; void generateGeometry() {}; diff --git a/src/dataset/Maximas.cpp b/src/dataset/Maximas.cpp index 649aece2..dbe1ab66 100644 --- a/src/dataset/Maximas.cpp +++ b/src/dataset/Maximas.cpp @@ -130,11 +130,11 @@ bool Maximas::load( nifti_image *pHeader, nifti_image *pBody ) } if( pHeader->sto_xyz.m[1][1] < 0.0 ) { - m_originalSagOrientation = ORIENTATION_ANT_TO_POST; + m_originalSagOrientation = ORIENTATION_POST_TO_ANT; } else { - m_originalSagOrientation = ORIENTATION_POST_TO_ANT; + m_originalSagOrientation = ORIENTATION_ANT_TO_POST; } } else if( pHeader->qform_code > 0 ) @@ -149,11 +149,11 @@ bool Maximas::load( nifti_image *pHeader, nifti_image *pBody ) } if( pHeader->qto_xyz.m[1][1] < 0.0 ) { - m_originalSagOrientation = ORIENTATION_ANT_TO_POST; + m_originalSagOrientation = ORIENTATION_POST_TO_ANT; } else { - m_originalSagOrientation = ORIENTATION_POST_TO_ANT; + m_originalSagOrientation = ORIENTATION_ANT_TO_POST; } } @@ -163,7 +163,7 @@ bool Maximas::load( nifti_image *pHeader, nifti_image *pBody ) RTTrackingHelper::getInstance()->setMaximaFlip(Vector(-1,1,1)); flipAnat( X_AXIS ); } - if( m_originalSagOrientation == ORIENTATION_ANT_TO_POST ) + if( m_originalSagOrientation == ORIENTATION_POST_TO_ANT) { flipAxis( Y_AXIS, true ); RTTrackingHelper::getInstance()->setMaximaFlip(Vector(1,-1,1)); @@ -264,32 +264,24 @@ bool Maximas::createStructure ( std::vector< float > &i_fileFloatData ) FMatrix transform = FMatrix( DatasetManager::getInstance()->getNiftiTransform() ); FMatrix rotMat( 3, 3 ); - transform.getSubMatrix( rotMat, 0, 0 ); - rotMat(0,0) = 1; - rotMat(1,1) = 1; - rotMat(2,2) = 1; - storedRot = rotMat; - - - /*float voxelX = DatasetManager::getInstance()->getVoxelX(); - float voxelY = DatasetManager::getInstance()->getVoxelY(); - float voxelZ = DatasetManager::getInstance()->getVoxelZ(); - FMatrix transform = FMatrix( DatasetManager::getInstance()->getNiftiTransform() ); - FMatrix rotMat( 3, 3 ); - transform.getSubMatrix( rotMat, 0, 0 ); - rotMat(0,0) = 1; - rotMat(1,1) = 1; - rotMat(2,2) = 1; - FMatrix test( rotMat ); - test = invert(rotMat); - rotMat = test;*/ + transform.getSubMatrix( rotMat, 0, 0 ); + + storedRot = rotMat*(1.0f/abs(rotMat(0,0))); //Divide by identity values for scaling + //std::cout << storedRot( 0, 0 ) << " " << storedRot( 0, 1 ) << " " << storedRot( 0, 2 ) << std::endl; + //std::cout << storedRot( 1, 0 ) << " " << storedRot( 1, 1 ) << " " << storedRot( 1, 2 ) << std::endl; + //std::cout << storedRot( 2, 0 ) << " " << storedRot( 2, 1 ) << " " << storedRot( 2, 2 ) << std::endl; + // //Fetching the directions for( it = i_fileFloatData.begin(), i = 0; it != i_fileFloatData.end(); it += m_bands, ++i ) { - m_mainDirections[i].insert( m_mainDirections[i].end(), it, it + m_bands ); + m_mainDirections[i].insert( m_mainDirections[i].end(), it, it + m_bands ); + } - /*FMatrix p1( 3, 1 ); + for( int i = 0; i < m_mainDirections.size(); i++ ) + { + + FMatrix p1( 3, 1 ); FMatrix p2( 3, 1 ); FMatrix p3( 3, 1 ); p1( 0, 0 ) = m_mainDirections[i][0]; @@ -300,14 +292,13 @@ bool Maximas::createStructure ( std::vector< float > &i_fileFloatData ) p2( 1, 0 ) = m_mainDirections[i][4]; p2( 2, 0 ) = m_mainDirections[i][5]; - p3( 0, 0 ) = m_mainDirections[i][6]; p3( 1, 0 ) = m_mainDirections[i][7]; p3( 2, 0 ) = m_mainDirections[i][8]; - FMatrix rotP1 = rotMat * p1; - FMatrix rotP2 = rotMat * p2; - FMatrix rotP3 = rotMat * p3; + FMatrix rotP1 = invert(storedRot) * p1; + FMatrix rotP2 = invert(storedRot) * p2; + FMatrix rotP3 = invert(storedRot) * p3; m_mainDirections[i][0] = rotP1( 0, 0 ); m_mainDirections[i][1] = rotP1( 1, 0 ); @@ -319,7 +310,7 @@ bool Maximas::createStructure ( std::vector< float > &i_fileFloatData ) m_mainDirections[i][6] = rotP3( 0, 0 ); m_mainDirections[i][7] = rotP3( 1, 0 ); - m_mainDirections[i][8] = rotP3( 2, 0 );*/ + m_mainDirections[i][8] = rotP3( 2, 0 ); } @@ -339,10 +330,13 @@ void Maximas::rotatePeaks() FMatrix rot; if(m_doRotate) - rot = invert(storedRot); - else rot = storedRot; + else + rot = invert(storedRot); + //std::cout << rot( 0, 0 ) << " " << rot( 0, 1 ) << " " << rot( 0, 2 ) << std::endl; + //std::cout << rot( 1, 0 ) << " " << rot( 1, 1 ) << " " << rot( 1, 2 ) << std::endl; + //std::cout << rot( 2, 0 ) << " " << rot( 2, 1 ) << " " << rot( 2, 2 ) << std::endl; for( int i = 0; i < m_mainDirections.size(); i++ ) { @@ -358,7 +352,6 @@ void Maximas::rotatePeaks() p2( 1, 0 ) = m_mainDirections[i][4]; p2( 2, 0 ) = m_mainDirections[i][5]; - p3( 0, 0 ) = m_mainDirections[i][6]; p3( 1, 0 ) = m_mainDirections[i][7]; p3( 2, 0 ) = m_mainDirections[i][8]; @@ -591,7 +584,7 @@ int zoomS = 300; wxBoxSizer *pBoxMain = new wxBoxSizer( wxVERTICAL ); - wxToggleButton *m_pToggleRotPeaks = new wxToggleButton( pParent, wxID_ANY,wxT("Rotate peaks with header"), wxDefaultPosition, wxSize(zoomS*2, -1) ); + wxToggleButton *m_pToggleRotPeaks = new wxToggleButton( pParent, wxID_ANY,wxT("Un-rotate peaks with header"), wxDefaultPosition, wxSize(zoomS*2, -1) ); pParent->Connect( m_pToggleRotPeaks->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(PropertiesWindow::OnToggleRotatePeaks) ); pBoxMain->Add( m_pToggleRotPeaks, 0, wxFIXED_MINSIZE | wxEXPAND, 0 ); diff --git a/src/dataset/Octree.cpp b/src/dataset/Octree.cpp index 1d381915..07c46b6d 100644 --- a/src/dataset/Octree.cpp +++ b/src/dataset/Octree.cpp @@ -37,35 +37,37 @@ Octree::~Octree() ////////////////////////////////////////// void Octree::findBoundingBox() { - m_maxPointX = m_pointArray[0]; - m_maxPointY = m_pointArray[1]; - m_maxPointZ = m_pointArray[2]; + DatasetManager *pDatMan = DatasetManager::getInstance(); - m_minPointX = m_pointArray[0]; - m_minPointY = m_pointArray[1]; - m_minPointZ = m_pointArray[2]; + m_maxPointX = pDatMan->getColumns() * pDatMan->getVoxelX(); + m_maxPointY = pDatMan->getRows() * pDatMan->getVoxelY(); + m_maxPointZ = pDatMan->getFrames() * pDatMan->getVoxelZ(); - //Find the bounding box for the dataSet - for(int i=0; i < m_countPoints; i++) - { - if(m_pointArray[i*3] > m_maxPointX) - m_maxPointX = m_pointArray[i*3]; + m_minPointX = 0.0f; + m_minPointY = 0.0f; + m_minPointZ = 0.0f; - if(m_pointArray[i*3+1] > m_maxPointY) - m_maxPointY = m_pointArray[i*3+1]; + ////Find the bounding box for the dataSet + //for(int i=0; i < m_countPoints; i++) + //{ + // if(m_pointArray[i*3] > m_maxPointX) + // m_maxPointX = m_pointArray[i*3]; - if(m_pointArray[i*3+2] > m_maxPointZ) - m_maxPointZ = m_pointArray[i*3+2]; + // if(m_pointArray[i*3+1] > m_maxPointY) + // m_maxPointY = m_pointArray[i*3+1]; - if(m_pointArray[i*3] < m_minPointX) - m_minPointX = m_pointArray[i*3]; + // if(m_pointArray[i*3+2] > m_maxPointZ) + // m_maxPointZ = m_pointArray[i*3+2]; - if(m_pointArray[i*3+1] < m_minPointY) - m_minPointY = m_pointArray[i*3+1]; + // if(m_pointArray[i*3] < m_minPointX) + // m_minPointX = m_pointArray[i*3]; - if(m_pointArray[i*3+2] < m_minPointZ) - m_minPointZ = m_pointArray[i*3+2]; - } + // if(m_pointArray[i*3+1] < m_minPointY) + // m_minPointY = m_pointArray[i*3+1]; + + // if(m_pointArray[i*3+2] < m_minPointZ) + // m_minPointZ = m_pointArray[i*3+2]; + //} } ////////////////////////////////////////// diff --git a/src/gui/PropertiesWindow.cpp b/src/gui/PropertiesWindow.cpp index e4edbb2c..8a6663d3 100644 --- a/src/gui/PropertiesWindow.cpp +++ b/src/gui/PropertiesWindow.cpp @@ -933,6 +933,18 @@ void PropertiesWindow::OnNormalMeanFiberColoring( wxCommandEvent& event ) } } +void PropertiesWindow::OnMeanMean( wxCommandEvent& event ) +{ + Logger::getInstance()->print( wxT( "Event triggered - PropertiesWindow::OnMeanMean" ), LOGLEVEL_DEBUG ); + + SelectionObject *pSelObj = m_pMainFrame->getCurrentSelectionObject(); + if( pSelObj != NULL ) + { + pSelObj->setMeanMethodMode( MEAN ); + pSelObj->notifyStatsNeedUpdating(); + } +} + /////////////////////////////////////////////////////////////////////////// // This function will be triggered when the user click on the custom coloring radio // button located in the mean fiber coloring option @@ -949,6 +961,18 @@ void PropertiesWindow::OnCustomMeanFiberColoring( wxCommandEvent& event ) } } +void PropertiesWindow::OnMeanCross( wxCommandEvent& event ) +{ + Logger::getInstance()->print( wxT( "Event triggered - PropertiesWindow::OnMeanCross" ), LOGLEVEL_DEBUG ); + + SelectionObject *pSelObj = m_pMainFrame->getCurrentSelectionObject(); + if( pSelObj != NULL ) + { + pSelObj->setMeanMethodMode( CROSS ); + pSelObj->notifyStatsNeedUpdating(); + } +} + /////////////////////////////////////////////////////////////////////////// // This function will be triggered when the user move the slider // button located in the mean fiber coloring option diff --git a/src/gui/PropertiesWindow.h b/src/gui/PropertiesWindow.h index 5db7082c..055e0c9d 100644 --- a/src/gui/PropertiesWindow.h +++ b/src/gui/PropertiesWindow.h @@ -105,6 +105,8 @@ class PropertiesWindow : public wxScrolledWindow void OnNormalMeanFiberColoring ( wxCommandEvent& event ); void OnCustomMeanFiberColoring ( wxCommandEvent& event ); + void OnMeanMean ( wxCommandEvent& event ); + void OnMeanCross ( wxCommandEvent& event ); void OnMeanFiberOpacityChange ( wxCommandEvent& event ); void OnCSThresholdChange ( wxCommandEvent& event ); void OnNoofCSchange ( wxCommandEvent& event ); diff --git a/src/gui/SelectionObject.cpp b/src/gui/SelectionObject.cpp index b9666fc0..44087e1e 100644 --- a/src/gui/SelectionObject.cpp +++ b/src/gui/SelectionObject.cpp @@ -1018,8 +1018,17 @@ void SelectionObject::updateStats() m_stats.m_meanCrossSection, m_stats.m_maxCrossSection, m_stats.m_minCrossSection ); + + if(m_meanFiberMode == MEAN) + { + getMeanFiber(l_fibersPtns, 50, m_meanFiberPoints); + } + else if(m_meanFiberMode == CROSS) + { + getSpline(); + } - getSpline(); + getFiberDispersion ( m_stats.m_dispersion ); updateStatsGrid(); @@ -1032,7 +1041,7 @@ void SelectionObject::getSpline() { FBSpline spline(4, VecMean); std::vector > pts; - spline.samplePoints(pts,100); + spline.samplePoints(pts,50); m_meanFiberPoints.clear(); for(int i =0; i< pts.size(); i++) { @@ -1262,11 +1271,9 @@ bool SelectionObject::getMeanFiber( const vector< vector< Vector > > &i_fibersPo unsigned int i_nbPoints, vector< Vector > &o_meanFiberPoints ) { - o_meanFiberPoints.resize( i_nbPoints ); + o_meanFiberPoints.assign(i_nbPoints, Vector( 0.0, 0.0, 0.0 )); std::vector firstStrmline; firstStrmline.resize(i_nbPoints); - vector > medianStreamPts; - medianStreamPts.resize(i_nbPoints); //For each streamline, resample to nbPoints for( unsigned int i = 0; i < i_fibersPoints.size(); ++i ) @@ -1278,7 +1285,7 @@ bool SelectionObject::getMeanFiber( const vector< vector< Vector > > &i_fibersPo // The -1 is because we dont take into consideration the number of points but // the number of vector between the points. - float l_currentFiberRatio = (float)( i_fibersPoints[i].size() - 1 ) / ( i_nbPoints - 1 ); + float l_currentFiberRatio = (float)( i_fibersPoints[i].size() ) / ( i_nbPoints ); currentStrmResampled[0] += i_fibersPoints[i][0]; currentStrmResampled[i_nbPoints - 1] += i_fibersPoints[i][l_currentFiberNbPoints - 1] ; @@ -1299,51 +1306,47 @@ bool SelectionObject::getMeanFiber( const vector< vector< Vector > > &i_fibersPo if(i==0) //keep first streamline order { o_meanFiberPoints = currentStrmResampled; - firstStrmline = currentStrmResampled; } else { - //Before insterting it in the o_meanfiberPoints, check MDF for flips - float dDirect = 0; - float dFlipped = 0; - for( unsigned int j = 0; j < i_nbPoints; ++j ) - { - dDirect += abs(sqrt((firstStrmline[j].x - currentStrmResampled[j].x)*(firstStrmline[j].x - currentStrmResampled[j].x) - +(firstStrmline[j].y - currentStrmResampled[j].y)*(firstStrmline[j].y - currentStrmResampled[j].y) - +(firstStrmline[j].z - currentStrmResampled[j].z)*(firstStrmline[j].z - currentStrmResampled[j].z))); - - int k = (i_nbPoints-1)-j; - - dFlipped += abs(sqrt((firstStrmline[j].x - currentStrmResampled[k].x)*(firstStrmline[j].x - currentStrmResampled[k].x) - +(firstStrmline[j].y - currentStrmResampled[k].y)*(firstStrmline[j].y - currentStrmResampled[k].y) - +(firstStrmline[j].z - currentStrmResampled[k].z)*(firstStrmline[j].z - currentStrmResampled[k].z))); - - dDirect /= i_nbPoints; - dFlipped /= i_nbPoints; - } - - if(dDirect < dFlipped) + float dDirect = 0.0; + float dFlipped = 0.0; + float dx, dy, dz; + float dxf, dyf, dzf; + + //Average the mean points + vector centroid; + centroid.assign(i_nbPoints, Vector( 0.0, 0.0, 0.0 )); + for( unsigned int it = 0; it < o_meanFiberPoints.size(); ++it ) + centroid[it] = o_meanFiberPoints[it] / i; + + for( unsigned int j=0; j < i_nbPoints; j++ ) { - for( unsigned int j = 0; j < i_nbPoints; ++j ) - { - o_meanFiberPoints[j] += currentStrmResampled[j]; - } + dx = centroid[j].x - currentStrmResampled[j].x; + dy = centroid[j].y - currentStrmResampled[j].y; + dz = centroid[j].z - currentStrmResampled[j].z; + dDirect += sqrt(dx * dx + dy * dy + dz * dz); + + dxf = centroid[j].x - currentStrmResampled[i_nbPoints-1-j].x; + dyf = centroid[j].y - currentStrmResampled[i_nbPoints-1-j].y; + dzf = centroid[j].z - currentStrmResampled[i_nbPoints-1-j].z; + dFlipped += sqrt(dxf * dxf + dyf * dyf + dzf * dzf); } - else + + dDirect /= i_nbPoints; + dFlipped /= i_nbPoints; + int idx; + for( unsigned int j = 0; j < i_nbPoints; ++j ) { - int l = 0; - for( int j = i_nbPoints - 1; j > -1; --j ) - { - o_meanFiberPoints[l] += currentStrmResampled[j]; - l++; - } + idx = (dDirect > dFlipped)? i_nbPoints-1-j : j; + o_meanFiberPoints[idx] += currentStrmResampled[j]; } } } //Average the mean points - for( unsigned int i = 0; i < o_meanFiberPoints.size(); ++i ) - o_meanFiberPoints[i] /= i_fibersPoints.size(); + for( unsigned int i = 0; i < o_meanFiberPoints.size(); ++i ) + o_meanFiberPoints[i] /= i_fibersPoints.size(); return true; } @@ -1498,8 +1501,10 @@ bool SelectionObject::performTractometry( const vector< vector< Vector > > &fibe Anatomy *pCurrentAnatomy( NULL ); std::vector > localMetrics; + std::vector > localDists; m_tractometrics.resize(noOfPts); localMetrics.resize(noOfPts); + localDists.resize(noOfPts); vector< Anatomy* > datasets = DatasetManager::getInstance()->getAnatomies(); if( m_pCBSelectDataSet == NULL && datasets.size() > 0 && m_pRefAnatInfo != NULL) @@ -1558,6 +1563,7 @@ bool SelectionObject::performTractometry( const vector< vector< Vector > > &fibe } } localMetrics[assignTo].push_back(value); + localDists[assignTo].push_back(dist); ++pointsCount; } @@ -1582,13 +1588,35 @@ bool SelectionObject::performTractometry( const vector< vector< Vector > > &fibe break; } } + vector distMins; + vector distMaxs; + //find min max dist for each point along the core to minmax norm their values when assigned + for(int l=0; l::infinity(); + float max = 0; + for(int m=0; m max) + { + max = v; + } + } + distMins.push_back(min); + distMaxs.push_back(max); + } for(int l=0; l &selectedFibersI dFlipped += abs(sqrt((firstStrmline[j].x - currentStrmResampled[k].x)*(firstStrmline[j].x - currentStrmResampled[k].x) +(firstStrmline[j].y - currentStrmResampled[k].y)*(firstStrmline[j].y - currentStrmResampled[k].y) +(firstStrmline[j].z - currentStrmResampled[k].z)*(firstStrmline[j].z - currentStrmResampled[k].z))); - - dDirect /= m_noOfMeanFiberPts; - dFlipped /= m_noOfMeanFiberPts; } + dDirect /= m_noOfMeanFiberPts; + dFlipped /= m_noOfMeanFiberPts; + if(dDirect < dFlipped) { for(int j = 0; j < m_noOfMeanFiberPts; ++j ) @@ -1917,7 +1949,7 @@ bool SelectionObject::getMeanMaxMinFiberCrossSection( const vector< vector< Vect /* if(i != 0 && i != m_crossSectionsPoints.size()-1) {*/ - m_meanFiberPoints[i] = mean; + //m_meanFiberPoints[i] = mean; vector v; v.push_back(mean.x); v.push_back(mean.y); @@ -2544,6 +2576,9 @@ void SelectionObject::setShowMeanFiberOption( bool i_val ) m_pLblColoring->Show( i_val ); m_pRadCustomColoring->Show( i_val ); m_pRadNormalColoring->Show( i_val ); + m_pLblMethod->Show( i_val ); + m_pRadMeanMean->Show( i_val ); + m_pRadMeanCross->Show( i_val ); m_pLblMeanFiberOpacity->Show( i_val ); m_pSliderMeanFiberOpacity->Show( i_val ); m_pSliderCSthreshold->Show( i_val ); @@ -2588,6 +2623,7 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) m_CSThreshold = 20; m_convexHullOpacity = 0.35f; m_meanFiberColorationMode = NORMAL_COLOR; + m_meanFiberMode = MEAN; ////////////////////////////////////////////////////////////////////////// #if _USE_ZOOM_GUI @@ -2622,12 +2658,14 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) m_pLblRefAnat = new wxStaticText( pParent, wxID_ANY, wxT( "Ref. Anat:" ) ); m_pBtnRefAnat = new wxButton( pParent, wxID_ANY, wxT( "Choose Anat" ) ); + m_pToggleDisplayMeanFiber = new wxToggleButton( pParent, wxID_ANY, wxT( "Display Mean Fiber" ) ); m_pToggleShowStartingPoint = new wxToggleButton( pParent, wxID_ANY, wxT( "Show starting point" ) ); m_pToggleFlipStartingPoint = new wxToggleButton( pParent, wxID_ANY, wxT( "Flip" ), DEF_POS, wxSize( 20, -1 ) ); m_pSaveTractometry = new wxButton( pParent, wxID_ANY, wxT( "Export values" ) ); m_pToggleDisplayConvexHull = new wxToggleButton( pParent, wxID_ANY, wxT( "Display convex hull" ) ); m_pLblColoring = new wxStaticText( pParent, wxID_ANY, wxT( "Coloring" ) ); + m_pLblMethod = new wxStaticText( pParent, wxID_ANY, wxT( "Method" ) ); m_pLblMeanFiberOpacity = new wxStaticText( pParent, wxID_ANY, wxT( "Opacity" ) ); m_pLblCrossSectionThreshold = new wxStaticText( pParent, wxID_ANY, wxT( "C.S. threshold" ) ); m_pLblNoOfCS = new wxStaticText( pParent, wxID_ANY, wxT( "No. of planes" ) ); @@ -2635,6 +2673,9 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) m_pLblConvexHullOpacity = new wxStaticText( pParent, wxID_ANY, wxT( "Opacity" ) ); m_pRadCustomColoring = new wxRadioButton( pParent, wxID_ANY, _T( "Custom" ), DEF_POS, DEF_SIZE, wxRB_GROUP ); m_pRadNormalColoring = new wxRadioButton( pParent, wxID_ANY, _T( "Normal" ) ); + m_pRadMeanMean = new wxRadioButton( pParent, wxID_ANY, _T( "Mean" ), DEF_POS, DEF_SIZE, wxRB_GROUP ); + m_pRadMeanCross = new wxRadioButton( pParent, wxID_ANY, _T( "Cross-sections" ) ); + //m_pRadMeanCross->SetValue(true); m_pSliderMeanFiberOpacity = new wxSlider( pParent, wxID_ANY, 35, 0, 100, DEF_POS, wxSize( 40, -1 ), wxSL_HORIZONTAL | wxSL_AUTOTICKS ); m_pSliderCSthreshold = new wxSlider( pParent, wxID_ANY, 20, 1, 100, DEF_POS, wxSize( 40, -1 ), wxSL_HORIZONTAL | wxSL_AUTOTICKS ); m_pSliderNoOfCS = new wxSlider( pParent, wxID_ANY, 20, 10, 30, DEF_POS, wxSize( 60, -1 ), wxSL_HORIZONTAL | wxSL_AUTOTICKS ); @@ -2687,10 +2728,12 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) pBoxMain->Add( m_pToggleCalculatesFibersInfo, 0, wxEXPAND | wxLEFT | wxRIGHT, 24 ); + #ifdef __WXMSW__ wxBoxSizer *pBoxSizerRef = new wxBoxSizer( wxHORIZONTAL ); pBoxSizerRef->Add( m_pLblRefAnat, 0, wxEXPAND, 0 ); pBoxSizerRef->Add( m_pBtnRefAnat, 1, wxEXPAND, 0 ); pBoxMain->Add( pBoxSizerRef, 0, wxEXPAND | wxALL, 1 ); + #endif pBoxMain->AddSpacer( 2 ); @@ -2766,6 +2809,16 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) pBoxMain->Add( pBoxColoring, 0, wxFIXED_MINSIZE | wxEXPAND | wxTOP | wxBOTTOM, 8 ); + wxBoxSizer *pBoxMethod = new wxBoxSizer( wxVERTICAL ); + pBoxMethod->Add( m_pLblMethod, 0, wxALIGN_LEFT | wxALL, 1 ); + + wxBoxSizer *pBoxMethodRadios = new wxBoxSizer( wxVERTICAL ); + pBoxMethodRadios->Add( m_pRadMeanMean, 0, wxALIGN_LEFT | wxALL, 1 ); + pBoxMethodRadios->Add( m_pRadMeanCross, 0, wxALIGN_LEFT | wxALL, 1 ); + pBoxMethod->Add( pBoxMethodRadios, 0, wxALIGN_LEFT | wxLEFT, 32 ); + + pBoxMain->Add( pBoxMethod, 0, wxFIXED_MINSIZE | wxEXPAND | wxTOP | wxBOTTOM, 8 ); + ////////////////////////////////////////////////////////////////////////// wxBoxSizer *pBoxSizer3 = new wxBoxSizer( wxHORIZONTAL ); @@ -2874,13 +2927,17 @@ void SelectionObject::createPropertiesSizer( PropertiesWindow *pParent ) pParent->Connect( pToggleAndNot->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnToggleAndNot ) ); pParent->Connect( m_pTogglePruneRemove->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnTogglePruneRemove ) ); pParent->Connect( m_pToggleCalculatesFibersInfo->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnDisplayFibersInfo ) ); + #ifdef __WXMSW__ pParent->Connect( m_pBtnRefAnat->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnSelectRefAnat ) ); + #endif pParent->Connect( m_pToggleDisplayMeanFiber->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnDisplayMeanFiber ) ); pParent->Connect( m_pToggleShowStartingPoint->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnShowStartingPoint ) ); pParent->Connect( m_pToggleFlipStartingPoint->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnFlipStartingPoint ) ); pParent->Connect( m_pToggleDisplayConvexHull->GetId(), wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( PropertiesWindow::OnDisplayConvexHull ) ); pParent->Connect( m_pRadCustomColoring->GetId(), wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PropertiesWindow::OnCustomMeanFiberColoring ) ); pParent->Connect( m_pRadNormalColoring->GetId(), wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PropertiesWindow::OnNormalMeanFiberColoring ) ); + pParent->Connect( m_pRadMeanMean->GetId(), wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PropertiesWindow::OnMeanMean ) ); + pParent->Connect( m_pRadMeanCross->GetId(), wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PropertiesWindow::OnMeanCross ) ); pParent->Connect( m_pSliderMeanFiberOpacity->GetId(), wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler( PropertiesWindow::OnMeanFiberOpacityChange ) ); pParent->Connect( m_pSliderCSthreshold->GetId(), wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler( PropertiesWindow::OnCSThresholdChange ) ); pParent->Connect( m_pSliderNoOfCS->GetId(), wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler( PropertiesWindow::OnNoofCSchange ) ); diff --git a/src/gui/SelectionObject.h b/src/gui/SelectionObject.h index 214fa31a..f30d032a 100644 --- a/src/gui/SelectionObject.h +++ b/src/gui/SelectionObject.h @@ -178,6 +178,9 @@ public : void setMeanFiberColorMode( FibersColorationMode i_mode ) { m_meanFiberColorationMode = i_mode; }; FibersColorationMode getMeanFiberColorMode() { return m_meanFiberColorationMode; }; + + void setMeanMethodMode( MeanMethods i_mode ) { m_meanFiberMode = i_mode; }; + MeanMethods getMeanMethodMode() { return m_meanFiberMode; }; // Methods related to the different fiber bundles selection. typedef DatasetIndex FiberIdType; @@ -262,6 +265,7 @@ protected : float m_meanFiberOpacity; //Between 0 and 1 float m_CSThreshold; FibersColorationMode m_meanFiberColorationMode; + MeanMethods m_meanFiberMode; // Those variables represent the min/max value in pixel of the object. float m_minX; @@ -409,6 +413,9 @@ protected : wxStaticText *m_pLblColoring; wxRadioButton *m_pRadCustomColoring; wxRadioButton *m_pRadNormalColoring; + wxStaticText *m_pLblMethod; + wxRadioButton *m_pRadMeanMean; + wxRadioButton *m_pRadMeanCross; wxStaticText *m_pLblMeanFiberOpacity; wxStaticText *m_pLblCrossSectionThreshold; wxStaticText *m_pLblNoOfCS; diff --git a/src/gui/ToolBar.cpp b/src/gui/ToolBar.cpp index db64843d..de033c81 100644 --- a/src/gui/ToolBar.cpp +++ b/src/gui/ToolBar.cpp @@ -221,7 +221,7 @@ wxImage bmpOpen(MyApp::iconsPath+ wxT("fileopen.png" ), wxBITMAP_TYPE_PNG); m_txtRuler->SetFont(font); m_pToolBar->AddControl(m_txtRuler); - m_txtProtractor = new wxTextCtrl(m_pToolBar, wxID_ANY,wxT("0­"), wxDefaultPosition, wxSize( 160, 24 ), wxTE_LEFT | wxTE_READONLY); + m_txtProtractor = new wxTextCtrl(m_pToolBar, wxID_ANY,wxT("0 deg"), wxDefaultPosition, wxSize( 160, 24 ), wxTE_LEFT | wxTE_READONLY); m_txtProtractor->SetForegroundColour(wxColour(wxT("#222222"))); m_txtProtractor->SetBackgroundColour(*wxWHITE); wxFont font2 = m_txtProtractor->GetFont(); diff --git a/src/misc/Algorithms/Helper.h b/src/misc/Algorithms/Helper.h index 6f3eef32..f7e2886a 100644 --- a/src/misc/Algorithms/Helper.h +++ b/src/misc/Algorithms/Helper.h @@ -139,6 +139,12 @@ enum FibersColorationMode CONSTANT_COLOR = 6 }; +enum MeanMethods +{ + MEAN = 0, + CROSS = 1, +}; + /////////////////////////////////////////////////////////////////////////// // Enum representing the different type of display associated to the cross sections. ///////////////////////////////////////////////////////////////////////////