Add and Delete in DbTree

Questions related to plugins development
Post Reply
Tolier
Posts: 11
Joined: Mon Jul 09, 2018 2:49 pm

Add and Delete in DbTree

Post by Tolier »

Hello,
I currently have a problem in my DB Tree.
First of all I create a directory, so I test if it exists or not and I do:

Code: Select all

if (!CVisee_group)
{
	CVisee_group = new ccHObject(type);
	m_app->dbRootObject()->addChild(CVisee_group);
	m_app->addToDB(CVisee_group, false, true, false, false);
}
The directory is added to the Db Tree, then I draw different ccCustomHObject and add each new obj in this way:

Code: Select all

m_pParentFolderVisee->addChild(pVisee);
m_app->addToDB(pVisee, false, true, false, false);
Once several obj added I want to delete them and continue to add more... and that's when it gets complicated!
I can delete my CustomHObject like that:

Code: Select all


ccHObject* root = m_app->dbRootObject();
ccHObject* pChildren = NULL;
for (int i =0; i < root->getChildrenNumber(); i++)
{
	pChildren = root->getChild(i);
	if (pChildren && pChildren->isKindOf(CC_TYPES::HIERARCHY_OBJECT))
	{
		ccHObject* pChildren2 = NULL;
		for (int j = 0;j < pChildren->getChildrenNumber(); j++)
		{
			pChildren2 = pChildren->getChild(j);
			if (ident == (pChildren2->getMetaData("ident").toInt()))
			{
				m_app->removeFromDB(pChildren2);
			}
		}
	}
}

Except that an error is triggered on:

Code: Select all

int ccHObject::getIndex() const
{
	return (m_parent ? m_parent->getChildIndex(this) : -1);
}
With a read access violation....
If I delete my CustomHObject in another way like this:

Code: Select all

pChildren2->getParent()->removeChild(pChildren2);
This does the job and deletes my obj but displays after many assert this error message for each obj deleted!

Would you have a correct method to better manage the addition and deletion of Objects in the dbtree
cheers
daniel
Site Admin
Posts: 7707
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: Add and Delete in DbTree

Post by daniel »

First, you don't need to call the dbRootObject() methods directly.

You can simply call 'addToDB' and it will be automatically (and properly) added to the DB tree. Same thing, to remove an object, just call 'removeFromDB' (as you did) and CC will take care of the rest (once again, properly). One potential issue in your code though is that when you delete remove the 'pChildren2' instance from the DB, it will also be detached from its parent. Therefore the number of children changes and the next call tp 'pChildren->getChild(j);' might corrupt the memory...

You should store the object you want to remove in a list (ccHObject::Container for instance) and then remove the listed objects.

Anyway, the most important thing is to avoid adding or removing children from objects that are already in the DB tree, as CC needs to synchronize the DB tree widgets with the real data hierarchy.
Daniel, CloudCompare admin
Tolier
Posts: 11
Joined: Mon Jul 09, 2018 2:49 pm

Re: Add and Delete in DbTree

Post by Tolier »

Thank you, okay!
I understood the principle,
I create my folder and add it to the dbtree
I then create my objects that I add as a child to my folder, it automatically adds it to my dbtree.

Cela resemble donc a ça :
Image
https://imgur.com/ttp2FZ5

Puis a ça :
Image
https://imgur.com/Do9Cvff

But finally let's imagine that my obj numbers 205,206,207 must be deleted!
But that just after their deletion of other obj of the same name will replace them with different coordinates and appearance.
And this is common practice.

you scare me when you say that you shouldn't avoid adding and removing objects in the dbtree.

Can you explain to me how the "ccHObject::Container" works because I don't see the need to delete a child (an obj) but, before deleting it, add it to this container and then delete it! In any case it will be removed from the container but also from the dbtree

You must have difficulty understanding my request because I haven't explained to you why I'm doing this.
If you want a clearer explanation of what I do to help you find your way around, don't hesitate.

cheers
daniel
Site Admin
Posts: 7707
Joined: Wed Oct 13, 2010 7:34 am
Location: Grenoble, France
Contact:

Re: Add and Delete in DbTree

Post by daniel »

I wanted to say that you should not remove or add children 'directly' to an object that is currently in the DB tree (avoid calling 'addChild' or 'removeChild'). Well you can call addChild or setParent so as to target the right 'father' but then you need to call 'addToDB'. But don't call 'removeChild' because the GUI won't be aware of this modification and the DB tree visualization will be deprecated (and then you'll get error messages).

And the container idea is to avoid removing the children inside a loop that depends on the number of elements of the father. Otherwise you will face a potential bug here. First make a list of the children you want to remove (so that when you iterate over the number of children, you don't change the set of children) then remove them...
Daniel, CloudCompare admin
Tolier
Posts: 11
Joined: Mon Jul 09, 2018 2:49 pm

Re: Add and Delete in DbTree

Post by Tolier »

Thank you, problem solved.

I'm working on several threads, and precisely it wasn't the main thread that added and removed in the dbTree. And knowing that drawing is forbidden in the secondary thread this must have been a problem because the secondary thread must have had a delay in information about the main one.
So I reviewed my code to switch to the main thread much earlier and create, add and delete on the main thread.
Post Reply