01When To Use Maya Integration
Quick gut check before you build in Maya: is this a person job or a machine job? If someone needs to look at the result before committing - a hero prop, a character piece, a "does this merge look okay" test - Maya is the right home. If it's four hundred props overnight, that's the standalone page and a build machine; keeping Maya open for that is just paying for a very expensive progress bar.
- Great in Maya: selected props, character pieces, material merge experiments, anything an artist wants to eyeball first.
- Wrong in Maya: big nightly batches. Unless the job genuinely needs Maya's scene evaluation, don't drag the whole DCC along for the ride.
- Either way, keep the actual Simplygon logic DCC-agnostic and call it from a thin Maya wrapper - then the same code serves both worlds.
02Load The Plugin
First job: make sure the plugin is actually loaded, and fail loudly if it isn't. Nothing erodes trust in a tool faster than a cryptic error because someone's Maya didn't have the plugin ticked. Run this from the Script Editor, a shelf tool, or mayapy:
import maya.cmds as cmds
def ensure_simplygon_plugin(plugin_name="SimplygonMaya"):
try:
loaded = cmds.pluginInfo(plugin_name, query=True, loaded=True)
except RuntimeError:
loaded = False
if not loaded:
cmds.loadPlugin(plugin_name)
if not cmds.pluginInfo(plugin_name, query=True, loaded=True):
raise RuntimeError(f"Could not load Maya plugin: {plugin_name}")
The reference scripts use SimplygonMaya. If your installed plugin has a versioned name, confirm it in Maya's Plug-in Manager and pass that name to the loader.
03Export Selection And Import Results
The whole Maya workflow hangs off one trick: the plugin command exports your selection to a Simplygon scene file, and imports a processed one back. Everything else on this page is just what happens between those two calls. A temp .sb file plays middleman:
import os
import tempfile
import maya.cmds as cmds
def selected_or_raise():
selection = cmds.ls(selection=True, long=True) or []
if not selection:
raise RuntimeError("Select one or more meshes before running Simplygon")
return selection
def export_selection_to_simplygon(path):
selected_or_raise()
ensure_simplygon_plugin()
cmds.Simplygon(exp=path)
def import_simplygon_scene(path, load_materials=True):
ensure_simplygon_plugin()
cmds.Simplygon(imp=path, lma=load_materials)
def temp_simplygon_path(label="maya_selection"):
return os.path.join(tempfile.gettempdir(), f"{label}.sb")
04Reduce The Current Selection
Put the pieces together and you get the tool every Maya TA ends up writing eventually: select, press button, reduced copy appears. Export the selection, run a pipeline on it, import the result back - that's the whole trick:
from simplygon10 import Simplygon
from sg_samples.core.simplygon_instance import SimplygonInstance
def reduce_maya_selection(ratio=0.5):
sg = SimplygonInstance()
temp_path = temp_simplygon_path("simplygon_maya_reduce")
export_selection_to_simplygon(temp_path)
scene = sg.CreateScene()
scene.LoadFromFile(temp_path)
pipeline = sg.CreateReductionPipeline()
settings = pipeline.GetReductionSettings()
settings.SetReductionTargets(
Simplygon.EStopCondition_All,
True, False, False, False
)
settings.SetReductionTargetTriangleRatio(ratio)
pipeline.RunScene(scene, Simplygon.EPipelineRunMode_RunInThisProcess)
processed_scene = pipeline.GetProcessedScene()
processed_scene.SaveToFile(temp_path)
import_simplygon_scene(temp_path, load_materials=True)
For an artist-facing shelf button, expose ratio as a slider. Keep sensible presets such as 0.75, 0.5, and 0.25, then let the artist inspect the result in Maya before saving it.
05Create An LOD Chain In Maya
The Maya LOD sample follows the same rule as the standalone chain: build each LOD from the original export, not from the previous LOD. That keeps errors from cascading.
from pathlib import Path
from simplygon10 import Simplygon
def create_maya_lod_chain(screen_sizes=(600, 300, 100)):
sg = SimplygonInstance()
source_path = temp_simplygon_path("simplygon_maya_lod_source")
export_selection_to_simplygon(source_path)
original = sg.CreateScene()
original.LoadFromFile(source_path)
imported_roots = []
for index, screen_size in enumerate(screen_sizes):
scene_copy = original.NewCopy()
pipeline = sg.CreateReductionPipeline()
settings = pipeline.GetReductionSettings()
settings.SetReductionTargets(
Simplygon.EStopCondition_Any,
False, True, False, False
)
settings.SetReductionTargetOnScreenSize(screen_size)
pipeline.RunScene(scene_copy, Simplygon.EPipelineRunMode_RunInThisProcess)
lod_path = temp_simplygon_path(f"simplygon_maya_lod{index}")
pipeline.GetProcessedScene().SaveToFile(lod_path)
before = set(cmds.ls(assemblies=True, long=True))
import_simplygon_scene(lod_path, load_materials=True)
after = set(cmds.ls(assemblies=True, long=True))
imported_roots.extend(sorted(after - before))
if imported_roots:
group = cmds.group(imported_roots, name="simplygon_LOD_chain")
return group
return None
After import, check the LODs in a simple turntable camera and in engine. Screen-size targets are useful, but game cameras and material complexity still decide whether an LOD is acceptable.
06Quad Reduction
Quad reduction is useful when the result still needs to be modeler-friendly or deformation-friendly. It's usually a better fit for close-up character or subdivision-style assets than aggressive triangle reduction.
def create_quad_reduction_pipeline(sg):
if hasattr(sg, "CreateQuadReductionPipeline"):
return sg.CreateQuadReductionPipeline()
raise RuntimeError(
"This SDK build does not expose a quad reduction pipeline. "
"Use triangle reduction or update the SDK/plugin."
)
If your SDK build exposes dedicated quad reduction settings, use them. If not, don't pretend triangle reduction is the same thing. Label the fallback clearly so artists know what topology to expect.
07Material Merging In Maya
If you want an easy win with the art team, ship this one first. An artist selects their seventeen-material kitbash prop, presses the button, and gets back one mesh with one baked atlas. Draw calls drop, nothing visibly changes, and suddenly everyone wants your tools.
from simplygon10 import Simplygon
def merge_maya_selection_materials(texture_size=2048):
sg = SimplygonInstance()
temp_path = temp_simplygon_path("simplygon_maya_material_merge")
export_selection_to_simplygon(temp_path)
scene = sg.CreateScene()
scene.LoadFromFile(temp_path)
pipeline = sg.CreateAggregationPipeline()
aggregation = pipeline.GetAggregationSettings()
aggregation.SetMergeGeometries(True)
mapping = pipeline.GetMappingImageSettings()
mapping.SetGenerateMappingImage(True)
output_material = mapping.GetOutputMaterialSettings(0)
output_material.SetTextureWidth(texture_size)
output_material.SetTextureHeight(texture_size)
color = sg.CreateColorCaster()
color.GetColorCasterSettings().SetMaterialChannel("Diffuse")
pipeline.AddMaterialCaster(color, 0)
normal = sg.CreateNormalCaster()
normal.GetNormalCasterSettings().SetMaterialChannel("Normals")
normal.GetNormalCasterSettings().SetGenerateTangentSpaceNormals(True)
pipeline.AddMaterialCaster(normal, 0)
pipeline.RunScene(scene, Simplygon.EPipelineRunMode_RunInThisProcess)
pipeline.GetProcessedScene().SaveToFile(temp_path)
import_simplygon_scene(temp_path, load_materials=True)
Add more casters for roughness, metallic, opacity, emissive, or studio-specific channels. Name your Maya materials predictably before export so imported results are easy to inspect.
08Artist-Facing UI Shape
A useful Maya tool should show a small set of predictable controls and hide the SDK plumbing.
| Control | Why It Exists |
|---|---|
| Mode | Reduction, LOD chain, remesh proxy, material merge, or quad reduction. |
| Target | Triangle ratio, screen size, texture size, or preset name. |
| Preserve | Options for materials, vertex colors, skin weights, seams, hard edges, or selection sets. |
| Output | Import into scene, save next to source, or export to a review folder. |
| Report | Warnings, before/after triangle counts, material count, texture sizes, and processing time. |
Artists should choose intent, not SDK terminology. Use labels like "close LOD", "far LOD", "merge kitbash prop", or "make proxy", then map those to versioned pipeline settings.
09Common Maya Pitfalls
- Selection is empty: fail with a clear message before exporting.
- Plugin is not loaded: load it explicitly and report the expected plugin name.
- Temp files collide: include the tool name, user, process id, or timestamp if multiple tools can run at once.
- Imported nodes are hard to find: capture root assemblies before and after import, then group or rename the imported result.
- Materials look different: check channel names, texture paths, tangent-space normal settings, and whether
lma=Trueloaded material assets. - Animated meshes deform badly: test in animation, preserve skin data, and use bone reduction only with explicit review.
- Artists can't compare: keep the original visible or duplicate it into a review group before replacing anything.
The Technical Artist