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

TFElement.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 /// TFElement.h
00019 
00020 #ifndef __TRANSFER_FUNCTION_ELEMENT_DOT_H
00021 #define __TRANSFER_FUNCTION_ELEMENT_DOT_H
00022 
00023 #include <smartptr.h>
00024 #include <simBase/simBase.h>
00025 #include <list>
00026 #include "TFParams.h"
00027 #include "TFEval.h"
00028 #include "TFBlend.h"
00029 #include <nrro/nrro.h>
00030 
00031 /// forward decls
00032 class TFEltView;
00033 
00034 ////////////////////////////////
00035 /// default blend types
00036 typedef TFBlendSum  RGBBlendType;
00037 typedef TFBlendSum  AlphaBlendType;
00038 
00039 //////////////////////////////////////////////////////////////////////////
00040 /// A generic transfer function element base (classification widget spec)
00041 /// not a concrete implementation. \n
00042 /// see below for a double indirection element (so they can change types
00043 ///   and you can track changes to them) TFEltSP
00044 ///
00045 /// For Collaboration with TFGeneric \n
00046 /// See also: TFEltView, TFElementBox, TFParams.h, TFViewWidget, 
00047 ///           TFSurfaceWidget 
00048 //////////////////////////////////////////////////////////////////////////
00049 class TFElement : 
00050    public SimBase, 
00051    public gutz::Counted
00052 {
00053 public:
00054    virtual ~TFElement() {}
00055 
00056    typedef STF::tfSType      SType; ///scalar type
00057    typedef STF::tfDomainType PosType;
00058    typedef STF::tfDomainVec  PosVecType;
00059    typedef STF::tfRangeType  ValType;
00060    typedef STF::tfRangeVec   ValVecType;
00061    typedef STF::tfVec2       tfVec2;
00062    typedef STF::tfRangeVec4  tfVec4;
00063 
00064    //////////////////////////////////////////////////
00065    ///@name Views, 2D projections
00066    ///@{
00067 
00068    /// get view, returns View interface, each concrete TFElement
00069    ///  should have an associated view object than handles the
00070    ///  collaboration between 2D manipulations and the full ND 
00071    ///  representation of the Element.  see TFEltView for
00072    ///  the interface spec.
00073    virtual TFEltView *getView(const gutz::vec2i &axes) = 0; 
00074    ///@}
00075 
00076    //////////////////////////////////////////////////
00077    ///@name Evaluate
00078    ///@{
00079 
00080    ///////////////////////////////////
00081    /// evaluate at generic position
00082    virtual ValType eval(const PosType &tfpos) const = 0;
00083    ///@}
00084 
00085    ///////////////////////////////////
00086    // evaluate only a 2D version.
00087    // implys projecting out all other dimensions
00088    // for building separable transfer functions
00089    //  Although this function is virtual in this interface
00090    //  it should NOT be virtual in any concrete class if
00091    //  you are using the rasterization helper in "TFRasterize.h"
00092    //  otherwize rasterization will slow to a snails pace.
00093    //virtual ValType eval(const tfVec2 &tfpos, 
00094    //                     const gutz::vec2i &posIdx) const = 0;
00095    ///////////////////////////////////
00096    // evalate only a 2D version for 
00097    //  4 specific Range (val) values.
00098    // implementation optional.
00099    //virtual tfVec4 eval(const tfVec2 &tfpos,
00100    //                    const gutz::vec2i posIdx,
00101    //                    const gutz::vec4i valIdx) const
00102    //{ 
00103    //   ValType r = eval(tfpos,posIdx); 
00104    //   return tfVec4(r[valIdx.x],r[valIdx.y],r[valIdx.z],r[valIdx.w]); 
00105    // }
00106 
00107    ///////////////////////////////////
00108    ///@name Zero Val 
00109    /// The "Zero Val" is the value for "unclassified regions"
00110    /// this may or may not actually be zero, so 
00111    /// you may need to change what that value is.
00112    /// The zero value defaults to tfRangeType_default
00113    ///@{
00114    ValType getZeroVal() const            {return _zeroVal;}
00115    void    setZeroVal(const ValType &zv) { _zeroVal = zv; }
00116    ///@}
00117 
00118    ///////////////////////////////////
00119    ///@name evaluator strategies Depricated?
00120    ///@{
00121    TFEvalSP getEvaluator() const     {return _eval;}
00122    void     setEvaluator(TFEvalSP e) {_eval = e;}
00123    ///@}
00124 
00125    ///////////////////////////////////
00126    // blendOp strategies
00127    //TFBlendOPSP getBlendOP(int i) const          {return _blend.getBlendOP(i);}
00128    //void        setBlendOP(int i, TFBlendOP *bo) {_blend.setBlendOP(i, bo);}
00129    // blends "u" into and under "o"
00130    //void        blend(ValType &o, const ValType &u)
00131    //{ for(int i=0; i< STF::TF_MAX_R; ++i) _blend[i]->blend(o,u,i); }
00132 
00133    /////////////////////////////////// 
00134    ///@name Domain/Position
00135    /// all of the "nodes" associated with this element,
00136    ///  ie, verticies of polytope in tf domain
00137    ///@{
00138    PosVecType &getPosVec()               { return _posVec; }
00139    PosVecType  getPosVec() const         { return _posVec; }
00140    void        setPosVec(PosVecType &pv) { _posVec = pv; }
00141    PosType    &getPos(int i)             { return _posVec[i]; }
00142    PosType     getPos(int i) const       { return _posVec[i]; }
00143    void        setPos(int i, PosType p)  { _posVec[i] = p; }
00144    ///@}
00145 
00146    ///@name domain bounding box 
00147    ///  you can override these for speed!!
00148    /// should we recompute on every call?? very slow! maybe you can
00149    /// cache this in a subclass.
00150    ///@{
00151    virtual PosType  getMinBox() const
00152    {
00153       PosType ret(STF::tfDomainType_max);
00154       for(int i=0; i<int(_posVec.size()); ++i)
00155          vs_min(ret, _posVec[i]);
00156       return ret;
00157    }
00158    virtual PosType  getMaxBox() const
00159    {
00160       PosType ret(STF::tfDomainType_min);
00161       for(int i=0; i<int(_posVec.size()); ++i)
00162          vs_max(ret, _posVec[i]);
00163       return ret;
00164    }
00165    ///@}
00166 
00167    /////////////////////////////////// 
00168    ///@name Range/Value
00169    /// all of the values associated with each node,
00170    ///  if vec.size() == 1 then the element has a global 
00171    ///  definition of range.
00172    ///@{
00173    ValVecType &getValVec()       { return _valVec; }
00174    ValVecType  getValVec() const { return _valVec; }
00175    ///@}
00176 
00177    ///////////////////////////////////
00178    /// check to see if this element needs to be removed/deleted
00179    bool  needRemove() const {return _remove;}
00180 
00181    ///////////////////////////////////
00182    /// rasterize this element into an image.
00183    /// For now, the image must have 4 channels
00184    virtual void rasterize2D(NrroSP n, 
00185                             const gutz::vec2i &posIdx,
00186                             const int kind = STF::TF_RGBA) = 0;
00187 
00188    ///////////////////////////////////
00189    /// a generic rasterization algorithm
00190    /// the index vector allows you to rearrange and select
00191    /// which values from the domain are rasterized
00192    /// into the 2D image map (ni). 
00193    /// defined in "TFRasterize.cpp", see for more details.
00194 /*
00195    template<class T> inline
00196       void rasterize2D(Nrro::NrroIter<T>      ni,      
00197                        const gutz::vec2i     &posIdx, 
00198                        const STF::tfRangeIdx &valIdx = STF::tfRangeIdx_ao) const;
00199 */
00200 protected:
00201    TFElement() : _remove(false), _eval(new TFEvalGaus()) {}
00202 
00203    PosVecType _posVec; // position parameters
00204    ValVecType _valVec; // value parameters
00205 
00206    ValType    _zeroVal;
00207 
00208    TFEvalSP   _eval;
00209    ///TFBlend    _blend;
00210 
00211    bool _remove;
00212 
00213 };
00214 
00215 typedef gutz::SmartPtr<TFElement> TFElementSP;
00216 
00217 //////////////////////////////////////////////////////////////////////////
00218 /// a double indirection tf element. Uses the SmartPtrRef interface 
00219 ///   so it behaves as a pointer to an element.  Used mainly as an 
00220 ///   observer for objects that use Elements, keeps a changeID to 
00221 ///   compare against the referenced element's current changeID.  
00222 //////////////////////////////////////////////////////////////////////////
00223 
00224 class TFEltSP : public gutz::SmartPtrRef<TFElement>, public SimBase
00225 {
00226 public:
00227    typedef gutz::SmartPtrRef<TFElement> btype;
00228 
00229    TFEltSP(TFElement *e) : btype(e), _lastChanged(e->getChangeID()) {}
00230    TFEltSP(const TFEltSP &tfe) : btype(), _lastChanged(tfe._lastChanged)
00231    { assign(const_cast<btype::type*>(tfe._ref)); }
00232 
00233    TFEltSP &operator=(const TFEltSP &tfe)
00234    { 
00235       assign(const_cast<btype::type*>(tfe._ref));
00236       setChanged();
00237       _lastChanged = -1;
00238       return *this;
00239    }
00240 
00241    /// if you are keeping track of changes yourself
00242    /// use this function, if you want to use this object
00243    /// as an observer, DO NOT use this one, use
00244    /// the functions below
00245    virtual int  getChangeID()               
00246    {
00247       if(_lastChanged != (*_ref)->getChangeID())
00248          setChanged();
00249       _lastChanged = (*_ref)->getChangeID();
00250       return SimBase::getChangeID();
00251    }
00252 
00253    /// see if the element we reference changed
00254    bool elementChanged() const { return _lastChanged != (*_ref)->getChangeID(); }
00255    /// set the element unchanged
00256    void updateChanged()  { _lastChanged = (*_ref)->getChangeID(); }
00257 
00258    virtual ~TFEltSP() {}
00259 
00260 protected:
00261    TFEltSP() {}
00262    int _lastChanged;
00263 };
00264 
00265 //////////////////////////////////////////////////////////////////////////
00266 /// a usefull LIST of transfer function elements
00267 //////////////////////////////////////////////////////////////////////////
00268 class TFElementList : 
00269    public std::list<TFEltSP>, 
00270    public gutz::Counted 
00271 {
00272 public:
00273    typedef TFElementList::iterator Iter;
00274 
00275    TFElementList() {}   
00276    virtual ~TFElementList() {}
00277 
00278    void addElement(TFElement *e)
00279    { push_back(TFEltSP(e)); }
00280 
00281    /// check if any element changed
00282    bool elementChanged()
00283    {
00284       bool ret = false;
00285       for(Iter i = begin(); i!=end(); ++i)
00286       {
00287          ret |= (*i).elementChanged();
00288       }
00289       return ret;
00290    }
00291    
00292    /// set all elements unchanged.
00293    void updateChanged()
00294    {
00295       for(Iter i=begin(); i!=end(); ++i)
00296       {
00297          (*i).updateChanged();
00298       }
00299    }
00300 
00301 protected:
00302 
00303 };
00304 
00305 typedef TFElementList::iterator       TFElementListIter;
00306 typedef TFElementList::const_iterator TFElementListConstIter;
00307 
00308 typedef gutz::SmartPtr<TFElementList> TFElementListSP;
00309 
00310 
00311 #endif
00312 

Send questions, comments, and bug reports to:
jmk