Skip to content

Commit

Permalink
[BoundingBox] refactor automatic bounding box
Browse files Browse the repository at this point in the history
- remove hardcoded nodes information from the code engine
- add "runtime attributes" for more flexibility
  • Loading branch information
almarouk committed Aug 29, 2023
1 parent 2ae0f16 commit 87a8376
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 70 deletions.
11 changes: 8 additions & 3 deletions meshroom/core/desc.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,9 +556,10 @@ class Node(object):
parallelization = None
documentation = ''
category = 'Other'
coreNode = None

def __init__(self):
pass
def __init__(self, coreNode = None):
self.coreNode = coreNode

def upgradeAttributeValues(self, attrValues, fromVersion):
return attrValues
Expand Down Expand Up @@ -599,6 +600,9 @@ class CommandLineNode(Node):
parallelization = None
commandLineRange = ''

def __init__(self, coreNode = None):
super().__init__(coreNode)

def buildCommandLine(self, chunk):

cmdPrefix = ''
Expand Down Expand Up @@ -665,7 +669,8 @@ class AVCommandLineNode(CommandLineNode):
cmdMem = ''
cmdCore = ''

def __init__(self):
def __init__(self, coreNode = None):
super().__init__(coreNode)

if AVCommandLineNode.cgroupParsed is False:

Expand Down
20 changes: 11 additions & 9 deletions meshroom/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from meshroom.core import desc, stats, hashValue, nodeVersion, Version
from meshroom.core.attribute import attributeFactory, ListAttribute, GroupAttribute, Attribute
from meshroom.core.exception import NodeUpgradeError, UnknownNodeTypeError
from meshroom.core.nodes import getNodeClass

def getWritingFilepath(filepath):
return filepath + '.writing.' + str(uuid.uuid4())
Expand Down Expand Up @@ -483,10 +482,6 @@ def __init__(self, nodeType, position=None, parent=None, **kwargs):
self._nodeType = nodeType
self.nodeDesc = None

# instantiate node description if nodeType is valid
if nodeType in meshroom.core.nodesDesc:
self.nodeDesc = meshroom.core.nodesDesc[nodeType]()

self.packageName = self.packageVersion = ""
self._internalFolder = ""

Expand All @@ -500,12 +495,17 @@ def __init__(self, nodeType, position=None, parent=None, **kwargs):
self._position = position or Position()
self._attributes = DictModel(keyAttrName='name', parent=self)
self._internalAttributes = DictModel(keyAttrName='name', parent=self)
self._runtimeAttributes = DictModel(keyAttrName='name', parent=self)
self.attributesPerUid = defaultdict(set)
self._alive = True # for QML side to know if the node can be used or is going to be deleted
self._locked = False
self._duplicates = ListModel(parent=self) # list of nodes with the same uid
self._hasDuplicates = False

# instantiate node description if nodeType is valid
if nodeType in meshroom.core.nodesDesc:
self.nodeDesc = meshroom.core.nodesDesc[nodeType](coreNode=self)

self.globalStatusChanged.connect(self.updateDuplicatesStatusAndLocked)

def __getattr__(self, k):
Expand Down Expand Up @@ -609,6 +609,10 @@ def internalAttribute(self, name):
# The internal attribute itself can be returned directly
return self._internalAttributes.get(name)

@Slot(str, result=Attribute)
def runtimeAttribute(self, name):
return self._runtimeAttributes.get(name)

def setInternalAttributeValues(self, values):
# initialize internal attribute values
for k, v in values.items():
Expand Down Expand Up @@ -1554,8 +1558,7 @@ def upgrade(self):
# store internal attributes that could be used during node upgrade
commonInternalAttributes.append(attrName)

cls = getNodeClass(self.nodeType)
node = cls(self.nodeType, position=self.position)
node = Node(self.nodeType, position=self.position)
# convert attributes from a list of tuples into a dict
attrValues = {key: value for (key, value) in self.inputs.items()}
intAttrValues = {key: value for (key, value) in self.internalInputs.items()}
Expand Down Expand Up @@ -1676,8 +1679,7 @@ def nodeFactory(nodeDict, name=None, template=False, uidConflict=False):
break

if compatibilityIssue is None:
cls = getNodeClass(nodeType)
node = cls(nodeType, position, **inputs)
node = Node(nodeType, position, **inputs)
node.setInternalAttributeValues(internalInputs)
else:
logging.warning("Compatibility issue detected for node '{}': {}".format(name, compatibilityIssue.name))
Expand Down
30 changes: 0 additions & 30 deletions meshroom/core/nodes/MeshingNode.py

This file was deleted.

23 changes: 0 additions & 23 deletions meshroom/core/nodes/__init__.py

This file was deleted.

4 changes: 2 additions & 2 deletions meshroom/nodes/aliceVision/CameraInit.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ class CameraInit(desc.AVCommandLineNode, desc.InitNode):
),
]

def __init__(self):
super(CameraInit, self).__init__()
def __init__(self, coreNode = None):
super(CameraInit, self).__init__(coreNode)

def initialize(self, node, inputs, recursiveInputs):
# Reset graph inputs
Expand Down
27 changes: 26 additions & 1 deletion meshroom/nodes/aliceVision/Meshing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
__version__ = "7.0"

from meshroom.core import desc
from meshroom.common import Slot
from meshroom.core.attribute import attributeFactory
import os
import threading
import psutil
Expand Down Expand Up @@ -533,10 +535,33 @@ class Meshing(desc.AVCommandLineNode):
),
]

def __init__(self, coreNode=None):
super().__init__(coreNode)

attrDesc = desc.BoolParam(
name="automaticBBoxValid",
label="",
description="",
value=False,
uid=[],
group=""
)
self.coreNode._runtimeAttributes.add(attributeFactory(attrDesc, None, False, self.coreNode))
coreNode.globalStatusChanged.connect(self.checkBBox)

def processChunk(self, chunk):
with boundingBoxMonitor(chunk.node):
super(Meshing, self).processChunk(chunk)

@Slot()
def checkBBox(self):
"""Load automatic bounding box if needed."""
if self.coreNode.useBoundingBox.value:
return
self.coreNode.runtimeAttribute('automaticBBoxValid').value = False
with boundingBoxMonitor(self.coreNode, checkOnce=True) as thread:
pass

@contextmanager
def boundingBoxMonitor(node, checkOnce=False):
"""
Expand Down Expand Up @@ -613,7 +638,7 @@ def updateBoundingBox(self) -> bool:
for x in vec.value:
x.value = data[i]
i += 1
self.node.automaticBBoxValid = True
self.node.runtimeAttribute('automaticBBoxValid').value = True
return True

def stopRequest(self):
Expand Down
4 changes: 2 additions & 2 deletions meshroom/ui/qml/Viewer3D/MediaLibrary.qml
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ Entity {
property bool hasBoundingBox: {
if(nodeType === "Meshing" && currentNode.attribute("useBoundingBox")) // Can have a BoundingBox
{
if(currentNode.automaticBBoxValid !== undefined)
return currentNode.attribute("useBoundingBox").value || currentNode.automaticBBoxValid
if(currentNode.runtimeAttribute("automaticBBoxValid") !== undefined)
return currentNode.attribute("useBoundingBox").value || currentNode.runtimeAttribute("automaticBBoxValid").value
return currentNode.attribute("useBoundingBox").value
}
return false
Expand Down

0 comments on commit 87a8376

Please sign in to comment.