レンダリングを高速化するスクリプト Vectorworks
Vectorworksのレンダリングを、高速化するスクリプトを作成しました。
基本的なCGに関する考えは次のように分けてます。
①コンペやリリース用のカッチリしたパース:外注やTwinmotionやenscapeとかのビジュアライズソフト
②設計を固める段階では、OpenGL(2022ではシェイドと呼んでるようですが)で動かしながら変更していく
③施主の窓口が社内展開用に使うパース:照明などセットしてそれなりに仕上げる
今回対象としてるのは、③です。
操作動画
まず、レンダリングはビューポートで行います。
①指定のアングルでビューポートを作成
②ビューポートを選択してスクリプトを実行
③明るさを調整して仕上(ダイアログ操作)
見て頂くとわかりますが、ダイアログのスライダーが二つあって、一つは明るさを、もう一つはコントラストを調整したかったのですが、Vectorworksの関数の不具合でコントラストをアンビエントオクルージョンで変更するのはできないようでした。残念。
レンダリングの補足説明は別でする予定です。
スクリプト(サンプル)
import vs
import os
def volD():#ダイアログの設定
kOK = 1
kCANCEL = 2
kSETUPDIALOG = 12255
def create_dialog():
dialog = vs.CreateLayout('OKボタンを押すとレンダリングが始まります。', False, 'OK', 'キャンセル')
vs.CreateStaticText( dialog, 5, '光源オブジェクトの配置はありますか?', 40 )
vs.SetFirstLayoutItem( dialog, 5 )
vs.CreateRadioButton(dialog, 10, '多い')
vs.SetBelowItem(dialog, 5,10,0,0)
vs.CreateRadioButton(dialog, 20, '普通')
vs.SetRightItem(dialog, 10, 20, 0, 0)
vs.CreateRadioButton(dialog, 30, '少ない')
vs.SetRightItem(dialog, 20, 30, 0, 0)
vs.CreateRadioButton(dialog, 40, '無い')
vs.SetRightItem(dialog, 30, 40, 0, 0)
return dialog
def dialog_handler(item,data):
if item == kOK:
volD.many = vs.GetBooleanItem(dialog, 10)
volD.just = vs.GetBooleanItem(dialog, 20)
volD.less = vs.GetBooleanItem(dialog, 30)
volD.nothing = vs.GetBooleanItem(dialog, 40)
elif item == kCANCEL:
pass
elif item == kSETUPDIALOG:
vs.SetBooleanItem(dialog, 10, False)
vs.SetBooleanItem(dialog, 20, True) #普通
vs.SetBooleanItem(dialog, 30, False)
vs.SetBooleanItem(dialog, 40, False)
return item
dialog = create_dialog()
result = False
volD.many = False
volD.just = False
volD.less = False
volD.nothing = False
if vs.RunLayoutDialog( dialog, dialog_handler ) == kOK:
result = True
return result , volD.many , volD.just , volD.less , volD.nothing
def repD():
kOK = 1
kCANCEL = 2
kSETUPDIALOG = 12255
widT = -1
def create_dialogR():
dialog = vs.CreateLayout('終了する場合はキャンセルを押してください', False, 'OK', 'キャンセル')
vs.CreateRadioButtonGroupBox(dialog, 100, '光の再調整', True)
vs.CreateControl(dialog, 110, 3, '陰影', 6) #3がスライダー / 6段階
vs.CreateControl(dialog, 120, 3, '全体の明るさ', 6)
vs.CreateStaticText(dialog, 130, 'より陰影を弱く', widT)
vs.CreateStaticText(dialog, 140, 'より陰影を強く', widT)
vs.CreateStaticText(dialog, 150, 'より全体を暗く', widT)
vs.CreateStaticText(dialog, 160, 'より全体を明るく', widT)
vs.SetFirstLayoutItem( dialog, 100 )
vs.SetFirstGroupItem(dialog,100,130,0,0)
vs.SetRightItem(dialog,130,110,0,0)
vs.SetRightItem(dialog,110,140,0,0)
vs.SetBelowItem(dialog,130,150,0,0)
vs.SetRightItem(dialog,150,120,0,0)
vs.SetRightItem(dialog,120,160,0,0)
vs.CreateRadioButtonGroupBox(dialog, 200, '最終レンダリング', True)
vs.CreateRadioButton(dialog, 210, '用紙に合わせる')
vs.CreateRadioButton(dialog, 220, '現在のサイズ')
vs.SetBelowItem(dialog,100,200,0,0)
vs.SetFirstGroupItem(dialog, 200,210)
vs.SetRightItem(dialog, 210,220,0,0)
return dialog
def dialog_handlerR(item,boo):
if item == kOK:
repD.repeat = vs.GetBooleanItem(dialog, 100) #光の再設定
repD.contrast = (vs.GetControlData(dialog, 110) -3)*5 #陰影
repD.brightness = (vs.GetControlData(dialog, 120) -3)*5 #全体を明るく
repD.finish = vs.GetBooleanItem(dialog, 200) #最終
repD.match = vs.GetBooleanItem(dialog, 210) #用紙サイズに合わせる
repD.current = vs.GetBooleanItem(dialog, 220) #現在のサイズ
#vs.EnableItem(dialogID, componentID, enableState)
elif item == kCANCEL:
pass
elif item == kSETUPDIALOG:
vs.SetBooleanItem(dialog, 100, True) #光の再設定
vs.SetBooleanItem(dialog, 200, False) #普通
vs.SetControlData(dialog, 110, 3) #陰影
vs.SetControlData(dialog, 120, 3) #全体を明るく
vs.SetBooleanItem(dialog, 210, True)
vs.SetBooleanItem(dialog, 220, False)
dialog = create_dialogR()
result = False
repD.repeat = False
repD.contrast = 0
repD.brightness = 0
repD.finish = False
repD.match = False
repD.current = False
if vs.RunLayoutDialog( dialog, dialog_handlerR ) == kOK:
result = True
return result , repD.repeat , repD.contrast , repD.brightness ,repD.finish ,repD.match ,repD.current
def sheetDpi(vp,dpi):
p1 , p2 = vs.GetDrawingSizeRect()
pW = p2[0] - p1[0]
pH = p1[1] - p2[1]
vpW = vs.HWidth(vp)
vpH = vs.HHeight(vp)
if pH/vpH >= pW/vpW:
vpScale = pW/vpW
else:
vpScale = pH/vpH
vs.Scale(vpScale,vpScale)
center = vs.HCenter(vp)
vs.HMove(vp, -center[0], -center[1])
vs.SetObjectVariableInt(vs.ActLayer(), 155 , dpi)
def firstRender(hand,bright,ao,aosize):#RWstyle
vs.SetObjectVariableInt(vs.ActLayer(), 155 , 72)
vs.SetObjectVariableBoolean(hand, 1268, True)#AOのONOF
vs.SetObjectVariableLongInt(hand, 1269, 2) #1269 間接光設定 3回が1 / 4回が2/ / 16回が3
vs.SetObjectVariableBoolean(hand, 1273, True) #背景放射光の適用
vs.SetObjectVariableReal(hand,1274,bright)#背景放射光の明るさ
vs.SetObjectVariableBoolean(hand, 1302, True)#AOのONOF
vs.SetObjectVariableReal(hand, 1303, ao) #AO 強さ 設定がされない不具合
vs.SetObjectVariableReal(hand, 1304, aosize) #AO サイズ 設定がされない不具合
def getRender(hand):
gi = vs.GetObjectVariableLongInt(hand, 1269) #間接光
bright = vs.GetObjectVariableReal(hand,1274)
ao = vs.GetObjectVariableReal(hand, 1303)
aosize = vs.GetObjectVariableReal(hand, 1304)
return gi,bright,ao,aosize
def setRender(hand,contrast,brightness):
#vs.SetObjectVariableLongInt(hand, 1269,gi) #間接光
vs.SetObjectVariableReal(hand,1274,bright+(brightness/100))
vs.SetObjectVariableReal(hand, 1303,ao+(contrast/100))
vs.SetObjectVariableReal(hand, 1304,aosize)
def setName(name):
i = 1
nameR = str(name)+'-'+str(i)
while True:
hand = vs.GetObject(str(nameR))
if hand == 0:
nameH = vs.GetObject(str(name))
vs.SetName(nameH,str(nameR))
alrt = name + 'は' + nameR + 'に変更しました。'
vs.AlrtDialog(str(alrt))
break
#vs.AlrtDialog(str(nameR))
i += 1
nameR = str(name)+'-'+str(i)
viewH = vs.FSActLayer()
handT = vs.GetTypeN(viewH)
selectN = vs.NumSelectedObjects()
if viewH == None or not handT == 122 or not selectN == 1:
vs.AlrtDialog('1つのビューポートを選択して下さい')
else:
rwH = vs.GetObject('repeatRW')
rwT = vs.GetTypeN(rwH) #Renderworksstyle 106
if rwH == 0: #repeatRWが無い
rwH = vs.CreateRenderworksStyle()
vs.SetName(rwH,'repeatRW')
else: #repeatRWがある
if rwT != 106:
setName('repeatRW')
rwH = vs.GetObject('repeatRW')
vs.SetObjectVariableInt(viewH, 1001, 15)
vs.SetObjectVariableHandle( viewH, 1281,rwH)
result , many , just , less , nothing = volD()
if result == True:
ao = 0.2
aosize = 400
if many == True:
bright = 0.4
elif just == True:
bright = 0.55
elif less == True:
bright = 0.7
else:
bright = 0.85
firstRender(rwH,bright,ao,aosize)
vs.UpdateVP(viewH)
vs.SetPref(596,True)
vs.ReDraw()
while True:
result , repeat , contrast , brightness ,finish ,match ,current = repD()
if result == False:
vs.AlrtDialog('キャンセルされました。')
break
else:
if finish == True:
if match == True:
sheetDpi(viewH,300)
vs.SetObjectVariableBoolean(viewH,1004,True)
vs.UpdateVP(viewH)
vs.SetPref(596,True)
vs.ReDraw()
break
else:
vs.SetObjectVariableInt(vs.ActLayer(), 155 , 300)
vs.SetObjectVariableBoolean(viewH,1004,True)
vs.UpdateVP(viewH)
vs.SetPref(596,True)
vs.ReDraw()
break
else: #RepeatがTrue
gi,bright,ao,aosize = getRender(rwH)
if bright > 1:
vs.SetObjectVariableLongInt(rwH, 1269,3)
setRender(rwH,contrast,brightness)
vs.SetObjectVariableBoolean(viewH,1004,True)
vs.UpdateVP(viewH)
vs.SetPref(596,True)
vs.ReDraw()
pass
else:
vs.AlrtDialog('キャンセルされました。')
pass