mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-30 02:37:26 +02:00
Merge branch 'develop' into dev_ml
This commit is contained in:
commit
4e4fce03eb
36 changed files with 236 additions and 78 deletions
|
@ -62,7 +62,7 @@ If you use this project for a publication, please cite the [paper](https://hal.a
|
||||||
```
|
```
|
||||||
@inproceedings{alicevision2021,
|
@inproceedings{alicevision2021,
|
||||||
title={{A}liceVision {M}eshroom: An open-source {3D} reconstruction pipeline},
|
title={{A}liceVision {M}eshroom: An open-source {3D} reconstruction pipeline},
|
||||||
authors={Carsten Griwodz and Simone Gasparini and Lilian Calvet and Pierre Gurdjos and Fabien Castan and Benoit Maujean and Gregoire De Lillo and Yann Lanthony},
|
author={Carsten Griwodz and Simone Gasparini and Lilian Calvet and Pierre Gurdjos and Fabien Castan and Benoit Maujean and Gregoire De Lillo and Yann Lanthony},
|
||||||
booktitle={Proceedings of the 12th ACM Multimedia Systems Conference - {MMSys '21}},
|
booktitle={Proceedings of the 12th ACM Multimedia Systems Conference - {MMSys '21}},
|
||||||
doi = {10.1145/3458305.3478443},
|
doi = {10.1145/3458305.3478443},
|
||||||
publisher = {ACM Press},
|
publisher = {ACM Press},
|
||||||
|
|
|
@ -177,7 +177,7 @@ with multiview.GraphModification(graph):
|
||||||
if args.paramOverrides:
|
if args.paramOverrides:
|
||||||
print("\n")
|
print("\n")
|
||||||
import re
|
import re
|
||||||
reExtract = re.compile('(\w+)([:.])(\w+)=(.*)')
|
reExtract = re.compile('(\w+)([:.])(\w[\w.]*)=(.*)')
|
||||||
for p in args.paramOverrides:
|
for p in args.paramOverrides:
|
||||||
result = reExtract.match(p)
|
result = reExtract.match(p)
|
||||||
if not result:
|
if not result:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import argparse
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import shlex
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
def trim(s):
|
def trim(s):
|
||||||
|
@ -60,7 +61,7 @@ parser.add_argument('node', metavar='NODE_NAME', type=str,
|
||||||
help='New node name')
|
help='New node name')
|
||||||
parser.add_argument('bin', metavar='CMDLINE', type=str,
|
parser.add_argument('bin', metavar='CMDLINE', type=str,
|
||||||
default=None,
|
default=None,
|
||||||
help='Output plugin folder')
|
help='Input executable')
|
||||||
parser.add_argument('--output', metavar='DIR', type=str,
|
parser.add_argument('--output', metavar='DIR', type=str,
|
||||||
default=os.path.dirname(__file__),
|
default=os.path.dirname(__file__),
|
||||||
help='Output plugin folder')
|
help='Output plugin folder')
|
||||||
|
@ -77,7 +78,7 @@ soft = "{nodeType}"
|
||||||
if args.bin:
|
if args.bin:
|
||||||
soft = args.bin
|
soft = args.bin
|
||||||
import subprocess
|
import subprocess
|
||||||
proc = subprocess.Popen(args=[args.bin, '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
proc = subprocess.Popen(args=shlex.split(args.bin) + ['--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
stdout, stderr = proc.communicate()
|
stdout, stderr = proc.communicate()
|
||||||
inputCmdLineDoc = stdout if stdout else stderr
|
inputCmdLineDoc = stdout if stdout else stderr
|
||||||
elif sys.stdin.isatty():
|
elif sys.stdin.isatty():
|
||||||
|
@ -137,7 +138,7 @@ choiceValues1_re = re.compile('\* (?P<value>\w+):')
|
||||||
choiceValues2_re = re.compile('\((?P<value>.+?)\)')
|
choiceValues2_re = re.compile('\((?P<value>.+?)\)')
|
||||||
choiceValues3_re = re.compile('\{(?P<value>.+?)\}')
|
choiceValues3_re = re.compile('\{(?P<value>.+?)\}')
|
||||||
|
|
||||||
cmdLineArgs = args_re.findall(inputCmdLineDoc)
|
cmdLineArgs = args_re.findall(inputCmdLineDoc.decode('utf-8'))
|
||||||
|
|
||||||
print('='*80)
|
print('='*80)
|
||||||
pprint(cmdLineArgs)
|
pprint(cmdLineArgs)
|
||||||
|
|
|
@ -272,9 +272,17 @@ def loadSubmitters(folder, packageName):
|
||||||
|
|
||||||
meshroomFolder = os.path.dirname(os.path.dirname(__file__))
|
meshroomFolder = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
additionalNodesPath = os.environ.get("MESHROOM_NODES_PATH", "").split(os.pathsep)
|
||||||
|
# filter empty strings
|
||||||
|
additionalNodesPath = [i for i in additionalNodesPath if i]
|
||||||
|
|
||||||
# Load plugins:
|
# Load plugins:
|
||||||
# - Nodes
|
# - Nodes
|
||||||
loadAllNodes(folder=os.path.join(meshroomFolder, 'nodes'))
|
nodesFolders = [os.path.join(meshroomFolder, 'nodes')] + additionalNodesPath
|
||||||
|
|
||||||
|
for f in nodesFolders:
|
||||||
|
loadAllNodes(folder=f)
|
||||||
|
|
||||||
# - Submitters
|
# - Submitters
|
||||||
subs = loadSubmitters(os.environ.get("MESHROOM_SUBMITTERS_PATH", meshroomFolder), 'submitters')
|
subs = loadSubmitters(os.environ.get("MESHROOM_SUBMITTERS_PATH", meshroomFolder), 'submitters')
|
||||||
|
|
||||||
|
|
7
meshroom/core/desc.py
Normal file → Executable file
7
meshroom/core/desc.py
Normal file → Executable file
|
@ -5,6 +5,8 @@ import math
|
||||||
import os
|
import os
|
||||||
import psutil
|
import psutil
|
||||||
import ast
|
import ast
|
||||||
|
import distutils.util
|
||||||
|
|
||||||
|
|
||||||
class Attribute(BaseObject):
|
class Attribute(BaseObject):
|
||||||
"""
|
"""
|
||||||
|
@ -191,7 +193,10 @@ class BoolParam(Param):
|
||||||
|
|
||||||
def validateValue(self, value):
|
def validateValue(self, value):
|
||||||
try:
|
try:
|
||||||
return bool(int(value)) # int cast is useful to handle string values ('0', '1')
|
if isinstance(value, pyCompatibility.basestring):
|
||||||
|
# use distutils.util.strtobool to handle (1/0, true/false, on/off, y/n)
|
||||||
|
return bool(distutils.util.strtobool(value))
|
||||||
|
return bool(value)
|
||||||
except:
|
except:
|
||||||
raise ValueError('BoolParam only supports bool value (param:{}, value:{}, type:{})'.format(self.name, value, type(value)))
|
raise ValueError('BoolParam only supports bool value (param:{}, value:{}, type:{})'.format(self.name, value, type(value)))
|
||||||
|
|
||||||
|
|
|
@ -95,23 +95,34 @@ class ComputerStatistics:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen([self.nvidia_smi, "-q", "-x"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
p = subprocess.Popen([self.nvidia_smi, "-q", "-x"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
xmlGpu, stdError = p.communicate(timeout=10) # 10 seconds
|
if sys.version_info[0] == 2:
|
||||||
|
# no timeout in python-2
|
||||||
|
xmlGpu, stdError = p.communicate()
|
||||||
|
else:
|
||||||
|
xmlGpu, stdError = p.communicate(timeout=10) # 10 seconds
|
||||||
|
|
||||||
smiTree = ET.fromstring(xmlGpu)
|
smiTree = ET.fromstring(xmlGpu)
|
||||||
gpuTree = smiTree.find('gpu')
|
gpuTree = smiTree.find('gpu')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._addKV('gpuMemoryUsed', gpuTree.find('fb_memory_usage').find('used').text.split(" ")[0])
|
gpuMemoryUsed = gpuTree.find('fb_memory_usage').find('used').text.split(" ")[0]
|
||||||
|
self._addKV('gpuMemoryUsed', gpuMemoryUsed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug('Failed to get gpuMemoryUsed: "{}".'.format(str(e)))
|
logging.debug('Failed to get gpuMemoryUsed: "{}".'.format(str(e)))
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self._addKV('gpuUsed', gpuTree.find('utilization').find('gpu_util').text.split(" ")[0])
|
self.gpuMemoryTotal = gpuTree.find('fb_memory_usage').find('total').text.split(" ")[0]
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
gpuUsed = gpuTree.find('utilization').find('gpu_util').text.split(" ")[0]
|
||||||
|
self._addKV('gpuUsed', gpuUsed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug('Failed to get gpuUsed: "{}".'.format(str(e)))
|
logging.debug('Failed to get gpuUsed: "{}".'.format(str(e)))
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self._addKV('gpuTemperature', gpuTree.find('temperature').find('gpu_temp').text.split(" ")[0])
|
gpuTemperature = gpuTree.find('temperature').find('gpu_temp').text.split(" ")[0]
|
||||||
|
self._addKV('gpuTemperature', gpuTemperature)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug('Failed to get gpuTemperature: "{}".'.format(str(e)))
|
logging.debug('Failed to get gpuTemperature: "{}".'.format(str(e)))
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -136,7 +136,7 @@ def findFilesByTypeInFolder(folder, recursive=False):
|
||||||
else:
|
else:
|
||||||
output.addFiles([os.path.join(currentFolder, filename) for filename in os.listdir(currentFolder)])
|
output.addFiles([os.path.join(currentFolder, filename) for filename in os.listdir(currentFolder)])
|
||||||
else:
|
else:
|
||||||
# if not a diretory or a file, it may be an expression
|
# if not a directory or a file, it may be an expression
|
||||||
import glob
|
import glob
|
||||||
paths = glob.glob(currentFolder)
|
paths = glob.glob(currentFolder)
|
||||||
filesByType = findFilesByTypeInFolder(paths, recursive=recursive)
|
filesByType = findFilesByTypeInFolder(paths, recursive=recursive)
|
||||||
|
@ -186,7 +186,7 @@ def panoramaFisheyeHdr(inputImages=None, inputViewpoints=None, inputIntrinsics=N
|
||||||
# when using fisheye images, 'sift' performs better than 'dspsift'
|
# when using fisheye images, 'sift' performs better than 'dspsift'
|
||||||
featureExtraction.attribute("describerTypes").value = ['sift']
|
featureExtraction.attribute("describerTypes").value = ['sift']
|
||||||
# when using fisheye images, the overlap between images can be small
|
# when using fisheye images, the overlap between images can be small
|
||||||
# and thus requires many features to get enough correspondances for cameras estimation
|
# and thus requires many features to get enough correspondences for cameras estimation
|
||||||
featureExtraction.attribute("describerPreset").value = 'high'
|
featureExtraction.attribute("describerPreset").value = 'high'
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
__version__ = "6.0"
|
__version__ = "7.0"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
@ -28,16 +28,17 @@ Viewpoint = [
|
||||||
|
|
||||||
Intrinsic = [
|
Intrinsic = [
|
||||||
desc.IntParam(name="intrinsicId", label="Id", description="Intrinsic UID", value=-1, uid=[0], range=None),
|
desc.IntParam(name="intrinsicId", label="Id", description="Intrinsic UID", value=-1, uid=[0], range=None),
|
||||||
desc.FloatParam(name="pxInitialFocalLength", label="Initial Focal Length",
|
desc.FloatParam(name="initialFocalLength", label="Initial Focal Length",
|
||||||
description="Initial Guess on the Focal Length (in pixels). \n"
|
description="Initial Guess on the Focal Length (in pixels). \n"
|
||||||
"When we have an initial value from EXIF, this value is not accurate but cannot be wrong. \n"
|
"When we have an initial value from EXIF, this value is not accurate but cannot be wrong. \n"
|
||||||
"So this value is used to limit the range of possible values in the optimization. \n"
|
"So this value is used to limit the range of possible values in the optimization. \n"
|
||||||
"If you put -1, this value will not be used and the focal length will not be bounded.",
|
"If you put -1, this value will not be used and the focal length will not be bounded.",
|
||||||
value=-1.0, uid=[0], range=None),
|
value=-1.0, uid=[0], range=None),
|
||||||
desc.GroupAttribute(name="pxFocalLength", label="Focal Length", description="Known/Calibrated Focal Length (in pixels)", groupDesc=[
|
desc.FloatParam(name="focalLength", label="Focal Length", description="Known/Calibrated Focal Length (in mm)", value=1000, uid=[], range=(0, 10000, 1)),
|
||||||
desc.FloatParam(name="x", label="x", description="", value=-1, uid=[], range=(0, 10000, 1)),
|
desc.FloatParam(name="pixelRatio", label="pixel Ratio", description="ratio between pixel width and pixel height", value=1, uid=[], range=(0, 10, 0.1)),
|
||||||
desc.FloatParam(name="y", label="y", description="", value=-1, uid=[], range=(0, 10000, 1)),
|
desc.BoolParam(name='pixelRatioLocked', label='Pixel ratio Locked',
|
||||||
]),
|
description='the pixelRatio value is locked for estimation',
|
||||||
|
value=True, uid=[0]),
|
||||||
desc.ChoiceParam(name="type", label="Camera Type",
|
desc.ChoiceParam(name="type", label="Camera Type",
|
||||||
description="Mathematical Model used to represent a camera:\n"
|
description="Mathematical Model used to represent a camera:\n"
|
||||||
" * pinhole: Simplest projective camera model without optical distortion (focal and optical center).\n"
|
" * pinhole: Simplest projective camera model without optical distortion (focal and optical center).\n"
|
||||||
|
@ -107,11 +108,6 @@ def readSfMData(sfmFile):
|
||||||
intrinsic['principalPoint']['x'] = pp[0]
|
intrinsic['principalPoint']['x'] = pp[0]
|
||||||
intrinsic['principalPoint']['y'] = pp[1]
|
intrinsic['principalPoint']['y'] = pp[1]
|
||||||
|
|
||||||
f = intrinsic['pxFocalLength']
|
|
||||||
intrinsic['pxFocalLength'] = {}
|
|
||||||
intrinsic['pxFocalLength']['x'] = f[0]
|
|
||||||
intrinsic['pxFocalLength']['y'] = f[1]
|
|
||||||
|
|
||||||
# convert empty string distortionParams (i.e: Pinhole model) to empty list
|
# convert empty string distortionParams (i.e: Pinhole model) to empty list
|
||||||
if intrinsic['distortionParams'] == '':
|
if intrinsic['distortionParams'] == '':
|
||||||
intrinsic['distortionParams'] = list()
|
intrinsic['distortionParams'] = list()
|
||||||
|
@ -255,12 +251,6 @@ The metadata needed are:
|
||||||
]
|
]
|
||||||
|
|
||||||
def upgradeAttributeValues(self, attrValues, fromVersion):
|
def upgradeAttributeValues(self, attrValues, fromVersion):
|
||||||
# Starting with version 5, the focal length is now split on x and y
|
|
||||||
if fromVersion < Version(5, 0):
|
|
||||||
for intrinsic in attrValues['intrinsics']:
|
|
||||||
pxFocalLength = intrinsic['pxFocalLength']
|
|
||||||
if not isinstance(pxFocalLength, dict):
|
|
||||||
intrinsic['pxFocalLength'] = {"x": pxFocalLength, "y": pxFocalLength}
|
|
||||||
|
|
||||||
# Starting with version 6, the principal point is now relative to the image center
|
# Starting with version 6, the principal point is now relative to the image center
|
||||||
if fromVersion < Version(6, 0):
|
if fromVersion < Version(6, 0):
|
||||||
|
@ -271,6 +261,20 @@ The metadata needed are:
|
||||||
"y": int(principalPoint["y"] - 0.5 * intrinsic['height'])
|
"y": int(principalPoint["y"] - 0.5 * intrinsic['height'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Starting with version 7, the focal length is now in mm
|
||||||
|
if fromVersion < Version(7, 0):
|
||||||
|
for intrinsic in attrValues['intrinsics']:
|
||||||
|
pxInitialFocalLength = intrinsic['pxInitialFocalLength']
|
||||||
|
pxFocalLength = intrinsic['pxFocalLength']
|
||||||
|
sensorWidth = intrinsic['sensorWidth']
|
||||||
|
width = intrinsic['width']
|
||||||
|
focalLength = (pxFocalLength / width) * sensorWidth
|
||||||
|
initialFocalLength = (pxInitialFocalLength / width) * sensorWidth
|
||||||
|
intrinsic['initialFocalLength'] = initialFocalLength
|
||||||
|
intrinsic['focalLength'] = focalLength
|
||||||
|
intrinsic['pixelRatio'] = 1.0
|
||||||
|
intrinsic['pixelRatioLocked'] = False
|
||||||
|
|
||||||
return attrValues
|
return attrValues
|
||||||
|
|
||||||
def readSfMData(self, sfmFile):
|
def readSfMData(self, sfmFile):
|
||||||
|
@ -329,7 +333,6 @@ The metadata needed are:
|
||||||
intrinsics = node.intrinsics.getPrimitiveValue(exportDefault=True)
|
intrinsics = node.intrinsics.getPrimitiveValue(exportDefault=True)
|
||||||
for intrinsic in intrinsics:
|
for intrinsic in intrinsics:
|
||||||
intrinsic['principalPoint'] = [intrinsic['principalPoint']['x'], intrinsic['principalPoint']['y']]
|
intrinsic['principalPoint'] = [intrinsic['principalPoint']['x'], intrinsic['principalPoint']['y']]
|
||||||
intrinsic['pxFocalLength'] = [intrinsic['pxFocalLength']['x'], intrinsic['pxFocalLength']['y']]
|
|
||||||
views = node.viewpoints.getPrimitiveValue(exportDefault=False)
|
views = node.viewpoints.getPrimitiveValue(exportDefault=False)
|
||||||
|
|
||||||
# convert the metadata string into a map
|
# convert the metadata string into a map
|
||||||
|
@ -338,7 +341,7 @@ The metadata needed are:
|
||||||
view['metadata'] = json.loads(view['metadata'])
|
view['metadata'] = json.loads(view['metadata'])
|
||||||
|
|
||||||
sfmData = {
|
sfmData = {
|
||||||
"version": [1, 2, 1],
|
"version": [1, 2, 2],
|
||||||
"views": views + newViews,
|
"views": views + newViews,
|
||||||
"intrinsics": intrinsics,
|
"intrinsics": intrinsics,
|
||||||
"featureFolder": "",
|
"featureFolder": "",
|
||||||
|
|
|
@ -17,7 +17,7 @@ Performs Macbeth color checker chart detection.
|
||||||
|
|
||||||
Outputs:
|
Outputs:
|
||||||
- the detected color charts position and colors
|
- the detected color charts position and colors
|
||||||
- the associated tranform matrix from "theoric" to "measured"
|
- the associated transform matrix from "theoric" to "measured"
|
||||||
assuming that the "theoric" Macbeth chart corners coordinates are:
|
assuming that the "theoric" Macbeth chart corners coordinates are:
|
||||||
(0, 0), (1675, 0), (1675, 1125), (0, 1125)
|
(0, 0), (1675, 0), (1675, 1125), (0, 1125)
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,38 @@ Use a downscale factor of one (full-resolution) only if the quality of the input
|
||||||
uid=[0],
|
uid=[0],
|
||||||
advanced=True,
|
advanced=True,
|
||||||
),
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmScale',
|
||||||
|
label='SGM: Downscale factor',
|
||||||
|
description='Semi Global Matching: Downscale factor used to compute the similarity volume.',
|
||||||
|
value=-1,
|
||||||
|
range=(-1, 10, 1),
|
||||||
|
uid=[0],
|
||||||
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmStepXY',
|
||||||
|
label='SGM: Step XY',
|
||||||
|
description='Semi Global Matching: Step used to compute the similarity volume on X and Y axis.',
|
||||||
|
value=-1,
|
||||||
|
range=(-1, 10, 1),
|
||||||
|
uid=[0],
|
||||||
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmStepZ',
|
||||||
|
label='SGM: Step Z',
|
||||||
|
description='Semi Global Matching: Step used to compute the similarity volume on Z axis.',
|
||||||
|
value=-1,
|
||||||
|
range=(-1, 10, 1),
|
||||||
|
uid=[0],
|
||||||
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmMaxSideXY',
|
||||||
|
label='SGM: Max Side',
|
||||||
|
description='Semi Global Matching: Max side in pixels used to automatically decide for sgmScale/sgmStep if not defined.',
|
||||||
|
value=700,
|
||||||
|
range=(-1, 1000, 1),
|
||||||
|
uid=[0],
|
||||||
|
),
|
||||||
desc.IntParam(
|
desc.IntParam(
|
||||||
name='sgmMaxTCams',
|
name='sgmMaxTCams',
|
||||||
label='SGM: Nb Neighbour Cameras',
|
label='SGM: Nb Neighbour Cameras',
|
||||||
|
@ -98,6 +130,59 @@ Use a downscale factor of one (full-resolution) only if the quality of the input
|
||||||
uid=[0],
|
uid=[0],
|
||||||
advanced=True,
|
advanced=True,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
desc.FloatParam(
|
||||||
|
name='sgmP1',
|
||||||
|
label='SGM: P1',
|
||||||
|
description='Semi Global Matching: P1.',
|
||||||
|
value=10.0,
|
||||||
|
range=(0.0, 255.0, 0.5),
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
desc.FloatParam(
|
||||||
|
name='sgmP2',
|
||||||
|
label='SGM: P2',
|
||||||
|
description='Semi Global Matching: P2 weight.',
|
||||||
|
value=100.0,
|
||||||
|
range=(-255.0, 255.0, 0.5),
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmMaxDepths',
|
||||||
|
label='SGM: Max Depths',
|
||||||
|
description='Semi Global Matching: Max number of depths in the overall similarity volume.',
|
||||||
|
value=3000,
|
||||||
|
range=(1, 5000, 1),
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
desc.IntParam(
|
||||||
|
name='sgmMaxDepthsPerTc',
|
||||||
|
label='SGM: Max Depths Per Camera Pairs',
|
||||||
|
description='Semi Global Matching: Max number of depths to sweep in the similarity volume per Rc/Tc cameras.',
|
||||||
|
value=1500,
|
||||||
|
range=(1, 5000, 1),
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
desc.BoolParam(
|
||||||
|
name='sgmUseSfmSeeds',
|
||||||
|
label='SGM: Use SfM Landmarks',
|
||||||
|
description='Semi Global Matching: Use landmarks from SfM to define the ranges for the plane sweeping.',
|
||||||
|
value=True,
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
desc.StringParam(
|
||||||
|
name='sgmFilteringAxes',
|
||||||
|
label='SGM: Filtering Axes',
|
||||||
|
description="Semi Global Matching: Define axes for the filtering of the similarity volume.",
|
||||||
|
value='YX',
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
desc.IntParam(
|
desc.IntParam(
|
||||||
name='refineMaxTCams',
|
name='refineMaxTCams',
|
||||||
label='Refine: Nb Neighbour Cameras',
|
label='Refine: Nb Neighbour Cameras',
|
||||||
|
|
|
@ -74,6 +74,15 @@ This allows to filter unstable points before starting the fusion of all depth ma
|
||||||
range=(0, 10, 1),
|
range=(0, 10, 1),
|
||||||
uid=[0],
|
uid=[0],
|
||||||
),
|
),
|
||||||
|
desc.FloatParam(
|
||||||
|
name='pixToleranceFactor',
|
||||||
|
label='Tolerance Size',
|
||||||
|
description='Filtering tolerance size factor (in px).',
|
||||||
|
value=2.0,
|
||||||
|
range=(0.001, 10.0, 0.1),
|
||||||
|
uid=[0],
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
desc.IntParam(
|
desc.IntParam(
|
||||||
name="pixSizeBall",
|
name="pixSizeBall",
|
||||||
label="Filtering Size in Pixels",
|
label="Filtering Size in Pixels",
|
||||||
|
|
|
@ -170,7 +170,7 @@ then it checks the number of features that validates this model and iterate thro
|
||||||
desc.BoolParam(
|
desc.BoolParam(
|
||||||
name='crossMatching',
|
name='crossMatching',
|
||||||
label='Cross Matching',
|
label='Cross Matching',
|
||||||
description='Make sure that the matching process is symmetric (same matches for I->J than fo J->I)',
|
description='Make sure that the matching process is symmetric (same matches for I->J than for J->I)',
|
||||||
value=False,
|
value=False,
|
||||||
uid=[0],
|
uid=[0],
|
||||||
),
|
),
|
||||||
|
|
|
@ -43,7 +43,7 @@ Estimate the seams lines between the inputs to provide an optimal compositing in
|
||||||
desc.BoolParam(
|
desc.BoolParam(
|
||||||
name='useGraphCut',
|
name='useGraphCut',
|
||||||
label='Use Smart Seams',
|
label='Use Smart Seams',
|
||||||
description='Use a graphcut algorithm to optmize seams for better transitions between images.',
|
description='Use a graphcut algorithm to optimize seams for better transitions between images.',
|
||||||
value=True,
|
value=True,
|
||||||
uid=[0],
|
uid=[0],
|
||||||
),
|
),
|
||||||
|
|
|
@ -200,7 +200,7 @@ Upload a textured mesh on Sketchfab.
|
||||||
modelEndpoint, **{'data': body, 'headers': headers})
|
modelEndpoint, **{'data': body, 'headers': headers})
|
||||||
chunk.logManager.completeProgressBar()
|
chunk.logManager.completeProgressBar()
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
chunk.logger.error(u'An error occured: {}'.format(e))
|
chunk.logger.error(u'An error occurred: {}'.format(e))
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
if r.status_code != requests.codes.created:
|
if r.status_code != requests.codes.created:
|
||||||
chunk.logger.error(u'Upload failed with error: {}'.format(r.json()))
|
chunk.logger.error(u'Upload failed with error: {}'.format(r.json()))
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Split360Images(desc.CommandLineNode):
|
||||||
commandLine = 'aliceVision_utils_split360Images {allParams}'
|
commandLine = 'aliceVision_utils_split360Images {allParams}'
|
||||||
|
|
||||||
category = 'Utils'
|
category = 'Utils'
|
||||||
documentation = '''This node is used to extract multiple images from equirectangular or dualfisheye images or image folder'''
|
documentation = "This node is used to extract multiple images from equirectangular or dualfisheye images."
|
||||||
|
|
||||||
inputs = [
|
inputs = [
|
||||||
desc.File(
|
desc.File(
|
||||||
|
|
|
@ -116,7 +116,7 @@ It iterates like that, adding cameras and triangulating new 2D features into 3D
|
||||||
desc.ChoiceParam(
|
desc.ChoiceParam(
|
||||||
name='observationConstraint',
|
name='observationConstraint',
|
||||||
label='Observation Constraint',
|
label='Observation Constraint',
|
||||||
description='Observation contraint mode used in the optimization:\n'
|
description='Observation constraint mode used in the optimization:\n'
|
||||||
' * Basic: Use standard reprojection error in pixel coordinates\n'
|
' * Basic: Use standard reprojection error in pixel coordinates\n'
|
||||||
' * Scale: Use reprojection error in pixel coordinates but relative to the feature scale',
|
' * Scale: Use reprojection error in pixel coordinates but relative to the feature scale',
|
||||||
value='Scale',
|
value='Scale',
|
||||||
|
@ -308,6 +308,13 @@ It iterates like that, adding cameras and triangulating new 2D features into 3D
|
||||||
value=False,
|
value=False,
|
||||||
uid=[0],
|
uid=[0],
|
||||||
),
|
),
|
||||||
|
desc.BoolParam(
|
||||||
|
name='computeStructureColor',
|
||||||
|
label='Compute Structure Color',
|
||||||
|
description='Enable/Disable color computation of each 3D point.',
|
||||||
|
value=True,
|
||||||
|
uid=[0],
|
||||||
|
),
|
||||||
desc.File(
|
desc.File(
|
||||||
name='initialPairA',
|
name='initialPairA',
|
||||||
label='Initial Pair A',
|
label='Initial Pair A',
|
||||||
|
|
|
@ -273,7 +273,7 @@ Many cameras are contributing to the low frequencies and only the best ones cont
|
||||||
desc.BoolParam(
|
desc.BoolParam(
|
||||||
name='forceVisibleByAllVertices',
|
name='forceVisibleByAllVertices',
|
||||||
label='Force Visible By All Vertices',
|
label='Force Visible By All Vertices',
|
||||||
description='''Triangle visibility is based on the union of vertices visiblity.''',
|
description='''Triangle visibility is based on the union of vertices visibility.''',
|
||||||
value=False,
|
value=False,
|
||||||
uid=[0],
|
uid=[0],
|
||||||
advanced=True,
|
advanced=True,
|
||||||
|
|
|
@ -31,7 +31,7 @@ def main():
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--useBackground", type=strtobool, required=True,
|
"--useBackground", type=strtobool, required=True,
|
||||||
help="Diplay the background image or not.",
|
help="Display the background image or not.",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -262,8 +262,8 @@ def main():
|
||||||
|
|
||||||
# For showing an outline of the object, we need to add two materials to the mesh:
|
# For showing an outline of the object, we need to add two materials to the mesh:
|
||||||
# Center and Edge, we are using a method that consists in having a "bold" effect on the Edge Material so we can see it
|
# Center and Edge, we are using a method that consists in having a "bold" effect on the Edge Material so we can see it
|
||||||
# around the Center material. We use a Solidify Modifier on which we flip normals and reduce Thickness to bellow zero.
|
# around the Center material. We use a Solidify Modifier on which we flip normals and reduce Thickness to below zero.
|
||||||
# The more the thickness get bellow zero, the more the egde will be largely revealed.
|
# The more the thickness get below zero, the more the edge will be largely revealed.
|
||||||
elif args.model.lower().endswith('.obj'):
|
elif args.model.lower().endswith('.obj'):
|
||||||
print("Import OBJ")
|
print("Import OBJ")
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
},
|
},
|
||||||
"GPU": {
|
"GPU": {
|
||||||
"NONE": [],
|
"NONE": [],
|
||||||
"NORMAL": ["!\"*rnd*\""],
|
"NORMAL": ["cuda8G"],
|
||||||
"INTENSIVE": ["!\"*rnd*\"", "@.nCPUs>=12"]
|
"INTENSIVE": ["cuda16G"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
import simpleFarm
|
import simpleFarm
|
||||||
from meshroom.core.desc import Level
|
from meshroom.core.desc import Level
|
||||||
|
@ -12,14 +13,12 @@ currentDir = os.path.dirname(os.path.realpath(__file__))
|
||||||
binDir = os.path.dirname(os.path.dirname(os.path.dirname(currentDir)))
|
binDir = os.path.dirname(os.path.dirname(os.path.dirname(currentDir)))
|
||||||
|
|
||||||
class SimpleFarmSubmitter(BaseSubmitter):
|
class SimpleFarmSubmitter(BaseSubmitter):
|
||||||
if 'REZ_MESHROOM_VERSION' in os.environ:
|
|
||||||
MESHROOM_PACKAGE = "meshroom-{}".format(os.environ.get('REZ_MESHROOM_VERSION', ''))
|
|
||||||
else:
|
|
||||||
MESHROOM_PACKAGE = None
|
|
||||||
|
|
||||||
filepath = os.environ.get('SIMPLEFARMCONFIG', os.path.join(currentDir, 'simpleFarmConfig.json'))
|
filepath = os.environ.get('SIMPLEFARMCONFIG', os.path.join(currentDir, 'simpleFarmConfig.json'))
|
||||||
config = json.load(open(filepath))
|
config = json.load(open(filepath))
|
||||||
|
|
||||||
|
reqPackages = []
|
||||||
|
environment = {}
|
||||||
ENGINE = ''
|
ENGINE = ''
|
||||||
DEFAULT_TAGS = {'prod': ''}
|
DEFAULT_TAGS = {'prod': ''}
|
||||||
|
|
||||||
|
@ -28,6 +27,32 @@ class SimpleFarmSubmitter(BaseSubmitter):
|
||||||
self.engine = os.environ.get('MESHROOM_SIMPLEFARM_ENGINE', 'tractor')
|
self.engine = os.environ.get('MESHROOM_SIMPLEFARM_ENGINE', 'tractor')
|
||||||
self.share = os.environ.get('MESHROOM_SIMPLEFARM_SHARE', 'vfx')
|
self.share = os.environ.get('MESHROOM_SIMPLEFARM_SHARE', 'vfx')
|
||||||
self.prod = os.environ.get('PROD', 'mvg')
|
self.prod = os.environ.get('PROD', 'mvg')
|
||||||
|
if 'REZ_REQUEST' in os.environ:
|
||||||
|
packages = os.environ.get('REZ_REQUEST', '').split()
|
||||||
|
resolvedPackages = os.environ.get('REZ_RESOLVE', '').split()
|
||||||
|
resolvedVersions = {}
|
||||||
|
for r in resolvedPackages:
|
||||||
|
# remove implict packages
|
||||||
|
if r.startswith('~'):
|
||||||
|
continue
|
||||||
|
# logging.info('REZ: {}'.format(str(r)))
|
||||||
|
v = r.split('-')
|
||||||
|
# logging.info(' v: {}'.format(str(v)))
|
||||||
|
if len(v) == 2:
|
||||||
|
resolvedVersions[v[0]] = v[1]
|
||||||
|
for p in packages:
|
||||||
|
if p.startswith('~'):
|
||||||
|
continue
|
||||||
|
v = p.split('-')
|
||||||
|
self.reqPackages.append('-'.join([v[0], resolvedVersions[v[0]]]))
|
||||||
|
logging.debug('REZ Packages: {}'.format(str(self.reqPackages)))
|
||||||
|
elif 'REZ_MESHROOM_VERSION' in os.environ:
|
||||||
|
self.reqPackages = ["meshroom-{}".format(os.environ.get('REZ_MESHROOM_VERSION', ''))]
|
||||||
|
else:
|
||||||
|
self.reqPackages = None
|
||||||
|
|
||||||
|
if 'REZ_DEV_PACKAGES_ROOT' in os.environ:
|
||||||
|
self.environment['REZ_DEV_PACKAGES_ROOT'] = os.environ['REZ_DEV_PACKAGES_ROOT']
|
||||||
|
|
||||||
def createTask(self, meshroomFile, node):
|
def createTask(self, meshroomFile, node):
|
||||||
tags = self.DEFAULT_TAGS.copy() # copy to not modify default tags
|
tags = self.DEFAULT_TAGS.copy() # copy to not modify default tags
|
||||||
|
@ -50,10 +75,10 @@ class SimpleFarmSubmitter(BaseSubmitter):
|
||||||
task = simpleFarm.Task(
|
task = simpleFarm.Task(
|
||||||
name=node.nodeType,
|
name=node.nodeType,
|
||||||
command='{exe} --node {nodeName} "{meshroomFile}" {parallelArgs} --extern'.format(
|
command='{exe} --node {nodeName} "{meshroomFile}" {parallelArgs} --extern'.format(
|
||||||
exe='meshroom_compute' if self.MESHROOM_PACKAGE else os.path.join(binDir, 'meshroom_compute'),
|
exe='meshroom_compute' if self.reqPackages else os.path.join(binDir, 'meshroom_compute'),
|
||||||
nodeName=node.name, meshroomFile=meshroomFile, parallelArgs=parallelArgs),
|
nodeName=node.name, meshroomFile=meshroomFile, parallelArgs=parallelArgs),
|
||||||
tags=tags,
|
tags=tags,
|
||||||
rezPackages=[self.MESHROOM_PACKAGE] if self.MESHROOM_PACKAGE else None,
|
rezPackages=self.reqPackages,
|
||||||
requirements={'service': str(','.join(allRequirements))},
|
requirements={'service': str(','.join(allRequirements))},
|
||||||
**arguments)
|
**arguments)
|
||||||
return task
|
return task
|
||||||
|
@ -74,6 +99,7 @@ class SimpleFarmSubmitter(BaseSubmitter):
|
||||||
job = simpleFarm.Job(name,
|
job = simpleFarm.Job(name,
|
||||||
tags=mainTags,
|
tags=mainTags,
|
||||||
requirements={'service': str(','.join(allRequirements))},
|
requirements={'service': str(','.join(allRequirements))},
|
||||||
|
environment=self.environment,
|
||||||
)
|
)
|
||||||
|
|
||||||
nodeNameToTask = {}
|
nodeNameToTask = {}
|
||||||
|
|
|
@ -515,7 +515,7 @@ class UIGraph(QObject):
|
||||||
@Slot(Node, QPoint, QObject)
|
@Slot(Node, QPoint, QObject)
|
||||||
def moveNode(self, node, position, nodes=None):
|
def moveNode(self, node, position, nodes=None):
|
||||||
"""
|
"""
|
||||||
Move 'node' to the given 'position' and also update the positions of 'nodes' if neccessary.
|
Move 'node' to the given 'position' and also update the positions of 'nodes' if necessary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
node (Node): the node to move
|
node (Node): the node to move
|
||||||
|
|
|
@ -118,7 +118,7 @@ Dialog {
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
text: "2010-2021 AliceVision contributors"
|
text: "2010-2022 AliceVision contributors"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ Dialog {
|
||||||
|
|
||||||
/// Return the text content of this dialog as a simple string.
|
/// Return the text content of this dialog as a simple string.
|
||||||
/// Used when copying the message in the system clipboard.
|
/// Used when copying the message in the system clipboard.
|
||||||
/// Can be overriden in components extending MessageDialog
|
/// Can be overridden in components extending MessageDialog
|
||||||
function getAsString() {
|
function getAsString() {
|
||||||
return asString
|
return asString
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Controls 1.0
|
||||||
*/
|
*/
|
||||||
QtObject {
|
QtObject {
|
||||||
|
|
||||||
readonly property string defaultErrorText: "An unexpected error has occured"
|
readonly property string defaultErrorText: "An unexpected error has occurred"
|
||||||
|
|
||||||
property Component infoDialog: Component {
|
property Component infoDialog: Component {
|
||||||
MessageDialog {
|
MessageDialog {
|
||||||
|
|
|
@ -63,7 +63,7 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Duplicate a node and optionnally all the following ones
|
/// Duplicate a node and optionally all the following ones
|
||||||
function duplicateNode(duplicateFollowingNodes) {
|
function duplicateNode(duplicateFollowingNodes) {
|
||||||
if (duplicateFollowingNodes) {
|
if (duplicateFollowingNodes) {
|
||||||
var nodes = uigraph.duplicateNodesFrom(uigraph.selectedNodes)
|
var nodes = uigraph.duplicateNodesFrom(uigraph.selectedNodes)
|
||||||
|
|
|
@ -48,6 +48,10 @@ Panel {
|
||||||
parseIntr()
|
parseIntr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeCurrentIndex(newIndex) {
|
||||||
|
_reconstruction.cameraInitIndex = newIndex
|
||||||
|
}
|
||||||
|
|
||||||
function populate_model()
|
function populate_model()
|
||||||
{
|
{
|
||||||
intrinsicModel.clear()
|
intrinsicModel.clear()
|
||||||
|
@ -474,9 +478,8 @@ Panel {
|
||||||
property var columnWidths: [105, 75, 75, 75, 125, 60, 60, 45, 45, 200, 60, 60]
|
property var columnWidths: [105, 75, 75, 75, 125, 60, 60, 45, 45, 200, 60, 60]
|
||||||
property var columnNames: [
|
property var columnNames: [
|
||||||
"intrinsicId",
|
"intrinsicId",
|
||||||
"pxInitialFocalLength",
|
"initialFocalLength",
|
||||||
"pxFocalLength.x",
|
"focalLength",
|
||||||
"pxFocalLength.y",
|
|
||||||
"type",
|
"type",
|
||||||
"width",
|
"width",
|
||||||
"height",
|
"height",
|
||||||
|
@ -499,7 +502,6 @@ Panel {
|
||||||
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[9]]} }
|
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[9]]} }
|
||||||
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[10]]} }
|
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[10]]} }
|
||||||
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[11]]} }
|
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[11]]} }
|
||||||
TableModelColumn { display: function(modelIndex){return parsedIntrinsic[modelIndex.row][intrinsicModel.columnNames[12]]} }
|
|
||||||
//https://doc.qt.io/qt-5/qml-qt-labs-qmlmodels-tablemodel.html#appendRow-method
|
//https://doc.qt.io/qt-5/qml-qt-labs-qmlmodels-tablemodel.html#appendRow-method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +543,7 @@ Panel {
|
||||||
font.family: MaterialIcons.fontFamily
|
font.family: MaterialIcons.fontFamily
|
||||||
ToolTip.text: "Next Group (Alt+Right)"
|
ToolTip.text: "Next Group (Alt+Right)"
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
enabled: root.cameraInitIndex < root.cameraInits.count - 1
|
enabled: nodesCB.currentIndex < root.cameraInits.count - 1
|
||||||
onClicked: nodesCB.incrementCurrentIndex()
|
onClicked: nodesCB.incrementCurrentIndex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ import QtQuick.Controls 2.3
|
||||||
/**
|
/**
|
||||||
* SortFilderDelegateModel adds sorting and filtering capabilities on a source model.
|
* SortFilderDelegateModel adds sorting and filtering capabilities on a source model.
|
||||||
*
|
*
|
||||||
* The way model data is accessed can be overriden by redefining the modelData function.
|
* The way model data is accessed can be overridden by redefining the modelData function.
|
||||||
* This is useful if the value is not directly accessible from the model and needs
|
* This is useful if the value is not directly accessible from the model and needs
|
||||||
* some extra logic.
|
* some extra logic.
|
||||||
*
|
*
|
||||||
* Regarding filtering, any type of value can be used as 'filterValue' (variant).
|
* Regarding filtering, any type of value can be used as 'filterValue' (variant).
|
||||||
* Filtering behavior can also be overriden by redefining the respectFilter function.
|
* Filtering behavior can also be overridden by redefining the respectFilter function.
|
||||||
*
|
*
|
||||||
* Based on http://doc.qt.io/qt-5/qtquick-tutorials-dynamicview-dynamicview4-example.html
|
* Based on http://doc.qt.io/qt-5/qtquick-tutorials-dynamicview-dynamicview4-example.html
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.pragma library
|
.pragma library
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform 'GET' request on url, and bind 'callback' to onreadystatechange (with XHR objet as parameter).
|
* Perform 'GET' request on url, and bind 'callback' to onreadystatechange (with XHR object as parameter).
|
||||||
*/
|
*/
|
||||||
function get(url, callback) {
|
function get(url, callback) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
|
@ -4,8 +4,8 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// required for perspective transform
|
// required for perspective transform
|
||||||
property real sizeX: 1675.0 // might be overrided in ColorCheckerViewer
|
property real sizeX: 1675.0 // might be overridden in ColorCheckerViewer
|
||||||
property real sizeY: 1125.0 // might be overrided in ColorCheckerViewer
|
property real sizeY: 1125.0 // might be overridden in ColorCheckerViewer
|
||||||
|
|
||||||
property var colors: null
|
property var colors: null
|
||||||
property var window: null
|
property var window: null
|
||||||
|
|
|
@ -200,7 +200,7 @@ FloatingPane {
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
opacity: featureType.viewer.visible ? 1.0 : 0.6
|
opacity: featureType.viewer.visible ? 1.0 : 0.6
|
||||||
}
|
}
|
||||||
// Tracks visibility toogle
|
// Tracks visibility toggle
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: tracksVisibilityButton
|
id: tracksVisibilityButton
|
||||||
checkable: true
|
checkable: true
|
||||||
|
@ -213,7 +213,7 @@ FloatingPane {
|
||||||
}
|
}
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
}
|
}
|
||||||
// Matches visibility toogle
|
// Matches visibility toggle
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: matchesVisibilityButton
|
id: matchesVisibilityButton
|
||||||
checkable: true
|
checkable: true
|
||||||
|
@ -225,7 +225,7 @@ FloatingPane {
|
||||||
}
|
}
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
}
|
}
|
||||||
// Landmarks visibility toogle
|
// Landmarks visibility toggle
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: landmarksVisibilityButton
|
id: landmarksVisibilityButton
|
||||||
checkable: true
|
checkable: true
|
||||||
|
|
|
@ -94,7 +94,7 @@ void main()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Viewport projection breaks down for one or two vertices.
|
// Viewport projection breaks down for one or two vertices.
|
||||||
// Caclulate what we can here and defer rest to fragment shader.
|
// Calculate what we can here and defer rest to fragment shader.
|
||||||
// Since this is coherent for the entire primitive the conditional
|
// Since this is coherent for the entire primitive the conditional
|
||||||
// in the fragment shader is still cheap as all concurrent
|
// in the fragment shader is still cheap as all concurrent
|
||||||
// fragment shader invocations will take the same code path.
|
// fragment shader invocations will take the same code path.
|
||||||
|
|
|
@ -21,7 +21,7 @@ Entity {
|
||||||
property Layer frontLayerComponent
|
property Layer frontLayerComponent
|
||||||
property var window
|
property var window
|
||||||
|
|
||||||
/// Camera to consider for positionning
|
/// Camera to consider for positioning
|
||||||
property Camera camera: null
|
property Camera camera: null
|
||||||
|
|
||||||
/// True while at least one media is being loaded
|
/// True while at least one media is being loaded
|
||||||
|
@ -190,7 +190,7 @@ Entity {
|
||||||
// whether MediaLoader has been fully instantiated by the NodeInstantiator
|
// whether MediaLoader has been fully instantiated by the NodeInstantiator
|
||||||
property bool fullyInstantiated: false
|
property bool fullyInstantiated: false
|
||||||
|
|
||||||
// explicitely store some attached model properties for outside use and ease binding
|
// explicitly store some attached model properties for outside use and ease binding
|
||||||
readonly property var attribute: model.attribute
|
readonly property var attribute: model.attribute
|
||||||
readonly property int idx: index
|
readonly property int idx: index
|
||||||
readonly property var modelSource: attribute || model.source
|
readonly property var modelSource: attribute || model.source
|
||||||
|
@ -216,7 +216,7 @@ Entity {
|
||||||
property string finalSource: model.requested ? currentSource : ""
|
property string finalSource: model.requested ? currentSource : ""
|
||||||
|
|
||||||
// To use only if we want to draw the input source and not the current node output (Warning: to use with caution)
|
// To use only if we want to draw the input source and not the current node output (Warning: to use with caution)
|
||||||
// There is maybe a better way to do this to avoid overwritting bindings which should be readonly properties
|
// There is maybe a better way to do this to avoid overwriting bindings which should be readonly properties
|
||||||
function drawInputSource() {
|
function drawInputSource() {
|
||||||
rawSource = Qt.binding(() => instantiatedEntity.currentNode ? instantiatedEntity.currentNode.attribute("input").value: "")
|
rawSource = Qt.binding(() => instantiatedEntity.currentNode ? instantiatedEntity.currentNode.attribute("input").value: "")
|
||||||
currentSource = Qt.binding(() => rawSource)
|
currentSource = Qt.binding(() => rawSource)
|
||||||
|
|
|
@ -120,7 +120,7 @@ Item {
|
||||||
}
|
}
|
||||||
Action {
|
Action {
|
||||||
id: displayLensDistortionToolBarAction
|
id: displayLensDistortionToolBarAction
|
||||||
text: "Display Lens Distorsion Toolbar"
|
text: "Display Lens Distortion Toolbar"
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: true
|
checked: true
|
||||||
enabled: viewer2D.useLensDistortionViewer
|
enabled: viewer2D.useLensDistortionViewer
|
||||||
|
|
|
@ -613,7 +613,7 @@ ApplicationWindow {
|
||||||
Action {
|
Action {
|
||||||
text: "About Meshroom"
|
text: "About Meshroom"
|
||||||
onTriggered: aboutDialog.open()
|
onTriggered: aboutDialog.open()
|
||||||
// shoud be StandardKey.HelpContents, but for some reason it's not stable
|
// should be StandardKey.HelpContents, but for some reason it's not stable
|
||||||
// (may cause crash, requires pressing F1 twice after closing the popup)
|
// (may cause crash, requires pressing F1 twice after closing the popup)
|
||||||
shortcut: "F1"
|
shortcut: "F1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,8 +358,9 @@ class ViewpointWrapper(QObject):
|
||||||
""" Get camera vertical field of view in degrees. """
|
""" Get camera vertical field of view in degrees. """
|
||||||
if not self.solvedIntrinsics:
|
if not self.solvedIntrinsics:
|
||||||
return None
|
return None
|
||||||
pxFocalLength = self.solvedIntrinsics["pxFocalLength"]
|
focalLength = self.solvedIntrinsics["focalLength"]
|
||||||
return 2.0 * math.atan(self.orientedImageSize.height() / (2.0 * float(pxFocalLength[0]))) * 180 / math.pi
|
sensorHeight = self.solvedIntrinsics["sensorHeight"]
|
||||||
|
return 2.0 * math.atan(float(sensorHeight) / (2.0 * float(focalLength))) * 180.0 / math.pi
|
||||||
|
|
||||||
@Property(type=QUrl, notify=denseSceneParamsChanged)
|
@Property(type=QUrl, notify=denseSceneParamsChanged)
|
||||||
def undistortedImageSource(self):
|
def undistortedImageSource(self):
|
||||||
|
|
|
@ -87,7 +87,7 @@ class QmlInstantEngine(QQmlApplicationEngine):
|
||||||
self._extensions = extensions
|
self._extensions = extensions
|
||||||
|
|
||||||
def setVerbose(self, verboseValue):
|
def setVerbose(self, verboseValue):
|
||||||
""" Activate (True) or desactivate (False) the verbose. """
|
""" Activate (True) or deactivate (False) the verbose. """
|
||||||
self._verbose = verboseValue
|
self._verbose = verboseValue
|
||||||
|
|
||||||
def addFile(self, filename):
|
def addFile(self, filename):
|
||||||
|
|
Loading…
Add table
Reference in a new issue