function [ROIS] = dicomrt_rasterizeVoi(VOI, ct, ct_xmesh, ct_ymesh, ct_zmesh)
% See also: dicomrt_build3dVOI()

% Check input
% % % Commented for ease of downsample
% % % [ct_temp,type_ct,label,PatientPosition]=dicomrt_checkinput(ct);
% % % ct=dicomrt_varfilter(ct_temp);
[VOI_temp]=dicomrt_checkinput(VOI);
VOI=dicomrt_varfilter(VOI_temp);

% TODO check VOI has to be 2D and along z
% TODO(?) check x,y,zmesh has to be monotonic and unique

% assistant variables
xdim = length(ct_xmesh);
ydim = length(ct_ymesh);
zdim = length(ct_zmesh);

voi2use = 1:size(VOI,1);

[XMESH YMESH] = meshgrid(ct_xmesh, ct_ymesh);

% Progress bar data
h = waitbar(0, 'Rasterizing', 'Name', 'dicomrt_rasterizeVoi');
for kk = 1:length(voi2use)
    waitbar(kk./length(voi2use), h, ['Rasterizing: ', VOI{kk,1}]);
        
    % For each voi create a matrix with just 1 and 0
    rasterVOI = zeros(xdim, ydim, zdim, 'int8');
    num_curves = numel(VOI{kk,2});
    for k = 1:num_curves
        % the N x 3 curve matrix
        curve = VOI{kk,2}{k};
        % skip empty curves
        numPoints = size(curve,1);
        if numPoints < 3
            continue;
        end
        % z coordinate of current VOI
        voi_z = VOI{kk,2}{k}(1,3);
        % find the appropriate slice
        % TODO can simplify this once I'm more confident
        dist_z = abs(ct_zmesh-voi_z);
        slice = find(dist_z == min(dist_z));
%         slice = find(abs(ct_zmesh-voi_z) < dz);
        if isempty(slice)
            warning('Can not find matching slice');
            error('Closest slice found at %f cm', min(abs(ct_zmesh-voi_z)));
        elseif numel(slice) > 1
            warning('Multiple matching slices found');
        elseif dist_z(slice) >= abs(ct_zmesh(1)-ct_zmesh(2))
            error('Closest slice found at %f cm', min(abs(ct_zmesh-voi_z)));
        end
        % binary mask of current curve
        if exist('InPolygon', 'file') == 3
            % favor the mex function for performance
            BW = InPolygon(XMESH,YMESH,curve(:,1),curve(:,2));
        else
            BW = inpolygon(XMESH,YMESH,curve(:,1),curve(:,2));
        end
        
        % merge with existing curve
        rasterVOI(:,:,slice) = int8(xor(BW, rasterVOI(:,:,slice)));
    end
    
    % Create contour polygon on X and Y plane
    Xcurves = cell(0);
    for slice = 1:size(rasterVOI, 1)
        B = bwboundaries(squeeze(rasterVOI(slice,:,:)));
        if ~isempty(B)
            for ii = 1:numel(B)
                % Here x, y, z vertices means coordinate along 1st, 2nd and 3rd dimension,
                % respectively as in line Xcurves{end+1} = cat(2, x, y, z);
                x_vertices = ct_xmesh(slice) * ones(size(B{ii}, 1), 1);
                y_vertices = interp1(1:numel(ct_ymesh), ct_ymesh, B{ii}(:,1));
                z_vertices = interp1(1:numel(ct_zmesh), ct_zmesh, B{ii}(:,2));
                Xcurves{end+1} = cat(2, x_vertices, y_vertices, z_vertices);
            end
        end
    end
    
    Ycurves = cell(0);
    for slice = 1:size(rasterVOI, 2)
        B = bwboundaries(squeeze(rasterVOI(:,slice,:)));
        if ~isempty(B)
            for ii = 1:numel(B)
                y_vertices = ct_ymesh(slice) * ones(size(B{ii}, 1), 1);
                x_vertices = interp1(1:numel(ct_xmesh), ct_xmesh, B{ii}(:,1));
                z_vertices = interp1(1:numel(ct_zmesh), ct_zmesh, B{ii}(:,2));
                Ycurves{end+1} = cat(2, x_vertices, y_vertices, z_vertices);
            end
        end
    end
    
    % Save the ROIs struct
    % ROIS{kk}.BW = rasterVOI;
    ROIS{kk}.name = VOI{kk,1};
    ROIS{kk}.Xcurves = Xcurves;
    ROIS{kk}.Ycurves = Ycurves;
    % legacy nomenclature: num_curves and curves both refer to Z dimension
    ROIS{kk}.num_curves = num_curves;
    for k = 1:num_curves
        ROIS{kk}.curves{k} = VOI{kk,2}{k};
    end
    ROIS{kk}.ind = int32(find(rasterVOI));
    ROIS{kk}.dim = [xdim ydim zdim];
    ROIS{kk}.pixdim = [abs(ct_xmesh(2)-ct_xmesh(1)) abs(ct_ymesh(2)-ct_ymesh(1)) abs(ct_zmesh(2)-ct_zmesh(1))];
    ROIS{kk}.start = [ct_xmesh(1) ct_ymesh(1) ct_zmesh(1)];
    ROIS{kk}.start_ind = '(1,1,1)';
end
delete(h);
