From 161c4476670d94ac83346906d2c0ce8154e5a199 Mon Sep 17 00:00:00 2001 From: KGV <> Date: Thu, 28 Apr 2011 15:07:08 +0000 Subject: [PATCH] OCC22199 OpenGL memory leaks in TKOpenGl --- src/AIS/AIS_TexturedShape.cxx | 6 +- src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx | 1 + .../InterfaceGraphic_PrimitiveArray.hxx | 1 + src/OpenGl/FILES | 7 + src/OpenGl/OpenGl_PrimitiveArray.cxx | 21 + src/OpenGl/OpenGl_Resource.hxx | 63 +++ src/OpenGl/OpenGl_ResourceCleaner.cxx | 210 ++++++++ src/OpenGl/OpenGl_ResourceCleaner.hxx | 79 +++ src/OpenGl/OpenGl_ResourceTexture.cxx | 45 ++ src/OpenGl/OpenGl_ResourceTexture.hxx | 37 ++ src/OpenGl/OpenGl_ResourceVBO.cxx | 45 ++ src/OpenGl/OpenGl_ResourceVBO.hxx | 37 ++ src/OpenGl/OpenGl_TextureBox.cxx | 39 +- src/OpenGl/OpenGl_togl_redraw.cxx | 4 +- src/OpenGl/OpenGl_txgl.cxx | 33 +- src/ViewerTest/ViewerTest.cxx | 26 +- src/ViewerTest/ViewerTest_ObjectCommands.cxx | 490 ++++++++++-------- 17 files changed, 885 insertions(+), 259 deletions(-) create mode 100755 src/OpenGl/OpenGl_Resource.hxx create mode 100755 src/OpenGl/OpenGl_ResourceCleaner.cxx create mode 100755 src/OpenGl/OpenGl_ResourceCleaner.hxx create mode 100755 src/OpenGl/OpenGl_ResourceTexture.cxx create mode 100755 src/OpenGl/OpenGl_ResourceTexture.hxx create mode 100755 src/OpenGl/OpenGl_ResourceVBO.cxx create mode 100755 src/OpenGl/OpenGl_ResourceVBO.hxx diff --git a/src/AIS/AIS_TexturedShape.cxx b/src/AIS/AIS_TexturedShape.cxx index bcee875be2..80d1dadcdc 100755 --- a/src/AIS/AIS_TexturedShape.cxx +++ b/src/AIS/AIS_TexturedShape.cxx @@ -342,8 +342,10 @@ void AIS_TexturedShape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aP BRepTools::Update(myshape); Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager(); - - myAspect = (new Prs3d_ShadingAspect())->Aspect(); + { + Handle(Prs3d_ShadingAspect) aPrs3d_ShadingAspect = new Prs3d_ShadingAspect; + myAspect = aPrs3d_ShadingAspect->Aspect(); + } if (!DoMapTexture) { myAspect->SetTextureMapOff(); diff --git a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx index cdca8abb7a..5d85b4ed5f 100755 --- a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx @@ -85,6 +85,7 @@ Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives ( myPrimitiveArray->num_edges = 0; myPrimitiveArray->VBOEnabled = -1; myPrimitiveArray->flagBufferVBO = -1; + myPrimitiveArray->contextId = 0; for( int i =0 ; i < VBOMaxType ; i++){ myPrimitiveArray->bufferVBO[i] = 0; diff --git a/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx b/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx index 064e25ffb3..cb2dc3efa1 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx @@ -67,6 +67,7 @@ typedef struct { Tint VBOEnabled; /* -1 - it is not known VBO status 0 - draw object without VBO 1 - draw object with VBO */ + Standard_Address contextId; /* remember context for VBO */ } CALL_DEF_PARRAY; #endif /* _InterfaceGraphic_PrimitiveArray_header_file_ */ diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 0bc8706bcc..8dcd730537 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -240,3 +240,10 @@ OpenGl_graduatedtrihedron.hxx OpenGl_togl_graduatedtrihedron.cxx OpenGl_FrameBuffer.hxx OpenGl_FrameBuffer.cxx +OpenGl_Resource.hxx +OpenGl_ResourceCleaner.cxx +OpenGl_ResourceCleaner.hxx +OpenGl_ResourceVBO.cxx +OpenGl_ResourceVBO.hxx +OpenGl_ResourceTexture.cxx +OpenGl_ResourceTexture.hxx diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 5b83767f2b..087bb80455 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -55,6 +55,8 @@ static unsigned long vRand = 1L; #include #include #include +#include +#include #include #include #include @@ -232,6 +234,10 @@ static void BuildVBO( CALL_DEF_PARRAY* p ) if( p->flagBufferVBO == VBO_OK ) clearRAMMemory(p); + + //specify context for VBO resource + p->contextId = (Standard_Address)GET_GL_CONTEXT(); + } /*----------------------------------------------------------------------*/ @@ -753,6 +759,21 @@ draw_array( call_def_parray p, Tint hflag, static TStatus ParrayDelete( TSM_ELEM_DATA data, Tint n, cmn_key *k ) { + call_def_parray p = (call_def_parray)data.pdata; + if( p->VBOEnabled == VBO_OK ) { + OpenGl_ResourceCleaner* resCleaner = OpenGl_ResourceCleaner::GetInstance(); + if( p->bufferVBO[VBOEdges] ) + resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOEdges]) ); + if( p->bufferVBO[VBOVertices] ) + resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVertices]) ); + if( p->bufferVBO[VBOVcolours] ) + resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVcolours]) ); + if( p->bufferVBO[VBOVnormals] ) + resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVnormals]) ); + if( p->bufferVBO[VBOVtexels] ) + resCleaner->AddResource( (GLCONTEXT)p->contextId, new OpenGl_ResourceVBO(p->bufferVBO[VBOVtexels]) ); + } + return TSuccess; } diff --git a/src/OpenGl/OpenGl_Resource.hxx b/src/OpenGl/OpenGl_Resource.hxx new file mode 100755 index 0000000000..9bb9a44b59 --- /dev/null +++ b/src/OpenGl/OpenGl_Resource.hxx @@ -0,0 +1,63 @@ +// File: OpenGl_Resource.hxx +// Created: 18.03.11 9:20:00 +// Author: Anton POLETAEV + +#ifndef _OPENGL_RESOURCE_H +#define _OPENGL_RESOURCE_H + +#include +#include +#include +#include +#include + +class Standard_Transient; +class Handle(Standard_Type); +class Handle(MMgt_TShared); +class OpenGl_ResourceCleaner; + +//! Class represents basic OpenGl memory resource, which +//! could be removed only if appropriate context is avaliable; +//! The cleaning procedure is done by OpenGl_ResourceCleaner +class OpenGl_Resource : public MMgt_TShared +{ + +public: + + //! Constructor + OpenGl_Resource() : myId(0) { } + + //! Constructor + OpenGl_Resource(GLuint theId) : myId(theId) { } + + //! Copy constructor + OpenGl_Resource(const OpenGl_Resource& theBase) : myId(theBase.myId) { } + + //! Copy operation + OpenGl_Resource& operator = (const OpenGl_Resource& theBase) + { + this->myId = theBase.myId; + return *this; + } + + //! Destructor + virtual ~OpenGl_Resource() { } + + //! method clean() is accessible only by OpenGl_ResourceCleaner + friend class OpenGl_ResourceCleaner; + +protected: + + //! Clean procedure, should be called only by OpenGl_ResourceCleaner; + //! Each type of resource has its own cleaning procedure + virtual void Clean() = 0; + +protected: + + GLuint myId; // Id of OpenGl memory resource + +}; + +DEFINE_STANDARD_HANDLE(OpenGl_Resource,MMgt_TShared) + +#endif diff --git a/src/OpenGl/OpenGl_ResourceCleaner.cxx b/src/OpenGl/OpenGl_ResourceCleaner.cxx new file mode 100755 index 0000000000..d1a3c3c527 --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceCleaner.cxx @@ -0,0 +1,210 @@ +// File: OpenGl_ResourceCleaner.cxx +// Created: 18.03.11 9:40:00 +// Author: Anton POLETAEV + +#include +#include + +//======================================================================= +//function : OpenGl_ResourceCleaner +//purpose : Constructor +//======================================================================= + +OpenGl_ResourceCleaner::OpenGl_ResourceCleaner() +{ + mySharedContexts.Clear(); + mySharedQueue.Clear(); + myInstanceQueue.Clear(); +} + +//======================================================================= +//function : AppendContext +//purpose : Append given OpenGl context to the OpenGl_ResourceCleaner +// control list +//======================================================================= + +void OpenGl_ResourceCleaner::AppendContext(GLCONTEXT theContext, Standard_Boolean isShared) +{ + + // appending shared context + if (isShared) + { + mySharedContexts.Add(theContext); + } + else + { + // if context is already in the list + if (myInstanceQueue.IsBound(theContext)) + { + QueueOfResources *aQueue = &myInstanceQueue.ChangeFind(theContext); + aQueue->Clear(); + } + else + { + // context is not in the list - create empty queue for it and add queue to the list + QueueOfResources aQueue; + aQueue.Clear(); + myInstanceQueue.Bind(theContext, aQueue); + } + } + +} + +//======================================================================= +//function : AddResource +//purpose : Tell the OpenGl_ResourceCleaner to clean up the OpenGl +// memory resource +//======================================================================= + +Standard_Boolean OpenGl_ResourceCleaner::AddResource(GLCONTEXT theContext, Handle_OpenGl_Resource theResource) +{ + // if context found in the shared list + if (mySharedContexts.Contains(theContext)) + { + mySharedQueue.Push(theResource); + return Standard_True; + } + // if not, then it might be found in the non-shared list + else if (myInstanceQueue.IsBound(theContext)) + { + QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext); + aQueue->Push(theResource); + return Standard_True; + } + + // context is not under OpenGl_ResourceCleaner control, do not tell to clean the resource + return Standard_False; +} + +//======================================================================= +//function : Clear +//purpose : Cancel clean procedure for all the resources added to the +// OpenGl_ResourceCleaner +//======================================================================= + +void OpenGl_ResourceCleaner::Clear() +{ + mySharedQueue.Clear(); + DataMapOfContextsResources::Iterator anIter(myInstanceQueue); + + // remove the resources from the list + for (anIter.Reset(); anIter.More(); anIter.Next()) + { + QueueOfResources * aQueue = &anIter.ChangeValue(); + aQueue->Clear(); + } + +} + +//======================================================================= +//function : Clear +//purpose : Cancel clean procedure for all the resources of the specific +// OpenGl context which were added to the OpenGl_ResourceCleaner +//======================================================================= + +Standard_Boolean OpenGl_ResourceCleaner::Clear(GLCONTEXT theContext) +{ + // check if the context in the the control list + if (myInstanceQueue.IsBound(theContext)) + { + QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext); + aQueue->Clear(); + return Standard_True; + } + + return Standard_False; +} + +//======================================================================= +//function : ClearShared +//purpose : Cancel clean procedure for all of the shared resources +//======================================================================= + +void OpenGl_ResourceCleaner::ClearShared() +{ + mySharedQueue.Clear(); +} + +//======================================================================= +//function : Cleanup +//purpose : Clear the unused resources for active OpenGl context +//======================================================================= + +void OpenGl_ResourceCleaner::Cleanup() +{ + GLCONTEXT aContext = GET_GL_CONTEXT(); + + // if we have active context, we can delete the resources + if (aContext != NULL) + // if the context is found in shared list + if (mySharedContexts.Contains(aContext)) + { + while(mySharedQueue.Size() > 0) + { + mySharedQueue.Front()->Clean(); // delete resource memory + mySharedQueue.Pop(); + } + } + // if the context is found in non-shared list + else if (myInstanceQueue.IsBound(aContext)) + { + QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(aContext); + while(aQueue->Size() > 0) + { + aQueue->Front()->Clean(); // delete resource memory + aQueue->Pop(); + } + } +} + +//======================================================================= +//function : RemoveContext +//purpose : Remove the OpenGl context from the OpenGl_ResourceCleaner list +//======================================================================= + +void OpenGl_ResourceCleaner::RemoveContext(GLCONTEXT theContext) +{ + // if context can be found in shared list try to remove it + // if it wasn't in there, try to remove it from non-shared list + if (!mySharedContexts.Remove(theContext)) + myInstanceQueue.UnBind(theContext); + + // if no contexts in shared list, then there is no need to clean + // the resources on redraw + if (mySharedContexts.Size() == 0) + mySharedQueue.Clear(); + +} + +//======================================================================= +//function : GetSharedContext +//purpose : Get any of shared contexts from the OpenGl_ResourceCleaner list +//======================================================================= + +GLCONTEXT OpenGl_ResourceCleaner::GetSharedContext() const +{ + if(mySharedContexts.Size() > 0) + { + MapOfContexts::Iterator anIter(mySharedContexts); + anIter.Reset(); + return anIter.Value(); + } + + return 0; +} + +//======================================================================= +//function : GetInstance +//purpose : Get the global instance of OpenGl_ResourceCleaner +//======================================================================= + +OpenGl_ResourceCleaner* OpenGl_ResourceCleaner::GetInstance() +{ + // the static instance entity + static OpenGl_ResourceCleaner* anInstance = NULL; + + if (anInstance == NULL) + anInstance = new OpenGl_ResourceCleaner; + + return anInstance; +} diff --git a/src/OpenGl/OpenGl_ResourceCleaner.hxx b/src/OpenGl/OpenGl_ResourceCleaner.hxx new file mode 100755 index 0000000000..a6ae69871b --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceCleaner.hxx @@ -0,0 +1,79 @@ +// File: OpenGl_ResourceCleaner.hxx +// Created: 18.03.11 9:30:00 +// Author: Anton POLETAEV + +#ifndef _OPENGL_RESOURCECLEANER_H +#define _OPENGL_RESOURCECLEANER_H + +#include +#include +#include +#include +#include +#include + +class OpenGl_Resource; +class Handle_OpenGl_Resource; + +typedef NCollection_Queue QueueOfResources; +typedef NCollection_DataMap DataMapOfContextsResources; +typedef NCollection_Map MapOfContexts; + +//! OpenGl_ResourceCleaner should be used to clean OpenGl memory resources; +//! The reason is that the resources might be shared between the contexts and +//! should be cleaned up only while suitable context is active; +class OpenGl_ResourceCleaner +{ + +public: + + //! Constructor + OpenGl_ResourceCleaner(); + + //! Destructor + virtual ~OpenGl_ResourceCleaner() { } + + //! Append OpenGl context to the OpenGl_ResourceCleaner + //! control list. + void AppendContext(GLCONTEXT theContext, Standard_Boolean isShared); + + //! Tell the OpenGl_ResourceCleaner to clean up the OpenGl memory resource + //! which has been created by the specified OpenGl context; + //! The context should be in the OpenGl_ResourceCleaner control list. + Standard_Boolean AddResource(GLCONTEXT theContext, Handle_OpenGl_Resource theResource); + + //! Cancel clean procedure for all the resources added to the OpenGl_ResourceCleaner. + void Clear(); + + //! Cancel clean procedure for all the resources of the specific OpenGl context + //! which were added to the OpenGl_ResourceCleaner. + Standard_Boolean Clear(GLCONTEXT theContext); + + //! Cancel clean procedure for all of the shared resources. + void ClearShared(); + + //! Clear the unused resources for active OpenGl context; + //! You should add the cleaner resources by AddResources method; + //! It is suggested to call this method right before the OpenGl + //! new frame drawing procedure starts. + void Cleanup(); + + //! Remove the OpenGl context from the OpenGl_ResourceCleaner control list. + void RemoveContext(GLCONTEXT theContext); + + //! Get any of shared contexts from the OpenGl_ResourceCleaner list + //! to share resources with a new one + GLCONTEXT GetSharedContext() const; + + //! Get the global instance of OpenGl_ResourceCleaner + static OpenGl_ResourceCleaner* GetInstance(); + +private: + + DataMapOfContextsResources myInstanceQueue; // map for queues of non-shared context's resources + QueueOfResources mySharedQueue; // queue of shared context's resources + MapOfContexts mySharedContexts; // the control list of shared contexts + +}; + +#endif diff --git a/src/OpenGl/OpenGl_ResourceTexture.cxx b/src/OpenGl/OpenGl_ResourceTexture.cxx new file mode 100755 index 0000000000..9b5d27b95a --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceTexture.cxx @@ -0,0 +1,45 @@ +// File: OpenGl_ResourceTexture.cxx +// Created: 18.03.11 9:40:00 +// Author: Anton POLETAEV + +#include +#include +#include + +#ifdef __sgi +#define glGenTextures glGenTexturesEXT +#define glDeleteTextures glDeleteTexturesEXT +#define glBindTexture glBindTextureEXT +#endif /* IRIX */ + +//======================================================================= +//function : OpenGl_ResourceTexture +//purpose : Constructor +//======================================================================= + +OpenGl_ResourceTexture::OpenGl_ResourceTexture(GLuint theId) +: OpenGl_Resource(theId) +{ + +} + +//======================================================================= +//function : OpenGl_ResourceTexture +//purpose : Copy constructor +//======================================================================= + +OpenGl_ResourceTexture::OpenGl_ResourceTexture(const OpenGl_ResourceTexture& theResource) +: OpenGl_Resource(theResource) +{ + +} + +//======================================================================= +//function : Clean +//purpose : free OpenGl memory allocated for texture resource +//======================================================================= + +void OpenGl_ResourceTexture::Clean() +{ + glDeleteTextures(1, &myId); +} diff --git a/src/OpenGl/OpenGl_ResourceTexture.hxx b/src/OpenGl/OpenGl_ResourceTexture.hxx new file mode 100755 index 0000000000..1ab4d51def --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceTexture.hxx @@ -0,0 +1,37 @@ +// File: OpenGl_ResourceTexture.hxx +// Created: 18.03.11 9:40:00 +// Author: Anton POLETAEV + +#ifndef _OPENGL_RESOURCETEXTURE_H +#define _OPENGL_RESOURCETEXTURE_H + +#include +#include + +class OpenGl_Resource; + +//! OpenGl_ResourceTexture represents the texture resource +//! for OpenGl_ResourceCleaner +class OpenGl_ResourceTexture : public OpenGl_Resource +{ + +public: + + //! Constructor + OpenGl_ResourceTexture(GLuint theId); + + //! Copy constructor + OpenGl_ResourceTexture(const OpenGl_ResourceTexture& theResource); + + //! Destructor + ~OpenGl_ResourceTexture() { } + +protected: + + //! Clean procedure for texture resource; + //! Should be called by the OpenGl_ResourceCleaner + void Clean(); + +}; + +#endif diff --git a/src/OpenGl/OpenGl_ResourceVBO.cxx b/src/OpenGl/OpenGl_ResourceVBO.cxx new file mode 100755 index 0000000000..7201fe1f59 --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceVBO.cxx @@ -0,0 +1,45 @@ +// File: OpenGl_ResourceVBO.cxx +// Created: 18.03.11 9:50:00 +// Author: Anton POLETAEV + +#include +#include +#include + +typedef void (APIENTRY* PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); + +extern PFNGLDELETEBUFFERSARBPROC glVBODeleteBuffersARB; +extern int VBOExtension; + +//======================================================================= +//function : OpenGl_ResourceVBO +//purpose : Constructor +//======================================================================= + +OpenGl_ResourceVBO::OpenGl_ResourceVBO(GLuint theId) +: OpenGl_Resource(theId) +{ + +} + +//======================================================================= +//function : OpenGl_ResourceVBO +//purpose : Copy constructor +//======================================================================= + +OpenGl_ResourceVBO::OpenGl_ResourceVBO( const OpenGl_ResourceVBO& theResource) +: OpenGl_Resource(theResource) +{ + +} + +//======================================================================= +//function : Clean +//purpose : free OpenGl memory allocated for vbo resource +//======================================================================= + +void OpenGl_ResourceVBO::Clean() +{ + if (VBOExtension) + glVBODeleteBuffersARB( 1 , &myId ); +} diff --git a/src/OpenGl/OpenGl_ResourceVBO.hxx b/src/OpenGl/OpenGl_ResourceVBO.hxx new file mode 100755 index 0000000000..6f212ccb1b --- /dev/null +++ b/src/OpenGl/OpenGl_ResourceVBO.hxx @@ -0,0 +1,37 @@ +// File: OpenGl_ResourceVBO.hxx +// Created: 18.03.11 9:50:00 +// Author: Anton POLETAEV + +#ifndef _OPENGL_RESOURCEVBO_H +#define _OPENGL_RESOURCEVBO_H + +#include +#include + +class OpenGl_Resource; + +//! OpenGl_ResourceVBO represents the Vertex Buffer +//! Object resource (VBO) for OpenGl_ResourceCleaner +class OpenGl_ResourceVBO : public OpenGl_Resource +{ + +public: + + //! Constructor + OpenGl_ResourceVBO(GLuint theId); + + //! Copy constructor + OpenGl_ResourceVBO(const OpenGl_ResourceVBO& theResource); + + //! Destructor + ~OpenGl_ResourceVBO() { } + +protected: + + //! Clean procedure for VBO resource; + //! Should be called by the OpenGl_ResourceCleaner + void Clean(); + +}; + +#endif diff --git a/src/OpenGl/OpenGl_TextureBox.cxx b/src/OpenGl/OpenGl_TextureBox.cxx index 73c2575bcf..f429c64408 100755 --- a/src/OpenGl/OpenGl_TextureBox.cxx +++ b/src/OpenGl/OpenGl_TextureBox.cxx @@ -81,6 +81,8 @@ #include #include #include +#include +#include /*----------------------------------------------------------------------*/ @@ -184,7 +186,6 @@ static GLboolean use_bind_texture = GL_FALSE; * Fonctions privees */ - /*----------------------------------------------------------------------*/ /* * recherche l'existence de datas de texture par son nom @@ -853,6 +854,7 @@ void SetCurrentTexture(TextureID ID) void FreeTexture(TextureID ID) { TextureDataID data; + bool notResource = false; // if there old-style texture deletion #if defined(GL_EXT_texture_object) GLCONTEXT cur_context; @@ -880,24 +882,35 @@ void FreeTexture(TextureID ID) printf("FreeTexture::liberation de %d\n", ID); #endif cur_context = 0; + bool isResource = false; + if (textab[ID].use_bind_texture[i]) { - GL_MAKE_CURRENT(GetCurrentDisplay(), - textab[ID].drawable[i], - textab[ID].context[i]); - - /*This check has been added to avoid exception, - which is raised when trying to delete textures when no rendering context - is available*/ - cur_context = GET_GL_CONTEXT(); - if( cur_context ) - glDeleteTextures(1, &textab[ID].number[i]); + if( !OpenGl_ResourceCleaner::GetInstance()->AddResource(textab[ID].context[i], + new OpenGl_ResourceTexture(textab[ID].number[i])) ) + { + GL_MAKE_CURRENT(GetCurrentDisplay(), + textab[ID].drawable[i], + textab[ID].context[i]); + + /*This check has been added to avoid exception, + which is raised when trying to delete textures when no rendering context + is available*/ + cur_context = GET_GL_CONTEXT(); + if( cur_context ) + glDeleteTextures(1, &textab[ID].number[i]); + notResource = true; + } + else + isResource = true; } - if( cur_context ) + + if( !isResource && cur_context ) glFinish(); } - GL_MAKE_CURRENT(GetCurrentDisplay(),cur_drawable,cur_context); + if( notResource ) + GL_MAKE_CURRENT(GetCurrentDisplay(),cur_drawable,cur_context); texdata[data].status = TEXDATA_NONE; #ifndef IMP141100 diff --git a/src/OpenGl/OpenGl_togl_redraw.cxx b/src/OpenGl/OpenGl_togl_redraw.cxx index 0f933b4136..9e3671196b 100755 --- a/src/OpenGl/OpenGl_togl_redraw.cxx +++ b/src/OpenGl/OpenGl_togl_redraw.cxx @@ -59,6 +59,7 @@ GLboolean g_fBitmap; #include #include #include +#include #include #include @@ -86,7 +87,7 @@ call_togl_redraw aFrameBuffer->BindBuffer(); swap = 0; // no need to swap buffers } - + OpenGl_ResourceCleaner::GetInstance()->Cleanup(); call_func_redraw_all_structs_begin (aview->WsId); if (anunderlayer->ptrLayer) { @@ -162,6 +163,7 @@ call_togl_redraw_area glScissor ((GLint )x, (GLint )((int )aview->DefWindow.dy - (y + height)), (GLsizei )width, (GLsizei )height); + OpenGl_ResourceCleaner::GetInstance()->Cleanup(); call_func_redraw_all_structs_begin (aview->WsId); if (anunderlayer->ptrLayer) { diff --git a/src/OpenGl/OpenGl_txgl.cxx b/src/OpenGl/OpenGl_txgl.cxx index bae2a81970..01b3040637 100755 --- a/src/OpenGl/OpenGl_txgl.cxx +++ b/src/OpenGl/OpenGl_txgl.cxx @@ -83,6 +83,7 @@ Old code resulted in crashes on some ATI Radeon cards under Linux. #include #include +#include #ifdef WNT @@ -312,6 +313,8 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( if( !ctx) return TFailure; + OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true ); + cmap = XCreateColormap( disp, par, vis->visual, AllocNone ); color.red = (unsigned short) (bgcolr * 0xFFFF); @@ -455,12 +458,29 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( return 0; } - if (previous_ctx == 0 ) - { + Standard_Boolean isShared = Standard_True; + + if (previous_ctx == 0 ) previous_ctx = hte -> hGLRC; - } else - wglShareLists(previous_ctx, hte -> hGLRC); + // if we already have some shared context + else + { + // try to share context with one from resource cleaner list + GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext(); + + if (shareCtx != 0) + isShared = (Standard_Boolean)wglShareLists(shareCtx, hte -> hGLRC); + else + { + isShared = (Standard_Boolean)wglShareLists(previous_ctx, hte -> hGLRC); + // add shared previous_ctx to a control list if it's not there + if (isShared) + OpenGl_ResourceCleaner::GetInstance()->AppendContext(previous_ctx, isShared); + } + } + // add the context to OpenGl_ResourceCleaner control list + OpenGl_ResourceCleaner::GetInstance()->AppendContext( hte -> hGLRC, isShared); _Txgl_Map.Bind( (Tint)par, hte ); return par; @@ -771,6 +791,7 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( /* FSXXX sync necessary if non-direct rendering */ glXWaitGL(); + OpenGl_ResourceCleaner::GetInstance()->RemoveContext( ctx ); _Txgl_Map.UnBind( win ); if (previous_ctx == ctx) { @@ -823,12 +844,16 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( if ( --hte -> nUsed == 0 ) { + OpenGl_ResourceCleaner::GetInstance()->RemoveContext( hte -> hGLRC ); #ifdef OCC954 if ( wglGetCurrentContext() != NULL ) #endif wglDeleteContext ( hte -> hGLRC ); ReleaseDC ( win, hte -> hDC ); _Txgl_Map.UnBind( (Tint ) win ); + if( _Txgl_Map.Size() == 0 ) { + previous_ctx = 0; + } delete hte; } diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 5ecfa22e1a..ba4e8487f0 100755 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -1659,17 +1659,17 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(myAISContext.IsNull()) { di << "use 'vinit' command before " << argv[0] << "\n"; - return 0; + return 1; } Handle(AIS_InteractiveObject) TheAisIO; Handle(AIS_TexturedShape) myShape; Standard_Integer myPreviousMode = 0; - if (!argv[1]) + if (argc<2 || !argv[1]) { di << argv[0] <<" syntax error - Type 'help vtex'"<<"\n"; - return 0; + return 1; } TCollection_AsciiString name = argv[1]; @@ -1681,7 +1681,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if (TheAisIO.IsNull()) { di <<"shape "<IsKind(STANDARD_TYPE(AIS_TexturedShape)) && !TheAisIO.IsNull()) @@ -1691,7 +1691,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha } else { - myAISContext->Erase(TheAisIO,Standard_False); + myAISContext->Clear(TheAisIO,Standard_False); myShape = new AIS_TexturedShape (DBRep::Get(argv[1])); GetMapOfAIS().UnBind1(TheAisIO); GetMapOfAIS().UnBind2(name); @@ -1703,9 +1703,9 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(argc<=1) { di << argv[0] <<" syntax error - Type 'help vtex'" << "\n"; - return 0; + return 1; } - if (argv[2]) + if (argc>2 && argv[2]) { if(strcasecmp(argv[2],"?")==0) { @@ -1744,7 +1744,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(argc<2) { di << argv[0] <<" syntax error - Type 'help vtex'" << "\n"; - return 0; + return 1; } myShape->SetTextureScale (( argv[2] ? Standard_True : Standard_False ), @@ -1756,7 +1756,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(argc<2) { di << argv[0] <<" syntax error - Type 'help vtex'" << "\n"; - return 0; + return 1; } myShape->SetTextureOrigin (( argv[2] ? Standard_True : Standard_False ), ( argv[2] ? atof(argv[2]) : 0.0 ), @@ -1767,9 +1767,9 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(argc<2) { di << argv[0] <<" syntax error - Type 'help vtex'" << "\n"; - return 0; + return 1; } - if (argv[2]) + if (argc>2 && argv[2]) { di <<"Texture repeat enabled"<<"\n"; myShape->SetTextureRepeat(Standard_True, atof(argv[2]), atof(argv[argc-1]) ); @@ -1789,7 +1789,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha if(argc<2) { di << argv[0] <<" syntax error - Type 'help vtex'" << "\n"; - return 0; + return 1; } myShape->SetTextureRepeat(Standard_False); myShape->SetTextureOrigin(Standard_False); @@ -1805,7 +1805,7 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha myAISContext->Display(myShape, Standard_True); myAISContext->Update(myShape,Standard_True); } - return 1; + return 0; } //============================================================================== diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 589dc114e4..b736fcf367 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -24,7 +24,7 @@ #include #include - +#include #include #include #include @@ -91,7 +91,7 @@ extern Handle(AIS_InteractiveContext)& TheAISContext(); //============================================================================== //function : Vtrihedron 2d //purpose : Create a plane with a 2D trihedron from a faceselection -//Draw arg : vtri2d name +//Draw arg : vtri2d name //============================================================================== #include @@ -105,7 +105,7 @@ static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char // Declarations Standard_Integer myCurrentIndex; - // Fermeture des contextes + // Fermeture des contextes TheAISContext()->CloseAllContexts(); // Ouverture d'un contexte local et recuperation de son index. TheAISContext()->OpenLocalContext(); @@ -133,7 +133,7 @@ static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE); TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() ); - // declarations + // declarations gp_Pnt A,B,C; // si il y a plusieurs edges @@ -167,7 +167,7 @@ static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char TheAISContext()->Display(theAISPlaneTri ); GetMapOfAIS().Bind ( theAISPlaneTri ,argv[1]); - return 0; + return 0; } @@ -219,7 +219,7 @@ static int VTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** GetMapOfAIS().Bind(aShape,name); TheAISContext()->Display(aShape); - return 0; + return 0; } @@ -241,7 +241,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv Standard_Boolean ThereIsName; Standard_Boolean ThereIsCurrent; Standard_Real value; - Standard_Boolean hascol; + Standard_Boolean hascol; #ifdef DEB Quantity_NameOfColor col; #else @@ -257,7 +257,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv else {ThereIsName=Standard_True;value=atof(argv[2]);} // On ferme le contexte local pour travailler dans le contexte global - if(TheAISContext()->HasOpenedContext()) + if(TheAISContext()->HasOpenedContext()) TheAISContext()->CloseLocalContext(); // On set le booleen ThereIsCurrent @@ -269,7 +269,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv //=============================================================== // Il n'y a pas de nom mais des objets selectionnes //=============================================================== - if (!ThereIsName && ThereIsCurrent) + if (!ThereIsName && ThereIsCurrent) { ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName @@ -283,7 +283,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv if (!aShape.IsNull() && TheAISContext()->IsCurrent(aShape) ) { - // On verifie que l'AIS InteraciveObject selectionne est bien + // On verifie que l'AIS InteraciveObject selectionne est bien // un AIS_Trihedron if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) { @@ -342,7 +342,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name)); - // On verifie que l'AIS InteraciveObject est bien + // On verifie que l'AIS InteraciveObject est bien // un AIS_Trihedron if (!aShape.IsNull() && aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) @@ -375,7 +375,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv } } } - return 0; + return 0; } @@ -384,7 +384,7 @@ static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv //============================================================================== //function : VPlaneTrihedron //purpose : Create a plane from a trihedron selection. If no arguments are set, the default -//Draw arg : vplanetri name +//Draw arg : vplanetri name //============================================================================== #include @@ -401,7 +401,7 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c // Fermeture des contextes locaux TheAISContext()->CloseAllContexts(); - // On recupere tous les trihedrons de la GetMapOfAIS() + // On recupere tous les trihedrons de la GetMapOfAIS() // et on active le mode de selection par face. // ================================================= @@ -448,14 +448,14 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c TheAISContext()->Display(PlaneB ); GetMapOfAIS().Bind ( PlaneB ,argv[1]); - return 0; + return 0; } //============================================================================== // Fonction First click 2de click -// +// // vaxis vertex vertex // edge None // vaxispara edge vertex @@ -465,7 +465,7 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c //============================================================================== //function : VAxisBuilder -//purpose : +//purpose : //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb //============================================================================== #include @@ -473,7 +473,7 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c #include #include -static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { // Declarations Standard_Boolean HasArg; @@ -523,7 +523,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvv = (const char **) buff; while (ViewerMainLoop( argcc, argvv) ) { } - // fin de la boucle + // fin de la boucle // recuperation de la shape. TopoDS_Shape ShapeA; @@ -547,7 +547,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { ShapeB = TheAISContext()->SelectedShape(); } @@ -558,7 +558,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* // Fermeture du context local TheAISContext()->CloseLocalContext(MyCurrentIndex); - // Construction de l'axe + // Construction de l'axe gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) ); gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) ); gp_Vec V (A,B); @@ -567,12 +567,12 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect); GetMapOfAIS().Bind (TheAxis,name); TheAISContext()->Display(TheAxis); - } + } else { // Un unique edge (ShapeA) a ete picke // Fermeture du context local TheAISContext()->CloseLocalContext(MyCurrentIndex); - // Constuction de l'axe + // Constuction de l'axe TopoDS_Edge ed =TopoDS::Edge(ShapeA); TopoDS_Vertex Va,Vb; TopExp::Vertices(ed,Va,Vb ); @@ -595,7 +595,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* TheAISContext()->OpenLocalContext(); MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal(); - // Active le mode edge + // Active le mode edge TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) ); di<<" Select an edge."<<"\n"; @@ -604,7 +604,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvv = (const char **) buff; while (ViewerMainLoop( argcc, argvv) ) { } - // fin de la boucle + // fin de la boucle TopoDS_Shape ShapeA; for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { @@ -620,7 +620,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle // On peut choisir un pnt sur l'edge TopoDS_Shape ShapeB; @@ -651,7 +651,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* TheAISContext()->OpenLocalContext(); MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal(); - // Active le mode edge + // Active le mode edge TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) ); di<<" Select an edge."<<"\n"; @@ -660,7 +660,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvv = (const char **) buff; while (ViewerMainLoop( argcc, argvv) ) { } - // fin de la boucle + // fin de la boucle TopoDS_Shape ShapeA; for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { @@ -676,7 +676,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle // On peut choisir un pnt sur l'edge TopoDS_Shape ShapeB; @@ -710,7 +710,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* //============================================================================== // Fonction First click Result -// +// // vpoint vertex AIS_Point=Vertex // edge AIS_Point=Middle of the edge //============================================================================== @@ -726,7 +726,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* #include #include -static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { // Declarations Standard_Boolean HasArg; @@ -811,7 +811,7 @@ static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char } //============================================================================== -// Fonction 1st click 2de click 3de click +// Fonction 1st click 2de click 3de click // vplane Vertex Vertex Vertex // Vertex Edge // Edge Vertex @@ -843,7 +843,7 @@ static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char #include #include -static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { // Declarations Standard_Boolean HasArg; @@ -895,7 +895,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char return 1; } - // Traitement des objets A,B,C + // Traitement des objets A,B,C // Downcaste de AIS_IO en AIS_Point Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA; Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB; @@ -939,7 +939,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char TheAISContext()->Display(myAISPlane); } - // si le premier argument est un AIS_Axis 2 + // si le premier argument est un AIS_Axis 2 // creation d'un plan orthogonal a l'axe passant par un point else if (theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==2 ) { // le deuxieme argument doit etre un AIS_Point @@ -959,7 +959,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char return 1; } - // Traitement des objets A et B + // Traitement des objets A et B Handle(AIS_Axis) theAISAxisA= *(Handle(AIS_Axis)*)& theShapeA; Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB; @@ -1000,7 +1000,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char return 1; } - // Traitement des objets A et B + // Traitement des objets A et B Handle(AIS_Plane) theAISPlaneA= *(Handle(AIS_Plane)*)& theShapeA; Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB; @@ -1085,10 +1085,10 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char // ShapeC est aussi un vertex... if (ShapeC.IsSame(ShapeA)||ShapeC.IsSame(ShapeB) ) {di<<" vplane: error, same points selected"<<"\n";return 1; } - // Fermeture du contexte local + // Fermeture du contexte local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) ); gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB ) ); gp_Pnt C=BRep_Tool::Pnt(TopoDS::Vertex(ShapeC ) ); @@ -1112,9 +1112,9 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char } else { // le vertex n'appartient pes a l'edge on peut construire le plane - // Fermeture du contexte local + // Fermeture du contexte local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane gp_Pnt A=BRep_Tool::Pnt(VertA ); TopoDS_Vertex VBa,VBb; TopExp::Vertices(EdgeB ,VBa ,VBb ); @@ -1161,9 +1161,9 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char } else { // le vertex n'appartient pas a l'edge on peut construire le plane - // Fermeture du contexte local + // Fermeture du contexte local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane gp_Pnt B=BRep_Tool::Pnt(VertB ); TopoDS_Vertex VAa,VAb; TopExp::Vertices(EdgeA ,VAa ,VAb ); @@ -1183,7 +1183,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char else { // Fermeture du contexte local: Plus rien a selectionner TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane TopoDS_Face myFace=TopoDS::Face(ShapeA); BRepAdaptor_Surface mySurface (myFace, Standard_False ); if (mySurface.GetType()==GeomAbs_Plane ) { @@ -1210,7 +1210,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char TheAISContext()->OpenLocalContext(); myCurrentIndex=TheAISContext()->IndexOfCurrentLocal(); - // Active les modes Vertex et Face + // Active les modes Vertex et Face TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) ); TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) ); di<<" Select a vertex or a face."<<"\n"; @@ -1249,7 +1249,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char // Fermeture du context local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) ); TopoDS_Face myFace=TopoDS::Face(ShapeB); @@ -1290,7 +1290,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char // Fermeture du context local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB ) ); TopoDS_Face myFace=TopoDS::Face(ShapeA); @@ -1321,7 +1321,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char TheAISContext()->OpenLocalContext(); myCurrentIndex=TheAISContext()->IndexOfCurrentLocal(); - // Active les modes Edge et Face + // Active les modes Edge et Face TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) ); TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) ); di<<" Select a face and an edge coplanar."<<"\n"; @@ -1359,7 +1359,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char // Fermeture du context local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA); TopoDS_Vertex VAa,VAb; // vi @@ -1369,8 +1369,8 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char gp_Vec ab (Aa,Ab); gp_Dir Dab (ab); - // Creation de mon axe de rotation - gp_Ax1 myRotAxis (Aa,Dab); + // Creation de mon axe de rotation + gp_Ax1 myRotAxis (Aa,Dab); TopoDS_Face myFace=TopoDS::Face(ShapeB); // Il faut imperativement que l'edge soit parallele a la face @@ -1379,7 +1379,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char BRepExtrema_ExtPF myHauteurB (VAb , myFace ); // on compare les deux hauteurs a la tolerance pres if ( fabs(sqrt(myHauteurA.SquareDistance(1)) - sqrt (myHauteurB.SquareDistance(1)) )>0.1 ) { - // l'edge n'est pas parallele a la face + // l'edge n'est pas parallele a la face di<<" vplaneOrtho error: l'edge n'est pas parallele a la face."<<"\n";return 1; } // l'edge est OK @@ -1424,7 +1424,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char // Fermeture du context local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du plane + // Construction du plane TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB); TopoDS_Vertex VBa,VBb; TopExp::Vertices(EdgeB ,VBa ,VBb ); @@ -1432,8 +1432,8 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char gp_Pnt Bb=BRep_Tool::Pnt(VBb); gp_Vec ab (Ba,Bb); gp_Dir Dab (ab); - // Creation de mon axe de rotation - gp_Ax1 myRotAxis (Ba,Dab); + // Creation de mon axe de rotation + gp_Ax1 myRotAxis (Ba,Dab); TopoDS_Face myFace=TopoDS::Face(ShapeA); // Il faut imperativement que l'edge soit parallele a la face @@ -1441,7 +1441,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char BRepExtrema_ExtPF myHauteurB (VBb , myFace ); // on compare les deux hauteurs a la tolerance pres if ( fabs(sqrt(myHauteurA.SquareDistance(1)) - sqrt(myHauteurB.SquareDistance(1)) )>0.1 ) { - // l'edge n'est pas parallele a la face + // l'edge n'est pas parallele a la face di<<" vplaneOrtho error: l'edge n'est pas parallele a la face."<<"\n";return 1; } // l'edge est OK @@ -1479,7 +1479,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char //============================================================================== //function : VLineBuilder -//purpose : Build an AIS_Line +//purpose : Build an AIS_Line //Draw arg : vline LineName [AIS_PointName] [AIS_PointName] // [Xa] [Ya] [Za] [Xb] [Yb] [Zb] //============================================================================== @@ -1487,7 +1487,7 @@ static int VPlaneBuilder(Draw_Interpretor& di, Standard_Integer argc, const char #include -static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { Standard_Integer myCurrentIndex; // Verifications @@ -1517,7 +1517,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* return 1; } } - else {di <<"vline error: wrong type of 1st argument."<<"\n";return 1; } + else {di <<"vline error: wrong type of 1st argument."<<"\n";return 1; } // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA; Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB; @@ -1545,7 +1545,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* // ================== else if (argc==8) { - // On verifie que les deux points ne sont pas confondus + // On verifie que les deux points ne sont pas confondus Standard_Real coord[6]; for(Standard_Integer i=0;i<=2;i++){ @@ -1598,7 +1598,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { ShapeB = TheAISContext()->SelectedShape(); @@ -1639,7 +1639,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* //============================================================================== //function : VCircleBuilder -//purpose : Build an AIS_Circle +//purpose : Build an AIS_Circle //Draw arg : vcircle CircleName PlaneName PointName Radius // PointName PointName PointName //============================================================================== @@ -1650,7 +1650,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char* #include #include -static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) { Standard_Integer myCurrentIndex; // verification of the arguments @@ -1674,7 +1674,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha { if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) { di<<"vcircle error: 2de argument is unexpected to be a point."<<"\n"; - return 1; + return 1; } // Le troisieme objet doit etre un point Handle(AIS_InteractiveObject) theShapeC = @@ -1682,7 +1682,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha if (theShapeC.IsNull() || theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) { di<<"vcircle error: 3de argument is unexpected to be a point."<<"\n"; - return 1; + return 1; } // tag // On verifie que les 3 points sont differents. @@ -1701,15 +1701,15 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha // Test A=B if (myCartPointA->X()==myCartPointB->X() && myCartPointA->Y()==myCartPointB->Y() && myCartPointA->Z()==myCartPointB->Z() ) { - di<<"vcircle error: Same points."<<"\n";return 1; + di<<"vcircle error: Same points."<<"\n";return 1; } // Test A=C if (myCartPointA->X()==myCartPointC->X() && myCartPointA->Y()==myCartPointC->Y() && myCartPointA->Z()==myCartPointC->Z() ) { - di<<"vcircle error: Same points."<<"\n";return 1; + di<<"vcircle error: Same points."<<"\n";return 1; } // Test B=C if (myCartPointB->X()==myCartPointC->X() && myCartPointB->Y()==myCartPointC->Y() && myCartPointB->Z()==myCartPointC->Z() ) { - di<<"vcircle error: Same points."<<"\n";return 1; + di<<"vcircle error: Same points."<<"\n";return 1; } // Construction du cercle GC_MakeCircle Cir=GC_MakeCircle (myCartPointA->Pnt(),myCartPointB->Pnt(),myCartPointC->Pnt() ); @@ -1724,7 +1724,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha // =================================== else if (theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==7 ) { if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) { - di<<"vcircle error: 2de element is a unexpected to be a point."<<"\n";return 1; + di<<"vcircle error: 2de element is a unexpected to be a point."<<"\n";return 1; } // On verifie que le rayon est bien >=0 if (atof(argv[4])<=0 ) {di<<"vcircle error: the radius must be >=0."<<"\n";return 1; } @@ -1795,7 +1795,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { ShapeB = TheAISContext()->SelectedShape(); @@ -1814,7 +1814,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvvv = (const char **) buffff; while (ViewerMainLoop( argcccc, argvvvv) ) { } - // fin de la boucle + // fin de la boucle for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { ShapeC = TheAISContext()->SelectedShape(); @@ -1826,7 +1826,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha // Fermeture du context local TheAISContext()->CloseLocalContext(myCurrentIndex); - // Construction du cercle + // Construction du cercle gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) ); gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) ); gp_Pnt C=BRep_Tool::Pnt(TopoDS::Vertex(ShapeC) ); @@ -1849,7 +1849,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" }; const char **argvvv = (const char **) bufff; while (ViewerMainLoop( argccc, argvvv) ) { } - // fin de la boucle + // fin de la boucle for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) { ShapeB = TheAISContext()->SelectedShape(); @@ -1906,7 +1906,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha #include #include #include -#include +#include #include #include #include @@ -1930,7 +1930,7 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha #include #include -#include +#include DEFINE_STANDARD_HANDLE(MyTextClass, AIS_InteractiveObject) @@ -1943,15 +1943,15 @@ public: MyTextClass(){}; - MyTextClass + MyTextClass ( const TCollection_ExtendedString& , const gp_Pnt& , - Quantity_Color color, - Standard_Integer aHJust, + Quantity_Color color, + Standard_Integer aHJust, Standard_Integer aVJust , - Standard_Real Angle , - Standard_Boolean Zoom , - Standard_Real Height, + Standard_Real Angle , + Standard_Boolean Zoom , + Standard_Real Height, OSD_FontAspect FontAspect, Standard_CString Font ); @@ -1963,7 +1963,7 @@ private: const Standard_Integer aMode); void ComputeSelection ( const Handle(SelectMgr_Selection)& aSelection, - const Standard_Integer aMode){} ; + const Standard_Integer aMode){} ; protected: TCollection_ExtendedString aText; @@ -1972,10 +1972,10 @@ protected: Standard_Real Green; Standard_Real Blue; Standard_Real aAngle; - Standard_Real aHeight; + Standard_Real aHeight; Standard_Boolean aZoomable; Quantity_Color aColor; - Standard_CString aFont; + Standard_CString aFont; OSD_FontAspect aFontAspect; Graphic3d_HorizontalTextAlignment aHJustification; Graphic3d_VerticalTextAlignment aVJustification; @@ -1984,13 +1984,13 @@ protected: IMPLEMENT_STANDARD_HANDLE(MyTextClass, AIS_InteractiveObject) -IMPLEMENT_STANDARD_RTTIEXT(MyTextClass, AIS_InteractiveObject) +IMPLEMENT_STANDARD_RTTIEXT(MyTextClass, AIS_InteractiveObject) -MyTextClass::MyTextClass( const TCollection_ExtendedString& text, const gp_Pnt& position, - Quantity_Color color = Quantity_NOC_YELLOW, - Standard_Integer aHJust = Graphic3d_HTA_LEFT, +MyTextClass::MyTextClass( const TCollection_ExtendedString& text, const gp_Pnt& position, + Quantity_Color color = Quantity_NOC_YELLOW, + Standard_Integer aHJust = Graphic3d_HTA_LEFT, Standard_Integer aVJust = Graphic3d_VTA_BOTTOM, Standard_Real angle = 0.0 , Standard_Boolean zoomable = Standard_True, @@ -1999,12 +1999,12 @@ MyTextClass::MyTextClass( const TCollection_ExtendedString& text, const gp_Pnt& Standard_CString font = "Courier") { aText = text; - aPosition = position; + aPosition = position; aHJustification = Graphic3d_HorizontalTextAlignment(aHJust); aVJustification = Graphic3d_VerticalTextAlignment(aVJust); aAngle = angle; - aZoomable = zoomable; - aHeight = height; + aZoomable = zoomable; + aHeight = height; aColor = color; aFontAspect = fontAspect; aFont = font; @@ -2027,12 +2027,12 @@ void MyTextClass::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentat asp->SetHeight(aHeight); // I am changing the myHeight value asp->SetHorizontalJustification(aHJustification); - asp->SetVerticalJustification(aVJustification); + asp->SetVerticalJustification(aVJustification); asp->Aspect()->SetTextZoomable(aZoomable); asp->Aspect()->SetTextAngle(aAngle); asp->Aspect()->SetTextFontAspect(aFontAspect); Prs3d_Text::Draw(aPresentation, asp, aText, aPosition); - + /* This comment code is worked Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation); Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect(); @@ -2073,7 +2073,7 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** G = atof(argv[6])/255.; B = atof(argv[7])/255.; - hor_align = atoi(argv[8]); + hor_align = atoi(argv[8]); ver_align = atoi(argv[9]); angle = atof(argv[10]); @@ -2091,16 +2091,16 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** if(argc == 16) { font.AssignCat(argv[14]); - font.AssignCat(" "); - font.AssignCat(argv[15]); + font.AssignCat(" "); + font.AssignCat(argv[15]); } - if(argc == 17) - { + if(argc == 17) + { font.AssignCat(argv[14]); - font.AssignCat(" "); + font.AssignCat(" "); font.AssignCat(argv[15]); - font.AssignCat(" "); - font.AssignCat(argv[16]); + font.AssignCat(" "); + font.AssignCat(argv[16]); } aColor.SetValues( R, G, B, Quantity_TOC_RGB ); @@ -2111,12 +2111,12 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** aContext->Display(my,Standard_True); - if(aContext.IsNull()) - { + if(aContext.IsNull()) + { di << "use 'vinit' command before " << argv[0] << "\n"; return -1; } - return 0; + return 0; } #include @@ -2159,7 +2159,7 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** //purpose : Create a Sphere //=============================================================================================== -Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z , +Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z , int res , double Radius ){ double mRadius = Radius; @@ -2222,7 +2222,7 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z number_pointArray++; numPoles++; } - + // Check data, determine increments, and convert to radians startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta); startTheta *= Standard_PI / 180.0; @@ -2260,7 +2260,7 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z if ( mStartPhi <= 0.0 ) { // around north pole number_triangle += localThetaResolution; } - + if ( mEndPhi >= 180.0 ) { // around south pole number_triangle += localThetaResolution; } @@ -2319,7 +2319,7 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z number_triangle++; } } - + if ( mEndPhi >= 180.0 ){ // around south pole numOffset = phiResolution - 1 + numPoles; for (i=0; i < localThetaResolution; i++){ @@ -2332,7 +2332,7 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z } // bands in-between poles - + for (i=0; i < localThetaResolution; i++){ for (j=0; j < (phiResolution-1); j++){ pts[0] = phiResolution*i + j + numPoles; @@ -2369,9 +2369,9 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z Standard_Real modmax = eqPlan.Modulus(); - if(modmax > Tol) + if(modmax > Tol) Nor = gp_Dir(eqPlan); - else + else Nor = gp_Dir(0., 0., 1.); Standard_Integer j = (i - PointsOfArray.Lower()) * 3; @@ -2390,138 +2390,176 @@ Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z //function : VDrawSphere //author : psn //purpose : Create an AIS shape. -//Draw arg : vdrawsphere [X] [Y] [Z] [Rezolution] [Radius] [VBOEnabled] //=============================================================================================== +static int VDrawSphere (Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + // check for errors + Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext(); + if (aContextAIS.IsNull()) + { + std::cout << "Call vinit before!\n"; + return 1; + } + else if (argc < 3) + { + std::cout << "Use: " << argv[0] + << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToEnableVBO=1] [NumberOfViewerUpdate=1] [ToShowEdges=0]\n"; + return 1; + } -#include - -static int VDrawSphere (Draw_Interpretor& di, Standard_Integer argc, const char** argv){ - // Verification des arguments - if ( argc > 9 ) {di< 5) ? atof (argv[3]) : 0.0; + Standard_Real aCenterY = (argc > 5) ? atof (argv[4]) : 0.0; + Standard_Real aCenterZ = (argc > 5) ? atof (argv[5]) : 0.0; + Standard_Real aRadius = (argc > 6) ? atof (argv[6]) : 100.0; + Standard_Boolean isVBOEnabled = (argc > 7) ? atoi (argv[7]) : Standard_True; + Standard_Integer aRedrawsNb = (argc > 8) ? atoi (argv[8]) : 1; + Standard_Boolean toShowEdges = (argc > 9) ? atoi (argv[9]) : Standard_False; + + if (aRedrawsNb <= 0) + { + aRedrawsNb = 1; + } - Standard_Real X,Y,Z; - X = atof(argv[1]); - Y = atof(argv[2]); - Z = atof(argv[3]); - - Standard_Integer Rezolution = atoi(argv[4]); - Standard_Real Radius = atof(argv[5]); - Standard_Integer VBOenabled = atoi(argv[6]);; - Standard_Integer NumberOfViewerUpdate = 1; - Standard_Integer ShowEdges = 0; - - if( argc == 9) - ShowEdges = atoi(argv[8]); - if( argc == 8) - NumberOfViewerUpdate = atoi(argv[7]); - if( argc == 7) - NumberOfViewerUpdate = 1; - - Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); - //ViewerTest::CurrentView()->SetTransparency(Standard_True); - - //enable VBO - Handle(Graphic3d_GraphicDriver) aDriver = - Handle(Graphic3d_GraphicDriver)::DownCast(aContext->CurrentViewer()->Device()->GraphicDriver() ); - - aDriver->EnableVBO( VBOenabled ); - - Standard_Integer numberTriangles = 0, numberPoints = 0; - printf("Compute Triangulation...\n"); - Handle(AIS_Triangulation) myShape = new AIS_Triangulation(CalculationOfSphere( X, Y, Z, - Rezolution, - Radius)); - numberPoints = myShape->GetTriangulation()->Nodes().Length(); - numberTriangles = myShape->GetTriangulation()->Triangles().Length(); - - Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger(1,numberPoints); - int color = 0; - int red = 0 ; - int green = 255 ; - int blue = 0 ; - int alpha = 0 ; // not used - color = red; - color += green << 8; - color += blue << 16; - color += alpha << 24; - for( int i = 1; i <= numberPoints ; i++ ){ - aColorArray->SetValue( i,color ); + // remove AIS object with given name from map + if (GetMapOfAIS().IsBound2 (aShapeName)) + { + Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aShapeName); + Handle(AIS_InteractiveObject) anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj); + if (anInterObj.IsNull()) + { + std::cout << "Shape name was used for non AIS viewer\n!"; + return 1; + } + aContextAIS->Remove (anInterObj, Standard_False); + GetMapOfAIS().UnBind2 (aShapeName); + } + + // enable/disable VBO + Handle(Graphic3d_GraphicDriver) aDriver = + Handle(Graphic3d_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Device()->GraphicDriver()); + if (!aDriver.IsNull()) + { + aDriver->EnableVBO (isVBOEnabled); + } + + std::cout << "Compute Triangulation...\n"; + Handle(AIS_Triangulation) aShape + = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ, + aResolution, + aRadius)); + Standard_Integer aNumberPoints = aShape->GetTriangulation()->Nodes().Length(); + Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length(); + + // register the object in map + GetMapOfAIS().Bind (aShape, aShapeName); + + // stupid initialization of Green color in RGBA space as integer + // probably wrong for big-endian CPUs + Standard_Integer aRed = 0; + Standard_Integer aGreen = 255; + Standard_Integer aBlue = 0; + Standard_Integer anAlpha = 0; // not used + Standard_Integer aColorInt = aRed; + aColorInt += aGreen << 8; + aColorInt += aBlue << 16; + aColorInt += anAlpha << 24; + + // setup colors array per vertex + Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints); + for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId) + { + aColorArray->SetValue (aNodeId, aColorInt); } - //enable or disable color - myShape->SetColors(aColorArray); - - printf("NumberOfPoints = %.i \n",numberPoints); - printf("NumberOfTriangles = %.i \n",numberTriangles); - int PointsSize = numberPoints * 12; - int NormalsSize = numberPoints * 12; - int ColorsSize = numberPoints * 12; - int TrianglesSize = numberTriangles * 3 * 4; - int PolyConnectSize = numberPoints * 4 + numberTriangles * 6 * 4; - int size = PointsSize + NormalsSize + ColorsSize + TrianglesSize ; - size>>=20;//MB - NormalsSize >>= 20; - ColorsSize >>= 20; - TrianglesSize >>= 20; - PolyConnectSize >>= 20; - printf("Amount of memory required for PolyTriangulation without Normals: %i Mb \n", size - NormalsSize ); - printf("Amount of memory for colors: %i Mb \n",ColorsSize); - printf("Amount of memory for PolyConnect: %i Mb \n", PolyConnectSize ); - printf("Amount of graphic card memory required: %i Mb \n",size); + aShape->SetColors (aColorArray); + + // show statistics + Standard_Integer aPointsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat + Standard_Integer aNormalsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat + Standard_Integer aColorsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat without alpha + Standard_Integer aTrianglesSize = aNumberTriangles * 3 * sizeof(int); // 3x GLint + Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4; + Standard_Integer aTotalSize = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize; + aTotalSize >>= 20; //MB + aNormalsSize >>= 20; + aColorsSize >>= 20; + aTrianglesSize >>= 20; + aPolyConnectSize >>= 20; + std::cout << "NumberOfPoints: " << aNumberPoints << "\n" + << "NumberOfTriangles: " << aNumberTriangles << "\n" + << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n" + << "Amount of memory for colors: " << aColorsSize << " Mb\n" + << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n" + << "Amount of graphic card memory required: " << aTotalSize << " Mb\n"; // Setting material properties, very important for desirable visual result! - Graphic3d_MaterialAspect aMat( Graphic3d_NOM_PLASTIC ); - aMat.SetAmbient( 0.2 ); - aMat.SetSpecular( 0.5 ); - Handle(Graphic3d_AspectFillArea3d) aspect = new Graphic3d_AspectFillArea3d( Aspect_IS_SOLID, - Quantity_NOC_RED, - Quantity_NOC_YELLOW, - Aspect_TOL_SOLID, - 1., - aMat, - aMat); + Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC); + aMat.SetAmbient (0.2); + aMat.SetSpecular (0.5); + Handle(Graphic3d_AspectFillArea3d) anAspect + = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, + Quantity_NOC_RED, + Quantity_NOC_YELLOW, + Aspect_TOL_SOLID, + 1.0, + aMat, + aMat); Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect(); - - if( ShowEdges > 0 ) - aspect->SetEdgeOn(); + if (toShowEdges) + { + anAspect->SetEdgeOn(); + } else - aspect->SetEdgeOff(); - - aShAsp -> SetAspect( aspect ); - //aShAsp -> SetTransparency( 0.5 ); - myShape -> Attributes() -> SetShadingAspect( aShAsp ); - - aContext->Display(myShape,Standard_False); + { + anAspect->SetEdgeOff(); + } + aShAsp->SetAspect (anAspect); + aShape->Attributes()->SetShadingAspect (aShAsp); - const Handle(V3d_Viewer)& viewer = aContext->CurrentViewer(); + aContextAIS->Display (aShape, Standard_False); // Two viewer updates are needed in order to measure time spent on - // loading triangulation to graphic card memory + redrawing (1st update) and + // loading triangulation to graphic card memory + redrawing (1st update) and // time spent on redrawing itself (2nd and all further updates) - OSD_Chronometer timer; - Standard_Real UserSeconds, SystemSeconds; - timer.Start(); - for ( int repeat = 0; repeat < NumberOfViewerUpdate; repeat++ ){ - for (viewer->InitActiveViews();viewer->MoreActiveViews();viewer->NextActiveViews()) + OSD_Chronometer aTimer; + Standard_Real aUserSeconds, aSystemSeconds; + aTimer.Start(); + const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer(); + for (Standard_Integer anInteration = 0; anInteration < aRedrawsNb; ++anInteration) + { + for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews()) { - if( repeat == 0 ) - viewer->ActiveView()->Update(); + if (anInteration == 0) + { + aViewer->ActiveView()->Update(); + } else - viewer->ActiveView()->Redraw(); + { + aViewer->ActiveView()->Redraw(); + } } } - timer.Show(UserSeconds,SystemSeconds); - timer.Stop(); - printf("Number of scene redrawings: %.i \n", NumberOfViewerUpdate); - printf("User Seconds: %.20f sec \n", UserSeconds); - printf("System Seconds: %.20f sec \n", SystemSeconds); - printf("Average time of scene redrawing : %.20f sec \n", (UserSeconds)/(Standard_Real)NumberOfViewerUpdate); + aTimer.Show (aUserSeconds, aSystemSeconds); + aTimer.Stop(); + std::cout << "Number of scene redrawings: " << aRedrawsNb << "\n" + << "CPU user time: " + << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * aUserSeconds + << " msec\n" + << "CPU system time: " + << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * aSystemSeconds + << " msec\n" + << "CPU average time of scene redrawing: " + << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * (aUserSeconds / (Standard_Real )aRedrawsNb) + << " msec\n"; return 0; } //======================================================================= //function : ObjectsCommands -//purpose : +//purpose : //======================================================================= void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) @@ -2531,11 +2569,11 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vtrihedron : vtrihedron name [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw] ", __FILE__,VTrihedron,group); - theCommands.Add("vtri2d", + theCommands.Add("vtri2d", "vtri2d Name Selection in the viewer only ", __FILE__,VTrihedron2D ,group); - theCommands.Add("vplanetri", + theCommands.Add("vplanetri", "vplanetri Name Selection in the viewer only ", __FILE__,VPlaneTrihedron ,group); @@ -2547,7 +2585,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vaxis nom [Xa] [Ya] [Za] [Xb] [Yb] [Zb]", __FILE__,VAxisBuilder,group); - theCommands.Add("vaxispara", + theCommands.Add("vaxispara", "vaxispara nom ", __FILE__,VAxisBuilder,group); @@ -2571,7 +2609,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vplaneortho PlaneName ", __FILE__,VPlaneBuilder,group); - theCommands.Add("vline", + theCommands.Add("vline", "vline: vline LineName [Xa/PointName] [Ya/PointName] [Za] [Xb] [Yb] [Zb] ", __FILE__,VLineBuilder,group); @@ -2584,7 +2622,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) __FILE__,VDrawText,group); theCommands.Add("vdrawsphere", - "vdrawsphere: VDrawSphere X Y Z Fineness Radius EnableVBO [NumberOfViewerUpdate(Default=1)] [ShowEdges(Default=0)]", + "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToEnableVBO=1] [NumberOfViewerUpdate=1] [ToShowEdges=0]\n", __FILE__,VDrawSphere,group); } -- 2.20.1