Scripting API
Toi et Moi
from ArtisanPlugin.Scripting import ToiEtMoiApi as toietmoi
A Toi et Moi is a ring top carrying two independent stones rather than one centre: they sit either side of the finger’s top, each leaning outwards, so the pair reads as two separate gems in conversation rather than a cluster. The classic versions mix cuts — pear with round, oval with emerald — and often mix compounds too.
This is the ArtisanToiEtMoi tool run headless: the same model, the same validation and the same builder the panel’s preview and Accept use.
Usage
ids = toietmoi.Create("PEAR", 0.75, "ROUND", 0.75)
ids = toietmoi.Create(shapeA, caratsA, shapeB, caratsB,
materialA, materialB,
angleA, angleB,
rotationYA, rotationYB,
distance, fingerDiameter)
| Parameter | Default | Meaning |
|---|---|---|
shapeA | — | Cut of the first stone, a GemShape name from GemApi.Shapes() |
caratsA | — | Carats of the first stone; must be greater than 0 |
shapeB | — | Cut of the second stone |
caratsB | — | Carats of the second stone; must be greater than 0 |
materialA | "Diamond" | Compound of the first stone, from GemApi.Materials() |
materialB | "Diamond" | Compound of the second stone |
angleA | 14 | Degrees the first stone is carried around the finger from the top |
angleB | -14 | Same for the second stone — the negative mirrors it to the other side |
rotationYA | 20 | Degrees the first stone leans outwards |
rotationYB | -20 | Same for the second stone, mirrored |
distance | 0 | Distance from the finger; 0 keeps the tool’s own default for each stone |
fingerDiameter | 0 | Finger diameter in millimetres; 0 uses the document’s finger size |
Only the four stone arguments are required. Left alone, the rest reproduce the tool’s default placement exactly: the two stones are carried ±14° around the top of the finger and lean ±20° outwards, mirrored about the top, at the builder’s default standoff. Passing angleB and rotationYB as positive values is how you break the mirror and build an asymmetric top.
The shape and material strings are parsed the same way as elsewhere in the gem API — trimmed, dashes and spaces turned into underscores, matched case-insensitively — and each stone’s carat weight drives its millimetre size through the usual proportion tables.
fingerDiameter of 0 reads the finger size from the document settings; giving a positive value overrides it for this call only, and the circumference is recomputed from it. distance of 0 leaves each stone at the model’s default distance rather than pushing it to the finger surface.
What it returns
A list of System.Guid — the ids of the two gems, in A then B order. Not handles, and not the group. Feed them through GemApi.Find when you want to keep working on the stones:
from ArtisanPlugin.Scripting import GemApi as gem, ToiEtMoiApi as toietmoi, Transaction
with Transaction.Begin("Toi et Moi"):
ids = toietmoi.Create("PEAR", 0.75, "OVAL", 0.70,
materialA = "Diamond", materialB = "Ruby")
for id in ids:
g = gem.Find(id)
if g is not None:
g.Select(True)
Alongside the two stones the call bakes an editable group that also carries the finger reference circle, so the result stays a Toi et Moi you can pick up again in the panel rather than two loose stones. The ids of that group’s other members are not returned.
Errors
The call mutates the document, so it raises ScriptingNotLicensedException without a valid licence, and “No active document.” with no document open. Each stone is validated independently before anything is built: “Carats must be > 0.”, “Unknown gem shape ‘X’.” or “Unknown gem material ‘X’.”, with the failing argument named so you know which of the two stones is at fault. The assembled model is then validated as a whole, and if the builder somehow fails to produce both stones the call throws “Toi et Moi generation failed to create both gems.” rather than leaving half a ring top behind.