# Crashed when removing primitive

**URL:** <https://community.cesium.com/t/crashed-when-removing-primitive/34073>\
**Category:** CesiumJS\
**Created:** [July 25, 2024, 12:08pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073 "2024-07-25T12:08:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Link\_ZY](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/link_zy/32/24912_2.png) [@Link\_ZY](https://community.cesium.com/u/Link_ZY)\
**Post date:** [July 25, 2024, 12:08pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/1 "2024-07-25T12:08:40Z")

</div>

I just want one volume in “viewer.scene.primitives”, so when I update the volume, I need to remove the last volume, and then cesium crashed like:

 ![Screenshot 2024-07-25 190302](https://global.discourse-cdn.com/cesium/original/3X/7/5/75f8f562c7dadbd57cb319cb4653dbd05850d2ed.png)

codes are below:

> function CesiumViewer({ volume }) {  
> const viewerRef = useRef(null);
> 
> ```
> useEffect(() => {
> const viewer = viewerRef.current;
> 
> if (!viewer || !volume) {
> return;
> }
> 
> if(viewer.scene.primitives.get(0)){
> viewer.scene.primitives.remove(viewer.scene.primitives.get(0));
> }
> viewer.scene.primitives.add(volume);
>     
> 
> }, [volume]);
> 
> useEffect(() => {
> const viewer = new Cesium.Viewer("cesiumContainer", {
> baseLayer: Cesium.ImageryLayer.fromProviderAsync(
> Cesium.TileMapServiceImageryProvider.fromUrl(
> Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII")
> )
> ),
> infoBox: false,
> geocoder: false,
> homeButton: false,
> sceneModePicker: false,
> baseLayerPicker: false,
> navigationHelpButton: false,
> animation: false,
> timeline: false,
> fullscreenButton: false,
> vrButton: false,
> selectionIndicator: true,
> shadows: true,
> shouldAnimate: true,
> scene3DOnly: true,
> contextOptions: {
> requestWebgl2: true, //using WEBGL2.0
> webgl: {
> alpha: true
> }
> }
> });
> viewer._cesiumWidget._creditContainer.style.display = "none";
> viewer.scene.logarithmicDepthBuffer = true;
> //viewer.scene.debugShowFramesPerSecond = true;
> 
> viewer.scene.fxaa = true;
> viewer.scene.postProcessStages.fxaa.enabled = true;
> 
> viewer.scene.screenSpaceCameraController.tiltEventTypes = [
> Cesium.CameraEventType.LEFT_DRAG,
> ];
> 
> viewer.scene.screenSpaceCameraController.zoomEventTypes = [
> Cesium.CameraEventType.MIDDLE_DRAG,
> Cesium.CameraEventType.WHEEL,
> Cesium.CameraEventType.PINCH,
> ];
> 
> viewer.scene.screenSpaceCameraController.rotateEventTypes = [
> Cesium.CameraEventType.RIGHT_DRAG,
> ];
> 
> viewerRef.current = viewer;
> 
>     
> }, []);
> 
> return <div id="cesiumContainer" ></div>;
> 
> ```
> 
> }

---

<div class="post-metadata">

**Author:** ![Marco13](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/marco13/32/2757_2.png) [@Marco13](https://community.cesium.com/u/Marco13)\
**Post date:** [July 25, 2024, 12:13pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/2 "2024-07-25T12:13:23Z")

</div>

Just to have the cross-link: You seem to also have mentioned that in the issue comment at [Bug when removing primitve with shared materials · Issue #1567 · CesiumGS/cesium · GitHub](https://github.com/CesiumGS/cesium/issues/1567#issuecomment-2250008899)

The error message is _slightly_ different, though. Here, it is

> `primitive.destroy is not a function`,

but in the issue it was

> `This object was destroyed, i.e., destroy() was called.`

This does not mean that they are not related (or have the same root cause), but this is something that has to be sorted out by whoever investigates this further.

---

<div class="post-metadata">

**Author:** ![Link\_ZY](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/link_zy/32/24912_2.png) [@Link\_ZY](https://community.cesium.com/u/Link_ZY)\
**Post date:** [July 25, 2024, 4:24pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/3 "2024-07-25T16:24:30Z")

</div>

![bug](https://global.discourse-cdn.com/cesium/original/3X/8/9/8920df82687fa3873ef5211c2fa2bbd9987a6134.jpeg)

---

<div class="post-metadata">

**Author:** ![Marco13](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/marco13/32/2757_2.png) [@Marco13](https://community.cesium.com/u/Marco13)\
**Post date:** [July 25, 2024, 4:26pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/4 "2024-07-25T16:26:55Z")

</div>

This is indeed a _feature_.

There are many subtleties that are related to the React infrastructure that is apparently used there. When using something like React, one might need a _deep_ understanding of what this framework actually _does_ under the hood. Similarly, when using CesiumJS, one might need an understanding of certain aspects of the framework.

Let’s look at the relevant part of the code:

```auto
function CesiumViewer({ volume }) {
...
useEffect(() => {
    ...
    if(viewer.scene.primitives.get(0)){
        viewer.scene.primitives.remove(viewer.scene.primitives.get(0));
    }
    viewer.scene.primitives.add(volume);

}, [volume]);

```

What this does is that it removes the _first_ primitive from the primitive collection of the scene (regardless of what this primitive is!).

And then adds the `volume` as a new primitive.

It is not clear what `volume` actually is, because you did not provide this information. Neither did you provide a Sandcastle so that people could try it out. But if this is called more than once (and your description sounds like it is), then it will remove the `volume` and add it back again.

Now, the documentation of the [PrimitiveCollection.remove](https://cesium.com/learn/ion-sdk/ref-doc/PrimitiveCollection.html#remove) function points to [PrimitiveCollection.destroyPrimitives](https://cesium.com/learn/ion-sdk/ref-doc/PrimitiveCollection.html#destroyPrimitives), which says

> Determines if primitives in the collection are destroyed when they are removed

So when the primitive is removed from the collection, then its rendering resources are destroyed (by default). And when trying to add this same primitive again, you might have to expect some form of error message. Maybe an error message like

> This object was destroyed, i.e., destroy() was called.

So this behavior indeed **is** a feature. Namely, that CesiumJS takes care of cleaning up unused resources.

* * *

You could switch this off, by setting  
`viewer.scene.primitives.destroyPrimitives = false;`  
**But…** you should be aware of the implications. When doing that, **you** will have to take care of all the resource management!

The other option is just to not remove-and-add the same primitive _twice_. And here, for your convenience, a Sandcastle, to quickly try this out:

> **[Cesium Sandcastle](https://sandcastle.cesium.com/index.html#c=rVVtb9owEP4rN740SNS0aqu+0WqU0q1aCwhY+yVSZZIDrDl2ZDu0bOK/z3HIC6Vo07R88vmeOz/nu8cJpNAGFgxfUcEVCHyFDmqWROTJ7Xl+LXB2RwpDmUDl1+qXvvBFswnPVAkmZhfwPEcBS5lAKMHMmW44Y04XCEZCwJEKSGKY4JyJMPV9SuOzU4kOUCCJFYuYYQvUJERtlFwOih1LbEq5RnfuNBGBYVJAoJAaLFBeILlUdfjlCwCFJlGiWk6JcwCAGcoIjVre2wugwhYJF1X8l3fuPKwMtPg1tss5i7VkYR5EMm656VXybmHLxJY2DRnb5NGhytgVFUfeyUH6kYMGlKvDg/Wy3ijTLNDGvN1JFVFTsnyq7JJBf3Q/vu/3Xtq925def/jYfsjjV/UyVyRD5I/UKPZWJsrsYxIl3LCYL2+WY0WF5jRti7cGua2pPUwTpNr0pDLz7/FY3rE3DO8UjdArCW/VSqZKRrc4U4ja2z8/ISfnp6enDTi2lR6dnR1Zijsuyd3KxiVtQtfkvUqRLLS17WHemL3CQY3FThLjZqPSJjdp5X10UvP9vLTzWFeKg6wntLjnbLHKidA4RqrS2M0JGKDKk7o07QLnFaF6KYK5kkImKVUnltSzql8C+GKV6iZwSi9kZjX1XkDVcsiwe5vqfJdGaRh6hZk9CCMqwsC2mmPqHUvJJ1TdJMbYofBrQ4ykPdViwHrtK4Gg7RDAPnSG7dHX7sivNaDQtrfW8a7jlcu2yWA3eovs6h8YU9cTKVLKz/3ht/9BOOuJzTv427Z8GXa7vT9XW01ZKbjWqLW0WXK8zofwM4tiK01IFPcIaRqMYqtj1M1JEvxAQwKts9MAWs1qaCtkC6ucqw/+D/bBp1pbzzThfMR+ol+7bjUtfiuUS/vgiVnfPlicLlPY/PD6IdskhLSa1vw40mTNepf5Nw)**
>
> The Cesium Sandcastle provides an interactive environment for testing Cesium code.

---

<div class="post-metadata">

**Author:** ![Link\_ZY](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/link_zy/32/24912_2.png) [@Link\_ZY](https://community.cesium.com/u/Link_ZY)\
**Post date:** [July 25, 2024, 4:45pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/5 "2024-07-25T16:45:18Z")

</div>

Wow, thank you!

I’m sorry, it turns out that it was my fault. I wrote a primitive-like class and forgot to include the _destroy()_ function. After I added this function, the _remove()_ method worked!!!

Guess I still got a lot to learn.

> class volumePrimitive {
> 
> ```
> constructor(options) {
> this.drawCommand = undefined;
> 
> if (Cesium.defined(options)) {
> this.modelMatrix = options.modelMatrix;
> this.geometry = options.geometry;
> this.data = options.data;
> this.width = options.width;
> this.height = options.height;
> this.depth = options.depth;
> this.dim = options.dim;
> this.threshold = options.threshold;
> this.lon = options.lon;
> this.lat = options.lat;
> this.alt = options.alt;
> this.isActive = options.isActive;
> }
> }
> createCommand(context) {
> if (!Cesium.defined(this.geometry)) {
> console.log("error")
> return;
> }
> const geometry = Cesium.BoxGeometry.createGeometry(this.geometry);
> const attributelocations = Cesium.GeometryPipeline.createAttributeLocations(geometry);
> this.vertexarray = Cesium.VertexArray.fromGeometry({
> context: context,
> geometry: geometry,
> attributes: attributelocations
> });
> const renderstate = Cesium.RenderState.fromCache({
> depthTest: {
> enabled: true,
> },
> cull: {
> enabled: false,
> },
> blending: Cesium.BlendingState.ALPHA_BLEND
> })
> const shaderProgram = Cesium.ShaderProgram.fromCache({
> context: context,
> vertexShaderSource: vs,
> fragmentShaderSource: fs,
> attributeLocations: attributelocations
> });
> const that = this;
> const uniformmap = {
> map() {
> return that.getTexture3D(context);
> },
> dim() {
> return that.dim;
> },
> threshold() {
> return that.threshold;
> },
> lon() {
> return that.lon;
> },
> lat() {
> return that.lat;
> },
> alt() {
> return that.alt;
> },
> isActive() {
> return that.isActive;
> }
> };
> 
> this.drawCommand = new Cesium.DrawCommand({
> boundingVolume: this.geometry.boundingSphere,
> modelMatrix: this.modelMatrix,
> pass: Cesium.Pass.VOXELS,
> shaderProgram: shaderProgram,
> renderState: renderstate,
> vertexArray: this.vertexarray,
> uniformMap: uniformmap
> });
> }
> 
> getTexture3D(context) {
> if (!this.texture) {
> this.texture = new Cesium.Texture3D({
> width: this.width,
> height: this.height,
> depth: this.depth,
> context: context,
> pixelFormat: Cesium.PixelFormat.ALPHA,
> pixelDataType: Cesium.ComponentDatatype.fromTypedArray(
> this.data
> ),
> source: {
> width: this.width,
> height: this.height,
> depth: this.depth,
> arrayBufferView: this.data,
> },
> sampler: new Cesium.Sampler({
> minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
> magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR
> }),
> })
> }
> return this.texture;
> }
> 
> update(frameState) {
> if (!this.drawCommand) {
> this.createCommand(frameState.context);
> }
> frameState.commandList.push(this.drawCommand);
> }
> 
> destroy() {
> return Cesium.destroyObject(this);
> }
> 
> ```
> 
> }

---

<div class="post-metadata">

**Author:** ![Marco13](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/marco13/32/2757_2.png) [@Marco13](https://community.cesium.com/u/Marco13)\
**Post date:** [July 25, 2024, 4:50pm UTC](https://community.cesium.com/t/crashed-when-removing-primitive/34073/6 "2024-07-25T16:50:57Z")

</div>

Good to hear that this is resolved now.

Initially, you said

> when I update the volume, I need to remove the last volume, and then cesium crashed

and one could probably dive deeper into what ‘updating’ means here. The approach that you have done now looks like you created a custom class that “looks like” a `Primitive`, and where objects (instances of that class) show a certain, special behavior. I cannot say whether this is “good” or “bad”. But … it _might_ have subtle, unexpected side-effects (and the `destroy()` behavior is only one of them). You might consider isloating the data that actually _changes_ during such an “update”, and create a new primitive with the updated data. But of course, these are engineering/implementation decisions that are eventually up to you.
