/// <summary> /// Function to specifically update Case Windows with input wedth and height parameters /// </summary> /// <param name="width">The new Width to set the Window</param> /// <param name="height">The new Height to set the Window</param> /// <returns>window count</returns> static public int UpdateWindowNodes(float width, float height) { IGlobal globalInterface = Autodesk.Max.GlobalInterface.Instance; IInterface14 coreInterface = globalInterface.COREInterface14; IINode nodeRoot = coreInterface.RootNode; m_sceneNodes.Clear(); GetSceneNodes(nodeRoot); // 3ds Max uses a class ID for all object types. This is easiest way to find specific type. // ClassID (1902665597L, 1593788199L) == 0x71685F7D, 0x5EFF4727 for casement window IClass_ID cidCasementWindow = globalInterface.Class_ID.Create(0x71685F7D, 0x5EFF4727); // Use LINQ to filter for windows only - in case scene has more than one, // but this should still give us at least one for single window scene! var sceneWindows = from node in m_sceneNodes where ((node.ObjectRef != null) && // In some cases the ObjectRef can be null for certain node types. (node.ObjectRef.ClassID.PartA == cidCasementWindow.PartA) && (node.ObjectRef.ClassID.PartB == cidCasementWindow.PartB)) select node; // Iterate the casement windws and update the hight and width parameters. foreach (IINode item in sceneWindows) { // window is using old-style ParamArray rather than newer ParamBlk2 IIParamArray pb = item.ObjectRef.ParamBlock; pb.SetValue(0, coreInterface.Time, height); // window height is at index zero. pb.SetValue(1, coreInterface.Time, width); // window width is at index one. } // If there are windows, save the window updates int status; if (sceneWindows.Count() > 0) { // The output file name must match what the Design Automation work item is specifying as output file. string full_filename = coreInterface.CurFilePath; string filename = coreInterface.CurFileName; string new_filename = full_filename.Replace(filename, "outputFile.max"); status = coreInterface.SaveToFile(new_filename, true, false); if (status == 0) //error { return(-1); } } // return how many windows were modified. return(sceneWindows.Count()); }
static public string UpdateNodes(float vertexPercent, bool keepNormals, bool collapseStack) { IGlobal globalInterface = Autodesk.Max.GlobalInterface.Instance; IInterface14 coreInterface = globalInterface.COREInterface14; // start the scene process globalInterface.TheHold.Begin(); IINode nodeRoot = coreInterface.RootNode; m_sceneNodes.Clear(); GetSceneNodes(nodeRoot); List <IINode> optimizedNodes = new List <IINode> { }; // Iterate each node in the scene file and process all meshes into ProOptimized meshes. foreach (IINode node in m_sceneNodes) { // Check for object assigned to node (could be something other than object) if (node.ObjectRef != null) { IObjectState os = node.ObjectRef.Eval(coreInterface.Time); IObject objOriginal = os.Obj; if (!objOriginal.IsSubClassOf(globalInterface.TriObjectClassID)) { // If it is NOT, see if we can convert it... if (objOriginal.CanConvertToType(globalInterface.TriObjectClassID) == 1) { objOriginal = objOriginal.ConvertToType(coreInterface.Time, globalInterface.TriObjectClassID); } else { RuntimeExecute.LogTrace("\nNode {0} Object Not Converted Error: {1}", node.NodeName, objOriginal.ObjectName); continue; } } ITriObject tri = objOriginal as ITriObject; if (tri == null) { RuntimeExecute.LogTrace("\nNode {0} Object Not Converted Error: {1}", node.NodeName, objOriginal.ObjectName); continue; } int val = tri.Mesh.NumVerts; AddOsmProoptimizer(node, vertexPercent, keepNormals); // get new mesh state os = node.ObjectRef.Eval(coreInterface.Time); tri = os.Obj as ITriObject; // ** after modifier operation we can see if success by checking if the mesh size is different than before if (val != tri.Mesh.NumVerts) { if (collapseStack) { coreInterface.CollapseNode(node, true); } optimizedNodes.Add(node); } } } int status; if (optimizedNodes.Count() > 0) { // Build result file name based on percentage used string full_filename = coreInterface.CurFilePath; string filename = coreInterface.CurFileName; vertexPercent = vertexPercent * 100; string stringVertexPercent = vertexPercent.ToString("F1"); stringVertexPercent = stringVertexPercent.Replace('.', '_'); string output = "outputFile-" + stringVertexPercent + ".max"; string new_filename = full_filename.Replace(filename, output); status = coreInterface.SaveToFile(new_filename, true, false); // setup to export as FBX as well string outputFBX = new_filename.Replace(".max", ".fbx"); string msCmdFbxExport = "exportFile \"" + outputFBX + "\" #noPrompt using:FBXEXP"; bool fbxOk = globalInterface.ExecuteMAXScriptScript(msCmdFbxExport, false, null, false); // If we changed something, put scene back for next iteration globalInterface.TheHold.Cancel(); if ((status == 0) || (fbxOk == false)) // error saving max or fbx file { return(null); } return(new_filename); } return(null); }