代码之家  ›  专栏  ›  技术社区  ›  Enoy

用程序表示以异步方式加载三个模型的顺序必须是确定的

  •  1
  • Enoy  · 技术社区  · 6 年前

    我目前编写了一个程序,加载三个模型:

    1) 第一个是可见的前景,它被称为 起初的 '型号:

    enter image description here

    2) 第二种是灰度模型,它是不可见的(它应该隐藏在前景后面),它被称为 分段 '型号:

    enter image description here

    3) 第三种是另一种灰度模型,它从不透明度0开始,所以它是不可见的,它的任务是用彩色部分可见,所以它是 颜色 '图层:

    enter image description here

    通常,执行顺序应该如前面所述:首先加载原始,然后分段,最后加载颜色,正如您在控制台中看到的:

    Has finished loading: original
    Has finished loading: segmented
    Has finished loading: colors
    

    然而,有时,每5次中有近1次,它首先加载分段,然后加载颜色,最后加载原始颜色,从而产生程序意外行为:

    Has finished loading: segmented
    Has finished loading: colors
    Has finished loading: original
    

    enter image description here

    createSceneSubjects(scene, IndexAtlas) {
    
    
        let isOriginalNrrd = true;
        const sceneSubjects = [
            new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'original')
        ];
        isOriginalNrrd = false;
        sceneSubjects.push(new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'segmented'));
        sceneSubjects.push(new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'colors'));
        return sceneSubjects;
    }
    

    export default class SceneSubject {
        constructor(scene, originalNrrd, IndexAtlas, name) {
    
            this.scene = scene;
            this.originalNrrd = originalNrrd;
    
            this.loader = new NRRDLoader();
            this.filename = this.getFilename(IndexAtlas, originalNrrd);
    
            this.volumesManager = new VolumesManager(this.loader);
    
            this.loader.load(this.filename, this.onSuccess.bind(this));
    
            this.name = name;
    
    
        }
    
        onSuccess(volume) {
            //z plane
            let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
    
            this.volumesManager.addVolumeSliceToMultiVolumeSlice(sliceZ, this.originalNrrd);
    
            this.handleLoadingSpinners();
    
            this.scene.add(sliceZ.mesh);
    
            console.log('Has finished loading:', this.name);
    
    
        }
    
    
        getFilename(IndexAtlas, originalNrrd) {
    
            if (partHasBeenChosenFromGalery()) {
                return getChoosenPartFromThePartClickedOnTheGallery();
            } else {
                return getChoosenPartFromSegmentClickedOnCoverPageURL();
            }
    
    
            function partHasBeenChosenFromGalery() {
                return window.partIndex != null;
            }
    
            function getChoosenPartFromThePartClickedOnTheGallery() {
                return originalNrrd ?
                    IndexAtlas.getSubAtlasActual().subAtlas[window.partIndex].getNrrdVolumen().getOriginal()
                    :
                    IndexAtlas.getSubAtlasActual().subAtlas[window.partIndex].getNrrdVolumen().getSegmentado();
            }
    
            function getChoosenPartFromSegmentClickedOnCoverPageURL() {
                return originalNrrd ?
                    IndexAtlas.getSubAtlasActual().getParteActual().getNrrdVolumen().getOriginal()
                    :
                    IndexAtlas.getSubAtlasActual().getParteActual().getNrrdVolumen().getSegmentado();
            }
        }
    
    
        handleLoadingSpinners() {
            if (isThereASpinner()) {
                removeSpinners();
            }
    
            function isThereASpinner() {
                return document.getElementsByClassName('spinner')[0];
            }
    
            function removeSpinners() {
                const spinners = document.getElementsByClassName('spinner');
                spinners[0].remove();
            }
        }
    
        update(time) {
    
        }
    
    
    }
    

    2) 我尝试了以下解决方案,将计时器添加到加载的第二个和第三个模型(分段和颜色模型)中,将其加载延迟10毫秒,希望能够解决问题:

    createSceneSubjects(scene, IndexAtlas) {
    
    
            let isOriginalNrrd = true;
            const sceneSubjects = [
                new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'original')
            ];
            isOriginalNrrd = false;
            window.setTimeout(this.addSceneSubject
            (sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'segmented'),
                10));
            window.setTimeout(this.addSceneSubject
                (sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'colors')),
                10);
            return sceneSubjects;
        }
    
        addSceneSubject(sceneSubjects, sceneSubject) {
            sceneSubjects.push(sceneSubject);
        }
    

    我已经证实,有时装载静置,如每15次中的1次,是意外的:

    已完成加载:分段
    已完成加载:颜色
    已完成加载:原始
    

    如下图所示:

    enter image description here

    3) 然后,我尝试了以下解决方案,创建一个全局变量,该变量将在原始模型成功加载时进行声明,然后加载分段和颜色模型,如下所示:

    SceneManager.js

    createSceneSubjects(scene, IndexAtlas) {
    
    
            let isOriginalNrrd = true;
            const sceneSubjects = [
                new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'original')
            ];
            isOriginalNrrd = false;
    
            if (window.hasOriginalLoaded) {
                this.addSceneSubject(sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'segmented'));
                this.addSceneSubject(sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'colors'));
            } else {
                this.addSceneSubject(sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'segmented'), 1000);
                this.addSceneSubject(sceneSubjects, new SceneSubject(scene, isOriginalNrrd, IndexAtlas, 'colors'), 1000);
            }
    
    
            return sceneSubjects;
        }
    

    场景主题.js

    export default class SceneSubject {
        constructor(scene, originalNrrd, IndexAtlas, name) {
    
            this.scene = scene;
            this.originalNrrd = originalNrrd;
    
            this.loader = new NRRDLoader();
            this.filename = this.getFilename(IndexAtlas, originalNrrd);
    
            this.volumesManager = new VolumesManager(this.loader);
    
            this.loader.load(this.filename, this.onSuccess.bind(this));
    
            this.name = name;
    
    
        }
    
        onSuccess(volume) {
            //z plane
            let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
    
            this.volumesManager.addVolumeSliceToMultiVolumeSlice(sliceZ, this.originalNrrd);
    
            this.handleLoadingSpinners();
    
            this.scene.add(sliceZ.mesh);
    
            console.log('Has finished loading:', this.name);
    
            if(this.name === 'original'){
                window.hasOriginalLoaded = true;
            }
        }
    

    已完成加载:分段
    已完成加载:颜色
    已完成加载:原始
    

    产生:

    enter image description here

    我们如何用程序来表示按顺序100%加载模型的条件?

    你能给我更多的阅读链接和建议来理解和解决这个问题吗?

    https://www.w3schools.com/Jsref/met_win_settimeout.asp

    用于以NRRD格式加载模型的加载程序如下所示:

    例子: https://threejs.org/examples/#webgl_loader_nrrd

    代码: https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_nrrd.html

    0 回复  |  直到 6 年前