Removing all primitives/entities

In our application I have the ability to toggle assets on an off through a set of menus. I've started trying to work in adding assets via the new Entity API. The issue I'm running into though is, I have a button that will "Reset" the globe. This removes all dataSources, all entities, and all primitives. If I do a removeAll and then try to toggle those assets back up, I get the error that those objects were already destroyed.

Does this have something to do with entities existing in both lists? By that I mean, they exist in the entities list and the primitives list.

Does this have something to do with entities existing in both lists?

Yes. Entities created primitives under the hood.

Try doing a removeAll for entities before doing the removeAll for primitives.

Patrick

I'm pretty sure I tried that at one point and still hit the same issue but I'll try it again soon

If you continue to run into issues, please create a stripped-down example to reproduce it in Sandcastle.

Patrick

Here ya go...

var viewer = new Cesium.Viewer('cesiumContainer');

var countries = [{name:'Afghanistan',position: new Cesium.Cartesian3.fromDegrees(33.835342, 66.082004)},
        {name:'Albania',position: new Cesium.Cartesian3.fromDegrees(20.174305, 41.167381)},
        {name:'Algeria',position: new Cesium.Cartesian3.fromDegrees(2.677619, 28.131878)},
        {name:'American Samoa',position: new Cesium.Cartesian3.fromDegrees(-170.729096, -14.301841)},
        {name:'Angola',position: new Cesium.Cartesian3.fromDegrees(17.479600, -12.474423)},
        {name:'Anguilla',position: new Cesium.Cartesian3.fromDegrees(-63.049084, 18.221567)},
        {name:'Antarctica',position: new Cesium.Cartesian3.fromDegrees(-133.412676, -83.063869)},
        {name:'Antigua And Barbuda',position: new Cesium.Cartesian3.fromDegrees(-61.794482, 17.081521)}];

function addLabels() {
    for (var i = 0,len = countries.length; i < len; i++) {
        var temp = {
            id: countries[i].name,
            name: countries[i].name,
            position: countries[i].position,
            label: {
                text: countries[i].name,
                font: '18px Verdana, sans-serif',
                translucencyByDistance: new Cesium.NearFarScalar(1.5e7, 100000, 2.5e7, 0)
            }
        };
        viewer.entities.add(temp);
    }
}

addLabels();
    
setTimeout(function() {
    console.log('Clearing');
    viewer.dataSources.removeAll();
    viewer.entities.removeAll();
    viewer.scene.primitives.removeAll();
},3000);

setTimeout(function() {
    console.log('Reinserting');
    addLabels();
},6000);

Hi David,

By default, DataSourceCollection destroys the removed data sources. To avoid this, pass false to removeAll:

viewer.dataSources.removeAll(false);

Amato, I’m guessing viewer.entities should either be excluded from the list of data sources removed, or it should be re-created afterward? Or something?

Kevin

dataSources aren't my issue. The only reason I have the removeAll on dataSources in this example is for completeness because that's what I have in the actual function I use. It does a removeAll on all three. You can comment out or remove it completely and the issue persists.

Ok. If you can provide us with a minimal example that shows the problem, then, we’ll probably be able to help you more quickly.

My previous post has an example that I created within the Sandcastle that replicates the error

Right, but if you can remove code and it still has the same problem, it’s not a minimal example.

Not trying to be a jerk… everyone is busy, and the smaller the example the less likely we are to get distracted by irrelevant details as I just was.

var viewer = new Cesium.Viewer('cesiumContainer');

var countries = [{name:'Afghanistan',position: new Cesium.Cartesian3.fromDegrees(33.835342, 66.082004)},
        {name:'Albania',position: new Cesium.Cartesian3.fromDegrees(20.174305, 41.167381)},
        {name:'Algeria',position: new Cesium.Cartesian3.fromDegrees(2.677619, 28.131878)},
        {name:'American Samoa',position: new Cesium.Cartesian3.fromDegrees(-170.729096, -14.301841)},
        {name:'Angola',position: new Cesium.Cartesian3.fromDegrees(17.479600, -12.474423)},
        {name:'Anguilla',position: new Cesium.Cartesian3.fromDegrees(-63.049084, 18.221567)},
        {name:'Antarctica',position: new Cesium.Cartesian3.fromDegrees(-133.412676, -83.063869)},
        {name:'Antigua And Barbuda',position: new Cesium.Cartesian3.fromDegrees(-61.794482, 17.081521)}];

function addLabels() {
    for (var i = 0,len = countries.length; i < len; i++) {
        var temp = {
            id: countries[i].name,
            name: countries[i].name,
            position: countries[i].position,
            label: {
                text: countries[i].name,
                font: '18px Verdana, sans-serif',
                translucencyByDistance: new Cesium.NearFarScalar(1.5e7, 100000, 2.5e7, 0)
            }
        };
        viewer.entities.add(temp);
        inc++;
    }
}

addLabels();
    
setTimeout(function() {
    viewer.entities.removeAll();
    viewer.scene.primitives.removeAll();
},3000);

setTimeout(function() {
    addLabels();
},6000);

Ok, I’d call this a Cesium bug.

The problem is that the entity visualizers create primitives for their own use and hold references to them. When you call primitives.removeAll, those primitives are removed and destroyed. The next time the visualizers access them, the “object destroyed” exception is thrown. The visualizers probably ought to be checking to see if their primitives have been destroyed and recreating them if they have.

That’s a change to Cesium, of course, so here’s a workaround in the meantime.

When you add primitives manually (i.e. not via entities), add them to a separate list in addition to adding them to the PrimitiveCollection. Then, instead of calling PrimitiveCollection.removeAll, loop over your list and remove each of the primitives individually. That will leave the visualizer-created primitives intact.

Kevin

A slightly easier workaround to Kevin’s suggestion is to create your own PrimitiveCollection and add items to that. Then instead of looping over them to remove, you can just add/remove the entire PrimitiveCollection. This is actually a pretty hard problem to solve without having a negative impact on performance but I’ll have to look into it when Ihave time. In general, I would recommend never calling removeAll on the primary scene.primitives collection.

If we shouldn't do that, that should probably be something that is documented somewhere. That is what I've always done to reset my globe back to a blank slate. The only reason I've finally run into issues was because I started mixing using the old primitives and using entities at the same time.