Files
2025-09-29 00:52:08 +02:00

1836 lines
55 KiB
Plaintext
Executable File

-- Vertex Colour Toolkit --
try (destroyDialog RsVertClrToolRoll) catch ()
callbacks.removeScripts id:#RsVertClrTool
RSTA_LoadCommonFunction #("fn_RSTA_vertexColours.ms")
filein (::RsConfigGetWildwestDir() + "Script/3dsMax/Maps/Materials/vertexColour_blender.ms")
---------------------------------------------------------------------------------------------------------------
--ROLLOUT DEFINITIONS
---------------------------------------------------------------------------------------------------------------
-- Controls common to all tabs:
rollout RsVertClrToolCommonRoll ""
(
local keepOpenState = true
-- Used to keep edit-rollout's colour-selection on changing tab:
local rememberClr = blue
dropDownList lstChans "Use Channel:" align:#left width:305 pos:[13,4]
local btnWidth = 80
local btnHeight = 18
button btnShowChan "Show Channel" align:#right tooltip:"Show this vertex channel on selected objects" width:btnWidth height:btnHeight offset:[0,-4]
button btnShowOff "Show Off" align:#right tooltip:"Don't show vertex channel on selected objects" width:btnWidth height:btnHeight offset:[0,-3]
button btnShowVertPaint "VertexPaint" align:#right tooltip:"Show VertexPaint modifier for selected channel" width:btnWidth height:btnHeight offset:[0,-3]
groupbox displayShadedGrp "Current Display Mode:" width:213 height:55 pos:(lstChans.pos + [0,22])
radioButtons rdoShaded "" labels:#("Material Colour (Textures)", "Object Colour (Colours)") align:#left offset:[5,-43] columns:1
fn getChan =
(
return (lstChans.selection - 3)
)
fn getShowClr =
(
local showClr = copy rememberClr
if (getChan() < 0) then
(
local greyVal = (showClr.r + showClr.g + showClr.b) / 3.0
showClr = color greyVal greyVal greyVal
)
return greyVal
)
-- Set colour-set control's colour, if rollout is shown:
fn SetClrCtrl =
(
if (::RsVertClrToolEditRoll.Open) do
(
RsVertClrToolEditRoll.ShowClr()
)
)
fn SetupChanList namedChannels:#() =
(
local namedVertChans = RsNamedMeshVertChannels + namedChannels
local namedChanIds = for item in namedVertChans collect item.id
local newItems = for n = -2 to (aMax namedChanIds) collect ((n as string) + ": ")
local knownChans = #{}
knownChans.count = newItems.count
for item in namedVertChans do
(
local chanIdx = item.id + 3
newItems[chanIdx] += item.name
knownChans[chanIdx] = true
)
for chanIdx = -knownChans do
(
newItems[chanIdx] += "[unused channel]"
)
lstChans.items = newItems
)
-- Update 'Display Shaded' radiobuttons to match current viewport-setting:
fn ShowDisplayShaded =
(
rdoShaded.state = case displayColor.shaded of
(
#material:1
#object:2
)
)
-- Set list/radiobutton selections to match requested values:
fn SetChanControls chan: chanName: shaded: =
(
local isValidChan = True
if (chan == unsupplied) then
(
-- Get channel-index from list:
chan = getChan()
)
else
(
-- We'll choose this list-item:
local newSel = (chan + 3)
isValidChan = (newSel > 0)
if isValidChan do
(
-- Make sure we have enough list-items
if (newSel > lstChans.items.count) do
(
local newItems = lstChans.items
for n = (lstChans.items.count + 1) to newSel do
(
append newItems (((n - 3) as string) + ": [unused channel]")
)
lstChans.items = newItems
)
-- Select requested item:
lstChans.selection = newSel
)
)
-- Rename selected list-item:
if isValidChan and (chanName != unsupplied) do
(
local selChanStr = (lstChans.selection - 3) as String
local items = lstChans.items
items[lstChans.selection] = (selChanStr + ": " + chanName)
lstChans.items = items
)
-- Update 'Display Shaded' radiobuttons:
ShowDisplayShaded()
return OK
)
fn ShowChannel chan: chanName: shaded: =
(
-- Get channel-index from list:
if (chan == unsupplied) do
(
chan = GetChan()
)
RsShowObjVertChannel chan updateListSel:False
SetChanControls chan:chan chanName:chanName
)
on LstChans selected val do
(
setClrCtrl()
)
on BtnShowChan pressed do
(
ShowChannel()
)
on btnShowOff pressed do
(
ShowChannel chan:-3
)
on btnShowVertPaint pressed do
(
local chan = (GetChan())
local chanName = ("Chan" + lstChans.selected)
RsShowVertPaintMod chan chanName:chanName
)
-- Auto-selects the channel shown on selected object(s)
fn ShowCurrentObjChannel =
(
local showChanObjs = for obj in selection where obj.showVertexColors collect obj
local chanIdxs = for obj in showChanObjs collect
(
case obj.vertexColorType of
(
#alpha:(1)
#illum:(2)
#color:(3)
#map_channel:(obj.vertexColorMapChannel + 3)
Default:DontCollect
)
)
chanIdxs = makeUniqueArray chanIdxs
if (chanIdxs.count == 1) do
(
lstChans.selection = chanIdxs[1]
setClrCtrl()
)
)
fn showShaded state =
(
displayColor.shaded = case state of
(
1:#material
2:#object
)
-- Trigger vertex-colours update:
objects.showVertexColors = False
if (displayColor.shaded == #object) do
(
objects.showVertexColors = True
)
return OK
)
on rdoShaded changed state do
(
showShaded state
)
on RsVertClrToolCommonRoll open do
(
chanIds = for item in RsNamedMeshVertChannels collect item.id
setupChanList()
-- Set selection to default channel:
lstChans.selection = 3
ShowDisplayShaded()
ShowCurrentObjChannel()
callbacks.addScript #viewportChange "RsVertClrToolCommonRoll.ShowDisplayShaded()" id:#RsVertClrTool
)
on RsVertClrToolCommonRoll close do
(
callbacks.removeScripts id:#RsVertClrTool
)
on RsVertClrToolCommonRoll rolledUp down do
(
if (keepOpenState != Down) do (RsVertClrToolCommonRoll.open = keepOpenState)
)
)
rollout RsVertClrWorkChannels "Split into Work Channels"
(
button btnToWorkChans "Split RGB" width:120 height:20 across:2 \
tooltip:"Copies each of the selected channel's colours into channel 20, 21 and 22"
button btnFromWorkChans "Combine RGB" width:120 height:20 \
tooltip:"Overwrites this channel by combining channel 20, 21 and 22 getting Red, Green and Blue from them respectively"
label showRGB "Show:" align:#left pos:(btnToWorkChans.pos + [3,24]) across:4
button BtnShowRed "Red" align:#left width:20 height:20 pos:(showRGB.pos + [33,-3]) \
images:#((bitmap 16 16 color:(Red*0.8+ white*0.2)), undefined, 1, 1, 1, 1, 1, false) \
tooltip:"Show the Red channel created by Split RGB (Channel 20)"
button BtnShowGreen "Green" align:#left width:20 height:20 pos:(showRGB.pos + [53,-3]) \
images:#((bitmap 16 16 color:(Green*0.8+ white*0.2)), undefined, 1, 1, 1, 1, 1, false) \
tooltip:"Show the Green channel created by Split RGB (Channel 21)"
button BtnShowBlue "Blue" align:#left width:20 height:20 pos:(showRGB.pos + [73,-3]) \
images:#((bitmap 16 16 color:(Blue*0.8 + white*0.2)), undefined, 1, 1, 1, 1, 1, false) \
tooltip:"Show the Blue channel created by Split RGB (Channel 22)"
-- 'Split/Combine RGB' use these working-channels:
local workChanItems =
#(
(dataPair id:20 name:"Working Channel: Red"), \
(dataPair id:21 name:"Working Channel: Green"), \
(dataPair id:22 name:"Working Channel: Blue")
)
local workChans = for chan in workChanItems collect chan.id
on btnToWorkChans pressed do
(
-- Rename list-items:
RsVertClrToolCommonRoll.setupChanList namedChannels:workChanItems
local chan = RsVertClrToolCommonRoll.getChan()
RsSplitVertRgbToChannels (GetCurrentSelection()) chan rgbChans:workChans
)
on btnFromWorkChans pressed do
(
local chan = RsVertClrToolCommonRoll.getChan()
RsCombineVertRgbChannels (GetCurrentSelection()) chan rgbChans:workChans
)
on BtnShowRed pressed do
(
local chanItem = workChanItems[1]
RsVertClrToolCommonRoll.showChannel chan:chanItem.id chanName:chanItem.name
)
on BtnShowGreen pressed do
(
local chanItem = workChanItems[2]
RsVertClrToolCommonRoll.showChannel chan:chanItem.id chanName:chanItem.name
)
on BtnShowBlue pressed do
(
local chanItem = workChanItems[3]
RsVertClrToolCommonRoll.showChannel chan:chanItem.id chanName:chanItem.name
)
)
rollout RsVertClrToolsRoll "Tools"
(
local btnWidth = 160
local btnHeight = 22
button btnChanClearer "Vertex Channel Clearer" width:btnWidth height:btnHeight offset:[0,-3]
button btnVertexPaintMgr "VertexPaint Manager" width:btnWidth height:btnHeight offset:[-1,-3]
-- button btnInitChannels "Activate Missing Channels" width:btnWidth height:btnHeight offset:[-1,-3] \
-- tooltip:"Find and activate channels on selected objects that are required by used materials"
on btnChanClearer pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/uvChannelClearer.ms")
)
on btnVertexPaintMgr pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/VertexPaintMgr.ms")
)
fn ArrayToString arr =
(
local outStr = (StringStream "")
for n = 1 to arr.count do
(
Format "%" (arr[n] as string) to:outStr
if (n != arr.count) do
(
Format ", " to:outStr
)
)
return (outStr as String)
)
on btnInitChannels pressed do
(
-- Collect channels required by each object's materials, and which channels are currently active:
struct sObjChans (obj, requiredChans, missingChans)
local chansPerObj = #()
for obj in (GetCurrentSelection()) do
(
-- Get channels used by materials applied to object:
local requiredChans = #()
local objMats = (RsGetMaterialsOnObjFaces obj)
for thisMat in objMats where (IsKindOf thisMat Rage_Shader) do
(
local matChans = (RstGetMaterialMapChannels thisMat)
for chan in matChans do
(
AppendIfUnique requiredChans chan
)
)
if (requiredChans.count != 0) do
(
Sort requiredChans
-- Which channels need to be activated for this object?
local objChansUsed = RsGetActiveChannels obj
local missingChans = for chan in requiredChans where (FindItem objChansUsed chan == 0) collect chan
Sort missingChans
Append chansPerObj (sObjChans obj:obj requiredChans:requiredChans missingChans:missingChans)
)
)
if (chansPerObj.count == 0) do
(
MessageBox "No valid RageShader materials were found on selected objects" title:"Invalid Selection"
return OK
)
-- Sort items with inactive channels to the top, otherwise sort by object-name:
fn SortInactiveToTop v1 v2 =
(
local inactiveA = (v1.missingChans.count != 0)
local inactiveB = (v2.missingChans.count != 0)
case of
(
(inactiveA and inactiveB):(StriCmp v1.obj.name v2.obj.name)
(inactiveA):-1
(inactiveB):1
Default:(StriCmp v1.obj.name v2.obj.name)
)
)
Qsort chansPerObj SortInactiveToTop
local listTitles = #("", "Object Name", "Required Channels", "Missing Channels")
local listItems = #()
local listChecked = #{}
for n = 1 to chansPerObj.count do
(
local item = chansPerObj[n]
local nameStr = (item.obj.name)
local requiredChansStr = (ArrayToString item.requiredChans)
local missingChansStr = (ArrayToString item.missingChans)
Append listItems #(nameStr, requiredChansStr, missingChansStr)
listChecked[n] = (item.missingChans.count != 0)
)
local msg = "Object materials require these vertex channels.\n\nActivate missing channels with their default colours?"
local title = "Activate Missing Channels?"
local btnLabels = #("Activate Missing Channels", "Cancel")
local checkLabels = #("Collapse Modifiers")
local checkStates = #{1}
local queryVal = RsQueryBoxMultiBtn msg title:title timeout:-1 width:500 labels:btnLabels \
listItems:listItems listTitles:listTitles listCheckStates:listChecked checkLabels:checkLabels checkStates:checkStates
-- If cancelled:
if (queryVal == 2) do return OK
local doCollapse = checkStates[1]
-- Filter list to checked items with missing channels:
chansPerObj = for n in listChecked collect chansPerObj[n]
chansPerObj = for item in chansPerObj where (item.missingChans.count != 0) collect item
if (chansPerObj.count == 0) do return OK
SuspendEditing()
undo "Activate Missing Channels" on
(
local selObjs = (GetCurrentSelection())
try
(
for item in chansPerObj do
(
local obj = item.obj
local missingChans = item.missingChans
-- Collect channel-edit definitions:
local clrEdits = for chan in missingChans collect
(
-- Get default colour for required channel:
local chanClr = (RsGetDefaultChannelColour chan)
(RsVertClrsEditDef chan:chan inputVal:chanClr modName:("Init [channel " + (Chan as string) + "]"))
)
-- Apply edit(s) to whole object:
Select obj
SubObjectLevel = 0
RsApplyVertClrChanges clrEdits
if doCollapse do
(
CollapseStack obj
)
)
)
catch ()
ResumeEditing()
Select selObjs
)
return OK
)
)
rollout RsVertClrCopyRoll "Copy Colour/Mapping Channels"
(
Dotnetcontrol LstCopyFrom "ComboBox" Align:#Left Width:146 Height:20 Offset:[-7,0] Across:3
Button BtnSwapChans "<->" Tooltip:"Swap Channels" Align:#Center Width:20 Height:20
Dotnetcontrol LstCopyTo "ComboBox" Align:#Right width:146 Height:20 Offset:[7,0]
Button BtnCopyChan "> Copy Channel >" Width:160 offset:[-2,-1]
fn GetChannelNum ThisList =
(
return (ThisList.SelectedIndex - 2)
)
fn SetBtnEnabled =
(
BtnCopyChan.Enabled = (LstCopyFrom.SelectedIndex != LstCopyTo.SelectedIndex)
BtnSwapChans.Enabled = BtnCopyChan.Enabled
)
on LstCopyFrom SelectionChangeCommitted Sender Args do ( SetBtnEnabled() )
on LstCopyTo SelectionChangeCommitted Sender Args do ( SetBtnEnabled() )
on BtnSwapChans Pressed do
(
local FromWas = LstCopyFrom.SelectedIndex
LstCopyFrom.SelectedIndex = LstCopyTo.SelectedIndex
LstCopyTo.SelectedIndex = FromWas
)
on BtnCopyChan Pressed do
(
local ChanFrom = (GetChannelNum LstCopyFrom)
local ChanTo = (GetChannelNum LstCopyTo)
for Obj in (GetCurrentSelection()) do
(
local ObjOp = (RsMeshPolyOp Obj)
if (ObjOp != undefined) and (ObjOp.GetMapSupport Obj ChanFrom) do
(
-- Collect existing paste-modifiers:
local PasteMods = for ThisMod in Obj.Modifiers where (isKindOf ThisMod UVW_Mapping_Paste) collect ThisMod
-- Copy/paste channel:
ChannelInfo.CopyChannel Obj 3 ChanFrom
ChannelInfo.PasteChannel Obj 3 ChanTo
-- Find new paste-modifier:
local PasteMod = undefined
for ThisMod in Obj.Modifiers while (PasteMod == undefined) do
(
if (isKindOf ThisMod UVW_Mapping_Paste) and (AppendIfUnique PasteMods ThisMod) do
(
PasteMod = ThisMod
)
)
-- Edit paste-modifier's name/mapId values:
if (PasteMod != undefined) do
(
PasteMod.Name = ("UV Paste [Chan " + (ChanTo as string) + "]")
PasteMod.MapId = ChanTo
-- Make sure renames are shown in list:
local CurrMod = ModPanel.GetCurrentObject()
if (CurrMod != undefined) do
(
ModPanel.SetCurrentObject CurrMod Node:Obj UI:True
)
)
)
)
)
on RsVertClrCopyRoll open do
(
for Lst in #(LstCopyFrom, LstCopyTo) do
(
Lst.DropDownStyle = Lst.DropDownStyle.DropDownList
Lst.DropDownWidth = 320
Lst.Items.Addrange RsVertClrToolCommonRoll.LstChans.Items
Lst.SelectedIndex = 2
)
SetBtnEnabled()
)
)
rollout RsVertClrProjectionRoll "Vertex Colour Projection"
(
Dotnetcontrol LstCopyFrom "ComboBox" Align:#Left Width:146 Height:20 Offset:[-7,0] Across:3
Button BtnSwapChans "<->" Tooltip:"Swap Channels" Align:#Center Width:20 Height:20
Dotnetcontrol LstCopyTo "ComboBox" Align:#Right width:146 Height:20 Offset:[7,0]
local selectedTargets = #()
fn pickFilter arg =
(
(classof arg.baseobject == Editable_Poly) or (classof arg.baseobject == Editable_mesh)
)
pickButton pickSource "Pick Source" filter:pickFilter width:150 height:23 across:2
button pickTargetBtn "Set Target(s)" width:150 height:23
label pickedSrc "" width:150 offset:[5,0] across:2
label pickedTgt "" width:150 offset:[5,0]
group ""
(
checkBox chkSampleBomb "Average Sample" tooltip:"Take more samples to average the colour transfer, better job, longer time" across:2
spinner spnPushPos "Push Value" type:#Float scale:0.1 range:[-9.99, 9.99, 0.0] tooltip:"Push the position values. Can help with meshes that are very close topographically"
label lblChannels "Channels:" tooltip:"Enable a channel to have it projected" across:4
checkBox chkRChan "R" checked:true
checkBox chkGChan "G" checked:true
checkBox chkBChan "B" checked:true
)
button btnProject "Project!" width:300
fn GetChannelNum ThisList =
(
return (ThisList.SelectedIndex - 2)
)
on BtnSwapChans Pressed do
(
local FromWas = LstCopyFrom.SelectedIndex
LstCopyFrom.SelectedIndex = LstCopyTo.SelectedIndex
LstCopyTo.SelectedIndex = FromWas
)
on btnProject pressed do
(
--Everything set right?
if (pickSource.object == undefined) or (selectedTargets.count == 0) do
(
messageBox "Your selection is not complete. Set a source and one or more targets"
return ok
)
if (findItem selectedTargets pickSource.object) != 0 do
(
messagebox "Source object cannot also be a target"
return ok
)
--source channel is?
local sourceChan = (GetChannelNum LstCopyFrom)
--target channel is?
local targetChan = (GetChannelNum LstCopyTo)
--average sample is selected?
local doSampleBomb = chkSampleBomb.state
--push value
local pushVal = spnPushPos.value
--what channels are active
local redSet = if chkRChan.checked then "r" else ""
local greenSet = if chkGChan.checked then "g" else ""
local blueSet = if chkBChan.checked then "b" else ""
local channelSetting = redSet + greenSet + blueSet
if (channelSetting == "") or (channelSetting == "rgb") do channelSetting = "all"
--format "ChannelSetting: % \n" channelSetting
for target in selectedTargets do
(
--call the projector
RsProjectVertexMap \
pickSource.object \
target \
SRCchannel:sourceChan TGTchannel:targetChan \
subChannels:channelSetting sampleBomb:doSampleBomb \
pushVal:pushVal
)
)
-----------------------
on pickSource picked obj do
(
if (obj != undefined) do
(
pickedSrc.text = obj.name
)
)
-----------------------
on pickTargetBtn pressed do
(
selectedTargets = for each in (GetCurrentSelection()) where isEditPolyMesh each collect each
if (selectedTargets.count == 1) then pickedTgt.text = selectedTargets[1].name
else if (selectedTargets.count > 1) do pickedTgt.text = selectedTargets[1].name + " and " + \
((selectedTargets.count-1) as string) + " more"
)
on RsVertClrProjectionRoll open do
(
for Lst in #(LstCopyFrom, LstCopyTo) do
(
Lst.DropDownStyle = Lst.DropDownStyle.DropDownList
Lst.DropDownWidth = 320
Lst.Items.Addrange RsVertClrToolCommonRoll.LstChans.Items
Lst.SelectedIndex = 2
)
)
)
rollout RSProjectClrMapRoll "Terrain Channel Transfer"
(
local wpfString = "<UserControl
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">
<ComboBox Name=\"Channels\">
</ComboBox>
</UserControl>"
local sourceMesh = undefined
local targetMesh = undefined
local theComboBox
local transferList = #()
local controls = Dictionary()
local maxNetGeo
struct ControlItem
(
stackpanel, textblock, checkbox
)
group "Channels"
(
DotNetControl XamlControl "Integration.ElementHost" Align:#Left Width:260 Height:20 Offset:[0,0] Across:2
checkbox chkAll "All" align:#right offset:[0, 3]
)
fn pickFilter obj =
(
return ((classof obj == editable_mesh) or (classof obj == editable_poly))
)
group "Selection"
(
label lblSource "Source: " align:#left across:4
pickbutton pckSource "Pick" filter:pickFilter width:100 offset:[-20, -3]
label lblTarget "Target: " offset:[-20, 0]
pickbutton pckTarget "Pick" filter:pickFilter width:100 offset:[-20, -3]
)
group ""
(
checkbox chkDistCut "Distance Cutoff: " across:2 align:#left
spinner spnMaxDist enabled:false Range:[0.1,100, 0.1] Scale:0.01 Type:#Float width:50 align:#left offset:[-45, 0]
)
button btnTransfer "Transfer" width:160
-------------------------------------------------------------------------------------------------
fn updateList item =
(
--get the channel idx
local mapIdxs = for chan in RsNamedMeshVertChannels where (chan.name == item) collect chan.id
local mapIdx
if (mapIdxs.count != 0) then mapIdx = mapIdxs[1]
--update state
local transferSet = finditem transferList mapIdx
if (transferSet != 0 ) then --its already set so switch it
(
deleteItem transferList transferSet
)
else --add it
(
append transferList mapIdx
)
)
-------------------------------------------------------------------------------------------------
fn doTransfer sourceMesh targetMesh channels:#all meshesWerePoly: =
(
if (maxNetGeo == undefined) then
(
maxNetGeo = dotnetobject "RSG.TechArt.Max.Geometry.Geo"
)
--check if the meshes are in containers, if they are then temporarily remove them whilst the imprinting is done
local sourceContainer = Containers.IsInContainer sourceMesh
local targetContainer = Containers.IsInContainer targetMesh
if(sourceContainer != undefined) then
(
sourceContainer.removeNodeFromContent sourceMesh true
)
if(targetContainer != undefined) then
(
targetContainer.removeNodeFromContent targetMesh true
)
try
(
for chan in transferList do
(
format "Transfering Chan %\n" chan
PushPrompt ("Transferring channel: " + chan as String)
local distanceVal = if spnMaxDist.enabled then spnMaxDist.value else -1
if (maxNetGeo == undefined) do
(
print "No Max Geo!"
continue
)
local hasMapSupport = true
local success = false
local sourceObjOp = RsMeshPolyOp sourceMesh
local targetObjOp = RsMeshPolyOp targetMesh
if not ((sourceObjOp.getMapSupport sourceMesh chan) \
and (targetObjOp.getMapSupport targetMesh chan)) do
(
format "\nThe chosen channel does not exist in one or both of the objects.\n"
format "Source 1: %\nTarget 2: %\nChannel: %\n" sourceMesh targetMesh chan
hasMapSupport = false
)
if (hasMapSupport) do
(
success = maxNetGeo.TransferMapChannel sourceMesh.handle #(targetMesh.handle) chan chan distanceVal
)
if not success then
(
format "Problem transferring: %\n" chan as String
)
)
replacePrompt ""
update targetMesh
--convert the meshes back to poly if thats what they were before
if (meshesWerePoly != unsupplied) do
(
if meshesWerePoly.source do convertToPoly sourceMesh
if meshesWerePoly.target do convertToPoly targetMesh
)
if(sourceContainer != undefined) then
(
sourceContainer.AddNodeToContent sourceMesh
)
if(targetContainer != undefined) then
(
targetContainer.AddNodeToContent targetMesh
)
)
catch --readd items to thier relative containers
(
if(sourceContainer != undefined) then
(
sourceContainer.AddNodeToContent sourceMesh
)
if(targetContainer != undefined) then
(
targetContainer.AddNodeToContent targetMesh
)
)
)
-----------------------
on pckSource picked obj do
(
if (obj != undefined) do
(
if (obj != targetMesh) then
(
sourceMesh = obj
pckSource.text = obj.name
)
)
)
-----------------------
on pckTarget picked obj do
(
if (obj != undefined) do
(
if (obj != sourceMesh) then
(
targetMesh = obj
pckTarget.text = obj.name
)
)
)
-----------------------
on chkDistCut changed active do
(
if active then
(
spnMaxDist.enabled = True
)
else
(
spnMaxDist.enabled = False
)
)
-----------------------
on btnTransfer pressed do
(
local sourceWasPoly = classof sourceMesh.baseobject == Editable_Poly
local targetWasPoly = classof targetMesh.baseobject == Editable_Poly
if (sourceMesh != undefined) and (targetMesh != undefined) then
(
if (classof sourceMesh != Editable_mesh) then
(
ConvertToMesh sourceMesh
)
if (classof targetMesh != Editable_mesh) then
(
ConvertToMesh targetMesh
)
local channelList = #()
if chkAll.state then
(
local ObjOp = (RsMeshPolyOp sourceMesh)
channelList = for item in RsNamedMeshVertChannels where (ObjOp.GetMapSupport sourceMesh item.id) collect item.id
)
else
(
-- channelSel = (LstCopyFrom.SelectedIndex - 2)
channelList = #()
local ObjOp = (RsMeshPolyOp sourceMesh)
for channelSel in transferList do
(
if (ObjOp != undefined) and (ObjOp.GetMapSupport sourceMesh channelSel) do
(
append channelList channelSel
)
)
)
if (channelList.count != 0) then
(
--check channels exist on source and target objects
missingSourceChannels = #()
missingTargetChannels = #()
for channelIdx in channelList do
(
local actualChan = channelIdx + 1
--Check map channel support on the target mesh
if not (meshop.getMapSupport targetMesh channelIdx) then
(
if ((meshop.getNumMaps targetMesh) < actualChan) then
(
meshop.setNumMaps targetMesh actualChan
)
meshop.setMapSupport targetMesh channelIdx true
for mv = 1 to (meshop.getNumMapVerts targetMesh channelIdx) do
(
meshop.setMapVert targetMesh channelIdx mv [0,0,0]
)
update targetMesh
)
if not (meshop.getMapSupport sourceMesh channelIdx) then
(
append missingSourceChannels channelIdx
)
if not (meshop.getMapSupport targetMesh channelIdx) then
(
append missingTargetChannels channelIdx
)
)
if (missingSourceChannels.count > 0) or (missingTargetChannels.count > 0) then
(
local list = NewScript()
format "SourceMesh Channels:\n" to:list
for idx in missingSourceChannels do
(
--get long name from index
local name = (for chan in RsNamedMeshVertChannels where chan.id == idx collect chan.name)[1]
format "Channel: %\n" ((idx as String) + ":" + name) to:list
)
format "TargetMesh Channels:\n" to:list
for idx in missingTargetChannels do
(
--get long name from index
local name = (for chan in RsNamedMeshVertChannels where chan.id == idx collect chan.name)[1]
format "Channel: %\n" ((idx as String) + ":" + name) to:list
)
messageBox "There are missing map channels, see the list" title:"Missing Map Channels"
return false
)
doTransfer sourceMesh targetMesh channels:channelList meshesWerePoly:(DataPair source:sourceWasPoly target:targetWasPoly)
)
else
(
messageBox "None of the channels selected have map support in the source object." title:"No Map Support"
)
if (transferList.count > channelList.count) and (channelList.count > 0) do
(
local difference = transferList.count - channelList.count
format "% Channels were not transfered due to lack of enabled MapSupport for those channels.\n" difference
format "Channels to transfer: %\n" transferList
format "Channels available: %\n" channelList
)
)
)
--------------------------
on chkAll changed checked do
(
--if its on disable the dropdown
if checked then
(
transferList = for chan in RsNamedMeshVertChannels collect chan.id
local scb = dotnetobject "Windows.Media.SolidColorBrush"
scb.Color = ((dotNetclass "System.Windows.Media.Color").FromArgb 0 0 0 0)
for item in controls.values() do
(
boolFalse = dotnetobject "System.Boolean" false
item.checkbox.IsChecked = boolFalse
item.stackpanel.Background = scb
)
theComboBox.Visibility = (dotnetclass "System.Windows.Visibility").Hidden
)
else
(
transferList = #()
theComboBox.Visibility = (dotnetclass "System.Windows.Visibility").Visible
)
)
-------------------------------------------------------------------------------------------------
on RSProjectClrMapRoll open do
(
dotnet.loadAssembly (RsConfigGetTechArtDir() + "dcc/3dsMax/RSG.TechArt.Max.dll")
dotNet.loadAssembly @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsFormsIntegration.dll"
XamlReader = (dotNetClass "Windows.Markup.XamlReader").Parse wpfString
XamlControl.child = XamlReader
dotNet.setLifetimeControl XamlReader #dotnet
theCanvas = XamlControl.Child
theComboBox = theCanvas.FindName "Channels"
fn chkClickFn sender ev =
(
updateList sender.Tag
local controlItem = controls.getValue sender.Tag
local sp = controlItem.stackpanel
if (controlItem.checkbox.IsChecked) then
(
-- if controlItem.stackpanel.Background
local scb = dotnetobject "Windows.Media.SolidColorBrush"
scb.Color = ((dotNetclass "System.Windows.Media.Color").FromArgb 255 64 96 0)
controlItem.stackpanel.Background = scb
)
else
(
local scb = dotnetobject "Windows.Media.SolidColorBrush"
scb.Color = ((dotNetclass "System.Windows.Media.Color").FromArgb 0 0 0 0)
controlItem.stackpanel.Background = scb
)
--theComboBox.IsDropDownOpen = false
)
for item in RsNamedMeshVertChannels do
(
--theComboBox.Items.Add item.name
stackpanel = dotnetobject "Windows.Controls.StackPanel"
stackpanel.orientation = dotnetclass "System.Windows.Controls.Orientation.Horizontal"
textblock = dotnetobject "Windows.Controls.TextBlock"
textblock.text = item.name + " [" + (item.id as String) + "]"
checkboxCtrl = dotnetobject "Windows.Controls.CheckBox"
th = dotnetobject "System.Windows.Thickness" 10 0 0 0
checkboxCtrl.Margin = th
checkboxCtrl.Tag = item.name
checkboxCtrl.IsThreeState = false
dotnet.AddEventHandler checkboxCtrl "Click" chkClickFn
-- append checkBoxes checkboxCtrl
stackpanel.Children.Add textblock
stackpanel.Children.Add checkboxCtrl
theComboBox.Items.Add stackpanel
controls.addKey item.name (ControlItem stackpanel:stackpanel textblock:textblock checkbox:checkboxCtrl)
)
theComboBox.SelectedIndex = 0
/*
LstCopyFrom.DropDownStyle = LstCopyFrom.DropDownStyle.DropDownList
LstCopyFrom.DropDownWidth = 320
local listItems = #()
for item in RsVertClrToolCommonRoll.LstChans.Items do
(
local chkBox = dotnetobject "CheckBox"
chkBox.text = item
chkBox.AccessibleName = item
append listItems chkBox
)
-- LstCopyFrom.Items.Addrange RsVertClrToolCommonRoll.LstChans.Items
LstCopyFrom.Items.Addrange listItems
LstCopyFrom.SelectedIndex = 2
*/
--Set channels 5(Terrain Uber Masking) and 9(Terrain Shader Lookup) by default
(
local channelIllum = RsNamedMeshVertChannels[2].name
local channel5 = RsNamedMeshVertChannels[8].name
local channel9 = RsNamedMeshVertChannels[12].name
local scb = dotnetobject "Windows.Media.SolidColorBrush"
scb.Color = ((dotNetclass "System.Windows.Media.Color").FromArgb 255 64 96 0)
updateList channelIllum
local controlItem = controls.getValue channelIllum
controlItem.checkbox.IsChecked = (dotnetobject "System.Boolean" true)
controlItem.stackpanel.Background = scb
updateList channel5
local controlItem = controls.getValue channel5
controlItem.checkbox.IsChecked = (dotnetobject "System.Boolean" true)
controlItem.stackpanel.Background = scb
updateList channel9
local controlItem = controls.getValue channel9
controlItem.checkbox.IsChecked = (dotnetobject "System.Boolean" true)
controlItem.stackpanel.Background = scb
)
)
)
rollout RsMapVertClrToolsRoll "Map Tools"
(
local btnWidth = 160
local btnHeight = 22
button btnSceneBaker "Scene Baker" width:btnWidth height:btnHeight offset:[-1,0]
button btnMeshTint "Mesh Tinting Tool" width:btnWidth height:btnHeight offset:[-1,-3]
button btnTerrain "Terrain Paint" width:btnWidth height:btnHeight offset:[-1,-3]
button btnChanClearer "Vertex Channel Clearer" width:btnWidth height:btnHeight offset:[0,-3]
button btnVertPaintTools "Vertex Paint Tools" width:btnWidth height:btnHeight offset:[-1,-3]
button btnVertPaintMgr "VertexPaint Manager" width:btnWidth height:btnHeight offset:[-1,-3]
button btnRandomPainter "Random Painter" width:btnWidth height:btnHeight offset:[-1,-3]
on btnSceneBaker pressed do
(
filein "rockstar/util/scenebaker/rsn_scenebaker.ms"
)
on btnMeshTint pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Props/MeshTint_tool.ms")
)
on btnTerrain pressed do
(
filein (RsConfigGetWildwestDir() + "Script/3dsMax/Maps/Materials/terrain_painter.ms")
)
on btnChanClearer pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/uvChannelClearer.ms")
)
on btnVertPaintTools pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Characters/Materials/Vertex_Bake_Painter.ms")
)
on btnVertPaintMgr pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/VertexPaintMgr.ms")
)
on btnRandomPainter pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/RandomPainter.ms")
)
)
rollout RsPedVertClrToolsRoll "Ped Tools"
(
local btnWidth = 160
local btnHeight = 22
button btnVertPaintTools "Vertex Paint Tools" width:btnWidth height:btnHeight
button btnChanClearer "Vertex Channel Clearer" width:btnWidth height:btnHeight offset:[1,-3]
button btnVertexPaintMgr "VertexPaint Manager" width:btnWidth height:btnHeight offset:[0,-3]
button btnPedDirtBaker "Ped Dirt Baker" width:btnWidth height:btnHeight offset:[1,-3]
on btnVertPaintTools pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Characters/Materials/Vertex_Bake_Painter.ms")
)
on btnChanClearer pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/uvChannelClearer.ms")
)
on btnVertexPaintMgr pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Maps/Materials/VertexPaintMgr.ms")
)
on btnPedDirtBaker pressed do
(
fileIn (::RsConfigGetWildWestDir() + "script/3dsMax/Characters/Materials/pedDirtBaker.ms")
)
)
rollout RsVertClrToolEditRoll "Edit Vert/Face Colours"
(
local clrFuncs =
#(
dataPair label:"Set Colour" action:#set,
dataPair label:"Colourise (Set Hue/Sat)" action:#colourise,
dataPair label:"Set Hue" action:#hue,
dataPair label:"Set Saturation" action:#saturation,
dataPair label:"Set Luminosity" action:#luminosity,
dataPair label:"Multiply" action:#multiply,
dataPair label:"Screen" action:#screen,
dataPair label:"Overlay" action:#overlay
)
local btnHeight = 20
local btnWidth = 30
local bmHeight = btnHeight-4
local bmWidth = btnWidth-4
group "Quick Pick/Apply (L/R-click):"
(
button btnBlk width:btnWidth height:btnHeight across:9
button btnWht width:btnWidth height:btnHeight
button btnGry width:btnWidth height:btnHeight
button btnRed width:btnWidth height:btnHeight
button btnYlw width:btnWidth height:btnHeight
button btnGrn width:btnWidth height:btnHeight
button btnTel width:btnWidth height:btnHeight
button btnBlu width:btnWidth height:btnHeight
button btnPur width:btnWidth height:btnHeight
)
local grey = Color 128 128 128
local teal = Color 0 255 255
local purple = Color 255 0 255
local btnColours = \
#(
DataPair button:btnBlk colour:Black,
DataPair button:btnWht colour:White,
DataPair button:btnGry colour:Grey,
DataPair button:btnRed colour:Red,
DataPair button:btnYlw colour:Yellow,
DataPair button:btnGrn colour:Green,
DataPair button:btnTel colour:Teal,
DataPair button:btnBlu colour:Blue,
DataPair button:btnPur colour:Purple
)
fn GetColourForButton inBtn=
(
local outColour = Undefined
for item in btnColours while (outColour == Undefined) do
(
if (item.button == inBtn) do
outColour = item.colour
)
return outColour
)
local clrSize = 122
local btnWidth = 150
checkButton btnPickFace "Pick Colour from Mesh" across:2 width:btnWidth align:#left offset:[0,0]
button btnObjPicker "Get Colour from Selected" width:btnWidth align:#right offset:[0,0] tooltip:"Pick Colour from selected object/sub-object selection, from \"Use Channel\""
button btnInvertColours "Invert Colours" across:2 width:btnWidth align:#left offset:[0,-3] tooltip:"Invert colours for selected subobjects"
button btnVertAverage "Average Per Vert" width:btnWidth align:#Right offset:[0,-3] tooltip:"Set average colour for selected verts - smooths over sharp seams"
button btnCurveMask "Curvature Mask" width:btnWidth align:#left offset:[0,-3] tooltip:"Bake curvature to active channel\n(Black: Flat, White: Max Curve)"
colorPicker clrPicker width:clrSize height:clrSize across:3 offset:[-10,0]
checkButton btnSyncToVpaint "Sync => VertexPaint" checked:False width:(clrSize - 3) height:28 pos:(clrPicker.pos + [0, clrSize + 3]) \
tooltip:"Send chosen colours to VertexPaint modifier"
radioButtons rdoSelEdit "" labels:(for item in clrFuncs collect item.label) pos:(clrPicker.pos + [clrSize + 4, 0])
button btnApply "Apply" tooltip:"Apply colour/action to selection" width:100 height:30 pos:[RsVertClrToolEditRoll.width - 106, rdoSelEdit.pos.Y + clrSize - 34]
spinner spnOpacity "Opacity:" range:[0,1,1] FieldWidth:40 pos:(btnApply.Pos + [7,33])
local clrBtnWidth = 16
local clrBmps = for clr in #(Red, Green, Blue) collect #((Bitmap 9 9 color:clr), Undefined, 1, 1, 1, 1, 1, True)
Label lblRGB "Edit Components:" Across:5 Align:#Right Offset:[193,-3]
CheckButton chkRed "" images:clrBmps[1] border:False checked:True align:#Right width:clrBtnWidth height:clrBtnWidth pos:(lblRGB.pos + [88,0])
CheckButton chkGreen "" images:clrBmps[2] border:False checked:True align:#Right width:clrBtnWidth height:clrBtnWidth pos:(chkRed.pos + [17,0])
CheckButton chkBlue "" images:clrBmps[3] border:False checked:True align:#Right width:clrBtnWidth height:clrBtnWidth pos:(chkGreen.pos + [17,0])
ColorPicker clrShowMix align:#Right width:8 height:16 pos:(chkBlue.pos + [13,0]) enabled:False
local subChanCtrls = #(chkRed, chkGreen, chkBlue)
Group "Select Subobjects with Matching Colour:"
(
button btnSelSubobjs "Select" tooltip:"Select verts/faces using this colour" width:80 align:#left offset:[-3,-1] across:2
spinner spnSelectDist "Match-range %" range:[0,256,10] type:#integer fieldwidth:30 pos:(btnSelSubobjs.pos + [80 + 8, 4])
)
-- Returns active rgb subchannels:
fn GetSubChans =
(
local retVal = #{}
for n = 1 to 3 do
(
retVal[n] = SubChanCtrls[n].Checked
)
return retVal
)
-- Transfer colour/opacity to VertexPaint floater:
fn sendToVpaint =
(
-- Get VertexPaint floater:
local vPaintTool = VertexPaintTool()
-- Set VertexPaint colour/opacity:
vPaintTool.paintColor = (clrPicker.color)
vPaintTool.brushOpacity = (100.0 * spnOpacity.value)
-- Trigger toolkit-update:
vPaintTool.keepToolboxOpen = vPaintTool.keepToolboxOpen
)
-- Modify chosen colour to match channel/subchannel settings:
fn ShowClr =
(
-- Is this a greyscale channel? (alpha/luminosity)
local isGreyScale = (RsVertClrToolCommonRoll.getChan() < 0)
-- Get unmodified chosen colour from Common rollout:
local theShowClr = Copy rsVertClrToolCommonRoll.rememberClr
-- Disable subchannel- controls for greyscale:
SubChanCtrls.Enabled = (not isGreyScale)
if (isGreyScale) then
(
-- Set control to greyscale version of RememberClr:
local greyVal = (theShowClr.r + theShowClr.g + theShowClr.b) / 3.0
theShowClr = Color greyVal greyVal greyVal
)
else
(
-- Modify RememberClr to mask out unwanted subchannels:
local maskedChans = -(GetSubChans())
if MaskedChans[1] do (theShowClr.r = 0)
if MaskedChans[2] do (theShowClr.g = 0)
if MaskedChans[3] do (theShowClr.b = 0)
)
-- Show colour:
ClrPicker.Color = theShowClr
-- Transfer new colour to VertexPaint floater:
if (btnSyncToVpaint.checked) do (sendToVpaint())
)
fn setThisClr newClr =
(
if (newClr != undefined) do
(
rsVertClrToolCommonRoll.rememberClr = newClr
-- Show colour in clrPicker, modified as necessary:
ShowClr()
)
)
on clrPicker changed newClr do
(
setThisClr newClr
)
on spnOpacity changed newVal do
(
-- Transfer new opacity to VertexPaint floater:
if (btnSyncToVpaint.checked) do (sendToVpaint())
)
on btnSyncToVpaint changed newState do
(
-- Transfer colour/opacity to VertexPaint floater:
if newState do (sendToVpaint())
)
fn UpdateComponentMix =
(
local clr = Black
if chkRed.checked do (clr += Red)
if chkGreen.checked do (clr += Green)
if chkBlue.checked do (clr += Blue)
clrShowMix.color = clr
)
-- Update colour whenever rgb checkboxes are changed:
on chkRed changed State do (UpdateComponentMix(); ShowClr())
on chkGreen changed State do (UpdateComponentMix(); ShowClr())
on chkBlue changed State do (UpdateComponentMix(); ShowClr())
on chkRed rightclick do (#(chkRed, chkGreen, chkBlue).checked = True; UpdateComponentMix())
on chkGreen rightclick do (#(chkRed, chkGreen, chkBlue).checked = True; UpdateComponentMix())
on chkBlue rightclick do (#(chkRed, chkGreen, chkBlue).checked = True; UpdateComponentMix())
on btnObjPicker pressed do
(
local chan = (RsVertClrToolCommonRoll.getChan())
local getClr = RsChooseColourFromSelObjs chan:chan
setThisClr getClr
)
on btnPickFace changed state do
(
-- Pick colour from selected object's mesh:
local chan = (RsVertClrToolCommonRoll.getChan())
local getClr = RsPickColourFromObj ($) chan:chan showOptions:True
-- Show picked colour:
setThisClr getClr
btnPickFace.checked = False
)
fn QuickSetVertColor aColour=
(
RsApplyVertColourChange chan:(RsVertClrToolCommonRoll.getChan()) action:#set\
inputVal:aColour opacity:1 SubChans:(GetSubChans()) AllowSoftSelect:True
)
fn QuickSetColourPicker aColour=
(
setThisClr aColour
)
on btnBlk rightClick do QuickSetVertColor (GetColourForButton btnBlk)
on btnWht rightClick do QuickSetVertColor (GetColourForButton btnWht)
on btnGry rightClick do QuickSetVertColor (GetColourForButton btnGry)
on btnRed rightClick do QuickSetVertColor (GetColourForButton btnRed)
on btnYlw rightClick do QuickSetVertColor (GetColourForButton btnYlw)
on btnGrn rightClick do QuickSetVertColor (GetColourForButton btnGrn)
on btnTel rightClick do QuickSetVertColor (GetColourForButton btnTel)
on btnBlu rightClick do QuickSetVertColor (GetColourForButton btnBlu)
on btnPur rightClick do QuickSetVertColor (GetColourForButton btnPur)
on btnBlk pressed do QuickSetColourPicker (GetColourForButton btnBlk)
on btnWht pressed do QuickSetColourPicker (GetColourForButton btnWht)
on btnGry pressed do QuickSetColourPicker (GetColourForButton btnGry)
on btnRed pressed do QuickSetColourPicker (GetColourForButton btnRed)
on btnYlw pressed do QuickSetColourPicker (GetColourForButton btnYlw)
on btnGrn pressed do QuickSetColourPicker (GetColourForButton btnGrn)
on btnTel pressed do QuickSetColourPicker (GetColourForButton btnTel)
on btnBlu pressed do QuickSetColourPicker (GetColourForButton btnBlu)
on btnPur pressed do QuickSetColourPicker (GetColourForButton btnPur)
on btnApply pressed do
(
local chan = RsVertClrToolCommonRoll.getChan()
local action = clrFuncs[rdoSelEdit.state].action
local inputVal = clrPicker.color
local opacity = spnOpacity.Value
local SubChans = (GetSubChans())
--format "chan: %\naction: %\ninputVal: %\nopacity: %\nSubChans: %\n" chan action inputVal opacity SubChans
RsApplyVertColourChange chan:chan action:action inputVal:inputVal opacity:opacity SubChans:SubChans AllowSoftSelect:True
)
on btnInvertColours pressed do
(
local chan = RsVertClrToolCommonRoll.GetChan()
local subChans = (GetSubChans())
RsApplyVertColourChange chan:chan action:#invert SubChans:SubChans
)
on btnVertAverage pressed do
(
local chan = RsVertClrToolCommonRoll.GetChan()
local subChans = (GetSubChans())
RsApplyVertColourChange chan:chan action:#VertAverage subChans:subChans
)
on btnCurveMask pressed do
(
local chan = RsVertClrToolCommonRoll.GetChan()
local subChans = (GetSubChans())
RsApplyVertColourChange chan:chan action:#Curvature subChans:subChans
)
on btnSelSubobjs pressed do
(
local findClr = clrPicker.color
local matchDist = spnSelectDist.value
local obj = $
if (not isEditPolyMesh obj) do return false
obj = obj.baseObject
local subObjType = RsGetSubObjLevelName()
if (subObjType != #face) do (subObjType = #vertex)
setCommandPanelTaskMode #modify
modPanel.setCurrentObject obj ui:True
-- Get colour/subobj lists:
local chan = RsVertClrToolCommonRoll.getChan()
local objClrs = #()
local clrVerts = #()
local clrFaces = #()
RsGetColourSubobjLists obj chan:chan colours:objClrs verts:clrVerts faces:clrFaces
-- Find matching colours: (convert to CIE-L*ab for better matching)
local findClrVal = (RsXYZtoCIELAB (RsRGBtoXYZ findClr))
local searchClrVals = for clr in objClrs collect (RsXYZtoCIELAB (RsRGBtoXYZ clr))
local searchSubObjs = if (subObjType == #face) then clrFaces else clrVerts
local matchedSubObjs = #{}
-- Find subobjects with matching colours:
for clrIdx = 1 to objClrs.count do
(
if (distance findClrVal searchClrVals[clrIdx]) <= matchDist do
(
matchedSubObjs += searchSubObjs[clrIdx]
)
)
-- Set subobject selection
case subObjType of
(
#vertex:
(
subObjectLevel = 1
case (classOf obj) of
(
Editable_Poly:(polyop.setVertSelection obj matchedSubObjs)
Editable_Mesh:(setVertSelection obj matchedSubObjs)
)
)
#face:
(
case (classOf obj) of
(
Editable_Poly:(polyop.setFaceSelection obj matchedSubObjs)
Editable_Mesh:(setFaceSelection obj matchedSubObjs)
)
)
)
completeRedraw()
return matchedSubObjs
)
on RsVertClrToolEditRoll open do
(
for item in btnColours do
item.button.images = #((Bitmap bmWidth bmHeight color:item.colour), Undefined, 1, 1, 1, 1, 1, True)
clrPicker.color = RsVertClrToolCommonRoll.rememberClr
UpdateComponentMix()
)
)
rollout RsVertClrToolVertMatcherRoll "Copy Edge-Vertex Colours"
(
label copyEdgeVertClrLbl "Copy the vertex colour of source to matching verts on selection"
button btnMatchEdgeVerts "Copy matching verts:" across:2 align:#right tooltip:"Colours are copied from verts on source-object, onto matching verts on selected objects"
pickButton btnPickMatchObj "Pick Source Object" filter:isEditPolyMesh autoDisplay:true align:#left offset:[2,0]
on btnPickMatchObj rightClick do (btnPickMatchObj.object = undefined)
on btnMatchEdgeVerts pressed do
(
local chan = RsVertClrToolCommonRoll.getChan()
local sourceObj = btnPickMatchObj.object
if (not isValidNode sourceObj) do
(
messageBox "Please pick a Source Object" title:"Error: No source-object picked"
return false
)
local targetObjs = for obj in selection where (isEditPolyMesh obj) and (obj != sourceObj) collect obj
if (targetObjs.count == 0) do
(
messageBox "Please select at least one Target Object" title:"Error: No target-objects selected"
return false
)
for obj in targetObjs do
(
local tempObj = RsVertClr_makeTempObj obj copyChan:chan
RsCopyVertColours sourceObj tempObj matchChannel:chan
RsVertClr_applyTempData tempObj obj chan
)
)
)
rollout RsVertClrToolFaceCopyRoll "Copy Face-Colours"
(
group "Copy face-colours:"
(
button btnCopyClr "Copy to selected:" across:2 align:#right tooltip:"Colours are copied from faces on source-object onto nearest faces (in local space) on selected objects"
pickButton btnPickSrcObj "Pick Source Object" filter:isEditPolyMesh autoDisplay:true align:#left offset:[2,0]
)
button btnMeshTintToSlods "Copy MeshTint to ComboLod sources" tooltip:"MeshTint colours are copied from faces on selected HD objects onto nearest faces (in local space) on their linked ComboLodder-source meshes"
on btnPickSrcObj rightClick do (btnPickSrcObj.object = undefined)
fn copyFaceColours sourceObjs targetObjLists chan:(RsVertClrToolCommonRoll.getChan()) =
(
local modName = "ColourCopy [chan " + (chan as string) + "]"
progressStart "Copying face-colours..."
local copyNum = 0
local copyCount = 0
for list in targetObjLists do (copyCount += 1)
local keepGoing = True
for n = 1 to sourceObjs.count while keepGoing do
(
local sourceObj = sourceObjs[n]
local targetObjs = targetObjLists[n]
for targetObj in targetObjs while keepGoing = (progressupdate ((100.0 * (copyNum += 1)) / copyCount)) do
(
local tempObj = RsVertClr_makeTempObj targetObj copyChan:chan
RsCopyFaceColours sourceObj tempObj chan:chan showProgress:False
RsVertClr_applyTempData tempObj targetObj chan modName:modName
)
)
progressEnd()
)
on btnCopyClr pressed do
(
local sourceObj = btnPickSrcObj.object
if (not isValidNode sourceObj) do
(
messageBox "Please pick a Source Object" title:"Error: No source-object picked"
return false
)
local targetObjs = for obj in selection where (isEditPolyMesh obj) and (obj != sourceObj) collect obj
if (targetObjs.count == 0) do
(
messageBox "Please select at least one Target Object" title:"Error: No target-objects selected"
return false
)
copyFaceColours #(sourceObj) #(targetObjs)
)
on btnMeshTintToSlods pressed do
(
local selObjs = for obj in selection where (isEditPolyMesh obj) collect
(
local slodChildren = #()
local slodParents = #()
RsSceneLink.GetChildren LinkType_CombinerMesh obj &slodChildren
RsSceneLink.GetParents LinkType_CombinerMesh obj &slodParents
if (slodChildren.count != 0) or (slodParents.count == 0) then dontCollect else obj
)
if (selObjs.count == 0) do
(
messageBox "Please select at least one high-def prop with linked ComboLod-sources" title:"Error: Invalid Selection"
return False
)
local sourceObjs = #()
local targetObjLists = #()
for sourceObj in selObjs do
(
local slodMeshes = #()
RsSceneLink.GetParents LinkType_CombinerMesh sourceObj &slodMeshes
local slodNum = 0
-- Get rest of objects from slod-source hierarchy:
while (slodNum < slodMeshes.count) do
(
slodNum += 1
local moreSlods = #()
RsSceneLink.GetParents LinkType_CombinerMesh slodMeshes[slodNum] &moreSlods
join slodMeshes moreSlods
)
append sourceObjs sourceObj
append targetObjLists slodMeshes
)
-- Do face-colour copy:
copyFaceColours sourceObjs targetObjLists chan:gRsMeshTintFuncs.tintChannel
)
)
rollout RsVertClrToolWeldVertsRoll "Weld Mapping-Verts"
(
Label LblWeld "Welds mapping-border verts for selected geometry-verts\nor object, on mapping-channel set as 'Use Channel'" Align:#Left Height:28
Spinner SpnThreshold "Threshold:" Range:[0.001,2.0,0.01] Scale:0.001 FieldWidth:40 Offset:[0,3] Across:2 Align:#Right
Button BtnWeldVerts "Weld Selected" Offset:[4,0] Align:#Left
on BtnWeldVerts pressed do
(
local SelObjs = for Obj in GetCurrentSelection() where (isEditPolyMesh Obj) collect Obj
if (SelObjs.Count == 0) do return False
-- Get weld-channel from common rollout:
local Chan = RsVertClrToolCommonRoll.GetChan()
-- Get verts from subobject-selection, or Unsupplied if we're applying weld to whole object(s)
local SelVerts = if (SelObjs.Count > 1) or ((RsGetSubObjLevelName()) == #object) then unsupplied else (RsGetSelVertNums SelObjs)
for Obj in SelObjs do
(
RsWeldMapBorderVerts Obj Chan Verts:SelVerts Threshold:SpnThreshold.Value
)
)
)
rollout RsVertClrToolRoll "Vertex Colour Toolkit"
(
local rollWidth
dotNetControl RsBannerPanel "Panel" pos:[0,0] height:32 width:RsVertClrToolRoll.width
local bannerStruct = makeRsBanner dn_Panel:RsBannerPanel versionNum:1.54 versionName:"Acrid Frustrum"
dotNetControl dnTabs "system.windows.forms.tabControl" width:(RsVertClrToolRoll.width + 2) height:25 align:#left pos:[-1, (RsBannerPanel.height + 2)]
subRollout theSubRollout width:(RsVertClrToolRoll.width + 1) pos:[-1, dnTabs.pos.y + dnTabs.height]
local rolloutPages =
#(
DataPair name:"Edit" rollouts:#(RsVertClrWorkChannels, RsVertClrToolEditRoll, RsVertClrToolsRoll, RsVertClrToolWeldVertsRoll, RsVertClrCopyRoll, RsVertClrProjectionRoll)
)
local rolloutCurrentPages = #()
fn SetPage idx =
(
if ( idx <= rolloutPages.count ) then
(
for roll in rolloutCurrentPages do
(
removeSubRollout theSubRollout roll
)
rolloutCurrentPages = #()
for roll in rolloutPages[idx].rollouts do
(
addSubRollout theSubRollout roll
append rolloutCurrentPages roll
)
-- Don't show common-controls tab if current tab doesn't use it:
local showCommon = TRUE -- (idx != 1)
RsVertClrToolCommonRoll.keepOpenState = showCommon
RsVertClrToolCommonRoll.open = showCommon
)
else
(
MessageBox "Internal Error. Tabs misconfigured. Contact tools."
)
)
on dnTabs Click do
(
local tabNum = dnTabs.SelectedIndex + 1
RsSettingWrite "RsVertClrToolRoll" "tabNum" tabNum
SetPage tabNum
)
fn arrangeCtrls =
(
theSubRollout.height = RsVertClrToolRoll.height - theSubRollout.pos.y - theSubRollout.pos.x
)
-- Only allow vertical resizing:
on RsVertClrToolRoll Resized newSize do
(
if (newSize.x != rollWidth) do
(
RsVertClrToolRoll.width = rollWidth
)
RsSettingWrite "RsVertClrToolRoll" "height" newSize.y
arrangeCtrls()
)
on RsVertClrToolRoll open do
(
-- Initialise tech-art banner:
bannerStruct.setup()
rollWidth = RsVertClrToolRoll.width
arrangeCtrls()
dnTabs.tabPages.clear()
for item in rolloutPages do
(
dnTabs.tabPages.add item.name
)
local tabNum = RsSettingsReadInteger "RsVertClrToolRoll" "tabNum" 1
if (tabNum > dnTabs.tabPages.count) do
(
tabNum = 1
)
dnTabs.SelectedIndex = (tabNum - 1)
addSubRollout theSubRollout RsVertClrToolCommonRoll
SetPage tabNum
)
fn create =
(
destroyDialog RsVertClrToolRoll
local rollHeight = RsSettingsReadInteger "RsVertClrToolRoll" "height" 712
CreateDialog RsVertClrToolRoll modal:false width:342 height:rollHeight style:#(#style_resizing, #style_titlebar, #style_border, #style_sysmenu )
)
) -- End rollout
RsVertClrToolRoll.create()