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 #657

Closed
wants to merge 76 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
44779f6
Bugfix for MESHROOM_SUBMITTERS_PATH env variable
mike1158 Aug 26, 2019
bd88d16
[nodes][aliceVision] New node for hdri panorama stitching
ToukL Aug 8, 2019
7fc3d50
[nodes] New GlobalSfM node
fabiencastan Sep 16, 2019
0cdb193
[nodes] New Panorama estimation node
fabiencastan Sep 16, 2019
fad4d53
[nodes] split Panorama into PanoramaEstimation and PanoramaStitching
fabiencastan Sep 18, 2019
36b591f
[nodes] PanoramaStitching: add a new debug param
fabiencastan Sep 18, 2019
e7022f0
[nodes] PanoramaEstimation: declare a param as "advanced"
fabiencastan Sep 18, 2019
2862458
[nodes] PanoramaStitching: add a new debug option
fabiencastan Sep 18, 2019
ade9360
[ui] WorkspaceView: open images in the 2D Viewer from the Graph/NodeE…
fabiencastan Sep 18, 2019
b87432f
[nodes] Panorama: new param "refine"
fabiencastan Sep 18, 2019
38d27c9
[nodes] new debug node: ExportMatches
fabiencastan Sep 18, 2019
378b142
Merge pull request #5 from alicevision/develop
ChemicalXandco Sep 19, 2019
704be1e
[ui] Reconstruction: add 'depthMap' member
ChemicalXandco Sep 24, 2019
f118bb9
add ComboBox to select depth map file
ChemicalXandco Sep 24, 2019
ef4b350
add button on 2D Viewer to view depth maps in the 3D Viewer
ChemicalXandco Sep 25, 2019
b8a13d1
Merge branch 'pr/6' into view_depthmaps2
ChemicalXandco Sep 26, 2019
ee6772b
adding a node for rotating head xml
servantftechnicolor Oct 1, 2019
77b867c
restart stitching
servantftechnicolor Oct 15, 2019
e97676f
Control panorama width
servantftechnicolor Oct 24, 2019
9d78c7b
Make a compatible LDRToHDR node
servantftechnicolor Oct 24, 2019
54a57a7
[nodes] LDR2HDR: resize dynamic node size based on groupSize param
fabiencastan Oct 25, 2019
ff9b0e6
Merge branch 'develop' of https://github.com/alicevision/meshroom int…
fabiencastan Nov 1, 2019
a85730a
Merge branch 'develop' of https://github.com/alicevision/meshroom int…
fabiencastan Nov 1, 2019
07f564d
[bin] meshroom: option to choose HDRI pipeline
fabiencastan Nov 3, 2019
f03b52e
[multiview] setup xml files to Panorama node, create KeyframeSelectio…
fabiencastan Nov 4, 2019
00e9067
Adding node for camera downscale
servantftechnicolor Nov 8, 2019
45efa8b
[nodes] LDRToHDR: expose more options
fabiencastan Nov 12, 2019
a4f1d84
Merge branch 'dev_hdriStitching' of https://github.com/alicevision/Me…
fabiencastan Nov 12, 2019
8b34d08
Splitting compositing and warping
servantftechnicolor Nov 13, 2019
6730dd3
add option for multiband
servantftechnicolor Nov 25, 2019
d72dd03
[hdri] update default hdri pipeline
fabiencastan Nov 26, 2019
d94dd9e
use getImageFile function to set image source
ChemicalXandco Dec 6, 2019
7eff5fb
[multiview] update hdri pipeline with PanoramaWarping/Compositing
fabiencastan Dec 9, 2019
d21079e
[nodes] ldr2hdr: add laguerre, refine exposures and calibration downs…
fabiencastan Dec 9, 2019
eeff5c2
add option to bypass HDR
servantftechnicolor Dec 11, 2019
d29b48e
add rotation offsets
servantftechnicolor Dec 11, 2019
1e7c201
[hdri] update default values for hdri pipeline
fabiencastan Dec 11, 2019
d92e761
[nodes] LDRToHDR: add highlight params
fabiencastan Dec 12, 2019
a0ba44f
[core] desc.Node: add update/postUpdate hooks
yann-lty Dec 13, 2019
0b4d2c8
[core] desc.Node: allow usage of DynamicNodeSize on output attributes
yann-lty Dec 13, 2019
97e18e0
[ui] Node: only display File attributes as Node attribute pins
yann-lty Dec 13, 2019
82f8429
Merge pull request #733 from alicevision/dev/invalidationHooks
fabiencastan Dec 13, 2019
a1c9802
[hdri] workaround for HDRI pipeline on tractor
fabiencastan Dec 13, 2019
9b1962f
[hdri] update default values for FeatureExtraction and LDRToHDR
fabiencastan Dec 13, 2019
180a256
[bin] meshroom_photogrammetry: add hdri pipeline option
fabiencastan Dec 13, 2019
b3653aa
[bin] meshroom_photogrammetry: add submit on renderfarm
fabiencastan Dec 13, 2019
ec94a21
[nodes] LDRToHDR: rename param to nbBrackets
fabiencastan Dec 13, 2019
7d70da2
[nodes] LDRToHDR: particular case for nbBrackets=0
fabiencastan Dec 13, 2019
af98984
Merge branch 'develop' of https://github.com/alicevision/meshroom int…
fabiencastan Dec 13, 2019
7e634ea
Add a selector for compositer type
servantftechnicolor Dec 16, 2019
18f2161
[ui] reconstruction: avoid problems on empty metadata
fabiencastan Dec 16, 2019
cbb176d
[nodes] LDRToHDR: add automatic detection of the number of brackets
fabiencastan Dec 16, 2019
e0f4fcb
[nodes] Panorama: minor fix to compositerType default value
fabiencastan Dec 16, 2019
9775924
[bin] photogrammetry: reduce the number of updates with "GraphModific…
fabiencastan Dec 16, 2019
69a1f15
[nodes] CameraInit: remove subprocess wait (communicate is enough)
fabiencastan Dec 16, 2019
be0fb57
[ui] set AA_EnableHighDpiScaling earlier to fix qt warnings
fabiencastan Dec 18, 2019
25127bb
[nodes] LDRToHDR: declare cpu/ram usages
fabiencastan Dec 18, 2019
ff96004
Merge pull request #610 from mike1158/develop
fabiencastan Jan 3, 2020
bfc901a
use Filepath.stringToUrl instead of "file:///"+
ChemicalXandco Jan 4, 2020
44901f0
Merge pull request #639 from alicevision/dev_hdriStitching
fabiencastan Jan 14, 2020
b214584
[Texturing] add options for retopoMesh & reorganise options
cvere Aug 2, 2019
35258ac
[nodes] Texturing: rename subdivision parameters
fabiencastan Jan 6, 2020
1814a34
[nodes] Texturing: simplify subdivision parameters
fabiencastan Jan 15, 2020
30f902b
[nodes] Texturing: correctEV param is now visible
fabiencastan Jan 15, 2020
2beb349
Merge pull request #571 from alicevision/dev/texturing_retopomesh
fabiencastan Jan 15, 2020
2431b53
[ui] fix import of images from command line
fabiencastan Jan 15, 2020
a0d6d23
[ui] add option to save the new project file from the command line
fabiencastan Jan 15, 2020
c82084a
[ui] command line: add support for filepath expressions in input
fabiencastan Jan 17, 2020
b244e2e
[ui] add verbose option
fabiencastan Jan 17, 2020
7b3ae2f
Merge pull request #759 from alicevision/dev/commandline
fabiencastan Jan 20, 2020
e6e3a78
Merge branch 'view_depthmaps2' of https://github.com/ChemicalXandco/m…
fabiencastan Jan 23, 2020
64befd2
[ui] viewer: move depthmap to 3D to the right and remove "Map" from c…
fabiencastan Jan 24, 2020
dfdd281
[ui] reset depthmap node when camerainit change
fabiencastan Jan 24, 2020
6210a71
[ui] minor qml warning fix
fabiencastan Jan 24, 2020
415cf50
[ui] Viewer: use label for DepthMap node instead of name
fabiencastan Jan 24, 2020
e7e2c5a
fix description of updateDepthMapNode function
ChemicalXandco Jan 24, 2020
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
146 changes: 82 additions & 64 deletions bin/meshroom_photogrammetry
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ meshroom.setupEnvironment()
import meshroom.core.graph
from meshroom import multiview

