Remove clipping CesiumPolygonRasterOverlay added during runtime

I was able to add clipping zones to my Cesium3DTiles during runtime using the blueprint suggestion by @janine in this comment and it works great. I am working with/interested in InvertSelection = true

However, I would also like to be able to remove both the CesiumCartographicPolygon from the world again as well as the CesiumPolygonRasterOverlay from the Cesium3Dtiles actor during runtime. I’m currently not sure how to best approach this.

  • Destroying the CesiumCartographicPolygon actor and refreshing the 3Dtiles crashes unreal (understandable because the CesiumPolygonRasterOverlay still exists and probably references the polygon)
  • setting the CesiumPolygonRasterOverlay Polygons field to an empty array and then calling Refresh Tileset works (sometimes?) if InvertSelection=false but otherwise the entire tileset stays invisible
  • calling Get Component by Class to get the CesiumPolygonRasterOverlay, destroying it and calling Refresh Tileset also does not restore the full Tileset.
  • Destroying the CesiumPolygonRasterOverlay Component and only then destroying the CesiumCartographicPolygon actor also crashes Unreal

It seems like there’s always something that remains from this combination and for some reason the 3dtileset doesn’t refresh to its original form.

Edit: I’m working with my own 3DTiles data that’s included locally as file:///... URL

Hi @arbertrary,

I would expect calling RemoveFromTileset on the CesiumPolygonRasterOverlay and then destroying it should do the trick.

I’d expect simply destroying the component to work as well, but the details of how exactly you’re doing that might matter. Can you share your code?

Hi, thanks for the reply. I’m using UE5.3.2 btw and the Cesium plugin through the marketplace.

This is the blueprint graph that I’m currently using to remove both the cartographic polygon as well as the overlay. The delay seems to be necessary as otherwise Unreal crashes. The actor that triggers the “Event Destroyed” is the clipping box that you can see in the video below.

This is resulting in the following behaviour:

https://youtu.be/-HE7Bdtp0s4

The first placed clipping box/rectangle can be removed almost correctly although it seems to exhibit a similar error as @Dmc-1234 is encountering in this thread.

Afterwards, however, the tileset doesn’t reset to its original form again.

Thanks for the details @arbertrary. I don’t know what’s going on there, but I’ve added it to our short list of user-reported issues for deeper investigation. We’ll report back here soon with what we find out.

Thanks @Kevin_Ring :slight_smile:

I’ve dug into it a bit more. and it seems like the Remove from Tileset blueprint node isn’t working as I expected it to.

I expected the node to reset the component, i.e. clear the Polygons array and also reset for example Invert Selection to the default value. Also (unrelated to Cesium) it doesn’t seem to be that easy to destroy a component. This caused my blueprint code to add additional components each time I’m spawning my clipping box.

Here is a video that shows what happens if I use the blueprint I posted above to remove the clipping overlay. As you can see the Polygons array is not being reset to an empty array.

https://youtu.be/zHYo3LGzgmc

I have now found a solution for both my initial removal problem and the strange flickering/missing of parts of the Cesium3DTileset after removal of the Clipping Polygon.

  1. I am not adding the CesiumPolygonRasterOverlay Component during runtime anymore. I have added this component to the persistent Tileset(s) in the Level. During runtime I’m just adding/removing the Cartographic Polygon actor to the Polygons array
  2. On Event Destroyed I’m now calling RemoveFromTileset, then clearing the Polygons array and I also have to set Invert Selection to false.
  3. Afterwards I can call Refresh Tileset which solves the flickering issue.

Edit: Ok, point 1. isn’t necessary if the blueprint to add the CesiumPolygonRasterOverlay component is set up e.g. like in the post by @Riwa_Unreal here i.e. checking if the component already exists.

Sorry for the delay on this, I finally got a chance to do a bit of investigation. A few notes that might be helpful:

  1. Instead of calling RemoveFromTileset, you should call Deactivate. The reason is that if you remove an overlay from a tileset without deactivating it, it will come back the next time the tileset is refreshed, which can be triggered in a number of ways. But if the component is deactivated, it will be removed and not re-added until it’s reactivated.
  2. Similarly, instead of calling AddToTileset on the component and RefreshTileset on the Tileset, you should just call Activate on the component. This will often (but not always) allow the overlay to be added to the tileset without reloading the tileset. The overlay will just be added to the existing tiles.
  3. Once a raster overlay is successfully added to the tileset (for some overlay types, this will happen before the AddComponentByClass node returns), changing properties will usually have no effect until you call Refresh on the overlay. For example, if you create a CesiumPolygonRasterOverlay and then set its Polygons, you will need to call Refresh before it will have any effect.
  4. Confusingly, some overlays will work differently from the above. CesiumIonRasterOverlay, for instance, is created in an invalid state (the Asset ID must be set before it is usable). Therefore, all you have to do is set the Asset ID and then call Activate and everything will work well. There’s no need to call Refresh in this case.
  5. You can avoid the inconsistency described above by clicking the “Add … Overlay” blueprint node and setting the “Auto Activate” property to false. This way, none of the overlay types will be created until Activate is called, and so properties you set before that call are guaranteed to take effect without ever needing to call Refresh. If you don’t call Activate, the overlay will not show up on the tileset.
  6. Unreal Engine has a strange limitation that only the Actor itself can call “Destroy Component” on one of its components. So if you hoped to add a component with a Level Blueprint, and then later remove that added component also from the Level Blueprint, as I did, well, UE says too bad. You’ll see an error like this in the log, and the component will not be removed.

LogActorComponent: Error: May not destroy component CesiumPolygonRasterOverlay /Game/CesiumSamples/Maps/01/UEDPIE_0_01_CesiumWorld.01_CesiumWorld:PersistentLevel.CesiumWorldTerrain_Blueprint_C_0.NODE_AddCesiumPolygonRasterOverlay-0 owned by CesiumWorldTerrain_Blueprint_C /Game/CesiumSamples/Maps/01/UEDPIE_0_01_CesiumWorld.01_CesiumWorld:PersistentLevel.CesiumWorldTerrain_Blueprint_C_0.

You can work around this by converting your Cesium3DTileset into a Blueprint class:

And then define a Blueprint function that calls Destroy Component:

And now you can call that from your level blueprint and the component will actually be destroyed. No need to call Deactivate or RemoveFromTileset or anything first.

Hopefully some of that is helpful to you! Let me know if you have any questions.

I just opened a PR to improve the documentation for some of those CesiumRasterOverlay functions. It also fixes a bug where calling Refresh on an inactive CesiumRasterOverlay would cause it to appear, only to be removed later if the tileset itself was refreshed.

I just discovered UE’s magical bAllowAnyoneToDestroyMe flag, which, when set, allows the component to be destroyed from outside the Actor. I’ve updated the PR above to also set that flag, so the workaround with the Blueprint class, as described above, will no longer be necessary in the next release.

Thanks for looking into that despite me having found a workaround solution.

I’ll check it out on the next release and adapt my code then. :+1: