// File: NIS_Drawer.hxx // Created: 06.07.07 21:10 // Author: Alexander GRIGORIEV // Copyright: Open Cascade 2007 #ifndef NIS_Drawer_HeaderFile #define NIS_Drawer_HeaderFile #include #include #include #include #include #include #ifdef WNT // Disable the warning "operator new unmatched by delete" #pragma warning (push) #pragma warning (disable:4480) #endif class Handle_NIS_InteractiveObject; class Handle_NIS_View; class Handle_NIS_Drawer; class NIS_InteractiveContext; class NIS_View; template class NCollection_Vector; /** * Abstract Drawer type. * Drawer provides the immediate OpenGL drawing for every NIS_InteractiveObject * maneged by the given Drawer instance. Each Drawer instance has reciprocal * link with a number of NIS_InteractiveObject instances of the same * (corresponding to Drawer) type. The idea is to group the drawing for all * referred interactive objects using the same pre- and post-treatment like * color setting, matrix, polygon offset, line thickness and what not. * * @section nis_drawer_visualprop Visual properties of Drawer * Normally visual properties of any NIS_InteractiveObject are stored in its * Drawer instance, but not in an object. For example, if an interactive object * has method SetColor() then the color is stored in the corresponding Drawer * rather than in the interactive object itself. This scheme avoid useless * duplication when a lot of objects have similar properties like color. Please * see @see nis_interactiveobject_drawer to learn how this mechanism * works from the side of NIS_InteractiveObject. * * @section nis_drawer_drawing Drawing * There are 3 virtual methods to implement OpenGL drawing in this API. They * define the drawing cycle that consists of filling the internal OpenGL draw * list with commands. This drawing cycle is triggered when the corresponding * internal instance of NIS_DrawList has 'IsUpdated' flag (you can set this * flag by means of public methods NIS_Drawer::SetUpdated()). *
    *
  • BeforeDraw() : contains all OpenGL commands that define the * common set of visual properties for all managed interactive objects. * This method is called once in the beginning of drawing cycle for the * Drawer instance
  • *
  • Draw() : all OpenGL commands that are specific to a given * interactive object, usually definition of vertices, triangles, lines, * or their arrays.
  • *
  • AfterDraw() : commands that revert the status of OpenGL context * to the state before execution of BeforeDraw(). This method is called * once in the end of drawing cycle.
  • *
* Each of these methods receives NIS_DrawList and DrawType, both identify the * OpenGL draw list that should be filled with commands. Based on DrawType * you will be able to define different presentation - the most important case * is how hilighted (selected) interactive object is presented. *

* For advanced purposes you also can redefine the virtual method redraw(), it * is dedicated to higher-level management of draw lists and ordering of * their update when necessary. * * @section nis_drawer_distinction Distinction of Drawer instances * Every Drawer should define which interactive objects it may manage and * which - may not. The same idea could be shaped alternatively: every * interactive object should understand to what Drawer it can attach itself. * This question is answerd by special virtual method IsEqual() that compares * two Drawers of the same type. Two instances of Drawer are equal if they * have the same set of visual properties that are implemented in BeforeDraw(). * The method IsEqual() is the core of Drawer architecture and it must * be implemented very carefully for any new type. Particularly, for any * derived class the method IsEqual() should first call the same method of * its superclass. *

* For the optimal efficiency of OpenGL drawing it is better to keep the size * of draw list (i.e., the number of interactive objects in a Drawer instance) * not too small and not too big. The latter limitation is entered by the * protected field myObjPerDrawer. It is used in method IsEqual() of the base * Drawer class: two Drawers are not equal if they are initialized on objects * that have too different IDs -- even if all visual properties of these two * Drawer instances coincide. *

