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

[经验分享] sierpinski triangle 2d in maya(with python API 2.0)

[复制链接]

尚未签到

发表于 2017-5-4 07:53:11 | 显示全部楼层 |阅读模式
DSC0000.jpg
DSC0001.jpg
在国庆前我刚好完成手上的工作,有两三天的空闲,于是就去研究了一下分形就当是练习算法,谢尔宾斯基三角形就是其中一个,关于它可以看http://en.wikipedia.org/wiki/Sierpinski_triangle
这里我们使用掏(去)心法和python API 2.0来实现谢尔宾斯基三角形2d(还存在3d的)版本.
算法很简单
DSC0002.jpg

  • 创建或得到一个三角形,等腰三角形最好,但不是等腰也行,只不过看起来有点别扭而已
  • 然后根据每条边的中点进行分割,可以得到4个三角形,把中间的三角形删除
  • 把剩下的n个三角形重复第二步的分割和删除
  • 不停的重复第二和第三步

import maya.api.OpenMaya as om
from maya import cmds
def sierpinskiTriangle_2d(loop=1):
triPoints = (om.MPoint(0, 0, -10), om.MPoint(-10, 0, 10), om.MPoint(10, 0, 10))
uValue = (0, 0.5, 1)
vValue = (0, 1, 0)
meshFn = om.MFnMesh()
meshFn.create(triPoints, (3,), (0, 1, 2), uValue, vValue)
meshFn.assignUVs((3,), (0, 1, 2))
name = meshFn.name()
for j in range(loop):
for i in range(meshFn.numPolygons):
cmds.select("%s.f[%d]" % (name, i), r=1)
edges = cmds.polyInfo(fe=1)[0].split()[-3:]
meshFn.split(((meshFn.kOnEdge, int(edges[2]), 0.5), (meshFn.kOnEdge, int(edges[1]), 0.5), (meshFn.kOnEdge, int(edges[0]), 0.5), (meshFn.kOnEdge, int(edges[2]), 0.5)))
meshFn.deleteFace(meshFn.numPolygons - 1)
meshFn.updateSurface()
cmds.select(name, r=1)
cmds.hyperShade(a="lambert1")
cmds.select(cl=1)
创建一个三角形
triPoints = (om.MPont(0, 0, -10), om.MPont(10, 0, 10), om.MPont(10, 0, 10))
uValue = (0, 0.5, 1)
vValue = (0, 1, 0)
meshFn = om.MFnMesh()
meshFn.create(triPoints, (3,), (0, 1, 2), uValue, vValue)
meshFn.assignUVs((3,), (0, 1, 2))
使用
om.MFnMesh.create()
来创建多边形,你需要提供多边形的所有顶点坐标,就是一个om.MPoint()或om.MFloatPoint()的列表我们的三角形只有3个顶点.
triPoints = (om.MPont(0, 0, -10), om.MPont(10, 0, 10), om.MPont(10, 0, 10))
然后是每个面有多少个顶点数;
接着是每个面应该由哪些顶点而构成;
uv信息是可以不提供的,不提供的话创建出来的多边形就是没uv的,uValue是一个基于uvId(uv顶点)排列的uv坐标数组,vValue也一样.我们只有3个uv顶点,我希望它们的坐标是(0, 0), (0.5, 1), (1, 0).
还有一个parent参数,也是一个可选参数,如果你提供了,那创建出来的多边形就会以你提供的节点来做父节点,不提供则创建一个transform节点来做父节点.我们这里不需要,所以忽略.
所有信息都提供了就可以创建多边形了
meshFn = om.MFnMesh()
meshFn.create(triPoints, (3,), (0, 1, 2), uValue, vValue)
三角形是创建了,但你会发现它是没有uv的,我们明明就提供了uv信息;其实是这样的om.MFnMesh.create()只是把你传递的uv信息保存而已,并不会真正的去创建uv map,为了让我们传递的uv信息被运用到模型上我们需要调用
meshFn.assignUVs((3,), (0, 1, 2))
第一个参数,uvCounts,是一个列表,每个uv面的uv顶点的数量;
uvIds,也是一个列表,是每个uv面的对应的uvId.
我们的三角形只有一个面,3个顶点,所以是(3,), (0, 1, 2)
到这里就进入算法的后面3步了
for j in range(loop):
是算法中的第四步,不停的重复第二,第三步;
for i in range(meshFn.numPolygons):
cmds.select("%.f[%d]" % (name, i), r=1)
edges = cmds.polyInfo(fe=1)[0].split()[-3:]
meshFn.split(((meshFn.kOnEdge, int(edges[2]), 0.5), (meshFn.kOnEdge, int(edges[1]), 0.5), (meshFn.kOnEdge, int(edges[0]), 0.5), (meshFn.kOnEdge, int(edges[2]), 0.5)))
meshFn.deleteFace(meshFn.numPolygons - 1)
meshFn.updateSurface()
就是对每个三角形进行分割并删除中间的三角形.
在python API 2.0多边形的顶点数,面数,uv数,边数等等都变成了,MFnMesh的实例属性而不是1.0中的方法,这更符合oop的概念,用起来也更简单方便,运行速度也相对快.
meshFn.numPolygons
# API 1.0
meshFn.numPolygons()
需要注意的是不要以为它们是实例属性就随便更改它们的数值,实际上它们是只读属性,就是你只能读取它们的值,不能覆盖或修改,如果你尝试修改,将会引发错误.
为了能将三角形进行分割,我们先要得到当前三角形的3条边,为了简单我就直接使用cmds
cmds.select("%.f[%d]" % (name, i), r=1)
edges = cmds.polyInfo(fe=1)[0].split()[-3:]
om.MFnMesh.split()有两中分割方式,一种是利用边上的点进行分割,就是提供两条边以上,每条边拿出一点来进行分割,另一种是拿面里面的点来进行分割,这个点不能是在所有边上面,也不能是面之外的点.也可以同时使用这两中方法.
这里我们需要在边的中点进行分割,所以先用om.MFnMesh.kOnEdge来确保在边上进行分割,然后指定是哪条边(的id)也就是上面得到的边,因为返回的是字符串列表,所以需要转换成int,最后是你希望在边上的点的位置,这个位置是基于百分比来计算的,所以我们需要0.5
meshFn.split(((meshFn.kOnEdge, int(edges[2]), 0.5), (meshFn.kOnEdge, int(edges[1]), 0.5), (meshFn.kOnEdge, int(edges[0]), 0.5), (meshFn.kOnEdge, int(edges[2]), 0.5)))
分割完成后我们需要把中间的三角形删除
meshFn.deleteFace(meshFn.numPolygons - 1)
为了能在下一个循环中得到正确的多边形信息,我们需要对多边形进行更新,实际上是只要你对多边形进行了添加或是删除的动作都应该调用下面的方法
meshFn.updateSurface()
最后我们创建的多边形是没有赋予材质的,给它一个材质
cmds.select(name, r=1)
cmds.hyperShade(a="lambert1")
cmds.select(cl=1)
如果你有兴趣的话,可以使用cmds来实现这个算法,或是pymel,又或是python API 1.0,除了pymel我都实现过了,最让我恶心的是API 1.0.
谢尔宾斯基三角形还有3d的版本,也以尝试去实现,挺好玩的.

运维网声明 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-372700-1-1.html 上篇帖子: 尝试用Python实现消息传递编程风格 下篇帖子: PLisp: 集成在Python中的LISP语言实现 (2)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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