Skip to content

Scripting API

Create

from ArtisanPlugin.Scripting import GemApi as gem

Create is how a script puts a stone into the document. You give it a cut, a compound, a carat weight and a plane; it builds the same proportioned, faceted gem the ribbon’s QuickGems places by hand, and hands you a handle to it.

Shapes and materials are named by string, so the honest way to write a script is to ask the API which strings exist before you use one.

Discovery

gem.Shapes()      # -> ["ROUND", "PRINCESS", "MARQUISE", "EMERALD", ...]
gem.Materials()   # -> ["DIAMOND", "RUBY", "SAPPHIRE", ...]

Both are read-only, need no Transaction and are not gated on the licence — an unlicensed user can still inspect what the plugin supports. Shapes() returns the names of the GemShape enumeration and Materials() the names of GemCompound, which are exactly the sets Create parses against. Call them and pick from the result rather than guessing a cut name; the list is the source of truth and it grows with the plugin.

The discovery-then-create loop is the whole idiom:

shapes = gem.Shapes()
if "PEAR" in shapes:
    g = gem.Create("PEAR", "Diamond", 0.75, Plane.WorldXY)

Or, to build one stone of every cut on a row:

from Rhino.Geometry import Plane, Point3d
from ArtisanPlugin.Scripting import Transaction

with Transaction.Begin("Shape sampler"):
    for i, shape in enumerate(gem.Shapes()):
        plane = Plane(Point3d(i * 8.0, 0, 0), Plane.WorldXY.ZAxis)
        gem.Create(shape, "Diamond", 0.50, plane)

Usage

g = gem.Create(shape, material, caratWeight, plane)   # -> an IGem handle
ParameterDefaultMeaning
shapeA cut name from Shapes(), e.g. "ROUND", "PRINCESS", "MARQUISE", "EMERALD"
materialA compound name from Materials(), e.g. "Diamond", "Ruby", "Sapphire"
caratWeightCarats; must be greater than 0. Drives the stone’s millimetre size through the proportion tables
planeA Rhino.Geometry.Plane giving both position and orientation. Plane.WorldXY means “at the origin, table up”

There are no optional arguments: all four are required, and plane is a full plane rather than a point, so the stone arrives already oriented.

How the strings are parsed

Both shape and material go through the same normalisation before they are matched against the enumeration: the string is trimmed, then every dash and every space becomes an underscore, and the comparison itself is case-insensitive. So "rose gold", "rose-gold", "Rose_Gold" and "ROSE_GOLD" all resolve to the same compound, and "round" is as good as "ROUND". This is the same convention SetMaterial uses on the handle, so the two surfaces stay consistent. What normalisation does not do is guess: an unknown name is an error, never a silent fallback to diamond.

What it returns

An IGem handle, not a Guid. The handle is a live view of the stone — read Shape, Material, CaratWeight, SizeX/SizeY/SizeZ, Position, Plane and LayerName from it, and mutate the stone through Move, Rotate, SetCaratWeight, Copy, Delete and the rest. It re-resolves the object from the document on every access rather than caching it, so it stays correct as the document changes. See the gem handle for the full surface. The Guid is still there if you need it, as g.Id.

Where the stone lands

The new gem is added to the active document as a proper Artisan gemstone object, its gemstone material is applied, and it is placed on the primary gems layer — not on the current layer, and not on whatever layer the script was working with. (Copy() on the handle behaves differently: a copy stays on the source gem’s layer.) The result is indistinguishable from a stone the user placed through the ribbon, and downstream tools — settings, cutters, reports, collision checks — treat it as such.

caratWeight is not a label attached to the stone: it is the input to the same proportion table QuickGems uses, which turns carats plus cut plus compound into the X, Y and Z millimetre dimensions the mesh is generated at. Change the carats later with SetCaratWeight and the stone is rebuilt at the new proportions, keeping its plane, layer and material.

Errors

Create mutates the document, so it requires a valid licence: it raises ScriptingNotLicensedException before doing anything otherwise. Beyond that it validates every argument and throws rather than approximating:

  • no open document — “No active document.”
  • an unrecognised cut — “Unknown gem shape ‘X’.”
  • an unrecognised compound — “Unknown gem material ‘X’.”
  • a zero or negative weight — “Carat weight must be > 0.”

Because Create writes to the document, wrap runs of them in a Transaction so the whole script collapses into one undo step.