Topographer.Renderer.Render C# (CSharp) Method

Render() public method

public Render ( ) : void
return void
        public void Render()
        {
            Point topLeft = new Point(int.MaxValue, int.MaxValue);
            Point bottomRight = new Point(int.MinValue, int.MinValue);

            if (LowerLimit > UpperLimit)
            {
                int temp = LowerLimit;
                LowerLimit = UpperLimit;
                UpperLimit = temp;
            }

            if (Only != null && Exclude != null)
            {
                foreach (byte b in Exclude)
                {
                    if (Only.Contains(b))
                        Only.Remove(b);
                }
                Exclude = null;
            }

            String[] paths = Directory.GetFiles(regionDir, "*.mca", SearchOption.TopDirectoryOnly);

            foreach (String path in paths)
            {
                Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mc[ar]");
                Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
                c.RegiontoAbsolute();
                if (c.X < topLeft.X)
                    topLeft.X = c.X;
                if (c.Z < topLeft.Y)
                    topLeft.Y = c.Z;
                c.Add(REGIONWIDTH, REGIONHEIGHT);
                if (c.X > bottomRight.X)
                    bottomRight.X = c.X;
                if (c.Z > bottomRight.Y)
                    bottomRight.Y = c.Z;
            }

            String format = String.Format("Reading region {{0}} of {0}", paths.Length);
            int count = 0;

            if (LessMemory)
            {
                int regionsWide = (bottomRight.X - topLeft.X) / REGIONWIDTH;
                int regionsTall = (bottomRight.Y - topLeft.Y) / REGIONHEIGHT;
                Point regionTopLeft = new Point(topLeft.X / REGIONWIDTH, topLeft.Y / REGIONHEIGHT);
                String[,] regions = new String[regionsWide, regionsTall];

                foreach (String path in paths)
                {
                    Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mc[ar]");
                    Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
                    c.Add(-regionTopLeft.X, -regionTopLeft.Y);
                    regions[c.X, c.Z] = path;
                }

                Bitmap strip = new Bitmap(bottomRight.X - topLeft.X, REGIONHEIGHT, PixelFormat.Format32bppArgb);
                PngWriter writer = new PngWriter(outPath, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);

                for (int y = 0; y < regionsTall; y++)
                {
                    using (Graphics g = Graphics.FromImage(strip))
                    {
                        g.Clear(Color.Transparent);
                    }

                    for (int x = 0; x < regionsWide; x++)
                    {
                        if (regions[x, y] != null)
                        {
                            count++;
                            if (updateStatus != null)
                                updateStatus(String.Format(format, count));
                            if (log != null)
                            {
                                log.Write(String.Format(format, count));
                                log.WriteLine(String.Format(" :: {0}", Path.GetFileName(regions[x, y])));
                            }

                            RegionFile region = new RegionFile(regions[x, y]);
                            Coord offset = new Coord(region.Coords);
                            offset.RegiontoAbsolute();
                            offset.X -= topLeft.X;

                            if (BiomeOverlay)
                                RenderRegionBiomes(region, strip, offset.X, 0);
                            else
                                RenderRegion(region, strip, offset.X, 0);
                        }
                    }
                    writer.WriteBitmap(strip);
                }

                writer.Close();
                strip.Dispose();
            }
            else
            {
                Bitmap map = new Bitmap(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
                foreach (String path in paths)
                {
                    count++;
                    if (updateStatus != null)
                        updateStatus(String.Format(format, count));
                    if (log != null)
                    {
                        log.Write(String.Format(format, count));
                        log.WriteLine(String.Format(" :: {0}", Path.GetFileName(path)));
                    }
                    RegionFile region = new RegionFile(path);
                    Coord offset = new Coord(region.Coords);
                    offset.RegiontoAbsolute();
                    offset.Add(-topLeft.X, -topLeft.Y);

                    if (BiomeOverlay)
                        RenderRegionBiomes(region, map, offset.X, offset.Z);
                    else
                        RenderRegion(region, map, offset.X, offset.Z);
                }

                if (CropMap)
                    map = Crop(map);
                Rotate = (Rotate % 360) / 90;
                if (Rotate == 1)
                    map.RotateFlip(RotateFlipType.Rotate90FlipNone);
                else if (Rotate == 2)
                    map.RotateFlip(RotateFlipType.Rotate180FlipNone);
                else if (Rotate == 3)
                    map.RotateFlip(RotateFlipType.Rotate270FlipNone);

                map.Save(outPath, ImageFormat.Png);
                map.Dispose();

            }

            if (updateStatus != null)
                updateStatus("Done");
            if (log != null)
                log.WriteLine("Done");
            if (callback != null)
                callback();
        }

Usage Example

Ejemplo n.º 1
0
        static void Main(String[] args)
        {
            String inPath = null;
            String outPath = null;

            bool help = false;
            bool biomeMap = false;
            String upperLimit = "255";
            String lowerLimit = "0";
            bool biomeFoliage = true;
            bool showHeight = true;
            bool transparency = true;
            bool dryRun = false;
            bool version = false;
            String rotation = "0";
            bool crop = true;
            String only = null;
            String exclude = null;
            bool lessMemory = false;

            OptionSet options = new OptionSet();
            options.Add("i|input=", "Path to directory containing *.mca region files. Can be relative to .minecraft/saves/.", delegate(String v) { inPath = v; });
            options.Add("o|output=", "Path including file name for where the output png will be saved.", delegate(String v) { outPath = v; });
            options.Add("m|map=", "\"terrain\" to generate a terrain map or \"biomes\" to generate a color-coded biome map instead. Default: \"terrain\".", delegate(String v) { biomeMap = (v == "biomes"); });
            options.Add("u|upper=", "Only render the world below this elevation, between 0 and 255. Default: 255.", delegate(String v) { upperLimit = v; });
            options.Add("l|lower=", "Only render the world down to this elevation, between 0 and 255. Default: 0.", delegate(String v) { lowerLimit = v; });
            options.Add("b|biome", "Whether blocks such as grass should have their color vary based on biome. Default: enabled. Use -b+ to enable or -b- to disable.", delegate(String v) { biomeFoliage = (v != null); });
            options.Add("h|height", "Whether colors should be made lighter or darker based on elevation. Default: enabled. Use -h+ to enable or -h- to disable.", delegate(String v) { showHeight = (v != null); });
            options.Add("t|transparency", "Whether areas beneath blocks such as water or glass should be visible. Default: enabled. Use -t+ to enable or -t- to disable.", delegate(String v) { transparency = (v != null); });
            options.Add("n|only=", "A comma separated list of block ids that will be the only type(s) of blocks rendered.", delegate(String v) { only = v; });
            options.Add("x|exclude=", "A comma separated list of block ids that will not be rendered.", delegate(String v) { exclude = v; });
            options.Add("r|rotate=", "How much the resulting map should be rotated. Valid values are 0, 90, 180, and 270. Default: 0.", delegate(String v) { rotation = v; });
            options.Add("c|crop", "If empty portions along the edges of the map should be cropped. Default: enabled. Use -c+ to enable or -c- to disable.", delegate(String v) { crop = (v != null); });
            options.Add("y|less-memory", "Generate the map in such a way that less memory is used, however cropping and rotating isn't supported. May be necessary for worlds with 100s of regions. Default: disabled. Use -y+ to enable or -y- to disable.", delegate(String v) { lessMemory = (v != null); });
            options.Add("d|dry-run", "If parameters should be parsed and any errors reported without actually doing anything.", delegate(String v) { dryRun = (v != null); });
            options.Add("?|help", "Display this help message.", delegate(String v) { help = (v != null); });
            options.Add("v|version", "Display version information.", delegate(String v) { version = (v != null); });

            options.Parse(args);

            if (version)
            {
                Console.WriteLine(String.Format("TopographerCMD (Topographer) {0}", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
                Console.WriteLine();
                Console.WriteLine("Copyright 2012 Matthew Blaine.");
                Console.WriteLine("For more details including license information, please see README.txt,");
                Console.WriteLine("LICENSE.txt, or visit https://github.com/mblaine/Topographer.");
                return;
            }

            if (help || inPath == null || outPath == null)
            {
                Console.WriteLine("Usage: TopographerCMD [OPTIONS] -i [DIRECTORY] -o [FILE]");
                Console.WriteLine("Examples:");
                Console.WriteLine("TopographerCMD /l 90 /h+ /t- -input /World1/DIM-1/region -output nether.png");
                Console.WriteLine("TopographerCMD -map=biomes -r 270 -i /World1/region -o World1.biomes.png");
                Console.WriteLine("TopographerCMD -x \"8,9,78,79\" --crop- -i /World1/region -o dry.png");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            String attempt = Path.GetFullPath(inPath);
            if (!Directory.Exists(attempt))
            {
                attempt = String.Format("{0}{1}.minecraft{1}saves{1}{2}", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Path.DirectorySeparatorChar, inPath.TrimStart(new char[] { '\\', '/' }));
                if (!Directory.Exists(attempt))
                {
                    Console.Error.WriteLine(String.Format("ERROR: Unable to find input directory \"{0}\".", inPath));
                    return;
                }
                else
                    inPath = attempt;
            }
            else
                inPath = attempt;

            outPath = Path.GetFullPath(outPath);
            attempt = Path.GetDirectoryName(outPath);
            if (!Directory.Exists(attempt))
            {
                Console.WriteLine(String.Format("ERROR: Unable to find output directory \"{0}\".", attempt));
                return;
            }

            byte upper = 255;
            byte lower = 0;
            uint rotate = 0;
            if (!biomeMap)
            {
                if (!byte.TryParse(upperLimit, out upper))
                {
                    Console.Error.WriteLine(String.Format("ERROR: Upper limit must be between 0 and 255 inclusive. Unable to parse \"{0}\".", upperLimit));
                    return;
                }

                if (!byte.TryParse(lowerLimit, out lower))
                {
                    Console.Error.WriteLine(String.Format("ERROR: Lower limit must be between 0 and 255 inclusive. Unable to parse \"{0}\".", lowerLimit));
                    return;
                }

                if (lower > upper)
                {
                    byte temp = lower;
                    lower = upper;
                    upper = temp;
                }

                if (!uint.TryParse(rotation, out rotate))
                {
                    Console.Error.WriteLine(String.Format("ERROR: Rotation must be a positive integer. Unable to parse \"{0}\".", rotation));
                    return;
                }
                else
                {
                    rotate = ((rotate % 360) / 90) * 90;
                }
            }

            HashSet<byte> onlyIds = null;
            if (only != null && only.Length > 0)
            {
                String[] ids = only.Split(new char[] { ',' });
                onlyIds = new HashSet<byte>();
                foreach (String id in ids)
                {
                    byte b;
                    if (byte.TryParse(id, out b))
                    {
                        onlyIds.Add(b);
                    }
                    else
                    {
                        Console.Error.WriteLine(String.Format("ERROR: Only must be a comma seperated list of block ids each between 0 and 255. Unable to parse\"{0}\".", id));
                        return;
                    }
                }
            }

            HashSet<byte> excludeIds = null;
            if (exclude != null && exclude.Length > 0)
            {
                String[] ids = exclude.Split(new char[] { ',' });
                excludeIds = new HashSet<byte>();
                foreach (String id in ids)
                {
                    byte b;
                    if (byte.TryParse(id, out b))
                    {
                        excludeIds.Add(b);
                    }
                    else
                    {
                        Console.Error.WriteLine(String.Format("ERROR: Exclude must be a comma seperated list of block ids each between 0 and 255. Unable to parse\"{0}\".", id));
                        return;
                    }
                }
            }

            if (onlyIds != null && excludeIds != null)
            {
                foreach (byte b in excludeIds)
                {
                    if (onlyIds.Contains(b))
                        onlyIds.Remove(b);
                }
                excludeIds = null;
            }

            Console.WriteLine(String.Format("Input: {0}", inPath));
            Console.WriteLine(String.Format("Output: {0}", outPath));
            Console.WriteLine(String.Format("Rendering: {0}", biomeMap ? "biome map" : "terrain map"));
            if (!biomeMap)
            {
                Console.WriteLine(String.Format("Rendering layers from {0} to {1}.", lower, upper));
                if (biomeFoliage)
                    Console.WriteLine("Blocks such as grass will have their color vary based on biome.");
                else
                    Console.WriteLine("Blocks such as grass will be their default color regardless of biome.");
                if (showHeight)
                    Console.WriteLine("Blocks will be lighter or darker in color depending on elevation");
                else
                    Console.WriteLine("Blocks of the same type will have the same brightness regardless of elevation.");
                if (transparency)
                    Console.WriteLine("Blocks such as water and glass will have transparency.");
                else
                    Console.WriteLine("All blocks will be opaque.");
            }

            if (onlyIds != null)
            {
                List<byte> l = new List<byte>(onlyIds);
                l.Sort();
                Console.WriteLine(String.Format("Only block ids {0} will be rendered.", String.Join<byte>(", ", l)));
            }

            if (excludeIds != null)
            {
                List<byte> l = new List<byte>(excludeIds);
                l.Sort();
                Console.WriteLine(String.Format("All blocks except block ids {0} will be rendered.", String.Join<byte>(", ", l)));
            }

            if (lessMemory)
                Console.WriteLine("The map will be generated using the algorithm that requires less memory.");
            else
                Console.WriteLine("The map will be generated using the normal algorithm.");

            if(!lessMemory && rotate > 0)
                Console.WriteLine(String.Format("Map will be rotated {0} degrees.", rotate));
            else
                Console.WriteLine("Map will not be rotated.");

            if (!lessMemory && crop)
                Console.WriteLine("Map will be cropped.");
            else
                Console.WriteLine("Map will not be cropped.");

            Renderer r = new Renderer(inPath, outPath, Console.Out);
            r.UpperLimit = upper;
            r.LowerLimit = lower;
            r.ConsiderBiomes = biomeFoliage;
            r.ShowHeight = showHeight;
            r.Transparency = transparency;
            r.BiomeOverlay = biomeMap;
            r.Only = onlyIds;
            r.Exclude = excludeIds;
            r.Rotate = rotate;
            r.CropMap = crop;
            r.LessMemory = lessMemory;

            if (dryRun)
                Console.WriteLine(String.Format("Found {0} *.mcr region files.", Renderer.GetRegionCount(inPath)));
            else
                r.Render();
        }