/* Copyright (C) 2012 University of Oxford */ /* Part of FSL - FMRIB's Software Library http://www.fmrib.ox.ac.uk/fsl fsl@fmrib.ox.ac.uk Developed at FMRIB (Oxford Centre for Functional Magnetic Resonance Imaging of the Brain), Department of Clinical Neurology, Oxford University, Oxford, UK LICENCE FMRIB Software Library, Release 5.0 (c) 2012, The University of Oxford (the "Software") The Software remains the property of the University of Oxford ("the University"). The Software is distributed "AS IS" under this Licence solely for non-commercial use in the hope that it will be useful, but in order that the University as a charitable foundation protects its assets for the benefit of its educational and research purposes, the University makes clear that no condition is made or to be implied, nor is any warranty given or to be implied, as to the accuracy of the Software, or that it will be suitable for any particular purpose or for use under any specific conditions. Furthermore, the University disclaims all responsibility for the use which is made of the Software. It further disclaims any liability for the outcomes arising from using the Software. The Licensee agrees to indemnify the University and hold the University harmless from and against any and all claims, damages and liabilities asserted by third parties (including claims for negligence) which arise directly or indirectly from the use of the Software or the sale of any products based on the Software. No part of the Software may be reproduced, modified, transmitted or transferred in any form or by any means, electronic or mechanical, without the express permission of the University. The permission of the University is not required if the said reproduction, modification, transmission or transference is done without financial return, the conditions of this Licence are imposed upon the receiver of the product, and all original and amended source code is included in any transmitted product. You may be held legally responsible for any copyright infringement that is caused or encouraged by your failure to abide by these terms and conditions. You are not permitted under this Licence to use this Software commercially. Use for which any financial return is received shall be defined as commercial use, and includes (1) integration of all or part of the source code or the Software into a product for sale or license by or on behalf of Licensee to third parties or (2) use of the Software or any derivative of it for research with the final aim of developing software products for sale or license to a third party or (3) use of the Software or any derivative of it for research with the final aim of developing non-software products for sale or license to a third party, or (4) use of the Software to provide any service to an external organisation for which payment is received. If you are interested in using the Software commercially, please contact Isis Innovation Limited ("Isis"), the technology transfer company of the University, to negotiate a licence. Contact details are: innovation@isis.ox.ac.uk quoting reference DE/9564. */ //#include //#define USE_VTK #include #include #include #include #include #include #include #include "math.h" #include "meshUtils.h" #include "fslvtkio/fslvtkio.h" #include "utils/options.h" #include "newimage/newimageall.h" #include "meshclass/meshclass.h" #include "first_lib/first_mesh.h" #include "first_lib/first_newmat_vec.h" //------------------------VTK STUFF------------------------// #ifdef USE_VTK #include "vtkPolyData.h" #include "vtkPolyDataReader.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkPoints.h" #include "vtkProperty.h" #include "vtkImagePlaneWidget.h" #include "vtkImageData.h" #include using namespace fslvtkconvname; #endif using namespace std; using namespace NEWIMAGE; using namespace mesh; using namespace fslvtkio; using namespace FIRST_LIB; // Local functions struct float3 { float x,y,z; }; struct float2 { float x,y; }; static float2 make_float2(float x, float y) { float2 t; t.x = x; t.y = y; return t; } static float3 make_float3(float x, float y, float z) { float3 t; t.x = x; t.y = y; t.z = z; return t; } inline float dot_prod(const float3 & v1 , const float3 & v2) { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; } inline float3 sub_vec(const float3 & v1 , const float3 & v2) { return make_float3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); } inline float3 add_vecs(const float3 & v1 , const float3 & v2, const float3 & v3) { return make_float3(v1.x+v2.x+v3.x, v1.y+v2.y+v3.y, v1.z+v2.z+v3.z); } inline float3 mul_vec(const float & sc , const float3 & v1) { return make_float3(sc*v1.x, sc*v1.y, sc*v1.z); } namespace meshutils { meshUtils::meshUtils(){ } meshUtils::meshUtils(const string & filename,const fslvtkIO::DataType i) { try { switch (i) { case 0: setDataType(i); readPolyData(filename); break; case 1: setDataType(i); cout<<"read unstructured grid meshutils"<(0)); readPolyData(meshname); } void meshUtils::getBounds(int *bounds,const float & xdim, const float & ydim,const float & zdim) { float xmin=1000,xmax=-1000,ymin=1000,ymax=-1000,zmin=1000,zmax=-1000; for (int i = 0; ixmax){ xmax=tempx; } if (tempyymax){ ymax=tempy; } if (tempzzmax){ zmax=tempz; } } *bounds=static_cast(floor(xmin/xdim)-1); *(bounds+1)=static_cast(ceil(xmax/xdim)+1); *(bounds+2)=static_cast(floor(ymin/ydim)-1); *(bounds+3)=static_cast(ceil(ymax/ydim)+1); *(bounds+4)=static_cast(floor(zmin/zdim)-1); *(bounds+5)=static_cast(ceil(zmax/zdim)+1); } void meshUtils::generateRandomMeshUsingScalar(const Mesh & min, const string & outname, const vector & scal, const int & N) { srand ( time(NULL) ); for (int i=0; i>sind; Mesh m=min; int count=0; for (vector::iterator i = m._points.begin(); i!=m._points.end(); i++ , count++ ) { cout<(rand()-RAND_MAX/2.0)<<" "<(rand()-RAND_MAX/2.0)/RAND_MAX<(rand()-RAND_MAX/2.0)/RAND_MAX*1.0+0.5; // cout<<"rn "<_update_coord = (*i)->get_coord() + rn * ((*i)->local_normal()); }else { // cout<(rand()-RAND_MAX/2.0)<<" "<(rand()-RAND_MAX/2.0)/RAND_MAX<(rand()-RAND_MAX/2.0)/RAND_MAX*1.0+0; // cout<<"rn2 "<_update_coord = (*i)->get_coord() + rn2 * ((*i)->local_normal()); } } m.update(); m.save(outname+sind+".vtk",3); } } float meshUtils::drawTriangleScalars(volume& image, volume& count, const unsigned int & tri_index) { float3 p0,p1,p2; float sc0,sc1,sc2; for (int pivot=0;pivot<3;pivot++) { switch (pivot) { case 0: p0 = make_float3( Points.element(Polygons.element(tri_index,0),0), Points.element(Polygons.element(tri_index,0),1), Points.element(Polygons.element(tri_index,0),2) ); p1 = make_float3( Points.element(Polygons.element(tri_index,1),0), Points.element(Polygons.element(tri_index,1),1), Points.element(Polygons.element(tri_index,1),2) ); p2 = make_float3( Points.element(Polygons.element(tri_index,2),0), Points.element(Polygons.element(tri_index,2),1), Points.element(Polygons.element(tri_index,2),2) ); sc0=Scalars.element(Polygons.element(tri_index,0),0); sc1=Scalars.element(Polygons.element(tri_index,1),0); sc2=Scalars.element(Polygons.element(tri_index,2),0); break; case 1: p1 = make_float3( Points.element(Polygons.element(tri_index,0),0), Points.element(Polygons.element(tri_index,0),1), Points.element(Polygons.element(tri_index,0),2) ); p0 = make_float3( Points.element(Polygons.element(tri_index,1),0), Points.element(Polygons.element(tri_index,1),1), Points.element(Polygons.element(tri_index,1),2) ); p2 = make_float3( Points.element(Polygons.element(tri_index,2),0), Points.element(Polygons.element(tri_index,2),1), Points.element(Polygons.element(tri_index,2),2) ); sc1=Scalars.element(Polygons.element(tri_index,0),0); sc0=Scalars.element(Polygons.element(tri_index,1),0); sc2=Scalars.element(Polygons.element(tri_index,2),0); break; case 2: p2 = make_float3( Points.element(Polygons.element(tri_index,0),0), Points.element(Polygons.element(tri_index,0),1), Points.element(Polygons.element(tri_index,0),2) ); p1 = make_float3( Points.element(Polygons.element(tri_index,1),0), Points.element(Polygons.element(tri_index,1),1), Points.element(Polygons.element(tri_index,1),2) ); p0 = make_float3( Points.element(Polygons.element(tri_index,2),0), Points.element(Polygons.element(tri_index,2),1), Points.element(Polygons.element(tri_index,2),2) ); sc2=Scalars.element(Polygons.element(tri_index,0),0); sc1=Scalars.element(Polygons.element(tri_index,1),0); sc0=Scalars.element(Polygons.element(tri_index,2),0); break; } float3 vu=sub_vec(p1,p0); float3 vv=sub_vec(p2,p0); float sc_u=sc1-sc0; float sc_v=sc2-sc0; float xdim=image.xdim(); float ydim=image.ydim(); float zdim=image.zdim(); for (float u=0;u<=1;u+=0.01) for (float v=0;v<=1;v+=0.01) { if ( (u+v)<=1 ) { float3 P=add_vecs(p0, mul_vec(u,vu), mul_vec(v,vv)); //if ((sc0 + u*sc_u +v*sc_v)<0) // cout<<"scalar "<(P.x/xdim+0.5), static_cast(P.y/ydim+0.5), static_cast(P.z/zdim+0.5) )+= sc0 + u*sc_u +v*sc_v; count.value(static_cast(P.x/xdim+0.5), static_cast(P.y/ydim+0.5), static_cast(P.z/zdim+0.5) )++; } } } } void meshUtils::generateRandom6DOFMatrices( const string & outname, const int & N) { const float PI=3.14159; //allow to go plus minus pi/4 in each direction srand ( time(NULL) ); for (int i=0; i>sind; float alpha=static_cast(rand()-RAND_MAX/2.0)*2*PI/(4.0*RAND_MAX) ; float beta=static_cast(rand()-RAND_MAX/2.0)*2*PI/(4.0*RAND_MAX) ; float gam=static_cast(rand()-RAND_MAX/2.0)*2*PI/(4.0*RAND_MAX) ; Matrix Rx(4,4); Matrix Ry(4,4); Matrix Rz(4,4); Rx=0; Rx.element(0,0)=1; Rx.element(1,1)=cos(alpha); Rx.element(1,2)=sin(alpha); Rx.element(2,1)=-Rx.element(1,2); Rx.element(2,2)=Rx.element(1,1); Rx.element(3,3)=1; Ry=0; Ry.element(1,1)=1; Ry.element(0,0)=cos(beta); Ry.element(0,2)=-sin(beta); Ry.element(2,0)=-Ry.element(0,2); Ry.element(2,2)=Ry.element(1,1); Ry.element(3,3)=1; Rz=0; Rz.element(2,2)=1; Rz.element(0,0)=cos(gam); Rz.element(0,1)=sin(gam); Rz.element(1,0)=-Rz.element(0,1); Rz.element(1,1)=Rz.element(0,0); Rz.element(3,3)=1; Matrix final=Rx*Ry*Rz; float tx=static_cast(rand()-RAND_MAX/2.0)*2*50/(RAND_MAX) ; float ty=static_cast(rand()-RAND_MAX/2.0)*2*50/(RAND_MAX) ; float tz=static_cast(rand()-RAND_MAX/2.0)*2*50/(RAND_MAX) ; final.element(0,3)=tx; final.element(1,3)=ty; final.element(2,3)=tz; ofstream fout; fout.open((outname+"_"+sind+".mat").c_str()); fout< & iCondMean, volume4D & iCondVar , const volume & im, const int & mode, const float & bmin, const float & bmax, const float & res, const float & mean_offset) { vector vars; for (int i=0;i<=mode;i++) vars.push_back(0); volume4D meanI4D; volume4D varI4D; cout<<"calculate base covariance"< > prec=min->getShape(0)->getICondPrec(); vector eigs=min->getShape(0)->getICondEigs(); unsigned int N=min->getDeformedIprof(vars,mode,vars.size()).size(); cout<<"convert vector to MAtrix"< iprof=min->getDeformedIprof(vars,mode,vars.size()); vector< vector > vcov; vector var; if ( !(eigs.size()==prec.size()) ) throw fslvtkIOException("number of eigenvalues does not match number of number modes"); volume imean=im; volume ivar=im; imean=0; ivar=0; float xdim=im.xdim(),ydim=im.ydim(),zdim=im.zdim() ; Mesh m= min->getDeformedMeshTrans(vars,mode,vars.size()); vector::iterator iprof_iter=iprof.begin(); int ipp=min->getIPP(0); cout<<"ipp "<::iterator k = m._points.begin(); k!=m._points.end(); k++ ) { Pt vertNew; Pt vert = (*k)->get_coord(); Vec normal; normal = (*k)->local_normal(); for (int j=0;j & scal) { // float mag=0; // for (vector::const_iterator i=scal.begin();i!=scal.end();i++) // { // if (*i) mag++; // } // mag=sqrt(mag); Mesh m =min->getShapeMesh(0); unsigned int count=0; for (vector::iterator i = m._points.begin(); i!=m._points.end(); i++ , count++ ) { vector< Vec > shapeMode; if (scal.at(count)){ vector eigNew; eigNew.push_back(1); for (int j=0;jgetNumberOfModes();j++) { eigNew.push_back(min->getEigenValue(j)); } min->setEigenValues(eigNew); for (unsigned int j=0;jlocal_normal()); else { Vec temp(0,0,0); shapeMode.push_back(temp); } } min->getShape(0)->insertModeVector(shapeMode,0); } } } */ //static function that takes in mesh class mesh void meshUtils::getBounds(const Mesh & m, int *bounds, const float & xdim, const float & ydim,const float & zdim){ float xmin=1000,xmax=-1000,ymin=1000,ymax=-1000,zmin=1000,zmax=-1000; for (vector::const_iterator i = m._points.begin(); i!=m._points.end(); i++ ){ float tempx=(*i)->get_coord().X; float tempy=(*i)->get_coord().Y; float tempz=(*i)->get_coord().Z; if (tempxxmax){ xmax=tempx; } if (tempyymax){ ymax=tempy; } if (tempzzmax){ zmax=tempz; } } *bounds=static_cast(floor(xmin/xdim)-1); *(bounds+1)=static_cast(ceil(xmax/xdim)+1); *(bounds+2)=static_cast(floor(ymin/ydim)-1); *(bounds+3)=static_cast(ceil(ymax/ydim)+1); *(bounds+4)=static_cast(floor(zmin/zdim)-1); *(bounds+5)=static_cast(ceil(zmax/zdim)+1); } //static void meshUtils::fileToVector(const string & fname, vector meshlist) { meshlist.clear(); ifstream fin; fin.open(fname.c_str()); string meshname; while (fin>>meshname) { meshlist.push_back(meshname); } } vector meshUtils::fileToVector(const string & fname) { vector meshlist; ifstream fin; fin.open(fname.c_str()); string meshname; while (fin>>meshname) { meshlist.push_back(meshname); } return meshlist; } ReturnMatrix meshUtils::readFlirtMat(const string & fname) { ifstream fin; fin.open(fname.c_str()); float ftemp; Matrix fmat(4,4); for (int i =0 ; i<4;i++) for (int j =0 ; j<4;j++) { fin>>ftemp; fmat.element(i,j)=ftemp; } fmat.Release(); return fmat; } void meshUtils::writeFlirtMatrix(const Matrix & fmat, const string & fname) { ofstream fout; fout.open(fname.c_str()); fout.flags( ios::fixed ); for (int i =0 ; i<4;i++) { for (int j =0 ; j<4;j++) fout<::iterator i = m._points.begin(); i!=m._points.end(); i++ ) { float x=(*i)->get_coord().X; float y=(*i)->get_coord().Y; float z=(*i)->get_coord().Z; Pt newPt(fmat.element(0,0)*x+fmat.element(0,1)*y+fmat.element(0,2)*z+fmat.element(0,3),\ fmat.element(1,0)*x+fmat.element(1,1)*y+fmat.element(1,2)*z+fmat.element(1,3), \ fmat.element(2,0)*x+fmat.element(2,1)*y+fmat.element(2,2)*z+fmat.element(2,3)); (*i)->_update_coord = newPt; } m.update(); } void meshUtils::meshReg(const Matrix & fmat){ ColumnVector ones(Points.Nrows()); ones=1; Points=Points | ones; Points=(fmat*(Points.t())).t(); Points=Points.SubMatrix(1,Points.Nrows(),1,3); } void meshUtils::shift3DVertexMatrix(Matrix & mat, const float & tx, const float & ty, const float & tz ){ for (int i=0; i::iterator i = m._points.begin(); i!=m._points.end(); i++ ) { (*i)->_update_coord.X=(*i)->get_coord().X+tx; (*i)->_update_coord.Y=(*i)->get_coord().Y+ty; (*i)->_update_coord.Z=(*i)->get_coord().Z+tz; } m.update(); } void meshUtils::shiftPoints( const float & tx, const float & ty, const float & tz ){ for (int i=0; i::const_iterator i=m1._points.begin(); i!=m1._points.end();i++,count++) { pointsRef.element(count,0)=(*i)->get_coord().X; pointsRef.element(count,1)=(*i)->get_coord().Y; pointsRef.element(count,2)=(*i)->get_coord().Z; } pointsRef.Release(); return pointsRef; } bool meshUtils::checkLine(const float & p1, const float & p2, const float & test){ return (((p1>test)&&(p2test))); } bool meshUtils::checkTriangleNeighbour(const short & tri0, const short & tri1, const short & tri2 , const short & ind0, const short & ind1, short & ind0new , short & ind1new){ if (((tri0==ind0) || (tri1==ind0) || (tri2==ind0)) && ((tri0==ind1) || (tri1==ind1) || (tri2==ind1))){ if (tri0==ind0) { ind0new=0 ; } else if (tri1==ind0) { ind0new=1 ; } else if (tri2==ind0) { ind0new=2 ; } if (tri0==ind1) { ind1new=0 ; } else if (tri1==ind1) { ind1new=1 ; } else if (tri2==ind1) { ind1new=2 ; } return true; } return false; } void meshUtils::intersectionPoint(const float & ycut, const float & px0, const float & py0, const float & pz0, const float & dx, const float & dy, const float & dz, vector & px, vector & py, vector & pz){ float t=(ycut-py0)/dy; px.push_back(px0+dx*t); py.push_back(ycut); pz.push_back(pz0+dz*t); } float meshUtils::myatan2(const float & y, const float & x) { const float PI=3.14159265358979323846; float f=atan2(y,x); /*float f=atan(y/x); if ((y<0)&&(x<0)) f+=PI; else if ((y>0)&&(x<0)) f+=PI; else if ((y<0)&&(x>0)) f+=2*PI; */ if (f<0) f+=2*PI; return f; } //assume unwrapped coordinates ReturnMatrix meshUtils::addSphericalCorrdinates( const Matrix & m1, const Matrix & m2 ) { //solves problem with avreage around 2pi/0 boundary //assume theta ranges from 0 to 2pi and is the second coordinate const float TPI=2*3.14159265358979323846; const float PI=3.14159265358979323846; Matrix Sum(m1.Nrows(),1); //we assume that problem are only with quadrant 1 and 4 operations for (int i=0;i(floor(m1.element(i+1,0) / (TPI) )); if (NcircM1<0) NcircM1++; int NcircM2= static_cast(floor(m2.element(i+1,0) / (TPI) )); if (NcircM2<0) NcircM2++; float remM1=m1.element(i+1,0) -NcircM1*TPI; float remM2=m2.element(i+1,0) - NcircM2*TPI; if (( (remM1>=0)&&(remM1<=PI/2) ) && ( (remM2>=3*PI/2)&&(remM2<=2*PI) ) ) { Sum.element(i+1,0)=m1.element(i+1,0)+(m2.element(i+1,0) - (abs(NcircM2)+1)*2*PI); cout<<"case 1 "<=0)&&(remM2<=PI/2) ) && ( (remM1>=3*PI/2)&&(remM1<=2*PI) ) ){ // Sum.element(i+1,0)=m1.element(i+1,0)-((abs(NcircM1)+1)*2*PI)+m2.element(i+1,0); // cout<<"case 2 "< & vmask) { unsigned int N=0; for (vector::const_iterator i=vmask.begin();i!=vmask.end();i++) if (*i) N++; Matrix subM(N,m.Ncols()); unsigned int count=1,count2=1; for (vector::const_iterator i=vmask.begin();i!=vmask.end();i++,count++) { if (*i) { subM.Row(count2)=m.Row(count); count2++; } } subM.Release(); return subM; } ReturnMatrix meshUtils::subSample_Nby1_3D_Matrix(const Matrix & m, const vector & vmask ) { unsigned int N=0; for (vector::const_iterator i=vmask.begin();i!=vmask.end();i++) if (*i) N++; Matrix subM(3*N,m.Ncols()); unsigned int count=1,count2=1; for (vector::const_iterator i=vmask.begin();i!=vmask.end();i++,count+=3) if (*i) { cout<<"N "<=0)&&(remM1<=PI/2) ) && ( (remM2>=3*PI/2.0)&&(remM2<2*PI) ) ) { cout<<"HMMMMM "<<3*PI/2.0<<" "<<3*PI/2<=0)&&(remM2<=PI/2) ) && ( (remM1>=3*PI/2.0)&&(remM1<2*PI) ) ){ Sum.element(i+1,0)=(m1.element(i+1,0)-2*PI)*N1+m2.element(i+1,0)*N2; cout<<"case 2 "<=0)&&(remM1(remM1+PI)) ) { Sum.element(i+1,0)=m1.element(i+1,0)*N1+(m2.element(i+1,0) -2*PI)*N2; cout<<"case 1 "<<" "<=0)&&(remM2(remM2+PI)) ){ Sum.element(i+1,0)=(m1.element(i+1,0)-2*PI)*N1+m2.element(i+1,0)*N2; cout<<"case 2 "<<" "<=0)&&(m1.element(i+1,0)<=PI/2) ) && ( (m2.element(i+1,0)>=3*PI/2)&&(m2.element(i+1,0)<=2*PI) ) ) Sum.element(i+1,0)=m1.element(i+1,0)-(m2.element(i+1,0) - 2*PI); else if ( ( (m2.element(i+1,0)>=0)&&(m2.element(i+1,0)<=PI/2) ) && ( (m1.element(i+1,0)>=3*PI/2)&&(m1.element(i+1,0)<=2*PI) ) ) Sum.element(i+1,0)=(m1.element(i+1,0)-2*PI)-m2.element(i+1,0); else Sum.element(i+1,0)=m1.element(i+1,0)-m2.element(i+1,0); if (Sum.element(i+1,0)<0) Sum.element(i+1,0)+=2*PI; Sum.element(i+2,0)=m1.element(i+2,0)+m2.element(i+2,0); } Sum.Release(); return Sum; } template void meshUtils::cartesianToSphericalCoord(vector & verts) { for (unsigned int i=0;i(vector & verts); template void meshUtils::sphericalToCartesianCoord(vector & verts) { for (unsigned int i=0;i(vector & verts); //these assumer unwrapped coordinates void meshUtils::getSphericalCoordFromCart(NEWMAT::Matrix & Mr, NEWMAT::Matrix & Mtheta, NEWMAT::Matrix & Mphi) { Mr.ReSize(Points.Nrows(),1); Mtheta.ReSize(Points.Nrows(),1); Mphi.ReSize(Points.Nrows(),1); for (int i=0;i void meshUtils::cartesianToSphericalCoord(Mesh & m) { for (vector::iterator i=m._points.begin();i!=m._points.end();i++) { T x=(*i)->get_coord().X; T y=(*i)->get_coord().Y; T z=(*i)->get_coord().Z; T r=sqrt(x*x+y*y+z*z); T theta=myatan2(y,x); T phi=cos(z/r); (*i)->_update_coord.X=r; (*i)->_update_coord.Y=theta; (*i)->_update_coord.Z=phi; } m.update(); } template void meshUtils::cartesianToSphericalCoord(Mesh & m); template void meshUtils::cartesianToSphericalCoord(Mesh & m); template void meshUtils::sphericalToCartesianCoord(Mesh & m) { for (vector::iterator i=m._points.begin();i!=m._points.end();i++) { T r=(*i)->get_coord().X; T theta=(*i)->get_coord().Y; T phi=(*i)->get_coord().Z; //put theta in x/z plane // (*i)->_update_coord.X=r*cos(theta)*sin(phi); // (*i)->_update_coord.Z=r*sin(theta)*sin(phi); // (*i)->_update_coord.Y=r*cos(phi); (*i)->_update_coord.X=r*cos(theta)*sin(phi); (*i)->_update_coord.Y=r*sin(theta)*sin(phi); (*i)->_update_coord.Z=r*cos(phi); } m.update(); } template void meshUtils::sphericalToCartesianCoord(Mesh & m); template void meshUtils::sphericalToCartesianCoord(Mesh & m); //-----------------------------Transformation Matrix Utilities Begin---------------------------// void meshUtils::preMultiplyGlobalRotation(Matrix & fmat, const Matrix & R) { //assume a 3by 3 rotation matrix //SubMatrix command has indices starting from 1 fmat.SubMatrix(1,3,1,3)=R*fmat.SubMatrix(1,3,1,3); fmat.SubMatrix(1,3,4,4)=R*fmat.SubMatrix(1,3,4,4); } void meshUtils::preMultiplyGlobalScale(Matrix & fmat, const float & s) { for (int col=0;col<4;col++) for (int row=0;row<3;row++) fmat.element(row,col)*=s; } void meshUtils::preMultiplyGlobalScale(Matrix & fmat, const float & sx,const float & sy, const float & sz) { for (int col=0;col<4;col++) fmat.element(0,col)*=sx; for (int col=0;col<4;col++) fmat.element(1,col)*=sy; for (int col=0;col<4;col++) fmat.element(2,col)*=sz; } void meshUtils::preMultiplyTranslation(Matrix & fmat, const float & tx, const float & ty, const float & tz ) { //must be a 4 by 4 matrix fmat.element(0,3)+=tx; fmat.element(1,3)+=ty; fmat.element(2,3)+=tz; } ReturnMatrix meshUtils::getIdentityMatrix(const short N) { Matrix fmat(N,N); fmat=0; for (int i=0;i & meshlist) { Matrix AllPoints,AllScalars,AllVectors, AllPolygons; for (unsigned int i=0;i im; //load data m.load(meshname); read_volume(im,imagename); float dx=im.xdim(), dy=im.ydim(), dz=im.zdim(); //variables int nverts=m._points.size(); ColumnVector Samples(nverts); int count=0; for (vector::iterator i = m._points.begin(); i!=m._points.end(); i++ ) { Samples.element(count)=im.interpolate(((*i)->get_coord().X)/dx,((*i)->get_coord().Y)/dy, ((*i)->get_coord().Z)/dz);//im.interpolate((*i)->get_coord().X, (*i)->get_coord().Y, (*i)->get_coord().Z); count++; } return Samples; } void meshUtils::sample_image_at_verticesNN(const string & meshname,const string & imagename,const string & outname) { //setup objects Mesh m; volume im; //load data m.load(meshname); read_volume(im,imagename); float dx=im.xdim(), dy=im.ydim(), dz=im.zdim(); //variables int nverts=m._points.size(); ColumnVector Samples(nverts); int count=0; for (vector::iterator iv = m._points.begin(); iv!=m._points.end(); iv++ ) { float val=im.interpolate(((*iv)->get_coord().X)/dx,((*iv)->get_coord().Y)/dy, ((*iv)->get_coord().Z)/dz); if (val!=0){ Samples.element(count)=val; }else{ float dist=1000; for (int i=-3;i<3;i++){ for (int j=-3;j<3;j++){ for (int k=-3;k<3;k++){ float val2=im.interpolate( ((*iv)->get_coord().X+i)/dx,((*iv)->get_coord().Y+j)/dy, ((*iv)->get_coord().Z+k)/dz); if ((val2!=0)&&(dist<(i*i+j*j+k*k))){ Samples.element(count)=val2; } } } } }//im.interpolate((*i)->get_coord().X, (*i)->get_coord().Y, (*i)->get_coord().Z); count++; } fslvtkIO* output = new fslvtkIO; output->setMesh(m); output->setScalars(Samples); output->save(outname); } void meshUtils::sampleSumAndWrite(const string & inname, const string & inmeshname, const string & outname){ fslvtkIO* output = new fslvtkIO; Mesh m; m.load(inmeshname); output->setMesh(m); ifstream fin; fin.open(inname.c_str()); int nSub; fin>>nSub; ColumnVector meanCV; for (int i=0;i>mname>>iname; cout<<"mname "<setScalars(meanCV); output->save(outname); // ofstream scout; // scout.open(outname.value().c_str()); // scout<<"SCALARS"<<" "< void meshUtils::sampleImageAtPoints(const volume & image, vector & vsamples) { vector vmask; float dx=image.xdim(), dy=image.ydim(), dz=image.zdim(); // cout<<"sample image at points "<(Points.Nrows());i++) { // vsamples.push_back(static_cast(image.value(Points.element(i,0)/dx, Points.element(i,1)/dy, Points.element(i,2)/dz ))); //cout<<"i "<(image.interpolate(Points.element(i,0)/dx, Points.element(i,1)/dy, Points.element(i,2)/dz ))); } // cout<<"done sampe image"<(const volume & image, vector & vsamples); template void meshUtils::sampleImageAtPoints(const volume & image, vector & vsamples); template void meshUtils::sampleImageAtPoints(const volume & image, vector & vsamples); void meshUtils::LQSurfaceReg(const Matrix & refPoints, Matrix & fmat, const int & dof) { //demenad vertices // cout<<"POINTS "<3) preMultiplyGlobalRotation(fmat,R); cout<<"fmat4 "< & im, const Matrix & fmat, float & cx, float & cy, float & cz) { int bounds[6]={0,0,0,0,0,0}; getBounds(bounds,im.xdim(),im.ydim(),im.zdim()); cy=(bounds[2]+bounds[3])/2 * im.ydim(); vector verts=sliceMesh(cy); cx=0,cz=0; float xmin=1000000,xmax=-10000, zmin=100000, zmax=-100000; vector::iterator i=verts.begin(); while (i!=verts.end()) { if ( (*i)>xmax ) xmax=(*i); if ( (*i)zmax ) zmax=(*i); if ( (*i) meshUtils::sliceMesh(const float & ycut) { short ind0=-1, ind1=-1, indP=-1; vector mask; for (int i=0; i(Polygons.element(i,0)),1), Points.element(static_cast(Polygons.element(i,1)),1),ycut) ) mask.push_back(i); else if ( checkLine(Points.element(static_cast(Polygons.element(i,0)),1), Points.element(static_cast(Polygons.element(i,2)),1),ycut) ) mask.push_back(i); else if ( checkLine(Points.element(static_cast(Polygons.element(i,1)),1), Points.element(static_cast(Polygons.element(i,2)),1),ycut) ) mask.push_back(i); } int count=0; //this deterimes which line of first polygon is cut if ( checkLine(Points.element(static_cast(Polygons.element(mask.at(0),0)),1), Points.element(static_cast(Polygons.element(mask.at(0),1)),1),ycut) ) { indP=mask.at(0); ind0=0; ind1=1; } else if ( checkLine(Points.element(static_cast(Polygons.element(mask.at(0),0)),1), Points.element(static_cast(Polygons.element(mask.at(0),2)),1),ycut) ) { indP=mask.at(0); ind0=0; ind1=2; } else if ( checkLine(Points.element(static_cast(Polygons.element(mask.at(0),1)),1), Points.element(static_cast(Polygons.element(mask.at(0),2)),1),ycut) ) { indP=mask.at(0); ind0=1; ind1=2; } //these describe the line float px0=Points.element(static_cast(Polygons.element(indP,ind0)),0); float dx=Points.element(static_cast(Polygons.element(indP,ind1)),0)-px0; float py0=Points.element(static_cast(Polygons.element(indP,ind0)),1); float dy=Points.element(static_cast(Polygons.element(indP,ind1)),1)-py0; float pz0=Points.element(static_cast(Polygons.element(indP,ind0)),2); float dz=Points.element(static_cast(Polygons.element(indP,ind1)),2)-pz0; //keep track of polygon id vector vP; vP.push_back(indP); vector vpx,vpy,vpz; //keep track of intersection points intersectionPoint(ycut, px0,py0,pz0,dx,dy,dz,vpx,vpy,vpz); //found start point now find second in triangle this will define the direction of rotation if ((ind0==0)&&(ind1==1)) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut)) { ind0=0; ind1=2; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,1)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut)) { ind0=1; ind1=2; } } else if ((ind0==0)&&(ind1==2)) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,1)),1),ycut)) { ind0=0; ind1=1; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,1)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut)) { ind0=1; ind1=2; } } else if ((ind0==1)&&(ind1==2)) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,1)),1),ycut) ) { ind0=0; ind1=1; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut) ) { ind0=0; ind1=2; } } px0=Points.element(static_cast(Polygons.element(indP,ind0)),0); py0=Points.element(static_cast(Polygons.element(indP,ind0)),1); pz0=Points.element(static_cast(Polygons.element(indP,ind0)),2); intersectionPoint(ycut, px0,py0,pz0,Points.element(static_cast(Polygons.element(indP,ind1)),0)-px0,Points.element(static_cast(Polygons.element(indP,ind1)),1)-py0,Points.element(static_cast(Polygons.element(indP,ind1)),2)-pz0,vpx,vpy,vpz); //we now have the point associate with the first triangle now find negihbouring triangle int n=0; do{ for (vector::iterator i=(mask.begin()+1); i!=mask.end(); i++){ short ind0new=-1, ind1new=-1; if ( (checkTriangleNeighbour(static_cast(Polygons.element(*i,0)),static_cast(Polygons.element(*i,1)),static_cast(Polygons.element(*i,2)), static_cast(Polygons.element(indP,ind0)),static_cast(Polygons.element(indP,ind1)) , ind0new, ind1new ) ) ){//&& ( notused)){ indP=*i; vP.push_back(indP); mask.erase(i); if ( ((ind0new==0)&&(ind1new==1)) || ((ind0new==1)&&(ind1new==0)) ) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut) ) { ind0=0; ind1=2; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,1)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut) ) { ind0=1; ind1=2; } }else if ( ((ind0new==0)&&(ind1new==2)) || ((ind0new==2)&&(ind1new==0)) ) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,1)),1),ycut) ) { ind0=0; ind1=1; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,1)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut) ) { ind0=1; ind1=2; } }else if ( ((ind0new==1)&&(ind1new==2)) || ((ind0new==2)&&(ind1new==1)) ) { if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,1)),1),ycut) ) { ind0=0; ind1=1; } else if ( checkLine(Points.element(static_cast(Polygons.element(indP,0)),1), Points.element(static_cast(Polygons.element(indP,2)),1),ycut) ) { ind0=0; ind1=2; } } px0=Points.element(static_cast(Polygons.element(indP,ind0)),0); py0=Points.element(static_cast(Polygons.element(indP,ind0)),1); pz0=Points.element(static_cast(Polygons.element(indP,ind0)),2); intersectionPoint(ycut, px0,py0,pz0,Points.element(static_cast(Polygons.element(indP,ind1)),0)-px0,Points.element(static_cast(Polygons.element(indP,ind1)),1)-py0,Points.element(static_cast(Polygons.element(indP,ind1)),2)-pz0,vpx,vpy,vpz); break; } } n++; }while (mask.size()>1); vector vVerts; vector::iterator j=vpy.begin(); vector::iterator k=vpz.begin(); for (vector::iterator i=vpx.begin(); i!=vpx.end();i++,j++,k++) { vVerts.push_back(*i); vVerts.push_back(*j); vVerts.push_back(*k); } return vVerts; } void meshUtils::sampleMeshProfilesFromImage(const volume & image, const float & sample_interval, const unsigned int & ipp) { const float xdim=image.xdim(); const float ydim=image.ydim(); const float zdim=image.zdim(); //read mesh //calculate normals for vertices vector shape=getPointsAsVector(); vector nx,ny,nz, dif; first_mesh::normal(shape,first_mesh::findNeighbourTriangles(getPolygonsAsVectorOfVectors(),getPointsAsMatrix().Nrows()),getPolygonsAsVectorOfVectors(),nx,ny,nz);//could possibly optimize further float inc_x1= sample_interval/xdim; float inc_y1= sample_interval/ydim; float inc_z1= sample_interval/zdim; vector::iterator nx_i=nx.begin(); vector::iterator ny_i=ny.begin(); vector::iterator nz_i=nz.begin(); for (vector::iterator k = shape.begin(); k!= shape.end(); k+=3,nx_i++,ny_i++, nz_i++) { float inc_x = (*nx_i) * inc_x1; float inc_y = (*ny_i) * inc_y1; float inc_z = (*nz_i) * inc_z1; (*k)=(*k)/xdim - (ipp-1)*0.5 * inc_x ; (*(k+1))=*(k+1)/ydim - (ipp-1)*0.5 * inc_y; (*(k+2))= *(k+2)/zdim - (ipp-1)*0.5 * inc_z; for (int j=0;j im; read_volume(im,imname); float xdim=im.xdim(),ydim=im.ydim(),zdim=im.zdim(); fslvtkIO* min = new fslvtkIO; min->setDataType(static_cast(0)); min->readPolyData(meshname); //register mesh //create contour in MNI space Matrix fmat=readFlirtMat(flirtmatname); meshReg(min,fmat); Matrix Points=min->getPointsAsMatrix(); Matrix Polys=min->getPolygons(); float minX=Points.Column(1).Minimum(); float minY=Points.Column(2).Minimum(); float minZ=Points.Column(3).Minimum(); float maxX=Points.Column(1).Maximum(); float maxY=Points.Column(2).Maximum(); float maxZ=Points.Column(3).Maximum(); cout<<"points bounds "< mask; for (int i=0; i0) cout<::iterator i=mask.begin(); i!=mask.end(); i++){ cout<<"M "<::iterator i=mask.begin(); i!=mask.end(); i++){ //check each line cout<<"coutn "< vP; vP.push_back(indP); vector vpx,vpy,vpz; intersectionPoint(ycut, px0,py0,pz0,dx,dy,dz,vpx,vpy,vpz); //found start point no find second in triangle this will define the direction of rotation if ((ind0==0)&&(ind1==1)){ if ( checkLine(Points.element(Polys.element(indP,0),1), Points.element(Polys.element(indP,2),1),ycut) ){ ind0=0; ind1=2; } else if ( checkLine(Points.element(Polys.element(indP,1),1), Points.element(Polys.element(indP,2),1),ycut) ){ ind0=1; ind1=2; } }else if ((ind0==0)&&(ind1==2)){ if ( checkLine(Points.element(Polys.element(indP,0),1), Points.element(Polys.element(indP,1),1),ycut) ){ind0=0; ind1=1; } else if ( checkLine(Points.element(Polys.element(indP,1),1), Points.element(Polys.element(indP,2),1),ycut) ){ind0=1; ind1=2; } }else if ((ind0==1)&&(ind1==2)){ if ( checkLine(Points.element(Polys.element(indP,0),1), Points.element(Polys.element(indP,1),1),ycut) ){ ind0=0; ind1=1; } else if ( checkLine(Points.element(Polys.element(indP,0),1), Points.element(Polys.element(indP,2),1),ycut) ){ ind0=0; ind1=2; } } px0=Points.element(Polys.element(indP,ind0),0); // dx=Points.element(Polys.element(indP,ind1),0)-px0; py0=Points.element(Polys.element(indP,ind0),1); // dy=Points.element(Polys.element(indP,ind1),1)-py0; pz0=Points.element(Polys.element(indP,ind0),2); // dz=Points.element(Polys.element(indP,ind1),2)-pz0; cout<<"point "<::iterator i=mask.begin(); i!=mask.end(); i++){ //cout<<"HMM "<::iterator pit=vP.begin(); pit!=vP.end(); pit++){ if ((*pit)==*i) notused=false; } cout<<"INDP "<::iterator i=mask.begin(); i!=mask.end(); i++){ cout<<"M "<& image, const Pt& p1, const Pt& p2, int label) { double xdim = (double) image.xdim(); double ydim = (double) image.ydim(); double zdim = (double) image.zdim(); //in new version of bet2 double mininc = min(xdim,min(ydim,zdim)) * .5; Vec n = (p1 - p2); double d = n.norm(); n.normalize(); // double l = d*4; for (double i=0; i<=d; i+=mininc) { Pt p = p2 + i* n; image((int) floor((p.X)/xdim +.5),(int) floor((p.Y)/ydim +.5),(int) floor((p.Z)/zdim +.5)) = label; } } volume meshUtils::draw_mesh(const volume& image, const Mesh &m, int label) { double xdim = (double) image.xdim(); double ydim = (double) image.ydim(); double zdim = (double) image.zdim(); //in new version of bet2 double mininc = min(xdim,min(ydim,zdim)) * .5; volume res = image; for (list::const_iterator i = m._triangles.begin(); i!=m._triangles.end(); i++) { Vec n = (*(*i)->get_vertice(0) - *(*i)->get_vertice(1)); double d = n.norm(); n.normalize(); for (double j=0; j<=d ; j+=mininc) { Pt p = (*i)->get_vertice(1)->get_coord() + (double)j* n; draw_segment(res, p, (*i)->get_vertice(2)->get_coord(),label); } } return res; } volume meshUtils::make_mask_from_mesh(const volume & image, const Mesh& m, int label, int* bounds, const bool & sep_boundary) { float xdim = (float) image.xdim(); float ydim = (float) image.ydim(); float zdim = (float) image.zdim(); volume mask; copyconvert(image,mask); mask = 0; if (sep_boundary) mask = draw_mesh(mask, m,label+100); else mask = draw_mesh(mask, m,label); // THIS EXCLUDEDS THE ACTUAL MESH volume otl=mask; getBounds(m,bounds,xdim,ydim,zdim); vector current; current.clear(); Pt c(bounds[0]-2, bounds[2]-2, bounds[4]-2); mask.value(static_cast(c.X),static_cast(c.Y),static_cast(c.Z)) = label; current.push_back(c); int fillCount=0; while (!current.empty()) { Pt pc = current.back(); int x, y, z; x=(int) pc.X; y=(int) pc.Y; z=(int) pc.Z; current.pop_back(); fillCount++; if (bounds[0]<=x-1 && mask.value(x-1, y, z)==0) { mask.value(x-1, y, z) = label; current.push_back(Pt(x-1, y, z)); } if (bounds[2]<=y-1 && mask.value(x, y-1, z)==0) { mask.value(x, y-1, z) = label; current.push_back(Pt(x, y-1, z)); } if (bounds[4]<=z-1 && mask.value(x, y, z-1)==0) { mask.value(x, y, z-1) = label; current.push_back(Pt(x, y, z-1)); } if (bounds[1]>=x+1 && mask.value(x+1, y, z)==0){ mask.value(x+1, y, z) = label; current.push_back(Pt(x+1, y, z)); } if (bounds[3]>=y+1 && mask.value(x, y+1, z)==0){ mask.value(x, y+1, z) = label; current.push_back(Pt(x, y+1, z)); } if (bounds[5]>=z+1 && mask.value(x, y, z+1)==0){ mask.value(x, y, z+1) = label; current.push_back(Pt(x, y, z+1)); } } for (int i=bounds[0];i im; read_volume(im,imname); Mesh m; m.load(meshname); int bounds[6]; volume imout; imout=make_mask_from_mesh(im, m, label, bounds,sep_bound); save_volume(imout,outname); } double meshUtils::maxScalar() { double max=-10e-6; for (unsigned int i=0; i(Scalars.Nrows());i++) { // cout<<"i "<max) max=Scalars.element(i,0); // cout<<"max "<setDataType(static_cast(0)); mesh1->readPolyData(mname1); fslvtkIO* mesh2 = new fslvtkIO; mesh2->setDataType(static_cast(0)); mesh2->readPolyData(mname2); Matrix vert1=mesh1->getPointsAsMatrix(); Matrix vert2=mesh2->getPointsAsMatrix(); Matrix Poly1=mesh1->getPolygons(); Matrix Poly2=mesh2->getPolygons(); vector vind1,vind2; bool foundM12=false; for (int i=0; i(Poly1.element(k,1)))) || (findVertex(vert1,vert2,static_cast(Poly1.element(k,2))))){ foundM12=true; } }else if(Poly1.element(k,1)==i){ if ( (findVertex(vert1,vert2,static_cast(Poly1.element(k,0)))) || (findVertex(vert1,vert2,static_cast(Poly1.element(k,2))))){ foundM12=true; } }else if(Poly1.element(k,2)==i){ if ( (findVertex(vert1,vert2,static_cast(Poly1.element(k,0)))) || (findVertex(vert1,vert2,static_cast(Poly1.element(k,1))))){ foundM12=true; } } } if (!foundM12){ vind1.push_back(i); vind2.push_back(j); } } } } vector vindP1; vector vindP2; int vindc=0; for ( int i=0;isetDataType(static_cast(0)); mout1->setPoints(vert1new); mout1->setPolygons(vert2new); } void meshUtils::labelAndCombineSharedBoundaries(const string & mname1, const string & mname2, const string & mout1name ){ //create mesh reader fslvtkIO* mesh1 = new fslvtkIO; mesh1->setDataType(static_cast(0)); mesh1->readPolyData(mname1); fslvtkIO* mesh2 = new fslvtkIO; mesh2->setDataType(static_cast(0)); mesh2->readPolyData(mname2); Matrix vert1=mesh1->getPointsAsMatrix(); Matrix vert2=mesh2->getPointsAsMatrix(); Matrix Poly1=mesh1->getPolygons(); Matrix Poly2=mesh2->getPolygons(); vector vind1,vind2; //bool foundM12=false; Matrix Sc1(vert1.Nrows(),1); int count=0; for (int i=0; i vind2.at(i)) { vind2.at(j)--; }//vind2 will store the indices of the altered vertices for ( int k=0;k (vind2.at(i)+shift)) { Poly2.element(k,l)--; } } } } /* for (unsigned int i=0;isetPoints(vert2); // mesh1->setPolygons(Poly2); mesh1->setPoints(vert1 & vert2); mesh1->setPolygons(Poly1 & Poly2); mesh1->setScalars(Sc1 & Sc2); mesh1->save(mout1name); } ReturnMatrix meshUtils::appendSharedBoundaryMask(const Matrix & Points2) { //create mesh reader //m1 is the template first styrcture //m2 is the boundary fro which we are searching for shared boundaries //mbase is of the same topology as m1, on which we are placing the scalars Matrix Sc1(Points.Nrows(),1); for (int i=0; i=0) Points.Row(i+1)=Points2.Row(static_cast(Scalars.element(i,0))+1); } } /* void meshUtils::appendSharedBoundaryMask(const string & mname1, const string & mname2,const string & mbase, const string & mout1name, const bool & indexed, const bool & useSc2 ){ //create mesh reader //m1 is the template first styrcture //m2 is the boundary fro which we are searching for shared boundaries //mbase is of the same topology as m1, on which we are placing the scalars fslvtkIO* mesh1 = new fslvtkIO; mesh1->setDataType(static_cast(0)); mesh1->readPolyData(mname1); fslvtkIO* mesh2 = new fslvtkIO; mesh2->setDataType(static_cast(0)); mesh2->readPolyData(mname2); fslvtkIO* meshB = new fslvtkIO; meshB->setDataType(static_cast(0)); meshB->readPolyData(mbase); Matrix vert1=mesh1->getPointsAsMatrix(); Matrix vert2=mesh2->getPointsAsMatrix(); Matrix Poly1=mesh1->getPolygons(); Matrix Poly2=mesh2->getPolygons(); vector vind1,vind2; //bool foundM12=false; Matrix Sc1(vert1.Nrows(),1); Matrix Sc2(vert2.Nrows(),1); Sc2=0; int count=0; for (int i=0; isetScalars(Sc2); }else{ meshB->setScalars(Sc1); } meshB->save(mout1name); mesh2->setScalars(Sc2); mesh2->save("st2_"+mout1name); } */ /* void meshUtils::applyFlirtThenSBmask(const string & mname1, const string & mname2,const string & mflirtname, const string & mout1name){ //create mesh reader //m1 is the template first styrcture //m2 is the boundary fro which we are searching for shared boundaries //mbase is of the same topology as m1, on which we are placing the scalars fslvtkIO* mesh1 = new fslvtkIO; mesh1->setDataType(static_cast(0)); mesh1->readPolyData(mname1); Matrix fmat=readFlirtMat(mflirtname); fmat=fmat.i(); meshReg(mesh1,fmat); fslvtkIO* mesh2 = new fslvtkIO; mesh2->setDataType(static_cast(0)); mesh2->readPolyData(mname2); Matrix vert1=mesh1->getPointsAsMatrix(); Matrix vert2=mesh2->getPointsAsMatrix(); // Matrix Poly1=mesh1->getPolygons(); // Matrix Poly2=mesh2->getPolygons(); // vector vind1,vind2; // bool foundM12=false; Matrix Sc1 = mesh1->getScalars(); Matrix Sc2 = mesh2->getScalars(); // Matrix Sc2(vert2.Nrows(),1); // Sc2=0; //int count=0; for (int i=0; i0){//search for coresponding vertex index for (int j=0; jsetPoints(vert1); mesh1->save(mout1name); } */ void meshUtils::do_work_uncentreMesh(const string & inim, const string & inmesh, const string & outmesh){ //this function is working directly on volumes volume im; read_volume(im,inim); float cx=(im.xsize()-1)/2.0*abs(im.xdim()); float cy=(im.ysize()-1)/2.0*abs(im.ydim()); float cz=(im.zsize()-1)/2.0*abs(im.zdim()); fslvtkIO* mesh = new fslvtkIO; mesh->setDataType(static_cast(0)); mesh->readPolyData(inmesh); Matrix MMesh = mesh->getPointsAsMatrix(); shift3DVertexMatrix(MMesh,cx,cy,cz); mesh->setPoints(MMesh); mesh->save(outmesh); delete mesh; } void meshUtils::do_work_MeshReg(const string & inim, const string & inmesh, const string & outmesh){ //this function is working directly on volumes volume im; read_volume(im,inim); float cx=(im.xsize()-1)/2.0*abs(im.xdim()); float cy=(im.ysize()-1)/2.0*abs(im.ydim()); float cz=(im.zsize()-1)/2.0*abs(im.zdim()); fslvtkIO* mesh = new fslvtkIO; mesh->setDataType(static_cast(0)); mesh->readPolyData(inmesh); Matrix MMesh = mesh->getPointsAsMatrix(); shift3DVertexMatrix(MMesh,cx,cy,cz); mesh->setPoints(MMesh); mesh->save(outmesh); delete mesh; } void meshUtils::subtractMeshes(const string & mesh1name, const string & mesh2name, const string & out){ fslvtkIO* mesh1 = new fslvtkIO; mesh1->setDataType(static_cast(0)); mesh1->readPolyData(mesh1name); fslvtkIO* mesh2 = new fslvtkIO; mesh2->setDataType(static_cast(0)); mesh2->readPolyData(mesh2name); Matrix Diff=mesh2->getPointsAsMatrix() - mesh1->getPointsAsMatrix(); mesh1->setVectors(Diff); mesh1->save(out); } void meshUtils::warpMeshWithDefField(const string & fieldname, const string & meshname, const string & meshoutname, const float & dx, const float & dy, const float & dz){ fslvtkIO* ugrid = new fslvtkIO; ugrid->setDataType(static_cast(0)); ugrid->readPolyData(meshname); Matrix Points=ugrid->getPointsAsMatrix(); //propogate volumetric mesh through deformation field //and sample intensities //cout<<"done flirt"< defField; read_volume4D(defField, fieldname); float resx=defField[0].xdim(); float resy=defField[0].ydim(); float resz=defField[0].zdim(); for (int i=0;isetPoints(Points); ugrid->save(meshoutname); } template< class T > void meshUtils::warpGridWithDefField(const volume4D & defField, const float & dx, const float & dy, const float & dz){ float resx=defField[0].xdim(); float resy=defField[0].ydim(); float resz=defField[0].zdim(); for (int i=0;i(const volume4D & fieldname, const float & dx, const float & dy, const float & dz); template void meshUtils::warpGridWithDefField(const volume4D & fieldname, const float & dx, const float & dy, const float & dz); template< class T > void meshUtils::warpGridWithDefField(const volume4D & defField, vector & points_in, float warpSc, const float & dx, const float & dy, const float & dz){ float resx=defField[0].xdim(); float resy=defField[0].ydim(); float resz=defField[0].zdim(); for (vector::iterator i=points_in.begin();i!=points_in.end();i+=3) { //shifts are for changes between roi and full image float px=*i; float py=*(i+1); float pz=*(i+2); *i = px + warpSc * defField[0].interpolate(px/resx,py/resy,pz/resz) + dx; *(i+1) = py + warpSc * defField[1].interpolate(px/resx,py/resy,pz/resz) + dy; *(i+2) = pz + warpSc * defField[2].interpolate(px/resx,py/resy,pz/resz) + dz; } } template void meshUtils::warpGridWithDefField(const volume4D & fieldname, vector & points_warped,float warpSc,const float & dx, const float & dy, const float & dz); template void meshUtils::warpGridWithDefField(const volume4D & fieldname, vector & points_warped,float warpSc,const float & dx, const float & dy, const float & dz); //template /*void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat){ //mat should be 4by 4 lfirt matrix //cout<<"done flirt"<::iterator i=m._points.begin();i!=m._points.end();i++){ //shifts are for changes between roi and full image float px=(*i)->get_coord().X; float py=(*i)->get_coord().Y; float pz=(*i)->get_coord().Z; pdef.element(0)=px+defField[0].interpolate(px/resx,py/resy,pz/resz); pdef.element(1)=py+defField[1].interpolate(px/resx,py/resy,pz/resz) ; pdef.element(2)=pz+defField[2].interpolate(px/resx,py/resy,pz/resz) ; pdef=mat*pdef; (*i)->_update_coord.X=pdef.element(0); (*i)->_update_coord.Y=pdef.element(1); (*i)->_update_coord.Z=pdef.element(2); } }*/ template void meshUtils::SurfDistToLabels( vector & vdist, const volume & image){ cout<<"enter surf dist "<(px), static_cast(py),static_cast(pz)}; Tdist dist=10000000; int layer=0; bool notFoundD=false; while (notFoundD) { for (int x=centre[0]-layer; x<=centre[0]+layer; x++) for (int y=centre[1]-layer; y<=centre[1]+layer;y++) for (int z=centre[2]-layer; z<=centre[2]+layer;z++) { if (image.value(x,y,z)>0) { float temp=x*x*xdim*xdim+y*y*ydim*ydim+z*z*zdim*zdim; if (temp(sqrt(dist))); } //setScalars(vdist); } template void meshUtils::SurfDistToLabels( vector & dist,const volume& image); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image); template void meshUtils::SurfDistToLabels( vector & vdist, const volume & image, const Tim & label){ vdist.clear(); float xdim=image.xdim(); float ydim=image.ydim(); float zdim=image.zdim(); for (int i=0; i(sqrt(dist))); } //setScalars(vdist); } /* template void meshUtils::SurfDistToLabels( vector & vdist, const volume & image, const Tim & label){ vdist.clear(); int bounds[6]={0,0,0,0,0,0}; float xdim=image.xdim(); float ydim=image.ydim(); float zdim=image.zdim(); getBounds(bounds,xdim,ydim,zdim); //switch to using vectors later for (int i=0; i(px/xdim), static_cast(py/ydim),static_cast(pz/zdim)}; cout<<"centre "<(sqrt(dist))); } //setScalars(vdist); } */ template void meshUtils::SurfDistToLabels( vector & dist,const volume& image, const unsigned & label); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image, const short & label); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image, const int & label); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image, const float & label); template void meshUtils::SurfDistToLabels( vector & dist,const volume& image, const double & label); void meshUtils::SurfScalarsMeanAndStdev(vector meshList, Matrix & MeanPoints, Matrix & MeanScalars, Matrix & StDevScalars ) { Matrix tempScalars; Matrix tempScalarsSq; for (unsigned int i=0;i(meshList.size()); MeanPoints/=N; MeanScalars=tempScalars/N; StDevScalars=(SP(tempScalars,tempScalars)-tempScalarsSq/N)/(N-1); for (int i=0; i void meshUtils::warpMeshWithDefField(mesh::Mesh & m, const volume4D & defField, const Matrix & mat){ //mat should be 4by 4 lfirt matrix //cout<<"done flirt"<::iterator i=m._points.begin();i!=m._points.end();i++){ //shifts are for changes between roi and full image float px=(*i)->get_coord().X; float py=(*i)->get_coord().Y; float pz=(*i)->get_coord().Z; pdef.element(0)=px+defField[0].interpolate(px/resx,py/resy,pz/resz); pdef.element(1)=py+defField[1].interpolate(px/resx,py/resy,pz/resz) ; pdef.element(2)=pz+defField[2].interpolate(px/resx,py/resy,pz/resz) ; pdef=mat*pdef; (*i)->_update_coord.X=pdef.element(0); (*i)->_update_coord.Y=pdef.element(1); (*i)->_update_coord.Z=pdef.element(2); } m.update(); } template void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat); template void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat); template void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat); template void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat); //template void meshUtils::warpMeshWithDefField( Mesh & m, const volume4D & defField, const Matrix & mat); template void meshUtils::ugridToImage(volume & im) { //for now use nearest neighbour float xres=im.xdim(); float yres=im.ydim(); float zres=im.zdim(); cout<<"scalars size "<(Points.element(i,0)/xres),static_cast(Points.element(i,1)/yres),static_cast(Points.element(i,2)/zres))=static_cast(Scalars.element(i,0)); //cout<(Scalars.element(indmin,0)); } // cout<(volume & im); template void meshUtils::ugridToImage(volume & im); template void meshUtils::ugridToImage(volume & im); ReturnMatrix meshUtils::getDeformedVector(const ColumnVector & mean, const Matrix & modes, const ColumnVector & eigs, const vector & vars ) { ColumnVector def(mean.Nrows()); def=mean; for (unsigned int i=0;i void meshUtils::deformSurface(const volume & image, const float & maxit, const float & wIm, const float & wTang_in, const float & w_area, const float & w_norm, const T & max_thresh, const unsigned int & interRate, const bool & enableInteraction, const string & name) { const T max_thresh_sq=max_thresh*max_thresh; const T xdim = static_cast(image.xdim()); const T ydim = static_cast(image.ydim()); const T zdim = static_cast(image.zdim()); float wTang=wTang_in; #ifdef USE_VTK vtkPolyData *meshData = vtkPolyData::New(); vtkPolyDataReader *vtkmesh = vtkPolyDataReader::New(); vtkRenderWindow *renWin = vtkRenderWindow::New(); vtkRenderer *ren1 =vtkRenderer::New(); vtkPolyDataMapper *meshmap = vtkPolyDataMapper::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); vtkImageData *imStruct =vtkImageData::New(); vtkImagePlaneWidget *planeWidgetX = vtkImagePlaneWidget::New(); vtkmesh->SetFileName(name.c_str()); meshData=(vtkmesh->GetOutput()); meshmap->SetInput(meshData); //actor coordinates, geome..etc vtkActor *aSurf = vtkActor::New(); aSurf->GetProperty()->SetColor(0.7,0,0); aSurf->GetProperty()->SetOpacity(1); aSurf->GetProperty()->SetEdgeColor(0.0,0,8); aSurf->GetProperty()->SetEdgeVisibility(1); aSurf->GetProperty()->SetPointSize(2); aSurf->GetProperty()->SetRepresentationToWireframe(); aSurf->SetMapper(meshmap); //interactorv iren->SetRenderWindow(renWin); //add actor ren1->AddActor(aSurf); //ren1->AddActor(aSphere2); ren1->SetBackground(0.4,0.4,0.4); //Render renWin->AddRenderer(ren1); imStruct=newimageTovtkImageData(image); planeWidgetX->DisplayTextOn(); planeWidgetX->SetInput(imStruct); planeWidgetX->SetPlaneOrientationToYAxes(); planeWidgetX->SetSliceIndex(120); planeWidgetX->SetKeyPressActivationValue('x'); planeWidgetX->SetInteractor(iren); planeWidgetX->TextureVisibilityOn(); planeWidgetX->GetTexturePlaneProperty()->SetOpacity(0.99); planeWidgetX->SetEnabled(1); renWin->Render(); if (enableInteraction) iren->Start(); #endif vector pts_org=getPointsAsVector(); vector pts=pts_org; vector< vector > cells=this->getPolygonsAsVectorOfVectors(); vector< vector > neighbours=first_mesh::findNeighbours(cells, pts.size()/3); vector< vector > neighbour_tris=first_mesh::findNeighbourTriangles(cells, pts.size()/3); for (int n_iter=1; n_iter<=maxit; n_iter++) { //iterations //calculate normals vector vnx,vny,vnz; first_mesh::normal(pts,neighbour_tris,cells,vnx,vny,vnz); vector vtri_x,vtri_y,vtri_z; first_mesh::maxTriangle(pts,neighbour_tris,cells,vtri_x,vtri_y,vtri_z); //clauclate medium of neigbours than teh diference vector vmx,vmy,vmz; first_mesh::medium_neighbours(pts,neighbours,cells,vmx,vmy,vmz); typename vector::iterator j=vmy.begin(); typename vector::iterator k=vmz.begin(); typename vector::iterator l=pts.begin(); typename vector::iterator m=vnx.begin(); typename vector::iterator n=vny.begin(); typename vector::iterator o=vnz.begin(); //find diffenrece vector vector v_im_nx,v_im_ny,v_im_nz; for (typename vector::iterator i=vmx.begin();i!=vmx.end();i++,j++,k++,m++,n++,o++,l+=3) { //calculate difference vector *i-=*l; *j-=*(l+1); *k-=*(l+2); T im_int = image.interpolate( (*l)/xdim, (*(l+1))/ydim, (*(l+2))/zdim ); v_im_nx.push_back(im_int * (*m) ); v_im_ny.push_back(im_int * (*n) ); v_im_nz.push_back(im_int * (*o) ); T norm= (*i) * (*m)+ (*j) * (*n) + (*k) * (*o); (*m) *= norm; (*n) *= norm; (*o) *= norm; (*i)-=(*m); (*j)-=(*n); (*k)-=(*o); } vector v_dx, v_dy, v_dz; typename vector::iterator tang_xi = vmx.begin(); typename vector::iterator tang_yi = vmy.begin(); typename vector::iterator tang_zi = vmz.begin(); typename vector::iterator norm_xi = vnx.begin(); typename vector::iterator norm_yi = vny.begin(); typename vector::iterator norm_zi = vnz.begin(); typename vector::iterator norm_im_xi = v_im_nx.begin(); typename vector::iterator norm_im_yi = v_im_ny.begin(); typename vector::iterator norm_im_zi = v_im_nz.begin(); typename vector::iterator vtri_xi = vtri_x.begin(); typename vector::iterator vtri_yi = vtri_y.begin(); typename vector::iterator vtri_zi = vtri_z.begin(); float max_step=0; for (typename vector::iterator i=pts.begin();i!=pts.end();i+=3, tang_xi++,tang_yi++,tang_zi++,norm_xi++,norm_yi++,norm_zi++, norm_im_xi++ , norm_im_yi++ , norm_im_zi++, vtri_xi++, vtri_yi++, vtri_zi++ ) { float dx = wTang * (*tang_xi) + w_norm * (*norm_xi) + wIm * (*norm_im_xi) + w_area * (*vtri_xi); float dy = wTang * (*tang_yi) + w_norm * (*norm_yi) + wIm * (*norm_im_yi) + w_area * (*vtri_yi); float dz = wTang * (*tang_zi) + w_norm * (*norm_zi) + wIm * (*norm_im_zi) + w_area * (*vtri_zi); v_dx.push_back( dx ); v_dy.push_back( dy ); v_dz.push_back( dz ); if ( (dx*dx +dy*dy +dz*dz) > max_step ) max_step=(dx*dx +dy*dy +dz*dz); } float scale=1; if ( max_step > max_thresh_sq) scale=max_thresh/sqrt(max_step); //update points typename vector::iterator dx_i = v_dx.begin(); typename vector::iterator dy_i = v_dy.begin(); typename vector::iterator dz_i = v_dz.begin(); int count=0; for (typename vector::iterator i=pts.begin();i!=pts.end();i+=3,dx_i++,dy_i++,dz_i++,count++) { *i+=(*dx_i)*scale; *(i+1)+=(*dy_i)*scale; *(i+2)+=(*dz_i)*scale; } if ( n_iter % interRate == 0) if (first_mesh::self_intersection_test(cells,pts)) { pts=pts_org; wTang+=0.1; cout<<"THE MESH SELF-INTERSECTS "<GetPoints()->Modified(); renWin->Render(); #endif } #ifdef USE_VTK if (enableInteraction) iren->Start(); #endif setPoints(pts); } template void meshUtils::deformSurface(const volume & image, const float & maxit, const float & wIm, const float & wTang, const float & maxTri, const float & w_norm, const float & max_thresh, const unsigned int & interRate, const bool & enableInteraction,const string & name); template void meshUtils::deformSurface(const volume & image, const float & maxit, const float & wIm, const float & wTang, const float & maxTri, const float & w_norm, const float & max_thresh, const unsigned int & interRate,const bool & enableInteraction, const string & name); void meshUtils::applyReg(Matrix & pts, const Matrix & fmat) { ColumnVector ones(pts.Nrows()); ones=1; Matrix temp= (pts | ones); // cout<<"dikms "<(Pts_src_dm.Nrows()) ;i++){ sumlx += Pts_src_dm.element(i,0)*Pts_src_dm.element(i,0); sumly += Pts_src_dm.element(i,1)*Pts_src_dm.element(i,1); sumlz += Pts_src_dm.element(i,2)*Pts_src_dm.element(i,2); sumrx += Pts_targ_dm.element(i,0)*Pts_targ_dm.element(i,0); sumry += Pts_targ_dm.element(i,1)*Pts_targ_dm.element(i,1); sumrz += Pts_targ_dm.element(i,2)*Pts_targ_dm.element(i,2); } if (global) { float scale=sqrt((sumrx+sumry+sumrz)/(sumlx+sumly+sumlz)); M_Sc.element(0,0)=scale;M_Sc.element(1,1)=scale;M_Sc.element(2,2)=scale; }else { M_Sc.element(0,0)=sqrt(sumrx/sumlx);M_Sc.element(1,1)=sqrt(sumry/sumly);M_Sc.element(2,2)=sqrt(sumrz/sumlz); } M_Sc.Release(); return M_Sc; } Matrix meshUtils::reg_leastsq(const Matrix & SourcePoints, const short & dof) { unsigned int Npoints=Points.Nrows(); Matrix M_trans_src(4,4); M_trans_src=0; M_trans_src.element(0,0)=1; M_trans_src.element(1,1)=1; M_trans_src.element(2,2)=1;M_trans_src.element(3,3)=1; Matrix M_trans_targ(4,4); M_trans_targ=0; M_trans_targ.element(0,0)=1; M_trans_targ.element(1,1)=1; M_trans_targ.element(2,2)=1;M_trans_targ.element(3,3)=1; Matrix M_Sc(4,4); M_Sc=0; M_Sc.element(0,0)=1;M_Sc.element(1,1)=1;M_Sc.element(2,2)=1;M_Sc.element(3,3)=1; Matrix M_Rot(4,4); M_Rot=0; M_Rot.element(0,0)=1;M_Rot.element(1,1)=1;M_Rot.element(2,2)=1;M_Rot.element(3,3)=1; //---------------------CALCULATE CENTROIDS----------------------// double mean_src_x=0, mean_src_y=0, mean_src_z=0; double mean_targ_x=0, mean_targ_y=0,mean_targ_z=0; for (unsigned int i=0; i=6) { M_Rot=calculateRotation(Pts_src_dm,Pts_targ_dm); M_Rot_final=M_Rot*M_Rot_final; if (dof==6) break; }//----------------------ADD NINE DEGREES OF FREEDON---------------------// //---------------------SCALE COMPONENT (OPTIONAL)----------------------// // cout<<"do Scale"<>fname) { meshUtils* meshIn=new meshUtils(fname,static_cast(0)); //Matrix Pts_src=; Matrix fmat=this->reg_leastsq(meshIn->getPointsAsMatrix(),dof); //cout<<"points orh "<getPointsAsMatrix()<meshReg(fmat); if ((allPoints.Nrows()==1)&&(allPoints.Ncols()==1)) { if (strcmp(outname.c_str(),"nosave")) { cout<<"adding DDDDDDDpoints"<setPolygons(meshIn->getPolygons()); fout->setPoints(meshIn->getPointsAsMatrix()); } allPoints = first_newmat_vector::unwrapMatrix(meshIn->getPointsAsMatrix()); }else { cout<getPointsAsMatrix().Nrows()<<" "<getPointsAsMatrix().Ncols()<<" "<getPointsAsMatrix().Nrows()<<" "<getPointsAsMatrix().Ncols()<<" "<appendPointsAndPolygons(meshIn->getPointsAsMatrix(), meshIn->getPolygons()); allPoints = allPoints | first_newmat_vector::unwrapMatrix(meshIn->getPointsAsMatrix()); } // cout<<"points reg "<getPointsAsMatrix()<save(outname.value()); cout<<"allPoints "<save(outname); delete fout; return allPoints; } }