------------------------------------------------------------------------------- -- TuneUpMaterial -- By Sergo Pogosyan (sergo.pogosyan@gmail.com) -- www.sergepogosyan.com -- v 1.0 -- Created: 2007-03-21 -- Last modifing: 2008-10-23 -- tested using Max 8.0, 2009 ------------------------------------------------------------------------------- -- Description: Change color, brightness, hue, saturation of the selected materials, -- multimaterials and add randomness to hsv. ------------------------------------------------------------------------------- -- Usage: Select material in material editor, start the script, apply color mods. ------------------------------------------------------------------------------- -- TO DO list: --add Apply button to fix changes and reset all sliders -DONE --random values must change when random slider changing, not when HSV slider changing, fix random seed -- add undo ability -- get materials from selected objects, make it like in blur's script material control -- work with materials selected by effectID and other properties -- work with raytrace, mentalray, vray, architectural, (mental ray arch for max9) materials. -- work with blend, shellac, composite materials -- add option to make the copy of material, especially when working with selected objects ------------------------------------------------------------------------------- -- history: --2008-10-02: separate random values added: value, hue, saturation. --2008-10-01: blend materials added macroScript TuneupMultiMaterial category:"Sergo Pogosyan" toolTip:"Modify compound material's color, saturation, hue, apply randomness" buttonText:"TuneUpMultimaterial" Icon:#("sergoIcons",14) /* on isEnabled return ( if selection.count == 1 and classof selection[1] == Editable_mesh and selection[1].modifiers.count == 0 then true else false ) on execute do ( */ ( global TuneUpMaterialFloater tuneMat = medit.getcurmtl() --get selected material oldColorArray = #() -- backup color array, used for reset button hsvColorArray = #() --copy of old (backup) colors to pass to functions. --all functions start with colors from this array, modify it and write them directly to "materialArray" --for immidiate result in Material Editor --only change color starts from the oldColorArray to apply different slider values. randomColorArray = #() materialArray = #() --materials to work with newHue = 0 newSaturation = 0 newValue = 0 newContrast = 0 newHueRandom = 0 newValueRandom = 0 newSaturationRandom = 0 average = 127 --value of lowest contrast supportedSoloMaterials = #("Standardmaterial","VRayMtl","RaytraceMaterial","Architectural","Arch___Design__mi") supportedMultiMaterials = #("Multimaterial","Blend") if (findItem supportedSoloMaterials (classof tuneMat as string) != 0 ) then --regular materials append materialArray tuneMat else if (classof tuneMat == Multimaterial) then --compound materials materialArray = tuneMat.materialList else if (classof tuneMat == Blend) then ( append materialArray tuneMat.map1 append materialArray tuneMat.map2 ) else print "use only standard or multimaterial materials" --create color array --populate array with color values from multimaterial --change color of material if it is enabled in multimaterial --fills oldColorArray with colors from materials of the multimaterial --works with standard, vray, mental ray material fn getColorsFromMat matArray = ( for i=1 to matArray.count do ( if(classof materialArray[i] == Standardmaterial) then ( oldDiffuseColor = materialArray[i].diffuse --get diffuse color of the sub-material append oldColorArray oldDiffuseColor --save current color for reset function append hsvColorArray oldDiffuseColor --save current color for hsv controls for the first time ) else if(classof materialArray[i] == VRayMtl) then ( oldDiffuseColor = materialArray[i].diffuse append oldColorArray oldDiffuseColor append hsvColorArray oldDiffuseColor ) else if(classof materialArray[i] == RaytraceMaterial) then ( oldDiffuseColor = materialArray[i].diffuse append oldColorArray oldDiffuseColor append hsvColorArray oldDiffuseColor ) else if(classof materialArray[i] == Architectural) then ( oldDiffuseColor = materialArray[i].diffuse append oldColorArray oldDiffuseColor append hsvColorArray oldDiffuseColor ) else if(classof materialArray[i] == Arch___Design__mi) then ( oldDiffuseColor = materialArray[i].diff_color append oldColorArray oldDiffuseColor append hsvColorArray oldDiffuseColor ) else ( messageBox "works only with Standard, Vray, Raytrace or Architectural materials" title:"macroscript" ) ) randomColorArray.count = matArray.count --set random values array count to material count ) getColorsFromMat materialArray fn getAverage colorArray = ( --find average contrast value local tempValue = 0 for i=1 to colorArray.count do ( tempValue = tempValue + colorArray[i].red tempValue = tempValue + colorArray[i].green tempValue = tempValue + colorArray[i].blue ) average = tempValue/(colorArray.count * 3) --endof find average contrast value ) getAverage hsvColorArray fn changeContrast colorArray = ( for i=1 to colorArray.count do ( newColor = copy colorArray[i] value = newColor.value sat = newColor.saturation red = newColor.red green = newColor.green blue = newColor.blue if newContrast < 0 then --all values must goes to average value of all colors ( if value < average then --raise it to averageValue value = value - (((average - value)/100.0) * newContrast ) else if value > average then --low to averageValue value = value + (((value - average)/100.0) * newContrast ) sat = sat + ((sat/100.0) * newContrast ) --saturation goes to 0 in all cases newColor.value = value newColor.saturation = sat ) else if newContrast > 0 then --all values goes to 0 or to 255, saturation to 255 ( --contrast raising for rgb if red > average then red = red + (((255-red)/100.0) * newContrast ) else if red < average then red = red - ((red/100.0) * newContrast ) if green > average then green = green + (((255-green )/100.0) * newContrast ) else if green < average then green = green - ((green /100.0) * newContrast ) if blue > average then blue = blue + (((255-blue)/100.0) * newContrast ) else if blue < average then blue = blue - ((blue/100.0) * newContrast ) --endof contrast raising for rgb if red < 0 then red = 0 else if red > 255.0 then red = 255 if green < 0 then green = 0 else if green > 255.0 then green = 255 if blue < 0 then blue = 0 else if blue > 255.0 then blue = 255 newColor.red = red newColor.green = green newColor.blue = blue ) materialArray[i].diffuse = newColor --set hsv + contrast modified color to the material color ) ) --change color value hue and saturation and in the end call contrast method --random values are added in this function too. fn changeColor val = ( for i=1 to materialArray.count do ( newColor = copy oldColorArray[i] --format "pre rnd and pre editcolor % % %\n" newColor.hue newColor.saturation newColor.value --hue saturation value if newSaturation < 0 then newColor.saturation = newColor.saturation + ((newColor.saturation/100.0) * newSaturation) else if newSaturation > 0 then newColor.saturation = newColor.saturation + (((255.0 - newColor.saturation)/100.0) * newSaturation) tempHue = newColor.hue + ((127.5/180.0) * newHue) --hue looping if tempHue > 255 then tempHue = tempHue - 255 if tempHue < 0 then tempHue = 255 + tempHue newColor.hue = tempHue --endof hue looping -- format "\ncolor value color in % \n" newColor.value if newValue < 0 then ( newColor.value = newColor.value + ((newColor.value/100.0) * newValue) if newColor.value < 0 then newColor.value = 0 ) else if newValue > 0 then ( tempval2 = newColor.value + (((255.0-newColor.value)/100) * newValue) newColor.value = tempval2 --though tempval2 == 255 after such assigning newColor.value becomes 0.0! -- format "color temp value color out2 % \n" tempval2 -- format "color value color out2 % \n" newColor.value if tempval2 >= 255.0 then --silly walkaround about the silly problem newColor.value = 255 ) --format "pre rnd colors % % %\n" newColor.hue newColor.saturation newColor.value if (randomColorArray[i] != undefined) then ( if (newColor.saturation != 0) then newColor.hue = newColor.hue + randomColorArray[i][1] if (newColor.hue != 0) then newColor.saturation = newColor.saturation + randomColorArray[i][2] newColor.value = newColor.value + randomColorArray[i][3] ) --format "post rnd colors % % %\n\n" newColor.hue newColor.saturation newColor.value hsvColorArray[i] = newColor --save hsv-modified color to the intermidiary array ) changeContrast hsvColorArray --call contrast ) fn randomValues val = ( --this function will be called only when random sliders are changing so changeColor function will not change random values. --try to calculate random values for every color in array --then apply these values in change color function for i=1 to materialArray.count do ( newColor = copy oldColorArray[i] --newColor = newColor as point3 tempArray = (point3 0 0 0) tempArray[1] = newColor.hue if (tempArray[2] == 255) then tempArray[2] = 0.0 tempArray[2] = newColor.saturation tempArray[3] = newColor.value newColor = tempArray --format "colors in rnd function %\n" newColor hueRndRatio = random (-newColor[1]) (255.0-newColor[1]) newColor[1] = (hueRndRatio/100.0)*newHueRandom saturationRndRatio = random (-newColor[2]) (255.0-newColor[2]) newColor[2] = (saturationRndRatio/100.0)*newSaturationRandom valueRndRatio = random (-newColor[3]) (255.0-newColor[3]) newColor[3] = (valueRndRatio/100.0)*newValueRandom randomColorArray[i] = newColor --save random value for every material in array --format "rndColors % % %\n" newColor[1] newColor[2] newColor[3] --format "random sliders % % %\n" newHueRandom newSaturationRandom newValueRandom --format "pre rnd colors % % %\n" hsvColorArray[i].hue hsvColorArray[i].saturation hsvColorArray[i].value ) changeColor val ) rollout TuneUpRollout "Tune Up" ( group "Controls" ( spinner hueSpinner type:#integer fieldWidth:50 align:#right range:[-180,180,0] slider hueSlider "Hue" type:#integer orient:#horizontal ticks:64 range:[-180,180,0] across:1 offset:[0,-20] spinner saturationSpinner type:#integer fieldWidth:50 align:#right range:[-100,100,0] slider saturationSlider "Saturation" type:#integer orient:#horizontal ticks:64 range:[-100,100,0] offset:[0,-20] spinner valueSpinner type:#integer fieldWidth:50 align:#right range:[-100,100,0] slider valueSlider "Value" type:#integer orient:#horizontal ticks:64 range:[-100,100,0]offset:[0,-20] spinner contrastSpinner type:#integer fieldWidth:50 align:#right range:[-100,100,0] slider contrastSlider "Contrast" type:#integer orient:#horizontal ticks:64 range:[-100,100,0]offset:[0,-20] spinner randomHueSpinner type:#integer fieldWidth:50 align:#right range:[0,100,0] slider randomHueSlider "Random Hue" type:#integer orient:#horizontal ticks:64 range:[0,100,0]offset:[0,-20] spinner randomValueSpinner type:#integer fieldWidth:50 align:#right range:[0,100,0] slider randomValueSlider "Random Value" type:#integer orient:#horizontal ticks:64 range:[0,100,0]offset:[0,-20] spinner randomSaturationSpinner type:#integer fieldWidth:50 align:#right range:[0,100,0] slider randomSaturationSlider "Random Saturation" type:#integer orient:#horizontal ticks:64 range:[0,100,0]offset:[0,-20] button resetButton "Reset" toolTip:"Reset to original color" button applyButton "Apply" toolTip:"Apply changes and reset sliders" ) on hueSpinner changed val do ( newHue = hueSlider.value = val changeColor val ) on hueSlider changed val do ( newHue = hueSpinner.value = val changeColor val ) on saturationSpinner changed val do ( newSaturation = saturationSlider.value = val changeColor val ) on saturationSlider changed val do ( newSaturation = saturationSpinner.value = val changeColor val ) on valueSpinner changed val do ( newValue = valueSlider.value = val changeColor val ) on valueSlider changed val do ( newValue = valueSpinner.value = val changeColor val ) on contrastSpinner changed val do ( newContrast = contrastSlider.value = val changeContrast hsvColorArray ) on contrastSlider changed val do ( newContrast = contrastSpinner.value = val changeContrast hsvColorArray ) on randomHueSpinner changed val do ( newHueRandom = randomHueSlider.value = val randomValues val ) on randomHueSlider changed val do ( newHueRandom = randomHueSpinner.value = val randomValues val ) on randomValueSpinner changed val do ( newValueRandom = randomValueSlider.value = val randomValues val ) on randomValueSlider changed val do ( newValueRandom = randomValueSpinner.value = val randomValues val ) on randomSaturationSpinner changed val do ( newSaturationRandom = randomSaturationSlider.value = val randomValues val ) on randomSaturationSlider changed val do ( newSaturationRandom = randomSaturationSpinner.value = val randomValues val ) on TuneUpRollout open do ( -- newHue = hueSlider.value = hueSpinner.value = matHue -- newSaturation = saturationSlider.value = saturationSpinner.value = matSaturation -- newValue = valueSlider.value = valueSpinner.value = matValue ) on resetButton pressed do ( newHue = hueSpinner.value = hueSlider.value = 0 newSaturation = saturationSpinner.value = saturationSlider.value = 0 newValue = valueSpinner.value = valueSlider.value = 0 newContrast = contrastSpinner.value = contrastSlider.value = 0 newHueRandom = randomHueSpinner.value = randomHueSlider.value = 0 newValueRandom = randomValueSpinner.value = randomValueSlider.value = 0 newSaturationRandom = randomSaturationSpinner.value = randomSaturationSlider.value = 0 for i=1 to materialArray.count do ( materialArray[i].diffuse = oldColorArray[i] hsvColorArray[i] = oldColorArray[i] randomColorArray = #() ) ) on applyButton pressed do ( newHue = hueSpinner.value = hueSlider.value = 0 newSaturation = saturationSpinner.value = saturationSlider.value = 0 newValue = valueSpinner.value = valueSlider.value = 0 newContrast = contrastSpinner.value = contrastSlider.value = 0 newHueRandom = randomHueSpinner.value = randomHueSlider.value = 0 newValueRandom = randomValueSpinner.value = randomValueSlider.value = 0 newSaturationRandom = randomSaturationSpinner.value = randomSaturationSlider.value = 0 for i=1 to materialArray.count do ( oldColorArray[i] = materialArray[i].diffuse hsvColorArray[i] = oldColorArray[i] randomColorArray = #() ) ) ) rollout aboutRoll "About" ( label lb_about "Tune Up Material 1.0" label lb_author "Sergo Pogosyan" hyperLink lb_email "sergo.pogosyan@gmail.com" address:"mailto:sergo.pogosyan@gmail.com" align:#center hyperLink lb_www "www.sergepogosyan.com" address:"http://www.sergepogosyan.com" align:#center label lb_year "2008" ) try(CloseRolloutFloater TuneUpMaterialFloater)catch() TuneUpMaterialFloater = newRolloutFloater "Tune Up Material" 250 530 addRollout TuneUpRollout TuneUpMaterialFloater addRollout aboutRoll TuneUpMaterialFloater aboutRoll.open = false )