filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_XML.ms") struct RsObj ( fn MakeXMLNodeWithInnerText name parent innnerText = ( local xn_node = rsta_xml.makeNode name parent xn_node.innerText = innnerText return xn_node ), --------------------------------------------------------------------------- fn OptimizeFloat value toString:true = ( local value = if ((mod value 1) == 0) then value as integer else value return (if toString then (value as string) else value) ), --------------------------------------------------------------------------- fn point3_to_string p3 endSpace:true = ( local pX = OptimizeFloat p3.x local pY = OptimizeFloat p3.y local pZ = OptimizeFloat p3.z return (pX + "," + pY + "," + pZ) + (if endSpace then " " else "") ), --------------------------------------------------------------------------- fn string_to_point3 s = ( local bits = FilterString s "," return [bits[1] as float, bits[2] as float, bits[3] as float ] ), --------------------------------------------------------------------------- fn string_to_bool s = ( if (s == "1") do return true if (s == "true") do return true return false ), --------------------------------------------------------------------------- fn transform_to_string Trans = ( return (point3_to_string Trans.row1) + (point3_to_string Trans.row2) + (point3_to_string Trans.row3) + (point3_to_string Trans.row4 endSpace:false) ), --------------------------------------------------------------------------- fn string_to_transform s = ( local bits = filterstring s " " return (matrix3 (string_to_point3 bits[1]) (string_to_point3 bits[2]) (string_to_point3 bits[3]) (string_to_point3 bits[4])) ), --------------------------------------------------------------------------- fn colour_to_string col = ( return ((OptimizeFloat col.r) + " " + (OptimizeFloat col.g) + " " + (OptimizeFloat col.b)) ), --------------------------------------------------------------------------- fn string_to_colour s = ( local bits = FilterString s " " return (color (bits[1] as integer) (bits[2] as integer) (bits[3] as integer)) ), --------------------------------------------------------------------------- fn InnerText_To_Array xml_node = ( if (xml_node != undefined) do return FilterString xml_node.innerText " " return #() ), --------------------------------------------------------------------------- fn xmlList_to_xmlArray xml_list = ( return for i=0 to xml_list.count-1 collect xml_list.item[i] ), --------------------------------------------------------------------------- fn material_to_xml mat parent mapID: = ( local xn_mat = rsta_xml.makeNode "Material" parent local shaderClass = classof mat xn_mat.setAttribute "type" (shaderClass as string) if (mapID != unsupplied) do xn_mat.setAttribute "mapID" (mapID as string) if (shaderClass == Multimaterial) do ( for i=1 to mat.materialList.count do material_to_xml (mat.materialList[i]) xn_mat mapID:(mat.materialIDList[i]) ) if (shaderClass == Rage_Shader) do ( MakeXMLNodeWithInnerText "RagePreset" xn_mat (RstGetShaderName mat) for n=1 to (RstGetVariableCount mat) do ( local xn_rageAttr = rsta_xml.makeNode "RageAttr" xn_mat xn_rageAttr.setAttribute "name" (RstGetVariableName mat n) xn_rageAttr.setAttribute "type" (RstGetVariableType mat n) xn_rageAttr.innertext = (RstGetVariable mat n) as string ) ) return xn_subMat ), --------------------------------------------------------------------------- fn xml_to_material xml_node = ( local mat = undefined case (xml_node.getAttribute "type") of ( "Multimaterial" : ( mat = Multimaterial() xn_subMats = xml_node.SelectNodes "Material" for i=0 to xn_subMats.count-1 do ( local xn_submat = xn_subMats.item[i] local subMat = xml_to_material xn_submat mat.materialList[i+1] = subMat mat.materialIDList[i+1] = (xn_submat.getAttribute "mapID") as integer ) ) "Rage_Shader" : ( mat = Rage_Shader() RstSetShaderName mat (xml_node.selectSingleNode "RagePreset").innerText local xn_rageAttrs = xml_node.selectNodes "RageAttr" for i=0 to xn_rageAttrs.count - 1 do ( local xn_rageAttr = xn_rageAttrs.item[i] local v = xn_rageAttr.innertext case (xn_rageAttr.getAttribute "type") of ( "float" : v = v as float "vector3" : string_to_point3 vA ) RstSetVariable mat (i+1) v ) ) ) return mat ), --------------------------------------------------------------------------- fn ExportObjects objs xmlFile: = ( if (xmlFile == unsupplied) do ( xmlFile = getSaveFileName caption:"Pick export location ..." types:"RsObj File|*.xml" ) local xml_io = rsta_xml_io() xml_io.new "RsObj" local xn_objects = rsta_xml.makeNode "Objects" xml_io.Root local materials = #() for obj in objs do ( local objMesh = obj.mesh local xn_obj = rsta_xml.makeNode "Object" xn_objects xn_obj.SetAttribute "name" obj.name xn_obj.SetAttribute "transform" (transform_to_string obj.transform) local xn_maxObj = rsta_xml.makeNode "MaxObject" xn_obj MakeXMLNodeWithInnerText "WireColour" xn_maxObj (colour_to_string obj.wirecolor) local xn_geo = rsta_xml.makeNode "Geometry" xn_obj -- VERTS ------------------------------------------------------ local string_verts = "" for i=1 to objMesh.numverts do string_verts += point3_to_string (getVert objMesh i) MakeXMLNodeWithInnerText "Verts" xn_geo string_verts -- FACES ------------------------------------------------------ local string_faces = "" local string_edgeVis = "" local string_smoothGroup = "" local string_faceIDs = "" for i=1 to objMesh.numfaces do ( string_faces += point3_to_string (getFace objMesh i) string_smoothGroup += (getFaceSmoothGroup objMesh i) as string + " " string_faceIDs += (getFaceMatID objMesh i) as string + " " string_edgeVis += (if (getEdgeVis objMesh i 1) then "1" else "0") + "," string_edgeVis += (if (getEdgeVis objMesh i 2) then "1" else "0") + "," string_edgeVis += (if (getEdgeVis objMesh i 3) then "1" else "0") + " " ) MakeXMLNodeWithInnerText "Faces" xn_geo string_faces MakeXMLNodeWithInnerText "EdgeVis" xn_geo string_edgeVis MakeXMLNodeWithInnerText "SmoothingGroups" xn_geo string_smoothGroup MakeXMLNodeWithInnerText "FaceIDs" xn_geo string_faceIDs -- MAP CHANNEL ------------------------------------------ local xn_mapChannels = rsta_xml.makeNode "MapChannels" xn_obj local mapChannelCount = meshop.getNumMaps objMesh xn_mapChannels.setAttribute "count" (mapChannelCount as string) for mapCh=-2 to mapChannelCount do ( if (meshop.getMapSupport objMesh mapCh) do ( local xn_mapChannel = rsta_xml.makeNode "MapChannel" xn_mapChannels xn_mapChannel.setAttribute "channel" (mapCh as string) local mapVertsString = "" for vert=1 to (meshop.getNumMapVerts objMesh mapCh) do mapVertsString += point3_to_string (meshop.getMapVert objMesh mapCh vert) MakeXMLNodeWithInnerText "Verts" xn_mapChannel mapVertsString local mapFacesString = "" for face=1 to (meshop.getNumMapFaces objMesh mapCh) do mapFacesString += point3_to_string (meshop.getMapFace objMesh mapCh face) MakeXMLNodeWithInnerText "Faces" xn_mapChannel mapFacesString ) ) local matIndex = findItem materials obj.mat if (matIndex == 0) do ( append materials obj.mat matIndex = materials.count ) xn_obj.setAttribute "MaterialIndex" (matIndex as string) -- ATTRIBUTES -------------------------------------- local xn_attrs = rsta_xml.makeNode "RsAttrs" xn_obj for i=1 to (GetNumAttr (GetAttrClass obj)) do ( local value = GetAttr obj i if (value != (GetAttrDefault (GetAttrClass obj) i)) do ( local xn_attr = rsta_xml.makeNode "Attr" xn_attrs xn_attr.setattribute "name" (GetAttrName (GetAttrClass obj) i) xn_attr.setattribute "type" (GetAttrType (GetAttrClass obj) i) xn_attr.innerText = value as string ) ) ) -- MATERIAL ------------------------------------------------------------ local xn_mats = rsta_xml.makeNode "Materials" xml_io.root for mat in materials do material_to_xml mat xn_mats xml_io.xmlFile = xmlFile xml_io.save saveWarning:false ), --------------------------------------------------------------------------- fn ImportObjects xmlFile: objNames: transforms:true = ( local newObjects = #() if (xmlFile == unsupplied) do ( xmlFile = getOpenFileName caption:"Pick file to import..." types:"RsObj File|*.xml" ) if (doesFileExist xmlFile) do ( local xml_io = rsta_xml_io xmlFile:xmlFile local xn_objects = xmlList_to_xmlArray (xml_io.root.SelectNodes "Objects/Object") -- FILTER BY NAME if (objNames != unsupplied) do ( objNames = for n in objNames collect toLower n xn_objects = for xn_obj in xn_objects where ((findItem objNames (toLower (xn_obj.getattribute "name"))) != 0) collect xn_obj ) for xn_obj in xn_objects do ( objMesh = mesh() append newObjects objMesh objMesh.name = uniqueName (xn_obj.getAttribute "name") if (transforms) do objMesh.transform = string_to_transform (xn_obj.getAttribute "transform") objMesh.wirecolor = string_to_colour (xn_obj.selectsinglenode "MaxObject/WireColour").InnerText local xn_geo = xn_obj.selectSingleNode "Geometry" -- VERTS ---------------------------------------------- local xn_verts = xn_geo.SelectSingleNode "Verts" local verts = for vert in (FilterString xn_verts.innerText " ") collect (string_to_point3 vert) -- FACES ---------------------------------------------- local xn_faces = xn_geo.SelectSingleNode "Faces" local faces = for face in (FilterString xn_faces.innerText " ") collect (string_to_point3 face) setmesh objMesh vertices:verts faces:faces -- EDGES ----------------------------------------------- local xn_edges = xn_geo.SelectSingleNode "EdgeVis" local face_array = FilterString xn_edges.innerText " " for f=1 to face_array.count do ( local eP = FilterString (face_array[f]) "," for i=1 to 3 do setEdgeVis objMesh f i (string_to_bool ep[i]) ) -- SMOOTHING GROUPS -------------------------- local smooth_array = InnerText_To_Array (xn_geo.SelectSingleNode "SmoothingGroups") for i=1 to smooth_array.count do setFaceSmoothGroup objMesh i (smooth_array[i] as integer) -- FACE IDS ----------------------------------------------- local faceID_array = InnerText_To_Array (xn_geo.SelectSingleNode "FaceIDs") for i=1 to faceID_array.count do setFaceMatID objMesh i (faceID_array[i] as integer) -- MAP CHANNELS -------------------------------------- local xn_mapChannelsRoot = xn_obj.SelectSingleNode "MapChannels" meshop.setNumMaps objMesh ((xn_mapChannelsRoot.GetAttribute "count") as integer) for xn_channel in (xmlList_to_xmlArray (xn_mapChannelsRoot.SelectNodes "MapChannel")) do ( local ch = (xn_channel.getAttribute "channel") as integer meshop.setMapSupport objMesh ch true -- VERTS local verts = InnerText_To_Array (xn_channel.SelectSingleNode "Verts") meshop.setNumMapVerts objMesh ch verts.count for v=1 to verts.count do meshop.setMapVert objMesh ch v (string_to_point3 verts[v]) -- FACES local faces = InnerText_To_Array (xn_channel.SelectSingleNode "Faces") meshop.setNumMapFaces objMesh ch faces.count for f=1 to faces.count do meshop.setMapFace objMesh ch f (string_to_point3 faces[f]) ) -- MATERIAL ---------------------------------------------- local matIndex = (xn_obj.getAttribute "MaterialIndex") as integer local xn_Materials = xml_io.root.SelectSingleNode "Materials" local xn_material = xn_Materials.ChildNodes.Item[matIndex-1] objMesh.mat = xml_to_material xn_Materials.ChildNodes.Item[matIndex-1] -- ATTRIBUTES ---------------------------------------- local xn_rsAttrs = xn_obj.SelectSingleNode "RsAttrs" for xn_attr in (xmlList_to_xmlArray (xn_rsAttrs.SelectNodes "Attr")) do ( local attr_idx = GetAttrIndex (GetAttrClass objMesh) (xn_attr.getAttribute "name") local value = (xn_attr.innertext) case (xn_attr.getAttribute "type") of ( "bool" : value = string_to_bool value "float" : value = value as float "int" : value = value as integer ) SetAttr objMesh attr_idx value ) update objMesh ) completeRedraw() RsScaleTexturesOnSelectedObjs 1.0 (objects as array) quiet:true ) return newObjects ) ) RsObj = RsObj()