/** * Input arguments: dataset (matrix), params (struct) * Output arguments: index (pointer to index), params (struct), speedup(double) */ static void _build_index(int nOutArray, mxArray* OutArray[], int nInArray, const mxArray* InArray[]) { /* Check the number of input arguments */ if(nInArray != 2) { mexErrMsgTxt("Incorrect number of input arguments"); } /* Check the number of output arguments */ if ((nOutArray == 0)||(nOutArray > 3)) { mexErrMsgTxt("Incorrect number of outputs."); } const mxArray* datasetMat = InArray[0]; check_allowed_type(datasetMat); int dcount = mxGetN(datasetMat); int length = mxGetM(datasetMat); const mxArray* pStruct = InArray[1]; /* get index parameters */ FLANNParameters p; matlabStructToFlannStruct(pStruct, p); float speedup = -1; TypedIndex* typedIndex = new TypedIndex(); if (mxIsSingle(datasetMat)) { float* dataset = (float*) mxGetData(datasetMat); typedIndex->index = flann_build_index_float(dataset,dcount,length, &speedup, &p); typedIndex->type = FLANN_FLOAT32; } else if (mxIsDouble(datasetMat)) { double* dataset = (double*) mxGetData(datasetMat); typedIndex->index = flann_build_index_double(dataset,dcount,length, &speedup, &p); typedIndex->type = FLANN_FLOAT64; } else if (mxIsUint8(datasetMat)) { unsigned char* dataset = (unsigned char*) mxGetData(datasetMat); typedIndex->index = flann_build_index_byte(dataset,dcount,length, &speedup, &p); typedIndex->type = FLANN_UINT8; } else if (mxIsInt32(datasetMat)) { int* dataset = (int*) mxGetData(datasetMat); typedIndex->index = flann_build_index_int(dataset,dcount,length, &speedup, &p); typedIndex->type = FLANN_INT32; } mxClassID classID; if (sizeof(flann_index_t)==4) { classID = mxUINT32_CLASS; } else if (sizeof(flann_index_t)==8) { classID = mxUINT64_CLASS; } /* Allocate memory for Output Matrix */ OutArray[0] = mxCreateNumericMatrix(1, 1, classID, mxREAL); /* Get pointer to Output matrix and store result*/ TypedIndex** pOut = (TypedIndex**)mxGetData(OutArray[0]); pOut[0] = typedIndex; if (nOutArray > 1) { OutArray[1] = flannStructToMatlabStruct(p); } if (nOutArray > 2) { OutArray[2] = mxCreateDoubleMatrix(1, 1, mxREAL); double* pSpeedup = mxGetPr(OutArray[2]); *pSpeedup = speedup; } }
int NearestNode(MacroMesh *m, real *xphy) { int nearest = -1; #ifdef _WITH_FLANN // Use of flann library: faster ??? static bool is_ready = false; static struct FLANNParameters p; static float speedup; static flann_index_t findex; // at first call: construct the index // TO DO free the index when finished if (!is_ready) { printf("Using flann: build search index...\n"); p = DEFAULT_FLANN_PARAMETERS; p.algorithm = FLANN_INDEX_AUTOTUNED; p.target_precision = 0.9; /* want 90% target precision */ #if real == double findex = flann_build_index_double(m->node, m->nbnodes, 3, &speedup, &p); #else findex = flann_build_index_float(m->node, m->nbnodes, 3, &speedup, &p); #endif is_ready = true; } // number of nearest neighbors to search int nn = 1; int result[nn]; real dists[nn]; // compute the nn nearest-neighbors of each point in xphy // with index construction // flann_find_nearest_neighbors_real(m->node, // nodes list // m->nbnodes, // number of nodes // 3, // space dim // xphy, // 1, // number of points in xphy // result, // nearest points indices // dists, // distances // nn, // &p); // flan struct #if real == double flann_find_nearest_neighbors_index_double(findex,// index xphy, 1, // number of points in xphy result, // nearest points indices dists, // distances nn, &p); // flan struct #else flann_find_nearest_neighbors_index_float(findex,// index xphy, 1, // number of points in xphy result, // nearest points indices dists, // distances nn, &p); // flan struct #endif nearest = result[0]; // printf("xphy=%f %f %f nearest=%d %f %f %f \n", // xphy[0],xphy[1],xphy[2],nearest+1, // m->node[0+nearest*3],m->node[1+nearest*3],m->node[2+nearest*3]); #else // Do not use FLANN library. // slow version: loops on all the points real d = 1e20; for(int ino = 0; ino < m->nbnodes; ino++){ real d2 = Dist(xphy, m->node + 3 * ino); if (d2 < d) { nearest = ino; d = d2; } } #endif return nearest; }