繁体   English   中英

Forge Autodesk 使用 ReactJS 在查看器中加载多个模型

[英]Forge Autodesk load multiple models in Viewer with ReactJS

我们正在使用 Forge Autodesk Viewer 加载 Forge 模型。 我们正在为我们的应用程序使用框架 ReactJS 并且我们有 function 波纹管在查看器中加载一个 model:

function loadModel(viewer, documentId) {
    function onDocumentLoadSuccess(viewerDocument) {
        // viewerDocument is an instance of Autodesk.Viewing.Document
        const bubbleNode = viewerDocument.getRoot();
        let defaultModel;

        if (props.phaseName) {
            defaultModel = bubbleNode.getMasterView(props.phaseName);
        } else if (props.guid) {
            defaultModel = bubbleNode.findByGuid(props.guid);
        } else if (props.viewableID) {
            const results = bubbleNode.search({viewableID: props.viewableID});
            if (results && results.length) {
                defaultModel = results[0];
            }
        } else if (props.geomIndex) {
            const geoms = bubbleNode.search({type: "geometry"});
            if (geoms.length) {
                if (props.geomIndex < 0 || props.geomIndex >= geoms.length) {
                    console.warn("GeometryIndex Error: Invalid geometry index.");
                }
                const index = Math.min(Math.max(props.geomIndex, 0), geoms.length - 1); // Ensure index is valid.
                defaultModel = geoms[index];
            }
        }

        if (!defaultModel) defaultModel = bubbleNode.getDefaultGeometry(true);
        const skipHiddenFragments = props.skipHiddenFragments || false;
        viewer.loadDocumentNode(viewerDocument, defaultModel, {
            keepCurrentModels: true,
            skipHiddenFragments: skipHiddenFragments,
        });

     
        viewer.prefs.set("ghosting", false);

            viewer.loadExtension("Autodesk.Viewing.MarkupsCore")
            viewer.loadExtension("Autodesk.Viewing.MarkupsGui")
    }

    function onDocumentLoadFailure() {
        console.error("Failed fetching Forge manifest");
    }

    if (documentId) {
        Autodesk.Viewing.Document.load(
            documentId,
            onDocumentLoadSuccess,
            onDocumentLoadFailure
        );
    } else {
        props.eventBus.dispatchEvent({type: "VIEWER_READY", data: {viewer}});
    }
}

我们实际上想知道如何使用 ReactJS 加载多个模型。 谢谢您的答复。

使代码支持 w/ 和 w/o react.js 之间的多个模型没有区别。 您可以通过搜索https://stackoverflow.com/search?q=%5Bautodesk-forge%5D+multiple+models找到很多示例

反正...

这是一个用于加载多个模型的方法,但是您必须更改传递给 Viewer 组件的道具,并相应地更改 Viewer 组件外部的事件调用。

//process each promise
//refer to http://jsfiddle.net/jfriend00/h3zaw8u8/
const promisesInSequence = (tasks, callback) => {
    const results = [];
    return tasks.reduce((p, item) => {
      return p.then(() => {
        return callback(item).then((data) => {
          results.push(data);
          return results;
        });
      });
    }, Promise.resolve());
};

const AGGREGATE_GEOMETRY_LOADED_EVENT = 'aggregateGeometryLoaded';

