function hm=plotmesh(node,varargin)
%
% hm=plotmesh(node,face,elem,opt)
%
% plot surface and volumetric meshes
%
% author: Qianqian Fang <q.fang at neu.edu>
%
% input:
% node: a node coordinate list, 3 columns for x/y/z; if node has a
% 4th column, it will be used to set the color at each node.
% face: a triangular surface face list; if face has a 4th column,
% it will be used to separate the surface into
% sub-surfaces and display them in different colors;
% face can be a cell array, each element of the array represents
% a polyhedral facet of the mesh, if an element is an array with
% two array subelements, the first one is the node index, the
% second one is a scalar as the group id of the facet.
% elem: a tetrahedral element list; if elem has a 5th column,
% it will be used to separate the mesh into
% sub-domains and display them in different colors.
% opt: additional options for the plotting
%
% for simple point plotting, opt can be markers
% or color options, such as 'r.', or opt can be
% a logic statement to select a subset of the mesh,
% such as 'x>0 & y+z<1', or an equation defining
% a plane at which a mesh cross-section is plotted, for
% example 'y=2*x'; opt can have more than one
% items to combine these options, for example:
% plotmesh(...,'x>0','r.'); the range selector must
% appear before the color/marker specifier
%
% in the event where all of the above inputs have extra settings related to
% the color of the plot, the priorities are given in the following order:
%
% opt > node(:,4) > elem(:,5) > face(:,4)
%
% output:
% hm: handle or handles (vector) to the plotted surfaces
%
% example:
%
% h=plotmesh(node,'r.');
% h=plotmesh(node,'x<20','r.');
% h=plotmesh(node,face);
% h=plotmesh(node,face,'y>10');
% h=plotmesh(node,face,'facecolor','r');
% h=plotmesh(node,elem,'x<20');
% h=plotmesh(node,elem,'x<20 & y>0');
% h=plotmesh(node,face,elem);
% h=plotmesh(node,face,elem,'linestyle','--');
% h=plotmesh(node,elem,'z=20');
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%
selector=[];
opt=[];
face=[];
elem=[];
if(nargin>1)
hasopt=0;
for i=1:length(varargin)
if(ischar(varargin{i}))
if(~isempty(regexp(varargin{i},'[x-zX-Z]')) && ~isempty(regexp(varargin{i},'[><=&|]')))
selector=varargin{i};
if(nargin>=i+1) opt=varargin(i+1:end); end
else
opt=varargin(i:end);
end
if(i==1)
face=[];elem=[];
elseif(i==2)
if(iscell(varargin{1}) || size(varargin{1},2)<4)
face=varargin{1}; elem=[];
elseif(size(varargin{1},2)==4)
faceid=unique(varargin{1}(:,4));
if(length(faceid)==1)
face=varargin{1}; elem=[];
elseif(any(hist(varargin{1}(:,4),unique(varargin{1}(:,4)))>50))
face=varargin{1}; elem=[];
else
elem=varargin{1}; face=[];
end
else
elem=varargin{1}; face=[];
end
elseif(i==3)
face=varargin{1};
elem=varargin{2};
end
hasopt=1;
break;
end
end
if(hasopt==0)
if(length(varargin)>=2)
face=varargin{1};
elem=varargin{2};
if(length(varargin)>2) opt=varargin(3:end); end
elseif(iscell(varargin{1}) || size(varargin{1},2)<4)
face=varargin{1}; elem=[];
elseif(size(varargin{1},2)==4)
faceid=unique(varargin{1}(:,4));
if(length(faceid)==1)
face=varargin{1}; elem=[];
elseif(any(hist(varargin{1}(:,4),unique(varargin{1}(:,4)))>50))
face=varargin{1}; elem=[];
else
elem=varargin{1}; face=[];
end
else
elem=varargin{1}; face=[];
end
end
end
holdstate=ishold;
if(~holdstate)
cla;
end
if(size(node,2)==4 && size(elem,2)==5)
warning(['You have specified the node colors by both the 4th ' ...
'and 5th columns of node and face inputs, respectively. ' ...
'The node input takes priority']);
end
if(isempty(face) && isempty(elem))
if(isempty(selector))
if(isempty(opt))
h=plot3(node(:,1),node(:,2),node(:,3),'o');
else
h=plot3(node(:,1),node(:,2),node(:,3),opt{:});
end
else
x=node(:,1);
y=node(:,2);
z=node(:,3);
idx=eval(['find(' selector ')']);
if(~isempty(idx))
if(isempty(opt))
h=plot3(node(idx,1),node(idx,2),node(idx,3),'o');
else
h=plot3(node(idx,1),node(idx,2),node(idx,3),opt{:});
end
else
warning('nothing to plot');
end
end
end
if(~isempty(face))
hold on;
if(isempty(selector))
if(isempty(opt))
h=plotsurf(node,face);
else
h=plotsurf(node,face,opt{:});
end
else
if(iscell(face))
cent=meshcentroid(node,face);
else
cent=meshcentroid(node,face(:,1:3));
end
x=cent(:,1);
y=cent(:,2);
z=cent(:,3);
idx=eval(['find(' selector ')']);
if(~isempty(idx))
if(iscell(face))
h=plotsurf(node,face(idx),opt{:});
else
h=plotsurf(node,face(idx,:),opt{:});
end
else
warning('no surface to plot');
end
end
end
if(~isempty(elem))
hold on;
if(isempty(selector))
if(isempty(opt))
h=plottetra(node,elem);
else
h=plottetra(node,elem,opt{:});
end
else
cent=meshcentroid(node,elem(:,1:4));
x=cent(:,1);
y=cent(:,2);
z=cent(:,3);
if(regexp(selector,'='))
if(size(node,2)==4)
[cutpos,cutvalue,facedata]=qmeshcut(elem,node(:,1:3),node(:,4),selector);
elseif(size(node,2)==3)
[cutpos,cutvalue,facedata]=qmeshcut(elem,node,node(:,3),selector);
else
error('plotmesh can only plot 3D tetrahedral meshes');
end
if(~isreal(cutvalue))
cutvalue=abs(cutvalue);
end
h=patch('Vertices',cutpos,'Faces',facedata,'FaceVertexCData',cutvalue,'facecolor','interp',opt{:});
else
idx=eval(['find(' selector ')']);
if(~isempty(idx))
if(isempty(opt))
h=plottetra(node,elem(idx,:));
else
h=plottetra(node,elem(idx,:),opt{:});
end
else
warning('no tetrahedral element to plot');
end
end
end
end
if(exist('h','var') && ~holdstate)
hold off;
end
if(exist('h','var'))
if(any(get(gca,'dataaspectratio')>1e8))
view(3);
end
axis equal;
end
if(exist('h','var') && nargout>=1)
hm=h;
end