Skip to content

2 DevDoc

Simon edited this page Jan 12, 2022 · 21 revisions

Implementing new nodes

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:

  1. CommandLineNodes: nodes run external cli programs - this is how most Meshroom nodes work.(exe files are placed in Meshroom-2019.2.0\aliceVision\bin)

    Simple example

 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

  1. 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):

https://github.com/alicevision/meshroom/blob/develop/meshroom/nodes/aliceVision/Publish.py

https://github.com/alicevision/meshroom/blob/develop/meshroom/nodes/aliceVision/SketchfabUpload.py

(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

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

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

`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

desc.BoolParam(
            name='fillHoles',
            label='Fill Holes',
            description='Fill Texture holes with plausible values',
            value=False,
            uid=[0],
        ),

RangeSlider (Integer)

desc IntParam

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

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

desc 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

desc 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."
        ),

desc ListAttribute-2

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.

About

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.

details

https://github.com/alicevision/meshroom/blob/develop/meshroom/core/desc.py

todo

https://github.com/alicevision/meshroom/tree/develop/tests

https://github.com/alicevision/meshroom/blob/develop/tests/test_invalidation.py

Clone this wiki locally