虚幻4渲染编程(DCC工具篇---SD)【Python Scripting in SD】

MY BLOG DIRECTORY:

YivanLee:专题概述及目录

INTRODUCTION:

SD里建立材质库以后,我们需要用一个手段去控制它们,这时候很多操作都是繁琐的,所以可以用插件解决,比如批量组合一些节点,用一个节点当作处理器处理大量贴图资源等。新版的Substance加入了SubstanceAPI,能让我们使用脚本去操控SubstanceDesigner中的全部功能。

FORWARD DECLARATION:

本文内容过于rua鸡。


MAIN CONTENT:

【1】Setup your first sd plugin

首先我们先建个插件,建插件前可以先把插件路径配好

v2-6a8749df945309577f10d58f8504b41a_b.jpg
v2-6ce4f6795b161ebda2715aae21c14c77_b.jpg

建好以后便可以在这里面敲代码来控制SD


【2】Plugin Location

v2-7e0393dda9e59eca37f775a6fe3d318b_b.jpg
        aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.SBSCompGraph, 0)
      

使用sdplugins.PluginLocationToolbar会把插件指认在Graph栏里。如果想把它指认在最上面的工具栏,则可以调用如下命令:

        aPluginLocation = sdplugins.PluginLocationMenu(sdplugins.MenuId.Scripts, 'CustomPlugin' ,0)
      
v2-2d51f8fa893bb09c32f25e5d535f9cfd_b.jpg

还可以把它放在主工具栏

v2-027f69e4eedafbe0e62e87f4dc5901fd_b.jpg
        aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.Main,0)
      


【3】Get the selected nodes

v2-9dd724e970264c66227c7cfcfc20828b_b.jpg
        import sd
import sdplugins
from sd.api.sdproperty import SDPropertyCategory

class NewPlugin(sdplugins.Plugin):
	sPluginDesc = sdplugins.PluginDesc(
		aLabel = 'My Plugin',
		aTooltip = 'My Plugin',
		aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.SBSCompGraph,0),
		aIconFileAbsPath = '')

	def run(self, aContext):
			#sdContext =  sd.getContext()
			sdApplication = aContext.getSDApplication()
			LocContext = sdApplication.getLocationContext()
			SelectedNodes = LocContext.getSelectedNodes()
			for node in SelectedNodes:
				print(node.getPosition())
# Register module classes
sd.getContext().getSDApplication().registerModule(__name__)
      

插件的按钮位置必须在Graph下才能拿到选中的Node。但是现在拿到这些Node没啥用,因为现在除了能改变Node的位置外我们什么也做不了。


【4】Load or get a graph

如果想用一个Graph批量处理大量贴图,我们需要做的第一件事情就是把这个图表先加载进来。首先我们先确保我们的电脑磁盘的指定路径下有一个package资源,这个Package资源中有一个Graph

v2-12be4e780a8dac3b7d3bd51c65f796a3_b.jpg

我把它暂时放在了桌面

v2-0c0d40964c5fdd0b43ef6fd4c683a257_b.png
        import sd
import sdplugins

class NewPlugin(sdplugins.Plugin):
	sPluginDesc = sdplugins.PluginDesc(
		aLabel = 'My Plugin',
		aTooltip = 'My Plugin',
		aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.Main,0),
		aIconFileAbsPath = '')

	def run(self, aContext) :
		sdContext =  sd.getContext()
		sdApplication = sdContext.getSDApplication()
		pkgManager = sdApplication.getPackageMgr()
		pkg = pkgManager.loadUserPackage('C:/Users/Yivanlee/Desktop/TestPKG.sbs')
		sbsCompGraph = pkg.findResourceFromUrl('TestGraph')
		sbsCompGraph.compute()

		pass

# Register module classes
sd.getContext().getSDApplication().registerModule(__name__)

      

你需要在pkg = pkgManager.loadUserPackage('C:/Users/yivanlee/Desktop/TestPKG.sbs')中指认自己的路径即可。

如果是获取Package,不想用SD加载它,那么可以使用以下代码,注意绝对路径需要更为自己电脑的:

        pkg = pkgManager.getUserPackageFromFilePath('C:/Users/Yivanlee/Desktop/TestPKG.sbs')
      

如果想在Export的时候让电脑弹出保存位置咨询框可以做如下修改

        import sd
import sdplugins
from sd.api.sdproperty import SDPropertyCategory
import os

