2013年4月17日水曜日

SoftimageScript : Fillet っぽいなにか



メモです

ちょっと パイプが山の用にあって
その曲がりの角ががが・・・ orz

Filletっぽい何かを作ってお茶を濁します。


FilletLinearCurve

リニアカーブのコントロールポイントを選択し、
実行します

カーブの再描画ですので、ご注意を。

# FilletLinerCurve
#
# リニアカーブの選択したポイントを分割、再描画してくれます
# 正確な円ではありません~ 付け焼刃
#
# v0.1 2013 0417

app = Application; log = app.LogMessage
from win32com.client import constants as c

 
#ログの表示を消す
cmdLog = app.Dictionary.GetObject( "preferences.scripting" )
cmdLog.cmdlog.value = False

#半径と、間に入る頂点数
gRadius   = 1
gDivision = 2


def CreateNewCurve(aPos):
 
 myNewCurve = app.SICreateCurve("",1,0)
 for i in range(len(aPos[0])):
  app.SIAddPointOnCurveAtEnd(myNewCurve,aPos[0][i],aPos[1][i],aPos[2][i],False,0)
 app.SelectObj(myNewCurve)
 return


def l2gArray(aPos,m4):
 v = XSIMath.CreateVector3()
 for i in range(len(aPos[0])):
  v.Set(aPos[0][i],aPos[1][i],aPos[2][i],)
  v.MulByMatrix4InPlace(m4)
  aPos[0][i] = v.X
  aPos[1][i] = v.Y
  aPos[2][i] = v.Z


def alog(aPos):
 log("cnt = " + str(len(aPos)))
 for i in range(len(aPos)):
  log( "V : " + 
  str( aPos[0][i]) + " , " +
  str( aPos[1][i]) + " , " +
  str( aPos[2][i])
  )


def GeiFilletPoint(posA,posB,posC,in_t):

 v1 = XSIMath.CreateVector3()
 v2 = XSIMath.CreateVector3()
 v3 = XSIMath.CreateVector3()
 
 p0 = XSIMath.CreateVector3()
 p1 = XSIMath.CreateVector3()
 p2 = XSIMath.CreateVector3()
 
 v1.Sub(posB,posA)
 v2.Sub(posC,posB)
 
 p1.ScaleAdd(in_t,v1,posA)
 p2.ScaleAdd(in_t,v2,posB)
 
 v3.Sub(p2,p1)
 p0.ScaleAdd(in_t,v3,p1)
 
 return p0
 
 
def addFiletPnts(x,y,z,i,aPos):
 
 #カーブのセグメントを追加 
 #ContorolPoints 0,1,2
 pos00 = XSIMath.CreateVector3(aPos[0][i - 1],aPos[1][i - 1],aPos[2][i - 1])
 pos10 = XSIMath.CreateVector3(aPos[0][i    ],aPos[1][i    ],aPos[2][i    ])
 pos20 = XSIMath.CreateVector3(aPos[0][i + 1],aPos[1][i + 1],aPos[2][i + 1])

 v1 = XSIMath.CreateVector3()
 v2 = XSIMath.CreateVector3()
 
 v1.Sub(pos00,pos10)
 v2.Sub(pos20,pos10)
 
 v1.NormalizeInPlace()
 v2.NormalizeInPlace()

 #new Point 
 pos01 = XSIMath.CreateVector3()
 pos02 = XSIMath.CreateVector3()
 
 #半径分Pos00からの距離
 pos01.ScaleAdd(gRadius,v1,pos10)
 pos02.ScaleAdd(gRadius,v2,pos10)
 
 #分割数分 FilletPositonの追加
 num = gDivision + 2
 
 for i in range(num):
  t = i * 1.0 / (num - 1)
  v = GeiFilletPoint(pos01,pos10,pos02,t)
  x.append( v.X )
  y.append( v.Y )
  z.append( v.Z )


def CreateNewPos(aPos,oSelIDs):

 x = []
 y = []
 z = []
 
 for i in range(len(aPos[0])):
  log(i)
  flg = True
  for j in oSelIDs:
   #最初と最後のポイントは無視(Closeには対応してません
   if i == j and i != 0 and i != len(aPos[0]) - 1:
   
    #選択したポイントであれば
    #log("match")
    flg = False
    
    #カーブのポイントを挿入
    addFiletPnts(x,y,z,i,aPos)
    
  if(flg == True):
   #log("NoMatch")
   x.append( aPos[0][i] )
   y.append( aPos[1][i] )
   z.append( aPos[2][i] )
   
 nPos = [x,y,z]
 
 return nPos
 

def main():
 if app.Selection.Count ==0:
  return
  
 oSel = app.Selection(0)
 if oSel.Type != "pntSubComponent":
  log("Select LinerCurve Control Points")
  return
  
 oSub = oSel.SubComponent
 oCurveList = oSub.Parent3DObject
 if oCurveList.Type != "crvlist":
  log("Select LinerCurve Control Points")
  return
  
 oColl = oSub.ComponentCollection
 oSelIDs = oColl.IndexArray
 oTrans = oCurveList.Kinematics.Global.Transform
 m4 = XSIMath.CreateMatrix4()
 oTrans.GetMatrix4(m4)
 
 #カーブからコントロールポイントのリスト、Posを取得
 oCurve = oCurveList.ActivePrimitive.Geometry.Curves(0)
 aPos = oCurve.ControlPoints.PositionArray
 aPos = [list(aPos[0]),list(aPos[1]),list(aPos[2])]
 
 l2gArray(aPos,m4)
 
 #新しいコントロールポイントのリストを作成
 nPos = CreateNewPos(aPos,oSelIDs)
 
 #新規カーブの作成
 CreateNewCurve(nPos)
 
main()


スミマセン、こうでもして書いておかないと
多忙なときは作ったことすら忘れますのでご容赦を

0 件のコメント:

コメントを投稿