25 #include <sys/malloc.h>
39 #define N(x) nodes_[(x)]
40 #define V(x) vertices_[nodes_[index].v_[(x)]]
41 #define IV(x) nodes_[index].v_[(x)]
42 #define W(x) vertices_[nodes_[index].w_[(x)]]
43 #define IW(x) nodes_[index].w_[(x)]
44 #define ICHILD(x) nodes_[index].childID_[(x)]
46 #define IV_(x) nodes_[index_].v_[(x)]
47 #define IW_(x) nodes_[index_].w_[(x)]
48 #define ICHILD_(x) nodes_[index_].childID_[(x)]
61 buildlevel_( (buildlevel == 0 || buildlevel > maxlevel) ? maxlevel : buildlevel)
63 size_t nodes,vertices;
65 vMax(&nodes,&vertices);
66 layers_.resize(buildlevel_+1);
67 nodes_.resize(nodes+1);
68 vertices_.resize(vertices+1);
73 layers_[0].level_ = 0;
74 layers_[0].nVert_ = 6;
75 layers_[0].nNode_ = 8;
76 layers_[0].nEdge_ = 12;
77 layers_[0].firstIndex_ = 1;
78 layers_[0].firstVertex_ = 0;
90 for(
int i = 0; i < 6; i++)
91 vertices_[i].set( v[i][0], v[i][1], v[i][2]);
107 size_t level = buildlevel_;
127 if(buildlevel_ == maxlevel_) {
129 v0 = vertices_[nodes_[idx].v_[0]];
130 v1 = vertices_[nodes_[idx].v_[1]];
131 v2 = vertices_[nodes_[idx].v_[2]];
138 uint64 sid =
id >> ((maxlevel_ - buildlevel_)*2);
141 v0 = vertices_[nodes_[idx].v_[0]];
142 v1 = vertices_[nodes_[idx].v_[1]];
143 v2 = vertices_[nodes_[idx].v_[2]];
148 for(
uint32 i = buildlevel_ + 1; i <= maxlevel_; i++) {
149 uint64 j = (
id >> ((maxlevel_ - i)*2) ) & 3;
182 SpatialIndex::makeNewLayer(
size_t oldlayer)
185 size_t newlayer = oldlayer + 1;
186 layers_[newlayer].level_ = layers_[oldlayer].level_+1;
187 layers_[newlayer].nVert_ = layers_[oldlayer].nVert_ +
188 layers_[oldlayer].nEdge_;
189 layers_[newlayer].nNode_ = 4 * layers_[oldlayer].nNode_;
190 layers_[newlayer].nEdge_ = layers_[newlayer].nNode_ +
191 layers_[newlayer].nVert_ - 2;
192 layers_[newlayer].firstIndex_ = index_;
193 layers_[newlayer].firstVertex_ = layers_[oldlayer].firstVertex_ +
194 layers_[oldlayer].nVert_;
196 uint64 ioffset = layers_[oldlayer].firstIndex_ ;
199 index < ioffset + layers_[oldlayer].nNode_; index++){
200 id =
N(index).id_ << 2;
212 SpatialIndex::newNode(
size_t v1,
size_t v2,
size_t v3,
uint64 id,
uint64 parent)
228 N(index_).index_ = index_;
229 N(index_).parent_ = parent;
241 SpatialIndex::vMax(
size_t *nodes,
size_t *vertices) {
245 int32 i = buildlevel_;
252 *nodes += (size_t)nf;
254 *vertices = (size_t)nv;
258 i = maxlevel_ - buildlevel_;
271 SpatialIndex::sortIndex() {
272 std::vector<QuadNode> oldnodes(nodes_);
277 #define ON(x) oldnodes[(x)]
281 index < nodes_.size(); index++) {
283 if(
ON(index).childID_[0] == 0 ) {
287 for (
size_t i = 0; i < 4; i++) {
288 if(
N(
N(leaf).parent_).childID_[i] == index) {
289 N(
N(leaf).parent_).childID_[i] = leaf;
298 N(nonleaf) =
ON(index);
299 ON(
N(nonleaf).childID_[0]).parent_ = nonleaf;
300 ON(
N(nonleaf).childID_[1]).parent_ = nonleaf;
301 ON(
N(nonleaf).childID_[2]).parent_ = nonleaf;
302 ON(
N(nonleaf).childID_[3]).parent_ = nonleaf;
304 for (
size_t i = 0; i < 4; i++) {
305 if(
N(
N(nonleaf).parent_).childID_[i] == index) {
306 N(
N(nonleaf).parent_).childID_[i] = nonleaf;
345 if(name[0] !=
'N' && name[0] !=
'S')
351 throw SpatialFailure(
"SpatialIndex:idByName:invalid name - too short ",name);
353 throw SpatialFailure(
"SpatialIndex:idByName:invalid name - too long ",name);
355 for(i = size-1; i > 0; i--) {
356 if(name[i] >
'3' || name[i] <
'0')
357 throw SpatialFailure(
"SpatialIndex:idByName:invalid name digit ",name);
358 out += (
uint64(name[i]-
'0') << 2*(size - i -1));
362 if(name[0]==
'N') i++;
363 out += (i << (2*size - 2) );
401 IDHIGHBIT = IDHIGHBIT << 63;
402 IDHIGHBIT2 = IDHIGHBIT2 << 62;
419 for(i = 0; i <
IDSIZE; i+=2) {
420 if ( (
id << i) & IDHIGHBIT )
break;
421 if ( (
id << i) & IDHIGHBIT2 )
427 size=(IDSIZE-i) >> 1;
430 name =
new char[size+1];
433 for(i = 0; i < size-1; i++)
434 name[size-i-1] =
'0' +
char( (
id >> i*2) & 3);
437 if( (
id >> (size*2-2)) & 1 ) {
453 float64 center_x, center_y, center_z, sum;
482 center_x = v0.x_ + v1.x_ + v2.x_;
483 center_y = v0.y_ + v1.y_ + v2.y_;
484 center_z = v0.z_ + v1.z_ + v2.z_;
485 sum = center_x * center_x + center_y * center_y + center_z * center_z;
506 for(index=1; index <=8; index++) {
515 for(
size_t i = 0; i < 4; i++) {
516 index = nodes_[oldindex].childID_[i];
524 if(maxlevel_ == buildlevel_)
return N(index).id_;
531 size_t len = strlen(name);
536 size_t level = maxlevel_ - buildlevel_;
543 if(isInside(v, v0, w2, w1)) {
547 }
else if(isInside(v, v1, w0, w2)) {
549 v0 = v1; v1 = w0; v2 = w2;
551 }
else if(isInside(v, v2, w1, w0)) {
553 v0 = v2; v1 = w1; v2 = w0;
555 }
else if(isInside(v, w0, w1, w2)) {
557 v0 = w0; v1 = w1; v2 = w2;
573 if( (v0 ^ v1) * v < -
gEpsilon)
return false;
574 if( (v1 ^ v2) * v < -
gEpsilon)
return false;
575 if( (v2 ^ v0) * v < -
gEpsilon)
return false;
SpatialException thrown on operational failure.
static uint64 idByName(const char *)
NodeName conversion to integer ID.
static char * nameById(uint64 ID, char *name=0)
int32 conversion to a string (name of database).
void pointById(SpatialVector &vector, uint64 ID) const
find the vector to the centroid of a triangle represented by the ID
The SpatialVector is a 3D vector usually living on the surface of the sphere.
SpatialIndex(size_t maxlevel, size_t buildlevel=5)
Constructor.
uint64 idByPoint(const SpatialVector &vector) const
find a node by giving a vector.
void nodeVertex(const uint64 id, SpatialVector &v1, SpatialVector &v2, SpatialVector &v3) const
return the actual vertex vectors
unsigned long long uint64
void normalize()
Normalize vector length to 1.