/*/////////////////////////////////////////////////////////////////
jpMayaToMia
author:
Jon Parker
[email protected]
created May 4, 2008
usage:
jpMayaToMia(<shader>)
jpMayaToMia_selected()
return value:
jpMayaToMia -> mia_material
description:
converts a maya blinn, phong, phongE, lambert or anisotropic
material to a mia_material shader. This does some rough
guesswork on converting some of the parameters and is often
not 100% visually identical to the original in its result.
/////////////////////////////////////////////////////////////////*/
// returns nodes of type "type" in input list
proc string[] jpFilterNodeType(string $type, string $inputList[])
{
string $outputNodeList[];
for ($input in $inputList)
{
string $inputType = `nodeType $input`;
string $inputClass[] =`getClassification $inputType`;
// do this to a type node
if ($inputType == $type)
{
$outputNodeList[size($outputNodeList)] = $input;
}
// do this to non-shader object
else if ($inputType == "transform" || $inputType == "mesh" || $inputType == "nurbsSurface")
{
string $shapeList[] = `listRelatives -ad -pa -type "surfaceShape" $input`;
$shapeList = stringArrayRemoveDuplicates($shapeList);
for ($shape in $shapeList)
{
string $sg[] = `listConnections -type "shadingEngine" $shape`;
if (($sg[0] != "initialShadingGroup") && (size($sg)))
{
string $shadingNetwork[] = `listHistory -pdo 1 $sg[0]`;
if (size($shadingNetwork))
{
for ($outputNode in $shadingNetwork)
{
if (`nodeType $outputNode` == $type)
{
$outputNodeList[size($outputNodeList)] = $outputNode;
}
}
}
}
}
}
// ...or do this to a shader
else
{
string $shadingNetwork[] = `listHistory -pdo 1 $input`;
if (size($shadingNetwork))
{
for ($outputNode in $shadingNetwork)
{
if (`nodeType $outputNode` == $type)
{
$outputNodeList[size($outputNodeList)] = $outputNode;
}
}
}
}
}
$outputNodeList = stringArrayRemoveDuplicates($outputNodeList);
return $outputNodeList;
}
proc string createAndPrepareMia(string $shader)
{
string $mia = `shadingNode -asShader -n ($shader+"_mia") mia_material_x`;
setAttr ".brdf_0_degree_refl" 1;
setAttr ".skip_inside_refl" 0;
setAttr ".refr_ior" 1.0 ;
setAttr ".brdf_conserve_energy" off ;
warning ("createAndPrepareMia: "+$mia+": 'brdf conserve energy' is turned off for visual equality with the Maya shader. You should turn this back on for better physical accuracy.");
return $mia;
}
proc copyAttribute(string $src, string $dest)
{
string $srcSplit[];
tokenize $src "." $srcSplit;
string $srcNode = $srcSplit[0];
string $srcAttr = $srcSplit[1];
string $srcScalar[] = `listAttr -s $src`;
// print $srcScalar;
string $destSplit[];
tokenize $dest "." $destSplit;
string $destNode = $destSplit[0];
string $destAttr = $destSplit[1];
string $destScalar[] = `listAttr -s $dest`;
// print $destScalar;
if (`attributeQuery -n $srcNode -uac $srcAttr` && `connectionInfo -id $src`)
{
string $inputNode = `connectionInfo -sfd $src`;
connectAttr -f $inputNode $dest;
}
else
{
for ($i = 0; $i < size($srcScalar); $i++)
{
if (`connectionInfo -id ($srcNode+"."+$srcScalar[$i])`)
{
string $inputNode = `connectionInfo -sfd ($srcNode+"."+$srcScalar[$i])`;
connectAttr -f $inputNode ($destNode+"."+$destScalar[$i]);
}
else
{
float $srcValue = `getAttr ($srcNode+"."+$srcScalar[$i])`;
setAttr ($destNode+"."+$destScalar[$i]) $srcValue;
}
}
}
}
global proc copyCommonAttributesToMiaMaterial(string $shader, string $mia)
{
// color
copyAttribute(($shader+".color"), ($mia+".diffuse"));
// transparency
// only set it up if we have transparency
float $trans[] = `getAttr ($shader+".transparency")`;
if ((`connectionInfo -id ($shader+".transparency")`) || ($trans[0] || $trans[1] || $trans[2] !=0))
{
print $trans;
setAttr ($mia+".transparency") 1;
copyAttribute(($shader+".transparency"), ($mia+".refr_color"));
}
// ambient color
setAttr ($mia+".ao_on") true;
setAttr ($mia+".ao_samples") 0;
setAttr ($mia+".ao_distance") 0;
setAttr ($mia+".ao_do_details") 0;
setAttr ($mia+".ao_dark") -type double3 1 1 1;
copyAttribute(($shader+".ambientColor"), ($mia+".ao_ambient"));
// incandescence
copyAttribute(($shader+".incandescence"), ($mia+".additional_color"));
// bump mapping
if (`connectionInfo -id ($shader+".normalCamera")`)
{
string $srcBump = `connectionInfo -sfd ($shader+".normalCamera")`;
connectAttr -f $srcBump ($mia+".overall_bump");
}
// diffuse attr
copyAttribute(($shader+".diffuse"), ($mia+".diffuse_weight"));
// translucence
if (`getAttr ($shader+".translucence")` != 0)
{
setAttr ($mia+".refr_translucency") on;
copyAttribute(($shader+".color"), ($mia+".refr_trans_color"));
copyAttribute(($shader+".translucence"), ($mia+".refr_trans_weight"));
// multiply it by the transparency...
if (`getAttr ($mia+".transparency")` != 0)
{
// set translucency weight
string $rev = `shadingNode -asUtility -n ($mia+"_refr_trans_weight_rev") reverse`;
string $lum = `shadingNode -asUtility -n ($mia+"_refr_trans_weight_lum") luminance`;
copyAttribute(($mia+".refr_color"), ($rev+".input"));
connectAttr -f ($rev+".output") ($lum+".value");
connectAttr -f ($lum+".outValue") ($mia+".refr_trans_weight");
// set translucency color
string $mult = `shadingNode -asUtility -n ($mia+"_refr_color_mult") multiplyDivide`;
copyAttribute(($shader+".color"), ($mult+".input1"));
copyAttribute(($shader+".translucence"), ($mult+".input2X"));
copyAttribute(($shader+".translucence"), ($mult+".input2Y"));
copyAttribute(($shader+".translucence"), ($mult+".input2Z"));
connectAttr -f ($mult+".output") ($mia+".refr_trans_color");
// set transparency color
string $rgbIn = `shadingNode -asUtility -n ($mia+"_refr_color_rgbIn") rgbToHsv`;
string $setRange = `shadingNode -asUtility -n ($mia+"_refr_color_setRange") setRange`;
setAttr ".minZ" 1;
setAttr ".maxX" 1;
setAttr ".maxY" 1;
setAttr ".maxZ" 1;
setAttr ".oldMaxX" 1;
setAttr ".oldMaxY" 1;
setAttr ".oldMaxZ" 1;
string $rgbOut = `shadingNode -asUtility -n ($mia+"_refr_color_rgbOut") hsvToRgb`;
copyAttribute(($shader+".transparency"), ($rgbIn+".inRgb"));
connectAttr -f ($rgbIn+".outHsv") ($setRange+".value") ;
connectAttr -f ($setRange+".outValue") ($rgbOut+".inHsv") ;
connectAttr -f ($rgbOut+".outRgb") ($mia+".refr_color") ;
}
else
{
copyAttribute(($shader+".translucence"), ($mia+".transparency"));
setAttr ($mia+".refr_trans_weight") 1;
}
}
// raytracing
if (`getAttr ($shader+".refractions")` == 1)
{
copyAttribute(($shader+".refractiveIndex"), ($mia+".refr_ior"));
copyAttribute(($shader+".refractionLimit"), ($mia+".refr_depth"));
if (`getAttr ($shader+".lightAbsorbance")` != 0)
{
setAttr ($mia+".refr_falloff_on") true;
copyAttribute(($shader+".lightAbsorbance"), ($mia+".refr_falloff_dist"));
}
}
// mental ray
// irradiance
if (`connectionInfo -id ($shader+".miIrradianceColor")`)
{
string $input = `connectionInfo -sfd ($shader+".miIrradianceColor")`;
string $lumaNode = `shadingNode -asUtility luminance`;
connectAttr -f $input ($lumaNode+".value") ;
connectAttr -f ($lumaNode+".outValue") ($mia+".indirect_multiplier");
}
else
{
float $irrad[] = `getAttr ($shader+".miIrradianceColor")`;
float $indMult = ($irrad[0]+$irrad[1]+$irrad[2])/3;
setAttr ($mia+".indirect_multiplier") $indMult;
}
// refraction blur
if (`connectionInfo -id ($shader+".miRefractionBlur")`)
{
string $input = `connectionInfo -sfd ($shader+".miRefractionBlur")`;
string $mult = `shadingNode -asUtility -n ($mia+"_refr_gloss_mult") multiplyDivide`;
setAttr ".input2X" 0.1 ;
string $rev = `shadingNode -asUtility -n ($mia+"_refr_gloss_rev") reverse`;
connectAttr -f $input ($mult+".input1X");
connectAttr -f ($mult+".outputX") ($rev+".inputX") ;
connectAttr -f ($rev+".outputX") ($mia+".refr_gloss") ;
}
else
{
float $refrBlur = `getAttr ($shader+".miRefractionBlur")`;
if ($refrBlur != 0) setAttr ($mia+".refr_gloss") (1-($refrBlur*.1)) ;
}
}
proc copyLambertAttributesToMiaMaterial(string $shader, string $mia)
{
setAttr ($mia+".reflectivity") 0;
}
proc copyPhongAttributesToMiaMaterial(string $shader, string $mia)
{
if (`connectionInfo -id ($shader+".cosinePower")`)
{
string $input = `connectionInfo -sfd ($shader+".cosinePower")`;
string $clamp = `shadingNode -asUtility -n ($mia+"_refl_gloss_clamp") clamp`;
setAttr ".maxR" 100 ;
string $mult = `shadingNode -asUtility -n ($mia+"_refl_gloss_mult") multiplyDivide`;
setAttr ".input2X" 0.01 ;
connectAttr -f $input ($clamp+".inputR") ;
connectAttr -f ($clamp+".outputR") ($mult+".input1X") ;
connectAttr -f ($mult+".outputX") ($mia+".refl_gloss") ;
}
else
{
float $cosine = `getAttr ($shader+".cosinePower")`;
setAttr ($mia+".refl_gloss") (clamp(0, 100, $cosine)*.01);
}
copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ;
copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ;
copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ;
}
proc copyPhongEAttributesToMiaMaterial(string $shader, string $mia)
{
warning "copyPhongEAttributesToMiaMaterial: certain phongE material settings are weird and unsupported... set the reflection glossiness in the mia material to approximate phongE specular attributes.";
copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ;
copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ;
copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ;
}
proc copyBlinnAttributesToMiaMaterial(string $shader, string $mia)
{
// figure out that inverse eccentricity thing... it's roughly worked out...
if (`connectionInfo -id ($shader+".eccentricity")`)
{
string $input = `connectionInfo -sfd ($shader+".eccentricity")`;
string $gamma = `shadingNode -asUtility -n ($mia+"_refl_gloss_gamma") gammaCorrect`;
setAttr ".gammaX" 2.718 ;
string $rev = `shadingNode -asUtility -n ($mia+"_refl_gloss_rev") reverse`;
connectAttr -f $input ($gamma+".valueX") ;
connectAttr -f ($gamma+".outValueX") ($rev+".inputX") ;
connectAttr -f ($rev+".outputX") ($mia+".refl_gloss") ;
}
else
{
float $ecc = `getAttr ($shader+".eccentricity")`;
float $thinger = 1-((exp($ecc)-.5) * .5);
setAttr ($mia+".refl_gloss") (1-((exp($ecc)-.5) * .5)) ;
}
// let's put the specular roll-off into the forward-facing reflectivity of the mia...
copyAttribute(($shader+".specularRollOff"), ($mia+".brdf_0_degree_refl")) ;
// do the standard specular stuff
copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ;
copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ;
copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ;
}
proc copyAnisoAttributesToMiaMaterial(string $shader, string $mia)
{
setAttr ($mia+".anisotropy_channel") -2 ;
// get angle, see if it's mapped first
if (`connectionInfo -id ($shader+".angle")`)
{
string $mult = `shadingNode -asUtility -n ($mia+"_anisotropy_rotation_mult") multiplyDivide`;
setAttr ".operation" 2 ;
setAttr ".input1Y" 720 ;
copyAttribute(($shader+".angle"), ($mult+".input1X"));
connectAttr -f ($mult+".outputX") ($mia+".anisotropy_rotation") ;
}
else
{
float $rotation = `getAttr ($shader+".angle")` / 720 ;
setAttr ($mia+".anisotropy_rotation") $rotation ;
}
// divide the x and y aniso values to approximate the mia anisotropy
if (`connectionInfo -id ($shader+".spreadX")` || `connectionInfo -id ($shader+".spreadY")`)
{
string $div = `shadingNode -asUtility -n ($mia+"_anisotropy_div") multiplyDivide`;
setAttr ".operation" 2 ;
copyAttribute(($shader+".spreadY"), ($div+".input1X"));
copyAttribute(($shader+".spreadX"), ($div+".input1Y"));
connectAttr -f ($div+".outputX") ($mia+".anisotropy");
}
else
{
float $anisoValue = `getAttr ($shader+".spreadY")` / `getAttr ($shader+".spreadX")`;
setAttr ($mia+".anisotropy") $anisoValue ;
}
// finally roughness
if (`connectionInfo -id ($shader+".roughness")`)
{
string $inv = `shadingNode -asUtility -n ($mia+"_refl_gloss_inv") reverse`;
copyAttribute ($shader+".roughness") ($inv+".inputX") ;
connectAttr -f ($inv+".outputX") ($mia+".refl_gloss") ;
}
else
{
float $gloss = 1 - `getAttr ($shader+".roughness")` ;
setAttr ($mia+".refl_gloss") $gloss ;
}
// figure out what to do with the anisotropic reflection attribute
if (`getAttr ($shader+".anisotropicReflectivity")`)
warning ("copyAnisoAttributesToMiaMaterial: "+$shader+": anisotropic reflectivity settings ignored.");
copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ;
copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ;
copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ;
}
global proc string jpMayaToMia(string $shader)
{
string $mia = createAndPrepareMia($shader);
copyCommonAttributesToMiaMaterial($shader, $mia);
if (`nodeType $shader` == "lambert") copyLambertAttributesToMiaMaterial($shader, $mia);
if (`nodeType $shader` == "phong") copyPhongAttributesToMiaMaterial($shader, $mia);
if (`nodeType $shader` == "phongE") copyPhongEAttributesToMiaMaterial($shader, $mia);
if (`nodeType $shader` == "blinn") copyBlinnAttributesToMiaMaterial($shader, $mia);
if (`nodeType $shader` == "anisotropic") copyAnisoAttributesToMiaMaterial($shader, $mia);
return $mia;
}
global proc jpMayaToMia_selected()
{
string $selection[] = `ls -sl`;
string $shaderList[] ;
string $lambertList[] = jpFilterNodeType("lambert", $selection) ;
string $phongList[] = jpFilterNodeType("phong", $selection) ;
string $phongEList[] = jpFilterNodeType("phongE", $selection);
string $blinnList[] = jpFilterNodeType("blinn", $selection);
string $anisoList[] = jpFilterNodeType("anisotropic", $selection);
$shaderList = stringArrayCatenate($shaderList, $lambertList);
$shaderList = stringArrayCatenate($shaderList, $phongList);
$shaderList = stringArrayCatenate($shaderList, $phongEList);
$shaderList = stringArrayCatenate($shaderList, $blinnList);
$shaderList = stringArrayCatenate($shaderList, $anisoList);
// print $shaderList ;
for ($shader in $shaderList)
{
string $mia = jpMayaToMia($shader) ;
string $sgList[] = `listConnections -type "shadingEngine" $shader`;
for ($sg in $sgList)
{
string $miaSG[] = `duplicate -ic -n ($mia + "SG") $sg` ;
string $shader = `connectionInfo -sfd ($miaSG[0]+".surfaceShader")`;
disconnectAttr $shader ($miaSG[0]+".surfaceShader") ;
connectAttr -f ($mia+".message") ($miaSG[0]+".miMaterialShader") ;
connectAttr -f ($mia+".message") ($miaSG[0]+".miPhotonShader") ;
connectAttr -f ($mia+".message") ($miaSG[0]+".miShadowShader") ;
string $assignedObjectList[] = `sets -q $sg`;
sets -e -fe $miaSG[0] $assignedObjectList ;
}
}
}