From 9d8dd890d9dba7b2687c287248e40e481e3652fe Mon Sep 17 00:00:00 2001 From: Matias Lavik Date: Sun, 24 Mar 2024 19:13:01 +0100 Subject: [PATCH] Fix prefab saving when overwriting existing prefab (don't duplicate objects) (#236) - Fix prefab saving when overwriting existing prefab (don't duplicate objects) - Don't keep volume texture data after uploading to GPU - Make sure volume data texture always is in sync on material --- Assets/Editor/DragDropHandler.cs | 45 +++++++++++++++---- Assets/Scripts/VolumeData/VolumeDataset.cs | 10 ++--- .../VolumeObject/VolumeRenderedObject.cs | 8 ++-- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/Assets/Editor/DragDropHandler.cs b/Assets/Editor/DragDropHandler.cs index af5a35e6..99890191 100644 --- a/Assets/Editor/DragDropHandler.cs +++ b/Assets/Editor/DragDropHandler.cs @@ -84,17 +84,44 @@ private static DragAndDropVisualMode OnProjectBrowserDrop(int dragInstanceId, st { VolumeRenderedObject srcVolRendObj = volRendObjects[i]; VolumeRenderedObject prefabVolRendObj = prefabVolRendObjects[i]; - VolumeDataset dataset = ScriptableObject.Instantiate(srcVolRendObj.dataset); - TransferFunction transferFunction = ScriptableObject.Instantiate(srcVolRendObj.transferFunction); - Material material = Material.Instantiate(srcVolRendObj.meshRenderer.sharedMaterial); - AssetDatabase.AddObjectToAsset(dataset, prefab); - AssetDatabase.AddObjectToAsset(transferFunction, prefab); - AssetDatabase.AddObjectToAsset(material, prefab); - prefabVolRendObj.dataset = dataset; - prefabVolRendObj.transferFunction = transferFunction; - prefabVolRendObj.meshRenderer.material = material; + if (srcVolRendObj.dataset != prefabVolRendObj.dataset) + { + // Dataset changed => remove old one form asset to avoid wasting space + if (prefabVolRendObj.dataset != null) + AssetDatabase.RemoveObjectFromAsset(prefabVolRendObj.dataset); + VolumeDataset dataset = ScriptableObject.Instantiate(srcVolRendObj.dataset); + AssetDatabase.AddObjectToAsset(dataset, prefab); + prefabVolRendObj.dataset = dataset; + } + if (srcVolRendObj.transferFunction != prefabVolRendObj.transferFunction) + { + if (prefabVolRendObj.transferFunction != null) + AssetDatabase.RemoveObjectFromAsset(prefabVolRendObj.transferFunction); + TransferFunction transferFunction = ScriptableObject.Instantiate(srcVolRendObj.transferFunction); + AssetDatabase.AddObjectToAsset(transferFunction, prefab); + prefabVolRendObj.transferFunction = transferFunction; + } + if (srcVolRendObj.meshRenderer.sharedMaterial != prefabVolRendObj.meshRenderer.sharedMaterial) + { + if (prefabVolRendObj.meshRenderer.sharedMaterial != null) + AssetDatabase.RemoveObjectFromAsset(prefabVolRendObj.meshRenderer.sharedMaterial); + Material material = Material.Instantiate(srcVolRendObj.meshRenderer.sharedMaterial); + AssetDatabase.AddObjectToAsset(material, prefab); + prefabVolRendObj.meshRenderer.material = material; + } } PrefabUtility.SavePrefabAsset(prefab); + for (int i = 0; i < volRendObjects.Length; i++) + { + VolumeRenderedObject srcVolRendObj = volRendObjects[i]; + VolumeRenderedObject prefabVolRendObj = prefabVolRendObjects[i]; + if (!AssetDatabase.Contains(srcVolRendObj.dataset)) + ScriptableObject.DestroyImmediate(srcVolRendObj.dataset); + srcVolRendObj.dataset = prefabVolRendObj.dataset; + srcVolRendObj.transferFunction = prefabVolRendObj.transferFunction; + srcVolRendObj.meshRenderer.sharedMaterial = prefabVolRendObj.meshRenderer.sharedMaterial; + srcVolRendObj.UpdateMaterialProperties(); + } } return DragAndDropVisualMode.Copy; diff --git a/Assets/Scripts/VolumeData/VolumeDataset.cs b/Assets/Scripts/VolumeData/VolumeDataset.cs index ffff8ca1..8b9a8fcb 100644 --- a/Assets/Scripts/VolumeData/VolumeDataset.cs +++ b/Assets/Scripts/VolumeData/VolumeDataset.cs @@ -274,7 +274,7 @@ await Task.Run(() => { texture = new Texture3D(dimX, dimY, dimZ, texformat, false); texture.wrapMode = TextureWrapMode.Clamp; texture.SetPixelData(pixelBytes, 0); - texture.Apply(); + texture.Apply(false, true); dataTexture = texture; pixelBytes.Dispose(); } @@ -299,7 +299,7 @@ await Task.Run(() => { texture = new Texture3D(dimX, dimY, dimZ, texformat, false); texture.wrapMode = TextureWrapMode.Clamp; texture.SetPixelData(pixelBytes, 0); - texture.Apply(); + texture.Apply(false, true); pixelBytes.Dispose(); } } @@ -315,7 +315,7 @@ await Task.Run(() => { for (int z = 0; z < dimZ; z++) texture.SetPixel(x, y, z, new Color((float)(data[x + y * dimX + z * (dimX * dimY)] - minValue) / maxRange, 0.0f, 0.0f, 0.0f)); - texture.Apply(); + texture.Apply(false, true); } progressHandler.EndStage(); Debug.Log("Texture generation done."); @@ -370,7 +370,7 @@ await Task.Run(() => { } progressHandler.EndStage(); progressHandler.StartStage(0.2f, "Uploading gradient texture"); - textureTmp.Apply(); + textureTmp.Apply(false, true); progressHandler.EndStage(); Debug.Log("Gradient gereneration done."); @@ -401,7 +401,7 @@ await Task.Run(() => { Texture3D texture = new Texture3D(dimX, dimY, dimZ, texformat, false); texture.wrapMode = TextureWrapMode.Clamp; texture.SetPixels(cols); - texture.Apply(); + texture.Apply(false, true); progressHandler.EndStage(); Debug.Log("Gradient gereneration done."); diff --git a/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs b/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs index 1151040c..a685845b 100644 --- a/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs +++ b/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs @@ -281,7 +281,7 @@ public async Task SetTransferFunctionAsync(TransferFunction tf, IProgressHandler await UpdateMaterialPropertiesAsync(progressHandler); } - private void UpdateMaterialProperties(IProgressHandler progressHandler = null) + public void UpdateMaterialProperties(IProgressHandler progressHandler = null) { Task task = UpdateMaterialPropertiesAsync(progressHandler); } @@ -293,8 +293,10 @@ private async Task UpdateMaterialPropertiesAsync(IProgressHandler progressHandle try { bool useGradientTexture = tfRenderMode == TFRenderMode.TF2D || renderMode == RenderMode.IsosurfaceRendering || lightingEnabled; - Texture3D texture = useGradientTexture ? await dataset.GetGradientTextureAsync(progressHandler) : null; - meshRenderer.sharedMaterial.SetTexture("_GradientTex", texture); + Texture3D gradientTexture = useGradientTexture ? await dataset.GetGradientTextureAsync(progressHandler) : null; + Texture3D dataTexture = await dataset.GetDataTextureAsync(progressHandler); + meshRenderer.sharedMaterial.SetTexture("_DataTex", dataTexture); + meshRenderer.sharedMaterial.SetTexture("_GradientTex", gradientTexture); UpdateMatInternal(); } finally