parser = argparse.ArgumentParser(description='Launch the full photogrammetry pipeline.')
parser = argparse.ArgumentParser(description='Launch the full photogrammetry or HDRI pipeline.')
parser.add_argument('-i', '--input', metavar='SFM/FOLDERS/IMAGES', type=str, nargs='*',
default=[],
help='Input folder containing images or folders of images or file (.sfm or .json) '
Expand All @@ -19,9 +19,8 @@ parser.add_argument('-I', '--inputRecursive', metavar='FOLDERS/IMAGES', type=str
default=[],
help='Input folders containing all images recursively.')

parser.add_argument('-p', '--pipeline', metavar='MESHROOM_FILE', type=str, required=False,
help='Meshroom file containing a pre-configured photogrammetry pipeline to run on input images. '
'If not set, the default photogrammetry pipeline will be used. '
parser.add_argument('-p', '--pipeline', metavar='photogrammetry/hdri/MG_FILE', type=str, default='photogrammetry',
help='"photogrammetry" pipeline, "hdri" pipeline or a Meshroom file containing a custom pipeline to run on input images. '
'Requirements: the graph must contain one CameraInit node, '
'and one Publish node if --output is set.')

Expand Down Expand Up @@ -60,6 +59,13 @@ parser.add_argument('--forceStatus', help='Force computation if status is RUNNIN
parser.add_argument('--forceCompute', help='Compute in all cases even if already computed.',
action='store_true')

parser.add_argument('--submit', help='Submit on renderfarm instead of local computation.',
action='store_true')
parser.add_argument('--submitter',
type=str,
default='SimpleFarm',
help='Execute job with a specific submitter.')

args = parser.parse_args()


Expand All @@ -78,7 +84,7 @@ if not args.input and not args.inputRecursive:

views, intrinsics = [], []
# Build image files list from inputImages arguments
images = []
filesByType = multiview.FilesByType()

hasSearchedForImages = False

Expand All @@ -88,21 +94,32 @@ if args.input:
from meshroom.nodes.aliceVision.CameraInit import readSfMData
views, intrinsics = readSfMData(args.input[0])
else:
images += multiview.findImageFiles(args.input, recursive=False)
filesByType.extend(multiview.findFilesByTypeInFolder(args.input, recursive=False))
hasSearchedForImages = True

if args.inputRecursive:
images += multiview.findImageFiles(args.inputRecursive, recursive=True)
filesByType.extend(multiview.findFilesByTypeInFolder(args.inputRecursive, recursive=True))
hasSearchedForImages = True

if hasSearchedForImages and not images:
if hasSearchedForImages and not filesByType.images:
print("No image found")
exit(-1)

# initialize photogrammetry pipeline
if args.pipeline:
# custom pipeline
graph = meshroom.core.graph.loadGraph(args.pipeline)
graph = multiview.Graph(name=args.pipeline)

with multiview.GraphModification(graph):
# initialize photogrammetry pipeline
if args.pipeline.lower() == "photogrammetry":
# default photogrammetry pipeline
multiview.photogrammetry(inputViewpoints=views, inputIntrinsics=intrinsics, output=args.output, graph=graph)
elif args.pipeline.lower() == "hdri":
# default hdri pipeline
graph = multiview.hdri(inputViewpoints=views, inputIntrinsics=intrinsics, output=args.output, graph=graph)
else:
# custom pipeline
graph.load(args.pipeline)
# graph.update()

cameraInit = getOnlyNodeOfType(graph, 'CameraInit')
# reset graph inputs
cameraInit.viewpoints.resetValue()
Expand All @@ -117,66 +134,67 @@ if args.pipeline:
if args.output:
publish = getOnlyNodeOfType(graph, 'Publish')
publish.output.value = args.output
else:
# default pipeline
graph = multiview.photogrammetry(inputViewpoints=views, inputIntrinsics=intrinsics, output=args.output)
cameraInit = getOnlyNodeOfType(graph, 'CameraInit')

if images:
views, intrinsics = cameraInit.nodeDesc.buildIntrinsics(cameraInit, images)
cameraInit.viewpoints.value = views
cameraInit.intrinsics.value = intrinsics

if args.overrides:
import io
import json
with io.open(args.overrides, 'r', encoding='utf-8', errors='ignore') as f:
data = json.load(f)
for nodeName, overrides in data.items():
for attrName, value in overrides.items():
graph.findNode(nodeName).attribute(attrName).value = value

if args.paramOverrides:
print("\n")
import re
reExtract = re.compile('(\w+)([:.])(\w+)=(.*)')
for p in args.paramOverrides:
result = reExtract.match(p)
if not result:
raise ValueError('Invalid param override: ' + str(p))
node, t, param, value = result.groups()
if t == ':':
nodesByType = graph.nodesByType(node)
if not nodesByType:
raise ValueError('No node with the type "{}" in the scene.'.format(node))
for n in nodesByType:
if filesByType.images:
views, intrinsics = cameraInit.nodeDesc.buildIntrinsics(cameraInit, filesByType.images)
cameraInit.viewpoints.value = views
cameraInit.intrinsics.value = intrinsics

if args.overrides:
import io
import json
with io.open(args.overrides, 'r', encoding='utf-8', errors='ignore') as f:
data = json.load(f)
for nodeName, overrides in data.items():
for attrName, value in overrides.items():
graph.findNode(nodeName).attribute(attrName).value = value

if args.paramOverrides:
print("\n")
import re
reExtract = re.compile('(\w+)([:.])(\w+)=(.*)')
for p in args.paramOverrides:
result = reExtract.match(p)
if not result:
raise ValueError('Invalid param override: ' + str(p))
node, t, param, value = result.groups()
if t == ':':
nodesByType = graph.nodesByType(node)
if not nodesByType:
raise ValueError('No node with the type "{}" in the scene.'.format(node))
for n in nodesByType:
print('Overrides {node}.{param}={value}'.format(node=node, param=param, value=value))
n.attribute(param).value = value
elif t == '.':
print('Overrides {node}.{param}={value}'.format(node=node, param=param, value=value))
n.attribute(param).value = value
elif t == '.':
print('Overrides {node}.{param}={value}'.format(node=node, param=param, value=value))
graph.findNode(node).attribute(param).value = value
else:
raise ValueError('Invalid param override: ' + str(p))
print("\n")

# setup DepthMap downscaling
if args.scale > 0:
for node in graph.nodesByType('DepthMap'):
node.downscale.value = args.scale

# setup cache directory
graph.cacheDir = args.cache if args.cache else meshroom.core.defaultCacheFolder

if args.save:
graph.save(args.save, setupProjectFile=not bool(args.cache))
print('File successfully saved: "{}"'.format(args.save))
graph.findNode(node).attribute(param).value = value
else:
raise ValueError('Invalid param override: ' + str(p))
print("\n")

# setup DepthMap downscaling
if args.scale > 0:
for node in graph.nodesByType('DepthMap'):
node.downscale.value = args.scale

# setup cache directory
graph.cacheDir = args.cache if args.cache else meshroom.core.defaultCacheFolder

if args.save:
graph.save(args.save, setupProjectFile=not bool(args.cache))
print('File successfully saved: "{}"'.format(args.save))

if not args.output:
print('No output set, results will be available in the cache folder: "{}"'.format(graph.cacheDir))

# find end nodes (None will compute all graph)
toNodes = graph.findNodes(args.toNode) if args.toNode else None

if args.compute:
if args.submit:
if not args.save:
raise ValueError('Need to save the project to file to submit on renderfarm.')
# submit on renderfarm
meshroom.core.graph.submit(args.save, args.submitter, toNode=toNodes)
elif args.compute:
# start computation
meshroom.core.graph.executeGraph(graph, toNodes=toNodes, forceCompute=args.forceCompute, forceStatus=args.forceStatus)
5 changes: 1 addition & 4 deletions meshroom/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,7 @@ def loadSubmitters(folder, packageName):
# - Nodes
loadAllNodes(folder=os.path.join(meshroomFolder, 'nodes'))
# - Submitters
subs = loadSubmitters(meshroomFolder, 'submitters')
# - additional 3rd party submitters
if "MESHROOM_SUBMITTERS_PATH" in os.environ:
subs += loadSubmitters(os.environ["MESHROOM_SUBMITTERS_PATH"], 'submitters')
subs = loadSubmitters(os.environ.get("MESHROOM_SUBMITTERS_PATH", meshroomFolder), 'submitters')

for sub in subs:
registerSubmitter(sub())
24 changes: 22 additions & 2 deletions meshroom/core/desc.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,14 @@ def __init__(self, param):

def computeSize(self, node):
param = node.attribute(self._param)
assert param.isInput
# Link: use linked node's size
if param.isLink:
return param.getLinkParam().node.size
# ListAttribute: use list size
if isinstance(param.desc, ListAttribute):
return len(param)
if isinstance(param.desc, IntParam):
return param.value
return 1


Expand Down Expand Up @@ -383,7 +384,26 @@ class Node(object):
def __init__(self):
pass

def updateInternals(self, node):
@classmethod
def update(cls, node):
""" Method call before node's internal update on invalidation.

Args:
node: the BaseNode instance being updated
See Also:
BaseNode.updateInternals
"""
pass

@classmethod
def postUpdate(cls, node):
""" Method call after node's internal update on invalidation.

Args:
node: the BaseNode instance being updated
See Also:
NodeBase.updateInternals
"""
pass

def stopProcess(self, chunk):
Expand Down
9 changes: 9 additions & 0 deletions meshroom/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ def _buildCmdVars(self):
for name, attr in self._attributes.objects.items():
if attr.isInput:
continue # skip inputs

# Only consider File attributes for command output parameters
if not isinstance(attr.attributeDesc, desc.File):
continue

attr.value = attr.attributeDesc.value.format(**self._cmdVars)
attr._invalidationValue = attr.attributeDesc.value.format(**cmdVarsNoCache)
v = attr.getValueStr()
Expand Down Expand Up @@ -555,6 +560,8 @@ def updateInternals(self, cacheDir=None):
Args:
cacheDir (str): (optional) override graph's cache directory with custom path
"""
if self.nodeDesc:
self.nodeDesc.update(self)
# Update chunks splitting
self._updateChunks()
# Retrieve current internal folder (if possible)
Expand All @@ -569,6 +576,8 @@ def updateInternals(self, cacheDir=None):
}
self._computeUids()
self._buildCmdVars()
if self.nodeDesc:
self.nodeDesc.postUpdate(self)
# Notify internal folder change if needed
if self.internalFolder != folder:
self.internalFolderChanged.emit()
Expand Down
Loading