Thanks for the reply, bassistas. For whatever reason, that workflow did not work for me. I can't explain why - there's something odd occurring with estimated position/rotation data being reset in the Reference pane GUI, but I've no idea if that's related.
However, I'm thrilled to say that I did find a solution that I could replicate - I simply had to Reset Transform for the chunk before running the script. I can't explain why that's the case at the moment (I didn't perform any transformation after chunk alignment).
If anyone else finds this useful, I've slightly modified the script for a workflow that doesn't require duplicating the chunk before alignment. I've also done my best to annotate the script with very basic explanations and instructions in hopes that it'll help anyone who comes across this.
#WORKFLOW INSTRUCTIONS (or at least this is what worked for me in Metashape v2.0)
# 1. Follow instructions to align terrestrial laser scans (TLS) and photos per
# https://agisoft.freshdesk.com/support/solutions/articles/31000168474-terrestrial-laser-scans-processing-in-metashape-2-0-0#Processing-of-terrestrial-laser-scans-with-images
# 2. Choose an aligned laser scan to re-import into the chunk. Verify that it loads in its original position.
# 3. Rename the duplicate laser scan as "GeoRef_Scan" ...in the code below, this duplicate scan is referenced by the "GeoRef_camera" variable.
# Right-click on the laser scan name in the Workspace pane and confirm that "Lock Transform" is checked in the laser scan contextual menu.
# 3A. In the code below, edit the "aligned_camera" variable definition as described in the in-line code explanation.
# 3B. In the code below, edit the chunk ID number as described in the in-line code explanation.
# 4. For good measure, save the file in case something goes wrong and you need to close & revert to the saved version.
# 5. Reset Transform (Model -> Transform Object -> Reset Transform).
# Resetting the transform may clear all estimated coordinate/rotation values (viewed in the Reference pane when "view estimated" button is selected) -
# not sure why that happens in the GUI, but the values must still be stored.
# 6. Run this script (copy the script text into a .txt file and save it - in Metashape, use shortkey ctrl+r to bring up the script dialog).
# Check that the chunk is transformed by comparing the estimated coordinate/rotation values in the
# Reference Pane for the originally aligned laser scan and the duplicate laser scan.
# Of course, the corresponding camera symbols and point clouds should also be perfectly aligned when viewed in model space.
#Defines chunk to reference.
# The "[5]" is the chunk ID, which is determined by the list position of the chunk in the Workspace tab.
# The chunk ID list starts at 0, not 1. I'm sure there's a way to make this more user-friendly (e.g., reference currently selected chunk), but that's for another day.
chunk = Metashape.app.document.chunks[0] #Replace "0" if the chunk isn't listed first in Workspace tab.
#Defines a function to get camera (i.e., laser scan) based on label
def get_camera(chunk,label):
for camera in chunk.cameras:
if camera.label == label:
return camera
return None
#Defines variables to reference the original and duplicate laser scans
GeoRef_camera = get_camera(chunk, "GeoRef_Scan")
aligned_camera = get_camera(chunk, "Ground-Ext-001") #Replace "Ground-Ext-001" with the name of the original, aligned laser scan
#Transform (i.e., shift & rotate) the chunk to align the original/aligned laser scan with the duplicate/untransformed laser scan.
# Appending the ".transform" to the scan ID variables references a 4x4 matrix that defines the position and rotation of the laser scan.
# So this code defines a chunk transform matrix by multiplying the matrix for the correct position by the inverse of the matrix for the transformed position that
# resulted from the alignment process. Multiplying by the inverted matrix essentially negates the transformation.
# For example, if you were to multiply a transform matrix by its own inverse, the result would be an identity matrix storing no position/rotation (i.e., correlating to the 0,0 origin)
chunk.transform.matrix = GeoRef_camera.transform * aligned_camera.transform.inv()