Hi,
I am using a python script to reset my model bounding box x and y locations and dimensions, as well as its z-rotation, while keeping the bounding box z extent and center the same. The x and y shift, scaling and rotation work well, but the bounding box seems to change its z-location relative to the model (even though a console output of the box center z value is the same before and after the transformation).
For clarity, I have attached screenshots before and after applying the transformation, showing the unwanted shift in z-location of the bounding box (which transfers the bounding box away from the model, making further processing fail); you can also see the console which shows the region center values before and after the transformation, showing the z value remains the same.
My code is below:
import PhotoScan
import math
bbox_center = [-119.43639088933767, 36.57570587655139] # deg - wgs84
bbox_size = [193.71339323337548, 99.76327818514577] # m
bbox_rot = 180.58462719482992 # deg
doc = PhotoScan.app.document
chunk = doc.chunk
reg = chunk.region
trans = chunk.transform.matrix
print("region center: {}".format(reg.center))
print("region size: {}".format(reg.size))
print("region rot: {}".format(reg.rot))
newregion = PhotoScan.Region()
center_geo = PhotoScan.Vector([bbox_center[0], bbox_center[1], 0.]) # uses existing region height
v_temp = chunk.crs.unproject(center_geo)
v_temp.size = 4
v_temp.w = 1
centerLocal = chunk.transform.matrix.inv() * v_temp
centerLocal.size = 3
newregion.center = PhotoScan.Vector([centerLocal[0], centerLocal[1], reg.center[2]]) # uses existing region height
print("newregion center: {}".format(newregion.center))
# Set region size:
# generate scale factor
rot_untransformed = PhotoScan.Matrix().diag([1, 1, 1, 1])
rot_temp = trans * rot_untransformed
s = math.sqrt(rot_temp[0, 0] ** 2 + rot_temp[0, 1] ** 2 + rot_temp[0, 2] ** 2)
# scale desired size in metres to chunk internal coordinate system
inter_size = PhotoScan.Vector([0, 0, 0])
geo_size = PhotoScan.Vector([bbox_size[0], bbox_size[1], 0]) # uses original chunk region z size
inter_size = geo_size / s
newregion.size = PhotoScan.Vector([inter_size[0], inter_size[1], reg.size[2]])
print("newregion size: {}".format(newregion.size))
# Set region rotation
# build z-axis rotation matrix
SinRotZ = math.sin(math.radians(bbox_rot))
CosRotZ = math.cos(math.radians(bbox_rot))
RotMat = PhotoScan.Matrix([[CosRotZ, -SinRotZ, 0, 0], [SinRotZ, CosRotZ, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
# rotate region bounding box
v = PhotoScan.Vector([0, 0, 0, 1])
v_t = trans * v
v_t.size = 3
m = chunk.crs.localframe(v_t)
m = m * trans
m = RotMat*m
s = math.sqrt(m[0, 0]**2 + m[0, 1]**2 + m[0, 2]**2) # scale factor
R = PhotoScan.Matrix([[m[0, 0], m[0, 1], m[0, 2]], [m[1, 0], m[1, 1], m[1, 2]], [m[2, 0], m[2, 1], m[2, 2]]])
R = R * (1. / s)
newregion.rot = R.t()
print("newregion rot: {}".format(newregion.rot))
# put newregion to chunk
chunk.region = newregion
Any ideas what I'm doing wrong and how to fix are greatly appreciated.
Thanks