Scripting Calculator Examples:

For “Projector Gradient” calculator:

  1. This calculator will build the old “Creation Workshop” style print mask based on one of the images you have uploaded. The old location that Photonic used to store uploaded files was: “/tmp/uploaddir/”
var sourceImage = javax.imageio.ImageIO.read(new java.io.File("/root/uploaddir/mask.png"));
var convertedImage = new java.awt.image.BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB);
convertedImage.getGraphics().drawImage(sourceImage, 0, 0, null);
org.area515.resinprinter.printphoto.CWConverter.convertImage(convertedImage, org.area515.resinprinter.printphoto.CWConverter.MaxIntensityDetermination.UseHighAndLowFromImage);
var rect = new java.awt.geom.Rectangle2D.Double(0, 0, sourceImage.getWidth(), sourceImage.getHeight());
new java.awt.TexturePaint(convertedImage, rect)
  1. This calculator will create a radial gradient between two different colors. Those colors should both be black and their alpha transparencies should measure between 0-completely transparent to 1-completely opaque. In the example below the colors are from 0 to .58 alpha. In the example below the gradient takes up 50%(totalSizeOfGradient * .5) of the screen size. This calculator can be generated by the output from: https://wiki.photonic3d.com/doku.php?id=mask_creator
var bulbCenter = new Packages.java.awt.geom.Point2D.Double(centerX, centerY);
var bulbFocus = new Packages.java.awt.geom.Point2D.Double(centerX, centerY);
var colors = [new Packages.java.awt.Color(0.0, 0.0, 0.0, 0.58), new Packages.java.awt.Color(0.0, 0.0, 0.0, 0.0)];
var fractions = [0.0, 1.0];
var totalSizeOfGradient = $buildPlatformXPixels > $buildPlatformYPixels?$buildPlatformXPixels:$buildPlatformYPixels;
new Packages.java.awt.RadialGradientPaint(bulbCenter, totalSizeOfGradient * .5, bulbFocus, fractions, colors, java.awt.MultipleGradientPaint.CycleMethod.NO_CYCLE);
  1. This calculator uses transparency in a PNG based on alpha levels instead of black levels as the old Creation Workshop application used to do.
var image = javax.imageio.ImageIO.read(new java.io.File("/root/uploaddir/gradientfile.png"));
var rect = new java.awt.geom.Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
new java.awt.TexturePaint(image, rect)

For “AffineTransform” Calculator:

  1. This calculator will twist your 3D figure as it prints upwards. You can play with the $CURSLICE variable in order to control the degree of “twist” that will be applied to your figure.
var currentTransform = new java.awt.geom.AffineTransform();
currentTransform.rotate(java.lang.Math.toRadians($CURSLICE));
currentTransform.translate(
   centerX-printImage.getWidth()/2,
   centerY-printImage.getHeight()/2);
currentTransform

- Let's assume you'd like to print an SVG file that has been built at 100pixels per MM. You could use the following calculator to properly scale your model to fit the calibrated settings for your printer:

java.awt.geom.AffineTransform.getScaleInstance(pixelsPerMMX * .01, pixelsPerMMY * .01)

For “Base Platform” Calculator:

- Here is a calculator that turns any 2d file into a keychain. The border around the hole and the hole itself is customizable.

var keyChainMM = {
   borderWidth: 5,
   holeDiameter: 10,
   cornerBevel: 3
};
var keyChainPixels = {
   keychainStartX: centerX - (printImage.getWidth() / 2), 
   keychainStartY: centerY - (printImage.getHeight() / 2), 
   borderWidthX: keyChainMM.borderWidth * pixelsPerMMX,
   //borderWidthY: keyChainMM.borderWidth * pixelsPerMMY,
   cornerBevelX: keyChainMM.cornerBevel * pixelsPerMMX,
   cornerBevelY: keyChainMM.cornerBevel * pixelsPerMMY,
   holeDiameterX: keyChainMM.holeDiameter * pixelsPerMMX,
   holeDiameterY: keyChainMM.holeDiameter * pixelsPerMMY,
   extrusionX: printImage.getWidth(),
   extrusionY: printImage.getHeight()
};
buildPlatformGraphics.fillRoundRect(
   keyChainPixels.keychainStartX,
   keyChainPixels.keychainStartY,
   keyChainPixels.extrusionX + keyChainPixels.holeDiameterX + keyChainPixels.borderWidthX * 2, 
   keyChainPixels.extrusionY,
   keyChainPixels.cornerBevelX, 
   keyChainPixels.cornerBevelY);
buildPlatformGraphics.setColor(java.awt.Color.BLACK);
buildPlatformGraphics.fillOval(
   keyChainPixels.keychainStartX + keyChainPixels.extrusionX + keyChainPixels.borderWidthX,
   centerY - keyChainPixels.holeDiameterY / 2,
   keyChainPixels.holeDiameterX,
   keyChainPixels.holeDiameterY);

