レンダリングを高速化するスクリプト 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

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です