r/Maya • • Jun 10 '26

MASH Hide instance of mash with animated geometry

Hello, I'm having a problem with Mash. When I connect a cube to a visibility node on my Mash using a falloff, the grass blades are correctly hidden at the cube's location. However, when I do the same with an animated ABC or a model that I blend shape onto the ABC, it doesn't work. All the grass disappears. I'm using the same settings, though.

I've also tried changing them, but the grass doesn't reappear. Does anyone have any ideas?

I'm also using a script to automatically generate my connections:

import maya.cmds as mc

from projectConfig.mayaConfig import MAYA_ROOT


def get_mash_visibility_nodes():
    return mc.ls(type="MASH_Visibility", recursive=True)


def get_mash_python_nodes():
    return mc.ls(type="MASH_Python", recursive=True)


def get_char_props_mesh():
    list_shape = []
    list_main_grps = [
        f'{MAYA_ROOT["long_name"]}|PRP|SURF',
        f'{MAYA_ROOT["long_name"]}|PROP|SURF',
        f'{MAYA_ROOT["long_name"]}|CHAR|SURF',
        f'{MAYA_ROOT["long_name"]}|CHAR|GROOM',
        f'{MAYA_ROOT["long_name"]}|VEH|SURF',
        f'{MAYA_ROOT["long_name"]}|VEG|SURF',
        f'{MAYA_ROOT["long_name"]}|VEGET|SURF',
    ]
    for grp in list_main_grps:
        if mc.objExists(grp):
            for shape in mc.listRelatives(grp, allDescendents=True, fullPath=True):
                if 'CHAR' in shape and 'body' in shape and 'Shape' in shape and 'GEO' in shape:
                    if not 'href' in shape:
                        list_shape.append(shape)
                elif 'CHAR' in shape and 'Body' in shape and 'Shape' in shape and 'GEO' in shape:
                    if not 'href' in shape:
                        list_shape.append(shape)
                elif 'CHAR' in shape and 'cloth' in shape and 'Shape' in shape and 'GEO' in shape:
                    list_shape.append(shape)
                else:
                    if not 'CHAR' in shape and 'Shape' in shape:
                        list_shape.append(shape)
    return list_shape


def get_mash_python_node(mash_vis):
    mash_python = mash_vis.replace("Visibility", "Python")
    if mc.objExists(mash_python):
        return mash_python
    else:
        return None


def add_mash_falloff(mash_vis, mash_python, list_shapes, search_radius=1.0, inner_radius=0.3):
    created_falloffs = []
    if not mash_python:
        return None

    for shape in list_shapes:
        if mc.objExists(shape):
            print(shape)
            try:
                idx = list_shapes.index(shape)
                trs = mc.listRelatives(shape, parent=True, fullPath=True)[0]
                meshName = trs.split('|')[-1].split(':')[-1].replace("msh", "")

                falloff_name = mash_vis.split(':')[-1].replace("Visibility_scene", 'Falloff') + meshName + '_' + str(idx)
                falloff_trs = mc.createNode('transform', name=falloff_name)
                falloff_node = mc.createNode("MASH_Falloff", name=falloff_name+'Shape', parent=falloff_trs)

                mc.setAttr(f"{falloff_node}.falloffShape", 6)
                mc.setAttr(f"{falloff_node}.invertFalloff", True)
                mc.setAttr(f"{falloff_node}.excludeInterior", False)
                mc.setAttr(f"{falloff_node}.searchRadius", search_radius)
                mc.setAttr(f"{falloff_node}.innerRadius", inner_radius)
                mc.setAttr(f"{falloff_node}.meshMode", 1)

                mc.connectAttr(f"{shape}.worldMesh", f"{falloff_node}.shapeIn")
                mc.connectAttr(f"{trs}.worldMatrix", f"{falloff_node}.shapeMatrix")
                mc.connectAttr(f"{mash_python}.outputPoints", f"{falloff_node}.falloffIn")
                mc.connectAttr(f"{falloff_node}.falloffOut", f"{mash_vis}.strengthPP[{idx}]")

                created_falloffs.append(falloff_node)
            except Exception as e:
                print(e)
                pass

    return created_falloffs

def create_scene_vis_mash(mash_vis):
    new_vis_name = mash_vis.split(':')[-1]+'_scene'
    visibility_node = mc.createNode("MASH_Visibility", name=new_vis_name)
    waiter_node = mash_vis.replace('_Visibility', '')
    mc.connectAttr(f"{visibility_node}.outputPoints", f"{waiter_node}.inputPoints", force=True)
    mc.connectAttr(f"{mash_vis}.outputPoints", f"{visibility_node}.inputPoints", force=True)
    return visibility_node


def connect_cam_to_mash(mash_vis):
    mc.setAttr(f"{mash_vis}.enableFrustum", 1)
    mc.setAttr(f"{mash_vis}.useFilmGate", 0)
    mc.setAttr(f"{mash_vis}.frustumBorder", 1.5)

    for camera in mc.ls(type="camera", long=True, recursive=True):
        if 'ROOT' in camera:
            mc.connectAttr(f"{camera}.message", f"{mash_vis}.camera", force=True)
            break


def mask_mash():
    for mash_vis in get_mash_visibility_nodes():
        connect_cam_to_mash(mash_vis)
        python_node = get_mash_python_node(mash_vis)
        vis_scene = create_scene_vis_mash(mash_vis)
        add_mash_falloff(vis_scene, python_node, get_char_props_mesh())


mask_mash()
1 Upvotes

5 comments sorted by

•

u/AutoModerator Jun 10 '26

You're invited to join the community discord for /r/maya users! https://discord.gg/FuN5u8MfMz

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/TomAMoreton Jun 10 '26

dunno about the script but when i have struggled to get blendshapes working in mash it has needed a time node too - not sure if that is obvious or not!

1

u/Domerian Jun 10 '26

Thanks for the tip, but I can't add node time to my mash network; it's greyed out. But it was a good idea 😉

1

u/sepu6 Jun 10 '26

can you share the scene or a repro? might be a different way to solve the issue

1

u/Domerian Jun 10 '26

I found part of the problem: the mesh of my character's body has holes around the eyes, so Mash is having trouble interpreting the object (I should have thought of that sooner, sorry ^^"). However, I have a cushion that works, but when I duplicate it to test with several meshes, it stops working.
Currently, I have one visibility node for the camera and one for the meshes.