I am performing some calculations where I need to evaluate fluxes between Voronoi Polygons that are centred around some nodes. To do this I need to find the common edges between pairs of polygons eg. V1 & V2 as shown in the figure below. Each edge should be evaluated once only.

To do this I take my x- & y-coordinates of the nodes and do a Delaunay triangulation to find the neighbour nodes. I then run a loop to figure out which nodes have common vertices. I then calculate Voronoi polygons and create an array (istr) with the index of the 'edge' number and the value is the central voronoi polygon. The 'neigh' array then has the index as the 'edge' number and all the neighbouring polygon values. After a check to make sure I don't repeat this evaluation for each edge I then calculate the edges (i.e. the vertices shared between each polygon).
I can calculate the edges using the code below, however there is a massive bottleneck in the for...loop for calculating nodneigh as components of a cell array need to be accessed iteratively. What takes up even more time is the calculation of edge using a cell function to access the outputs of the Delaunay triangulation/Voronoi polygons.
My question is how can I speed up these two bottlenecks? Whilst I appreciate the flexibility of the cell array in Matlab, I feel like it is really slowing everything down when I don't need it to. I have tried padding out the cell array with NaNs, converting it to a matrix and performing a row-wise intersect but this hasn't been so successful: arrayfun takes much, much longer and I can't seem to use intersect with GPU computing.
% Create dummy data
nstr = 1000; % number of particles
x = rand(nstr,1); % particle x coordinates
y = rand(nstr,1); % particle y coordinates
% Delaunay triangulation
DT = delaunayTriangulation(x,y);
% Determine node neighbors of the original nodes
nodneigh = cell(nstr,1);
numtotneigh = 0; % initialise total # of neighbors
bla = DT.vertexAttachments; % Get the particle/triangle IDs
% BOTTLENECK 1: Find out which particles/triangles are neighbours
for istr = 1:nstr
nodneigh{istr} = setdiff(unique(DT.ConnectivityList(bla{istr},:)),istr);
numtotneigh = numtotneigh+length(nodneigh{istr});
end
% Construct Thiessen polygons by Voronoi tessalation
[voro_V,voro_R] = DT.voronoiDiagram;
% Bookkeeping - create an index of edges with associated voronoi regions
cellsz = cellfun(@size,nodneigh,'uni',false);
cellsz = cell2mat(cellsz);
cellsz = cellsz(:,1);
temp = [1:nstr];
idx([cumsum([1 cellsz(cellsz>0)'])]) = 1;
istr = temp(cumsum(idx(1:find(idx,1,'last')-1)))'; % Region number
neigh = vertcat(nodneigh{:}); % Region neighbours
neigh_m = mod(neigh,nstr);
% Make sure neighbourship has not already been evaluated
idx = neigh_m == 0;
neigh_m(idx,:) = nstr;
neigh = vertcat(nodneigh{:});
% BOTTLENECK 2:
% Determine which edges are common to both central and neighbour regions
edge = cellfun(@intersect,voro_R(istr),voro_R(neigh),...
'UniformOutput',false);
edge = cell2mat(edge);