class NewPlugin(sdplugins.Plugin):
	sPluginDesc = sdplugins.PluginDesc(
		aLabel = 'My Plugin',
		aTooltip = 'My Plugin',
		aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.Main,0),
		aIconFileAbsPath = '')

	def run(self, aContext) :
		sdContext =  sd.getContext()
		sdApplication = sdContext.getSDApplication()
		pkgManager = sdApplication.getPackageMgr()
		#pkg = pkgManager.loadUserPackage('C:/Users/YivanLee/Desktop/TestPKG.sbs')
		pkg = pkgManager.getUserPackageFromFilePath('C:/Users/YivanLee/Desktop/TestPKG.sbs')
		sbsCompGraph = pkg.findResourceFromUrl('TestGraph')
		sbsCompGraph.compute()

		saveDir = sd.ui.filedialog.selectDirectory(aTitle='', aInitialDirectory='', aTkinterParentWidget=None)		
		
		for sbsCompOutputNode in sbsCompGraph.getOutputNodes():
			#print(getOutputNodes)
			for sdOutputProperty in sbsCompOutputNode.getProperties(SDPropertyCategory.Output):
				#print(sdOutputProperty.getLabel())
				sdPropertyValue = sbsCompOutputNode.getPropertyValue(sdOutputProperty)
				sdTexture = sdPropertyValue.toSDTexture()
				filename = os.path.abspath(saveDir + '/%s.png' % sdOutputProperty.getLabel())
				sdTexture.save(filename)

# Register module classes
sd.getContext().getSDApplication().registerModule(__name__)
      

使用sd.ui.filedialog.selectDirectory(aTitle='', aInitialDirectory='', aTkinterParentWidget=None) 来创建保存路径询问事件。


【5】Save output node data into texture

有了Graph以后,需要把Graph中的结果存到磁盘

v2-a6b659aa31bcd4ecad6507cde8e90291_b.jpg
        import sd
import sdplugins
from sd.api.sdproperty import SDPropertyCategory
import os

class NewPlugin(sdplugins.Plugin):
	sPluginDesc = sdplugins.PluginDesc(
		aLabel = 'My Plugin',
		aTooltip = 'My Plugin',
		aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.Main,0),
		aIconFileAbsPath = '')

	def run(self, aContext) :
		sdContext =  sd.getContext()
		sdApplication = sdContext.getSDApplication()
		pkgManager = sdApplication.getPackageMgr()
		#pkg = pkgManager.loadUserPackage('C:/Users/YivanLee/Desktop/TestPKG.sbs')
		pkg = pkgManager.getUserPackageFromFilePath('C:/Users/YivanLee/Desktop/TestPKG.sbs')
		sbsCompGraph = pkg.findResourceFromUrl('TestGraph')
		sbsCompGraph.compute()
		
		for sbsCompOutputNode in sbsCompGraph.getOutputNodes():
			#print(getOutputNodes)
			for sdOutputProperty in sbsCompOutputNode.getProperties(SDPropertyCategory.Output):
				#print(sdOutputProperty.getLabel())
				sdPropertyValue = sbsCompOutputNode.getPropertyValue(sdOutputProperty)
				sdTexture = sdPropertyValue.toSDTexture()
				filename = os.path.abspath('C:/Users/YivanLee/Desktop/Output/%s.png' % sdOutputProperty.getLabel())
				sdTexture.save(filename)

# Register module classes
sd.getContext().getSDApplication().registerModule(__name__)

      

这样就可以把SubstanceDesigner当成图片处理器来使用了,我下面做了个简单演示,处理一张图片。

v2-4bc230fd3301e6ca8c89ae96e09dcb6b_b.jpg
v2-93e815d6b1f5cba32ea982d0f330ceb8_b.jpg


【6】Load texture

v2-302256ea4b6b2aa625c85112dc1e0a32_b.jpg

我们有时候需要自动化地把资源从外部批量化导入

        import sd
from sd.api.sdresourcebitmap import SDResourceBitmap
from sd.api.sdresource import EmbedMethod
context = sd.getContext()
app = context.getSDApplication()
UIMgr = app.getQtForPythonUIMgr()
pkgMgr = app.getPackageMgr()

pkgs = pkgMgr.getUserPackages()
thisPkg = pkgs[0]
bitmap = SDResourceBitmap.sNewFromFile(thisPkg,r'C:\Users\YivanLee\Desktop\Test.png',EmbedMethod.Linked)
      

SUMMARY AND OUTLOOK:

Substance Designer 的脚本系统现在还不是非常完善,2018版本非常简单,2019版本有一次比较大的改动,官方应该会在未来不断完善,目前2019版本的Substance Designer还处于勉强能用的程度。


NEXT:

maybe never....

发布了384 篇原创文章 · 获赞 4 · 访问量 8045

猜你喜欢

转载自blog.csdn.net/cpongo10/article/details/100745174
sd