Skip to content

Python API

The functions the window calls. Signatures are the real ones; defaults are what you get if you leave the argument out.

from Am_landmark.core import shaders, symmetry, tools, landmark_io
from Am_landmark.core import mesh_utils, color_utils, naming

Opening the window

import Am_landmark

Am_landmark.load()                      # open (or raise) the window
Am_landmark.reload(open_window=None)    # re-import the package; see Install
Am_landmark.__version__

shaders

Create, tag, colour, assign and delete landmarks.

Creating and editing

create_landmark(name, rgb=(0.8, 0.2, 0.2), shader_type="surfaceShader",
                group="", notes="", reuse_existing=True)
Creates or updates one landmark and its shading group. Returns {"shader": name, "shadingGroup": name, "color": rgb}. With reuse_existing, a landmark that already has this name is updated rather than duplicated.

rename_landmark(shader, new_name)          # renames the shading group too
duplicate_landmark(shader, new_name=None)  # copy, own shading group, unassigned
change_shader_type(shader, new_type)       # keeps the assignment; see Shaders
delete_landmarks(shaders, restore_to_default=True)
delete_unused(include_untagged=False, pattern="")

Colour

get_color(shader, linearize=None)          # display-space (r, g, b)
set_color(shader, rgb, linearize=None)
color_attr(shader)                         # "color", "outColor", "baseColor" …
get_transparency(shader)                   # 0..1
set_transparency(shader, amount)
transparency_attr(shader)

linearize overrides the sRGB→linear preference for one call.

Metadata

is_landmark(node)
tag_landmark(shader, group="", notes="", landmark_id=None)
untag_landmark(shader)
landmark_group(shader)          / set_landmark_group(shader, group)
landmark_notes(shader)          / set_landmark_notes(shader, notes)
landmark_id(shader)             / set_landmark_id(shader, value)

Finding

landmark_shaders(include_untagged=False, pattern="")   # every landmark, sorted
landmark_groups()                                      # group names in use
landmark_info(shader)                                  # everything, one pass
landmarks_on_selection(targets=None)
is_unused(shader) / unused_landmarks(...)
available_shader_types(candidates=SHADER_TYPES)        # what this Maya can make
is_protected(node)                                     # default / referenced / locked

landmark_info returns shader, type, shadingGroup, color, group, notes, id, faces, meshes, tagged.

Assigning

assign(shader_or_group, targets=None)      # targets default to the selection
assign_faces(shader_or_group, mapping)     # {shape: ids or None}
clear_assignment(shader_or_group, targets=None)
assigned_faces(shader_or_group)            # {shape: set_of_ids}
assigned_face_count(shader_or_group)
select_assigned(shaders, replace=True)

Shading groups and nodes

shading_group(shader) / ensure_shading_group(shader) / shader_of(group)
select_nodes(shaders, include_shading_group=False, replace=True)
show_in_attribute_editor(shader)
show_in_hypershade(shaders)

Constants

SHADER_TYPES, COLOR_PLUGS, PROTECTED_MATERIALS, PROTECTED_SETS, ATTR_LANDMARK, ATTR_GROUP, ATTR_NOTES, ATTR_ID, PREF_LINEARIZE.

symmetry

The operation

mirror_assignments(shapes=None, mode=MODE_SPATIAL, axis="X", space="Object",
                   pivot=0.0, tolerance=0.001, direction=DIR_POS_TO_NEG,
                   selected_faces_only=False, landmarks_only=True,
                   cross_mesh=True, side_pairs=None)
Returns {"mirrored": n, "unmatched": n, "shapes": {shape: [ids]}, "messages": [...]}.

mirror_face_selection(mode=MODE_SPATIAL, axis="X", space="Object", pivot=0.0,
                      tolerance=0.001, add=False)
symmetry_report(shapes=None, axis="X", space="Object", pivot=0.0,
                tolerance=0.001, mode=MODE_SPATIAL)
select_unmatched(report)

Maya's own symmetry

maya_symmetry_state()      # (enabled, axis, space, topological)
set_maya_symmetry(enabled=True, axis="X", space="Object", topological=False)
maya_symmetry_faces(shape, face_ids)

The maps

face_mirror_map(shape, mode=MODE_SPATIAL, axis="X", space="Object",
                pivot=0.0, tolerance=0.001)          # ({face: face}, info)
cross_mesh_mirror_map(source_shape, target_shape, axis="X", space="World", ...)
counterpart_shape(shape, pairs=None)                 # L_arm_geo -> R_arm_geo

Pure, Maya-free, and unit tested — useful if you are building your own tool:

spatial_map(source_points, target_points, axis=0, pivot=0.0,
            tolerance=0.001, mirror=True)            # {index: index}
build_edge_face_table(face_vertices)
find_seam_seed(face_vertices, vertex_points, face_centers, axis=0,
               pivot=0.0, tolerance=0.001)
build_topological_map(face_vertices, seed_face_a, seed_face_b, vertex_seed)
mirror_point(point, axis=0, pivot=0.0)

Constants

MODES — MODE_SPATIAL, MODE_MAYA_TOPO, MODE_SEAM_TOPO. DIRECTIONS — DIR_POS_TO_NEG, DIR_NEG_TO_POS, DIR_SWAP. AXES, SPACES, DEFAULT_TOLERANCE.

tools

coverage_report(shapes=None)
select_unassigned(shapes=None)
select_landmark_faces(shapes=None)

