PDA

View Full Version : Duplicating a shader and connecting all attributes


Toxicfrog
03-27-2009, 09:11 PM
im trying to do a small script to save me some annoying work, but i am not very experienced in scripting, only some javascript :P

maybe someone can help?

im trying to duplicate a shader and connect all its attributes to the duplicate so i can control all the duplicates from by editing the original.

$nodeToCopy = `ls -sl`;
$attrList = `listAttr $nodeToCopy`;
$copiedNode = `duplicate $nodeToCopy`;
for ($Attr in $attrList){
connectAttr ($nodeToCopy + "." + $Attr) ($copiedNode + "." + $Attr);
}

:banghead: doesnt work, i dont get the syntax right i think...

DOor
03-27-2009, 10:45 PM
$nodeToCopy = `ls -sl`;
$attrList = `listAttr $nodeToCopy`;
$copiedNode = `duplicate $nodeToCopy`;
for ($Attr in $attrList){
connectAttr ($nodeToCopy + "." + $Attr) ($copiedNode + "." + $Attr);
}


I think you should try looking at the -upstreamNodes and -inputConnections flag for the duplicate command. if that does not give you the results you are looking for I see a couple things wrong with your code.

first, your variables are not declared as arrays-- try writing them like this: (not the index brackets [] that signify the array)

string $copiedNode[] = `duplicate $nodeToCopy`; //note when you do this you will get both a shape node and a transform node.


second, the listAttr command will give you a TON of results (very much slowing down your script) that have no connections in your shading network. I suggest looking at the listConnections and connectionInfo commands instead.


hope this helps get you on track.

scarface1
03-27-2009, 11:00 PM
maybe you want to assign the same shader to a bunch of geos but have them different in
some attr like coller or whatever,if its what you want try single,double and triple switch node
which allows you to have only one shader but with different colors on each geo.i think i wrote a script to automate that,do you want it?

Toxicfrog
03-27-2009, 11:33 PM
huh its a little bit complicated...

I think you should try looking at the -upstreamNodes and -inputConnections flag for the duplicate command. if that does not give you the results you are looking for I see a couple things wrong with your code.