* @section nis_drawer_cloning Cloning Drawer instances * It is possible to clone a Drawer instance with the viryual method Assign(). * This method copies all visual properties and other important data from the * Drawer provided as parameter. Method Clone() also should be very carefully * implemented for any new Drawer type, to make sure that all necessary data * fields and structures are properly copied. */ class NIS_Drawer : public Standard_Transient { public: #if defined(WNT) && (_MSC_VER >= 1400) enum DrawType : unsigned int { #else enum DrawType { #endif Draw_Normal = 0, Draw_Top = 1, Draw_Transparent = 2, Draw_Hilighted = 3, Draw_DynHilighted = 4 }; public: // ---------- PUBLIC METHODS ---------- /** * Empty constructor. */ inline NIS_Drawer () : myTransparency (0.f), myIniId (0), myObjPerDrawer (1024), myCtx (0L) {} /** * Destructor. */ Standard_EXPORT virtual ~NIS_Drawer (); /** * Query the Interactive Context. */ inline NIS_InteractiveContext * GetContext () const { return myCtx; } /** * Copy the relevant information from another instance of Drawer. * raises exception if theOther has incompatible type (test IsKind). */ Standard_EXPORT virtual void Assign (const Handle_NIS_Drawer& theOther); /** * Create a3D bounding box of drawn objects. * @param pView * In not NULL, only objects visible in this view are taken. */ Standard_EXPORT virtual const Bnd_B3f& GetBox (const NIS_View * pView = 0L) const; /** * Mark all draw lists for update */ Standard_EXPORT void SetUpdated (const DrawType theType) const; Standard_EXPORT void SetUpdated (const DrawType theType1, const DrawType theType2) const; Standard_EXPORT void SetUpdated (const DrawType theType1, const DrawType theType2, const DrawType theType3) const; Standard_EXPORT void SetUpdated (const DrawType theType1, const DrawType theType2, const DrawType theType3, const DrawType theType4) const; /** * Switch on/off the dynamic hilight of the given object in the * given view. * @param isHilighted * True if the object should be hilighted, False - if not hilighted * @param theObj * Object instance that should be hilighted or unhilighted. * @param theView * View where the status of object must be changed. If NULL, the object * is hilighted/unhilighted in all views. */ Standard_EXPORT void SetDynamicHilighted (const Standard_Boolean isHilighted, const Handle_NIS_InteractiveObject& theObj, const Handle_NIS_View& theView = 0L); /** * Hash value, for Map interface. */ Standard_EXPORT virtual Standard_Integer HashCode(const Standard_Integer theN) const; /** * Matching two instances, for Map interface. */ Standard_EXPORT virtual Standard_Boolean IsEqual (const Handle_NIS_Drawer& theOth) const; /** * Obtain the iterator of IDs of associated objects. */ inline TColStd_MapIteratorOfPackedMapOfInteger ObjectIterator () const { return TColStd_MapIteratorOfPackedMapOfInteger (myMapID); } /** * Query associated draw lists. */ inline NCollection_List GetLists() const { return myLists; } protected: /** * Called to add draw list IDs to ex-list Ids of view. These draw lists are * eventually released in the callback function, before anything is displayed */ Standard_EXPORT void UpdateExListId (const Handle_NIS_View& theView) const; // ---------- PROTECTED METHODS ---------- /** * Called before execution of Draw(), once per group of interactive objects. */ Standard_EXPORT virtual void BeforeDraw (const DrawType theType, const NIS_DrawList& theDrawList ); /** * Called after execution of Draw(), once per group of interactive objects. */ Standard_EXPORT virtual void AfterDraw (const DrawType theType, const NIS_DrawList& theDrawList); /** * Main function: display the given interactive object in the given view. */ Standard_EXPORT virtual void Draw (const Handle_NIS_InteractiveObject&, const DrawType theType, const NIS_DrawList& theDrawList)= 0; Standard_EXPORT virtual void redraw (const DrawType theType, const Handle_NIS_View& theView); Standard_EXPORT void addObject (const NIS_InteractiveObject * theObj, const Standard_Boolean isShareList, const Standard_Boolean isUpVws); Standard_EXPORT void removeObject (const NIS_InteractiveObject * theObj, const Standard_Boolean isUpVws); Standard_EXPORT virtual NIS_DrawList* createDefaultList (const Handle_NIS_View&) const; protected: //! Get the number of interactive objects in this drawer inline Standard_Integer NObjects() const { return myMapID.Extent(); } private: // ---------- PRIVATE (PROHIBITED) METHODS ---------- NIS_Drawer (const NIS_Drawer& theOther); NIS_Drawer& operator = (const NIS_Drawer& theOther); // ---------- PRIVATE METHODS ---------- void prepareList (const NIS_Drawer::DrawType theType, const NIS_DrawList& theDrawLst, const TColStd_PackedMapOfInteger& mapObj); protected: // ---------- PROTECTED FIELDS ---------- NCollection_List myLists; Standard_ShortReal myTransparency; //! ID of the initializing InteractiveObject. It is never changed, can be //! used to compute hash code of the Drawer instance. Standard_Integer myIniId; //! Maximal range of IDs of objects in one drawer. Limits the size of //! draw lists. Can be initialized only in constructor (default 1024). It is //! strictly prohibited to change this value outside the constructor. Standard_Integer myObjPerDrawer; private: // ---------- PRIVATE FIELDS ---------- NIS_InteractiveContext * myCtx; TColStd_PackedMapOfInteger myMapID; Bnd_B3f myBox; friend class NIS_InteractiveContext; friend class NIS_InteractiveObject; friend class NIS_View; public: // Declaration of CASCADE RTTI DEFINE_STANDARD_RTTI (NIS_Drawer) }; // Definition of HANDLE object using Standard_DefineHandle.hxx DEFINE_STANDARD_HANDLE (NIS_Drawer, Standard_Transient) //======================================================================= //function : HashCode //purpose : //======================================================================= inline Standard_Integer HashCode (const Handle_NIS_Drawer& theDrawer, const Standard_Integer theN) { return theDrawer.IsNull() ? 0 : theDrawer->HashCode (theN); } //======================================================================= //function : IsEqual //purpose : //======================================================================= inline Standard_Boolean IsEqual (const Handle_NIS_Drawer& theDrawer1, const Handle_NIS_Drawer& theDrawer2) { return theDrawer1.IsNull()? Standard_False: theDrawer1->IsEqual(theDrawer2); } #ifdef WNT #pragma warning (pop) #endif #endif