function outputfile = EDB1edgeox(cadgeofile,outputfile,open_or_closed_model,int_or_ext_model,specorder,difforder,nedgesubs,firstskipcorner,planeseesplanestrategy)
% EDB1edgeox - Calculates some plane- and edge-related geometrical parameters.
% EDB1edgeo calculates some plane- and edge-related geometrical parameters
% based on corners and planes in a .mat-file generated by EDB1readcad
% but only data that is independent of the source and receiver.
% The output is saved in a .mat-file.
%
% Input parameters:
%	cadgeofile (optional)	The .mat file with the corners and plane data.			
%							If it is not specified, a file opening window is presented.
%	outputfile (optional)	The .mat file where the output data will be stored.
%							If it is not specified, an automatic file name is constructed
%							using the same filename stem as the cadgeofile, but ending
%                           with '_edgeo'.
%   open_or_closed_model    'o' or 'c' defining whether the model is open or closed.
%   int_or_ext_model        'i' or 'e' defining whether the model is interior or exterior.
%   specorder               The highest order of any reflection kind (specular and/or diffraction).
%	difforder (optional)	The highest order of diffraction. If it is 0 or 1 then the parameter
%							edgeseespartialedge is not calculated. Default: 1
%	nedgesubs (optional)	The number of segments that each edge will be
%							subdivided into for visibility/obstruction tests. Default: 2
%							NB! When nedgesubs = 2, only the two end points will be checked.
%	firstskipcorner (optional)	All edges including at least one corner with this number or
%                   		higher will be excluded from the calculations. Default: 1e6
%   planeseesplanestrategy (optional)   If this parameter is given the value 1, a plane-to-plane
%                           visibility check is done by checking the plane-midpoint to plane-midpoint
%                           for obstructions, which might be enough for some geometries.
%	SHOWTEXT (global)		An integer value; if it is 4 or higher, then messages will be printed on the
%							screen during calculations.
% Output parameters:
%	outputfile				The name of the outputfile, generated either automatically or specified as 
%							an input parameter.
%
% Output parameters in the outputfile:
%    (Taken directly from the cadgeo-file:)
%		corners planecorners  planeeqs planenvecs ncornersperplanevec
%		minvals maxvals planehasindents indentingcorners
%    (Taken directly from the setup-file:)
%       int_or_ext_model
%	 (Calculated by EDB1edgeo:)
%	edgecorners             Matrix [nedges,2] with the corner numbers that
%	                        define each edge, in the reference order.
%   edgestartcoords         Matrix [nedges,3] with the coordinates of the
%                           start corner for each edge.
%   edgeendcoords           Matrix [nedges,3] with the coordinates of the
%                           end corner for each edge.
%   edgelengthvec           List [nedges,1] with the lengths of each edge.
%   planesatedge            Matrix [nedges,2] with the plane numbers of the
%                           two planes that connect to each edge. The first
%                           plane is considered as the reference plane for
%                           each edge. Rule: if the RH thumb is placed
%                           along the edge, from start to end, and the hand
%                           is rotated, the fingers should "come up
%                           through" the reference plane.
%   closwedangvec           List [nedges,1] with the angles in radians of
%                           each edge - for the closed part of each edge.
%   edgenvecs               Matrix [nedges,3] with the normal vectors of
%                           the reference plane for each edge.
%	offedges                List [nlength,1] where nlength = 0-nedges
%                           containing the edge numbers that should not
%                           used.
%   reflfactors             List [nplanes,1] with the reflection factors
%                           of each plane. The only supported values are
%                           +1 for rigid planes, 0 for perfectlt absorbing
%                           planes and -1 for pressure-release planes. The
%                           pressure-release cases might not be implemented
%                           fully.
%   planeisthin             List [nplanes,1] with the value 1 or 0 stating
%                           whether the plane is thin or not. 
%   rearsideplane           List [nplanes,1] with the plane number that is at
%                           the rear side. If a plane is non-thin, the
%                           value in this list is zero.
%   planehasindents         List [nplanes,1] with the value 1 or 0 stating
%                           whether a plane has indents or not.
%   indentingedgepairs      Matrix [nindentingedgepairs,2] where each row
%                           gives two connected edges that form an indent
%                           in the shared plane. Consequently, those two
%                           edges can never see each other.
%   canplaneobstruct        List [nplanes,1] with the value 1 or 0 stating
%                           whether a plane has the potential to obstruct
%                           or not.
%   planeseesplane          A matrix, [nplanes,nplanes], with the value 1
%                           0,-1,-2 stating:
%                           1 A plane is front of another plane and could
%                             then potentially see it.
%                           0 A plane is completely behind another plane
%                             but they are not aligned
%                           -1 A plane is aligned with another plane
%                           -2 A plane is back-to-back with another plane.
%   edgesatplane            A matrix, [nplanes,nmaxedgesperplane] which for
%                           row N contains the edge numbers that connect to
%                           to plane N.
%   edgeseesplane           A matrix, [nplanes,nedges], which contains the
%                           values 0,1,-2 or -2, meaning:
%                           0   The edge is completely behind a plane
%                           -1  The edge can never see the plane and the
%                               edge is aligned with the plane
%                           -2  The edge can never see the plane and the
%                               edge belongs to the plane
%                           1   The edge has at least one point in front of the plane.
%
% Uses the functions EDB1coordtrans1
%                    EDB1infrontofplane, EDB1strpend, EDB1cross
%
% ----------------------------------------------------------------------------------------------
%   This file is part of the Edge Diffraction Toolbox by Peter Svensson.                       
%                                                                                              
%   The Edge Diffraction Toolbox is free software: you can redistribute it and/or modify       
%   it under the terms of the GNU General Public License as published by the Free Software     
%   Foundation, either version 3 of the License, or (at your option) any later version.        
%                                                                                              
%   The Edge Diffraction Toolbox is distributed in the hope that it will be useful,       
%   but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS  
%   FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.             
%                                                                                              
%   You should have received a copy of the GNU General Public License along with the           
%   Edge Diffraction Toolbox. If not, see <http://www.gnu.org/licenses/>.                 
% ----------------------------------------------------------------------------------------------
% Peter Svensson (svensson@iet.ntnu.no) 20090709
%
% outputfile = EDB1edgeox(cadgeofile,outputfile,open_or_closed_model,int_or_ext_model,specorder,difforder,nedgesubs,firstskipcorner,planeseesplanestrategy);

global SHOWTEXT 

geomacc = 1e-10;

if nargin < 9
    planeseesplanestrategy = 0;
	if nargin < 8
		firstskipcorner = 1e6;
		if nargin < 7
			nedgesubs = 2;
			if nargin < 6
				difforder = 1;
			else
				if isempty(difforder), difforder = 1; end		
			end
		else
			if isempty(nedgesubs), nedgesubs = 2; end	
		end
	else
		if isempty(firstskipcorner), firstskipcorner = 1e6; end
	end
end

%---------------------------------------------------------------
% If no cadgeofile was specified, present a file opening window

if isempty(cadgeofile)
	[cadgeofile,filepath] = uigetfile('*.mat','Please select the cadgeofile');
    [filepath,temp1,temp2] = fileparts(filepath);
	if ~isstr(cadgeofile)
		return
	end
    [temp1,filestem,fileext,temp2] = fileparts(cadgeofile);
    cadgeofile = [filepath,filestem,'.mat'];
else
    [filepath,filestem,fileext] = fileparts(cadgeofile);
    if ~isempty(filepath)
        cadgeofile = [[filepath,filesep],filestem,'.mat'];
    else
        cadgeofile = [filestem,'.mat'];        
    end
end


%---------------------------------------------------------------
% If no output file was specified, construct an automatic file name

if isempty(outputfile)
	filestem = EDB1strpend(filestem,'_cadgeo');
	outputfile = [[filepath,filesep],filestem,'_eddata.mat'];
