public Schematic WriteSchematic() { Schematic finalSchematic = new Schematic(); if (mSchematic != null) { finalSchematic = new Schematic(mSchematic.GetAllVoxels()); } Console.WriteLine("[INFO] Count steps: " + mHeightmapData.Steps.Length); for (int index = 0; index < mHeightmapData.Steps.Length; index++) { Console.WriteLine("[INFO] Start parse heightmap for step : " + index); HeightmapStep step = mHeightmapData.Steps[index]; step.ValidateSettings(); step.DisplayInfo(); Bitmap bitmap = new Bitmap(new FileInfo(step.TexturePath).FullName); Bitmap bitmapColor = null; if (!string.IsNullOrEmpty(step.ColorTexturePath)) { bitmapColor = new Bitmap(new FileInfo(step.ColorTexturePath).FullName); } Schematic schematicStep = ImageUtils.WriteSchematicFromImage(bitmap, bitmapColor, step); finalSchematic = SchematicMerger.Merge(finalSchematic, schematicStep, step); } return(finalSchematic); }
public static Schematic Merge(Schematic schematicA, Schematic schematicB, HeightmapStep heightmapStep) { switch (heightmapStep.PlacementMode) { case PlacementMode.ADDITIVE: return(MergeAdditive(schematicA, schematicB)); case PlacementMode.REPLACE: return(MergeReplace(schematicA, schematicB)); case PlacementMode.SUBSTRACT: return(MergeSubstract(schematicA, schematicB)); case PlacementMode.TOP_ONLY: return(MergeTopOnly(schematicA, schematicB, heightmapStep)); default: return(MergeAdditive(schematicA, schematicB)); } }
protected override Schematic WriteSchematicMain() { if (!File.Exists(PathFile)) { Console.WriteLine("[ERROR] The file path is invalid for path : " + PathFile); return(null); } if (!string.IsNullOrEmpty(ColorPath) && !File.Exists(ColorPath)) { Console.WriteLine("[ERROR] The color path is invalid"); return(null); } Bitmap bitmap = new Bitmap(new FileInfo(PathFile).FullName); Bitmap bitmapColor = null; if (!string.IsNullOrEmpty(ColorPath)) { bitmapColor = new Bitmap(new FileInfo(ColorPath).FullName); } HeightmapStep heightmapStep = new HeightmapStep() { TexturePath = PathFile, ColorLimit = ColorLimit, ColorTexturePath = ColorPath, EnableColor = Color, Excavate = Excavate, Height = MaxHeight, Offset = 0, Reverse = false, PlacementMode = PlacementMode.ADDITIVE, RotationMode = RotationMode.Y }; return(ImageUtils.WriteSchematicFromImage(bitmap, bitmapColor, heightmapStep)); }
public static Schematic WriteSchematicIntern(Bitmap bitmap, Bitmap bitmapColor, HeightmapStep heightmapStep) { Schematic schematic = new Schematic(); Bitmap bitmapBlack = Grayscale.MakeGrayscale3(bitmap); DirectBitmap directBitmapBlack = new DirectBitmap(bitmapBlack, heightmapStep.Height); DirectBitmap directBitmap = new DirectBitmap(bitmap, 1); DirectBitmap directBitmapColor = new DirectBitmap(bitmapColor, 1); if (bitmap.Width > Schematic.MAX_WORLD_WIDTH || bitmap.Height > Schematic.MAX_WORLD_LENGTH) { throw new ArgumentException($"Image is too big (max size ${Schematic.MAX_WORLD_WIDTH}x${Schematic.MAX_WORLD_LENGTH} px)"); } using (FileToVoxCore.Utils.ProgressBar progressbar = new FileToVoxCore.Utils.ProgressBar()) { Console.WriteLine("[INFO] Started to write schematic from picture..."); Console.WriteLine("[INFO] Picture Width: " + bitmap.Width); Console.WriteLine("[INFO] Picture Height: " + bitmap.Height); int size = bitmap.Width * bitmap.Height; int i = 0; int w = bitmap.Width; int h = bitmap.Height; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { Color color = directBitmap.GetPixel(x, y); Color finalColor = !string.IsNullOrEmpty(heightmapStep.ColorTexturePath) ? directBitmapColor.GetPixel(x, y) : (heightmapStep.EnableColor) ? color : Color.White; if (color.A != 0) { if (heightmapStep.Height != 1) { if (heightmapStep.Excavate) { GenerateFromMinNeighbor(ref schematic, directBitmapBlack, w, h, finalColor, x, y, heightmapStep.Height, heightmapStep.Offset, heightmapStep.RotationMode, heightmapStep.Reverse); } else { int computeHeight = directBitmapBlack.GetHeight(x, y) + heightmapStep.Offset; AddMultipleBlocks(ref schematic, heightmapStep.Offset, computeHeight, x, y, finalColor, heightmapStep.RotationMode); } } else { AddSingleVoxel(ref schematic, x, heightmapStep.Offset, y, finalColor, heightmapStep.RotationMode, heightmapStep.Reverse); } } progressbar.Report((i++ / (float)size)); } } } Console.WriteLine("[INFO] Done."); return(schematic); }
public static Schematic WriteSchematicFromImage(Bitmap bitmap, Bitmap colorBitmap, HeightmapStep heightmapStep) { if (colorBitmap != null) { if (bitmap.Height != colorBitmap.Height || bitmap.Width != colorBitmap.Width) { throw new ArgumentException("[ERROR] Image color is not the same size of the original image"); } if (heightmapStep.ColorLimit != 256 || colorBitmap.CountColor() > 256) { Quantizer.Quantizer quantizer = new Quantizer.Quantizer(); colorBitmap = quantizer.QuantizeImage(colorBitmap, 10, 70, heightmapStep.ColorLimit); } } else if (heightmapStep.EnableColor) { if (heightmapStep.ColorLimit != 256 || bitmap.CountColor() > 256) { Quantizer.Quantizer quantizer = new Quantizer.Quantizer(); bitmap = quantizer.QuantizeImage(bitmap, 10, 70, heightmapStep.ColorLimit); } } Schematic schematic = WriteSchematicIntern(bitmap, colorBitmap, heightmapStep); return(schematic); }
private static Schematic MergeTopOnly(Schematic schematicA, Schematic schematicB, HeightmapStep step) { Console.WriteLine("[INFO] Start to merge schematic with top only mode"); List <Voxel> allVoxels = schematicA.GetAllVoxels(); List <Voxel> allVoxelsB = schematicB.GetAllVoxels(); using (ProgressBar progressbar = new ProgressBar()) { //int max = schematicA.Length * schematicA.Width; int max = allVoxels.Count + allVoxelsB.Count; int index = 0; Dictionary <int, List <int> > tops = new Dictionary <int, List <int> >(); foreach (Voxel voxel in allVoxels) { int x = voxel.X; int y = voxel.Y; int z = voxel.Z; if (x == 0 || y == 0 || z == 0) { continue; } Vector3Int position; int index2d = Schematic.GetVoxelIndex2DFromRotation(x, y, z, step.RotationMode); switch (step.RotationMode) { case RotationMode.X: position = new Vector3Int(x + 1, y, z); break; case RotationMode.Y: position = new Vector3Int(x, y + 1, z); break; case RotationMode.Z: position = new Vector3Int(x, y, z + 1); break; default: position = new Vector3Int(x, y + 1, z); break; } if (schematicA.GetColorAtVoxelIndex(position) == 0) { if (!tops.ContainsKey(index2d)) { tops[index2d] = new List <int>(); } if (step.RotationMode == RotationMode.Y) { tops[index2d].Add(y); } else if (step.RotationMode == RotationMode.X) { tops[index2d].Add(x); } else if (step.RotationMode == RotationMode.Z) { tops[index2d].Add(z); } } progressbar.Report(index++ / (double)max); } foreach (Voxel voxel in allVoxelsB) { int x = voxel.X; int y = voxel.Y; int z = voxel.Z; int index2d = Schematic.GetVoxelIndex2DFromRotation(x, y, z, step.RotationMode); if (tops.ContainsKey(index2d)) { foreach (int maxHeight in tops[index2d]) { switch (step.RotationMode) { case RotationMode.X: schematicA.AddVoxel(x + maxHeight + step.OffsetMerge, y, z, voxel.Color); break; case RotationMode.Y: schematicA.AddVoxel(x, y + maxHeight + step.OffsetMerge, z, voxel.Color); break; case RotationMode.Z: schematicA.AddVoxel(x, y, z + maxHeight + step.OffsetMerge, voxel.Color); break; } } } progressbar.Report(index++ / (double)max); } } Console.WriteLine("[INFO] Done"); return(schematicA); }