Can't remove primitives from scene

1,438 views
Skip to first unread message

Brent Shanahan

unread,
May 20, 2015, 11:14:05 AM5/20/15
to cesiu...@googlegroups.com
I have a function that creates a geometry primitive from a geometry instance. I works great when creating new geometry.

Now I need to remove some of the primitives so that I can re-create them in a different location. 

I'm not storing the original geometry primitive data anywhere but I do have the parameters that were input into the function used to create it. My logic was that if I could recreate the exact same parameters within a primitive, then I could just use that to remove the pre-existing primitive.

The problem is that when I try to re-create the primitive object it refuses to accept the instance.

Here is an example of what I'm trying to do that can be copied to the sandbox:

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

var input = {
    id: 'ID1',
    length: 500000,
    topRadius: 300000,
    bottomRadius: 1000
};

function arCylinder(ar, input){
    
    var instance = new Cesium.GeometryInstance({
        geometry: new Cesium.CylinderOutlineGeometry({
            length: input.length,
            topRadius: input.topRadius,
            bottomRadius: input.bottomRadius,
            slices: 10
        }),
        modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
            Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),
        id: input.id,
        attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW)
        }
    });
    
    var newPrimitive = new Cesium.Primitive({
        geometryInstances: instance,
        appearance: new Cesium.PerInstanceColorAppearance({
            flat: true
        })
    });
    
    if (ar === 'a') {
        scene.primitives.add(newPrimitive);
    }else if(ar === 'r'){
        scene.primitives.remove(newPrimitive);
    }
}

Sandcastle.addToolbarButton('Add', function() {
    arCylinder('a', input);
});
Sandcastle.addToolbarButton('Remove', function() {
    arCylinder('r', input);
});

Both times the function is run it should create the exact same 'newPrimitive', but if you debug newPrimitive, 'newPrimitive.numberOfInstances' is 0 on the remove pass. 

Why isn't it adding the instance to the primitive when I am trying to recreate the original geometry variable to remove it?

Mike LP

unread,
May 20, 2015, 1:31:03 PM5/20/15
to cesiu...@googlegroups.com, brents...@gmail.com
The problem you're having is that you keep generating an entirely new Primitive each time through, even on the remove.  So your trying to remove a primitive that has never been added to the scene's primitive collection.

I modified your code sample a little to illustrate how the behavior of the collections and it's objects.  Let me know if this helps

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

   
var input = {
        id
: 'ID1',
        length
: 500000,
        topRadius
: 300000,
        bottomRadius
: 1000
   
};


   
var myPrimitives = [];

   
var instance = new Cesium.GeometryInstance({
        geometry
: new Cesium.CylinderOutlineGeometry({
            length
: input.length,
            topRadius
: input.topRadius,
            bottomRadius
: input.bottomRadius,
            slices
: 10
       
}),
        modelMatrix
: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(
               
Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),
        id
: input.id,
        attributes
: {
            color
: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW)
       
}
   
});


   
function arCylinder(ar){

       
if (ar === 'a') {

           
var myPrimitive = new Cesium.Primitive({

                geometryInstances
: instance,
                appearance
: new Cesium.PerInstanceColorAppearance({
                    flat
: true
               
})
           
});


            myPrimitives
.push(myPrimitive);
            scene
.primitives.add(myPrimitive);

       
}

       
else if(ar === 'r'){

            scene
.primitives.remove(myPrimitives.pop());
       
}
   
}

    Sandcastle.addToolbarButton('Add', function() {
        arCylinder
('a');

    });

   
Sandcastle.addToolbarButton('Remove', function() {

        arCylinder
('r');
    });

Brent Shanahan

unread,
May 20, 2015, 1:57:00 PM5/20/15
to cesiu...@googlegroups.com
I see. 

I assumed that if a primitive was constructed using identical properties that it would be the same but it looks like that's not the case (a unique ID assigned by Cesium somewhere in the primitive object?). 

I take it that if I wanted to remove by the primitive's ID I could use an object instead of an array and use the object keys to search and remove by ID, then delete the key and it's primitive content from the library. My concern is that this library could get particularly heavy if there is a lot of geometry added.

I tried passing the created primitive through socket.io to store it in a database so that I could remove it later but it exceeded the size limit on what could be passed to the server using socket.io.

From my searches I didn't see a way to update a primitive without removing it and recreating it but if there is a way to update a pre-existing primitive I would love to know how it's done.

Mike LP

unread,
May 22, 2015, 9:34:18 AM5/22/15
to cesiu...@googlegroups.com, brents...@gmail.com
The primitives collection does not have a getById method so you're going to need to store a ref to each of the primitives you've created with their associated IDs if you're going to need quick access to remove specific ones.  

example:

var myPrimitives = {};
...
//primitive created
var myNewPrimitive = new Cesium.Primitive...

myPrimitive
[myNewPrimitivesId] = myNewPrimitive;
...

viewer
.scene.primitives.remove( myPrimitives[myPrimitiveId] );
...



This method is only going to be storing a reference to your primitive so it will not be adding much to your memory overhead.

Since primitives are non-mutable objects you're going to need destroy and recreate them when you need to make modifications.

Geoneer

unread,
Dec 11, 2017, 4:17:23 PM12/11/17
to cesium-dev
well... this does not work in my situation. maybe this is changed in Cesium? 

Gabby Getz

unread,
Dec 13, 2017, 4:27:34 PM12/13/17
to cesium-dev
Hi,

The scene has a PrimitiveCollection, with add, contains, and remove functionality. Will that work in your situation?

Thanks,
Gabby
Reply all
Reply to author
Forward
0 new messages