Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/adtree.cpp
3206 views
1
#include <mystdlib.h>
2
3
4
#include <myadt.hpp>
5
// class DenseMatrix;
6
#include <gprim.hpp>
7
8
namespace netgen
9
{
10
11
12
/* ******************************* ADTree ******************************* */
13
14
15
ADTreeNode :: ADTreeNode(int adim)
16
{
17
pi = -1;
18
19
left = NULL;
20
right = NULL;
21
father = NULL;
22
nchilds = 0;
23
dim = adim;
24
data = new float [dim];
25
boxmin = NULL;
26
boxmax = NULL;
27
}
28
29
30
31
32
ADTreeNode :: ~ADTreeNode()
33
{
34
delete data;
35
}
36
37
38
ADTree :: ADTree (int adim, const float * acmin,
39
const float * acmax)
40
: ela(0), stack(1000), stackdir(1000)
41
{
42
dim = adim;
43
cmin = new float [dim];
44
cmax = new float [dim];
45
memcpy (cmin, acmin, dim * sizeof(float));
46
memcpy (cmax, acmax, dim * sizeof(float));
47
48
root = new ADTreeNode (dim);
49
root->sep = (cmin[0] + cmax[0]) / 2;
50
root->boxmin = new float [dim];
51
root->boxmax = new float [dim];
52
memcpy (root->boxmin, cmin, dim * sizeof(float));
53
memcpy (root->boxmax, cmax, dim * sizeof(float));
54
}
55
56
ADTree :: ~ADTree ()
57
{
58
;
59
}
60
61
void ADTree :: Insert (const float * p, int pi)
62
{
63
ADTreeNode *node(NULL);
64
ADTreeNode *next;
65
int dir;
66
int lr(1);
67
68
float * bmin = new float [dim];
69
float * bmax = new float [dim];
70
71
memcpy (bmin, cmin, dim * sizeof(float));
72
memcpy (bmax, cmax, dim * sizeof(float));
73
74
75
next = root;
76
dir = 0;
77
while (next)
78
{
79
node = next;
80
81
if (node->pi == -1)
82
{
83
memcpy (node->data, p, dim * sizeof(float));
84
node->pi = pi;
85
86
if (ela.Size() < pi+1)
87
ela.SetSize (pi+1);
88
ela[pi] = node;
89
90
return;
91
}
92
93
if (node->sep > p[dir])
94
{
95
next = node->left;
96
bmax[dir] = node->sep;
97
lr = 0;
98
}
99
else
100
{
101
next = node->right;
102
bmin[dir] = node->sep;
103
lr = 1;
104
}
105
106
dir++;
107
if (dir == dim)
108
dir = 0;
109
}
110
111
112
next = new ADTreeNode(dim);
113
memcpy (next->data, p, dim * sizeof(float));
114
next->pi = pi;
115
next->sep = (bmin[dir] + bmax[dir]) / 2;
116
next->boxmin = bmin;
117
next->boxmax = bmax;
118
119
if (ela.Size() < pi+1)
120
ela.SetSize (pi+1);
121
ela[pi] = next;
122
123
124
if (lr)
125
node->right = next;
126
else
127
node->left = next;
128
next -> father = node;
129
130
while (node)
131
{
132
node->nchilds++;
133
node = node->father;
134
}
135
}
136
137
void ADTree :: DeleteElement (int pi)
138
{
139
ADTreeNode * node = ela[pi];
140
141
node->pi = -1;
142
143
node = node->father;
144
while (node)
145
{
146
node->nchilds--;
147
node = node->father;
148
}
149
}
150
151
152
void ADTree :: SetCriterion (ADTreeCriterion & acriterion)
153
{
154
criterion = & acriterion;
155
}
156
157
158
void ADTree :: Reset ()
159
{
160
stack.Elem(1) = root;
161
stackdir.Elem(1) = 0;
162
stackindex = 1;
163
}
164
165
166
int ADTree:: Next ()
167
{
168
ADTreeNode *node;
169
int dir;
170
171
if (stackindex == 0)
172
return -1;
173
174
do
175
{
176
node = stack.Get(stackindex);
177
dir = stackdir.Get(stackindex);
178
stackindex --;
179
180
if (criterion -> Eval(node))
181
{
182
int ndir = dir + 1;
183
if (ndir == dim)
184
ndir = 0;
185
186
if (node -> left && criterion -> Eval (node->left))
187
{
188
stackindex ++;
189
stack.Elem(stackindex) = node -> left;
190
stackdir.Elem(stackindex) = ndir;
191
}
192
if (node->right && criterion -> Eval (node -> right))
193
{
194
stackindex++;
195
stack.Elem(stackindex) = node->right;
196
stackdir.Elem(stackindex) = ndir;
197
}
198
199
if (node -> pi != -1)
200
return node->pi;
201
}
202
}
203
while (stackindex > 0);
204
205
return -1;
206
}
207
208
209
void ADTree :: GetMatch (ARRAY <int> & matches)
210
{
211
int nodenr;
212
213
Reset();
214
215
while ( (nodenr = Next()) != -1)
216
matches.Append (nodenr);
217
}
218
219
220
void ADTree :: PrintRec (ostream & ost, const ADTreeNode * node) const
221
{
222
223
if (node->data)
224
{
225
ost << node->pi << ": ";
226
ost << node->nchilds << " children , ";
227
for (int i = 0; i < dim; i++)
228
ost << node->data[i] << " ";
229
ost << endl;
230
}
231
if (node->left)
232
{
233
ost << "l ";
234
PrintRec (ost, node->left);
235
}
236
if (node->right)
237
{
238
ost << "r ";
239
PrintRec (ost, node->right);
240
}
241
}
242
243
244
/* ******************************* ADTree3 ******************************* */
245
246
247
ADTreeNode3 :: ADTreeNode3()
248
{
249
pi = -1;
250
251
left = NULL;
252
right = NULL;
253
father = NULL;
254
nchilds = 0;
255
}
256
257
void ADTreeNode3 :: DeleteChilds ()
258
{
259
if (left)
260
{
261
left->DeleteChilds();
262
delete left;
263
left = NULL;
264
}
265
if (right)
266
{
267
right->DeleteChilds();
268
delete right;
269
right = NULL;
270
}
271
}
272
273
274
BlockAllocator ADTreeNode3 :: ball(sizeof (ADTreeNode3));
275
276
277
void * ADTreeNode3 :: operator new(size_t s)
278
{
279
return ball.Alloc();
280
}
281
282
void ADTreeNode3 :: operator delete (void * p)
283
{
284
ball.Free (p);
285
}
286
287
288
289
290
291
292
293
ADTree3 :: ADTree3 (const float * acmin,
294
const float * acmax)
295
: ela(0)
296
{
297
memcpy (cmin, acmin, 3 * sizeof(float));
298
memcpy (cmax, acmax, 3 * sizeof(float));
299
300
root = new ADTreeNode3;
301
root->sep = (cmin[0] + cmax[0]) / 2;
302
}
303
304
ADTree3 :: ~ADTree3 ()
305
{
306
root->DeleteChilds();
307
delete root;
308
}
309
310
311
void ADTree3 :: Insert (const float * p, int pi)
312
{
313
ADTreeNode3 *node(NULL);
314
ADTreeNode3 *next;
315
int dir;
316
int lr(0);
317
318
float bmin[3];
319
float bmax[3];
320
321
memcpy (bmin, cmin, 3 * sizeof(float));
322
memcpy (bmax, cmax, 3 * sizeof(float));
323
324
next = root;
325
dir = 0;
326
while (next)
327
{
328
node = next;
329
330
if (node->pi == -1)
331
{
332
memcpy (node->data, p, 3 * sizeof(float));
333
node->pi = pi;
334
335
if (ela.Size() < pi+1)
336
ela.SetSize (pi+1);
337
ela[pi] = node;
338
339
return;
340
}
341
342
if (node->sep > p[dir])
343
{
344
next = node->left;
345
bmax[dir] = node->sep;
346
lr = 0;
347
}
348
else
349
{
350
next = node->right;
351
bmin[dir] = node->sep;
352
lr = 1;
353
}
354
355
dir++;
356
if (dir == 3)
357
dir = 0;
358
}
359
360
361
next = new ADTreeNode3;
362
memcpy (next->data, p, 3 * sizeof(float));
363
next->pi = pi;
364
next->sep = (bmin[dir] + bmax[dir]) / 2;
365
366
367
if (ela.Size() < pi+1)
368
ela.SetSize (pi+1);
369
ela[pi] = next;
370
371
372
if (lr)
373
node->right = next;
374
else
375
node->left = next;
376
next -> father = node;
377
378
while (node)
379
{
380
node->nchilds++;
381
node = node->father;
382
}
383
}
384
385
void ADTree3 :: DeleteElement (int pi)
386
{
387
ADTreeNode3 * node = ela[pi];
388
389
node->pi = -1;
390
391
node = node->father;
392
while (node)
393
{
394
node->nchilds--;
395
node = node->father;
396
}
397
}
398
399
void ADTree3 :: GetIntersecting (const float * bmin,
400
const float * bmax,
401
ARRAY<int> & pis) const
402
{
403
static ARRAY<ADTreeNode3*> stack(1000);
404
static ARRAY<int> stackdir(1000);
405
ADTreeNode3 * node;
406
int dir, stacks;
407
408
stack.SetSize (1000);
409
stackdir.SetSize(1000);
410
pis.SetSize(0);
411
412
stack.Elem(1) = root;
413
stackdir.Elem(1) = 0;
414
stacks = 1;
415
416
while (stacks)
417
{
418
node = stack.Get(stacks);
419
dir = stackdir.Get(stacks);
420
stacks--;
421
422
if (node->pi != -1)
423
{
424
if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&
425
node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&
426
node->data[2] >= bmin[2] && node->data[2] <= bmax[2])
427
428
pis.Append (node->pi);
429
}
430
431
432
int ndir = dir+1;
433
if (ndir == 3)
434
ndir = 0;
435
436
if (node->left && bmin[dir] <= node->sep)
437
{
438
stacks++;
439
stack.Elem(stacks) = node->left;
440
stackdir.Elem(stacks) = ndir;
441
}
442
if (node->right && bmax[dir] >= node->sep)
443
{
444
stacks++;
445
stack.Elem(stacks) = node->right;
446
stackdir.Elem(stacks) = ndir;
447
}
448
}
449
}
450
451
void ADTree3 :: PrintRec (ostream & ost, const ADTreeNode3 * node) const
452
{
453
454
if (node->data)
455
{
456
ost << node->pi << ": ";
457
ost << node->nchilds << " children , ";
458
for (int i = 0; i < 3; i++)
459
ost << node->data[i] << " ";
460
ost << endl;
461
}
462
if (node->left)
463
PrintRec (ost, node->left);
464
if (node->right)
465
PrintRec (ost, node->right);
466
}
467
468
469
470
471
472
473
474
475
#ifdef ABC
476
477
/* ******************************* ADTree3Div ******************************* */
478
479
480
ADTreeNode3Div :: ADTreeNode3Div()
481
{
482
pi = 0;
483
484
int i;
485
for (i = 0; i < ADTN_DIV; i++)
486
childs[i] = NULL;
487
488
father = NULL;
489
nchilds = 0;
490
minx = 0;
491
dist = 1;
492
}
493
494
void ADTreeNode3Div :: DeleteChilds ()
495
{
496
int i;
497
for (i = 0; i < ADTN_DIV; i++)
498
if (childs[i])
499
{
500
childs[i]->DeleteChilds();
501
delete childs[i];
502
childs[i] = NULL;
503
}
504
}
505
506
507
BlockAllocator ADTreeNode3Div :: ball(sizeof (ADTreeNode3Div));
508
509
void * ADTreeNode3Div :: operator new(size_t)
510
{
511
return ball.Alloc();
512
}
513
514
void ADTreeNode3Div :: operator delete (void * p)
515
{
516
ball.Free (p);
517
}
518
519
520
521
522
523
524
525
ADTree3Div :: ADTree3Div (const float * acmin,
526
const float * acmax)
527
: ela(0)
528
{
529
memcpy (cmin, acmin, 3 * sizeof(float));
530
memcpy (cmax, acmax, 3 * sizeof(float));
531
532
root = new ADTreeNode3Div;
533
534
root->minx = cmin[0];
535
root->dist = (cmax[0] - cmin[0]) / ADTN_DIV;
536
537
// root->sep = (cmin[0] + cmax[0]) / 2;
538
}
539
540
ADTree3Div :: ~ADTree3Div ()
541
{
542
root->DeleteChilds();
543
delete root;
544
}
545
546
547
void ADTree3Div :: Insert (const float * p, int pi)
548
{
549
ADTreeNode3Div *node;
550
ADTreeNode3Div *next;
551
int dir;
552
int bag;
553
554
float bmin[3];
555
float bmax[3];
556
557
memcpy (bmin, cmin, 3 * sizeof(float));
558
memcpy (bmax, cmax, 3 * sizeof(float));
559
560
561
next = root;
562
dir = 0;
563
while (next)
564
{
565
node = next;
566
567
if (!node->pi)
568
{
569
memcpy (node->data, p, 3 * sizeof(float));
570
node->pi = pi;
571
572
if (ela.Size() < pi)
573
ela.SetSize (pi);
574
ela.Elem(pi) = node;
575
576
return;
577
}
578
579
double dx = (bmax[dir] - bmin[dir]) / ADTN_DIV;
580
bag = int ((p[dir]-bmin[dir]) / dx);
581
582
// (*testout) << "insert, bag = " << bag << endl;
583
584
if (bag < 0) bag = 0;
585
if (bag >= ADTN_DIV) bag = ADTN_DIV-1;
586
587
double nbmin = bmin[dir] + bag * dx;
588
double nbmax = bmin[dir] + (bag+1) * dx;
589
590
/*
591
(*testout) << "bmin, max = " << bmin[dir] << "-" << bmax[dir]
592
<< " p = " << p[dir];
593
*/
594
next = node->childs[bag];
595
bmin[dir] = nbmin;
596
bmax[dir] = nbmax;
597
598
// (*testout) << "new bmin, max = " << bmin[dir] << "-" << bmax[dir] << endl;
599
600
601
/*
602
if (node->sep > p[dir])
603
{
604
next = node->left;
605
bmax[dir] = node->sep;
606
lr = 0;
607
}
608
else
609
{
610
next = node->right;
611
bmin[dir] = node->sep;
612
lr = 1;
613
}
614
*/
615
616
dir++;
617
if (dir == 3)
618
dir = 0;
619
}
620
621
622
next = new ADTreeNode3Div;
623
memcpy (next->data, p, 3 * sizeof(float));
624
next->pi = pi;
625
626
next->minx = bmin[dir];
627
next->dist = (bmax[dir] - bmin[dir]) / ADTN_DIV;
628
// next->sep = (bmin[dir] + bmax[dir]) / 2;
629
630
631
if (ela.Size() < pi)
632
ela.SetSize (pi);
633
ela.Elem(pi) = next;
634
635
node->childs[bag] = next;
636
next -> father = node;
637
638
while (node)
639
{
640
node->nchilds++;
641
node = node->father;
642
}
643
}
644
645
void ADTree3Div :: DeleteElement (int pi)
646
{
647
ADTreeNode3Div * node = ela.Get(pi);
648
649
node->pi = 0;
650
651
node = node->father;
652
while (node)
653
{
654
node->nchilds--;
655
node = node->father;
656
}
657
}
658
659
void ADTree3Div :: GetIntersecting (const float * bmin,
660
const float * bmax,
661
ARRAY<int> & pis) const
662
{
663
static ARRAY<ADTreeNode3Div*> stack(1000);
664
static ARRAY<int> stackdir(1000);
665
ADTreeNode3Div * node;
666
int dir, i, stacks;
667
668
stack.SetSize (1000);
669
stackdir.SetSize(1000);
670
pis.SetSize(0);
671
672
stack.Elem(1) = root;
673
stackdir.Elem(1) = 0;
674
stacks = 1;
675
676
while (stacks)
677
{
678
node = stack.Get(stacks);
679
dir = stackdir.Get(stacks);
680
stacks--;
681
682
if (node->pi)
683
{
684
if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&
685
node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&
686
node->data[2] >= bmin[2] && node->data[2] <= bmax[2])
687
688
pis.Append (node->pi);
689
}
690
691
692
int ndir = dir+1;
693
if (ndir == 3)
694
ndir = 0;
695
696
int mini = int ( (bmin[dir] - node->minx) / node->dist );
697
int maxi = int ( (bmax[dir] - node->minx) / node->dist );
698
699
// (*testout) << "get int, mini, maxi = " << mini << ", " << maxi << endl;
700
if (mini < 0) mini = 0;
701
if (maxi >= ADTN_DIV) maxi = ADTN_DIV-1;
702
703
for (i = mini; i <= maxi; i++)
704
if (node->childs[i])
705
{
706
stacks++;
707
stack.Elem(stacks) = node->childs[i];
708
stackdir.Elem(stacks) = ndir;
709
}
710
711
712
/*
713
if (node->left && bmin[dir] <= node->sep)
714
{
715
stacks++;
716
stack.Elem(stacks) = node->left;
717
stackdir.Elem(stacks) = ndir;
718
}
719
if (node->right && bmax[dir] >= node->sep)
720
{
721
stacks++;
722
stack.Elem(stacks) = node->right;
723
stackdir.Elem(stacks) = ndir;
724
}
725
*/
726
}
727
}
728
729
void ADTree3Div :: PrintRec (ostream & ost, const ADTreeNode3Div * node) const
730
{
731
732
if (node->data)
733
{
734
ost << node->pi << ": ";
735
ost << node->nchilds << " children , ";
736
ost << " from " << node->minx << " - " << node->minx + node->dist*ADTN_DIV << " ";
737
for (int i = 0; i < 3; i++)
738
ost << node->data[i] << " ";
739
ost << endl;
740
}
741
int i;
742
for (i = 0; i < ADTN_DIV; i++)
743
if (node->childs[i])
744
PrintRec (ost, node->childs[i]);
745
}
746
747
748
749
750
751
752
753
754
755
756
757
758
/* ******************************* ADTree3M ******************************* */
759
760
761
ADTreeNode3M :: ADTreeNode3M()
762
{
763
int i;
764
for (i = 0; i < ADTN_SIZE; i++)
765
pi[i] = 0;
766
767
left = NULL;
768
right = NULL;
769
father = NULL;
770
nchilds = 0;
771
}
772
773
void ADTreeNode3M :: DeleteChilds ()
774
{
775
if (left)
776
{
777
left->DeleteChilds();
778
delete left;
779
left = NULL;
780
}
781
if (right)
782
{
783
right->DeleteChilds();
784
delete right;
785
right = NULL;
786
}
787
}
788
789
790
BlockAllocator ADTreeNode3M :: ball(sizeof (ADTreeNode3M));
791
792
void * ADTreeNode3M :: operator new(size_t)
793
{
794
return ball.Alloc();
795
}
796
797
void ADTreeNode3M :: operator delete (void * p)
798
{
799
ball.Free (p);
800
}
801
802
803
804
805
806
807
808
ADTree3M :: ADTree3M (const float * acmin,
809
const float * acmax)
810
: ela(0)
811
{
812
memcpy (cmin, acmin, 3 * sizeof(float));
813
memcpy (cmax, acmax, 3 * sizeof(float));
814
815
root = new ADTreeNode3M;
816
root->sep = (cmin[0] + cmax[0]) / 2;
817
}
818
819
ADTree3M :: ~ADTree3M ()
820
{
821
root->DeleteChilds();
822
delete root;
823
}
824
825
826
void ADTree3M :: Insert (const float * p, int pi)
827
{
828
ADTreeNode3M *node;
829
ADTreeNode3M *next;
830
int dir;
831
int lr;
832
int i;
833
float bmin[3];
834
float bmax[3];
835
836
memcpy (bmin, cmin, 3 * sizeof(float));
837
memcpy (bmax, cmax, 3 * sizeof(float));
838
839
next = root;
840
dir = 0;
841
while (next)
842
{
843
node = next;
844
845
for (i = 0; i < ADTN_SIZE; i++)
846
if (!node->pi[i])
847
{
848
memcpy (node->data[i], p, 3 * sizeof(float));
849
node->pi[i] = pi;
850
851
if (ela.Size() < pi)
852
ela.SetSize (pi);
853
ela.Elem(pi) = node;
854
855
return;
856
}
857
858
if (node->sep > p[dir])
859
{
860
next = node->left;
861
bmax[dir] = node->sep;
862
lr = 0;
863
}
864
else
865
{
866
next = node->right;
867
bmin[dir] = node->sep;
868
lr = 1;
869
}
870
871
dir++;
872
if (dir == 3)
873
dir = 0;
874
}
875
876
877
next = new ADTreeNode3M;
878
memcpy (next->data[0], p, 3 * sizeof(float));
879
next->pi[0] = pi;
880
next->sep = (bmin[dir] + bmax[dir]) / 2;
881
882
883
if (ela.Size() < pi)
884
ela.SetSize (pi);
885
ela.Elem(pi) = next;
886
887
888
if (lr)
889
node->right = next;
890
else
891
node->left = next;
892
next -> father = node;
893
894
while (node)
895
{
896
node->nchilds++;
897
node = node->father;
898
}
899
}
900
901
void ADTree3M :: DeleteElement (int pi)
902
{
903
ADTreeNode3M * node = ela.Get(pi);
904
905
int i;
906
for (i = 0; i < ADTN_SIZE; i++)
907
if (node->pi[i] == pi)
908
node->pi[i] = 0;
909
910
node = node->father;
911
while (node)
912
{
913
node->nchilds--;
914
node = node->father;
915
}
916
}
917
918
void ADTree3M :: GetIntersecting (const float * bmin,
919
const float * bmax,
920
ARRAY<int> & pis) const
921
{
922
static ARRAY<ADTreeNode3M*> stack(1000);
923
static ARRAY<int> stackdir(1000);
924
ADTreeNode3M * node;
925
int dir, i, stacks;
926
927
stack.SetSize (1000);
928
stackdir.SetSize(1000);
929
pis.SetSize(0);
930
931
stack.Elem(1) = root;
932
stackdir.Elem(1) = 0;
933
stacks = 1;
934
935
while (stacks)
936
{
937
node = stack.Get(stacks);
938
dir = stackdir.Get(stacks);
939
stacks--;
940
941
int * hpi = node->pi;
942
for (i = 0; i < ADTN_SIZE; i++)
943
if (hpi[i])
944
{
945
float * datai = &node->data[i][0];
946
if (datai[0] >= bmin[0] && datai[0] <= bmax[0] &&
947
datai[1] >= bmin[1] && datai[1] <= bmax[1] &&
948
datai[2] >= bmin[2] && datai[2] <= bmax[2])
949
950
pis.Append (node->pi[i]);
951
}
952
953
954
int ndir = dir+1;
955
if (ndir == 3)
956
ndir = 0;
957
958
if (node->left && bmin[dir] <= node->sep)
959
{
960
stacks++;
961
stack.Elem(stacks) = node->left;
962
stackdir.Elem(stacks) = ndir;
963
}
964
if (node->right && bmax[dir] >= node->sep)
965
{
966
stacks++;
967
stack.Elem(stacks) = node->right;
968
stackdir.Elem(stacks) = ndir;
969
}
970
}
971
}
972
973
void ADTree3M :: PrintRec (ostream & ost, const ADTreeNode3M * node) const
974
{
975
976
if (node->data)
977
{
978
// ost << node->pi << ": ";
979
ost << node->nchilds << " children , ";
980
for (int i = 0; i < 3; i++)
981
ost << node->data[i] << " ";
982
ost << endl;
983
}
984
if (node->left)
985
PrintRec (ost, node->left);
986
if (node->right)
987
PrintRec (ost, node->right);
988
}
989
990
991
992
993
994
995
996
997
998
999
1000
1001
/* ******************************* ADTree3F ******************************* */
1002
1003
1004
ADTreeNode3F :: ADTreeNode3F()
1005
{
1006
pi = 0;
1007
father = NULL;
1008
nchilds = 0;
1009
int i;
1010
for (i = 0; i < 8; i++)
1011
childs[i] = NULL;
1012
}
1013
1014
void ADTreeNode3F :: DeleteChilds ()
1015
{
1016
int i;
1017
1018
for (i = 0; i < 8; i++)
1019
{
1020
if (childs[i])
1021
childs[i]->DeleteChilds();
1022
delete childs[i];
1023
childs[i] = NULL;
1024
}
1025
}
1026
1027
1028
BlockAllocator ADTreeNode3F :: ball(sizeof (ADTreeNode3F));
1029
1030
void * ADTreeNode3F :: operator new(size_t)
1031
{
1032
return ball.Alloc();
1033
}
1034
1035
void ADTreeNode3F :: operator delete (void * p)
1036
{
1037
ball.Free (p);
1038
}
1039
1040
1041
1042
1043
1044
1045
1046
ADTree3F :: ADTree3F (const float * acmin,
1047
const float * acmax)
1048
: ela(0)
1049
{
1050
memcpy (cmin, acmin, 3 * sizeof(float));
1051
memcpy (cmax, acmax, 3 * sizeof(float));
1052
1053
root = new ADTreeNode3F;
1054
for (int i = 0; i < 3; i++)
1055
root->sep[i] = (cmin[i] + cmax[i]) / 2;
1056
}
1057
1058
ADTree3F :: ~ADTree3F ()
1059
{
1060
root->DeleteChilds();
1061
delete root;
1062
}
1063
1064
1065
void ADTree3F :: Insert (const float * p, int pi)
1066
{
1067
ADTreeNode3F *node;
1068
ADTreeNode3F *next;
1069
int lr;
1070
1071
float bmin[3];
1072
float bmax[3];
1073
int i, dir;
1074
1075
memcpy (bmin, cmin, 3 * sizeof(float));
1076
memcpy (bmax, cmax, 3 * sizeof(float));
1077
1078
1079
next = root;
1080
while (next)
1081
{
1082
node = next;
1083
1084
if (!node->pi)
1085
{
1086
memcpy (node->data, p, 3 * sizeof(float));
1087
node->pi = pi;
1088
1089
if (ela.Size() < pi)
1090
ela.SetSize (pi);
1091
ela.Elem(pi) = node;
1092
1093
return;
1094
}
1095
1096
dir = 0;
1097
for (i = 0; i < 3; i++)
1098
{
1099
if (node->sep[i] > p[i])
1100
{
1101
bmax[i] = node->sep[i];
1102
}
1103
else
1104
{
1105
bmin[i] = node->sep[i];
1106
dir += (1 << i);
1107
}
1108
}
1109
next = node->childs[dir];
1110
1111
/*
1112
if (node->sep > p[dir])
1113
{
1114
next = node->left;
1115
bmax[dir] = node->sep;
1116
lr = 0;
1117
}
1118
else
1119
{
1120
next = node->right;
1121
bmin[dir] = node->sep;
1122
lr = 1;
1123
}
1124
*/
1125
}
1126
1127
1128
next = new ADTreeNode3F;
1129
memcpy (next->data, p, 3 * sizeof(float));
1130
next->pi = pi;
1131
1132
for (i = 0; i < 3; i++)
1133
next->sep[i] = (bmin[i] + bmax[i]) / 2;
1134
1135
1136
if (ela.Size() < pi)
1137
ela.SetSize (pi);
1138
ela.Elem(pi) = next;
1139
1140
node->childs[dir] = next;
1141
next->father = node;
1142
1143
while (node)
1144
{
1145
node->nchilds++;
1146
node = node->father;
1147
}
1148
}
1149
1150
void ADTree3F :: DeleteElement (int pi)
1151
{
1152
ADTreeNode3F * node = ela.Get(pi);
1153
1154
node->pi = 0;
1155
1156
node = node->father;
1157
while (node)
1158
{
1159
node->nchilds--;
1160
node = node->father;
1161
}
1162
}
1163
1164
void ADTree3F :: GetIntersecting (const float * bmin,
1165
const float * bmax,
1166
ARRAY<int> & pis) const
1167
{
1168
static ARRAY<ADTreeNode3F*> stack(1000);
1169
ADTreeNode3F * node;
1170
int dir, i, stacks;
1171
1172
stack.SetSize (1000);
1173
pis.SetSize(0);
1174
1175
stack.Elem(1) = root;
1176
stacks = 1;
1177
1178
while (stacks)
1179
{
1180
node = stack.Get(stacks);
1181
stacks--;
1182
1183
if (node->pi)
1184
{
1185
if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&
1186
node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&
1187
node->data[2] >= bmin[2] && node->data[2] <= bmax[2])
1188
1189
pis.Append (node->pi);
1190
}
1191
1192
1193
int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;
1194
int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;
1195
int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;
1196
int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;
1197
int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;
1198
int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;
1199
1200
int i1, i2, i3;
1201
for (i1 = i1min; i1 <= i1max; i1++)
1202
for (i2 = i2min; i2 <= i2max; i2++)
1203
for (i3 = i3min; i3 <= i3max; i3++)
1204
{
1205
i = i1+2*i2+4*i3;
1206
if (node->childs[i])
1207
{
1208
stacks++;
1209
stack.Elem(stacks) = node->childs[i];
1210
}
1211
}
1212
1213
/*
1214
if (node->left && bmin[dir] <= node->sep)
1215
{
1216
stacks++;
1217
stack.Elem(stacks) = node->left;
1218
stackdir.Elem(stacks) = ndir;
1219
}
1220
if (node->right && bmax[dir] >= node->sep)
1221
{
1222
stacks++;
1223
stack.Elem(stacks) = node->right;
1224
stackdir.Elem(stacks) = ndir;
1225
}
1226
*/
1227
}
1228
}
1229
1230
void ADTree3F :: PrintRec (ostream & ost, const ADTreeNode3F * node) const
1231
{
1232
int i;
1233
if (node->data)
1234
{
1235
ost << node->pi << ": ";
1236
ost << node->nchilds << " children , ";
1237
for (i = 0; i < 3; i++)
1238
ost << node->data[i] << " ";
1239
ost << endl;
1240
}
1241
1242
for (i = 0; i < 8; i++)
1243
if (node->childs[i])
1244
PrintRec (ost, node->childs[i]);
1245
}
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
/* ******************************* ADTree3FM ******************************* */
1260
1261
1262
ADTreeNode3FM :: ADTreeNode3FM()
1263
{
1264
father = NULL;
1265
nchilds = 0;
1266
int i;
1267
1268
for (i = 0; i < ADTN_SIZE; i++)
1269
pi[i] = 0;
1270
1271
for (i = 0; i < 8; i++)
1272
childs[i] = NULL;
1273
}
1274
1275
void ADTreeNode3FM :: DeleteChilds ()
1276
{
1277
int i;
1278
1279
for (i = 0; i < 8; i++)
1280
{
1281
if (childs[i])
1282
childs[i]->DeleteChilds();
1283
delete childs[i];
1284
childs[i] = NULL;
1285
}
1286
}
1287
1288
1289
BlockAllocator ADTreeNode3FM :: ball(sizeof (ADTreeNode3FM));
1290
1291
void * ADTreeNode3FM :: operator new(size_t)
1292
{
1293
return ball.Alloc();
1294
}
1295
1296
void ADTreeNode3FM :: operator delete (void * p)
1297
{
1298
ball.Free (p);
1299
}
1300
1301
1302
1303
1304
1305
1306
1307
ADTree3FM :: ADTree3FM (const float * acmin,
1308
const float * acmax)
1309
: ela(0)
1310
{
1311
memcpy (cmin, acmin, 3 * sizeof(float));
1312
memcpy (cmax, acmax, 3 * sizeof(float));
1313
1314
root = new ADTreeNode3FM;
1315
for (int i = 0; i < 3; i++)
1316
root->sep[i] = (cmin[i] + cmax[i]) / 2;
1317
}
1318
1319
ADTree3FM :: ~ADTree3FM ()
1320
{
1321
root->DeleteChilds();
1322
delete root;
1323
}
1324
1325
1326
void ADTree3FM :: Insert (const float * p, int pi)
1327
{
1328
ADTreeNode3FM *node;
1329
ADTreeNode3FM *next;
1330
int lr;
1331
1332
float bmin[3];
1333
float bmax[3];
1334
int i, dir;
1335
1336
memcpy (bmin, cmin, 3 * sizeof(float));
1337
memcpy (bmax, cmax, 3 * sizeof(float));
1338
1339
next = root;
1340
while (next)
1341
{
1342
node = next;
1343
1344
for (i = 0; i < ADTN_SIZE; i++)
1345
if (!node->pi[i])
1346
{
1347
memcpy (node->data[i], p, 3 * sizeof(float));
1348
node->pi[i] = pi;
1349
1350
if (ela.Size() < pi)
1351
ela.SetSize (pi);
1352
ela.Elem(pi) = node;
1353
1354
return;
1355
}
1356
1357
dir = 0;
1358
for (i = 0; i < 3; i++)
1359
{
1360
if (node->sep[i] > p[i])
1361
{
1362
bmax[i] = node->sep[i];
1363
}
1364
else
1365
{
1366
bmin[i] = node->sep[i];
1367
dir += (1 << i);
1368
}
1369
}
1370
next = node->childs[dir];
1371
1372
/*
1373
if (node->sep > p[dir])
1374
{
1375
next = node->left;
1376
bmax[dir] = node->sep;
1377
lr = 0;
1378
}
1379
else
1380
{
1381
next = node->right;
1382
bmin[dir] = node->sep;
1383
lr = 1;
1384
}
1385
*/
1386
}
1387
1388
1389
next = new ADTreeNode3FM;
1390
memcpy (next->data[0], p, 3 * sizeof(float));
1391
next->pi[0] = pi;
1392
1393
for (i = 0; i < 3; i++)
1394
next->sep[i] = (bmin[i] + bmax[i]) / 2;
1395
1396
1397
if (ela.Size() < pi)
1398
ela.SetSize (pi);
1399
ela.Elem(pi) = next;
1400
1401
node->childs[dir] = next;
1402
next->father = node;
1403
1404
while (node)
1405
{
1406
node->nchilds++;
1407
node = node->father;
1408
}
1409
}
1410
1411
void ADTree3FM :: DeleteElement (int pi)
1412
{
1413
ADTreeNode3FM * node = ela.Get(pi);
1414
1415
int i;
1416
for (i = 0; i < ADTN_SIZE; i++)
1417
if (node->pi[i] == pi)
1418
node->pi[i] = 0;
1419
1420
node = node->father;
1421
while (node)
1422
{
1423
node->nchilds--;
1424
node = node->father;
1425
}
1426
}
1427
1428
void ADTree3FM :: GetIntersecting (const float * bmin,
1429
const float * bmax,
1430
ARRAY<int> & pis) const
1431
{
1432
static ARRAY<ADTreeNode3FM*> stack(1000);
1433
ADTreeNode3FM * node;
1434
int dir, i, stacks;
1435
1436
stack.SetSize (1000);
1437
pis.SetSize(0);
1438
1439
stack.Elem(1) = root;
1440
stacks = 1;
1441
1442
while (stacks)
1443
{
1444
node = stack.Get(stacks);
1445
stacks--;
1446
1447
int * hpi = node->pi;
1448
for (i = 0; i < ADTN_SIZE; i++)
1449
if (hpi[i])
1450
{
1451
float * datai = &node->data[i][0];
1452
if (datai[0] >= bmin[0] && datai[0] <= bmax[0] &&
1453
datai[1] >= bmin[1] && datai[1] <= bmax[1] &&
1454
datai[2] >= bmin[2] && datai[2] <= bmax[2])
1455
1456
pis.Append (node->pi[i]);
1457
}
1458
1459
/*
1460
if (node->pi)
1461
{
1462
if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&
1463
node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&
1464
node->data[2] >= bmin[2] && node->data[2] <= bmax[2])
1465
1466
pis.Append (node->pi);
1467
}
1468
*/
1469
1470
int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;
1471
int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;
1472
int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;
1473
int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;
1474
int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;
1475
int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;
1476
1477
int i1, i2, i3;
1478
for (i1 = i1min; i1 <= i1max; i1++)
1479
for (i2 = i2min; i2 <= i2max; i2++)
1480
for (i3 = i3min; i3 <= i3max; i3++)
1481
{
1482
i = i1+2*i2+4*i3;
1483
if (node->childs[i])
1484
{
1485
stacks++;
1486
stack.Elem(stacks) = node->childs[i];
1487
}
1488
}
1489
1490
/*
1491
if (node->left && bmin[dir] <= node->sep)
1492
{
1493
stacks++;
1494
stack.Elem(stacks) = node->left;
1495
stackdir.Elem(stacks) = ndir;
1496
}
1497
if (node->right && bmax[dir] >= node->sep)
1498
{
1499
stacks++;
1500
stack.Elem(stacks) = node->right;
1501
stackdir.Elem(stacks) = ndir;
1502
}
1503
*/
1504
}
1505
}
1506
1507
void ADTree3FM :: PrintRec (ostream & ost, const ADTreeNode3FM * node) const
1508
{
1509
int i;
1510
if (node->data)
1511
{
1512
ost << node->pi << ": ";
1513
ost << node->nchilds << " children , ";
1514
for (i = 0; i < 3; i++)
1515
ost << node->data[i] << " ";
1516
ost << endl;
1517
}
1518
1519
for (i = 0; i < 8; i++)
1520
if (node->childs[i])
1521
PrintRec (ost, node->childs[i]);
1522
}
1523
1524
1525
1526
1527
#endif
1528
1529
1530
1531
1532
1533
1534
/* ******************************* ADTree6 ******************************* */
1535
1536
1537
ADTreeNode6 :: ADTreeNode6()
1538
{
1539
pi = -1;
1540
1541
left = NULL;
1542
right = NULL;
1543
father = NULL;
1544
nchilds = 0;
1545
}
1546
1547
void ADTreeNode6 :: DeleteChilds ()
1548
{
1549
if (left)
1550
{
1551
left->DeleteChilds();
1552
delete left;
1553
left = NULL;
1554
}
1555
if (right)
1556
{
1557
right->DeleteChilds();
1558
delete right;
1559
right = NULL;
1560
}
1561
}
1562
1563
1564
BlockAllocator ADTreeNode6 :: ball (sizeof (ADTreeNode6));
1565
void * ADTreeNode6 :: operator new(size_t)
1566
{
1567
return ball.Alloc();
1568
}
1569
1570
void ADTreeNode6 :: operator delete (void * p)
1571
{
1572
ball.Free (p);
1573
}
1574
1575
1576
1577
1578
1579
ADTree6 :: ADTree6 (const float * acmin,
1580
const float * acmax)
1581
: ela(0)
1582
{
1583
memcpy (cmin, acmin, 6 * sizeof(float));
1584
memcpy (cmax, acmax, 6 * sizeof(float));
1585
1586
root = new ADTreeNode6;
1587
root->sep = (cmin[0] + cmax[0]) / 2;
1588
}
1589
1590
ADTree6 :: ~ADTree6 ()
1591
{
1592
root->DeleteChilds();
1593
delete root;
1594
}
1595
1596
void ADTree6 :: Insert (const float * p, int pi)
1597
{
1598
ADTreeNode6 *node(NULL);
1599
ADTreeNode6 *next;
1600
int dir;
1601
int lr(0);
1602
1603
float bmin[6];
1604
float bmax[6];
1605
1606
1607
memcpy (bmin, cmin, 6 * sizeof(float));
1608
memcpy (bmax, cmax, 6 * sizeof(float));
1609
1610
next = root;
1611
dir = 0;
1612
while (next)
1613
{
1614
node = next;
1615
1616
if (node->pi == -1)
1617
{
1618
memcpy (node->data, p, 6 * sizeof(float));
1619
node->pi = pi;
1620
1621
if (ela.Size() < pi+1)
1622
ela.SetSize (pi+1);
1623
ela[pi] = node;
1624
1625
return;
1626
}
1627
1628
if (node->sep > p[dir])
1629
{
1630
next = node->left;
1631
bmax[dir] = node->sep;
1632
lr = 0;
1633
}
1634
else
1635
{
1636
next = node->right;
1637
bmin[dir] = node->sep;
1638
lr = 1;
1639
}
1640
1641
dir++;
1642
if (dir == 6) dir = 0;
1643
}
1644
1645
1646
next = new ADTreeNode6;
1647
memcpy (next->data, p, 6 * sizeof(float));
1648
next->pi = pi;
1649
next->sep = (bmin[dir] + bmax[dir]) / 2;
1650
1651
if (ela.Size() < pi+1)
1652
ela.SetSize (pi+1);
1653
ela[pi] = next;
1654
1655
if (lr)
1656
node->right = next;
1657
else
1658
node->left = next;
1659
next -> father = node;
1660
1661
while (node)
1662
{
1663
node->nchilds++;
1664
node = node->father;
1665
}
1666
}
1667
1668
void ADTree6 :: DeleteElement (int pi)
1669
{
1670
ADTreeNode6 * node = ela[pi];
1671
1672
node->pi = -1;
1673
1674
node = node->father;
1675
while (node)
1676
{
1677
node->nchilds--;
1678
node = node->father;
1679
}
1680
}
1681
1682
void ADTree6 :: PrintMemInfo (ostream & ost) const
1683
{
1684
ost << Elements() << " elements a " << sizeof(ADTreeNode6)
1685
<< " Bytes = "
1686
<< Elements() * sizeof(ADTreeNode6) << endl;
1687
ost << "maxind = " << ela.Size() << " = " << sizeof(ADTreeNode6*) * ela.Size() << " Bytes" << endl;
1688
}
1689
1690
1691
1692
class inttn6 {
1693
public:
1694
int dir;
1695
ADTreeNode6 * node;
1696
};
1697
1698
1699
1700
1701
void ADTree6 :: GetIntersecting (const float * bmin,
1702
const float * bmax,
1703
ARRAY<int> & pis) const
1704
{
1705
static ARRAY<inttn6> stack(10000);
1706
1707
stack.SetSize (10000);
1708
pis.SetSize(0);
1709
1710
stack[0].node = root;
1711
stack[0].dir = 0;
1712
int stacks = 0;
1713
1714
while (stacks >= 0)
1715
{
1716
ADTreeNode6 * node = stack[stacks].node;
1717
int dir = stack[stacks].dir;
1718
1719
stacks--;
1720
1721
if (node->pi != -1)
1722
{
1723
if (node->data[0] > bmax[0] ||
1724
node->data[1] > bmax[1] ||
1725
node->data[2] > bmax[2] ||
1726
node->data[3] < bmin[3] ||
1727
node->data[4] < bmin[4] ||
1728
node->data[5] < bmin[5])
1729
;
1730
else
1731
pis.Append (node->pi);
1732
}
1733
1734
int ndir = (dir+1) % 6;
1735
1736
if (node->left && bmin[dir] <= node->sep)
1737
{
1738
stacks++;
1739
stack[stacks].node = node->left;
1740
stack[stacks].dir = ndir;
1741
}
1742
if (node->right && bmax[dir] >= node->sep)
1743
{
1744
stacks++;
1745
stack[stacks].node = node->right;
1746
stack[stacks].dir = ndir;
1747
}
1748
}
1749
}
1750
1751
void ADTree6 :: PrintRec (ostream & ost, const ADTreeNode6 * node) const
1752
{
1753
1754
if (node->data)
1755
{
1756
ost << node->pi << ": ";
1757
ost << node->nchilds << " children , ";
1758
for (int i = 0; i < 6; i++)
1759
ost << node->data[i] << " ";
1760
ost << endl;
1761
}
1762
if (node->left)
1763
PrintRec (ost, node->left);
1764
if (node->right)
1765
PrintRec (ost, node->right);
1766
}
1767
1768
1769
int ADTree6 :: DepthRec (const ADTreeNode6 * node) const
1770
{
1771
int ldepth = 0;
1772
int rdepth = 0;
1773
1774
if (node->left)
1775
ldepth = DepthRec(node->left);
1776
if (node->right)
1777
rdepth = DepthRec(node->right);
1778
return 1 + max2 (ldepth, rdepth);
1779
}
1780
1781
int ADTree6 :: ElementsRec (const ADTreeNode6 * node) const
1782
{
1783
int els = 1;
1784
if (node->left)
1785
els += ElementsRec(node->left);
1786
if (node->right)
1787
els += ElementsRec(node->right);
1788
return els;
1789
}
1790
1791
1792
1793
1794
1795
1796
#ifdef ABC
1797
1798
/* ******************************* ADTree6F ******************************* */
1799
1800
1801
ADTreeNode6F :: ADTreeNode6F()
1802
{
1803
pi = 0;
1804
father = NULL;
1805
nchilds = 0;
1806
int i;
1807
for (i = 0; i < 64; i++)
1808
childs[i] = NULL;
1809
}
1810
1811
void ADTreeNode6F :: DeleteChilds ()
1812
{
1813
int i;
1814
1815
for (i = 0; i < 64; i++)
1816
{
1817
if (childs[i])
1818
childs[i]->DeleteChilds();
1819
delete childs[i];
1820
childs[i] = NULL;
1821
}
1822
}
1823
1824
1825
BlockAllocator ADTreeNode6F :: ball(sizeof (ADTreeNode6F));
1826
1827
void * ADTreeNode6F :: operator new(size_t)
1828
{
1829
return ball.Alloc();
1830
}
1831
1832
void ADTreeNode6F :: operator delete (void * p)
1833
{
1834
ball.Free (p);
1835
}
1836
1837
1838
1839
1840
1841
1842
1843
ADTree6F :: ADTree6F (const float * acmin,
1844
const float * acmax)
1845
: ela(0)
1846
{
1847
memcpy (cmin, acmin, 6 * sizeof(float));
1848
memcpy (cmax, acmax, 6 * sizeof(float));
1849
1850
root = new ADTreeNode6F;
1851
for (int i = 0; i < 6; i++)
1852
root->sep[i] = (cmin[i] + cmax[i]) / 2;
1853
}
1854
1855
ADTree6F :: ~ADTree6F ()
1856
{
1857
root->DeleteChilds();
1858
delete root;
1859
}
1860
1861
1862
void ADTree6F :: Insert (const float * p, int pi)
1863
{
1864
ADTreeNode6F *node;
1865
ADTreeNode6F *next;
1866
int lr;
1867
1868
float bmin[6];
1869
float bmax[6];
1870
int i, dir;
1871
1872
memcpy (bmin, cmin, 6 * sizeof(float));
1873
memcpy (bmax, cmax, 6 * sizeof(float));
1874
1875
next = root;
1876
while (next)
1877
{
1878
node = next;
1879
1880
if (!node->pi)
1881
{
1882
memcpy (node->data, p, 6 * sizeof(float));
1883
node->pi = pi;
1884
1885
if (ela.Size() < pi)
1886
ela.SetSize (pi);
1887
ela.Elem(pi) = node;
1888
1889
return;
1890
}
1891
1892
dir = 0;
1893
for (i = 0; i < 6; i++)
1894
{
1895
if (node->sep[i] > p[i])
1896
{
1897
bmax[i] = node->sep[i];
1898
}
1899
else
1900
{
1901
bmin[i] = node->sep[i];
1902
dir += (1 << i);
1903
}
1904
}
1905
next = node->childs[dir];
1906
1907
/*
1908
if (node->sep > p[dir])
1909
{
1910
next = node->left;
1911
bmax[dir] = node->sep;
1912
lr = 0;
1913
}
1914
else
1915
{
1916
next = node->right;
1917
bmin[dir] = node->sep;
1918
lr = 1;
1919
}
1920
*/
1921
}
1922
1923
1924
next = new ADTreeNode6F;
1925
memcpy (next->data, p, 6 * sizeof(float));
1926
next->pi = pi;
1927
1928
for (i = 0; i < 6; i++)
1929
next->sep[i] = (bmin[i] + bmax[i]) / 2;
1930
1931
1932
if (ela.Size() < pi)
1933
ela.SetSize (pi);
1934
ela.Elem(pi) = next;
1935
1936
node->childs[dir] = next;
1937
next->father = node;
1938
1939
while (node)
1940
{
1941
node->nchilds++;
1942
node = node->father;
1943
}
1944
}
1945
1946
void ADTree6F :: DeleteElement (int pi)
1947
{
1948
ADTreeNode6F * node = ela.Get(pi);
1949
1950
node->pi = 0;
1951
1952
node = node->father;
1953
while (node)
1954
{
1955
node->nchilds--;
1956
node = node->father;
1957
}
1958
}
1959
1960
void ADTree6F :: GetIntersecting (const float * bmin,
1961
const float * bmax,
1962
ARRAY<int> & pis) const
1963
{
1964
static ARRAY<ADTreeNode6F*> stack(1000);
1965
ADTreeNode6F * node;
1966
int dir, i, stacks;
1967
1968
stack.SetSize (1000);
1969
pis.SetSize(0);
1970
1971
stack.Elem(1) = root;
1972
stacks = 1;
1973
1974
while (stacks)
1975
{
1976
node = stack.Get(stacks);
1977
stacks--;
1978
1979
if (node->pi)
1980
{
1981
if (
1982
node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&
1983
node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&
1984
node->data[2] >= bmin[2] && node->data[2] <= bmax[2] &&
1985
node->data[3] >= bmin[3] && node->data[3] <= bmax[3] &&
1986
node->data[4] >= bmin[4] && node->data[4] <= bmax[4] &&
1987
node->data[5] >= bmin[5] && node->data[5] <= bmax[5]
1988
)
1989
1990
pis.Append (node->pi);
1991
}
1992
1993
1994
int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;
1995
int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;
1996
int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;
1997
int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;
1998
int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;
1999
int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;
2000
2001
int i4min = (bmin[3] <= node->sep[3]) ? 0 : 1;
2002
int i4max = (bmax[3] < node->sep[3]) ? 0 : 1;
2003
int i5min = (bmin[4] <= node->sep[4]) ? 0 : 1;
2004
int i5max = (bmax[4] < node->sep[4]) ? 0 : 1;
2005
int i6min = (bmin[5] <= node->sep[5]) ? 0 : 1;
2006
int i6max = (bmax[5] < node->sep[5]) ? 0 : 1;
2007
2008
int i1, i2, i3, i4, i5, i6;
2009
for (i1 = i1min; i1 <= i1max; i1++)
2010
for (i2 = i2min; i2 <= i2max; i2++)
2011
for (i3 = i3min; i3 <= i3max; i3++)
2012
for (i4 = i4min; i4 <= i4max; i4++)
2013
for (i5 = i5min; i5 <= i5max; i5++)
2014
for (i6 = i6min; i6 <= i6max; i6++)
2015
{
2016
i = i1 + 2*i2 + 4*i3 + 8*i4 + 16*i5 +32*i6;
2017
if (node->childs[i])
2018
{
2019
stacks++;
2020
stack.Elem(stacks) = node->childs[i];
2021
}
2022
}
2023
2024
/*
2025
if (node->left && bmin[dir] <= node->sep)
2026
{
2027
stacks++;
2028
stack.Elem(stacks) = node->left;
2029
stackdir.Elem(stacks) = ndir;
2030
}
2031
if (node->right && bmax[dir] >= node->sep)
2032
{
2033
stacks++;
2034
stack.Elem(stacks) = node->right;
2035
stackdir.Elem(stacks) = ndir;
2036
}
2037
*/
2038
}
2039
}
2040
2041
void ADTree6F :: PrintRec (ostream & ost, const ADTreeNode6F * node) const
2042
{
2043
int i;
2044
if (node->data)
2045
{
2046
ost << node->pi << ": ";
2047
ost << node->nchilds << " children , ";
2048
for (i = 0; i < 6; i++)
2049
ost << node->data[i] << " ";
2050
ost << endl;
2051
}
2052
2053
for (i = 0; i < 64; i++)
2054
if (node->childs[i])
2055
PrintRec (ost, node->childs[i]);
2056
}
2057
2058
2059
2060
#endif
2061
2062
2063
2064
/* ************************************* Point3dTree ********************** */
2065
2066
2067
2068
Point3dTree :: Point3dTree (const Point3d & pmin, const Point3d & pmax)
2069
{
2070
float pmi[3], pma[3];
2071
for (int i = 0; i < 3; i++)
2072
{
2073
pmi[i] = pmin.X(i+1);
2074
pma[i] = pmax.X(i+1);
2075
}
2076
tree = new ADTree3 (pmi, pma);
2077
}
2078
2079
Point3dTree :: ~Point3dTree ()
2080
{
2081
delete tree;
2082
}
2083
2084
2085
2086
void Point3dTree :: Insert (const Point3d & p, int pi)
2087
{
2088
static float pd[3];
2089
pd[0] = p.X();
2090
pd[1] = p.Y();
2091
pd[2] = p.Z();
2092
tree->Insert (pd, pi);
2093
}
2094
2095
void Point3dTree :: GetIntersecting (const Point3d & pmin, const Point3d & pmax,
2096
ARRAY<int> & pis) const
2097
{
2098
float pmi[3], pma[3];
2099
for (int i = 0; i < 3; i++)
2100
{
2101
pmi[i] = pmin.X(i+1);
2102
pma[i] = pmax.X(i+1);
2103
}
2104
tree->GetIntersecting (pmi, pma, pis);
2105
}
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
Box3dTree :: Box3dTree (const Point3d & apmin, const Point3d & apmax)
2117
{
2118
boxpmin = apmin;
2119
boxpmax = apmax;
2120
float tpmin[6], tpmax[6];
2121
for (int i = 0; i < 3; i++)
2122
{
2123
tpmin[i] = tpmin[i+3] = boxpmin.X(i+1);
2124
tpmax[i] = tpmax[i+3] = boxpmax.X(i+1);
2125
}
2126
tree = new ADTree6 (tpmin, tpmax);
2127
}
2128
2129
Box3dTree :: ~Box3dTree ()
2130
{
2131
delete tree;
2132
}
2133
2134
void Box3dTree :: Insert (const Point3d & bmin, const Point3d & bmax, int pi)
2135
{
2136
static float tp[6];
2137
2138
for (int i = 0; i < 3; i++)
2139
{
2140
tp[i] = bmin.X(i+1);
2141
tp[i+3] = bmax.X(i+1);
2142
}
2143
2144
tree->Insert (tp, pi);
2145
}
2146
2147
void Box3dTree ::GetIntersecting (const Point3d & pmin, const Point3d & pmax,
2148
ARRAY<int> & pis) const
2149
{
2150
float tpmin[6];
2151
float tpmax[6];
2152
2153
for (int i = 0; i < 3; i++)
2154
{
2155
tpmin[i] = boxpmin.X(i+1);
2156
tpmax[i] = pmax.X(i+1);
2157
2158
tpmin[i+3] = pmin.X(i+1);
2159
tpmax[i+3] = boxpmax.X(i+1);
2160
}
2161
2162
tree->GetIntersecting (tpmin, tpmax, pis);
2163
}
2164
2165
}
2166
2167