Пример #1
0
Int_Arraylist* Stack_Sp_Grow(const Stack *stack, const size_t *seeds, 
			     int nseed, const size_t *targets, int ntarget, 
			     Sp_Grow_Workspace *sgw)
{
  size_t nvoxel = Stack_Voxel_Number(stack);
  sgw->width = stack->width;
  sgw->height = stack->height;
  sgw->depth = stack->depth;

  /* allocate workspace */
  if (sgw->size < nvoxel) {
    sgw->dist = (double*) Guarded_Realloc(sgw->dist, sizeof(double) * nvoxel,
					  "Stack_Sp_Grow");
    sgw->path = (int*) Guarded_Realloc(sgw->path, sizeof(int) * nvoxel,
				       "Stack_Sp_Grow");
    sgw->checked = (int*) Guarded_Realloc(sgw->checked, sizeof(int) * nvoxel,
					  "Stack_Sp_Grow");
    sgw->flag = (uint8_t*) Guarded_Realloc(sgw->flag, sizeof(uint8_t) * nvoxel,
					  "Stack_Sp_Grow");
    if (sgw->lengthBufferEnabled) {
      sgw->length = (double*) Guarded_Realloc(
          sgw->length, sizeof(double) * nvoxel, "Stack_Sp_Grow");
    }
  } else {
    if (sgw->dist == NULL) {
      sgw->dist = (double*) Guarded_Malloc(sizeof(double) * nvoxel,
					   "Stack_Sp_Grow");
    }
    if (sgw->path == NULL) {
      sgw->path = (int*) Guarded_Malloc(sizeof(int) * nvoxel,
					"Stack_Sp_Grow");
    }
    if (sgw->checked == NULL) {
      sgw->checked = (int*) Guarded_Malloc(sizeof(int) * nvoxel,
					   "Stack_Sp_Grow");
    }
    if (sgw->flag == NULL) {
      sgw->flag = (uint8_t*) Guarded_Malloc(sizeof(uint8_t) * nvoxel,
					   "Stack_Sp_Grow");    
    }

    if (sgw->lengthBufferEnabled) {
      if (sgw->length == NULL) {
        sgw->length = (double*) Guarded_Malloc(
            sizeof(double) * nvoxel, "Stack_Sp_Grow");
      }
    }
  }

  sgw->size = nvoxel;
  
  /* initialize */
  size_t s;
  for (s = 0; s < nvoxel; s++) {
    sgw->dist[s] = Infinity;
    if (sgw->length != NULL) {
      sgw->length[s] = 0.0;
    }
    sgw->path[s] = -1;
    sgw->checked[s] = 0;
    sgw->flag[s] = 0;
  }

  if (sgw->mask != NULL) {
    memcpy(sgw->flag, sgw->mask, nvoxel);
  }

  /* Recruit seeds (source) */
  int i;
  for (i = 0; i < nseed; i++) {
    if (sgw->sp_option == 1) {
      sgw->dist[seeds[i]] = -Stack_Array_Value(stack, seeds[i]);
    } else {
      sgw->dist[seeds[i]] = 0.0;
    }
    sgw->checked[seeds[i]] = 1;
    sgw->flag[seeds[i]] = SP_GROW_SOURCE;
  }
  
  if (sgw->mask != NULL) {
    for (s = 0; s < nvoxel; s++) {
      if (sgw->flag[s] == SP_GROW_SOURCE) {
        if (sgw->sp_option == 1) {
          sgw->dist[s] = -Stack_Array_Value(stack, s);
        } else {
          sgw->dist[s] = 0.0;
        }
        sgw->checked[s] = 1;	
      }
    }
  }

  Int_Arraylist *result = New_Int_Arraylist();

  for (i = 0; i < ntarget; i++) {
    if (sgw->flag[targets[i]] == 2) { /* overlap of source and target */
      Int_Arraylist_Add(result, targets[i]);
      sgw->value = 0.0;
      return result;
    }
    sgw->flag[targets[i]] = SP_GROW_TARGET;
  }

  int width = Stack_Width(stack);
  int height = Stack_Height(stack);
  int depth = Stack_Depth(stack);

  double dist[26];
  Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist);

  int is_in_bound[26];
  int neighbors[26];
  Stack_Neighbor_Offset(sgw->conn, Stack_Width(stack), Stack_Height(stack), 
			neighbors);			

  BOOL stop = FALSE;

  /* Check neighbors of seeds */
  int j;
  //  for (i = 0; i < nseed; i++) {
  // size_t r = seeds[i];

  /* alloc <heap> */
  Int_Arraylist *heap = New_Int_Arraylist();

  size_t r;
  for (r = 0; r < nvoxel; r++) {
    if (sgw->flag[r] == SP_GROW_SOURCE) { /* seeds */
      int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, 
          r, is_in_bound);

      if (nbound == sgw->conn) { /* all neighbors are in bound */
        for (j = 0; j < sgw->conn; j++) {
          size_t nbr_index = r + neighbors[j];
          if (sgw->checked[nbr_index] != 1) {
            update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
          }
        }
      } else if (nbound > 0) {
        for (j = 0; j < sgw->conn; j++) {
          if (is_in_bound[j]) {
            size_t nbr_index = r + neighbors[j];
            if (sgw->checked[nbr_index] != 1) {
              update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
            }
          }
        }
      }
    }
  }

  //Verify_Int_Heap_I(heap, sgw->dist);

  ssize_t last_r = -1;

  while (stop == FALSE) {
    ssize_t r = extract_min(sgw->dist, sgw->checked, sgw->size, heap);

    if (r >= 0) {
      last_r = r;
      if (sgw->flag[r] == 0) { /* normal voxel */
        int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
            depth, r, is_in_bound);

        if (nbound == sgw->conn) { /* all neighbors are in bound */
          for (j = 0; j < sgw->conn; j++) {
            size_t nbr_index = r + neighbors[j];
            if (sgw->checked[nbr_index] != 1) {
              update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
            }
          }
        } else if (nbound > 0) {
          for (j = 0; j < sgw->conn; j++) {
            if (is_in_bound[j]) {
              size_t nbr_index = r + neighbors[j];
              if (sgw->checked[nbr_index] != 1) {
                update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw);
              }
            }
          }
        }
        //Print_Int_Heap(heap, "%d");
        //Verify_Int_Heap_I(heap, sgw->dist);
      } else if (sgw->flag[r] == SP_GROW_TARGET) { /* target reached */
        //Int_Arraylist_Add(result, r);
        stop = TRUE;
      } else if (sgw->flag[r] == SP_GROW_CONDUCTOR) { 
        /* 0-distance region (super conductor) */
        int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
            depth, r, is_in_bound);
        size_t tail_index = r;
        size_t old_tail_index = tail_index;
        size_t cur_index = r;
