www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/xregsurfaceb.m

    function [h, h2] = xregsurfaceb(varargin)
%XREGSURFACEB Create surface clipped by a boundary.
%
%  XREGSURFACEB(X,Y,Z,B,C) is analogous to SURFACE(X,Y,Z,C) except that the
%  surface is formed from patches and is clipped to the region where
%  B <= 0.
%  XREGSURFACEB(X,Y,Z,B) uses C = Z, so color is proportional to surface
%  height.
%  XREGSURFACEB(Z,B) and XREGSURFACEB(Z,B,C) use X = 1:M and Y = 1:N where
%  [M,N] = SIZE(Z).
%  XREGSURFACEB(...,'DisplayExterior', 'on') creates an additional patch
%  that shows the area outside the boundary and is colored with the
%  standard MBC boundary color.  The additional patch has HandleVisibility
%  set to off and is linked to the main one to ensure that it is destroyed
%  and set invisible when the main patch is destroyed or set invisible.
%  XREGSURFACEB(...,'Patch', H) specifies a handle to a patch to use for the
%  surface.  This allows reuse of a single patch object.
%
%  XREGSURFACEB returns a handle to a PATCH object.
%
%  The arguments to XREGSURFACEB can be followed by parameter/value pairs to
%  specify additional properties of the patch.
%
%  See also SURFACE, PATCH.

%  Copyright 2000-2014 The MathWorks, Inc. and Ford Global Technologies, Inc.


narginchk(2,Inf);

firstChar = find( cellfun( 'isclass', varargin, 'char' ), 1);
if isempty( firstChar ),
    firstChar = nargin + 1;
    patchArgs = {};
else 
    patchArgs = varargin(firstChar:end);
end

switch firstChar
    case 3
        % XREGSURFACEB(Z,B,<parameter>,<value>,...)
        z = varargin{1};
        b = varargin{2};
        c = z;
        [m, n] = size( z );
        x = 1:m;
        y = 1:n;
    case 4
        % XREGSURFACEB(Z,B,C,<parameter>,<value>,...)
        z = varargin{1};
        b = varargin{2};
        c = varargin{3};
        [m, n] = size( z );
        x = 1:m;
        y = 1:n;
    case 5
        % XREGSURFACEB(X,Y,Z,B,<parameter>,<value>,...)
        x = varargin{1};
        y = varargin{2};
        z = varargin{3};
        b = varargin{4};
        c = z;
    case 6
        % XREGSURFACEB(X,Y,Z,B,C,<parameter>,<value>,...)
        x = varargin{1};
        y = varargin{2};
        z = varargin{3};
        b = varargin{4};
        c = varargin{5};
    otherwise
        error(message('mbc:xregsurfaceb:InvalidArgument'));
end

% Check for additional args that are not patch properties
plotExterior = false;
h = [];
if ~isempty(patchArgs)
    patchIdx = 1;
    while patchIdx<length(patchArgs)
        switch patchArgs{patchIdx}
            case 'DisplayExterior'
                plotExterior = strcmpi(patchArgs{patchIdx+1}, 'on');
            case 'Patch'
                h = patchArgs{patchIdx+1};
            otherwise
                break
        end
        patchIdx = patchIdx+2;
    end
    patchArgs(1:patchIdx-1) = [];
end

if ~any( size( x ) == 1 )
    if x(2,1)==x(1,1)
        % Check for x being the wrong way round.
        x = x.';
        y = y.';
        z = z.';
        c = c.';
        b = b.';
    end

    % x is a matrix ==> want the first column
    x = x(:,1);
end
if ~any( size( y ) == 1 )
    % y is a matrix ==> want the first row
    y = y(1,:);
end


[insideFaces,outsideFaces,vertices,normals,colors] = mbcInOutTriangles(x,y,z,b,c);

% inside 
% draw patches
if isempty(h)
    h = patch( ...
        'Faces', insideFaces, ...
        'Vertices', vertices, ...
        'FaceVertexCData', colors, ...
        'VertexNormals', normals, ...
        patchArgs{:});
else
    set(h, 'Faces', insideFaces, ...
        'Vertices', vertices, ...
        'FaceVertexCData', colors, ...
        'VertexNormals', normals, ...
        patchArgs{:});
end


h = mbcgui.hgclassesutil.toHandle(h);
% Look for a secondary patch attached to the main one
if isprop(h, 'BoundaryExteriorHandle')
    h2 = get(h, 'BoundaryExteriorHandle');
else
    h2 = [];
    mbcgui.hgclassesutil.addprop(h, 'BoundaryExteriorHandle', 'Hidden', true);
end


if plotExterior
    if isempty(h2)
        h2 = patch( ...
        'Faces', outsideFaces, ...
        'Vertices', vertices, ...
        'FaceVertexCData', colors, ...
        'VertexNormals', normals, ...
        patchArgs{:}, ...
        'FaceColor', mbcbdrycolor, ...
        'HandleVisibility', 'off');
    else
        set(h2, 'Faces', outsideFaces, ...
        'Vertices', vertices, ...
        'FaceVertexCData', colors, ...
        'VertexNormals', normals, ...
        patchArgs{:}, ...
        'FaceColor', mbcbdrycolor, ...
        'HandleVisibility', 'off');
    end
    set(h,'BoundaryExteriorHandle', h2);
    L = { ...
        mbcgui.hgclassesutil.listener(h, 'ObjectBeingDestroyed', @i_killbdry), ...
        mbcgui.hgclassesutil.proplistener(h, 'Visible', 'PostSet', @i_setbdryvis) ...
        };
    set(h2, 'UserData', L);
else
    if ~isempty(h2) && isgraphics(h2)
        delete(h2);
    end
    h.BoundaryExteriorHandle = [];
    h2 = [];
end
end



%Callbacks from linking a hidden exterior patch to an interior one
function i_killbdry(~, evt)
if isprop(evt,'AffectedObject')
    h= evt.AffectedObject;
else
    h = evt.Source;
end
hAx = get(h, 'Parent');
if ~mbcgui.util.isBeingDestroyed(hAx)
    delete(h.BoundaryExteriorHandle);
end
end

function i_setbdryvis(~, evt)
h = evt.AffectedObject;
set(h.BoundaryExteriorHandle, 'Visible', get(h, 'Visible'));
end



%