0022650: Exception in Primitive Array during Redisplay of Presentable Object
authorAPL <>
Wed, 31 Aug 2011 11:56:35 +0000 (11:56 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:29:53 +0000 (19:29 +0400)
src/Graphic3d/Graphic3d_GraphicDriver.cdl
src/Graphic3d/Graphic3d_Group_1.cxx
src/Graphic3d/Graphic3d_Group_13.cxx
src/Graphic3d/Graphic3d_Structure.cxx
src/OpenGl/OpenGl_GraphicDriver.cdl
src/OpenGl/OpenGl_GraphicDriver_713.cxx
src/OpenGl/OpenGl_tgl_funcs.hxx
src/OpenGl/OpenGl_togl_parray.cxx

index c548b89..3f6c369 100755 (executable)
@@ -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
+        -- <theCGroup>. This method is internal and should be used
+        -- by Graphic3d_Group only.
+
     --------------------------
     -- Category: Class methods
     --------------------------
index 4d7fb59..4911091 100755 (executable)
@@ -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 () {
index 9f0f8c5..f607fff 100755 (executable)
@@ -45,8 +45,17 @@ void Graphic3d_Group :: AddPrimitiveArray ( const Handle(Graphic3d_ArrayOfPrimit
 }
 
 void Graphic3d_Group :: RemovePrimitiveArrays () {
-
-       MyListOfPArray.Clear();
+  // 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());
+  }
+
+  // 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,                               
index 814f834..534d547 100755 (executable)
@@ -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);
 
-  MyCStructure.ContainsFacet      = 0;
+  // only then remove group references
+  if (WithDestruction)
+  {
+    MyGroupGenId.Free();
+    MyGroups.Clear();
+  }
 
-  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
index bd35b40..19af1a5 100755 (executable)
@@ -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
+        -- <theCGroup>. This method is internal and should be used
+        -- by Graphic3d_Group only.
+
 end GraphicDriver from OpenGl;
index 05ef87c..7ace67d 100755 (executable)
@@ -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
+//           <theCGroup>. 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 )
index 9e0e0d3..a4d3e6d 100755 (executable)
@@ -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,
index a336183..66b655b 100755 (executable)
@@ -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 <thePArray> and clean its visualization data. The driver
+//           clears all its references to array and stops displaying it.
+//           <theGroup> is the group that has added <thePArray> 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();
+}