Другое

Оптимизация производительности APS Viewer для Revit-моделей

Узнайте, как ускорить просмотр больших моделей Revit в Autodesk Platform Services: настройка SVF2, кэширование OPFS и параметры просмотра, чтобы сократить время загрузки до 10 секунд.

Почему просмотрщик Autodesk Platform Services (APS) работает значительно медленнее, чем просмотрщик Autodesk Construction Cloud (ACC) для одних и тех же моделей Revit?

У меня наблюдается серьёзная проблема с производительностью: приложение APS загружает модели Revit (600–700 МБ) примерно за 2 минуты, тогда как те же модели в ACC открываются менее чем за 10 секунд. Это существенное различие указывает на потенциальные возможности оптимизации в реализации APS.

Текущая конфигурация:

  • Используется версия просмотрщика APS v7.114.0
  • Применён формат SVF2
  • Добавлен параметр ?useOPFS=true в URL приложения
  • Для конвертации производных используется следующий код:
javascript
const { ModelDerivativeClient, ConversionMethod, View, Type } = require("@aps_sdk/model-derivative");

const urn = req.body.objectName;
const svfPayloadFormat = {
    views: [View._2d, View._3d],
    type: Type.Svf2,
};

const JobPayload = {
    input: { urn: urn, compressedUrn: false },
    output: {
        formats: [svfPayloadFormat],
    }
};

try {
    const job2 = await modelDerivativeClient.startJob(req.oauth_token.access_token, JobPayload);
    return job2.result;
} catch (error) {
    next(error);
}

Какие оптимизации или изменения в настройках я могу внести, чтобы сократить время загрузки в моём приложении APS и достичь производительности, аналогичной ACC?

Сильное различие в скорости загрузки моделей в вашем APS‑viewer и Autodesk Construction Cloud (ACC) скорее всего связано с несколькими пробелами в оптимизации текущей реализации. ACC использует собственные серверные оптимизации, инфраструктуру кэширования и настройки просмотрщика, которые не применяются автоматически в пользовательских APS‑решениях. Время загрузки 2 минуты в APS против менее 10 секунд в ACC указывает на возможности улучшения через правильную конфигурацию SVF2, реализацию кэширования и настройки просмотрщика.

Содержание

Понимание разрыва в производительности

Viewer в Autodesk Construction Cloud (ACC) получает выгоду от собственных серверных оптимизаций и инфраструктуры уровня предприятия, которые не доступны в пользовательских APS‑реализациях. Согласно документации Autodesk по производительности, разрыв в производительности возникает из‑за того, что ACC использует специализированные техники оптимизации, включая:

  • Продвинутая оптимизация геометрии специально для моделей Revit
  • Инфраструктура кэширования уровня предприятия с глобальной CDN‑распределённостью
  • Механизмы выборочного загрузки приоритетизирующие видимую геометрию
  • Предобработанные форматы производных оптимизированные для веб‑передачи

Ваша APS‑реализация, хотя и использует формат SVF2, может не использовать эти стратегии оптимизации. Модели Revit размером 600–700 МБ особенно трудны для веб‑просмотрщиков, и без надлежащей оптимизации большие наборы геометрии могут вызывать значительные задержки при загрузке.

“Выпуск SVF2 в конвейер Model Derivative позволяет клиентам получать лучшую производительность при просмотре моделей, особенно тех, которые поступают из Revit.” - Autodesk Platform Services Blog

Оптимизация формата SVF2

Формат SVF2 специально разработан для улучшенной потоковой передачи, но необходимо убедиться, что он правильно настроен для больших моделей Revit. Текущая реализация запрашивает только базовые 2D и 3D представления, что может не использовать все возможности оптимизации SVF2.

Расширенная конфигурация представлений

Рассмотрите возможность добавления специализированных представлений, оптимизированных под разные сценарии использования:

