/* ============================================================================= * PdoExpansion * ============================================================================= */ static bool_t PdoExpansion (router_t* routerPtr, grid_t* myGridPtr, queue_t* queuePtr, coordinate_t* srcPtr, coordinate_t* dstPtr) { long xCost = routerPtr->xCost; long yCost = routerPtr->yCost; long zCost = routerPtr->zCost; /* * Potential Optimization: Make 'src' the one closest to edge. * This will likely decrease the area of the emitted wave. */ PQUEUE_CLEAR(queuePtr); long* srcGridPointPtr = grid_getPointRef(myGridPtr, srcPtr->x, srcPtr->y, srcPtr->z); PQUEUE_PUSH(queuePtr, (void*)srcGridPointPtr); grid_setPoint(myGridPtr, srcPtr->x, srcPtr->y, srcPtr->z, 0); grid_setPoint(myGridPtr, dstPtr->x, dstPtr->y, dstPtr->z, GRID_POINT_EMPTY); long* dstGridPointPtr = grid_getPointRef(myGridPtr, dstPtr->x, dstPtr->y, dstPtr->z); bool_t isPathFound = FALSE; while (!PQUEUE_ISEMPTY(queuePtr)) { long* gridPointPtr = (long*)PQUEUE_POP(queuePtr); if (gridPointPtr == dstGridPointPtr) { isPathFound = TRUE; break; } long x; long y; long z; grid_getPointIndices(myGridPtr, gridPointPtr, &x, &y, &z); long value = (*gridPointPtr); /* * Check 6 neighbors * * Potential Optimization: Only need to check 5 of these */ PexpandToNeighbor(myGridPtr, x+1, y, z, (value + xCost), queuePtr); PexpandToNeighbor(myGridPtr, x-1, y, z, (value + xCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y+1, z, (value + yCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y-1, z, (value + yCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y, z+1, (value + zCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y, z-1, (value + zCost), queuePtr); } /* iterate over work queue */ #if DEBUG printf("Expansion (%li, %li, %li) -> (%li, %li, %li):\n", srcPtr->x, srcPtr->y, srcPtr->z, dstPtr->x, dstPtr->y, dstPtr->z); grid_print(myGridPtr); #endif /* DEBUG */ return isPathFound; }
/* ============================================================================= * TMnet_findDescendants * -- Contents of bitmapPtr set to 1 if descendants, else 0 * -- Returns false if id is not root node (i.e., has cycle back id) * ============================================================================= */ bool_t TMnet_findDescendants (TM_ARGDECL net_t* netPtr, long id, bitmap_t* descendantBitmapPtr, queue_t* workQueuePtr) { bool_t status; vector_t* nodeVectorPtr = netPtr->nodeVectorPtr; assert(descendantBitmapPtr->numBit == vector_getSize(nodeVectorPtr)); PBITMAP_CLEARALL(descendantBitmapPtr); PQUEUE_CLEAR(workQueuePtr); { net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, id); list_t* childIdListPtr = nodePtr->childIdListPtr; list_iter_t it; TMLIST_ITER_RESET(&it, childIdListPtr); while (TMLIST_ITER_HASNEXT(&it, childIdListPtr)) { long childId = (long)TMLIST_ITER_NEXT(&it, childIdListPtr); status = PBITMAP_SET(descendantBitmapPtr, childId); assert(status); status = PQUEUE_PUSH(workQueuePtr, (void*)childId); assert(status); } } while (!PQUEUE_ISEMPTY(workQueuePtr)) { long childId = (long)PQUEUE_POP(workQueuePtr); if (childId == id) { queue_clear(workQueuePtr); return FALSE; } net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, childId); list_t* grandChildIdListPtr = nodePtr->childIdListPtr; list_iter_t it; TMLIST_ITER_RESET(&it, grandChildIdListPtr); while (TMLIST_ITER_HASNEXT(&it, grandChildIdListPtr)) { long grandChildId = (long)TMLIST_ITER_NEXT(&it, grandChildIdListPtr); if (!PBITMAP_ISSET(descendantBitmapPtr, grandChildId)) { status = PBITMAP_SET(descendantBitmapPtr, grandChildId); assert(status); status = PQUEUE_PUSH(workQueuePtr, (void*)grandChildId); assert(status); } } } return TRUE; }
/* ============================================================================= * TMnet_findAncestors * -- Contents of bitmapPtr set to 1 if ancestor, else 0 * -- Returns false if id is not root node (i.e., has cycle back id) * ============================================================================= */ bool_t TMnet_findAncestors (TM_ARGDECL net_t* netPtr, long id, bitmap_t* ancestorBitmapPtr, queue_t* workQueuePtr) { bool_t status; vector_t* nodeVectorPtr = netPtr->nodeVectorPtr; assert(ancestorBitmapPtr->numBit == vector_getSize(nodeVectorPtr)); PBITMAP_CLEARALL(ancestorBitmapPtr); PQUEUE_CLEAR(workQueuePtr); { net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, id); list_t* parentIdListPtr = nodePtr->parentIdListPtr; list_iter_t it; TMLIST_ITER_RESET(&it, parentIdListPtr); while (TMLIST_ITER_HASNEXT(&it, parentIdListPtr)) { long parentId = (long)TMLIST_ITER_NEXT(&it, parentIdListPtr); status = PBITMAP_SET(ancestorBitmapPtr, parentId); assert(status); status = PQUEUE_PUSH(workQueuePtr, (void*)parentId); assert(status); } } while (!PQUEUE_ISEMPTY(workQueuePtr)) { long parentId = (long)PQUEUE_POP(workQueuePtr); if (parentId == id) { PQUEUE_CLEAR(workQueuePtr); return FALSE; } net_node_t* nodePtr = (net_node_t*)vector_at(nodeVectorPtr, parentId); list_t* grandParentIdListPtr = nodePtr->parentIdListPtr; list_iter_t it; TMLIST_ITER_RESET(&it, grandParentIdListPtr); while (TMLIST_ITER_HASNEXT(&it, grandParentIdListPtr)) { long grandParentId = (long)TMLIST_ITER_NEXT(&it, grandParentIdListPtr); if (!PBITMAP_ISSET(ancestorBitmapPtr, grandParentId)) { status = PBITMAP_SET(ancestorBitmapPtr, grandParentId); assert(status); status = PQUEUE_PUSH(workQueuePtr, (void*)grandParentId); assert(status); } } } return TRUE; }
/* ============================================================================= * TMgrowRegion * -- Return NULL if success, else pointer to encroached boundary * ============================================================================= */ element_t* TMgrowRegion (TM_ARGDECL element_t* centerElementPtr, region_t* regionPtr, mesh_t* meshPtr, MAP_T* edgeMapPtr) { bool_t isBoundary = FALSE; if (element_getNumEdge(centerElementPtr) == 1) { isBoundary = TRUE; } list_t* beforeListPtr = regionPtr->beforeListPtr; list_t* borderListPtr = regionPtr->borderListPtr; queue_t* expandQueuePtr = regionPtr->expandQueuePtr; PLIST_CLEAR(beforeListPtr); PLIST_CLEAR(borderListPtr); PQUEUE_CLEAR(expandQueuePtr); coordinate_t centerCoordinate = TMelement_getNewPoint(TM_ARG centerElementPtr); coordinate_t* centerCoordinatePtr = ¢erCoordinate; PQUEUE_PUSH(expandQueuePtr, (void*)centerElementPtr); while (!PQUEUE_ISEMPTY(expandQueuePtr)) { element_t* currentElementPtr = (element_t*)PQUEUE_POP(expandQueuePtr); PLIST_INSERT(beforeListPtr, (void*)currentElementPtr); /* no duplicates */ list_t* neighborListPtr = TMelement_getNeighborListPtr(TM_ARG currentElementPtr); list_iter_t it; TMLIST_ITER_RESET(&it, neighborListPtr); while (TMLIST_ITER_HASNEXT(&it, neighborListPtr)) { element_t* neighborElementPtr = (element_t*)TMLIST_ITER_NEXT(&it, neighborListPtr); TMELEMENT_ISGARBAGE(neighborElementPtr); /* so we can detect conflicts */ if (!list_find(beforeListPtr, (void*)neighborElementPtr)) { if (element_isInCircumCircle(neighborElementPtr, centerCoordinatePtr)) { /* This is part of the region */ if (!isBoundary && (element_getNumEdge(neighborElementPtr) == 1)) { /* Encroached on mesh boundary so split it and restart */ return neighborElementPtr; } else { /* Continue breadth-first search */ bool_t isSuccess; isSuccess = PQUEUE_PUSH(expandQueuePtr, (void*)neighborElementPtr); assert(isSuccess); } } else { /* This element borders region; save info for retriangulation */ edge_t* borderEdgePtr = TMelement_getCommonEdge(TM_ARG neighborElementPtr, currentElementPtr); if (!borderEdgePtr) { TM_RESTART(); } PLIST_INSERT(borderListPtr, (void*)borderEdgePtr); /* no duplicates */ if (!MAP_CONTAINS(edgeMapPtr, borderEdgePtr)) { PMAP_INSERT(edgeMapPtr, borderEdgePtr, neighborElementPtr); } } } /* not visited before */ } /* for each neighbor */ } /* breadth-first search */ return NULL; }