Maya python api — рендеринг камеры и сохранение в переменной

Я работаю с Maya 2012 и хочу сделать вид с камеры. Я обнаружил, что это можно сделать с помощью команды MEL «рендерить» (вызывая ее через python). Однако, насколько я знаю, эта команда рендерит изображение и сохраняет его на диск, возвращая только путь к сохраненному изображению.

Пример:

import maya.cmds as cmds
import cv2 as cv

pathToFile = cmds.render()
renderImage = cv.imread(pathToFile)

Поскольку я заинтересован в использовании изображения для выполнения различных алгоритмов компьютерного зрения, сохранение его на диск, а затем чтение с диска создает ненужные вычислительные затраты.

Можно ли отрендерить камеру и сохранить изображение в переменной без необходимости этого делать? Это позволило бы ускорить цикл между рендерингом и анализом изображения рендеринга.


На случай, если кто-то столкнется с этим вопросом в будущем: я попробовал подход с RAM-диском (используя dataram RAMDisk), который был предложен, и, к сожалению, это не дало никакого увеличения скорости.


person Alexandros Gouvatsos    schedule 12.12.2012    source источник
comment
Это не обязательно возможно для Maya API. Код, который вам нужен, зависит от того, какой механизм рендеринга вы используете, поскольку вам необходимо реализовать серверную часть механизма рендеринга для данных. Посмотрите, как рендерер фактически использует диск для сохранения необходимого объема данных. Даже внутренний предварительный рендеринг Maya работает с дисковым решением. PS: есть тривиальное решение для этого жесткого, сделать ram disk и положить туда образ.   -  person joojaa    schedule 13.12.2012


Ответы (1)


Если вы ищете эффективность, вы можете рассмотреть возможность использования пакетов OpenMaya для доступа к контексту OpenGL для представлений и рендеринга представления Viewport 2.0 в текстуру. Затем получите доступ к этой текстуре программно.

В качестве альтернативы вы можете написать плагин, который обертывает другой плагин рендеринга, такой как Mayatomr или модуль рендеринга Hardware 2.0, и помещает визуализированное изображение в некоторое пространство общей памяти.

Но эти решения настолько невероятно сложны, затрагивая так много недокументированных функций. Вероятно, вам следует просто установить средство рендеринга на Hardware 2.0, сохранить изображение в формате BMP (которое OpenCV в любом случае читает очень быстро), возможно, на RAM-диск, как было предложено выше, и назвать это днем.

Поправка

Возможно, есть более простой способ. Создайте пользовательский узел, реализующий MPxHardwareShader спецификации, описанные здесь:

http://images.autodesk.com/adsk/files/viewportMPxHardwareShader0_api_gold.pdf

Другими словами, переопределить рендеринг Hardware/Viewport 2.0 для некоторого узла. Вместо того, чтобы что-то рисовать, используйте свой доступ к контексту OpenGL для рендеринга области просмотра в текстуру.

http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/

Потом делай с ним что хочешь. Умно, а?

person DoctorPangloss    schedule 13.12.2012
comment
Большое спасибо за ваш ответ. Вот что я хотел узнать, есть ли столь же простой способ просто сохранить изображение в переменной! Возможно, в будущем я попробую более сложное решение, но пока, как вы сказали, я на этом закончу! :) - person Alexandros Gouvatsos; 13.12.2012
comment
Теперь я дошел до того, что мне действительно нужно оптимизировать это и получить прямой доступ к информации о рендеринге. Я просмотрел документацию и нашел пример renderAccessNode.cpp (tinyurl.com/azjj9x8). Я пытался создать что-то подобное (в основном, переопределяя функцию renderCallback()), но даже с загруженным плагином, как будто renderCallback() на самом деле никогда не вызывается; есть оператор печати, который ничего не печатает. Не могли бы вы (или кто-либо другой) знать, как решить эту проблему или какой-либо другой способ сделать то, что мне нужно? - person Alexandros Gouvatsos; 21.01.2013
comment
Я отправил вам новое решение. - person DoctorPangloss; 22.01.2013
comment
Огромное спасибо! Я попробую это сейчас и сообщу о своих результатах! Таким образом, я буду использовать функцию MPxShaderOverride, чтобы передать drawContext текстуре в памяти. Будет ли эта переопределяющая функция действовать каждый раз, когда я вызываю функцию render(), или когда это произойдет? К сожалению, моя репутация недостаточно высока, чтобы дать вам репутацию! - person Alexandros Gouvatsos; 23.01.2013
comment
Вам не нужно звонить render(), я думаю, в этом случае. Вы перемещаете камеру, и она преобразует текстуру в реальном времени. Вы можете добавить переключатель к узлу, чтобы сообщить ему, когда сохранять и не сохранять. Или вы можете playblast, что имеет тот же эффект, что и рендеринг в OpenGL каждого кадра один за другим без каких-либо промежуточных кадров. Это, вероятно, то, что вы хотите. - person DoctorPangloss; 23.01.2013
comment
Я возился с тем, что вы сказали сегодня, и, к сожалению, я не могу заставить его работать с MPxShaderNode. Я просмотрел примеры из руководства Viewport 2.0 API, и этот tinyurl.com/ajzsfgy кажется самое близкое, что я мог получить. По сути, если я ввожу оператор печати в функцию draw(), я вижу его всякий раз, когда происходит какое-либо обновление (либо перемещение камеры, либо перемещение объектов и т. д.). Однако я не уверен, что это на самом деле дает мне доступ к нужному мне контексту - это дает мне доступ к M3dView. - person Alexandros Gouvatsos; 23.01.2013
comment
Я также думаю, что playblast — это способ ускорить рендеринг. И на самом деле, он может работать с Viewport 2.0. - person Drake Guan; 09.12.2013