Skip to content

Scripting API

Gem tools

from ArtisanPlugin.Scripting import GemToolsApi as gemtools, Transaction

The gem utility commands of the ribbon - the ones that are not gem creators - exposed as twelve headless methods. All lengths are millimetres in a mm document. Every method that writes to the document checks the licence first and ends with a viewport redraw; wrap those in a Transaction so the whole script undoes in one step. Centers is the only read-only method here and needs no transaction.

Usage

ids = [g.Id for g in gem.Selected()]

pts = gemtools.Centers(ids)                       # read-only

with Transaction.Begin("Prong guides and tags"):
    gemtools.CenterBetweenGems(ids)
    gemtools.AddTags(ids)

How gemIds resolves

The rule is not uniform, and it is worth getting right.

  1. If you pass ids, each one is validated: a non-gem id throws ArgumentException naming it - Object … is not an Artisan diamond or gemstone. Duplicates are dropped, and the selection is never consulted.
  2. If gemIds is None or empty, the gems currently selected in the viewport are used.
  3. Only three methods - CenterBetweenGems, ColorBySize and AddTags - additionally fall back to every gem in the document when the selection contains none, matching the commands that accept Enter with nothing selected. Centers, AddCenterPoints, CurveFromGems, ExtractGemCurves, OffsetGemCurves, RotateGems and AlignGems do not: with nothing selected they throw No gems to work on: select (or pass) at least one Artisan diamond or gemstone.

CopyByGems uses its own rules (see below), and RecoverGems takes no ids at all - it always scans the whole document.

Centers

gemtools.Centers(gemIds = None)   # -> list of Point3d

The centre of each gem - its plane origin, which sits on the girdle. Read-only: nothing is added to the document, no licence is needed, no transaction required. The points come back in the same order as gemIds, or in selection order when it is None. Gems whose plane cannot be read are skipped, so the result can be shorter than the input.

Selection fallback only; no document-wide fallback.

AddCenterPoints

gemtools.AddCenterPoints(gemIds = None)   # -> list of Guid

ArtisanGemsCenter, headless: adds a point object at the centre of each gem - the anchors you snap prongs, cutters or a rail curve to. Returns the ids of the created points. Mutates the document.

Selection fallback only.

CenterBetweenGems

gemtools.CenterBetweenGems(gemIds = None)   # -> list of Guid

ArtisanCenterBetweenGems, headless: for every triple of mutually adjacent stones it fits the circle tangent to the three girdle circles and adds it - the classic shared-prong guide. Adjacency is a cheap distance test (centres closer than the sum of the two diameters), and clearly scalene triples are rejected unless the stones are large enough to still touch a common prong. Duplicate results within 0.001 mm are collapsed, and stacked gems sharing a plane count once.

All the circles created in one call are put in a single group, so one click picks up the whole guide set. Returns the ids of the created circles - possibly empty, when no triple qualifies. Mutates the document.

Falls back to the selection, then to every gem in the document.

CurveFromGems

gemtools.CurveFromGems(gemIds = None)   # -> Guid

ArtisanCurveFromGems, headless: interpolates a degree-3 curve through the gem centres and adds it to the document. Returns the id of the single created curve. Mutates the document.

Consecutive coincident centres (stacked duplicates) are skipped so the interpolation does not fail. At least two distinct centres are required, otherwise At least two gems with distinct centres are required to create a curve. If the interpolation itself fails you get It is not possible to create a curve through those gem centers.

Selection fallback only.

ExtractGemCurves

gemtools.ExtractGemCurves(gemIds = None)   # -> list of Guid

ArtisanGemsCurve, headless: duplicates the girdle curve of each gem as a plain document curve - the profile you sweep, loft or cut against. Works on all five Artisan gem object types. Returns the ids of the created curves; gems whose curve cannot be read are skipped. Mutates the document.

Selection fallback only.

OffsetGemCurves

gemtools.OffsetGemCurves(gemIds = None, distance = 1.0)   # -> list of Guid

ArtisanGemOffset, headless: offsets each gem’s girdle curve outward by distance mm and adds the result as a parametric gem-offset object. The offset direction is normalised against the gem’s own plane, so the girdle curve’s own direction does not matter.

Each curve is added with a history record pointing at the gem-offset command, exactly as the ribbon button does, so the offset curve follows its gem when the gem is moved, rotated or resized. If the plugin’s gem-offset command is not available in the session, the call fails with The gem-offset command is not available in this Rhino session.

A distance smaller than the document’s absolute tolerance adds the girdle curve unchanged - the same as answering 0 in the command. Gems whose offset fails (a self-intersecting result, or an offset that yields more than one curve) are skipped, as in the command. Returns the ids of the created curves. Mutates the document.

Selection fallback only.

CopyByGems

gemtools.CopyByGems(objectIds, targetGemIds,
                    originGemId = Guid.Empty, scale = "No")   # -> list of Guid

ArtisanCopyByGems, headless: takes a prong, a cutter, a bezel - whatever you have modelled around one stone - and copies it onto every gem in targetGemIds, mapping from the origin gem’s plane to each target gem’s plane. The copies are made with TransformWithHistory, so they stay linked to the original just as the command’s do, and the parametric engine is told to reconcile and invalidate the children of the target gems afterwards.

