Maya-沿着曲面放置几何体

突然想起来以前的时候经常为了在曲面上放置大量重复物体的问题而烦恼,想想能不能写个脚本解决一下。

  1. 首先在曲面以外的空间上放置一组几何体,用来确定前向和向右的距离。最后按照中上右的顺序运行相应脚本
  2. 选择目标曲面运行相应脚本
  3. 在曲面开始复制的位置放好第一个砖块。选择并运行相应脚本
  4. 运行剩下的脚本,数量多的话maya会卡一会儿,等等就好。

在曲面弯曲的不是很厉害的地方效果还是不错的,中间弯曲过大的地方效果不是很理想。没有UI运行起来很抽象,还有就是脚本运行很慢,应该是我使用的方法不对,找找看有没有新的方法。

# -*- coding:utf-8 -*-

import pymel.core as pm


def dupObj(obj):
    dup = pm.duplicate(obj, rr=1)
    pm.move(dist.x, dist.y, dist.z, dup, relative=True, worldSpace=True, worldSpaceDistance=True)
    geometryCon = pm.geometryConstraint(target, dup)
    normalCon = pm.normalConstraint(target, dup, worldUpType='vector', aimVector=(0, 1, 0), upVector=(0, 1, 0),
                                    weight=1, worldUpVector=(0, 1, 0))
    pm.delete(geometryCon, normalCon)
    dupNext = pm.duplicate(obj, rr=1)
    pm.move(distNext.x, distNext.y, distNext.z, dupNext, relative=True, worldSpace=True, worldSpaceDistance=True)
    geometryCon = pm.geometryConstraint(target, dupNext)
    normalCon = pm.normalConstraint(target, dupNext, worldUpType='vector', aimVector=(0, 1, 0), upVector=(0, 1, 0),
                                    weight=1, worldUpVector=(0, 1, 0))
    pm.delete(geometryCon, normalCon)
    return dup,dupNext

def loopDupObj(obj):
    dup = pm.duplicate(obj,rr=1)
    pm.move(dist.x , dist.y , dist.z , dup, relative=True , worldSpace = True , worldSpaceDistance = True)
    geometryCon = pm.geometryConstraint(target,dup)
    normalCon = pm.normalConstraint(target,dup,worldUpType = 'vector', aimVector=(0,1,0),upVector = (0,1,0),weight = 1, worldUpVector = (0,1,0))
    pm.delete(geometryCon,normalCon)
    return dup


def loopDup(dup):
    parameterU = 0.0
    parameterV = 0.0
    dupList = []
    while True:
        dup = loopDupObj(dup)
        dupList.append(dup)
        pm.setAttr('pointOnMesh.inPosition', dup[0].getTranslation(worldSpace=True))
        if (int(parameterU*100) == int(PointOnMesh.getAttr('parameterU')*100)) & (int(parameterV*100) == int(PointOnMesh.getAttr('parameterV')*100)):#乘以100转换int等于截取小数点后两位
            print 'parameterU:{} NewParameterU:{}'.format(parameterU, PointOnMesh.getAttr('parameterU'))
            print 'parameterV:{} NewParameterV:{}'.format(parameterV, PointOnMesh.getAttr('parameterV'))
            pm.delete(dupList[-1], dupList[-2])
            break
        parameterU = PointOnMesh.getAttr('parameterU')
        parameterV = PointOnMesh.getAttr('parameterV')


def testNext (obj):
    parameterU = 0.0
    parameterV = 0.0
    pm.setAttr('pointOnMesh.inPosition', obj[0].getTranslation(worldSpace=True))
    parameterU = PointOnMesh.getAttr('parameterU')
    parameterV = PointOnMesh.getAttr('parameterV')
    dupResult = dupObj(obj)
    dupNow = dupResult[0]
    dupNext = dupResult[1]
#    loopDup(dupNow)
    pm.setAttr('pointOnMesh.inPosition', dupNext[0].getTranslation(worldSpace=True))
    if (parameterU == PointOnMesh.getAttr('parameterU')) & (parameterV == PointOnMesh.getAttr('parameterV')):
        pm.delete(dupNext)
        dupNext= None
    return dupNow,dupNext


#按照中心位置砖块,上部砖块,右边砖块顺序进行选择后运行这一段
# -*- coding:utf-8 -*-
original = pm.ls(selection=True)
dist = pm.getAttr(original[1] + '.translate') - pm.getAttr(original[0] + '.translate')
distNext = pm.getAttr(original[2] + '.translate') - pm.getAttr(original[0] + '.translate')


#选择要放置的平面运行这一块
# -*- coding:utf-8 -*-
target = pm.ls(selection=True)
pm.delete(pm.ls('pointOnMesh'))
PointOnMesh = pm.createNode("closestPointOnMesh", name='pointOnMesh')
pm.connectAttr(pm.listRelatives(target, shapes=True)[0] + ".worldMesh[0]", 'pointOnMesh.inMesh', force=True)
pm.connectAttr(pm.listRelatives(target, shapes=True)[0] + ".worldMatrix[0]", 'pointOnMesh.inputMatrix', force=True)


#选择开始位置运行这一块
# -*- coding:utf-8 -*-
startObj = pm.ls(selection=True)


#运行这里开始复制
# -*- coding:utf-8 -*-
newNext = testNext(startObj)
while True:
    loopDup(newNext[0])
    if newNext[1] == None:
        break
    newNext = testNext(newNext[1])


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值