diff --git a/changelog.txt b/changelog.txt index 852bd8f9..bcced31b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,16 @@ +v1.0.11 December 10th, 2024 +fbx: + - adjust mesh and mesh instancing setup +gltf: + - adjust mesh and mesh instancing setup +sbsar: + - add texture export +utility: + - usd v24.11 cleanup + - doc updates + - refactor utility exporting, cmake cleanup, rename files, remove extra logs + + v1.0.10 November 19th, 2024 fbx: - small fbx spot light fixes diff --git a/fbx/src/fbx.cpp b/fbx/src/fbx.cpp index a65c82be..d3f8e2c1 100644 --- a/fbx/src/fbx.cpp +++ b/fbx/src/fbx.cpp @@ -12,7 +12,7 @@ governing permissions and limitations under the License. #include "fbx.h" #include "debugCodes.h" #include -#include +#include #include #include #include diff --git a/fbx/src/fbx.h b/fbx/src/fbx.h index 24fe63be..32ce5100 100644 --- a/fbx/src/fbx.h +++ b/fbx/src/fbx.h @@ -16,7 +16,7 @@ governing permissions and limitations under the License. #include #include #include -#include +#include #include diff --git a/fbx/src/fbxExport.cpp b/fbx/src/fbxExport.cpp index d1b0a1f2..23845e56 100644 --- a/fbx/src/fbxExport.cpp +++ b/fbx/src/fbxExport.cpp @@ -11,12 +11,12 @@ governing permissions and limitations under the License. */ #include "fbxExport.h" #include "debugCodes.h" -#include "layerWriteShared.h" -#include #include -#include -#include -#include +#include +#include +#include +#include +#include #include diff --git a/fbx/src/fbxExport.h b/fbx/src/fbxExport.h index 9598333e..1ea6c311 100644 --- a/fbx/src/fbxExport.h +++ b/fbx/src/fbxExport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include "fbx.h" -#include +#include namespace adobe::usd { diff --git a/fbx/src/fbxImport.cpp b/fbx/src/fbxImport.cpp index f333453a..fb5af35b 100644 --- a/fbx/src/fbxImport.cpp +++ b/fbx/src/fbxImport.cpp @@ -11,17 +11,17 @@ governing permissions and limitations under the License. */ #include "fbxImport.h" #include "debugCodes.h" -#include #include #include -#include #include -#include +#include +#include +#include +#include #include #include #include #include -#include using namespace PXR_NS; using namespace fbxsdk; diff --git a/fbx/src/fbxImport.h b/fbx/src/fbxImport.h index 57347696..181573fc 100644 --- a/fbx/src/fbxImport.h +++ b/fbx/src/fbxImport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include "fbx.h" -#include +#include namespace adobe::usd { diff --git a/fbx/src/fbxResolver.cpp b/fbx/src/fbxResolver.cpp index 7247622f..3a3832fd 100644 --- a/fbx/src/fbxResolver.cpp +++ b/fbx/src/fbxResolver.cpp @@ -13,7 +13,7 @@ governing permissions and limitations under the License. #include "debugCodes.h" #include "fbx.h" #include "fbxImport.h" -#include +#include #include #include #include diff --git a/fbx/src/fbxResolver.h b/fbx/src/fbxResolver.h index be4793f1..42a40f57 100644 --- a/fbx/src/fbxResolver.h +++ b/fbx/src/fbxResolver.h @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ #pragma once -#include +#include namespace adobe::usd { diff --git a/fbx/src/fileFormat.cpp b/fbx/src/fileFormat.cpp index 96b32b30..39413201 100644 --- a/fbx/src/fileFormat.cpp +++ b/fbx/src/fileFormat.cpp @@ -16,11 +16,11 @@ governing permissions and limitations under the License. #include "fbxExport.h" #include "fbxImport.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include diff --git a/fbx/src/fileFormat.h b/fbx/src/fileFormat.h index 3122cde6..c852fda9 100644 --- a/fbx/src/fileFormat.h +++ b/fbx/src/fileFormat.h @@ -21,10 +21,10 @@ governing permissions and limitations under the License. #endif // _MSC_VER #include "api.h" #include +#include #include #include #include -#include #include #include diff --git a/gltf/src/fileFormat.cpp b/gltf/src/fileFormat.cpp index 45e5a470..07f4d9f6 100644 --- a/gltf/src/fileFormat.cpp +++ b/gltf/src/fileFormat.cpp @@ -16,11 +16,11 @@ governing permissions and limitations under the License. #include "gltfImport.h" // utils -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include // USD #include diff --git a/gltf/src/fileFormat.h b/gltf/src/fileFormat.h index 9bd6f422..4244d440 100644 --- a/gltf/src/fileFormat.h +++ b/gltf/src/fileFormat.h @@ -13,7 +13,7 @@ governing permissions and limitations under the License. #include "api.h" #include -#include +#include #include #include diff --git a/gltf/src/gltf.cpp b/gltf/src/gltf.cpp index 637e9e9f..c97e4348 100644 --- a/gltf/src/gltf.cpp +++ b/gltf/src/gltf.cpp @@ -11,10 +11,10 @@ governing permissions and limitations under the License. */ #include "gltf.h" #include "debugCodes.h" -#include "neuralAssetsHelper.h" -#include #include #include +#include +#include #include #include #include diff --git a/gltf/src/gltfAnisotropy.cpp b/gltf/src/gltfAnisotropy.cpp index 7664aba5..b6a0c623 100644 --- a/gltf/src/gltfAnisotropy.cpp +++ b/gltf/src/gltfAnisotropy.cpp @@ -13,10 +13,11 @@ governing permissions and limitations under the License. #include "debugCodes.h" #include "gltfImport.h" #include -#include #include #include +#include + using namespace PXR_NS; namespace adobe::usd { @@ -456,7 +457,9 @@ constructAnisotropyImage(const Material& m, roughness = static_cast(roughnessImage->image[i]) / MAX_COLOR_VALUE; } } else { - roughness = m.roughness.value.Get(); + if (m.roughness.value.IsHolding()) { + roughness = m.roughness.value.Get(); + } } // Set anisotropy level (blue channel) @@ -491,11 +494,10 @@ exportAnisotropyExtension(ExportGltfContext& ctx, tinygltf::ExtensionMap ext; if (m.anisotropyLevel.value.IsHolding()) { // Use default roughness if none is available - float roughness = m.roughness.value.IsHolding() - ? m.roughness.value.UncheckedGet() - : 0.0f; - reconstructedStrength = reverseASMLevel( - m.anisotropyLevel.value.UncheckedGet(), 1.0f, roughness); + float roughness = + m.roughness.value.IsHolding() ? m.roughness.value.UncheckedGet() : 0.0f; + reconstructedStrength = + reverseASMLevel(m.anisotropyLevel.value.UncheckedGet(), 1.0f, roughness); addFloatValueToExt(ext, "anisotropyStrength", reconstructedStrength); } diff --git a/gltf/src/gltfAnisotropy.h b/gltf/src/gltfAnisotropy.h index ccdf7dc2..c285694e 100644 --- a/gltf/src/gltfAnisotropy.h +++ b/gltf/src/gltfAnisotropy.h @@ -12,9 +12,9 @@ governing permissions and limitations under the License. #pragma once #include "gltf.h" #include "gltfExport.h" -#include "images.h" #include "importGltfContext.h" -#include "usdData.h" +#include +#include #include namespace adobe::usd { diff --git a/gltf/src/gltfExport.cpp b/gltf/src/gltfExport.cpp index 871496af..52b58f29 100644 --- a/gltf/src/gltfExport.cpp +++ b/gltf/src/gltfExport.cpp @@ -12,10 +12,10 @@ governing permissions and limitations under the License. #include "gltfExport.h" #include "debugCodes.h" #include "gltfAnisotropy.h" -#include "neuralAssetsHelper.h" -#include -#include -#include +#include +#include +#include +#include #include #include #include diff --git a/gltf/src/gltfExport.h b/gltf/src/gltfExport.h index 7a683028..4892b3a0 100644 --- a/gltf/src/gltfExport.h +++ b/gltf/src/gltfExport.h @@ -11,9 +11,9 @@ governing permissions and limitations under the License. */ #pragma once #include "gltf.h" -#include "materials.h" #include -#include +#include +#include namespace adobe::usd { diff --git a/gltf/src/gltfImport.cpp b/gltf/src/gltfImport.cpp index db9c627a..0c22fb27 100644 --- a/gltf/src/gltfImport.cpp +++ b/gltf/src/gltfImport.cpp @@ -14,9 +14,9 @@ governing permissions and limitations under the License. #include "gltfAnisotropy.h" #include "gltfSpecGloss.h" #include "importGltfContext.h" -#include "neuralAssetsHelper.h" -#include -#include +#include +#include +#include #include #include @@ -1413,6 +1413,7 @@ void importMeshes(ImportGltfContext& ctx) { ctx.meshes.resize(ctx.gltf->meshes.size()); + ctx.meshUseCount.resize(ctx.gltf->meshes.size(), 0); for (size_t i = 0; i < ctx.gltf->meshes.size(); i++) { const tinygltf::Mesh& gmesh = ctx.gltf->meshes[i]; ctx.meshes[i].resize(gmesh.primitives.size()); @@ -1426,7 +1427,11 @@ importMeshes(ImportGltfContext& ctx) auto [meshIndex, mesh] = ctx.usd->addMesh(); ctx.meshes[i][j] = meshIndex; mesh.name = gmesh.name; - mesh.instanceable = true; + // When we have multiple GLTF primitives that we turn into meshes, we create names that + // are derived from the primitive index instead of just duplicating the name. + if (gmesh.primitives.size() > 1) { + mesh.name = mesh.name + "_primitive" + std::to_string(j); + } int positionsIndex = getPrimitiveAttribute(primitive, "POSITION"); int normalsIndex = getPrimitiveAttribute(primitive, "NORMAL"); int tangentsIndex = getPrimitiveAttribute(primitive, "TANGENT"); @@ -2103,6 +2108,7 @@ importNodes(ImportGltfContext& ctx) int usdParentIndex = (parentIndex != -1) ? ctx.nodeMap[parentIndex] : -1; n.parent = usdParentIndex; if (node.mesh >= 0) { + ctx.meshUseCount[node.mesh]++; // If the node has a skin, add the mesh to the root node of the skeleton held by the // skin. if (node.skin >= 0) { @@ -2174,6 +2180,27 @@ importNodes(ImportGltfContext& ctx) return true; } +void +checkMeshInstancing(ImportGltfContext& ctx) +{ + // Visit all meshes and check if they are used by more than one node and if so mark them as + // instanceable + for (size_t meshIdx = 0; meshIdx < ctx.meshUseCount.size(); ++meshIdx) { + int useCount = ctx.meshUseCount[meshIdx]; + if (useCount > 1) { + const std::vector& meshPrimitiveIndices = ctx.meshes[meshIdx]; + for (int primitiveIdx : meshPrimitiveIndices) { + ctx.usd->meshes[primitiveIdx].instanceable = true; + } + } + + if (useCount == 0) { + const tinygltf::Mesh& gmesh = ctx.gltf->meshes[meshIdx]; + TF_WARN("Mesh %zu (%s) appears to be unused", meshIdx, gmesh.name.c_str()); + } + } +} + static const std::set supportedExtension = { // Ratified extensions "KHR_draco_mesh_compression", @@ -2293,6 +2320,7 @@ importGltf(const ImportGltfOptions& options, importAnimationTracks(ctx); importNodeAnimations(ctx); importSkeletonAnimations(ctx); + checkMeshInstancing(ctx); } usd.metadata.SetValueAtPath("filenames", VtValue(ctx.filenames)); diff --git a/gltf/src/gltfImport.h b/gltf/src/gltfImport.h index 3b843930..2e95fe5a 100644 --- a/gltf/src/gltfImport.h +++ b/gltf/src/gltfImport.h @@ -13,7 +13,7 @@ governing permissions and limitations under the License. #include "gltf.h" #include "importGltfContext.h" #include -#include +#include namespace adobe::usd { diff --git a/gltf/src/gltfResolver.cpp b/gltf/src/gltfResolver.cpp index 8e5c2186..8211f0bd 100644 --- a/gltf/src/gltfResolver.cpp +++ b/gltf/src/gltfResolver.cpp @@ -17,9 +17,6 @@ governing permissions and limitations under the License. #include -// from utils -#include - using namespace PXR_NS; namespace adobe::usd { diff --git a/gltf/src/gltfResolver.h b/gltf/src/gltfResolver.h index ebc159d4..6665219e 100644 --- a/gltf/src/gltfResolver.h +++ b/gltf/src/gltfResolver.h @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ #pragma once -#include +#include namespace adobe::usd { diff --git a/gltf/src/gltfSpecGloss.cpp b/gltf/src/gltfSpecGloss.cpp index 5d974eba..2513953e 100644 --- a/gltf/src/gltfSpecGloss.cpp +++ b/gltf/src/gltfSpecGloss.cpp @@ -13,8 +13,8 @@ governing permissions and limitations under the License. #include "debugCodes.h" #include "gltfImport.h" #include "importGltfContext.h" -#include -#include +#include +#include #include #include diff --git a/gltf/src/gltfSpecGloss.h b/gltf/src/gltfSpecGloss.h index b259cc24..6d3a95fb 100644 --- a/gltf/src/gltfSpecGloss.h +++ b/gltf/src/gltfSpecGloss.h @@ -12,7 +12,7 @@ governing permissions and limitations under the License. #pragma once #include "gltf.h" #include "importGltfContext.h" -#include "usdData.h" +#include #include diff --git a/gltf/src/importGltfContext.h b/gltf/src/importGltfContext.h index 647b3c42..4770ec74 100644 --- a/gltf/src/importGltfContext.h +++ b/gltf/src/importGltfContext.h @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ #pragma once -#include "usdData.h" +#include #include #include #include @@ -29,6 +29,7 @@ struct ImportGltfContext std::vector parentMap; std::vector skeletonNodeNames; std::vector> meshes; + std::vector meshUseCount; // paths to files loaded on import PXR_NS::VtArray filenames; diff --git a/obj/src/fileFormat.cpp b/obj/src/fileFormat.cpp index e6ab1e92..8aa921c7 100644 --- a/obj/src/fileFormat.cpp +++ b/obj/src/fileFormat.cpp @@ -16,13 +16,13 @@ governing permissions and limitations under the License. #include "objExport.h" #include "objImport.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/obj/src/fileFormat.h b/obj/src/fileFormat.h index fae0991c..4e47a545 100644 --- a/obj/src/fileFormat.h +++ b/obj/src/fileFormat.h @@ -15,7 +15,7 @@ governing permissions and limitations under the License. #include #include #include -#include +#include #include #include diff --git a/obj/src/obj.cpp b/obj/src/obj.cpp index 6dcd83cc..ba42a01e 100644 --- a/obj/src/obj.cpp +++ b/obj/src/obj.cpp @@ -37,9 +37,9 @@ governing permissions and limitations under the License. #include "debugCodes.h" #include #include -#include #include #include +#include #include #include #include diff --git a/obj/src/obj.h b/obj/src/obj.h index 197d677b..c6eaede3 100644 --- a/obj/src/obj.h +++ b/obj/src/obj.h @@ -21,11 +21,11 @@ governing permissions and limitations under the License. #include #include +#include #include #include #include #include -#include #include namespace adobe::usd { diff --git a/obj/src/objExport.cpp b/obj/src/objExport.cpp index b4990659..24dc39a2 100644 --- a/obj/src/objExport.cpp +++ b/obj/src/objExport.cpp @@ -11,8 +11,8 @@ governing permissions and limitations under the License. */ #include "objExport.h" #include "debugCodes.h" -#include -#include +#include +#include #include #include #include @@ -125,7 +125,7 @@ exportMesh(Obj& obj, v = GfVec3f(worldTransform.Transform(v)); } if (m.colors.size()) { - const Primvar& color = m.colors[0]; // only export first color set + const Primvar& color = m.colors[0]; // only export first color set if (color.indices.size() == 0 && color.values.size() == m.points.size()) { g.colors = color.values; // Perform color space conversion if necessary @@ -201,11 +201,11 @@ bool exportObj(const ExportObjOptions& options, const UsdData& usd, Obj& obj) { GfMatrix4d correctionTransform(1); - if (usd.upAxis == PXR_NS::UsdGeomTokens->z) { + if (usd.upAxis == UsdGeomTokens->z) { correctionTransform.SetRotate(GfQuatd(0.7071068, -0.7071068, 0, 0)); // rotate -90 deg in x TF_DEBUG_MSG(FILE_FORMAT_OBJ, "obj::write correct rotation { rotX: %s }\n", - usd.upAxis == PXR_NS::UsdGeomTokens->z ? "-90deg" : "0deg"); + usd.upAxis == UsdGeomTokens->z ? "-90deg" : "0deg"); } obj.comments.push_back("# Meters per unit: " + TfStringify(usd.metersPerUnit)); diff --git a/obj/src/objExport.h b/obj/src/objExport.h index d310153f..ea3fea6b 100644 --- a/obj/src/objExport.h +++ b/obj/src/objExport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include "obj.h" -#include +#include namespace adobe::usd { diff --git a/obj/src/objImport.cpp b/obj/src/objImport.cpp index ac7c1041..3e3ac72a 100644 --- a/obj/src/objImport.cpp +++ b/obj/src/objImport.cpp @@ -11,9 +11,9 @@ governing permissions and limitations under the License. */ #include "objImport.h" #include "debugCodes.h" -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/obj/src/objImport.h b/obj/src/objImport.h index d1086b12..f1afca61 100644 --- a/obj/src/objImport.h +++ b/obj/src/objImport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include "obj.h" -#include +#include namespace adobe::usd { diff --git a/obj/src/objResolver.cpp b/obj/src/objResolver.cpp index 1399cbc3..bc56c5ce 100644 --- a/obj/src/objResolver.cpp +++ b/obj/src/objResolver.cpp @@ -13,7 +13,7 @@ governing permissions and limitations under the License. #include "obj.h" #include "objImport.h" #include -#include +#include using namespace PXR_NS; namespace adobe::usd { diff --git a/obj/src/objResolver.h b/obj/src/objResolver.h index e731d172..0fe88f90 100644 --- a/obj/src/objResolver.h +++ b/obj/src/objResolver.h @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ #pragma once -#include +#include namespace adobe::usd { diff --git a/ply/src/fileFormat.cpp b/ply/src/fileFormat.cpp index 9ece52c7..aaa277a2 100644 --- a/ply/src/fileFormat.cpp +++ b/ply/src/fileFormat.cpp @@ -16,10 +16,10 @@ governing permissions and limitations under the License. #include "plyExport.h" #include "plyImport.h" -#include -#include -#include -#include +#include +#include +#include +#include #include diff --git a/ply/src/fileFormat.h b/ply/src/fileFormat.h index 7ee24bf2..8a060ed5 100644 --- a/ply/src/fileFormat.h +++ b/ply/src/fileFormat.h @@ -12,10 +12,10 @@ governing permissions and limitations under the License. #pragma once #include "api.h" #include +#include #include #include #include -#include #include #include diff --git a/ply/src/plyExport.cpp b/ply/src/plyExport.cpp index ae127830..9a9b34bb 100644 --- a/ply/src/plyExport.cpp +++ b/ply/src/plyExport.cpp @@ -11,9 +11,10 @@ governing permissions and limitations under the License. */ #include "plyExport.h" #include "debugCodes.h" -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -47,7 +48,6 @@ governing permissions and limitations under the License. #include #include #include -#include using namespace PXR_NS; @@ -357,7 +357,7 @@ exportPly(UsdData& usd, happly::PLYData& ply) expandIndexedValues(m.normals.indices.size() ? m.normals.indices : m.indices, m.normals.values); if (m.colors.size()) { // translate only first set of colors - Primvar& colorSet = m.colors[0]; + Primvar& colorSet = m.colors[0]; expandIndexedValues(colorSet.indices.size() ? colorSet.indices : m.indices, colorSet.values); } diff --git a/ply/src/plyExport.h b/ply/src/plyExport.h index 958575f4..33322632 100644 --- a/ply/src/plyExport.h +++ b/ply/src/plyExport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include -#include +#include namespace adobe::usd { diff --git a/ply/src/plyImport.cpp b/ply/src/plyImport.cpp index b2181319..bb721a65 100644 --- a/ply/src/plyImport.cpp +++ b/ply/src/plyImport.cpp @@ -13,12 +13,12 @@ governing permissions and limitations under the License. #include "debugCodes.h" #include #include -#include -#include #include -#include +#include +#include +#include +#include #include -#include #include #include #include diff --git a/ply/src/plyImport.h b/ply/src/plyImport.h index 1c7475d5..ab330330 100644 --- a/ply/src/plyImport.h +++ b/ply/src/plyImport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include -#include +#include namespace adobe::usd { diff --git a/sbsar/src/assetResolver/sbsarImage.cpp b/sbsar/src/assetResolver/sbsarImage.cpp index a51a10fc..f4e01d33 100644 --- a/sbsar/src/assetResolver/sbsarImage.cpp +++ b/sbsar/src/assetResolver/sbsarImage.cpp @@ -311,13 +311,13 @@ SbsarImage::_OpenForReading(const std::string& filename, std::shared_ptr asset = PXR_NS::ArGetResolver().OpenAsset(PXR_NS::ArResolvedPath(filename)); if (!asset) { - TF_RUNTIME_ERROR("Fail to retrieve asset"); + TF_RUNTIME_ERROR("Fail to retrieve asset %s", filename.c_str()); return false; } mSbsarAsset = std::dynamic_pointer_cast(asset); if (!mSbsarAsset) { - TF_RUNTIME_ERROR("Fail to retrieve asset"); + TF_RUNTIME_ERROR("Fail to cast file %s to SbsarAsset", filename.c_str()); return false; } diff --git a/sbsar/src/sbsarfileformat.cpp b/sbsar/src/sbsarfileformat.cpp index dbec3f91..81faa028 100644 --- a/sbsar/src/sbsarfileformat.cpp +++ b/sbsar/src/sbsarfileformat.cpp @@ -32,8 +32,8 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include +#include +#include #include #include diff --git a/sbsar/src/usdGeneration/sbsarAsm.cpp b/sbsar/src/usdGeneration/sbsarAsm.cpp index f2d5f2f5..f8a76f7f 100644 --- a/sbsar/src/usdGeneration/sbsarAsm.cpp +++ b/sbsar/src/usdGeneration/sbsarAsm.cpp @@ -14,9 +14,9 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include -#include +#include +#include +#include #include diff --git a/sbsar/src/usdGeneration/sbsarLuxDomeLight.cpp b/sbsar/src/usdGeneration/sbsarLuxDomeLight.cpp index 9ff5f3ee..66318b4d 100644 --- a/sbsar/src/usdGeneration/sbsarLuxDomeLight.cpp +++ b/sbsar/src/usdGeneration/sbsarLuxDomeLight.cpp @@ -19,8 +19,8 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include +#include +#include PXR_NAMESPACE_USING_DIRECTIVE using namespace SubstanceAir; diff --git a/sbsar/src/usdGeneration/sbsarMaterial.cpp b/sbsar/src/usdGeneration/sbsarMaterial.cpp index 528d5d36..214c7197 100644 --- a/sbsar/src/usdGeneration/sbsarMaterial.cpp +++ b/sbsar/src/usdGeneration/sbsarMaterial.cpp @@ -23,8 +23,8 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include +#include +#include PXR_NAMESPACE_USING_DIRECTIVE using namespace SubstanceAir; diff --git a/sbsar/src/usdGeneration/sbsarMtlx.cpp b/sbsar/src/usdGeneration/sbsarMtlx.cpp index 46be0f7c..e2d6cce7 100644 --- a/sbsar/src/usdGeneration/sbsarMtlx.cpp +++ b/sbsar/src/usdGeneration/sbsarMtlx.cpp @@ -14,9 +14,9 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include -#include +#include +#include +#include #include diff --git a/sbsar/src/usdGeneration/sbsarUsdPreviewSurface.cpp b/sbsar/src/usdGeneration/sbsarUsdPreviewSurface.cpp index 30384031..7b5869b0 100644 --- a/sbsar/src/usdGeneration/sbsarUsdPreviewSurface.cpp +++ b/sbsar/src/usdGeneration/sbsarUsdPreviewSurface.cpp @@ -14,9 +14,9 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include -#include +#include +#include +#include #include diff --git a/sbsar/src/usdGeneration/usdGenerationHelpers.cpp b/sbsar/src/usdGeneration/usdGenerationHelpers.cpp index 62c07fd7..3fe969fe 100644 --- a/sbsar/src/usdGeneration/usdGenerationHelpers.cpp +++ b/sbsar/src/usdGeneration/usdGenerationHelpers.cpp @@ -28,8 +28,9 @@ governing permissions and limitations under the License. #include // File format utils -#include -#include +#include +#include +#include #include @@ -369,20 +370,6 @@ getGraphCategory(const GraphDesc& graphDesc, SymbolMapper& symbolMapper) return symbolMapper.GetSymbol(graphDesc.mCategory.c_str()); } -std::vector -_split(const std::string& s, char delim) -{ - std::vector result; - std::stringstream ss(s); - std::string item; - - while (std::getline(ss, item, delim)) { - result.push_back(item); - } - - return result; -} - void setGraphMetadataOnPrim(SdfAbstractData* sdfData, const SdfPath& primPath, @@ -424,7 +411,7 @@ setGraphMetadataOnPrim(SdfAbstractData* sdfData, customData["category"] = graphDesc.mCategory.c_str(); } if (!graphDesc.mKeywords.empty()) { - auto keywords = _split(std::string(graphDesc.mKeywords), ';'); + auto keywords = split(std::string(graphDesc.mKeywords), ';'); customData["keywords"] = VtArray(keywords.begin(), keywords.end()); } if (!graphDesc.mAuthor.empty()) { diff --git a/stl/src/fileFormat.cpp b/stl/src/fileFormat.cpp index 0253423f..329828e6 100644 --- a/stl/src/fileFormat.cpp +++ b/stl/src/fileFormat.cpp @@ -16,9 +16,9 @@ governing permissions and limitations under the License. #include "stlImport.h" #include "stlModel.h" -#include -#include -#include +#include +#include +#include #include #include diff --git a/stl/src/fileFormat.h b/stl/src/fileFormat.h index d7db419d..a7cb90f4 100644 --- a/stl/src/fileFormat.h +++ b/stl/src/fileFormat.h @@ -12,10 +12,10 @@ governing permissions and limitations under the License. #pragma once #include "api.h" #include +#include #include #include #include -#include #include #include diff --git a/stl/src/stlExport.cpp b/stl/src/stlExport.cpp index ae424239..50d3f635 100644 --- a/stl/src/stlExport.cpp +++ b/stl/src/stlExport.cpp @@ -11,8 +11,8 @@ governing permissions and limitations under the License. */ #include "stlExport.h" -#include -#include +#include +#include #include @@ -68,8 +68,8 @@ exportStl(const ExportStlOptions& options, const UsdData& usd, StlModel& stl) for (int j = 0; j < 3; j++) { StlVec3f vertex; const int vertex_index = meshIndices[i + j]; - const PXR_NS::GfVec3f& vertex_data = mesh.points[vertex_index]; - const PXR_NS::GfVec3f transformedPoint = GfVec3f(worldTransform.Transform(vertex_data)); + const GfVec3f& vertex_data = mesh.points[vertex_index]; + const GfVec3f transformedPoint = GfVec3f(worldTransform.Transform(vertex_data)); vertex = { transformedPoint[0], transformedPoint[1], transformedPoint[2] }; facet.vertices[j] = vertex; } diff --git a/stl/src/stlExport.h b/stl/src/stlExport.h index 6df1f7e8..b95f2aa3 100644 --- a/stl/src/stlExport.h +++ b/stl/src/stlExport.h @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ #pragma once #include "stlModel.h" -#include +#include using namespace adobe::usd; diff --git a/stl/src/stlImport.cpp b/stl/src/stlImport.cpp index f75e5e18..6ea52d71 100644 --- a/stl/src/stlImport.cpp +++ b/stl/src/stlImport.cpp @@ -11,8 +11,7 @@ governing permissions and limitations under the License. */ #include "stlImport.h" #include "stlModel.h" -#include -#include +#include #include #include diff --git a/stl/src/stlImport.h b/stl/src/stlImport.h index 4eb5c157..877d0d91 100644 --- a/stl/src/stlImport.h +++ b/stl/src/stlImport.h @@ -13,7 +13,7 @@ governing permissions and limitations under the License. #include "stlModel.h" -#include +#include using namespace adobe::usd; diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index f8f45d42..c57b6d41 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -12,49 +12,64 @@ add_library(fileformatUtils SHARED) target_compile_definitions(fileformatUtils PRIVATE USDFFUTILS_EXPORTS) usd_plugin_compile_config(fileformatUtils) -target_sources(fileformatUtils -PRIVATE - "README.md" +set(HEADERS "assetresolver.h" - "assetresolver.cpp" "common.h" - "common.cpp" "debugCodes.h" "dictencoder.h" - "dictencoder.cpp" "geometry.h" - "geometry.cpp" "transforms.h" - "transforms.cpp" "images.h" - "images.cpp" "layerRead.h" - "layerRead.cpp" "layerWriteShared.h" - "layerWriteShared.cpp" "layerWriteMaterial.h" - "layerWriteMaterial.cpp" "layerWriteMaterialX.h" - "layerWriteMaterialX.cpp" "layerWriteSdfData.h" - "layerWriteSdfData.cpp" "materials.h" - "materials.cpp" "neuralAssetsHelper.h" - "neuralAssetsHelper.cpp" "resolver.h" - "resolver.cpp" "sdfMaterialUtils.h" - "sdfMaterialUtils.cpp" "sdfUtils.h" - "sdfUtils.cpp" "usdData.h" +) + +set(SOURCES + "assetresolver.cpp" + "common.cpp" + "dictencoder.cpp" + "geometry.cpp" + "transforms.cpp" + "images.cpp" + "layerRead.cpp" + "layerWriteShared.cpp" + "layerWriteMaterial.cpp" + "layerWriteMaterialX.cpp" + "layerWriteSdfData.cpp" + "materials.cpp" + "neuralAssetsHelper.cpp" + "resolver.cpp" + "sdfMaterialUtils.cpp" + "sdfUtils.cpp" "usdData.cpp" ) +# Prepend paths +list(TRANSFORM HEADERS PREPEND "include/fileformatutils/") +list(TRANSFORM SOURCES PREPEND "src/") + +# Add sources to target +target_sources(fileformatUtils +PRIVATE + "README.md" + ${HEADERS} + ${SOURCES} +) + target_include_directories(fileformatUtils - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE "${PROJECT_BINARY_DIR}" + PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/include" + PRIVATE + "${PROJECT_BINARY_DIR}" ) target_link_libraries(fileformatUtils @@ -70,6 +85,7 @@ PUBLIC usdShade usdUtils usdVol + hio arch ZLIB::ZLIB ) @@ -77,8 +93,8 @@ PUBLIC if(USD_FILEFORMATS_BUILD_TESTS) target_sources(fileformatUtils PRIVATE - "test.h" - "test.cpp" + "include/fileformatutils/test.h" + "src/test.cpp" ) target_link_libraries(fileformatUtils PUBLIC diff --git a/utils/api.h b/utils/include/fileformatutils/api.h similarity index 100% rename from utils/api.h rename to utils/include/fileformatutils/api.h diff --git a/utils/assetresolver.h b/utils/include/fileformatutils/assetresolver.h similarity index 100% rename from utils/assetresolver.h rename to utils/include/fileformatutils/assetresolver.h diff --git a/utils/common.h b/utils/include/fileformatutils/common.h similarity index 96% rename from utils/common.h rename to utils/include/fileformatutils/common.h index 2008cade..51431401 100644 --- a/utils/common.h +++ b/utils/include/fileformatutils/common.h @@ -16,6 +16,7 @@ governing permissions and limitations under the License. #include #include #include +#include /// We defined these tokens to skip linking to usd imaging, which is heavy. // XXX Split this list into categories for easier maintenance @@ -388,4 +389,16 @@ trim(std::string& s) ltrim(s); } +std::vector USDFFUTILS_API +split(const std::string& str, char delimiter); + +bool USDFFUTILS_API +createDirectory(const std::filesystem::path& directoryPath); + +std::string USDFFUTILS_API +getSanitizedExtension(const std::string& file); + +std::string USDFFUTILS_API +getLayerFilePath(const std::string& layerIdentifier); + } diff --git a/utils/debugCodes.h b/utils/include/fileformatutils/debugCodes.h similarity index 100% rename from utils/debugCodes.h rename to utils/include/fileformatutils/debugCodes.h diff --git a/utils/dictencoder.h b/utils/include/fileformatutils/dictencoder.h similarity index 100% rename from utils/dictencoder.h rename to utils/include/fileformatutils/dictencoder.h diff --git a/utils/geometry.h b/utils/include/fileformatutils/geometry.h similarity index 100% rename from utils/geometry.h rename to utils/include/fileformatutils/geometry.h diff --git a/utils/images.h b/utils/include/fileformatutils/images.h similarity index 79% rename from utils/images.h rename to utils/include/fileformatutils/images.h index e243f32d..a3b344c3 100644 --- a/utils/images.h +++ b/utils/include/fileformatutils/images.h @@ -122,4 +122,36 @@ srgbToLinear(float s); USDFFUTILS_API float linearToSRGB(float s); +/// \ingroup utils_materials +/// \brief Is the resolved asset path a supported image file +bool USDFFUTILS_API +isImageFileSupported(const std::string& resolvedAssetPath); + +/// \ingroup utils_materials +/// \brief Is the uri a sbsar image +bool USDFFUTILS_API +isUriSbsarImage(const std::string& uri); + +/// \ingroup utils_materials +/// \brief Get the sbsar usage from the parameters string +std::string USDFFUTILS_API +getSbsarUsageFromParameters(const std::string& parametersStr); + +/// \ingroup utils_materials +/// \brief Get the sbsar image extension +std::string USDFFUTILS_API +getSbsarImageExtension(const std::string& resolvedAssetPath); + +/// \ingroup utils_materials +/// \brief Extract the file path from the asset path +std::string USDFFUTILS_API +extractFilePathFromAssetPath(const std::string& assetPath); + +/// \ingroup utils_materials +/// \brief Transcodes an image asset to memory +bool USDFFUTILS_API +transcodeImageAssetToMemory(const std::string& resolvedAssetPath, + const std::string& filename, + std::vector& outputPixelData); + } diff --git a/utils/layerRead.h b/utils/include/fileformatutils/layerRead.h similarity index 79% rename from utils/layerRead.h rename to utils/include/fileformatutils/layerRead.h index 2342d981..01d0862d 100644 --- a/utils/layerRead.h +++ b/utils/include/fileformatutils/layerRead.h @@ -29,6 +29,16 @@ struct USDFFUTILS_API ReadLayerOptions int maxMeshInfluenceCount = 4; }; +/// \ingroup utils_layer +/// \brief Takes a SBSAR texture parameterization. +USDFFUTILS_API std::string +getSbsarUsageFromParameters(const std::string& parametersStr); + +/// \ingroup utils_layer +/// \brief This function extracts a usable file path from an assetPath. +USDFFUTILS_API std::string +extractFilePathFromAssetPath(const std::string& assetPath); + /// \ingroup utils_layer /// \brief Reads data from a USD layer and dumps it into a UsdData structure. USDFFUTILS_API bool @@ -36,5 +46,4 @@ readLayer(const ReadLayerOptions& options, const PXR_NS::SdfLayer& layer, UsdData& data, const std::string& debugTag); - } \ No newline at end of file diff --git a/utils/layerWriteMaterial.h b/utils/include/fileformatutils/layerWriteMaterial.h similarity index 100% rename from utils/layerWriteMaterial.h rename to utils/include/fileformatutils/layerWriteMaterial.h diff --git a/utils/layerWriteMaterialX.h b/utils/include/fileformatutils/layerWriteMaterialX.h similarity index 100% rename from utils/layerWriteMaterialX.h rename to utils/include/fileformatutils/layerWriteMaterialX.h diff --git a/utils/layerWriteSdfData.h b/utils/include/fileformatutils/layerWriteSdfData.h similarity index 100% rename from utils/layerWriteSdfData.h rename to utils/include/fileformatutils/layerWriteSdfData.h diff --git a/utils/layerWriteShared.h b/utils/include/fileformatutils/layerWriteShared.h similarity index 100% rename from utils/layerWriteShared.h rename to utils/include/fileformatutils/layerWriteShared.h diff --git a/utils/materials.h b/utils/include/fileformatutils/materials.h similarity index 100% rename from utils/materials.h rename to utils/include/fileformatutils/materials.h diff --git a/utils/neuralAssetsHelper.h b/utils/include/fileformatutils/neuralAssetsHelper.h similarity index 100% rename from utils/neuralAssetsHelper.h rename to utils/include/fileformatutils/neuralAssetsHelper.h diff --git a/utils/resolver.h b/utils/include/fileformatutils/resolver.h similarity index 100% rename from utils/resolver.h rename to utils/include/fileformatutils/resolver.h diff --git a/utils/sdfMaterialUtils.h b/utils/include/fileformatutils/sdfMaterialUtils.h similarity index 100% rename from utils/sdfMaterialUtils.h rename to utils/include/fileformatutils/sdfMaterialUtils.h diff --git a/utils/sdfUtils.h b/utils/include/fileformatutils/sdfUtils.h similarity index 100% rename from utils/sdfUtils.h rename to utils/include/fileformatutils/sdfUtils.h diff --git a/utils/test.h b/utils/include/fileformatutils/test.h similarity index 100% rename from utils/test.h rename to utils/include/fileformatutils/test.h diff --git a/utils/transforms.h b/utils/include/fileformatutils/transforms.h similarity index 100% rename from utils/transforms.h rename to utils/include/fileformatutils/transforms.h diff --git a/utils/usdData.h b/utils/include/fileformatutils/usdData.h similarity index 100% rename from utils/usdData.h rename to utils/include/fileformatutils/usdData.h diff --git a/utils/assetresolver.cpp b/utils/src/assetresolver.cpp similarity index 98% rename from utils/assetresolver.cpp rename to utils/src/assetresolver.cpp index d225e180..1a4189b0 100644 --- a/utils/assetresolver.cpp +++ b/utils/src/assetresolver.cpp @@ -9,8 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "assetresolver.h" -#include "debugCodes.h" +#include +#include #include #include diff --git a/utils/common.cpp b/utils/src/common.cpp similarity index 73% rename from utils/common.cpp rename to utils/src/common.cpp index e0618743..a7103aa5 100644 --- a/utils/common.cpp +++ b/utils/src/common.cpp @@ -9,8 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "common.h" -#include "debugCodes.h" +#include +#include #include #include #include @@ -19,6 +19,10 @@ governing permissions and limitations under the License. #include #include #include +#include +#include +#include +#include PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PUBLIC_TOKENS(AdobeTokens, ADOBE_TOKENS); @@ -168,4 +172,59 @@ getCurrentDate() { return ss.str(); } +// Splits the input string into a vector of substrings based on the specified delimiter. +std::vector +split(const std::string& str, char delimiter) +{ + std::vector pieces; + size_t start = 0; + size_t end = str.find(delimiter); + while (end != std::string::npos) { + pieces.push_back(str.substr(start, end - start)); + start = end + 1; + end = str.find(delimiter, start); + } + pieces.push_back(str.substr(start)); + + return pieces; +} + +// Creates a directory at the specified path, including any necessary parent directories. +// Returns true if the directory was created successfully or already exists, false otherwise. +bool +createDirectory(const std::filesystem::path& directoryPath) +{ + try { + std::filesystem::create_directories(directoryPath); + } catch (const std::filesystem::filesystem_error& e) { + TF_CODING_ERROR("Error creating directory:\n \"{}\"", e.what()); + return false; + } + + return true; +} + +// Retrieves the sanitized file extension from the given filename by removing any trailing ']' character. +std::string +getSanitizedExtension(const std::string& file) { + std::string ext = TfGetExtension(file); + if (ext.length() > 1 && ext.back() == ']') { + ext.pop_back(); + } + return ext; +} + +// Retrieves the file path associated with a given layer identifier. +// Parses the layer identifier to extract the outer and inner paths, +// and returns the inner path if available; otherwise, returns the outer path. +std::string +getLayerFilePath(const std::string& layerIdentifier) +{ + std::string layerPath; + SdfLayer::FileFormatArguments arguments; + SdfLayer::SplitIdentifier(layerIdentifier, &layerPath, &arguments); + const auto [outer, inner] = ArSplitPackageRelativePathInner(layerPath); + return inner.empty() ? outer : inner; +} + } \ No newline at end of file diff --git a/utils/dictencoder.cpp b/utils/src/dictencoder.cpp similarity index 98% rename from utils/dictencoder.cpp rename to utils/src/dictencoder.cpp index b9bb9858..4bc62868 100644 --- a/utils/dictencoder.cpp +++ b/utils/src/dictencoder.cpp @@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "dictencoder.h" +#include #include #include diff --git a/utils/geometry.cpp b/utils/src/geometry.cpp similarity index 99% rename from utils/geometry.cpp rename to utils/src/geometry.cpp index 8ec17163..5a37beeb 100644 --- a/utils/geometry.cpp +++ b/utils/src/geometry.cpp @@ -9,8 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "geometry.h" -#include "debugCodes.h" +#include +#include using namespace PXR_NS; diff --git a/utils/images.cpp b/utils/src/images.cpp similarity index 64% rename from utils/images.cpp rename to utils/src/images.cpp index 40259f03..faafc3d5 100644 --- a/utils/images.cpp +++ b/utils/src/images.cpp @@ -9,14 +9,16 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "images.h" -#include "common.h" -#include "debugCodes.h" #include #include #include +#include +#include +#include #include #include +#include +#include using namespace PXR_NS; @@ -455,4 +457,212 @@ linearToSRGB(float s) return 1.055f * std::pow(s, (1.0f / 2.4f)) - 0.055f; } +bool +isImageFileSupported(const std::string& resolvedAssetPath) +{ + // Runtime cache for the supported file types. We don't expect the available plugins to change + // at run-time. The query to the HioImage::IsSupportedImageFile is quite expensive, so we cache + // it. + static std::unordered_map supportedExtensions; + // We want this to be multi-threading save, so we protect the cache + static std::mutex supportedExtensionsMutex; + + std::lock_guard lock(supportedExtensionsMutex); + + std::string ext = getSanitizedExtension(resolvedAssetPath); + auto [it, inserted] = supportedExtensions.emplace(ext, false); + if (inserted) { + it->second = HioImage::IsSupportedImageFile("filename." + ext); + } + return it->second; +} + +bool +isUriSbsarImage(const std::string& uri) +{ + size_t pos = uri.find_first_of('?'); + return uri.length() > 1 && pos != std::string::npos; +} + +// Takes a SBSAR texture parameterization like +// usage=ambientOcclusion#preset=Torn#packageHash=b427747e86441362#params={"$outputsize":\[4,4\]} +// and extracts the value for 'usage' +// --> ambientOcclusion +// Returns an empty string if the parsing fails +std::string +getSbsarUsageFromParameters(const std::string& parametersStr) +{ + auto params = split(parametersStr, '#'); + for (const auto& param : params) { + auto keyValue = split(param, '='); + if (keyValue.size() != 2) { + continue; + } + if (keyValue[0] == "usage") { + return keyValue[1]; + } + } + + return {}; +} + +std::string +getSbsarImageExtension(const std::string& resolvedAssetPath) +{ + if (!isImageFileSupported(resolvedAssetPath)) { + TF_WARN("Asset %s is not a supported image type", resolvedAssetPath.c_str()); + return {}; + } + + HioImageSharedPtr inputImage = HioImage::OpenForReading(resolvedAssetPath); + if (!inputImage) { + TF_WARN("Couldn't open image %s for reading", resolvedAssetPath.c_str()); + return {}; + } + + HioFormat hioFormat = inputImage->GetFormat(); + + // Floating point images are stored as exr files + if (hioFormat == HioFormatFloat16 || hioFormat == HioFormatFloat16Vec2 || + hioFormat == HioFormatFloat16Vec3 || hioFormat == HioFormatFloat16Vec4 || + hioFormat == HioFormatFloat32 || hioFormat == HioFormatFloat32Vec2 || + hioFormat == HioFormatFloat32Vec3 || hioFormat == HioFormatFloat32Vec4 || + hioFormat == HioFormatDouble64 || hioFormat == HioFormatDouble64Vec2 || + hioFormat == HioFormatDouble64Vec3 || hioFormat == HioFormatDouble64Vec4) { + return std::string("exr"); + } + + // All other images are most likely textures and we default to png + return std::string("png"); +} + +// This function extracts a usable file path from an assetPath, which might be a bit funky: +// Examples: +// Easy: some/path/to/texture.png -> some/path/to/texture.png +// With?: some/path/to/texture.png?param1=val1#param2=val2 -> some/path/to/texture.png +// SBSAR: +// graphs/CardBoard/images?usage=ambientOcclusion#preset=Torn#packageHash=b427747e86441362#params={"$outputsize":\[4,4\]}.png +// With some effort -> CardBoard_ambientOcclusion.png +std::string +extractFilePathFromAssetPath(const std::string& assetPath) +{ + // If there are no parameters after the file name we just take the whole path + auto q = assetPath.find_first_of('?'); + if (q == std::string::npos) { + return assetPath; + } + + // If the path contains a '?', take the first part as the subpath + std::string subpath = assetPath.substr(0, q); + // If this subpath has a file extension then we just take that path + if (std::filesystem::path(subpath).has_extension()) { + return subpath; + } + + // If the subpath does not have a file extension, check if the full asset path has an extension + // Note, the extension returned here does not have a '.', so we get 'png' + std::string ext = ArGetResolver().GetExtension(assetPath); + if (ext.empty()) { + TF_WARN("Could not find file extension for asset path %s", assetPath.c_str()); + } + + // Extract the parameters after the '?' and before the extension + // Note, we want to skip the '.' of the extension, which is where the + 1 for the extension + // length is coming from. + std::string parameters = assetPath.substr(q + 1, assetPath.size() - (q + 1) - (ext.size() + 1)); + + // Check if this is a SBSAR texture parameterization + // If so, we can do a better job than naming the file `images.png` + std::string usage = getSbsarUsageFromParameters(parameters); + if (!usage.empty()) { + // graphs/CardBoard/images -> CardBoard + std::string graphName = std::filesystem::path(subpath).parent_path().filename().u8string(); + subpath = graphName + "_" + usage; + } + + // Append the extension to create a complete path + subpath = subpath + "." + ext; + + return subpath; +} + +bool +transcodeImageAssetToMemory(const std::string& resolvedAssetPath, + const std::string& filename, + std::vector& outputPixelData) +{ + if (!isImageFileSupported(resolvedAssetPath)) { + TF_WARN("Asset %s is not a supported image type", resolvedAssetPath.c_str()); + return false; + } + + // Define the temporary directory path and create it if it doesn't exist + std::filesystem::path tempDir = std::filesystem::temp_directory_path() / "transcoded_images"; + if (!std::filesystem::exists(tempDir)) { + if (!createDirectory(tempDir)) { + TF_WARN("Failed to create temporary directory: %s", tempDir.string().c_str()); + return false; + } + } + + std::filesystem::path filePath = tempDir / filename; + if (!isImageFileSupported(filePath.string())) { + TF_WARN("Output %s is not a supported image type", filePath.c_str()); + return false; + } + + HioImageSharedPtr inputImage = HioImage::OpenForReading(resolvedAssetPath); + if (!inputImage) { + TF_WARN("Couldn't open image %s for reading", resolvedAssetPath.c_str()); + return false; + } + + HioImage::StorageSpec storage; + storage.width = inputImage->GetWidth(); + storage.height = inputImage->GetHeight(); + storage.format = inputImage->GetFormat(); + int bytesPerPixel = inputImage->GetBytesPerPixel(); + std::vector pixelData(storage.width * storage.height * bytesPerPixel); + storage.data = pixelData.data(); + + if (!inputImage->Read(storage)) { + TF_WARN("Reading of image %s failed", resolvedAssetPath.c_str()); + return false; + } + + HioImageSharedPtr outputImage = HioImage::OpenForWriting(filePath.string()); + if (!outputImage) { + TF_WARN("Couldn't open image %s for writing", filePath.string().c_str()); + return false; + } + + // Unfortunately, with the HioImage API and there is no way to write to memory + // and have it encoded to PNG or another format. We could refactor this in the + // future to use OIIO. + if (!outputImage->Write(storage)) { + TF_WARN("Writing of image %s failed", filePath.string().c_str()); + return false; + } + + // Read the output image file as binary data into outputPixelData + std::ifstream file(filePath, std::ios::binary | std::ios::ate); + if (!file) { + TF_WARN("Couldn't open outputImage %s for reading", filePath.string().c_str()); + return false; + } + + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + outputPixelData.resize(size); + if (!file.read(reinterpret_cast(outputPixelData.data()), size)) { + TF_WARN("Reading of transcoded image %s failed", filePath.string().c_str()); + return false; + } + + TF_STATUS("Transcoded image: %s -> %s and populated memory buffer", + resolvedAssetPath.c_str(), + filePath.string().c_str()); + return true; +} + } diff --git a/utils/layerRead.cpp b/utils/src/layerRead.cpp similarity index 95% rename from utils/layerRead.cpp rename to utils/src/layerRead.cpp index 06709a3e..a83d4cf9 100644 --- a/utils/layerRead.cpp +++ b/utils/src/layerRead.cpp @@ -9,20 +9,20 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "layerRead.h" -#include "common.h" -#include "debugCodes.h" -#include "geometry.h" -#include "layerWriteShared.h" -#include "usdData.h" #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include #include #include #include @@ -922,56 +922,87 @@ readVolume(ReadLayerContext& ctx, const UsdPrim& prim, int parent) return true; } +// Populates the absolute path, base name, and sanitized extension for an SBSAR asset by resolving +// the absolute path from the provided URI. +void +populateSbsarPathNameExtension(const SdfAssetPath& path, + std::string& absPath, + std::string& name, + std::string& extension) +{ + absPath = ArGetResolver().Resolve(path.GetResolvedPath()); + std::string layerPath = getLayerFilePath(path.GetResolvedPath()); + std::string filePath = extractFilePathFromAssetPath(layerPath); + name = TfStringGetBeforeSuffix(TfGetBaseName(filePath)); + extension = getSanitizedExtension(TfGetBaseName(filePath)); +} + bool readImage(ReadLayerContext& ctx, const SdfAssetPath& path, int& index) { - const std::string& uri = path.GetAssetPath(); - std::string name = TfStringGetBeforeSuffix(TfGetBaseName(uri)); - std::string extension = TfGetExtension(uri); - // If asset path originates from a custom resolver, fix name and extension: - size_t pos = name.find_first_of('['); - if (name.length() > 1 && pos != std::string::npos) { - name = name.substr(pos + 1, name.size()); - } - if (extension.length() > 1 && extension.back() == ']') { - extension = extension.substr(0, extension.size() - 1); - } - std::string absPath = path.GetResolvedPath().empty() - ? ArGetResolver().Resolve(path.GetAssetPath()) - : path.GetResolvedPath(); - if (const auto& it = ctx.images.find(uri); it != ctx.images.end()) { - index = it->second; - TF_DEBUG_MSG( - FILE_FORMAT_UTIL, "%s: Image (cached): %s\n", ctx.debugTag.c_str(), uri.c_str()); - } else { + std::string absPath, extension, name, uri; - // Deduplicate name - if (const auto& itName = ctx.imageNames.find(name); itName != ctx.imageNames.end()) { - itName->second++; - name = name + "_" + std::to_string(itName->second); - TF_DEBUG_MSG(FILE_FORMAT_UTIL, - "%s: Deduplicated image name: %s\n", - ctx.debugTag.c_str(), - name.c_str()); - } else { - ctx.imageNames[name] = 1; + // SBSAR images are special cases where the URI must be resolved + if (isUriSbsarImage(path.GetAssetPath())) { + uri = path.GetResolvedPath(); + populateSbsarPathNameExtension(path, absPath, name, extension); + } else { + uri = path.GetAssetPath(); + absPath = path.GetResolvedPath().empty() ? ArGetResolver().Resolve(path.GetAssetPath()) + : path.GetResolvedPath(); + name = TfStringGetBeforeSuffix(TfGetBaseName(uri)); + extension = getSanitizedExtension(uri); + size_t pos = name.find_first_of('['); + if (pos != std::string::npos) { + name = name.substr(pos + 1); } + } + + if (const auto& it = ctx.images.find(uri); it != ctx.images.end()) { + index = it->second; + TF_WARN("%s: Image (cached): %s\n", ctx.debugTag.c_str(), uri.c_str()); + return true; + } + // deduplicate name + if (const auto& itName = ctx.imageNames.find(name); itName != ctx.imageNames.end()) { + itName->second++; + name += "_" + std::to_string(itName->second); + TF_WARN("%s: Deduplicated image name: %s\n", ctx.debugTag.c_str(), name.c_str()); + } else { + ctx.imageNames[name] = 1; + } + + std::string assetPath; + SdfLayer::FileFormatArguments arguments; + SdfLayer::SplitIdentifier(uri, &assetPath, &arguments); + extension = getSanitizedExtension(assetPath); + auto [imageIndex, image] = ctx.usd->addImage(); + if (extension == "sbsarimage") { + // SBSAR images are special cases where the data is stored raw must be transcoded to memory + extension = getSbsarImageExtension(assetPath); + uri = image.uri = name + "." + extension; + transcodeImageAssetToMemory(assetPath, image.uri, image.image); + } else { ArResolver& ar = ArGetResolver(); - std::shared_ptr asset = ar.OpenAsset(ArResolvedPath(absPath)); - if (!asset) + auto resolvedPath = ArResolvedPath(absPath); + auto asset = ar.OpenAsset(resolvedPath); + if (!asset) { + TF_WARN("%s: Unable to open asset: %s\n", + ctx.debugTag.c_str(), + resolvedPath.GetPathString().c_str()); return false; - int length = asset->GetSize(); - auto [imageIndex, image] = ctx.usd->addImage(); - image.name = name; + } image.uri = name + "." + extension; - image.format = getFormat(extension); - image.image.resize(length); - memcpy(image.image.data(), asset->GetBuffer().get(), length); - ctx.images[uri] = imageIndex; - index = imageIndex; - TF_DEBUG_MSG(FILE_FORMAT_UTIL, "%s: Image (new): %s\n", ctx.debugTag.c_str(), uri.c_str()); + image.image.resize(asset->GetSize()); + memcpy(image.image.data(), asset->GetBuffer().get(), asset->GetSize()); } + + image.name = name; + image.format = getFormat(extension); + ctx.images[uri] = imageIndex; + index = imageIndex; + TF_WARN("%s: Image (new): index: %d uri: %s\n", ctx.debugTag.c_str(), imageIndex, uri.c_str()); return true; } @@ -1844,5 +1875,4 @@ readLayer(const ReadLayerOptions& options, return true; } - } diff --git a/utils/layerWriteMaterial.cpp b/utils/src/layerWriteMaterial.cpp similarity index 98% rename from utils/layerWriteMaterial.cpp rename to utils/src/layerWriteMaterial.cpp index b2054055..3d4055a8 100644 --- a/utils/layerWriteMaterial.cpp +++ b/utils/src/layerWriteMaterial.cpp @@ -9,13 +9,13 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "layerWriteMaterial.h" +#include -#include "common.h" -#include "debugCodes.h" -#include "layerRead.h" -#include "sdfMaterialUtils.h" -#include "sdfUtils.h" +#include +#include +#include +#include +#include #include diff --git a/utils/layerWriteMaterialX.cpp b/utils/src/layerWriteMaterialX.cpp similarity index 99% rename from utils/layerWriteMaterialX.cpp rename to utils/src/layerWriteMaterialX.cpp index 5a8b15dc..05b824d7 100644 --- a/utils/layerWriteMaterialX.cpp +++ b/utils/src/layerWriteMaterialX.cpp @@ -9,12 +9,12 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "layerWriteMaterialX.h" +#include -#include "common.h" -#include "debugCodes.h" -#include "sdfMaterialUtils.h" -#include "sdfUtils.h" +#include +#include +#include +#include #include diff --git a/utils/layerWriteSdfData.cpp b/utils/src/layerWriteSdfData.cpp similarity index 92% rename from utils/layerWriteSdfData.cpp rename to utils/src/layerWriteSdfData.cpp index 5144aef3..45fb2861 100644 --- a/utils/layerWriteSdfData.cpp +++ b/utils/src/layerWriteSdfData.cpp @@ -9,17 +9,17 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "layerWriteSdfData.h" - -#include "common.h" -#include "debugCodes.h" -#include "geometry.h" -#include "layerWriteMaterial.h" -#include "layerWriteMaterialX.h" -#include "sdfMaterialUtils.h" -#include "sdfUtils.h" -#include "usdData.h" -#include "version.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -558,14 +558,26 @@ _writePoints(SdfAbstractData* sdfData, const SdfPath& parentPath, const Mesh& me return primPath; } +void +_bindMeshMaterial(SdfAbstractData* sdfData, + const SdfPath& primPath, + const SdfPathVector& materialMap, + const Mesh& mesh) +{ + if (mesh.material >= 0) { + _bindMaterial(sdfData, primPath, materialMap[mesh.material]); + } +} + SdfPath _writeMesh(SdfAbstractData* sdfData, const SdfPath& parentPath, const SdfPathVector& materialMap, const Mesh& mesh, - const SdfPath& skeletonPath) + const std::string& meshName, + const SdfPath& skeletonPath = SdfPath::EmptyPath()) { - SdfPath primPath = createPrimSpec(sdfData, parentPath, TfToken(mesh.name), UsdGeomTokens->Mesh); + SdfPath primPath = createPrimSpec(sdfData, parentPath, TfToken(meshName), UsdGeomTokens->Mesh); TF_DEBUG_MSG(FILE_FORMAT_UTIL, "write mesh: path=%s\n", primPath.GetString().c_str()); if (!skeletonPath.IsEmpty()) { @@ -632,16 +644,11 @@ _writeMesh(SdfAbstractData* sdfData, mesh.geomBindTransform); } - // Material binding - if (mesh.material >= 0) { - _bindMaterial(sdfData, primPath, materialMap[mesh.material]); - } - // Subsets if (mesh.subsets.size()) { for (size_t i = 0; i < mesh.subsets.size(); i++) { const Subset& subset = mesh.subsets[i]; - TfToken subsetName = TfToken(mesh.name + "_sub" + std::to_string(i)); + TfToken subsetName = TfToken(meshName + "_sub" + std::to_string(i)); SdfPath subsetPath = _createGeomSubset(sdfData, primPath, subsetName, subset); if (subset.material >= 0) { @@ -653,46 +660,78 @@ _writeMesh(SdfAbstractData* sdfData, return primPath; } -bool -_writePointsOrInstancedMesh(WriteSdfContext& ctx, - const SdfPath& parentPath, - const Mesh& mesh, - int meshIdx, - int childIdx, - const SdfPath& skeletonPath) +void +_writePointsOrMesh(WriteSdfContext& ctx, + const SdfPath& parentPath, + const Mesh& mesh, + const SdfPath& skeletonPath = SdfPath::EmptyPath()) { if (mesh.asPoints) { _writePoints(ctx.sdfData, parentPath, mesh); - } else if (mesh.instanceable) { - // XXX Note, slightly awkward name generator to match old behavior. Once the old code has - // been removed, this can be cleaned up to any scheme that produces unique names - std::string scopeNameStr = - "GeomScope" + (childIdx == 0 ? "" : std::to_string(childIdx - 1)); - - SdfPath scopePath = - createPrimSpec(ctx.sdfData, parentPath, TfToken(scopeNameStr), UsdGeomTokens->Scope); - - const SdfPath& prototypePath = ctx.meshPrototypeMap[meshIdx]; - if (!prototypePath.IsEmpty()) { - addPrimReference(ctx.sdfData, scopePath, SdfReference("", prototypePath)); - setPrimMetadata(ctx.sdfData, scopePath, SdfFieldKeys->Instanceable, VtValue(true)); - TF_DEBUG_MSG(FILE_FORMAT_UTIL, - "layer::write gScope %s, Instance of %s\n", - scopePath.GetText(), - prototypePath.GetText()); - } else { - _writeMesh(ctx.sdfData, scopePath, ctx.materialMap, mesh, skeletonPath); - // Add this first instance to the list of prototypes - ctx.meshPrototypeMap[meshIdx] = scopePath; - TF_DEBUG_MSG(FILE_FORMAT_UTIL, - "layer::write gScope %s (add new prototype)\n", - scopePath.GetText()); - } } else { - _writeMesh(ctx.sdfData, parentPath, ctx.materialMap, mesh, skeletonPath); + SdfPath meshPath = + _writeMesh(ctx.sdfData, parentPath, ctx.materialMap, mesh, mesh.name, skeletonPath); + _bindMeshMaterial(ctx.sdfData, meshPath, ctx.materialMap, mesh); } +} - return true; +void +_writeInstancedMesh(WriteSdfContext& ctx, + const SdfPath& parentPath, + const Mesh& mesh, + int meshIdx, + const std::string& meshName) +{ + if (!mesh.instanceable) { + TF_CODING_ERROR("Trying to write instanced mesh %s/%s that is not instanceable", + parentPath.GetText(), + meshName.c_str()); + return; + } + if (mesh.asPoints) { + TF_CODING_ERROR("Trying to write instanced points %s/%s, which is not supported", + parentPath.GetText(), + meshName.c_str()); + return; + } + + SdfPath prototypePath = ctx.meshPrototypeMap[meshIdx]; + if (prototypePath.IsEmpty()) { + TfToken meshPrototypeName = TfToken("_MeshPrototype_" + meshName); + + // For Hydra to be happy with the prototype mesh, it needs to be under a transformable + // prim, hence we nest it here under a typeless `over` prim spec, so that it does not + // appear in the scene by itself. Only by being referenced onto an instancer. + prototypePath = + createPrimSpec(ctx.sdfData, parentPath, meshPrototypeName, TfToken(), SdfSpecifierOver); + + _writeMesh(ctx.sdfData, prototypePath, ctx.materialMap, mesh, meshName); + + // Add this to the list of prototypes + ctx.meshPrototypeMap[meshIdx] = prototypePath; + TF_DEBUG_MSG(FILE_FORMAT_UTIL, + "layer::write prototype %s for mesh %s\n", + prototypePath.GetText(), + meshName.c_str()); + } + + // We instantiate the mesh via a Xform prim that references the untyped prototype prim + SdfPath meshPath = + createPrimSpec(ctx.sdfData, parentPath, TfToken(meshName), UsdGeomTokens->Xform); + addPrimReference(ctx.sdfData, meshPath, SdfReference("", prototypePath)); + setPrimMetadata(ctx.sdfData, meshPath, SdfFieldKeys->Instanceable, VtValue(true)); + + // The material is bound on the instance and not on the actual prototype mesh, so that it + // becomes easy to override later. + // XXX if the instanced mesh has subsets, those material bindings are currently authored + // in the prototype, which makes it hard to manipulate after the fact. + _bindMeshMaterial(ctx.sdfData, meshPath, ctx.materialMap, mesh); + + TF_DEBUG_MSG(FILE_FORMAT_UTIL, + "layer::write mesh xform %s, instance of %s (%s)\n", + meshPath.GetText(), + prototypePath.GetText(), + meshName.c_str()); } // Layout of control points in USD is: row-major with U considered rows, and V columns. @@ -819,10 +858,24 @@ _writeNode(WriteSdfContext& ctx, const SdfPath& primPath, const Node& node) _writeLight(ctx.sdfData, primPath, ctx.usdData->lights[node.light]); } + // Uninstanced meshes first + for (int meshIndex : node.staticMeshes) { + const Mesh& mesh = ctx.usdData->meshes[meshIndex]; + if (!mesh.instanceable) { + _writePointsOrMesh(ctx, primPath, mesh); + } + } + + // Instanced meshes second. They need a name resolution to make sure they are unique + UniqueNameEnforcer enforcer; int i = 0; for (int meshIndex : node.staticMeshes) { const Mesh& mesh = ctx.usdData->meshes[meshIndex]; - _writePointsOrInstancedMesh(ctx, primPath, mesh, meshIndex, i++, SdfPath::EmptyPath()); + if (mesh.instanceable) { + std::string meshName = mesh.name; + enforcer.enforceUniqueness(meshName); + _writeInstancedMesh(ctx, primPath, mesh, meshIndex, meshName); + } } _writeNodes(ctx, primPath, node.children); @@ -1273,8 +1326,8 @@ _writeLayerSdfData(const WriteLayerOptions& options, for (int meshIndex : skeleton.meshSkinningTargets) { const Mesh& mesh = ctx.usdData->meshes[meshIndex]; - _writePointsOrInstancedMesh( - ctx, skelRootPath, mesh, meshIndex, meshChildIndex, skeletonPath); + // Note, skinned meshes are never emitted as instanced + _writePointsOrMesh(ctx, skelRootPath, mesh, skeletonPath); meshChildIndex++; } @@ -1325,7 +1378,8 @@ writeLayer(const WriteLayerOptions& options, // Add file names to metadata if (!data.importedFileNames.empty()) { - PXR_NS::VtArray filenames(data.importedFileNames.begin(), data.importedFileNames.end()); + PXR_NS::VtArray filenames(data.importedFileNames.begin(), + data.importedFileNames.end()); data.metadata.SetValueAtPath("filenames", VtValue(filenames)); } diff --git a/utils/layerWriteShared.cpp b/utils/src/layerWriteShared.cpp similarity index 97% rename from utils/layerWriteShared.cpp rename to utils/src/layerWriteShared.cpp index d11d1055..dadc1aba 100644 --- a/utils/layerWriteShared.cpp +++ b/utils/src/layerWriteShared.cpp @@ -9,9 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "layerWriteShared.h" +#include -#include "common.h" +#include #include #include diff --git a/utils/materials.cpp b/utils/src/materials.cpp similarity index 99% rename from utils/materials.cpp rename to utils/src/materials.cpp index 94c5bae4..7752dc81 100644 --- a/utils/materials.cpp +++ b/utils/src/materials.cpp @@ -9,10 +9,10 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "materials.h" -#include "common.h" -#include "debugCodes.h" -#include "images.h" +#include +#include +#include +#include #include #include @@ -768,7 +768,8 @@ InputTranslator::translatePhong2PBR(const Input& diffuseIn, GfVec3f diffuseValue = diffuseIn.value.Get(); GfVec3f specularValue = !specularIn.value.IsEmpty() ? specularIn.value.Get() : GfVec3f(.5); - float shininessValue = !glosinessIn.value.IsEmpty() ? glosinessIn.value.Get() : .5; + float shininessValue = + glosinessIn.value.IsHolding() ? glosinessIn.value.UncheckedGet() : 0.5f; // float shininess = m.ns == -1 ? 1 : m.ns; GfVec3f albedo; float roughness; diff --git a/utils/neuralAssetsHelper.cpp b/utils/src/neuralAssetsHelper.cpp similarity index 99% rename from utils/neuralAssetsHelper.cpp rename to utils/src/neuralAssetsHelper.cpp index 0cf85bac..436a273e 100644 --- a/utils/neuralAssetsHelper.cpp +++ b/utils/src/neuralAssetsHelper.cpp @@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "neuralAssetsHelper.h" +#include #include #include diff --git a/utils/resolver.cpp b/utils/src/resolver.cpp similarity index 94% rename from utils/resolver.cpp rename to utils/src/resolver.cpp index e85c5541..03d91a21 100644 --- a/utils/resolver.cpp +++ b/utils/src/resolver.cpp @@ -9,11 +9,11 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "resolver.h" -#include "assetresolver.h" -#include "common.h" -#include "debugCodes.h" -#include "images.h" +#include +#include +#include +#include +#include #include #include #include diff --git a/utils/sdfMaterialUtils.cpp b/utils/src/sdfMaterialUtils.cpp similarity index 99% rename from utils/sdfMaterialUtils.cpp rename to utils/src/sdfMaterialUtils.cpp index efd9e583..bf7e256c 100644 --- a/utils/sdfMaterialUtils.cpp +++ b/utils/src/sdfMaterialUtils.cpp @@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "sdfMaterialUtils.h" +#include PXR_NAMESPACE_USING_DIRECTIVE diff --git a/utils/sdfUtils.cpp b/utils/src/sdfUtils.cpp similarity index 99% rename from utils/sdfUtils.cpp rename to utils/src/sdfUtils.cpp index e9c9bfef..703632a3 100644 --- a/utils/sdfUtils.cpp +++ b/utils/src/sdfUtils.cpp @@ -9,10 +9,10 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "sdfUtils.h" +#include -#include "common.h" -#include "debugCodes.h" +#include +#include #include #include diff --git a/utils/test.cpp b/utils/src/test.cpp similarity index 99% rename from utils/test.cpp rename to utils/src/test.cpp index ae29f11d..7400b194 100644 --- a/utils/test.cpp +++ b/utils/src/test.cpp @@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "test.h" +#include #include #include #include diff --git a/utils/transforms.cpp b/utils/src/transforms.cpp similarity index 94% rename from utils/transforms.cpp rename to utils/src/transforms.cpp index 6179f261..f300c972 100644 --- a/utils/transforms.cpp +++ b/utils/src/transforms.cpp @@ -9,9 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "transforms.h" -#include "common.h" -#include "debugCodes.h" +#include +#include +#include #include using namespace PXR_NS; diff --git a/utils/usdData.cpp b/utils/src/usdData.cpp similarity index 98% rename from utils/usdData.cpp rename to utils/src/usdData.cpp index e5f55944..c4ae0ee5 100644 --- a/utils/usdData.cpp +++ b/utils/src/usdData.cpp @@ -9,10 +9,10 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "usdData.h" -#include "common.h" -#include "debugCodes.h" #include +#include +#include +#include #include #include @@ -539,6 +539,11 @@ _uniquifySiblingMeshes(std::vector& all, const std::vector& siblingIn for (int idx : siblingIndices) { Mesh& sibling = all[idx]; sibling.name = _makeValidPrimName(sibling.name, sibling.asPoints ? pointsStr : meshStr); + // We skip uniquifying the names of meshes that will become prototypes, since the unique + // name belongs to the node that instances the mesh and not the mesh itself. + if (sibling.instanceable) { + continue; + } _makeUniqueAndAdd(siblingNames, sibling.name); } } diff --git a/version b/version index 437d26b1..86844988 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.0.10 \ No newline at end of file +1.0.11 \ No newline at end of file