/* ======================================================================== * Copyright (c) 2005-2026 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using System.Collections.Generic; using Opc.Ua.OpenUsd.Scene; namespace Opc.Ua.OpenUsd.Tests { /// /// Small query helpers over a , so the assertions in the /// server test fixtures read close to the address-space concepts they check. /// internal static class SceneQuery { /// /// The materialized prim at an absolute SdfPath (for example /Plant). /// public static UsdPrimState Prim(this MaterializedScene ms, string path) { return ms.Result.PrimsByPath[path]; } /// /// The materialized attribute keyed <primPath>.<name>. /// public static UsdAttributeState Attr(this MaterializedScene ms, string key) { return ms.Result.AttributesByPath[key]; } /// /// The attribute's ArrayDimensions as a plain array, or null for a scalar — the /// ArrayOf<uint> a materialized Variable carries unwraps to a /// uint[]? that NUnit compares element-wise. /// public static uint[]? Dims(this UsdAttributeState attribute) { return attribute.ArrayDimensions.ToArray(); } /// /// The boxed value of a materialized attribute, or null when unset. /// public static object? BoxedValue(this UsdAttributeState attribute) { return attribute.Value.AsBoxedObject(); } /// /// The materialized AddIns of type under a prim's /// AppliedSchemas folder, in address-space order. /// public static List AppliedSchemas(this MaterializedScene ms, string primPath) where T : NodeState { FolderState? folder = ms.Prim(primPath).AppliedSchemas; if (folder == null) { return new List(); } return MaterializationHarness.ChildrenOfType(ms.Context, folder); } /// /// The materialized composition arcs under a prim's Composition folder, in /// address-space order. /// public static List CompositionArcs( this MaterializedScene ms, string primPath) { FolderState? folder = ms.Prim(primPath).Composition; if (folder == null) { return new List(); } return MaterializationHarness.ChildrenOfType(ms.Context, folder); } /// /// The absolute SdfPath of a parsed prim, walked from its parent chain. /// public static string PathOf(this Scene.UsdPrim prim) { var parts = new List(); Scene.UsdPrim? current = prim; while (current != null) { parts.Insert(0, current.Name); current = current.Parent; } return "/" + string.Join("/", parts); } /// /// The total number of authored attribute connections across a whole scene. /// public static int TotalConnections(this Scene.UsdStage stage) { int total = 0; foreach (Scene.UsdPrim prim in stage.AllPrims()) { foreach (Scene.UsdAttribute attribute in prim.Attributes) { total += attribute.Connections.Count; } } return total; } /// /// Nulls every attribute value and clears every attribute connection across a scene, so /// two scenes can be compared on structure and provenance alone. This is the workaround /// for the two exporter round-trip defects the fixtures pin separately. /// public static Scene.UsdStage NormalizeValuesAndConnections(this Scene.UsdStage stage) { foreach (Scene.UsdPrim prim in stage.AllPrims()) { foreach (Scene.UsdAttribute attribute in prim.Attributes) { attribute.Value = Scene.UsdValue.Null; attribute.Connections.Clear(); } } return stage; } } }