Browse Source

Model3DView 模型释放问题

master
修宁 7 months ago
parent
commit
d1f4f961d1
  1. 1
      src/components/ShowDialogWrap.vue
  2. 117
      src/designer/Model3DView.vue
  3. 1
      src/designer/viewWidgets/alarm/AlarmView.vue
  4. 3
      src/runtime/System.ts

1
src/components/ShowDialogWrap.vue

@ -24,6 +24,7 @@
</div> </div>
</template> </template>
<script> <script>
import _ from 'lodash'
import { markRaw } from 'vue' import { markRaw } from 'vue'
import ElementDialogResize from '@/components/element-dialog-resize' import ElementDialogResize from '@/components/element-dialog-resize'

117
src/designer/Model3DView.vue

@ -70,7 +70,7 @@
</template> </template>
<script setup> <script setup>
import TransformEdit from '@/components/propertyEdit/TransformEdit.vue' import TransformEdit from '@/components/propertyEdit/TransformEdit.vue'
import { ref, onMounted, nextTick, reactive, watch } from 'vue' import { ref, onMounted, nextTick, reactive, watch, getCurrentInstance, onUnmounted, onBeforeUnmount } from 'vue'
import * as THREE from 'three' import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader' import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
@ -92,7 +92,7 @@ const transformEditCtl = ref(null)
// Three.js // Three.js
let scene, camera, renderer, controls let scene, camera, renderer, controls
let statsControls, axesHelper, gridHelper let statsControls, axesHelper, gridHelper
let gui, tcontrols, modelGroup let gui, tcontrols, modelGroup, resizeObserver
const restate = reactive({ const restate = reactive({
targetColor: '#ff0000', targetColor: '#ff0000',
@ -116,9 +116,31 @@ onMounted(() => {
nextTick(() => { nextTick(() => {
initThree() initThree()
initGUI() initGUI()
const viewerDom = canvasContainer.value
if (resizeObserver) {
resizeObserver.unobserve(viewerDom)
}
resizeObserver = new ResizeObserver(handleResize)
resizeObserver.observe(viewerDom)
window['model3dView'] = getCurrentInstance()
window['model3dViewRenderer'] = renderer
}) })
}) })
onBeforeUnmount(() => {
cleanupThree()
const viewerDom = canvasContainer.value
if (resizeObserver) {
resizeObserver.unobserve(viewerDom)
}
window['model3dView'] = null
window['model3dViewRenderer'] = null
})
watch(() => restate.targetColor, (newVal) => { watch(() => restate.targetColor, (newVal) => {
if (modelGroup) { if (modelGroup) {
modelGroup.traverse((child) => { modelGroup.traverse((child) => {
@ -221,11 +243,6 @@ function initThree() {
// tcontrols.size = 1 // tcontrols.size = 1
// tcontrols.space = 'local' // tcontrols.space = 'local'
scene.add(tcontrols.getHelper()) scene.add(tcontrols.getHelper())
// ResizeObserver
const resizeObserver = new ResizeObserver(handleResize)
// DOM
resizeObserver.observe(viewerDom)
} }
// //
@ -397,6 +414,9 @@ function handleTextureUpload(file) {
file = file.raw file = file.raw
//
cleaupModel()
const fileName = file.name.toLowerCase() const fileName = file.name.toLowerCase()
const reader = new FileReader() const reader = new FileReader()
reader.onerror = (error) => { reader.onerror = (error) => {
@ -435,12 +455,7 @@ function handleMtlUpload(file) {
file = file.raw file = file.raw
// //
if (modelGroup) { cleaupModel()
scene.remove(modelGroup)
}
tcontrols.detach()
transformEditCtl.value.detach()
modelGroup = null
const fileName = file.name.toLowerCase() const fileName = file.name.toLowerCase()
const reader = new FileReader() const reader = new FileReader()
@ -528,11 +543,7 @@ function handleFileChange(file) {
file = file.raw file = file.raw
// //
if (modelGroup) { cleaupModel()
scene.remove(modelGroup)
}
tcontrols.detach()
transformEditCtl.value.detach()
const fileName = file.name.toLowerCase() const fileName = file.name.toLowerCase()
const reader = new FileReader() const reader = new FileReader()
@ -582,6 +593,76 @@ function handleFileChange(file) {
} }
} }
function cleaupModel() {
if (modelGroup) {
scene.remove(modelGroup)
}
tcontrols.detach()
transformEditCtl.value.detach()
}
function cleanupThree() {
//
if (scene) {
scene.traverse((obj) => {
//
if (obj.geometry) {
obj.geometry.dispose()
}
//
if (obj.material) {
if (Array.isArray(obj.material)) {
obj.material.forEach(m => m.dispose())
} else {
obj.material.dispose()
}
}
//
if (obj.texture) {
obj.texture.dispose()
}
//
if (obj.renderTarget) {
obj.renderTarget.dispose()
}
// OrbitControls
if (obj.dispose) {
obj.dispose()
}
})
if (modelGroup) {
scene.remove(modelGroup)
}
//
scene.children = []
modelGroup = null
}
if (gui) {
gui.destroy()
}
if (tcontrols) {
tcontrols.dispose()
}
if (statsControls) {
statsControls.dom.remove()
}
if (renderer) {
renderer.dispose()
renderer.forceContextLoss()
console.log('WebGL disposed, memory:', renderer.info.memory)
renderer.domElement = null
}
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.model3d-view { .model3d-view {

1
src/designer/viewWidgets/alarm/AlarmView.vue

@ -59,7 +59,6 @@ import IWidgets from '../IWidgets.js'
export default { export default {
name: 'AlarmView', name: 'AlarmView',
webSocketSubscribe: ['alarm'],
emits: ['close'], emits: ['close'],
mixins: [IWidgets], mixins: [IWidgets],
data() { data() {

3
src/runtime/System.ts

@ -40,6 +40,9 @@ export default class System {
constructor(app: App) { constructor(app: App) {
this.app = app this.app = app
window['_'] = _
window['$'] = $
window['JSON5'] = JSON5
} }
/** /**

Loading…
Cancel
Save