예제 #1
0
        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);
        }
예제 #3
0
            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);
            }
예제 #4
0
        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);
        }
예제 #5
0
 public static void AssemblyMain()
 {
     Global = GlobalInterface.Instance;
     Core = Global.COREInterface14;
     Class_ID = Global.Class_ID.Create(0x8217f123, 0xef980456);
     Core.AddClass(new Descriptor());
 }
예제 #6
0
        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);
        }
예제 #7
0
파일: Loader.cs 프로젝트: hunbums/Exporters
 public static void AssemblyMain()
 {
     Global   = GlobalInterface.Instance;
     Core     = Global.COREInterface14;
     Class_ID = Global.Class_ID.Create(0x8217f123, 0xef980456);
     Core.AddClass(new Descriptor());
 }
        /// <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);
        }
예제 #9
0
 static void Initialize()
 {
     if (Class_ID == null)
     {
         Class_ID = Global.Class_ID.Create(0x8217f123, 0xef980456);
         Core.AddClass(new Descriptor());
     }
 }
예제 #10
0
   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);
      }
   }
예제 #11
0
 static void Initialize()
 {
     if (global == null)
     {
         global   = GlobalInterface.Instance;
         core     = global.COREInterface14;
         Class_ID = global.Class_ID.Create(0x8217f123, 0xef980456);
         core.AddClass(new Descriptor());
     }
 }
예제 #12
0
   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);
   }
예제 #13
0
   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;
        }
예제 #21
0
 /// <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();
 }
예제 #23
0
 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);
 }
예제 #24
0
 public bool Equals(IClass_ID other)
 {
     return(partA.Equals(other.PartA) && partB.Equals(other.PartB));
 }
예제 #25
0
 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);
        }
예제 #28
0
 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);
        }
예제 #30
0
 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();
 }
예제 #32
0
        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);
        }
예제 #33
0
 /// <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;
 }
예제 #34
0
 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();
 }