void C4DefGraphicsPtrBackup::AssignRemoval()
{
	// Reset all mesh materials to what they were before the update
	MeshMaterialUpdate.Cancel();
	UpdateMeshes();

	// only if graphics are assigned
	if (pGraphicsPtr)
	{
		// check all objects
		for (C4Object *pObj : Objects)
			if (pObj && pObj->Status)
				{
					if (pObj->pGraphics == pGraphicsPtr)
					{
						// same graphics found. If these are mesh graphics then remove
						// the object because the StdMesh has already been unloaded.
						if(pObj->pMeshInstance)
						{
							assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh());

							pObj->AssignRemoval();
							delete pObj->pMeshInstance;
							pObj->pMeshInstance = NULL;
							pObj->pGraphics = NULL;
						}
						// sprite graphics; reset them
						else if (!pObj->SetGraphics()) { pObj->AssignRemoval(); pObj->pGraphics=NULL; }
					}
					// remove any overlay graphics
					for (;;)
					{
						C4GraphicsOverlay *pGfxOverlay;
						for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
							if (pGfxOverlay->GetGfx() == pGraphicsPtr)
							{
								// then remove this overlay and redo the loop, because iterator has become invalid
								pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID());
								break;
							}
						// looped through w/o removal?
						if (!pGfxOverlay) break;
					}
					// remove menu frame decorations
					C4GUI::FrameDecoration *pDeco;
					if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
						if (pDeco->idSourceDef == pDef->id)
							pObj->Menu->SetFrameDeco(NULL);
				}
		// done; reset field to indicate finished update
		pGraphicsPtr = NULL;
	}
	// check next graphics
	if (pNext) pNext->AssignRemoval();
}
void C4DefGraphicsPtrBackupEntry::AssignUpdate()
{
	// Update all attached meshes that were using this mesh
	UpdateAttachedMeshes();

	// only if graphics are assigned
	if (pGraphicsPtr)
	{
		// check all objects
		for (C4Object *pObj : Objects)
		{
			if (pObj && pObj->Status)
				{
					if (pObj->pGraphics == pGraphicsPtr)
					{
						// same graphics found. Update mesh graphics if any.
						if(pMeshUpdate)
						{
							assert(pObj->pMeshInstance != NULL); // object had mesh graphics, so mesh instance should be present
							assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh()); // mesh instance of correct type even

							// Get new mesh from reloaded graphics
							C4DefGraphics *pGrp = pDef->Graphics.Get(Name);
							if(pGrp && pGrp->Type == C4DefGraphics::TYPE_Mesh)
								pMeshUpdate->Update(pObj->pMeshInstance, *pGrp->Mesh);
						}

						// try to set new graphics
						if (!pObj->SetGraphics(Name, pDef))
							if (!pObj->SetGraphics(Name, pObj->Def))
							{
								// shouldn't happen
								pObj->AssignRemoval(); pObj->pGraphics=NULL;
							}
					}

					// remove any overlay graphics
					for (;;)
					{
						C4GraphicsOverlay *pGfxOverlay;
						for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
							if (pGfxOverlay->GetGfx() == pGraphicsPtr)
							{
								// then remove this overlay and redo the loop, because iterator has become invalid
								pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID());
								break;
							}
						// looped through w/o removal?
						if (!pGfxOverlay) break;
					}
					// update menu frame decorations - may do multiple updates to the same deco if multiple menus share it...
					C4GUI::FrameDecoration *pDeco;
					if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
						if (pDeco->idSourceDef == pDef->id)
							if (!pDeco->UpdateGfx())
								pObj->Menu->SetFrameDeco(NULL);
				}
		}
		// done; reset field to indicate finished update
		pGraphicsPtr = NULL;
	}
}