react项目使用web-ifc-three、web-ifc导入ifc文件

界面组件

            <div className='file-btn-container'>
                <input className='file-btn' type='file' />
            </div>

组件事件

import { IFCLoader } from 'web-ifc-three/dist/IFCLoader';
import { IFCOPENINGELEMENT, IFCSPACE } from 'web-ifc';
import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree } from 'three-mesh-bvh';


export default function DrawPanel() {
    const { projectId } = useParams();
    const [loading, setLoading] = useState<boolean>(false);
    const [loadingTip, setLoadingTip] = useState<string>('');
    const [sceneUpdate, setSceneUpdate] = useState<string>(''); // 场景更新的信号
    const systemContext = useContext<SystemStatus>(SystemContext);
    const drawRef = useRef(null);
    const [ifcModels, setIfcModels] = useState<any[]>([]);
    const ifcLoader = new IFCLoader();

    useEffect(() => {
        setupIfcLoader();
        setupFileOpener();
    }, [])

    const setupThreeMeshBVH = () => {
        ifcLoader.ifcManager.setupThreeMeshBVH(
            computeBoundsTree,
            disposeBoundsTree,
            acceleratedRaycast
        );
    }
    const setupIfcLoader = async () => {

        await ifcLoader.ifcManager.parser.setupOptionalCategories({
            [IFCSPACE]: false,
            [IFCOPENINGELEMENT]: false
        });

        // await this.ifcLoader.ifcManager.useWebWorkers(true, 'IFCWorker.js');
        setupThreeMeshBVH();
    }

    const setupFileOpener = () => {
        const input = document.querySelector('input[type="file"]');
        if (!input) return;
        input.addEventListener(
            'change',
            async (changed) => {
                await loadIFC(changed);
            },
            false
        );
    }

    const loadIFC = async (changed) => {
        const start = window.performance.now()
        const ifcURL = URL.createObjectURL(changed.target.files[0]);
        ifcLoader.ifcManager.setOnProgress((event) => console.log(event));
        const firstModel = Boolean(ifcModels.length === 0);
        await ifcLoader.ifcManager.applyWebIfcConfig({
            COORDINATE_TO_ORIGIN: firstModel
        });
        const ifcModel: any = await ifcLoader.loadAsync(ifcURL);
        if (firstModel) {
            const matrixArr: any = ifcLoader.ifcManager.ifcAPI.GetCoordinationMatrix(ifcModel.modelID);
            const matrix = new Matrix4().fromArray(matrixArr);
            ifcLoader.ifcManager.setupCoordinationMatrix(matrix);
        }
        ifcModels.push(ifcModel);
        setIfcModels(ifcModels);
        graphicStore.extraContext.sceneContext.scene.add(ifcModel);
        const stop = window.performance.now()
        console.log(`Time Taken to load = ${(stop - start) / 1000} seconds`);
    }

运行报错

上段代码中主要通过下面这行代码加载ifc文件:

const ifcModel: any = await ifcLoader.loadAsync(ifcURL);

其中,ifcLoader来自web-ifc-three包,但直接npm install的包无法使用,运行报错“wasm streaming compile failed: LinkError: WebAssembly.instantiate(): Import #49 "a" "X": function import requires a callable”。

解决办法

1 从web-ifc下载源码,按照readme文件说明一步一步build项目,最后将整体dist文件夹替换react项目node_modules\web-ifc文件夹;

2 从web-ifc-three下载源码,打开web-ifc-three文件夹,运行npm run build,最后将包含有dist文件夹的整个web-ifc-three文件夹替换react项目node_modules\web-ifc-three文件夹;

3 react项目npm run build,build成功之后,将第1步中dist文件夹中的web-ifc.wasm文件复制到build目录下;

4 配置nginx的config文件,添加以下内容,重启动nginx:

server {
        listen  3000;
        server_name  localhost;

        location / {
            root "replace with your react project address"/build;
            try_files $uri /index.html;
            add_header Cache-Control no-store;
        }

        location ~* \.(wasm)$ {
            root "replace with your react project address"/build;
            types {
                application/wasm wasm;
            }
            add_header Cache-Control "public, max-age=31536000, immutable";
        }
}

5 打开对应端口,即可正常使用;

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值