function [kernelmtx_optim, points] = exclude_probe_points3D(kernelmtx_optim, w, points, nelx, nely, nelz, highCutOff, lowCutOff)
    %exclude_probe_points updates the kernelmatrix by excluding probe points

    points_elements = points;
    points_elements(points_elements(:, 1) == nelx, 1) = nelx - 0.000001; % correct points that lie exactly on the border in x direction
    points_elements(points_elements(:, 2) == nely, 2) = nely - 0.000001; % correct points that lie exactly on the border in y direction
    points_elements(points_elements(:, 3) == nelz, 3) = nelz - 0.000001; % correct points that lie exactly on the border in z direction

    points_elements = floor(points_elements) + 1; % find elements containing probe points

    points_ele_idx = grid2idx3D(points_elements(:, 1), points_elements(:, 2), points_elements(:, 3), nelx, nely, nelz); % convert probe point coordinates to topopt indices
    w_points = w(points_ele_idx, :); % select the corresponding widths
    w_points_low = w_points(:); %flatten the same way as the probe points are flattened for optimization
    w_points_high = [any(w_points > highCutOff, 2); any(w_points > highCutOff, 2); any(w_points > highCutOff, 2)]; % if any of the three layer is above highCutOff%, then we mark all three probe points as high

    %% only use points where at least one layer is bigger than lowCutOff
    % points = points(any(w_points> 0.1,2), :);

    %% remove probe points from kernelmatrix in layer that are smaller than lowCutOff
    kernelmtx_optim(w_points_low < lowCutOff, :) = 0;

    %% remove probe points in layers with high density
    % kernelmtx_optim(w_points_high, :) = 0;
end
