423 lines
15 KiB
Plaintext
Executable File
423 lines
15 KiB
Plaintext
Executable File
--=============================================================--
|
|
-- AUTH: Kyle Hansen - Rockstar San Diego: kyle.hansen@rockstarsandiego.com
|
|
-- 1.0 - 06-21-2012
|
|
|
|
-- maps selected faces using a uvw modifier, then sets the length,
|
|
-- width, utile and vtile of the modifier to specific settings read in from an xml.
|
|
-- currently the XML lives here:
|
|
-- X:\project\tools\wildwest\etc\config\general\uvStructureToolSettings.xml
|
|
--=============================================================--
|
|
|
|
filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms")
|
|
dotnet.LoadAssembly "System.Xml.XPath.dll"
|
|
|
|
global projectUVToolInstance
|
|
try (projectUVToolInstance.Close()) catch()
|
|
|
|
(
|
|
|
|
--LOCAL VAR USED AS A GLOBAL THROUGH THE SCRIPT
|
|
local uvwProjectionType = 0
|
|
|
|
--=============================================================--
|
|
-- Catches any selection based errors
|
|
----- Errors when:
|
|
-- Object is not editpoly, or editmesh
|
|
-- More than one object selected, or no objects are selected
|
|
-- No Faces in selection
|
|
--=============================================================--
|
|
fn meshErrorChecking =
|
|
(
|
|
|
|
local errorMsg = ""
|
|
local retVar = true
|
|
local selectedObject = (getCurrentSelection() as array)
|
|
|
|
if selectedObject.count == 0 then
|
|
(
|
|
print "Error: No objects selected!"
|
|
errorMsg = "Error: No objects selected!"
|
|
retVar = false
|
|
)
|
|
else if selectedObject.Count > 1 then
|
|
(
|
|
print "Error: Multiple objects selected, please make a face selection on one object only!"
|
|
errorMsg = "Error: Multiple objects selected, please make a face selection on one object only!"
|
|
retVar = false
|
|
)
|
|
else
|
|
(
|
|
selectedObject = (getCurrentSelection() as array)[1]
|
|
|
|
-- Check for invalid scale.
|
|
if selectedObject.transform.scalepart != [ 1, 1, 1 ] then (
|
|
errorMsg = "The object (" + selectedObject.name + ") needs to have its transform reset! Cannot continue."
|
|
|
|
retVar = false
|
|
)
|
|
|
|
if classOf selectedObject == Editable_Mesh then
|
|
(
|
|
local selectedFaces = getFaceSelection (selectedObject) as array
|
|
)
|
|
else if classOf selectedObject == Editable_Poly then
|
|
(
|
|
local selectedFaces = polyOp.getFaceSelection (selectedObject) as array
|
|
)
|
|
|
|
-- if the object is not a mesh or poly, then error, as well as test for facial selections
|
|
if classOf selectedObject != Editable_Mesh and classOf selectedObject != Editable_Poly then
|
|
(
|
|
errorMsg = "Error: Object must be an Editable Poly or Editable mesh. Please convert your object, and make a face selection."
|
|
retVar = false
|
|
)
|
|
else if selectedFaces == undefined then
|
|
(
|
|
errorMsg = "Error: No faces selected, Please make a selection of faces!"
|
|
retVar = false
|
|
)
|
|
else if selectedFaces.Count == 0 then
|
|
(
|
|
errorMsg = "Error: No faces selected, Please make a selection of faces!"
|
|
retVar = false
|
|
)
|
|
)
|
|
|
|
if retVar == false then
|
|
(
|
|
messageBox errorMsg
|
|
)
|
|
|
|
retVar
|
|
)
|
|
|
|
--=============================================================--
|
|
------ Reads XML attribute
|
|
-- selectedSet = dotNet xml document navigator selection set, attributeName = Case sensitive XML attribute name
|
|
--=============================================================--
|
|
fn getXMLAttribute selectedSet attributeName =
|
|
(
|
|
-- use the passed in set of nodes to search for our attribute
|
|
local attributeIterator = selectedSet.Current.Select("@" + attributeName)
|
|
if attributeIterator.Count > 0 then
|
|
(
|
|
attributeIterator.MoveNext()
|
|
local returnValue = attributeIterator.Current.Value
|
|
--print ("Value: " + attributeIterator.Current.Value)
|
|
)
|
|
returnValue
|
|
)
|
|
|
|
--=============================================================--
|
|
------ Loads in the required XML, returns array of arrays holding the type and values
|
|
--=============================================================--
|
|
fn loadTextureSettingsXML =
|
|
(
|
|
local projToolsRoot = theProjectToolsRoot
|
|
|
|
local textureSettingsFilePath = (projToolsRoot + "wildwest\\etc\\config\\general\\uvStructureToolSettings.xml")
|
|
|
|
|
|
-- create an xml instance
|
|
local textureSettingsXML = XmlDocument()
|
|
textureSettingsXML.init()
|
|
textureSettingsXML.Load textureSettingsFilePath
|
|
-- now create a XML document instance to read from
|
|
local textureSettingsDocument = textureSettingsXML.Document
|
|
-- create our navigator which we use to survey the xml document
|
|
local textureSettingsNavigator = textureSettingsDocument.CreateNavigator()
|
|
textureSettingsNavigator.MoveToRoot()
|
|
|
|
-- find all of the specific nodes we are looking for
|
|
local settingsSelectionSet = textureSettingsNavigator.Select(textureSettingsNavigator.Compile("/textureSettings/Setting"))
|
|
|
|
|
|
local settingsFileFormatted = #()
|
|
-- lets loop through all of the found nodes and then search for each attribute we are looking for, compiling it in an array of values
|
|
while (settingsSelectionSet.MoveNext()) do
|
|
(
|
|
local nameAttribute = getXMLAttribute settingsSelectionSet "Name"
|
|
local uAttribute = getXMLAttribute settingsSelectionSet "U"
|
|
local vAttribute = getXMLAttribute settingsSelectionSet "V"
|
|
append settingsFileFormatted #(nameAttribute, uAttribute, vAttribute)
|
|
)
|
|
|
|
settingsFileFormatted
|
|
)
|
|
|
|
--=============================================================--
|
|
-- Main button callback
|
|
----------
|
|
-- senderControl = the button control object, e = the returned dotnet handle
|
|
-- DESC: Looks at the "Tag" on the passed in control object, and gets the
|
|
-- uv info. String is organized in (u, v)
|
|
--=============================================================--
|
|
fn projectUVFromSetting senderControl e =
|
|
(
|
|
if meshErrorChecking() == true then
|
|
(
|
|
local selectedObject = (getCurrentSelection() as array)[1]
|
|
|
|
local dataString = getProperty senderControl "Tag"
|
|
local dataTok = filterString dataString " "
|
|
|
|
local uWidth = dataTok[1] as float
|
|
local vLength = dataTok[2] as float
|
|
local projectionAxis = dataTok[3] as integer
|
|
|
|
if superclassof selectedObject == geometryClass then
|
|
(
|
|
local faceId = undefined
|
|
if uvwProjectionType == 0 then
|
|
(
|
|
if classof selectedObject == Editable_Mesh then (
|
|
faceId = ( ( getFaceSelection selectedObject ) as array )[ 1 ]
|
|
|
|
) else if classof selectedObject == Editable_Poly then (
|
|
faceId = ( ( polyop.getFaceSelection selectedObject ) as array )[ 1 ]
|
|
)
|
|
|
|
if faceId != undefined do (
|
|
local worldUpVec = [ 0, 0, 1 ]
|
|
|
|
local faceNormal = undefined
|
|
|
|
if classof selectedObject == Editable_Mesh then (
|
|
faceNormal = in coordsys selectedObject ( getFaceNormal selectedObject faceId )
|
|
|
|
) else if classof selectedObject == Editable_Poly then (
|
|
faceNormal = in coordsys selectedObject ( polyop.getFaceNormal selectedObject faceId )
|
|
)
|
|
|
|
local rightVec = normalize ( cross worldUpVec faceNormal )
|
|
local upVec = normalize ( cross rightVec faceNormal )
|
|
|
|
local normalMatrix = matrix3 rightVec upVec faceNormal [ 0, 0, 0 ]
|
|
|
|
local uvMod = Uvwmap()
|
|
uvMod.length = vLength
|
|
uvMod.width = uWidth
|
|
uvMod.height = uWidth
|
|
uvMod.utile = uWidth
|
|
uvMod.vtile = vLength
|
|
uvMod.maptype = uvwProjectionType
|
|
|
|
modPanel.addModToSelection uvMod ui:on
|
|
uvMod.gizmo.transform = normalMatrix
|
|
|
|
collapseStack selectedObject
|
|
|
|
local uvwUnwrapMod = Unwrap_UVW()
|
|
subobjectLevel = 4
|
|
modpanel.addmodtoselection uvwUnwrapMod
|
|
subobjectLevel = 3
|
|
uvwUnwrapMod.unwrap.edit ()
|
|
)
|
|
)
|
|
else
|
|
(
|
|
if classof selectedObject == Editable_Mesh then (
|
|
faceId = ( ( getFaceSelection selectedObject ) as array )[ 1 ]
|
|
|
|
) else if classof selectedObject == Editable_Poly then (
|
|
faceId = ( ( polyop.getFaceSelection selectedObject ) as array )[ 1 ]
|
|
)
|
|
|
|
if faceId != undefined do (
|
|
local worldUpVec = [ 0, 0, 1 ]
|
|
|
|
local faceNormal = undefined
|
|
|
|
if classof selectedObject == Editable_Mesh then (
|
|
faceNormal = in coordsys selectedObject ( getFaceNormal selectedObject faceId )
|
|
|
|
) else if classof selectedObject == Editable_Poly then (
|
|
faceNormal = in coordsys selectedObject ( polyop.getFaceNormal selectedObject faceId )
|
|
)
|
|
|
|
local rightVec = normalize ( cross worldUpVec faceNormal )
|
|
local upVec = normalize ( cross rightVec faceNormal )
|
|
|
|
-- Always project with z up and x forward from the face.
|
|
local normalMatrix = matrix3 faceNormal rightVec [0,0,1] [ 0, 0, 0 ]
|
|
local uvMod = Uvwmap()
|
|
|
|
-- make the length and width equal because of the box map. Height is new length.
|
|
uvMod.length = uWidth
|
|
uvMod.width = uWidth
|
|
uvMod.height = vLength
|
|
|
|
uvMod.utile = uWidth
|
|
uvMod.vtile = vLength
|
|
uvMod.wtile = vLength
|
|
uvMod.maptype = uvwProjectionType
|
|
|
|
modPanel.addModToSelection uvMod ui:on
|
|
uvMod.gizmo.transform = normalMatrix
|
|
|
|
|
|
collapseStack selectedObject
|
|
|
|
local uvwUnwrapMod = Unwrap_UVW()
|
|
subobjectLevel = 4
|
|
modpanel.addmodtoselection uvwUnwrapMod
|
|
subobjectLevel = 3
|
|
uvwUnwrapMod.unwrap.edit ()
|
|
|
|
)
|
|
)
|
|
|
|
)
|
|
)
|
|
)
|
|
|
|
fn changeProjectionType senderControl e=
|
|
(
|
|
uvwProjectionType = getProperty senderControl "Tag" as Integer
|
|
)
|
|
|
|
fn projectUVToolCreatUI =
|
|
(
|
|
local panelOffset = 40
|
|
local mainForm = dotNetObject "maxCustomControls.maxForm"
|
|
mainForm.Size = dotNetObject "System.Drawing.Size" 264 (96 + panelOffset)
|
|
mainForm.Location = dotNetObject "System.Drawing.Point" 0 0
|
|
mainForm.Text = "UV Structure Mapper"
|
|
|
|
|
|
--======== ADD THE BANNER TO THE TOOL =================--
|
|
local rsBannerPanel = dotNetObject "Panel"
|
|
rsBannerPanel.Dock = rsBannerPanel.Dock.Top
|
|
local banner = makeRsBanner dn_Panel:rsBannerPanel width:250 wiki:"SD_UV_Structure_Mapper" filename:(getThisScriptFilename())
|
|
banner.setup()
|
|
|
|
mainForm.Controls.Add rsBannerPanel
|
|
--==========================================================--
|
|
|
|
|
|
-- Create elements of the base form.
|
|
--Main Panel
|
|
local mainPanel = dotNetObject "System.Windows.Forms.Panel"
|
|
mainPanel.Dock = dockStyle_Fill
|
|
mainPanel.Size = dotNetObject "System.Drawing.Size" 242 7
|
|
mainPanel.Location = dotNetObject "System.Drawing.Point"3 (48 + panelOffset)
|
|
mainPanel.BorderStyle = (dotNetClass "System.Windows.Forms.BorderStyle").FixedSingle
|
|
|
|
|
|
local titleLabel = dotNetObject "System.Windows.Forms.Label"
|
|
titleLabel.Text = "Texture Types"
|
|
titleLabel.Width = 80
|
|
titleLabel.Height = 18
|
|
titleLabel.Location = dotNetObject "System.Drawing.Point" 25 (40 + panelOffset)
|
|
titleLabel.ForeColor = (dotnetclass "system.drawing.color").white
|
|
titleLabel.BorderStyle = (dotNetClass "System.Windows.Forms.BorderStyle").FixedSingle
|
|
mainForm.Controls.Add titleLabel
|
|
|
|
local titleLabel2 = dotNetObject "System.Windows.Forms.Label"
|
|
titleLabel2.Text = "Project UV Map"
|
|
titleLabel2.Width = 85
|
|
titleLabel2.Height = 15
|
|
titleLabel2.Location = dotNetObject "System.Drawing.Point" 155 (40 + panelOffset)
|
|
titleLabel2.ForeColor = (dotnetclass "system.drawing.color").white
|
|
titleLabel2.BorderStyle = (dotNetClass "System.Windows.Forms.BorderStyle").FixedSingle
|
|
mainForm.Controls.Add titleLabel2
|
|
|
|
|
|
|
|
--=======================
|
|
local radioGroup = dotNetObject "System.Windows.Forms.GroupBox"
|
|
radioGroup.Width = 150
|
|
radioGroup.Height = 35
|
|
radioGroup.Location = dotNetObject "System.Drawing.Point" 8 35
|
|
radioGroup.Text = "Projection Type"
|
|
radioGroup.ForeColor = (dotnetclass "system.drawing.color").white
|
|
mainForm.Controls.Add radioGroup
|
|
dotNet.setLifetimeControl radioGroup #dotNet
|
|
|
|
local rdoProjectionType0 = dotNetObject "System.Windows.Forms.RadioButton"
|
|
rdoProjectionType0.Text = "Planar"
|
|
rdoProjectionType0.Width = 60
|
|
rdoProjectionType0.Height = 15
|
|
rdoProjectionType0.Checked = True
|
|
rdoProjectionType0.Location = dotNetObject "System.Drawing.Point" 5 14
|
|
rdoProjectionType0.Tag = 0
|
|
radioGroup.Controls.Add rdoProjectionType0
|
|
dotNet.AddEventHandler rdoProjectionType0 "Click" changeProjectionType
|
|
dotNet.setLifetimeControl rdoProjectionType0 #dotNet
|
|
|
|
local rdoProjectionType4 = dotNetObject "System.Windows.Forms.RadioButton"
|
|
rdoProjectionType4.Text = "Box"
|
|
rdoProjectionType4.Width = 60
|
|
rdoProjectionType4.Height = 15
|
|
rdoProjectionType4.Location = dotNetObject "System.Drawing.Point" 80 14
|
|
rdoProjectionType4.Tag = 4
|
|
radioGroup.Controls.Add rdoProjectionType4
|
|
dotNet.AddEventHandler rdoProjectionType4 "Click" changeProjectionType
|
|
dotNet.setLifetimeControl rdoProjectionType4 #dotNet
|
|
--=========================
|
|
|
|
local settingsXMLFile = loadTextureSettingsXML()
|
|
|
|
local lineIndex = 20
|
|
|
|
local buttonArray = #()
|
|
local labelArray = #()
|
|
--local buttonNameArray = #("X/Y", "Z")
|
|
local buttonNameArray = #("MAP")
|
|
|
|
for xmlLine in settingsXMLFile do
|
|
(
|
|
|
|
for i = 1 to buttonNameArray.count do
|
|
(
|
|
append labelArray (dotNetObject "Label")
|
|
local labelIndex = labelArray.count
|
|
|
|
-- lets use the labels to display the type of texture setting
|
|
|
|
labelArray[labelIndex] = dotNetObject "System.Windows.Forms.Label"
|
|
labelArray[labelIndex] .Text = xmlLine[1]
|
|
labelArray[labelIndex] .Width = 140
|
|
labelArray[labelIndex] .Location = dotNetObject "System.Drawing.Point" 10 (lineIndex - 5)
|
|
mainPanel.Controls.Add labelArray[labelIndex]
|
|
|
|
append buttonArray (dotNetObject "Button")
|
|
buttonArrayIndex = buttonArray.count
|
|
|
|
buttonArray[buttonArrayIndex].Width = 65
|
|
buttonArray[buttonArrayIndex].Height = 25
|
|
buttonArray[buttonArrayIndex].Text = (buttonNameArray[i])
|
|
buttonArray[buttonArrayIndex].FlatStyle = dotNetObject "System.Windows.Forms.FlatStyle" Flat
|
|
buttonArray[buttonArrayIndex].FlatAppearance.BorderColor = (dotnetclass "system.drawing.color").gray
|
|
buttonArray[buttonArrayIndex].Location = dotNetObject "System.Drawing.Point" (((i - 1) * 68) + 30 + labelArray[labelIndex].Width) (lineIndex - 12)
|
|
|
|
-- add the xml elements we found to the tag to use as "arguments" in the click callback
|
|
buttonArray[buttonArrayIndex].Tag = (xmlLine[2] + " " + xmlLine[3] + " " + (i) as string)
|
|
|
|
dotNet.AddEventHandler buttonArray[buttonArrayIndex] "Click" projectUVFromSetting
|
|
dotNet.setLifetimeControl buttonArray[buttonArrayIndex] #dotNet
|
|
mainPanel.Controls.Add buttonArray[buttonArrayIndex]
|
|
)
|
|
|
|
lineIndex = lineIndex + 32
|
|
mainPanel.Height += 32
|
|
mainForm.Height += 32
|
|
)
|
|
|
|
|
|
|
|
mainForm.Controls.Add mainPanel
|
|
|
|
--Display the user interface.
|
|
mainForm.showModeless()
|
|
|
|
return mainForm
|
|
)
|
|
|
|
|
|
projectUVToolInstance = projectUVToolCreatUI()
|
|
)
|
|
|
|
|
|
|