Skip to content

Commit

Permalink
refcator, add node settings in rules, better PxrSurface match
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippe Leprince committed Oct 19, 2018
1 parent e43abb7 commit 6d0ba9e
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 53 deletions.
2 changes: 1 addition & 1 deletion RenderMan/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"description": "This plugin exports a painter project to RenderMan Assets.",
"url": "https://github.com/pleprince/RfSP",
"version": "0.2.1",
"version": "0.2.2",
"license": "<a href=\"https://opensource.org/licenses/MIT\">MIT</a>"
}
6 changes: 5 additions & 1 deletion RenderMan/renderman.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function exportAssets(bxdf) {
// store env vars
//
fileContent += tab + "\"scene\": \"" + scene_name + "\",\n"
fileContent += tab + "\"sp_version\": \"" + alg.version.painter + "\",\n"
fileContent += tab + "\"RMANTREE\": \"" + jsonPath(alg.settings.value("RMANTREE")) + "\",\n"
fileContent += tab + "\"RMSTREE\": \"" + jsonPath(alg.settings.value("RMSTREE")) + "\",\n"
fileContent += tab + "\"bxdf\": \"" + bxdf + "\",\n"
Expand All @@ -123,10 +124,13 @@ function exportAssets(bxdf) {

// Parse all materials (texture sets)
//
for (matIdx = 0; matIdx < document.materials.length; matIdx++) {
for (matIdx = 0; matIdx < document.materials.length; matIdx++)
{
var material = document.materials[matIdx].name
fileContent += tab2 + "{\n"
fileContent += tab3 + "\"textureSet\": \"" + material + "\",\n"
var resolution = alg.mapexport.textureSetResolution(material)
fileContent += tab3 + "\"resolution\": \"" + resolution + "\",\n"
fileContent += tab3 + "\"channels\": {\n"
// alg.log.info("RenderMan: Texture Set \"" + material + "\" : ")

Expand Down
110 changes: 66 additions & 44 deletions RenderMan/rmanAssetsSubstancePainter.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import json
import shutil
import logging
import getpass

THIS_DIR = os.path.dirname(os.path.realpath(__file__))
LOGFILE = os.path.join(THIS_DIR, 'rfsp_log.txt')
Expand Down Expand Up @@ -171,6 +172,33 @@ def setup_environment(jsonDict):
return rman_version


def set_params(settings_dict, chan, node_name, asset):
# The bxdf may need specific settings to match Substance Painter
try:
params = settings_dict[chan]
except (KeyError, TypeError):
pass
else:
for pname, pdict in params.iteritems():
asset.addParam(node_name, pname, pdict)
DBUG(' |_ param: %s %s = %s', pdict['type'], pname, pdict['value'])


def add_texture_node(asset, node_name, ntype, filepath):
asset.addNode(node_name, ntype, 'pattern', ntype)
pdict = {'type': 'string', 'value': filepath}
asset.addParam(node_name, 'filename', pdict)


def set_metadata(asset, mat_dict):
meta = asset.stdMetadata()
meta['author'] = getpass.getuser()
meta['description'] = 'Created by RenderMan for Substance Painter 0.2.2'
meta['resolution'] = ' x '.join(mat_dict['resolution'].split(','))
for k, v in meta.iteritems():
asset.addMetadata(k, v)


def export():
"""Export a RenderManAsset package based on a json file.
"""
Expand All @@ -195,12 +223,16 @@ def export():
DBUG('OK: imported rmanAssets')

# constants
_bump = ['height', 'normal']
_bump = ('height', 'normal')
slotsFile = FilePath(os.path.dirname(os.path.realpath(__file__))).join('rules.json')
_rules = readJson(slotsFile)
rules = readJson(slotsFile)
DBUG('OK: rules read')

_bxdf = jsonDict['bxdf']
bxdf_rules = rules[_bxdf]
mappings = bxdf_rules['mapping']
graph = bxdf_rules.get('graph', None)
settings = bxdf_rules.get('settings', None)

# we save the assets to SP's export directory, because we know it is writable.
# We will move them to the requested location later.
Expand All @@ -213,12 +245,12 @@ def export():
for mat in matArray:
label = '%s_%s' % (scene, mat['textureSet'])
chans = mat['channels']
DBUG('+ Exporting %s' % label)
DBUG('+ Exporting %s', label)

assetPath = exportPath.join(label + '.rma')
DBUG(' + assetPath %s' % assetPath)
DBUG(' + assetPath %s', assetPath)
assetJsonPath = assetPath.join('asset.json')
DBUG(' + assetJsonPath %s' % assetJsonPath)
DBUG(' + assetJsonPath %s', assetJsonPath)

# create asset directory
if not assetPath.exists():
Expand All @@ -227,9 +259,9 @@ def export():
except (OSError, IOError):
XCPT('Asset directory could not be created !')
sys.exit(0)
DBUG(' + Created dir: %s' % assetPath)
DBUG(' + Created dir: %s', assetPath)
else:
DBUG(' + dir exists: %s' % assetPath)
DBUG(' + dir exists: %s', assetPath)

# create asset
try:
Expand All @@ -240,16 +272,14 @@ def export():

# create standard metadata
#
meta = asset.stdMetadata()
for k, v in meta.iteritems():
asset.addMetadata(k, v)
set_metadata(asset, mat)

# Compatibility data
# This will help other application decide if they can use this asset.
#
prmanVersion = str(rman_version)
asset.setCompatibility(hostName='Substance Painter',
hostVersion='2.4',
hostVersion=jsonDict['sp_version'],
rendererVersion=prmanVersion)
DBUG(' + compatibility set')

Expand All @@ -260,13 +290,16 @@ def export():
asset.addNode(rootNode, 'shadingEngine', 'root', 'shadingEngine')
pdict = {'type': 'reference float[]', 'value': None}
asset.addParam(rootNode, 'surfaceShader', pdict)
DBUG(' + Root node: %s' % rootNode)
DBUG(' + Root node: %s', rootNode)

# add a disney or pixar bxdf
#
bxdfNode = label + "_Srf"
asset.addNode(bxdfNode, _bxdf, 'bxdf', _bxdf)
DBUG(' + BxDF node: %s (%s)' % (rootNode, _bxdf))
DBUG(' + BxDF node: %s (%s)', (rootNode, _bxdf))

# The bxdf may need specific settings to match Substance Painter
set_params(settings, 'bxdf', bxdfNode, asset)

# connect surf to root node
#
Expand All @@ -275,9 +308,9 @@ def export():

# build additional nodes if need be.
#
if 'graph' in _rules[_bxdf]:
if graph:
DBUG(' + Create graph nodes...')
for nname, ndict in _rules[_bxdf]['graph']['nodes'].iteritems():
for nname, ndict in graph['nodes'].iteritems():
lname = label + nname
asset.addNode(lname, ndict['nodetype'],
'pattern', ndict['nodetype'])
Expand All @@ -293,38 +326,27 @@ def export():
chanNodes = {}
for chan, fpath in chans.iteritems():
nodeName = "%s_%s_tex" % (label, chan)
DBUG(' |_ %s' % nodeName)
chanNodes[chan] = nodeName
if chan not in _bump:
asset.addNode(nodeName, 'PxrTexture', 'pattern', 'PxrTexture')
pdict = {'type': 'string', 'value': fpath}
asset.addParam(nodeName, 'filename', pdict)
pdict = {'type': 'int', 'value': 1}
asset.addParam(nodeName, 'linearize', pdict)
add_texture_node(asset, nodeName, 'PxrTexture', fpath)
set_params(settings, chan, nodeName, asset)
else:
if chan == 'normal':
asset.addNode(nodeName, 'PxrNormalMap',
'pattern', 'PxrNormalMap')
pdict = {'type': 'string', 'value': fpath}
asset.addParam(nodeName, 'filename', pdict)
pdict = {'type': 'float', 'value': 1.0}
asset.addParam(nodeName, 'adjustAmount', pdict)
add_texture_node(asset, nodeName, 'PxrNormalMap', fpath)
elif chan == 'height':
asset.addNode(nodeName, 'PxrBump', 'pattern', 'PxrBump')
pdict = {'type': 'string', 'value': fpath}
asset.addParam(nodeName, 'filename', pdict)
pdict = {'type': 'float', 'value': 1.0}
asset.addParam(nodeName, 'adjustAmount', pdict)
add_texture_node(asset, nodeName, 'PxrBump', fpath)
else:
DBUG(' ! wow: %s' % chan)
DBUG(' |_ %s' % nodeName)
set_params(settings, chan, nodeName, asset)

# make direct connections
#
DBUG(' + Direct connections...')
for chan in chans:
src = None
dstType = _rules[_bxdf]['mapping'][chan]['type']
dstParam = _rules[_bxdf]['mapping'][chan]['param']
dstType = mappings[chan]['type']
dstParam = mappings[chan]['param']
if dstType == 'normal':
src = '%s.resultN' % (chanNodes[chan])
elif dstType == 'color':
Expand Down Expand Up @@ -352,10 +374,10 @@ def export():

# make graph connections
#
if 'graph' in _rules[_bxdf]:
if 'connections' in _rules[_bxdf]['graph']:
if graph:
if 'connections' in graph:
DBUG(' + Connect graph nodes...')
for con in _rules[_bxdf]['graph']['connections']:
for con in graph['connections']:

src_node = con['src']['node']
src_ch = None
Expand Down Expand Up @@ -441,13 +463,13 @@ def export():
else:
DBUG('Cleanup: %s' % fpath)

# if os.path.exists(jsonFile):
# try:
# os.remove(jsonFile)
# except (OSError, IOError):
# XCPT('Cleanup failed: %s' % jsonFile)
# else:
# DBUG('Cleanup: %s' % jsonFile)
if os.path.exists(jsonFile):
try:
os.remove(jsonFile)
except (OSError, IOError):
XCPT('Cleanup failed: %s' % jsonFile)
else:
DBUG('Cleanup: %s' % jsonFile)

INFO('RenderMan : Done !')

Expand Down
108 changes: 101 additions & 7 deletions RenderMan/rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,57 @@
"param": "emitColor",
"type": "color"
},
"height": {
"normal": {
"param": "bumpNormal",
"type": "normal"
}
},
"settings": {
"basecolor": {
"linearize": {
"type": "int",
"value": 1
}
},
"specular": {
"linearize": {
"type": "int",
"value": 1
}
},
"roughness": {
"linearize": {
"type": "int",
"value": 0
}
},
"metallic": {
"linearize": {
"type": "int",
"value": 0
}
},
"opacity": {
"linearize": {
"type": "int",
"value": 0
}
},
"emissive": {
"linearize": {
"type": "int",
"value": 1
}
},
"normal": {
"param": "bumpNormal",
"type": "normal"
"orientation": {
"type": "int",
"value": 1
},
"adjustAmount": {
"type": "float",
"value": 1.0
}
}
}
},
Expand Down Expand Up @@ -61,10 +105,6 @@
"param": "glowColor",
"type": "color"
},
"height": {
"param": "bumpNormal",
"type": "normal"
},
"normal": {
"param": "bumpNormal",
"type": "normal"
Expand Down Expand Up @@ -252,6 +292,60 @@
}
}
]
},
"settings": {
"bxdf": {
"specularModelType": {
"type": "int",
"value": 1
}
},
"basecolor": {
"linearize": {
"type": "int",
"value": 1
}
},
"specular": {
"linearize": {
"type": "int",
"value": 1
}
},
"roughness": {
"linearize": {
"type": "int",
"value": 0
}
},
"metallic": {
"linearize": {
"type": "int",
"value": 0
}
},
"opacity": {
"linearize": {
"type": "int",
"value": 0
}
},
"emissive": {
"linearize": {
"type": "int",
"value": 1
}
},
"normal": {
"orientation": {
"type": "int",
"value": 1
},
"adjustAmount": {
"type": "float",
"value": 1.0
}
}
}
}
}

0 comments on commit 6d0ba9e

Please sign in to comment.