Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Preface

ProFacet was created for cutters who want to understand every facet of their craft. That vision led to FSL—a new faceting specification language shaped by Hackagem’s journey and refined through collaboration with expert designers and gem cutters.

Standard Faceting diagrams show you the result, but not the path to get there or how to adapt when things change. It’s like the difference between a photo of a cake and the recipe behind it. FSL gives you the recipe—the structure and freedom to recreate, adjust, and invent. Every feature in this handbook reflects that philosophy.

We are currently in a public preview. The core engine and the FSL language are considered stable, so no breaking changes are expected. Documentation, the printable diagram, UI polish, performance tuning, and smaller bug fixes are still being worked through, and your feedback accelerates that work.

The interactive slicer in ProFacet is your daily driver. Drag facets, adjust girdles, and watch the studio write FSL in real time. For most designs you never need to type a command, yet the language is always there when a peculiar cut or unconventional meet point demands it. That balance keeps experimentation fun without hiding the machinery that makes a stone reproducible.

When it is time to push performance, the Optimizer takes over. It speaks FSL natively, so you can tag any parameter and let the engine chase brightness, contrast, and scintillation using a modern metaheuristic evolutionary search. Under the hood, ultra-optimized GPU algorithms evaluate candidates faster than a human can pour water into a drip tank, but the controls stay simple: pick targets that matter, set sensible bounds, and let the system converge.

Timeline

  • Test Phase: now through 1 Mar 2026—iterate, gather feedback, and refine the tools and documentation while everything is still in flux.
  • Contest Window: 1 Mar – 1 May 2026—run the launch performance contest and keep the Hobbyist tier free so every cutter can participate.
  • Paid Phase: begins 1 May 2026—introduce billing for the Analyzer, Optimizer and Cloud Sync. The "offline" modus without these tools will stay free to use.

ProFacet is still in an early testing phase. Bugs, feature requests, questions, and general comments are welcome at https://github.com/mastercutter/ProFacet/issues; every report helps shape the launch roadmap.

Start Here

This quick tour shows you how to open the studio, look at a stone, and print a faceting diagram in a couple of minutes.

Tip: The studio autosaves in your browser. Close the tab and come back later - your last design reopens automatically.

1. Learn the controls

  • Drag with the left mouse button (or a single finger) to orbit. Use the right button or a two-finger drag to pan, and the scroll wheel or pinch gesture to zoom.
  • The toolbar above the canvas holds your helpers. View cycles shading styles, Flip jumps from crown to pavilion, and the menu button reveals extra overlays such as wireframe and debug points.

2. Edit your first design

Click New to load the starter template, place the cursor in the editor, paste the snippet below, and press Process (or hit Cmd/Ctrl + Enter):

set name "Simple Octagon"

// Cut a pavilion tier (named 'P') starting at index 0, 
// and at 45 degrees, towards the centerpoint (cp).
// Repeat this 8 times (8-fold symmetry)
P 0 @ 45 : cp x 8

// Cut the girdle (at 90 degrees) with a fixed depth (size).
// Note that we don't need to specify the symmetry again. 
G 0 @ 90 : size

// Cut the crown at 28 degrees, aiming for the meetpoint G, P
// but keeping the girdle.
C 0 @ 28 : mp(G, P) +girdle

// Add a floating table (at 0.2).
T 0 @ 0 : 0.2

The viewer updates instantly, the diagnostics area stays quiet, and the Printable Instructions panel lists your tiers. Each line in the snippet follows the same pattern: tier name (P, G, C, T), index, angle or reference point, and optional symmetry (x 8). Change an angle, press Process again, and watch the stone respond.

3. Preview and print

  1. Open the Diagram panel on the left.
  2. Pick a theme, toggle Compact if you need tighter tables, and choose Small or Large SVGs.
  3. Click Print to switch into a clean preview, then save as PDF or send it straight to paper.

4. What to explore next

  • Visit Tooling -> Web Studio for a deeper tour of the editor, viewer, and instructions panels.
  • Read the Analyzer and Optimizer guides to see how optical analysis and auto-tuning work.
  • Browse the FSL Tour for more language building blocks and design patterns.

FSL Tour

The Faceting Specification Language (FSL) is the handful of keywords you type inside the studio to describe a cut. Every snippet in this tour is written the way a cutter would write it—no compiler jargon, just the rules you need to shape a stone.

Work through the chapters in order or jump to the one you need:

  • Core Concepts explains how the studio reads an .fsl file, what “up” and “down” mean, and how state carries from line to line.
  • Statements shows the building blocks—set, let, facet commands, macros—each with short examples you can paste directly into the studio.
  • Expressions covers numbers, point helpers, and the handy math functions you will reach for when lining up meet points.
  • Macros & Reuse teaches you how to use this advanced feature to package repeated steps, especially for complex gem outlines.
  • Facets and Tiers connects statement syntax to what actually happens to the stone.

The snippets are arranged so you can copy them into a new file, hit Process, and see the result immediately. Treat this section as your language playground.

Core Concepts

Before we dive into individual commands, it helps to understand how the studio reads an .fsl file. Think of the interpreter as a very patient cutter: it reads a line, applies the change, then moves to the next line without skipping ahead or rearranging anything.

How the studio reads your file

  • The file is a simple list of statements. Each line happens in the order you write it.
  • Blank lines and comments are ignored, so feel free to add notes with // whenever it helps future-you.

Here is a tiny program you can paste into the studio to see the order in action:

set name "Order Matters"

P 0 @ 45 : cp x 4
G 0 @ 90 : size
C 0 @ 28 : mp(G, P) +girdle  // Depends on G and P already existing
T 0 @ 0 : 0.2

The crown (C) tier uses a meet point created by the P and G, so the line with the crown tier must come after P and G.

What the studio remembers for you

While it reads the file, the studio tracks a handful of details in the background:

  • Stone metadataset name, set ri, and friends.
  • Machine setupset gear 96 cw sticks until you change it, so every later facet uses the same gear and rotation.
  • Variableslet statements store numbers or points that you can reuse later. Edge helpers always return two endpoints, so you must bind them with destructuring (let a, b = edge(...)) rather than assigning the whole edge to a single name.
  • Last side and symmetry – if you cut a pavilion facet (down) and the next line starts with a tier name, the interpreter keeps using down unless you say otherwise. Same story for symmetry; once you type x8, the next command will still be single unless you repeat the modifier.

If anything goes wrong—maybe a meet point cannot be found—the interpreter stops right there and the diagnostics panel shows the line and message.

Crown versus pavilion (and everything between)

  • down facets belong to the pavilion and tilt toward negative Z.
  • up facets belong to the crown and tilt toward positive Z.
  • Tier labels are just names. P1, C1, Break, and Star all work.

Symmetry in plain language

Add xN after a facet command to copy it around the stone every 360 / N degrees. Use xxN when you want mirrored N-fold symmetry (each pair becomes a left/right mirror). The count must be a positive whole number:

P3 12 @ 38.2 : 0.16 x 8        // eight pavilion mains
G1 0 @ 90 : size x 16          // sixteen girdle facets (90° so size works)

There is no need to specify the symmetry for the next tier if there is no change in symmetry.

Numbers, points, and edges

Most expressions boil down to one of three value types:

  • Number – plain angles, depths, or calculations like deg2rad(32).
  • Point – created with helpers such as mp(P1), gp(G1), or fred(...). These mark locations in space.
  • Edge – less common but handy for advanced macros, created with edge(tier:index, tier:index).

You can store numbers or points in variables. Edge helpers always produce two points, so capture them with a destructuring assignment instead of storing the edge itself:

let table = mp(P1)
let safety = 0.05
let first, second = edge(P1:0, P1:12)
C2 up 0 @ 29.5 : table + girdle x16

Variables live until the end of the file (or until a macro finishes, if you are inside one).

With these basics in mind, continue to Statements to see every command you can type.

Statements

Every line in an .fsl file starts with a keyword or tier name. This chapter explains what each statement does, why you would reach for it, and where it appears in the example at the end.

set – project-wide settings

Use set to update metadata (set name, set ri) or machine configuration (set gear, set girdle). The change applies immediately and carries forward to later lines.

