-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve command line arguments #632
Changes from 7 commits
a4d7554
231125e
ad9a215
ee2fc63
979ee4b
fa7b458
06543f8
a53940d
ce6dcba
49c5789
9a473ad
ab7b940
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -234,7 +234,15 @@ def fileFeatures(self): | |||||
return Graph.IO.getFeaturesForVersion(self.header.get(Graph.IO.Keys.FileVersion, "0.0")) | ||||||
|
||||||
@Slot(str) | ||||||
def load(self, filepath): | ||||||
def load(self, filepath, setupFileRef=True): | ||||||
""" | ||||||
Load a meshroom graph ".mg" file. | ||||||
|
||||||
Args: | ||||||
filepath: project filepath to load | ||||||
setupFileRef: Setup reference to the project file, like setup cacheDir, keep filepath for save, etc. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
This option allows to disable it, to only load the project file as a template. | ||||||
""" | ||||||
self.clear() | ||||||
with open(filepath) as jsonFile: | ||||||
fileData = json.load(jsonFile) | ||||||
|
@@ -265,8 +273,9 @@ def load(self, filepath): | |||||
# Add node to the graph with raw attributes values | ||||||
self._addNode(n, nodeName) | ||||||
|
||||||
# Update filepath related members | ||||||
self._setFilepath(filepath) | ||||||
if setupFileRef: | ||||||
# Update filepath related members | ||||||
self._setFilepath(filepath) | ||||||
|
||||||
# Create graph edges by resolving attributes expressions | ||||||
self._applyExpr() | ||||||
|
@@ -896,7 +905,7 @@ def toDict(self): | |||||
def asString(self): | ||||||
return str(self.toDict()) | ||||||
|
||||||
def save(self, filepath=None): | ||||||
def save(self, filepath=None, setupFileRef=True): | ||||||
path = filepath or self._filepath | ||||||
if not path: | ||||||
raise ValueError("filepath must be specified for unsaved files.") | ||||||
|
@@ -920,7 +929,7 @@ def save(self, filepath=None): | |||||
with open(path, 'w') as jsonFile: | ||||||
json.dump(data, jsonFile, indent=4) | ||||||
|
||||||
if path != self._filepath: | ||||||
if path != self._filepath and setupFileRef: | ||||||
self._setFilepath(path) | ||||||
|
||||||
def _setFilepath(self, filepath): | ||||||
|
@@ -930,7 +939,9 @@ def _setFilepath(self, filepath): | |||||
Args: | ||||||
filepath: the graph file path | ||||||
""" | ||||||
assert os.path.isfile(filepath) | ||||||
if not os.path.isfile(filepath): | ||||||
self._unsetFilepath() | ||||||
return | ||||||
|
||||||
if self._filepath == filepath: | ||||||
return | ||||||
|
@@ -942,6 +953,12 @@ def _setFilepath(self, filepath): | |||||
self.cacheDir = os.path.join(os.path.abspath(os.path.dirname(filepath)), meshroom.core.cacheFolderName) | ||||||
self.filepathChanged.emit() | ||||||
|
||||||
def _unsetFilepath(self): | ||||||
self._filepath = "" | ||||||
self.name = "" | ||||||
self.cacheDir = meshroom.core.defaultCacheFolder | ||||||
self.filepathChanged.emit() | ||||||
|
||||||
def updateInternals(self, startNodes=None, force=False): | ||||||
nodes, edges = self.dfsOnFinish(startNodes=startNodes) | ||||||
for node in nodes: | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,22 @@ class MeshroomApp(QApplication): | |
""" Meshroom UI Application. """ | ||
def __init__(self, args): | ||
QtArgs = [args[0], '-style', 'fusion'] + args[1:] # force Fusion style by default | ||
|
||
parser = argparse.ArgumentParser(prog=args[0], description='Launch Meshroom UI.', add_help=True) | ||
|
||
parser.add_argument('input', metavar='INPUT', type=str, nargs='?', | ||
help='Meshroom project file (e.g. myProject.mg) or folder with images to reconstruct.') | ||
parser.add_argument('-i', '--import', metavar='IMAGES/FOLDERS', type=str, nargs='*', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't now the arguments a little bit too redundant? |
||
help='Import images or folder with images to reconstruct.') | ||
parser.add_argument('-I', '--importRecursive', metavar='FOLDERS', type=str, nargs='*', | ||
help='Import images to reconstruct from specified folder and sub-folders.') | ||
parser.add_argument('-p', '--project', metavar='MESHROOM_FILE', type=str, required=False, | ||
help='Meshroom project file (e.g. myProject.mg).') | ||
parser.add_argument('-P', '--pipeline', metavar='MESHROOM_FILE', type=str, required=False, | ||
help='Override the default Meshroom pipeline with this external graph.') | ||
|
||
args = parser.parse_args(args[1:]) | ||
|
||
super(MeshroomApp, self).__init__(QtArgs) | ||
|
||
self.setOrganizationName('AliceVision') | ||
|
@@ -105,12 +121,44 @@ def __init__(self, args): | |
# request any potential computation to stop on exit | ||
self.aboutToQuit.connect(r.stopChildThreads) | ||
|
||
parser = argparse.ArgumentParser(prog=args[0], description='Launch Meshroom UI.') | ||
parser.add_argument('--project', metavar='MESHROOM_FILE', type=str, required=False, | ||
help='Meshroom project file (e.g. myProject.mg).') | ||
args = parser.parse_args(args[1:]) | ||
if args.pipeline: | ||
# the pipeline from the command line has the priority | ||
r.setDefaultPipeline(args.pipeline) | ||
else: | ||
# consider the environment variable | ||
defaultPipeline = os.environ.get("MESHROOM_DEFAULT_PIPELINE", "") | ||
if defaultPipeline: | ||
r.setDefaultPipeline(args.pipeline) | ||
|
||
if args.input: | ||
if not os.path.isfile(args.input) and not os.path.isdir(args.input): | ||
raise RuntimeError( | ||
"Meshroom Command Line Error: 'INPUT' argument should be a Meshroom project file (.mg) or a folder with input images.\n" | ||
"Invalid value: '{}'".format(args.input)) | ||
if args.project and not os.path.isfile(args.project): | ||
raise RuntimeError( | ||
"Meshroom Command Line Error: '--project' argument should be a Meshroom project file (.mg).\n" | ||
"Invalid value: '{}'".format(args.project)) | ||
|
||
if args.project and args.input and not os.path.isdir(args.input): | ||
raise RuntimeError("Meshroom Command Line Error: 'INPUT' and '--project' arguments cannot both load a Meshroom project file (.mg).") | ||
|
||
if args.project: | ||
r.loadUrl(QUrl.fromLocalFile(args.project)) | ||
r.load(args.project) | ||
|
||
if args.input: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't At least if And if we give # initialize photogrammetry pipeline
if args.pipeline:
# custom pipeline
graph = meshroom.core.graph.loadGraph(args.pipeline)
cameraInit = getOnlyNodeOfType(graph, 'CameraInit')
# reset graph inputs
cameraInit.viewpoints.resetValue()
cameraInit.intrinsics.resetValue()
# add views and intrinsics (if any) read from args.input
cameraInit.viewpoints.extend(views)
cameraInit.intrinsics.extend(intrinsics)
if not graph.canComputeLeaves:
raise RuntimeError("Graph cannot be computed. Check for compatibility issues.")
if args.output:
publish = getOnlyNodeOfType(graph, 'Publish')
publish.output.value = args.output
else:
# default pipeline
graph = multiview.photogrammetry(inputViewpoints=views, inputIntrinsics=intrinsics, output=args.output)
cameraInit = getOnlyNodeOfType(graph, 'CameraInit')
if images:
views, intrinsics = cameraInit.nodeDesc.buildIntrinsics(cameraInit, images)
cameraInit.viewpoints.value = views
cameraInit.intrinsics.value = intrinsics There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, there is no error for now but that's the usage intention. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is changed and I have also added another argument "--import". |
||
if os.path.isfile(args.input): | ||
# we assume that it is an ".mg" file. | ||
r.load(args.input) | ||
elif os.path.isdir(args.input): | ||
r.importImagesFromFolder(args.input, recursive=False) | ||
|
||
# import is a python keyword, so we have to access the attribute by a string | ||
if getattr(args, "import", None): | ||
r.importImagesFromFolder(getattr(args, "import"), recursive=False) | ||
|
||
if args.importRecursive: | ||
r.importImagesFromFolder(args.importRecursive, recursive=True) | ||
|
||
self.engine.load(os.path.normpath(url)) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about
overrideProjectFile
?