ADNExplodeGeometry.ADN_Utility.ConvertToTriangleFaces C# (CSharp) Method

ConvertToTriangleFaces() public static method

This is the routine to convert the input node to triangle faces.
public static ConvertToTriangleFaces ( uint nodeHandle, bool convertToTri = true, bool addShell = true, float shell = 0.1f, bool addEditMesh = true, bool collapseNode = true, bool centerPivot = true ) : int
nodeHandle uint Input the node by handle.
convertToTri bool Input whether to convert to a tri object first.
addShell bool Input whether to add the shell modifier when finished converting to face.
shell float Input the shell thickness amount.
addEditMesh bool Input whether to add the Edit Mesh modifier when finished converting to face.
collapseNode bool Input whether to collapse the node afterwards.
centerPivot bool Input whether to center the pivot on each new face.
return int
        public static 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;
        }

Usage Example

Example #1
0
        private void m_btnExplodeIt_Click(object sender, RoutedEventArgs e)
        {
            //
            IGlobal      global = Autodesk.Max.GlobalInterface.Instance;
            IInterface14 ip     = global.COREInterface14;

            this.m_pnlProgressPanel.Visibility = System.Windows.Visibility.Visible;

            try
            {
                global.TheHold.Begin();

                ADN_Utility.SetProgressControl(this);

                bool convertPoly = EI_ConvertTypePoly; // true = poly, false = tri
                bool attemptConvert;
                if (convertPoly)
                {
                    attemptConvert = EI_AttemptConvertToPoly;
                }
                else
                {
                    attemptConvert = EI_AttemptConvertToTri;
                }
                bool  addShell      = EI_AddShellModifier;
                float shellAmount   = EI_ShellAmount;
                bool  addEditMesh   = EI_AddEditMeshModifier;
                bool  collapseStack = EI_CollapseStack;
                bool  deleteNode    = EI_DeleteOriginal;

                //ip.DisableSceneRedraw();
                int stat         = 0;
                int nNumSelNodes = ip.SelNodeCount;
                m_lblTotNode.Content = nNumSelNodes.ToString();

                for (int i = 0; i < nNumSelNodes; i++)
                {
                    IINode nodeCur = ip.GetSelNode(i);
                    m_lblNodeName.Content = nodeCur.Name;
                    m_lblCurrNode.Content = i + 1;
                    if (convertPoly)
                    {
                        stat = ADN_Utility.ConvertToPolygonFaces(nodeCur.Handle, attemptConvert, addShell, shellAmount, addEditMesh, collapseStack);
                        if (stat < 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        stat = ADN_Utility.ConvertToTriangleFaces(nodeCur.Handle, attemptConvert, addShell, shellAmount, addEditMesh, collapseStack);
                        if (stat < 0)
                        {
                            break;
                        }
                    }
                }


                if (stat < 0)
                {
                    global.TheHold.Cancel();
                }
                else
                {
                    // now we need to start at the top to delete the original nodes.
                    if (deleteNode)
                    {
                        IINodeTab tabNodes = global.INodeTabNS.Create();
                        ip.GetSelNodeTab(tabNodes);
                        if (tabNodes != null)
                        {
                            ip.DeleteNodes(tabNodes, true, true, false);
                        }
                    }
                    global.TheHold.Accept("ADN-PolygonExplode");
                }

                ip.RedrawViews(0, RedrawFlags.Normal, null);
            }
            catch
            {
                global.TheHold.Cancel();
            }

            this.m_pnlProgressPanel.Visibility = System.Windows.Visibility.Hidden;
            ADN_Utility.ClearProgressControl(this);

            m_winParent.Close();
            m_bOk = true;
        }