设为首页 收藏本站
查看: 505|回复: 0

[经验分享] GPU, Python and Maya

[复制链接]

尚未签到

发表于 2017-4-29 11:55:51 | 显示全部楼层 |阅读模式
Here an example how to use pyopencl in Maya.
yTwistNodeGPU.py
# --------------------------------------------------------------------------------
# Copyright (c) 2013 Mack Stone. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# --------------------------------------------------------------------------------
"""
Simple deform node use pyopencl in Maya.
@author: Mack Stone
"""
import sys
import logging
import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx
from maya import utils
import numpy
import pyopencl as cl

# opencl code, run on GPU
kernelCode = """
__kernel void ytwist(__global const float4 *pos,
__global float4 *newPos,
float angle,
float envelope)
{
int gid = get_global_id(0);
newPos[gid].xyzw = pos[gid].xyzw;
float ff = angle * pos[gid].y * envelope;
if(ff != 0.0f)
{
float cct = cos(ff);
float cst = sin(ff);
newPos[gid].x = pos[gid].x * cct - pos[gid].z * cst;
newPos[gid].z = pos[gid].x * cst + pos[gid].z * cct;
}
}
"""
class YTwistNode(ompx.MPxDeformerNode):
NAME = "yTwistNode"
ID = om.MTypeId(0x8702)
angle = om.MObject()
def __init__(self):
ompx.MPxDeformerNode.__init__(self)
# create context
self._ctx = cl.create_some_context()
# command queue
self._queue = cl.CommandQueue(self._ctx)
# create and build GPU program
self._program = cl.Program(self._ctx, kernelCode).build()
# setup logger
formatter = logging.Formatter("%(asctime)s - %(message)s")
utils._guiLogHandler.setFormatter(formatter)
def deform(self, dataBlock, geomIter, matrix, multiIndex):
logging.info("start deforming")
# get the angle from the datablock
angleHandle = dataBlock.inputValue( self.angle )
angleValue = angleHandle.asDouble()
# get the envelope
envelope = OpenMayaMPx.cvar.MPxDeformerNode_envelope
envelopeHandle = dataBlock.inputValue( envelope )
envelopeValue = envelopeHandle.asFloat()
# get all position data
logging.info("get all position data")
pos = numpy.zeros((geomIter.count(), 4), dtype=numpy.float32)
while not geomIter.isDone():
point = geomIter.position()
index = geomIter.index()
pos[index, 0] = point.x
pos[index, 1] = point.y
pos[index, 2] = point.z
pos[index, 3] = point.w
geomIter.next()
logging.info("start copy data to GPU")
memf = cl.mem_flags
# create buffer from pos
posBuf = cl.Buffer(self._ctx, memf.READ_ONLY | memf.COPY_HOST_PTR, hostbuf=pos)
# create write buffer
outBuf = cl.Buffer(self._ctx, memf.WRITE_ONLY, pos.nbytes)
# run GPU Program
logging.info("run GPU Program")
self._program.ytwist(self._queue, pos.shape, None, posBuf, outBuf,
numpy.float32(angleValue), numpy.float32(envelopeValue))
logging.info("end GPU Program")
# copy data back to memory
newPos = numpy.zeros_like(pos)
cl.enqueue_copy(self._queue, newPos, outBuf).wait()
# set positions
logging.info("set all position")
geomIter.reset()
while not geomIter.isDone():
point = geomIter.position()
index = geomIter.index()
point.x = float(newPos[index, 0])
point.y = float(newPos[index, 1])
point.z = float(newPos[index, 2])
geomIter.next()
logging.info("end deform")
@staticmethod
def creator():
return ompx.asMPxPtr(YTwistNode())
@staticmethod
def initialize():
# angle
nAttr = om.MFnNumericAttribute()
YTwistNode.angle = nAttr.create("angle", "fa", om.MFnNumericData.kDouble, 0.0)
nAttr.setKeyable(1)
# add attribute
YTwistNode.addAttribute(YTwistNode.angle)
outputGeom = ompx.cvar.MPxDeformerNode_outputGeom
YTwistNode.attributeAffects(YTwistNode.angle, outputGeom)
# initialize the script plug-in
def initializePlugin(mobject):
mplugin = ompx.MFnPlugin(mobject)
try:
mplugin.registerNode(YTwistNode.NAME, YTwistNode.ID, YTwistNode.creator,
YTwistNode.initialize, ompx.MPxNode.kDeformerNode )
except:
sys.stderr.write("Failed to register node: %s\n" % YTwistNode.NAME)
# uninitialize the script plug-in
def uninitializePlugin(mobject):
mplugin = ompx.MFnPlugin(mobject)
try:
mplugin.deregisterNode(YTwistNode.ID)
except:
sys.stderr.write("Failed to unregister node: %s\n" % YTwistNode.NAME )


It's slower than yTwistNode.py(CPU) when I test it.
My testing hardware:
CPU: intel Xeon w3530 2.80GHz
Graphics card: nvidia quadro FX 1800
Test on a obj with 960002 vertexes.
GPU: about 18s a time
CPU: about 10s a time
But the slow part is not the GPU computing. It's the while loop. Two while loop take almost 18s.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-370753-1-1.html 上篇帖子: Python处理01背包问题 下篇帖子: ElasticSearch的python使用--pyes
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表