diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cdl b/src/Graphic3d/Graphic3d_GraphicDriver.cdl index c548b89e84..3f6c369283 100755 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cdl +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cdl @@ -1323,6 +1323,15 @@ is ProgressBarFunc : Address from Standard = NULL; ProgressObject : Address from Standard = NULL ) is deferred; + RemovePrimitiveArray( me : mutable; + theCGroup : CGroup from Graphic3d; + thePArray : PrimitiveArray from Graphic3d ) + is deferred; + ---Purpose: Clear visualization data in graphical driver and + -- stop displaying the primitives array of the graphical group + -- . This method is internal and should be used + -- by Graphic3d_Group only. + -------------------------- -- Category: Class methods -------------------------- diff --git a/src/Graphic3d/Graphic3d_Group_1.cxx b/src/Graphic3d/Graphic3d_Group_1.cxx index 4d7fb59c5f..49110918bb 100755 --- a/src/Graphic3d/Graphic3d_Group_1.cxx +++ b/src/Graphic3d/Graphic3d_Group_1.cxx @@ -69,6 +69,10 @@ void Graphic3d_Group::Destroy () { cout << "Graphic3d_Group::Destroy ()\n"; #endif + // tell graphics driver to clear internal resources of the group + if (!IsEmpty () && !MyGraphicDriver.IsNull ()) + MyGraphicDriver->ClearGroup (MyCGroup); + } void Graphic3d_Group::Remove () { diff --git a/src/Graphic3d/Graphic3d_Group_13.cxx b/src/Graphic3d/Graphic3d_Group_13.cxx index 9f0f8c5fd3..f607fff7dc 100755 --- a/src/Graphic3d/Graphic3d_Group_13.cxx +++ b/src/Graphic3d/Graphic3d_Group_13.cxx @@ -45,8 +45,17 @@ void Graphic3d_Group :: AddPrimitiveArray ( const Handle(Graphic3d_ArrayOfPrimit } void Graphic3d_Group :: RemovePrimitiveArrays () { + // clear primitives array's visualization data in graphics driver and remove + // references to it in driver + if (!IsEmpty() && !MyGraphicDriver.IsNull()) + { + for (Graphic3d_ListIteratorOfListOfPArray it (MyListOfPArray); + it.More(); it.Next()) + MyGraphicDriver->RemovePrimitiveArray (MyCGroup, it.Value()->Array()); + } - MyListOfPArray.Clear(); + // remove references to primitives arrays + MyListOfPArray.Clear(); } Standard_Integer Graphic3d_Group :: ArrayNumber () const { @@ -80,7 +89,14 @@ void Graphic3d_Group :: RemovePrimitiveArray ( const Standard_Integer aRank ) { for( Standard_Integer i=1 ; it.More() ; it.Next(),i++ ) { if( aRank == i ) break; } - MyListOfPArray.Remove(it); + + // clear primitives array's visualization data in graphics driver and remove + // references to it in driver + if (!IsEmpty() && !MyGraphicDriver.IsNull()) + MyGraphicDriver->RemovePrimitiveArray (MyCGroup, it.Value()->Array()); + + // remove references to primitives array + MyListOfPArray.Remove (it); } void Graphic3d_Group :: UserDraw ( const Standard_Address AnObject, diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index 814f8345ed..534d547e1b 100755 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -216,22 +216,32 @@ void Graphic3d_Structure::Destroy () { //-Methods, in order -void Graphic3d_Structure::Clear (const Standard_Boolean WithDestruction) { +void Graphic3d_Structure::Clear (const Standard_Boolean WithDestruction) +{ + if (IsDeleted()) return; - if (IsDeleted ()) return; + MyCStructure.ContainsFacet = 0; - if (WithDestruction) { - MyGroupGenId.Free (); - MyGroups.Clear (); + // clean groups in graphics driver at first + if (WithDestruction) + { + // clean and empty each group + Standard_Integer Length = MyGroups.Length(); + for (Standard_Integer aGrId = 1; aGrId <= Length; ++aGrId) + MyGroups.ChangeValue (aGrId)->Clear(); + } + GraphicClear (WithDestruction); + + // only then remove group references + if (WithDestruction) + { + MyGroupGenId.Free(); + MyGroups.Clear(); } - MyCStructure.ContainsFacet = 0; - - GraphicClear (WithDestruction); MyStructureManager->Clear (this, WithDestruction); - Update (); - + Update(); } void Graphic3d_Structure::Remove () { @@ -250,6 +260,12 @@ void Graphic3d_Structure::Remove () { #endif Standard_Integer i, Length; + + // clean groups in graphics driver at first + Length = MyGroups.Length(); + for (Standard_Integer aGrId = 1; aGrId <= Length; ++aGrId) + MyGroups.ChangeValue (aGrId)->Clear(); + // Standard_Address APtr = (void *) This ().operator->(); Standard_Address APtr = (void *) this; // It is necessary to remove the eventual pointer on the structure diff --git a/src/OpenGl/OpenGl_GraphicDriver.cdl b/src/OpenGl/OpenGl_GraphicDriver.cdl index bd35b40717..19af1a5afe 100755 --- a/src/OpenGl/OpenGl_GraphicDriver.cdl +++ b/src/OpenGl/OpenGl_GraphicDriver.cdl @@ -1302,4 +1302,13 @@ is -- returns Standard_False if fails -- ABD Integration support of system fonts (using FTGL and FreeType) + RemovePrimitiveArray( me : mutable; + theCGroup : CGroup from Graphic3d; + thePArray : PrimitiveArray from Graphic3d ) + is redefined static; + ---Purpose: Clear visualization data in graphical driver and + -- stop displaying the primitives array of the graphical group + -- . This method is internal and should be used + -- by Graphic3d_Group only. + end GraphicDriver from OpenGl; diff --git a/src/OpenGl/OpenGl_GraphicDriver_713.cxx b/src/OpenGl/OpenGl_GraphicDriver_713.cxx index 05ef87c5a1..7ace67d077 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_713.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_713.cxx @@ -36,7 +36,7 @@ Standard_Boolean OpenGl_GraphicDriver { #ifdef BUC61044 Graphic3d_CView MyCView = view; - return (call_togl_isdepthtest( &MyCView ) != 0); + return call_togl_isdepthtest (&MyCView) != 0; #endif } @@ -64,7 +64,7 @@ Standard_Boolean OpenGl_GraphicDriver { #ifdef BUC61045 Graphic3d_CView MyCView = view; - return (call_togl_isgllight( &MyCView ) != 0); + return call_togl_isgllight (&MyCView) != 0; #endif } @@ -77,6 +77,20 @@ void OpenGl_GraphicDriver :: PrimitiveArray( const Graphic3d_CGroup& ACGroup, if( parray ) call_togl_parray (&MyCGroup,parray); } +//======================================================================= +//function : RemovePrimitiveArray +//purpose : Purpose: Clear visualization data in graphical driver and +// stop displaying the primitives array of the graphical group +// . This method is internal and should be used by +// Graphic3d_Group only. +//======================================================================= + +void OpenGl_GraphicDriver::RemovePrimitiveArray (const Graphic3d_CGroup& theCGroup, + const Graphic3d_PrimitiveArray& thePArray) +{ + Graphic3d_CGroup MyCGroup = theCGroup; + if (thePArray != NULL) call_togl_parray_remove (&MyCGroup, thePArray); +} void OpenGl_GraphicDriver :: UserDraw ( const Graphic3d_CGroup& ACGroup, const Graphic3d_CUserDraw& AUserDraw ) diff --git a/src/OpenGl/OpenGl_tgl_funcs.hxx b/src/OpenGl/OpenGl_tgl_funcs.hxx index 9e0e0d3408..a4d3e6d5b5 100755 --- a/src/OpenGl/OpenGl_tgl_funcs.hxx +++ b/src/OpenGl/OpenGl_tgl_funcs.hxx @@ -351,6 +351,7 @@ extern void call_func_eval_map_matrix3( view_map3 *Map, int *err_ind, #define call_func_del_struct TsmDeleteStructure #define call_func_inq_elem_ptr TsmGetCurElemPtr +#define call_func_inq_elem TsmGetCurElem /* Declarations des subroutines triedron */ @@ -1318,6 +1319,13 @@ void EXPORT call_togl_parray ( ); +void EXPORT call_togl_parray_remove ( + + CALL_DEF_GROUP *agroup, + CALL_DEF_PARRAY* parray + + ); + void EXPORT call_togl_userdraw ( CALL_DEF_GROUP *agroup, diff --git a/src/OpenGl/OpenGl_togl_parray.cxx b/src/OpenGl/OpenGl_togl_parray.cxx index a336183558..66b655b141 100755 --- a/src/OpenGl/OpenGl_togl_parray.cxx +++ b/src/OpenGl/OpenGl_togl_parray.cxx @@ -21,3 +21,72 @@ void EXPORT call_togl_parray if (! agroup->IsOpen) call_togl_closegroup (agroup); return; } + +//======================================================================= +//function : call_togl_parray_remove +//purpose : Remove the driver's element corresponding to the primitives +// array and clean its visualization data. The driver +// clears all its references to array and stops displaying it. +// is the group that has added to driver. +//======================================================================= + +void EXPORT call_togl_parray_remove (CALL_DEF_GROUP* theGroup, + CALL_DEF_PARRAY* thePArray) +{ + CALL_DEF_PARRAY* anElData; + Tint aBegId, aEndId, aCurId; + TSM_ELEM anElem; + + // set edit mode and open struct + call_func_set_edit_mode (CALL_PHIGS_EDIT_REPLACE); + call_func_open_struct (theGroup->Struct->Id); + + // get begin label + call_func_set_elem_ptr (0); + if (call_func_set_elem_ptr_label (theGroup->LabelBegin) == TFailure) + return; + call_func_inq_elem_ptr (&aBegId); + + // get end label + if (call_func_set_elem_ptr_label (theGroup->LabelEnd) == TFailure) + return; + call_func_inq_elem_ptr (&aEndId); + + // iterate between labels and search for the array + if (aBegId != aEndId) + { + // move one element back + if (call_func_offset_elem_ptr (-1) == TFailure || + call_func_inq_elem_ptr (&aCurId) == TFailure) + return; + + // iterate from end label to begin label + while (aCurId > aBegId) + { + call_func_inq_elem (&anElem); + + // compare element with the array + if (anElem.el == TelParray && anElem.data.pdata == (void* )thePArray) + { + anElData = (CALL_DEF_PARRAY* )anElem.data.pdata; + + // validate for correct pointer + if (anElData->num_bounds == thePArray->num_bounds && + anElData->num_edges == thePArray->num_edges && + anElData->num_vertexs == thePArray->num_vertexs && + anElData->type == thePArray->type) + { + call_func_del_elem(); + break; + } + } + else + { + call_func_offset_elem_ptr (-1); + call_func_inq_elem_ptr (&aCurId); + } + } + } + + call_func_close_struct(); +}