/* for ducumentation see tensorfield.h Author: Raimundo Sierra www.rsierra.com Copyright: Copyright (c) 2000 Raimundo Sierra. All rights reserved. LICENSE: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "tensorfield.h" #ifdef debug int fieldcounter=0; // counts calls to constructors int fielddestructorcounter=0; // counts calls to destructors #endif //constructors //tensorfield::tensorfield() // not needed sinse tensorfield( int, int, int) defaults to 256, 256, 1. tensorfield::tensorfield(const char path[], const int dimx=256, const int dimy=256, const int dimz=1) { int length = strlen(path); if(path[length-3] =='x' && path[length-2] =='m' && path[length-1] =='l'){ // reading xml-header cout << "Initializing tensorfield from xml-file\t\t"<< flush; this->read_XMLHeader(path); _field = new tensor[_dimx*_dimy*_dimz]; cout << "done\n" << flush; length = strlen(_datafile); char *datapath = new char[length+5]; strcpy(datapath, _datafile); datapath[length] = '.'; datapath[length+1] = 't'; datapath[length+2] = 'e'; datapath[length+3] = 'n'; datapath[length+4] = '\0'; //cout <load(datapath); return; } cout << "Initializing tensorfield \t\t\t" << flush; // reading raw data _dimx = dimx; _dimy = dimy; _dimz = dimz; _deltax = _deltay = _deltaz = 1; _field = new tensor[_dimx*_dimy*_dimz]; cout << "done\n" << flush; char tmp[length + 4]; char number[4]; _sourcefile = new char[length]; strcpy(_sourcefile, path); for(int i=1; i<=_dimz; i++){ if(i<100){ number[0] = char(i/10+48); number[1] = char(i%10+48); number[2] = '\0'; } else if(i<1000){ number[0] = char(i/100+48); number[1] = char((i/10)%10+48); number[2] = char(i%100%10+48); number[3] = '\0'; } else { cerr << "Too many slices, cannot process in tensorfield::tensorfield(char, int, int, int)\nEXIT\n"; exit(0); } strcat(strcpy(tmp, path), number); read_tensorslice(tmp, (i-1)); } #ifdef debug fieldcounter++; cout << "tensorcounter is: "<= 1\nEXIT\n"; exit(0); } cout << "Initializing tensorfield of size ("<= _dimx || y >= _dimy || z >= _dimz || x < 0 || y < 0 || z < 0 ){ cerr << "ERROR:Requesting tensor out of field\nExit\n"; exit(0); } return &_field[x+y*_dimx+z*_dimx*_dimy]; } tensor* tensorfield::get(const int position) { if( position>=_dimx*_dimy*_dimz || position < 0 ){ cerr << "ERROR: Requesting tensor out of field\nExit\n"; exit(0); } return &_field[position]; } void tensorfield::separate(float * array1, float * array2, float * array3, float * array4, float * array5, float * array6) { for(int i=0; i<_dimx*_dimy*_dimz; i++){ array1[i] = _field[i].get(0,0); array2[i] = _field[i].get(1,1); array3[i] = _field[i].get(2,2); array4[i] = _field[i].get(0,1); array5[i] = _field[i].get(0,2); array6[i] = _field[i].get(1,2); } } void tensorfield::merge(float * array1, float * array2, float * array3, float * array4, float * array5, float * array6) { for(int i=0; i<_dimx*_dimy*_dimz; i++){ _field[i].set(array1[i], array2[i], array3[i], array4[i], array5[i], array6[i]); } } void tensorfield::merge(float * array1, float * array2, float * array3, float * array4, float * array5, float * array6, float * array7, float * array8, float * array9) { for(int i=0; i<_dimx*_dimy*_dimz; i++){ _field[i].set(array1[i], array2[i], array3[i], array4[i], array5[i], array6[i], array7[i], array8[i], array9[i]); } } void tensorfield::set(const tensor t, const int x, const int y, const int z = 0) { if( x>=_dimx || y>=_dimy || z>=_dimz || x < 0 || y < 0 || z < 0){ cout << "Setting tensor out of field, do nothing\n"; return; } _field[x+y*_dimx+z*_dimx*_dimy] = t; } void tensorfield::save(const char path[], int offset[3]=NULL, int windowsize[3]=NULL) { cout << "Writing tensorfield to disc"< add extensions for tensorfile (not needed for xmlfile) filename[length] = '.'; filename[length+1] = 't'; filename[length+2] = 'e'; filename[length+3] = 'n'; filename[length+4] = '\0'; } tensor *tmp_ptr; FILE *out_file; out_file = fopen(filename, "w"); if(out_file == NULL){ cout << "\n\t Cannot open file "<write_XMLHeader(xmlpath); delete[] filename; delete[] xmlpath; cout <<"\t\t\tdone\n"<= _dimx || y >= _dimy || z >= _dimz || x < 0 || y < 0 || z < 0){ cout << "Requesting tensor out of field, do nothing\n"; return; } cout <<"Tensor at position ("<1 || t1yy>1 || t1zz>1 || t1xx<0 || t1yy<0 || t1zz<0 || t1xy>1 || t1xz>1 || t1yz>1 || t1xy<-1 || t1xz<-1 || t1yz<-1){ cout <<"tensorsize wrong\n"; } */ /* } else { t1xx = t1yy = t1zz = t1xy = t1xz = t1yz = 0; } if(normfactor2!=0){ t2xx = double(le2x[pos]*le2x[pos]) / normfactor2; t2yy = double(le2y[pos]*le2y[pos]) / normfactor2; t2zz = double(le2z[pos]*le2z[pos]) / normfactor2; t2xy = double(le2x[pos]*le2y[pos]) / normfactor2; t2xz = double(le2x[pos]*le2z[pos]) / normfactor2; t2yz = double(le2y[pos]*le2z[pos]) / normfactor2; } else { t2xx = t2yy = t2zz = t2xy = t2xz = t2yz = 0; } if(normfactor3!=0){ t3xx = double(le3x[pos]*le3x[pos]) / normfactor3; t3yy = double(le3y[pos]*le3y[pos]) / normfactor3; t3zz = double(le3z[pos]*le3z[pos]) / normfactor3; t3xy = double(le3x[pos]*le3y[pos]) / normfactor3; t3xz = double(le3x[pos]*le3z[pos]) / normfactor3; t3yz = double(le3y[pos]*le3z[pos]) / normfactor3; } else { t3xx = t3yy = t3zz = t3xy = t3xz = t3yz = 0; } t1 = float( double(lam1[pos]) * t1xx + double(lam2[pos]) * t2xx + double(lam3[pos]) * t3xx); t2 = float( double(lam1[pos]) * t1yy + double(lam2[pos]) * t2yy + double(lam3[pos]) * t3yy); t3 = float( double(lam1[pos]) * t1zz + double(lam2[pos]) * t2zz + double(lam3[pos]) * t3zz); t4 = float( double(lam1[pos]) * t1xy + double(lam2[pos]) * t2xy + double(lam3[pos]) * t3xy); t5 = float( double(lam1[pos]) * t1xz + double(lam2[pos]) * t2xz + double(lam3[pos]) * t3xz); t6 = float( double(lam1[pos]) * t1yz + double(lam2[pos]) * t2yz + double(lam3[pos]) * t3yz); _field[pos + slice_no*_dimx*_dimy].set(t1, t2, t3, t4, t5, t6); } } cout <<"\t\t\tdone\n" << flush; delete[] lam1; delete[] lam2; delete[] lam3; delete[] le1x; delete[] le1y; delete[] le1z; delete[] le2x; delete[] le2y; delete[] le2z; delete[] le3x; delete[] le3y; delete[] le3z; } */ void tensorfield::remove_strips(const int inside=0) { // take a 3*1 window and scan the field int pos =0; int pos_k=0; int pos_j=0; int back =0; float euclid_0, euclid_1, euclid_2; if(inside==0){ // asumes only 1 object cout << "Removing strips outside object"<< flush; for(int k=0; k<_dimz; k++){ pos_k = k*_dimx*_dimy; for(int j=0; j<_dimy; j++){ pos_j = j*_dimx+pos_k; euclid_1 = _field[pos_j].euclid(); // initiale values for euclid_1 and euclid_2 euclid_2 = _field[pos_j+1].euclid(); for(int i=1; i<_dimx-1; i++){ // forward scan pos = i+pos_j; euclid_0 = euclid_1; // forward values euclid_1 = euclid_2; euclid_2 = _field[pos+1].euclid(); if(euclid_0 == 0 && euclid_1 != 0 && euclid_2 == 0){ _field[pos].setZero(); } else if(euclid_0 == 0 && euclid_1 != 0 && euclid_2 != 0){ // inside object -> have to do backward scan back = 1; break; // stop forward scan } } if(back==1){ euclid_1 = _field[pos_j+255].euclid(); // initiale values for euclid_0 and euclid_1 euclid_0 = _field[pos_j+254].euclid(); for(int i=_dimx-2; i>0; i--){ // backward scan pos = i+pos_j; euclid_2 = euclid_1; // forward values euclid_1 = euclid_0; euclid_0 = _field[pos-1].euclid(); if(euclid_0 == 0 && euclid_1 != 0 && euclid_2 == 0){ _field[pos].setZero(); } else if(euclid_2 == 0 && euclid_1 != 0 && euclid_0 != 0){ // inside object break; // stop backward scan } } back = 0; } } } } else { cout << "Removing strips in- and outside object"<< flush; for(int k=0; k<_dimz; k++){ pos_k = k*_dimx*_dimy; for(int j=0; j<_dimy; j++){ pos_j = j*_dimx+pos_k; euclid_1 = _field[pos_j].euclid(); // initiale values for euclid_1 and euclid_2 euclid_2 = _field[pos_j+1].euclid(); for(int i=1; i<_dimx-1; i++){ pos = i+pos_j; euclid_0 = euclid_1; euclid_1 = euclid_2; euclid_2 = _field[pos+1].euclid(); if(euclid_0 == 0 && euclid_1 != 0 && euclid_2 == 0){ _field[pos].setZero(); } } } } } cout << "\t\tdone\n"<< flush; } void tensorfield::smooth(const int filterlength=3) { cout << "Smoothing tensorfield with filterlength "<separate(a, b, c, d, e, f); GaussSmoothFloatArray(a, _dimx, _dimy, _dimz, filterlength); GaussSmoothFloatArray(b, _dimx, _dimy, _dimz, filterlength); GaussSmoothFloatArray(c, _dimx, _dimy, _dimz, filterlength); GaussSmoothFloatArray(d, _dimx, _dimy, _dimz, filterlength); GaussSmoothFloatArray(e, _dimx, _dimy, _dimz, filterlength); GaussSmoothFloatArray(f, _dimx, _dimy, _dimz, filterlength); this->merge(a, b, c, d, e, f); delete[] a; delete[] b; delete[] c; delete[] d; delete[] e; delete[] f; cout << "done\n"<smooth(smoothlength); for(int k=0; k<_dimz; k++){ for(int j=0; j<_dimy; j++){ for(int i=0; i<_dimx; i++){ if(i%factor==0 && j%factor==0){ smallfield.set(_field[i+j*_dimx+k*_dimx*_dimy], i/factor, j/factor, k); //cout << (*smallfield.get(x/factor, y/factor, k)); } } } } //return &smallfield; } void tensorfield::trace(float * array) const { for(int i=0; i<_dimx*_dimy*_dimz; i++){ array[i] = _field[i].trace(); } } void tensorfield::det(float * array) const { for(int i=0; i<_dimx*_dimy*_dimz; i++){ array[i] = _field[i].det(); } } void tensorfield::roundnessCF(float * pointarray, const float thresh=0.01) { float maxtrace = 0; for(int i=0; i<_dimx*_dimy*_dimz; i++){ if(fabs(_field[i].trace()) > maxtrace) maxtrace = fabs(_field[i].trace()); pointarray[i] = 0; /* if(_field[i].det()!=0){ cout << "Field position "<Allocate( window[0]*window[1]*window[2]); int pos = 0; for(int k=0; kSetComponent(0,0, _field[pos].get(0,0)); tensor->SetComponent(0,1, _field[pos].get(0,1)); tensor->SetComponent(0,2, _field[pos].get(0,2)); tensor->SetComponent(1,0, _field[pos].get(1,0)); tensor->SetComponent(1,1, _field[pos].get(1,1)); tensor->SetComponent(1,2, _field[pos].get(1,2)); tensor->SetComponent(2,0, _field[pos].get(2,0)); tensor->SetComponent(2,1, _field[pos].get(2,1)); tensor->SetComponent(2,2, _field[pos].get(2,2)); newTensors->InsertNextTensor(tensor); } } } tensor->Delete(); } void tensorfield::det2vtkScalars(const int offset[3], const int window[3], vtkScalars *newScalars) const { newScalars->Allocate( window[0]*window[1]*window[2]); float tmp; int pos = 0; for(int k=0; kInsertNextScalar(tmp); } } } }