apply_palette(shaders, targets=None, spread="Per Object")   # or "Per Shell", "All"
landmarks_from_shells(shape=None, prefix="shell",
                      shader_type="surfaceShader", group="", colors=None)
recolor(shaders, mode="Distinct", **generator_kwargs)
sort_by_hue(shaders)

transfer_landmarks(source_shape, target_shapes, mode="Face Index",
                   tolerance=0.01, space="World", landmarks_only=True)

bake_to_vertex_colors(shapes=None, landmarks_only=True, display=True)
clear_vertex_colors(shapes=None)

create_preview_spheres(shaders, radius=0.5, spacing=1.3)
delete_preview_spheres()
isolate_landmarks(shaders, enable=True)
frame_landmarks(shaders)

connected_shells(face_vertices)      # pure: faces -> [[face ids], …]
mesh_shells(shape)

coverage_report returns total, landmark, other, none and a per-shape breakdown with the actual face ids.

landmark_io

export_landmarks(shaders, path, include_assignments=True,
                 include_attributes=True, include_uv=False,
                 include_point=False, point_space="Object", meta=None)

import_landmarks(path, create_missing=True, apply_assignments=True,
                 apply_attributes=True, search="", replace="",
                 match_mode="Contains", namespace="", strip_namespaces=False,
                 recolor_existing=True, match_method=MATCH_FACE_INDEX,
                 tolerance=None, color_set=None)

import_landmarks returns created, updated, assigned, landmarks, unmatched, method, missing_meshes, messages, and error if the file could not be read.

Lower level, if you are building files yourself:

collect_entries(shaders, ...)     # scene  -> entries
build_document(entries, meta=None)# entries -> document
parse_document(data)              # document -> entries  (v1, v2 and v3)
read_file(path) / write_file(path, document)
remap_assignments(assignments, transform, namespace=None, strip_namespaces=False)

Constants

MATCH_METHODS — MATCH_FACE_INDEX, MATCH_UV, MATCH_POINT, MATCH_COLOR_SET. DEFAULT_TOLERANCE (a dict, per method), POINT_SPACES, FORMAT_NAME, FORMAT_VERSION, ATTRIBUTE_WHITELIST.

mesh_utils

mesh_shapes(nodes=None, selection_fallback=True)
shape_of(node) / long_name(node) / face_count(shape)
parse_selection(items=None, convert_components=True)   # {shape: ids or None}
resolve_faces(shape, ids)
select_faces(mapping, replace=True)

face_centers(shape, space="object")        # [(x, y, z), …] by face id
face_vertices(shape)                       # [(v, v, v, v), …] winding order
vertex_positions(shape, space="object")
face_uv_centers(shape, uv_set=None)        # [(u, v) or None, …]
face_colors(shape, color_set=None)         # [(r, g, b) or None, …]
bounding_box(shape, space="object")

uv_sets(shape) / current_uv_set(shape)
color_sets(shape) / current_color_set(shape)

connected_shaders(shape)                   # (names, per-face index)
faces_by_shading_group(shape)              # {group: set_of_ids}
unassigned_faces(shape)

compress_ids(ids)                          # {0,1,2,5} -> [(0,2),(5,5)]
expand_ranges(ranges)
component_strings(node, ids, attr="f")     # chunked "shape.f[0:2]" lists
parse_component_string(text)

color_utils

No Maya import at all — usable anywhere.

hue_wheel(count, saturation=0.72, value=0.95, offset=0.0)
distinct(count, saturation=0.72, value=0.95, offset=0.0)
ramp(start_rgb, end_rgb, count, space="HSV", shortest_hue=True)
harmony(base_rgb, kind="Complementary", count=5)
random_palette(count, seed=None, saturation=0.72, value=0.95,
               min_distance=0.22, jitter=0.18)
preview_swatches(mode, count, **kwargs)    # the dispatch the UI uses

rgb_to_hex(rgb) / hex_to_rgb(text, default=(0.5, 0.5, 0.5))
hsv_to_rgb(h, s, v) / rgb_to_hsv(r, g, b)
srgb_to_linear(value) / linear_to_srgb(value)
display_to_rendering(rgb) / rendering_to_display(rgb)
relative_luminance(rgb) / readable_ink(rgb) / color_distance(a, b)

GENERATOR_MODES, HARMONY_KINDS and RAMP_SPACES are the lists the UI shows.

naming

Also Maya-free.

swap_side(name, pairs=None)          # L_arm_geo <-> R_arm_geo
side_of(name, pairs=None)            # "left" / "right" / ""
has_side_token(name, pairs=None)
side_pairs(left_raw=None, right_raw=None)

build_name_transform(search, replace, mode="Contains")   # -> fn(name) -> name
strip_namespace(name) / apply_namespace(name, namespace) / namespace_of(name)
node_name(path) / sanitize(name) / numbered(base, index, pad=2)
next_free_name(base, taken)

MATCH_MODES is ("Contains", "Prefix", "Suffix", "Regex"); DEFAULT_SIDE_PAIRS is the left/right token table.

Undo

from Am_landmark.core.undo import undo_chunk, preserve_selection

with undo_chunk("My tool: mark up head"):
    ...          # several landmark operations, one Ctrl+Z for the user

with preserve_selection():
    ...          # restores the user's selection afterwards

The public operations already do this; you need it only when combining several into one action of your own.