PricingDeep DiveLevel 2 - Post-Process Deep Dives

Vapor Smoothing

How to price vapor smoothing post-processing in Phasio, with volume-based and batch-amortisation Level 2 algorithms.

What this process does

Vapor smoothing uses a controlled solvent atmosphere (temperature + pressure) to reflow the outer surface of plastic parts. The result is a smooth, semi-glossy, near-watertight surface without material removal.

Key process characteristics for pricing:

  • Batch process: a chamber holds N parts per cycle, typically 20-60 minutes per cycle
  • Cost is primarily machine time + solvent consumption, not part-specific
  • Larger parts consume more solvent and may displace smaller parts from the batch
  • Parts are priced individually at Level 2, but the underlying cost is batch-level

How to model it

Three approaches, in order of increasing accuracy:

1. Flat rate per part (simplest - use when parts are consistently similar in size)

2. Volume-based (better - larger parts consume more solvent and chamber space)

3. Batch amortisation (most accurate - but requires estimating how many parts share a run)

For most shops, approach 2 is the right balance of accuracy and simplicity.


Level 2 algorithm - volume-based

const { area } = specification

// Surface volume proxy: area × 1mm shell depth → mm3, then /1000 for cm3
const surfaceVolumeCm3 = (area * 1) / 1000
const ratePerCm3 = variable('Rate per cm3', 0.25)
const MIN_CHARGE = variable('Minimum charge', 8.00)

const calculatedCost = round(surfaceVolumeCm3 * ratePerCm3, 2)
const unitPrice = variable('unitPrice', Math.max(MIN_CHARGE, calculatedCost))
done(unitPrice, 2)  // constant 2 hours per part

Level 2 algorithm - batch amortisation

If you want to reflect batch economics precisely, calculate how many parts fit in a single chamber run and split the run cost across them:

/**
 * Post-Processing Equation: Vapor Smoothing
 * Pay for chamber space used across all runs
 */
const { width, height, length } = specification
const { quantity } = requisition

// Parameters — adjust to your machine
const costPerRun = 150
const chamberX = 100, chamberY = 150, chamberZ = 200
const spacing = 5

// Calculate max parts per run: test all 6 orientations, take the best fit
const orientations = [
  [width, height, length], [width, length, height],
  [height, length, width], [height, width, length],
  [length, width, height], [length, height, width]
]
const partsPerRun = Math.max(1, ...orientations.map(([w, h, l]) =>
  Math.floor(chamberX / (w + spacing)) * Math.floor(chamberY / (h + spacing)) * Math.floor(chamberZ / (l + spacing))
))

// Expose key values for per-order override
const capacity = variable('Parts per run', partsPerRun)
const runCost  = variable('Cost per run', costPerRun)

// Unit price = total runs × run cost, spread across quantity
const finalUnitPrice = variable('finalUnitPrice', round((quantity / capacity) * runCost / quantity, 2))

done(finalUnitPrice, Math.ceil(quantity / capacity) * 2)  // 2 hours per run

Material variables

No material variables required for the flat-rate or volume-based approaches - all values are in variable() fields for per-order override. If you want ratePerCm3 to differ per material, move it to material.variables['vapourSmoothingRate'].


Notes

  • Very thin walls (<0.5mm) may distort during vapor smoothing. Consider flagging these with reviewRequired.
  • Parts with deep internal channels may not smooth uniformly - operator judgement required.

Last updated on

On this page