77
80
node->index= index;
78
81
copy_v3_v3(node->co, co);
79
if(nor) copy_v3_v3(node->nor, nor);
82
if (nor) copy_v3_v3(node->nor, nor);
82
85
static KDTreeNode *kdtree_balance(KDTreeNode *nodes, int totnode, int axis)
101
while (right > left) {
99
102
co= nodes[right].co[axis];
104
while(nodes[++i].co[axis] < co);
105
while(nodes[--j].co[axis] > co && j>left);
107
while (nodes[++i].co[axis] < co);
108
while (nodes[--j].co[axis] > co && j>left);
108
111
SWAP(KDTreeNode, nodes[i], nodes[j]);
111
114
SWAP(KDTreeNode, nodes[i], nodes[right]);
129
132
tree->root= kdtree_balance(tree->nodes, tree->totnode, 0);
132
static float squared_distance(float *v2, float *v1, float *n1, float *n2)
135
static float squared_distance(const float v2[3], const float v1[3], float *UNUSED(n1), float *n2)
134
137
float d[3], dist;
137
140
d[1]= v2[1]-v1[1];
138
141
d[2]= v2[2]-v1[2];
140
dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
142
//if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f)
143
if(n2 && d[0]*n2[0] + d[1]*n2[1] + d[2]*n2[2] < 0.0f)
143
dist = dot_v3v3(d, d);
145
//if (n1 && n2 && (dot_v3v3(n1, n2) < 0.0f))
147
/* can someone explain why this is done?*/
148
if (n2 && (dot_v3v3(d, n2) < 0.0f)) {
164
170
min_dist= squared_distance(root->co,co,root->nor,nor);
166
if(co[root->d] < root->co[root->d]) {
172
if (co[root->d] < root->co[root->d]) {
168
174
stack[cur++]=root->right;
170
176
stack[cur++]=root->left;
174
180
stack[cur++]=root->left;
176
182
stack[cur++]=root->right;
182
188
cur_dist = node->co[node->d] - co[node->d];
185
191
cur_dist= -cur_dist*cur_dist;
187
if(-cur_dist<min_dist){
193
if (-cur_dist<min_dist) {
188
194
cur_dist=squared_distance(node->co,co,node->nor,nor);
189
if(cur_dist<min_dist){
195
if (cur_dist<min_dist) {
190
196
min_dist=cur_dist;
194
200
stack[cur++]=node->left;
197
203
stack[cur++]=node->right;
200
206
cur_dist= cur_dist*cur_dist;
202
if(cur_dist<min_dist){
208
if (cur_dist<min_dist) {
203
209
cur_dist=squared_distance(node->co,co,node->nor,nor);
204
if(cur_dist<min_dist){
210
if (cur_dist<min_dist) {
205
211
min_dist=cur_dist;
209
215
stack[cur++]=node->right;
212
218
stack[cur++]=node->left;
214
if(cur+3 > totstack){
220
if (cur+3 > totstack) {
215
221
KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
216
222
memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
217
if(stack != defaultstack)
223
if (stack != defaultstack)
218
224
MEM_freeN(stack);
225
231
nearest->index= min_node->index;
226
232
nearest->dist= sqrt(min_dist);
227
233
copy_v3_v3(nearest->co, min_node->co);
230
if(stack != defaultstack)
236
if (stack != defaultstack)
231
237
MEM_freeN(stack);
233
239
return min_node->index;
254
260
/* finds the nearest n entries in tree to specified coordinates */
255
261
int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest)
257
KDTreeNode *root, *node=0;
263
KDTreeNode *root, *node= NULL;
258
264
KDTreeNode **stack, *defaultstack[100];
260
266
int i, totstack, cur=0, found=0;
265
271
stack= defaultstack;
270
276
cur_dist= squared_distance(root->co,co,root->nor,nor);
271
277
add_nearest(nearest,&found,n,root->index,cur_dist,root->co);
273
if(co[root->d] < root->co[root->d]) {
279
if (co[root->d] < root->co[root->d]) {
275
281
stack[cur++]=root->right;
277
283
stack[cur++]=root->left;
281
287
stack[cur++]=root->left;
283
289
stack[cur++]=root->right;
289
295
cur_dist = node->co[node->d] - co[node->d];
292
298
cur_dist= -cur_dist*cur_dist;
294
if(found<n || -cur_dist<nearest[found-1].dist){
300
if (found<n || -cur_dist<nearest[found-1].dist) {
295
301
cur_dist=squared_distance(node->co,co,node->nor,nor);
297
if(found<n || cur_dist<nearest[found-1].dist)
303
if (found<n || cur_dist<nearest[found-1].dist)
298
304
add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
301
307
stack[cur++]=node->left;
304
310
stack[cur++]=node->right;
307
313
cur_dist= cur_dist*cur_dist;
309
if(found<n || cur_dist<nearest[found-1].dist){
315
if (found<n || cur_dist<nearest[found-1].dist) {
310
316
cur_dist=squared_distance(node->co,co,node->nor,nor);
311
if(found<n || cur_dist<nearest[found-1].dist)
317
if (found<n || cur_dist<nearest[found-1].dist)
312
318
add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
315
321
stack[cur++]=node->right;
318
324
stack[cur++]=node->left;
320
if(cur+3 > totstack){
326
if (cur+3 > totstack) {
321
327
KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
322
328
memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
323
if(stack != defaultstack)
329
if (stack != defaultstack)
324
330
MEM_freeN(stack);
330
for(i=0; i<found; i++)
336
for (i=0; i<found; i++)
331
337
nearest[i].dist= sqrt(nearest[i].dist);
333
if(stack != defaultstack)
339
if (stack != defaultstack)
334
340
MEM_freeN(stack);
341
347
const KDTreeNearest *kda = a;
342
348
const KDTreeNearest *kdb = b;
344
if(kda->dist < kdb->dist)
350
if (kda->dist < kdb->dist)
346
else if(kda->dist > kdb->dist)
352
else if (kda->dist > kdb->dist)
353
359
KDTreeNearest *to;
355
if(found+1 > *totfoundstack) {
361
if (found+1 > *totfoundstack) {
356
362
KDTreeNearest *temp=MEM_callocN((*totfoundstack+50)*sizeof(KDTreeNode), "psys_treefoundstack");
357
363
memcpy(temp, *ptn, *totfoundstack * sizeof(KDTreeNearest));
361
367
*totfoundstack+=50;
370
376
int BLI_kdtree_range_search(KDTree *tree, float range, float *co, float *nor, KDTreeNearest **nearest)
372
KDTreeNode *root, *node=0;
378
KDTreeNode *root, *node= NULL;
373
379
KDTreeNode **stack, *defaultstack[100];
374
380
KDTreeNearest *foundstack=NULL;
375
381
float range2 = range*range, dist2;
376
382
int totstack, cur=0, found=0, totfoundstack=0;
378
if(!tree || !tree->root)
384
if (!tree || !tree->root)
381
387
stack= defaultstack;
384
390
root= tree->root;
386
if(co[root->d] + range < root->co[root->d]) {
392
if (co[root->d] + range < root->co[root->d]) {
388
394
stack[cur++]=root->left;
390
else if(co[root->d] - range > root->co[root->d]) {
396
else if (co[root->d] - range > root->co[root->d]) {
392
398
stack[cur++]=root->right;
395
401
dist2 = squared_distance(root->co, co, root->nor, nor);
397
403
add_in_range(&foundstack, found++, &totfoundstack, root->index, dist2, root->co);
400
406
stack[cur++]=root->left;
402
408
stack[cur++]=root->right;
408
if(co[node->d] + range < node->co[node->d]) {
414
if (co[node->d] + range < node->co[node->d]) {
410
416
stack[cur++]=node->left;
412
else if(co[node->d] - range > node->co[node->d]) {
418
else if (co[node->d] - range > node->co[node->d]) {
414
420
stack[cur++]=node->right;
417
423
dist2 = squared_distance(node->co, co, node->nor, nor);
419
425
add_in_range(&foundstack, found++, &totfoundstack, node->index, dist2, node->co);
422
428
stack[cur++]=node->left;
424
430
stack[cur++]=node->right;
427
if(cur+3 > totstack){
433
if (cur+3 > totstack) {
428
434
KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
429
435
memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
430
if(stack != defaultstack)
436
if (stack != defaultstack)
431
437
MEM_freeN(stack);
437
if(stack != defaultstack)
443
if (stack != defaultstack)
438
444
MEM_freeN(stack);
441
447
qsort(foundstack, found, sizeof(KDTreeNearest), range_compare);
443
449
*nearest = foundstack;