Hello Patrick,
Currently mesh export doesn't take into consideration the bounding box (as dense cloud export does), so I can suggest to adjust the box prior to the mesh generation procedure.
In principle, using the Python scripting it is possible to remove all the polygons that are outside the box, but the edges of the model wouldn't be straight then.
You can check the following script:
#compatibility PhotoScan Pro 1.3.4
import PhotoScan
from PySide2 import QtCore, QtGui, QtWidgets
from multiprocessing.dummy import Pool as ThreadPool ##
def checkFaceTask(face):
global vertices
face_vertices = [vertices[v] for v in face.vertices]
checkFace(face, face_vertices)
class progressDialog(QtWidgets.QDialog):
def __init__(self, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Crop mesh by region")
self.btnQuit = QtWidgets.QPushButton("Quit")
self.btnQuit.setFixedSize(100,50)
self.btnP1 = QtWidgets.QPushButton("Start")
self.btnP1.setFixedSize(100,50)
self.pBar = QtWidgets.QProgressBar()
self.pBar.setTextVisible(False)
self.pBar.setFixedSize(100, 50)
layout = QtWidgets.QGridLayout()
layout.addWidget(self.pBar, 0, 0)
layout.addWidget(self.btnP1, 0, 1)
layout.addWidget(self.btnQuit, 0, 2)
self.setLayout(layout)
self.move(500, 400)
proc_markers = lambda : self.process()
QtCore.QObject.connect(self.btnP1, QtCore.SIGNAL("clicked()"), proc_markers)
QtCore.QObject.connect(self.btnQuit, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("reject()"))
self.exec()
def isReady(self):
for task in self.tasks:
if (not task.done):
return False
return True
def onReady(self, result):
print("on ready")
self.pBar.setRange(0,1)
self.btnP1.setDisabled(False)
self.btnQuit.setDisabled(False)
app.processEvents()
PhotoScan.app.update()
print("Script finished.")
#self.close()
def process(self):
global doc, app
global region, vertices
chunk = doc.chunk
region = chunk.region
print("\nScript started...")
self.btnP1.setDisabled(True)
self.btnQuit.setDisabled(True)
self.pBar.setRange(0,0)
app.processEvents()
for i in range(len(chunk.frames)):
chunk.frame = i
frame = chunk.frames[i]
if not frame.model:
continue
vertices = frame.model.vertices
result = ThreadPool().map_async(checkFaceTask, frame.model.faces, callback = self.onReady)
app.processEvents()
frame.model.removeSelection()
app.processEvents()
def checkFace(face, face_vertices):
global region
R = region.rot #Bounding box rotation matrix
C = region.center #Bounding box center vector
size = region.size
remove_vertices = 0
for vertex in face_vertices:
v = vertex.coord
v.size = 3
v_c = v - C
v_r = R.t() * v_c
if abs(v_r.x) > abs(size.x / 2.):
remove_vertices += 1
elif abs(v_r.y) > abs(size.y / 2.):
remove_vertices += 1
elif abs(v_r.z) > abs(size.z / 2.):
remove_vertices += 1
else:
continue
if remove_vertices == 3:
face.selected = True
def main():
global doc
doc =PhotoScan.app.document
global app
app = QtWidgets.QApplication.instance()
parent = app.activeWindow()
dlg = progressDialog(parent)
PhotoScan.app.addMenuItem("Custom menu/Crop mesh by bounding box", main)