1 /*=========================================================================
4 =========================================================================*/
7 #include "vtkPolyData.h"
8 #include "vtkObjectFactory.h"
10 //#include "vtkimagethreshold.h"
11 //#include "vtkImageCast.h"
12 //#include "vtkImageSeedConnectivity.h"
13 //#include "vtkImageData.h"
14 //#include "vtkMarchingCubes.h"
15 //#include "vtkDoubleArray.h"
16 //#include "vtkPointData.h"
17 //#include "vtkextractvoi.h"
22 #include "axisExtractor.h"
24 #define min(a,b) (((a)<(b))?(a):(b))
27 vtkStandardNewMacro(axisExtractor);
30 axisExtractor::axisExtractor() {
32 this->NumberOfRequiredInputs = 1;
35 this->maxpropradio=100;
39 this->resample= vtkImageResample::New();
40 this->resample->SetDimensionality (3);
42 this->extrac = vtkExtractVOI::New();
43 this->extrac->SetInput(this->resample->GetOutput());
44 this->extrac->SetSampleRate(1, 1, 1);
46 this->thresh = vtkImageThreshold::New();
47 this->thresh->SetInput(this->extrac->GetOutput());
48 this->thresh->SetInValue(255);
49 this->thresh->SetOutValue(0);
50 this->thresh->ReleaseDataFlagOff();
52 this->cast = vtkImageCast::New();
53 this->cast->SetInput(this->thresh->GetOutput());
54 this->cast->SetOutputScalarTypeToUnsignedChar();
56 this->connect = vtkImageSeedConnectivity::New();
57 this->connect->SetInput(this->cast->GetOutput());
58 this->connect->SetInputConnectValue(255);
59 this->connect->SetOutputConnectedValue(255);
60 this->connect->SetOutputUnconnectedValue(0);
62 this->dataprov=vtkImageData::New();
63 this->dataprov->SetScalarTypeToChar();
65 this->datatotal=vtkImageData::New();
66 this->datatotal->SetScalarTypeToChar();
73 //----------------------------------------------------------------------------
74 // Specify the input data or filter.
75 void axisExtractor::SetInput(vtkImageData *input)
81 this->vtkProcessObject::SetNthInput(0, input);
82 this->resample->SetInput(input);
83 input->GetSpacing(espprin);
86 minspac=min(espprin[0],min(espprin[1],espprin[2]));
89 this->resample->SetAxisOutputSpacing( 0, minspac);
90 this->resample->SetAxisOutputSpacing( 1, minspac);
91 this->resample->SetAxisOutputSpacing( 2, minspac);
92 this->resample->Update();
98 //----------------------------------------------------------------------------
99 // Specify the input data or filter.
101 void axisExtractor::Execute()
103 this->points = vtkPoints::New();
104 this->lineas = vtkCellArray::New();
109 this->datatotal->Delete();
110 this->datatotal=vtkImageData::New();
111 this->datatotal->SetScalarTypeToUnsignedChar();
113 this->datatotal->SetExtent(this->resample->GetOutput()->GetExtent());
114 this->datatotal->SetSpacing(this->resample->GetOutput()->GetSpacing());
119 while( !m_Stack0.empty()){
125 this->GetOutput()->SetPoints (this->points);
126 this->GetOutput()->SetLines(this->lineas);
127 this->GetOutput()->Modified();
129 // this->GetOutput()->GetPointData()->SetVectors(this->salidas);
139 //----------------------------------------------------------------------------
140 // Specify the input data or filter.
141 vtkImageData *axisExtractor::GetInput()
143 if (this->NumberOfInputs < 1){
147 return (vtkImageData *)(this->Inputs[0]);
156 //----------------------------------------------------------------------------
157 // Specify the input data or filter.
158 vtkImageData *axisExtractor::GetVolumen()
161 return this->datatotal;
169 //----------------------------------------------------------------------------
170 void axisExtractor::PrintSelf(ostream& os, vtkIndent indent)
172 this->Superclass::PrintSelf(os,indent);
182 //----------------------------------------------------------------------------
183 void axisExtractor::SetMaxPropRadio(double value)
185 this->maxpropradio=value;
190 //----------------------------------------------------------------------------
191 double axisExtractor::GetMaxPropRadio()
193 return this->maxpropradio;
198 //----------------------------------------------------------------------------
200 void axisExtractor::SetHumbral(double value)
207 //----------------------------------------------------------------------------
209 double axisExtractor::GetHumbral()
211 return this->humbral;
215 //----------------------------------------------------------------------------
217 void axisExtractor::SetMaxPropMasa(double value)
219 this->maxpropmasa=value;
224 //----------------------------------------------------------------------------
226 double axisExtractor::GetMaxPropMasa()
228 return this->maxpropmasa;
232 //----------------------------------------------------------------------------
234 void axisExtractor::SetMinPropMasa(double value)
236 this->minpropmasa=value;
241 //----------------------------------------------------------------------------
243 double axisExtractor::GetMinPropMasa()
245 return this->minpropmasa;
254 //----------------------------------------------------------------------------
255 void axisExtractor::SetPoint(double puntoactualprov[3] )
258 realtoreal(puntoactualprov,puntoactualprov);
261 m_Stack0.push(puntoactualprov[0]);
262 m_Stack1.push(puntoactualprov[1]);
263 m_Stack2.push(puntoactualprov[2]);
264 m_Stack3.push(puntoactualprov[0]);
265 m_Stack4.push(puntoactualprov[1]);
266 m_Stack5.push(puntoactualprov[2]);
279 //----------------------------------------------------------------------------
280 void axisExtractor::realtoreal(double a[3], double b[3] )
286 this->resample->GetOutput()->GetSpacing(espprin);
287 this->resample->GetOutput()->GetExtent(extprin);
289 b[0]=a[0]+(espprin[0]*extprin[0]);
290 b[1]=a[1]+(espprin[1]*extprin[2]);
300 //----------------------------------------------------------------------------
301 void axisExtractor::realtoreal2(double a[3], double b[3] )
307 this->resample->GetOutput()->GetSpacing(espprin);
308 this->resample->GetOutput()->GetExtent(extprin);
310 b[0]=a[0]-(espprin[0]*extprin[0]);
311 b[1]=a[1]-(espprin[1]*extprin[2]);
322 //----------------------------------------------------------------------------
323 void axisExtractor::realtoindex(double a[3], int b[3] )
332 this->resample->GetOutput()->GetSpacing(espprin);
333 this->resample->GetOutput()->GetExtent(extprin);
335 minspac=min(espprin[0],min(espprin[1],espprin[2]));
341 b[0]=(int)(a[0]/minspac);
342 b[1]=(int)(a[1]/minspac);
343 b[2]=(int)(a[2]/minspac);
363 //----------------------------------------------------------------------------
364 void axisExtractor::indextoreal(int a[3], double b[3] )
371 this->resample->GetOutput()->GetSpacing(espprin);
372 this->resample->GetOutput()->GetExtent(extprin);
374 minspac=min(espprin[0],min(espprin[1],espprin[2]));
385 //----------------------------------------------------------------------------
386 void axisExtractor::indextoreal(double a[3], double b[3] )
393 this->resample->GetOutput()->GetSpacing(espprin);
394 this->resample->GetOutput()->GetExtent(extprin);
396 minspac=min(espprin[0],min(espprin[1],espprin[2]));
406 //----------------------------------------------------------------------------
407 void axisExtractor::searc(int i, int j, int k)
419 ptr=(unsigned char *) this->connect->GetOutput()->GetScalarPointer(i,j,k);
420 ptr2=(char *) this->dataprov->GetScalarPointer(i,j,k);
426 this->connect->GetOutput()->GetExtent(ext);
428 radio=(ext[1]-ext[0])/2;
437 this->vector[this->label-1][0]+=1;
438 this->vector[this->label-1][1]+=i;
439 this->vector[this->label-1][2]+=j;
440 this->vector[this->label-1][3]+=k;
444 this->vectorb[this->label2-1][0]+=1;
445 this->vectorb[this->label2-1][1]+=i;
446 this->vectorb[this->label2-1][2]+=j;
447 this->vectorb[this->label2-1][3]+=k;
451 for(i3=-1;i3<=1;i3++){
452 for(j3=-1;j3<=1;j3++){
453 for(k3=-1;k3<=1;k3++){
454 if(i+i3>=ext[0] && i+i3<=ext[1] && j+j3>=ext[2] && j+j3<=ext[3] && k+k3>=ext[4] && k+k3<=ext[5] ){
455 ptr=(unsigned char *) this->connect->GetOutput()->GetScalarPointer(i+i3,j+j3,k+k3);
456 ptr2=(char *) this->dataprov->GetScalarPointer(i+i3,j+j3,k+k3);
457 if(ptri==255 && *ptr==255 && *ptr2==0 && (radio*radio)>=((i2+i3)*(i2+i3))+((j2+j3)*(j2+j3))+((k2+k3)*(k2+k3)) && ((radio-1)*(radio-1))<=((i2+i3)*(i2+i3))+((j2+j3)*(j2+j3))+((k2+k3)*(k2+k3))){
458 this->searc(i+i3, j+j3, k+k3);
460 else if(ptri==0 && *ptr==0 && *ptr2==0 && (radio*radio)>=((i2+i3)*(i2+i3))+((j2+j3)*(j2+j3))+((k2+k3)*(k2+k3)) && ((radio-1)*(radio-1))<=((i2+i3)*(i2+i3))+((j2+j3)*(j2+j3))+((k2+k3)*(k2+k3))){
461 this->searc(i+i3, j+j3, k+k3);
475 //----------------------------------------------------------------------------
476 void axisExtractor::find_components( )
486 this->connect->GetOutput()->GetExtent(ext);
489 radio=(ext[1]-ext[0])/2;
496 for(i=ext[0], i2=-radio;i<=ext[1];i++, i2++){
497 for(j=ext[2], j2=-radio;j<=ext[3];j++, j2++){
498 for(k=ext[4], k2=-radio;k<=ext[5];k++, k2++){
499 ptr=(unsigned char *) this->connect->GetOutput()->GetScalarPointer(i,j,k);
500 ptr2=(char *) this->dataprov->GetScalarPointer(i,j,k);
502 if(*ptr==255 && *ptr2==0 && (radio*radio)>=(i2*i2)+(j2*j2)+(k2*k2) && ((radio-1)*(radio-1))<=(i2*i2)+(j2*j2)+(k2*k2) ){
503 this->label=this->label+1;
504 this->vector[this->label-1][0]=0;
505 this->vector[this->label-1][1]=0;
506 this->vector[this->label-1][2]=0;
507 this->vector[this->label-1][3]=0;
508 this->searc(i, j, k);
511 else if(*ptr==0 && *ptr2==0 && (radio*radio)>=(i2*i2)+(j2*j2)+(k2*k2) && ((radio-1)*(radio-1))<=(i2*i2)+(j2*j2)+(k2*k2) ){
512 this->label2=this->label2+1;
513 this->vectorb[this->label2-1][0]=0;
514 this->vectorb[this->label2-1][1]=0;
515 this->vectorb[this->label2-1][2]=0;
516 this->vectorb[this->label2-1][3]=0;
517 this->searc(i, j, k);
535 //----------------------------------------------------------------------------
536 unsigned short axisExtractor::maximo( )
540 unsigned short max=0;
542 this->extrac->GetOutput()->GetExtent(ext);
547 for(i=ext[0];i<=ext[1];i++){
548 for(j=ext[2];j<=ext[3];j++){
549 for(k=ext[4];k<=ext[5];k++){
550 ptr=(unsigned short *)this->extrac->GetOutput()->GetScalarPointer(i,j,k);
567 //----------------------------------------------------------------------------
568 void axisExtractor::blanquear()
573 this->dataprov->GetExtent(ext);
579 for(i=ext[0];i<=ext[1];i++){
580 for(j=ext[2];j<=ext[3];j++){
581 for(k=ext[4];k<=ext[5];k++){
582 ptr=(char *) this->dataprov->GetScalarPointer(i,j,k);
594 //----------------------------------------------------------------------------
595 void axisExtractor::blanquear2()
600 this->datatotal->GetExtent(ext);
606 for(i=ext[0];i<=ext[1];i++){
607 for(j=ext[2];j<=ext[3];j++){
608 for(k=ext[4];k<=ext[5];k++){
609 ptr=(unsigned char *) this->datatotal->GetScalarPointer(i,j,k);
619 //----------------------------------------------------------------------------
620 void axisExtractor::copiar(vtkImageData *data, vtkImageData *data2 )
625 data->GetExtent(ext);
627 unsigned char *ptr, *ptr2;
629 for(i=ext[0];i<=ext[1];i++){
630 for(j=ext[2];j<=ext[3];j++){
631 for(k=ext[4];k<=ext[5];k++){
632 ptr=(unsigned char *) data->GetScalarPointer(i,j,k);
633 ptr2=(unsigned char *) data2->GetScalarPointer(i,j,k);
634 if(*ptr!=0 && *ptr2==0){
648 //----------------------------------------------------------------------------
649 double axisExtractor::distancia(double a[3], double b[3] )
653 return sqrt(((a[0]-b[0])*(a[0]-b[0]))+((a[1]-b[1])*(a[1]-b[1]))+((a[2]-b[2])*(a[2]-b[2])));
663 //----------------------------------------------------------------------------
664 int axisExtractor::envolumen(int a[3], vtkImageData *datae )
673 ptr=(unsigned char *) datae->GetScalarPointer(a);
692 //----------------------------------------------------------------------------
693 void axisExtractor::corte(double punto1[3], double punto2[3], double punto3[3], double centro[3], double radio )
703 m1=punto2[0]-punto1[0];
704 m2=punto2[1]-punto1[1];
705 m3=punto2[2]-punto1[2];
707 b1=punto1[0]-centro[0];
708 b2=punto1[1]-centro[1];
709 b3=punto1[2]-centro[2];
711 c0=m1*m1+m2*m2+m3*m3;
712 c1=2*m1*b1+2*m2*b2+2*m3*b3;
713 c2=b1*b1+b2*b2+b3*b3-radio*radio;
715 roots=vtkMath::SolveQuadratic (c0, c1, c2);
717 if(roots[1]>=0 && roots[1]<=1){
724 punto3[0]=punto1[0]+root*(punto2[0]-punto1[0]);
725 punto3[1]=punto1[1]+root*(punto2[1]-punto1[1]);
726 punto3[2]=punto1[2]+root*(punto2[2]-punto1[2]);
741 //----------------------------------------------------------------------------
742 void axisExtractor::redondear(vtkImageData *data )
748 data->GetExtent(ext);
752 radio=(ext[1]-ext[0])/2;
755 for(i=ext[0], i2=-radio;i<=ext[1];i++, i2++){
756 for(j=ext[2], j2=-radio;j<=ext[3];j++, j2++){
757 for(k=ext[4], k2=-radio;k<=ext[5];k++, k2++){
758 ptr=(unsigned char *) data->GetScalarPointer(i,j,k);
759 tmpsqrt = (i2*i2)+(j2*j2)+(k2*k2);
760 if( radio<sqrt(tmpsqrt) ){
781 //----------------------------------------------------------------------------
782 void axisExtractor::avanzar()
788 double puntoactual[3];
789 double puntoanterior[3];
790 double puntoactualdis[3];
791 double puntoactualcorre[3];
792 int puntoactualarr[3];
795 double vector2[50][3];
797 unsigned long vectortemp[4];
798 double vector2temp[3];
807 double puntoactualcorre2[3];
820 int cantidadanterior=0;
821 int cantidadanteriorb=0;
833 if(!m_Stack0.empty()){
835 indexp=m_Stack.top();
837 puntoactual[0]=m_Stack0.top();
838 puntoactual[1]=m_Stack1.top();
839 puntoactual[2]=m_Stack2.top();
841 puntoanterior[0]=m_Stack3.top();
842 puntoanterior[1]=m_Stack4.top();
843 puntoanterior[2]=m_Stack5.top();
853 dirant[0]=puntoanterior[0]-puntoactual[0];
854 dirant[1]=puntoanterior[1]-puntoactual[1];
855 dirant[2]=puntoanterior[2]-puntoactual[2];
857 radioactual=distancia(puntoactual, puntoanterior);
859 realtoindex(puntoactual, puntoactualarr);
861 for(this->label=1, this->label2=0;flag4==0 &&(this->label>0) && (this->label==1 && ( radiocorte==0 || radiotrabajo<=radiocorte4 ) ) || (this->label>1 && radiotrabajo<=radiocorte4) ;radiotrabajo++){
863 extint[0]=puntoactualarr[0]-radiotrabajo;
864 extint[1]=puntoactualarr[0]+radiotrabajo;
865 extint[2]=puntoactualarr[1]-radiotrabajo;
866 extint[3]=puntoactualarr[1]+radiotrabajo;
867 extint[4]=puntoactualarr[2]-radiotrabajo;
868 extint[5]=puntoactualarr[2]+radiotrabajo;
870 extrac->SetVOI(extint);
871 extrac->UpdateWholeExtent();
873 extrac->GetOutput()->GetExtent(extintreal);
875 if(extint[0]!=extintreal[0] || extint[1]!=extintreal[1] || extint[2]!=extintreal[2] || extint[3]!=extintreal[3] || extint[4]!=extintreal[4] || extint[5]!=extintreal[5]){
881 if(puntoactualarr[0]>=extintreal[0] && puntoactualarr[0]<=extintreal[1] && puntoactualarr[1]>=extintreal[2] && puntoactualarr[1]<=extintreal[3] && puntoactualarr[2]>=extintreal[4] && puntoactualarr[2]<=extintreal[5] ){
883 thresh->ThresholdByUpper(this->maximo()*this->humbral);
884 thresh->UpdateWholeExtent();
887 redondear(thresh->GetOutput());
889 cast->UpdateWholeExtent();
892 connect->RemoveAllSeeds();
893 connect->AddSeed(puntoactualarr[0],puntoactualarr[1],puntoactualarr[2]);
894 connect->UpdateWholeExtent();
897 this->dataprov->Delete();
899 this->dataprov=vtkImageData::New();
900 this->dataprov->SetScalarTypeToChar();
902 this->dataprov->SetExtent(this->connect->GetOutput()->GetExtent());
903 this->dataprov->SetSpacing(this->connect->GetOutput()->GetSpacing());
907 this->find_components();
909 if(this->label2>0 && flag==0){
910 radiocorte=radiotrabajo;
911 vector2b[0]=((double)vectorb[0][1]/(double)vectorb[0][0])-(double)puntoactualarr[0];
912 vector2b[1]=((double)vectorb[0][2]/(double)vectorb[0][0])-(double)puntoactualarr[1];
913 vector2b[2]=((double)vectorb[0][3]/(double)vectorb[0][0])-(double)puntoactualarr[2];
916 if(this->label2>1 && flag5==0){
917 radiocorte5=radiotrabajo;
921 if( this->label>1 && flag2==0){
922 radiocorte2=radiotrabajo;
927 radiocorte6=radiocorte2;
930 radiocorte6=min(radiocorte2, radiocorte5);
933 if((radiocorte6-radiocorte)>1 && flagg<=4){
943 if(this->label>2 && flag3==0){
944 radiocorte3=radiotrabajo;
947 if( this->label==2 && cantidadanterior!=this->label){
948 radiocorte7=radiotrabajo;
951 if( this->label==3 && cantidadanterior!=this->label){
952 radiocorte8=radiotrabajo;
954 if( cantidadanterior!=this->label || cantidadanteriorb!=this->label2){
956 radiocorte4=radiotrabajo+10*(radiotrabajo-radiocorte9);
959 radiocorte4=radiotrabajo+(radiotrabajo-radiocorte9);
961 radiocorte9=radiotrabajo;
964 cantidadanterior=this->label;
965 cantidadanteriorb=this->label2;
971 radiocorte10=radiotrabajo;
974 if(this->label>=2 && radiocorte10!=radiocorte9+1){
975 radiotrabajo=radiocorte9+1;
977 extint[0]=puntoactualarr[0]-radiotrabajo;
978 extint[1]=puntoactualarr[0]+radiotrabajo;
979 extint[2]=puntoactualarr[1]-radiotrabajo;
980 extint[3]=puntoactualarr[1]+radiotrabajo;
981 extint[4]=puntoactualarr[2]-radiotrabajo;
982 extint[5]=puntoactualarr[2]+radiotrabajo;
984 extrac->SetVOI(extint);
985 extrac->UpdateWholeExtent();
987 extrac->GetOutput()->GetExtent(extintreal);
989 thresh->ThresholdByUpper(this->maximo()*this->humbral);
990 thresh->UpdateWholeExtent();
993 redondear(thresh->GetOutput());
995 cast->UpdateWholeExtent();
998 connect->RemoveAllSeeds();
999 connect->AddSeed(puntoactualarr[0],puntoactualarr[1],puntoactualarr[2]);
1000 connect->UpdateWholeExtent();
1003 this->dataprov->Delete();
1005 this->dataprov=vtkImageData::New();
1006 this->dataprov->SetScalarTypeToChar();
1008 this->dataprov->SetExtent(this->connect->GetOutput()->GetExtent());
1009 this->dataprov->SetSpacing(this->connect->GetOutput()->GetSpacing());
1014 this->find_components();
1021 //printf("no corrigio\n");
1023 realtoreal2(puntoactual, provvc);
1024 points->InsertPoint(buenos,provvc);
1027 lineas->InsertNextCell(2);
1028 lineas->InsertCellPoint(indexp);
1029 lineas->InsertCellPoint(buenos);
1037 //printf("corrigio\n");
1043 norvec=distancia(provvc, vector2b);
1045 proprov=(radiocorte6-radiocorte)/(2*norvec);
1047 puntoactualcorre[0]=(puntoactualarr[0]-(vector2b[0]*proprov));
1048 puntoactualcorre[1]=(puntoactualarr[1]-(vector2b[1]*proprov));
1049 puntoactualcorre[2]=(puntoactualarr[2]-(vector2b[2]*proprov));
1051 indextoreal(puntoactualcorre, puntoactualcorre2);
1053 m_Stack0.push(puntoactualcorre2[0]);
1054 m_Stack1.push(puntoactualcorre2[1]);
1055 m_Stack2.push(puntoactualcorre2[2]);
1056 m_Stack3.push(puntoanterior[0]);
1057 m_Stack4.push(puntoanterior[1]);
1058 m_Stack5.push(puntoanterior[2]);
1059 m_Stack.push(indexp);
1069 for(i=0;i<this->label;i++){
1070 vector2[i][0]=((double)vector[i][1]/(double)vector[i][0])-(double)puntoactualarr[0];
1071 vector2[i][1]=((double)vector[i][2]/(double)vector[i][0])-(double)puntoactualarr[1];
1072 vector2[i][2]=((double)vector[i][3]/(double)vector[i][0])-(double)puntoactualarr[2];
1073 if(maxmasa<vector[i][0]){
1074 maxmasa=vector[i][0];
1078 for(i=0;i<this->label;i++){
1079 for(j=i;j<this->label;j++){
1080 if(vector[j][0]<vector[i][0]){
1081 vectortemp[0]=vector[i][0];
1082 vectortemp[1]=vector[i][1];
1083 vectortemp[2]=vector[i][2];
1084 vectortemp[3]=vector[i][3];
1085 vector2temp[0]=vector2[i][0];
1086 vector2temp[1]=vector2[i][1];
1087 vector2temp[2]=vector2[i][2];
1089 vector[i][0]=vector[j][0];
1090 vector[i][1]=vector[j][1];
1091 vector[i][2]=vector[j][2];
1092 vector[i][3]=vector[j][3];
1093 vector2[i][0]=vector2[j][0];
1094 vector2[i][1]=vector2[j][1];
1095 vector2[i][2]=vector2[j][2];
1097 vector[j][0]=vectortemp[0];
1098 vector[j][1]=vectortemp[1];
1099 vector[j][2]=vectortemp[2];
1100 vector[j][3]=vectortemp[3];
1101 vector2[j][0]=vector2temp[0];
1102 vector2[j][1]=vector2temp[1];
1103 vector2[j][2]=vector2temp[2];
1110 for(i=0;i<this->label;i++){
1111 if(maxmasa*this->minpropmasa<vector[i][0]){
1113 indesxdis[0]=(int) (puntoactualarr[0]+vector2[i][0]);
1114 indesxdis[1]=(int) (puntoactualarr[1]+vector2[i][1]);
1115 indesxdis[2]=(int) (puntoactualarr[2]+vector2[i][2]);
1117 indextoreal(indesxdis, puntoactualdis);
1119 if(envolumen(indesxdis, datatotal)==0){
1120 m_Stack0.push(puntoactualdis[0]);
1121 m_Stack1.push(puntoactualdis[1]);
1122 m_Stack2.push(puntoactualdis[2]);
1123 m_Stack3.push(puntoactual[0]);
1124 m_Stack4.push(puntoactual[1]);
1125 m_Stack5.push(puntoactual[2]);
1126 m_Stack.push(buenos-1);
1134 copiar(this->connect->GetOutput(), datatotal );