fix: resolve Context Lost by fixing GPU memory leaks and removing base64 model conversion
Build and Deploy / build-and-push (push) Successful in 55s
Build and Deploy / build-and-push (push) Successful in 55s
This commit is contained in:
+27
-16
@@ -297,20 +297,34 @@ export default function Editor() {
|
||||
|
||||
// Dispose old model when new one is loaded
|
||||
const prevLoadedModelRef = useRef<THREE.Object3D | null>(null);
|
||||
useEffect(() => {
|
||||
if (prevLoadedModelRef.current && prevLoadedModelRef.current !== loadedModel) {
|
||||
prevLoadedModelRef.current.traverse((child) => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
child.geometry.dispose();
|
||||
|
||||
const disposeObject = (obj: THREE.Object3D) => {
|
||||
obj.traverse((child) => {
|
||||
if (child instanceof THREE.Mesh) {
|
||||
if (child.geometry) child.geometry.dispose();
|
||||
if (child.material) {
|
||||
if (Array.isArray(child.material)) {
|
||||
child.material.forEach(m => m.dispose());
|
||||
} else {
|
||||
child.material.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (prevLoadedModelRef.current && prevLoadedModelRef.current !== loadedModel) {
|
||||
disposeObject(prevLoadedModelRef.current);
|
||||
}
|
||||
prevLoadedModelRef.current = loadedModel;
|
||||
|
||||
return () => {
|
||||
if (prevLoadedModelRef.current) {
|
||||
disposeObject(prevLoadedModelRef.current);
|
||||
prevLoadedModelRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [loadedModel]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [importProgress, setImportProgress] = useState(0);
|
||||
@@ -348,7 +362,9 @@ export default function Editor() {
|
||||
|
||||
if (parsedSd.modelData && parsedSd.modelData.data === 'model.glb' && unzipped['model.glb']) {
|
||||
const modelBlob = new Blob([unzipped['model.glb']]);
|
||||
parsedSd.modelData.data = URL.createObjectURL(modelBlob);
|
||||
const bUrl = URL.createObjectURL(modelBlob);
|
||||
parsedSd.modelData.data = bUrl;
|
||||
setBlobURLs(prev => [...prev, bUrl]);
|
||||
}
|
||||
sd = parsedSd;
|
||||
}
|
||||
@@ -992,9 +1008,7 @@ export default function Editor() {
|
||||
setIsLoading(true);
|
||||
setImportStatus("Restoring model...");
|
||||
try {
|
||||
const response = await fetch(modelInfo.data);
|
||||
const blob = await response.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const url = modelInfo.data;
|
||||
|
||||
const manager = new THREE.LoadingManager();
|
||||
let object: THREE.Object3D | null = null;
|
||||
@@ -5201,12 +5215,9 @@ export default function Editor() {
|
||||
|
||||
// Save model data for scene persistence
|
||||
const modelBlob = await fetch(modelUrl).then(r => r.blob());
|
||||
const modelBase64 = await new Promise<string>((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result as string);
|
||||
reader.readAsDataURL(modelBlob);
|
||||
});
|
||||
setModelData({ name: "Generated_Model.glb", data: modelBase64, extension: 'glb' });
|
||||
const blobUrl = URL.createObjectURL(modelBlob);
|
||||
setBlobURLs(prev => [...prev, blobUrl]);
|
||||
setModelData({ name: "Generated_Model.glb", data: blobUrl, extension: 'glb' });
|
||||
|
||||
const boundingBox = new THREE.Box3().setFromObject(object);
|
||||
const center = new THREE.Vector3();
|
||||
|
||||
Reference in New Issue
Block a user