From c7538a7372f44872061c5751d5d2cc0350da2d76 Mon Sep 17 00:00:00 2001 From: ivanimanishi Date: Thu, 20 Jul 2023 15:03:58 -0700 Subject: [PATCH] LinkedScene : Fix incorrect `linkLocations` attribute value The old code was incorrectly appending the target's location to the `linkLocations`. The `linkLocations` are expected to hold the locations in the current LinkedScene that contain links to other files. These paths are expected to exist in the LinkedScene itself. Everything worked fine if the target location was set to the ROOT, but if it was targeting an internal location, that would be appended which would result in an invalid path. The cause for that bug was that we were updating `m_linkedScene`, which is used to compute LinkedScene::path(), but not updating the `m_rootLinkDepth` property, which is also used to compute the path, by stripping out part of it based on the depth of the link. For `linkLocations`, that depth should generally be expected to completely remove any contributions from `m_linkedScene`, since this is the location where the link is being created, and therefore the `m_rootLinkDepth` will match the length of the path inside the target linked scene that we are linking to. Note that existing saved `lscc` files have the attribute baked in, and are therefore not fixed by this commit. A new export is necessary in order to fix it. --- Changes | 6 ++++++ src/IECoreScene/LinkedScene.cpp | 1 + test/IECoreScene/LinkedSceneTest.py | 21 ++++++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Changes b/Changes index 0eeb572c45..8dc9e76c41 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,12 @@ 10.4.x.x (relative to 10.4.10.1) ======== +Fixes +----- + +- LinkedScene : Fixed bug where `linkLocations` attribute was baked incorrectly if the link target location wasn't the ROOT + - This in turn caused LinkedScene::setNames() and LinkedScene::readSet() to error + 10.4.10.1 (relative to 10.4.10.0) ======== diff --git a/src/IECoreScene/LinkedScene.cpp b/src/IECoreScene/LinkedScene.cpp index 13148a0368..bfd17eac4e 100644 --- a/src/IECoreScene/LinkedScene.cpp +++ b/src/IECoreScene/LinkedScene.cpp @@ -700,6 +700,7 @@ void LinkedScene::writeAttribute( const Name &name, const Object *attribute, dou { throw Exception( "Trying to store a broken link!" ); } + m_rootLinkDepth = linkDepth; // check for child name clashes: NameList mainSceneChildren; diff --git a/test/IECoreScene/LinkedSceneTest.py b/test/IECoreScene/LinkedSceneTest.py index 37529d147c..3d82ff40b6 100644 --- a/test/IECoreScene/LinkedSceneTest.py +++ b/test/IECoreScene/LinkedSceneTest.py @@ -1094,26 +1094,41 @@ def testCanReadSetNamesAndMembersOfLinkedScene( self ) : r = IECoreScene.SceneCache( sceneFile, IECore.IndexedIO.OpenMode.Read ) A = r.child( "A" ) + B = A.child( "B" ) # Master scene which contains link to above scene # C # D -> [target.scc, /] + # E + # A -> [target.scc, /A] + # F + # A + # B -> [target.scc, /A/B] sceneFile = os.path.join( self.tempDir, "scene.lscc" ) w = IECoreScene.LinkedScene( sceneFile, IECore.IndexedIO.OpenMode.Write ) C = w.createChild( "C" ) D = C.createChild( "D" ) + E = w.createChild( "E" ) + A1 = E.createChild( "A" ) + + F = w.createChild( "F" ) + A2 = F.createChild( "A" ) + B1 = A2.createChild( "B" ) + + A1.writeLink( A ) D.writeLink( r ) + B1.writeLink( B ) - del w, C, D + del w, C, D, E, F, A1, A2, B1 # ok lets read back in our linked scene and try and read the set names r = IECoreScene.LinkedScene( sceneFile, IECore.IndexedIO.OpenMode.Read ) self.assertEqualUnordered( r.setNames(), ['don', 'stew'] ) - self.assertEqual( r.readSet( "don" ), IECore.PathMatcher(['/C/D/A'] ) ) - self.assertEqual( r.readSet( "stew" ), IECore.PathMatcher(['/C/D/A/B'] ) ) + self.assertEqual( r.readSet( "don" ), IECore.PathMatcher( ['/C/D/A', '/E/A' ] ) ) + self.assertEqual( r.readSet( "stew" ), IECore.PathMatcher( ['/C/D/A/B', '/E/A/B', '/F/A/B' ] ) ) self.assertEqualUnordered( r.setNames( includeDescendantSets = False ), [] )