javascript
const svfPayloadFormat = {
    views: [
        View._2d, 
        View._3d,
        View.aecPlan,      // Оптимизировано для архитектурных планов
        View.aecElevation, // Оптимизировано для фасадов
        View.aecSection    // Оптимизировано для разрезов
    ],
    type: Type.Svf2,
};

Оптимизация, специфичная для модели

Для больших моделей Revit рассмотрите внедрение оптимизации, специфичной для геометрии:

javascript
const JobPayload = {
    input: { 
        urn: urn, 
        compressedUrn: false,
        // Добавьте оптимизации, специфичные для модели
        derivativeOptions: {
            3d: {
                // Низкий LOD (уровень детализации) для более быстрой начальной загрузки
                lods: [2, 3, 4], // Начинаем с низких LOD
                // Пошаговая загрузка
                progressive: true,
                // Упрощение сложной геометрии
                simplify: true
            }
        }
    },
    output: {
        formats: [svfPayloadFormat],
    }
};

Согласно документации Autodesk по SVF2, формат SVF2 «значительно уменьшает размер хранилища Viewable и ускоряет просмотр и загрузку» при правильной настройке для конкретных случаев использования.


Реализация кэширования OPFS

Вы уже реализовали ?useOPFS=true, что отлично подходит для постоянного кэширования, но есть дополнительные возможности оптимизации:

Конфигурация кэша

Убедитесь, что ваш просмотрщик правильно обрабатывает кэш OPFS:

javascript
// Убедитесь в правильной инициализации OPFS
const viewerConfig = {
    useOPFS: true,
    // Дополнительные настройки оптимизации кэша
    cacheConfig: {
        // Увеличьте размер кэша при необходимости
        maxCacheSize: 2048, // 2GB кэш
        // Включите агрессивное кэширование геометрии
        geometryCacheEnabled: true,
        // Включите кэширование текстур
        textureCacheEnabled: true,
        // Настройки истечения срока действия кэша
        cacheExpiration: 7 * 24 * 60 * 60 * 1000 // 7 дней
    }
};

Управление кэшем

Реализуйте стратегии управления кэшем для больших моделей:

javascript
// Перед загрузкой проверьте доступность кэша
async function checkCacheAvailability() {
    try {
        if ('storage' in navigator && 'estimate' in navigator.storage) {
            const estimate = await navigator.storage.estimate();
            const availableSpace = estimate.quota - estimate.usage;
            const requiredSpace = 1024 * 1024 * 512; // Оценка 512MB для модели
            
            if (availableSpace < requiredSpace) {
                // Очистите кэш или уведомите пользователя
                await clearViewerCache();
            }
        }
    } catch (error) {
        console.warn('Проверка доступности кэша не удалась:', error);
    }
}

// Очистка кэша просмотрщика при необходимости
async function clearViewerCache() {
    if ('caches' in window) {
        const cacheNames = await caches.keys();
        for (const cacheName of cacheNames) {
            if (cacheName.includes('autodesk-viewer')) {
                await caches.delete(cacheName);
            }
        }
    }
}

Как отмечено в обновлении по производительности Autodesk, «APS Viewer загружает большие объемы геометрических данных каждый раз, когда открывает модель SVF2 впервые», и кэширование OPFS необходимо для «ускорения последующих загрузок моделей».


Конфигурация Model Derivative

Текущая конфигурация Model Derivative может не быть оптимизированной для больших моделей Revit. Рассмотрите следующие улучшения:

Расширенные настройки конвертации

javascript
const JobPayload = {
    input: { 
        urn: urn, 
        compressedUrn: false,
        // Добавьте сжатие для больших моделей
        advanced: {
            // Включите сжатие геометрии
            geometryCompression: true,
            // Включите сжатие текстур
            textureCompression: true,
            // Установите соответствующие уровни качества
            quality: 'medium' // Может быть 'low', 'medium', 'high'
        }
    },
    output: {
        formats: [{
            type: Type.Svf2,
            views: [View._2d, View._3d],
            // Добавьте параметры, специфичные для формата
            advanced: {
                // Включите прогрессивную загрузку
                progressive: true,
                // Включите выборочную загрузку геометрии
                selectiveGeometry: true,
                // Включите оптимизацию LOD
                lodOptimization: true
            }
        }]
    }
};

