Request for Raycast Python code / Action graph for Omniverse composer application

Hi Richard,

I took the script shared in the other query (Isaac Sim related) and modified to serve my purpose.

I am able to get the Outlining performed when hovered.

But, The script only works from Script editor.

When I try to run the script through the Python scripting component added to an xform, I am getting “viewport not defined” error.

Can you please check the script and help me with updating the code to work as a python scripting component.

import omni.usd
from omni import ui
from omni.ui import scene as sc
from omni.kit.viewport.utility import get_active_viewport_and_window
from pxr import UsdGeom, Gf, Vt

context = omni.usd.get_context()
group_idx = context.register_selection_group()
default_color = Vt.Vec3fArray([Gf.Vec3f(0.0, 0.0, 255.0 / 255.0)])
hit_color = Vt.Vec3fArray([Gf.Vec3f(255.0 / 255.0, 255.0 / 255.0, 0.0)])
context.set_selection_group_outline_color(group_idx, (1, 1, 0, 1))  # Set outline color
context.set_selection_group_shade_color(group_idx, (0, 1, 1, 0)) # alpha 0 for no fill

# Define prim paths for different machines/groups
station2Benchmill = [
    "/prim_path/sample1",
    "/prim_path/sample2"
]

station2RoboticArm = [
    "/prim_path/sample1",
    "/prim_path/sample2"
]

station3Engraver = [
    "/prim_path/sample1",
    "/prim_path/sample2"
]

station3RoboticArm = [
    "/prim_path/sample1",
    "/prim_path/sample2"
]

station4RoboticArm = [
    "/prim_path/sample1",
    "/prim_path/sample2"
]

# Store all machine paths.  Crucially, use a *dictionary* here.
machine_prims = {
    "Machine1": station2Benchmill,
    "Machine2": station2RoboticArm,
    "Machine3": station3Engraver,
    "Machine4": station3RoboticArm,
    "Machine5": station4RoboticArm
}

highlighted_prims = set() #keep track of highlighted prims

def on_hovered(sender: sc.Screen):
    global highlighted_prims # Fix: Declare highlighted_prims as global
    def process_query(prim_path: str, world_position, *args):
        stage = omni.usd.get_context().get_stage()

        # Clear outline from *all* previously highlighted prims
        prims_to_clear = list(highlighted_prims)
        for p in prims_to_clear:
            context.set_selection_group(0, p)
            highlighted_prims.remove(p)

        # Get the prim that was actually hovered on
        hovered_prim = stage.GetPrimAtPath(prim_path)
        if not hovered_prim.IsValid():
            return  # Exit if the hovered prim is invalid

        # Determine which machine group the hovered prim belongs to
        machine_to_highlight = None
        for machine_name, prim_list in machine_prims.items():
            if prim_path in prim_list:
                machine_to_highlight = machine_name
                break  # Found the machine, no need to keep searching

        # If found, highlight all prims in that machine group
        if machine_to_highlight:
            for prim_to_highlight_path in machine_prims[machine_to_highlight]:
                context.set_selection_group(group_idx, prim_to_highlight_path)
                highlighted_prims.add(prim_to_highlight_path)

    mouse, api = viewport.map_ndc_to_texture_pixel(sender.gesture_payload.mouse)
    if api:
        viewport.request_query(mouse, process_query)

viewport, window = get_active_viewport_and_window()
with window.get_frame("HoverHighlight") as hover_frame:
    scene_view = sc.SceneView()
    viewport.add_scene_view(scene_view)
    with scene_view.scene:
        hovered_gesture = sc.HoverGesture(on_changed_fn=on_hovered)
        screen = sc.Screen(gestures=[hovered_gesture])

Error :