CommandValue syntaxWhat it controlsNotes
set name "Brilliant Oval"Quoted stringUpdates the project title used in the viewer, analyzer panels, and printable exports.Keep the quotes when you need spaces; later set name calls overwrite the previous label.
set ri 1.760Plain number or optimizable literal (for example [1.76, 1.70, 1.80])Defines the refractive index the renderer, analyzer, and optimizer use for light calculations.Makes RI available to the optimizer if you supply the square-bracket form.
set color #ffd166Hex literal (#fff, #ffaa33), named color (red, cyan, ...).Sets the simulated material color in screenshots and raytraces.
set absorption 0.6Number from 0.0–1.0Controls how strongly the gem colour tints the interactive WebGL preview.Defaults to 0.6; lower numbers reduce tinting while 1.0 fully uses the gem colour.
set gear 96 cwPositive integer followed by optional cw or ccwSets the index gear tooth count and dop rotation direction for every later facet.Gear must be an integer; include cw/ccw only when you need to flip the rotation.
set girdle 4.5Number representing a percentage of the stone’s average widthAdjusts how thick the girdle is when interpreting +/- girdle offsets.Typical values are 2–5; larger numbers make the girdle offsets push farther.
set cube 3.0Number interpreted as the cube’s edge lengthRebuilds the starting blank as a cube of the given size before additional cuts.This discards previously cut geometry, so place it near the top of a file.

let – save a value for later

let table = mp(G1) stores a point or number so you can reuse it further down. Inside macros, the binding disappears when the macro finishes; elsewhere it lives to the end of the file. Edge helpers are the only exception: they emit two points, so let edge_ref = edge(...) is invalid—always destructure the pair.

Need both endpoints of an existing facet edge? Add a second identifier on the left and feed an edge(...) helper. The interpreter assigns the ordered pair of edge points to those identifiers. Replace whichever side you do not care about with _ to discard it. In a fresh file you can try:

set name "Edge destructuring"
set gear 96

P1 down 0 @ 41.8 : 0.18 x8

let break_a, break_b = edge(P1:0, P1:12)
let keep, _ = edge(P1:12, P1:24)

Those bindings behave like any other point variable—you can aim facets at them, drop debug markers, or pass them into macros.

show – drop a marker (or edge) in the viewer