/**
 * @component
 * Component for rendering LMV
 * @param {Object} props
 * @param {("AutodeskProduction"|"AutodeskStaging"|"MD20ProdUS"|"MD20ProdEU")} [props.env] Forge API environment
 * @param {Function} props.getToken Returns the Forge API token to access LMV
 * @param {"derivativeV2"|"derivativeV2_EU"|"modelDerivativeV2"|"fluent"|"D3S"|"D3S_EU"} [props.api] Default = "derivativeV2". Please refer to LMV documentation for more information.
 * @param {Object[]} [props.docUrns] Model data to be loaded
 * @param {string} [modelURNs[].urn] Document URN of the model to be loaded
 * @param {Object} [modelURNs[].options] model options used in loading the specfic model
 * @param {string} [modelURNs[].options.phaseName] phaseName of view to load in scene.
 * @param {string} [modelURNs[].options.guid] guid of BubbleNode to load in scene.
 * @param {string} [modelURNs[].options.viewableID] viewableID of BubbleNode to load in scene.
 * @param {number} [modelURNs[].options.geomIndex] Index of geometry to load in scene.
 * @param {Boolean} [modelURNs[].options.skipHiddenFragments] Boolean to specify if hidden fragments should be skipped (Default: false,
 * Hidden fragments are required for heatmaps in rooms, only applicable to SVF2)
 * @param {OnModelLoaded} [props.onModelLoaded] Callback function invoked when the model has loaded
 * @param {OnViewerInitialized} [props.onViewerInitialized] Callback function invoked when LMV has been intialized
 * @param {string[]} [props.extensions] List of extension ids forwarded to viewer config to load.
 * @param {Object.<string, Object>} [props.disabledExtensions] Default extensions to prevent being loaded.
 * @param {Object} [props.viewerOptions] Options object to forward to Autodesk.Viewing.Initializer
 * @memberof Autodesk.DataVisualization.UI
 * @alias Autodesk.DataVisualization.UI.Viewer
 */
