2014年6月9日月曜日

Metasequia Script : UVStitch

メタセコイア 4.2がでましたね〜
FaceなどのSnapが今回の目玉でしょうか。

64bitOSで、32bit版のMetasequiaが動く

知りませんでした> アフォすぎる。
プラグインも32bit版のものも動くようです

ずっと基本機能で 64bit版使ってたよ orz


UV Stitich

UVPowerTools Plugin
残念ながら64bit化しておりません。

誰かが作ってくれるのを待ってる訳ですが
神は訪れず


スクリプトエディッタ上でのPythonの調査
Classの練習がてら、つらつらコードを書いてたのですが、
なんとなく、必要な情報がそろいましたので

選択UVを縫い合わせるスクリプトを作ってみました。

#UVStitch
#選択したUVを縫い合わせる

app = MQSystem; log = app.println
debug = False

def dlog( string ):
 if debug == True:
  log ( string )
  

class pairValue:
 def __init__(self,face,line):
  self.face = face
  self.line = line

   
class UVNode:
 def __init__(self,index,obj,objID,faceID,faceVertexID,vertexID,UVType,isSelected,UVCoord):
  self.index = index
  self.obj = obj
  self.objectID = objID
  self.faceID = faceID
  self.faceVertexID = faceVertexID
  self.vertexID = vertexID
  self.UVType = UVType
  self.isSelected = isSelected
  self.uvCoordinate = UVCoord
  
 def uvSelfTranslate(self):
  self.obj.face[ self.faceID ].setCoord( self.faceVertexID, self.uvCoordinate)
  
 def uvTranslate(self,uValue,vValue):
  uv = app.newCoordinate(uValue,vValue)
  self.obj.face[ self.faceID ].setCoord( self.faceVertexID, uv)
  

class objInfo:
 def __init__(self,obj,oi):
  doc = app.getDocument()
  materials = doc.material
  self.obj = obj
  self.vertCount = obj.numVertex
  self.faceCount = obj.numFace
  self.face2MatID = []
  self.UVNodeList = []
  self.nodeCount= 0
  
  self.vertex2Node = []
  for vi in range(self.vertCount):
   self.vertex2Node.append([])
   
  
  for fi in range( self.faceCount ):
   face = obj.face[fi]
   self.face2MatID.append(face.material)
   mat = materials[face.material]
   mapType = mat.mapType
   verteciesIDs = face.index
   
   for fvi in range(face.numVertex):
    sel = doc.isSelectUVVertex(oi, fi,fvi)
    index = self.nodeCount
    vertexID = verteciesIDs[fvi]
    self.vertex2Node[vertexID].append(index) # vertex2Node
    #log(str(fi))
    self.UVNodeList.append( UVNode( index, self.obj, oi, fi, fvi,vertexID, mapType, sel, face.getCoord(fvi) ) )
    self.nodeCount += 1
  
 def infoView(self):
  log("")
  log( "UVInfo" )
  log("objectName : "+ str( self.obj.name ))
  log("nodeCount  : " + str ( self.nodeCount) )
  
  log("vertex2Node")
  for i in range(len(self.vertex2Node)):
   log("vertexID : " + str( i ) + " : " +str(self.vertex2Node[i]) )
  
  for ni in range(self.nodeCount):
   node = self.UVNodeList[ni]
   log(
    "Node :" + str(node.index) +  ",   " +
    "oi,fi,fvi : " + str(node.objectID ) + "," +  str(node.faceID) + "," + str(node.faceVertexID) + ",  " +
    "vID : " + str(node.vertexID) + ",   " +
    "Sel : " + str(node.isSelected)
    )
  log("---UV info END ---")
    