Управление задачами и мониторинг

Реализуйте мониторинг задач для отслеживания прогресса конвертации и эффективной обработки больших моделей:

javascript
async function monitorConversionJob(accessToken, jobId) {
    const maxAttempts = 60; // максимум 5 минут ожидания
    let attempts = 0;
    
    while (attempts < maxAttempts) {
        try {
            const jobStatus = await modelDerivativeClient.getJob(accessToken, jobId);
            
            if (jobStatus.status === 'success') {
                return jobStatus;
            } else if (jobStatus.status === 'failed') {
                throw new Error(`Конвертация не удалась: ${jobStatus.error}`);
            }
            
            // Ожидание перед следующим запросом
            await new Promise(resolve => setTimeout(resolve, 5000));
            attempts++;
        } catch (error) {
            console.error('Ошибка мониторинга задачи:', error);
            throw error;
        }
    }
    
    throw new Error('Таймаут конвертации');
}

Согласно руководству Autodesk, «большие AEC‑ориентированные модели из Revit или IFC обычно выигрывают от повторной трансляции» и «поскольку оптимизация специфична для геометрии, а исходные форматы могут включать собственную оптимизацию, это не всегда приводит к значительным улучшениям».


Настройки и конфигурация просмотрщика

Конфигурация вашего APS‑viewer может не использовать все доступные настройки оптимизации производительности, доступные в API просмотрщика.

Инициализация просмотрщика

javascript
const viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('viewerContainer'), {
    // Настройки оптимизации производительности
    performance: {
        // Включить прогрессивный рендеринг
        progressive: true,
        // Включить упрощение геометрии
        simplify: true,
        // Включить оптимизацию текстур
        textureOptimization: true,
        // Включить выборочную загрузку
        selectiveLoading: true,
        // Установить соответствующие настройки качества
        quality: {
            geometry: 'medium',
            textures: 'medium',
            shadows: false // Отключить тени для более быстрой загрузки
        }
    },
    // Оптимизация UI
    ui: {
        // Отключить ненужные элементы UI для ускорения загрузки
        hideToolbar: false,
        hideMenuBar: false,
        // Включить мониторинг производительности
        showPerformanceMonitor: true
    },
    // Настройки рендеринга
    render: {
        // Включить оптимизации WebGL
        webgl: {
            antialias: true,
            preserveDrawingBuffer: false
        }
    }
});

Управление памятью

Реализуйте стратегии управления памятью для больших моделей:

javascript
// Функции оптимизации памяти
const viewerMemoryManager = {
    // Уменьшить использование памяти, когда это не нужно
    reduceMemoryUsage: function() {
        if (viewer) {
            // Очистить неиспользуемую геометрию
            viewer.clearSelection();
            
            // Уменьшить качество текстур
            viewer.impl.textureQuality = 0.5;
            
            // Отключить ненужные функции
            viewer.setGroundShadow(false);
            viewer.setGridVisibility(false);
            
            // Принудительно вызвать сборку мусора (если доступно)
            if (window.gc) {
                window.gc();
            }
        }
    },
    
    // Восстановить производительность при необходимости
    restorePerformance: function() {
        if (viewer) {
            // Восстановить качество текстур
            viewer.impl.textureQuality = 1.0;
            
            // Включить функции
            viewer.setGroundShadow(true);
            viewer.setGridVisibility(true);
        }
    }
};

Как упомянуто в обсуждениях Stack Overflow, «в новых улучшениях SVF2» для работы с большими моделями, и «Autodesk.MemoryLimited устаревает, пожалуйста, не используйте его».


Лучшие практики для больших моделей

Подготовка модели

