00001 #include "SUMA_suma.h"
00002 
00003 extern SUMA_CommonFields *SUMAg_CF;
00004 extern SUMA_DO *SUMAg_DOv;
00005 extern SUMA_SurfaceViewer *SUMAg_SVv;
00006 extern int SUMAg_N_SVv; 
00007 extern int SUMAg_N_DOv;  
00008 
00009 
00010 SUMA_M2M_STRUCT *SUMA_NewM2M(char *SO1_id, int N_SO1_nodes, char *SO2_id)
00011 {
00012    static char FuncName[]={"SUMA_NewM2M"};
00013    SUMA_M2M_STRUCT *M2M=NULL;
00014    SUMA_ENTRY;
00015    
00016    if (!SO1_id || !SO2_id) SUMA_RETURN(M2M);
00017    
00018    M2M = (SUMA_M2M_STRUCT*)SUMA_malloc(sizeof(SUMA_M2M_STRUCT));
00019    
00020    M2M->M1Nn = N_SO1_nodes;
00021    M2M->M1n = (int*)SUMA_calloc(M2M->M1Nn, sizeof(int));
00022    M2M->M2t_M1n = (int*)SUMA_calloc(M2M->M1Nn, sizeof(int));
00023    M2M->M2Nne_M1n = (int*)SUMA_calloc(M2M->M1Nn, sizeof(int));
00024    M2M->M2ne_M1n = (int**)SUMA_calloc(M2M->M1Nn, sizeof(int*));
00025    M2M->M2pb_M1n = (float *)SUMA_calloc(2*M2M->M1Nn, sizeof(float));
00026    M2M->M2p_M1n = (float *)SUMA_calloc(3*M2M->M1Nn, sizeof(float));
00027    M2M->PD = (double *)SUMA_calloc(M2M->M1Nn, sizeof(double));
00028    M2M->M2we_M1n = (double**)SUMA_calloc(M2M->M1Nn, sizeof(double*));
00029    if (!M2M->M1n || !M2M->M2t_M1n || !M2M->M2Nne_M1n || !M2M->M2ne_M1n || !M2M->M2we_M1n) {
00030       SUMA_SL_Crit("Failed to allocate");
00031       SUMA_RETURN(NULL);
00032    }
00033    
00034    M2M->M1_IDcode = SUMA_copy_string(SO1_id);
00035    M2M->M2_IDcode = SUMA_copy_string(SO2_id);
00036    
00037    
00038    SUMA_RETURN(M2M);
00039 }  
00040 
00041 SUMA_M2M_STRUCT *SUMA_FreeM2M(SUMA_M2M_STRUCT *M2M)
00042 {
00043    static char FuncName[]={"SUMA_FreeM2M"};
00044    int i;
00045    
00046    SUMA_ENTRY;
00047    
00048    if (!M2M) SUMA_RETURN(NULL);
00049    if (M2M->M2we_M1n) {
00050       for (i=0; i<M2M->M1Nn; ++i) { 
00051          if (M2M->M2we_M1n[i]) {
00052             SUMA_free(M2M->M2we_M1n[i]);
00053             M2M->M2we_M1n[i] = NULL;
00054          }
00055       }
00056       SUMA_free(M2M->M2we_M1n);
00057       M2M->M2we_M1n = NULL;
00058    }
00059    if (M2M->M2ne_M1n) {
00060       for (i=0; i<M2M->M1Nn; ++i) { 
00061          if (M2M->M2ne_M1n[i]) {
00062             SUMA_free(M2M->M2ne_M1n[i]);
00063             M2M->M2ne_M1n[i] = NULL;
00064          }
00065       }
00066       SUMA_free(M2M->M2ne_M1n);
00067       M2M->M2ne_M1n = NULL;
00068    }
00069    if (M2M->M1n) SUMA_free(M2M->M1n); M2M->M1n = NULL;
00070    if (M2M->M2t_M1n) SUMA_free(M2M->M2t_M1n); M2M->M2t_M1n= NULL;
00071    if (M2M->M2Nne_M1n) SUMA_free(M2M->M2Nne_M1n); M2M->M2Nne_M1n = NULL;
00072    if (M2M->M2pb_M1n) SUMA_free(M2M->M2pb_M1n); M2M->M2pb_M1n = NULL;
00073    if (M2M->M2p_M1n) SUMA_free(M2M->M2p_M1n); M2M->M2p_M1n = NULL;
00074    if (M2M->PD) SUMA_free(M2M->PD); M2M->PD = NULL;
00075    if (M2M->M1_IDcode) SUMA_free(M2M->M1_IDcode); M2M->M1_IDcode = NULL;
00076    if (M2M->M2_IDcode) SUMA_free(M2M->M2_IDcode); M2M->M2_IDcode = NULL;
00077 
00078    SUMA_free(M2M);
00079    SUMA_RETURN(NULL);     
00080 } 
00081   
00082 char *SUMA_M2M_node_Info (SUMA_M2M_STRUCT *M2M, int node)
00083 {
00084    static char FuncName[]={"SUMA_M2M_node_Info"};
00085    char *s = NULL;
00086    SUMA_STRING *SS = NULL;
00087    int i, found, j;
00088    
00089 
00090    SS = SUMA_StringAppend(NULL, NULL);
00091       
00092    if (!M2M) { SS = SUMA_StringAppend(SS,"NULL M2M"); goto CLEAN_RETURN; }
00093    
00094    if (M2M->M1_IDcode) { SS = SUMA_StringAppend_va(SS, "M1_IDcode %s\n", M2M->M1_IDcode); }
00095    else { SS = SUMA_StringAppend_va(SS, "M1_IDcode is NULL\n"); }
00096    if (M2M->M2_IDcode) { SS = SUMA_StringAppend_va(SS, "M2_IDcode %s\n", M2M->M2_IDcode); }
00097    else { SS = SUMA_StringAppend_va(SS, "M2_IDcode is NULL\n"); }
00098   
00099    i = 0; found = 0;
00100    while (i < M2M->M1Nn && !found) {
00101       if (M2M->M1n[i] == node) {
00102          found = 1;
00103       } else ++i;
00104    }
00105    
00106    if (!found) { SS = SUMA_StringAppend_va (SS, "Node %d not found in M2M->M1n", node); goto CLEAN_RETURN; }
00107    
00108    SS = SUMA_StringAppend_va (SS, "Mapping results for node %d (n1) of mesh 1 (M1):\n", M2M->M1n[i]);
00109    SS = SUMA_StringAppend_va (SS, "Index of triangle (t2) in mesh 2 (M2) hosting n1: %d\n", M2M->M2t_M1n[i]);
00110    SS = SUMA_StringAppend_va (SS, "Projection coordinates in t2 (%f,%f,%f)\n", M2M->M2p_M1n[3*i], M2M->M2p_M1n[3*i+1], M2M->M2p_M1n[3*i+2]);
00111    SS = SUMA_StringAppend_va (SS, "Projection barycentric coordinates in t2 (%g,%g)\n", M2M->M2pb_M1n[2*i], M2M->M2pb_M1n[2*i+1]);
00112    SS = SUMA_StringAppend_va (SS, "Projection distance of n1 onto t2 is: %g\n", M2M->PD[i]);
00113    SS = SUMA_StringAppend_va (SS, "Number of nodes (n2) in M2 considered neighbors to n1: %d\n", M2M->M2Nne_M1n[i]);
00114    SS = SUMA_StringAppend_va (SS, "n2   \tw2weight\n");
00115    for (j=0; j< M2M->M2Nne_M1n[i]; ++j) {
00116       SS = SUMA_StringAppend_va (SS, "%s\t%g\n", MV_format_fval2(M2M->M2ne_M1n[i][j], 5), M2M->M2we_M1n[i][j]);
00117    }
00118    
00119    
00120    CLEAN_RETURN:
00121    SUMA_SS2S(SS,s);
00122    
00123    SUMA_RETURN(s);
00124 } 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144  
00145 SUMA_M2M_STRUCT *SUMA_GetM2M_NN( SUMA_SurfaceObject *SO1, SUMA_SurfaceObject *SO2,
00146                                  int *oNL_1, int N_NL_1, float *PD_1, float dlim, 
00147                                  int NodeDbg)
00148 {
00149    static char FuncName[]={"SUMA_GetM2M_NN"};
00150    SUMA_M2M_STRUCT *M2M = NULL;
00151    int *NL_1 = NULL;
00152    int j, id, id2, nnt, k, nj, t3, j3;
00153    float *triNode0, *triNode1, *triNode2, *hit;
00154    float delta_t;
00155    double *wv, wgt[3], weight_tot; 
00156    float P0[3], P1[3], P2[3], N0[3];
00157    float Points[2][3];
00158    SUMA_MT_INTERSECT_TRIANGLE *MTI = NULL;
00159    struct timeval tt; 
00160    SUMA_Boolean LocalHead = NOPE;
00161    
00162    SUMA_ENTRY;
00163    
00164    SUMA_etime (&tt, 0);
00165    
00166    if (!SO1 || !SO2) { SUMA_SL_Err("NULL input"); goto CLEAN_EXIT; }
00167    if (!oNL_1) N_NL_1 = SO1->N_Node;
00168    if (N_NL_1 < 1) { SUMA_SL_Err("No nodes to consider"); goto CLEAN_EXIT; }
00169    if (dlim <= 0) dlim = 100.0; 
00170    
00171    M2M = SUMA_NewM2M(SO1->idcode_str, N_NL_1, SO2->idcode_str);
00172    if (!M2M) { SUMA_SL_Crit("Failed to create M2M"); goto CLEAN_EXIT; }
00173    
00174    
00175    if (!oNL_1) { for (j=0; j<N_NL_1; ++j) M2M->M1n[j]= j; }
00176    else { for (j=0; j<N_NL_1; ++j) M2M->M1n[j]= oNL_1[j]; }
00177    
00178    if (!PD_1) PD_1 = SO1->NodeNormList;
00179    
00180    for (j = 0; j < M2M->M1Nn; ++j) {
00181       j3    = 3 * j;
00182       nj    = M2M->M1n[j];
00183       id    = SO1->NodeDim * nj;
00184       P0[0] = SO1->NodeList[id];
00185       P0[1] = SO1->NodeList[id+1];
00186       P0[2] = SO1->NodeList[id+2];
00187 
00188       N0[0] = PD_1[id  ];
00189       N0[1] = PD_1[id+1];
00190       N0[2] = PD_1[id+2];
00191       
00192       SUMA_POINT_AT_DISTANCE(N0, P0, dlim, Points);
00193       
00194       P1[0] = Points[0][0];
00195       P1[1] = Points[0][1];
00196       P1[2] = Points[0][2];
00197       P2[0] = Points[1][0];
00198       P2[1] = Points[1][1];
00199       P2[2] = Points[1][2];
00200  
00201       
00202       MTI = SUMA_MT_intersect_triangle(P0, P1, SO2->NodeList, SO2->N_Node, SO2->FaceSetList, SO2->N_FaceSet, MTI);
00203       if (LocalHead) fprintf(SUMA_STDERR,"%s: number of hits for node %d : %d\n", FuncName, nj, MTI->N_hits);  
00204       if (MTI->N_hits ==0) {
00205          if (LocalHead) fprintf(SUMA_STDERR, "%s: Could not find hit for node %d in either direction.\n", FuncName, nj);
00206          M2M->M2Nne_M1n[j] = 0;
00207          M2M->M2t_M1n[j] = -1;
00208          M2M->PD[j] = 0.0;
00209          M2M->M2pb_M1n[2*j  ] = -1.0;
00210          M2M->M2pb_M1n[2*j+1] = -1.0;
00211          j3 = 3*j; hit = &(M2M->M2p_M1n[j3]);
00212          hit[0] = -1.0;
00213          hit[1] = -1.0;
00214          hit[2] = -1.0;      
00215       } else {
00216          if (LocalHead) {
00217              for (k = 0; k < MTI->N_el; k++) {
00218                if (MTI->isHit[k] == YUP) fprintf(SUMA_STDERR, "%s: hit %d: %f (%f, %f)\n",FuncName, k, MTI->t[k], MTI->u[k], MTI->v[k]);
00219             }
00220          }
00221          M2M->M2t_M1n[j] = MTI->ifacemin;
00222          M2M->PD[j] = MTI->t[MTI->ifacemin];
00223          
00224          
00225          M2M->M2Nne_M1n[j] = 3; 
00226          M2M->M2ne_M1n[j] = (int *)SUMA_malloc(M2M->M2Nne_M1n[j]*sizeof(int));
00227                                          *(M2M->M2ne_M1n[j]  ) = MTI->inodemin;   
00228          nnt = (MTI->inodeminlocal+1)%3; *(M2M->M2ne_M1n[j]+1) = SO2->FaceSetList[3*MTI->ifacemin+nnt]; 
00229          nnt = (MTI->inodeminlocal+2)%3; *(M2M->M2ne_M1n[j]+2) = SO2->FaceSetList[3*MTI->ifacemin+nnt]; 
00230 
00231          
00232          M2M->M2we_M1n[j] = (double *)SUMA_malloc(M2M->M2Nne_M1n[j]*sizeof(double));
00233 
00234          
00235          j3 = 3*j; hit = &(M2M->M2p_M1n[j3]);
00236          hit[0] = MTI->P[0];
00237          hit[1] = MTI->P[1];
00238          hit[2] = MTI->P[2];
00239          if (M2M->M1n[j] == NodeDbg) {
00240             fprintf(SUMA_STDERR, "%s: Hit coords for node %d of M1: \n"
00241                                  "%f %f %f\n"
00242                                  "%f %f %f\n", FuncName, M2M->M1n[j], hit[0], hit[1], hit[2], 
00243                                  M2M->M2p_M1n[j3], M2M->M2p_M1n[j3+1], M2M->M2p_M1n[j3+2]);
00244          }
00245          
00246          M2M->M2pb_M1n[2*j  ] = MTI->u[MTI->ifacemin];
00247          M2M->M2pb_M1n[2*j+1] = MTI->v[MTI->ifacemin];
00248 
00249 
00250 
00251 
00252             
00253             t3 = 3*MTI->ifacemin;
00254             triNode0 = &(SO2->NodeList[ 3*M2M->M2ne_M1n[j][0] ]);
00255             triNode1 = &(SO2->NodeList[ 3*M2M->M2ne_M1n[j][1] ]);
00256             triNode2 = &(SO2->NodeList[ 3*M2M->M2ne_M1n[j][2] ]);
00257 
00258          SUMA_TRI_AREA( ((MTI->P)), triNode1, triNode2, wgt[0] ); 
00259          SUMA_TRI_AREA( ((MTI->P)), triNode0, triNode2, wgt[1] ); 
00260          SUMA_TRI_AREA( ((MTI->P)), triNode0, triNode1, wgt[2] ); 
00261 
00262          weight_tot =  wgt[0] + wgt[1] + wgt[2];
00263 
00264          wv = M2M->M2we_M1n[j];
00265          if (weight_tot) {
00266             wv[0] = wgt[0] / weight_tot;
00267             wv[1] = wgt[1] / weight_tot;
00268             wv[2] = wgt[2] / weight_tot;
00269          }else { 
00270             wv[0] = wv[1] =  wv[2] = 1.0/3.0;
00271          }
00272       }
00273 
00274       
00275       if (!(j%500) && j) {
00276          delta_t = SUMA_etime(&tt, 1);
00277          fprintf (SUMA_STDERR, " [%d]/[%d] %.2f/100%% completed. Dt = %.2f min done of %.2f min total\r" ,  j, N_NL_1, (float)j / N_NL_1 * 100, delta_t/60, delta_t/j * N_NL_1/60);
00278          if (LocalHead) {
00279             char *s = NULL;
00280             s = SUMA_M2M_node_Info(M2M, M2M->M1n[j]);
00281             fprintf(SUMA_STDERR,"\n***\n%s\n***\n", s); 
00282             SUMA_free(s); s = NULL;
00283          }
00284       }
00285 
00286    }
00287 
00288    if (LocalHead) {
00289       delta_t = SUMA_etime(&tt, 1);
00290       fprintf (SUMA_STDERR, " [%d]/[%d] %.2f/100%% completed. Dt = %.2f min done of %.2f min total\r" ,  j, N_NL_1, (float)j / N_NL_1 * 100, delta_t/60, delta_t/j * N_NL_1/60);
00291       fprintf (SUMA_STDERR, "\n");
00292    }
00293 
00294    CLEAN_EXIT:
00295    if (MTI) MTI = SUMA_Free_MT_intersect_triangle(MTI); 
00296 
00297    
00298    SUMA_RETURN(M2M);
00299 }
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 float *SUMA_M2M_interpolate(SUMA_M2M_STRUCT *M2M, float *far_data, int ncol, int nrow, SUMA_INDEXING_ORDER d_order, int useClosest )
00318 {
00319    static char FuncName[]={"SUMA_M2M_interpolate"};
00320    int j, k, i, nk, nkid, njid, N_k, nj;
00321    float *dt=NULL;
00322    SUMA_Boolean LocalHead = NOPE;
00323 
00324    SUMA_ENTRY;
00325    
00326    if (!M2M || !far_data) {
00327       SUMA_SL_Err("NULL input");
00328       SUMA_RETURN(dt);
00329    }
00330    
00331    dt = (float *)SUMA_calloc(M2M->M1Nn*ncol, sizeof(float));
00332    if (!dt) { SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(dt); }
00333 
00334    
00335    if (d_order == SUMA_ROW_MAJOR) {
00336       if (!useClosest) {
00337          SUMA_LH("Using all neighbors, ROW MAJOR interpolation");
00338          for (j=0; j<M2M->M1Nn; ++j) {
00339             nj = M2M->M1n[j]; 
00340             njid = j*ncol; 
00341             N_k = M2M->M2Nne_M1n[j]; 
00342             for (i=0; i<ncol; ++i) { 
00343                dt[njid+i] = 0.0;
00344                for (k=0; k<N_k; ++k) { 
00345                   nk = M2M->M2ne_M1n[j][k]; 
00346                   nkid = nk * ncol; 
00347                   dt[njid+i] += far_data[nkid+i] * M2M->M2we_M1n[j][k]; 
00348                }
00349             }
00350          }   
00351       } else {
00352          SUMA_LH("Using immediate neighbor, ROW MAJOR interpolation");
00353          k = 0; 
00354          for (j=0; j<M2M->M1Nn; ++j) {
00355             nj = M2M->M1n[j]; 
00356             njid = j*ncol; 
00357             for (i=0; i<ncol; ++i) { 
00358                dt[njid+i] = 0.0;      
00359                if (M2M->M2Nne_M1n[j]) { 
00360                   
00361                   nk = M2M->M2ne_M1n[j][k]; 
00362                   nkid = nk * ncol; 
00363                   dt[njid+i] += far_data[nkid+i];
00364                }
00365             }
00366          }
00367       }
00368    } else if (d_order == SUMA_COLUMN_MAJOR) {
00369       if (!useClosest) {
00370          SUMA_LH("Using all neighbors, COLUMN MAJOR interpolation");
00371          for (i=0; i<ncol; ++i) { 
00372             for (j=0; j<M2M->M1Nn; ++j) { 
00373                nj = M2M->M1n[j]; 
00374                njid = j+i*M2M->M1Nn; 
00375                dt[njid] = 0;
00376                N_k = M2M->M2Nne_M1n[j]; 
00377                for (k=0; k<N_k; ++k) { 
00378                   nk = M2M->M2ne_M1n[j][k];
00379                   nkid = nk + i*nrow;  
00380                   dt[njid] += far_data[nkid]* M2M->M2we_M1n[j][k];
00381                }
00382             }
00383          }
00384       } else {
00385          SUMA_LH("Using immediate neighbor, COLUMN MAJOR interpolation");
00386          k = 0;   
00387          for (i=0; i<ncol; ++i) { 
00388             for (j=0; j<M2M->M1Nn; ++j) { 
00389                nj = M2M->M1n[j]; 
00390                njid = j+i*M2M->M1Nn; 
00391                dt[njid] = 0;
00392                N_k = M2M->M2Nne_M1n[j]; 
00393                if (M2M->M2Nne_M1n[j]) { 
00394                   
00395                   nk = M2M->M2ne_M1n[j][k];
00396                   nkid = nk + i*nrow;  
00397                   dt[njid] += far_data[nkid];
00398                }
00399             }
00400          }
00401       }
00402    } else {
00403       SUMA_SL_Err("Bad order option");
00404       SUMA_free(dt); dt = NULL; SUMA_RETURN(dt); 
00405    }
00406 
00407    SUMA_RETURN(dt); 
00408 }