Skip to content
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

Ability to load depth maps into 2D and 3D Viewers within meshroom #769

Merged
merged 15 commits into from
Jan 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions meshroom/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ def loadPlugins(folder, packageName, classType):
errors.append(' * {}: {}'.format(pluginName, str(e)))

if errors:
logging.warning('== The following plugins could not be loaded ==\n'
'{}\n'
.format('\n'.join(errors)))
logging.warning('== The following "{package}" plugins could not be loaded ==\n'
'{errorMsg}\n'
.format(package=packageName, errorMsg='\n'.join(errors)))
return pluginTypes


Expand Down
2 changes: 1 addition & 1 deletion meshroom/ui/qml/GraphEditor/CompatibilityManager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ MessageDialog {
// alias to underlying compatibilityNodes model
readonly property var nodesModel: uigraph.graph.compatibilityNodes
// the total number of compatibility issues
readonly property int issueCount: nodesModel.count
readonly property int issueCount: (nodesModel != undefined) ? nodesModel.count : 0
// the number of CompatibilityNodes that can be upgraded
readonly property int upgradableCount: {
var count = 0
Expand Down
73 changes: 62 additions & 11 deletions meshroom/ui/qml/Viewer/Viewer2D.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import MaterialIcons 2.2

import Controls 1.0

FocusScope {
id: root

clip: true

property url source
property var metadata
property var viewIn3D

function clear()
{
Expand All @@ -35,6 +36,15 @@ FocusScope {
image.y = Math.max((root.height-image.height*image.scale)*0.5, 0)
}

function getImageFile(type) {
if (type == "image") {
return root.source;
} else if (_reconstruction.depthMap != undefined && _reconstruction.selectedViewId >= 0) {
return Filepath.stringToUrl(_reconstruction.depthMap.internalFolder+_reconstruction.selectedViewId+"_"+type+"Map.exr");
}
return "";
}

// context menu
property Component contextMenu: Menu {
MenuItem {
Expand All @@ -56,7 +66,7 @@ FocusScope {
fillMode: Image.PreserveAspectFit
autoTransform: true
onWidthChanged: if(status==Image.Ready) fit()
source: root.source
source: getImageFile(imageType.type)
onStatusChanged: {
// update cache source when image is loaded
if(status === Image.Ready)
Expand Down Expand Up @@ -152,15 +162,31 @@ FocusScope {
width: parent.width
radius: 0
padding: 4
// selectable filepath to source image
TextField {
width: parent.width
padding: 0
background: Item {}
font.pointSize: 8
readOnly: true
selectByMouse: true
text: Filepath.urlToString(source)

RowLayout {
anchors.fill: parent
// selectable filepath to source image
TextField {
padding: 0
background: Item {}
horizontalAlignment: TextInput.AlignLeft
Layout.fillWidth: true
font.pointSize: 8
readOnly: true
selectByMouse: true
text: Filepath.urlToString(image.source)
}
// show which depthmap node is active
Label {
id: depthMapNodeName
visible: (_reconstruction.depthMap != undefined) && (imageType.type != "image")
text: (_reconstruction.depthMap != undefined ? _reconstruction.depthMap.label : "")
font.pointSize: 8

horizontalAlignment: TextInput.AlignLeft
Layout.fillWidth: false
Layout.preferredWidth: contentWidth
}
}
}

Expand Down Expand Up @@ -227,6 +253,31 @@ FocusScope {
}
}

ComboBox {
id: imageType
// set min size to 5 characters + one margin for the combobox
Layout.minimumWidth: 6.0 * Qt.application.font.pixelSize
Layout.preferredWidth: Layout.minimumWidth
flat: true

property var types: ["image", "depth", "sim"]
property string type: types[currentIndex]

model: types
enabled: _reconstruction.depthMap != undefined
}

MaterialToolButton {
font.pointSize: 11
enabled: _reconstruction.depthMap != undefined
ToolTip.text: "View Depth Map in 3D (" + (_reconstruction.depthMap != undefined ? _reconstruction.depthMap.label : "No DepthMap Node Selected") + ")"
text: MaterialIcons.input

onClicked: {
root.viewIn3D(root.getImageFile("depth"))
}
}

ToolButton {
id: metadataCB
padding: 3
Expand Down
4 changes: 3 additions & 1 deletion meshroom/ui/qml/WorkspaceView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,13 @@ Item {
title: "Image Viewer"
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 40
Layout.minimumWidth: 280
Viewer2D {
id: viewer2D
anchors.fill: parent

viewIn3D: root.load3DMedia

Connections {
target: imageGallery
onCurrentItemChanged: {
Expand Down
16 changes: 16 additions & 0 deletions meshroom/ui/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ def __init__(self, defaultPipeline='', parent=None):
# - Prepare Dense Scene (undistorted images)
self._prepareDenseScene = None

# - Depth Map
self._depthMap = None
self.cameraInitChanged.connect(self.updateDepthMapNode)

# - Texturing
self._texturing = None

Expand Down Expand Up @@ -441,6 +445,7 @@ def onGraphChanged(self):
self.featureExtraction = None
self.sfm = None
self.prepareDenseScene = None
self.depthMap = None
self.texturing = None
self.updateCameraInits()
if not self._graph:
Expand Down Expand Up @@ -482,6 +487,10 @@ def updateFeatureExtraction(self):
""" Set the current FeatureExtraction node based on the current CameraInit node. """
self.featureExtraction = self.lastNodeOfType('FeatureExtraction', self.cameraInit) if self.cameraInit else None

def updateDepthMapNode(self):
""" Set the current FeatureExtraction node based on the current CameraInit node. """
self.depthMap = self.lastNodeOfType('DepthMapFilter', self.cameraInit) if self.cameraInit else None

def lastSfmNode(self):
""" Retrieve the last SfM node from the initial CameraInit node. """
return self.lastNodeOfType("StructureFromMotion", self._cameraInit, Status.SUCCESS)
Expand Down Expand Up @@ -787,6 +796,8 @@ def setActiveNodeOfType(self, node):
self.cameraInit = node
elif node.nodeType == "PrepareDenseScene":
self.prepareDenseScene = node
elif node.nodeType in ("DepthMap", "DepthMapFilter"):
self.depthMap = node

def updateSfMResults(self):
"""
Expand Down Expand Up @@ -947,8 +958,13 @@ def getPoseRT(self, viewpoint):
# convenient property for QML binding re-evaluation when sfm report changes
sfmReport = Property(bool, lambda self: len(self._poses) > 0, notify=sfmReportChanged)
sfmAugmented = Signal(Node, Node)

prepareDenseSceneChanged = Signal()
prepareDenseScene = makeProperty(QObject, "_prepareDenseScene", notify=prepareDenseSceneChanged, resetOnDestroy=True)

depthMapChanged = Signal()
depthMap = makeProperty(QObject, "_depthMap", depthMapChanged, resetOnDestroy=True)

texturingChanged = Signal()
texturing = makeProperty(QObject, "_texturing", notify=texturingChanged)

Expand Down