mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-29 02:08:08 +02:00
125 lines
4 KiB
Python
Executable file
125 lines
4 KiB
Python
Executable file
import os
|
|
from threading import Thread
|
|
|
|
from PySide2.QtCore import QObject, Slot, Property, Signal, QJsonValue, QUrl
|
|
|
|
from meshroom import multiview
|
|
from meshroom.core import graph, defaultCacheFolder, cacheFolderName
|
|
from meshroom.ui import commands
|
|
|
|
|
|
class Reconstruction(QObject):
|
|
|
|
def __init__(self, graphFilepath="", parent=None):
|
|
super(Reconstruction, self).__init__(parent)
|
|
self._graph = None
|
|
self._undoStack = commands.UndoStack(self)
|
|
self._computeThread = Thread()
|
|
self._filepath = graphFilepath
|
|
if self._filepath:
|
|
self.load(self._filepath)
|
|
else:
|
|
self.new()
|
|
|
|
@Slot()
|
|
def new(self):
|
|
self.clear()
|
|
self._graph = multiview.photogrammetryPipeline()
|
|
self._graph.cacheDir = defaultCacheFolder
|
|
self.graphChanged.emit()
|
|
|
|
def clear(self):
|
|
if self._graph:
|
|
self._graph.deleteLater()
|
|
self._graph = None
|
|
self.setFilepath("")
|
|
self._undoStack.clear()
|
|
|
|
def setFilepath(self, path):
|
|
if self._filepath == path:
|
|
return
|
|
self._filepath = path
|
|
self.filepathChanged.emit()
|
|
|
|
@Slot(str)
|
|
def addNode(self, nodeType):
|
|
self._undoStack.tryAndPush(commands.AddNodeCommand(self._graph, nodeType))
|
|
|
|
@Slot(graph.Node)
|
|
def removeNode(self, node):
|
|
self._undoStack.tryAndPush(commands.RemoveNodeCommand(self._graph, node))
|
|
|
|
@Slot(graph.Attribute, graph.Attribute)
|
|
def addEdge(self, src, dst):
|
|
self._undoStack.tryAndPush(commands.AddEdgeCommand(self._graph, src, dst))
|
|
|
|
@Slot(graph.Edge)
|
|
def removeEdge(self, edge):
|
|
self._undoStack.tryAndPush(commands.RemoveEdgeCommand(self._graph, edge))
|
|
|
|
@Slot(graph.Attribute, "QVariant")
|
|
def setAttribute(self, attribute, value):
|
|
self._undoStack.tryAndPush(commands.SetAttributeCommand(self._graph, attribute, value))
|
|
|
|
@Slot(graph.Attribute, QJsonValue)
|
|
def appendAttribute(self, attribute, value):
|
|
if value.isArray():
|
|
pyValue = value.toArray().toVariantList()
|
|
else:
|
|
pyValue = None if value.isNull() else value.toObject()
|
|
self._undoStack.tryAndPush(commands.ListAttributeAppendCommand(self._graph, attribute, pyValue))
|
|
|
|
@Slot(graph.Attribute)
|
|
def removeAttribute(self, attribute):
|
|
self._undoStack.tryAndPush(commands.ListAttributeRemoveCommand(self._graph, attribute))
|
|
|
|
def load(self, filepath):
|
|
self.clear()
|
|
self._graph = graph.Graph("")
|
|
self._graph.load(filepath)
|
|
self.setFilepath(filepath)
|
|
self.graphChanged.emit()
|
|
|
|
@Slot(QUrl)
|
|
def loadUrl(self, url):
|
|
self.load(url.toLocalFile())
|
|
|
|
@Slot(QUrl)
|
|
def saveAs(self, url):
|
|
self.setFilepath(url.toLocalFile())
|
|
self.save()
|
|
|
|
@Slot()
|
|
def save(self):
|
|
self._graph.save(self._filepath)
|
|
self._graph.cacheDir = os.path.join(os.path.dirname(self._filepath), cacheFolderName)
|
|
self._undoStack.setClean()
|
|
|
|
@Slot(graph.Node)
|
|
def execute(self, node=None):
|
|
if self.computing:
|
|
return
|
|
nodes = [node] if node else self._graph.getLeaves()
|
|
self._computeThread = Thread(target=self._execute, args=(nodes,))
|
|
self._computeThread.start()
|
|
|
|
def _execute(self, nodes):
|
|
self.computingChanged.emit()
|
|
graph.execute(self._graph, nodes)
|
|
self.computingChanged.emit()
|
|
|
|
@Slot()
|
|
def stopExecution(self):
|
|
if not self.computing:
|
|
return
|
|
self._graph.stopExecution()
|
|
self._computeThread.join()
|
|
self.computingChanged.emit()
|
|
|
|
undoStack = Property(QObject, lambda self: self._undoStack, constant=True)
|
|
graphChanged = Signal()
|
|
graph = Property(graph.Graph, lambda self: self._graph, notify=graphChanged)
|
|
computingChanged = Signal()
|
|
computing = Property(bool, lambda self: self._computeThread.is_alive(), notify=computingChanged)
|
|
filepathChanged = Signal()
|
|
filepath = Property(str, lambda self: self._filepath, notify=filepathChanged)
|