diff --git a/SwiftUsd.docc/AboutThisRepo/ChangeLog.md b/SwiftUsd.docc/AboutThisRepo/ChangeLog.md index dc0342f993..64767892e9 100644 --- a/SwiftUsd.docc/AboutThisRepo/ChangeLog.md +++ b/SwiftUsd.docc/AboutThisRepo/ChangeLog.md @@ -15,6 +15,7 @@ Changes to SwiftUsd Released TBD, based on OpenUSD TBD - Add `Overlay.HgiGLWrapper`, exposing HgiGL alongside HgiMetal in the Swift bindings - Add `Overlay.ExecUsdSystem`, exposing ExecUsdSystem in the Swift bindings +- Add `Overlay.ArAssetWrapper`, `Overlay.ArWritableAssetWrapper` ### 7.0.1 Released 2026-06-04, based on OpenUSD v26.05 diff --git a/SwiftUsd.docc/WrappedSymbolDocumentation/WrappedTypes.md b/SwiftUsd.docc/WrappedSymbolDocumentation/WrappedTypes.md index 3dfcc3fec7..dec46b895f 100644 --- a/SwiftUsd.docc/WrappedSymbolDocumentation/WrappedTypes.md +++ b/SwiftUsd.docc/WrappedSymbolDocumentation/WrappedTypes.md @@ -24,6 +24,8 @@ Since Swift-Cxx interop doesn't currently support specializing class templates f Access these types by prefixing their name with `Overlay` - ``OpenUSD/Overlay/TfErrorMarkWrapper`` - ``OpenUSD/Overlay/ArResolverWrapper`` +- ``OpenUSD/Overlay/ArAssetWrapper`` +- ``OpenUSD/Overlay/ArWritableAssetWrapper`` - ``OpenUSD/Overlay/UsdPrimTypeInfoWrapper`` - ``OpenUSD/Overlay/HioImageWrapper`` - ``OpenUSD/Overlay/HgiWrapper`` diff --git a/source/SwiftOverlay/TypeConversionInitializers.swift b/source/SwiftOverlay/TypeConversionInitializers.swift index 827b0cde04..a1c59d42c6 100644 --- a/source/SwiftOverlay/TypeConversionInitializers.swift +++ b/source/SwiftOverlay/TypeConversionInitializers.swift @@ -27,6 +27,18 @@ extension Float { } // GfHalf.init(Float) provided by ilmbase_half.h +extension Double { + public init(_ x: pxr.GfHalf) { + self.init(Float(x)) + } +} + +extension pxr.GfHalf { + public init(_ x: Double) { + self.init(Float(x)) + } +} + extension String { public init(_ token: pxr.TfToken) { diff --git a/source/SwiftOverlay/operatorBool.cpp b/source/SwiftOverlay/operatorBool.cpp index 1b746a252b..acf9293fa8 100644 --- a/source/SwiftOverlay/operatorBool.cpp +++ b/source/SwiftOverlay/operatorBool.cpp @@ -78,6 +78,12 @@ bool __Overlay::convertToBool(const pxr::ArResolvedPath& x) { bool __Overlay::convertToBool(const pxr::SdfZipFile& x) { return (bool) x; } +bool __Overlay::convertToBool(const Overlay::ArAssetWrapper& x) { + return (bool) x; +} +bool __Overlay::convertToBool(const Overlay::ArWritableAssetWrapper& x) { + return (bool) x; +} bool __Overlay::convertToBool(const Overlay::HioImageWrapper& x) { return (bool) x; } diff --git a/source/SwiftOverlay/operatorBool.h b/source/SwiftOverlay/operatorBool.h index 8aeb69c50b..e88c984df8 100644 --- a/source/SwiftOverlay/operatorBool.h +++ b/source/SwiftOverlay/operatorBool.h @@ -42,6 +42,8 @@ #include "pxr/usd/sdf/zipFile.h" #include "pxr/usd/ar/resolvedPath.h" #include "pxr/imaging/hgi/texture.h" +#include "swiftUsd/Wrappers/ArAssetWrapper.h" +#include "swiftUsd/Wrappers/ArWritableAssetWrapper.h" #include "swiftUsd/Wrappers/HioImageWrapper.h" namespace __Overlay { @@ -65,6 +67,8 @@ namespace __Overlay { bool convertToBool(const pxr::ArResolvedPath& x); bool convertToBool(const pxr::SdfZipFile& x); bool convertToBool(const pxr::HgiTextureHandle& x); + bool convertToBool(const Overlay::ArAssetWrapper& x); + bool convertToBool(const Overlay::ArWritableAssetWrapper& x); bool convertToBool(const Overlay::HioImageWrapper& x); } diff --git a/source/SwiftOverlay/operatorBool.swift b/source/SwiftOverlay/operatorBool.swift index 15846567ca..accf3792e0 100644 --- a/source/SwiftOverlay/operatorBool.swift +++ b/source/SwiftOverlay/operatorBool.swift @@ -105,6 +105,15 @@ extension Bool { self.init(__Overlay.convertToBool(x)) } + /// Returns `true` if the `ArAsset` is valid + public init(_ x: Overlay.ArAssetWrapper) { + self.init(__Overlay.convertToBool(x)) + } + /// Returns `true` if the `ArAsset` is valid + public init(_ x: Overlay.ArWritableAssetWrapper) { + self.init(__Overlay.convertToBool(x)) + } + #if canImport(SwiftUsd_PXR_ENABLE_IMAGING_SUPPORT) /// Returns `true` if the `HioImage` is valid public init(_ x: Overlay.HioImageWrapper) { diff --git a/source/Wrappers/ArAssetWrapper.cpp b/source/Wrappers/ArAssetWrapper.cpp new file mode 100644 index 0000000000..47b92ceb11 --- /dev/null +++ b/source/Wrappers/ArAssetWrapper.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// This source file is part of github.com/apple/SwiftUsd +// +// Copyright © 2025 Apple Inc. and the SwiftUsd project authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +//===----------------------------------------------------------------------===// + +#include "swiftUsd/Wrappers/ArAssetWrapper.h" + +size_t Overlay::ArAssetWrapper::GetSize() const { + return get()->GetSize(); +} + +std::shared_ptr Overlay::ArAssetWrapper::GetBuffer() const { + return get()->GetBuffer(); +} + +size_t Overlay::ArAssetWrapper::Read(void* buffer, size_t count, size_t offset) const { + return get()->Read(buffer, count, offset); +} + +std::pair Overlay::ArAssetWrapper::GetFileUnsafe() const { + return get()->GetFileUnsafe(); +} + +Overlay::ArAssetWrapper Overlay::ArAssetWrapper::GetDetachedAsset() const { + return Overlay::ArAssetWrapper(get()->GetDetachedAsset()); +} + +// MARK: SwiftUsd implementation access + +Overlay::ArAssetWrapper::ArAssetWrapper(std::shared_ptr _ptr) : _ptr(_ptr) {} + +pxr::ArAsset* Overlay::ArAssetWrapper::get() const { + return _ptr.get(); +} + +std::shared_ptr Overlay::ArAssetWrapper::get_shared() const { + return _ptr; +} + +Overlay::ArAssetWrapper::operator bool() const { + return (bool)_ptr; +} + diff --git a/source/Wrappers/ArAssetWrapper.h b/source/Wrappers/ArAssetWrapper.h new file mode 100644 index 0000000000..df8a94917a --- /dev/null +++ b/source/Wrappers/ArAssetWrapper.h @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// This source file is part of github.com/apple/SwiftUsd +// +// Copyright © 2025 Apple Inc. and the SwiftUsd project authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +//===----------------------------------------------------------------------===// + +// Original documentation for pxr::ArAsset from +// https://github.com/PixarAnimationStudios/OpenUSD/blob/v26.05/pxr/usd/ar/asset.h + +#ifndef SWIFTUSD_WRAPPERS_ARASSETWRAPPER_H +#define SWIFTUSD_WRAPPERS_ARASSETWRAPPER_H + +#include +#include +#include "pxr/usd/ar/asset.h" + + +namespace Overlay { + class ArAssetWrapper { + public: + /// Returns size of the asset. + size_t GetSize() const; + + /// Returns a pointer to a buffer with the contents of the asset, + /// with size given by GetSize(). Returns an invalid std::shared_ptr + /// if the contents could not be retrieved. + /// + /// The data in the returned buffer must remain valid while there are + /// outstanding copies of the returned std::shared_ptr. Note that the + /// deleter stored in the std::shared_ptr may contain additional data + /// needed to maintain the buffer's validity. + std::shared_ptr GetBuffer() const; + + /// Read \p count bytes at \p offset from the beginning of the asset + /// into \p buffer. Returns number of bytes read, or 0 on error. + /// + /// Implementers should range-check calls and return zero for out-of-bounds + /// reads. + size_t Read(void* buffer, size_t count, size_t offset) const; + + /// Returns a read-only FILE* handle for this asset if + /// available, or (nullptr, 0) otherwise. + /// + /// The returned handle must remain valid for the lifetime of this + /// ArAsset object. The returned offset is the offset from the beginning + /// of the FILE* where the asset's contents begins. + /// + /// This function is marked unsafe because the handle may wind up + /// being used in multiple threads depending on the underlying + /// resolver implementation. For instance, a resolver may cache + /// and return ArAsset objects with the same FILE* to multiple + /// threads. + /// + /// Clients MUST NOT use this handle with functions that cannot be + /// called concurrently on the same file descriptor, e.g. read, + /// fread, fseek, etc. See ArchPRead for a function that can be used + /// to read data from this handle safely + std::pair GetFileUnsafe() const; + + /// Returns an ArAsset with the contents of this asest detached from + /// from this asset's serialized data. External changes to the serialized + /// data must not have any effect on the ArAsset returned by this function. + /// + /// The default implementation returns a new instance of an ArInMemoryAsset + /// that reads the entire contents of this asset into a heap-allocated + /// buffer. + Overlay::ArAssetWrapper GetDetachedAsset() const; + + // MARK: SwiftUsd implementation access + + /// SwiftUsd wrapping constructor + ArAssetWrapper(std::shared_ptr _ptr); + + /// Returns the underlying ArAsset wrapped by this instance + pxr::ArAsset*_Nullable get() const; + + /// Returns the underlying ArAsset wrapped by this instance + std::shared_ptr get_shared() const; + + /// Returns `true` iff the underlying instance is valid + explicit operator bool() const; + + private: + std::shared_ptr _ptr; + }; +} + +#endif /* SWIFTUSD_WRAPPERS_ARASSETWRAPPER_H */ diff --git a/source/Wrappers/ArResolverWrapper.cpp b/source/Wrappers/ArResolverWrapper.cpp index 8c453009db..0d7e865afa 100644 --- a/source/Wrappers/ArResolverWrapper.cpp +++ b/source/Wrappers/ArResolverWrapper.cpp @@ -97,12 +97,12 @@ pxr::ArTimestamp Overlay::ArResolverWrapper::GetModificationTimestamp(const std: return get()->GetModificationTimestamp(assetPath, resolvedPath); } -std::shared_ptr Overlay::ArResolverWrapper::OpenAsset(const pxr::ArResolvedPath& resolvedPath) const { - return get()->OpenAsset(resolvedPath); +Overlay::ArAssetWrapper Overlay::ArResolverWrapper::OpenAsset(const pxr::ArResolvedPath& resolvedPath) const { + return Overlay::ArAssetWrapper(get()->OpenAsset(resolvedPath)); } -std::shared_ptr Overlay::ArResolverWrapper::OpenAssetForWrite(const pxr::ArResolvedPath& resolvedPath, Overlay::ArResolverWrapper::WriteMode writeMode) const { - return get()->OpenAssetForWrite(resolvedPath, static_cast(writeMode)); +Overlay::ArWritableAssetWrapper Overlay::ArResolverWrapper::OpenAssetForWrite(const pxr::ArResolvedPath& resolvedPath, Overlay::ArResolverWrapper::WriteMode writeMode) const { + return Overlay::ArWritableAssetWrapper(get()->OpenAssetForWrite(resolvedPath, static_cast(writeMode))); } bool Overlay::ArResolverWrapper::CanWriteAssetToPath(const pxr::ArResolvedPath& resolvedPath, diff --git a/source/Wrappers/ArResolverWrapper.h b/source/Wrappers/ArResolverWrapper.h index b7261498d4..6f2548d6f0 100644 --- a/source/Wrappers/ArResolverWrapper.h +++ b/source/Wrappers/ArResolverWrapper.h @@ -27,6 +27,8 @@ #include "pxr/usd/ar/resolver.h" #include #include +#include "swiftUsd/Wrappers/ArAssetWrapper.h" +#include "swiftUsd/Wrappers/ArWritableAssetWrapper.h" namespace Overlay { class ArResolverWrapper; @@ -272,7 +274,7 @@ namespace Overlay { /// /// The returned ArAsset object provides functions for accessing the /// contents of the specified asset. - std::shared_ptr OpenAsset( + Overlay::ArAssetWrapper OpenAsset( const pxr::ArResolvedPath& resolvedPath) const; /// Enumeration of write modes for OpenAssetForWrite @@ -300,7 +302,7 @@ namespace Overlay { // is open for write is implementation-specific. For example, writes to /// an asset may or may not be immediately visible to other threads or /// processes depending on the implementation. - std::shared_ptr OpenAssetForWrite( + Overlay::ArWritableAssetWrapper OpenAssetForWrite( const pxr::ArResolvedPath& resolvedPath, WriteMode writeMode) const; diff --git a/source/Wrappers/ArWritableAssetWrapper.cpp b/source/Wrappers/ArWritableAssetWrapper.cpp new file mode 100644 index 0000000000..0380b56f64 --- /dev/null +++ b/source/Wrappers/ArWritableAssetWrapper.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// This source file is part of github.com/apple/SwiftUsd +// +// Copyright © 2025 Apple Inc. and the SwiftUsd project authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +//===----------------------------------------------------------------------===// + +#include "swiftUsd/Wrappers/ArWritableAssetWrapper.h" + +bool Overlay::ArWritableAssetWrapper::Close() { + return get()->Close(); +} + +size_t Overlay::ArWritableAssetWrapper::Write(const void *buffer, size_t count, size_t offset) { + return get()->Write(buffer, count, offset); +} + +Overlay::ArWritableAssetWrapper::ArWritableAssetWrapper(std::shared_ptr _ptr) : _ptr(_ptr) {} + +pxr::ArWritableAsset*_Nullable Overlay::ArWritableAssetWrapper::get() const { + return _ptr.get(); +} + +std::shared_ptr Overlay::ArWritableAssetWrapper::get_shared() const { + return _ptr; +} + +Overlay::ArWritableAssetWrapper::operator bool() const { + return (bool)_ptr; +} + + diff --git a/source/Wrappers/ArWritableAssetWrapper.h b/source/Wrappers/ArWritableAssetWrapper.h new file mode 100644 index 0000000000..68ae9f5571 --- /dev/null +++ b/source/Wrappers/ArWritableAssetWrapper.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// This source file is part of github.com/apple/SwiftUsd +// +// Copyright © 2025 Apple Inc. and the SwiftUsd project authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +//===----------------------------------------------------------------------===// + +// Original documentation for pxr::ArWritableAsset from +// https://github.com/PixarAnimationStudios/OpenUSD/blob/v26.05/pxr/usd/ar/writableAsset.h + +#ifndef SWIFTUSD_WRAPPERS_ARWRITABLEASSETWRAPPER_H +#define SWIFTUSD_WRAPPERS_ARWRITABLEASSETWRAPPER_H + +#include +#include +#include "pxr/usd/ar/writableAsset.h" + +namespace Overlay { + class ArWritableAssetWrapper { + public: + /// Close this asset, performing any necessary finalization or commits + /// of data that was previously written. Returns true on success, false + /// otherwise. + /// + /// If successful, reads to the written asset in the same process should + /// reflect the fully written state by the time this function returns. + /// Also, further calls to any functions on this interface are invalid. + bool Close(); + + /// Writes \p count bytes from \p buffer at \p offset from the beginning + /// of the asset. Returns number of bytes written, or 0 on error. + size_t Write(const void* buffer, size_t count, size_t offset); + + // MARK: SwiftUsd implementation access + + /// SwiftUsd wrapping constructor + ArWritableAssetWrapper(std::shared_ptr _ptr); + + /// Returns the underlying ArWritableAsset wrapped by this instance + pxr::ArWritableAsset*_Nullable get() const; + + /// Returns the underlying ArWritableAsset wrapped by this instance + std::shared_ptr get_shared() const; + + /// Returns `true` iff the underlying instance is valid + explicit operator bool() const; + + private: + std::shared_ptr _ptr; + }; +} + +#endif /* SWIFTUSD_WRAPPERS_ARWRITABLEASSETWRAPPER_H */ diff --git a/source/swiftUsd.h b/source/swiftUsd.h index 5c882e989c..f276ae64e6 100644 --- a/source/swiftUsd.h +++ b/source/swiftUsd.h @@ -43,6 +43,8 @@ #include "swiftUsd/CxxOnly/Deprecated.h" #include "swiftUsd/Wrappers/ArResolverWrapper.h" +#include "swiftUsd/Wrappers/ArAssetWrapper.h" +#include "swiftUsd/Wrappers/ArWritableAssetWrapper.h" #include "swiftUsd/Wrappers/ExecUsdSystemWrapper.h" #include "swiftUsd/Wrappers/HgiGLWrapper.h" #include "swiftUsd/Wrappers/HgiMetalWrapper.h" @@ -69,6 +71,8 @@ #includeforswiftdocc "swiftUsd/TfNotice/SwiftKey.h" #includeforswiftdocc "swiftUsd/Wrappers/ArResolverWrapper.h" +#includeforswiftdocc "swiftUsd/Wrappers/ArAssetWrapper.h" +#includeforswiftdocc "swiftUsd/Wrappers/ArWritableAssetWrapper.h" #includeforswiftdocc "swiftUsd/Wrappers/ExecUsdSystemWrapper.h" #includeforswiftdocc "swiftUsd/Wrappers/HgiGLWrapper.h" #includeforswiftdocc "swiftUsd/Wrappers/HgiMetalWrapper.h"