Code covered by the BSD License  

Highlights from
Biohydrodynamics Toolbox

image thumbnail
from Biohydrodynamics Toolbox by Alexandre Munnier
Tool to simulate easily the motion of moving solids or swimming robots in a potential fluid flow.

[gene_data,...
function [gene_data,...
          discret_data,...
          bound_data,...
          ode_data,...
          phys_data,...
          fish] = bht_translation(filename)
% BHT_TRANSLATION
% 
% Turn the data of the DAT-File into MATLAB structure array variables.
% 
% Syntax
% 
%     [gene_data,discret_data,bound_data,ode_data,phys_data,fish] =
%     BHT_TRANSLATION(filename)
% 
% Description
% 
%     The function is ran by BHT_DATA_COMPILE. It reads the DAT-File
%     filename, extracts the data and sets up fields of the output
%     structure array variables gene_data,discret_data, bound_data,
%     ode_data, phys_data and fish after prealocating them. Not all of the
%     fields of these variables are set up by BHT_TRANSLATION. Actually,
%     this function does not perform any computation. Computations on data
%     (center of mass, boundaries' mesh...) are done by the functions
%     BHT_BOUNDARIES_INIT and BHT_SOLIDS_DATA_INIT also ran by
%     BHT_DATA_COMPILE.
% 
% Output variables
% 
%     The following fields are set up by BHT_TRANSLATION (we refer to the
%     List of output variables for a description).
% 
%     * Field(s) of gene_data: pb_type, collisions, alpha, epsilon, 
%       array_fishes_solids, base_filename	
%     * Field(s) of discret_data: mesh_size
%     * Field(s) of bound_data: mfilename, settings, color
%     * Field(s) of ode_data: Tmax, dT, initial_positions,
%       initial_velocities
%     * Field(s) of phys_data: rhof, rhos
%     * Field(s) of fish: father, label, body, density, hinge_coord,
%       local_hinge, color
% 
% See also BHT_DATA_COMPILE, BHT_BOUNDARIES_INIT, BHT_SOLIDS_DATA_INIT, 
%   BHT_G_KINEMATICS, BHT_G_CONTROLS

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                         %
%                      BIOHYDRODYNAMICS MATLAB TOOLBOX                    %
%                                                                         %
%                         A. MUNNIER and B. PINCON                        %
%                                                                         %
% alexandre.munnier@iecn.u-nancy.fr        bruno.pincon@iecn.u-nancy.fr   %
% http://www.iecn.u-nancy.fr/~munnier  http://www.iecn.u-nancy.fr/~pincon %                                                                 
%                                                                         %              
%                      INSTITUT ELIE CARTAN, NANCY 1                      %
%                       http://www.iecn.u-nancy.fr/                       %
%                                                                         %
%                      INRIA Lorraine, Projet CORIDA                      %
%                    http://www.iecn.u-nancy.fr/~corida/                  %
%                                                                         %  
%                                                                         %  
%                                                                         %  
%                            August 15th 2008                             %
%                                                                         %
%                                               GNU GPL v3 licence        %
%                                                                         %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%##########################################################################
% Set default values. These values will replaced missing optional values 

default_meshsize = 0.1;
default_fluid_density = 1;
default_collisions = 0;
default_color = [0.9 0.9 1];
default_colormap = 'autumn';
default_pb_type = 0;

    %-------------------------------------
    if default_pb_type == 0
        default_pb_type_name = 'exterior';
    else
        default_pb_type_name = 'interior';
    end
    %-------------------------------------
    if default_collisions == 0
        default_collisions_name = 'not allowed';
    else
        default_collisions_name = 'allowed';
    end


%##########################################################################
% PREALLOCATION OF VARIABLES
%---------------------------

gene_data = struct('base_filename',' ',...
                   'pb_type',[],...
                   'collisions',[],...
                   'alpha',[],...
                   'epsilon',[],...
                   'nb_fishes',[],...
                   'nb_solids',[],...
                   'array_fishes_solids',[],...
                   'nb_boundaries',[]);


bound_data = struct('mfilename',{},...
                    'settings',{},...
                    'nbr_modes',{},...
                    'nbr_points',{},...
                    't',{},...
                    'dt',{},...
                    'X',{},...
                    'dl',{},...
                    'Nn',{},...
                    'N',{},...
                    'K',{},...
                    'flux',{},...
                    'fflux',{},...
                    'color',{});

ode_data = struct('Tmax',[],...
                  'dT',[],...
                  'initial_positions',[],...
                  'initial_velocities',[]);

phys_data = struct('rhof',[],...
                   'rhos',[],...
                   'Ms',[],...
                   'solids_area',[],...
                   'fishes_mass',[]);
               
discret_data = struct('mesh_size',[],...
                      'last_line',[]);
 
%-------------------------------------------
% 'solide' is a local struct array variable. 

solide = struct('label',{},...
                'father',{},...
                'num_father',{},...
                'mfilename',{},...
                'settings',{},...
                'hinge_coord',{},...
                'local_hinge',{},...
                'density',{},...
                'color',{});               


%##########################################################################
% DATA READING 
%--------------------------------------------------------------------------
% Read data from the data file and compil its in a large string 'bigstr'
%--------------------------------------------------------------------------

    bigstr = textread(filename, '%s', 'whitespace', '');

    bigstr = bigstr{1};

%##########################################################################
% DATA EXTRACTION
%--------------------------------------------------------------------------
% Data extraction from the big string 'bigstr' and storage into output
% variables
%
%==========================================================================
% Extraction of 'mesh_size'
%--------------------------

mesh_size = regexpi(bigstr,'mesh\s*size\s*=\s*(\S*)', 'tokens');

if isempty(mesh_size)
    warning('FluidStruct:Meshmiss',['mesh size is missing.\n',...
        'Variable automatically set to mesh_size = ',...
         num2str(default_meshsize)]);
     
    mesh_size = default_meshsize;
else
    mesh_size = str2num(mesh_size{1}{1}); %#ok<ST2NM>
    disp(['mesh_size = ',num2str(mesh_size)]);
end

%++++++++++++++++++++++++++++++++++
discret_data.mesh_size = mesh_size;
%++++++++++++++++++++++++++++++++++

%==========================================================================
% Extraction of fluid's density
%------------------------------

fluid_density = regexpi(bigstr,'fluid\s*density\s*=\s*(\S*)',...
                                                                 'tokens');

if isempty(fluid_density)
    fluid_density = 1;
    warning('FluidStruct:densityMiss',['Fluid density is missing.\n ',...
        'Variable automatically set to fluid_density = ',...
         num2str(default_fluid_density)]);
else
    fluid_density = str2num(fluid_density{1}{1}); %#ok<ST2NM>
    disp(['fluid_density = ',num2str(fluid_density)]);
end

%++++++++++++++++++++++++++++++
phys_data.rhof = fluid_density;
%++++++++++++++++++++++++++++++

%==========================================================================
% Extraction of fluid's boundaries' data (boundaries not shared with solids) 
% and creation of the struct array local variable 'boundaries_ext'
%----------------------------------------------------------------

tok = regexpi(bigstr,'boundary\s*=\s*{(.*?)}', 'tokens');

nb_bound_ext = numel(tok);

disp(['Number of exterior boundaries found : ',num2str(nb_bound_ext)]);

%----------------------------------------------------------
%Prealocation of struct array local variable 'boundary_ext'
%----------------------------------------------------------

boundaries_ext = struct('mfilename',{},...
                        'settings',{},...
                        'color',{});

%==========================================================================
% Loop on boundaries not shared with solids
%==========================================================================
for k = 1:nb_bound_ext
   
    % =====================================================================
    % Extraction of boundary's file name
    %-----------------------------------
    
    rien = regexpi(tok{k}{1},'mfilename\s*=\s*(\w*)\s*','tokens');
    
     if isempty(rien)
            error(['Filename for exterior boundary ',num2str(k),...
                   ' is missing. Add a field ''mfilename = ...'' to DAT-Filename.']);
     end
     %++++++++++++++++++++++++++++++++++++++++
     boundaries_ext(k).mfilename = rien{1}{1};
     %++++++++++++++++++++++++++++++++++++++++
     
     % ====================================================================
     % Extraction of boudary's settings
     %-----------------------------------
     
     rien = regexpi(tok{k}{1},'settings\s*=\s*\[(.*?)\]\s*','tokens');
    
     if ~isempty(rien)
        boundaries_ext(k).settings = str2num(rien{1}{1}); %#ok<ST2NM>
     else
        boundaries_ext(k).settings = [];
     end
     
     % ====================================================================
     % Extraction of boudary fill color
     %---------------------------------
     
     rien = regexpi(tok{k}{1},'color\s*=\s*\[(.*?)\]\s*','tokens');
    
     if ~isempty(rien)
        boundaries_ext(k).color = str2num(rien{1}{1}); %#ok<ST2NM>
     else
        boundaries_ext(k).color = default_color;
     end
     
end

%==========================================================================
% Extraction of pb type (0 = exterior, 1 = interior)
%---------------------------------------------------

pb_type = regexpi(bigstr,'problem\s*type\s*=\s*(\d)', 'tokens');

if isempty(pb_type)
    
    warning('FluidStruct:PbTypMiss',['Problem type (exterior/interior) is missing.\n ',...
        'Variable automatically set to pb_type = ',num2str(default_pb_type),...
                                      '(',default_pb_type_name,').']);
    pb_type = default_pb_type;
                                  
elseif strcmpi(pb_type{1}{1},'exterior') || strcmpi(pb_type{1}{1},'ext')
    pb_type = 0;
    disp('Problem type : exterior'); 
else
    pb_type = 1;
    disp('Problem type : interior');
end

%++++++++++++++++++++++++++++
gene_data.pb_type = pb_type;
%++++++++++++++++++++++++++++

%==========================================================================
% Extraction of 'collisions' (=1 if collisions are allowed =0 otherwise)
%-----------------------------------------------------------------------

collisions = regexpi(bigstr,'collisions\s*=\s*(\w*)\s', 'tokens');

if isempty(collisions)
    warning('FluidStruct:CollMiss',['Whether collisions are allowed or not, not specified.\n ',...
        'Variable automatically set to collisions = ',num2str(default_collisions),' (', ...
        default_collisions_name,').']);
    collisions = default_collisions;
else
    collisions = collisions{1}{1};
    collisions = (strcmpi(collisions,'yes') | strcmpi(collisions,'y'));
    if collisions
        collisions_name = 'allowed';
    else
        collisions_name = 'not allowed';
    end
    disp(['Collisions = ',num2str(collisions),' (',collisions_name,')']);
end
   
%++++++++++++++++++++++++++++++++++
gene_data.collisions = collisions;
%++++++++++++++++++++++++++++++++++

% =========================================================================
% Extraction of collisions' parameters (only when collisions are allowed)
%------------------------------------------------------------------------

if collisions
    
    epsilon = regexpi(bigstr,'epsilon\s*=\s*(\S*)', 'tokens');
    alpha = regexpi(bigstr,'alpha\s*=\s*(\S*)', 'tokens');
    
    if isempty(epsilon) || isempty(alpha)
        error(['Collisions allowed but parameter epsilon or/and alpha is missing.',...
               'Add a field ''epsilon = ...'' or/and ''alpha = ...'' to DAT-File.'])
    else
        
        epsilon = str2num(epsilon{1}{1}); %#ok<ST2NM>
        alpha = str2num(alpha{1}{1}); %#ok<ST2NM>

        if isempty(epsilon) || isempty(alpha) || isnan(epsilon) || isnan(alpha)
            error(['Collisions allowed but parameter epsilon or/and alpha is missing.',...
               'Add a field ''epsilon = ...'' or/and ''alpha = ...'' to DAT-File.'])
        end
        %++++++++++++++++++++++++++++
        gene_data.alpha = alpha;
        gene_data.epsilon = epsilon;
        %++++++++++++++++++++++++++++
    end
end

%==========================================================================
% Extraction of simulation's time
%--------------------------------

Tmax = regexpi(bigstr,'max\s*time\s*=\s*(\S*)', 'tokens');

if isempty(Tmax)
    error('Simulation time is missing. Add a field ''max time ='' to DAT-File.')
end

Tmax = str2num(Tmax{1}{1}); %#ok<ST2NM>

%++++++++++++++++++++++
ode_data.Tmax = Tmax;
%++++++++++++++++++++++

disp(['Simulation''s time = ',num2str(Tmax)]);

%==========================================================================
% Extraction of time step
%------------------------

dT = regexpi(bigstr,'time\s*step\s*=\s*(\S*)', 'tokens');

if isempty(dT)
    error('Time step is missing. Add a field ''time step = ...'' to DAT-File.')
end

dT = str2num(dT{1}{1}); %#ok<ST2NM>

%++++++++++++++++++
ode_data.dT = dT;
%++++++++++++++++++

disp(['Time step  = ',num2str(dT)]);

%==========================================================================
%  Extraction of fishes's data                   
%==========================================================================
% Preallocation of variables
%---------------------------

%++++++++++++++++++++++++++++++++
ode_data.initial_positions = [];
ode_data.initial_velocities = [];
%++++++++++++++++++++++++++++++++

%==========================================================================
% Extraction of fishes's data and storage into a cell array variable 'tok'
%-------------------------------------------------------------------------

tok = regexp(bigstr,'fish\s*=\s*{(.*?})\s*}', 'tokens');

nb_fish = numel(tok);

if nb_fish == 0
    error('No fish neither solid found. Add a field ''fish = {...}'' to DAT-File.')
end
%++++++++++++++++++++++++++++++
gene_data.nb_fishes = nb_fish;
%++++++++++++++++++++++++++++++

disp(['Number of fish(es) found : ',num2str(nb_fish)]);

%==========================================================================
% Preallocation of output cell array variable 'fish' and local cell array
% variable 'fish_colormap'
%-------------------------

fish = cell(1,nb_fish);

fish_colormap = cell(1,nb_fish);

%==========================================================================
% Main loop (on fishes)
%==========================================================================
for i = 1:nb_fish
    
    %======================================================================
    % extraction of data of the ith fish
    %======================================================================
    
    %======================================================================
    % Extraction of initial position
    %-------------------------------
    
    rien = regexpi(tok{i}{1},'initial\s*position\s*=\s*\[(.*?)\]','tokens');
    
    if isempty(rien)
        error(['Initial position of fish or solid ',num2str(i),...
            ' is missing. Add a field ''initial position = ...'' to DAT-File.']);
    end

    rien = str2num(rien{1}{1}); %#ok<ST2NM>
    
    %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ode_data.initial_positions = vertcat(ode_data.initial_positions,...
                                                  reshape(rien,3,1));
    %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    %======================================================================
    % Extraction of initial velocity
    %-------------------------------
    
    rien = regexpi(tok{i}{1},'initial\s*velocity\s*=\s*\[(.*?)\]','tokens');
    
    if isempty(rien)
        error(['Initial velocity of fish or solid ',num2str(i),...
            ' is missing. Add a field ''initial velocity = ...'' to DAT-File.']);
    end

    rien = str2num(rien{1}{1}); %#ok<ST2NM>
    
    %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ode_data.initial_velocities = vertcat(ode_data.initial_velocities,...
                                                   reshape(rien,3,1));
    %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    %======================================================================
	% Extraction of the number of links in the ith fish
    %--------------------------------------------------
  
    stok = regexp(tok{i}{1},'link\s*=\s*{(.*?)}', 'tokens');
    nb_solids = numel(stok);
    
    if nb_solids == 0
        error(['Fish ',num2str(i),' is empty (no solid found). Add a field ''link = ...'' to DAT-File.'])
    end
    
    %+++++++++++++++++++++++++++++++++++++++++++
    gene_data.array_fishes_solids(i) = nb_solids;
    %+++++++++++++++++++++++++++++++++++++++++++
    
    %======================================================================
	% Extraction of the colormap for the ith fish
    %--------------------------------------------
    
    rien = regexpi(tok{i}{1},'colormap\s*=\s*(\w*)\s*','tokens');
    
    fish_colormap{i} = feval(default_colormap,nb_solids+1);
    
    if ~isempty(rien)
        fish_colormap{i} = feval(rien{1}{1},nb_solids+1);
    end

    %======================================================================
    % Internal loop (on solids composing the ith fish)
    %======================================================================
    for k = 1:nb_solids
        solid = stok{k}{1};
        
        % =================================================================
        % Extraction of label
        %--------------------
        
        rien = regexpi(solid,'label\s*=\s*([a-zA-Z]\w*)','tokens');
        
        if isempty(rien)
            error(['One solid in fish ',num2str(i),' has no label.',...
                    ' Add a field ''label = ...'' to DAT-File.']);
        end
        %+++++++++++++++++++++++++++
        solide(k).label = rien{1}{1};
        %+++++++++++++++++++++++++++
        
        % =================================================================
        % Extraction of father's label (label of the link the current
        % solid is attached to)
        %----------------------
        
        rien = regexpi(solid,'father\s*=\s*(\w*)','tokens');
        
        if ~isempty(rien)
            solide(k).father = rien{1}{1};
        end
        
        % =================================================================
        % Extraction of the file name for the function that parameterize
        % the solid
        %--------------------
        
        rien = regexpi(solid,'mfilename\s*=\s*(\w*)','tokens');
        
        if isempty(rien)
            error(['One solid in fish ',num2str(i),' has no M-File name specified.',...
                'Add a field ''mfilename = ...'' to DAT-File.']);
        end
        
        %+++++++++++++++++++++++++++
        solide(k).mfilename = rien{1}{1};
        %+++++++++++++++++++++++++++
        
        
        % =================================================================
        % Extraction of boundary's settings
        %------------------------------------------------------------
        
        rien = regexpi(solid,'settings\s*=\s*\[(.*?)\]','tokens');
        
        if ~isempty(rien)
            %++++++++++++++++++++++++++++++++++++++++++
            solide(k).settings = str2num(rien{1}{1}); %#ok<ST2NM>
            %++++++++++++++++++++++++++++++++++++++++++
        else
            %+++++++++++++++++++++++++
            solide(k).settings = [];
            %+++++++++++++++++++++++++
        end
        
        % =================================================================
        % Extraction of the solid's density
        %----------------------------------
        
        rien = regexpi(solid,'density\s*=\s*(\d*(?:\.?\d*))','tokens');
        
        if isempty(rien)
        warning('FluidStruct:SolidDensityMiss',['One solid in fish ',...
            num2str(i),' has no density specified.\n ',...
           'Density automaticaly set to fluid density (= ',...
                                             num2str(fluid_density),').']);
            %+++++++++++++++++++++++++++++++++
            solide(k).density = fluid_density;
            %+++++++++++++++++++++++++++++++++
        else
            %+++++++++++++++++++++++++++++++++++++++
            solide(k).density = str2num(rien{1}{1}); %#ok<ST2NM>
            %+++++++++++++++++++++++++++++++++++++++
        end
        
        % =================================================================
        % Extraction of the hinge coordinates (in the father's frame)
        %------------------------------------------------------------
        
        rien = regexpi(solid,'hinge\s*coord\s*=\s*\[(.*?)\]','tokens');
        
        if ~isempty(rien)
            %++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            solide(k).hinge_coord = reshape(str2num(rien{1}{1}),2,1); %#ok<ST2NM>
            %++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        end
        
        % =================================================================
        % Extraction of the hinge coordinates (in the current solid's
        % frame)
        %----------
        
        rien = regexpi(solid,'hinge\s*local\s*coord\s*=\s*\[(.*?)\]','tokens');
        
        if ~isempty(rien)
            %++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            solide(k).local_hinge = reshape(str2num(rien{1}{1}),2,1); %#ok<ST2NM>
            %++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        end
        
        % =================================================================
        % Extraction of the solid's color (RGB formalism)
        %------------------------------------------------
        
        rien = regexpi(solid,'color\s*=\s*\[(.*?)\]','tokens');
        
        if ~isempty(rien)
            %++++++++++++++++++++++++++++++++++++++++++++++++++
            solide(k).color = reshape(str2num(rien{1}{1}),1,3); %#ok<ST2NM>
            %++++++++++++++++++++++++++++++++++++++++++++++++++
        else
            %++++++++++++++++++++
            solide(k).color = [];
            %++++++++++++++++++++
        end
    end
    
    %======================================================================
    % Storage into the output cell array variable 'fish'
    %---------------------------------------------------
    
    %++++++++++++++++
    fish{i} = solide;
    %++++++++++++++++
    
end


%##########################################################################
% Data postprocessing
%--------------------------------------------------------------------------
% Checking if solids in the same fish have distinct names
%--------------------------------------------------------

for j = 1:nb_fish
    SA = fish{j};
    nb_solids = numel(SA);
    if nb_solids > 1
        for k = 1:nb_solids-1;
            for p = k+1:nb_solids;
                if strcmpi(SA(k).label,SA(p).label)
                    error(['Two or more solids have the same label in fish ',...
                                                           num2double(j)]);
                end
            end
        end
    end
end

%==========================================================================
% Changing solids's order ; placing solid 'father' before its children ;
% Giving each solid a number and the corresponding father's number
%-----------------------------------------------------------------

for j = 1:nb_fish
    
    SA = fish{j};
    
    nb_solids = numel(SA);
    
    for k = 1:nb_solids
        for p = 1:nb_solids
            if strcmpi(SA(k).label,SA(p).father)
                fils = SA(p);
                father = SA(k);
                SA(min([k,p])) = father;
                SA(max([k,p])) = fils;
                %++++++++++++++++++++++++++++++++++++++
                SA(max([k,p])).num_father = min([k,p]);
                %++++++++++++++++++++++++++++++++++++++
            end
            
            if strcmpi(SA(p).label,SA(k).father)
                fils = SA(k);
                father = SA(p);
                SA(min([k,p])) = father;
                SA(max([k,p])) = fils;
                %++++++++++++++++++++++++++++++++++++++
                SA(max([k,p])).num_father = min([k,p]);
                %++++++++++++++++++++++++++++++++++++++
            end
        end
    end
    
    %++++++++++++
    fish{j} = SA;
    %++++++++++++

end

%==========================================================================
% Collecting of all the boundaries's filename, settings, density and 
% color in the struct array 'boundaries'
%--------------------------------------------------------------------------
% Processing first the solids
%----------------------------
iter = 0;

for j = 1:nb_fish
    
    SA = fish{j};
    
    nb_solids = numel(SA);
    
    for k = 1:nb_solids
        iter = iter + 1;
        %++++++++++++++++++++++++++++++++++++++++++++++
        bound_data(iter).mfilename = SA(k).mfilename;
        bound_data(iter).settings = SA(k).settings;
        %++++++++++++++++++++++++++++++++++++++++++++++
        
        if ~isempty(SA(k).color)
            %++++++++++++++++++++++++++++++++++++
            bound_data(iter).color = SA(k).color;
            %++++++++++++++++++++++++++++++++++++
        else
            %++++++++++++++++++++++++++++++++++++++++++++++
            bound_data(iter).color = fish_colormap{j}(k,:);
            %++++++++++++++++++++++++++++++++++++++++++++++
        end
        %++++++++++++++++++++++++++++++++++++
        phys_data.rhos(iter) = SA(k).density;
        %++++++++++++++++++++++++++++++++++++
    end 
end

%-----------------
% number of solids
%+++++++++++++++++++++++++++
gene_data.nb_solids = iter;
%+++++++++++++++++++++++++++

disp(['Total number of solids: ',num2str(iter)]);

%--------------------------------------------------------------------------
% Processing now the boundaries not shared with solids
%-----------------------------------------------------

if nb_bound_ext > 0
    for k = 1:nb_bound_ext;
        iter = iter + 1;
        %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        bound_data(iter).mfilename = boundaries_ext(k).mfilename;
        bound_data(iter).settings = boundaries_ext(k).settings;
        bound_data(iter).color = boundaries_ext(k).color;
        %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    end
end

%+++++++++++++++++++++++++++++++
gene_data.nb_boundaries = iter;
%+++++++++++++++++++++++++++++++

disp(['Total number of boundaries: ',num2str(iter)]);

%==========================================================================
% Checking if each solid (but the first one) has a father
%---------------------------------------------------------

for j = 1:nb_fish
    
    SA = fish{j};
    
    nb_solids = numel(SA);
    
    if nb_solids > 1
        for k = nb_solids:-1:2
            test_father = 0;
            for p = 1:k-1
              test_father = test_father + strcmpi(SA(k).father,SA(p).label);
            end
            if ~test_father
                error(['One solid has no father in fish ',num2str(j)])
            end
        end
    end
end

%==========================================================================
% Checking if each solid (but the first one) has hinges
%------------------------------------------------------

for j = 1:nb_fish
    
    SA = fish{j};
    
    nb_solids = numel(SA);
    
    if nb_solids > 1
        for k = 2:nb_solids
            if isempty(SA(k).hinge_coord) || isempty(SA(k).local_hinge)
                error(['One solid in fish ',num2str(j),...
                    ' has no hinge coordinates specified. Add a field ''hinge coord = ...'' to DAT-File']);
            end
        end
    end
end

%##########################################################################
% Saving data
%------------

base_filename = regexp(filename,'(\w*).\w*', 'tokens');
base_filename = base_filename{1}{1};

%++++++++++++++++++++++++++++++++++++++++
gene_data.base_filename = base_filename;
%++++++++++++++++++++++++++++++++++++++++

end



Contact us at files@mathworks.com