arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

TFBase.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     3-20-03
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2003 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 // TFBase.h
00019 
00020 // a base interface for transfer functions
00021 
00022 #ifndef __SIMIAN_TRANSFER_FUNCTION_BASE_DOT_H
00023 #define __SIMIAN_TRANSFER_FUNCTION_BASE_DOT_H
00024 
00025 #include <simBase/simBase.h>
00026 #include <volume/Volume.h>
00027 #include <smartptr.h>
00028 #include "TFParams.h"
00029 #include "TFElement.h"
00030 #include "TFImage.h"
00031 #include <nrro/nrro.h>
00032 
00033 
00034 //////////////////////////////////////////////////////////////////////////
00035 /// a generic ND transfer function.
00036 ///   Handles basic TFElement management and various TF generation 
00037 ///   methods.
00038 //////////////////////////////////////////////////////////////////////////
00039 class TFGeneric : public SimBase, public gutz::Counted {
00040 public:
00041    typedef STF::tfDomainType PosType;
00042    typedef STF::tfRangeType  ValType;
00043 
00044    TFGeneric();
00045    TFGeneric(VolumeSP vol);
00046    virtual ~TFGeneric();
00047 
00048    ///////////////////////////////////////////
00049    ///@name Evaluate 
00050    ///  Evaluate the transfer function at some arbitrary position
00051    ///@{
00052    virtual ValType eval(const PosType &tfpos);
00053    ///@}
00054 
00055    //////////////////////////////////////////////////////
00056    ///@name Domain
00057    ///@{
00058 
00059    ///////////////////////////////////////////
00060    /// dimension of transfer function domain
00061    /// how many axies does the transfer function have???
00062    virtual int sizeDomain() const  { return 0;}
00063    
00064    ///////////////////////////////////////////
00065    /// how many bins will discrete TF maps have?
00066    /// default is 256 for all TF domain axes.
00067    virtual PosType getDomainRes() const            {return _res;}
00068    /// notice that you are passing a gutz::vec, so you
00069    ///  can have a different number of bins for each axis
00070    virtual void    setDomainRes(const PosType &res){_res = res;}
00071    
00072    ///@}
00073    //////////////////////////////////////////////////////
00074 
00075 
00076    ///////////////////////////////////////////
00077    ///@name Range
00078    /// dimension of transfer function range,
00079    ///  ex. 4 is probably standard for RGBA output
00080    ///@{
00081    virtual int sizeRange() const   { return 0;} 
00082    ///@}
00083 
00084    ///////////////////////////////////////////
00085    ///@name Volume stuff
00086    ///@{
00087    virtual void     setVolume(VolumeSP v) { _vol = v;   }
00088    virtual VolumeSP getVolume() const     { return _vol;}
00089    ///@}
00090 
00091    ///////////////////////////////////////////
00092    ///@name Transfer function elements
00093    ///@{
00094    TFElementListSP  getTFElts() const               { return _elts; }
00095    void             setTFElts(TFElementListSP _tfe) { _elts = _tfe;}
00096    void             addTFElt(TFEltSP tfelt)         { _elts->push_back(tfelt); }
00097    void             addTFElement(TFElement *tfelt)  { addTFElt( TFEltSP(tfelt) ); }
00098    ///@}
00099 
00100    ///////////////////////////////////////////
00101    /// reimplemented from SimBase, needed since changes are dependent on
00102    /// sub-objects like TFElements
00103    virtual int   getChangeID();
00104 
00105    ////////////////////////////////////////////
00106    /// Generate a 2D tf image (map) from a pair 
00107    ///  of axies (axiesIdx) of the tfdomain ...
00108    ///  ... with some size, type, specific values in your choice of order,
00109    ///  ... and your choice of how many values (channels) it should have
00110    /// kind is from STF::TF_4MAP_KINDS
00111    /// type is from Nrro::NRRO_TYPES
00112    ////////////////////////////////////////////
00113    TFImageSP  get2DMap(
00114       gutz::vec2i axesIdx,                          /// idicies of domain axes
00115       const gutz::vec2i size = gutz::vec2i_neg_one, /// size of map
00116       int type = Nrro::UCHAR,                       /// what data type?
00117       int kind = STF::TF_RGBA);                     /// type of TFimage (which channels?)
00118 
00119 protected:
00120    ///////////////////////////////////////////
00121    /// update the transfer function, checks to see if any of the elements
00122    /// changed and updates if it needs to. You can call this whenever you
00123    /// want.
00124    virtual void     update();
00125 
00126    TFImageSP getImage(const gutz::vec2i &ai);
00127    void      setImage(const TFImageSP im);
00128 
00129    VolumeSP _vol;
00130    TFElementListSP _elts;
00131 
00132    PosType _res;
00133 
00134    /// cache generated tf images...
00135    TFImageSPMap _images;
00136 };
00137 
00138 typedef gutz::SmartPtr<TFGeneric> TFGenericSP;
00139 
00140 //////////////////////////////////////////////////////////////////////////
00141 //// a double indirection tf class so that you can dynamically change the 
00142 //// tf and those changes will be reflected everywhere,
00143 ////   holds an actual transfer function (one that implements the interface)
00144 ////   allows you access to that guy. Unfortunately, you shouldn't copy
00145 ////   this, you would have to make a specific sub class that knew what
00146 ////   kind of tf actually implemented the interface; ie. copy won't copy
00147 ////   the transfer function interface, just the pointer!!!
00148 ////
00149 //// If you use a transfer function somewhere use one of these and stay in
00150 //// synch with it, ie. assume it is volitle.  If you implement a new TF type
00151 //// implement the TFBaseIF, so that users can plug it into one of these
00152 //// DO NOT Subclass this guy, only the (user) interface!
00153 ////  TODO: should we rethink the name of this thing??? seems like we 
00154 ////    should be more expicit about the double indirection nature...
00155 ///////////////////////////////////////////////////////////////////////////
00156 class TFBaseSP : 
00157    public gutz::SmartPtrRef<TFGeneric>,
00158    public SimBase
00159 {
00160 public:
00161    typedef gutz::SmartPtrRef<TFGeneric> btype;
00162    
00163    TFBaseSP() 
00164       : btype(new TFGeneric()), 
00165       _lastChanged((*_ref)->getChangeID()) 
00166    {}
00167    
00168    TFBaseSP(VolumeSP vol) 
00169       : btype(new TFGeneric(vol)), 
00170       _lastChanged((*_ref)->getChangeID()) 
00171    {}
00172    
00173    TFBaseSP(TFGeneric *tf) 
00174       : btype(tf), 
00175       _lastChanged((*_ref)->getChangeID()) 
00176    {}
00177 
00178    ///we are not really a reference, we are a double indirection
00179    /// thingy, not really a pointer pointer, not really a ref either.
00180    /// this means that we have to copy the pointer inside the
00181    /// ref for copy and assignment so that changes are reflected
00182    /// everywhere.
00183    TFBaseSP(const TFBaseSP &tfbsp) : btype() 
00184    { 
00185       assign(const_cast<btype::type*>(tfbsp._ref));
00186       _lastChanged = (*_ref)->getChangeID();
00187    }
00188 
00189    TFBaseSP &operator=(const TFBaseSP &tfbsp) 
00190    { 
00191       assign(const_cast<btype::type*>(tfbsp._ref));
00192       setChanged();
00193       _lastChanged = -1;
00194       return *this; 
00195    }
00196 
00197    virtual ~TFBaseSP() {}
00198 
00199    /// if you are keeping track of changes yourself
00200    /// use this function, if you want to use this object
00201    /// as an observer, DO NOT use this one, use
00202    /// the functions below
00203    virtual int  getChangeID()               
00204    {
00205       if(_lastChanged != (*_ref)->getChangeID())
00206          setChanged();
00207       _lastChanged = (*_ref)->getChangeID();
00208       return SimBase::getChangeID();
00209    }
00210 
00211    /// if you have one of thses objects, you don't need to 
00212    /// keep track of the change id yourself. use these
00213    /// functions to see if the tf has changed since the last
00214    /// time you called "updateChanged()"
00215    bool tfChanged() const { return _lastChanged != (*_ref)->getChangeID(); }
00216    void updateChanged()   { _lastChanged = (*_ref)->getChangeID(); }
00217 
00218 protected:
00219    int _lastChanged;
00220 };
00221 
00222 #endif
00223 

Send questions, comments, and bug reports to:
jmk