/// <summary> /// Process an input runtime layer. /// </summary> /// <param name="ranged">The current ranged layer.</param> /// <param name="layer">The current runtime layer.</param> /// <param name="input">The input runtime layer.</param> /// <returns>The input ranged layer.</returns> private static RangedLayer ProcessInput(RangedLayer currentRanged, RuntimeLayer currentRuntime, RuntimeLayer inputRuntime) { // Set up the new ranged layer. var inputRanged = new RangedLayer(); inputRanged.X = currentRanged.X; inputRanged.Y = currentRanged.Y; inputRanged.Z = currentRanged.Z; inputRanged.Width = currentRanged.Width; inputRanged.Height = currentRanged.Height; inputRanged.Depth = currentRanged.Depth; inputRanged.Layer = inputRuntime; // Determine if we need to adjust the width, height and depth. if (currentRuntime.Algorithm.InputWidthAtHalfSize[0]) { inputRanged.Width = CreateDivideByTwo(inputRanged.Width); } if (currentRuntime.Algorithm.InputHeightAtHalfSize[0]) { inputRanged.Height = CreateDivideByTwo(inputRanged.Height); } if (currentRuntime.Algorithm.InputDepthAtHalfSize[0]) { inputRanged.Depth = CreateDivideByTwo(inputRanged.Depth); } // Determine if we need to adjust the X, Y or Z offsets. if (currentRuntime.Algorithm.RequiredXBorder[0] > 0) { inputRanged.X = CreateSubtraction(inputRanged.X, currentRuntime.Algorithm.RequiredXBorder[0]); //inputRanged.Width = CreateAddition(inputRanged.Width, currentRuntime.Algorithm.RequiredXBorder * 2); } if (currentRuntime.Algorithm.RequiredYBorder[0] > 0) { inputRanged.Y = CreateSubtraction(inputRanged.Y, currentRuntime.Algorithm.RequiredYBorder[0]); //inputRanged.Height = CreateAddition(inputRanged.Height, currentRuntime.Algorithm.RequiredYBorder * 2); } if (currentRuntime.Algorithm.RequiredZBorder[0] > 0) { inputRanged.Z = CreateSubtraction(inputRanged.Z, currentRuntime.Algorithm.RequiredZBorder[0]); //inputRanged.Depth = CreateAddition(inputRanged.Depth, currentRuntime.Algorithm.RequiredZBorder * 2); } // Process inputs recursively. var inputs = inputRuntime.GetInputs(); inputRanged.Inputs = new RangedLayer[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { inputRanged.Inputs[i] = inputs[i] == null ? null : ProcessInput(inputRanged, inputRuntime, inputs[i]); } // Return the new layer. return(inputRanged); }
private static void PerformOperationRecursively(Action <RuntimeLayer> operation, RuntimeLayer layer) { operation(layer); foreach (var input in layer.GetInputs()) { if (input != null) { PerformOperationRecursively(operation, input); } } }
/// <summary> /// Initializes the ranged layer from a runtime layer. /// </summary> private static void InitializeFromRuntime(RangedLayer ranged, RuntimeLayer layer) { // Set up the initial expressions. ranged.X = new IdentifierExpression("x"); ranged.Y = new IdentifierExpression("y"); ranged.Z = new IdentifierExpression("z"); ranged.Width = new IdentifierExpression("width"); ranged.Height = new IdentifierExpression("height"); ranged.Depth = new IdentifierExpression("depth"); // Go through all of the inputs and process them. var inputs = layer.GetInputs(); ranged.Inputs = new RangedLayer[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { ranged.Inputs[i] = inputs[i] == null ? null : ProcessInput(ranged, layer, inputs[i]); } }
private static ProcessedResult CompileRuntimeLayer(RuntimeLayer layer, RangedLayer ranged, IAlgorithm parent) { // Create our own processed result; a copy of our own state plus // somewhere to accumulate code. var result = new ProcessedResult(); result.ProcessedCode = ""; // Get a reference to the algorithm that the runtime layer is using. var algorithm = layer.Algorithm; if (algorithm == null) { throw new InvalidOperationException("Attempted to compile null runtime layer!"); } var algorithmType = algorithm.GetType(); // If the runtime layer has inputs, we need to process them first. if (layer.Algorithm.InputTypes.Length > 0) { var inputs = layer.GetInputs(); result.InputVariableNames = new string[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { var inputResult = CompileRuntimeLayer(inputs[i], ranged.Inputs[i], layer.Algorithm); result.ProcessedCode += inputResult.ProcessedCode; result.InputVariableNames[i] = inputResult.OutputVariableName; result.Declarations += inputResult.Declarations; } } // Create the storage array. result.OutputVariableName = GenerateRandomIdentifier(); result.OutputVariableType = algorithm.OutputType.FullName; result.Declarations += result.OutputVariableType + "[] " + result.OutputVariableName + " = new " + result.OutputVariableType + "[__cwidth * __cheight * __cdepth];\n"; Console.WriteLine(ranged.ToString()); // Add the conditional container. string code = "if (k >= (int)((" + ranged.Z.GetText(null) + ") - z) && i >= (int)((" + ranged.X.GetText(null) + ") - x) && j >= (int)((" + ranged.Y.GetText(null) + ") - y)" + " && k < " + ranged.OuterZ.GetText(null) + " && i < " + ranged.OuterX.GetText(null) + " && j < " + ranged.OuterY.GetText(null) + @") { "; /*result.Declarations += "Console.WriteLine(\"COMPILED: \" + " + * "" + ranged.X + " + \" \" + " + * "" + ranged.Y + " + \" \" + " + * "" + ranged.Z + " + \" \" + " + * "" + ranged.Width + " + \" \" + " + * "" + ranged.Height + " + \" \" + " + * "" + ranged.Depth + ");";*/ // Refactor the method. AstBuilder astBuilder; var method = DecompileUtil.GetAlgorithmCode(algorithmType, out astBuilder); AlgorithmRefactorer.InlineMethod(algorithm, method, result.OutputVariableName, result.InputVariableNames, "__cx", "__cy", "__cz", "__cwidth", "__cheight", "__cdepth"); AlgorithmRefactorer.RemoveUsingStatements(astBuilder.CompilationUnit, result.UsingStatements); code += method.Body.GetText(); // Terminate the conditional container and return. code += "computations += 1;"; code += "}\n"; result.ProcessedCode += code; return(result); }
private static Bitmap Regenerate3DImageForLayer(RuntimeLayer runtimeLayer, long ox, long oy, long oz, int width, int height, int depth, IGenerator compiledLayer = null) { int owidth = width; int oheight = height; width = 128; height = 192; // this affects bitmaps and rendering and stuff :( depth = 128; // ARGHGHG FIXME Bitmap b = new Bitmap(width, height); Graphics g = Graphics.FromImage(b); g.Clear(Color.White); g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; int computations = 0; dynamic data; if (compiledLayer != null) { data = compiledLayer.GenerateData(ox, oy, oz, RenderWidth, RenderHeight, RenderDepth, out computations); } else { data = runtimeLayer.GenerateData(ox, oy, oz, RenderWidth, RenderHeight, RenderDepth, out computations); } StorageLayer parent; if (runtimeLayer.GetInputs().Length == 0) { parent = null; } else { parent = StorageAccess.FromRuntime(runtimeLayer.GetInputs()[0]); } int[] render = GetCellRenderOrder(RenderToNE, RenderWidth, RenderHeight); int ztop = runtimeLayer.Algorithm.Is2DOnly ? 1 : RenderDepth; int zbottom = 0; for (int z = zbottom; z < ztop; z++) { int rcx = width / 2 - 1; int rcy = height / 2 - 31; int rw = 2; int rh = 1; for (int i = 0; i < render.Length; i++) { // Calculate the X / Y of the tile in the grid. int x = render[i] % RenderWidth; int y = render[i] / RenderWidth; // Calculate the render position on screen. int rx = rcx + (int)((x - y) / 2.0 * rw);// (int)(x / ((RenderWidth + 1) / 2.0) * rw); int ry = rcy + (x + y) * rh - (rh / 2 * (RenderWidth + RenderHeight)) - (z - zbottom) * 1; while (true) { try { Color lc = runtimeLayer.Algorithm.GetColorForValue( parent, data[x + y * owidth + z * owidth * oheight]); SolidBrush sb = new SolidBrush(Color.FromArgb(lc.A, lc.R, lc.G, lc.B)); g.FillRectangle( sb, new Rectangle(rx, ry, rw, rh) ); break; } catch (InvalidOperationException) { // Graphics can be in use elsewhere, but we don't care; just try again. } } } } return(b); }
/// <summary> /// Process an input runtime layer. /// </summary> /// <param name="ranged">The current ranged layer.</param> /// <param name="layer">The current runtime layer.</param> /// <param name="input">The input runtime layer.</param> /// <param name="idx">The index of the input layer in the parent layer.</param> /// <returns>The input ranged layer.</returns> private static RangedLayer ProcessInput( RangedLayer currentRanged, RuntimeLayer currentRuntime, RuntimeLayer inputRuntime, int idx) { // Set up the new ranged layer. var inputRanged = new RangedLayer(); inputRanged.X = currentRanged.X; inputRanged.Y = currentRanged.Y; inputRanged.Z = currentRanged.Z; inputRanged.Width = currentRanged.Width; inputRanged.Height = currentRanged.Height; inputRanged.Depth = currentRanged.Depth; inputRanged.OuterX = currentRanged.OuterX; inputRanged.OuterY = currentRanged.OuterY; inputRanged.OuterZ = currentRanged.OuterZ; inputRanged.Layer = inputRuntime; // Determine if we need to adjust the width, height and depth. if (currentRuntime.Algorithm.InputWidthAtHalfSize[idx]) { inputRanged.Width = CreateDivideByTwo(inputRanged.Width); inputRanged.OuterX = CreateDivideByTwo(inputRanged.OuterX); } if (currentRuntime.Algorithm.InputHeightAtHalfSize[idx]) { inputRanged.Height = CreateDivideByTwo(inputRanged.Height); inputRanged.OuterY = CreateDivideByTwo(inputRanged.OuterY); } if (currentRuntime.Algorithm.InputDepthAtHalfSize[idx]) { inputRanged.Depth = CreateDivideByTwo(inputRanged.Depth); inputRanged.OuterZ = CreateDivideByTwo(inputRanged.OuterZ); } // Determine if we need to adjust the X, Y or Z offsets. if (currentRuntime.Algorithm.RequiredXBorder[idx] > 0) { inputRanged.X = CreateSubtraction( inputRanged.X, currentRuntime.Algorithm.RequiredXBorder[idx]); inputRanged.Width = CreateAddition( inputRanged.Width, currentRuntime.Algorithm.RequiredXBorder[idx] * 2); inputRanged.OuterX = CreateAddition( inputRanged.OuterX, currentRuntime.Algorithm.RequiredXBorder[idx]); } if (currentRuntime.Algorithm.RequiredYBorder[idx] > 0) { inputRanged.Y = CreateSubtraction( inputRanged.Y, currentRuntime.Algorithm.RequiredYBorder[idx]); inputRanged.Height = CreateAddition( inputRanged.Height, currentRuntime.Algorithm.RequiredYBorder[idx] * 2); inputRanged.OuterY = CreateAddition( inputRanged.OuterY, currentRuntime.Algorithm.RequiredYBorder[idx]); } if (currentRuntime.Algorithm.RequiredZBorder[idx] > 0) { inputRanged.Z = CreateSubtraction( inputRanged.Z, currentRuntime.Algorithm.RequiredZBorder[idx]); inputRanged.Depth = CreateAddition( inputRanged.Depth, currentRuntime.Algorithm.RequiredZBorder[idx] * 2); inputRanged.OuterZ = CreateAddition( inputRanged.OuterZ, currentRuntime.Algorithm.RequiredZBorder[idx]); } // Process inputs recursively. var inputs = inputRuntime.GetInputs(); inputRanged.Inputs = new RangedLayer[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { inputRanged.Inputs[i] = inputs[i] == null ? null : ProcessInput(inputRanged, inputRuntime, inputs[i], i); } // Run AST visitors over the expression to simplify. inputRanged.X = AstHelpers.OptimizeExpression(inputRanged.X); inputRanged.Y = AstHelpers.OptimizeExpression(inputRanged.Y); inputRanged.Z = AstHelpers.OptimizeExpression(inputRanged.Z); inputRanged.Width = AstHelpers.OptimizeExpression(inputRanged.Width); inputRanged.Height = AstHelpers.OptimizeExpression(inputRanged.Height); inputRanged.Depth = AstHelpers.OptimizeExpression(inputRanged.Depth); inputRanged.OuterX = AstHelpers.OptimizeExpression(inputRanged.OuterX); inputRanged.OuterY = AstHelpers.OptimizeExpression(inputRanged.OuterY); inputRanged.OuterZ = AstHelpers.OptimizeExpression(inputRanged.OuterZ); // Return the new layer. return inputRanged; }
/// <summary> /// Initializes the ranged layer from a runtime layer. /// </summary> private static void InitializeFromRuntime(RangedLayer ranged, RuntimeLayer layer) { // Set up the initial expressions. ranged.X = new IdentifierExpression("x"); ranged.Y = new IdentifierExpression("y"); ranged.Z = new IdentifierExpression("z"); ranged.Layer = layer; ranged.Width = new IdentifierExpression("width"); ranged.Height = new IdentifierExpression("height"); ranged.Depth = new IdentifierExpression("depth"); ranged.OuterX = new BinaryOperatorExpression( ranged.X.Clone(), BinaryOperatorType.Add, ranged.Width.Clone()); ranged.OuterY = new BinaryOperatorExpression( ranged.Y.Clone(), BinaryOperatorType.Add, ranged.Height.Clone()); ranged.OuterZ = new BinaryOperatorExpression( ranged.Z.Clone(), BinaryOperatorType.Add, ranged.Depth.Clone()); // Go through all of the inputs and process them. var inputs = layer.GetInputs(); ranged.Inputs = new RangedLayer[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { ranged.Inputs[i] = inputs[i] == null ? null : ProcessInput(ranged, layer, inputs[i], i); } // Now we have to find the maximum values. Expression mx, my, mz, mwidth, mheight, mdepth, mouterx, moutery, mouterz; FindMaximumBounds( ranged, out mx, out my, out mz, out mwidth, out mheight, out mdepth, out mouterx, out moutery, out mouterz); // And recalculate back all of the calculation start / end values. ranged.CalculationStartI = DetermineCalculationStartForRootLayerFromMaximumBound(mx.Clone(), "x"); ranged.CalculationStartJ = DetermineCalculationStartForRootLayerFromMaximumBound(my.Clone(), "y"); ranged.CalculationStartK = DetermineCalculationStartForRootLayerFromMaximumBound(mz.Clone(), "z"); ranged.CalculationEndI = mwidth.Clone(); ranged.CalculationEndJ = mheight.Clone(); ranged.CalculationEndK = mdepth.Clone(); ranged.OffsetI = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartI, ranged.X, mx, "x"); ranged.OffsetJ = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartJ, ranged.Y, my, "y"); ranged.OffsetK = DetermineRelativeOffsetForLayerFromXYZ(ranged.CalculationStartK, ranged.Z, mz, "z"); ranged.OffsetX = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(mx.Clone(), "x"); ranged.OffsetY = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(my.Clone(), "y"); ranged.OffsetZ = DetermineAbsoluteOffsetForRootLayerFromMaximumBound(mz.Clone(), "z"); // Go through all of the inputs and backfill them. for (var i = 0; i < inputs.Length; i++) { BackfillInput(ranged, layer, ranged.Inputs[i], i, mx, my, mz); } }
private static Bitmap RenderPartial3D(RuntimeLayer layer, int sx, int sy, int sz, int width, int height, int depth) { var bitmap = new Bitmap(width * 2, height * 3); var graphics = Graphics.FromImage(bitmap); graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; int[] data; try { int computations; data = layer.GenerateData(TemporaryCrapBecauseIDidNotReallyDesignThingsVeryWell.X + sx, TemporaryCrapBecauseIDidNotReallyDesignThingsVeryWell.Y + sy, TemporaryCrapBecauseIDidNotReallyDesignThingsVeryWell.Z + sz, width, height, depth, out computations); var render = GetCellRenderOrder(RenderToNE, width, height); var ztop = layer.Algorithm.Is2DOnly ? 1 : depth; var zbottom = 0; for (var z = zbottom; z < ztop; z++) { var rcx = width / 2 - 1 + 16; var rcy = height / 2 - 15 + 32; var rw = 2; var rh = 1; for (var i = 0; i < render.Length; i++) { // Calculate the X / Y of the tile in the grid. var x = render[i] % width; var y = render[i] / width; // Calculate the render position on screen. var rx = rcx + (int)((x - y) / 2.0 * rw);// (int)(x / ((RenderWidth + 1) / 2.0) * rw); var ry = rcy + (x + y) * rh - (rh / 2 * (width + height)) - (z - zbottom) * 1; while (true) { try { Color lc; if (layer.GetInputs().Length > 0) { lc = layer.Algorithm.GetColorForValue( StorageAccess.FromRuntime(layer.GetInputs()[0]), data[x + y * width + z * width * height]); } else { lc = layer.Algorithm.GetColorForValue( null, data[x + y * width + z * width * height]); } var sb = new SolidBrush(Color.FromArgb(lc.A, lc.R, lc.G, lc.B)); graphics.FillRectangle( sb, new Rectangle(rx, ry, rw, rh) ); break; } catch (InvalidOperationException) { // Graphics can be in use elsewhere, but we don't care; just try again. } } } } } catch (Exception) { } return(bitmap); }
public static Bitmap RenderTraceResult( RuntimeLayer layer, dynamic data, int width, int height, int depth) { int owidth = width; int oheight = height; width = 128 * TraceScale; height = 128 * TraceScale; depth = 128 * TraceScale; Bitmap b = new Bitmap(width, height); Graphics g = Graphics.FromImage(b); g.Clear(Color.White); g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; StorageLayer parent; if (layer.GetInputs().Length == 0) { parent = null; } else { parent = StorageAccess.FromRuntime(layer.GetInputs()[0]); } int[] render = GetCellRenderOrder(RenderToNE, TraceRenderWidth, TraceRenderHeight); int ztop = layer.Algorithm.Is2DOnly ? 1 : 128; int zbottom = 0; for (int z = zbottom; z < ztop; z++) { int rcx = width / 2 - 1; int rcy = height / 2 - (height / 2 - 1); int rw = 2; int rh = 1; for (int i = 0; i < render.Length; i++) { // Calculate the X / Y of the tile in the grid. int x = render[i] % TraceRenderWidth; int y = render[i] / TraceRenderWidth; // Calculate the render position on screen. int rx = rcx + (int)((x - y) / 2.0 * rw);// (int)(x / ((RenderWidth + 1) / 2.0) * rw); int ry = rcy + (x + y) * rh - (rh / 2 * (TraceRenderWidth + TraceRenderHeight)) - (z - zbottom) * 1; while (true) { try { Color lc = layer.Algorithm.GetColorForValue( parent, data[x + y * owidth + z * owidth * oheight]); SolidBrush sb = new SolidBrush(Color.FromArgb(lc.A, lc.R, lc.G, lc.B)); g.FillRectangle( sb, new Rectangle(rx, ry, rw, rh) ); break; } catch (InvalidOperationException) { // Graphics can be in use elsewhere, but we don't care; just try again. } } } } return(b); }
private static ProcessedResult CompileRuntimeLayer(RuntimeLayer layer, RangedLayer ranged, IAlgorithm parent) { // Create our own processed result; a copy of our own state plus // somewhere to accumulate code. var result = new ProcessedResult(); result.ProcessedCode = string.Empty; result.InitializationCode = string.Empty; // Get a reference to the algorithm that the runtime layer is using. var algorithm = layer.Algorithm; if (algorithm == null) throw new InvalidOperationException("Attempted to compile null runtime layer!"); var algorithmType = algorithm.GetType(); // If the runtime layer has inputs, we need to process them first. var inputs = layer.GetInputs(); result.InputVariableNames = new string[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { var inputResult = CompileRuntimeLayer(inputs[i], ranged.Inputs[i], layer.Algorithm); result.ProcessedCode += inputResult.ProcessedCode; result.InitializationCode += inputResult.InitializationCode; result.InputVariableNames[i] = inputResult.OutputVariableName; result.Declarations += inputResult.Declarations; result.UsingStatements.AddRange(inputResult.UsingStatements); } // Create the storage array. result.OutputVariableName = GenerateRandomIdentifier(); result.OutputVariableType = algorithm.OutputType.FullName; result.Declarations += result.OutputVariableType + "[] " + result.OutputVariableName + " = new " + result.OutputVariableType + "[__cwidth * __cheight * __cdepth];\n"; // Add the conditional container. var code = "if (i >= " + ranged.CalculationStartI.GetText(null) + " && " + " j >= " + ranged.CalculationStartJ.GetText(null) + " && " + " k >= " + ranged.CalculationStartK.GetText(null) + " && " + " i <= " + ranged.CalculationEndI.GetText(null) + " && " + " j <= " + ranged.CalculationEndJ.GetText(null) + " && " + " k <= " + ranged.CalculationEndK.GetText(null) + ") {"; // Refactor the method. AstBuilder astBuilder; var method = DecompileUtil.GetMethodCode(algorithmType, out astBuilder, "ProcessCell"); MethodDeclaration initialize = null; try { initialize = DecompileUtil.GetMethodCode(algorithmType, out astBuilder, "Initialize"); } catch (MissingMethodException) { } AlgorithmRefactorer.InlineMethod( algorithm, method, result.OutputVariableName, result.InputVariableNames, new ParenthesizedExpression( new BinaryOperatorExpression( new BinaryOperatorExpression( new IdentifierExpression("x"), BinaryOperatorType.Add, ranged.OffsetX.Clone()), BinaryOperatorType.Add, new BinaryOperatorExpression( new IdentifierExpression("i"), BinaryOperatorType.Add, ranged.OffsetI.Clone()))), new ParenthesizedExpression( new BinaryOperatorExpression( new BinaryOperatorExpression( new IdentifierExpression("y"), BinaryOperatorType.Add, ranged.OffsetY.Clone()), BinaryOperatorType.Add, new BinaryOperatorExpression( new IdentifierExpression("j"), BinaryOperatorType.Add, ranged.OffsetJ.Clone()))), new ParenthesizedExpression( new BinaryOperatorExpression( new BinaryOperatorExpression( new IdentifierExpression("z"), BinaryOperatorType.Add, ranged.OffsetZ.Clone()), BinaryOperatorType.Add, new BinaryOperatorExpression( new IdentifierExpression("k"), BinaryOperatorType.Add, ranged.OffsetK.Clone()))), new ParenthesizedExpression( new BinaryOperatorExpression( new IdentifierExpression("i"), BinaryOperatorType.Add, ranged.OffsetI.Clone())), new ParenthesizedExpression( new BinaryOperatorExpression( new IdentifierExpression("j"), BinaryOperatorType.Add, ranged.OffsetJ.Clone())), new ParenthesizedExpression( new BinaryOperatorExpression( new IdentifierExpression("k"), BinaryOperatorType.Add, ranged.OffsetK.Clone())), new IdentifierExpression("__cwidth"), new IdentifierExpression("__cheight"), new IdentifierExpression("__cdepth"), new PrimitiveExpression(0), new PrimitiveExpression(0), new PrimitiveExpression(0)); if (initialize != null) AlgorithmRefactorer.InlineInitialize(algorithm, initialize); AlgorithmRefactorer.RemoveUsingStatements(astBuilder.CompilationUnit, result.UsingStatements); AlgorithmRefactorer.FactorOutAlgorithmFields(algorithmType, method, initialize, ref result.Declarations); code += method.Body.GetText(); // Terminate the conditional container and return. code += "computations += 1;"; code += "}\n"; result.ProcessedCode += code; if (initialize != null) result.InitializationCode += initialize.Body.GetText(); return result; }