ParameterDefaultMeaning
objectIds-The objects to copy. None or empty means the current selection (any objects, not only gems); if that is empty too: Nothing to copy: select (or pass) at least one object.
targetGemIds-The gems to copy onto. No fallback: each id must be an Artisan diamond or gemstone, and at least one is required - At least one target gem is required.
originGemIdGuid.EmptyThe gem the objects were modelled around. Guid.Empty means they are modelled on the world XY plane - the command’s “Enter = CPlane” answer
scale"No"Case-insensitive: "No" copies as-is; "2D" scales X and Y by targetGemSizeX / originGemSizeX; "3D" scales X, Y and Z by that same factor. Anything else throws Unknown scale mode ‘xxx’. Valid values: No, 2D, 3D.

With originGemId = Guid.Empty the origin size is taken as 1, so "2D" and "3D" scale by the target’s X size in millimetres - meaningful only if the objects were modelled around a 1 mm reference.

Returns the ids of the created copies, targets times objects. Mutates the document.

ColorBySize

gemtools.ColorBySize(gemIds = None)   # -> int

ArtisanGemsColorBySize, headless: gives every gem a per-size display colour so that equal stones read at a glance across a pavé. Sizes are grouped by X dimension rounded to 1e-3 mm, so float noise does not split one size into two colours, and the palette is stable: colour 0 is always the smallest size. Returns the number of gems recoloured. Mutates the document (object colour set to from object).

Falls back to the selection, then to every gem in the document.

RotateGems

gemtools.RotateGems(gemIds = None, angleDegrees = 90)   # -> int

The document effect of the ArtisanGemsOrientation handles, and of ArtisanRotateGemsLeft / Right, headless: rotates each gem around its own plane normal, in place. Positive is counter-clockwise; each click of the orientation gumball is +90, which is the default. Pass a negative angle to rotate clockwise. Squares and baguettes in a channel are the usual case.

Returns the number of gems rotated. Mutates the document.

Selection fallback only.

AddTags

gemtools.AddTags(gemIds = None)   # -> list of Guid

ArtisanGemTags, headless: places a three-line text entity on the top face (table) of each gem - measures as X x Y in mm, then carat weight, then material with underscores turned into spaces. The text plane is lifted from the girdle to the table by measuring the gem’s bounding box in its own plane, and the text height is scaled to the stone at 18% of its largest side, so tags stay legible on a 1 mm melee and on a 10 mm centre alike. The tags land on the primary user layer.

Returns the ids of the created text entities. Mutates the document.

Falls back to the selection, then to every gem in the document.

RecoverGems

gemtools.RecoverGems()   # -> int

ArtisanGemsRecover, headless, and the one method with no parameters at all: it always scans the whole document. Dumb gem geometry exported by Matrix, MatrixGold, RhinoGold or an older RhinoArtisan is recognised by its exact mesh or brep topology and replaced with a parametric Artisan gemstone of the measured shape and size - after which the stone answers to GemApi and to every tool on this page.

The underlying command runs without prompts, so it is invoked directly; the recovery is therefore byte-identical to the ribbon button and picks up new fingerprints automatically. Returns the number of gems recovered - 0 means nothing recognisable was found. Mutates the document.

AlignGems

gemtools.AlignGems(targetIds, gemIds = None,
                   flip = False, adaptToSurface = False, alignTop = False)   # -> int

ArtisanAlignGems, headless: drops each gem onto the target objects. A ray is shot from the gem’s centre along its own axis, +Z first and then -Z, so a stone that already sits past the surface still lands on it, and the gem is translated to the hit point. The targets are meshed together as one high-resolution mesh, like the command.

ParameterDefaultMeaning
targetIds-The surfaces, polysurfaces or meshes to land on. Required, no fallback: empty throws At least one target object is required., a missing id throws Target object … does not exist., and geometry that meshes to nothing throws The target objects produced no surface to align on: pass surfaces, polysurfaces or meshes.
gemIdsNoneThe gems to move. Selection fallback only - no document-wide fallback
flipFalseTurn the gem upside down at the landing point (the command’s Flip toggle, No by default)
adaptToSurfaceFalseOrient the gem’s axis to the surface normal at the landing point (the command’s Orientation toggle, Keep by default)
alignTopFalseSink the gem along its axis by its own height above the girdle, so the table sits on the surface instead of the girdle (the command’s Alignment toggle, On Girdle by default)

The height above the girdle is measured before any move, so alignTop sinks the stone by exactly the right amount whatever the earlier toggles did. Gems whose axis never hits the targets are skipped, as in the command. Positions change in place - the gems keep their Guids.

Returns the number of gems aligned. Mutates the document.

At a glance

MethodReturnsWritesgemIds fallback
CentersPoint3d listnoselection
AddCenterPointsGuid listyesselection
CenterBetweenGemsGuid listyesselection, then all gems
CurveFromGemssingle Guidyesselection (list order matters)
ExtractGemCurvesGuid listyesselection
OffsetGemCurvesGuid listyesselection
CopyByGemsGuid listyestargets required; objects fall back to selection
ColorBySizeint countyesselection, then all gems
RotateGemsint countyesselection
AddTagsGuid listyesselection, then all gems
RecoverGemsint countyesnone - whole document
AlignGemsint countyestargets required; gems fall back to selection