these flags are useful when duplicating geometry i think, i tried it with a shader it doesnt work.
hmm, ok i try with arrays... (but why do i need arrays

i want to assign a shader with only one difference: the displacement direction.
i modelled a bottle with som displacement for some "ornamental features" on the outside. the walls of the bottle are thick so, for refractions to look correct the normals must point outward.
now the displacementshader is a projection for some reasons i'm to lazy to explain right now...
anyway, a projection goes, different from uvmaps, through the whole geometry, so i have displacement on the inside of the bottle. thats cool. but it goes the wrong direction.
it blows up in both directions. so i assigned two shaders, one for the outside of the bottle with positive displacement and one for the inside.that works.
now im in the process of tuning the shader and im getting tired of doing all the changes twice.

now that i think about it. yes i could just tune the shader and then copy and make the connections to the displacement. but i think it can't be that difficult to write something like that ? it would be nice though...

for now, thanks for the replys, you folks are great:applause:

Toxicfrog
03-29-2009, 01:14 PM
I managed to get it to work somehow:

string $selected[] = `ls -sl`;
$copy = `duplicate ($selected[0])`;
string $Attr[] = (`listAttr -v -c -r -w -k $copy[0]`);
for ($s in $Attr){
connectAttr ($selected[0] + "." + $s +"\n") ($copy[0] + "." + $s +"\n");
}

for now it seems to do what i want, maybe someone with more experience has some comments if this is bad in any way?


thank you again DOor for pointing me on the array thing.

EightBit
04-02-2009, 06:11 AM
maybe you want to assign the same shader to a bunch of geos but have them different in
some attr like coller or whatever,if its what you want try single,double and triple switch node
which allows you to have only one shader but with different colors on each geo.i think i wrote a script to automate that,do you want it?
Hey scarface1, I'd appreciate if you could share that script, or just explain how you would use the switch node to apply the same shader with different image maps to various objects.
Thanks a lot.

scarface1
04-02-2009, 10:51 AM
you just have to create a tripleShadingSwitch node and connect its output to input color of your shader.then select the tripleShadingSwitch node and in the attribute edittor click add surface button.then you create your texture node like various file textures and then connect the out color of each texture to tripleShadingSwitch.input[i].inTriple with mell command or connection editor.
(i.e. connectAttr file1.outColor tripleShadingSwitch.input[i].inTriple puts file1 on i'th surface)
the script is just for single attrs that means you should use it three times to handle color and it connects a single value in a shader to y position of a curves cv for each surface.
and is made for animatin purpose.and its nothing special but maybe handy.
if (`window -exists shaderSwitcherUI`)
{
deleteUI shaderSwitcherUI;
}
window -t "shader Switcher" shaderSwitcherUI;
columnLayout
-adj 1
mainCol;
textFieldButtonGrp -label "controlled node" -text ""
-buttonLabel "insert" -buttonCommand "insertNode"
-changeCommand insertAttrs
nodeNameTFGRP;
textScrollList -allowMultiSelection true
-showIndexedItem 4
-w 30
-h 250
attributesSCL;



button -l " insert mesh" -c insertMeshes;
textScrollList -allowMultiSelection true
-showIndexedItem 4
-w 30
-h 250
meshesTSL;



button -l " DO IT"
-c "shaderSwitcher" shaderSwitcher;
showWindow shaderSwitcherUI;



global proc insertNode()
{
string $node[]=`ls -sl`;
textFieldButtonGrp -e -text $node [0] nodeNameTFGRP;
insertAttrs;
}
global proc insertAttrs()
{
string $node=`textFieldButtonGrp -q -text nodeNameTFGRP`;
string $attrs[]=`listAttr -c -r -s $node`;
textScrollList -e -removeAll attributesSCL;
for ($each in $attrs)
{
textScrollList -e -append $each attributesSCL;
}
}

global proc insertMeshes()
{
string $node[]=`ls -sl `;
string $shapes[]=`listRelatives $node`;
textScrollList -e -removeAll meshesTSL;

for ($each in $shapes)
{
if (`nodeType $each`=="mesh"||`nodeType $each`=="nurbsSurface")
textScrollList -e -append $each meshesTSL;


}
}
global proc shaderSwitcher()
{
string $attrs[]=`textScrollList -q -selectItem attributesSCL`;
string $nodeName=`textFieldButtonGrp -q -text nodeNameTFGRP`;
string $switchNode=`createNode singleShadingSwitch`;
for ($each in $attrs)
{
connectAttr -f ($switchNode+".output") ($nodeName+"."+$each);
}
string $meshes[]=`textScrollList -q -allItems meshesTSL`;
int $i=0;
for ($each in $meshes)
{
connectAttr ($each+".instObjGroups[0]")
($switchNode+".input["+$i+"].inShape");
$i++;
}
int $numControls=`size $meshes`;
string $myCurve=`curve -d 1 -p -5 0 0 -p 5 0 0`;
rebuildCurve -ch 1 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1
-kt 0 -s $numControls -d 1 -tol 0.01 $myCurve;
string $myCurveShape[]=`listRelatives -s $myCurve`;
string $indexNode[]=`spaceLocator `;
for ($i=0;$i<$numControls;$i++)
{

string $pointOnCurveInfo=`createNode pointOnCurveInfo`;
connectAttr -f ($myCurveShape[0]+".local") ($pointOnCurveInfo+".inputCurve");
setAttr ($pointOnCurveInfo+".turnOnPercentage") 1;
float $parameter=$i;
setAttr ($pointOnCurveInfo+".parameter") ($parameter/($numControls-1));
addAttr -k 1 -ln ($meshes[$i]+"parameter")
-at double -dv 0 $indexNode[0];
connectAttr -f ($indexNode[0]+"."+$meshes[$i]+"parameter")
($switchNode+".input["+$i+"].inSingle") ;
connectAttr -f ($pointOnCurveInfo+".positionY")
($indexNode[0]+"."+$meshes[$i]+"parameter") ;
}
}

EightBit
04-02-2009, 05:00 PM
Thanks a lot. I'll check it out.

EightBit
04-02-2009, 11:10 PM
Can you tell me how to use the script?

What should I select as a "Controlled Node" and what as "Insert Mesh" (I assume any mesh?).

I don't know if this is possible, but here's what I'm trying to do (see pic):
I have several pieces of paper - each 2 sided geometry. In order to get the 2 sided geometry, I'm connecting output of a samplerInfo.flippedNormal to condition.secondTerm. So if I had 5 pieces of paper, I'd have up to 10 textures (some pages are blank). Can I setup the all the texture nodes and then pipe them all thru the same condition node?

Thanks a lot.

scarface1
04-03-2009, 11:58 AM
I don't know if this is possible, but here's what I'm trying to do (see pic):
I have several pieces of paper - each 2 sided geometry. In order to get the 2 sided geometry, I'm connecting output of a samplerInfo.flippedNormal to condition.secondTerm. So if I had 5 pieces of paper, I'd have up to 10 textures (some pages are blank). Can I setup the all the texture nodes and then pipe them all thru the same condition node?
yes you can use one conditionnode.this pdf can say how Document.pdf (http://forums.cgsociety.org/attachment.php?attachmentid=140657&stc=1)
and about the script ,it doesnt assign different textures,just different animateable colors
but if you think you want it , you're lucky cuz when i sent this script to a friend,i sent him a guide file.
casey.zip (http://forums.cgsociety.org/attachment.php?attachmentid=140658&stc=1)

EightBit
04-06-2009, 10:36 PM
Thanks a lot for putting that together - works great! Very generous of you to take the time to explain.

For anyone interested, here is some code:
// =========== TRIPLE SHADER ================
// === Given 2 pieces of paper - page01 and page02, make them each display as 2 sided: ===
// ==============================================================================

// Create pageMain shader thru which all the page materials will pass
// This will control all shading attr of pages except color/texture map:
shadingNode -asShader phong - n "mainPage_phong";
sets -renderable true -noSurfaceShader true -empty -name phong1SG;
connectAttr -f mainPage_phong.outColor phong1SG.surfaceShader;

// Connect the main shader to the geometry:
defaultNavigation -source mainPage_phong -destination |page01|page01Shape.instObjGroups[0] -connectToExisting;
defaultNavigation -source mainPage_phong -destination |page02|page02Shape.instObjGroups[0] -connectToExisting;

// Create Condition Node, set to "not Equal", & connect Condition to mainPage shader:
shadingNode -asUtility condition -n "pageSide_cnd";
setAttr pageSide_cnd.operation 1;
connectAttr -f pageSide_cnd.outColor mainPage_phong.incandescence;

// Create samplerInfo node and connect flippedNormal to second term of condition:
shadingNode -asUtility samplerInfo -n "pageNormal_sampler";
connectAttr -force pageNormal_sampler.flippedNormal pageSide_cnd.secondTerm;

// Create 2 triple shading switches. One for front side of pages, one for backs.
shadingNode -asUtility tripleShadingSwitch -n "pageFront_trplSwtch";
shadingNode -asUtility tripleShadingSwitch -n "pageBack_trplSwtch";
connectAttr -force pageFront_trplSwtch.output pageSide_cnd.colorIfTrue;
connectAttr -force pageBack_trplSwtch.output pageSide_cnd.colorIfFalse;

// Create 4 Blinn Matls which will contain colors/maps for pages
// This will only be mapped to incandescence, all other materials attr will come
// pageMain shader - THEY ARE NOT CONNECTED TO OUTPUT SG
shadingNode -asShader blinn -n "page01Front";
setAttr "page01Front.color" -type double3 0.5 0.055 0.0579667 ;

shadingNode -asShader blinn -n "page01Back";
setAttr "page01Back.color" -type double3 0.5 0.5 0.05;

shadingNode -asShader blinn -n "page02Front";
setAttr "page02Front.color" -type double3 0.05 0.5 0.05 ;

shadingNode -asShader blinn -n "page02Back";
setAttr "page02Back.color" -type double3 0.5 0.05 0.55;

// Connect the corresponding page shapes and surfaces to the tripleShading switches
// Page01 Front:
connectAttr page01Shape.instObjGroups[0] pageFront_trplSwtch.input[0].inShape;
connectAttr -f page01Front.color pageFront_trplSwtch.input[0].inTriple;

// Page01 Back:
connectAttr page01Shape.instObjGroups[0] pageBack_trplSwtch.input[0].inShape;
connectAttr -f page01Back.color pageBack_trplSwtch.input[0].inTriple;

// page02 Front:
connectAttr page02Shape.instObjGroups[0] pageFront_trplSwtch.input[1].inShape;
connectAttr -f page02Front.color pageFront_trplSwtch.input[1].inTriple;

// page02 Back:
connectAttr page02Shape.instObjGroups[0] pageBack_trplSwtch.input[1].inShape;
connectAttr -f page02Back.color pageBack_trplSwtch.input[1].inTriple;

I did run into one strange behavior. After setting this up, if I delete the materials which have been connected to the triple shaders:delete page01Front page01Back page02Back page02Front ; the geometry continues to render as 2 sides, using the colors I assigned - but where are those colors coming from?
Thanks again.

CGTalk Moderation
04-06-2009, 10:36 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.