Code covered by the BSD License  

Highlights from
Carving a Dinosaur

image thumbnail

Carving a Dinosaur

by

 

21 Dec 2009 (Updated )

This is a demo of reconstructing a 3D shape from multiple images using space-carving.

tmwMultiWaitbar( label, value, amnt )
function tmwMultiWaitbar( label, value, amnt )
%TMWMULTIWAITBAR: add, remove or update an entry on the multi waitbar
%
%   TMWMULTIWAITBAR(LABEL, VALUE) adds a waitbar for the specified label, or
%   if it already exists updates the value. LABEL must be a string and
%   VALUE a number between zero and one or the string 'Close' to remove the
%   entry Setting value equal to 0 or 'Reset' will cause the progress bar
%   to reset and the time estimate to be re-initialised. 
%
%   TMWMULTIWAITBAR(LABEL,'INCREMENT',AMNT) increments a progress bar by
%   AMNT instead of setting the value explicitly.
% 
%   TMWMULTIWAITBAR(LABEL,'COLOR',color) changes the color of the specified
%   waitbar.
%
%   Examples:
%   >> tmwMultiWaitbar( 'Task 1', 0 );
%   >> tmwMultiWaitbar( 'Task 2', 0 );
%   >> tmwMultiWaitbar( 'Task 1', 0.1 );
%   >> tmwMultiWaitbar( 'Task 2', 'Increment', 0.2 );
%   >> tmwMultiWaitbar( 'Task 2', 'Close' );
%   >> tmwMultiWaitbar( 'Task 1', 'Reset' );
%   >> tmwMultiWaitbae( 'Task 1', 'Color', 'green')
%   >> tmwMultiWaitbae( 'Task 1', 'Color', [1 0 0.5])

%   Copyright 2007-2008 The MathWorks, Inc.
%   $Revision: 33 $Date: 2007-10-17$


persistent on 

switch label
    case 'turn off'
        on = false;
        return
    case 'turn on'
        on = true;
        return
end
if ~isempty(on) && ~on
    return
end

if nargin<2
    error( 'tmwMultiWaitbar:BadSyntax', 'Usage: MULTIWAITBAR(LABEL,VALUE)' );
end

% Try to get hold of the figure
f = findall( 0, 'Type', 'figure', 'Tag', 'MultiProgress' );
if isempty(f)
    f = nCreateFig();
    set( f, 'ResizeFcn', @nRedraw );
else
    f = f(1);
end

% Get the list of entries and see if this one already exists
entries = getappdata( f, 'ProgressEntries' );
if isempty(entries)
    idx = [];
else
    idx = strmatch( label, {entries.label}, 'exact' );
end

% Now work out whether to add, update or remove
if ischar( value ) && ismember( upper(value), {'RESET','ZERO','SHOW'} )
    value = 0;
end
if ischar( value ) && ismember( upper(value), {'INC','INCREMENT'} )
    % Increment an existing value
    if isempty(idx)
        value = amnt;
    else
        value = entries(idx).value + amnt;
    end
end


if ischar( value ) && ismember( upper(value), {'COLOR','COLOUR'} )
    % Increment an existing value
    entries(idx).color = amnt;    
    iSetAppData( f, 'ProgressEntries', entries );
    nUpdateEntry(entries(idx),entries(idx).value);    
    nRedraw();
    return
end


if ischar( value ) && ismember( upper(value), {'DONE','CLOSE'} )
    if ~isempty(idx)
        % Remove the selected entry
        entries = nDeleteEntry( entries, idx );
    end
    if isempty( entries )
        close( f );
        drawnow();
    else
        setappdata( f, 'ProgressEntries', entries );
        nRedraw();
    end
else
    if isempty(idx)
        % Create a new entry
        entries = nAddEntry( entries, label, value );        
        setappdata( f, 'ProgressEntries', entries );
        nRedraw();
        nUpdateEntry(newentry,value);
    else
        % Update the selected entry
        entries(idx,:) = nUpdateEntry( entries(idx,:), value );
        iSetAppData( f, 'ProgressEntries', entries );
    end
end

%-------------------------------------------------------------------------%
    function iSetAppData( src, param, value )
        % Safely set application data into a handle
        if ishandle( src )
            setappdata( src, param, value );
        end
    end

%-------------------------------------------------------------------------%
    function nRedraw( src, evt ) %#ok<INUSD>
        entries = getappdata( f, 'ProgressEntries' );
        p = get( f, 'Position' );
        border = 5;
        textheight = 16;
        barheight = 16;
        panelheight = 10;

        % Check the height is correct
        heightperentry = textheight+barheight+panelheight;
        requiredheight = 2*border + numel(entries)*heightperentry - panelheight;
        if ~isequal( p(4), requiredheight )
            p(2) = p(2) + p(4) - requiredheight;
            p(4) = requiredheight;
            set( f, 'Position', p );
        end
        ypos = p(4) - border;
        width = p(3) - 2*border;
        for ii=1:numel(entries)
            set( entries(ii).labeltext, 'Position', [border ypos-textheight width*0.75 textheight] );
            set( entries(ii).etatext, 'Position', [border+width*0.75 ypos-textheight width*0.25 textheight] );
            ypos = ypos - textheight;
            set( entries(ii).axes, 'Position', [border ypos-barheight width barheight] );
            ypos = ypos - barheight;
            set( entries(ii).panel, 'Position', [-500 ypos-500-panelheight/2 p(3)+1000 500] );
            ypos = ypos - panelheight;
            N=numel(entries(ii).bar)-1;
            for k=1:N
                fade = 0.4;
                if ii == numel(entries)
                    color = entries(ii).color*(1-fade*(N-k)/(N-1));
                else
                    gray = [1,1,1] * mean(entries(ii).color);
                    color = gray*(1-fade*(N-k)/(N-1));
                end
                set(entries(ii).bar(k),'FaceColor',color);                
                set(entries(ii).bar(k),'EdgeColor',color);
            end
            set(entries(ii).bar(N+1),'FaceColor','none')
            set(entries(ii).bar(N+1),'EdgeColor',[0 0 0])
        end
        drawnow();
    end

