Skip to content

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)
ParameterDefaultMeaning
shapeACut of the first stone, a GemShape name from GemApi.Shapes()
caratsACarats of the first stone; must be greater than 0
shapeBCut of the second stone
caratsBCarats 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
angleA14Degrees the first stone is carried around the finger from the top
angleB-14Same for the second stone — the negative mirrors it to the other side
rotationYA20Degrees the first stone leans outwards
rotationYB-20Same for the second stone, mirrored
distance0Distance from the finger; 0 keeps the tool’s own default for each stone
fingerDiameter0Finger 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.