show mp(P1) drops a marker using the default highlight colour (#ffd166). Add up or down (right after show) if you want to force the side, and optionally supply a colour: either one of the named options (cyan, orange, etc.) or a hex literal such as #ffe422 or #fff. The web studio keeps a small picker next to the editor so you can drop in hex values without memorising them.

Need to highlight a segment instead of a single point? Feed show edge(Tier:Index, Tier:Index) and the viewer/printable exports draw the coloured line. Just like the let statement, show does not accept edge variables directly—call edge(...) inline or reuse the destructured point pair.

Macros – reuse a favourite sequence

define macro wraps statements so you can replay them with a single command. Every parameter is named ($Macro(tier = "C1")), and defaults live either in the header or inline using ${param = ...}. They are an advanced feature, often used for complex gem outlines.

Facet commands – the main event

When a line starts with a tier name (P1, Star, etc.) you are cutting a facet. Read it like a simple recipe:

Tier [up|down] index @ angle : target xN ["note"] frosted

Go left to right:

  • Tier – the label that will appear in the printable diagram.
  • up / down – crown or pavilion. Leave it off when the tier already implies the side (for example, a C tier lives on the crown, a P tier is pavilion).
  • index @ angle – which tooth on the gear and which angle to lock in. Legacy notes that show < still parse the same way.
  • : target – how far to swing the quill. This can be a depth (: 0.18), a meet point (: mp(G1)), or the special word size for auto-depth on 90° girdle cuts.
  • xN – how many times to echo the facet around the dop. Use xxN when you want mirror-image pairs (for example, left/right star facets).
  • "note" / frosted – optional add-ons: custom printable text or hatch marks.

Here is the classic pavilion break written that way:

P1 down 0 @ 41.8 : 0.18 x8
  • P1 — name in the legend.
  • down — pavilion side.
  • 0 @ 41.8 — tooth 0, 41.8° on the dial.
  • : 0.18 — stop when the quill drops 0.18 units.
  • x8 — repeat eight times (every 45°).

Once you remember the pattern, you only need to choose which target style fits:

  1. Angle + depthP1 down 0 @ 41.8 : 0.18 x8. Great for pavilion mains, breaks, or any cut where you know the depth. Use : size only with 90° girdle passes that should land exactly on the girdle thickness.
  2. Angle + pointC1 up 0 @ 32 : mp(G1) + girdle x16. Aim the facet at a meet point or helper. Add + girdle / - girdle if the point should sit slightly outside or inside the default girdle radius.
  3. Point pairG3 0 : mp(G1) : mp(C2) x16. Define the plane using two points instead of an angle. Ideal for tidying a girdle or bridging between meet points when the trig would be a pain.

Tier naming, sides, and base index rules

Every tier label must be a single string with no whitespace inside it, and it has to start with an alphanumeric character. Reserved keywords (set, let, show, etc.) are off limits as tier names. The optional up/down flag tells the interpreter which side of the stone to use, but most of the time the engine can infer it:

  • Names that start with P default to the pavilion.
  • Names that start with C default to the crown.
  • If you omit the side and the previous cut specified one, that side carries forward.

That’s why a table named T typically doesn’t need up—it inherits the current crown context. You can always override the inference by writing the side explicitly.

The base_index argument is zero-based and must stay below gear / symmetry. Until you dig into the Symmetry section later in this guide, use this mental model:

  • With a 96 index gear and 4-fold symmetry, the valid base index range is 0 .. (96 / 4 - 1)0 .. 23.

Some quick examples:

P1 1 …     // Pavilion cut using base index 1
G2 1 …     // Girdle tier; inherits the pavilion side from P1
C1 3 …     // Crown cut using base index 3
X8 down …  // Non-standard tier name forced onto the pavilion

Everything together

Paste the snippet below into a fresh file to see each statement in context. Feel free to tweak the numbers and watch how the studio responds.

set name "Statement Tour"
set gear 96
set ri 1.760

P1 down 0 @ 41.8 : 0.18 x8
P2 down 6 @ 39.4 : mp(P1) x8

let break_angle = 23.2

show mp(P1) #0011ff

G1 0 @ 90 : size x16
G2 0 @ 90 : mp(G1) x16

let table = mp(G1)
show table #ff004c

define macro CrownRing(tier, angle = 32.0, target = table)
  ${tier} up 0 @ ${angle} : ${target} + girdle x16
end macro

$CrownRing(tier = "C1", angle = break_angle)
$CrownRing(tier = "C2", angle = 27.5)

Once you are comfortable with the building blocks, jump to Expressions to see how to shape angles, numbers, and points inside those statements.

Curious how we handle your designs or what to expect from the simulator? Read the Privacy, ownership, and disclaimer note for the plain-language policy.

Expressions

Note: Most designs never touch custom expressions. Skip this page unless you are building CAM outline macros or a highly specialised cut that needs custom math.

Expressions are the pieces that fit inside statements: numbers, point helpers, comparisons, and function calls. If you can read a simple calculator formula, you already know most of what you need.

Numbers, booleans, and strings

  • Numbers accept decimals and scientific notation (42, 0.18, 1.5e-2).
  • Booleans are just true and false.
  • Strings live inside double quotes and support escapes like \" and \n. You will mostly see them in set name or macro bodies.

Optimizable numbers use square brackets—[41.8, 38, 44, "pavilion-angle"]—to record a starting value, optional minimum/maximum bounds, and an optional label that shows up in the optimizer. Commas separate the items; you can stop after the value, or add one, two, or three extra entries.

Operator rhythm

FSL follows the same order of operations you learned in school:

  1. Negation and logical NOT (-depth, !flag)
  2. Multiplication, division, modulo (depth / 2)
  3. Addition and subtraction (angle + 2)
  4. Comparisons (<=, >=, <, >, ==, !=)
  5. Logical AND/OR (&&, ||)
  6. Function calls (sin(angle))

Parentheses always win when you want to override the default order.

Handy functions

Call functions by name with parentheses. The most common helpers are:

  • sin, cos, tan, asin, acos, atan, atan2
  • deg2rad, rad2deg
  • sqrt, abs, log, log10, floor

You can also read the current gear with the built-in constant GEAR.

Point helpers

Point helpers return locations in space and slot neatly into facet commands or variables. Store them with let point = mp(G1) and reuse as often as you like. The edge(...) helper is the lone exception: it returns two points, so you must destructure it (let left, right = edge(P1:0, P1:12)) instead of assigning the whole edge to a single identifier. When you need deeper explanations or syntax variations, head to the dedicated Point Helper Reference for cp, gp, mp, ep, fred, prz, edge, and the at attachment clause.

Everything in motion

Paste this snippet into the studio to see several expression types working together:

set name "Expression Tour"
set gear 96

P1 0 @ 41.8 : 0.18 x8
P2 6 @ 39.4 : mp(P1)
P3 12 @ (39.4 - 1.2) : [0.18 - abs(-0.02), 0.14, 0.22]

let shoulder = mp(P3) at (12, 39.4)

show down shoulder green

G1 0 @ 90 : size x16
G2 0 @ 90 : mp(G1) x16

let table = mp(G1)
show table magenta

C1 0 @ deg2rad(rad2deg(32.0) + 0.2) : table + girdle
C2 0 : 28.0 : ep(edge(C1:0, C1:6), 0.5)

Try editing the expressions—change the angles, adjust the math—and watch the viewer and analyzer respond immediately. Once you are comfortable, move on to Macros & Reuse to package these ideas for repeated use.

Point Helper Reference

Point helpers turn the geometry you have already cut into reusable coordinates. They power angle + point cuts, point-pair slices, macros, and optimizer targets. Every helper resolves to a 3D point once the referenced tiers exist.

Center point (cp)

cp sits on the stone's centre axis. It always returns (0, 0, 1) when the active side is the crown (up) and (0, 0, -1) when the active side is the pavilion (down).

set name "Center Anchors"

// Mark the culet to check alignment
show cp blue
P1 down 0 @ 41 : cp x8
P1
Centerpoint

Girdle points (gp)

gp scans the vertical girdle facets and returns the vertex that sits “in front” of the requested index/angle. Inside a cut command it borrows the current index/angle automatically; elsewhere you must supply at(index, angle) (angle optional) so the helper knows where to search.

set name "Girdle Pickup"
set gear 96

P1 0 @ 45 : cp x8
G1 0 @ 90 : size x16
C1 6 @ 34 : MP(P1,G1) + girdle x16

show gp at (0) cyan
show gp at (24) orange
C1
Girdle Point Top View
G1P1
Girdle Point Side View

For uneven girdle lines, there is some extra logic that decides if a point can be a true girdle point. If this fails for some reason, the user can use the mp() function, explained next.

Meet points (mp)

mp searches for the intersection of tiers you name. Pass one or more tiers to include, prefix a tier with ! to exclude it, and ProFacet finds the point that satisfies all of the remaining facets on the current side.

Because mp respects the current index and angle context, you can add at (explained later) to jump directly to a specific tooth.

Matching tiers vs. explicit indices

Think of mp as a facet filter: every positive tier you list must participate in the actual meet, while negated tiers must be absent. There are often several equivalent ways to describe the same vertex.

// A few common patterns
mp(C1)                 // single-tier meet
mp(C1, G1)             // multiple tiers
mp(C1, C1)             // requires C1 to be part of the meet twice
mp(C1, G1, !C2)        // exclude an unwanted tier
mp(C1:12, C2:16)       // insist on specific cut indices
mp(C1) at (3, 45.0)    // explicit tooth/angle override

Symmetry means those filters can match multiple physical points. That’s usually fine inside a facet command because the base index and angle narrow the choice. Outside of a cut—show mp(C1) or let helper = mp(G1)—add an at(index, angle) clause to keep things deterministic:

Relying on explicit indices ties the design to a particular gear/symmetry combination, so prefer tier filters when you can.

Examples

set name "Meetpoint Examples"
set gear 96

P1 3 @ 41.0 : cp xx 8
G1 3 @ 90.0 : size
P2 0 @ 39.8 : gp
C1 3 @ 50.0 : mp(P1, P2) +girdle
C2 0 @ 38.0 : gp
C3 6 @ 26.0 : mp(C1)
T 0 @ 0 : mp(C2) x1

show mp(C1) green
show mp(C2) blue
show mp(C1, G1) purple
show mp(C1, C1, !C2) orange
show mp(P1, P2, P2) red
C1C2G1P1P2
mp() examples

Edge references (edge)

edge returns the shared edge between two previously cut facets. You pass tier/index pairs (edge(C1:0, C1:6)), and the helper returns both endpoints so other helpers can work with them.

C1 up 0 @ 32 : 0.08 x16
let long_edge, _ = edge(C1:0, C1:6)

Use edge only after both referenced facets exist; otherwise the interpreter raises an error telling you which tier/index is missing.

Edge interpolation (ep)

ep walks along an edge or between two arbitrary points. Supply either edge(...) plus a factor between 0.0 and 1.0, or two point helpers and the factor. Zero sticks to the first point, one sticks to the second, and any other value interpolates in between.

set name "Edge Interpolation"

C1 up 0 @ 32 : 0.08 x16

let girdle_start, girdle_end = edge(C1:0, C1:6)
let mid_edge = ep(girdle_start, girdle_end, 0.5)

show up mid_edge cyan
C2 up 0 @ 32 : mid_edge + girdle x16

ep(mp(...), mp(...), 0.25) is equally valid when you want a point partway between two meetpoints.

Projected crossover (fred)

fred solves more complex intersections—ideal when the optimizer needs a reference that depends on multiple moving parts. Conceptually it projects two line segments onto the XY plane, finds their intersection, then lifts that XY intersection back onto one of the original segments. The helper was named in honor of Fred Van Sant—one of the most inventive gem designers the lapidary world has ever seen—whose many masterpieces lean on these projected crossings to stay perfectly stitched together.

  • fred(p1, p2, p3, p4) intersects the XY projections of p1–p2 with p3–p4 and returns the point that lives along the p3–p4 segment.
  • fred(p1, p2, edge(F1, F2)) is shorthand that uses the shared edge between F1 and F2 for the second segment.
set name "Fred Demo"

P1 down 0 @ 41.8 : 0.18 x8
P2 down 12 @ 40.0 : mp(P1) x8
G1 0 @ 90 : size x16
T up 0 @ 0 : cp x16

let culet = cp
let table = cp
let bridge = fred(culet, table, edge(G1:0, G1:6))

show bridge magenta

This helper is crucial for elaborate patterns such as Honeycomb FVS or Round Trichecker-1, where you have to drop points onto the exact crossover of two projected paths without breaking symmetry.

Projection workflow for the fred helper
Visualizing the `fred` projection workflow

Projected reference (prz)

prz drops an existing point onto either a reference line or an existing facet. It mirrors the projection math used by fred, but instead of intersecting two lines it projects the target straight to the chosen guide and returns the corresponding 3D point.

  • prz(p_target, line_start, line_end) works with any combination of point helpers or variables that resolve to points and projects in the XY plane (so the projected point can fall outside the original segment if your geometry demands it).
  • prz(p_target, facet_ref) uses a facet reference such as P1:12 and projects onto the live plane of that facet. The facet must already exist in the current geometry—the interpreter will raise a clear error if it has been cut away or is degenerate.
set name "Projected Reference"
set gear 96

P1 down 0 @ 41.8 : 0.18 x8
G1 0 @ 90 : size x16
C1 6 @ 34 : mp(P1, G1) + girdle x16

let rail_start = mp(G1)
let rail_end = mp(G1) at (6)
let culet = mp(P1)

let drop = prz(culet, rail_start, rail_end)
show drop orange

Use prz to pin decorative girdle cuts or checkerboard overlays to a reference rail without introducing extra tiers purely to feed edge(...), or to drop an exploratory helper directly onto an existing facet plane with prz(mp(G1), P1:12) when you just need a quick reference on that surface.

Index and Angle override (at)

at is a trailing clause—not a separate function—that pins a helper to a specific index and optional angle: mp(P1) at (12, 39.4). The first number is the index (integer), and the second is the angle override. If you omit the angle (mp(P1) at (12)), the helper keeps the current angle context.

set name "Attachments"
set gear 96

P1 0 @ 41.5 : 0.18 x8

let tooth_12 = mp(P1) at (12, 41.5)
show tooth_12 green

C1 0 @ 32.2 : tooth_12 + girdle x8

Facets and Tiers

Facet commands translate the numbers you type into actual cuts. When you enter a line such as P1 0 @ 41.8 : 0.18 x8, you first describe one reference facet (P1 0 @ 41.8 : 0.18, with the legacy < token still accepted) and then immediately tell the studio to rotate it eight times (x8). Together, that single line defines the whole tier. This chapter spells out how the reference facet is evaluated and how symmetry turns it into a complete ring of facets.

Describe the reference facet

Every facet statement starts by naming the tier (P1, PF2, Break), optionally choosing a side (up for crown, down for pavilion), and giving an index. The index is the gear tooth where the reference facet begins, so it must be a whole number. If you omit up/down, the studio keeps the previous choice; crown tiers default to up, everything else keeps whatever you last typed.

Cut tiers before you reference them. Point helpers and edge lookups only work after the relevant facets exist, so keep the cut order and the reference order aligned.

Aim the reference facet

Once the tier, side, and base index are set, you provide one of three specifiers:

  1. Angle + depth – supply both values and the studio cuts to that exact combination. Use the size keyword for 90° cuts (girdle and table facets) when you want the depth handled automatically.
  2. Angle + point – pick an angle and let a point helper decide the depth. Add + girdle or - girdle to nudge toward or away from the girdle by the percentage you set earlier.
  3. Point pair – specify two points and the studio slices a plane that touches both, which is ideal for matching opposing facets.

The key idea: the tier/side/index plus specifier only define a single, precise facet at the stated index. The tier becomes complete the moment you append symmetry (x8, xx6, etc.), because those modifiers rotate or mirror that one facet without re-aiming it.

Symmetry builds the tier

After the specifier, symmetry modifiers (xN, xxN) tell the studio how to copy the reference facet around the stone:

  • xN rotates the reference facet every 360 / N degrees. The first rotation uses the index you typed; subsequent facets are pure rotations of that plane.
  • xxN mirrors each rotated facet, creating alternating clockwise/counter-clockwise mates for designs that need paired faces.

Important: The studio never “hunts” for meet points when it replicates a tier. It evaluates the reference facet once—using your tier, side, index, and aiming instructions—and then performs exact rotations (and optional mirrors) to fill out the tier. No meetpoints are searched; the reference facet is simply rotated from the base index you specified. No extra math, no iterative refinement, no automatic adjustments.

The result is a full facet tier: the first facet establishes the geometry, symmetry copies it, and modifiers (below) tweak presentation.

Modifiers that follow the specifier

ModifierWhat it does
xN / xxNApply symmetry. x8 rotates the facet every 360/8 degrees. xx8 produces mirrored pairs.
"instruction"Replace the auto-generated printable description.
frostedMark the facet with hatch lines in the printable diagrams.

Modifiers can appear in any order after the main specifier.

Workspaces & Tools

The released ProFacet studio puts every workflow in the browser. These chapters explain what each panel does, why you might use it, and how the pieces work together.

  • Web Studio - tour the editor, diagnostics, camera controls, and printable instructions.
  • Analyzer - peek under the hood of the light-return charts and learn how to read them.
  • Optimizer - understand the sliders, presets, and progress meters before you launch a run.
  • Interactive Slicer - preview a candidate facet, inspect meetpoints, and drop the generated command into the editor.
  • Inline FSL Figures - embed live diagrams in training material or club handouts.
  • Cloud Sync & Accounts - optional online capabilities for sharing designs across devices.

Browse in whatever order fits your session. Every walkthrough assumes you are using the live app and focuses on what you will see and click there.

Web Studio

Launch the browser studio (see Start Here) to get an editor, GPU viewer, printable instructions, and performance tools in a single workspace. Nothing to install - everything runs locally in your browser.

Editing workflow

  • The studio auto-saves shortly after you stop typing, keeping a private copy of every design in your browser.
  • Use Open... to browse your saved designs, restore deleted entries, or export a backup. New loads the default template.
  • Errors and warnings appear directly under the editor with line numbers. Fix them before running the Analyzer or Optimizer - the performance tools stay locked until the last run succeeds.
  • The inline colour picker updates show command highlights.
  • Rotate with a left-button drag (or a single-finger drag on touch).
  • Pan with the right or middle button; on touch devices use a two-finger drag.
  • Zoom with the mouse wheel or a pinch gesture. Double-click the canvas to reset the default view.
  • Use the toolbar buttons to toggle overlays, cycle view modes (Monochrome -> Palette -> Raytraced), reveal wireframe edges, display debug points, flip between crown and pavilion, or show the angle guide.

Interactive Slicing mirrors your current design: the panel slices the model, shows meetpoint indices, and reacts to Control/Cmd held down while you move the mouse for quick previews.

Printable instructions

Open Diagram to generate the same packet your printer will see:

  • Pick a theme and SVG size (Small or Large) without leaving the studio.
  • Toggle Compact to tighten table spacing for travel kits.
  • Click Print to switch into a browser print preview; the rest of the UI hides automatically.

Performance tools

  • Analyzer simulates 19 tilt positions on the GPU (see Analyzer for details). The panel stays disabled until the current design processes without errors and WebGPU is available.
  • Optimizer adjusts every bracketed value, reuses the Analyzer scores, and keeps the best candidate ready for comparison (see Optimizer).

Both panels share the same analyzer engine, so once WebGPU initialises successfully the buttons unlock together.

Troubleshooting

  • "Analyze/Optimize (Locked)" - process the design first and verify WebGPU support.
  • Viewer looks empty - double-click the canvas to reset the orbit, or use Flip if you accidentally parked the camera inside the pavilion.
  • Save badge stuck on "Last save failed" - check your connection to browser storage (IndexedDB). Retrying a manual save updates the badge.
  • Printable export misaligned - switch to the Large SVG size or disable Compact mode before printing.

Need more help? Copy the message from the diagnostics bar and consult Error Helper - each entry links back to possible fixes. For account or sync questions, open the Help panel or reach out through the community forum.

Analyzer

The Analyzer renders your design on the GPU, tilts it through 19 viewing positions, and reports how much light returns toward the viewer. It runs the same optical pipeline the optimizer uses, so the scores you see here match the ones the optimizer chases.

Before you start

  • Process the design first (Cmd/Ctrl + Enter) so the interpreter, viewer, and Analyzer are working on the same geometry.
  • Clear every FSL error. The Analyze button is disabled until the last run finished without errors.
  • The studio needs WebGPU and the Analyzer feature on your account. When either is unavailable the button reads Analyze (Locked) or Analyze (Unsupported) and shows the reason in its tooltip.

Run an analysis

  1. Open a design and click Open Analyzer in the Performance column.
  2. Press Analyze. The studio keeps the Analyzer panel open, switches the button text to Analyzing..., and shows "Analyzing optical performance..." while it renders every tilt frame with the head shadow and cosine lighting enabled.
  3. When the run finishes the metrics, charts, and timings update immediately. Editing the FSL afterwards replaces the message with "Design changed. Run performance analysis again..." so you know the results are stale.

Understand the results

  • Metric cards list Average Brightness, Contrast Density, Contrast Intensity, Scintillation Score, and Compactness. Each value is shown as a percentage relative to the Hearts & Arrows brilliant reference that ships with the studio.
    • Average Brightness is the mean return light over every valid pixel in the sweep.
    • Contrast Density is the share of the stone that blinks between bright and dark as it tilts.
    • Contrast Intensity is how strong those blinks are when they happen.
    • Scintillation Score counts blink events between angles and normalises them by the number of pixels and tilt steps.
    • Compactness comes from the current mesh and reports how much of the stone's footprint-and-height envelope is filled by the actual volume.
  • Per-angle sparklines ("Brightness by Angle", "Contrast Density", "Contrast Intensity") plot the same metrics for each of the 19 tilt angles so you can see where the stone rises or falls off.
  • Lighting sweep renders each frame with cosine-weighted lighting and a standard head shadow. The 19 tilt positions start 45° down on the X axis, move through the upright view, and finish 45° toward the Y axis. Step sizes tighten near upright so more samples are taken where the stone spends most of its time, making every average a weighted view of the sweep.
  • Timings show total, GPU, and CPU milliseconds for the most recent run.

Try it now

Paste the snippet below, process the design, and run the Analyzer to watch how tiny angle tweaks change the sparkline profiles.

set name "Analyzer Demo"
set gear 96
set girdle 4.5

P1 down 0 @ 41.8 : 0.18 x8
P2 down 6 @ 39.6 : mp(P1) x8

G1 0 @ 90 : size x16
C1 up 0 @ 32.2 : mp(G1,P1) + girdle x16
T up 0 @ 0 : 0.86

Optimizer

The optimizer varies bracketed numbers in your design, runs the same 19-angle Analyzer sweep the manual tool uses, and scores every candidate with your chosen weights. It relies on WebGPU and the same feature gate as the Analyzer.

It reads the FSL directly, so you can tag any number of values and let the optimizer chase brightness, contrast, and scintillation with a modern evolutionary search. WebGPU kernels score each candidate in milliseconds, so the workflow stays simple: choose the metrics that matter, set sensible bounds, and let the run settle.

Prepare adjustable values

  • Wrap any numeric literal you want to expose with square brackets: [ value ], or [ value, min, max ].
  • min and max are optional. When you leave them out the optimizer uses a +/-10% window around the starting value.
  • Brackets work anywhere the interpreter accepts a literal: set statements, facet commands, macro arguments, and expressions.

Example block ready for optimization:

set name "Optimizer Demo"
set gear 96

P1 0 @ [41.0, 40.0, 42.5] : 0.18 x8
P2 6 @ [39.5, 38.0, 41.0] : mp(P1)
P3 12 @ 38.2 : 0.16

G1 0 @ 90 : size x16
C1 0 @ [32.0, 30.0, 33.0] : mp(G1,P1) + girdle
T 0 @ 0 : .9

If no brackets are present the engine returns "No optimizable parameters found" and stays idle.

Choose your weights

  • Open the optimizer panel with Open Optimizer. The sliders appear once the design has been processed successfully (Cmd/Ctrl + Enter).
  • Pick a preset to load weights for Average Brightness, Contrast Density, Contrast Intensity, Scintillation Score, and Compactness. The built-in presets are Balanced Default, Brilliance Boost, Contrast Focus, Precision Cut, and 2026 Launch Contest.
  • Adjust any slider between 0 and 10. Press Save Preset to store the current mix; the studio keeps a local copy and syncs it to your account when cloud features are available.

Launch and monitor a run

  1. Process the design and clear every FSL error. The optimizer checks the same run status as the Analyzer and will show the reason if it stays locked.
  2. Press Start Optimization. The button switches to "Optimization Running", the cancel button becomes Stop & Keep Best, and the viewer throttles to ~20 FPS while the GPU works.
  3. The progress panel lists the current status, iteration, best score (calculated from your weights on Hearts & Arrows-normalised metrics), analyser throughput in pixels per second, and metric deltas versus the starting design.
  4. Stopping keeps the strongest candidate so far and turns the start button into Resume Optimization; you can pick up right where you left off without losing that snapshot.

Behind the scenes the optimizer explores nearby combinations automatically and never strays outside the min and max you set.

Compare and apply

  • As soon as a valid candidate exists the comparison panel opens with side-by-side viewports labeled Original and Optimized plus a contribution table that shows how each metric moved.
  • The Replace Editor with Optimized button swaps the editor contents with the current best parameters. Save Optimized as New Version writes a revision while preserving the original file.
  • Apply actions stay hidden until you stop a run. Resume after applying if you want to explore further from the updated baseline.

Interactive Slicer

The Interactive Slicer panel (the “Interactive Slicing” column under the viewer) lets you preview a candidate facet, inspect the exact meetpoints it would hit, and then paste the generated FSL command into the editor with one click. It is powered by the same renderer and meetpoint pipeline that the studio uses during normal execution, so the preview reflects the current geometry, symmetry, and girdle settings.

The slicer reads the most recent machine snapshot exposed by ProFacet’s engine. If the design has not been processed successfully, the panel still opens, but meetpoint and girdle lookups fall back to simple centre markers.

Panel layout

The slicing panel

  • Side – choose Up (crown) or Down (pavilion). The current side feeds every preview and determines the sign of the girdle offset.
  • Angle / Index – slider + number pairs that map directly to the machine angle (0–90°) and index (0–gear). Drag the slider for coarse changes, or type numbers for precise edits. While the pointer is over a slider, hold Ctrl (Cmd on macOS) to activate fine-grained mode.
  • Target – selects what the facet should touch:
    • None (hide preview) disables all overlays and buttons.
    • Center point uses cp (the centre axis) and asks ProFacet for the exact centre when context is available.
    • Girdle returns the girdle contact at the current index/angle using the gp helper.
    • Proper meetpoint pulls clustered meetpoints from listMeetpoints; use ◀/▶ to cycle through candidates.
    • Depth exposes a depth slider (0–1.00) for classic angle + depth cuts.
  • Symmetry / Mirror – set the repeat count (xN) and whether to emit mirrored pairs (xxN). The slicer syncs the starting value from the current machine snapshot; it only appends x/xx to the preview command when you change it.
  • Girdle offset – when the target is cp, gp, or Proper meetpoint, adds +girdle on the crown or -girdle on the pavilion automatically.

Below the controls you will see:

  • A meetpoint navigator (visible only for Proper meetpoint). Each candidate shows its label, order, and whether it is a fallback. When the selected point lies on the girdle, the preview command switches to gp.
  • A live preview string that mirrors the facet command that would be added to the editor.
  • The floating Preview badge, plus Cancel and Commit buttons.

The slicing panel

Preview behaviour

  • Dragging the angle or index slider, hovering the Preview badge, or holding Ctrl/Cmd keeps the preview active.
  • The viewer shows:
    • A plane overlay and cap polygon sliced through the current mesh.
  • Markers for the selected meetpoint (and neighbouring candidates), the current cp or gp, and any girdle candidate provided by ProFacet.
    • The angle guide if it is enabled in the viewer.
  • When you release the slider or let go of the modifier key, the preview snaps back to the base mesh.

Committing or cancelling

  • Commit appends the preview line to the editor, choosing the next sequential tier name (P, C, or G based on side/angle), and reruns the interpreter so the viewer stays in sync.
  • Cancel clears the preview state and resets the target to None.

Meetpoints and girdle logic

  • Proper meetpoint filters out fallback candidates and anything that falls on the opposite side of the plane. The panel remembers your selection as you change the angle or index.
  • When ProFacet reports a girdle contact for the current sweep, the panel highlights it and offers the Girdle offset toggle so you can nudge the facet just inside or outside the girdle automatically.

Symmetry and warnings

  • The symmetry count must divide the machine gear. If it does not (or if the index exceeds gear / symmetry), the input fields highlight in red and a warning appears above the preview string.
  • Mirroring uses xx and produces left/right pairs, matching the way the runtime interprets xxN.

Tips

  • Precision mode (Ctrl/Cmd while the pointer is over a slider) lets you make sub-degree or sub-index adjustments without typing numbers.
  • Hold Ctrl/Cmd while tapping arrow keys in the numeric boxes to keep the preview active.
  • The preview command already includes any +girdle, symmetry, or meetpoint specifier adjustments, so the inserted line is ready to run as-is. You can still edit it manually in the editor after committing if you need to tweak the tier name or add notes.

Cloud Sync & Accounts

ProFacet stores every edit in your browser first for speed and data privacy. Cloud sync builds on that foundation: when you sign in, the studio mirrors those designs to your account so you can pick up the same work on another machine. This chapter explains what stays local, what changes after authentication, and how to keep multiple browsers aligned.

Local storage and manual backups

  • The studio auto-saves every design into your browser's private cache, keeping edits fast and under your control unless you choose to sync.
  • Browsers may automatically purge site data when disk space runs low. Treat IndexedDB and local storage as a cache, not your only archive.
  • Open Design -> Backup exports the entire library (active and deleted designs) as a JSON file. Restoring that file walks you through conflicts: you can overwrite locals with the backup or keep whichever version has the newest change.
  • Deleted entries stay in the dialog's Deleted filter until you purge them or restore them, so accidental removals are easy to undo.
  • Clearing site data empties the cache. Export a backup first if you plan to reset the browser.
  • Always keep multiple backups (cloud sync, JSON export, external drive) so you can recover if either the browser or the device has a bad day.

Signing in unlocks cloud sync

Click the Sign In badge in the editor header to open the account menu. Depending on the deployment, cloud features may be disabled entirely - in that case the badge simply reads Offline and behaves like a label.

When cloud sync is available, authenticating adds:

  • Automatic backups - the latest copy of every design is stored alongside your account.
  • Cross-device libraries - any browser that signs in with the same account receives the same portfolio. Remote designs win when they have a newer modification timestamp; otherwise your local edits stay in place.
  • Preset sync - user-created optimizer presets are uploaded alongside designs, so the Optimizer panel shows the same list everywhere.
  • Account controls - the menu offers Account Overview, Sync Now, Resend verification email (when needed), Delete Account, and Sign Out. Signed-out users get a one-click option to authenticate.

The badge shows a subtle spinner while sync is in flight (aria-busy="true"). Signing out stops remote sync immediately; the local cache stays in place.

How syncing behaves

  • Initial merge - the first sign-in pulls any remote snapshot, combines it with your local designs (newer changes win), saves the result back to the browser, and, if nothing is open, loads the most recently edited piece.
  • Deferred uploads - after you edit a design, the badge notes that changes are waiting. About 45 seconds after you stop typing, the studio pushes the updated library so quick tweaks batch together.
  • Interval syncs - while you are signed in, the studio also refreshes your cloud copy roughly every 10 minutes in the background.
  • Manual Sync Now - choose Sync Now from the profile menu to force an immediate round-trip before you close a laptop or switch machines. The menu closes once the request completes.
  • Optimizer presets - the presets you create travel with your account, so the Optimizer panel shows the same list wherever you sign in.

If the network is unavailable, sync retries later and your edits remain in IndexedDB. The spinner disappears once the controller falls back to idle.

Troubleshooting

  • Designs are missing after signing in - open the profile menu and run Sync Now once to trigger a merge. If the designs still do not appear, check the browser console for [cloud-sync] errors.
  • Contest submission says email unverified - use the menu's Resend verification email action and complete the link in your inbox, then try again.
  • Preparing to wipe a device - export a JSON backup first (Open Design -> Backup). You can restore that file on the fresh install before or after you sign in.
  • Keep everything local - click Sign Out. The badge switches back to Sign In (or Offline when cloud is disabled) and the local library stays intact.
  • Remove the hosted copy - pick Delete Account from the menu to start the managed account-deletion flow. This only affects the hosted data; it does not erase local IndexedDB entries.

Advanced

This chapter collects deep dives for cutters who want to stretch ProFacet beyond the basics. Each article focuses on a specialized workflow or design pattern so you can mix and match the right techniques for a particular stone.

Pavilion Angles from RI

Want to compute pavilion angles straight from the active refractive index? Head over to RI-Driven Pavilion Angles for a complete walkthrough and sample code that keeps your pavilion tracking the material's critical angle automatically.

Macros & Reuse

Macros are an advanced feature for packaging a sequence of cuts so you can replay it with a single command. While you can use them for simple repetition like a pavilion break, they are most powerful when defining complex gem outlines using the Centerpoint-Angle Method (CAM).

Anatomy of a macro

define macro Name(parameter = default, ...)
  # Optional docstring lines that explain the intent.
  STATEMENTS...
end macro
  • Name – any identifier. The studio treats names case-insensitively.
  • Parameters – always named (key = value when you call the macro). Defaults are optional.
  • Body – regular FSL statements. Use ${parameter} to inject values.

Inside the macro you can run set, let, assert, facet commands—anything you would normally write by hand. Once the macro ends, any temporary variables disappear.

Calling a macro

Invoke a macro with $Name(key = value, ...). Every argument is explicit, which keeps macros readable and avoids guessing which number corresponds to what.

$CrownRing(tier = "C1", angle = 32.5)

If you skip a parameter, the default from the definition (or inline placeholder) is used instead. Macros are also the best place to guard your design with assert statements—for example, to stop the interpreter if a caller passes an angle outside the safe range.

Full example

The snippet below defines a macro that cuts two crown rings and checks the parameters before it runs. Paste it into the studio and tweak the angles to see how the macro behaves.

set name "Macro Tour"
set gear 96
set girdle 3.5

P1 down 0 @ 41.8 : 0.18 x8
P2 down 6 @ 39.4 : mp(P1) x8

G1 0 @ 90 : size x16

let crown_target = mp(G1)

define macro CrownRing(tier, angle = 32.0, target = crown_target)
  # Validate the inputs before cutting
  assert ${angle} > 0 "Crown angle must be positive"
  assert ${angle} < 35 "Keep crown angles below 35 degrees"
  ${tier} up 0 @ ${angle} : ${target} + girdle x16
end macro

$CrownRing(tier = "C1", angle = 32.4)
$CrownRing(tier = "C2", angle = 28.6)

Use macros sparingly—just enough to remove repetition without hiding what the stone is doing. For everyday tips on statements and expressions, revisit the earlier chapters; for advanced point tricks, head to Facets and Tiers.

CAM system macros

The studio ships a handful of Centerpoint–Angle Method helpers so you can block in pavilion preforms without rewriting the same geometry. Every macro below is available automatically—just call it from any design, tweak the arguments, and continue cutting. For rendered outlines and meetpoint callouts, see the CAM section in Facets and Tiers.

Gemstone Design Styles in ProFacet

This guide outlines three primary design styles used in ProFacet. Each style emphasizes different cutting constraints and offers unique advantages depending on whether you want reproducibility, fluid exploration, or full geometric freedom.

Style I: Angle + Depth

Style I leans on angle plus depth cutting. It is less flexible than other methods, but it excels when you want to recreate existing designs that are documented with explicit depths or perform a fast floating facet check.

set name "Hearts and Arrows I"
set gear 96

P1 3 @ 41.0 : cp xx 8
G1 3 @ 90.0 : size
P2 0 @ 39.8 : .753
C1 3 @ 50.0 : .700
C2 0 @ 38.0 : .547
C3 6 @ 26.0 : .4383
T 0 @ 0 : .207

Style II: Angle + Point

Style II combines angle plus point cutting, making it far more flexible and fluid than Style I. The primary ProFacet UI emits cuts in this style, and it is a great fit for porting existing diagrams while keeping the option to experiment.

set name "Hearts and Arrows II"
set ri 2.46
set gear 96

P1 3 @ 41.0 : cp xx 8
G1 3 @ 90.0 : size
P2 0 @ 39.8 : gp
C1 3 @ 50.0 : mp(P1, P2) +girdle
C2 0 @ 38.0 : gp
C3 6 @ 26.0 : mp(C1)
T 0 @ 0 : mp(C2)

Style III: Point + Point

Style III— the fully fluid model—relies on point plus point cutting. Only one pavilion angle and one crown angle are specified; every other facet is derived from intersections of calculated points. It is indispensable for designs such as checkerboards where point-to-point control is required.

set name "Hearts and Arrows III"
set ri 2.46
set gear 96

P1 3 @ 41.0 : cp xx 8
G1 3 @ 90.0 : size
P2 0 : ep(edge(P1:3, P1:9), 0.76): gp
C1 3 @ 50.0 : mp(P1, P2) +girdle
C2 0 : ep(edge(C1:3, C1:9), 0.13) : gp
C3 6 : ep(mp(C2), mp(C2,G1),0.6) : mp(C1)
T 0 @ 0 : mp(C2)

The Optimizer

The optimizer can be used with all three styles. Style III is especially well-suited for optimization sessions because its point-to-point architecture can preserve facet counts, something that is difficult—or sometimes impossible—with Styles I and II.

Mixing Styles

Nothing prevents you from mixing these approaches inside a single project.

CAM Outlines

The Centerpoint–Angle Method (CAM) starts the build with a shallow pavilion preform. You cut down to a temporary culet, flatten the girdle from that reference, and only then worry about the crown. It is the fastest way to block in outlines that would otherwise need dozens of exploratory facets.

ProFacet exposes CAM-friendly helpers as macros so you can sketch a girdle in a single line and refine the angles later. The following outlines are ready today:

  • Rectangle — the straight rectangle via $Rect.
  • Truncated rectangle — available through $RectTr.
  • Truncated square — available through $SquareTr.
  • Double-truncated rectangle — available through $RectDblTr.
  • Truncated triangle — available through $TriTr.
  • Cushioned truncated square — available through $SquareCushTr.
  • Cushioned truncated triangle — available through $TriCushTr.
  • Cushioned truncated pentagonPlaceholder. Depends on 5-fold CAM helpers.
  • EllipsePlaceholder. Elliptical CAM requires variable index spacing; watch the release notes.

Rectangle

set name "CAM Rectangle"
set gear 96

$Rect(lwr = 1.6, angle = 45)
PF1PF2
CAM rectangle viewed from the pavilion

Truncated rectangle macro

Use $RectTr to block in a classic competition outline: pick a length-to-width ratio, the pavilion angle for the long face, and an optional truncation ratio for the corners.

set name "CAM Truncated Rectangle"
set gear 96

$RectTr(lwr = 1.6, angle = 45, truncation = 0.30, offset = 5)
PF1PF2PF3
CAM truncated rectangle viewed from the pavilion

The macro generates the shallow preform (tiers PF1PF3) and a finished girdle loop (G1G3). Tweak truncation toward 0.0 for squarer corners or up toward 1.0 for aggressive chamfers. offset is optional and rotates the corner facets if you want the long edge aligned to a different index.

Truncated square macro

$SquareTr mirrors the same control scheme on 4-fold symmetry. It cuts four identical long facets, then trims each corner using the truncation ratio. Keep truncation between 0.0 and 1.0 for light chamfers, or push it toward 2.0 when you deliberately want octagonal outlines.

set name "CAM Truncated Square"
set gear 96

$SquareTr(angle = 45, truncation = 0.35, offset = 4)

The optional offset rotates the square if you need the long flats aligned to an existing index. Because the macro expects a gear divisible by four it runs cleanly on 64-, 80-, 96-, or 120-tooth laps.

Cushioned truncated square macro

$SquareCushTr builds a softened square outline by offsetting the four primary girdle facets and trimming the corners with a controllable cushion ratio. Use cushion to steer the amount of cushioning, set the pavilion angle for those primary facets, and dial truncation between 0.0 (sharp corners) and about 1.0.

set name "CAM Cushioned Square"
set gear 96

$SquareCushTr(angle = 45, cushion = 2, truncation = 0.40)
PF1PF2
CAM cushioned truncated square viewed from the pavilion

The macro mirrors the pavilion cuts using xx4 symmetry so the cushion stays balanced even if you rotate the starting index. Lower offset keeps the flats on the 0 index; bump it higher to align the flats with any pre-existing tier. Use the girdle percentage or follow-up tiers to stretch the outline without rewriting the macro call.

Double-truncated rectangle macro

$RectDblTr stacks two corner trims so you can rough-in competition octagons that still polish down to razor corners. The first_truncation parameter sets the outer chamfer exactly like $RectTr. second_truncation carves an additional facet inside that first chamfer and accepts values up to roughly 2.0.

set name "CAM Double Trunc"
set gear 96

$RectDblTr(lwr = 1.6, angle = 45, first_truncation = 0.30, second_truncation = 0.25, offset = 5)

Both truncation settings must stay non-negative, and lwr must be greater than zero—violations now fail fast during interpretation instead of collapsing the girdle geometry.

Truncated triangle macro

$TriTr blocks in a three-fold outline with controllable corner trims. Pass the pavilion angle for the primary girdle facets and adjust truncation between 0.0 (sharp points) and roughly 1.5 (heavy chamfers). The macro assumes a standard 0.7 girdle radius and uses mp(...) so the corners stay aligned.

set name "CAM Truncated Triangle"
set gear 96

$TriTr(angle = 44, truncation = 0.35)
PF1PF2
CAM truncated triangle viewed from the pavilion

Cushioned truncated triangle macro

$TriCushTr mirrors the same workflow but lets you offset the long side by tweaking the optional cushion index. Use it when you need a slightly rounded triangle that still lands on three repeatable meetpoints. The macro shares the same truncation and angle controls as $TriTr, so you can swap between the two without rewriting your design.

set name "CAM Cushioned Triangle"
set gear 96

$TriCushTr(angle = 44, truncation = 0.30, cushion = 2)
PF1PF2
CAM cushioned truncated triangle viewed from the pavilion

RI-Driven Pavilion Angles

The pavilion's performance depends on how closely you aim each facet at the material's critical angle. Now that FSL expressions can read the gemstone's refractive index through the built-in RI constant, you can script those angles directly instead of retyping tables from reference books.

Reading the active RI

RI always mirrors the most recent set ri command (including optimizable expressions and overrides), and it is case-insensitive (RI, ri, Ri, etc.). Because it behaves like a read-only variable, you can combine it with any of the math helpers in expressions, macro parameters, or optimizer targets.

Example: pavilion cut at the computed critical angle

The snippet below calculates the material's critical angle, adds a one-degree safety margin, and then cuts a pavilion that tracks that calculation. Any change to set ri automatically recomputes the angles—perfect for trying new materials or letting the optimizer sweep the refractive index.

set name "Critical Pavilion"
set gear 96
set ri 1.76

let critical_angle = rad2deg(asin(1 / RI))
let pavilion_angle = critical_angle + 1.0 // 1° safety margin


P1 2 @ pavilion_angle : cp x8

Try changing the RI to quartz (set ri 1.544) and re-run the design—the pavilion reorients itself instantly based on the new physics. You can extend the same approach to crowns, macro defaults, or optimizer objectives by referencing RI anywhere a numeric expression is allowed.

Examples

This chapter gathers a set of illustrative faceting plans that show how different gem styles can be expressed with ProFacet's Facet Specification Language (FSL). Each page combines three elements:

  • A narrative overview that explains the aesthetic intent and cut strategy.
  • A minimal but complete FSL specification you can adapt to your own experiments.
  • Two quick SVG sketches that separate crown and pavilion thinking for fast iteration.

Use these examples as launch points: duplicate one of the pages, tweak the FSL values, and refresh the sketches to reflect your own measurements.

Brilliant Cut

The classic round brilliant maximizes sparkle by balancing crown height, pavilion depth, and table ratio. Use this template as a familiar starting point.

Sources

  • https://www.gia.edu/round-brilliant-cut-diamond
  • https://en.wikipedia.org/wiki/Round_brilliant
  • https://en.wikipedia.org/wiki/Tolkowsky

FSL Spec

set name "Example:: Round Brilliant"
set ri 2.46
set gear 96

P1 3 @ 41.0 : cp xx 8
G1 3 @ 90.0 : size
P2 0 @ 39.8 : gp
C1 3 @ 50.0 : mp(P1, P2) +girdle
C2 0 @ 38.0 : gp
C3 6 @ 26.0 : mp(C1)
T 0 @ 0 : mp(C2) x1

Crown View

C1C2C3T
Brilliant cut crown overview

Pavilion View

P1P2
Brilliant cut pavilion overview

Step Cut

Step cuts emphasize broad flashes over scintillation. Long, parallel facets reward precise meetpoint control and reveal clarity, making them ideal for emerald or asscher style outlines.

Because not all cuts are meetpoint based, the design of emerald type cuts isn't straighforward. In the code below we create helper points at fixed distances, and cur through these. The angles can be changed, without changing teh proportions of the facets, allowing to optimize this cut.

Design Highlights

  • Rectangular outline with clipped corners for durable setting points.
  • Tiered crown steps that keep the table expansive while adding subtle height.
  • Pavilion tiers tuned to keep light return without creating a deep window.

FSL Spec

set name "Emerald Cut"
set ri 1.54
set gear 96
set color #00a300

// Pavilion angles
let ang1 = [53.0306]
let ang2 = [33]
let ang3 = [22.7648]

// Crown angles
let angc1 = [45]
let angc2 = [27.5353]
let angc3 = [27.5]

$RectTr(lwr=1.5,angle=40,truncation=0.4)

P1 0 @ ang1 : cp x2

let p7 = ep(edge(P1:0,G2:0), 0.5)
let p8 = ep(edge(P1:48,G2:48), 0.5)
let p9 = ep(p7,p8, 1/6)
let px = prz(p9, p7,cp)

P2 0 @ ang2 : px 

let ncp = ep(edge(P2:0, P2:48), 0.5)
let midp = ep(ncp, px,0.5)

P3 0 @ ang3 : midp 

P4 12 @ ang1 : mp(G2,P1) xx2
P5 12 @ ang2 : mp(P4,P1)
P6 12 @ ang3 : mp(P5,P2)

P7 24 @ ang1 : gp
P8 24 : mp(P2,P5) : mp(P4,P7)
P9 24 @ ang3 : mp(P5)
C1 0 @ angc1 : mp(P1) + girdle

let cmp1 = ep(edge(C1:0, G2:0),0.5)
let cmp2 = ep(edge(C1:48, G2:48),0.5)
let cmp3 = ep(cmp1, cmp2, 1/10)
let cmp5 = ep(edge(C1:0, C1:48),0.5)
let pp = prz(cmp3,cmp5,cmp1)

C2 0 @ angc2 : pp

let cmp6 = ep(edge(C2:0, C2:48),0.5)
let cmp7 = ep(cmp1, cmp2, 2/10)
let pp2 = prz(cmp7, cmp6,pp)

C3 0 @ angc3 : pp2

let cmp10 = ep(edge(C3:0, C3:48),0.5)
let cmp11 = ep(cmp1, cmp2, 2.5/10)
let pp3 = prz(cmp11, pp2,cmp10)

T 0 @ 0 : pp3

C4 12 @ angc1 : mp(G2,G3)
C5 12 @ angc2 : mp(C1,C4)
C6 12 @ angc3 : mp(C2,C5)

C7 24 @ angc1 : mp(G1,G3)
C8 24 @ angc2 : mp(C4,C7)
C9 24 @ angc3 : mp(C5,C8)





Crown View

C1C2C3C4C5C6C7C8C9T
Step cut crown overview

Pavilion View

P1P2P3P4P5P7P8P9
Step cut pavilion overview

Mixed Cut

Mixed cuts pair a brilliant crown with a step pavilion, creating hybrid light behavior suited for off-standard shapes. This concept favors custom designs where you want lively face-up play but tight control over depth.

Design Highlights

  • Brilliant-style halo of crown facets to energize the table.
  • Pavilion steps that manage depth for easier setting tolerances.

FSL Spec

set name "FVS-12 Karen-2"
set ri 1.76
set gear 64

$RectTr(angle=34,lwr=[1.5])


P1 0 @ 61.50 : cp xx 2
P2 8 @ 41: mp(G2) 
P3 16 @ 46.00 : mp(G3)
P4 4 @ 42.73 : gp
P5 14 :mp(P2) :gp
P6 1 @ 43.41 : ep(mp(P4,P4,P4), mp(P2),0.5) 
P7 0 : mp(P1) : mp(P4)


let ang1 = [36.64]
let ang2 = [30.64]
let ang3 = [28.98]

C1 8 @ ang1 : mp(P2) + girdle
C2 8 @ ang2 :  ep(mp(C1),mp(G3),0.9)
C3 8 @ ang3 :  ep(mp(C2),mp(C1),0.9)

C4 0 @ ang1 : mp(G3)
C5 0 @ ang2 : mp(C1)
C6 0 @ ang3 : mp(C2)

C7 16 @ ang1 : mp(G3)
C8 16 @ ang2 : mp(C1)
C9 16 @ ang3 : mp(C2)

C10 0 @ 0.00 : mp(C3)

Crown View

C1C10C2C3C4C5C6C7C8C9
Mixed cut crown overview

Pavilion View

P2P3P4P5P6P7
Mixed cut pavilion overview

Checkerboard

Checkerboard crowns stretch facets into squares across the table, yielding bold sparkle even on shallow stones. This layout is popular for colored gems that rely on saturation rather than brilliance.

Design Highlights

  • Square outline with evenly spaced crown facets to create the grid effect.
  • Flatter crown to keep the table broad while still offering relief cuts.
  • Pavilion angles tuned shallow to keep depth low for weight retention.

FSL Spec

set name "Examples :: Checkerboard"
set ri 1.810
set gear 96

P1 0 @ 37.5 : cp xx 4

Crown View

Checkerboard crown overview

Pavilion View

P1
Checkerboard pavilion overview

Honeycomb

The honeycomb motif as in FVS-222 is an advanced design that step by step creates (helper) points by interpolating and the use of the fred function. It is a "Projected crossover" used in a way to get a perfect honeycomb pattern. Note that the actual cuttings angles are computed and adapt when the starting position changes due to e.g. optimization. GemCad allows designing (by using Shift-click) checkerboards but not more "free form" patterns like this one.

FSL Spec

set name "FVS-222 Honeycomb"
set ri 1.54
set gear 96

G1 5 @ 90 :size xx6
P1 5 @ [43.02] : cp
G2 0 @ 90 : ep(edge(G1:5, P1:5), 0.25)
P2 0 @ 41.3 : mp(G1,G2,P1)
P3 8 @ 40.9 : mp(G1,P1)
C1 5 @ 35 : mp(P3) + girdle
C2 0 @ 28.6 : mp(G2,G1,C1) at (4,45)

let p1 = mp(G2,G1,C2) at(4,45) 
let p2 = mp(G2,G1,C2) at(10,45)

let p3 = fred(p1,p2,  edge(C1:11, C1:5))
show p1 #6d4370
show p2 purple
show p3 #1eff00

C3 8 @ 25.04 : p3

let p4 = mp(G2,G1,C2) at (46,45)
show p4  red

let p_white = fred(p1, p4, edge(C2:0, C3:8))
show p_white white

let orange1 =  mp(C1,C1,C3) at (88,45) 
let orange2 =mp(C1,C1,C3) at (24,45) 
show orange1 #9c3540
show orange2 #2b2417

let center = mp(C1,C1,C3) at (0,45) 
show center #b6a486

let blue1 = mp(C3) at (0,5)


let green1 = fred(orange1, orange2, center, blue1) 
        

C4 0 :green1 :p_white        
T 0 @ 0 : ep(edge(C4:0,C4:16), 0.5)

 

Crown View

C1C2C3C4T
Honeycomb crown overview

Pavilion View

P1P2P3
Honeycomb pavilion overview

WebGPU FAQ

Q: Why does ProFacet lean on WebGPU for its heavy compute passes instead of sticking to CPU or WebGL?
A: Optimization sweeps, lighting analyses, and the raytraced preview all boil down to parallel math: tracing millions of rays, sampling BRDFs, and updating facet energy buffers every frame. WebGPU unlocks dedicated compute pipelines, storage buffers, and subgroup ops, so we can keep those workloads on the GPU without round-tripping through JavaScript. Trying to express that in WebGL would mean abusing fragment shaders and multiple render targets, which is slower, harder to debug, and far less predictable across drivers.

Q: How do I know whether my browser (or GPU driver) supports WebGPU today?
A: Visit caniuse.com/?search=webgpu and scroll down to the support matrix. Green boxes indicate native support; yellow entries usually require enabling an experimental flag in chrome://flags, edge://flags, or the equivalent in Safari Technology Preview. Red entries mean WebGPU is still unavailable on that platform, so plan on updating your browser or OS before relying on it for production work.

Privacy, Ownership, and Simulation Disclaimer

We built ProFacet so you can explore gem designs without wondering what we do with your data. This page captures the short version of our privacy stance and the legal fine print.

Cookies and tracking

  • We do not use third-party cookies, analytics pixels, or advertising trackers.
  • Session cookies stay first-party (scoped to profacet.app) and exist only to keep you signed in when you opt into account features.

Design ownership

  • Your designs remain yours. We do not mine, resell, or reuse them.
  • Designs are only shared outside your account when you submit them to an official contest.

Hosting and infrastructure

  • ProFacet is hosted on Firebase (Google Cloud). Think of it as renting a secure storage unit: we control the keys and decide what lives there.
  • Firebase serves the app over our own domain, so it does not drop third-party cookies or inject ads—everything you load still counts as first-party traffic.
  • When you enable cloud sync, the files you pick are stored in Firebase solely so you can reach them from another device. Firebase acts as our subprocessor and cannot repurpose that data.
  • Plain-language version for non-technical folks: we use Google’s servers the way you might use a bank vault. They keep the lights on, but they do not get to open the box, copy your designs, or sell your activity.

Storage model

  • Projects live in your browser or desktop client first. They stay local unless and until you enable cloud sync.
  • Cloud sync mirrors exactly the files you pick to your account so you can retrieve them on another machine; disable it and no further uploads occur.

Simulation disclaimer

  • The renderer, analyzer, and optimizer are sophisticated simulations, but they are still simulations.
  • Real stones will deviate because of polishing, material tolerances, lighting, and refractive index variance, so treat virtual results as guidance rather than a guarantee of optical performance.