突然想起来以前的时候经常为了在曲面上放置大量重复物体的问题而烦恼,想想能不能写个脚本解决一下。
- 首先在曲面以外的空间上放置一组几何体,用来确定前向和向右的距离。最后按照中上右的顺序运行相应脚本
- 选择目标曲面运行相应脚本
- 在曲面开始复制的位置放好第一个砖块。选择并运行相应脚本
- 运行剩下的脚本,数量多的话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])