Generic Coding

Isn’t it amazing to have one and only one function that handles smartly and automatically different scenarios such as diversity in inputs and outputs? It is, indeed. Such philosophy requires some more and deeper planning for the code so to be generic, comprehensive and easy to use. The resulting functions are outstanding. Moreover, such philosophy provides a unique workbench well prepared for the future developments. In the following example, the Backbone function accepts lines (either 2D or 3D) and returns the backbone structure, with no hassle. I am currently working on applying this philosophy to {ADFNE }package.

function [bbn,b] = Backbone(in,tol)
% Backbone
% returns backbone structure of 2D/3D fracture network
%
% Usage :
% [bbn,b] = Backbone(in,tol)
%
% input : in (n,4):lines (2D)
% (n,6):lines (3D)
% tol (1):tolerance
% output: bbn (m,4):lines (2D)
% (m,6):lines (3D)
% b (n), boolean
%
% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

if nargin < 2; tol = 1e-9; end
b = false(size(in,1),1); % mask
while true % iterative check
c = IsolatedLines(in(~b,:),tol);
if ~any(c); break; end % all done?
b(~b) = c;
end
bbn = in(~b,:); % backbone
b = ~b; % mask update
function graph = BackboneToGraph(bbn)
% BackboneToGraph
% returns graph structure generated for 2D/3D backbone
%
% Usage :
% graph = BackboneToGraph(bbn)
%
% input : bbn (m,n):backbone
% output: graph struct:(nodes,edges,node's connected edges,...
% edge's nodes,node's connected nodes,...
% node coordinates)
%
% Alghalandis Discrete Fracture Network Engineering (ADFNE)
% Author: Younes Fadakar Alghalandis
% Copyright (c) 2016 Alghalandis Computing @ http://alghalandis.net
% All rights reserved.

[m,n] = size(bbn);
n = floor(n/2); % 2D/3D switch
kys = unique(Reshape(bbn,[],n),'rows','stable'); % keys:points
k = size(kys,1);
nodes = cell(k,1); % nodes:{edge indices}
for i=1:size(bbn,1)
[~,idx] = ismember(bbn(i,1:n),kys,'rows');
nodes{idx} = [nodes{idx},i];
[~,idx] = ismember(bbn(i,n+1:end),kys,'rows');
nodes{idx} = [nodes{idx},i];
end
edges = cell(m,1); % edges:{node indices}
for i=1:k
nn = nodes{i};
for j=1:numel(nn)
edges{nn(j)} = [edges{nn(j)},i];
end
end
nnn = cell(k,1); % node's neighbor nodes
for i=1:m
nd = edges{i};
nnn{nd(1)} = [nnn{nd(1)},nd(2)];
nnn{nd(2)} = [nnn{nd(2)},nd(1)];
end
graph = struct(); % graph structure
graph.Nodes = nodes;
graph.Edges = edges;
graph.NodeNeighbors = nnn;
graph.NodeLocation = kys;
graph.Size = [k,m];

Note also that, I am removing dependency to third-party packages so everything will be ADFNE itself and Matlab.