Hello Michel,
Please see the sample script that creates the animation camera track, based on selected shapes (polylines and polygons).
There are some limitations, which could be fixed, if necessary:
- script only works with polygonal and polyline shapes, which are defined in 3D and do not have attached markers,
- script assumes that the project is georeferenced (let me know, if you are planning to apply the script to unreferenced projects or projects in local coordinates),
- each polyline/polygon segment would contain N camera track keyframes with equal spacing (N is hardcoded in the script body).
import Metashape
def flatten_list(input_list):
if not input_list:
return []
output_list = []
for i in input_list:
if not isinstance(i, list):
output_list.append(i)
else:
output_list += flatten_list(i)
return output_list
def shape_to_camera_track(chunk, shape):
N = 10 #keyframes per polyline segment
if shape.geometry.type not in [Metashape.Geometry.Type.LineStringType, Metashape.Geometry.Type.PolygonType]:
print("Only polygonal and polyline shapes are supported, skipping shape " + shape.label)
return 0
if not shape.geometry.is_3d:
print("Only 3D shapes are supported, skipping shape " + shape.label)
if shape.is_attached:
print("Shapes with attached markers not yet supported, skipping shape " + shape.label)
#TODO, if necessary
return 0
animation = chunk.addCameraTrack()
chunk.camera_track = animation
animation.label = "({:d}) {:s}".format(shape.key, shape.label)
frames = []
vertices = flatten_list(shape.geometry.coordinates)
T = chunk.transform.matrix
shapes_crs = chunk.shapes.crs
if not shapes_crs:
shapes_crs = chunk.crs
for i in range(0, len(vertices) - 1):
start = Metashape.CoordinateSystem.transform(vertices[i], shapes_crs, chunk.crs.geoccs)
finish = Metashape.CoordinateSystem.transform(vertices[i+1], shapes_crs, chunk.crs.geoccs)
for j in range(N):
coord = start + j * (finish - start) / N
coord = T.inv().mulp(coord)
rot = Metashape.Matrix().Diag([1,1,1])
frame = chunk.addCamera()
frame.type = Metashape.Camera.Type.Keyframe
frame.transform = Metashape.Matrix.Translation(coord) * Metashape.Matrix.Rotation(rot)
frames.append(frame)
animation.keyframes = frames
print("Created camera track from shape " + shape.label)
return 1
doc = Metashape.app.document
chunk = doc.chunk
shapes = [s for s in chunk.shapes if s.geometry.type in [Metashape.Geometry.Type.LineStringType, Metashape.Geometry.Type.PolygonType]]
if len(shapes):
for shape in [s for s in shapes if s.selected]:
shape_to_camera_track(chunk, shape)
else:
print("No polygonal or polyline shapes, script aborted")