#ifdef _DEBUG_2
        printf("r: %lu\n", r);
#endif

#define UPDATE_SUPER_CONDUCTOR				\
        size_t nbr_index = cur_index + neighbors[j];	\
        if (sgw->flag[nbr_index] == 4) {				\
          if (sgw->checked[nbr_index] > 1) {				\
            Int_Heap_Remove_I_At(heap, nbr_index, sgw->dist,		\
                sgw->checked);				\
          }								\
          tail_index = update_neighbor(cur_index, tail_index, nbr_index,sgw); \
        } else {							\
          update_waiting(stack, cur_index, nbr_index, dist[j], heap, result,sgw); \
        }

        if (nbound == sgw->conn) { /* all neighbors are in bound */
          for (j = 0; j < sgw->conn; j++) {
            UPDATE_SUPER_CONDUCTOR
          }
        } else if (nbound > 0) {
          for (j = 0; j < sgw->conn; j++) {
            if (is_in_bound[j]) {
              UPDATE_SUPER_CONDUCTOR
            }
          }
        }

        int count = 0;
        while (tail_index != old_tail_index) {
          old_tail_index = tail_index;

          size_t cur_index = tail_index;
          while (sgw->checked[cur_index] != 1) {
            int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, 
                depth, cur_index, 
                is_in_bound);
            if (nbound == sgw->conn) { /* all neighbors are in bound */
              for (j = 0; j < sgw->conn; j++) {
                UPDATE_SUPER_CONDUCTOR
              }
            } else if (nbound > 0) {
              for (j = 0; j < sgw->conn; j++) {
                if (is_in_bound[j]) {
                  UPDATE_SUPER_CONDUCTOR
                }
              }
            }

            sgw->checked[cur_index] = 1;
            size_t tmp_index = cur_index;
            cur_index = sgw->path[cur_index];
            sgw->path[tmp_index] = r;
            count++;
          }
        }