end

%---------------------------------------------------------------

eval(['load ',cadgeofile])

ncorners = length(cornernumbers);
[nplanes,maxncornersperplane] = size(planecorners);
minncornersperplane = min(ncornersperplanevec);
nedgesperplanevec = double(ncornersperplanevec);
ncornersperplanevec = double(ncornersperplanevec);

switchoffcorners = find( cornernumbers >= firstskipcorner );

onesvec2 = ones(nplanes,1);
zerosvec1 = zeros(nplanes,1);
zerosvec2 = int8(zeros(nplanes,nplanes));

%----------------------------------------------------------------------------
%
%		GEOMETRICAL ACOUSTICS PARAMETERS
%
%----------------------------------------------------------------------------
% 
% Go through all planeabstypes. If it is:
%	'SOFT' or 'soft'  then reflfactors should be -1.
%	'TOTA' or 'tota' then reflfactors should be 0 (short for TOTABS)
%   Otherwise it is assumed to be rigid, so reflfactors = 1.

if SHOWTEXT >= 4
	disp('         Check abstypes')
end

[slask,nchars] = size(planeabstypes);
reflfactors = ones(nplanes,1);
if nchars >= 4
    planeabstypes = lower(full(planeabstypes(:,1:min([4,nchars]))));

    comptxt = 'soft';
    ivpotential = find(planeabstypes(:,1)==comptxt(1));
    if ~isempty(ivpotential)
        comptxt = 'oft';
        compmat = comptxt(ones(length(ivpotential),1),:);
        ivsoft   = ivpotential(find(prod( (planeabstypes(ivpotential,2:4).*compmat).' ).'));
        reflfactors(ivsoft)   = -1*ones(size(ivsoft));
    end
    
    comptxt = 'tota';
    ivpotential = find(planeabstypes(:,1)==comptxt(1));
    if ~isempty(ivpotential)
        comptxt = 'ota';
        compmat = comptxt(ones(length(ivpotential),1),:);
        ivtotabs =  ivpotential(find(prod( double(planeabstypes(ivpotential,2:4)==compmat).' ).'));
        reflfactors(ivtotabs) = zeros(size(ivtotabs));
    end
end

%----------------------------------------------------------------------------
%
%		EDGE PARAMETERS
%
%----------------------------------------------------------------------------
%
% Check that the planecorners matrix contains no zeros. In such case
% add the circular repetition of coordinates.

if SHOWTEXT >= 4
	disp('         Circular')
end
if sum(sum( planecorners == 0 )) ~= 0
	for ii = 1:nplanes
		iv = find( planecorners(ii,:) ~= 0);
		ncornersatplane = length(iv);
		if ncornersatplane ~= maxncornersperplane
			pattern = planecorners(ii,iv);
			nrepeatings = ceil(maxncornersperplane/ncornersatplane);
			for jj = 1:nrepeatings-1
				pattern = [pattern planecorners(ii,iv)];
			end
			planecorners(ii,:) = pattern(1:maxncornersperplane);
		end
	end
end
    
%--------------------------------------------------------------------------------
%
% Find all edges
%
% Go through all planes. All consecutive pairs of corners form an edge.
% The list planesatedge gives the one or two planes that connect
% to each edge. If the second plane number, for a certain edge
% is zero, then that specific edge is a plate edge.

edgesatplane = zeros( size(planecorners) );

if SHOWTEXT >= 4
	disp('         Defining edges...')
end

nedgesguess = sum(ncornersperplanevec);
edgecorners = zeros(nedgesguess,2);
tempplanesatedge = zeros(nedgesguess,1);
nedges = 0;
thirdpoint = [];
edgecounter = 0;
multfac = round(10^(floor(log10(nedgesguess))+2));

% First go through all planes, and construct edges from the list of corners
% that define every plane. This way, many edges will occur twice, unless
% a thin plane has no rear side (then the edge occurs a single time)
% or if two thin planes are connected (then the edge occurs four times)

for ii = 1:nplanes
   for jj = 1:nedgesperplanevec(ii)
      edgecounter = edgecounter + 1;   
      corner1 = planecorners(ii,jj);
      if jj + 1 <= ncornersperplanevec(ii)
         corner2 = planecorners(ii,jj+1);
      else
         corner2 = planecorners(ii,1);
      end
	  edgecorners(edgecounter,:) = [corner1 corner2];
	  tempplanesatedge(edgecounter) = ii;
   end

end

if edgecounter < nedgesguess
	edgecorners(edgecounter+1:nedgesguess,:) = [];
	tempplanesatedge(edgecounter+1:nedgesguess,:) = [];
end

% To find all duplicates, the edge list is sorted in numerical order
% If an edge is defined twice or four times, then this is an OK edge.
% If an edge is defined a single time, it is connected to a plane which is not connected, and then the
% edge should be switched off.
% If an edge is defined three times, there must be something like a reflector array where one of
% the rear planes is missing.

[test,flipvec] = sort(edgecorners.');
test = test.';
flipvec = flipvec(1,:).';

test = test(:,1)*multfac + test(:,2);
[test,sortvec] = sort(test);
tempplanesatedge = tempplanesatedge(sortvec);
flipvec = flipvec(sortvec);
planesatedge = [tempplanesatedge.*(flipvec==1) tempplanesatedge.*(flipvec==2)];

% Check if there are loners; remove and give a warning.
 
dtest = diff([0;test;test(length(test))+100]);
ntest = length(dtest);
loners = find(dtest(1:ntest-1)~=0 & dtest(2:ntest)~=0);

if ~isempty(loners)
	disp('WARNING! Some edges had only one plane connected and they will be excluded.')
	disp('         Check if they should be corrected. ')
	disp('         Remember that reflectors must have a plane at the rear side too')
	disp('         Set SHOWTEXT to 4 or higher to get a list of these edges')
	if SHOWTEXT >= 4
		disp('         The edges are (EDB1 corner numbers for the two edge point are given):')
		nloners = length(loners);
		for jjdisp = 1:nloners
			indlon = loners(jjdisp);
			disp(['      ',int2str( floor(test(indlon)/multfac) ),' ',int2str( test(indlon)-floor(test(indlon)/multfac)*multfac )])
			disp(['      CATT: ',int2str( cornernumbers(floor(test(indlon)/multfac) )),' ',int2str( cornernumbers(test(indlon)-floor(test(indlon)/multfac)*multfac ))])
		end
	end
	
	test(loners) = [];
	planesatedge(loners,:) = [];
	
end

ntest = length(test);
if ntest >= 2
    if test(ntest) ~= test(ntest-1)
	    test(ntest) = [];
	    planesatedge(ntest,:) = [];
    end
end

% Check if there are triplets

triptest = test(1:2:length(test))-test(2:2:length(test));
triplets = find(triptest~=0);

if ~isempty(triplets)
	disp('ERROR: Triplets: some edges are defined three times which means that two thin planes have a correct')
	disp('       definition but some error on the rear side. You must correct these. ')
	disp('       Only the first one can be detected; it is:')
	disp('       (EDB1 corner numbers for the two edge points are given)')
	[floor(test(triplets(1)*2-1)/multfac) test(triplets(1)*2-1)-floor(test(triplets(1)*2-1)/multfac)*multfac]
    save ~/Documents/Temp/test.mat
	error
end

edgecounter = length(test);

iv1 = find(planesatedge(:,1)~=0);
iv2 = 1:edgecounter;
iv2(iv1) = [];

edgecorners = [floor(test(iv1)/multfac) test(iv1)-floor(test(iv1)/multfac)*multfac];
planesatedge = planesatedge(iv1,:) + planesatedge(iv2,:);

[nedges,slask] = size(edgecorners);

zerosvec3 = zeros(nedges,1);
zerosvec5 = zeros(nedges,3);

if SHOWTEXT >= 4
	disp(['         ',int2str(nedges),' edges found'])
end
thirdpoint = zerosvec5;
for ii = 1:nedges
	refplane = planesatedge(ii,1);
	secondplane = planesatedge(ii,2);
	if secondplane ~= 0
		edgeco1 = corners(edgecorners(ii,1),:);
		edgeco2 = corners(edgecorners(ii,2),:);
		edgemidpoint = edgeco1 + (edgeco2-edgeco1)/2;
		intoplanevec = EDB1cross( (edgeco2-edgeco1).',(planenvecs(secondplane,:)).').';
		inplanepoint = edgemidpoint + intoplanevec*0.1;
		if sum(abs(inplanepoint)) == 0
			inplanepoint = edgemidpoint + intoplanevec*0.2;		
		end
		thirdpoint(ii,:) = inplanepoint;
	end
end


%---------------------------------------------------------------
% Calculate the closwedang values for all edges

if SHOWTEXT >= 4
	disp('         wedge angles...')
end
closwedangvec = zerosvec3;

ivec = find( planesatedge(:,1).*planesatedge(:,2) ~= 0);
xwedgevec = [corners(edgecorners(ivec,1),:) corners(edgecorners(ivec,2),:)];
nvec1vec  = planenvecs( planesatedge(ivec,1),: );
xsouvec   = thirdpoint(ivec,:);

for jj = 1:length(ivec)
  
   ii = ivec(jj);
   [slask,thetas,slask] = EDB1coordtrans1(xsouvec(jj,:),[xwedgevec(jj,1:3);xwedgevec(jj,4:6)],nvec1vec(jj,:));
   if thetas == 0
      closwedangvec(ii) = 0;
   else
      closwedangvec(ii) = 2*pi - thetas;
   end
   	
end

%-------------------------------------------------------------------
% Now we check for duplicates of the edge definitions
% Some edge definitions might need to be swapped: if there are duplicate edges, 
% and one of them has closwedangvec = 0
% then there is a mistake in the edge definition, so a swap will be made.

edgecosinglelist = edgecorners(:,1)*multfac + edgecorners(:,2);
nsteps = diff([0;edgecosinglelist]);
ivduplicates = find(nsteps == 0);
nduplicates = length(ivduplicates);
if nduplicates > 0
	if SHOWTEXT >= 4
		disp(['         ',int2str(nduplicates),' edges formed by connected thin plates'])
	end
	for ii = 1:nduplicates
		comb1 = ivduplicates(ii)-1;
		comb2 = comb1+1;
		if closwedangvec(comb1) == 0 | closwedangvec(comb2) == 0,		% edge definitions should be swapped
			plane1 = planesatedge(comb1,2);
			plane2 = planesatedge(comb2,2);
			planesatedge(comb1,2) = plane2;
			planesatedge(comb2,2) = plane1;		
			temp1 = thirdpoint(comb1,:);
			temp2 = thirdpoint(comb2,:);
			thirdpoint(comb1,:) = temp2;
			thirdpoint(comb2,:) = temp1;
			if SHOWTEXT >= 4
				disp(['         Swapping an edge definition'])
				disp(['            Planes ',int2str(planesatedge(comb1,1)),' and ',int2str(planesatedge(comb1,2))])
				disp(['            CATT:  ',int2str(planenumbers(planesatedge(comb1,1))),' and ',int2str(planenumbers(planesatedge(comb1,2)))])
				disp(['            Planes ',int2str(planesatedge(comb2,1)),' and ',int2str(planesatedge(comb2,2))])
				disp(['            CATT:  ',int2str(planenumbers(planesatedge(comb2,1))),' and ',int2str(planenumbers(planesatedge(comb2,2)))])
			end

   			xwedge = [corners(edgecorners(comb1,1),:);corners(edgecorners(comb1,2),:)];
   			nvec1   = planenvecs( planesatedge(comb1,1),: );
   			xsou   = thirdpoint(comb1,:);
   			[slask,thetas,slask] = EDB1coordtrans1(xsou,xwedge,nvec1);
   			if thetas == 0
    	  		closwedangvec(comb1) = 0;
   			else
    	  		closwedangvec(comb1) = 2*pi - thetas;
   			end

   			xwedge = [corners(edgecorners(comb2,1),:);corners(edgecorners(comb2,2),:)];
   			nvec1   = planenvecs( planesatedge(comb2,1),: );
   			xsou   = thirdpoint(comb2,:);
   			[slask,thetas,slask] = EDB1coordtrans1(xsou,xwedge,nvec1);
   			if thetas == 0
    	  		closwedangvec(comb2) = 0;
   			else
    	  		closwedangvec(comb2) = 2*pi - thetas;
   			end

		end   % if closwedangvec(comb1) == 0 | 

	end		% for ii = 1:nduplicates
end

if nplanes < 256
    planesatedge = uint8(planesatedge);
elseif nplanes < 65535
    planesatedge = uint16(planesatedge);
else
    planesatedge = uint32(planesatedge);
end

%-------------------------------------------------------------------
% Find which edges each plane is connected to

if SHOWTEXT >= 4
	disp('         find edgesatplane')
end

edgesatplane = zeros(nplanes,double(max(ncornersperplanevec)));

for ii= 1:nplanes
	iv = find(planesatedge==ii);
	iv = iv - floor((iv-1)/nedges)*nedges;
	if ~isempty(iv)
		edgesatplane(ii,1:length(iv)) = iv.';
	end
end

% Check how many edges are defined for each plane. There must be at
% least three edges per plane.

tempnedgesperplanevec = sum(edgesatplane.'~=0).';

iv = find(tempnedgesperplanevec<3);

if ~isempty(iv)
    
    disp(' ')
    if SHOWTEXT >= 4
        for ii = 1:length(iv)
            disp(['         Plane ',int2str(iv(ii)),' has only ',int2str(tempnedgesperplanevec(iv(ii))),' edges connected to it'])        
        end
        error(['ERROR: The planes above have less than three edges.'])
    else
        error(['ERROR: Some planes have less than three edges. Set SHOWTEXT >= 4 to see a list of those planes.'])
    end
        
end



%-------------------------------------------------------------------
% Make a special list of thin planes

planeisthin = zerosvec1;
rearsideplane = zerosvec1;

iv = find(closwedangvec==0);
if ~isempty(iv)
	planenumberlist = planesatedge(iv,1);
	planeisthin(planenumberlist) = planeisthin(planenumberlist) + 1;
	rearsideplane(planenumberlist) = planesatedge(iv,2);
end

iv = find(closwedangvec == 0 & planesatedge(:,2)~=0);
if ~isempty(iv)
	planenumberlist = planesatedge(iv,2);
	planeisthin(planenumberlist)   = planeisthin(planenumberlist) + 1;		
	rearsideplane(planenumberlist) = planesatedge(iv,1); 
end

planeisthin = sign(planeisthin);
listofthinplanes = find(planeisthin);

%---------------------------------------------------------------
% Closwedangvec should be calculated into nyvec

nyvec = pi./(2*pi - closwedangvec);
integerny = ( abs(nyvec - round(nyvec)) < 1e-10 );

%-----------------------------------------------------------
% Construct some other useful edge variables

if difforder >= 1
	edgestartcoords      = zerosvec5;
	edgestartcoordsnudge = zerosvec5;
	edgeendcoords        = zerosvec5;
	edgeendcoordsnudge   = zerosvec5;
	edgemidcoords        = zerosvec5;
	edgenvecs            = zerosvec5;
	
    edgestartcoords = [corners(edgecorners(:,1),:)];
	edgeendcoords   = [corners(edgecorners(:,2),:)];
	edgemidcoords   = (edgestartcoords+edgeendcoords)/2;
	edgenvecs       = planenvecs(planesatedge(:,1),:);

    edgenormvecs = edgeendcoords - edgestartcoords;
    
	edgestartcoordsnudge = edgestartcoords + 1e-10*edgenormvecs;
	edgeendcoordsnudge   = edgeendcoords   - 1e-10*edgenormvecs;

    edgelengthvec = sqrt(sum( ((edgenormvecs).^2).' )).';
	edgenormvecs = edgenormvecs./edgelengthvec(:,ones(1,3));

else
    edgestartcoords = [];
    edgeendcoords = [];
    edgenvecs = [];
    edgelengthvec = [];
end


%---------------------------------------------------------------
%
%		BACK TO SOME PURE PLANE RELATED PARAMETERS
%
%---------------------------------------------------------------
%
% First, make a list of which planes that are absorbing/non-reflective

planeisabsorbing = zerosvec1;

listofactiveplanes = find(reflfactors~=0);
listofabsorbingplanes = find(reflfactors == 0);
planeisabsorbing(listofabsorbingplanes) = ones(size(listofabsorbingplanes));

%---------------------------------------------------------------
% Help variables: planealignedwplane and planeconnectstoplane
%
% Preparatory for the check of which planes see which plane: check
% if any planes are aligned with each other. If two planes are aligned
% then planealignedwplane = 1 for that combination.
% However, if two planes are back-to back (thin planes), then
% planealignedwplane = 2 for that combination.
%
% Also make a matrix of which planes connect to which planes and via
% which edges.

planealignedwplane = zerosvec2;

% First, check which planes are aligned with each other

for ii = 1:nplanes-1
	if planeisabsorbing(ii) ~= 1
		oneplaneeq = planeeqs(ii,:);
		diffvec1 = oneplaneeq(ones(nplanes-ii,1),:) - planeeqs(ii+1:nplanes,:);
		diffvec2 = oneplaneeq(ones(nplanes-ii,1),:) + planeeqs(ii+1:nplanes,:);
		diffvec = min( [sum( diffvec1.'.^2 ).'   sum( diffvec2.'.^2 ).'].' ).';
		alignedplanes = find(diffvec < geomacc) + ii;
		if ~isempty(alignedplanes)
			planealignedwplane(alignedplanes,ii) = int8(double(planealignedwplane(alignedplanes,ii)) + double((planeisabsorbing(alignedplanes)~=1))); 
		end	
	end
end

planealignedwplane = (sparse(sign(double(planealignedwplane) + double(planealignedwplane).')));

% Second, check which planes are back to back

if ~isempty(listofthinplanes)
	for ii = 1:length(listofthinplanes)
		plane = listofthinplanes(ii);
		rearplane = rearsideplane(plane);
		if planeisabsorbing(plane) ~= 1 & planeisabsorbing(rearplane) ~= 1
			planealignedwplane(plane,rearplane) = 2;
			planealignedwplane(rearplane,plane) = 2;
		end
	end
end

planeconnectstoplane = zerosvec2;
clear zerosvec2

for ii = 1:nplanes
	if planeisabsorbing(ii) ~= 1
		edgelist = edgesatplane(ii,:);
 		edgelist = edgesatplane(ii,1:double(ncornersperplanevec(ii)));
		ivec = planesatedge(edgelist,:);
		ivec = reshape(ivec.',length(edgelist)*2,1);
		ivec = ivec(find(ivec~=ii));
		okplanes = find(planeisabsorbing(ivec)~=1);
		ivec = ivec(okplanes);
		if ~isempty(ivec)
			planeconnectstoplane(ii,ivec) = edgelist(okplanes);
		end
	end
end

%---------------------------------------------------------------
%
%			planeseesplane
%
%---------------------------------------------------------------
% Check which planes see which planes:
% 1. If one of the planes has reflfactors = 0, then the two can't see each other.
% 2. Reflective planes that are aligned with each other can not reach each other
% 3. Reflective planes that are not aligned but have the same normal vectors
%    can not reach each other
% 4. Planes that have all its corners behind another plane can not be seen by that plane.
%
% planeseesplane = 0 means that either, one of the planes is non-reflective or, that
%					 two planes never can see each other, but they are not aligned with each other.
% planeseesplane = 1 means that two reflective planes might see each other, but there could
%                    be obstructions
% planeseesplane = -1 means that two reflective planes are aligned (but they are not back-to-back)
%					  and thus they can never see each other.
% planeseesplane = -2 means that two reflective planes are back-to-back with each other and thus
%					  they can never see each other.

if SHOWTEXT >= 4
	disp('         Check which planes see which planes')
end

% First an auxilliary matrix which can be used for edgeseesplane later:
% cornerinfrontofplane, size [nplanes,ncorners]
% Values are the same as given by EDB1infrontofplane:
%   1 means that a point is in front of the plane
%   0 means that a point is aligned with a plane
%   -1 means that a point is behind a plane
% All corners that belong to a plane will have the value 0.

% Corner number is given by the col no.
if ncorners < 256
    cornernumb = uint8([1:ncorners]);
elseif ncorners < 65536
    cornernumb = uint16([1:ncorners]);
else
    cornernumb = uint32([1:ncorners]);        
end

% Plane numbers is given by the row no.
if nplanes < 256
    planenumb = uint8([1:nplanes].');
elseif nplanes < 65536
    planenumb = uint16([1:nplanes].');
else
    planenumb = uint32([1:nplanes].');
end

cornerinfrontofplane = int8(EDB1infrontofplane(corners,planenvecs,planecorners,[],cornernumb,planenumb));
clear planenumb cornernumb
cornerinfrontofplane = reshape(cornerinfrontofplane,nplanes,ncorners);

planeseesplane = int8(ones(nplanes,nplanes));

% 1. If one of the planes has reflfactors = 0, then the two can't see each other.

if ~isempty(listofabsorbingplanes)
	zerosvec = zeros(length(listofabsorbingplanes),nplanes);
	planeseesplane(listofabsorbingplanes,:) = zerosvec;
	planeseesplane(:,listofabsorbingplanes) = zerosvec.';
end

% 2. Reflective planes that are aligned with each other can not reach each other

ivec = find( planealignedwplane == 1);
if ~isempty(ivec)
	planeseesplane(ivec) = - 1*ones(size(ivec));
end

ivec = find( planealignedwplane == 2);
if ~isempty(ivec)
	planeseesplane(ivec) = - 2*ones(size(ivec));
end

% 3. Reflective planes that have the same normal vectors can not reach each other

numvec = [1:nplanes];
for ii = 1:nplanes
	if planeisabsorbing(ii) ~= 1
		nvec1 = planenvecs(ii,:);
		ivec = find(planealignedwplane(ii,:)==0 & planeisabsorbing.'==0 & numvec>ii);
		if ~isempty(ivec)
			similarvec = abs( nvec1(ones(length(ivec),1),:) - planenvecs(ivec,:)) < geomacc;	
			similarvec = prod(  double(similarvec.') ).';
			ivec2 = ivec(find(similarvec==1));
			if ~isempty(ivec2)
				zerosvec = zeros(size(ivec2));
				planeseesplane(ii,ivec2) = zerosvec;	
				planeseesplane(ivec2,ii) = zerosvec.';
			end		
		end
	end
end

% 3.5 A plane does not see itself

iv = [0:nplanes-1]*nplanes + [1:nplanes];
planeseesplane(iv) = zeros(size(iv));

% 4. Planes that have all its corners behind another plane can not be seen by that plane.
%    First, we construct a list referring to the complete matrix of size [nplanes,nplanes]
%    The index vector is called iv. Then we find which combinations that
%    could be cleared. After having cleared a number of combinations (in
%    iv, fromplanenumb and toplanenumb) we pick out out only the non-zero
%    indices in iv.

if nplanes*nplanes < 128
    iv = int8([1:nplanes*nplanes].');                
elseif nplanes*nplanes < 32768
    iv = int16([1:nplanes*nplanes].');                
else
    iv = int32([1:nplanes*nplanes].');                
end
iv = reshape(iv,nplanes,nplanes);

% If there are any absorbing planes, we zero all plane-to-plane
% combinations that involve such a plane

if ~isempty(listofabsorbingplanes)
    nabsorbingplanes = length(listofabsorbingplanes);
    iv(listofabsorbingplanes,:) = zeros(nabsorbingplanes,nplanes);
    iv(:,listofabsorbingplanes) = zeros(nplanes,nabsorbingplanes);
end

% Check connecting planes first: if two planes are connected and their
% shared edge has a closwedangvec > pi, then the two planes can see each
% other. So, we can zero the plane-pair combinations where closwedangvec
% <= pi but larger than zero.

edgecombstozero = find(closwedangvec<=pi & closwedangvec > 0);
if ~isempty(edgecombstozero)
    ivzerocombs = (double(planesatedge(edgecombstozero,1))-1)*nplanes + double(planesatedge(edgecombstozero,2));
    iv(ivzerocombs) = zeros(size(ivzerocombs));
    ivzerocombs = (double(planesatedge(edgecombstozero,2))-1)*nplanes + double(planesatedge(edgecombstozero,1));
    iv(ivzerocombs) = zeros(size(ivzerocombs));
end

% Now we should keep only the index numbers in iv that are still non-zero
% We also take the chance to zero planeseesplane for the combinations that
% could be cleared.
ivclear = uint32(find(iv==0));
planeseesplane(ivclear) = zeros(size(ivclear));
iv(ivclear) = [];

% Of the remaining plane-to-plane combinations, we pick out the ones 
% for which we need to check if the "to-plane" is in front of the "from-plane"
iv = iv(find(planeseesplane(iv)==1 & planeconnectstoplane(iv)==0));

% We create full matrices, fromplanenumb and toplanenumb, and then keep
% only the combinations that remain in iv
% to keep fromplanenumb and toplanenumb aligned with iv.

% To-plane numbers is given by the row no.
if nplanes < 256
    toplanenumb = uint8([1:nplanes].');
elseif nplanes < 65536
    toplanenumb = uint16([1:nplanes].');
else
    toplanenumb = uint32([1:nplanes].');
end
toplanenumb = reshape(toplanenumb(:,ones(1,nplanes)),nplanes*nplanes,1);
toplanenumb = toplanenumb(iv);

% From-plane numbers is given by the col no.
if nplanes < 256
    fromplanenumb = uint8([1:nplanes]);
elseif nplanes < 65536
    fromplanenumb = uint16([1:nplanes]);
else
    fromplanenumb = uint32([1:nplanes]);
end
fromplanenumb = reshape(fromplanenumb(ones(nplanes,1),:),nplanes*nplanes,1);
fromplanenumb = fromplanenumb(iv);

% Now, if a plane has *all* its corners behind another plane, those two
% planes can not see each other.
% We check the corners of the "to-plane" (columns) and check if they are in front of
% the "from-plane" (rows).
% The ivreftocoplamatrix is the index number to the
% cornerinfrontofplanematrix, which has the size [nplanes,ncorners].
% NB! In order to save some space, we don't construct the ivreftocoplamatrix specifically.

% First we check the first 3 corners since all planes have at least 3
% corners.

% Plane corner 1
cornersbehind = cornerinfrontofplane(double(fromplanenumb) + ( double(planecorners( toplanenumb,1 ))-1 )*nplanes)<1;

% Plane corner 2
cornersbehind = cornersbehind &(cornerinfrontofplane(double(fromplanenumb) + ( double(planecorners( toplanenumb,2 ))-1 )*nplanes) < 1);

% Plane corner 3
cornersbehind = cornersbehind &(cornerinfrontofplane(double(fromplanenumb) + ( double(planecorners( toplanenumb,3 ))-1 )*nplanes) < 1);

if minncornersperplane == 4 & maxncornersperplane == 4
%   Plane corner 4
    cornersbehind = cornersbehind &(cornerinfrontofplane(double(fromplanenumb) + ( double(planecorners( toplanenumb,4 ))-1 )*nplanes) < 1);
elseif not(minncornersperplane == 3 & maxncornersperplane == 3)
    ivall = uint32([1:length(fromplanenumb)].');
    if minncornersperplane == 3
        iv3cornerplanes = find(ncornersperplanevec(toplanenumb)==3);
        ivall(iv3cornerplanes) = [];
    end
    if maxncornersperplane == 4
% Plane corner 4
        cornersbehind(ivall) = cornersbehind(ivall) &(cornerinfrontofplane(double(fromplanenumb(ivall)) + ( double(planecorners( toplanenumb(ivall),4 ))-1 )*nplanes) < 1);
    else
        ivmorethan4 = find(ncornersperplanevec(toplanenumb(ivall))>4);
        temp = ivall(ivmorethan4);
        ivall(ivmorethan4) = [];
        ivmorethan4 = temp;
        cornersbehind(ivall) = cornersbehind(ivall) &(cornerinfrontofplane(double(fromplanenumb(ivall)) + ( double(planecorners( toplanenumb(ivall),4 ))-1 )*nplanes) < 1);
        for ii = 5:maxncornersperplane
            ivselection = find(ncornersperplanevec(toplanenumb(ivmorethan4))>=ii);
            cornersbehind(ivmorethan4(ivselection)) = cornersbehind(ivmorethan4(ivselection)) &(cornerinfrontofplane(double(fromplanenumb(ivmorethan4(ivselection))) + ( double(planecorners( toplanenumb(ivmorethan4(ivselection)),ii ))-1 )*nplanes) < 1);
        end
        clear ivselection
    end
end
clear toplanenumb fromplanenumb

ivclear = iv(find(cornersbehind==1));
clear iv

planeseesplane(ivclear) = zeros(size(ivclear));
clear ivclear

temp1 = (planeseesplane~=0);
temp2 = (planeseesplane.'~=0);
planeseesplane = int8(double(planeseesplane).*(temp1.*temp2));

% New addition:
% If the user has asked for it, check plane-mid-point to plane-mid-point
% for obstruction. If there are obstructions, set planeseesplane to 0 for
% that combination.

if planeseesplanestrategy == 1
	ivorig = uint32(find(planeseesplane==1));
    iv = ivorig;
	fromplane = ceil(double(iv)/nplanes);
	toplane = uint16(double(iv) - (fromplane-1)*nplanes);
    fromplane = uint16(fromplane);
	listofplanesthatcanobscure = find( sum(planeseesplane==1) );

    iv4planes = find(ncornersperplanevec == 4);
    planemidpoints = zeros(nplanes,3);
    
    if any(ncornersperplanevec~=4)
        disp('WARNING: planeseesplanestrategy 1 not implemented for models with non-4-corner planes')
        planeseesplanestrategy = 0;
    else
        xvalues = corners(planecorners.',1);
        xvalues = reshape(xvalues,4,length(xvalues)/4);
        yvalues = corners(planecorners.',2);
        yvalues = reshape(yvalues,4,length(yvalues)/4);
        zvalues = corners(planecorners.',3);
        zvalues = reshape(zvalues,4,length(zvalues)/4);
        planemidpoints = [mean(xvalues).' mean(yvalues).' mean(zvalues).'];
    end
end

if planeseesplanestrategy == 1
	for ii = listofplanesthatcanobscure
        planeobsc = ii;
        ivcheckvis1 = uint32( planeobsc + (double(fromplane)-1)*nplanes);
        ivcheckvis2 = uint32( planeobsc + (double(toplane)-1)*nplanes);        
        iv3 = find(toplane~=planeobsc & fromplane~=planeobsc & ((planeseesplane(ivcheckvis1) == 1) | (planeseesplane(ivcheckvis2) == 1)) & (planeseesplane(ivcheckvis1) >= 0) & (planeseesplane(ivcheckvis2) >= 0) );
        tempcanplaneobstruct = zerosvec1.';
        tempcanplaneobstruct(planeobsc) = 1;
        [nonobstructedpaths,nobstructions,edgehits,cornerhits] = EDB1checkobstrpaths(planemidpoints(fromplane(iv3),:),planemidpoints(toplane(iv3),:),[],[],tempcanplaneobstruct,planeseesplane,...
            planeeqs,planenvecs,minvals,maxvals,planecorners,corners,ncornersperplanevec,rearsideplane);
        if length(iv3) > length(nonobstructedpaths)
            iv3(nonobstructedpaths) = [];
            iv(iv3) = [];
	        toplane(iv3) = [];
	        fromplane(iv3) = [];
        end
	end
    planeseesplane(ivorig) = 0;    
    planeseesplane(iv) = 1;    
    clear iv ivorig toplane fromplane ivcheckvis ivcheckvis2
end

%---------------------------------------------------------------
%
%		EDGE RELATED PARAMETERS AGAIN
%
%---------------------------------------------------------------
%
% Which edges should be switched off?
% (1) Go through the list edgecorners. If any edge contains one of the
%     corners, whose numbers are in switchoffcorners, then that edge should be
%     stored in the list offedges.
% (2) If an edge has an integer ny-value, then it should be switched off.
% (3) If one of the two connecting planes has reflfactors = 0, then it should
%     be switched off.

% disp('   switching off possibly unwanted edges...')

offedges = zerosvec3;

% (1) Go through the list edgecorners. If any edge contains one of the
%     corners, whose numbers are in switchoffcorners, then that edge should be
%     stored in the list offedges.

if ~isempty(switchoffcorners)
	for ii = 1:nedges
	   corner1 = edgecorners(ii,1);
	   corner2 = edgecorners(ii,2);
	   remove = sum( corner1 == switchoffcorners ) + sum( corner2 == switchoffcorners );
	   offedges(ii) = sign(remove);
	end
end

% (2) If an edge has an integer ny-value, then it should be switched off.

offedges = offedges + integerny;

% (3) If one of the two connecting planes has reflfactors = 0, then it should
%     be switched off.

reflectingedges = reshape(reflfactors(planesatedge),nedges,2);
reflectingedges = reflectingedges(:,1).*reflectingedges(:,2);
offedges = offedges + (1-reflectingedges);

offedges = find(offedges ~= 0);

%--------------------------------------------------------------------------------
%
%			edgeseesplane
%
%--------------------------------------------------------------------------------
%
% Now check which planes each edge can see. 
%    1. Set all combinations with reflfactors = 0 to -3
%    2. Switch off all combinations with offedges
% 	 3. For all edges that are aligned with a plane, set edgeseesplane to:
%			-1 if the edge doesn't belong to the plane
%			-2 if the edge does belong to the plane
%    4. If at least one edge end point is in front of a plane, then the
%       plane is potentially visible (edgeseesplane = 1)
%    5. If at least one corner point is in front of:
%           *one* of the two edge planes, when closwedang < pi
%           *both* edge planes, when closwedangvec > pi

if SHOWTEXT >= 4
	disp('         Check which edges see which planes')
end

edgeseesplane = int8(ones(nplanes,nedges));

% % % 20120414 PS: Why has this first stage been shut off? CHECK
%    1. Set all edges belonging to planes with reflfactors = 0 to
%    edgeseesplane = -3.

% % if ~isempty(listofabsorbingplanes)
% % 	edgeseesplane(listofabsorbingplanes,:) = -3*ones(length(listofabsorbingplanes),nedges);
% % end

%    2. Switch off all combinations with offedges

if ~isempty(offedges)
	edgeseesplane(:,offedges) = zeros(nplanes,length(offedges));
end

% 	3.  For all edges that belong to a plane, set edgeseesplane to -2
%    	Also, for all other edges that are aligned with a plane, set
%    	edgeseesplane to -1

edgelist = [1:nedges].';
edgelist(offedges) = [];

plane1list = planesatedge(edgelist,1); 
plane2list = planesatedge(edgelist,2); 
indexvec = uint32( double(plane1list) + (edgelist-1)*nplanes);
edgeseesplane(indexvec) = -2*(reflfactors(plane1list)~=0);
indexvec = uint32( double(plane2list) + (edgelist-1)*nplanes);
edgeseesplane(indexvec) = -2*(reflfactors(plane2list)~=0);

for ii = 1:length(edgelist)

	aligners1 = find(planealignedwplane(:,plane1list(ii))==1);
	if ~isempty(aligners1)
		edgeseesplane(aligners1,edgelist(ii)) = -1*ones(size(aligners1));
	end

	aligners2 = find(planealignedwplane(:,plane2list(ii))==1);
	if ~isempty(aligners2)
		edgeseesplane(aligners2,edgelist(ii)) = -1*ones(size(aligners2));
	end

end

%    4. If at least one edge end point is in front of a plane, then the
%       plane is potentially visible.
%       Do this for all plane-edge combinations for which edgeseesplane = 1
%       up til now.
%    5. If at least one corner point is in front of:
%           *one* of the two edge planes, when closwedang < pi
%           *both* edge planes, when closwedangvec > pi

ntot = nplanes*nedges;
ivclear = find(edgeseesplane~=1);
% Edge number is given by the col no.
if nedges < 256
    edgenumb = uint8([1:nedges]);
elseif nedges < 65536
    edgenumb = uint16([1:nedges]);
else
    edgenumb = uint32([1:nedges]);        
end
edgenumb = reshape(edgenumb(ones(nplanes,1),:),nplanes*nedges,1);
edgenumb(ivclear) = [];
% Plane numbers is given by the row no.
if nplanes < 256
    planenumb = uint8([1:nplanes].');
elseif nplanes < 65536
    planenumb = uint16([1:nplanes].');
else
    planenumb = uint32([1:nplanes].');
end
planenumb = reshape(planenumb(:,ones(1,nedges)),nplanes*nedges,1);
planenumb(ivclear) = [];

if nplanes*nedges < 128
    iv = int8([1:nplanes*nedges].');                
elseif nplanes*nedges < 32768
    iv = int16([1:nplanes*nedges].');                
else
    iv = int32([1:nplanes*nedges].');                
end
iv(ivclear) = [];

if ~isempty(edgenumb)
	% For the "edgecorners in front of plane"-test
	% we can use the cornerinfrontofplane matrix, but we need to construct
	% index vectors, based on the planenumb and edgenumb values.
	
	edgeinfrontofplane =                      cornerinfrontofplane( double(planenumb) + ( double( edgecorners(edgenumb,1) )-1 )*nplanes );
	edgeinfrontofplane = (edgeinfrontofplane==1) | (cornerinfrontofplane( double(planenumb) + ( double( edgecorners(edgenumb,2) )-1 )*nplanes )==1);
	edgeseesplane(iv) = int8(double(edgeseesplane(iv)).*double(edgeinfrontofplane)); 
	clear edgeinfrontofplane
end

if ~isempty(edgenumb)
	% For the "planecorners in front of edge-plane"-test
	% we can use the cornerinfrontofplane matrix, but we need to construct
	% index vectors, based on the planenumb and edgenumb values.
	%
	% First we split up the iv into two halves: the one with edges < pi and the
	% one with edges > pi;
	
	ivsmaller = uint32(find(closwedangvec(edgenumb)<pi));
	ivlarger = uint32([1:length(edgenumb)].');
	ivlarger(ivsmaller) = [];

    if ~isempty(ivsmaller)
		% First the edges smaller than pi (closwedang < pi): at least one plane corner needs
		% to be in front of one or the other plane.
		% Plane corner 1
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),1)  ) + ( double(planecorners( planenumb(ivsmaller),1 ))-1 )*nplanes;
		planecornerinfrontofedge =                            cornerinfrontofplane(ivreftocoplamatrix)==1;
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),2)  ) + ( double(planecorners( planenumb(ivsmaller),1 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		% Plane corner 2
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),1)  ) + ( double(planecorners( planenumb(ivsmaller),2 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),2)  ) + ( double(planecorners( planenumb(ivsmaller),2 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		% Plane corner 3
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),1)  ) + ( double(planecorners( planenumb(ivsmaller),3 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),2)  ) + ( double(planecorners( planenumb(ivsmaller),3 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		
		if minncornersperplane == 4 & maxncornersperplane == 4
            % Plane corner 4
			ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),1)  ) + ( double(planecorners( planenumb(ivsmaller),4 ))-1 )*nplanes;
			planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
			ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller),2)  ) + ( double(planecorners( planenumb(ivsmaller),4 ))-1 )*nplanes;
			planecornerinfrontofedge = planecornerinfrontofedge | (cornerinfrontofplane(ivreftocoplamatrix)==1);
		elseif not(minncornersperplane == 3 & maxncornersperplane == 3)
            ivall = uint32(1:length(ivsmaller));
            if minncornersperplane == 3
                iv3cornerplanes = find(ncornersperplanevec(planenumb(ivsmaller))==3);
                ivall(iv3cornerplanes) = [];
            end
            if maxncornersperplane == 4
                % Plane corner 4
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivall)),1)  ) + ( double(planecorners( planenumb(ivsmaller(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivall)),2)  ) + ( double(planecorners( planenumb(ivsmaller(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
            else
                ivmorethan4 = find(ncornersperplanevec(planenumb(ivsmaller(ivall)))>4);
                temp = ivall(ivmorethan4);
                ivall(ivmorethan4) = [];
                ivmorethan4 = temp;
                % Plane corner 4
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivall)),1)  ) + ( double(planecorners( planenumb(ivsmaller(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivall)),2)  ) + ( double(planecorners( planenumb(ivsmaller(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
                for ii = 5:maxncornersperplane
                    % Plane corner 5,6,7,etc
                    ivselection = find(ncornersperplanevec(planenumb(ivsmaller(ivmorethan4)))>=ii);
					ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivmorethan4)),1)  ) + ( double(planecorners( planenumb(ivsmaller(ivmorethan4)),4 ))-1 )*nplanes;
					planecornerinfrontofedge(ivmorethan4) = planecornerinfrontofedge(ivmorethan4) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
					ivreftocoplamatrix = double(  planesatedge(edgenumb(ivsmaller(ivmorethan4)),2)  ) + ( double(planecorners( planenumb(ivsmaller(ivmorethan4)),4 ))-1 )*nplanes;
					planecornerinfrontofedge(ivmorethan4) = planecornerinfrontofedge(ivmorethan4) | (cornerinfrontofplane(ivreftocoplamatrix)==1);
                end
                clear ivselection
            end
		end
		clear ivreftocoplamatrix
		
		ivclear = ivsmaller(find(planecornerinfrontofedge==0));
		edgeseesplane(iv(ivclear)) = 0;
    end
    
    if ~isempty(ivlarger)
		% Second the edges larger than pi (closwedang > pi): at least one plane corner needs
		% to be in front of *both* edge planes.
		% Plane corner 1
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),1)  ) + ( double(planecorners( planenumb(ivlarger),1 ))-1 )*nplanes;
		planecornerinfrontofedge =                            cornerinfrontofplane(ivreftocoplamatrix)==1;
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),2)  ) + ( double(planecorners( planenumb(ivlarger),1 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge & (cornerinfrontofplane(ivreftocoplamatrix)==1);
		% Plane corner 2
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),1)  ) + ( double(planecorners( planenumb(ivlarger),2 ))-1 )*nplanes;
		temp =                                                cornerinfrontofplane(ivreftocoplamatrix)==1;
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),2)  ) + ( double(planecorners( planenumb(ivlarger),2 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
		% Plane corner 3
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),1)  ) + ( double(planecorners( planenumb(ivlarger),3 ))-1 )*nplanes;
		temp =                                                cornerinfrontofplane(ivreftocoplamatrix)==1;
		ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),2)  ) + ( double(planecorners( planenumb(ivlarger),3 ))-1 )*nplanes;
		planecornerinfrontofedge = planecornerinfrontofedge | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
		
		if minncornersperplane == 4 & maxncornersperplane == 4
            % Plane corner 4
			ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),1)  ) + ( double(planecorners( planenumb(ivlarger),4 ))-1 )*nplanes;
			temp =                                                cornerinfrontofplane(ivreftocoplamatrix)==1;
			ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger),2)  ) + ( double(planecorners( planenumb(ivlarger),4 ))-1 )*nplanes;
			planecornerinfrontofedge = planecornerinfrontofedge | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
		elseif not(minncornersperplane == 3 & maxncornersperplane == 3)
            ivall = uint32(1:length(ivlarger));
            if minncornersperplane == 3
                iv3cornerplanes = find(ncornersperplanevec(planenumb(ivlarger))==3);
                ivall(iv3cornerplanes) = [];
            end
            if maxncornersperplane == 4
                % Plane corner 4
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivall)),1)  ) + ( double(planecorners( planenumb(ivlarger(ivall)),4 ))-1 )*nplanes;
				temp =                                                              cornerinfrontofplane(ivreftocoplamatrix)==1;
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivall)),2)  ) + ( double(planecorners( planenumb(ivlarger(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
            else
                ivmorethan4 = find(ncornersperplanevec(planenumb(ivlarger(ivall)))>4);
                temp = ivall(ivmorethan4);
                ivall(ivmorethan4) = [];
                ivmorethan4 = temp;
              % Plane corner 4
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivall)),1)  ) + ( double(planecorners( planenumb(ivlarger(ivall)),4 ))-1 )*nplanes;
				temp =                                                              cornerinfrontofplane(ivreftocoplamatrix)==1;
				ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivall)),2)  ) + ( double(planecorners( planenumb(ivlarger(ivall)),4 ))-1 )*nplanes;
				planecornerinfrontofedge(ivall) = planecornerinfrontofedge(ivall) | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
                for ii = 5:maxncornersperplane
                    % Plane corner 5,6,7,etc
                    ivselection = find(ncornersperplanevec(planenumb(ivlarger(ivmorethan4)))>=ii);
					ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivmorethan4)),1)  ) + ( double(planecorners( planenumb(ivlarger(ivmorethan4)),4 ))-1 )*nplanes;
					temp =                                                          cornerinfrontofplane(ivreftocoplamatrix)==1;
					ivreftocoplamatrix = double(  planesatedge(edgenumb(ivlarger(ivmorethan4)),2)  ) + ( double(planecorners( planenumb(ivlarger(ivmorethan4)),4 ))-1 )*nplanes;
					planecornerinfrontofedge(ivmorethan4) = planecornerinfrontofedge(ivmorethan4) | (temp & (cornerinfrontofplane(ivreftocoplamatrix)==1));
                end
                clear ivselection
            end
		end
		
		ivclear = ivlarger(find(planecornerinfrontofedge==0));
		edgeseesplane(iv(ivclear)) = 0;
    end
