2010년. 새해. 첫날. 꼭두새벽.부터
질문 드리게 돼서 영광이네요..;; 모두가 행복해졌으면 하는 마음입니다. ㅎㅎ
파이썬 공부중에 좋은 답변들이 정말 큰 도움이 되어 드디어 스크립트를 하나 짜봤는데요...( 초보에요..)
이게 실행은 잘 됩니다.
그런데 몇번 반복해서 실행하면 자꾸 다운이 되길래 살펴보니 메모리부족이 원인 이더군요..
서너번 실행하면 거의 1기가를 넘어 서는듯 합니다.
그래서 제가 참고한 스크립트로 실행해보니 이건 메모리를 거의 잡아먹질 않아서
열어보니 OpenMaya를 이용해서 짠거더군요.
단순히 멜과 API의 차이 때문은 아닐꺼 같아서 질문 드립니다.
어쩜 Python 의 문제....이진 않겠네요.. 참고한 스크립트도 UI 부분은 Mel이지만 본문은 Python 이니까요..;;
스크립트 실행중에 메모리를 많이 차지하는 부분을 알수있는 방법이 있을까요?
내용은 별거 없고 Locator 위치들 알아내서 각 Locator의 중간거리값 구해서 메쉬를 잘라주는거 외엔 별거 없거든요.
하지만 for 문을 두번 겹쳐 써서 반복은 많이 하겠네요..
메모리부하를 줄일수 있는 방법이 있을지도 궁금합니다..
(아..스크립트는 highend3d 에 있는 voronoi shatter?? 란 멜입니다.)
그럼 새해 복 많이 받으시구요...
봐 주시겠다니 감사합니다.. 내심 바랬어요..ㅎ
잘 아시겠지만 혹시나 해서 적는건데요..
emitter type: omni
rate: 40
30frame 까지 플레이 시켜서 cube 와 particle을 선택하고 실행 하면 거의 1G 조금 넘어 갑니다.
import maya.cmds as cmds
import math
class shatter:
def __init__(self,offSet):
self._offset = offSet
_sel = cmds.ls(sl=1,fl=1)
if len(_sel) == 2:
for x in _sel:
_type = cmds.nodeType(cmds.listHistory(x)[0])
if _type == 'mesh':
self.obj_name= x
elif _type == 'particle':
self.ptcl_name = x
self.ptcl_Sname = cmds.listRelatives(self.ptcl_name ,s=1)[0]
self.ptcl_count = cmds.getAttr(x + '.count')
else: print 'wrong select...'
def testPtcle2Loc(self):
self.p_grp = cmds.group(n='particleLocatorGrp',empty=1)
cmds.setAttr(self.ptcl_name + '.visibility',0)
##p_count =cmds.getAttr(p_name+'.count')
self.ptcl_pos_list = []
for x in range(self.ptcl_count):
#p_pos = cmds.getParticleAttr(self.ptcl_count+'.pt[%s]'%x,at='worldPosition')
p_pos = cmds.xform(self.ptcl_name + '.pt[%d]'% x ,q=1,ws=1,t=1)
p_loc = cmds.spaceLocator(n='testPoint_#')
cmds.setAttr(p_loc[0] + '.translate', p_pos[0], p_pos[1], p_pos[2])
cmds.setAttr(p_loc[0] + '.scale', 0.1, 0.1, 0.1)
cmds.parent(p_loc[0], self.p_grp)
self.ptcl_pos_list.append(p_pos)
#return self.p_grp
def testCreateCutBlock(self):
b_box = cmds.exactWorldBoundingBox(self.obj_name)
biggest_dimension = abs(b_box[3] - b_box[0])
if (abs(b_box[4] - b_box[1]) > biggest_dimension):
biggest_dimension = abs(b_box[4]-b_box[1])
elif (abs(b_box[5] - b_box[2]) > biggest_dimension):
biggest_dimension = abs(b_box[5]-b_box[2])
biggest_dimension = biggest_dimension * 4
cut_blockCreate = cmds.polyPlane(sx=1,sy=1,ax=(0,1,0),cuv=2,ch=0,n='cutBlock')
self.cut_blockName = cut_blockCreate[0]
cmds.setAttr(self.cut_blockName + '.scaleX' , biggest_dimension)
cmds.setAttr(self.cut_blockName + '.scaleZ' , biggest_dimension)
cmds.polyExtrudeFacet(self.cut_blockName + '.f[0]',ch=0,ltz=biggest_dimension*2,
smoothingAngle=0)
cmds.makeIdentity(self.cut_blockName,apply =1,t=1,r=1,s=1,n=0)
cmds.setAttr(self.cut_blockName + '.visibility',0)
cmds.select(cl=1)
#return(cut_blockName)
def _exe(self):
cut_block = self.testCreateCutBlock()
loc_grp = self.testPtcle2Loc()
temp_exist = cmds.objExists('testShardMaterial')
if temp_exist == 0:
_mat = cmds.shadingNode('lambert', asShader=1,n='testShardMat')
cmds.sets(r=1,nss=1,em=1,n=_mat+'SG')
cmds.connectAttr(_mat+'.outColor' , _mat+'SG.surfaceShader' , f=1)
cmds.setAttr(_mat+'.color',1, 0, 0, type="double3")
shard_grp = cmds.group(em=1,n='shardsGRP')
cmds.setAttr(self.ptcl_name + '.visibility' , 0)
cmds.setAttr(self.p_grp + '.visibility' , 1)
_locs = cmds.listRelatives(self.p_grp,c=1,type='transform')
len_locs = len(_locs)
for i in range(len_locs):
#a_pos = cmds.xform(_locs[i],q=1,ws=1,t=1)
a_pos = self.ptcl_pos_list[i]
active_shard = []
dupMesh = cmds.duplicate(self.obj_name,rr =1)
cmds.setAttr(self.obj_name + '.visibility' ,1)
active_shard.append(dupMesh[0])
cmds.setAttr(active_shard[0]+'.visibility' , 1)
for j in range(len_locs):
if i != j:
#b_pos = cmds.xform(_locs[j],q=1,ws=1,t=1)
b_pos = self.ptcl_pos_list[j]
mid_point = ((a_pos[0]+b_pos[0])/2,(a_pos[1]+b_pos[1])/2,(a_pos[2]+b_pos[2])/2)
_dir = (a_pos[0]-mid_point[0],a_pos[1]-mid_point[1],a_pos[2]-mid_point[2])
mag_dir = math.sqrt(_dir[0]**2+_dir[1]**2+_dir[2]**2)
_dir = (_dir[0]/mag_dir,_dir[1]/mag_dir,_dir[2]/mag_dir)
##
_t = (self._offset * _dir[0],self._offset * _dir[1],self._offset * _dir[2])
off_midPoint = (mid_point[0]+_t[0],mid_point[1]+_t[1],mid_point[2]+_t[2])
aim_loc = cmds.spaceLocator(p=(b_pos[0],b_pos[1],b_pos[2]))
cmds.xform(aim_loc[0],cp=1)
#
cut_cube = cmds.duplicate(self.cut_blockName,rr=1)
cmds.setAttr(cut_cube[0]+'.visibility',1)
cmds.setAttr(cut_cube[0]+'.translate',off_midPoint[0],off_midPoint[1],off_midPoint[2])
aim_const = cmds.aimConstraint(aim_loc,cut_cube,o=(0,0,0),w=1,aim=(0,1,0),u=(0,1,0),
wut='vector',wu=(0,1,0))
#
for k in range(len(aim_const)):
if cmds.objExists(aim_const[k]):
cmds.delete(aim_const[k])
for m in range(len(aim_loc)):
if cmds.objExists(aim_loc[m]):
cmds.delete(aim_loc[m])
cut_blockRot = cmds.xform(cut_cube[0],q=1,ws=1,ro=1)
num_face = cmds.polyEvaluate(active_shard,f=1)
cmds.polyCut(active_shard[0]+'.f[0:%s]' %num_face,ch=0,df=1,
pc=(off_midPoint[0],off_midPoint[1],off_midPoint[2]),
ro=(cut_blockRot[0]+90,cut_blockRot[1],cut_blockRot[2]))
num_cutFace = cmds.polyEvaluate(active_shard,f=1)
cmds.polyCloseBorder(active_shard,ch=0)
num_newFace = cmds.polyEvaluate(active_shard,f=1)
_f = num_cutFace
while _f < num_newFace:
_f += 1
cmds.sets(active_shard[0]+'.f[%s]' % _f ,e=1,fe= _mat+'SG' )
cmds.select(cl=1)
if cmds.objExists(cut_cube[0]):
cmds.delete(cut_cube[0])
cmds.parent(active_shard,shard_grp)
cmds.refresh()
cmds.delete(self.cut_blockName)
a = shatter(0.002)
#a.testPtcle2Loc()
#a.testCreateCutBlock()
a._exe()
죄송합니다..맨 처음꺼를 올렸네요..;;
그닥 큰 차이는 없지만 좀 더 수정한겁니다.;;
import maya.cmds as cmds
import math
import time
class shatter:
def __init__(self,offSet):
self._offset = offSet
_sel = cmds.ls(sl=1,fl=1)
if len(_sel) == 2:
for x in _sel:
_type = cmds.nodeType(cmds.listHistory(x)[0])
if _type == 'mesh':
self.obj_name= x
elif _type == 'particle':
self.ptcl_name = x
self.ptcl_Sname = cmds.listRelatives(self.ptcl_name ,s=1)[0]
self.ptcl_count = cmds.getAttr(x + '.count')
else: print 'wrong select...'
def testPtcle2Loc(self):
self.p_grp = cmds.group(n='particleLocatorGrp',empty=1)
cmds.setAttr(self.ptcl_name + '.visibility',0)
self.ptcl_pos_list=[cmds.xform(self.ptcl_name+'.pt[%d]'% x ,q=1,ws=1,t=1) for x in range(self.ptcl_count)]
for x in self.ptcl_pos_list:
#p_pos = cmds.getParticleAttr(self.ptcl_count+'.pt[%s]'%x,at='worldPosition')
#p_pos = cmds.xform(self.ptcl_name + '.pt[%d]'% x ,q=1,ws=1,t=1)
p_loc = cmds.spaceLocator(n='testPoint_#')
cmds.move(x[0],x[1],x[2],p_loc)
cmds.scale(0.2,0.2,0.2,p_loc)
cmds.parent(p_loc[0], self.p_grp)
def testCreateCutBlock(self):
b_box = cmds.exactWorldBoundingBox(self.obj_name)
biggest_dimension = abs(b_box[3] - b_box[0])
if (abs(b_box[4] - b_box[1]) > biggest_dimension):
biggest_dimension = abs(b_box[4]-b_box[1])
elif (abs(b_box[5] - b_box[2]) > biggest_dimension):
biggest_dimension = abs(b_box[5]-b_box[2])
biggest_dimension = biggest_dimension * 4
cut_blockCreate = cmds.polyPlane(sx=1,sy=1,ax=(0,1,0),cuv=2,ch=0,n='cutBlock')
self.cut_blockName = cut_blockCreate[0]
cmds.setAttr(self.cut_blockName + '.scaleX' , biggest_dimension)
cmds.setAttr(self.cut_blockName + '.scaleZ' , biggest_dimension)
cmds.polyExtrudeFacet(self.cut_blockName + '.f[0]',ch=0,ltz=biggest_dimension*2,
smoothingAngle=0)
cmds.makeIdentity(self.cut_blockName,apply =1,t=1,r=1,s=1,n=0)
cmds.setAttr(self.cut_blockName + '.visibility',0)
cmds.select(cl=1)
def _exe(self):
st = time.time()
cmds.undoInfo( state = False)
self.testPtcle2Loc()
self.testCreateCutBlock()
temp_exist = cmds.objExists('testShardMaterial')
if temp_exist == 0:
_mat = cmds.shadingNode('lambert', asShader=1,n='testShardMat')
cmds.sets(r=1,nss=1,em=1,n=_mat+'SG')
cmds.connectAttr(_mat+'.outColor' , _mat+'SG.surfaceShader' , f=1)
cmds.setAttr(_mat+'.color',1, 0, 0, type="double3")
shard_grp = cmds.group(em=1,n='shardsGRP')
cmds.setAttr(self.ptcl_name + '.visibility' , 0)
cmds.setAttr(self.p_grp + '.visibility' , 0)
_locs = cmds.listRelatives(self.p_grp,c=1,type='transform')
cut_cube = cmds.duplicate(self.cut_blockName)
for n,i in enumerate(iter(self.ptcl_pos_list)):
dupMesh = cmds.duplicate(self.obj_name,rr =1)
cmds.setAttr(self.obj_name + '.visibility' ,0)
cmds.setAttr(dupMesh[0]+'.visibility' , 1)
for m,j in enumerate(iter(self.ptcl_pos_list)):
if n != m:
mid_point = ((i[0]+j[0])/2,(i[1]+j[1])/2,(i[2]+j[2])/2)
_dir = (i[0]-mid_point[0],i[1]-mid_point[1],i[2]-mid_point[2])
mag_dir = math.sqrt(_dir[0]**2+_dir[1]**2+_dir[2]**2)
_dir = (_dir[0]/mag_dir,_dir[1]/mag_dir,_dir[2]/mag_dir)
_t = (self._offset * _dir[0],self._offset * _dir[1],self._offset * _dir[2])
off_midPoint = (mid_point[0]+_t[0],mid_point[1]+_t[1],mid_point[2]+_t[2])
cmds.setAttr(cut_cube[0]+'.translate',off_midPoint[0],off_midPoint[1],off_midPoint[2])
aim_const = cmds.aimConstraint('testPoint_%s'%str(m+1),cut_cube,o=(0,0,0),w=1,aim=(0,1,0),u=(0,1,0),
wut='vector',wu=(0,1,0))
cut_blockRot = cmds.xform(cut_cube[0],q=1,ws=1,ro=1)
#num_face = cmds.polyEvaluate(dupMesh,f=1)
cmds.polyCut(dupMesh[0],ch=0,df=1,
pc=(off_midPoint[0],off_midPoint[1],off_midPoint[2]),
ro=(cut_blockRot[0]+90,cut_blockRot[1],cut_blockRot[2]))
cmds.delete(aim_const)
#num_cutFace = cmds.polyEvaluate(dupMesh,f=1)
cmds.polyCloseBorder(dupMesh,ch=0)
num_newFace = cmds.polyEvaluate(dupMesh,f=1)
cmds.sets(dupMesh[0]+'.f[%s]' % num_newFace ,e=1,fe= _mat+'SG' )
cmds.select(cl=1)
cmds.parent(dupMesh,shard_grp)
cmds.refresh()
cmds.delete(cut_cube)
cmds.undoInfo( state = True)
et = time.time()
print 'total',et - st
a = shatter(0.002)
a._exe()

Python 프로그래밍하면서 memory leaking 문제가 생길 수 있습니다.
소스를 보여주시면, 어디가 문제인지 생각해 볼 수 있을 것 같네요.
공개하기 곤란하시면, 메일로 보내주셔도 되구요. gyedojeon앳gmail
알려주신 스크립트를 보니 OpenMaya 모듈이 python에서 접근가능하군요.
이제 Maya API를 쓰기 위해 힘들게 C++로 만들지 않아도 되겠네요.
엄청납니다 :)
ps) 다른 분들이 검색하시기 쉽게, 제목에는 질문요약을 적어주세요.
인사는 생략하셔도 됩니다 ^__^