0

I'm trying to delete all the scene objects in the GLScene container and I use the following code snippet to do it, but for some unknown reasons it crashes raises the segmentation fault when I try to free the object.

I tried to debug line by line and it revealed that somehow container class of Glscene1.Objects[i] contains some inexplicable classes which has the '#2' class name. I 've tried to run through the very same code snippet w/o calling the Free method then there doesn't occur any abnormalitie, objects are not deleted but there is consistency in object class names.

for i := 0 to GLScene1.Objects.Count - 1 do
  begin
     if (not GLScene1.Objects[i].ClassNameIs('TGLCamera')) and
        (not GLScene1.Objects[i].ClassNameIs('TGLLightSource')) and
        (not GLScene1.Objects[i].ClassNameIs('TGLDummyCube')) and
        (not GLScene1.Objects[i].ClassNameIs('TGLXYZGrid')) and
        (not GLScene1.Objects[i].ClassNameIs('TGLSceneRootObject')) then
     begin
//      if GLScene1.Objects[i].Count > 0 then
//      GLScene1.Objects[i].DeleteChildren;
      GLScene1.Objects.Remove(GLScene1.Objects[i],false);

      if GLScene1.Objects[i] <> nil then    // I comment out these lines 
        GLScene1.Objects[i].free;           // I comment out these lines 
     end;

  end;
Sonya Blade
  • 399
  • 7
  • 24
  • Hi Sonya. I would recommend reversing the for, i.e. for i := GlScene1.Objects.Count-1 downto 0 do ... Otherwise, the object indexes you attempt to delete may already be out of range. – BARSAN-PIPU Claudiu Apr 05 '14 at 06:53
  • For the googlers, down counting is also good strategy to erase the objects in scene but along with that instead of excluding the intended classtypes, try to erase only the intended class types e.g. GLFreeForm, GLLines etc.. For some unknown reasons GLScene root have some reference or block objects in the Object container class any you also delete them, this is what I learnt tentatively. – Sonya Blade Apr 27 '14 at 12:33

1 Answers1

0

The most often mistake made is a try to delete GlFreeForm when there is still GLProxyObject that reffer to a parent GlFreeForm. So the best solution to clear scene is to set all GLProxyObject's MasterObject parameter to nil first. To avoid blocking objects it is advised to use single GLDummyCube (GLDummyCube1 in this example) as a root object for all other scene objects:

if Form1.GLDummyCube1.Count>0 then
begin
  for I := (Form1.GLDummyCube1.Count-1) downto 0 do
  begin
    if (Form1.GLDummyCube1.Children[I].ClassNameIs('TGLProxyObject')) then
    begin
      TGLProxyObject(Form1.GLDummyCube1.Children[I]).MasterObject := nil;
    end;
  end;

  while (Form1.GLDummyCube1.Count>0) do
  begin
    try
      Form1.GLScene1.FindSceneObject(Form1.GLDummyCube1.Children[0].Name).Destroy;
    except
      //inform error, but I never had one
    end;
  end;
end;

I never had any problems with that code for a long 4 years of heavy usage, so feel free to use it.

Kainax
  • 1,431
  • 19
  • 29