Рассмотрите предварительную оптимизацию ваших моделей Revit перед конвертацией:

  1. Упрощение геометрии

    • Удалите ненужные детали из больших семей
    • Используйте подходящие настройки LOD (уровень детализации)
    • Упростите сложные кривые и поверхности
  2. Оптимизация текстур

    • Используйте сжатые текстуры (JPEG, PNG)
    • Ограничьте разрешение текстур до 1024×1024 или 2048×2048
    • Удалите неиспользуемые материалы и текстуры
  3. Разделение модели

    • Рассмотрите возможность разделения очень больших моделей на логические части
    • Используйте отдельные файлы для разных дисциплин (строительство, MEP, архитектура)

Как отмечено в обсуждениях Autodesk Community, «что работало для нас, так это разделение моделей по дисциплинам (MEP отдельно), простая структура папок с самого начала и минимальные права доступа».

Реализация прогрессивной загрузки

Реализуйте прогрессивную загрузку для улучшения восприятия производительности:

javascript
// Конфигурация прогрессивной загрузки
const progressiveConfig = {
    // Сначала загружайте низкий LOD
    initialLoad: {
        lod: 2,
        elements: 'visible' // Загружайте только видимые элементы изначально
    },
    // Затем загружайте более высокие LOD
    progressiveLoad: {
        lod: [3, 4],
        delay: 1000, // Задержка 1 секунда между загрузками LOD
        elements: 'all' // Загружайте все элементы постепенно
    }
};

// Примените прогрессивную загрузку к viewer
function applyProgressiveLoading(viewer, config) {
    if (viewer && viewer.impl) {
        viewer.impl.setLODProgressive(config.initialLoad.lod);
        
        // Настройте прогрессивную загрузку для более высоких LOD
        setTimeout(() => {
            viewer.impl.setProgressiveLOD(config.progressiveLoad.lod);
        }, config.progressiveLoad.delay);
    }
}

Оптимизация кода

Оптимизированный код Model Derivative

Ниже приведена оптимизированная версия вашего кода конвертации Model Derivative:

javascript
const { ModelDerivativeClient, ConversionMethod, View, Type } = require("@aps_sdk/model-derivative");

async function optimizedModelDerivative(req, next) {
    const urn = req.body.objectName;
    
    try {
        // Создайте полезную нагрузку, оптимизированную для больших моделей Revit
        const svfPayloadFormat = {
            views: [
                View._2d, 
                View._3d,
                View.aecPlan,
                View.aecElevation
            ],
            type: Type.Svf2,
        };

        const JobPayload = {
            input: { 
                urn: urn, 
                compressedUrn: false,
                derivativeOptions: {
                    3d: {
                        lods: [2, 3, 4],
                        progressive: true,
                        simplify: true
                    },
                    2d: {
                        exportViews: true,
                        cropping: true
                    }
                }
            },
            output: {
                formats: [{
                    type: Type.Svf2,
                    views: [View._2d, View._3d],
                    advanced: {
                        progressive: true,
                        selectiveGeometry: true,
                        lodOptimization: true
                    }
                }]
            }
        };

        // Запустите задачу конвертации
        const job = await modelDerivativeClient.startJob(
            req.oauth_token.access_token, 
            JobPayload
        );

        // Мониторинг завершения задачи
        const completedJob = await monitorConversionJob(
            req.oauth_token.access_token, 
            job.result
        );

        return completedJob;
        
    } catch (error) {
        console.error('Ошибка конвертации Model Derivative:', error);
        next(error);
    }
}

// Добавьте функцию мониторинга задачи
async function monitorConversionJob(accessToken, jobId) {
    const maxAttempts = 60; // максимум 5 минут ожидания
    let attempts = 0;
    
    while (attempts < maxAttempts) {
        try {
            const jobStatus = await modelDerivativeClient.getJob(accessToken, jobId);
            
            if (jobStatus.status === 'success') {
                return jobStatus;
            } else if (jobStatus.status === 'failed') {
                throw new Error(`Конвертация не удалась: ${jobStatus.error}`);
            }
            
            // Ожидание перед следующим запросом
            await new Promise(resolve => setTimeout(resolve, 5000));
            attempts++;
        } catch (error) {
            console.error('Ошибка мониторинга задачи:', error);
            throw error;
        }
    }
    
    throw new Error('Таймаут конвертации');
}