#選択したUVを縫い合わせる
def uvStitch(in_ObjectInfo,in_oi):
 dlog("----- uvStich -----")

 info = in_ObjectInfo
 obj = in_ObjectInfo.obj
 oi = in_oi
 
 nodes = info.UVNodeList
 
 
 #ノードのチェックリストを作成
 isChkedNodeList = []
 for ni in range(info.nodeCount ):
  isChkedNodeList.append(False)
  
 #vertexIDのチェックリストを作成
 isChkedVertexIDs = []
 for vi in range( info.vertCount ):
  isChkedVertexIDs.append( False )
   
 #ノードごとにチェックする
 #選択していないものは動かないのでチェック済みに入れる
 for ni in range(info.nodeCount ):
  if nodes[ni].isSelected == 0:
   isChkedNodeList[ni] = True
 
 dlog(str(isChkedNodeList))
 
 #チェック済み評価
 for ni in range( info.nodeCount ):
 
  #チェックしてない
  if( isChkedNodeList[ ni ] == False):
   node = nodes[ ni ]
  
   moveNodeGroupIDs = []
   uMin = node.uvCoordinate.u
   uMax = node.uvCoordinate.u
   vMin = node.uvCoordinate.v
   vMax = node.uvCoordinate.v
   
   serchUnionUV = False
   
   moveVertexNodeCount = 0
  

   #共通する頂点を持ったノードを探す
   vertex2Nodes = info.vertex2Node[node.vertexID]
    
   #共通の頂点をもつノードを精査
   for subi in vertex2Nodes:
   
    # チェック済みであれば次へ
    if isChkedNodeList[subi] == True:
     continue;
     
    #mapTypeがUVでなければ次へ
    if node.UVType != 0:
     continue
    
    tNode = nodes[subi]
   
    #チェック済みに
    isChkedNodeList[subi] = True
    
    #移動用のアレイに入れる
    moveNodeGroupIDs.append(subi)
   
    #座標をbBoxチェックに
    if uMin > tNode.uvCoordinate.u:
     uMin = tNode.uvCoordinate.u
    if uMax < tNode.uvCoordinate.u:
     uMax = tNode.uvCoordinate.u
    if vMin > tNode.uvCoordinate.v:
     vMin = tNode.uvCoordinate.v
    if vMax < tNode.uvCoordinate.v:
     vMax = tNode.uvCoordinate.v
     
    moveVertexNodeCount += 1
    
    #頂点内はすべて終わった 
    serchUnionUV = True
   
   #移動数が2以上でなければ
   if moveVertexNodeCount < 2:
    continue
    
   #頂点内がすべて終わっていれば
   if serchUnionUV == True:
    dlog("serched")
   
    #BBOXの平均を出す
    uv = app.newCoordinate( uMin + ( uMax - uMin) *0.5 , vMin + ( vMax - vMin ) * 0.5 )
    
    #各NodeのUVを更新
    for nid in moveNodeGroupIDs:
     dlog(str(nodes[nid].uvCoordinate ))
     nodes[nid].uvCoordinate = uv
   
     dlog(str(nodes[nid].uvCoordinate ))
   
 #UVを実移動する
 
 for node in nodes:
  #dlog("UVTrans")
  node.uvSelfTranslate()


def main():
 log("")
 log( "----- ScriptStarts -----" )
 doc = app.getDocument()
 num = doc.numObject
 currentObjectID = doc.currentObjectIndex
 materials = doc.material
 
 for oi in range(num):
 
  #カレントオブジェクトかどうか(不格好だが、複数アイテムに対応しやすいため
  if oi != currentObjectID :
   continue

  obj = doc.object[oi]
  if obj is None: continue
  
  info = objInfo(obj,oi)
  
  #info.infoView()
  
  uvStitch(info,oi)
  
  
 log( "----- Finish -----" )
  
 
 
main()
スクリプトエディッタにコピペして実行してください
対応したUVが縫い合わされるはずです。


きゃー
Pythonで初クラス
とりあえず動くまではいけました。

いや、MAYAの習得の方が先ですよね、わかってます orz

0 件のコメント:

コメントを投稿