end

clear ivlarger ivsmaller ivreftocoplamatrix edgenumb planenumb iv

%----------------------------------------------------------------------------
%
%           indentingedgepairs
%
%--------------------------------------------------------------------------------
%
% If there are any planes with indents, make a list of all consecutive edge pairs that
% form an indent, because such edge pairs could never see each other.

indentingedgepairs = [];

if any(planehasindents)
    iv = find(indentingcorners);
    indentingedgepairs = zeros(length(iv),2);
    indentingplanenumbers = mod(iv,nplanes);
    ivzeros = find(indentingplanenumbers==0);
    if ~isempty(ivzeros)
       indentingplanenumbers(ivzeros) = nplanes; 
    end
    conumbers = (iv - indentingplanenumbers)/nplanes+1;
    
    % We expand planecorners temporarily, cyclically
    planecorners = [planecorners planecorners(:,1:2)];
    
    for ii = 1:length(iv)
        edge1cornerpair = sort(planecorners(indentingplanenumbers(ii),conumbers(ii):conumbers(ii)+1));
        edge2cornerpair = sort(planecorners(indentingplanenumbers(ii),conumbers(ii)+1:conumbers(ii)+2));
        
        [slask,edge1] = ismember(edge1cornerpair,edgecorners,'rows');
        [slask,edge2] = ismember(edge2cornerpair,edgecorners,'rows');
        
        edgepair = sort([edge1 edge2]);
        indentingedgepairs(ii,:) = edgepair;
    
    end
    
    % Remove the temporary expansion
    
    planecorners = planecorners(:,1:size(planecorners,2)-2);