Пример #2
0
Graph* Stack_Graph_W(const Stack *stack, Stack_Graph_Workspace *sgw)
{
  int x, y, z;
  int offset = 0;
  int is_in_bound[26];
  int nbound;
  int i;
  int stack_range[6];

  int *range = sgw->range;

  if (range == NULL) {
    stack_range[0] = 0;
    stack_range[1] = stack->width - 1;
    stack_range[2] = 0;
    stack_range[3] = stack->height - 1;
    stack_range[4] = 0;
    stack_range[5] = stack->depth - 1;
  } else {
    stack_range[0] = imax2(0, range[0]);
    stack_range[1] = imin2(stack->width - 1, range[1]);
    stack_range[2] = imax2(0, range[2]);
    stack_range[3] = imin2(stack->height - 1, range[3]);
    stack_range[4] = imax2(0, range[4]);
    stack_range[5] = imin2(stack->depth - 1, range[5]);
  }
  
  int cdepth = stack_range[5] - stack_range[4];
  int cheight = stack_range[3] - stack_range[2];
  int cwidth = stack_range[1] - stack_range[0];
  
  int nvertex = (cwidth + 1) * (cheight + 1) * (cdepth + 1);
  sgw->virtualVertex = nvertex;

  BOOL weighted = TRUE;
  if (sgw->sp_option == 1) {
    weighted = FALSE;
    sgw->intensity = darray_malloc(nvertex + 1);
    sgw->intensity[nvertex] = Infinity;
  }
  Graph *graph = Make_Graph(nvertex, nvertex, weighted);

  int neighbor[26];
  int scan_mask[26];
  Stack_Neighbor_Offset(sgw->conn, cwidth + 1, cheight + 1, neighbor);

  int org_neighbor[26];
  Stack_Neighbor_Offset(sgw->conn, Stack_Width(stack), Stack_Height(stack), 
      org_neighbor);

  double dist[26];
  Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist);
  //const double *dist = Stack_Neighbor_Dist(sgw->conn);
  const int *x_offset = Stack_Neighbor_X_Offset(sgw->conn);
  const int *y_offset = Stack_Neighbor_Y_Offset(sgw->conn);
  const int *z_offset = Stack_Neighbor_Z_Offset(sgw->conn);

  /* go forward */
  for (i = 0; i < sgw->conn; i++) {
    scan_mask[i] = (neighbor[i] > 0);
  }

#define STACK_GRAPH_ADD_EDGE(cond) \
  for (i = 0; i < sgw->conn; i++) { \
    if (cond) { \
      int nx = x + stack_range[0]; \
      int ny = y + stack_range[2]; \
      int nz = z + stack_range[4]; \
      if (Graph_Is_Weighted(graph)) { \
	double weight = dist[i]; \
	if (sgw->wf != NULL) { \
	  sgw->argv[0] = dist[i]; \
	  \
	  sgw->argv[1] = Get_Stack_Pixel((Stack *)stack, nx, ny, nz, 0); \
	  sgw->argv[2] = \
	  Get_Stack_Pixel((Stack *)stack, nx + x_offset[i], \
	      ny + y_offset[i], nz + z_offset[i], 0); \
	  weight = sgw->wf(sgw->argv); \
	} \
	Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], \
	    weight); \
      } else { \
	Graph_Add_Edge(graph, offset, offset + neighbor[i]); \
	sgw->intensity[offset] = Get_Stack_Pixel((Stack*) stack, \
	      nx, ny, nz, 0); \
      } \
    } \
  }

  int groupVertexMap[256];
  for (i = 0; i < 256; ++i) {
    groupVertexMap[i] = 0;
  }

  int swidth = cwidth + 1;
  int sarea =  (cwidth + 1) * (cheight + 1);
  int area = stack->width * stack->height;
  for (z = 0; z <= cdepth; z++) {
    for (y = 0; y <= cheight; y++) {
      for (x = 0; x <= cwidth; x++) {
	nbound = Stack_Neighbor_Bound_Test_S(sgw->conn, cwidth, cheight, 
					     cdepth, 
					     x, y, z, is_in_bound);
	size_t offset2 = Stack_Subindex((size_t) offset, stack_range[0],
	    stack_range[2], stack_range[4],
	    swidth, sarea, stack->width, area);

#ifdef _DEBUG_2
        if (offset == 36629) {
          printf("debug here\n");
        }
#endif

	if (nbound == sgw->conn) {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && 
              (sgw->signal_mask == NULL ? 1 : 
               ((sgw->signal_mask->array[offset2] > 0) &&
                (sgw->signal_mask->array[offset2+org_neighbor[i]] > 0))))
	} else {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && is_in_bound[i] && 
	      (sgw->signal_mask == NULL ? 1 : 
	       ((sgw->signal_mask->array[offset2] > 0) &&
		(sgw->signal_mask->array[offset2+org_neighbor[i]]) >
		0)))
	}
	if (sgw->group_mask != NULL) {
          int groupId = sgw->group_mask->array[offset2];
	  if (groupId > 0) {
#ifdef _DEBUG_2
	    sgw->group_mask->array[offset2] = 2;
#endif
            int groupVertex = groupVertexMap[groupId];
            if (groupVertex <= 0) {
              groupVertex = nvertex++;
              groupVertexMap[groupId] = groupVertex;
            }

            Graph_Add_Weighted_Edge(graph, groupVertex, offset, 0.0);
	  }
	}

	offset++;
      }
    }
  }

  return graph;
}