1836 lines
55 KiB
Plaintext
Executable File
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()
|