classdef GLOBALCONST
    % a list of constants
    
    % switches
    methods(Static=true)
        % debug signals
        function DBG_SET(dbsig)
            global dbsiglist__;
            if isempty(dbsiglist__)
                dbsiglist__{end+1}=dbsig;
            elseif ~GLOBALCONST.DBG_CHECK(dbsig)
                dbsiglist__{end+1}=dbsig;
            end
        end
        
        function DBG_UNSET(dbsig)
            global dbsiglist__;
            if ~isempty(dbsiglist__)
                mask = strcmpi(dbsig,dbsiglist__);
                if nnz(mask)
                    dbsiglist__ = dbsiglist__(~mask);
                end
            end
        end
        
        function val = DBG_CHECK(dbsig,warn)
            if nargin < 2
                warn = true;
            end
            
            val = false;
            global dbsiglist__;
            if ~isempty(dbsiglist__)
                mask = cellfun(@(x)isequal(dbsig,x),dbsiglist__);
                val = any(mask);
            end
            
            if val && ~isempty(warn)
                if islogical(warn)
                    str = sprintf('[%s] in effect',num2str(dbsig));
                else
                    str = sprintf('[%s] %s',num2str(dbsig),warn);
                end
                warning(str);
            end
        end
        
        function DBG_CLEAR
            global dbsiglist__;
            dbsiglist__ = {};
        end
        
        function val = DBG_LIST
            global dbsiglist__;
            val=dbsiglist__;
        end
        
        function SET_VAR(varname,val)
            global gcvals;
            gcvals.(varname) = val;
        end
        
        function val = GET_VAR(varname)
            global gcvals;
            hasfield = isfield(gcvals,varname);
            if hasfield
                val = gcvals.(varname);
            else
                % use default values
                switch varname
                    case GLOBALCONST.VARNAME_DATA_SUBDIR
                        val = GLOBALCONST.DATASUBDIR_JUNCTION_NOSYM; %default subdir
                    case GLOBALCONST.VARNAME_INSPECTDATA
                        gcvals.(varname) = SBSRINSPECTDATA;
                        val = gcvals.(varname);
                    case GLOBALCONST.VARNAME_ACCBYCOMP_MINCOVER
                        val = 0.7;
                end
            end
        end
        
        function CLEAR_VAR(varname)
            global gcvals
            if nargin < 1
                gcvals = [];
            elseif isfield(gcvals,varname)
                gcvals.(varname)=[];
            end
        end
        
        function SET_DATASUBDIR(subdir)
            GLOBALCONST.SET_VAR(GLOBALCONST.VARNAME_DATA_SUBDIR,subdir);
        end
        
        function SET_ACCBYCOMP_MINCOVER(val)
            GLOBALCONST.SET_VAR(GLOBALCONST.VARNAME_ACCBYCOMP_MINCOVER,val);
        end
        
        function val = ACCBYCOMP_MINCOVER
            val = GLOBALCONST.GET_VAR(GLOBALCONST.VARNAME_ACCBYCOMP_MINCOVER);
        end
        
        function val = VARNAME_ACCBYCOMP_MINCOVER
            % if this percent of a component's pixel has the correct label,
            % the component is correctly labeled
            val = 'accbycomp_mincover';
        end
        
        function val = VARNAME_DATA_SUBDIR
            % sketch data dir
            val = 'datasubdir';
        end
        
        function val = VARNAME_INSPECTDATA
            val = 'inspectdata';
        end
        
        function val = DATASUBDIR
            val = GLOBALCONST.GET_VAR(GLOBALCONST.VARNAME_DATA_SUBDIR);
        end
        
        function val = DATASUBDIR_JUNCTION_NOSYM
            val = 'data_junction_nosym';
        end
        
        function val = DATASUBDIR_JUNCTION
            val = 'data_junction';
        end
        
        function val = DATASUBDIR_AUTOVIEW
            val = 'data_junction_autoview';
        end
        
        function val = DATASUBDIR_AUTOVIEW_NOSYM
            val = 'data_jc_autoview_nosym';
        end
        
        function val = DATASUBDIR_MANUALVIEW_NOSYM_NDBOBJ(n)
            val = sprintf('data_jc_manualview_nosym_%d',n);
		end
        
		function val = PROXYSPACE_MAX_PIXLENGTH
            val = 60;
		end
		
		function val = NDIR
			val = 48;
		end
    end
    
    methods(Static=true)
        function val = KW_GEO_CYLINDER
            %this object/space is close to cylinder
            val = 'cylinder';
        end
        
        function val = KW_MARKER
            %this object is used as marker to indicate something else
            val = 'marker';
        end
        
        function val = KW_MESHMARKER
            %this object is used as a marker for component
            val = 'meshmarker';
		end
		
		function val = KW_MESHFEATURE_SYMPLANE
            val = 'symplane';
		end
		
		function val = KW_CONNPTS
            %splan obj used to represent connection points
            val = 'connpts';
        end
        
        function [vts,adjmat,edges] = STDBOX_OUTLINE
            %[vts,adjmat,edges] = STDBOX_OUTLINE
            vts = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1]';
            edges = [1 5;2 6;3 7;4 8;1 2;2 3;3 4;4 1;5 6;6 7;7 8;8 5]';
            adjmat = zeros(size(vts,2));
            idx = sub2ind(size(adjmat),edges(1,:),edges(2,:));
            adjmat(idx) = 1;
            adjmat = (adjmat + adjmat')>0;
        end
        
        function [vts,fcs] = STDBOX_MESH
            vts = [0 0 0;1 0 0;1 1 0;0 1 0;0 0 1;1 0 1;1 1 1;0 1 1]';
            fcs = [1 3 2;1 4 3;3 8 7;3 4 8;3 7 6;2 3 6;6 1 2;6 5 1;5 8 1;1 8 4;6 8 5;6 7 8]';
        end
        
        function val = N_ANGLES_SPLAN_ELEMENT_BASIS
            val = 1;
		end
		
		function val = CONNPTS_LB_RED
			val = 1;
		end
		
		function val = CONNPTS_LB_BLUE
			val = 2;
		end
    end
    
    % small inline functions, to eliminate function call overhead
    methods(Static=true)
        function val = FUNC_CPU2GPU
            val = inline('gsingle(x)','x');
        end
        
        function val = FUNC_FLIP_FOR_CONV
            val = inline('x(end:-1:1,end:-1:1,end:-1:1)','x');
        end
        
        function val = FUNC_STR_ANY_CONTAIN
            %             val = @(strlist,querystr)~cellfun('isempty',strfind(strlist,querystr));
            val = inline('~cellfun(''isempty'',strfind(strlist,querystr))','strlist','querystr');
        end
    end
    
    methods(Static=true)
        function val = DBCONFIGFILE
            val = 'function_modules\config.txt';
        end
        
        function val = FILE_RETRIEVAL_EXE
            val = 'function_modules/function_modules.exe';
        end
        
        function val = FILE_RETRIEVAL_CONFIG
            val = 'function_modules/config.txt';
        end
        
        function val = FILE_DATASET_CHAIR
            val = 'localdata/chairs';
        end
        
        function val = FILE_RETRIEVAL_DBFILE_CHAIR_ALLVIEW
            val = 'localdata/chairs.bin';
        end
        
        function val = FILE_RETRIEVAL_DBFILE_CHAIR_FIXVIEW
            val = 'localdata/chairs_fixview.bin';
        end
        
        function val = PLOT_MARKER_TYPES
            val = '+o*.xsd^v><ph';
        end
        
        function val = PLOT_COLOR_TYPES
            val = 'rgbcmyk';
        end
        
        function val = PLOT_COLOR_MARKER_LIST
            markertypes = GLOBALCONST.PLOT_MARKER_TYPES;
            colortypes = GLOBALCONST.PLOT_COLOR_TYPES;
            [xx yy] = ndgrid(1:length(colortypes),1:length(markertypes));
            
            mks=  markertypes(yy(:));
            cls = colortypes(xx(:));
            
            % iterate through colors and then marker
            val = [cls(:) mks(:)]';
        end
        
        function val = PLOT_DIFF_MARKER_LIST
            mktypes = GLOBALCONST.PLOT_MARKER_TYPES;
            cltypes = GLOBALCONST.PLOT_COLOR_TYPES;
            lens = min(length(mktypes),length(cltypes));
            mk1 = cat(1,mktypes(1:lens),cltypes(1:lens));
            mk2 = cat(1,fliplr(mktypes(1:lens)),cltypes(1:lens));
            val = cat(2,mk1,mk2);
            val = flipud(val);
        end
        
        function val = THRES_SUBSTRUCTURE_FITSCORE
            val =2.5;
        end
        
        function val = RATIO_STDVAR_OF_LINK_GMDIST_TO_SKETCH_DIAG
            val = 0.1;
        end
        
        function val = WEIGHT_MATCH_CONTRIBUTION
            val = 0.7;
        end
        
        function val = DEFAULT_SKETCH_SIZE
            val = [320 320];
        end
        
        % generator graph type
        function val = GGTYPE_SKETCH
            val = 1;
        end
        
        function val = GGTYPE_GEOMETRY
            val = 2;
        end
        
        % shape context parameters
        function val = SCX_NDIST
            val = 4;
        end
        
        function val = SCX_NDIR
            val = 4;
        end
        
        function val = SCX_MAXDIST_TO_DIAG
            % maxdist/norm(size(img))
            val = 0.8;
        end
        
        function val = SCX_NLDIR
            % line direction context: number of directiosn
            val = 3;
        end
        
        % vote point clustering
        function val = VOTEPOINT_MINDIST_TO_DIAG
            % minimum pairwise distance of two vote points relative to the
            % diag of the AABB of sketch
            val = 0.1;
        end
        
        function val = THRES_SEGMENT_BDS_MINDIST
            % use this to extract boundary mask for sbsrsegment
            val = 0.1;
        end
        
        function val = THRES_COVERPTS_MAXANGLE
            val = pi/6;
        end
        
        function val = THRES_COVERPTS_MAXDIST_TO_DIAG
            val = 0.1;
        end
        
        function val = THRES_COVERPTS_MAXDIST_TO_GLOBAL_DIAG
            val = GLOBALCONST.THRES_COVERPTS_MAXDIST_TO_DIAG/2;
        end
        
        function val = THRES_NPIXSMOOTH_TO_DIAG
            val = 0.05;
        end
        
        function val = THRES_NCLUSTER_PIVOT_PER_SEG
            val = 20;
        end
        
        function val = THRES_COVERAGE_MIN
            % at least have this much coverage in order to be considered as
            % an ok match, this is for 3d segment
            val = 0.4;
        end
        
        function val = THRES_NCLUSTER_PIVOT_PER_LABEL
            val = 30;
        end
        
        function val = THRES_DISTMATEXP_MIN_AS_SOLID
            % when bwdist2_exp is larger than this, the point is
            % consdered 'solid'
            val = 0.95;
        end
        
        function val = THRES_CONFLICT_MIN_MOVMENTDIST_TO_DIAG
            % minimum allowed movement when evaluating edge conflict
            val = 0.1;
        end
        
        function val = THRES_MIN_STRUCTURE_SCORE_ACCEPTABLE
            % minimum acceptable structure score
            val = 0.01;
            %             val = 0.7;
        end
        
        function val = THRES_MAX_OVERLAP_COST_ACCEPTABLE
            % maximum acceptable overlap score
            val = 0.5;
        end
        
        function val = THRES_MIN_COVERAGE_TO_TERMINATE
            % terminate search when this coverage is reached
            val = 0.9;
        end
        
        function val = THRES_MIN_SYMSCORE_ACCEPTABLE
            val = 0.5;
        end
        
        function val = THRES_RELAX_OVERLAP_FOR_SYMMETRY
            val = 0.8;
        end
        
        % a segment should be covered at least this much for it to be
        % considered as "covered", this is for 2d segment
        function val = THRES_MIN_SEGMENT_COVER
            val = 0.5;
        end
        
        function val = DISABLED_LABELS
            val = [];
            val(end+1) = GLOBALCONST.CHAIR_SEATSUPPORT;
            val(end+1) = GLOBALCONST.CHAIR_APRON; %new
            val(end+1) = GLOBALCONST.TABLE_JOINT;
            val(end+1) = GLOBALCONST.TABLE_TOPSTRETCHER;
            val(end+1) = GLOBALCONST.TABLE_DRAWER; %new
        end
        
        % labels
        function val = CHAIR_BACK
            val = 10;
        end
        function val = CHAIR_STILE
            val = 101;
        end
        function val = CHAIR_LEG
            val = 11;
        end
        function val = CHAIR_LEGSUPPORT
            val = 111;
        end
        function val = CHAIR_BASE
            val = 112;
        end
        function val = CHAIR_FOOT
            val = 113;
        end
        function val = CHAIR_STRETCHER
            val = 114;
        end
        function val = CHAIR_SEAT
            val = 12;
        end
        function val = CHAIR_SEATSUPPORT
            val = 121;
        end
        function val = CHAIR_APRON
            val = 122;
        end
        function val = CHAIR_ARM
            val = 13;
        end
        function val = CHAIR_SPINDLE
            val = 123;
        end
        function val = CHAIR_RAIL
            val = 124;
        end
        function val = AIRPLANE_BODY
            val = 20;
        end
        function val = AIRPLANE_WING
            val = 21;
        end
        function val = AIRPLANE_HORISTAB
            val = 22;
        end
        function val = AIRPLANE_VERTSTAB
            val = 23;
        end
        function val = AIRPLANE_ENGINE
            val = 24;
        end
        function val = AIRPLANE_PROPELLER
            val = 25;
        end
        function val = AIRPLANE_TAIL
            val = 26;
        end
        
        function val = TABLE_TOP
            val = 31;
        end
        function val = TABLE_DRAWER
            val = 32;
        end
        function val = TABLE_LEG
            val = 33;
        end
        function val = TABLE_STRETCHER
            val = 34;
        end
        function val = TABLE_BASE
            val = 35;
        end
        function val = TABLE_JOINT
            val = 36;
        end
        function val = TABLE_TOPSUPPORT
            val = 37;
        end
        function val = TABLE_LEGSUPPORT
            val = 38;
        end
        function val = TABLE_TOPSTRETCHER
            val = 39;
        end
        function val = TABLE_MIDSUPPORT
            val = 70;
        end
        
        function val = BICYCLE_SADDLE
            val = 40;
        end
        function val = BICYCLE_FRONTFRAME
            val = 41;
        end
        function val = BICYCLE_WHEEL
            val = 42;
        end
        function val = BICYCLE_HANDLE
            val = 43;
        end
        function val = BICYCLE_PEDAL
            val = 44;
        end
        function val = BICYCLE_CHAIN
            val = 45;
        end
        function val = BICYCLE_FORK
            val = 46;
        end
        function val = BICYCLE_BACKFRAME
            val = 47;
        end
        function val = BICYCLE_SUPPORT
            val = 48;
        end
        function val = BICYCLE_BACKCOVER
            val = 49;
        end
        
        function val = CANDELABRA_BASE
            val = 80;
        end
        function val = CANDELABRA_CANDLE
            val = 81;
        end
        function val = CANDELABRA_FIRE
            val = 82;
        end
        function val = CANDELABRA_HANDLE
            val = 83;
        end
        function val = CANDELABRA_SHAFT
            val = 84;
        end
        function val = CANDELABRA_ARM
            val = 85;
        end
        
        function val = FOURLEG_BODY
            val = 91;
        end
        function val = FOURLEG_EAR
            val = 92;
        end
        function val = FOURLEG_HEAD
            val = 93;
        end
        function val = FOURLEG_LEG
            val = 94;
        end
        function val = FOURLEG_TAIL
            val = 95;
        end
        
        function val = GOBLET_BASE
            val = 131;
        end
        function val = GOBLET_SUPPORT
            val = 132;
        end
        function val = GOBLET_CUP
            val = 133;
        end
        
        function val = GUITAR_NECK
            val = 141;
        end
        function val = GUITAR_HEADSTOCK
            val = 142;
        end
        function val = GUITAR_BODY
            val = 143;
        end
        
        function val = IRON_HANDLE
            val = 151;
        end
        function val = IRON_BASE
            val = 152;
        end
        function val = IRON_SOLEPLATE
            val = 153;
        end
        
        function val = LAMP_TUBE
            val = 161;
        end
        function val = LAMP_BASE
            val = 162;
        end
        function val = LAMP_SHADE
            val = 163;
        end
        
        function val = VASE_LIP
            val = 171;
        end
        function val = VASE_HANDLE
            val = 172;
        end
        function val = VASE_BODY
            val = 173;
        end
        function val = VASE_FOOT
            val = 174;
        end
        
        function val = HUMAN_HEAD
            val = 181;
        end
        function val = HUMAN_BODY
            val = 182;
        end
        function val = HUMAN_UPPERARM
            val = 183;
        end
        function val = HUMAN_LOWERARM
            val = 184;
        end
        function val = HUMAN_UPPERLEG
            val = 185;
        end
        function val = HUMAN_LOWERLEG
            val = 186;
        end
        function val = HUMAN_HAND
            val = 187;
        end
        function val = HUMAN_FOOT
            val = 188;
        end
        
        function val = RIFLE_BARREL
            val = 190;
        end
        function val = RIFLE_BODY
            val = 191;
        end
        function val = RIFLE_HANDGRIP
            val = 192;
        end
        function val = RIFLE_MAGAZINE
            val = 193;
        end
        function val = RIFLE_TRIGGER
            val = 194;
        end
        function val = RIFLE_BUTT
            val = 195;
        end
        function val = RIFLE_SIGHT
            val = 196;
        end
        
        function val = UNKNOWNLABEL
            val = 0;
        end
        
        function val = LABEL_CATEGORIES
            val = {'chair','airplane','table','bicycle',...
                'candelabra','fourleg','goblet','guitar',...
                'iron','lamp','vase','human',...
                'rifle'};
        end
        function val = LABEL_CATEGORIES_USE
            val = {'chair','airplane','table','bicycle',...
                'fourleg','lamp','vase','human','candelabra','rifle'};
        end
        
        function val = LABEL_MARKERS
            % val(:,i) = [label,marker], for example, [CHAIR_SEAT,'r+'].
            
            lbs2marker = zeros(2,GLOBALCONST.LABEL_MAXVAL);
            objtypelist = GLOBALCONST.LABEL_CATEGORIES;
            for i=1:length(objtypelist)
                objtype = objtypelist{i};
                lbs_thistype = util_get_label_set_by_name(objtype);
                mklist = GLOBALCONST.PLOT_DIFF_MARKER_LIST;
                lbs2marker(:,lbs_thistype) = mklist(:,1:length(lbs_thistype));
            end
            
            for i=1:size(lbs2marker,2)
                switch i
                    % lamp class
                    case GLOBALCONST.LAMP_BASE
                        mk = 'rh';
                    case GLOBALCONST.LAMP_SHADE
                        mk = 'bo';
                    case GLOBALCONST.LAMP_TUBE
                        mk = 'm+';
                    
                    % table class
                    case GLOBALCONST.TABLE_BASE
                        mk = 'mx';
                    case GLOBALCONST.TABLE_LEG
                        mk = 'bo';
                    case GLOBALCONST.TABLE_LEGSUPPORT
                        mk = 'gh';
                    case GLOBALCONST.TABLE_MIDSUPPORT
                        mk = 'c*';
                    case GLOBALCONST.TABLE_STRETCHER
                        mk = 'gs';
                    case GLOBALCONST.TABLE_TOP
                        mk = 'r+';
                    case GLOBALCONST.TABLE_TOPSUPPORT
                        mk = 'ro';
                        
                    % chair class
                    case GLOBALCONST.CHAIR_ARM
                        mk = 'gh';
                    case GLOBALCONST.CHAIR_BACK
                        mk = 'mx';
                    case GLOBALCONST.CHAIR_BASE
                        mk = 'b+';
                    case GLOBALCONST.CHAIR_FOOT
                        mk = 'mo';
                    case GLOBALCONST.CHAIR_LEG
                        mk = 'bo';
                    case GLOBALCONST.CHAIR_LEGSUPPORT
                        mk = 'c*';
                    case GLOBALCONST.CHAIR_RAIL
                        mk = 'bd';
                    case GLOBALCONST.CHAIR_SEAT
                        mk = 'r+';
                    case GLOBALCONST.CHAIR_SPINDLE
                        mk = 'rs';
                    case GLOBALCONST.CHAIR_STILE
                        mk = 'bp';
                    case GLOBALCONST.CHAIR_STRETCHER
                        mk = 'cv';
                    otherwise
                        continue;
                end
                lbs2marker(:,i) = mk;
            end
            
            % each label must already has a marker, so this returns all
            % labels
            lbs = find(lbs2marker(2,:));
            mks = lbs2marker(:,lbs);
            val = [lbs(:)';mks];
        end
        
        function val = LABEL_MAXVAL
            %the label that has max value
            names = GLOBALCONST.LABEL_CATEGORIES;
            lbs = cellfun(@(x)util_get_label_set_by_name(x),names,'uniformoutput',false);
            lbs = cat(2,lbs{:});
            val = max(lbs);
        end
        function val = LABEL_MAXCOUNT
            % val(x) = number of components with label x can exist in a
            % structure
            lbs2maxcount = zeros(1,GLOBALCONST.LABEL_MAXVAL);
            lbs2maxcount(:) = inf;
            lbs2maxcount(GLOBALCONST.CHAIR_SEAT) = 1;
            lbs2maxcount(GLOBALCONST.CHAIR_BACK) = 1;
            lbs2maxcount(GLOBALCONST.TABLE_TOP) = 1;
            lbs2maxcount(GLOBALCONST.TABLE_TOPSTRETCHER) = 0;
            lbs2maxcount(GLOBALCONST.AIRPLANE_BODY) = 1;
            lbs2maxcount(GLOBALCONST.CHAIR_APRON) = 0; %misleading component
            
            lbs2maxcount(GLOBALCONST.BICYCLE_BACKFRAME) = 1;
            lbs2maxcount(GLOBALCONST.BICYCLE_FRONTFRAME) = 1;
            
            lbs2maxcount(GLOBALCONST.HUMAN_BODY) = 1;
            lbs2maxcount(GLOBALCONST.HUMAN_HEAD) = 1;
            lbs2maxcount(GLOBALCONST.HUMAN_FOOT) = 2;
            lbs2maxcount(GLOBALCONST.HUMAN_HAND) = 2;
            lbs2maxcount(GLOBALCONST.HUMAN_UPPERARM) = 4;
            lbs2maxcount(GLOBALCONST.HUMAN_UPPERLEG) = 4;
            
            lbs2maxcount(GLOBALCONST.VASE_BODY) = 1;
            lbs2maxcount(GLOBALCONST.VASE_FOOT) = 1;
            lbs2maxcount(GLOBALCONST.VASE_LIP) = 1;
            
            lbs2maxcount(GLOBALCONST.FOURLEG_BODY) = 1;
            lbs2maxcount(GLOBALCONST.FOURLEG_HEAD) = 1;
            lbs2maxcount(GLOBALCONST.FOURLEG_TAIL) = 1;
%             lbs2maxcount(GLOBALCONST.FOURLEG_LEG) = 4;

            lbs2maxcount(GLOBALCONST.CANDELABRA_BASE) = 1;
            
            lbs2maxcount(GLOBALCONST.RIFLE_BARREL) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_BODY) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_BUTT) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_HANDGRIP) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_MAGAZINE) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_SIGHT) = 1;
            lbs2maxcount(GLOBALCONST.RIFLE_TRIGGER) = 1;
            
            val = lbs2maxcount;
        end
        function val = LABEL_MINCOUNT
            % val(x) = number of components with label x must exist
            lbs2mincount = zeros(1,GLOBALCONST.LABEL_MAXVAL);
            lbs2mincount(:) = 0;
            lbs2mincount(GLOBALCONST.HUMAN_HEAD) = 1;
            lbs2mincount(GLOBALCONST.HUMAN_BODY) = 1;
            lbs2mincount(GLOBALCONST.HUMAN_UPPERARM) = 1;
            lbs2mincount(GLOBALCONST.HUMAN_UPPERLEG) = 1;
            
            lbs2mincount(GLOBALCONST.VASE_BODY) = 1;
            
            lbs2mincount(GLOBALCONST.FOURLEG_BODY) = 1;
            lbs2mincount(GLOBALCONST.FOURLEG_HEAD) = 1;
            
            lbs2mincount(GLOBALCONST.LAMP_BASE) = 1;
            lbs2mincount(GLOBALCONST.LAMP_SHADE) = 1;
            lbs2mincount(GLOBALCONST.LAMP_TUBE) = 1;
            
            lbs2mincount(GLOBALCONST.AIRPLANE_BODY) = 1;
            lbs2mincount(GLOBALCONST.AIRPLANE_WING) = 2;
            
            lbs2mincount(GLOBALCONST.BICYCLE_WHEEL) = 1;
            
            lbs2mincount(GLOBALCONST.CANDELABRA_BASE) = 1;
            
            lbs2mincount(GLOBALCONST.RIFLE_BARREL) = 1;
            lbs2mincount(GLOBALCONST.RIFLE_BODY) = 1;
            lbs2mincount(GLOBALCONST.RIFLE_TRIGGER) =1;
            
            val = lbs2mincount;
        end
        
        function [val,invalidmat] = LABELPAIR_INVALID_CONNECTION
            % forbid val(1,i) connects to val(2,i)
            % invalidmat(lb1,lb2) = 1 iff label lb1 and label lb2 are
            % forbidden to connect
            val = [GLOBALCONST.CHAIR_BASE,GLOBALCONST.CHAIR_BASE;...
                GLOBALCONST.CHAIR_APRON,GLOBALCONST.CHAIR_BACK;...
                GLOBALCONST.CHAIR_APRON,GLOBALCONST.CHAIR_SEAT;...
                GLOBALCONST.CHAIR_STRETCHER,GLOBALCONST.CHAIR_BACK;...
                GLOBALCONST.CHAIR_STRETCHER,GLOBALCONST.CHAIR_SEAT;...
                GLOBALCONST.AIRPLANE_HORISTAB,GLOBALCONST.AIRPLANE_HORISTAB;...
                GLOBALCONST.AIRPLANE_HORISTAB,GLOBALCONST.AIRPLANE_WING;...
                GLOBALCONST.AIRPLANE_ENGINE,GLOBALCONST.AIRPLANE_BODY;...
                GLOBALCONST.HUMAN_UPPERARM,GLOBALCONST.HUMAN_UPPERLEG;...
                GLOBALCONST.HUMAN_HEAD,GLOBALCONST.HUMAN_UPPERARM;...
                GLOBALCONST.FOURLEG_TAIL,GLOBALCONST.FOURLEG_LEG;...
                GLOBALCONST.FOURLEG_LEG,GLOBALCONST.FOURLEG_LEG;...
                GLOBALCONST.FOURLEG_BODY,GLOBALCONST.FOURLEG_EAR]';
            
            invalidmat = false(GLOBALCONST.LABEL_MAXVAL);
            idx = sub2ind(size(invalidmat),val(1,:),val(2,:));
            invalidmat(idx) = true;
            invalidmat = invalidmat | invalidmat';
        end
        function val = LABEL_REPLACE
            %val(:,i)=[lbfrom,lbto], replace lbfrom by lbto
            val = [GLOBALCONST.TABLE_TOPSTRETCHER,GLOBALCONST.TABLE_STRETCHER;
                   GLOBALCONST.HUMAN_LOWERARM,GLOBALCONST.HUMAN_UPPERARM;
                   GLOBALCONST.HUMAN_LOWERLEG,GLOBALCONST.HUMAN_UPPERLEG]';
        end
        function val = LABEL_SNAPPABLE
            % these elements allow snapping connection points to convex
            % curvature connpts
            val = [...
                GLOBALCONST.CHAIR_APRON,...
                GLOBALCONST.CHAIR_ARM,...
                GLOBALCONST.CHAIR_BASE,...
                GLOBALCONST.CHAIR_FOOT,...
                GLOBALCONST.CHAIR_LEG,...
                GLOBALCONST.CHAIR_LEGSUPPORT,...
                GLOBALCONST.CHAIR_STILE,...
                GLOBALCONST.CHAIR_STRETCHER,...
                GLOBALCONST.TABLE_LEG,...
                GLOBALCONST.TABLE_LEGSUPPORT,...
                GLOBALCONST.TABLE_STRETCHER,...
                GLOBALCONST.TABLE_TOPSTRETCHER,...
                GLOBALCONST.TABLE_TOPSUPPORT,...
                GLOBALCONST.LAMP_TUBE,...
                GLOBALCONST.VASE_HANDLE,...
                ];
        end
        function val = LABEL_SYMABLE
            % these types of components are allowed to have symmetric
            % component
            lbstosym = [GLOBALCONST.CHAIR_ARM,...
                GLOBALCONST.CHAIR_LEG,...
                GLOBALCONST.CHAIR_FOOT,...
                GLOBALCONST.CHAIR_STILE,...
                GLOBALCONST.TABLE_LEG,...
                GLOBALCONST.TABLE_LEGSUPPORT,...
                GLOBALCONST.AIRPLANE_HORISTAB,...
                GLOBALCONST.AIRPLANE_WING,...
                GLOBALCONST.AIRPLANE_ENGINE,...
                GLOBALCONST.VASE_HANDLE,...
                GLOBALCONST.CANDELABRA_ARM,...
                GLOBALCONST.CANDELABRA_HANDLE,...
                ];
            val = lbstosym;
        end
        function val = LABEL_SYMABLE_EXCLUDE
            % when in construction, ignore the symmetric of this kind of
            % component
            lbstoexclude = [GLOBALCONST.AIRPLANE_HORISTAB];
            val = lbstoexclude;
        end
        function val = LABEL_SYMABLE_IN_CONSTRUCTION
            % when in construction, only these labels are allowed to have
            % symmetric components
            val = setdiff(GLOBALCONST.LABEL_SYMABLE,GLOBALCONST.LABEL_SYMABLE_EXCLUDE);
        end
        function val = EXCLUDE_CONFUSING_SEG
            val = 1;
        end
        
        function WARN_MIRROR_REFLECTION_ASSUMED
            warning('sbsrwarn:mirror_reflection_assumed','Assuming mirror reflection');
        end
        
        function WARN_INTERNAL_HACK
            warning('sbsrwarn:internal_hack','Hacking internal members');
        end
        
        function val = LATEX_COMPILER_PATH
            pathlist = {
                    'D:/Program Files (x86)/MiKTeX 2.9/miktex/bin/pdflatex.exe',...
                    'D:/texlive/2013/bin/win32/pdflatex.exe',...
                    'D:/Program Files/MiKTeX 2.9/miktex/bin/x64/pdflatex.exe',...
                };
            maskok = cellfun(@(x)exist(x,'file')~=0,pathlist);
            val = pathlist(maskok);
            assert(~isempty(val),'no latex compiler');
            val = val{1};
        end
        
        function val = PICKAS(objtype)
            val = 'top3mip';
            if any(strcmpi(objtype,{'table','lamp','airplane'}))
                val = 'original';
            end
        end
        
        function val = SHEN_CPP_PATH
            val = 'shencompose/x64/Release/shencompose.exe';
        end
        
        function val = SHEN_MIN_FDSCORE
            % an element must have at least this fdscore to be selectable
            val = 0.45;
        end
        
        function val = SHEN_MAX_DIST_TO_DIAGLENS
            % the distance of the element to the closest element must be
            % less than val*diaglens
            val = 0.05;
        end
        
        function val = SHEN_MAX_OVERLAP
            val = 0.7;
        end
        
        function val = FONTNAME_LEGEND
            val = 'arial';
        end
        
        function val = DEFAULT_SPARSITY
            sparsity = zeros(1,max(GLOBALCONST.LABEL_MAXVAL));
            high_sparsity = 0.5;
            low_sparsity = 0.1;
            sparsity(:) = low_sparsity;
            sparsity(GLOBALCONST.CHAIR_LEG) = high_sparsity;
            sparsity(GLOBALCONST.CHAIR_STILE) = high_sparsity;
            sparsity(GLOBALCONST.CHAIR_STRETCHER) = high_sparsity;
            sparsity(GLOBALCONST.CHAIR_LEGSUPPORT) = high_sparsity;
            sparsity(GLOBALCONST.CHAIR_FOOT) = high_sparsity;
            sparsity(GLOBALCONST.TABLE_LEG) = high_sparsity;
            sparsity(GLOBALCONST.TABLE_LEGSUPPORT) = high_sparsity;
            sparsity(GLOBALCONST.TABLE_STRETCHER) = high_sparsity;
            val = sparsity;
		end
		
		function val = USE_3DSMAX_Z_ZUP_BY_DEFAULT
			% assuming x3d file is exported as Y-UP, and when reading into
			% matlab, automatically transform it into Z-UP.
			val = true;
		end
    end
end