Hello giancan,
Please check if the following script works for the guided marker placement approach (note that camera index and coordinates of the marker on the given photo should be assigned in the script body):
#guided marker placement approach using Python scripting
#compatibility PhotoScan Pro 1.1.0
import PhotoScan
def cross(a, b):
result = PhotoScan.Vector([a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x])
return result
print("Script started")
doc = PhotoScan.app.document
chunk = doc.chunk
model = chunk.model
vertices = chunk.model.vertices
if chunk.transform.matrix:
T0 = chunk.transform.matrix
else:
T0 = PhotoScan.Matrix().diag([1, 1, 1, 1])
camera = chunk.cameras[120] #camera index #should be changed for user input
marker_2D = (500, 400) #projections of marker on the given photo #should be changed for user input
chunk.addMarker()
marker = chunk.markers[-1] #the last marker in set
marker.projections[camera] = marker_2D
point_2D = marker.projections[camera].coord
vect = camera.sensor.calibration.unproject(point_2D)
vect = camera.transform.mulv(vect)
center = camera.center
#estimating ray and surface intersection
for face in model.faces:
v = face.vertices
E1 = PhotoScan.Vector(vertices[v[1]].coord - vertices[v[0]].coord)
E2 = PhotoScan.Vector(vertices[v[2]].coord - vertices[v[0]].coord)
D = PhotoScan.Vector(vect)
T = PhotoScan.Vector(center - vertices[v[0]].coord)
P = cross(D, E2)
Q = cross(T, E1)
result = PhotoScan.Vector([Q * E2, P * T, Q * D]) / (P * E1)
if (0 < result[1]) and (0 < result[2]) and (result[1] + result[2] <= 1):
t = (1 - result[1] - result[2]) * vertices[v[0]].coord
u = result[1] * vertices[v[1]].coord
v_ = result[2] * vertices[v[2]].coord
point_3D = T0.mulp(u + v_ + t)
point_3D = chunk.crs.project(point_3D)
break
point = chunk.crs.unproject(point_3D)
point = T0.inv().mulp(point)
for cur_camera in chunk.cameras:
if (cur_camera == camera) or not cur_camera.transform:
continue
cur_proj = cur_camera.project(point)
if (0 <= cur_proj[0] < camera.sensor.width) and (0 <= cur_proj[1] < camera.sensor.height):
marker.projections[cur_camera] = cur_proj
print("Script finished")