- This calculator will create a 3D fractal for it's base platform when printing 2D images.

    //http://rembound.com/articles/drawing-mandelbrot-fractals-with-html5-canvas-and-javascript
    var maxiterations = $CURSLICE +1;
    var extrusionX = printImage.getWidth() > printImage.getHeight()?printImage.getWidth():printImage.getHeight();
    var extrusionY = extrusionX;

    // Pan and zoom parameters
    var offsetx = -extrusionX/2;
    var offsety = -extrusionY/2;
    var panx = -100;
    var pany = 0;
    var zoom = 150;
 
    // Generate the fractal image
    function generateImage() {
        // Iterate over the pixels
        for (var y=0; y<extrusionY; y++) {
            for (var x=0; x<extrusionX; x++) {
                iterate(x, y, maxiterations);
            }
        }
    }
 
    // Calculate the color of a specific pixel
    function iterate(x, y, maxiterations) {
        // Convert the screen coordinate to a fractal coordinate
        var x0 = (x + offsetx + panx) / zoom;
        var y0 = (y + offsety + pany) / zoom;
 
        // Iteration variables
        var a = 0;
        var b = 0;
        var rx = 0;
        var ry = 0;
 
        // Iterate
        var iterations = 0;
        while (iterations < maxiterations && (rx * rx + ry * ry <= 4)) {
            rx = a * a - b * b + x0;
            ry = 2 * a * b + y0;
 
            // Next iteration
            a = rx;
            b = ry;
            iterations++;
        }
 
        // Get palette color based on the number of iterations
        var color;
        if (iterations == maxiterations) {
            color = { r:255, g:255, b:255}; // Black
        } else {
            var index = Math.floor((iterations / (maxiterations-1)) * 255);
            color = {r:0, g:0, b:0};//Gray
        }
 
        // Apply the color
        buildPlatformRaster.setPixel((centerX - (extrusionX / 2) + x), (centerY - (extrusionY / 2) + y), Java.to([color.r, color.g, color.b, 255],"int[]"));
    }

generateImage();

- This calculator will generate a set of vertical pegs that are designed to test the capabilities(overhang, minimal support radius) of your printer. As you can see, the set of pegs can be customized greatly depending on what you are attempting to test. The height of the print(and thus the pegs) will be determined by platform height set in the “2D File Settings” for your printer. The 2d extrusion height of your printer should be set to 0 so that you don't actually print the 2d image. The finished product of your print will be something very similar to what is displayed on figure 4, page 5 of this paper: http://hpcg.purdue.edu/papers/Vanek14SGP.pdf

var pegSettingsMM = {
  rows: 5, 
  columns: 5, 
  fontDepth: .5,
  fontPointSize: 42,
  startingOverhangDegrees: 45,
  degreeIncrement: 1,
  pegDiameter: 3,
  pegStandHeight: 1, 
  pegStandWidth: 5,
  distanceBetweenStands: 1};

var pegStandCount = pegSettingsMM.pegStandHeight / $LayerThickness;
var fontCount = pegSettingsMM.fontDepth / $LayerThickness;
var pegSettingsPixels = {
  pegDiameterX: pegSettingsMM.pegDiameter * pixelsPerMMX,
  pegDiameterY: pegSettingsMM.pegDiameter * pixelsPerMMY,
  pegStandWidthX: pegSettingsMM.pegStandWidth * pixelsPerMMX,
  pegStandWidthY: pegSettingsMM.pegStandWidth * pixelsPerMMY,
  distanceBetweenStandsX: pegSettingsMM.distanceBetweenStands * pixelsPerMMX,
  distanceBetweenStandsY: pegSettingsMM.distanceBetweenStands * pixelsPerMMY,
  pegStandDifferenceOffsetX: ((pegSettingsMM.pegStandWidth * pixelsPerMMX) - (pegSettingsMM.pegDiameter * pixelsPerMMX)) / 2,
  pegStandDifferenceOffsetY: ((pegSettingsMM.pegStandWidth * pixelsPerMMY) - (pegSettingsMM.pegDiameter * pixelsPerMMY)) / 2
}
if ($CURSLICE < pegStandCount) {
   for (var x = 0; x < pegSettingsMM.columns; x++) {
      for (var y = 0; y < pegSettingsMM.rows; y++) {
         var overhangAngle = pegSettingsMM.startingOverhangDegrees + (y * pegSettingsMM.columns + x) * pegSettingsMM.degreeIncrement;
         var startingX = x * pegSettingsPixels.pegStandWidthX + x * pegSettingsPixels.distanceBetweenStandsX;
         var startingY = y * pegSettingsPixels.pegStandWidthY + y * pegSettingsPixels.distanceBetweenStandsY;
         buildPlatformGraphics.setColor(java.awt.Color.WHITE);
         buildPlatformGraphics.fillRect(
            startingX,
            startingY,
            pegSettingsPixels.pegStandWidthX,
            pegSettingsPixels.pegStandWidthY);
         if ($CURSLICE < fontCount) {
            buildPlatformGraphics.setColor(java.awt.Color.BLACK);
            buildPlatformGraphics.setFont(new java.awt.Font("Dialog", 0, pegSettingsMM.fontPointSize));
            buildPlatformGraphics.drawString(overhangAngle + "", startingX, startingY + pegSettingsPixels.pegStandWidthY);
         }
      }
   }
} else {
   for (var x = 0; x < pegSettingsMM.columns; x++) {
      for (var y = 0; y < pegSettingsMM.rows; y++) {
         var overhangAngle = pegSettingsMM.startingOverhangDegrees + (y * pegSettingsMM.columns + x) * pegSettingsMM.degreeIncrement;
         var singleOverhangIncrement = java.lang.Math.tan(java.lang.Math.toRadians(overhangAngle)) * $LayerThickness * pixelsPerMMX;
         var circleOffsetX = pegSettingsPixels.pegStandDifferenceOffsetX * ((x + 1) * 2 - 1);
         var circleOffsetY = pegSettingsPixels.pegStandDifferenceOffsetY * ((y + 1) * 2 - 1);
         buildPlatformGraphics.fillOval(
            circleOffsetX + (singleOverhangIncrement * ($CURSLICE - pegStandCount)) + (x * pegSettingsPixels.pegDiameterX) + (x * pegSettingsPixels.distanceBetweenStandsX),
            circleOffsetY + (y * pegSettingsPixels.pegDiameterY) + (y * pegSettingsPixels.distanceBetweenStandsY),
            pegSettingsPixels.pegDiameterX,
            pegSettingsPixels.pegDiameterY);
      }
   }
}