1 |
/* |
2 |
========================================================================= |
3 |
k-nearest neighbour lookup routines for out-of-core octree data structure |
4 |
|
5 |
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
6 |
(c) Lucerne University of Applied Sciences and Arts, |
7 |
supported by the Swiss National Science Foundation (SNSF, #147053) |
8 |
========================================================================= |
9 |
|
10 |
$Id: oocnn.h,v 2.1 2016/05/17 17:39:47 rschregle Exp $ |
11 |
*/ |
12 |
|
13 |
|
14 |
|
15 |
#ifndef OOC_SEARCH_H |
16 |
#define OOC_SEARCH_H |
17 |
|
18 |
#include "oococt.h" |
19 |
|
20 |
/* Priority queue node for octree lookups */ |
21 |
typedef struct { |
22 |
float dist2; /* Record's *SQUARED* distance to query point */ |
23 |
unsigned idx; /* Record's index in queue buffer */ |
24 |
} OOC_SearchQueueNode; |
25 |
|
26 |
|
27 |
/* Priority queue for octree lookups. Note that we explicitly store the |
28 |
* NN candidates in a local in-core buffer nnRec for later retrieval |
29 |
* without incurring additional disk I/O. */ |
30 |
typedef struct { |
31 |
OOC_SearchQueueNode *node; |
32 |
unsigned len, tail, recSize; |
33 |
void *nnRec; |
34 |
} OOC_SearchQueue; |
35 |
|
36 |
|
37 |
/* Filter for k-NN search; records are accepted for which func(rec, data) |
38 |
* returns nonzero */ |
39 |
typedef struct { |
40 |
int (*func)(void *rec, void *data); |
41 |
void *data; |
42 |
} OOC_SearchFilter; |
43 |
|
44 |
#ifdef __cplusplus |
45 |
extern "C" { |
46 |
#endif |
47 |
|
48 |
float OOC_FindNearest (OOC_Octree *oct, OOC_Node *node, |
49 |
OOC_DataIdx dataIdx, const FVECT org, float size, |
50 |
const FVECT key, const OOC_SearchFilter *filter, |
51 |
OOC_SearchQueue *queue, float maxDist2); |
52 |
/* Find k nearest neighbours (where k = queue -> len) within a maximum |
53 |
* SQUARED distance of maxDist2 around key. Returns the corresponding |
54 |
* data records with their SQUARED distances in the search queue |
55 |
* (queue -> node [0] .. queue -> node [queue -> tail - 1]), with the |
56 |
* furthest neighbour at the queue head and queue->tail <= queue->len. |
57 |
* |
58 |
* This is a recursive function requiring params for the current node: |
59 |
* DataIdx is the data offset for records in the current node, which is |
60 |
* necessary for implied addressing into the leaf file. Org and size are |
61 |
* the origin and size of the current node's bounding box. |
62 |
* |
63 |
* An optional filter may be specified; if filter != NULL, filter->func() |
64 |
* is called for each potential nearest neighbour along with additional |
65 |
* data provided by the caller; see OOC_SearchFilter typedef above. |
66 |
* |
67 |
* Return value is the SQUARED distance to furthest neighbour on success, |
68 |
* else -1 on failure. */ |
69 |
|
70 |
|
71 |
float OOC_Find1Nearest (OOC_Octree *oct, OOC_Node *node, |
72 |
OOC_DataIdx dataIdx, const FVECT org, float size, |
73 |
const FVECT key, const OOC_SearchFilter *filter, |
74 |
void *nnRec, float maxDist2); |
75 |
/* Find single nearest neighbour within max SQUARED distance maxDist2 |
76 |
* around key and copy corresponding record in nnRec. This is an |
77 |
* optimised version of OOC_FindNearest() without a search queue */ |
78 |
|
79 |
|
80 |
int OOC_InitNearest (OOC_SearchQueue *squeue, |
81 |
unsigned len, unsigned recSize); |
82 |
/* Initialise NN search queue of length len and local buffa for records |
83 |
* of size recSize; precondition to calling OOC_FindNearest() */ |
84 |
|
85 |
|
86 |
void *OOC_GetNearest (const OOC_SearchQueue *queue, unsigned idx); |
87 |
/* Return pointer to record at pos idx in search queue after calling |
88 |
* OOC_FindNearest() */ |
89 |
|
90 |
#ifdef __cplusplus |
91 |
} |
92 |
#endif |
93 |
|
94 |
#endif |