Merge pull request #1839 from alicevision/dev/fixQmlWarnings

[ui] Fix all "TypeError" QML warnings
This commit is contained in:
Fabien Castan 2022-12-06 11:38:16 +01:00 committed by GitHub
commit a2f559f48a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 103 additions and 90 deletions

View file

@ -14,7 +14,7 @@ MessageDialog {
// the UIGraph instance
property var uigraph
// alias to underlying compatibilityNodes model
readonly property var nodesModel: uigraph.graph.compatibilityNodes
readonly property var nodesModel: uigraph ? uigraph.graph.compatibilityNodes : undefined
// the total number of compatibility issues
readonly property int issueCount: (nodesModel != undefined) ? nodesModel.count : 0
// the number of CompatibilityNodes that can be upgraded
@ -47,7 +47,10 @@ MessageDialog {
title: "Compatibility issues detected"
text: "This project contains " + issueCount + " node(s) incompatible with the current version of Meshroom."
detailedText: "Project was created with Meshroom " + uigraph.graph.fileReleaseVersion + "."
detailedText: {
let releaseVersion = uigraph ? uigraph.graph.fileReleaseVersion : "0.0"
return "Project was created with Meshroom " + releaseVersion + "."
}
helperText: upgradableCount ?
upgradableCount + " node(s) can be upgraded but this might invalidate already computed data.\n"

View file

@ -441,7 +441,7 @@ Item {
MenuItem {
text: "Submit"
enabled: nodeMenu.canComputeNode && nodeMenu.canSubmitOrCompute > 1
visible: uigraph.canSubmit
visible: uigraph ? uigraph.canSubmit : false
height: visible ? implicitHeight : 0
onTriggered: submitRequest(nodeMenu.currentNode)
}
@ -759,7 +759,7 @@ Item {
flat: true
model: ['Minimum', 'Maximum']
implicitWidth: 80
currentIndex: uigraph.layout.depthMode
currentIndex: uigraph ? uigraph.layout.depthMode : -1
onActivated: {
uigraph.layout.depthMode = currentIndex
}

View file

@ -31,7 +31,7 @@ FocusScope {
selectByMouse: true
selectionColor: activePalette.highlight
color: activePalette.text
text: node.documentation
text: node ? node.documentation : ""
wrapMode: TextEdit.Wrap
}
}

View file

@ -39,7 +39,7 @@ Item {
TextMetrics {
id: nbMetrics
text: root.taskManager.nodes.count
text: root.taskManager ? root.taskManager.nodes.count : "0"
}
TextMetrics {
@ -67,7 +67,7 @@ Item {
anchors.fill: parent
ScrollBar.vertical: ScrollBar {}
model: parent.taskManager.nodes
model: parent.taskManager ? parent.taskManager.nodes : null
spacing: 3
headerPositioning: ListView.OverlayHeader

View file

@ -58,7 +58,7 @@ Item {
}
MenuItem {
text: "Define As Center Image"
property var activeNode: _reconstruction.activeNodes.get("SfMTransform").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("SfMTransform").node : null
enabled: !root.readOnly && _viewpoint.viewId != -1 && _reconstruction && activeNode
onClicked: activeNode.attribute("transformation").value = _viewpoint.viewId.toString()
}

View file

@ -35,7 +35,7 @@ Panel {
QtObject {
id: m
property variant currentCameraInit: _reconstruction.tempCameraInit ? _reconstruction.tempCameraInit : root.cameraInit
property variant currentCameraInit: _reconstruction && _reconstruction.tempCameraInit ? _reconstruction.tempCameraInit : root.cameraInit
property variant viewpoints: currentCameraInit ? currentCameraInit.attribute('viewpoints').value : undefined
property variant intrinsics: currentCameraInit ? currentCameraInit.attribute('intrinsics').value : undefined
property bool readOnly: root.readOnly || displayHDR.checked
@ -144,7 +144,7 @@ Panel {
SensorDBDialog {
id: sensorDBDialog
sensorDatabase: cameraInit ? Filepath.stringToUrl(cameraInit.attribute("sensorDatabase").value) : ""
readOnly: _reconstruction.computing
readOnly: _reconstruction ? _reconstruction.computing : false
onUpdateIntrinsicsRequest: _reconstruction.rebuildIntrinsics(cameraInit)
}
@ -273,11 +273,11 @@ Panel {
spacing: 2
property bool valid: Qt.isQtObject(object) // object can be evaluated to null at some point during creation/deletion
property bool inViews: valid && _reconstruction.sfmReport && _reconstruction.isInViews(object)
property bool inViews: valid && _reconstruction && _reconstruction.sfmReport && _reconstruction.isInViews(object)
// Camera Initialization indicator
IntrinsicsIndicator {
intrinsic: parent.valid ? _reconstruction.getIntrinsic(object) : null
intrinsic: parent.valid && _reconstruction ? _reconstruction.getIntrinsic(object) : null
metadata: imageDelegate.metadata
}
@ -540,7 +540,7 @@ Panel {
RowLayout {
Layout.fillHeight: false
visible: root.cameraInits.count > 1
visible: root.cameraInits ? root.cameraInits.count > 1 : false
Layout.alignment: Qt.AlignHCenter
spacing: 2
@ -560,8 +560,10 @@ Panel {
// display of group indices (real indices still are from
// 0 to cameraInits.count - 1)
var l = [];
for (var i = 1; i <= root.cameraInits.count; i++) {
l.push(i);
if (root.cameraInits) {
for (var i = 1; i <= root.cameraInits.count; i++) {
l.push(i);
}
}
return l;
}
@ -569,13 +571,13 @@ Panel {
currentIndex: root.cameraInitIndex
onActivated: root.changeCurrentIndex(currentIndex)
}
Label { text: "/ " + (root.cameraInits.count) }
Label { text: "/ " + (root.cameraInits ? root.cameraInits.count : "Unknown") }
ToolButton {
text: MaterialIcons.navigate_next
font.family: MaterialIcons.fontFamily
ToolTip.text: "Next Group (Alt+Right)"
ToolTip.visible: hovered
enabled: nodesCB.currentIndex < root.cameraInits.count - 1
enabled: root.cameraInits ? nodesCB.currentIndex < root.cameraInits.count - 1 : false
onClicked: nodesCB.incrementCurrentIndex()
}
}
@ -617,10 +619,10 @@ Panel {
Layout.minimumWidth: childrenRect.width
ToolTip.text: label + " Estimated Cameras"
iconText: MaterialIcons.videocam
label: _reconstruction.nbCameras ? _reconstruction.nbCameras.toString() : "-"
label: _reconstruction && _reconstruction.nbCameras ? _reconstruction.nbCameras.toString() : "-"
padding: 3
enabled: _reconstruction.cameraInit && _reconstruction.nbCameras
enabled: _reconstruction ? _reconstruction.cameraInit && _reconstruction.nbCameras : false
checkable: true
checked: false
@ -646,10 +648,10 @@ Panel {
Layout.minimumWidth: childrenRect.width
ToolTip.text: label + " Non Estimated Cameras"
iconText: MaterialIcons.videocam_off
label: _reconstruction.nbCameras ? ((m.viewpoints ? m.viewpoints.count : 0) - _reconstruction.nbCameras.toString()).toString() : "-"
label: _reconstruction && _reconstruction.nbCameras ? ((m.viewpoints ? m.viewpoints.count : 0) - _reconstruction.nbCameras.toString()).toString() : "-"
padding: 3
enabled: _reconstruction.cameraInit && _reconstruction.nbCameras
enabled: _reconstruction ? _reconstruction.cameraInit && _reconstruction.nbCameras : false
checkable: true
checked: false
@ -704,7 +706,7 @@ Panel {
MaterialToolLabelButton {
id: displayHDR
Layout.minimumWidth: childrenRect.width
property var activeNode: _reconstruction.activeNodes.get("LdrToHdrMerge").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("LdrToHdrMerge").node : null
ToolTip.text: "Visualize HDR images: " + (activeNode ? activeNode.label : "No Node")
iconText: MaterialIcons.filter
label: activeNode ? activeNode.attribute("nbBrackets").value : ""
@ -747,7 +749,7 @@ Panel {
id: imageProcessing
Layout.minimumWidth: childrenRect.width
property var activeNode: _reconstruction.activeNodes.get("ImageProcessing").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("ImageProcessing").node : null
font.pointSize: 15
padding: 0
ToolTip.text: "Preprocessed Images: " + (activeNode ? activeNode.label : "No Node")

View file

@ -13,7 +13,7 @@ Panel {
id: root
property variant reconstruction
readonly property variant liveSfmManager: reconstruction.liveSfmManager
readonly property variant liveSfmManager: reconstruction ? reconstruction.liveSfmManager : null
title: "Live Reconstruction"
icon: Label {
@ -41,7 +41,7 @@ Panel {
width: parent.width
GroupBox {
Layout.fillWidth: true
enabled: !liveSfmManager.running
enabled: liveSfmManager ? !liveSfmManager.running : false
GridLayout {
width: parent.width
@ -59,7 +59,7 @@ Panel {
id: folderPath
Layout.fillWidth: true
selectByMouse: true
text: liveSfmManager.folder
text: liveSfmManager ? liveSfmManager.folder : ""
placeholderText: "Select a Folder"
}
ToolButton {
@ -90,8 +90,8 @@ Panel {
Button {
Layout.alignment: Qt.AlignCenter
text: checked ? "Stop" : "Start"
enabled: liveSfmManager.running || folderPath.text.trim() != ''
checked: liveSfmManager.running
enabled: liveSfmManager ? liveSfmManager.running || folderPath.text.trim() != '' : false
checked: liveSfmManager ? liveSfmManager.running : false
onClicked: {
if(!liveSfmManager.running)
liveSfmManager.start(folderPath.text, minImg_SB.value)

View file

@ -24,7 +24,7 @@ FocusScope {
property alias useLensDistortionViewer: displayLensDistortionViewer.checked
property alias usePanoramaViewer: displayPanoramaViewer.checked
property var activeNodeFisheye: _reconstruction.activeNodes.get("PanoramaInit").node
property var activeNodeFisheye: _reconstruction ? _reconstruction.activeNodes.get("PanoramaInit").node : null
property bool cropFisheye : activeNodeFisheye ? activeNodeFisheye.attribute("useFisheye").value : false
property bool enable8bitViewer: MeshroomApp.default8bitViewerEnabled
@ -202,15 +202,15 @@ FocusScope {
if (useExternal) {
return sourceExternal;
}
if (!displayedNode || outputAttribute.name == "gallery") {
if (_reconstruction && (!displayedNode || outputAttribute.name == "gallery")) {
return getViewpointPath(_reconstruction.selectedViewId);
}
return getFileAttributePath(displayedNode, outputAttribute.name, _reconstruction.selectedViewId);
return getFileAttributePath(displayedNode, outputAttribute.name, _reconstruction ? _reconstruction.selectedViewId : -1);
}
function getMetadata() {
// entry point for getting the image metadata
if (useExternal) {
if (useExternal || !_reconstruction) {
return {};
} else {
return getViewpointMetadata(_reconstruction.selectedViewId);
@ -220,6 +220,8 @@ FocusScope {
function getFileAttributePath(node, attrName, viewId) {
// get output attribute with matching name
// and parse its value to get the image filepath
if (!node)
return "";
for (var i = 0; i < node.attributes.count; i++) {
var attr = node.attributes.at(i);
if (attr.name == attrName) {
@ -429,7 +431,7 @@ FocusScope {
'sfmRequired': Qt.binding(function(){ return displayLensDistortionViewer.checked ? true : false;}),
'surface.msfmData': Qt.binding(function() { return (msfmDataLoader.status === Loader.Ready && msfmDataLoader.item != null && msfmDataLoader.item.status === 2) ? msfmDataLoader.item : null; }),
'canBeHovered': false,
'idView': Qt.binding(function() { return _reconstruction.selectedViewId; }),
'idView': Qt.binding(function() { return (_reconstruction ? _reconstruction.selectedViewId : -1); }),
'cropFisheye': false
})
} else {
@ -521,7 +523,7 @@ FocusScope {
Loader {
id: featuresViewerLoader
active: displayFeatures.checked
property var activeNode: _reconstruction.activeNodes.get("FeatureExtraction").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("FeatureExtraction").node : null
// handle rotation/position based on available metadata
rotation: {
@ -554,7 +556,7 @@ FocusScope {
// note: use a Loader to evaluate if a PanoramaInit node exist and displayFisheyeCircle checked at runtime
Loader {
anchors.centerIn: parent
property var activeNode: _reconstruction.activeNodes.get("PanoramaInit").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("PanoramaInit").node : null
active: (displayFisheyeCircleLoader.checked && activeNode)
// handle rotation/position based on available metadata
@ -602,7 +604,7 @@ FocusScope {
Loader {
id: colorCheckerViewerLoader
anchors.centerIn: parent
property var activeNode: _reconstruction.activeNodes.get("ColorCheckerDetection").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("ColorCheckerDetection").node : null
active: (displayColorCheckerViewerLoader.checked && activeNode)
@ -706,7 +708,7 @@ FocusScope {
id: mfeaturesLoader
property bool isUsed: displayFeatures.checked
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get("FeatureExtraction").node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get("FeatureExtraction").node : null
property bool isComputed: activeNode && activeNode.isComputed
active: false
@ -749,7 +751,7 @@ FocusScope {
}
// For lens distortion viewer: use all nodes creating a sfmData file
var nodeType = displayLensDistortionViewer.checked ? 'sfmData' : 'sfm'
var sfmNode = _reconstruction.activeNodes.get(nodeType).node
var sfmNode = _reconstruction ? _reconstruction.activeNodes.get(nodeType).node : null
if(sfmNode === null){
return null
}
@ -827,7 +829,7 @@ FocusScope {
id: mtracksLoader
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked || displayPanoramaViewer.checked
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('FeatureMatching').node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('FeatureMatching').node : null
property bool isComputed: activeNode && activeNode.isComputed
active: false
@ -921,7 +923,7 @@ FocusScope {
id: ldrHdrCalibrationGraph
anchors.fill: parent
property var activeNode: _reconstruction.activeNodes.get('LdrToHdrCalibration').node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get('LdrToHdrCalibration').node : null
property var isEnabled: displayLdrHdrCalibrationGraph.checked && activeNode && activeNode.isComputed
// active: isEnabled
// Setting "active" from true to false creates a crash on linux with Qt 5.14.2.
@ -995,7 +997,7 @@ FocusScope {
}
MaterialToolButton {
id: displayLensDistortionViewer
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfmData').node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('sfmData').node : null
property bool isComputed: {
if(!activeNode)
return false;
@ -1031,7 +1033,7 @@ FocusScope {
}
MaterialToolButton {
id: displayPanoramaViewer
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('SfMTransform').node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('SfMTransform').node : null
property bool isComputed: {
if(!activeNode)
return false;
@ -1083,7 +1085,7 @@ FocusScope {
}
MaterialToolButton {
id: displayFisheyeCircleLoader
property var activeNode: _reconstruction.activeNodes.get('PanoramaInit').node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get('PanoramaInit').node : null
ToolTip.text: "Display Fisheye Circle: " + (activeNode ? activeNode.label : "No Node")
text: MaterialIcons.vignette
// text: MaterialIcons.panorama_fish_eye
@ -1096,7 +1098,7 @@ FocusScope {
}
MaterialToolButton {
id: displayColorCheckerViewerLoader
property var activeNode: _reconstruction.activeNodes.get('ColorCheckerDetection').node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get('ColorCheckerDetection').node : null
ToolTip.text: "Display Color Checker: " + (activeNode ? activeNode.label : "No Node")
text: MaterialIcons.view_comfy //view_module grid_on gradient view_comfy border_all
font.pointSize: 11
@ -1121,7 +1123,7 @@ FocusScope {
MaterialToolButton {
id: displayLdrHdrCalibrationGraph
property var activeNode: _reconstruction.activeNodes.get("LdrToHdrCalibration").node
property var activeNode: _reconstruction ? _reconstruction.activeNodes.get("LdrToHdrCalibration").node : null
property bool isComputed: activeNode && activeNode.isComputed
ToolTip.text: "Display Camera Response Function: " + (activeNode ? activeNode.label : "No Node")
text: MaterialIcons.timeline
@ -1166,7 +1168,7 @@ FocusScope {
}
MaterialToolButton {
property var activeNode: root.oiioPluginAvailable ? _reconstruction.activeNodes.get('allDepthMap').node : null
property var activeNode: root.oiioPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('allDepthMap').node : null
enabled: activeNode
ToolTip.text: "View Depth Map in 3D (" + (activeNode ? activeNode.label : "No DepthMap Node Selected") + ")"
text: MaterialIcons.input
@ -1180,7 +1182,7 @@ FocusScope {
MaterialToolButton {
id: displaySfmStatsView
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfm').node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('sfm').node : null
font.family: MaterialIcons.fontFamily
text: MaterialIcons.assessment
@ -1205,7 +1207,7 @@ FocusScope {
MaterialToolButton {
id: displaySfmDataGlobalStats
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfm').node : null
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('sfm').node : null
font.family: MaterialIcons.fontFamily
text: MaterialIcons.language

View file

@ -64,7 +64,7 @@ AlembicEntity {
*/
PhongMaterial{
id: mat
ambient: viewId === _reconstruction.selectedViewId ? activePalette.highlight : customColor // "#CCC"
ambient: _reconstruction && viewId === _reconstruction.selectedViewId ? activePalette.highlight : customColor // "#CCC"
diffuse: cameraPicker.containsMouse ? Qt.lighter(activePalette.highlight, 1.2) : ambient
},
ObjectPicker {

View file

@ -112,7 +112,7 @@ FloatingPane {
// Synchronization
MaterialToolButton {
id: syncViewpointCamera
enabled: _reconstruction.sfmReport
enabled: _reconstruction ? _reconstruction.sfmReport : false
text: MaterialIcons.linked_camera
ToolTip.text: "Sync with Image Selection"
checked: enabled && Viewer3DSettings.syncViewpointCamera
@ -200,8 +200,8 @@ FloatingPane {
// add mediaLibrary.count in the binding to ensure 'entity'
// is re-evaluated when mediaLibrary delegates are modified
property bool loading: model.status === SceneLoader.Loading
property bool hovered: model.attribute ? uigraph.hoveredNode === model.attribute.node : containsMouse
property bool isSelectedNode: model.attribute ? uigraph.selectedNode === model.attribute.node : false
property bool hovered: model.attribute ? (uigraph ? uigraph.hoveredNode === model.attribute.node : false) : containsMouse
property bool isSelectedNode: model.attribute ? (uigraph ? uigraph.selectedNode === model.attribute.node : false) : false
onIsSelectedNodeChanged: updateCurrentIndex()

View file

@ -26,7 +26,7 @@ FocusScope {
readonly property vector3d defaultCamUpVector: Qt.vector3d(0.0, 1.0, 0.0)
readonly property vector3d defaultCamViewCenter: Qt.vector3d(0.0, 0.0, 0.0)
readonly property var viewpoint: _reconstruction.selectedViewpoint
readonly property var viewpoint: _reconstruction ? _reconstruction.selectedViewpoint : null
readonly property bool doSyncViewpointCamera: Viewer3DSettings.syncViewpointCamera && (viewpoint && viewpoint.isReconstructed)
// functions

View file

@ -20,7 +20,7 @@ Item {
id: root
property variant reconstruction: _reconstruction
readonly property variant cameraInits: _reconstruction.cameraInits
readonly property variant cameraInits: _reconstruction ? _reconstruction.cameraInits : null
property bool readOnly: false
property alias panel3dViewer: panel3dViewerLoader.item
readonly property Viewer2D viewer2D: viewer2D
@ -50,7 +50,7 @@ Item {
// Load reconstruction's current SfM file
function viewSfM() {
var activeNode = _reconstruction.activeNodes.get('sfm').node;
var activeNode = _reconstruction.activeNodes ? _reconstruction.activeNodes.get('sfm').node : null;
if(!activeNode)
return;
if(panel3dViewerLoader.active) {
@ -75,9 +75,9 @@ Item {
Layout.fillHeight: true
readOnly: root.readOnly
cameraInits: root.cameraInits
cameraInit: reconstruction.cameraInit
tempCameraInit: reconstruction.tempCameraInit
cameraInitIndex: reconstruction.cameraInitIndex
cameraInit: reconstruction ? reconstruction.cameraInit : null
tempCameraInit: reconstruction ? reconstruction.tempCameraInit : null
cameraInitIndex: reconstruction ? reconstruction.cameraInitIndex : -1
onRemoveImageRequest: reconstruction.removeAttribute(attribute)
onFilesDropped: reconstruction.handleFilesDrop(drop, augmentSfm ? null : cameraInit)
}
@ -208,7 +208,7 @@ Item {
// Load reconstructed model
Button {
readonly property var outputAttribute: _reconstruction.texturing ? _reconstruction.texturing.attribute("outputMesh") : null
readonly property var outputAttribute: _reconstruction && _reconstruction.texturing ? _reconstruction.texturing.attribute("outputMesh") : null
readonly property bool outputReady: outputAttribute && _reconstruction.texturing.globalStatus === "SUCCESS"
readonly property int outputMediaIndex: c_viewer3D.library.find(outputAttribute)

View file

@ -24,8 +24,8 @@ ApplicationWindow {
visible: true
title: {
var t = (_reconstruction.graph && _reconstruction.graph.filepath) ? _reconstruction.graph.filepath : "Untitled"
if(!_reconstruction.undoStack.clean)
var t = (_reconstruction && _reconstruction.graph && _reconstruction.graph.filepath) ? _reconstruction.graph.filepath : "Untitled"
if (_reconstruction && !_reconstruction.undoStack.clean)
t += "*"
t += " - " + Qt.application.name + " " + Qt.application.version
return t
@ -73,12 +73,12 @@ ApplicationWindow {
property var _callback: undefined
title: Filepath.basename(_reconstruction.graph.filepath) || "Unsaved Project"
title: (_reconstruction ? Filepath.basename(_reconstruction.graph.filepath) : "") || "Unsaved Project"
preset: "Info"
canCopy: false
text: _reconstruction.graph.filepath ? "Current project has unsaved modifications."
text: _reconstruction && _reconstruction.graph.filepath ? "Current project has unsaved modifications."
: "Current project has not been saved."
helperText: _reconstruction.graph.filepath ? "Would you like to save those changes?"
helperText: _reconstruction && _reconstruction.graph.filepath ? "Would you like to save those changes?"
: "Would you like to save this project?"
standardButtons: Dialog.Save | Dialog.Cancel | Dialog.Discard
@ -165,14 +165,18 @@ ApplicationWindow {
property bool warnIfUnsaved: true
// evaluate if global reconstruction computation can be started
property bool canStartComputation: _reconstruction.viewpoints.count >= 2 // at least 2 images
&& !_reconstruction.computing // computation is not started
&& _reconstruction.graph.canComputeLeaves // graph has no uncomputable nodes
property bool canStartComputation: _reconstruction ?
_reconstruction.viewpoints.count >= 2 // at least 2 images
&& !_reconstruction.computing // computation is not started
&& _reconstruction.graph.canComputeLeaves : // graph has no uncomputable nodes
false
// evaluate if graph computation can be submitted externally
property bool canSubmit: _reconstruction.canSubmit // current setup allows to compute externally
&& canStartComputation // can be computed
&& _reconstruction.graph.filepath // graph is saved on disk
property bool canSubmit: _reconstruction ?
_reconstruction.canSubmit // current setup allows to compute externally
&& canStartComputation // can be computed
&& _reconstruction.graph.filepath : // graph is saved on disk
false
function compute(node, force) {
if(!force && warnIfUnsaved && !_reconstruction.graph.filepath)
@ -276,7 +280,7 @@ ApplicationWindow {
preset: "Warning"
title: "Unsaved Project"
text: "Data will be computed in the default cache folder if project remains unsaved."
detailedText: "Default cache folder: " + _reconstruction.graph.cacheDir
detailedText: "Default cache folder: " + (_reconstruction ? _reconstruction.graph.cacheDir : "unknown")
helperText: "Save project first?"
standardButtons: Dialog.Discard | Dialog.Cancel | Dialog.Save
@ -377,7 +381,7 @@ ApplicationWindow {
// is busy building intrinsics while importing images
id: buildingIntrinsicsDialog
modal: true
visible: _reconstruction.buildingIntrinsics
visible: _reconstruction ? _reconstruction.buildingIntrinsics : false
closePolicy: Popup.NoAutoClose
title: "Initializing Cameras"
icon.text: MaterialIcons.camera
@ -404,19 +408,19 @@ ApplicationWindow {
Action {
id: undoAction
property string tooltip: 'Undo "' +_reconstruction.undoStack.undoText +'"'
property string tooltip: 'Undo "' + (_reconstruction ? _reconstruction.undoStack.undoText : "Unknown") + '"'
text: "Undo"
shortcut: "Ctrl+Z"
enabled: _reconstruction.undoStack.canUndo && _reconstruction.undoStack.isUndoableIndex
enabled: _reconstruction ? _reconstruction.undoStack.canUndo && _reconstruction.undoStack.isUndoableIndex : false
onTriggered: _reconstruction.undoStack.undo()
}
Action {
id: redoAction
property string tooltip: 'Redo "' +_reconstruction.undoStack.redoText +'"'
property string tooltip: 'Redo "' + (_reconstruction ? _reconstruction.undoStack.redoText : "Unknown") + '"'
text: "Redo"
shortcut: "Ctrl+Shift+Z"
enabled: _reconstruction.undoStack.canRedo && !_reconstruction.undoStack.lockedRedo
enabled: _reconstruction ? _reconstruction.undoStack.canRedo && !_reconstruction.undoStack.lockedRedo : false
onTriggered: _reconstruction.undoStack.redo()
}
Action {
@ -424,16 +428,18 @@ ApplicationWindow {
property string tooltip: {
var s = "Copy selected node"
s += (_reconstruction.selectedNodes.count > 1 ? "s (" : " (") + getSelectedNodesName()
s += (_reconstruction && _reconstruction.selectedNodes.count > 1 ? "s (" : " (") + getSelectedNodesName()
s += ") to the clipboard"
return s
}
text: "Copy Node" + (_reconstruction.selectedNodes.count > 1 ? "s " : " ")
enabled: _reconstruction.selectedNodes.count > 0
text: "Copy Node" + (_reconstruction && _reconstruction.selectedNodes.count > 1 ? "s " : " ")
enabled: _reconstruction ? _reconstruction.selectedNodes.count > 0 : false
onTriggered: graphEditor.copyNodes()
function getSelectedNodesName()
{
if (!_reconstruction)
return ""
var nodesName = ""
for (var i = 0; i < _reconstruction.selectedNodes.count; i++)
{
@ -612,7 +618,7 @@ ApplicationWindow {
id: saveAction
text: "Save"
shortcut: "Ctrl+S"
enabled: (_reconstruction.graph && !_reconstruction.graph.filepath) || !_reconstruction.undoStack.clean
enabled: _reconstruction ? (_reconstruction.graph && !_reconstruction.graph.filepath) || !_reconstruction.undoStack.clean : false
onTriggered: {
if(_reconstruction.graph.filepath) {
_reconstruction.save()
@ -742,7 +748,7 @@ ApplicationWindow {
TextField {
readOnly: true
selectByMouse: true
text: _reconstruction.graph.cacheDir
text: _reconstruction ? _reconstruction.graph.cacheDir : "Unknown"
color: Qt.darker(palette.text, 1.2)
background: Item {}
}
@ -809,12 +815,12 @@ ApplicationWindow {
}
Button {
text: "Stop"
enabled: _reconstruction.computingLocally
enabled: _reconstruction ? _reconstruction.computingLocally : false
onClicked: _reconstruction.stopExecution()
}
Item { width: 20; height: 1 }
Button {
visible: _reconstruction.canSubmit
visible: _reconstruction ? _reconstruction.canSubmit : false
text: "Submit"
onClicked: computeManager.submit(null)
}
@ -839,7 +845,7 @@ ApplicationWindow {
id: chunksListView
Layout.fillWidth: true
height: 6
model: _reconstruction.sortedDFSChunks
model: _reconstruction ? _reconstruction.sortedDFSChunks : null
}
WorkspaceView {
@ -848,7 +854,7 @@ ApplicationWindow {
Layout.fillHeight: true
Layout.minimumHeight: 50
reconstruction: _reconstruction
readOnly: _reconstruction.computing
readOnly: _reconstruction ? _reconstruction.computing : false
function viewNode(node, mouse) {
// 2D viewer
@ -899,7 +905,7 @@ ApplicationWindow {
updatingStatus = false
}
property bool updatingStatus: false
enabled: !updatingStatus && !_reconstruction.computingLocally
enabled: !updatingStatus && (_reconstruction ? !_reconstruction.computingLocally : false)
}
MaterialToolButton {
text: MaterialIcons.more_vert
@ -914,7 +920,7 @@ ApplicationWindow {
x: -width + parent.width
MenuItem {
text: "Clear Pending Status"
enabled: !_reconstruction.computingLocally
enabled: _reconstruction ? !_reconstruction.computingLocally : false
onTriggered: _reconstruction.graph.clearSubmittedNodes()
}
MenuItem {
@ -948,7 +954,7 @@ ApplicationWindow {
visible: graphEditorPanel.currentTab === 1
uigraph: _reconstruction
taskManager: _reconstruction.taskManager
taskManager: _reconstruction ? _reconstruction.taskManager : null
anchors.fill: parent
}
@ -958,8 +964,8 @@ ApplicationWindow {
NodeEditor {
id: nodeEditor
width: Math.round(parent.width * 0.3)
node: _reconstruction.selectedNode
property bool computing: _reconstruction.computing
node: _reconstruction ? _reconstruction.selectedNode : null
property bool computing: _reconstruction ? _reconstruction.computing : false
// Make NodeEditor readOnly when computing
readOnly: node ? node.locked : false