Оптимизация загрузки просмотрщика

Оптимизируйте процесс загрузки вашего просмотрщика:

javascript
// Оптимизированная инициализация просмотрщика
async function initializeOptimizedViewer(urn, accessToken, containerId) {
    try {
        // Инициализация Autodesk.Viewing
        await Autodesk.Viewing.Initializer({
            accessToken: accessToken,
            env: 'AutodeskProduction'
        });

        // Создайте оптимизированный просмотрщик
        const viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById(containerId), {
            performance: {
                progressive: true,
                simplify: true,
                textureOptimization: true,
                quality: {
                    geometry: 'medium',
                    textures: 'medium',
                    shadows: false
                }
            },
            ui: {
                hideToolbar: false,
                hideMenuBar: false,
                showPerformanceMonitor: true
            }
        });

        // Загрузите модель с оптимизированными настройками
        const options = {
            progressiveLoad: true,
            lodProgressive: 2,
            preferWebGL: true
        };

        await Autodesk.Viewing.Document.loadDocument(
            `urn:${urn}`,
            (doc) => {
                const viewables = Autodesk.Viewing.Document.getSubItemsWithProperties(
                    doc.getRootItem(),
                    { 'type': 'geometry' },
                    true
                );
                if (viewables.length > 0) {
                    viewer.load(doc.getViewablePath(viewables[0]), options);
                }
            },
            (error) => {
                console.error('Ошибка загрузки документа:', error);
            }
        );

        return viewer;
        
    } catch (error) {
        console.error('Ошибка инициализации просмотрщика:', error);
        throw error;
    }
}

Источники

  1. Model Derivative SVF2 enhancements - Part 1 Viewer | Autodesk Platform Services
  2. UPDATE: SVF2 GA: the new streaming web format for Forge Viewer is now production ready! | Autodesk Platform Services
  3. SVF2 Public Beta: a new optimized viewer format | Autodesk Platform Services
  4. Viewer Performance Update (Part 2 of 3): OPFS Caching | Autodesk Platform Services
  5. Very slow load on APS viewer - Stack Overflow
  6. Optimizing APS Forge Viewer for Large Models on Low-Memory Devices - Stack Overflow
  7. Call for private beta testers - SVF performance enhancements | Autodesk Platform Services
  8. Best Practices for Managing Large Projects in Autodesk Construction Cloud (ACC) - Autodesk Community

Заключение

Разрыв в производительности между вашим APS‑viewer и ACC можно значительно сократить, применив стратегические оптимизации в нескольких ключевых областях:

  1. Оптимизируйте конфигурацию конвертации SVF2 добавляя специализированные представления, прогрессивную загрузку и настройки, специфичные для геометрии, чтобы лучше обрабатывать большие модели Revit.
  2. Улучшите реализацию кэширования OPFS с правильным управлением кэшем, настройкой размера и проверкой доступности, чтобы обеспечить оптимальную производительность в нескольких сессиях.
  3. Реализуйте лучшие практики подготовки модели включая упрощение геометрии, оптимизацию текстур и разделение модели для очень больших файлов.
  4. Настройте просмотрщик с параметрами оптимизации производительности включая прогрессивный рендеринг, выборочную загрузку и соответствующие уровни качества, чтобы сбалансировать производительность и визуальное качество.
  5. Эффективно управляйте использованием памяти с помощью стратегий управления памятью и прогрессивной загрузки.

Внедрив эти оптимизации, вы сможете сократить время загрузки APS‑viewer с 2 минут до более конкурентоспособного уровня, близкого к производительности ACC. Помните, что некоторые различия в производительности всегда будут из‑за инфраструктуры ACC, но вы можете значительно сократить разрыв с правильной реализацией этих стратегий.

Авторы
Проверено модерацией
Модерация