Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/adtree.cpp
3206 views
#include <mystdlib.h>123#include <myadt.hpp>4// class DenseMatrix;5#include <gprim.hpp>67namespace netgen8{91011/* ******************************* ADTree ******************************* */121314ADTreeNode :: ADTreeNode(int adim)15{16pi = -1;1718left = NULL;19right = NULL;20father = NULL;21nchilds = 0;22dim = adim;23data = new float [dim];24boxmin = NULL;25boxmax = NULL;26}2728293031ADTreeNode :: ~ADTreeNode()32{33delete data;34}353637ADTree :: ADTree (int adim, const float * acmin,38const float * acmax)39: ela(0), stack(1000), stackdir(1000)40{41dim = adim;42cmin = new float [dim];43cmax = new float [dim];44memcpy (cmin, acmin, dim * sizeof(float));45memcpy (cmax, acmax, dim * sizeof(float));4647root = new ADTreeNode (dim);48root->sep = (cmin[0] + cmax[0]) / 2;49root->boxmin = new float [dim];50root->boxmax = new float [dim];51memcpy (root->boxmin, cmin, dim * sizeof(float));52memcpy (root->boxmax, cmax, dim * sizeof(float));53}5455ADTree :: ~ADTree ()56{57;58}5960void ADTree :: Insert (const float * p, int pi)61{62ADTreeNode *node(NULL);63ADTreeNode *next;64int dir;65int lr(1);6667float * bmin = new float [dim];68float * bmax = new float [dim];6970memcpy (bmin, cmin, dim * sizeof(float));71memcpy (bmax, cmax, dim * sizeof(float));727374next = root;75dir = 0;76while (next)77{78node = next;7980if (node->pi == -1)81{82memcpy (node->data, p, dim * sizeof(float));83node->pi = pi;8485if (ela.Size() < pi+1)86ela.SetSize (pi+1);87ela[pi] = node;8889return;90}9192if (node->sep > p[dir])93{94next = node->left;95bmax[dir] = node->sep;96lr = 0;97}98else99{100next = node->right;101bmin[dir] = node->sep;102lr = 1;103}104105dir++;106if (dir == dim)107dir = 0;108}109110111next = new ADTreeNode(dim);112memcpy (next->data, p, dim * sizeof(float));113next->pi = pi;114next->sep = (bmin[dir] + bmax[dir]) / 2;115next->boxmin = bmin;116next->boxmax = bmax;117118if (ela.Size() < pi+1)119ela.SetSize (pi+1);120ela[pi] = next;121122123if (lr)124node->right = next;125else126node->left = next;127next -> father = node;128129while (node)130{131node->nchilds++;132node = node->father;133}134}135136void ADTree :: DeleteElement (int pi)137{138ADTreeNode * node = ela[pi];139140node->pi = -1;141142node = node->father;143while (node)144{145node->nchilds--;146node = node->father;147}148}149150151void ADTree :: SetCriterion (ADTreeCriterion & acriterion)152{153criterion = & acriterion;154}155156157void ADTree :: Reset ()158{159stack.Elem(1) = root;160stackdir.Elem(1) = 0;161stackindex = 1;162}163164165int ADTree:: Next ()166{167ADTreeNode *node;168int dir;169170if (stackindex == 0)171return -1;172173do174{175node = stack.Get(stackindex);176dir = stackdir.Get(stackindex);177stackindex --;178179if (criterion -> Eval(node))180{181int ndir = dir + 1;182if (ndir == dim)183ndir = 0;184185if (node -> left && criterion -> Eval (node->left))186{187stackindex ++;188stack.Elem(stackindex) = node -> left;189stackdir.Elem(stackindex) = ndir;190}191if (node->right && criterion -> Eval (node -> right))192{193stackindex++;194stack.Elem(stackindex) = node->right;195stackdir.Elem(stackindex) = ndir;196}197198if (node -> pi != -1)199return node->pi;200}201}202while (stackindex > 0);203204return -1;205}206207208void ADTree :: GetMatch (ARRAY <int> & matches)209{210int nodenr;211212Reset();213214while ( (nodenr = Next()) != -1)215matches.Append (nodenr);216}217218219void ADTree :: PrintRec (ostream & ost, const ADTreeNode * node) const220{221222if (node->data)223{224ost << node->pi << ": ";225ost << node->nchilds << " children , ";226for (int i = 0; i < dim; i++)227ost << node->data[i] << " ";228ost << endl;229}230if (node->left)231{232ost << "l ";233PrintRec (ost, node->left);234}235if (node->right)236{237ost << "r ";238PrintRec (ost, node->right);239}240}241242243/* ******************************* ADTree3 ******************************* */244245246ADTreeNode3 :: ADTreeNode3()247{248pi = -1;249250left = NULL;251right = NULL;252father = NULL;253nchilds = 0;254}255256void ADTreeNode3 :: DeleteChilds ()257{258if (left)259{260left->DeleteChilds();261delete left;262left = NULL;263}264if (right)265{266right->DeleteChilds();267delete right;268right = NULL;269}270}271272273BlockAllocator ADTreeNode3 :: ball(sizeof (ADTreeNode3));274275276void * ADTreeNode3 :: operator new(size_t s)277{278return ball.Alloc();279}280281void ADTreeNode3 :: operator delete (void * p)282{283ball.Free (p);284}285286287288289290291292ADTree3 :: ADTree3 (const float * acmin,293const float * acmax)294: ela(0)295{296memcpy (cmin, acmin, 3 * sizeof(float));297memcpy (cmax, acmax, 3 * sizeof(float));298299root = new ADTreeNode3;300root->sep = (cmin[0] + cmax[0]) / 2;301}302303ADTree3 :: ~ADTree3 ()304{305root->DeleteChilds();306delete root;307}308309310void ADTree3 :: Insert (const float * p, int pi)311{312ADTreeNode3 *node(NULL);313ADTreeNode3 *next;314int dir;315int lr(0);316317float bmin[3];318float bmax[3];319320memcpy (bmin, cmin, 3 * sizeof(float));321memcpy (bmax, cmax, 3 * sizeof(float));322323next = root;324dir = 0;325while (next)326{327node = next;328329if (node->pi == -1)330{331memcpy (node->data, p, 3 * sizeof(float));332node->pi = pi;333334if (ela.Size() < pi+1)335ela.SetSize (pi+1);336ela[pi] = node;337338return;339}340341if (node->sep > p[dir])342{343next = node->left;344bmax[dir] = node->sep;345lr = 0;346}347else348{349next = node->right;350bmin[dir] = node->sep;351lr = 1;352}353354dir++;355if (dir == 3)356dir = 0;357}358359360next = new ADTreeNode3;361memcpy (next->data, p, 3 * sizeof(float));362next->pi = pi;363next->sep = (bmin[dir] + bmax[dir]) / 2;364365366if (ela.Size() < pi+1)367ela.SetSize (pi+1);368ela[pi] = next;369370371if (lr)372node->right = next;373else374node->left = next;375next -> father = node;376377while (node)378{379node->nchilds++;380node = node->father;381}382}383384void ADTree3 :: DeleteElement (int pi)385{386ADTreeNode3 * node = ela[pi];387388node->pi = -1;389390node = node->father;391while (node)392{393node->nchilds--;394node = node->father;395}396}397398void ADTree3 :: GetIntersecting (const float * bmin,399const float * bmax,400ARRAY<int> & pis) const401{402static ARRAY<ADTreeNode3*> stack(1000);403static ARRAY<int> stackdir(1000);404ADTreeNode3 * node;405int dir, stacks;406407stack.SetSize (1000);408stackdir.SetSize(1000);409pis.SetSize(0);410411stack.Elem(1) = root;412stackdir.Elem(1) = 0;413stacks = 1;414415while (stacks)416{417node = stack.Get(stacks);418dir = stackdir.Get(stacks);419stacks--;420421if (node->pi != -1)422{423if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&424node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&425node->data[2] >= bmin[2] && node->data[2] <= bmax[2])426427pis.Append (node->pi);428}429430431int ndir = dir+1;432if (ndir == 3)433ndir = 0;434435if (node->left && bmin[dir] <= node->sep)436{437stacks++;438stack.Elem(stacks) = node->left;439stackdir.Elem(stacks) = ndir;440}441if (node->right && bmax[dir] >= node->sep)442{443stacks++;444stack.Elem(stacks) = node->right;445stackdir.Elem(stacks) = ndir;446}447}448}449450void ADTree3 :: PrintRec (ostream & ost, const ADTreeNode3 * node) const451{452453if (node->data)454{455ost << node->pi << ": ";456ost << node->nchilds << " children , ";457for (int i = 0; i < 3; i++)458ost << node->data[i] << " ";459ost << endl;460}461if (node->left)462PrintRec (ost, node->left);463if (node->right)464PrintRec (ost, node->right);465}466467468469470471472473474#ifdef ABC475476/* ******************************* ADTree3Div ******************************* */477478479ADTreeNode3Div :: ADTreeNode3Div()480{481pi = 0;482483int i;484for (i = 0; i < ADTN_DIV; i++)485childs[i] = NULL;486487father = NULL;488nchilds = 0;489minx = 0;490dist = 1;491}492493void ADTreeNode3Div :: DeleteChilds ()494{495int i;496for (i = 0; i < ADTN_DIV; i++)497if (childs[i])498{499childs[i]->DeleteChilds();500delete childs[i];501childs[i] = NULL;502}503}504505506BlockAllocator ADTreeNode3Div :: ball(sizeof (ADTreeNode3Div));507508void * ADTreeNode3Div :: operator new(size_t)509{510return ball.Alloc();511}512513void ADTreeNode3Div :: operator delete (void * p)514{515ball.Free (p);516}517518519520521522523524ADTree3Div :: ADTree3Div (const float * acmin,525const float * acmax)526: ela(0)527{528memcpy (cmin, acmin, 3 * sizeof(float));529memcpy (cmax, acmax, 3 * sizeof(float));530531root = new ADTreeNode3Div;532533root->minx = cmin[0];534root->dist = (cmax[0] - cmin[0]) / ADTN_DIV;535536// root->sep = (cmin[0] + cmax[0]) / 2;537}538539ADTree3Div :: ~ADTree3Div ()540{541root->DeleteChilds();542delete root;543}544545546void ADTree3Div :: Insert (const float * p, int pi)547{548ADTreeNode3Div *node;549ADTreeNode3Div *next;550int dir;551int bag;552553float bmin[3];554float bmax[3];555556memcpy (bmin, cmin, 3 * sizeof(float));557memcpy (bmax, cmax, 3 * sizeof(float));558559560next = root;561dir = 0;562while (next)563{564node = next;565566if (!node->pi)567{568memcpy (node->data, p, 3 * sizeof(float));569node->pi = pi;570571if (ela.Size() < pi)572ela.SetSize (pi);573ela.Elem(pi) = node;574575return;576}577578double dx = (bmax[dir] - bmin[dir]) / ADTN_DIV;579bag = int ((p[dir]-bmin[dir]) / dx);580581// (*testout) << "insert, bag = " << bag << endl;582583if (bag < 0) bag = 0;584if (bag >= ADTN_DIV) bag = ADTN_DIV-1;585586double nbmin = bmin[dir] + bag * dx;587double nbmax = bmin[dir] + (bag+1) * dx;588589/*590(*testout) << "bmin, max = " << bmin[dir] << "-" << bmax[dir]591<< " p = " << p[dir];592*/593next = node->childs[bag];594bmin[dir] = nbmin;595bmax[dir] = nbmax;596597// (*testout) << "new bmin, max = " << bmin[dir] << "-" << bmax[dir] << endl;598599600/*601if (node->sep > p[dir])602{603next = node->left;604bmax[dir] = node->sep;605lr = 0;606}607else608{609next = node->right;610bmin[dir] = node->sep;611lr = 1;612}613*/614615dir++;616if (dir == 3)617dir = 0;618}619620621next = new ADTreeNode3Div;622memcpy (next->data, p, 3 * sizeof(float));623next->pi = pi;624625next->minx = bmin[dir];626next->dist = (bmax[dir] - bmin[dir]) / ADTN_DIV;627// next->sep = (bmin[dir] + bmax[dir]) / 2;628629630if (ela.Size() < pi)631ela.SetSize (pi);632ela.Elem(pi) = next;633634node->childs[bag] = next;635next -> father = node;636637while (node)638{639node->nchilds++;640node = node->father;641}642}643644void ADTree3Div :: DeleteElement (int pi)645{646ADTreeNode3Div * node = ela.Get(pi);647648node->pi = 0;649650node = node->father;651while (node)652{653node->nchilds--;654node = node->father;655}656}657658void ADTree3Div :: GetIntersecting (const float * bmin,659const float * bmax,660ARRAY<int> & pis) const661{662static ARRAY<ADTreeNode3Div*> stack(1000);663static ARRAY<int> stackdir(1000);664ADTreeNode3Div * node;665int dir, i, stacks;666667stack.SetSize (1000);668stackdir.SetSize(1000);669pis.SetSize(0);670671stack.Elem(1) = root;672stackdir.Elem(1) = 0;673stacks = 1;674675while (stacks)676{677node = stack.Get(stacks);678dir = stackdir.Get(stacks);679stacks--;680681if (node->pi)682{683if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&684node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&685node->data[2] >= bmin[2] && node->data[2] <= bmax[2])686687pis.Append (node->pi);688}689690691int ndir = dir+1;692if (ndir == 3)693ndir = 0;694695int mini = int ( (bmin[dir] - node->minx) / node->dist );696int maxi = int ( (bmax[dir] - node->minx) / node->dist );697698// (*testout) << "get int, mini, maxi = " << mini << ", " << maxi << endl;699if (mini < 0) mini = 0;700if (maxi >= ADTN_DIV) maxi = ADTN_DIV-1;701702for (i = mini; i <= maxi; i++)703if (node->childs[i])704{705stacks++;706stack.Elem(stacks) = node->childs[i];707stackdir.Elem(stacks) = ndir;708}709710711/*712if (node->left && bmin[dir] <= node->sep)713{714stacks++;715stack.Elem(stacks) = node->left;716stackdir.Elem(stacks) = ndir;717}718if (node->right && bmax[dir] >= node->sep)719{720stacks++;721stack.Elem(stacks) = node->right;722stackdir.Elem(stacks) = ndir;723}724*/725}726}727728void ADTree3Div :: PrintRec (ostream & ost, const ADTreeNode3Div * node) const729{730731if (node->data)732{733ost << node->pi << ": ";734ost << node->nchilds << " children , ";735ost << " from " << node->minx << " - " << node->minx + node->dist*ADTN_DIV << " ";736for (int i = 0; i < 3; i++)737ost << node->data[i] << " ";738ost << endl;739}740int i;741for (i = 0; i < ADTN_DIV; i++)742if (node->childs[i])743PrintRec (ost, node->childs[i]);744}745746747748749750751752753754755756757/* ******************************* ADTree3M ******************************* */758759760ADTreeNode3M :: ADTreeNode3M()761{762int i;763for (i = 0; i < ADTN_SIZE; i++)764pi[i] = 0;765766left = NULL;767right = NULL;768father = NULL;769nchilds = 0;770}771772void ADTreeNode3M :: DeleteChilds ()773{774if (left)775{776left->DeleteChilds();777delete left;778left = NULL;779}780if (right)781{782right->DeleteChilds();783delete right;784right = NULL;785}786}787788789BlockAllocator ADTreeNode3M :: ball(sizeof (ADTreeNode3M));790791void * ADTreeNode3M :: operator new(size_t)792{793return ball.Alloc();794}795796void ADTreeNode3M :: operator delete (void * p)797{798ball.Free (p);799}800801802803804805806807ADTree3M :: ADTree3M (const float * acmin,808const float * acmax)809: ela(0)810{811memcpy (cmin, acmin, 3 * sizeof(float));812memcpy (cmax, acmax, 3 * sizeof(float));813814root = new ADTreeNode3M;815root->sep = (cmin[0] + cmax[0]) / 2;816}817818ADTree3M :: ~ADTree3M ()819{820root->DeleteChilds();821delete root;822}823824825void ADTree3M :: Insert (const float * p, int pi)826{827ADTreeNode3M *node;828ADTreeNode3M *next;829int dir;830int lr;831int i;832float bmin[3];833float bmax[3];834835memcpy (bmin, cmin, 3 * sizeof(float));836memcpy (bmax, cmax, 3 * sizeof(float));837838next = root;839dir = 0;840while (next)841{842node = next;843844for (i = 0; i < ADTN_SIZE; i++)845if (!node->pi[i])846{847memcpy (node->data[i], p, 3 * sizeof(float));848node->pi[i] = pi;849850if (ela.Size() < pi)851ela.SetSize (pi);852ela.Elem(pi) = node;853854return;855}856857if (node->sep > p[dir])858{859next = node->left;860bmax[dir] = node->sep;861lr = 0;862}863else864{865next = node->right;866bmin[dir] = node->sep;867lr = 1;868}869870dir++;871if (dir == 3)872dir = 0;873}874875876next = new ADTreeNode3M;877memcpy (next->data[0], p, 3 * sizeof(float));878next->pi[0] = pi;879next->sep = (bmin[dir] + bmax[dir]) / 2;880881882if (ela.Size() < pi)883ela.SetSize (pi);884ela.Elem(pi) = next;885886887if (lr)888node->right = next;889else890node->left = next;891next -> father = node;892893while (node)894{895node->nchilds++;896node = node->father;897}898}899900void ADTree3M :: DeleteElement (int pi)901{902ADTreeNode3M * node = ela.Get(pi);903904int i;905for (i = 0; i < ADTN_SIZE; i++)906if (node->pi[i] == pi)907node->pi[i] = 0;908909node = node->father;910while (node)911{912node->nchilds--;913node = node->father;914}915}916917void ADTree3M :: GetIntersecting (const float * bmin,918const float * bmax,919ARRAY<int> & pis) const920{921static ARRAY<ADTreeNode3M*> stack(1000);922static ARRAY<int> stackdir(1000);923ADTreeNode3M * node;924int dir, i, stacks;925926stack.SetSize (1000);927stackdir.SetSize(1000);928pis.SetSize(0);929930stack.Elem(1) = root;931stackdir.Elem(1) = 0;932stacks = 1;933934while (stacks)935{936node = stack.Get(stacks);937dir = stackdir.Get(stacks);938stacks--;939940int * hpi = node->pi;941for (i = 0; i < ADTN_SIZE; i++)942if (hpi[i])943{944float * datai = &node->data[i][0];945if (datai[0] >= bmin[0] && datai[0] <= bmax[0] &&946datai[1] >= bmin[1] && datai[1] <= bmax[1] &&947datai[2] >= bmin[2] && datai[2] <= bmax[2])948949pis.Append (node->pi[i]);950}951952953int ndir = dir+1;954if (ndir == 3)955ndir = 0;956957if (node->left && bmin[dir] <= node->sep)958{959stacks++;960stack.Elem(stacks) = node->left;961stackdir.Elem(stacks) = ndir;962}963if (node->right && bmax[dir] >= node->sep)964{965stacks++;966stack.Elem(stacks) = node->right;967stackdir.Elem(stacks) = ndir;968}969}970}971972void ADTree3M :: PrintRec (ostream & ost, const ADTreeNode3M * node) const973{974975if (node->data)976{977// ost << node->pi << ": ";978ost << node->nchilds << " children , ";979for (int i = 0; i < 3; i++)980ost << node->data[i] << " ";981ost << endl;982}983if (node->left)984PrintRec (ost, node->left);985if (node->right)986PrintRec (ost, node->right);987}9889899909919929939949959969979989991000/* ******************************* ADTree3F ******************************* */100110021003ADTreeNode3F :: ADTreeNode3F()1004{1005pi = 0;1006father = NULL;1007nchilds = 0;1008int i;1009for (i = 0; i < 8; i++)1010childs[i] = NULL;1011}10121013void ADTreeNode3F :: DeleteChilds ()1014{1015int i;10161017for (i = 0; i < 8; i++)1018{1019if (childs[i])1020childs[i]->DeleteChilds();1021delete childs[i];1022childs[i] = NULL;1023}1024}102510261027BlockAllocator ADTreeNode3F :: ball(sizeof (ADTreeNode3F));10281029void * ADTreeNode3F :: operator new(size_t)1030{1031return ball.Alloc();1032}10331034void ADTreeNode3F :: operator delete (void * p)1035{1036ball.Free (p);1037}10381039104010411042104310441045ADTree3F :: ADTree3F (const float * acmin,1046const float * acmax)1047: ela(0)1048{1049memcpy (cmin, acmin, 3 * sizeof(float));1050memcpy (cmax, acmax, 3 * sizeof(float));10511052root = new ADTreeNode3F;1053for (int i = 0; i < 3; i++)1054root->sep[i] = (cmin[i] + cmax[i]) / 2;1055}10561057ADTree3F :: ~ADTree3F ()1058{1059root->DeleteChilds();1060delete root;1061}106210631064void ADTree3F :: Insert (const float * p, int pi)1065{1066ADTreeNode3F *node;1067ADTreeNode3F *next;1068int lr;10691070float bmin[3];1071float bmax[3];1072int i, dir;10731074memcpy (bmin, cmin, 3 * sizeof(float));1075memcpy (bmax, cmax, 3 * sizeof(float));107610771078next = root;1079while (next)1080{1081node = next;10821083if (!node->pi)1084{1085memcpy (node->data, p, 3 * sizeof(float));1086node->pi = pi;10871088if (ela.Size() < pi)1089ela.SetSize (pi);1090ela.Elem(pi) = node;10911092return;1093}10941095dir = 0;1096for (i = 0; i < 3; i++)1097{1098if (node->sep[i] > p[i])1099{1100bmax[i] = node->sep[i];1101}1102else1103{1104bmin[i] = node->sep[i];1105dir += (1 << i);1106}1107}1108next = node->childs[dir];11091110/*1111if (node->sep > p[dir])1112{1113next = node->left;1114bmax[dir] = node->sep;1115lr = 0;1116}1117else1118{1119next = node->right;1120bmin[dir] = node->sep;1121lr = 1;1122}1123*/1124}112511261127next = new ADTreeNode3F;1128memcpy (next->data, p, 3 * sizeof(float));1129next->pi = pi;11301131for (i = 0; i < 3; i++)1132next->sep[i] = (bmin[i] + bmax[i]) / 2;113311341135if (ela.Size() < pi)1136ela.SetSize (pi);1137ela.Elem(pi) = next;11381139node->childs[dir] = next;1140next->father = node;11411142while (node)1143{1144node->nchilds++;1145node = node->father;1146}1147}11481149void ADTree3F :: DeleteElement (int pi)1150{1151ADTreeNode3F * node = ela.Get(pi);11521153node->pi = 0;11541155node = node->father;1156while (node)1157{1158node->nchilds--;1159node = node->father;1160}1161}11621163void ADTree3F :: GetIntersecting (const float * bmin,1164const float * bmax,1165ARRAY<int> & pis) const1166{1167static ARRAY<ADTreeNode3F*> stack(1000);1168ADTreeNode3F * node;1169int dir, i, stacks;11701171stack.SetSize (1000);1172pis.SetSize(0);11731174stack.Elem(1) = root;1175stacks = 1;11761177while (stacks)1178{1179node = stack.Get(stacks);1180stacks--;11811182if (node->pi)1183{1184if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&1185node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&1186node->data[2] >= bmin[2] && node->data[2] <= bmax[2])11871188pis.Append (node->pi);1189}119011911192int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;1193int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;1194int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;1195int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;1196int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;1197int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;11981199int i1, i2, i3;1200for (i1 = i1min; i1 <= i1max; i1++)1201for (i2 = i2min; i2 <= i2max; i2++)1202for (i3 = i3min; i3 <= i3max; i3++)1203{1204i = i1+2*i2+4*i3;1205if (node->childs[i])1206{1207stacks++;1208stack.Elem(stacks) = node->childs[i];1209}1210}12111212/*1213if (node->left && bmin[dir] <= node->sep)1214{1215stacks++;1216stack.Elem(stacks) = node->left;1217stackdir.Elem(stacks) = ndir;1218}1219if (node->right && bmax[dir] >= node->sep)1220{1221stacks++;1222stack.Elem(stacks) = node->right;1223stackdir.Elem(stacks) = ndir;1224}1225*/1226}1227}12281229void ADTree3F :: PrintRec (ostream & ost, const ADTreeNode3F * node) const1230{1231int i;1232if (node->data)1233{1234ost << node->pi << ": ";1235ost << node->nchilds << " children , ";1236for (i = 0; i < 3; i++)1237ost << node->data[i] << " ";1238ost << endl;1239}12401241for (i = 0; i < 8; i++)1242if (node->childs[i])1243PrintRec (ost, node->childs[i]);1244}12451246124712481249125012511252125312541255125612571258/* ******************************* ADTree3FM ******************************* */125912601261ADTreeNode3FM :: ADTreeNode3FM()1262{1263father = NULL;1264nchilds = 0;1265int i;12661267for (i = 0; i < ADTN_SIZE; i++)1268pi[i] = 0;12691270for (i = 0; i < 8; i++)1271childs[i] = NULL;1272}12731274void ADTreeNode3FM :: DeleteChilds ()1275{1276int i;12771278for (i = 0; i < 8; i++)1279{1280if (childs[i])1281childs[i]->DeleteChilds();1282delete childs[i];1283childs[i] = NULL;1284}1285}128612871288BlockAllocator ADTreeNode3FM :: ball(sizeof (ADTreeNode3FM));12891290void * ADTreeNode3FM :: operator new(size_t)1291{1292return ball.Alloc();1293}12941295void ADTreeNode3FM :: operator delete (void * p)1296{1297ball.Free (p);1298}12991300130113021303130413051306ADTree3FM :: ADTree3FM (const float * acmin,1307const float * acmax)1308: ela(0)1309{1310memcpy (cmin, acmin, 3 * sizeof(float));1311memcpy (cmax, acmax, 3 * sizeof(float));13121313root = new ADTreeNode3FM;1314for (int i = 0; i < 3; i++)1315root->sep[i] = (cmin[i] + cmax[i]) / 2;1316}13171318ADTree3FM :: ~ADTree3FM ()1319{1320root->DeleteChilds();1321delete root;1322}132313241325void ADTree3FM :: Insert (const float * p, int pi)1326{1327ADTreeNode3FM *node;1328ADTreeNode3FM *next;1329int lr;13301331float bmin[3];1332float bmax[3];1333int i, dir;13341335memcpy (bmin, cmin, 3 * sizeof(float));1336memcpy (bmax, cmax, 3 * sizeof(float));13371338next = root;1339while (next)1340{1341node = next;13421343for (i = 0; i < ADTN_SIZE; i++)1344if (!node->pi[i])1345{1346memcpy (node->data[i], p, 3 * sizeof(float));1347node->pi[i] = pi;13481349if (ela.Size() < pi)1350ela.SetSize (pi);1351ela.Elem(pi) = node;13521353return;1354}13551356dir = 0;1357for (i = 0; i < 3; i++)1358{1359if (node->sep[i] > p[i])1360{1361bmax[i] = node->sep[i];1362}1363else1364{1365bmin[i] = node->sep[i];1366dir += (1 << i);1367}1368}1369next = node->childs[dir];13701371/*1372if (node->sep > p[dir])1373{1374next = node->left;1375bmax[dir] = node->sep;1376lr = 0;1377}1378else1379{1380next = node->right;1381bmin[dir] = node->sep;1382lr = 1;1383}1384*/1385}138613871388next = new ADTreeNode3FM;1389memcpy (next->data[0], p, 3 * sizeof(float));1390next->pi[0] = pi;13911392for (i = 0; i < 3; i++)1393next->sep[i] = (bmin[i] + bmax[i]) / 2;139413951396if (ela.Size() < pi)1397ela.SetSize (pi);1398ela.Elem(pi) = next;13991400node->childs[dir] = next;1401next->father = node;14021403while (node)1404{1405node->nchilds++;1406node = node->father;1407}1408}14091410void ADTree3FM :: DeleteElement (int pi)1411{1412ADTreeNode3FM * node = ela.Get(pi);14131414int i;1415for (i = 0; i < ADTN_SIZE; i++)1416if (node->pi[i] == pi)1417node->pi[i] = 0;14181419node = node->father;1420while (node)1421{1422node->nchilds--;1423node = node->father;1424}1425}14261427void ADTree3FM :: GetIntersecting (const float * bmin,1428const float * bmax,1429ARRAY<int> & pis) const1430{1431static ARRAY<ADTreeNode3FM*> stack(1000);1432ADTreeNode3FM * node;1433int dir, i, stacks;14341435stack.SetSize (1000);1436pis.SetSize(0);14371438stack.Elem(1) = root;1439stacks = 1;14401441while (stacks)1442{1443node = stack.Get(stacks);1444stacks--;14451446int * hpi = node->pi;1447for (i = 0; i < ADTN_SIZE; i++)1448if (hpi[i])1449{1450float * datai = &node->data[i][0];1451if (datai[0] >= bmin[0] && datai[0] <= bmax[0] &&1452datai[1] >= bmin[1] && datai[1] <= bmax[1] &&1453datai[2] >= bmin[2] && datai[2] <= bmax[2])14541455pis.Append (node->pi[i]);1456}14571458/*1459if (node->pi)1460{1461if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&1462node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&1463node->data[2] >= bmin[2] && node->data[2] <= bmax[2])14641465pis.Append (node->pi);1466}1467*/14681469int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;1470int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;1471int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;1472int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;1473int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;1474int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;14751476int i1, i2, i3;1477for (i1 = i1min; i1 <= i1max; i1++)1478for (i2 = i2min; i2 <= i2max; i2++)1479for (i3 = i3min; i3 <= i3max; i3++)1480{1481i = i1+2*i2+4*i3;1482if (node->childs[i])1483{1484stacks++;1485stack.Elem(stacks) = node->childs[i];1486}1487}14881489/*1490if (node->left && bmin[dir] <= node->sep)1491{1492stacks++;1493stack.Elem(stacks) = node->left;1494stackdir.Elem(stacks) = ndir;1495}1496if (node->right && bmax[dir] >= node->sep)1497{1498stacks++;1499stack.Elem(stacks) = node->right;1500stackdir.Elem(stacks) = ndir;1501}1502*/1503}1504}15051506void ADTree3FM :: PrintRec (ostream & ost, const ADTreeNode3FM * node) const1507{1508int i;1509if (node->data)1510{1511ost << node->pi << ": ";1512ost << node->nchilds << " children , ";1513for (i = 0; i < 3; i++)1514ost << node->data[i] << " ";1515ost << endl;1516}15171518for (i = 0; i < 8; i++)1519if (node->childs[i])1520PrintRec (ost, node->childs[i]);1521}15221523152415251526#endif1527152815291530153115321533/* ******************************* ADTree6 ******************************* */153415351536ADTreeNode6 :: ADTreeNode6()1537{1538pi = -1;15391540left = NULL;1541right = NULL;1542father = NULL;1543nchilds = 0;1544}15451546void ADTreeNode6 :: DeleteChilds ()1547{1548if (left)1549{1550left->DeleteChilds();1551delete left;1552left = NULL;1553}1554if (right)1555{1556right->DeleteChilds();1557delete right;1558right = NULL;1559}1560}156115621563BlockAllocator ADTreeNode6 :: ball (sizeof (ADTreeNode6));1564void * ADTreeNode6 :: operator new(size_t)1565{1566return ball.Alloc();1567}15681569void ADTreeNode6 :: operator delete (void * p)1570{1571ball.Free (p);1572}157315741575157615771578ADTree6 :: ADTree6 (const float * acmin,1579const float * acmax)1580: ela(0)1581{1582memcpy (cmin, acmin, 6 * sizeof(float));1583memcpy (cmax, acmax, 6 * sizeof(float));15841585root = new ADTreeNode6;1586root->sep = (cmin[0] + cmax[0]) / 2;1587}15881589ADTree6 :: ~ADTree6 ()1590{1591root->DeleteChilds();1592delete root;1593}15941595void ADTree6 :: Insert (const float * p, int pi)1596{1597ADTreeNode6 *node(NULL);1598ADTreeNode6 *next;1599int dir;1600int lr(0);16011602float bmin[6];1603float bmax[6];160416051606memcpy (bmin, cmin, 6 * sizeof(float));1607memcpy (bmax, cmax, 6 * sizeof(float));16081609next = root;1610dir = 0;1611while (next)1612{1613node = next;16141615if (node->pi == -1)1616{1617memcpy (node->data, p, 6 * sizeof(float));1618node->pi = pi;16191620if (ela.Size() < pi+1)1621ela.SetSize (pi+1);1622ela[pi] = node;16231624return;1625}16261627if (node->sep > p[dir])1628{1629next = node->left;1630bmax[dir] = node->sep;1631lr = 0;1632}1633else1634{1635next = node->right;1636bmin[dir] = node->sep;1637lr = 1;1638}16391640dir++;1641if (dir == 6) dir = 0;1642}164316441645next = new ADTreeNode6;1646memcpy (next->data, p, 6 * sizeof(float));1647next->pi = pi;1648next->sep = (bmin[dir] + bmax[dir]) / 2;16491650if (ela.Size() < pi+1)1651ela.SetSize (pi+1);1652ela[pi] = next;16531654if (lr)1655node->right = next;1656else1657node->left = next;1658next -> father = node;16591660while (node)1661{1662node->nchilds++;1663node = node->father;1664}1665}16661667void ADTree6 :: DeleteElement (int pi)1668{1669ADTreeNode6 * node = ela[pi];16701671node->pi = -1;16721673node = node->father;1674while (node)1675{1676node->nchilds--;1677node = node->father;1678}1679}16801681void ADTree6 :: PrintMemInfo (ostream & ost) const1682{1683ost << Elements() << " elements a " << sizeof(ADTreeNode6)1684<< " Bytes = "1685<< Elements() * sizeof(ADTreeNode6) << endl;1686ost << "maxind = " << ela.Size() << " = " << sizeof(ADTreeNode6*) * ela.Size() << " Bytes" << endl;1687}1688168916901691class inttn6 {1692public:1693int dir;1694ADTreeNode6 * node;1695};16961697169816991700void ADTree6 :: GetIntersecting (const float * bmin,1701const float * bmax,1702ARRAY<int> & pis) const1703{1704static ARRAY<inttn6> stack(10000);17051706stack.SetSize (10000);1707pis.SetSize(0);17081709stack[0].node = root;1710stack[0].dir = 0;1711int stacks = 0;17121713while (stacks >= 0)1714{1715ADTreeNode6 * node = stack[stacks].node;1716int dir = stack[stacks].dir;17171718stacks--;17191720if (node->pi != -1)1721{1722if (node->data[0] > bmax[0] ||1723node->data[1] > bmax[1] ||1724node->data[2] > bmax[2] ||1725node->data[3] < bmin[3] ||1726node->data[4] < bmin[4] ||1727node->data[5] < bmin[5])1728;1729else1730pis.Append (node->pi);1731}17321733int ndir = (dir+1) % 6;17341735if (node->left && bmin[dir] <= node->sep)1736{1737stacks++;1738stack[stacks].node = node->left;1739stack[stacks].dir = ndir;1740}1741if (node->right && bmax[dir] >= node->sep)1742{1743stacks++;1744stack[stacks].node = node->right;1745stack[stacks].dir = ndir;1746}1747}1748}17491750void ADTree6 :: PrintRec (ostream & ost, const ADTreeNode6 * node) const1751{17521753if (node->data)1754{1755ost << node->pi << ": ";1756ost << node->nchilds << " children , ";1757for (int i = 0; i < 6; i++)1758ost << node->data[i] << " ";1759ost << endl;1760}1761if (node->left)1762PrintRec (ost, node->left);1763if (node->right)1764PrintRec (ost, node->right);1765}176617671768int ADTree6 :: DepthRec (const ADTreeNode6 * node) const1769{1770int ldepth = 0;1771int rdepth = 0;17721773if (node->left)1774ldepth = DepthRec(node->left);1775if (node->right)1776rdepth = DepthRec(node->right);1777return 1 + max2 (ldepth, rdepth);1778}17791780int ADTree6 :: ElementsRec (const ADTreeNode6 * node) const1781{1782int els = 1;1783if (node->left)1784els += ElementsRec(node->left);1785if (node->right)1786els += ElementsRec(node->right);1787return els;1788}1789179017911792179317941795#ifdef ABC17961797/* ******************************* ADTree6F ******************************* */179817991800ADTreeNode6F :: ADTreeNode6F()1801{1802pi = 0;1803father = NULL;1804nchilds = 0;1805int i;1806for (i = 0; i < 64; i++)1807childs[i] = NULL;1808}18091810void ADTreeNode6F :: DeleteChilds ()1811{1812int i;18131814for (i = 0; i < 64; i++)1815{1816if (childs[i])1817childs[i]->DeleteChilds();1818delete childs[i];1819childs[i] = NULL;1820}1821}182218231824BlockAllocator ADTreeNode6F :: ball(sizeof (ADTreeNode6F));18251826void * ADTreeNode6F :: operator new(size_t)1827{1828return ball.Alloc();1829}18301831void ADTreeNode6F :: operator delete (void * p)1832{1833ball.Free (p);1834}18351836183718381839184018411842ADTree6F :: ADTree6F (const float * acmin,1843const float * acmax)1844: ela(0)1845{1846memcpy (cmin, acmin, 6 * sizeof(float));1847memcpy (cmax, acmax, 6 * sizeof(float));18481849root = new ADTreeNode6F;1850for (int i = 0; i < 6; i++)1851root->sep[i] = (cmin[i] + cmax[i]) / 2;1852}18531854ADTree6F :: ~ADTree6F ()1855{1856root->DeleteChilds();1857delete root;1858}185918601861void ADTree6F :: Insert (const float * p, int pi)1862{1863ADTreeNode6F *node;1864ADTreeNode6F *next;1865int lr;18661867float bmin[6];1868float bmax[6];1869int i, dir;18701871memcpy (bmin, cmin, 6 * sizeof(float));1872memcpy (bmax, cmax, 6 * sizeof(float));18731874next = root;1875while (next)1876{1877node = next;18781879if (!node->pi)1880{1881memcpy (node->data, p, 6 * sizeof(float));1882node->pi = pi;18831884if (ela.Size() < pi)1885ela.SetSize (pi);1886ela.Elem(pi) = node;18871888return;1889}18901891dir = 0;1892for (i = 0; i < 6; i++)1893{1894if (node->sep[i] > p[i])1895{1896bmax[i] = node->sep[i];1897}1898else1899{1900bmin[i] = node->sep[i];1901dir += (1 << i);1902}1903}1904next = node->childs[dir];19051906/*1907if (node->sep > p[dir])1908{1909next = node->left;1910bmax[dir] = node->sep;1911lr = 0;1912}1913else1914{1915next = node->right;1916bmin[dir] = node->sep;1917lr = 1;1918}1919*/1920}192119221923next = new ADTreeNode6F;1924memcpy (next->data, p, 6 * sizeof(float));1925next->pi = pi;19261927for (i = 0; i < 6; i++)1928next->sep[i] = (bmin[i] + bmax[i]) / 2;192919301931if (ela.Size() < pi)1932ela.SetSize (pi);1933ela.Elem(pi) = next;19341935node->childs[dir] = next;1936next->father = node;19371938while (node)1939{1940node->nchilds++;1941node = node->father;1942}1943}19441945void ADTree6F :: DeleteElement (int pi)1946{1947ADTreeNode6F * node = ela.Get(pi);19481949node->pi = 0;19501951node = node->father;1952while (node)1953{1954node->nchilds--;1955node = node->father;1956}1957}19581959void ADTree6F :: GetIntersecting (const float * bmin,1960const float * bmax,1961ARRAY<int> & pis) const1962{1963static ARRAY<ADTreeNode6F*> stack(1000);1964ADTreeNode6F * node;1965int dir, i, stacks;19661967stack.SetSize (1000);1968pis.SetSize(0);19691970stack.Elem(1) = root;1971stacks = 1;19721973while (stacks)1974{1975node = stack.Get(stacks);1976stacks--;19771978if (node->pi)1979{1980if (1981node->data[0] >= bmin[0] && node->data[0] <= bmax[0] &&1982node->data[1] >= bmin[1] && node->data[1] <= bmax[1] &&1983node->data[2] >= bmin[2] && node->data[2] <= bmax[2] &&1984node->data[3] >= bmin[3] && node->data[3] <= bmax[3] &&1985node->data[4] >= bmin[4] && node->data[4] <= bmax[4] &&1986node->data[5] >= bmin[5] && node->data[5] <= bmax[5]1987)19881989pis.Append (node->pi);1990}199119921993int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1;1994int i1max = (bmax[0] < node->sep[0]) ? 0 : 1;1995int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1;1996int i2max = (bmax[1] < node->sep[1]) ? 0 : 1;1997int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1;1998int i3max = (bmax[2] < node->sep[2]) ? 0 : 1;19992000int i4min = (bmin[3] <= node->sep[3]) ? 0 : 1;2001int i4max = (bmax[3] < node->sep[3]) ? 0 : 1;2002int i5min = (bmin[4] <= node->sep[4]) ? 0 : 1;2003int i5max = (bmax[4] < node->sep[4]) ? 0 : 1;2004int i6min = (bmin[5] <= node->sep[5]) ? 0 : 1;2005int i6max = (bmax[5] < node->sep[5]) ? 0 : 1;20062007int i1, i2, i3, i4, i5, i6;2008for (i1 = i1min; i1 <= i1max; i1++)2009for (i2 = i2min; i2 <= i2max; i2++)2010for (i3 = i3min; i3 <= i3max; i3++)2011for (i4 = i4min; i4 <= i4max; i4++)2012for (i5 = i5min; i5 <= i5max; i5++)2013for (i6 = i6min; i6 <= i6max; i6++)2014{2015i = i1 + 2*i2 + 4*i3 + 8*i4 + 16*i5 +32*i6;2016if (node->childs[i])2017{2018stacks++;2019stack.Elem(stacks) = node->childs[i];2020}2021}20222023/*2024if (node->left && bmin[dir] <= node->sep)2025{2026stacks++;2027stack.Elem(stacks) = node->left;2028stackdir.Elem(stacks) = ndir;2029}2030if (node->right && bmax[dir] >= node->sep)2031{2032stacks++;2033stack.Elem(stacks) = node->right;2034stackdir.Elem(stacks) = ndir;2035}2036*/2037}2038}20392040void ADTree6F :: PrintRec (ostream & ost, const ADTreeNode6F * node) const2041{2042int i;2043if (node->data)2044{2045ost << node->pi << ": ";2046ost << node->nchilds << " children , ";2047for (i = 0; i < 6; i++)2048ost << node->data[i] << " ";2049ost << endl;2050}20512052for (i = 0; i < 64; i++)2053if (node->childs[i])2054PrintRec (ost, node->childs[i]);2055}2056205720582059#endif2060206120622063/* ************************************* Point3dTree ********************** */2064206520662067Point3dTree :: Point3dTree (const Point3d & pmin, const Point3d & pmax)2068{2069float pmi[3], pma[3];2070for (int i = 0; i < 3; i++)2071{2072pmi[i] = pmin.X(i+1);2073pma[i] = pmax.X(i+1);2074}2075tree = new ADTree3 (pmi, pma);2076}20772078Point3dTree :: ~Point3dTree ()2079{2080delete tree;2081}2082208320842085void Point3dTree :: Insert (const Point3d & p, int pi)2086{2087static float pd[3];2088pd[0] = p.X();2089pd[1] = p.Y();2090pd[2] = p.Z();2091tree->Insert (pd, pi);2092}20932094void Point3dTree :: GetIntersecting (const Point3d & pmin, const Point3d & pmax,2095ARRAY<int> & pis) const2096{2097float pmi[3], pma[3];2098for (int i = 0; i < 3; i++)2099{2100pmi[i] = pmin.X(i+1);2101pma[i] = pmax.X(i+1);2102}2103tree->GetIntersecting (pmi, pma, pis);2104}21052106210721082109211021112112211321142115Box3dTree :: Box3dTree (const Point3d & apmin, const Point3d & apmax)2116{2117boxpmin = apmin;2118boxpmax = apmax;2119float tpmin[6], tpmax[6];2120for (int i = 0; i < 3; i++)2121{2122tpmin[i] = tpmin[i+3] = boxpmin.X(i+1);2123tpmax[i] = tpmax[i+3] = boxpmax.X(i+1);2124}2125tree = new ADTree6 (tpmin, tpmax);2126}21272128Box3dTree :: ~Box3dTree ()2129{2130delete tree;2131}21322133void Box3dTree :: Insert (const Point3d & bmin, const Point3d & bmax, int pi)2134{2135static float tp[6];21362137for (int i = 0; i < 3; i++)2138{2139tp[i] = bmin.X(i+1);2140tp[i+3] = bmax.X(i+1);2141}21422143tree->Insert (tp, pi);2144}21452146void Box3dTree ::GetIntersecting (const Point3d & pmin, const Point3d & pmax,2147ARRAY<int> & pis) const2148{2149float tpmin[6];2150float tpmax[6];21512152for (int i = 0; i < 3; i++)2153{2154tpmin[i] = boxpmin.X(i+1);2155tpmax[i] = pmax.X(i+1);21562157tpmin[i+3] = pmin.X(i+1);2158tpmax[i+3] = boxpmax.X(i+1);2159}21602161tree->GetIntersecting (tpmin, tpmax, pis);2162}21632164}216521662167