示例#1
0
// GetGoogleSpec returns a google-specific tile spec, which includes how the tile is positioned relative to
// scaled volume boundaries.  Not that the size parameter is the desired size and not what is required to fit
// within a scaled volume.
func (d *Data) GetGoogleSpec(scaling Scaling, plane dvid.DataShape, offset dvid.Point3d, size dvid.Point2d) (*GoogleTileSpec, error) {
	tile := new(GoogleTileSpec)
	tile.offset = offset

	// Convert combination of plane and size into 3d size.
	sizeWant, err := dvid.GetPoint3dFrom2d(plane, size, 1)
	if err != nil {
		return nil, err
	}
	tile.sizeWant = sizeWant

	// Determine which geometry is appropriate given the scaling and the shape/orientation
	tileSpec, err := GetTileSpec(scaling, plane)
	if err != nil {
		return nil, err
	}
	geomIndex, found := d.TileMap[*tileSpec]
	if !found {
		return nil, fmt.Errorf("Could not find scaled volume in %q for %s with scaling %d", d.DataName(), plane, scaling)
	}
	geom := d.Scales[geomIndex]
	tile.gi = geomIndex
	tile.channelCount = geom.ChannelCount
	tile.channelType = geom.ChannelType

	// Get the # bytes for each pixel
	switch geom.ChannelType {
	case "uint8":
		tile.bytesPerVoxel = 1
	case "float":
		tile.bytesPerVoxel = 4
	case "uint64":
		tile.bytesPerVoxel = 8
	default:
		return nil, fmt.Errorf("Unknown volume channel type in %s: %s", d.DataName(), geom.ChannelType)
	}

	// Check if the tile is completely outside the volume.
	volumeSize := geom.VolumeSize
	if offset[0] >= volumeSize[0] || offset[1] >= volumeSize[1] || offset[2] >= volumeSize[2] {
		tile.outside = true
		return tile, nil
	}

	// Check if the tile is on the edge and adjust size.
	var adjSize dvid.Point3d = sizeWant
	maxpt, err := offset.Expand2d(plane, size)
	for i := 0; i < 3; i++ {
		if maxpt[i] > volumeSize[i] {
			tile.edge = true
			adjSize[i] = volumeSize[i] - offset[i]
		}
	}
	tile.size = adjSize

	return tile, nil
}
示例#2
0
// GetGoogleSubvolGeom returns a google-specific voxel spec, which includes how the data is positioned relative to
// scaled volume boundaries.  Not that the size parameter is the desired size and not what is required to fit
// within a scaled volume.
func (d *Data) GetGoogleSubvolGeom(scaling Scaling, shape dvid.DataShape, offset dvid.Point3d, size dvid.Point) (*GoogleSubvolGeom, error) {
	gsg := new(GoogleSubvolGeom)
	if err := gsg.shape.FromShape(shape); err != nil {
		return nil, err
	}
	gsg.offset = offset

	// If 2d plane, convert combination of plane and size into 3d size.
	if size.NumDims() == 2 {
		size2d := size.(dvid.Point2d)
		sizeWant, err := dvid.GetPoint3dFrom2d(shape, size2d, 1)
		if err != nil {
			return nil, err
		}
		gsg.sizeWant = sizeWant
	} else {
		var ok bool
		gsg.sizeWant, ok = size.(dvid.Point3d)
		if !ok {
			return nil, fmt.Errorf("Can't convert %v to dvid.Point3d", size)
		}
	}

	// Determine which geometry is appropriate given the scaling and the shape/orientation
	tileSpec, err := GetGSpec(scaling, shape)
	if err != nil {
		return nil, err
	}
	geomIndex, found := d.GeomMap[*tileSpec]
	if !found {
		return nil, fmt.Errorf("Could not find scaled volume in %q for %s with scaling %d", d.DataName(), shape, scaling)
	}
	geom := d.Scales[geomIndex]
	gsg.gi = geomIndex
	gsg.channelCount = geom.ChannelCount
	gsg.channelType = geom.ChannelType

	// Get the # bytes for each pixel
	switch geom.ChannelType {
	case "UINT8":
		gsg.bytesPerVoxel = 1
	case "FLOAT":
		gsg.bytesPerVoxel = 4
	case "UINT64":
		gsg.bytesPerVoxel = 8
	default:
		return nil, fmt.Errorf("Unknown volume channel type in %s: %s", d.DataName(), geom.ChannelType)
	}

	// Check if the requested area is completely outside the volume.
	volumeSize := geom.VolumeSize
	if offset[0] >= volumeSize[0] || offset[1] >= volumeSize[1] || offset[2] >= volumeSize[2] {
		gsg.outside = true
		return gsg, nil
	}

	// Check if the requested shape is on the edge and adjust size.
	adjSize := gsg.sizeWant
	maxpt := offset.Add(adjSize)
	for i := uint8(0); i < 3; i++ {
		if maxpt.Value(i) > volumeSize[i] {
			gsg.edge = true
			adjSize[i] = volumeSize[i] - offset[i]
		}
	}
	gsg.size = adjSize

	return gsg, nil
}