pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00044 #ifdef HAVE_CONFIG_H 00045 #include "config.h" 00046 #endif 00047 00048 #include "global.h" 00049 00050 #include <assert.h> 00051 #include <inttypes.h> 00052 #include <setjmp.h> 00053 00054 #include "mymem.h" 00055 00056 #include "rtree.h" 00057 00058 #ifdef HAVE_LIBDMALLOC 00059 #include <dmalloc.h> 00060 #endif 00061 00062 #define SLOW_ASSERTS 00063 /* All rectangles are closed on the bottom left and open on the 00064 * top right. i.e. they contain one corner point, but not the other. 00065 * This requires that the corner points not be equal! 00066 */ 00067 00068 /* the number of entries in each rtree node 00069 * 4 - 7 seem to be pretty good settings 00070 */ 00071 #define M_SIZE 6 00072 00073 /* it seems that sorting the leaf order slows us down 00074 * but sometimes gives better routes 00075 */ 00076 #undef SORT 00077 #define SORT_NONLEAF 00078 00079 #define DELETE_BY_POINTER 00080 00081 typedef struct 00082 { 00083 const BoxType *bptr; /* pointer to the box */ 00084 BoxType bounds; /* copy of the box for locality of reference */ 00085 } Rentry; 00086 00087 struct rtree_node 00088 { 00089 BoxType box; /* bounds rectangle of this node */ 00090 struct rtree_node *parent; /* parent of this node, NULL = root */ 00091 struct 00092 { 00093 unsigned is_leaf:1; /* this is a leaf node */ 00094 unsigned manage:31; /* true==should free 'rect.bptr' if node is destroyed */ 00095 } 00096 flags; 00097 union 00098 { 00099 struct rtree_node *kids[M_SIZE + 1]; /* when not leaf */ 00100 Rentry rects[M_SIZE + 1]; /* when leaf */ 00101 } u; 00102 }; 00103 00104 #ifndef NDEBUG 00105 #ifdef SLOW_ASSERTS 00106 static int 00107 __r_node_is_good (struct rtree_node *node) 00108 { 00109 int i, flag = 1; 00110 int kind = -1; 00111 bool last = false; 00112 00113 if (node == NULL) 00114 return 1; 00115 for (i = 0; i < M_SIZE; i++) 00116 { 00117 if (node->flags.is_leaf) 00118 { 00119 if (!node->u.rects[i].bptr) 00120 { 00121 last = true; 00122 continue; 00123 } 00124 /* check that once one entry is empty, all the rest are too */ 00125 if (node->u.rects[i].bptr && last) 00126 assert (0); 00127 /* check that the box makes sense */ 00128 if (node->box.X1 > node->box.X2) 00129 assert (0); 00130 if (node->box.Y1 > node->box.Y2) 00131 assert (0); 00132 /* check that bounds is the same as the pointer */ 00133 if (node->u.rects[i].bounds.X1 != node->u.rects[i].bptr->X1) 00134 assert (0); 00135 if (node->u.rects[i].bounds.Y1 != node->u.rects[i].bptr->Y1) 00136 assert (0); 00137 if (node->u.rects[i].bounds.X2 != node->u.rects[i].bptr->X2) 00138 assert (0); 00139 if (node->u.rects[i].bounds.Y2 != node->u.rects[i].bptr->Y2) 00140 assert (0); 00141 /* check that entries are within node bounds */ 00142 if (node->u.rects[i].bounds.X1 < node->box.X1) 00143 assert (0); 00144 if (node->u.rects[i].bounds.X2 > node->box.X2) 00145 assert (0); 00146 if (node->u.rects[i].bounds.Y1 < node->box.Y1) 00147 assert (0); 00148 if (node->u.rects[i].bounds.Y2 > node->box.Y2) 00149 assert (0); 00150 } 00151 else 00152 { 00153 if (!node->u.kids[i]) 00154 { 00155 last = true; 00156 continue; 00157 } 00158 /* make sure all children are the same type */ 00159 if (kind == -1) 00160 kind = node->u.kids[i]->flags.is_leaf; 00161 else if (kind != node->u.kids[i]->flags.is_leaf) 00162 assert (0); 00163 /* check that once one entry is empty, all the rest are too */ 00164 if (node->u.kids[i] && last) 00165 assert (0); 00166 /* check that entries are within node bounds */ 00167 if (node->u.kids[i]->box.X1 < node->box.X1) 00168 assert (0); 00169 if (node->u.kids[i]->box.X2 > node->box.X2) 00170 assert (0); 00171 if (node->u.kids[i]->box.Y1 < node->box.Y1) 00172 assert (0); 00173 if (node->u.kids[i]->box.Y2 > node->box.Y2) 00174 assert (0); 00175 } 00176 flag <<= 1; 00177 } 00178 /* check that we're completely in the parent's bounds */ 00179 if (node->parent) 00180 { 00181 if (node->parent->box.X1 > node->box.X1) 00182 assert (0); 00183 if (node->parent->box.X2 < node->box.X2) 00184 assert (0); 00185 if (node->parent->box.Y1 > node->box.Y1) 00186 assert (0); 00187 if (node->parent->box.Y2 < node->box.Y2) 00188 assert (0); 00189 } 00190 /* make sure overflow is empty */ 00191 if (!node->flags.is_leaf && node->u.kids[i]) 00192 assert (0); 00193 if (node->flags.is_leaf && node->u.rects[i].bptr) 00194 assert (0); 00195 return 1; 00196 } 00197 00201 static bool 00202 __r_tree_is_good (struct rtree_node *node) 00203 { 00204 int i; 00205 00206 if (!node) 00207 return 1; 00208 if (!__r_node_is_good (node)) 00209 assert (0); 00210 if (node->flags.is_leaf) 00211 return 1; 00212 for (i = 0; i < M_SIZE; i++) 00213 { 00214 if (!__r_tree_is_good (node->u.kids[i])) 00215 return 0; 00216 } 00217 return 1; 00218 } 00219 #endif 00220 #endif 00221 00222 #ifndef NDEBUG 00223 00226 void 00227 __r_dump_tree (struct rtree_node *node, int depth) 00228 { 00229 int i, j; 00230 static int count; 00231 static double area; 00232 00233 if (depth == 0) 00234 { 00235 area = 0; 00236 count = 0; 00237 } 00238 area += 00239 (node->box.X2 - node->box.X1) * (double) (node->box.Y2 - node->box.Y1); 00240 count++; 00241 for (i = 0; i < depth; i++) 00242 printf (" "); 00243 if (!node->flags.is_leaf) 00244 { 00245 printf ( 00246 "p=0x%p node X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", %" PRIi64 00247 ")\n", 00248 (void *) node, 00249 (int64_t) (node->box.X1), 00250 (int64_t) (node->box.X2), 00251 (int64_t) (node->box.Y1), 00252 (int64_t) (node->box.Y2) ); 00253 } 00254 else 00255 { 00256 printf ( 00257 "p=0x%p leaf manage(%02x) X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 00258 ", %" PRIi64 ")\n", 00259 (void *) node, 00260 node->flags.manage, 00261 (int64_t) (node->box.X1), 00262 (int64_t) (node->box.X2), 00263 (int64_t) (node->box.Y1), 00264 (int64_t) (node->box.Y2) ); 00265 for (j = 0; j < M_SIZE; j++) 00266 { 00267 if (!node->u.rects[j].bptr) 00268 break; 00269 area += 00270 (node->u.rects[j].bounds.X2 - 00271 node->u.rects[j].bounds.X1) * 00272 (double) (node->u.rects[j].bounds.Y2 - 00273 node->u.rects[j].bounds.Y1); 00274 count++; 00275 for (i = 0; i < depth + 1; i++) 00276 printf (" "); 00277 printf ( 00278 "entry 0x%p X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", " 00279 "%" PRIi64 ")\n", 00280 (void *) (node->u.rects[j].bptr), 00281 (int64_t) (node->u.rects[j].bounds.X1), 00282 (int64_t) (node->u.rects[j].bounds.X2), 00283 (int64_t) (node->u.rects[j].bounds.Y1), 00284 (int64_t) (node->u.rects[j].bounds.Y2) ); 00285 } 00286 return; 00287 } 00288 for (i = 0; i < M_SIZE; i++) 00289 if (node->u.kids[i]) 00290 __r_dump_tree (node->u.kids[i], depth + 1); 00291 if (depth == 0) 00292 printf ("average box area is %g\n", area / count); 00293 } 00294 #endif 00295 00296 #ifdef SORT 00297 00307 static int 00308 cmp_box (const BoxType * a, const BoxType * b) 00309 { 00310 if (a->X1 < b->X1) 00311 return 0; 00312 if (a->X1 > b->X1) 00313 return 1; 00314 if (a->X2 > b->X2) 00315 return 0; 00316 if (a->X2 < b->X2) 00317 return 1; 00318 if (a->Y1 < b->Y1) 00319 return 0; 00320 if (a->Y1 > b->Y1) 00321 return 1; 00322 if (a->Y2 > b->Y2) 00323 return 0; 00324 return 1; 00325 } 00326 00327 static void 00328 sort_node (struct rtree_node *node) 00329 { 00330 if (node->flags.is_leaf) 00331 { 00332 register Rentry *r, *i, temp; 00333 00334 for (r = &node->u.rects[1]; r->bptr; r++) 00335 { 00336 temp = *r; 00337 i = r - 1; 00338 while (i >= &node->u.rects[0]) 00339 { 00340 if (cmp_box (&i->bounds, &r->bounds)) 00341 break; 00342 *(i + 1) = *i; 00343 i--; 00344 } 00345 *(i + 1) = temp; 00346 } 00347 } 00348 #ifdef SORT_NONLEAF 00349 else 00350 { 00351 register struct rtree_node **r, **i, *temp; 00352 00353 for (r = &node->u.kids[1]; *r; r++) 00354 { 00355 temp = *r; 00356 i = r - 1; 00357 while (i >= &node->u.kids[0]) 00358 { 00359 if (cmp_box (&(*i)->box, &(*r)->box)) 00360 break; 00361 *(i + 1) = *i; 00362 i--; 00363 } 00364 *(i + 1) = temp; 00365 } 00366 } 00367 #endif 00368 } 00369 #else 00370 #define sort_node(x) 00371 #endif 00372 00377 static void 00378 adjust_bounds (struct rtree_node *node) 00379 { 00380 int i; 00381 00382 assert (node); 00383 assert (node->u.kids[0]); 00384 if (node->flags.is_leaf) 00385 { 00386 node->box = node->u.rects[0].bounds; 00387 for (i = 1; i < M_SIZE + 1; i++) 00388 { 00389 if (!node->u.rects[i].bptr) 00390 return; 00391 MAKEMIN (node->box.X1, node->u.rects[i].bounds.X1); 00392 MAKEMAX (node->box.X2, node->u.rects[i].bounds.X2); 00393 MAKEMIN (node->box.Y1, node->u.rects[i].bounds.Y1); 00394 MAKEMAX (node->box.Y2, node->u.rects[i].bounds.Y2); 00395 } 00396 } 00397 else 00398 { 00399 node->box = node->u.kids[0]->box; 00400 for (i = 1; i < M_SIZE + 1; i++) 00401 { 00402 if (!node->u.kids[i]) 00403 return; 00404 MAKEMIN (node->box.X1, node->u.kids[i]->box.X1); 00405 MAKEMAX (node->box.X2, node->u.kids[i]->box.X2); 00406 MAKEMIN (node->box.Y1, node->u.kids[i]->box.Y1); 00407 MAKEMAX (node->box.Y2, node->u.kids[i]->box.Y2); 00408 } 00409 } 00410 } 00411 00424 rtree_t * 00425 r_create_tree (const BoxType * boxlist[], int N, int manage) 00426 { 00427 rtree_t *rtree; 00428 struct rtree_node *node; 00429 int i; 00430 00431 assert (N >= 0); 00432 rtree = (rtree_t *)calloc (1, sizeof (*rtree)); 00433 /* start with a single empty leaf node */ 00434 node = (struct rtree_node *)calloc (1, sizeof (*node)); 00435 node->flags.is_leaf = 1; 00436 node->parent = NULL; 00437 rtree->root = node; 00438 /* simple, just insert all of the boxes! */ 00439 for (i = 0; i < N; i++) 00440 { 00441 assert (boxlist[i]); 00442 r_insert_entry (rtree, boxlist[i], manage); 00443 } 00444 #ifdef SLOW_ASSERTS 00445 assert (__r_tree_is_good (rtree->root)); 00446 #endif 00447 return rtree; 00448 } 00449 00453 static void 00454 __r_destroy_tree (struct rtree_node *node) 00455 { 00456 int i, flag = 1; 00457 00458 if (node->flags.is_leaf) 00459 for (i = 0; i < M_SIZE; i++) 00460 { 00461 if (!node->u.rects[i].bptr) 00462 break; 00463 if (node->flags.manage & flag) 00464 free ((void *) node->u.rects[i].bptr); 00465 flag = flag << 1; 00466 } 00467 else 00468 for (i = 0; i < M_SIZE; i++) 00469 { 00470 if (!node->u.kids[i]) 00471 break; 00472 __r_destroy_tree (node->u.kids[i]); 00473 } 00474 free (node); 00475 } 00476 00480 void 00481 r_destroy_tree (rtree_t ** rtree) 00482 { 00483 00484 __r_destroy_tree ((*rtree)->root); 00485 free (*rtree); 00486 *rtree = NULL; 00487 } 00488 00489 typedef struct 00490 { 00491 int (*check_it) (const BoxType * region, void *cl); 00492 int (*found_it) (const BoxType * box, void *cl); 00493 void *closure; 00494 } r_arg; 00495 00503 int 00504 __r_search (struct rtree_node *node, const BoxType * query, r_arg * arg) 00505 { 00506 assert (node); 00507 /* assert that starting_region is well formed */ 00508 assert (query->X1 < query->X2 && query->Y1 < query->Y2); 00509 assert (node->box.X1 < query->X2 && node->box.X2 > query->X1 && 00510 node->box.Y1 < query->Y2 && node->box.Y2 > query->Y1); 00511 #ifdef SLOW_ASSERTS 00512 /* assert that node is well formed */ 00513 assert (__r_node_is_good (node)); 00514 #endif 00515 /* the check for bounds is done before entry. This saves the overhead 00516 * of building/destroying the stack frame for each bounds that fails 00517 * to intersect, which is the most common condition. 00518 */ 00519 if (node->flags.is_leaf) 00520 { 00521 register int i; 00522 if (arg->found_it) /* test this once outside of loop */ 00523 { 00524 register int seen = 0; 00525 for (i = 0; node->u.rects[i].bptr; i++) 00526 { 00527 if ((node->u.rects[i].bounds.X1 < query->X2) && 00528 (node->u.rects[i].bounds.X2 > query->X1) && 00529 (node->u.rects[i].bounds.Y1 < query->Y2) && 00530 (node->u.rects[i].bounds.Y2 > query->Y1) && 00531 arg->found_it (node->u.rects[i].bptr, arg->closure)) 00532 seen++; 00533 } 00534 return seen; 00535 } 00536 else 00537 { 00538 register int seen = 0; 00539 for (i = 0; node->u.rects[i].bptr; i++) 00540 { 00541 if ((node->u.rects[i].bounds.X1 < query->X2) && 00542 (node->u.rects[i].bounds.X2 > query->X1) && 00543 (node->u.rects[i].bounds.Y1 < query->Y2) && 00544 (node->u.rects[i].bounds.Y2 > query->Y1)) 00545 seen++; 00546 } 00547 return seen; 00548 } 00549 } 00550 00551 /* not a leaf, recurse on lower nodes */ 00552 if (arg->check_it) 00553 { 00554 int seen = 0; 00555 struct rtree_node **n; 00556 for (n = &node->u.kids[0]; *n; n++) 00557 { 00558 if ((*n)->box.X1 >= query->X2 || 00559 (*n)->box.X2 <= query->X1 || 00560 (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1 || 00561 !arg->check_it (&(*n)->box, arg->closure)) 00562 continue; 00563 seen += __r_search (*n, query, arg); 00564 } 00565 return seen; 00566 } 00567 else 00568 { 00569 int seen = 0; 00570 struct rtree_node **n; 00571 for (n = &node->u.kids[0]; *n; n++) 00572 { 00573 if ((*n)->box.X1 >= query->X2 || 00574 (*n)->box.X2 <= query->X1 || 00575 (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1) 00576 continue; 00577 seen += __r_search (*n, query, arg); 00578 } 00579 return seen; 00580 } 00581 } 00582 00611 int 00612 r_search (rtree_t * rtree, const BoxType * query, 00613 int (*check_region) (const BoxType * region, void *cl), 00614 int (*found_rectangle) (const BoxType * box, void *cl), void *cl) 00615 { 00616 r_arg arg; 00617 00618 if (!rtree || rtree->size < 1) 00619 return 0; 00620 if (query) 00621 { 00622 #ifdef SLOW_ASSERTS 00623 assert (__r_tree_is_good (rtree->root)); 00624 #endif 00625 #ifdef DEBUG 00626 if (query->X2 <= query->X1 || query->Y2 <= query->Y1) 00627 return 0; 00628 #endif 00629 /* check this box. If it's not touched we're done here */ 00630 if (rtree->root->box.X1 >= query->X2 || 00631 rtree->root->box.X2 <= query->X1 || 00632 rtree->root->box.Y1 >= query->Y2 00633 || rtree->root->box.Y2 <= query->Y1) 00634 return 0; 00635 arg.check_it = check_region; 00636 arg.found_it = found_rectangle; 00637 arg.closure = cl; 00638 return __r_search (rtree->root, query, &arg); 00639 } 00640 else 00641 { 00642 arg.check_it = check_region; 00643 arg.found_it = found_rectangle; 00644 arg.closure = cl; 00645 return __r_search (rtree->root, &rtree->root->box, &arg); 00646 } 00647 } 00648 00652 static int 00653 __r_region_is_empty_rect_in_reg (const BoxType * box, void *cl) 00654 { 00655 jmp_buf *envp = (jmp_buf *) cl; 00656 longjmp (*envp, 1); /* found one! */ 00657 } 00658 00664 int 00665 r_region_is_empty (rtree_t * rtree, const BoxType * region) 00666 { 00667 jmp_buf env; 00668 #ifndef NDEBUG 00669 int r; 00670 #endif 00671 00672 if (setjmp (env)) 00673 return 0; 00674 #ifndef NDEBUG 00675 r = 00676 #endif 00677 r_search (rtree, region, NULL, __r_region_is_empty_rect_in_reg, &env); 00678 #ifndef NDEBUG 00679 assert (r == 0); /* otherwise longjmp would have been called */ 00680 #endif 00681 return 1; /* no rectangles found */ 00682 } 00683 00684 struct centroid 00685 { 00686 float x, y, area; 00687 }; 00688 00693 struct rtree_node * 00694 find_clusters (struct rtree_node *node) 00695 { 00696 float total_a, total_b; 00697 float a_X, a_Y, b_X, b_Y; 00698 bool belong[M_SIZE + 1]; 00699 struct centroid center[M_SIZE + 1]; 00700 int clust_a, clust_b, tries; 00701 int a_manage = 0, b_manage = 0; 00702 int i, old_ax, old_ay, old_bx, old_by; 00703 struct rtree_node *new_node; 00704 BoxType *b; 00705 00706 for (i = 0; i < M_SIZE + 1; i++) 00707 { 00708 if (node->flags.is_leaf) 00709 b = &(node->u.rects[i].bounds); 00710 else 00711 b = &(node->u.kids[i]->box); 00712 center[i].x = 0.5 * (b->X1 + b->X2); 00713 center[i].y = 0.5 * (b->Y1 + b->Y2); 00714 /* adding 1 prevents zero area */ 00715 center[i].area = 1. + (float) (b->X2 - b->X1) * (float) (b->Y2 - b->Y1); 00716 } 00717 /* starting 'A' cluster center */ 00718 a_X = center[0].x; 00719 a_Y = center[0].y; 00720 /* starting 'B' cluster center */ 00721 b_X = center[M_SIZE].x; 00722 b_Y = center[M_SIZE].y; 00723 /* don't allow the same cluster centers */ 00724 if (b_X == a_X && b_Y == a_Y) 00725 { 00726 b_X += 10000; 00727 a_Y -= 10000; 00728 } 00729 for (tries = 0; tries < M_SIZE; tries++) 00730 { 00731 old_ax = (int) a_X; 00732 old_ay = (int) a_Y; 00733 old_bx = (int) b_X; 00734 old_by = (int) b_Y; 00735 clust_a = clust_b = 0; 00736 for (i = 0; i < M_SIZE + 1; i++) 00737 { 00738 float dist1, dist2; 00739 00740 dist1 = SQUARE (a_X - center[i].x) + SQUARE (a_Y - center[i].y); 00741 dist2 = SQUARE (b_X - center[i].x) + SQUARE (b_Y - center[i].y); 00742 if (dist1 * (clust_a + M_SIZE / 2) < dist2 * (clust_b + M_SIZE / 2)) 00743 { 00744 belong[i] = true; 00745 clust_a++; 00746 } 00747 else 00748 { 00749 belong[i] = false; 00750 clust_b++; 00751 } 00752 } 00753 /* kludge to fix degenerate cases */ 00754 if (clust_a == M_SIZE + 1) 00755 belong[M_SIZE / 2] = false; 00756 else if (clust_b == M_SIZE + 1) 00757 belong[M_SIZE / 2] = true; 00758 /* compute new center of gravity of clusters */ 00759 total_a = total_b = 0; 00760 a_X = a_Y = b_X = b_Y = 0; 00761 for (i = 0; i < M_SIZE + 1; i++) 00762 { 00763 if (belong[i]) 00764 { 00765 a_X += center[i].x * center[i].area; 00766 a_Y += center[i].y * center[i].area; 00767 total_a += center[i].area; 00768 } 00769 else 00770 { 00771 b_X += center[i].x * center[i].area; 00772 b_Y += center[i].y * center[i].area; 00773 total_b += center[i].area; 00774 } 00775 } 00776 a_X /= total_a; 00777 a_Y /= total_a; 00778 b_X /= total_b; 00779 b_Y /= total_b; 00780 if (old_ax == (int) a_X && old_ay == (int) a_Y && 00781 old_bx == (int) b_X && old_by == (int) b_Y) 00782 break; 00783 } 00784 /* Now 'belong' has the partition map */ 00785 new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); 00786 new_node->parent = node->parent; 00787 new_node->flags.is_leaf = node->flags.is_leaf; 00788 clust_a = clust_b = 0; 00789 if (node->flags.is_leaf) 00790 { 00791 int flag, a_flag, b_flag; 00792 flag = a_flag = b_flag = 1; 00793 for (i = 0; i < M_SIZE + 1; i++) 00794 { 00795 if (belong[i]) 00796 { 00797 node->u.rects[clust_a++] = node->u.rects[i]; 00798 if (node->flags.manage & flag) 00799 a_manage |= a_flag; 00800 a_flag <<= 1; 00801 } 00802 else 00803 { 00804 new_node->u.rects[clust_b++] = node->u.rects[i]; 00805 if (node->flags.manage & flag) 00806 b_manage |= b_flag; 00807 b_flag <<= 1; 00808 } 00809 flag <<= 1; 00810 } 00811 } 00812 else 00813 { 00814 for (i = 0; i < M_SIZE + 1; i++) 00815 { 00816 if (belong[i]) 00817 node->u.kids[clust_a++] = node->u.kids[i]; 00818 else 00819 { 00820 node->u.kids[i]->parent = new_node; 00821 new_node->u.kids[clust_b++] = node->u.kids[i]; 00822 } 00823 } 00824 } 00825 node->flags.manage = a_manage; 00826 new_node->flags.manage = b_manage; 00827 assert (clust_a != 0); 00828 assert (clust_b != 0); 00829 if (node->flags.is_leaf) 00830 for (; clust_a < M_SIZE + 1; clust_a++) 00831 node->u.rects[clust_a].bptr = NULL; 00832 else 00833 for (; clust_a < M_SIZE + 1; clust_a++) 00834 node->u.kids[clust_a] = NULL; 00835 adjust_bounds (node); 00836 sort_node (node); 00837 adjust_bounds (new_node); 00838 sort_node (new_node); 00839 return (new_node); 00840 } 00841 00845 static void 00846 split_node (struct rtree_node *node) 00847 { 00848 int i; 00849 struct rtree_node *new_node; 00850 00851 assert (node); 00852 assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE]. 00853 bptr : (void *) node->u.kids[M_SIZE]); 00854 new_node = find_clusters (node); 00855 if (node->parent == NULL) /* split root node */ 00856 { 00857 struct rtree_node *second; 00858 00859 second = (struct rtree_node *)calloc (1, sizeof (*second)); 00860 *second = *node; 00861 if (!second->flags.is_leaf) 00862 for (i = 0; i < M_SIZE; i++) 00863 if (second->u.kids[i]) 00864 second->u.kids[i]->parent = second; 00865 node->flags.is_leaf = 0; 00866 node->flags.manage = 0; 00867 second->parent = new_node->parent = node; 00868 node->u.kids[0] = new_node; 00869 node->u.kids[1] = second; 00870 for (i = 2; i < M_SIZE + 1; i++) 00871 node->u.kids[i] = NULL; 00872 adjust_bounds (node); 00873 sort_node (node); 00874 #ifdef SLOW_ASSERTS 00875 assert (__r_tree_is_good (node)); 00876 #endif 00877 return; 00878 } 00879 for (i = 0; i < M_SIZE; i++) 00880 if (!node->parent->u.kids[i]) 00881 break; 00882 node->parent->u.kids[i] = new_node; 00883 #ifdef SLOW_ASSERTS 00884 assert (__r_node_is_good (node)); 00885 assert (__r_node_is_good (new_node)); 00886 #endif 00887 if (i < M_SIZE) 00888 { 00889 #ifdef SLOW_ASSERTS 00890 assert (__r_node_is_good (node->parent)); 00891 #endif 00892 sort_node (node->parent); 00893 return; 00894 } 00895 split_node (node->parent); 00896 } 00897 00898 static inline int 00899 contained (struct rtree_node *node, const BoxType * query) 00900 { 00901 if (node->box.X1 > query->X1 || node->box.X2 < query->X2 || 00902 node->box.Y1 > query->Y1 || node->box.Y2 < query->Y2) 00903 return 0; 00904 return 1; 00905 } 00906 00907 00913 static inline double 00914 penalty (struct rtree_node *node, const BoxType * query) 00915 { 00916 double score; 00917 00918 score = (MAX (node->box.X2, query->X2) - MIN (node->box.X1, query->X1)); 00919 score *= (MAX (node->box.Y2, query->Y2) - MIN (node->box.Y1, query->Y1)); 00920 score -= 00921 (double)(node->box.X2 - node->box.X1) * 00922 (double)(node->box.Y2 - node->box.Y1); 00923 return score; 00924 } 00925 00926 static void 00927 __r_insert_node (struct rtree_node *node, const BoxType * query, 00928 int manage, bool force) 00929 { 00930 00931 #ifdef SLOW_ASSERTS 00932 assert (__r_node_is_good (node)); 00933 #endif 00934 /* Ok, at this point we must already enclose the query or we're forcing 00935 * this node to expand to enclose it, so if we're a leaf, simply store 00936 * the query here 00937 */ 00938 00939 if (node->flags.is_leaf) 00940 { 00941 register int i; 00942 00943 if (UNLIKELY (manage)) 00944 { 00945 register int flag = 1; 00946 00947 for (i = 0; i < M_SIZE; i++) 00948 { 00949 if (!node->u.rects[i].bptr) 00950 break; 00951 flag <<= 1; 00952 } 00953 node->flags.manage |= flag; 00954 } 00955 else 00956 { 00957 for (i = 0; i < M_SIZE; i++) 00958 if (!node->u.rects[i].bptr) 00959 break; 00960 } 00961 /* the node always has an extra space available */ 00962 node->u.rects[i].bptr = query; 00963 node->u.rects[i].bounds = *query; 00964 /* first entry in node determines initial bounding box */ 00965 if (i == 0) 00966 node->box = *query; 00967 else if (force) 00968 { 00969 MAKEMIN (node->box.X1, query->X1); 00970 MAKEMAX (node->box.X2, query->X2); 00971 MAKEMIN (node->box.Y1, query->Y1); 00972 MAKEMAX (node->box.Y2, query->Y2); 00973 } 00974 if (i < M_SIZE) 00975 { 00976 sort_node (node); 00977 return; 00978 } 00979 /* we must split the node */ 00980 split_node (node); 00981 return; 00982 } 00983 else 00984 { 00985 int i; 00986 struct rtree_node *best_node; 00987 double score, best_score; 00988 00989 if (force) 00990 { 00991 MAKEMIN (node->box.X1, query->X1); 00992 MAKEMAX (node->box.X2, query->X2); 00993 MAKEMIN (node->box.Y1, query->Y1); 00994 MAKEMAX (node->box.Y2, query->Y2); 00995 } 00996 00997 /* this node encloses it, but it's not a leaf, so descend the tree */ 00998 00999 /* First check if any children actually encloses it */ 01000 assert (node->u.kids[0]); 01001 for (i = 0; i < M_SIZE; i++) 01002 { 01003 if (!node->u.kids[i]) 01004 break; 01005 if (contained (node->u.kids[i], query)) 01006 { 01007 __r_insert_node (node->u.kids[i], query, manage, false); 01008 sort_node (node); 01009 return; 01010 } 01011 } 01012 01013 /* see if there is room for a new leaf node */ 01014 if (node->u.kids[0]->flags.is_leaf && i < M_SIZE) 01015 { 01016 struct rtree_node *new_node; 01017 new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); 01018 new_node->parent = node; 01019 new_node->flags.is_leaf = true; 01020 node->u.kids[i] = new_node; 01021 new_node->u.rects[0].bptr = query; 01022 new_node->u.rects[0].bounds = *query; 01023 new_node->box = *query; 01024 if (UNLIKELY (manage)) 01025 new_node->flags.manage = 1; 01026 sort_node (node); 01027 return; 01028 } 01029 01030 /* Ok, so we're still here - look for the best child to push it into */ 01031 best_score = penalty (node->u.kids[0], query); 01032 best_node = node->u.kids[0]; 01033 for (i = 1; i < M_SIZE; i++) 01034 { 01035 if (!node->u.kids[i]) 01036 break; 01037 score = penalty (node->u.kids[i], query); 01038 if (score < best_score) 01039 { 01040 best_score = score; 01041 best_node = node->u.kids[i]; 01042 } 01043 } 01044 __r_insert_node (best_node, query, manage, true); 01045 sort_node (node); 01046 return; 01047 } 01048 } 01049 01050 void 01051 r_insert_entry (rtree_t * rtree, const BoxType * which, int man) 01052 { 01053 assert (which); 01054 assert (which->X1 <= which->X2); 01055 assert (which->Y1 <= which->Y2); 01056 /* recursively search the tree for the best leaf node */ 01057 assert (rtree->root); 01058 __r_insert_node (rtree->root, which, man, 01059 rtree->root->box.X1 > which->X1 01060 || rtree->root->box.X2 < which->X2 01061 || rtree->root->box.Y1 > which->Y1 01062 || rtree->root->box.Y2 < which->Y2); 01063 rtree->size++; 01064 } 01065 01066 bool 01067 __r_delete (struct rtree_node *node, const BoxType * query) 01068 { 01069 int i, flag, mask, a; 01070 01071 /* the tree might be inconsistent during delete */ 01072 if (query->X1 < node->box.X1 || query->Y1 < node->box.Y1 01073 || query->X2 > node->box.X2 || query->Y2 > node->box.Y2) 01074 return false; 01075 if (!node->flags.is_leaf) 01076 { 01077 for (i = 0; i < M_SIZE; i++) 01078 { 01079 /* if this is us being removed, free and copy over */ 01080 if (node->u.kids[i] == (struct rtree_node *) query) 01081 { 01082 free ((void *) query); 01083 for (; i < M_SIZE; i++) 01084 { 01085 node->u.kids[i] = node->u.kids[i + 1]; 01086 if (!node->u.kids[i]) 01087 break; 01088 } 01089 /* nobody home here now ? */ 01090 if (!node->u.kids[0]) 01091 { 01092 if (!node->parent) 01093 { 01094 /* wow, the root is empty! */ 01095 node->flags.is_leaf = 1; 01096 /* changing type of node, be sure it's all zero */ 01097 for (i = 1; i < M_SIZE + 1; i++) 01098 node->u.rects[i].bptr = NULL; 01099 return true; 01100 } 01101 return (__r_delete (node->parent, &node->box)); 01102 } 01103 else 01104 /* propegate boundary adjust upward */ 01105 while (node) 01106 { 01107 adjust_bounds (node); 01108 node = node->parent; 01109 } 01110 return true; 01111 } 01112 if (node->u.kids[i]) 01113 { 01114 if (__r_delete (node->u.kids[i], query)) 01115 return true; 01116 } 01117 else 01118 break; 01119 } 01120 return false; 01121 } 01122 /* leaf node here */ 01123 mask = 0; 01124 a = 1; 01125 for (i = 0; i < M_SIZE; i++) 01126 { 01127 #ifdef DELETE_BY_POINTER 01128 if (!node->u.rects[i].bptr || node->u.rects[i].bptr == query) 01129 #else 01130 if (node->u.rects[i].bounds.X1 == query->X1 && 01131 node->u.rects[i].bounds.X2 == query->X2 && 01132 node->u.rects[i].bounds.Y1 == query->Y1 && 01133 node->u.rects[i].bounds.Y2 == query->Y2) 01134 #endif 01135 break; 01136 mask |= a; 01137 a <<= 1; 01138 } 01139 if (!node->u.rects[i].bptr) 01140 return false; /* not at this leaf */ 01141 if (node->flags.manage & a) 01142 { 01143 free ((void *) node->u.rects[i].bptr); 01144 node->u.rects[i].bptr = NULL; 01145 } 01146 /* squeeze the manage flags together */ 01147 flag = node->flags.manage & mask; 01148 mask = (~mask) << 1; 01149 node->flags.manage = flag | ((node->flags.manage & mask) >> 1); 01150 /* remove the entry */ 01151 for (; i < M_SIZE; i++) 01152 { 01153 node->u.rects[i] = node->u.rects[i + 1]; 01154 if (!node->u.rects[i].bptr) 01155 break; 01156 } 01157 if (!node->u.rects[0].bptr) 01158 { 01159 if (node->parent) 01160 __r_delete (node->parent, &node->box); 01161 return true; 01162 } 01163 else 01164 /* propagate boundary adjustment upward */ 01165 while (node) 01166 { 01167 adjust_bounds (node); 01168 node = node->parent; 01169 } 01170 return true; 01171 } 01172 01173 bool 01174 r_delete_entry (rtree_t * rtree, const BoxType * box) 01175 { 01176 bool r; 01177 01178 assert (box); 01179 assert (rtree); 01180 r = __r_delete (rtree->root, box); 01181 if (r) 01182 rtree->size--; 01183 #ifdef SLOW_ASSERTS 01184 assert (__r_tree_is_good (rtree->root)); 01185 #endif 01186 return r; 01187 }