示例#1
0
int igtl_export igtl_polydata_unpack(int type, void * byte_array, igtl_polydata_info * info, igtl_uint64 size)
{
    /* size = number of ponits (not number of bytes). In case of vertices, this is specfied
       by size_vertices in igtl_polydata_header. */
    igtl_polydata_header * header;
    char * ptr;

    igtl_uint32 * ptr32_src;
    igtl_uint32 * ptr32_src_end;
    igtl_uint32 * ptr32_dst;
    igtl_uint32   s;

    igtl_polydata_attribute_header * att_header;
    igtl_polydata_attribute * att;

    int total_name_length;
    int name_length;
    char name_buf[IGTL_POLY_MAX_ATTR_NAME_LEN+1];

    unsigned int i;
    int n;

    if (byte_array == NULL || info == NULL || size == 0)
    {
        return 0;
    }

    /* POLYDATA header */
    header = (igtl_polydata_header *) byte_array;
    if (igtl_is_little_endian())
    {
        info->header.npoints              = BYTE_SWAP_INT32(header->npoints);
        info->header.nvertices            = BYTE_SWAP_INT32(header->nvertices);
        info->header.size_vertices        = BYTE_SWAP_INT32(header->size_vertices);
        info->header.nlines               = BYTE_SWAP_INT32(header->nlines);
        info->header.size_lines           = BYTE_SWAP_INT32(header->size_lines);
        info->header.npolygons            = BYTE_SWAP_INT32(header->npolygons);
        info->header.size_polygons        = BYTE_SWAP_INT32(header->size_polygons);
        info->header.ntriangle_strips     = BYTE_SWAP_INT32(header->ntriangle_strips);
        info->header.size_triangle_strips = BYTE_SWAP_INT32(header->size_triangle_strips);
        info->header.nattributes          = BYTE_SWAP_INT32(header->nattributes);
    }
    else
    {
        memcpy(&(info->header), header, sizeof(igtl_polydata_header));
    }

    /* Allocate memory to read data */
    /* TODO: compare the size of info before copying the header. */
    /* If the size doesn't change, avoid reallocation of memory. */
    if (igtl_polydata_alloc_info(info) == 0)
    {
        return 0;
    }

    /* POINT section */
    ptr = (char*) byte_array + sizeof(igtl_polydata_header);
    if (!igtl_is_little_endian())
    {
        memcpy(info->points, ptr, sizeof(igtl_float32)*info->header.npoints*3);
    }
    else
    {
        ptr32_src = (igtl_uint32 *) ptr;
        ptr32_src_end = ptr32_src + info->header.npoints*3;
        ptr32_dst = (igtl_uint32 *) info->points;
        while (ptr32_src < ptr32_src_end)
        {
            *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src);
            ptr32_dst ++;
            ptr32_src ++;
        }
    }

    ptr += sizeof(igtl_float32)*info->header.npoints*3;

    /* Check size parameters */
    if (info->header.size_vertices%sizeof(igtl_uint32) != 0 ||
            info->header.size_lines%sizeof(igtl_uint32) != 0 ||
            info->header.size_polygons%sizeof(igtl_uint32) != 0 ||
            info->header.size_triangle_strips%sizeof(igtl_uint32))
    {
        /* More than one of size parameters is multiples of 4 (size of 32-bit value) */
        return 0;
    }

    /* VERTICES section */
    igtl_polydata_convert_byteorder_topology(info->vertices, (igtl_uint32*)ptr, info->header.size_vertices);
    ptr += info->header.size_vertices;

    /* LINES section */
    igtl_polydata_convert_byteorder_topology(info->lines, (igtl_uint32*)ptr, info->header.size_lines);
    ptr += info->header.size_lines;

    /* POLYGONS section */
    igtl_polydata_convert_byteorder_topology(info->polygons, (igtl_uint32*)ptr, info->header.size_polygons);
    ptr += info->header.size_polygons;

    /* TRIANGLE_STRIPS section */
    igtl_polydata_convert_byteorder_topology(info->triangle_strips, (igtl_uint32*)ptr, info->header.size_triangle_strips);
    ptr += info->header.size_triangle_strips;

    /* Attribute header */
    for (i = 0; i < info->header.nattributes; i ++)
    {
        att = &(info->attributes[i]);
        att_header = (igtl_polydata_attribute_header *) ptr;
        att->type        = att_header->type;
        att->ncomponents = att_header->ncomponents;
        if (igtl_is_little_endian())
        {
            att->n = BYTE_SWAP_INT32(att_header->n);
        }
        else
        {
            att->n = att_header->n;
        }
        ptr += sizeof(igtl_polydata_attribute_header);
    }

    /* Attribute names */
    total_name_length = 0;
    name_buf[IGTL_POLY_MAX_ATTR_NAME_LEN] = '\0';
    for (i = 0; i < info->header.nattributes; i ++)
    {
        name_length = strlen(ptr);
        if (name_length <= IGTL_POLY_MAX_ATTR_NAME_LEN)
        {
            info->attributes[i].name = malloc(name_length+1);
            strcpy(info->attributes[i].name, ptr);
        }
        else
        {
            /* invalid name length */
            return 0;
        }
        total_name_length += (name_length+1);
        ptr += (name_length+1);
    }

    if (total_name_length % 2 > 0)
    {
        /* add padding */
        ptr ++;
    }

    /* Attributes */
    for (i = 0; i < info->header.nattributes; i ++)
    {
        if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_SCALAR)
        {
            n = info->attributes[i].ncomponents * info->attributes[i].n;
            s = n * sizeof(igtl_float32);
        }
        else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_NORMAL)
        {
            n = 3 * info->attributes[i].n;
            s = n * sizeof(igtl_float32);
        }
        else if (info->attributes[i].type == IGTL_POLY_ATTR_TYPE_VECTOR)
        {
            n = 3 * info->attributes[i].n;
            s = n * sizeof(igtl_float32);
        }
        else /* TENSOR */
        {
            n = 9 * info->attributes[i].n;
            s = n * sizeof(igtl_float32);
        }
        info->attributes[i].data = (igtl_float32*)malloc((size_t)s);
        ptr32_dst = (igtl_uint32*)info->attributes[i].data;
        ptr32_src = (igtl_uint32*)ptr;
        ptr32_src_end = ptr32_src + n;
        while (ptr32_src < ptr32_src_end)
        {
            *ptr32_dst = BYTE_SWAP_INT32(*ptr32_src);
            ptr32_dst ++;
            ptr32_src ++;
        }
        ptr += s;
    }

    return 1;
}
int main( int argc, char * argv [] )
{
  /*** Message structures and byte array ***/
  igtl_header header;
  void * body;
  
  igtl_polydata_info info;

  int rh; /* Comparison result for header */
  int rb; /* Comparison result for body */

  unsigned int i;
  int s;
  igtl_float32 * ptr_f;
  igtl_uint32 *  ptr_i;
  igtl_uint64 body_size;
  
  
  static igtl_float32 points[8][3]={{0,0,0}, {1,0,0}, {1,1,0}, {0,1,0},
                                    {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}};
  static igtl_uint32 poly[6][4]={{0,1,2,3}, {4,5,6,7}, {0,1,5,4},
                                 {1,2,6,5}, {2,3,7,6}, {3,0,4,7}};
  static igtl_float32 attribute[8]={0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};

  /*** Generate test data ***/
  /* Note that the size of polygon data (or other cell data) is calculated by
   * number of polygons * (number of points + 1)
   * '+ 1' is required because of the number of points in the polygon (uint32)
   * is stored at the begining of polygon data.
   */
  igtl_polydata_init_info(&info);
  info.header.npoints           = 8;
  info.header.nvertices         = 0;
  info.header.size_vertices     = 0;
  info.header.nlines            = 0;
  info.header.size_lines        = 0;
  info.header.npolygons         = 6;
  info.header.size_polygons     = 6 * ((4+1) * sizeof(igtl_float32));
  info.header.ntriangle_strips  = 0;
  info.header.size_triangle_strips = 0;
  info.header.nattributes       = 1;

  if (igtl_polydata_alloc_info(&info) == 0)
    {
    return EXIT_FAILURE;
    }

  /*** Substitute cube point data ***/
  if (info.points)
    {
    ptr_f = info.points;
    for (i = 0; i < info.header.npoints; i ++)
      {
      *(ptr_f++) = points[i][0];
      *(ptr_f++) = points[i][1];
      *(ptr_f++) = points[i][2];
      }
    }
  else
    {
    return EXIT_FAILURE;
    }

  /*** Substitute polygon data ***/
  if (info.polygons)
    {
    ptr_i = info.polygons;
    for (i = 0; i  < info.header.npolygons; i ++)
      {
      *(ptr_i++) = 4;  /* Number of points in the polygon */
      *(ptr_i++) = poly[i][0];
      *(ptr_i++) = poly[i][1];
      *(ptr_i++) = poly[i][2];
      *(ptr_i++) = poly[i][3];
      }
    }

  /*** Substitute attribute data ***/
  if (info.attributes)
    {
    info.attributes[0].type        = IGTL_POLY_ATTR_TYPE_SCALAR;
    info.attributes[0].ncomponents = 1;
    info.attributes[0].n           = 8;
    info.attributes[0].name        = malloc(5);
    strcpy(info.attributes[0].name, "attr");
    info.attributes[0].data        = malloc(sizeof(igtl_float32) * 8);
    ptr_f = info.attributes[0].data;
    for (i = 0; i < 8; i ++)
      {
      *(ptr_f++) = attribute[i];
      }
    }

  /** Allocate memory for pack **/
  body_size = igtl_polydata_get_size(&info, IGTL_TYPE_PREFIX_NONE);
  body = malloc((igtl_uint32)body_size);

  if (body == NULL)
    {
    igtl_polydata_free_info(&info);
    return EXIT_FAILURE;
    }

  igtl_polydata_pack(&info, body, IGTL_TYPE_PREFIX_NONE);

  /*** Set OpenIGTLink header ***/
  header.version = 1;
  strncpy( (char*)&(header.name), "POLYDATA", 12 );
  strncpy( (char*)&(header.device_name), "DeviceName", 20 );
  header.timestamp = 1234567890;
  header.body_size = body_size;
  header.crc = igtl_polydata_get_crc(&info, IGTL_TYPE_PREFIX_NONE, body);
  igtl_header_convert_byte_order( &(header) );

  /* Dumping data -- for testing */
  /*
  FILE *fp;
  fp = fopen("polydata.bin", "w");
  fwrite(&(header), IGTL_HEADER_SIZE, 1, fp);
  fwrite(body, body_size, 1, fp);
  fclose(fp);
  */

  rh = memcmp((const void*)&header, (const void*)test_polydata_message_header, IGTL_HEADER_SIZE);
  rb = memcmp((const void*)body, (const void*)test_polydata_message_body, (size_t) body_size);

  igtl_polydata_free_info(&info);
  free(body);

  if (rh == 0 && rb == 0)
    {
    return EXIT_SUCCESS;
    }
  else
    {
    /* Print first 256 bytes as HEX values in STDERR for debug */
    s = IGTL_HEADER_SIZE + (int)body_size;
    if (s > 256)
      {
      s = 256;
      }

    fprintf(stdout, "\n===== First %d bytes of the test message =====\n", s);
    igtl_message_dump_hex(stdout, (const void*)&header, s);

    return EXIT_FAILURE;
    }

}