%-------------------------------------------------------------------------%
    function entry = nUpdateEntry( entry, value )
        % Make sure it's within limits
        value = max(0,value);
        value = min(1,value);
        entry.value = value;
        N=numel(entry.bar)-1;
        colorWidthV = 0.4;
        colorWidthH = 0.01;
        for k=1:N
            
            if value < colorWidthH
                scaling = 0;
            else
                scaling = (k-1)/(N-1);
            end
            colorWidthV_ = colorWidthV*scaling;
            colorWidthH_ = colorWidthH*scaling;
            set( entry.bar(k), 'Position', [colorWidthH_ colorWidthV_ max(0.001,value-2*colorWidthH_) 1-2*colorWidthV_] );
        end
        set( entry.bar(N+1), 'Position', [0 0 max(0.001,value) 1] );
        
        set( entry.labeltext, 'String', sprintf( '%s (%d%%)', entry.label, round(value*100) ) );


        if value <= 0
            % Zero value, so clear the eta
            entry.created = now();
            eta = '';
        else
            elapsedtime = now() - entry.created; % in days by default

            % Only show the remaining time if we've had time to estimate
            if elapsedtime < (5/(60*60*24)) % 5 secs
                % Not enough time has passed since starting, so leave blank
                eta = '';
            else
                % Calculate a rough ETA
                remainingtime = elapsedtime * (1-entry.value) / entry.value;

                if remainingtime > 2
                    eta = sprintf( '%d days', round(remainingtime) );
                else
                    remainingtime = remainingtime * 24; % Convert to hours
                    if remainingtime > 2
                        eta = sprintf( '%d hours', round(remainingtime) );
                    else
                        remainingtime = remainingtime * 60; % Convert to minutes
                        if remainingtime > 2
                            eta = sprintf( '%d mins', round(remainingtime) );
                        else
                            remainingtime = round(remainingtime * 60); % Convert to seconds
                            if remainingtime > 1
                                eta = sprintf( '%d secs', remainingtime );
                            elseif remainingtime == 1
                                eta = '1 sec';
                            else
                                eta = ''; % Nearly done (<1sec)
                            end
                        end
                    end
                end
            end
        end
        set( entry.etatext, 'String', eta );
        drawnow('expose');
    end

%-------------------------------------------------------------------------%
    function entries = nAddEntry( entries, label, value )
        labeltext = uicontrol( 'Style', 'Text', ...
            'String', sprintf( '%s (%d%%)', label, round(value*100) ), ...
            'Parent', f, ...
            'HorizontalAlignment', 'Left' );
        etatext = uicontrol( 'Style', 'Text', ...
            'String', '', ...
            'Parent', f, ...
            'HorizontalAlignment', 'Right' );
        myaxes = axes( ...
            'Units', 'Pixels', ...
            'XLim', [0 1], 'YLim', [0 1], ...
            'XTick', [], 'YTick', [], ...
            'Box', 'on', ...
            'HandleVisibility', 'off', ...
            'Parent', f );
        mypanel = uipanel( 'Parent', f, 'Units', 'Pixels' );
        mybar = zeros(10,1);
        for k=1:10
        mybar(k) = rectangle( 'Parent', myaxes, ...
            'FaceColor', [1 0 0], ...
            'EdgeColor', 0.5*[1 0 0], ...
            'Position', [0 0 max(0.001,value), 1] );
        end
        newentry = struct( ...
            'label', label, ...
            'value', value, ...
            'created', now(), ...
            'labeltext', labeltext, ...
            'etatext', etatext, ...
            'axes', myaxes, ...
            'panel', mypanel, ...
            'bar', mybar, ...
            'color', [1 0 0]);
        if isempty( entries )
            entries = newentry;
        else
            entries = [entries;newentry];
        end       
    end % nAddEntry

%-------------------------------------------------------------------------%
    function entries = nDeleteEntry( entries, idx )
        delete( entries(idx).labeltext );
        delete( entries(idx).etatext );
        delete( entries(idx).axes );
        delete( entries(idx).panel );
        entries(idx,:) = [];
    end % nDeleteEntry

%-------------------------------------------------------------------------%
    function f = nCreateFig()
        f = figure( ...
            'Name', 'Progress', ...
            'Tag', 'MultiProgress', ...
            'Color', get(0,'DefaultUIControlBackgroundColor'), ...
            'MenuBar', 'none', ...
            'ToolBar', 'none', ...
            'NumberTitle', 'off', ...
            'HandleVisibility', 'callback' );
        % Resize
        p = get( f, 'Position' );
        p(3:4) = [450 50];
        set( f, 'Position', p);
        setappdata( f, 'ProgressEntries', [] );
    end % nCreateFig

%-------------------------------------------------------------------------%
end% EOF

Contact us