Help with Object Deleting

Blitz3D Forums/Blitz3D Beginners Area/Help with Object Deleting

Guy Fawkes(Posted 2012) [#1]
Hi, all :) Ok, so I created an ALMOST working Delete object OR ALL objects function. Delete ALL objects part of it works fine (I think, and correct me if I'm wrong), but when I hold Control + Shift + D, which should ONLY delete a SELECTED object, and remove 1 from the "objcount" variable, which is the total number of objects created in the scene, BUT after I delete it, and select another object, for SOME reason, it says 'entity does not exist', when it clearly DOES exist. And YES, Rob, I wrote the Delete & Save functions myself :)



Keys are:



Control + Shift + D to delete a SINGLE selected object, and subtract 1 from the 'objcount' variable, until there are no objects left in the scene



Control + D to delete ALL objects in the ENTIRE scene, and set the 'objcount' variable to 0, when there are no objects left in the scene



Here's the code:







Any help is GREATLY appreciated! :)



Thanks! :)

Last edited 2012


Ross C(Posted 2012) [#2]
From a brief read through, you should not be doing:

FreeEntity picked

Reason being, you are relying on the picked object to be the one selected. Also use your own records via the type collection you set up. That's why it's there.

You should be looking through the selected_objects type collection and deleting the object held in there. Your delete function doesn't make sense though. Delete a single selected object. What if you press them keys whilst there is several things selected? Shouldn't the purpose of the function be "Delete selected objects"

Last edited 2012

Last edited 2012


Guy Fawkes(Posted 2012) [#3]
I need a way of deleting single objects, OR all objects. If it's 2 functions, thats fine. But as of now, I am lost...


Ross C(Posted 2012) [#4]
But if you have multiple selections, how does that work? Your function should be to delete all selected items. That way, if you want to delete one item, you simply select it. Job done. That's how every other editor i've ever used works.

And, rather than having a delete all, have a select all function/button. That way, you can just press the delete key and you don't need seperate functions for delete single object and all objects.


Rob the Great(Posted 2012) [#5]
Yeah, Ross C has the same approach that I had in mind. It doesn't matter if 1 object is selected or 1000 objects are selected, you should have a single function that will delete the selected object(s). If you want to delete all of them, you should write a function that selects all of the objects. This could be as easy as:
For c.Obj = Each Obj
   c\selected = 1
Next

The reason why you were getting a MAV is because you were deleting the mesh, but not the corresponding object from the type list. Suppose you delete a mesh, c\mesh. The mesh is gone, but the object isn't. So, when you call:
For c.Obj = Each Obj
   EntityAlpha c\mesh,0.5
Next

you will get a MAV because one of the c\mesh entities is still trying to change its alpha, even though it doesn't exist anymore. This situation is equivalent to:
cube = CreateCube()
FreeEntity cube
EntityAlpha cube,0.5

So, to fix the problem, you have to remove the corresponding object from the type list. To do this, all you have to do is type in Delete c (or whatever you decided to call the type objects in the function) after FreeEntity c\mesh.
With that in mind, here's the modified Delete_Selected_Objects() function. Notice how easy this is once there is a good type system in play:
Function Delete_Selected_Objects()


	Local continue = 0
	FlushKeys()
	While Not continue
		If KeyDown(1) Then End
		If KeyHit(21) Then continue = 1
		If KeyHit(49) Then continue = -1
		UpdateWorld
		RenderWorld
		Color 255,0,0
		Text GraphicsWidth()/2,GraphicsHeight()*0.33,"ARE YOU SURE YOU WANT TO DELETE THE SELECTED OBJECTS? YOU CANNOT UNDO THIS ACTION.",True,True
		Text GraphicsWidth()/2,GraphicsHeight()*0.33+30,"Push " + Chr(34) + "Y" + Chr(34) + " to confirm or " + Chr(34) + "N" + Chr(34) + " to return.",True,True
		Flip
	Wend
	
	If continue = -1
		RenderWorld
		UpdateWorld
		Color 0,255,0
		Text GraphicsWidth()/2,GraphicsHeight()/2,"OBJECTS KEPT!",True,True
		Flip
		Delay 2000
		Color 255,255,255
		Return
	EndIf
	
	Local c.Obj
	For c.Obj = Each Obj
		If c\selected = 1
			objcountselected = objcountselected - 1
			FreeEntity c\mesh
			Delete c
		EndIf
	Next
	
	RenderWorld
	UpdateWorld
	Color 255,0,0
	Text GraphicsWidth()/2,GraphicsHeight()/2,"DELETED",True,True
	Flip
	Delay 2000
	Color 255,255,255


End Function

Remember that even when you are in single select mode, the actual picking function will look at all of the objects as a whole and change the c\selected field if the specific type should be selected. This makes everything so much simpler in the long run.

Last edited 2012


K(Posted 2012) [#6]
Note that he runs Delete c after FreeEntity.


This is very important to understand, pay attention carefully...

1) on line 550 add DebugLog picked. Run the program, let it glitch,and diagnose it. What's the problem here? open up "c.obj" in the right panel of the debugger, what's the value of "c\mesh"? THE SAME AS WHAT YOU PUT IN THE DEBUG LOG. What does this mean?
It means that error is a procedural goof, you are telling your program to update a mesh that you have already freed.
2)In other words, you freed the entity from the 3d engine, but you didn't delete the object from your engine. "C\Mesh" is just a memory address in the end. FreeEntity will NOT magically reset this to another value.
3)The root of the problem is that you have all these addresses floating around, and they don't all lead places. You need to eliminate them when you no longer need them.


As a point of advice, I'd say use the forums only when you are absolutely stumped. In general, analyze. Almost any problem is created by none other than the programmer, and the computer will do nothing you didn't tell it to do. You'd be surprised how much more productive you could be not even visiting this site for a week or so.

Last edited 2012


Guy Fawkes(Posted 2012) [#7]
Ok, so I added a small fix to the single delete objects function.


I made it so u CANNOT access the delete menu until an object is physically selected.


This is what I did:







HOWEVER...


The PROBLEM I'm having, is with the ALL object delete function.


For some ODD reason, selecting everything at once and deleting it is NOT working ><



Here's the function:







Any help is greatly appreciated as always! :)



Thanks! :)

Last edited 2012


Ross C(Posted 2012) [#8]
You need to remove the c.obj for each entity you are freeing as well.


Rob the Great(Posted 2012) [#9]
Another note:
For c.Obj = Each Obj
   c\selected = 1 ;Don't need this since you're deleting them all anyway
   If c\selected = 1 ;Don't need this since you're deleting them all anyway
      FreeEntity c\mesh ;this is fine
      ;Like Ross C says, you need this line as well
      Delete c
   EndIf
Next



Guy Fawkes(Posted 2012) [#10]



They're still not deleting unfortunately. infact. it's doing NOTHING when I hold Ctrl, and press the D key...



This looks right... at least to me... :





Rob the Great(Posted 2012) [#11]
I'm guessing there's something wrong with the first line in your last codebox. What exactly are you trying to accomplish as far as KeyHit() and KeyDown()? I think order of operations is hurting you here. Try adding parenthesis around your conditions to help keep it straight:
If  (  KeyDown(29) Or KeyDown(157)  )  And  (  KeyDown(42) Or KeyDown(54)  )

Reading it a second time, I've also noticed that there is no difference in the logic between your first keydown condition and your second. First, let me know how you want to activate Delete_All_Objects() with buttons, and we can go from there.

Last edited 2012


Guy Fawkes(Posted 2012) [#12]
Well. when u want to SELECT an object or objects, and delete them, i want to be able to hold Ctrl + Shift + D. BUT. When u wanna delete ALL objects at ONCE, then hold Control + D, and it will ask u if u wanna delete all objects.


Ross C(Posted 2012) [#13]
Your still making this more complicated than it needs to be. Use the standard CTRL + A to select all, and have ONE delete function, that deletes whatever is selected. Less hassle, less coding, and people will have an existing knowledge in the standard CTRL + A shortcut key.

As Rob says, if the KEYDOWN(29) and KEYDOWN(157) is detected in the first IF statement, the second detection, after the ELSE won't even run. You need to:


	If (KeyDown(29) Or KeyDown(157)) And (KeyDown(42) Or KeyDown(54)) And (KeyHit(32))

			If picked<>0
				Delete_Selected_Objects()
			ElseIf picked = 0
				Color 255, 255, 255
				UpdateWorld()
				RenderWorld()
				Text GraphicsWidth()/2, GraphicsHeight()/2+2, "CANNOT DELETE - OBJECT NOT SELECTED!", True, True
				Flip
				Delay 2000
				Color 255, 255, 255
			EndIf

	Else
			If (KeyDown(29) Or KeyDown(157)) And (KeyHit(32))

					Delete_All_Objects()

			EndIf
	EndIf


And there is no need to use the picked variable (don't rely on that to determine whether anything is selected) to check whether anything is selected. The delete_selected_objects() function will only delete anything with the selected flag set, so that check is unnessesary. So it is refined to :



	If (KeyDown(29) Or KeyDown(157)) And (KeyDown(42) Or KeyDown(54)) And (KeyHit(32))

				Delete_Selected_Objects()


	Else
			If (KeyDown(29) Or KeyDown(157)) And (KeyHit(32))

					Delete_All_Objects()

			EndIf
	EndIf


Also, you do realise your stopping your code from doing anything for 2 whole seconds. That will get annoying pretty fast. Another question. Why not just use the delete key? Why ctrl+shift? Please think about the CTRL + A method for selecting all, and the delete key deletes all selected objects.


Rob the Great(Posted 2012) [#14]
Sorry, the Delay thing was my doing. I put it in one of the functions as lazy way to read the text before exiting the function, but in the final version, it should definitely go.

Anyways, Ross has the right idea. In almost any program I use, CRTL+A has always been the "select all" command. If all of your objects are selected and you call Delete_Selected_Objects(), it will delete all of them, so another function called Delete_All_Objects() would be redundant. Remember, you're using Type lists to set additional properties of your entities, so use this to your advantage. The system is set up where every single entity that is a part of the Obj Type has it's own variable called "selected", which will keep track of which objects are currently selected, whether this be one entity selected (as in single mode), or 10,000 entities selected. There is no difference in the way Blitz handles the selected objects in either mode, only in the way that you can select an object because of how it is setup.


Ross C(Posted 2012) [#15]
Ah, no bother!


Guy Fawkes(Posted 2012) [#16]
Ok. well it's still not letting me select all objects at once... :/



Here's the code:









Last edited 2012


Ross C(Posted 2012) [#17]
You've not changed the code based on what we've posted above though.


Guy Fawkes(Posted 2012) [#18]
Wrong. I changed the keyhit function. Look closer.


Ross C(Posted 2012) [#19]
Your still relying on picked to determine whether anything is selected.


Guy Fawkes(Posted 2012) [#20]
what does that have to do with it? -.-


Guy Fawkes(Posted 2012) [#21]
Look, here's what I have....


Here's the code:









Last edited 2012


Ross C(Posted 2012) [#22]
Why is your select all objects function, deleting meshes?

For c.Obj = Each Obj
	picked = c\mesh
	FreeEntity picked
	picked = 0
	objcount = 0
	Delete c
Next


Why are you assigning picked to c\mesh, then freeing the picked entity? Why not just FreeEntity c\mesh?

My previous point refers to your picked variable. What information does that hold? If it holds the lastest picked entity, you might pick nothing, but have objects selected. I'm just saying, you don't need to refer to it. Your deleted_selected_object function actually checks all the objects for the selected flag. It cuts down the chance of your code breaking.


	If (KeyDown(29) Or KeyDown(157)) And (KeyDown(42) Or KeyDown(54)) And (KeyHit(32))

				Delete_Selected_Objects()


	Else
			If (KeyDown(29) Or KeyDown(157)) And (KeyHit(32))

					Delete_All_Objects()

			EndIf
	EndIf


You'll need to post the full code.

Last edited 2012


Guy Fawkes(Posted 2012) [#23]
Here...





Ross C(Posted 2012) [#24]
To start with, as my previous post:

Function Select_All_Objects(camera)


	;oldwhichmode = whichmode


	;whichmode = 2
For c.Obj = Each Obj
	picked = c\mesh
	FreeEntity picked
	picked = 0
	objcount = 0
	Delete c
Next


	;whichmode = oldwhichmode


End Function


You are deleting meshes from your collection in the select_all function. You shouldn't be doing that. Also, you seem to have changed it so it doesn't actually set the selected flag. That would be the most obvious reason for it not working.

In post #16, your function would work properly. Why did you change it?

Your deleted selected objects function looks good.

Looking outwith that, I wouldn't use TurnEntity to rotate your meshes. Try using:

RotateEntity entity,EntityPitch(entity)+x,EntityYaw(entity)+y,EntityRoll(entity)+z


Where x,y and z are the amounts you want to rotate by.


Guy Fawkes(Posted 2012) [#25]
So THAT'S how to do that... Rotateentity always gave me a problem when rotating an object ><


and in ur answer as to why i would change it?


Well, because for SOME reason, c\selected = 1 does NOTHING at all T_T the delete function works.... i think. o.o


Ross C(Posted 2012) [#26]
But... you've changed the function called Select_All_Objects(). It deletes stuff now. At least rename it. c\selected will set the entity to be selected. That works. It's something else in the code that's doing it.

Again, stop using the picked variable to determine whether anything is selected.

Running the code, why on earth do you have a single select mode? Your making things way more complicated than they need to be. No-one would be happy running an editor where they have to change modes, just to multiple select something.

You need to have one mode that deals with selecting, copying, deleting etc etc


Guy Fawkes(Posted 2012) [#27]
simple... i can remove the modes, and make it keys EASILY... but in order to continue on, I need to know how to select all objects at once with the KEYS. :)


Ross C(Posted 2012) [#28]
I've told you, you need to put back in the c\selected to start with. Bugger it, I have written this in an hour. This is how it should work:



CTRL A selects ALL
CTRL C copies all selected
DEL deletes all selected

Last edited 2012


Guy Fawkes(Posted 2012) [#29]
Ross, I can't thank you enough. I will definitely be adding u to the credits :)


Ross C(Posted 2012) [#30]
It has a very modular approach, so you don't need to mess with adding code for selecting/deselecting objects. This way, if you want to change the entities look when selected, you have to just change the one function. Please study this! And no worries. You were trying this time!

Last edited 2012


Guy Fawkes(Posted 2012) [#31]
U got it, Ross! :)


Ross C(Posted 2012) [#32]
Oh, about the copy thing. When you press CTRL + C, it will deselect the original and select the copy, so you can continue copying across. Study the function parameters. I have made it easy to choose the direction of the copy, by sending different parameters to the function.