end

%----------------------------------------------------------------------------
%
%           canplaneobstruct
%
%--------------------------------------------------------------------------------
%
% Check which planes that are potentially obstructing:
%
% If **all** closwedangvec are < pi and we have an exterior problem =>
%   the scatterer is without indents.
%   
% If **all** closwedangvec are > pi and we have an interior problem =>
%   the room is without any indents so there can be no obstructions.
%
% For exterior problems, all active planes can potentially obstruct.
%
% If these simple checks give a results that conflict with the input
% parameters open_or_closed_model or int_or_ext_model, give an
% error message.

canplaneobstruct = [];
if sum(closwedangvec<pi) == 0
    if SHOWTEXT >= 2
        disp(' ')
        disp('   The model is an interior problem, and the room has no indents')
        disp('   so no obstruction tests will be necessary.')
    end
    if int_or_ext_model == 'e'
        disp( 'ERROR: In the setup file this model was defined as an exterior problem, but it is clearly an interior problem.')
        error('       Please check the orientation of the planes.')    
    end
    canplaneobstruct = zeros(1,nplanes);
elseif sum(closwedangvec>0) == 0
    if SHOWTEXT >= 2
        disp(' ')
        disp('   The model is an exterior problem (scattering)')
        disp('   with only thin planes.')
    end
    if int_or_ext_model == 'i'
        disp( 'ERROR: In the setup file this model was defined as an interior problem, but it is clearly an exterior problem.')
        error('       Please check the orientation of the planes.')    
    end
    canplaneobstruct = ones(1,nplanes);
