-
Notifications
You must be signed in to change notification settings - Fork 7
2 DevDoc
Implementation notes: It is easy to write a node for an existing cli tool, but if you want to contribute your node to the main Meshroom repository, a native Meshroom implementation is preferred. It can be a pure python node or c++ implementation on the alicevision side with the corresponding python cli node for Meshroom. This is to ensure multi platform compatibility and reduce dependencies on third parties. Licenses should be compatible with MPL2. Another acceptable implementation for external tools would be to provide a "path to installation" field to link the external tool from within the node.example
https://meshroom-manual.readthedocs.io/en/latest/feature-documentation/core/nodes.html
Here are the basics on how to implement new nodes:
-
CommandLineNodes: nodes run external cli programs - this is how most Meshroom nodes work.(exe files are placed in Meshroom-2019.2.0\aliceVision\bin)
class Convert2MVE(desc.CommandLineNode):
commandLine = 'aliceVision_exportMVE2 {allParams}'
Runs aliceVision_exportMVE2.exe with all parameters. {allParams} is supported by native alicevision plugins (loads all parameters with --param).
For external programs cli parameters need to be adjusted (example):
Using Mogrify (ImageMagick)
class ImageMasking(desc.CommandLineNode):
commandLine = 'mogrify -format png -path {outputValue} -type Grayscale -negate -fill black -fuzz {fuzzValue}% +opaque "#ffffff" -blur {radiusValue}x{sigmaValue} -type Bilevel -depth 1 {inputValue}/*jpg'
Runs mogrify.exe with defined parameters
- Native Python nodes
It is possible to implement new nodes in python without running an external program from the cli.
Here is a good examples for pure python nodes: https://github.com/alicevision/meshroom/blob/develop/meshroom/nodes/aliceVision/SketchfabUpload.py and https://github.com/alicevision/meshroom/pull/641/files (import modules)
Additional packages can be copied into the 'lib' folder ('/meshroom-2019.2.0/lib')
Good reference: https://github.com/natowi/meshroom_external_plugins/issues/2
class Publish(desc.Node):
(Has also some interesting code: https://github.com/alicevision/meshroom/blob/develop/meshroom/nodes/aliceVision/CameraInit.py)
GUI elements
References on different supported GUI elements for nodes can be found here
Meshroom default nodes support the following GUI elements:
version = "1.1" --> needs to be increased to avoid incompatibility issues
File
desc.File(
name='outputTextures',
label='Output Textures',
description='Folder for output mesh: OBJ, material and texture files.',
value=desc.Node.internalFolder + 'texture_*.{outputTextureFileTypeValue}',
uid=[],
group='',
),
DropDown
desc.ChoiceParam(
name='textureSide',
label='Texture Side',
description='''Output texture size''',
value=8192,
values=(1024, 2048, 4096, 8192, 16384),
exclusive=True,
uid=[0],
),
String
`desc.StringParam(`
`name='transformation',`
`label='Transformation',`
`description="Required only for 'transformation' and 'from_single_camera' methods:\n"`
`" * transformation: Align [X,Y,Z] to +Y-axis, rotate around Y by R deg, scale by S; syntax: X,Y,Z;R;S\n"`
`" * from_single_camera: Camera UID or image filename",`
`value='',`
`uid=[0],`
`),`
Checkbox (Boolean)
desc.BoolParam(
name='fillHoles',
label='Fill Holes',
description='Fill Texture holes with plausible values',
value=False,
uid=[0],
),
RangeSlider (Integer)
advanced=True, --> hide option by default, show only in advanced mode
desc.IntParam(
name='padding',
label='Padding',
description='''Texture edge padding size in pixel''',
value=5,
range=(0, 20, 1),
uid=[0],
advanced=True,
),
RangeSlider (Float)
desc.FloatParam(
name='bestScoreThreshold',
label='Best Score Threshold',
description='''(0.0 to disable filtering based on threshold to relative best score)''',
value=0.1,
range=(0.0, 1.0, 0.01),
uid=[0],
advanced=True,
),
GroupAttribute
- A macro Attribute composed of several Attributes
- :param groupDesc: the description of the Attributes composing this group
- GroupAttribute only supports dict input values (param:{}, value:{}, type:{})
- Check that 'value' contains the exact same set of keys as GroupAttribute's group description and that every child value match corresponding child attribute description.
desc.GroupAttribute(
name="multiBandNbContrib",
label="MultiBand contributions",
groupDesc=[
desc.IntParam(name="high", label="High Freq", description="High Frequency Band", value=1, uid=[0], range=None),
desc.IntParam(name="midHigh", label="Mid-High Freq", description="Mid-High Frequency Band", value=5, uid=[0], range=None),
desc.IntParam(name="midLow", label="Mid-Low Freq", description="Mid-Low Frequency Band", value=10, uid=[0], range=None),
desc.IntParam(name="low", label="Low Freq", description="Low Frequency Band", value=0, uid=[0], range=None),
],
description='''Number of contributions per frequency band for multiband blending (each frequency band also contributes to lower bands)''',
advanced=True,
),
ListAttribute
- A list of Attributes
- :param elementDesc: the Attribute description of elements to store in that list
- ListAttribute only supports list/tuple input values (param:{}, value:{}, type:{})
desc.ListAttribute(
elementDesc=desc.File(
name="featuresFolder",
label="Features Folder",
description="",
value="",
uid=[0],
),
name="featuresFolders",
label="Features Folders",
description="Folder(s) containing the extracted features and descriptors."
),
Viewpoint = [
desc.IntParam(name="viewId", label="Id", description="Image UID", value=-1, uid=[0], range=None),
desc.IntParam(name="poseId", label="Pose Id", description="Pose Id", value=-1, uid=[0], range=None),
desc.File(name="path", label="Image Path", description="Image Filepath", value="", uid=[0]),
desc.IntParam(name="intrinsicId", label="Intrinsic", description="Internal Camera Parameters", value=-1, uid=[0], range=None),
desc.IntParam(name="rigId", label="Rig", description="Rig Parameters", value=-1, uid=[0], range=None),
desc.IntParam(name="subPoseId", label="Rig Sub-Pose", description="Rig Sub-Pose Parameters", value=-1, uid=[0], range=None),
desc.StringParam(name="metadata", label="Image Metadata", description="", value="", uid=[], advanced=True),
]
desc.ListAttribute(
name="viewpoints",
elementDesc=desc.GroupAttribute(name="viewpoint", label="Viewpoint", description="", groupDesc=Viewpoint),
label="Viewpoints",
description="Input viewpoints",
group="",
),
DynamicNodeSize
- DynamicNodeSize expresses a dependency to an input attribute to define the size of a Node in terms of individual tasks for parallelization.
- If the attribute is a link to another node, Node's size will be the same as this connected node.
- If the attribute is a ListAttribute, Node's size will be the size of this list.
size = desc.DynamicNodeSize('inputFiles')
inputs = [
desc.ListAttribute(
elementDesc=desc.File(
name="input",
label="Input",
description="",
value="",
uid=[0],
),
name="inputFiles",
label="Input Files",
description="Input Files to publish.",
group="",
),
MultiDynamicNodeSize
MultiDynamicNodeSize expresses dependencies to multiple input attributes to define the size of a node in terms of individual tasks for parallelization. Works as DynamicNodeSize and sum the sizes of each dependency.
StaticNodeSize
StaticNodeSize expresses a static Node size in terms of individual tasks for parallelization.
Meshroom is a GUI for Alicevision
Alicevision is written in C++ and derived from OpenMVG in 2016.
Many OpenMVG features are not (yet) available in Alicevision/Meshroom.
https://github.com/alicevision/meshroom/blob/develop/meshroom/core/desc.py
https://github.com/alicevision/meshroom/tree/develop/tests
https://github.com/alicevision/meshroom/blob/develop/tests/test_invalidation.py