2013年5月14日火曜日

Softimage Script : ZSortNumbering v0.1

ども、まだまだ修羅場中のTERAです。
あいかわらず、チラ裏スクリプトです
(整理とか、エラー処理とかしてません)


今回の背景はアルファオブジェクト(半透明)
を多用しています

ZSortの場合アルファオブジェクトは
描画順を指定してやらねばなりません、
※最近のIntelAPUでは、力づくで解決してるみたいだけど


まだまだ世の中はオールドテク万歳です。


で、奥から描画するとして、
命名規則で指定する事になりました

・・・数が・・・。
大量にアルファオブジェクトがあると、
めんどくさいのでスクリプト化します


ZSortNumbering


オブジェクト(複数)を選択して実行すると
奥から順に番号を降ってくれます

axxx_ObjectName
最後のナンバリングは消してます


現状PPG無し、カメラの指定は決めうち、など
Toolとして、体をなしてなく、
条件がたくさんですが
とりあえず乗っけておきます。


こういった事案が多数 or 要望があればTool化するかもしれません。


※拡張性として、以下のスイッチがあります
カメラ平面からの距離 <> カメラからの距離
オブジェクトのセンター <> オブジェクトのBBOXセンター
です。
あと、番号の始まりと、頭につける文字の変更とか。

#ZSortNumbering
#
# 選択したオブジェクトをZSort順に命名変更します
# a000_ObjectName
#
# v0.1 0510 2013 とりあえず動いた
#

from win32com.client import constants as c
app = Application; log = app.LogMessage
import re
p = re.compile("[0-9]")

#GlobalValue
PREFIX = "a"
STRRTINGNUMBER = 0
tempCAM ="Camera"
ZDEPTH = True #ZDEPTH or Distance
OBJECTCENTER = False # Switch BBOX

def vLog(v):
 log(str( v.X ) + " , " + str(v.Y) + " , " + str(v.Z) )


def aPosLog(aPos):
 for v in aPos:
  log(str( v.X ) + " , " + str(v.Y) + " , " + str(v.Z) )

#
# bNumDelete
#
def bNumDelete(in_str):
 oName = in_str
 for i in range( len( oName ) ):
  if p.match(oName[-1:]) != None:
   oName = oName[:-1]
  elif oName == "_":
   oName = oName[:-1]
  else:
   break
 return oName

#
# getNumbering
#
def getNumbering(in_digi,in_Start,in_Count):
 num = in_Count + in_Start
 num = str(num).rjust(in_digi,"0")
 return num


#
# getSelectMeshs
#
def getSelectMeshs():

 #-製作中-現在は選択したメッシュのみ
 col = XSIFactory.CreateObject("xsi.collection")
 oMeshs = XSIFactory.CreateObject("xsi.collection")
 col.Unique = True
 oMeshs.Unique = True
 
 oSels = app.Selection
 for oSel in oSels:
  if oSel.Type == "polymsh":
   oMeshs.Add(oSel)
   
 return oMeshs


#
# getCamera
#
def getCamera():
 #カメラ取得は仮
 oCam = app.Dictionary.GetObject(tempCAM)
 
 return oCam


#
# getObjectBBOXPositionArray
# 
def getObjectBBOXPositionArray(inObjects):
 aPos = []
 for oObj in inObjects:
  pos = XSIMath.CreateVector3()
  oTrans = oObj.Kinematics.Global.Transform
  oA = oObj.GetBoundingBox( oTrans );
  pos.Set( (oA[3] - oA[0]) *.5 + oA[0],
     (oA[4] - oA[1]) *.5 + oA[1],
     (oA[5] - oA[2]) *.5 + oA[2] )
  aPos.append(pos)
 return aPos


#
# getObjectPositionArray
#
def getObjectPositionArray(inObjects):
 aPos = []
 for oObj in inObjects:
  pos = XSIMath.CreateVector3()
  oTrans = oObj.Kinematics.Global.Transform
  oTrans.GetTranslation(pos)
  aPos.append(pos)
 return aPos