elseif sum(closwedangvec>pi) == 0
    if SHOWTEXT >= 2
        disp(' ')
        disp('   The model is an exterior problem (scattering)')
        disp('   and the scatterer has no indents.')
    end
    if int_or_ext_model == 'i'
        disp( 'ERROR: In the setup file this model was defined as an interior problem, but it is clearly an exterior problem.')
        error('       Please check the orientation of the planes.')    
    end
    canplaneobstruct = ones(1,nplanes);
end

% For an interior problem we know for sure that if a plane 
% has all other points in front of itself, it can not obstruct.
% NB! We need to check only points that do not belong to planes
% that are aligned with the plane, or planes that are non-active.

if int_or_ext_model == 'e'
    canplaneobstruct = (reflfactors.'~=0);
elseif isempty(canplaneobstruct)
    
    canplaneobstruct = (reflfactors.'~=0);
    maskvec1 = canplaneobstruct.';
    listofactiveplanes = find(canplaneobstruct);
    zerosvec = zeros(nplanes,1);
    
    for ii = 1:length(listofactiveplanes)
        iplane = listofactiveplanes(ii);
        maskvec2 = zerosvec;
        maskvec2(iplane) = 1;
        otherplanestocheck = find((double(planeseesplane(:,iplane))+maskvec2)~=1 & planeseesplane(:,iplane)~=-1 & maskvec1~=0);
        if ~isempty(otherplanestocheck),        
            cornerstocheck = unique(planecorners(otherplanestocheck,:));
            cornerstocheck = setdiff(unique(cornerstocheck),planecorners(iplane,1:ncornersperplanevec(iplane)));
            pointinfront = EDB1infrontofplane(corners(cornerstocheck,:),planenvecs(iplane,:),corners(planecorners(iplane,1),:),corners(planecorners(iplane,2),:));
            if isempty(find(pointinfront==-1))
                canplaneobstruct(iplane) = 0;    
            end
        else
            canplaneobstruct(iplane) = 0;    
        end
        
    end
end

%---------------------------------------------------------------
% For each thin plane, make sure that all edges have the same normal
% vector. If not, switch the direction of that edge, and all the other
% relevant parameters.

if difforder >= 1
	ivthin = find(planeisthin);
	
	for ii = 1:length(ivthin)
        plane = ivthin(ii);
        if rearsideplane(plane) > plane
            edgelist = unique(edgesatplane(plane,1:nedgesperplanevec(plane)));
            iv = find(closwedangvec(edgelist,:)==0);
            if ~isempty(iv)
                edgelist = edgelist(iv);
                nedgestemp = length(edgelist);
                edgenveclist = edgenvecs(edgelist,:);
                refnvec = edgenveclist(1,:);
                nvecdiff = edgenveclist(2:nedgestemp,:) - refnvec(ones(nedgestemp-1,1),:);            
                nvecdiff = sum(abs(nvecdiff.')).';
                ivswitch = find(nvecdiff)+1;
                if ~isempty(ivswitch)
                    edgenumber = edgelist(ivswitch);
                    edgecorners(edgenumber,:)  = [edgecorners(edgenumber,2) edgecorners(edgenumber,1)];
                    planesatedge(edgenumber,:) = [planesatedge(edgenumber,2) planesatedge(edgenumber,1)];
                    edgenvecs(edgenumber,:) = -edgenvecs(edgenumber,:);
                    edgestartcoords(edgenumber,:) = corners(edgecorners(edgenumber,1),:);
                    edgeendcoords(edgenumber,:)   = corners(edgecorners(edgenumber,2),:);
                    tempvec = edgeendcoordsnudge(edgenumber,:);    
                    edgeendcoordsnudge(edgenumber,:) = edgestartcoordsnudge(edgenumber,:);
                    edgestartcoordsnudge(edgenumber,:) = tempvec;
                end
            end        
        end
        
	end
end

%----------------------------------------------------------------------------
%
%		SAVE THE VARIABLES
%
%----------------------------------------------------------------------------
%
% Also the variables from cadgeo??
% Yes: planeeqs planenvecs ncornersperplanevec planecorners corners
%      minvals maxvals

edgeseesplane = int8(edgeseesplane);
planeseesplane = int8(planeseesplane);

if ncorners < 256
    planecorners = uint8(planecorners);
elseif ncorners < 65536
    planecorners = uint16(planecorners);    
end   
planeisthin = uint8(planeisthin);

if max(ncornersperplanevec) <= 255
    ncornersperplanevec = uint8(ncornersperplanevec);
else
    ncornersperplanevec = uint16(ncornersperplanevec);
end

Varlist =        [ ' edgecorners planesatedge closwedangvec planehasindents indentingedgepairs'];
Varlist = [Varlist,' planeisthin planeseesplane rearsideplane edgeseesplane canplaneobstruct'];
Varlist = [Varlist,' corners planecorners  planeeqs planenvecs ncornersperplanevec cornerinfrontofplane'];
Varlist = [Varlist,' edgestartcoords edgeendcoords edgenvecs reflfactors edgesatplane edgelengthvec'];
Varlist = [Varlist,' minvals maxvals offedges '];
Varlist = [Varlist,'  int_or_ext_model'];
if difforder >= 1
    edgedata.edgestartcoordsnudge = edgestartcoordsnudge;
    edgedata.edgeendcoordsnudge = edgeendcoordsnudge;
    edgedata.edgenormvecs = edgenormvecs;    
    Varlist = [Varlist, '  edgedata '];    
end
eval(['save ',outputfile,Varlist])
