// Created on: 2012-04-09 // Created by: Sergey ANIKIN // Copyright (c) 2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName, const Handle(AIS_InteractiveObject)& theAISObj, Standard_Boolean theReplaceIfExists = Standard_True); //======================================================================= //function : VUserDraw //purpose : Checks availability and operation of UserDraw feature //======================================================================= DEFINE_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject) class VUserDrawObj : public AIS_InteractiveObject { public: // CASCADE RTTI DEFINE_STANDARD_RTTI(VUserDrawObj); VUserDrawObj() { myCoords[0] = -10.; myCoords[1] = -20.; myCoords[2] = -30.; myCoords[3] = 10.; myCoords[4] = 20.; myCoords[5] = 30.; } public: class Element : public OpenGl_Element { private: Handle(VUserDrawObj) myIObj; public: Element (const Handle(VUserDrawObj)& theIObj, CALL_DEF_BOUNDS* theBounds) : myIObj( theIObj ) { if (!myIObj.IsNull()) myIObj->GetBounds(theBounds); } virtual ~Element () { } virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const { if (!myIObj.IsNull()) myIObj->Render(theWorkspace); } public: DEFINE_STANDARD_ALLOC }; private: // Virtual methods implementation void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode); void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, const Standard_Integer theMode); // Called by VUserDrawElement void Render(const Handle(OpenGl_Workspace)& theWorkspace) const; void GetBounds(CALL_DEF_BOUNDS* theBounds); GLfloat myCoords[6]; friend class Element; }; IMPLEMENT_STANDARD_HANDLE(VUserDrawObj, AIS_InteractiveObject) IMPLEMENT_STANDARD_RTTIEXT(VUserDrawObj, AIS_InteractiveObject) void VUserDrawObj::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) { thePresentation->Clear(); Handle(Graphic3d_Group) aGrp = Prs3d_Root::CurrentGroup(thePresentation); aGrp->UserDraw(this, Standard_True, Standard_True); } void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, const Standard_Integer theMode) { Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this); Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, 5); aPnts->SetValue(1, gp_Pnt(myCoords[0], myCoords[1], myCoords[2])); aPnts->SetValue(2, gp_Pnt(myCoords[3], myCoords[4], myCoords[2])); aPnts->SetValue(3, gp_Pnt(myCoords[3], myCoords[4], myCoords[5])); aPnts->SetValue(4, gp_Pnt(myCoords[0], myCoords[1], myCoords[5])); aPnts->SetValue(5, gp_Pnt(myCoords[0], myCoords[1], myCoords[2])); Handle(Select3D_SensitiveCurve) aSensitive = new Select3D_SensitiveCurve(anEntityOwner, aPnts); theSelection->Add(aSensitive); } void VUserDrawObj::GetBounds(CALL_DEF_BOUNDS* theBounds) { if (theBounds) { theBounds->XMin = myCoords[0]; theBounds->YMin = myCoords[1]; theBounds->ZMin = myCoords[2]; theBounds->XMax = myCoords[3]; theBounds->YMax = myCoords[4]; theBounds->ZMax = myCoords[5]; } } void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const { // To test linking against OpenGl_Workspace and all aspect classes const OpenGl_AspectLine* aLA = theWorkspace->AspectLine(0); const OpenGl_AspectFace* aFA = theWorkspace->AspectFace(0); aFA->Context(); const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0); aMA->Type(); const OpenGl_AspectText* aTA = theWorkspace->AspectText(0); aTA->Font(); TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ? *(theWorkspace->HighlightColor) : aLA->Color(); // To test OpenGl_Window Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext(); GLCONTEXT aGlContext = theWorkspace->GetGContext(); // To link against OpenGl_Context and extensions GLuint aVboId = -1, aTexId = -1; if (aCtx->arbVBO) aCtx->arbVBO->glGenBuffersARB(1, &aVboId); glGenTextures(1, &aTexId); // To link against OpenGl_ResourceCleaner, OpenGl_ResourceVBO, OpenGl_ResourceTexture OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance(); if (aVboId != (GLuint)-1) aResCleaner->AddResource(aGlContext, new OpenGl_ResourceVBO(aVboId)); if (aTexId != (GLuint)-1) aResCleaner->AddResource(aGlContext, new OpenGl_ResourceTexture(aTexId)); // Finally draw something to make sure UserDraw really works glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glColor4fv(aColor.rgb); glBegin(GL_LINE_LOOP); glVertex3f(myCoords[0], myCoords[1], myCoords[2]); glVertex3f(myCoords[3], myCoords[4], myCoords[2]); glVertex3f(myCoords[3], myCoords[4], myCoords[5]); glVertex3f(myCoords[0], myCoords[1], myCoords[5]); glEnd(); glPopAttrib(); } OpenGl_Element* VUserDrawCallback(const CALL_DEF_USERDRAW * theUserDraw) { Handle(VUserDrawObj) anIObj = (VUserDrawObj*)theUserDraw->Data; if (anIObj.IsNull()) { std::cout << "VUserDrawCallback error: null object passed, the custom scene element will not be rendered" << std::endl; } return new VUserDrawObj::Element(anIObj, theUserDraw->Bounds); } static Standard_Integer VUserDraw (Draw_Interpretor& di, Standard_Integer argc, const char ** argv) { Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); if (aContext.IsNull()) { di << argv[0] << "Call 'vinit' before!\n"; return 1; } if (argc > 2) { di << argv[0] << "Wrong number of arguments, only the object name expected\n"; return 1; } TCollection_AsciiString aName (argv[1]); VDisplayAISObject(aName, Handle(AIS_InteractiveObject)()); // register the custom element factory function ::UserDrawCallback() = VUserDrawCallback; Handle(VUserDrawObj) anIObj = new VUserDrawObj(); VDisplayAISObject(aName, anIObj); return 0; } //======================================================================= //function : OpenGlCommands //purpose : //======================================================================= void ViewerTest::OpenGlCommands(Draw_Interpretor& theCommands) { const char* aGroup ="Commands for low-level TKOpenGl features"; theCommands.Add("vuserdraw", "vuserdraw : name - simulates drawing with help of UserDraw", __FILE__, VUserDraw, aGroup); }