#
# getMeshZNumber
#
def getMeshZNumber(oCam, oMeshs):
 log("-----getMehsNumber-----")
 aDis = []
 aNum = []
 
 #ObjectPositionArray
 if OBJECTCENTER:
  aPos = getObjectPositionArray( oMeshs )
  
 else:
  aPos = getObjectBBOXPositionArray( oMeshs ) 
 
 #aPosLog(aPos) 
 
 #ZDepth or Distance
 camPos = XSIMath.CreateVector3()
 camAxis = XSIMath.CreateVector3()
 camRot = XSIMath.CreateRotation()
 m3 = XSIMath.CreateMatrix3()
 oCamTrans = oCam.Kinematics.Global.Transform
 oCamTrans.GetTranslation(camPos)
 oCamTrans.GetRotation(camRot)
 camRot.GetMatrix3(m3)
 aM3 = m3.Get2()
 camAxis.Set(aM3[6],aM3[7],aM3[8])
 
 log("")
 log("---camPos---")
 vLog(camPos)
 
 log("")
 log("---camAxis---") 
 vLog(camAxis)
 
 if(ZDEPTH):#ZDepthの場合
  log("-----ZDepth-----")
  d = camPos.Dot(camAxis) #PolyPlane = p・n - d
  #log(d)
  for oPos in aPos:
   dis = ( oPos.Dot(camAxis) - d ) * -1
   aDis.append(dis)
   log(dis)
 else:
  v = XSIMath.CreateVector3()
  for oPos in aPos:
   v.Sub(camPos,oPos)
   dis = v.Length()
   aDis.append(dis)
   log(dis)
 
 aTemp = []
 for i,d in enumerate(aDis):
  bTemp = [d,i]
  aTemp.append(bTemp)
  
 aTemp.sort()
 aTemp.reverse()
 
 log(str(aTemp))
 for i in aTemp:
  aNum.append(i[1])
   
 return aNum

#
# main
#
def main():
 log("-----ASortNumbering")
 
 #GetMeshObject
 oMeshs = getSelectMeshs()
 if oMeshs.Count == 0:
  log("Pls Select Meshs")
  return
  
 #Camera
 oCam = getCamera()
 
 #GetNumber From Depth
 aNum = getMeshZNumber(oCam,oMeshs)
 log(str(aNum))
 
 #Renema
 for i,num in enumerate(aNum):
  oObj = oMeshs(num)
  no = getNumbering(3,STRRTINGNUMBER,i)
  oName = PREFIX + str(no) + "_" + oObj.Name
  oObj.Name = bNumDelete(oName)
main()

2013年4月27日土曜日

Photo : Panorama : 偏光フィルタを使った、パノラマ撮影実験


先日、偏光フィルタなるものを入手しました。
偏光フィルタとは・・・。ググってください :p


スペキュラを押さえた、テクスチャ撮影が可能になります
雲がきれいに撮れます :D

最近になって気づきました orz


というわけで、魚眼レンズに無理矢理偏光フィルタをかまして、
全周囲パノラマをやってやろうって、あふぉな話です

※Tokina10-17mm fisheyeは C-PLフィルタは通常つきません。
良い子はまねしないように


撮影結果



書き出したHDRをPhotoshopで調整したもの


偏光フィルタの使用前、使用後





素材


ハード
・パノラマ撮影器具
・C-PLフィルタ

ソフト
・Lightroom
・PTGui
・Photoshop


1.撮影


まずは通常通り、偏光フィルタをつけずに撮影します。
これの合成結果の計算をテンプレート化し、偏光フィルタをつけたものに適用させます。

しっかりキャリブレーションが取れている場合は、
PTGuiの、テンプレートを流用する事が出来ると思います

左、偏光フィルタ使用前、右、偏光フィルタ装着時

ケラレまくりで、おそらく、レンズに影を落としたり悪影響を及ぼしてるはずw


2.現像

LightRoomで現像DNG化します、一応リニア設定

3.PTGuiで通常撮影したものをパノラマ化


・通常の作業

・テンプレート保存

4.PTGuiでC-PLフィルタの撮影したものをパノラマ化


・テンプレートを利用して並べる

まあ、ひどい事になってます。これをマスキング


・マスクの作成


手作業で軽くあたりをつけたらマスクを保存し、Photoshopでマスクを調整


・マスクの調整

PTGUIでこのマスクを再適用し、すべての写真に適用させていきます・・・メンドクサイ orz


・書き出し



とりあえずやってみた、反省はしてみる


感触としてはアリ

ただ、環境マップとしては正確なライティングでは無くなりますw
ミー散乱や、レイリー散乱を排除するため

Tokina10-17
10mmで撮影、ケラレ具合で
通常撮影している+30,30度だと上下がなくなる

ズームで画角を調整すればよいが、
CPLフィルタを付けた際に回してしまう可能性があるため

次回は45度で試してみようかと思う


後日 角度+45 -45で撮影したもので問題なくいけた。
けど、なんらかの光の干渉があるみたい。

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()


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

Blog : GameDev : Simon schreibt Blogのゲーム技術ネタ

