Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alicevision/meshroom.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoïc Vital <mugulmotion@gmail.com>2022-09-20 19:26:20 +0300
committerFabien Castan <fabcastan@gmail.com>2022-10-19 11:50:08 +0300
commita574c0fc9b30d1d67ff6addc00afa55a6dade3cc (patch)
tree5bd18f032c3e115861d9ed65cbcffc92583daee8 /meshroom
parentfc5ab540f5a231a2510997d61d65c600bcb9e394 (diff)
use semantic field in file attributes to specify images and store displayed node in 2D viewer to adapt UI
Diffstat (limited to 'meshroom')
-rw-r--r--meshroom/core/desc.py1
-rw-r--r--meshroom/core/node.py4
-rw-r--r--meshroom/nodes/aliceVision/DepthMap.py22
-rw-r--r--meshroom/nodes/aliceVision/DepthMapFilter.py18
-rw-r--r--meshroom/nodes/aliceVision/ImageProcessing.py17
-rw-r--r--meshroom/nodes/aliceVision/Texturing.py15
-rw-r--r--meshroom/ui/qml/Viewer/Viewer2D.qml83
-rw-r--r--meshroom/ui/qml/WorkspaceView.qml8
-rwxr-xr-xmeshroom/ui/qml/main.qml54
9 files changed, 139 insertions, 83 deletions
diff --git a/meshroom/core/desc.py b/meshroom/core/desc.py
index 1810c9d2..6766f729 100644
--- a/meshroom/core/desc.py
+++ b/meshroom/core/desc.py
@@ -489,7 +489,6 @@ class Node(object):
parallelization = None
documentation = ''
category = 'Other'
- outputImageTypes = ['image']
def __init__(self):
pass
diff --git a/meshroom/core/node.py b/meshroom/core/node.py
index 25b05443..372c5384 100644
--- a/meshroom/core/node.py
+++ b/meshroom/core/node.py
@@ -568,9 +568,6 @@ class BaseNode(BaseObject):
def getAttributes(self):
return self._attributes
- def getOutputImageTypes(self):
- return self.nodeDesc.outputImageTypes
-
@Slot(str, result=bool)
def hasAttribute(self, name):
return name in self._attributes.keys()
@@ -1056,7 +1053,6 @@ class BaseNode(BaseObject):
x = Property(float, lambda self: self._position.x, notify=positionChanged)
y = Property(float, lambda self: self._position.y, notify=positionChanged)
attributes = Property(BaseObject, getAttributes, constant=True)
- outputImageTypes = Property(Variant, getOutputImageTypes, constant=True)
internalFolderChanged = Signal()
internalFolder = Property(str, internalFolder.fget, notify=internalFolderChanged)
depthChanged = Signal()
diff --git a/meshroom/nodes/aliceVision/DepthMap.py b/meshroom/nodes/aliceVision/DepthMap.py
index 8bd810e2..53da77f0 100644
--- a/meshroom/nodes/aliceVision/DepthMap.py
+++ b/meshroom/nodes/aliceVision/DepthMap.py
@@ -293,11 +293,27 @@ Use a downscale factor of one (full-resolution) only if the quality of the input
outputs = [
desc.File(
name='output',
- label='Output',
+ label='Output Folder',
description='Output folder for generated depth maps.',
value=desc.Node.internalFolder,
uid=[],
),
+ desc.File(
+ name='depth',
+ label='Depth Maps',
+ description='Generated depth maps.',
+ semantic='image',
+ value=desc.Node.internalFolder + '<VIEW_ID>_depthMap.exr',
+ uid=[],
+ group='', # do not export on the command line
+ ),
+ desc.File(
+ name='sim',
+ label='Sim Maps',
+ description='Generated sim maps.',
+ semantic='image',
+ value=desc.Node.internalFolder + '<VIEW_ID>_simMap.exr',
+ uid=[],
+ group='', # do not export on the command line
+ ),
]
-
- outputImageTypes = ['depth', 'sim']
diff --git a/meshroom/nodes/aliceVision/DepthMapFilter.py b/meshroom/nodes/aliceVision/DepthMapFilter.py
index 5043d074..5280c808 100644
--- a/meshroom/nodes/aliceVision/DepthMapFilter.py
+++ b/meshroom/nodes/aliceVision/DepthMapFilter.py
@@ -128,4 +128,22 @@ This allows to filter unstable points before starting the fusion of all depth ma
value=desc.Node.internalFolder,
uid=[],
),
+ desc.File(
+ name='depth',
+ label='Depth Maps',
+ description='Filtered depth maps.',
+ semantic='image',
+ value=desc.Node.internalFolder + '<VIEW_ID>_depthMap.exr',
+ uid=[],
+ group='', # do not export on the command line
+ ),
+ desc.File(
+ name='sim',
+ label='Sim Maps',
+ description='Filtered sim maps.',
+ semantic='image',
+ value=desc.Node.internalFolder + '<VIEW_ID>_simMap.exr',
+ uid=[],
+ group='', # do not export on the command line
+ ),
]
diff --git a/meshroom/nodes/aliceVision/ImageProcessing.py b/meshroom/nodes/aliceVision/ImageProcessing.py
index e276c365..652ef3b3 100644
--- a/meshroom/nodes/aliceVision/ImageProcessing.py
+++ b/meshroom/nodes/aliceVision/ImageProcessing.py
@@ -338,12 +338,21 @@ Convert or apply filtering to the input images.
value=desc.Node.internalFolder,
uid=[],
),
+ #desc.File(
+ # name='outputImages',
+ # label='Output Images',
+ # description='Output Image Files.',
+ # value= outputImagesValueFunct,
+ # group='', # do not export on the command line
+ # uid=[],
+ #),
desc.File(
name='outputImages',
label='Output Images',
description='Output Image Files.',
- value= outputImagesValueFunct,
- group='', # do not export on the command line
- uid=[],
- ),
+ semantic='image',
+ value=desc.Node.internalFolder + '<VIEW_ID>.exr',
+ group='', # do not export on the command line
+ uid=[]
+ )
]
diff --git a/meshroom/nodes/aliceVision/Texturing.py b/meshroom/nodes/aliceVision/Texturing.py
index 34ed45d4..1f1c9bba 100644
--- a/meshroom/nodes/aliceVision/Texturing.py
+++ b/meshroom/nodes/aliceVision/Texturing.py
@@ -342,14 +342,23 @@ Many cameras are contributing to the low frequencies and only the best ones cont
uid=[],
group='',
),
+ #desc.File(
+ # name='outputTextures',
+ # label='Textures',
+ # description='Output Texture files.',
+ # value= lambda attr: desc.Node.internalFolder + 'texture_*.' + attr.node.colorMapping.colorMappingFileType.value if attr.node.colorMapping.enable.value else '',
+ # uid=[],
+ # group='',
+ # ),
desc.File(
name='outputTextures',
label='Textures',
description='Output Texture files.',
- value= lambda attr: desc.Node.internalFolder + 'texture_*.' + attr.node.colorMapping.colorMappingFileType.value if attr.node.colorMapping.enable.value else '',
+ semantic='image',
+ value=desc.Node.internalFolder+'texture_*.exr',
uid=[],
- group='',
- ),
+ group=''
+ )
]
def upgradeAttributeValues(self, attrValues, fromVersion):
diff --git a/meshroom/ui/qml/Viewer/Viewer2D.qml b/meshroom/ui/qml/Viewer/Viewer2D.qml
index f60e5e26..c181ae73 100644
--- a/meshroom/ui/qml/Viewer/Viewer2D.qml
+++ b/meshroom/ui/qml/Viewer/Viewer2D.qml
@@ -9,6 +9,7 @@ FocusScope {
clip: true
+ property var displayedNode: _reconstruction.cameraInit
property url source
property var metadata
property var viewIn3D
@@ -153,20 +154,66 @@ FocusScope {
imgContainer.y = Math.max((imgLayout.height - imgContainer.image.height * imgContainer.scale)*0.5, 0)
}
- function getImageFile(type) {
- if(!_reconstruction.activeNodes)
- return "";
- var depthMapNode = _reconstruction.activeNodes.get('allDepthMap').node;
- if (type == "image") {
- return root.source;
- } else if (depthMapNode != undefined && _reconstruction.selectedViewId >= 0) {
- return Filepath.stringToUrl(depthMapNode.internalFolder+_reconstruction.selectedViewId+"_"+type+"Map.exr");
+ function getImageFile() {
+ if (outputAttribute.name == "") {
+ return getViewpointPath(_reconstruction.selectedViewId);
+ }
+ return getFileAttributePath(displayedNode, outputAttribute.name, _reconstruction.selectedViewId);
+ }
+
+ function getFileAttributePath(node, attrName, viewId) {
+ // get output attribute with matching name
+ // and parse its value to get the image filepath
+ for (var i = 0; i < node.attributes.count; i++) {
+ var attr = node.attributes.at(i);
+ if (attr.name == attrName) {
+ return Filepath.stringToUrl(String(attr.value).replace("<VIEW_ID>", viewId));
+ }
+ }
+ return "";
+ }
+
+ function getViewpointPath(viewId) {
+ // get viewpoint from cameraInit with matching id
+ // and get its image filepath
+ for (var i = 0; i < _reconstruction.viewpoints.count; i++) {
+ var vp = _reconstruction.viewpoints.at(i);
+ if (vp.childAttribute("viewId").value == viewId) {
+ return Filepath.stringToUrl(vp.childAttribute("path").value);
+ }
}
return "";
}
- function setImageTypes(types) {
- imageType.types = types;
+ function getViewpointMetadata(viewId) {
+ // get viewpoint from cameraInit with matching id
+ // and get its image filepath
+ for (var i = 0; i < _reconstruction.viewpoints.count; i++) {
+ var vp = _reconstruction.viewpoints.at(i);
+ if (vp.childAttribute("viewId").value == viewId) {
+ return vp.childAttribute("metadata").value;
+ }
+ }
+ return "";
+ }
+
+ onDisplayedNodeChanged: {
+ var names = [];
+ for (var i = 0; i < displayedNode.attributes.count; i++) {
+ var attr = displayedNode.attributes.at(i);
+ if (attr.isOutput && attr.desc.semantic == "image") {
+ names.push(attr.name);
+ }
+ }
+ outputAttribute.names = names;
+ }
+
+ Connections {
+ target: _reconstruction
+ onSelectedViewIdChanged: {
+ root.source = getImageFile();
+ root.metadata = getViewpointMetadata(_reconstruction.selectedViewId);
+ }
}
// context menu
@@ -276,7 +323,7 @@ FocusScope {
// Note: It does not work to use previously created component, so we re-create it with setSource.
// floatViewerComp.createObject(floatImageViewerLoader, {
setSource("FloatImage.qml", {
- 'source': Qt.binding(function() { return getImageFile(imageType.type); }),
+ 'source': Qt.binding(function() { return getImageFile(); }),
'gamma': Qt.binding(function() { return hdrImageToolbar.gammaValue; }),
'gain': Qt.binding(function() { return hdrImageToolbar.gainValue; }),
'channelModeString': Qt.binding(function() { return hdrImageToolbar.channelModeValue; }),
@@ -340,7 +387,7 @@ FocusScope {
fillMode: Image.PreserveAspectFit
autoTransform: true
onWidthChanged: if(status==Image.Ready) fit()
- source: getImageFile(imageType.type)
+ source: getImageFile()
onStatusChanged: {
// update cache source when image is loaded
if(status === Image.Ready)
@@ -504,7 +551,7 @@ FocusScope {
font.pointSize: 8
readOnly: true
selectByMouse: true
- text: Filepath.urlToString(getImageFile(imageType.type))
+ text: Filepath.urlToString(getImageFile())
}
// show which depthmap node is active
@@ -994,7 +1041,7 @@ FocusScope {
}
ComboBox {
- id: imageType
+ id: outputAttribute
property var activeNode: root.oiioPluginAvailable ? _reconstruction.activeNodes.get('allDepthMap').node : null
// set min size to 5 characters + one margin for the combobox
clip: true
@@ -1002,10 +1049,10 @@ FocusScope {
Layout.preferredWidth: 6.0 * Qt.application.font.pixelSize
flat: true
- property var types: ["image"]
- property string type: enabled ? types[currentIndex] : types[0]
+ property var names: []
+ property string name: (names.length > 0) ? (enabled ? names[currentIndex] : names[0]) : ""
- model: types
+ model: names
enabled: activeNode
}
@@ -1018,7 +1065,7 @@ FocusScope {
Layout.minimumWidth: 0
onClicked: {
- root.viewIn3D(root.getImageFile("depth"))
+ root.viewIn3D(root.getFileAttributePath(activeNode, "depth", _reconstruction.selectedViewId));
}
}
diff --git a/meshroom/ui/qml/WorkspaceView.qml b/meshroom/ui/qml/WorkspaceView.qml
index ced16fe2..c4582e8f 100644
--- a/meshroom/ui/qml/WorkspaceView.qml
+++ b/meshroom/ui/qml/WorkspaceView.qml
@@ -148,14 +148,6 @@ Item {
viewIn3D: root.load3DMedia
- Connections {
- target: imageGallery
- onCurrentItemChanged: {
- viewer2D.source = imageGallery.currentItemSource
- viewer2D.metadata = imageGallery.currentItemMetadata
- }
- }
-
DropArea {
anchors.fill: parent
keys: ["text/uri-list"]
diff --git a/meshroom/ui/qml/main.qml b/meshroom/ui/qml/main.qml
index bd3977dd..db84ae24 100755
--- a/meshroom/ui/qml/main.qml
+++ b/meshroom/ui/qml/main.qml
@@ -851,11 +851,17 @@ ApplicationWindow {
reconstruction: _reconstruction
readOnly: _reconstruction.computing
- function viewAttribute(attribute, mouse) {
- let viewable = false;
- viewable = workspaceView.viewIn2D(attribute);
- viewable |= workspaceView.viewIn3D(attribute, mouse);
- return viewable;
+ function viewNode(node, mouse) {
+ // 2D viewer
+ viewer2D.displayedNode = node;
+
+ // 3D viewer
+ for(var i=0; i < node.attributes.count; ++i)
+ {
+ var attr = node.attributes.at(i)
+ if(attr.isOutput && workspaceView.viewIn3D(attr, mouse))
+ break;
+ }
}
function viewIn3D(attribute, mouse) {
@@ -867,33 +873,6 @@ ApplicationWindow {
panel3dViewer.viewer3D.solo(attribute);
return loaded;
}
-
- function viewIn2D(attribute) {
- var imageExts = ['.exr', '.jpg', '.tif', '.png'];
- var ext = Filepath.extension(attribute.value);
- if(imageExts.indexOf(ext) == -1)
- {
- return false;
- }
-
- if(attribute.value.includes('*'))
- {
- // For now, the viewer only supports a single image.
- var firstFile = Filepath.globFirst(attribute.value)
- viewer2D.source = Filepath.stringToUrl(firstFile);
- }
- else
- {
- viewer2D.source = Filepath.stringToUrl(attribute.value);
- return true;
- }
-
- return false;
- }
-
- function setImageTypes(types) {
- viewer2D.setImageTypes(types);
- }
}
}
@@ -958,17 +937,8 @@ ApplicationWindow {
nodeTypesModel: _nodeTypes
onNodeDoubleClicked: {
- workspaceView.setImageTypes(node.outputImageTypes);
-
_reconstruction.setActiveNode(node);
-
- let viewable = false;
- for(var i=0; i < node.attributes.count; ++i)
- {
- var attr = node.attributes.at(i)
- if(attr.isOutput && workspaceView.viewAttribute(attr, mouse))
- break;
- }
+ workspaceView.viewNode(node, mouse);
}
onComputeRequest: computeManager.compute(node)
onSubmitRequest: computeManager.submit(node)