added 3de to photoscan export script

This commit is contained in:
2016-09-22 20:28:56 +02:00
parent a8a2ef83f9
commit b587afa89e
3 changed files with 370 additions and 0 deletions

184
xg_export_photoscan.py Normal file
View File

@@ -0,0 +1,184 @@
#
#
# 3DE4.script.name: Photoscan...
#
# 3DE4.script.version: v1.0
#
# 3DE4.script.gui: Main Window::3DE4::Export Project
#
# 3DE4.script.comment: Creates a py script file that contains all project data, which can be imported into Photoscan to build Point Cloud.
#
# Giovanni Di Grezia 2016
# http://www.xgiovio.com
#
# Some functions are from 3de export scripts
from vl_sdv import *
def convertToAngles(r3d):
rot = rot3d(mat3d(r3d)).angles(VL_APPLY_ZXY)
rx = (rot[0]*180.0)/3.141592654
ry = (rot[1]*180.0)/3.141592654
rz = (rot[2]*180.0)/3.141592654
return(rx,ry,rz)
#maybe this function is not correct
def rot_matrix_for_photoscan (r3d):
rot3d_old = rot3d(mat3d(r3d)).angles(VL_APPLY_ZXY)
rot3d_new = rot3d(rot3d_old[1],rot3d_old[0],rot3d_old[2],VL_APPLY_ZXY)
return rot3d_new.mat()
def prepareImagePath(path,startframe):
path = path.replace("\\","/")
i = 0
n = 0
i0 = -1
while(i<len(path)):
if path[i]=='#': n += 1
if n==1: i0 = i
i += 1
if i0!=-1:
fstring = "%%s%%0%dd%%s"%(n)
path2 = fstring%(path[0:i0],startframe,path[i0+n:len(path)])
path = path2
return path
def callback (req,label,event):
if label == "match_align":
if tde4.getWidgetValue(req,"match_align") == 1:
tde4.setWidgetSensitiveFlag(req,"build_dense_cloud",1)
tde4.setWidgetSensitiveFlag(req,"match_align_keypoint_limit",1)
tde4.setWidgetSensitiveFlag(req,"match_align_tiepoint_limit",1)
else:
tde4.setWidgetSensitiveFlag(req,"build_dense_cloud",0)
tde4.setWidgetSensitiveFlag(req,"match_align_keypoint_limit",0)
tde4.setWidgetSensitiveFlag(req,"match_align_tiepoint_limit",0)
#
# search for camera point group...
campg = None
pgl = tde4.getPGroupList()
for pg in pgl:
if tde4.getPGroupType(pg)=="CAMERA": campg = pg
if campg==None:
tde4.postQuestionRequester("Export Photoscan..","Error, there is no camera point group.","Ok")
else :
cams_undistorted_path = {}
req = tde4.createCustomRequester()
tde4.addFileWidget(req,"file_browser","Exportfile...","*.py")
tde4.addTextFieldWidget(req,"step","Frames Step","10")
tde4.addSeparatorWidget(req,"separator")
cl = tde4.getCameraList()
for cam in cl:
tde4.addTextFieldWidget(req,cam,tde4.getCameraName(cam) + " undistorted",tde4.getCameraPath(cam))
tde4.addSeparatorWidget(req,"separator2")
tde4.addTextFieldWidget(req,"accuracy_position","Position Accuracy in Units","0.1")
tde4.addTextFieldWidget(req,"accuracy_rotation","Rotation Accuracy in Degrees","2.0")
tde4.addSeparatorWidget(req,"separator3")
tde4.addToggleWidget(req,"match_align","Match Photos and Align",1)
tde4.addTextFieldWidget(req,"match_align_keypoint_limit","KeyPoint Limit","40000")
tde4.addTextFieldWidget(req,"match_align_tiepoint_limit","TiePoint Limit","4000")
tde4.addSeparatorWidget(req,"separator4")
tde4.addToggleWidget(req,"build_dense_cloud","Build Dense Cloud",1)
tde4.setWidgetCallbackFunction(req,"match_align","callback")
ret = tde4.postCustomRequester(req,"Export Photoscan (py-Script)...",800,0,"Ok","Cancel")
if ret==1:
path = tde4.getWidgetValue(req,"file_browser")
image_stepping = int(tde4.getWidgetValue(req,"step"))
for cam in cl:
cams_undistorted_path[cam] = tde4.getWidgetValue(req,cam)
if path!=None:
if not path.endswith('.py'): path = path+'.py'
f = open(path,"w")
if not f.closed:
f.write("import PhotoScan\n")
f.write("doc = PhotoScan.app.document\n")
f.write("chunk = PhotoScan.app.document.addChunk()\n")
# write cameras...
cl = tde4.getCameraList()
for cam in cl:
camType = tde4.getCameraType(cam)
noframes = tde4.getCameraNoFrames(cam)
lens = tde4.getCameraLens(cam)
image_width = tde4.getCameraImageWidth(cam)
image_height = tde4.getCameraImageHeight(cam)
offset_timeline = tde4.getCameraFrameOffset(cam)
source_start = tde4.getCameraSequenceAttr(cam)[0]
if lens!=None:
fback_w_mm = tde4.getLensFBackWidth(lens) * 10 #mm
fback_h_mm = tde4.getLensFBackHeight(lens) * 10 #mm
frame = offset_timeline
while frame<=noframes + offset_timeline - 1:
if (frame - offset_timeline) % image_stepping == 0 :
path = cams_undistorted_path[cam]
path = prepareImagePath(path,source_start + frame - offset_timeline)
f.write("chunk.addPhotos([\"" + path +"\"])\n")
focal_mm= tde4.getCameraFocalLength(cam,frame) * 10 #mm
f.write("for cam in chunk.cameras:\n")
f.write("\tif (cam.photo.path.split(\"/\")[-1]) == " + "\"" + path.split("/")[-1] + "\":\n")
f.write("\t\tcamera = cam\n")
f.write("\t\tbreak\n")
f.write("camera.sensor = chunk.addSensor()\n" )
f.write("camera.sensor.type = camera.sensor.Type.Frame\n")
f.write("camera.sensor.fixed = True\n")
f.write("camera.sensor.width = " + str(image_width) + "\n")
f.write("camera.sensor.height = " + str(image_height) + "\n")
f.write("calibration = PhotoScan.Calibration()\n" )
f.write("calibration.f = ( " + str(focal_mm) + " / " + str(fback_w_mm) + ") * " + str(image_width) + "\n")
f.write("camera.sensor.user_calib = calibration\n")
position_3vector = tde4.getPGroupPosition3D(campg,cam,frame)
f.write("camera.reference.location = PhotoScan.Vector ( (" + str(position_3vector[0]) + "," + str(position_3vector[1]) + "," + str(position_3vector[2]) + "))\n" )
rotation_3matrix = tde4.getPGroupRotation3D(campg,cam,frame)
rotation_angles = convertToAngles (rotation_3matrix)
#in photoscan yaw is 3de rotation y - pitch is 3de rotation x - roll is 3de rotation z
f.write("camera.reference.rotation = PhotoScan.Vector ( (" + str(rotation_angles[1]) + "," + str(rotation_angles[0]) + "," + str(rotation_angles[2]) + "))\n" )
#### 3de rotation matrix is different in axis from photoscan. If you want to set camera.transform = PhotoScan.Matrix you should create a new rotation matrix
'''
position_4matrix = mat4d( vec4d( 1.0,0,0,position_3vector[0]), vec4d( 0,1.0,0,position_3vector[1]) ,vec4d( 0,0,1.0,position_3vector[2]),vec4d( 0,0,0,1.0))
rotation_3matrix = rot_matrix_for_photoscan (rotation_3matrix)
rotation_4matrix = mat4d( vec4d( rotation_3matrix[0][0],rotation_3matrix[0][1],rotation_3matrix[0][2],0),vec4d( rotation_3matrix[1][0],rotation_3matrix[1][1],rotation_3matrix[1][2],0),vec4d( rotation_3matrix[2][0],rotation_3matrix[2][1],rotation_3matrix[2][2],0),vec4d( 0,0,0,1))
transform_matrix = position_4matrix * rotation_4matrix
f.write("camera.transform = PhotoScan.Matrix ([[" + str(transform_matrix[0][0]) + "," + str(transform_matrix[0][1]) + "," + str(transform_matrix[0][2]) + "," + str(transform_matrix[0][3]) +"], [" + str(transform_matrix[1][0]) + "," + str(transform_matrix[1][1]) + "," + str(transform_matrix[1][2]) + "," + str(transform_matrix[1][3]) + "], [" + str(transform_matrix[2][0]) + "," + str(transform_matrix[2][1]) + "," + str(transform_matrix[2][2]) + "," + str(transform_matrix[2][3]) + "], [" + str(transform_matrix[3][0]) + "," + str(transform_matrix[3][1]) + "," + str(transform_matrix[3][2]) + "," + str(transform_matrix[3][3]) + "]])\n" )
'''
frame += 1
#### 3de markers not exported. Maybe coulb useful in the future if api allow to set the 2d tracking position on the frames using markers
'''
l = tde4.getPointList(campg)
for p in l:
if tde4.isPointCalculated3D(campg,p):
name = tde4.getPointName(campg,p)
p3d = tde4.getPointCalcPosition3D(campg,p)
f.write("marker = chunk.addMarker()\n")
f.write("marker.reference.location = PhotoScan.Vector ( (" + str(p3d[0]) + "," + str(p3d[1]) + "," + str(p3d[2]) + "))\n" )
f.write("marker.label = \"" + name + "\"\n")
'''
f.write("chunk.accuracy_cameras = PhotoScan.Vector( (" + tde4.getWidgetValue(req,"accuracy_position") +"," + tde4.getWidgetValue(req,"accuracy_position") + "," + tde4.getWidgetValue(req,"accuracy_position") +") )\n")
f.write("chunk.accuracy_cameras_ypr = PhotoScan.Vector( (" + tde4.getWidgetValue(req,"accuracy_rotation") +"," + tde4.getWidgetValue(req,"accuracy_rotation") + "," + tde4.getWidgetValue(req,"accuracy_rotation") +") )\n")
if tde4.getWidgetValue(req,"match_align") == 1:
f.write("chunk.matchPhotos(accuracy=PhotoScan.Accuracy.HighestAccuracy, preselection=PhotoScan.Preselection.NoPreselection, filter_mask=False, keypoint_limit= " + tde4.getWidgetValue(req,"match_align_keypoint_limit") + ", tiepoint_limit=" + tde4.getWidgetValue(req,"match_align_tiepoint_limit") + " )\n")
f.write("chunk.alignCameras()\n")
if tde4.getWidgetValue(req,"build_dense_cloud") == 1:
f.write("chunk.buildDenseCloud(quality=PhotoScan.Quality.UltraQuality, filter=PhotoScan.FilterMode.NoFiltering ,keep_depth=False, reuse_depth=False)\n")
f.close()
tde4.postQuestionRequester("Export Photoscan...","Project successfully exported.","Ok")
else:
tde4.postQuestionRequester("Export Photoscan...","Error, couldn't open file.","Ok")