MY BLOG DIRECTORY:
INTRODUCTION:
SD里建立材质库以后,我们需要用一个手段去控制它们,这时候很多操作都是繁琐的,所以可以用插件解决,比如批量组合一些节点,用一个节点当作处理器处理大量贴图资源等。新版的Substance加入了SubstanceAPI,能让我们使用脚本去操控SubstanceDesigner中的全部功能。
FORWARD DECLARATION:
本文内容过于rua鸡。
MAIN CONTENT:
【1】Setup your first sd plugin
首先我们先建个插件,建插件前可以先把插件路径配好
建好以后便可以在这里面敲代码来控制SD
【2】Plugin Location
aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.SBSCompGraph, 0)
使用sdplugins.PluginLocationToolbar会把插件指认在Graph栏里。如果想把它指认在最上面的工具栏,则可以调用如下命令:
aPluginLocation = sdplugins.PluginLocationMenu(sdplugins.MenuId.Scripts, 'CustomPlugin' ,0)
还可以把它放在主工具栏
aPluginLocation = sdplugins.PluginLocationToolbar(sdplugins.ToolBarId.Main,0)
【3】Get the selected nodes
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
我把它暂时放在了桌面
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中的结果存到磁盘
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当成图片处理器来使用了,我下面做了个简单演示,处理一张图片。
【6】Load texture
我们有时候需要自动化地把资源从外部批量化导入
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....