public static ITriObject GetTriObjectFromNode(this IINode node, int time, out bool deleteIt) { deleteIt = false; IObject obj = node.EvalWorldState(time, true).Obj; IClass_ID triObjId = MaxGlobal.Class_ID.Create((int)BuiltInClassIDA.TRIOBJ_CLASS_ID, 0); if (obj.CanConvertToType(triObjId) != 0) { ITriObject tri = (ITriObject)obj.ConvertToType(time, triObjId); // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() if (obj != tri) { deleteIt = true; } return(tri); } else { return(null); } }
/// <summary> /// Adds the Shell modifier to the provided node (by handle). /// </summary> /// <param name="nodeHandle"> Input the node handle to add the modifier to. </param> /// <param name="shellAmount"> Input the amount of shell thickness as float. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int AddOsmShell(uint nodeHandle, float shellAmount) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IClass_ID cidOsmShell = global.Class_ID.Create(0x3b9b1a16, 0x6d84e8d0); AddOsmModifier(nodeHandle, cidOsmShell); IINode node = ip.GetINodeByHandle(nodeHandle); IModifier mod = GetModifier(node, cidOsmShell); if (mod != null) { IIParamBlock2 pb = mod.GetParamBlock(0); pb.SetValue(0, 0, shellAmount, 0); // innerAmount parameter is at index zero of the parameter block. } } catch (Exception ex) { Debug.Print(ex.Message); return(-1); } return(1); }
public Descriptor(IGlobal global) { this.global = global; // The two numbers used for class id have to be unique/random classID = global.Class_ID.Create(253674, 23564); }
public MaxSceneServerUtilityDescriptor(IGlobal global) { this.global = global; // The two numbers used for class id have to be unique/random classID = global.Class_ID.Create(681601651, 1321680997); }
public static void AssemblyMain() { Global = GlobalInterface.Instance; Core = Global.COREInterface14; Class_ID = Global.Class_ID.Create(0x8217f123, 0xef980456); Core.AddClass(new Descriptor()); }
public static bool Export_To(string _filepath) { List <IINode> nodes = GetSelection(); foreach (IINode _node in nodes) { IIDerivedObject _gObject = (IIDerivedObject)_node.ObjectRef; IClass_ID classID = maxGlobal.Class_ID.Create((uint)BuiltInClassIDA.TRIOBJ_CLASS_ID, 0); ITriObject _mObject = (ITriObject)_gObject.ObjRef.ConvertToType(0, classID); IMesh _mMesh = _mObject.Mesh; _mMesh.BuildNormals(); IIDerivedObject theObj = (IIDerivedObject)_node.ObjectRef; for (int m = 0; m < theObj.Modifiers.Count; m++) { IModifier theModifier = theObj.GetModifier(m); if (theModifier.ClassName == "Skin") { IISkin _skin = (IISkin)theModifier.GetInterface((InterfaceID)(0x00010000)); IISkinContextData _skinContext = _skin.GetContextInterface(_node); ComputeVertexData(_mMesh, _skinContext, semantic, _filepath); } } } return(true); }
/// <summary> /// Adds an object space modifier to provided node (by handle). /// </summary> /// <param name="nodeHandle"> Input the node handle to add the modifier to. </param> /// <param name="cid"> Input the class id of the modifier add. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int AddOsmModifier(uint nodeHandle, IClass_ID cid) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IINode node = ip.GetINodeByHandle(nodeHandle); IObject obj = node.ObjectRef; IIDerivedObject dobj = global.CreateDerivedObject(obj); object objMod = ip.CreateInstance(SClass_ID.Osm, cid as IClass_ID); IModifier mod = (IModifier)objMod; dobj.AddModifier(mod, null, 0); // top of stack node.ObjectRef = dobj; } catch (Exception ex) { Debug.Print(ex.Message); return(-1); } return(1); }
static void Initialize() { if (Class_ID == null) { Class_ID = Global.Class_ID.Create(0x8217f123, 0xef980456); Core.AddClass(new Descriptor()); } }
internal static void Start() { NestedLayers.classID = MaxInterfaces.Global.Class_ID.Create(CID_A, CID_B); foreach (KeyValuePair<GlobalDelegates.Delegate5, SystemNotificationCode> cb in NestedLayers.callbacks) { MaxInterfaces.Global.RegisterNotification(cb.Key, null, cb.Value); } }
static void Initialize() { if (global == null) { global = GlobalInterface.Instance; core = global.COREInterface14; Class_ID = global.Class_ID.Create(0x8217f123, 0xef980456); core.AddClass(new Descriptor()); } }
internal static void Start() { AutoInheritProperties.classID = MaxInterfaces.Global.Class_ID.Create(CID_A, CID_B); ProcLayerChanged = new GlobalDelegates.Delegate5(layerChanged); MaxInterfaces.Global.RegisterNotification(ProcLayerChanged, null, SystemNotificationCode.NodeLayerChanged); IISceneEventManager sceneEventMgr = MaxInterfaces.Global.ISceneEventManager; cbObject = new LayerCallbacks(); cbKey = sceneEventMgr.RegisterCallback(cbObject, false, 100, true); }
public static void Start() { ColorTags.classID = MaxInterfaces.Global.Class_ID.Create(CID_A, CID_B); IIColorManager colorMan = MaxInterfaces.Global.ColorManager; foreach (KeyValuePair<ColorTag, Tuple<uint, Color>> color in ColorTags.colors) { colorMan.RegisterColor(color.Value.Item1 , color.Key.ToString() , "Outliner" , color.Value.Item2); } }
/// <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()); }
/// <summary> /// Adds the Edit Mesh modifier to the provided node (by handle). /// </summary> /// <param name="nodeHandle"> Input the node handle to add the modifier to. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int AddOsmEditMesh(uint nodeHandle) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IClass_ID cidOsmEditMesh = global.Class_ID.Create(0x00050, 0); AddOsmModifier(nodeHandle, cidOsmEditMesh); } catch (Exception ex) { Debug.Print(ex.Message); return(-1); } return(1); }
public override void InternalExecute() { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; //note that global will be an instance of an abstract class. var i = global.COREInterface13; IClass_ID cid = global.Class_ID.Create((uint)BuiltInClassIDA.TEAPOT_CLASS_ID, (uint)BuiltInClassIDB.TEAPOT_CLASS_ID); object obj = i.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID); if (obj == null) { throw new Exception("Failed to create a sphere!"); } IINode n = global.COREInterface.CreateObjectNode((IObject)obj); IObject iobj = (IObject)obj; IIParamArray ps = iobj.ParamBlock; ps.SetValue(0, global.COREInterface.Time, 20.0f); n.Move(global.COREInterface.Time, global.Matrix3.Create(), global.Point3.Create(20, 20, 0), true, true, 0, true); } catch (System.Exception ex) { MessageBox.Show("Creating teapot failed: " + ex.Message); } }
/// <summary> /// Adds the Shell modifier to the provided node (by handle). /// </summary> /// <param name="nodeHandle"> Input the node handle to add the modifier to. </param> /// <param name="shellAmount"> Input the amount of shell thickness as float. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int AddOsmProoptimizer(IINode node, float VertexPercent, bool KeepNormals) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; int t = ip.Time; // classID:#(1056067556, 1496462090) IClass_ID cidOsmProoptimizer = global.Class_ID.Create(0x3EF24FE4, 0x5932330A); AddOsmModifier(node, cidOsmProoptimizer); IModifier mod = GetModifier(node, cidOsmProoptimizer); if (mod != null) { // In order to get the "Calculate" parameter to trigger the modifier to execute, we have to enable some UI elements. ip.CmdPanelOpen = true; // ensures the command panel in general is open ip.SelectNode(node, true); // Select the node to make it active ip.CommandPanelTaskMode = 2; // TASK_MODE_MODIFY. This makes the modifier panel active. // Now we can set the parameters on the modifier, and at end "calculate" the results. IIParamBlock2 pb = mod.GetParamBlock(0); pb.SetValue((int)ProOptimizerPBValues.optimizer_main_ratio, t, VertexPercent, 0); pb.SetValue((int)ProOptimizerPBValues.optimizer_options_keep_uv, t, 1, 0); pb.SetValue((int)ProOptimizerPBValues.optimizer_options_keep_normals, t, 0, 0); // There is no true way to know if this was valid/invalid for the mesh, so we check the outer level routine on triobject for changes. ** pb.SetValue((int)ProOptimizerPBValues.optimizer_main_calculate, t, 1, 0); ip.ClearNodeSelection(false); } } catch (Exception ex) { Debug.Print(ex.Message); return(-1); } return(1); }
/// <summary> /// This will return a modifier from the stack /// </summary> /// <param name="nodeToSearch"> Input node to search. </param> /// <param name="cid"> Input the class id of the modifier to find. </param> /// <returns> The found modifier or null if not found. </returns> static public IModifier GetModifier(IINode nodeToSearch, IClass_ID cid) { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IIDerivedObject dobj = nodeToSearch.ObjectRef as IIDerivedObject; while (dobj != null) { int nmods = dobj.NumModifiers; for (int i = 0; i < nmods; i++) { IModifier mod = dobj.GetModifier(i); // have to compare ClassID Parts A and B separately. The equals operator is not // implemented so it will return false even when they are equal. if ((mod.ClassID.PartA == cid.PartA) && (mod.ClassID.PartB == cid.PartB)) { return(mod); } } dobj = dobj.ObjRef as IIDerivedObject; } return(null); }
/// <summary> /// This will return a modifier from the stack /// </summary> /// <param name="nodeToSearch"> Input node to search. </param> /// <param name="cid"> Input the class id of the modifier to find. </param> /// <returns> The found modifier or null if not found. </returns> public static IModifier GetModifier(IINode nodeToSearch, IClass_ID cid) { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IIDerivedObject dobj = nodeToSearch.ObjectRef as IIDerivedObject; while (dobj != null) { int nmods = dobj.NumModifiers; for (int i = 0; i < nmods; i++) { IModifier mod = dobj.GetModifier(i); // have to compare ClassID Parts A and B separately. The equals operator is not // implemented so it will return false even when they are equal. if ((mod.ClassID.PartA == cid.PartA) && (mod.ClassID.PartB == cid.PartB)) return mod; } dobj = dobj.ObjRef as IIDerivedObject; } return null; }
/// <summary> /// Adds an object space modifier to provided node (by handle). /// </summary> /// <param name="nodeHandle"> Input the node handle to add the modifier to. </param> /// <param name="cid"> Input the class id of the modifier add. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> public static int AddOsmModifier(uint nodeHandle, IClass_ID cid) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IINode node = ip.GetINodeByHandle(nodeHandle); IObject obj = node.ObjectRef; IIDerivedObject dobj = global.CreateDerivedObject(obj); object objMod = ip.CreateInstance(SClass_ID.Osm, cid as IClass_ID); IModifier mod = (IModifier)objMod; dobj.AddModifier(mod, null, 0); // top of stack node.ObjectRef = dobj; } catch (Exception ex) { Debug.Print(ex.Message); return -1; } return 1; }
/// <summary> /// Determines if the ClassID and the BuiltInClassID are equivalent. /// </summary> public static bool Equals(IClass_ID cid, BuiltInClassIDA cidA) { return ClassIDs.Equals(cid, (uint)cidA, 0); }
public bool RemoveAppDataChunk(IClass_ID cid, SClass_ID sid, uint sbid) { throw new NotImplementedException(); }
public UtilityMeshInspectorDesc(IGlobal global) { // create a class id // this id must be unique, use the gencid.exe inside maxsdk\help for creating one UtilityMeshInspectorDesc.ms_classID = global.Class_ID.Create(0x62067494, 0x259d7195); }
public bool Equals(IClass_ID other) { return(partA.Equals(other.PartA) && partB.Equals(other.PartB)); }
public WalkingCharacterClassDesc(IGlobal global) { this.global = global; WalkingCharacterClassID = global.Class_ID.Create(0x5cd75bd2, 0xc497dd9); }
public bool IsSubClassOf(IClass_ID classID) { throw new NotImplementedException(); }
/// <summary> /// This is the routine to convert the input node to triangle faces. /// </summary> /// <param name="nodeHandle"> Input the node by handle. </param> /// <param name="convertToTri"> Input whether to convert to a tri object first. </param> /// <param name="addShell"> Input whether to add the shell modifier when finished converting to face. </param> /// <param name="shell"> Input the shell thickness amount. </param> /// <param name="addEditMesh"> Input whether to add the Edit Mesh modifier when finished converting to face. </param> /// <param name="collapseNode"> Input whether to collapse the node afterwards. </param> /// <param name="centerPivot"> Input whether to center the pivot on each new face. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int ConvertToTriangleFaces(uint nodeHandle, bool convertToTri = true, // C# now supports default parameters bool addShell = true, float shell = 0.1f, bool addEditMesh = true, bool collapseNode = true, bool centerPivot = true) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IINode node = ip.GetINodeByHandle(nodeHandle); // Get it's current object state. If a modifier has been applied, for example, // it is going to return the OS of the mesh in it's current form in the timeline. IObjectState os = node.ObjectRef.Eval(ip.Time); // Now grab the object itself. IObject objOriginal = os.Obj; // Let's make sure it is a TriObject, which is the typical kind of object with a mesh if (!objOriginal.IsSubClassOf(global.TriObjectClassID)) { // If it is NOT, see if we can convert it... if (convertToTri && objOriginal.CanConvertToType(global.TriObjectClassID) == 1) { objOriginal = objOriginal.ConvertToType(ip.Time, global.TriObjectClassID); } else { return(-1); } } // Now we should be safe to know it is a TriObject and we can cast it as such. // An exception will be thrown... ITriObject triOriginal = objOriginal as ITriObject; // Let's first setup a class ID for the type of objects are are creating. // New TriObject in this case to hold each face. IClass_ID cid = global.Class_ID.Create((uint)BuiltInClassIDA.TRIOBJ_CLASS_ID, 0); IMatrix3 mat = node.GetNodeTM(0, null); IPoint3 ptOffsetPos = node.ObjOffsetPos; IQuat quatOffsetRot = node.ObjOffsetRot; IScaleValue scaleOffsetScale = node.ObjOffsetScale; // We can grab the faces as a List and iterate them in .NET API. IMesh mesh = triOriginal.Mesh; IList <IFace> faces = triOriginal.Mesh.Faces; int nNumFaces = faces.Count; if (m_bUsingProgress) { m_ctrlProgress.PB_ProgressMaxNum = nNumFaces; } ADN_UserBreakCheck checkUserBreak = new ADN_UserBreakCheck(); int count = 0; foreach (IFace face in faces) { if (checkUserBreak.Check() == true) { return(-1); } if (m_bUsingProgress) { m_ctrlProgress.PB_ProgressCurrNum = ++count; } // Create a new TriObject for each new face. object objectNewFace = ip.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID); // Create a new node to hold it in the scene. IObject objNewFace = (IObject)objectNewFace; IINode n = global.COREInterface.CreateObjectNode(objNewFace); // Name it and ensure it is unique... string newname = "ADN-Sample-Face"; ip.MakeNameUnique(ref newname); n.Name = newname; // Based on what we created above, we can safely cast it to TriObject ITriObject triNewFace = objNewFace as ITriObject; // Setup the new TriObject with 1 face, and the vertex count from the original object's face we are processing triNewFace.Mesh.SetNumFaces(1, false, false); triNewFace.Mesh.SetNumVerts(face.V.Count(), false, false); // Finish setting up the face (always face '0' because there will only be one per object). triNewFace.Mesh.Faces[0].SetVerts(0, 1, 2); triNewFace.Mesh.Faces[0].SetEdgeVisFlags(EdgeVisibility.Vis, EdgeVisibility.Vis, EdgeVisibility.Vis); triNewFace.Mesh.Faces[0].SmGroup = 2; // Now, for each vertex, get the old face's points and store into new. for (int i = 0; i < face.V.Count(); i++) { //Get the vertex from the original object's face we are processing IPoint3 point = triOriginal.Mesh.GetVert((int)face.GetVert(i)); // Set the vertex point in the new face vertex triNewFace.Mesh.SetVert(i, point); } // make it draw. triNewFace.Mesh.InvalidateGeomCache(); if (addShell) { AddOsmShell(n.Handle, shell); } if (addEditMesh) { AddOsmEditMesh(n.Handle); } if (collapseNode) { ip.CollapseNode(n, true); } // update transform to match object being exploded. n.SetNodeTM(0, mat); n.ObjOffsetPos = ptOffsetPos; n.ObjOffsetRot = quatOffsetRot; n.ObjOffsetScale = scaleOffsetScale; n.ObjOffsetPos = ptOffsetPos; if (centerPivot) { n.CenterPivot(0, false); } } } catch (Exception) { return(-1); } return(1); }
public static bool EqualsClassID(this IClass_ID classA, IClass_ID classB) { return ((classA.PartA == classB.PartA) && (classA.PartB == classB.PartB)); }
/// <summary> /// This is the routine to convert the input node to polygon faces. /// </summary> /// <param name="nodeHandle"> Input the node by handle. </param> /// <param name="convertToTri"> Input whether to convert to a poly object first. </param> /// <param name="addShell"> Input whether to add the shell modifier when finished converting to face. </param> /// <param name="shell"> Input the shell thickness amount. </param> /// <param name="addEditMesh"> Input whether to add the Edit Mesh modifier when finished converting to face. </param> /// <param name="collapseNode"> Input whether to collapse the node afterwards. </param> /// <param name="centerPivot"> Input whether to center the pivot on each new face. </param> /// <returns> Returns 1 if successful or -1 if not. </returns> static public int ConvertToPolygonFaces(uint nodeHandle, bool convertToPoly = true, // C# now supports default parameters bool addShell = true, float shell = 0.1f, bool addEditMesh = true, bool collapseNode = true, bool centerPivot = true) { try { IGlobal global = Autodesk.Max.GlobalInterface.Instance; IInterface14 ip = global.COREInterface14; IINode node = ip.GetINodeByHandle(nodeHandle); if (node == null) { return(-1); } // Get it's current object state. If a modifier has been applied, for example, // it is going to return the OS of the mesh in it's current form in the timeline. IObjectState os = node.ObjectRef.Eval(ip.Time); // Now grab the object itself. IObject objOriginal = os.Obj; IPolyObject polyObject = objOriginal as IPolyObject; IClass_ID cid = global.Class_ID.Create((uint)BuiltInClassIDA.POLYOBJ_CLASS_ID, 0); IPolyObject polyObj = ip.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID) as IPolyObject; if (polyObject == null && convertToPoly) { if (objOriginal.CanConvertToType(global.TriObjectClassID) == 1) { objOriginal = objOriginal.ConvertToType(ip.Time, global.TriObjectClassID); } else { return(-1); } ITriObject triOriginal = objOriginal as ITriObject; polyObj.Mesh.AddTri(triOriginal.Mesh); polyObj.Mesh.FillInMesh(); polyObj.Mesh.EliminateBadVerts(0); polyObj.Mesh.MakePolyMesh(0, true); } else if (polyObject == null) { polyObj = polyObject; } else { return(-1); } IMatrix3 mat = node.GetNodeTM(0, null); IPoint3 ptOffsetPos = node.ObjOffsetPos; IQuat quatOffsetRot = node.ObjOffsetRot; IScaleValue scaleOffsetScale = node.ObjOffsetScale; // We can grab the faces as a List and iterate them in .NET API. int nNumFaces = polyObj.Mesh.FNum; if (m_bUsingProgress) { m_ctrlProgress.PB_ProgressMaxNum = nNumFaces; } ADN_UserBreakCheck checkUserBreak = new ADN_UserBreakCheck(); for (int i = 0; i < nNumFaces; i++) { if (checkUserBreak.Check() == true) { return(-1); } if (m_bUsingProgress) { m_ctrlProgress.PB_ProgressCurrNum = i; } // Create a new poly object for each new face. object objectNewFace = ip.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID); // Create a new node to hold it in the scene. IObject objNewFace = (IObject)objectNewFace; IINode n = global.COREInterface.CreateObjectNode(objNewFace); // Name it and ensure it is unique... string newname = "ADN-Sample-Face"; ip.MakeNameUnique(ref newname); n.Name = newname; // Based on what we created above, we can safely cast it to TriObject IPolyObject polyNewFace = objNewFace as IPolyObject; // Setup the new poly object with 1 face, and the vertex count from the original object's face we are processing polyNewFace.Mesh.SetNumFaces(1); polyNewFace.Mesh.SetMapNum(2); IMNFace f = polyObj.Mesh.F(i); polyNewFace.Mesh.F(0).Assign(f); IMNFace fnew = polyNewFace.Mesh.F(0); IList <int> vtx = f.Vtx; polyNewFace.Mesh.SetNumVerts(vtx.Count); for (int k = 0; k < vtx.Count; k++) { int nvindex = vtx[k]; IMNVert vert = polyObj.Mesh.V(nvindex); Debug.Print("\nVertex = " + k + ", " + nvindex); polyNewFace.Mesh.V(k).Assign(vert); fnew.Vtx[k] = k; } int nedge = nedge = polyNewFace.Mesh.SimpleNewEdge(0, 1); IMNEdge edge = polyNewFace.Mesh.E(nedge); edge.Track = -1; edge.F1 = 0; edge.F2 = -1; polyNewFace.Mesh.SetEdgeVis(nedge, true); nedge = polyNewFace.Mesh.SimpleNewEdge(1, 2); edge = polyNewFace.Mesh.E(nedge); edge.Track = -1; edge.F1 = 0; edge.F2 = -1; polyNewFace.Mesh.SetEdgeVis(nedge, true); nedge = polyNewFace.Mesh.SimpleNewEdge(2, 3); edge = polyNewFace.Mesh.E(nedge); edge.Track = -1; edge.F1 = 0; edge.F2 = -1; polyNewFace.Mesh.SetEdgeVis(nedge, true); nedge = polyNewFace.Mesh.SimpleNewEdge(3, 0); edge = polyNewFace.Mesh.E(nedge); edge.Track = -1; edge.F1 = 0; edge.F2 = -1; polyNewFace.Mesh.SetEdgeVis(nedge, true); polyNewFace.Mesh.FillInMesh(); // make it update. polyNewFace.Mesh.InvalidateGeomCache(); if (addShell) { AddOsmShell(n.Handle, shell); } if (addEditMesh) { AddOsmEditMesh(n.Handle); } if (collapseNode) { ip.CollapseNode(n, true); } // update transform to match object being exploded. n.SetNodeTM(0, mat); n.ObjOffsetPos = ptOffsetPos; n.ObjOffsetRot = quatOffsetRot; n.ObjOffsetScale = scaleOffsetScale; n.ObjOffsetPos = ptOffsetPos; if (centerPivot) { n.CenterPivot(0, false); } } } catch (Exception ex) { Debug.Print(ex.Message); return(-1); } return(1); }
public ClassIDWrapper(IClass_ID classID) { partA = classID.PartA; partB = classID.PartB; }
public void AddAppDataChunk(IClass_ID cid, SClass_ID sid, uint sbid, byte[] data) { throw new NotImplementedException(); }
public static IINode FlattenHierarchy(this IINode node) { IILayer nodeLayer = LayerUtilities.GetNodeLayer(node); if (nodeLayer != null) { Loader.Core.LayerManager.SetCurrentLayer(nodeLayer.Name); } List <IINode> children = node.NodeTree().ToList(); List <IINode> nonMeshChildren = children.Where(x => !x.IsMesh()).ToList(); List <IINode> meshChildren = children.Where(x => x.IsMesh()).ToList(); IClass_ID cid = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.SPHERE_CLASS_ID, 0); object obj = Loader.Core.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID); IINode result = Loader.Core.CreateObjectNode((IObject)obj); result.Name = node.Name; result.SetNodeTM(Loader.Core.Time, node.GetNodeTM(Loader.Core.Time, Forever)); node.ParentNode.AttachChild(result, true); string convertToEditablePoly = $"ConvertTo (maxOps.getNodeByHandle {result.Handle}) Editable_Poly"; ScriptsUtilities.ExecuteMaxScriptCommand(convertToEditablePoly); IPolyObject polyObject = result.GetPolyObjectFromNode(); IEPoly nodeEPoly = (IEPoly)polyObject.GetInterface(Loader.EditablePoly); List <IMtl> newMultiMat = new List <IMtl>(); foreach (IINode n in meshChildren) { ITriObject triObject = n.GetTriObjectFromNode(); IMesh mesh = triObject.Mesh; if (n.Mtl.IsMultiMtl) { Dictionary <IMtl, List <IFace> > matIDtoFacesMap = new Dictionary <IMtl, List <IFace> >(); ////List<int> matIDsInUse = new List<int>(); foreach (IFace face in mesh.Faces) { int faceMatID = face.MatID; IMtl mat = n.Mtl.GetSubMtl(faceMatID); if (!matIDtoFacesMap.ContainsKey(mat)) { List <IFace> facesOfMat = new List <IFace>(); matIDtoFacesMap.Add(mat, facesOfMat); } matIDtoFacesMap[mat].Add(face); } foreach (KeyValuePair <IMtl, List <IFace> > matToFaceKeyValue in matIDtoFacesMap) { IMtl faceMat = matToFaceKeyValue.Key; //get the material from the list of the multimaterial if (!newMultiMat.Contains(faceMat)) { newMultiMat.Add(faceMat); } ushort newId = (ushort)(newMultiMat.IndexOf(faceMat)); foreach (IFace face in matToFaceKeyValue.Value) { face.MatID = newId; } } } else { //IMtl currentMat = n.Mtl; //int matID = newMultiMat.IndexOf(currentMat); //if (matID == -1) //{ // newMultiMat.Add(currentMat); // ushort newId = (ushort)newMultiMat.Count; // for (int fID = 0; fID < mesh.NumFaces; fID++) // { // mesh.SetFaceMtlIndex(fID, (ushort)newId); // } //} //else //{ // for (int fID = 0; fID < mesh.NumFaces; fID++) // { // mesh.SetFaceMtlIndex(fID, (ushort)matID); // } //} } triObject.Mesh = mesh; n.ObjectRef = triObject; //bool undo = false; //nodeEPoly.EpfnAttach(n, ref undo,result, Loader.Core.Time); } IClass_ID matCid = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.MULTI_MATERIAL_CLASS_ID, 0); IMtl finalMat = (IMtl)Loader.Core.CreateInstance(SClass_ID.Material, matCid); for (int i = 0; i < newMultiMat.Count; i++) { finalMat.SetSubMtl(i, newMultiMat[i]); } finalMat.Name = "final mat"; result.Mtl = finalMat; foreach (IINode n in nonMeshChildren) { result.AttachChild(n, true); } Loader.Core.DeleteNode(node, false, false); return(result); }
/// <summary> /// Determines if the ClassID and the uints are equivalent. /// </summary> public static bool Equals(IClass_ID cid, uint cidA, uint cidB) { if (cid == null) return false; else return cid.PartA == cidA && cid.PartB == cidB; }
public MaxBridgeUtilityDescriptor(IGlobal global) { // The two numbers used for class id have to be unique/random classID = global.Class_ID.Create(118920184, 157352180); }
public IAppDataChunk GetAppDataChunk(IClass_ID cid, SClass_ID sid, uint sbid) { throw new NotImplementedException(); }