Simon schreibt Blogのゲーム技術ネタ

OmoriさんのBlogから、Simon schreibtのサイトの紹介,
ゲムの表現の謎解きなど、かなりのネタ解説

必読なのでメモ

Softimage : Modeling : Tutorial : Sloth Robot 3d design – Timelapse video –

ymt3Dさんのブログ 3D人から
リンク>



ふへーこの人SIユーザーだったんだ


気になるところとしては NGON気にしてない。
TextureはKeyLightで作ってるのでUVも気にしてない。


しわはMAYA
メッシュの流れを大きく変えるのに、頂点を選択してのベベル
クロスに最適

限定的なモデリングではあるけれど、
これだけ出来れば、きれいなトポロジも出来るに違いない〜

あと、パーツの蓄え、知識だな〜


後日談
一日Blogを寝かしてたんだけど ツイッターを見る限り

高速モデリングと割り切ってるので、こういう割り方は限定的で、
彼の通常のモデルはきれいなんだそうだ。

あと、SIのモデリングはMAYAなどから見るとうらやましいらしい。

SI のモデリング、いいらしいですよ〜

2013年4月16日火曜日

Softimage Tips テクスチャサポートを残したままフリーズ

Softimage2014も出た事ですが、華麗にスルーしてスクリプトです

Softimage の UV って浮遊しないよね

UVSwimの機能があるのですが、
これって、あまり機能しなくないですか?

いつの間にか、頂点を移動するとUVがくっついてくる。

これは Modeling Freeze をした際
Texture Support もフリーズ、削除されるのが原因です


情報を集めたところ、メーリングリスト、ツイッターから、

コンストラクションヒストリーから、
右クリックでフリーズを選択
すると

Texture Support はフリーズ、削除されないとの事でした。



というわけで、作ってみました。

#Python
app = Application
log = app.LogMessage


def FreezeConstruction(oObj):
 oPri = oObj.ActivePrimitive
 oHis = oPri.ConstructionHistory
 oCol = XSIFactory.CreateObject("XSI.Collection")
 oFlag = False
 for i in oHis:
  if oFlag == False:
   if i.Name == "Modeling":
    oFlag = True
  else:
   oCol.Add(i)
   break
   
 if oCol.Count == 0:
  return

 app.FreezeObj(oCol(0), "", "")

def main():
 oSels = app.Selection
 if oSels.Count == 0:
  return
  
 for oSel in oSels:
  if oSel.Type == "SubCompoent":
   oObj = oSel.SubComponent.Parent3DObject
   FreezeConstruction(oSel) 
  
  if oSel.Type == "polymsh":
   FreezeConstruction(oSel)

main()

モデリングコンストラクション以下の
オペレータのみフリーズするスクリプトです

ボタン化などしたら使い勝手が良いようです


Plugin化とも思ったのですが
現在製作しているツール群に入れようと思ったので
コードのままです orz すみません



近況
資料の入稿が伸びたので多少時間がありました(過去形)

建物の壁をFacerdと言うらしいのですが、
こちらのモデリングを効率化することが、
現在の最優先事項です(した)

というのも FarCry3 の地形エディッタを使ってみたのですが、
これが、パーツをブロックごとに扱い、
背景を制作する手順でした。

その機能の洗練具合に打ちのめされたからではないですが・・・
うそです。勝てないと思いました orz

背景屋さんは使ってみると良いデス
ゲムも最高に面白いデス

あと、アサクリも凄いっすね。
凄いっす。


建物は規格の固まりですので、
なんとか、簡単に出来ないものかと、
余暇で、テスト モデリングをしつつ、
ツールの再整備、C++化など行ってます


ある程度、手順化出来、ツールが大まかな形を見せてきました


正面の写真から、
この程度のモデリングでしたら15分でいけると思います
オブジェクトが単純だものねー


しかし、MAX2014のパースマッチングうらやましい

2013年4月1日月曜日

Softimage OriginalPlugin : CleanPlanePoly

現在の背景、次の資料待ち中なのですが、
プラグインが完成したので公開致します〜

CleanPlanePoly


平面のポリゴンをまとめます

多角ポリゴンが出来ますので、注意が必要ですが、
下絵などのワイヤーフレーム表示見づらい場合は
効果があるかもしれません



ここから > CleanPlanePoly


近況
今回の仕事、なかなかにタイトなのですが、
なんとかこなしてる状態です

UVToolsの説明の方も進めようかと思ったのですが、
プラグインの公開を優先させます〜
その方がモチベが高いので・・・。