ChronoEngineAddin.ConvexDecomp2.SetMeshInfo C# (CSharp) Method

SetMeshInfo() public method

public SetMeshInfo ( int numfaces, int numvertexes ) : void
numfaces int
numvertexes int
return void
        public void SetMeshInfo(int numfaces, int numvertexes)
        {
            this.label_meshinfo.Text = "Original mesh: " + numfaces + " faces and " + numvertexes + " vertexes.";
        }

Usage Example

        private void button_convexdecomp_Click(object sender, EventArgs e)
        {
            ModelDoc2 swModel;
            swModel = (ModelDoc2)this.mSWApplication.ActiveDoc;
            if (swModel == null)
            {
                System.Windows.Forms.MessageBox.Show("Please open a part and select a solid body!");
                return;
            }

            SelectionMgr swSelMgr = (SelectionMgr)swModel.SelectionManager;

            if (swSelMgr.GetSelectedObjectCount2(-1) == 0)
            {
                System.Windows.Forms.MessageBox.Show("Please select one or more solid bodies!");
                return;
            }

            for (int isel = 1; isel <= swSelMgr.GetSelectedObjectCount2(-1); isel++)
            {
                if ((swSelectType_e)swSelMgr.GetSelectedObjectType3(isel, -1) != swSelectType_e.swSelSOLIDBODIES)
                {
                    System.Windows.Forms.MessageBox.Show("This function can be applied only to solid bodies! Select one or more bodies before using it.");
                    return;
                }

                bool rbody_converted = false;
                Body2 swBodyIn = (Body2)swSelMgr.GetSelectedObject6(isel, -1);

                // ----- tesselate
                Face2 swFace = null;
                Tessellation swTessellation = null;

                bool bResult = false;

                // Pass in null so the whole body will be tessellated
                swTessellation = (Tessellation)swBodyIn.GetTessellation(null);

                // Set up the Tessellation object
                swTessellation.NeedFaceFacetMap = true;
                swTessellation.NeedVertexParams = true;
                swTessellation.NeedVertexNormal = true;
                swTessellation.ImprovedQuality = true;

                int group_vstride = 0;

                // How to handle matches across common edges
                swTessellation.MatchType = (int)swTesselationMatchType_e.swTesselationMatchFacetTopology;

                // Do it
                if (swProgress != null)
                    swProgress.UpdateTitle("Tesselation process...");
                bResult = swTessellation.Tessellate();

                // Now get the facet data per face
                int[] aFacetIds;
                int iNumFacetIds;
                int[] aFinIds;
                int[] aVertexIds;
                double[] aVertexCoords1;

                int numv = swTessellation.GetVertexCount();
                int numf = swTessellation.GetFacetCount();
                int iface = 0;

                // Get all vertexes
                vhacd_CLI.Vect3D[] myvertexes = new vhacd_CLI.Vect3D[numv];
                vhacd_CLI.Triangle[] mytriangles = new vhacd_CLI.Triangle[numf];

                for (int iv = 0; iv < numv; iv++)
                {
                    if ((swProgress != null) && (iv % 200 == 0))
                        swProgress.UpdateTitle("Vertexes process: " + iv + "-th vertex ...");
                    aVertexCoords1 = (double[])swTessellation.GetVertexPoint(iv);
                    myvertexes[iv] = new vhacd_CLI.Vect3D(
                        aVertexCoords1[0],
                        aVertexCoords1[1],
                        aVertexCoords1[2] );
                }

                // Loop over faces
                swFace = (Face2)swBodyIn.GetFirstFace();

                while (swFace != null)
                {
                    aFacetIds = (int[])swTessellation.GetFaceFacets(swFace);

                    iNumFacetIds = aFacetIds.Length;

                    for (int iFacetIdIdx = 0; iFacetIdIdx < iNumFacetIds; iFacetIdIdx++)
                    {
                        if ((swProgress != null) && (iFacetIdIdx % 100 == 0))
                            swProgress.UpdateTitle("Faces process: " + iFacetIdIdx + "-th face ...");

                        aFinIds = (int[])swTessellation.GetFacetFins(aFacetIds[iFacetIdIdx]);

                        // There should always be three fins per facet
                        int iFinIdx = 0;
                        aVertexIds = (int[])swTessellation.GetFinVertices(aFinIds[iFinIdx]);
                        int ip1 = aVertexIds[0] + group_vstride;
                        iFinIdx = 1;
                        aVertexIds = (int[])swTessellation.GetFinVertices(aFinIds[iFinIdx]);
                        int ip2 = aVertexIds[0] + group_vstride;
                        iFinIdx = 2;
                        aVertexIds = (int[])swTessellation.GetFinVertices(aFinIds[iFinIdx]);
                        int ip3 = aVertexIds[0] + group_vstride;

                        mytriangles[iface] = new vhacd_CLI.Triangle(ip1, ip2, ip3);

                        iface++;
                    }
                    swFace = (Face2)swFace.GetNextFace();
                }

                group_vstride += swTessellation.GetVertexCount();

                // construct a new customer dialog
                ConvexDecomp2 myCustomerDialog = new ConvexDecomp2();
                myCustomerDialog.SetMeshInfo(numf, numv);
                // show the modal dialog
                if (myCustomerDialog.ShowDialog() == DialogResult.OK)
                {

                    // Perform convexdecomposition
                    vhacd_CLI.vhacd_CLI_wrapper myConvexDecomp = new vhacd_CLI.vhacd_CLI_wrapper();

                    myConvexDecomp.SetMesh(myvertexes, mytriangles);

                    myConvexDecomp.targetNTrianglesDecimatedMesh = myCustomerDialog.m_decimate;
                    myConvexDecomp.alpha = myCustomerDialog.m_alpha;
                    myConvexDecomp.concavity = myCustomerDialog.m_concavity;
                    myConvexDecomp.depth = myCustomerDialog.m_depht;
                    myConvexDecomp.posSampling = myCustomerDialog.m_positionsampling;
                    myConvexDecomp.angleSampling = myCustomerDialog.m_anglesampling;
                    myConvexDecomp.posRefine = myCustomerDialog.m_posrefine;
                    myConvexDecomp.angleRefine = myCustomerDialog.m_anglerefine;

                    int nhulls = myConvexDecomp.Compute(true, false);

                    Body2 myNewBody = null;
                    IPartDoc mpart = null;

                    if (myConvexDecomp.GetNClusters() > 0)
                    {
                        Configuration swConf;
                        Component2 swRootComp;

                        swConf = (Configuration)swModel.GetActiveConfiguration();
                        swRootComp = (Component2)swConf.GetRootComponent3(true);

                        if (swModel.GetType() == (int)swDocumentTypes_e.swDocPART)
                        {
                            mpart = (IPartDoc)swModel;
                        }
                    }

                    for (int nc = 0; nc < myConvexDecomp.GetNClusters(); nc++)
                    {
                        vhacd_CLI.Vect3D[] hull_vertexes = new vhacd_CLI.Vect3D[0];
                        vhacd_CLI.Triangle[] hull_triangles = new vhacd_CLI.Triangle[0];
                        int npoints = myConvexDecomp.GetClusterConvexHull(nc, ref hull_vertexes, ref hull_triangles);

                        if (mpart != null)
                        {
                            //myNewBody = (Body2)mpart.CreateNewBody();
                            myNewBody = (Body2)mpart.ICreateNewBody2();

                            for (int ihf = 0; ihf < hull_triangles.GetLength(0); ihf++)
                            {
                                double[] vPt = new double[9];
                                vPt[0] = hull_vertexes[hull_triangles[ihf].p1].X;
                                vPt[1] = hull_vertexes[hull_triangles[ihf].p1].Y;
                                vPt[2] = hull_vertexes[hull_triangles[ihf].p1].Z;
                                vPt[3] = hull_vertexes[hull_triangles[ihf].p2].X;
                                vPt[4] = hull_vertexes[hull_triangles[ihf].p2].Y;
                                vPt[5] = hull_vertexes[hull_triangles[ihf].p2].Z;
                                vPt[6] = hull_vertexes[hull_triangles[ihf].p3].X;
                                vPt[7] = hull_vertexes[hull_triangles[ihf].p3].Y;
                                vPt[8] = hull_vertexes[hull_triangles[ihf].p3].Z;
                                myNewBody.CreatePlanarTrimSurfaceDLL((Object)vPt, null);
                            }
                            bool created = myNewBody.CreateBodyFromSurfaces();
                            if (created)
                            {
                                ModelDocExtension mextension = swModel.Extension;
                                Feature mlastfeature = mextension.GetLastFeatureAdded();
                                mlastfeature.Select2(true, nc); // does not append?
                                /*  ***TO DO***
                                int materr = myNewBody.SetMaterialProperty("Default", "", "Air");
                                if (materr != 1)
                                    materr = myNewBody.SetMaterialProperty("Default", "", "Aria");
                                if (materr != 1)
                                    materr = myNewBody.SetMaterialProperty("Default", "", "Luft");
                                //if (materr != 1)
                                //    System.Windows.Forms.MessageBox.Show("Warning! could not assign 'air' material to the collision shape: " + myNewBody.Name + "\n This can affect mass computations.");
                                */
                                double[] mcolor = new double[9] { 1, 0, 0, 1, 1, 1, 0, 0.7, 0 }; //  R, G, B, Ambient, Diffuse, Specular, Shininess, Transparency, Emission
                                myNewBody.MaterialPropertyValues2 = mcolor;  // it does not work
                            }
                        }
                    } // end loop on clusters
                    /* ***TO DO***
                    // all new 'imported body' features must be grouped into a folder to avoid confusion:
                    IFeatureManager swFeatMgr = swModel.FeatureManager;
                    Feature swFeat = swFeatMgr.InsertFeatureTreeFolder2((int)swFeatureTreeFolderType_e.swFeatureTreeFolder_Containing);
                    */
                    // must force rebuild otherwise one cannot see in the design tree that an 'air' material has been added to collision bodies, etc.
                    //swModel.Rebuild((int)swRebuildOptions_e.swForceRebuildAll);
                    swModel.ForceRebuild3(false);

                } // end if user choose OK to decompose

            } // end loop on selected items
        }