예제 #1
0
        public static void GenerateKulerIslandMap(List <String> files = null, int resolution = 1024, int padding = 0, string colorize = "Random", string wireframe = "None", float wirethickness = 2F)
        {
            /*  Process Walkthrough
             *  01: - collect all vertex data from each OBJ file
             *  02: - sort tris into islands for colorizing
             *  03: - create bitmaps
             */

            if (files == null || files.Count() == 0)
            {
                return;
            }

            // list containg all the file assets collected
            List <ModelAsset> Assets = new List <ModelAsset>();

            /* 01 */
            // loop through each file and collect the vertex data
            foreach (string filepath in files)
            {
                // get data from file
                if (filepath.ToLower().EndsWith(".obj"))
                {
                    ModelAsset newAsset = ReadFileOBJ(filepath: filepath);
                    newAsset.SourceFile = filepath;
                    Assets.Add(newAsset);
                    Console.WriteLine("Completed Reading OBJ File - {0}", filepath);
                }
            }

            /* 02 */
            // loop through each assets collected data and sort into UV lands
            // Matt's Algorithm
            FindIslands(Assets);

            /* 03 */
            // eventually condense into foreach loop above - john
            // Next Generate the actual bitmaps
            foreach (ModelAsset asset in Assets)
            {
                //Create bitmap with padding and crop afterwards to avoid pixels being placed out of place
                Bitmap   bitmap = new Bitmap(Convert.ToInt32(resolution), Convert.ToInt32(resolution), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                Graphics g      = Graphics.FromImage(bitmap);
                // make optional to use Alias or not Aliased
                // Set the SmoothingMode property to smooth the line.
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                // flip image on the y. UV space in 3d apps [0,0] starts in the bottom/left, images start start top/left
                g.ScaleTransform(1.0F, -1.0F);
                // Translate the drawing area accordingly
                g.TranslateTransform(0.0F, -(float)resolution);
                // clear canvas background to be black
                g.Clear(Color.Black);

                // color each island based on user settings
                for (int i = 0; i < asset.Islands.Count; i++)
                {
                    var island = asset.Islands[i];

                    // Create solid brush color based on user settings
                    Color      col   = GetRandomColor(colorize);
                    SolidBrush brush = new SolidBrush(col);

                    // draw the original fill color
                    foreach (Tri tri in island.TriList)
                    {
                        PointF   A        = ConvertUVSpaceToPixels(tri.posA, resolution, padding);
                        PointF   B        = ConvertUVSpaceToPixels(tri.posB, resolution, padding);
                        PointF   C        = ConvertUVSpaceToPixels(tri.posC, resolution, padding);
                        PointF[] Triangle = { A, B, C };
                        g.FillPolygon(brush, Triangle);

                        if (padding != 0)
                        {
                            Pen penPadding = new Pen(brush);
                            penPadding.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
                            penPadding.Width    = padding;
                            g.DrawPolygon(penPadding, Triangle);
                            penPadding.Dispose();
                        }
                    }
                    // if we don't draw wire after the fill color it will appear broken
                    if (wireframe != "None")
                    {
                        foreach (Tri tri in island.TriList)
                        {
                            PointF   A        = ConvertUVSpaceToPixels(tri.posA, resolution, padding);
                            PointF   B        = ConvertUVSpaceToPixels(tri.posB, resolution, padding);
                            PointF   C        = ConvertUVSpaceToPixels(tri.posC, resolution, padding);
                            PointF[] Triangle = { A, B, C };

                            Pen penWire = wireframe == "White" ? new Pen(Brushes.White) : new Pen(Brushes.Black);
                            penWire.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
                            penWire.Width    = wirethickness;
                            g.DrawPolygon(penWire, Triangle);
                            penWire.Dispose();
                        }
                    }
                }
                // save bitmap
                var    bmpFilepath = Path.ChangeExtension(asset.SourceFile, "_UVMap_KI.png");
                string filepath    = bmpFilepath;
                bitmap.Save(filepath, ImageFormat.Png);
                Console.WriteLine("Completed Image Creation - {0}", filepath);
            }
        }
예제 #2
0
        // returns asset with tri list contain vert positions and corresponding indices
        public static ModelAsset ReadFileOBJ(string filepath = "")
        {
            // complete asset
            ModelAsset newAsset = new ModelAsset();
            // list used to store position data from OBJ file
            List<PointF> positionList = new List<PointF>();
            // list used to store position indices from OBJ file
            List<List<int>> indicesList = new List<List<int>>();

            try
            {
                // Read each line of the file into a string array. Each element of the array is one line of the file.
                string[] lines = System.IO.File.ReadAllLines(filepath);

                // OBJ format: only collect valid UV Verts from lines which start with vt
                foreach (string line in lines)
                {
                    // TVerts - positions
                    if (line.StartsWith("vt"))
                    {
                        /*  Example Lines
                            3dsMax: vt 0.0854 0.0854 0.0000
                            Maya: vt 0.0854 0.0854 0.0000
                        */

                        // remove leading 'vt' text from each line of the file
                        char[] invalidChars = { 'v', 't', ' ' };
                        string pointString = line.TrimStart(invalidChars);

                        // remove any leading or trailing spaces
                        pointString = pointString.Trim();

                        // split each pt into it's respected parts X,Y,Z
                        string[] parts = pointString.Split(' ');

                        if (parts.Length >= 2)
                        {
                            float X = Convert.ToSingle(parts[0]);
                            float Y = Convert.ToSingle(parts[1]);
                            PointF pt = new PointF(X, Y);
                            positionList.Add(pt);
                        }
                    }
                    // TVert Indices
                    if (line.StartsWith("f "))
                    {
                        /*  Example Lines
                            3dsMax: f 1/1 2/2 3/3 4/4
                            Maya: f 1/1/1 2/2/2 3/3/3 4/4/4
                        */

                        // remove leading 'f' text from each line of the file
                        char[] invalidChars = { 'f', ' ' };
                        string pointString = line.TrimStart(invalidChars);

                        // remove any leading or trailing spaces
                        pointString = pointString.Trim();

                        // split each pt into it's respected parts A,B,C or A,B,C,D
                        string[] parts = pointString.Split(' ');

                        if (parts.Length >= 2)
                        {
                            // list containing indices collect from line of file
                            List<int> indices = new List<int>();

                            foreach (string p in parts)
                            {
                                string[] subParts = p.Split('/');
                                // the second value in the 1/1/1 is the vertex id
                                int id = Convert.ToInt32(subParts[1]);
                                indices.Add(id);
                            }

                            // generate Tri object for each tri in faces
                            // Important: offset the indices by '-1' since arrays start at 0 but indices in the OBJ files start at 1
                            // Matt@boomerlabs:: you should really do a -1 here and not bother later
                            switch (indices.Count)
                            {
                                case 3: // single tri face
                                    Tri triA = new Tri();
                                    triA.indexA = indices[0]-1;
                                    triA.indexB = indices[1]-1;
                                    triA.indexC = indices[2]-1;
                                    newAsset.TriList.Add(triA);
                                    break;
                                case 4: // quad face made of two tris
                                    Tri triB = new Tri();
                                    triB.indexA = indices[0]-1;
                                    triB.indexB = indices[1]-1;
                                    triB.indexC = indices[2]-1;
                                    newAsset.TriList.Add(triB);
                                    Tri triC = new Tri();
                                    triC.indexA = indices[2]-1;
                                    triC.indexB = indices[3]-1;
                                    triC.indexC = indices[0]-1;
                                    newAsset.TriList.Add(triC);
                                    break;
                            }
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException) { }

            // if UV coordinate data exists go through and assign positions to the Tri's
            if (positionList.Count >= 3)
            {
                foreach (var t in newAsset.TriList)
                {
                    t.posA = positionList[t.indexA];
                    t.posB = positionList[t.indexB];
                    t.posC = positionList[t.indexC];
                }
            }

            // Store the number of verts
            newAsset.numberOfVerts = positionList.Count();

            return newAsset;
        }
예제 #3
0
        // returns asset with tri list contain vert positions and corresponding indices
        public static ModelAsset ReadFileOBJ(string filepath = "")
        {
            // complete asset
            ModelAsset newAsset = new ModelAsset();
            // list used to store position data from OBJ file
            List <PointF> positionList = new List <PointF>();
            // list used to store position indices from OBJ file
            List <List <int> > indicesList = new List <List <int> >();

            try
            {
                // Read each line of the file into a string array. Each element of the array is one line of the file.
                string[] lines = System.IO.File.ReadAllLines(filepath);

                // OBJ format: only collect valid UV Verts from lines which start with vt
                foreach (string line in lines)
                {
                    // TVerts - positions
                    if (line.StartsWith("vt"))
                    {
                        /*  Example Lines
                         *  3dsMax: vt 0.0854 0.0854 0.0000
                         *  Maya: vt 0.0854 0.0854 0.0000
                         */

                        // remove leading 'vt' text from each line of the file
                        char[] invalidChars = { 'v', 't', ' ' };
                        string pointString  = line.TrimStart(invalidChars);

                        // remove any leading or trailing spaces
                        pointString = pointString.Trim();

                        // split each pt into it's respected parts X,Y,Z
                        string[] parts = pointString.Split(' ');

                        if (parts.Length >= 2)
                        {
                            float  X  = Convert.ToSingle(parts[0]);
                            float  Y  = Convert.ToSingle(parts[1]);
                            PointF pt = new PointF(X, Y);
                            positionList.Add(pt);
                        }
                    }
                    // TVert Indices
                    if (line.StartsWith("f "))
                    {
                        /*  Example Lines
                         *  3dsMax: f 1/1 2/2 3/3 4/4
                         *  Maya: f 1/1/1 2/2/2 3/3/3 4/4/4
                         */

                        // remove leading 'f' text from each line of the file
                        char[] invalidChars = { 'f', ' ' };
                        string pointString  = line.TrimStart(invalidChars);

                        // remove any leading or trailing spaces
                        pointString = pointString.Trim();

                        // split each pt into it's respected parts A,B,C or A,B,C,D
                        string[] parts = pointString.Split(' ');

                        if (parts.Length >= 2)
                        {
                            // list containing indices collect from line of file
                            List <int> indices = new List <int>();

                            foreach (string p in parts)
                            {
                                string[] subParts = p.Split('/');
                                // the second value in the 1/1/1 is the vertex id
                                int id = Convert.ToInt32(subParts[1]);
                                indices.Add(id);
                            }

                            // generate Tri object for each tri in faces
                            // Important: offset the indices by '-1' since arrays start at 0 but indices in the OBJ files start at 1
                            // Matt@boomerlabs:: you should really do a -1 here and not bother later
                            switch (indices.Count)
                            {
                            case 3:     // single tri face
                                Tri triA = new Tri();
                                triA.indexA = indices[0] - 1;
                                triA.indexB = indices[1] - 1;
                                triA.indexC = indices[2] - 1;
                                newAsset.TriList.Add(triA);
                                break;

                            case 4:     // quad face made of two tris
                                Tri triB = new Tri();
                                triB.indexA = indices[0] - 1;
                                triB.indexB = indices[1] - 1;
                                triB.indexC = indices[2] - 1;
                                newAsset.TriList.Add(triB);
                                Tri triC = new Tri();
                                triC.indexA = indices[2] - 1;
                                triC.indexB = indices[3] - 1;
                                triC.indexC = indices[0] - 1;
                                newAsset.TriList.Add(triC);
                                break;
                            }
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException) { }

            // if UV coordinate data exists go through and assign positions to the Tri's
            if (positionList.Count >= 3)
            {
                foreach (var t in newAsset.TriList)
                {
                    t.posA = positionList[t.indexA];
                    t.posB = positionList[t.indexB];
                    t.posC = positionList[t.indexC];
                }
            }

            // Store the number of verts
            newAsset.numberOfVerts = positionList.Count();

            return(newAsset);
        }