Как загрузить 3D-модель с помощью PyWeb3D

    Из материала статьи вы узнаете, как загрузить 3D-модель в пространство сцены с помощью PyWeb3D .

    3D-модель автомобиля, загруженная с помощью pyweb3d

    3D-модели доступны в сотнях файловых форматов, каждый из которых обладает своим назначением, особенностями и уровнем сложности. Несмотря на то, что three.js предоставляет множество загрузчиков, выбор правильного формата и рабочего процесса сэкономит время и избавит от разочарований в дальнейшем. Ведь некоторые форматы вызывают трудности в процессе работы, демонстрируют низкую производительность в режиме реального времени или просто не поддерживаются на данный момент.

    Мы будем задействовать формат glTF, рекомендуемый для three.js.

    Примечание. Обе версии формата, .GLB и .GLTF, отлично поддерживаются.

    Для загрузки модели в пространство сцены используется three.js GLTFLoader.

    С модифицированной версией для PyWeb3D можно ознакомиться по ссылке.

    Шаблонный код HTML

    <!DOCTYPE html><html>  <head> <meta charset="utf-8"> <title>PyWeb3D webgl - GLTFloader</title> <script src="https://cdn.jsdelivr.net/npm/Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..7/brython.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..7/brython_stdlib.js"></script> <script src="https://unpkg.com/Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..0/build/three.js"></script> <script src="https://www.pyweb3d.org/pyweb3d/v1.0.0/pyweb3d.brython.js"></script> <style>     body { margin: 0; } </style> </head> <body onload="brython(1)">    <script src="/../jsm/loaders/GLTFLoader.js"></script>    <script src="/../jsm/controls/OrbitControls.js"></script>    <script src="/../jsm/loaders/RGBELoader.js"></script>        <script type="text/python">      # Код Python размещается здесь     </script>  <body> </html>

    Весь нижеследующий код размещается в строчном теге <script type=”text/python”> в теле HTML-файла.

    Импорт требуемых модулей и функций

    from browser import document, windowfrom  pyweb3d.pyweb3d import *from javascript import UNDEFINED as undefined

    Инициализация дополнительIх модулей

    GLTFLoader = window.THREE.GLTFLoader.newOrbitControls = window.THREE.OrbitControls.newRGBELoader = window.THREE.RGBELoader.new

    В данном фрагменте кода мы инициализируем дополнительные модули GLTFLoader, OrbitControls и RGBELoader напрямую из файла JavaScript в код Python.

    Создание сцены и загрузка модели

    #Переменные для настройки camera = Nonerenderer = Nonescene = Nonecar = Nonedef init():    global camera    global renderer    global scene    global car    #Создание сцены     scene = Scene()    scene.background = Color( 0x333333 )    scene.environment = RGBELoader().load( ‘textures/venice_sunset_1k.hdr’ )    scene.environment.mapping = EquirectangularReflectionMapping    scene.fog = Fog( 0x333333, 10, 15 )    grid = GridHelper( 20, 40, 0xffffff, 0xffffff )    grid.material.opacity = 0.2    grid.material.depthWrite = False    grid.material.transparent = True    scene.add( grid )    fov = 45    aspect = window.innerWidth / window.innerHeight    near = 1    far = 1500    #Настройка камеры     camera = PerspectiveCamera(fov, aspect, near, far)    camera.position.x = 8    camera.position.y = 1    camera.position.z = 10        #Настройка источников света     ambientLight = AmbientLight( ‘white’, 2 )    scene.add( ambientLight )    DirectLight = DirectionalLight( ‘white’, 3.5 )    DirectLight.position.set( 100, 100, 100 )    scene.add( DirectLight )    hemiLight = HemisphereLight(’white’, ‘darkslategrey’, 5)    scene.add(hemiLight)    #Визуализатор     renderer = WebGLRenderer( { ‘antialias’: True } )    renderer.setPixelRatio( window.devicePixelRatio )    renderer.setSize( window.innerWidth, window.innerHeight )    document.body.appendChild( renderer.domElement )    controls = OrbitControls(camera, renderer.domElement)    #Загрузка модели     loader = GLTFLoader()    def loadGLTF(gltf):        car = gltf.scene        car.scale.setScalar( 1.5 )        # центр         box = Box3().setFromObject( car )        center = box.getCenter( Vector3() )        car.position.x += ( car.position.x - center.x )        car.position.y += ( car.position.y - center.y + 1.4)        car.position.z += ( car.position.z - center.z )        scene.add( car )        animate(0)    def onError(error):        print(error)    loader.load( ‘models/Nissan_Z_Proto/scene.gltf’, loadGLTF, undefined, onError)

    Построчно разберем содержимое данного кода.

    • Строки 2 — 5. Объявляем пустые переменные для хранения камеры, визуализатора, сцены и автомобиля.
    • Строки 7 — 75. Определяем функцию init(). Внутри нее создаем сцену, камеру, сетку, источник света и загружаем модель.

    Переходим к более детальному разбору.

    • Строки 8 — 11. Делаем переменные из строк 2–5 изменяемыми. Для тех, кто только начинает работать с Python, отметим, что ключевое слово global необходимо для изменения глобальной копии переменных, объявленных в строках 2 — 5.
    • Строки 14 — 18. Создаем сцену, добавляем к ней фоновый цвет, текстуру и эффект тумана.
    • Строки 20 — 24. Создаем сетку и добавляем ее к сцене.
    • Строки 26 — 35. Создаем камеру с перспективной проекцией и задаем ей область просмотра, соотношение сторон, ближнюю и дальнюю плоскости отсечения.
    • Строки 38 — 39. Создаем источник рассеянного света и добавляем его к сцене.
    • Строки 41 — 43. Создаем источник направленного света и добавляем его к сцене.
    • Строки 45 — 46. Создаем полусферический источник света и добавляем его к сцене.
    • Строки 49 -52. Создаем визуализатор WebGL и добавляем его в тело HTML-файла.
    • Строка 54. Создаем элемент управления вращением камеры OrbitControl, который принимает цель в качестве аргумента (в данном случае камеру и renderer.domElement или элемент <canvas>).
    • Строка 57. Инстанцируем GLTFLoader.
    • Строки 59 — 70. Определяем функцию обратного вызова loadGLTF() для обработки настроек модели gLTF.
    • Строки 72 — 73. Определяем функцию обратного вызова onError(). Она обрабатывает сообщения об ошибках и помогает устранять неполадки в случае сбоев загрузки модели.
    • Строка 75. Загружаем модель и передаем функции обратного вызова методу load в качестве аргумента.

    Обработка события изменения размера окна и анимации

    def onWindowResize(resize):    camera.aspect = window.innerWidth / window.innerHeight    camera.updateProjectionMatrix()    renderer.setSize( window.innerWidth, window.innerHeight )window.addEventListener( ‘resize’, onWindowResize )def animate(time):    window.requestAnimationFrame( animate )    renderer.render( scene, camera )init()

    Строки 1 — 8. Обрабатываем событие изменения размера окна.

    Строки 10 — 12. Обрабатываем цикл анимации.

    Строка 14. Вызываем функцию init(), определенную в строках 7 — 75 предыдущего фрагмента кода.

    Запуск кода

    Открываем HTML-файл в браузере и видим прекрасную модель спорткара Nissan Z Proto.

    Версия в интерактивном режиме по ссылке.

    3D-модель автомобиля, загруженного с помощью pyweb3d