export default function Viewer(props) {
    const viewerRef = useRef(null);
    const viewerDomRef = useRef(null);

    function onModelLoaded(event) {
        const viewer = viewerRef.current;

        // const av = Autodesk.Viewing;
        // viewer.removeEventListener(av.GEOMETRY_LOADED_EVENT, onModelLoaded);
        viewer.removeEventListener(AGGREGATE_GEOMETRY_LOADED_EVENT, onModelLoaded);

        if (props.onModelLoaded) {
            props.onModelLoaded(viewer, event);
        }
    }

    /**
     * Initializes LMV.
     *
     * @memberof Autodesk.DataVisualization.UI
     * @alias Autodesk.DataVisualization.UI.Viewer#initializeViewer
     * @private
     */
    function initializeViewer() {
        let viewerOptions = props.viewerOptions;

        var options = Object.assign({}, viewerOptions, {
            env: props.env,
            api: props.api || "derivativeV2", // for models uploaded to EMEA change this option to 'derivativeV2_EU'
            getAccessToken: async function (onTokenReady) {
                let token = await props.getToken();
                var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
                onTokenReady(token, timeInSeconds);
            },
        });

        Autodesk.Viewing.Initializer(options, async function () {
            const extensionsToLoad = props.extensions;

            const extensionsWithConfig = [];
            const extensionsWithoutConfig = [];

            for (let key in extensionsToLoad) {
                const config = extensionsToLoad[key];
                if (Object.keys(config).length === 0) {
                    extensionsWithoutConfig.push(key);
                } else {
                    extensionsWithConfig.push(key);
                }
            }

            const viewer = new Autodesk.Viewing.GuiViewer3D(viewerDomRef.current, {
                extensions: extensionsWithoutConfig,
                disabledExtensions: props.disabledExtensions || {},
            });

            extensionsWithConfig.forEach((ext) => {
                viewer.loadExtension(ext, extensionsToLoad[ext]);
            });

            viewerRef.current = viewer;

            const startedCode = viewer.start(undefined, undefined, undefined, undefined, options);
            if (startedCode > 0) {
                console.error("Failed to create a Viewer: WebGL not supported.");
                return;
            }

            // loadModel(viewer, props.docUrn);
            await loadModels(viewer, props.docUrns);

            if (props.onViewerInitialized) {
                props.onViewerInitialized(viewer);
            }
        });
    }

    /**
     * Loads the specified models into the viewer.
     *
     * @param {Object} viewer Initialized LMV object
     * @param {string} documentId Document URN of the model to be loaded
     * @param {Object} options
     * @param {string} [options.phaseName] phaseName of view to load in scene.
     * @param {string} [options.guid] guid of BubbleNode to load in scene.
     * @param {string} [options.viewableID] viewableID of BubbleNode to load in scene.
     * @param {number} [options.geomIndex] Index of geometry to load in scene.
     * @param {Boolean} [options.skipHiddenFragments] Boolean to specify if hidden fragments should be skipped (Default: false,
     * Hidden fragments are required for heatmaps in rooms, only applicable to SVF2)
     * @memberof Autodesk.DataVisualization.UI
     * @alias Autodesk.DataVisualization.UI.Viewer#loadModelAsync
     * @private
     */
    async function loadModelAsync(viewer, documentId, options) {
        return new Promise((resolve, reject) => {
            async function onDocumentLoadSuccess(viewerDocument) {
                // viewerDocument is an instance of Autodesk.Viewing.Document
                const bubbleNode = viewerDocument.getRoot();
                let defaultModel;

                if (options.phaseName) {
                    defaultModel = bubbleNode.getMasterView(options.phaseName);
                } else if (options.guid) {
                    defaultModel = bubbleNode.findByGuid(options.guid);
                } else if (options.viewableID) {
                    const results = bubbleNode.search({ viewableID: options.viewableID });
                    if (results && results.length) {
                        defaultModel = results[0];
                    }
                } else if (options.geomIndex) {
                    const geoms = bubbleNode.search({ type: "geometry" });
                    if (geoms.length) {
                        if (options.geomIndex < 0 || options.geomIndex >= geoms.length) {
                            console.warn("GeometryIndex Error: Invalid geometry index.");
                        }
                        const index = Math.min(Math.max(options.geomIndex, 0), geoms.length - 1); // Ensure index is valid.
                        defaultModel = geoms[index];
                    }
                }

                if (!defaultModel) defaultModel = bubbleNode.getDefaultGeometry(true);
                const skipHiddenFragments = options.skipHiddenFragments || false;
                let model = await viewer.loadDocumentNode(viewerDocument, defaultModel, {
                    keepCurrentModels: true,
                    skipHiddenFragments: skipHiddenFragments,
                });

                // modify the preference settings, since ghosting is causing heavy z-fighting with the room geometry
                // it would be good we turn it off
                if (!viewer.model)
                    viewer.prefs.set("ghosting", false);

                await viewer.waitForLoadDone();
                resolve(model);
            }

            function onDocumentLoadFailure() {
                console.error("Failed fetching Forge manifest");
            }

            if (documentId) {
                Autodesk.Viewing.Document.load(
                    documentId,
                    onDocumentLoadSuccess,
                    onDocumentLoadFailure
                );
            } else {
                props.eventBus.dispatchEvent({ type: "VIEWER_READY", data: { viewer } });
            }
        });
    }


    /**
     * Loads the specified models into the viewer.
     *
     * @param {Object} viewer Initialized LMV object
     * @param {Object[]} modelURNs Model data to be loaded
     * @param {string} [modelURNs[].urn] Document URN of the model to be loaded
     * @param {Object} [modelURNs[].options] model options used in loading the specfic model
     * @param {string} [modelURNs[].options.phaseName] phaseName of view to load in scene.
     * @param {string} [modelURNs[].options.guid] guid of BubbleNode to load in scene.
     * @param {string} [modelURNs[].options.viewableID] viewableID of BubbleNode to load in scene.
     * @param {number} [modelURNs[].options.geomIndex] Index of geometry to load in scene.
     * @param {Boolean} [modelURNs[].options.skipHiddenFragments] Boolean to specify if hidden fragments should be skipped (Default: false,
     * Hidden fragments are required for heatmaps in rooms, only applicable to SVF2)
     * @memberof Autodesk.DataVisualization.UI
     * @alias Autodesk.DataVisualization.UI.Viewer#loadModelAsync
     * @private
     */
    async function loadModelsAsync(viewer, modelURNs) {
        // const av = Autodesk.Viewing;
        // viewer.addEventListener(av.GEOMETRY_LOADED_EVENT, onModelLoaded, { once: true });
        viewer.addEventListener(AGGREGATE_GEOMETRY_LOADED_EVENT, onModelLoaded, { once: true });

        const results = await promisesInSequence(modelURNs, (d) => loadModelAsync(d.urn, d.options));
        viewer.fireEvent({
            type: AGGREGATE_GEOMETRY_LOADED_EVENT,
            models: results
        });
    }

    useEffect(() => {
        initializeViewer();

        return function cleanUp() {
            if (viewerRef.current) {
                viewerRef.current.finish();
            }
        };
    }, []);

    return <div id="forgeViewer" ref={viewerDomRef}></div>;
}

Viewer.displayName = "Viewer";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM