def surface_poisson(script, octree_depth=<NUM_LIT:10>, solver_divide=<NUM_LIT:8>,<EOL>samples_per_node=<NUM_LIT:1.0>, offset=<NUM_LIT:1.0>):

Use the points and normals to build a surface using the Poisson
        Surface reconstruction approach.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        octree_depth (int): Set the depth of the Octree used for extracting the
            final surface. Suggested range 5..10. Higher numbers mean higher
            precision in the reconstruction but also higher processing times.
            Be patient.
        solver_divide (int): This integer argument specifies the depth at which
            a block Gauss-Seidel solver is used to solve the Laplacian
            equation. Using this parameter helps reduce the memory overhead at
            the cost of a small increase in reconstruction time. In practice,
            the authors have found that for reconstructions of depth 9 or
            higher a subdivide depth of 7 or 8 can reduce the memory usage. The
            default value is 8.
        samples_per_node (float): This floating point value specifies the
            minimum number of sample points that should fall within an octree
            node as the octree
construction is adapted to sampling density.
            For noise-free samples, small values in the range [1.0 - 5.0] can
            be used. For more noisy samples, larger values in the range
            [15.0 - 20.0] may be needed to provide a smoother, noise-reduced,
            reconstruction. The default value is 1.0.
        offset (float): This floating point value specifies a correction value
            for the isosurface threshold that is chosen. Values less than 1
            mean internal offsetting, greater than 1 mean external offsetting.
            Good values are in the range 0.5 .. 2. The default value is 1.0
            (no offsetting).

    Layer stack:
        Creates 1 new layer 'Poisson mesh'
        Current layer is changed to new layer

    MeshLab versions:
        1.3.4BETA


def surface_poisson_screened(script, visible_layer=False, depth=<NUM_LIT:8>,<EOL>full_depth=<NUM_LIT:5>, cg_depth=<NUM_LIT:0>, scale=<NUM_LIT>,<EOL>samples_per_node=<NUM_LIT>, point_weight=<NUM_LIT>,<EOL>iterations=<NUM_LIT:8>, confidence=False, pre_clean=False):

This surface reconstruction algorithm creates watertight
        surfaces from oriented point sets.

    The filter uses the original code of Michael Kazhdan and Matthew Bolitho
    implementing the algorithm in the following paper:

    Michael Kazhdan, Hugues Hoppe,
    "Screened Poisson surface reconstruction"
    ACM Trans. Graphics, 32(3), 2013

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        visible_layer (bool): If True all the visible layers will be used for
            providing the points
        depth (int): This integer is the maximum depth of the tree that will
            be used for surface reconstruction. Running at depth d corresponds
            to solving on a voxel grid whose resolution is no larger than
            2^d x 2^d x 2^d. Note that since the reconstructor adapts the
            octree to the sampling density, the specified reconstruction depth
            is only an upper bound. The default value for this parameter is 8.
        full_depth (int): This integer specifies the depth beyond depth the
            octree will be adapted. At coarser depths, the octree will be
            complete, containing all 2^d x 2^d x 2^d nodes. The default value
            for this parameter is 5.
        cg_depth (int): This integer is the depth up to which a
            conjugate-gradients solver will be used to solve the linear system.
            Beyond this depth Gauss-Seidel relaxation will be used. The default
            value for this parameter is 0.
        scale (float): This floating point value specifies the ratio between
            the diameter of the cube used for reconstruction and the diameter
            of the samples' bounding cube.  The default value is 1.1.
        samples_per_node (float): This floating point value specifies the
            minimum number of sample points that should fall within an octree
            node as the octree construction is adapted to sampling density. For
            noise-free samples, small values in the range [1.0 - 5.0] can be
            used. For more noisy samples, larger values in the range
            [15.0 - 20.0] may be needed to provide a smoother, noise-reduced,
            reconstruction. The default value is 1.5.
        point_weight (float): This floating point value specifies the
            importance that interpolation of the point samples is given in the
            formulation of the screened Poisson equation. The results of the
            original (unscreened) Poisson Reconstruction can be obtained by
            setting this value to 0. The default value for this parameter is 4.
        iterations (int): This integer value specifies the number of
            Gauss-Seidel relaxations to be performed at each level of the
            hierarchy. The default value for this parameter is 8.
        confidence (bool): If True this tells the reconstructor to use the
            quality as confidence information; this is done by scaling the unit
            normals with the quality values. When the flag is not enabled, all
            normals are normalized to have unit-length prior to reconstruction.
        pre_clean (bool): If True will force a cleaning pre-pass on the data
            removing all unreferenced vertices or vertices with null normals.

    Layer stack:
        Creates 1 new layer 'Poisson mesh'
        Current layer is not changed

    MeshLab versions:
        2016.12


def curvature_flipping(script, angle_threshold=<NUM_LIT:1.0>, curve_type=<NUM_LIT:0>,<EOL>selected=False):

Use the points and normals to build a surface using the Poisson
        Surface reconstruction approach.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        angle_threshold (float): To avoid excessive flipping/swapping we
            consider only couple of faces with a significant diedral angle
            (e.g. greater than the indicated threshold).
        curve_type (int): Choose a metric to compute surface curvature on vertices
            H = mean curv, K = gaussian curv, A = area per vertex
            1: Mean curvature = H
            2: Norm squared mean curvature = (H * H) / A
            3: Absolute curvature:
                if(K >= 0) return 2 * H
                else return 2 * sqrt(H ^ 2 - A * K)

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def voronoi(script, hole_num=<NUM_LIT:50>, target_layer=None, sample_layer=None, thickness=<NUM_LIT:0.5>, backward=True):

if target_layer is None:<EOL><INDENT>target_layer = script.current_layer()<EOL><DEDENT>if sample_layer is None:<EOL><INDENT>sampling.poisson_disk(script, sample_num=hole_num)<EOL>sample_layer = script.last_layer()<EOL><DEDENT>vert_color.voronoi(script, target_layer=target_layer, source_layer=sample_layer, backward=backward)<EOL>select.vert_quality(script, min_quality=<NUM_LIT:0.0>, max_quality=thickness)<EOL>if backward:<EOL><INDENT>select.invert(script)<EOL><DEDENT>delete.selected(script)<EOL>smooth.laplacian(script, iterations=<NUM_LIT:3>)<EOL>return None<EOL>

Turn a model into a surface with Voronoi style holes in it

    References:
    http://meshlabstuff.blogspot.com/2009/03/creating-voronoi-sphere.html
    http://meshlabstuff.blogspot.com/2009/04/creating-voronoi-sphere-2.html

    Requires FilterScript object

    Args:
        script: the FilterScript object to write the filter to. Does not
            work with a script filename.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Select all the faces of the current mesh

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        faces (bool): If True the filter will select all the faces.
        verts (bool): If True the filter will select all the vertices.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Clear the current set of selected faces

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        faces (bool): If True the filter will deselect all the faces.
        verts (bool): If True the filter will deselect all the vertices.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def invert(script, face=True, vert=True):

Invert the current set of selected faces

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        faces (bool): If True the filter will invert the selected faces.
        verts (bool): If True the filter will invert the selected vertices.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Select vertices and faces on the boundary

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>for _ in range(iterations):<EOL><INDENT>util.write_filter(script, filter_xml)<EOL><DEDENT>return None<EOL>

Grow (dilate, expand) the current set of selected faces

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): the number of times to grow the selection.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Shrink (erode, reduce) the current set of selected faces

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): the number of times to shrink the selection.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Select only self intersecting faces

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Select the non manifold vertices that do not belong to non manifold
        edges.

    For example two cones connected by their apex. Vertices incident on
    non manifold edges are ignored.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Select the faces and the vertices incident on non manifold edges (e.g.
        edges where more than two faces are incident).

    Note that this function selects the components that are related to
    non manifold edges. The case of non manifold vertices is specifically
    managed by nonmanifold_vert.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def small_parts(script, ratio=<NUM_LIT>, non_closed_only=False):

Select the small disconnected parts (components) of a mesh.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        ratio (float): This ratio (between 0 and 1) defines the meaning of
            'small' as the threshold ratio between the number of faces of the
            largest component and the other ones. A larger value will select
            more components.
        non_closed_only (bool): Select only non-closed components.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def vert_quality(script, min_quality=<NUM_LIT:0.0>, max_quality=<NUM_LIT>, inclusive=True):

Select all the faces and vertexes within the specified vertex quality
        range.

    Args:
        script: the FilterScript object or script filename to write
            the filter] to.
        min_quality (float): Minimum acceptable quality value.
        max_quality (float): Maximum acceptable quality value.
        inclusive (bool): If True only the faces with ALL the vertices within
            the specified range are selected. Otherwise any face with at least
            one vertex within the range is selected.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(function).replace('<STR_LIT:&>', '<STR_LIT>').replace('<STR_LIT:<>', '<STR_LIT>')),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Boolean function using muparser lib to perform face selection over
        current mesh.

    See help(mlx.muparser_ref) for muparser reference documentation.

    It's possible to use parenthesis, per-vertex variables and boolean operator:
        (, ), and, or, <, >, =
    It's possible to use per-face variables like attributes associated to the three
    vertices of every face.

    Variables (per face):
        x0, y0, z0 for first vertex; x1,y1,z1 for second vertex; x2,y2,z2 for third vertex
        nx0, ny0, nz0, nx1, ny1, nz1, etc. for vertex normals
        r0, g0, b0, a0, etc. for vertex color
        q0, q1, q2 for quality
        wtu0, wtv0, wtu1, wtv1, wtu2, wtv2 (per wedge texture coordinates)
        ti for face texture index (>= ML2016.12)
        vsel0, vsel1, vsel2 for vertex selection (1 yes, 0 no) (>= ML2016.12)
        fr, fg, fb, fa for face color (>= ML2016.12)
        fq for face quality (>= ML2016.12)
        fnx, fny, fnz for face normal (>= ML2016.12)
        fsel face selection (1 yes, 0 no) (>= ML2016.12)

    Args:
        script: the FilterScript object or script filename to write
            the filter] to.
        function (str): a boolean function that will be evaluated in order
            to select a subset of faces.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def vert_function(script, function='<STR_LIT>', strict_face_select=True):

if script.ml_version == '<STR_LIT>':<EOL><INDENT>strict_select = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(strict_face_select).lower()),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>])<EOL><DEDENT>else:<EOL><INDENT>strict_select = '<STR_LIT>'<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(function).replace('<STR_LIT:&>', '<STR_LIT>').replace('<STR_LIT:<>', '<STR_LIT>')),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>strict_select,<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Boolean function using muparser lib to perform vertex selection over current mesh.

    See help(mlx.muparser_ref) for muparser reference documentation.

    It's possible to use parenthesis, per-vertex variables and boolean operator:
        (, ), and, or, <, >, =
    It's possible to use the following per-vertex variables in the expression:

    Variables:
        x, y, z (coordinates)
        nx, ny, nz (normal)
        r, g, b, a (color)
        q (quality)
        rad
        vi (vertex index)
        vtu, vtv (texture coordinates)
        ti (texture index)
        vsel (is the vertex selected? 1 yes, 0 no)
        and all custom vertex attributes already defined by user.

    Args:
        script: the FilterScript object or script filename to write
            the filter] to.
        function (str): a boolean function that will be evaluated in order
            to select a subset of vertices. Example: (y > 0) and (ny > 0)
        strict_face_select (bool): if True a face is selected if ALL its
            vertices are selected. If False a face is selected if at least
            one of its vertices is selected. ML v1.3.4BETA only; this is
            ignored in 2016.12. In 2016.12 only vertices are selected.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def cylindrical_vert(script, radius=<NUM_LIT:1.0>, inside=True):

if inside:<EOL><INDENT>function = '<STR_LIT>'.format(radius)<EOL><DEDENT>else:<EOL><INDENT>function = '<STR_LIT>'.format(radius)<EOL><DEDENT>vert_function(script, function=function)<EOL>return None<EOL>

Select all vertices within a cylindrical radius

    Args:
        radius (float): radius of the sphere
        center_pt (3 coordinate tuple or list): center point of the sphere

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def spherical_vert(script, radius=<NUM_LIT:1.0>, center_pt=(<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>)):

function = '<STR_LIT>'.format(<EOL>center_pt[<NUM_LIT:0>], center_pt[<NUM_LIT:1>], center_pt[<NUM_LIT:2>], radius)<EOL>vert_function(script, function=function)<EOL>return None<EOL>

Select all vertices within a spherical radius

    Args:
        radius (float): radius of the sphere
        center_pt (3 coordinate tuple or list): center point of the sphere

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def laplacian(script, iterations=<NUM_LIT:1>, boundary=True, cotangent_weight=True,<EOL>selected=False):

Laplacian smooth of the mesh: for each vertex it calculates the average
        position with nearest vertex

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): The number of times that the whole algorithm (normal
            smoothing + vertex fitting) is iterated.
        boundary (bool): If true the boundary edges are smoothed only by
            themselves (e.g. the polyline forming the boundary of the mesh is
            independently smoothed). Can reduce the shrinking on the border but
            can have strange effects on very small boundaries.
        cotangent_weight (bool): If True the cotangent weighting scheme is
            computed for the averaging of the position. Otherwise (False) the
            simpler umbrella scheme (1 if the edge is present) is used.
        selected (bool): If selected the filter is performed only on the
            selected faces

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


HC Laplacian Smoothing, extended version of Laplacian Smoothing, based
        on the paper of Vollmer, Mencl, and Muller

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def taubin(script, iterations=<NUM_LIT:10>, t_lambda=<NUM_LIT:0.5>, t_mu=-<NUM_LIT>, selected=False):

The lambda & mu Taubin smoothing, it make two steps of smoothing, forth
        and back, for each iteration.

    Based on:
    Gabriel Taubin
    "A signal processing approach to fair surface design"
    Siggraph 1995

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): The number of times that the taubin smoothing is
            iterated. Usually it requires a larger number of iteration than the
            classical laplacian.
        t_lambda (float): The lambda parameter of the Taubin Smoothing algorithm
        t_mu (float): The mu parameter of the Taubin Smoothing algorithm
        selected (bool): If selected the filter is performed only on the
            selected faces

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def twostep(script, iterations=<NUM_LIT:3>, angle_threshold=<NUM_LIT>, normal_steps=<NUM_LIT:20>, fit_steps=<NUM_LIT:20>,<EOL>selected=False):

Two Step Smoothing, a feature preserving/enhancing fairing filter.

    It is based on a Normal Smoothing step where similar normals are averaged
    together and a step where the vertexes are fitted on the new normals.

    Based on:
    A. Belyaev and Y. Ohtake,
    "A Comparison of Mesh Smoothing Methods"
    Proc. Israel-Korea Bi-National Conf. Geometric Modeling and Computer
    Graphics, pp. 83-87, 2003.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): The number of times that the whole algorithm (normal
            smoothing + vertex fitting) is iterated.
        angle_threshold (float): Specify a threshold angle (0..90) for features
            that you want to be preserved.  Features forming angles LARGER than
            the specified threshold will be preserved.
            0 -> no smoothing
            90 -> all faces will be smoothed
        normal_steps (int): Number of iterations of normal smoothing step. The
            larger the better and (the slower)
        fit_steps (int): Number of iterations of the vertex fitting procedure
        selected (bool): If selected the filter is performed only on the
            selected faces

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def depth(script, iterations=<NUM_LIT:3>, viewpoint=(<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>), selected=False):

A laplacian smooth that is constrained to move vertices only along the
        view direction.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): The number of times that the whole algorithm (normal
            smoothing + vertex fitting) is iterated.
        viewpoint (vector tuple or list): The position of the view point that
            is used to get the constraint direction.
        selected (bool): If selected the filter is performed only on the
            selected faces

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def join(script, merge_visible=True, merge_vert=False, delete_layer=True,<EOL>keep_unreferenced_vert=False):

Flatten all or only the visible layers into a single new mesh.

    Transformations are preserved. Existing layers can be optionally
    deleted.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        merge_visible (bool): merge only visible layers
        merge_vert (bool): merge the vertices that are duplicated among
            different layers. Very useful when the layers are spliced portions
            of a single big mesh.
        delete_layer (bool): delete all the merged layers. If all layers are
            visible only a single layer will remain after the invocation of
            this filter.
        keep_unreferenced_vert (bool): Do not discard unreferenced vertices
            from source layers. Necessary for point-only layers.

    Layer stack:
        Creates a new layer "Merged Mesh"
        Changes current layer to the new layer
        Optionally deletes all other layers

    MeshLab versions:
        2016.12
        1.3.4BETA

    Bugs:
        UV textures: not currently preserved, however will be in a future
            release. https://github.com/cnr-isti-vclab/meshlab/issues/128
        merge_visible: it is not currently possible to change the layer
            visibility from meshlabserver, however this will be possible
            in the future https://github.com/cnr-isti-vclab/meshlab/issues/123


filter_xml = '<STR_LIT>'<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>if (layer_num is None) or (layer_num == script.current_layer()):<EOL><INDENT>util.write_filter(script, filter_xml)<EOL>script.del_layer(script.current_layer())<EOL><DEDENT>else:<EOL><INDENT>cur_layer = script.current_layer()<EOL>change(script, layer_num)<EOL>util.write_filter(script, filter_xml)<EOL>if layer_num < script.current_layer():<EOL><INDENT>change(script, cur_layer - <NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>change(script, cur_layer)<EOL><DEDENT>script.del_layer(layer_num)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>util.write_filter(script, filter_xml)<EOL><DEDENT>return None<EOL>

Delete layer

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        layer_num (int): the number of the layer to delete. Default is the
            current layer. Not supported on the file base API.

    Layer stack:
        Deletes a layer
        will change current layer if deleted layer is lower in the stack

    MeshLab versions:
        2016.12
        1.3.4BETA


def rename(script, label='<STR_LIT:blank>', layer_num=None):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(label),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>if (layer_num is None) or (layer_num == script.current_layer()):<EOL><INDENT>util.write_filter(script, filter_xml)<EOL>script.layer_stack[script.current_layer()] = label<EOL><DEDENT>else:<EOL><INDENT>cur_layer = script.current_layer()<EOL>change(script, layer_num)<EOL>util.write_filter(script, filter_xml)<EOL>change(script, cur_layer)<EOL>script.layer_stack[layer_num] = label<EOL><DEDENT><DEDENT>else:<EOL><INDENT>util.write_filter(script, filter_xml)<EOL><DEDENT>return None<EOL>

Rename layer label

    Can be useful for outputting mlp files, as the output file names use
    the labels.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        label (str): new label for the mesh layer
        layer_num (int): layer number to rename. Default is the
            current layer. Not supported on the file base API.

    Layer stack:
        Renames a layer

    MeshLab versions:
        2016.12
        1.3.4BETA


if layer_num is None:<EOL><INDENT>if isinstance(script, mlx.FilterScript):<EOL><INDENT>layer_num = script.last_layer()<EOL><DEDENT>else:<EOL><INDENT>layer_num = <NUM_LIT:0><EOL><DEDENT><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(layer_num),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>script.set_current_layer(layer_num)<EOL><DEDENT>return None<EOL>

Change the current layer by specifying the new layer number.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        layer_num (int): the number of the layer to change to. Default is the
            last layer if script is a mlx.FilterScript object; if script is a
            filename the default is the first layer.

    Layer stack:
        Modifies current layer

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>if (layer_num is None) or (layer_num == script.current_layer()):<EOL><INDENT>util.write_filter(script, filter_xml)<EOL>script.add_layer('<STR_LIT>'.format(script.layer_stack[script.current_layer()]), True)<EOL><DEDENT>else:<EOL><INDENT>change(script, layer_num)<EOL>util.write_filter(script, filter_xml)<EOL>script.add_layer('<STR_LIT>'.format(script.layer_stack[layer_num]), True)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>util.write_filter(script, filter_xml)<EOL><DEDENT>return None<EOL>

Duplicate a layer.

    New layer label is '*_copy'.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        layer_num (int): layer number to duplicate. Default is the
            current layer. Not supported on the file base API.

    Layer stack:
        Creates a new layer
        Changes current layer to the new layer

    MeshLab versions:
        2016.12
        1.3.4BETA


def split_parts(script, part_num=None, layer_num=None):

filter_xml = '<STR_LIT>'<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>if (layer_num is not None) and (layer_num != script.current_layer()):<EOL><INDENT>change(script, layer_num)<EOL><DEDENT>util.write_filter(script, filter_xml)<EOL>if part_num is not None:<EOL><INDENT>for i in range(part_num):<EOL><INDENT>script.add_layer('<STR_LIT>'.format(i), True)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>script.add_layer('<STR_LIT>', True)<EOL>print('<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>util.write_filter(script, filter_xml)<EOL><DEDENT>return None<EOL>

Split current layer into many layers, one for each part (connected
        component)

    Mesh is split so that the largest part is the lowest named layer "CC 0"
    and the smallest part is the highest numbered "CC" layer.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        part_num (int): the number of parts in the model. This is needed in
            order to properly create and manage the layer stack. Can be found
            with mlx.compute.measure_topology.
        layer_num (int): the number of the layer to split. Default is the
            current layer. Not supported on the file base API.

    Layer stack:
        Creates a new layer for each part named "CC 0", "CC 1", etc.
        Changes current layer to the last new layer

    MeshLab versions:
        2016.12
        1.3.4BETA

    Bugs:
        UV textures: not currently preserved, however will be in a future
            release. https://github.com/cnr-isti-vclab/meshlab/issues/127


if layer_num is None:<EOL><INDENT>layer_num = script.current_layer()<EOL><DEDENT>if layer_num != <NUM_LIT:0>:<EOL><INDENT>change(script, <NUM_LIT:0>)<EOL><DEDENT>for i in range(layer_num):<EOL><INDENT>delete(script, <NUM_LIT:0>)<EOL><DEDENT>return None<EOL>

Delete all layers below the specified one.

    Useful for MeshLab ver 2016.12, whcih will only output layer 0.


select.nonmanifold_vert(script)<EOL>selected(script, face=False)<EOL>return None<EOL>

Select & delete the non manifold vertices that do not belong to
        non manifold edges.

    For example two cones connected by their apex. Vertices incident on
    non manifold edges are ignored.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


select.nonmanifold_edge(script)<EOL>selected(script, face=False)<EOL>return None<EOL>

Select & delete the faces and the vertices incident on
        non manifold edges (e.g. edges where more than two faces are incident).

    Note that this function selects the components that are related to
    non manifold edges. The case of non manifold vertices is specifically
    managed by nonmanifold_vert.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


select.small_parts(script, ratio, non_closed_only)<EOL>selected(script)<EOL>return None<EOL>

Select & delete the small disconnected parts (components) of a mesh.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        ratio (float): This ratio (between 0 and 1) defines the meaning of
            'small' as the threshold ratio between the number of faces of the
            largest component and the other ones. A larger value will select
            more components.
        non_closed_only (bool): Select only non-closed components.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def selected(script, face=True, vert=True):

if face and vert:<EOL><INDENT>filter_xml = '<STR_LIT>'<EOL><DEDENT>elif face and not vert:<EOL><INDENT>filter_xml = '<STR_LIT>'<EOL><DEDENT>elif not face and vert:<EOL><INDENT>filter_xml = '<STR_LIT>'<EOL><DEDENT>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Delete selected vertices and/or faces

    Note: if the mesh has no faces (e.g. a point cloud) you must
    set face=False, or the vertices will not be deleted

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        face (bool): if True the selected faces will be deleted. If vert
            is also True, then all the vertices surrounded by those faces will
            also be deleted. Note that if no faces are selected (only vertices)
            then this filter will not do anything. For example, if you want to
            delete a point cloud selection, you must set this to False.
        vert (bool): if True the selected vertices will be deleted.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>util.write_filter(script, filter_xml)<EOL>unreferenced_vert(script)<EOL>return None<EOL>

For each non manifold edge it iteratively deletes the smallest area
        face until it becomes two-manifold.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


if script.ml_version == '<STR_LIT>':<EOL><INDENT>filter_xml = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>filter_xml = '<STR_LIT>'<EOL><DEDENT>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Check for every vertex on the mesh: if it is NOT referenced by a face,
        removes it.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Delete all the duplicate faces.

    Two faces are considered equal if they are composed by the same set of
    vertices, regardless of the order of the vertices.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Check for every vertex on the mesh: if there are two vertices with
        the same coordinates they are merged into a single one.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Remove null faces (the ones with area equal to zero)

    Args:
        script: the FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def hausdorff_distance(script, sampled_layer=<NUM_LIT:1>, target_layer=<NUM_LIT:0>,<EOL>save_sample=False, sample_vert=True, sample_edge=True,<EOL>sample_faux_edge=False, sample_face=True,<EOL>sample_num=<NUM_LIT:1000>, maxdist=<NUM_LIT:10>):

Compute the Hausdorff Distance between two meshes, sampling one of the
        two and finding for each sample the closest point over the other mesh.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        sampled_layer (int): The mesh layer whose surface is sampled. For each
            sample we search the closest point on the target mesh layer.
        target_layer (int): The mesh that is sampled for the comparison.
        save_sample (bool): Save the position and distance of all the used
            samples on both the two surfaces, creating two new layers with two
            point clouds representing the used samples.
        sample_vert (bool): For the search of maxima it is useful to sample
            vertices and edges of the mesh with a greater care. It is quite
            probable that the farthest points falls along edges or on mesh
            vertexes, and with uniform montecarlo sampling approaches the
            probability of taking a sample over a vertex or an edge is
            theoretically null. On the other hand this kind of sampling could
            make the overall sampling distribution slightly biased and slightly
            affects the cumulative results.
        sample_edge (bool): see sample_vert
        sample_faux_edge (bool): see sample_vert
        sample_face (bool): see sample_vert
        sample_num (int): The desired number of samples. It can be smaller or
            larger than the mesh size, and according to the chosen sampling
            strategy it will try to adapt.
        maxdist (int): Sample points for which we do not find anything within
            this distance are rejected and not considered neither for averaging
            nor for max.

    Layer stack:
        If save_sample is True, two new layers are created: 'Hausdorff Closest
            Points' and 'Hausdorff Sample Point'; and the current layer is
            changed to the last newly created layer.
        If save_sample is False, no impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def poisson_disk(script, sample_num=<NUM_LIT:1000>, radius=<NUM_LIT:0.0>,<EOL>montecarlo_rate=<NUM_LIT:20>, save_montecarlo=False,<EOL>approx_geodesic_dist=False, subsample=False, refine=False,<EOL>refine_layer=<NUM_LIT:0>, best_sample=True, best_sample_pool=<NUM_LIT:10>,<EOL>exact_num=False, radius_variance=<NUM_LIT:1.0>):

Create a new layer populated with a point sampling of the current mesh.

    Samples are generated according to a Poisson-disk distribution, using the
    algorithm described in:

    'Efficient and Flexible Sampling with Blue Noise Properties of Triangular Meshes'
    Massimiliano Corsini, Paolo Cignoni, Roberto Scopigno
    IEEE TVCG 2012

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        sample_num (int): The desired number of samples. The radius of the disk
            is calculated according to the sampling density.
        radius (float): If not zero this parameter overrides the previous
            parameter to allow exact radius specification.
        montecarlo_rate (int): The over-sampling rate that is used to generate
            the intial Monte Carlo samples (e.g. if this parameter is 'K' means
            that 'K * sample_num' points will be used). The generated
            Poisson-disk samples are a subset of these initial Monte Carlo
            samples. Larger numbers slow the process but make it a bit more
            accurate.
        save_montecarlo (bool): If True, it will generate an additional Layer
            with the Monte Carlo sampling that was pruned to build the Poisson
            distribution.
        approx_geodesic_dist (bool): If True Poisson-disk distances are
            computed using an approximate geodesic distance, e.g. an Euclidean
            distance weighted by a function of the difference between the
            normals of the two points.
        subsample (bool): If True the original vertices of the base mesh are
            used as base set of points. In this case the sample_num should be
            obviously much smaller than the original vertex number. Note that
            this option is very useful in the case you want to subsample a
            dense point cloud.
        refine (bool): If True the vertices of the refine_layer mesh layer are
            used as starting vertices, and they will be utterly refined by
            adding more and more points until possible.
        refine_layer (int): Used only if refine is True.
        best_sample (bool): If True it will use a simple heuristic for choosing
            the samples. At a small cost (it can slow the process a bit) it
            usually improves the maximality of the generated sampling.
        best_sample_pool (bool): Used only if best_sample is True. It controls
            the number of attempts that it makes to get the best sample. It is
            reasonable that it is smaller than the Monte Carlo oversampling
            factor.
        exact_num (bool): If True it will try to do a dicotomic search for the
            best Poisson-disk radius that will generate the requested number of
            samples with a tolerance of the 0.5%. Obviously it takes much
            longer.
        radius_variance (float): The radius of the disk is allowed to vary
            between r and r*var. If this parameter is 1 the sampling is the
            same as the Poisson-disk Sampling.

    Layer stack:
        Creates new layer 'Poisson-disk Samples'. Current layer is NOT changed
            to the new layer (see Bugs).
        If save_montecarlo is True, creates a new layer 'Montecarlo Samples'.
            Current layer is NOT changed to the new layer (see Bugs).

    MeshLab versions:
        2016.12
        1.3.4BETA

    Bugs:
        Current layer is NOT changed to the new layer, which is inconsistent
            with the majority of filters that create new layers.


def mesh_element(script, sample_num=<NUM_LIT:1000>, element='<STR_LIT>'):

if element.lower() == '<STR_LIT>':<EOL><INDENT>element_num = <NUM_LIT:0><EOL><DEDENT>elif element.lower() == '<STR_LIT>':<EOL><INDENT>element_num = <NUM_LIT:1><EOL><DEDENT>elif element.lower() == '<STR_LIT>':<EOL><INDENT>element_num = <NUM_LIT:2><EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(element_num),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(sample_num),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, FilterScript):<EOL><INDENT>script.add_layer('<STR_LIT>')<EOL><DEDENT>return None<EOL>

Create a new layer populated with a point sampling of the current mesh,
        at most one sample for each element of the mesh is created.

    Samples are taking in a uniform way, one for each element
    (vertex/edge/face); all the elements have the same probabilty of being
    choosen.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        sample_num (int): The desired number of elements that must be chosen.
            Being a subsampling of the original elements if this number should
            not be larger than the number of elements of the original mesh.
        element (enum in ['VERT', 'EDGE', 'FACE']): Choose what mesh element
            will be used for the subsampling. At most one point sample will
            be added for each one of the chosen elements

    Layer stack:
        Creates new layer 'Sampled Mesh'. Current layer is changed to the new
            layer.

    MeshLab versions:
        2016.12
        1.3.4BETA


def clustered_vert(script, cell_size=<NUM_LIT:1.0>, strategy='<STR_LIT>', selected=False):

if strategy.lower() == '<STR_LIT>':<EOL><INDENT>strategy_num = <NUM_LIT:0><EOL><DEDENT>elif strategy.lower() == '<STR_LIT>':<EOL><INDENT>strategy_num = <NUM_LIT:1><EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(cell_size),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(strategy_num),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(selected).lower()),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, FilterScript):<EOL><INDENT>script.add_layer('<STR_LIT>')<EOL><DEDENT>return None<EOL>

Create a new layer populated with a subsampling of the vertexes of the
        current mesh

    The subsampling is driven by a simple one-per-gridded cell strategy.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        cell_size (float): The size of the cell of the clustering grid. Smaller the cell finer the resulting mesh. For obtaining a very coarse mesh use larger values.
        strategy (enum 'AVERAGE' or 'CENTER'): Average: for each cell we take the average of the sample falling into. The resulting point is a new point.
Closest to center: for each cell we take the sample that is closest to the center of the cell. Choosen vertices are a subset of the original ones.
        selected (bool): If true only for the filter is applied only on the selected subset of the mesh.

    Layer stack:
        Creates new layer 'Cluster Samples'. Current layer is changed to the new
            layer.

    MeshLab versions:
        2016.12
        1.3.4BETA


def flat_plane(script, plane=<NUM_LIT:0>, aspect_ratio=False):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % plane,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(aspect_ratio).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def per_triangle(script, sidedim=<NUM_LIT:0>, textdim=<NUM_LIT>, border=<NUM_LIT:2>, method=<NUM_LIT:1>):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % sidedim,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textdim,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % border,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % method,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def voronoi(script, region_num=<NUM_LIT:10>, overlap=False):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % region_num,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(overlap).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def isometric(script, targetAbstractMinFaceNum=<NUM_LIT>, targetAbstractMaxFaceNum=<NUM_LIT>,<EOL>stopCriteria=<NUM_LIT:1>, convergenceSpeed=<NUM_LIT:1>, DoubleStep=True):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % targetAbstractMinFaceNum,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % targetAbstractMaxFaceNum,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % stopCriteria,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % convergenceSpeed,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(DoubleStep).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % BorderSize,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Isometric parameterization: Build Atlased Mesh

    This actually generates the UV mapping from the isometric parameterization


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % AbsName,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Isometric parameterization: Save Abstract Domain


Isometric parameterization: Load Abstract Domain


def isometric_transfer(script, sourceMesh=<NUM_LIT:0>, targetMesh=<NUM_LIT:1>):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % sourceMesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % targetMesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Isometric parameterization: transfer between meshes

    Provide the layer numbers of the source and target meshes.


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % SamplingRate,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def set_texture(script, textName="<STR_LIT>", textDim=<NUM_LIT>):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textName,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textDim,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def project_rasters(script, tex_file_out="<STR_LIT>", tex_size=<NUM_LIT>,<EOL>fill_atlas_gaps=False, depth_threshold=<NUM_LIT:0.5>,<EOL>selected=False, use_angle=True, use_distance=True,<EOL>use_borders=True, use_silhouettes=True, use_alpha=False):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_file_out,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_size,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(fill_atlas_gaps).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % depth_threshold,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(selected).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(use_angle).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(use_distance).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(use_borders).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(use_silhouettes).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(use_alpha).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Set texture

    Creates new texture file
    tex_file_out = must be png
    fill_atlas_gaps  = setting this to false will leave the unprojected area transparent. This can then be easily composed with the original texture with PIL


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % texsize,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textName,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(colorCorrection).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % colorCorrectionFilterSize,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useDistanceWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useImgBorderWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useAlphaWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(cleanIsolatedTriangles).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(stretchingAllowed).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textureGutter,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


def param_from_rasters(script, useDistanceWeight=True, useImgBorderWeight=True,<EOL>useAlphaWeight=False, cleanIsolatedTriangles=True,<EOL>stretchingAllowed=False, textureGutter=<NUM_LIT:4>):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useDistanceWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useImgBorderWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(useAlphaWeight).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(cleanIsolatedTriangles).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(stretchingAllowed).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % textureGutter,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>


pass<EOL>

Reference documentation for muparser.

    muparser is used by many internal MeshLab filters, specifically those
    where you can control parameters via a mathematical expression. Examples:
        transform.function
        select.vert_function
        vert_color.function

    The valid variables that can be used in an expression are given in the
    documentation for the individual functions. Generally, it's possible to use
    the following per-vertex variables in the expression:

    Variables (per vertex):
        x, y, z (coordinates)
        nx, ny, nz (normal)
        r, g, b, a (color)
        q (quality)
        rad
        vi (vertex index)
        vtu, vtv (texture coordinates)
        ti (texture index)
        vsel (is the vertex selected? 1 yes, 0 no)
        and all custom vertex attributes already defined by user.

    Below is a list of the predefined operators and functions within muparser.

    muparser homepage: http://beltoforion.de/article.php?a=muparser
    ml_version='1.3.4Beta' muparser version: 1.3.2
    ml_version='2016.12' muparser version: 2.2.5

    Built-in functions:
        Name    Argc.   Explanation
        ----------------------------
        sin     1       sine function
        cos     1       cosine function
        tan     1       tangens function
        asin    1       arcus sine function
        acos    1       arcus cosine function
        atan    1       arcus tangens function
        atan2   2       *
        sinh    1       hyperbolic sine function
        cosh    1       hyperbolic cosine
        tanh    1       hyperbolic tangens function
        asinh   1       hyperbolic arcus sine function
        acosh   1       hyperbolic arcus tangens function
        atanh   1       hyperbolic arcur tangens function
        log2    1       logarithm to the base 2
        log10   1       logarithm to the base 10
        log     1       logarithm to the base 10
        ln      1       logarithm to base e (2.71828...)
        exp     1       e raised to the power of x
        sqrt    1       square root of a value
        sign    1       sign function -1 if x<0; 1 if x>0
        rint    1       round to nearest integer
        abs     1       absolute value
        min     var.    min of all arguments
        max     var.    max of all arguments
        sum     var.    sum of all arguments
        avg     var.    mean value of all arguments

    Built-in binary operators
        Operator    Description                Priority
        -----------------------------------------------
        =           assignment                 -1
        &&          logical and*                1
        ||          logical or*                 2
        <=          less or equal               4
        >=          greater or equal            4
        !=          not equal                   4
        ==          equal                       4
        >           greater than                4
        <           less than                   4
        +           addition                    5
        -           subtraction                 5
        *           multiplication              6
        /           division                    6
        ^           raise x to the power of y   7

    Built-in ternary operator
        ?:         (Test ? Then_value : Otherwise_value)*

    *: Some operators in older muparser (ml_version='1.3.4Beta') are different:
        and        logical and                 1
        or         logical or                  2
        if         ternary operator: if(Test, Then_value, Otherwise_value)
        atan2      not included; use mp_atan2 below


return '<STR_LIT>'.replace(<EOL>'<STR_LIT>', str(math.pi)).replace('<STR_LIT:y>', y).replace('<STR_LIT:x>', x)<EOL>

muparser atan2 function

    Implements an atan2(y,x) function for older muparser versions (<2.1.0);
    atan2 was added as a built-in function in muparser 2.1.0

    Args:
        y (str): y argument of the atan2(y,x) function
        x (str): x argument of the atan2(y,x) function

    Returns:
        A muparser string that calculates atan2(y,x)


"""<STR_LIT>"""<EOL>i = '<STR_LIT>'.format(u1=u[<NUM_LIT:1>], u2=u[<NUM_LIT:2>], v1=v[<NUM_LIT:1>], v2=v[<NUM_LIT:2>])<EOL>j = '<STR_LIT>'.format(u0=u[<NUM_LIT:0>], u2=u[<NUM_LIT:2>], v0=v[<NUM_LIT:0>], v2=v[<NUM_LIT:2>])<EOL>k = '<STR_LIT>'.format(u0=u[<NUM_LIT:0>], u1=u[<NUM_LIT:1>], v0=v[<NUM_LIT:0>], v1=v[<NUM_LIT:1>])<EOL>return [i, j, k]<EOL>

muparser cross product function

    Compute the cross product of two 3x1 vectors

    Args:
        u (list or tuple of 3 strings): first vector
        v (list or tuple of 3 strings): second vector
    Returns:
        A list containing a muparser string of the cross product


vector = []<EOL>for i, x in enumerate(v1):<EOL><INDENT>vector.append('<STR_LIT>'.format(scalar, v1[i]))<EOL><DEDENT>return vector<EOL>


def torus_knot(t, p=<NUM_LIT:3>, q=<NUM_LIT:4>, scale=<NUM_LIT:1.0>, radius=<NUM_LIT>):

return ['<STR_LIT>'.format(t=t, p=p, scale=scale, radius=radius),<EOL>'<STR_LIT>'.format(t=t, p=p, scale=scale, radius=radius),<EOL>'<STR_LIT>'.format(t=t, q=q, scale=scale)]<EOL>

A tight (small inner crossings) (p,q) torus knot parametric curve

    Source (for trefoil): https://en.wikipedia.org/wiki/Trefoil_knot


return [<NUM_LIT:2>*scale*(<NUM_LIT:1> + radius), <NUM_LIT:2>*scale*(<NUM_LIT:1> + radius), <NUM_LIT:2>*scale]<EOL>

Bounding box of the sprecified torus knot


def vert_attr(script, name='<STR_LIT>', function='<STR_LIT>'):

Add a new Per-Vertex scalar attribute to current mesh and fill it with
        the defined function.

    The specified name can be used in other filter functions.

    It's possible to use parenthesis, per-vertex variables and boolean operator:
        (, ), and, or, <, >, =
    It's possible to use the following per-vertex variables in the expression:

    Variables:
        x, y, z (coordinates)
        nx, ny, nz (normal)
        r, g, b, a (color)
        q (quality)
        rad
        vi (vertex index)
        ?vtu, vtv (texture coordinates)
        ?ti (texture index)
        ?vsel (is the vertex selected? 1 yes, 0 no)
        and all custom vertex attributes already defined by user.

    Args:
        script: the FilterScript object or script filename to write
            the filter] to.
        name (str): the name of new attribute. You can access attribute in
            other filters through this name.
        function (str): function to calculate custom attribute value for each
            vertex

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def face_attr(script, name='<STR_LIT>', function='<STR_LIT>'):

Add a new Per-Face attribute to current mesh and fill it with
        the defined function..

    The specified name can be used in other filter functions.

    It's possible to use parenthesis, per-face variables and boolean operator:
        (, ), and, or, <, >, =

    It's possible to use per-face variables like attributes associated to the
    three vertices of every face.

    It's possible to use the following per-face variables in the expression:

    Variables:
        x0,y0,z0 (first vertex); x1,y1,z1 (second vertex); x2,y2,z2 (third vertex)
        nx0,ny0,nz0; nx1,ny1,nz1; nx2,ny2,nz2 (normals)
        r0,g0,b0 (color)
        q0,q1,q2 (quality)
        wtu0, wtv0; wtu1, wtv1; wtu2, wtv2 (per wedge tex coord)
        fi (face index)
        ?fsel (is the vertex selected? 1 yes, 0 no)
        fi (face index)
        and all custom face attributes already defined by user.

    Args:
        script: the FilterScript object or script filename to write
            the filter] to.
        name (str): the name of new attribute. You can access attribute in
            other filters through this name.
        function (str): function to calculate custom attribute value for each
            face

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def vq_function(script, function='<STR_LIT>', normalize=False, color=False):

:Quality function using muparser to generate new Quality for every vertex
It's possibile to use the following per-vertex variables in the expression:
x, y, z, nx, ny, nz (normal), r, g, b (color), q (quality), rad, vi,
and all custom vertex attributes already defined by user.

    function function to generate new Quality for every vertex
    normalize if checked normalize all quality values in range [0..1]
    color if checked map quality generated values into per-vertex color


def fq_function(script, function='<STR_LIT>', normalize=False, color=False):

:Quality function using muparser to generate new Quality for every face
Insert three function each one for quality of the three vertex of a face
It's possibile to use per-face variables like attributes associated to the three vertex of every face.
x0,y0,z0 for first vertex; x1,y1,z1 for second vertex; x2,y2,z2 for third vertex.
and also nx0,ny0,nz0 nx1,ny1,nz1 etc. for normals and r0,g0,b0 for color,q0,q1,q2 for quality.

    function function to generate new Quality for each face
    normalize if checked normalize all quality values in range [0..1]
    color if checked map quality generated values into per-vertex color


def section(script, axis='<STR_LIT:z>', offset=<NUM_LIT:0.0>, surface=False, custom_axis=None,<EOL>planeref=<NUM_LIT:2>):

<EOL>if axis.lower() == '<STR_LIT:x>':<EOL><INDENT>axis_num = <NUM_LIT:0><EOL>axis_name = '<STR_LIT:X>'<EOL><DEDENT>elif axis.lower() == '<STR_LIT:y>':<EOL><INDENT>axis_num = <NUM_LIT:1><EOL>axis_name = '<STR_LIT:Y>'<EOL><DEDENT>elif axis.lower() == '<STR_LIT:z>':<EOL><INDENT>axis_num = <NUM_LIT:2><EOL>axis_name = '<STR_LIT>'<EOL><DEDENT>else:  <EOL><INDENT>axis_num = <NUM_LIT:3><EOL>axis_name = '<STR_LIT>'<EOL>if custom_axis is None:<EOL><INDENT>print('<STR_LIT>',<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>if custom_axis is None:<EOL><INDENT>custom_axis = (<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:1.0>)<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(axis_num),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(custom_axis[<NUM_LIT:0>], custom_axis[<NUM_LIT:1>],<EOL>custom_axis[<NUM_LIT:2>]),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(offset),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(planeref),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(surface).lower()),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>current_layer_label = script.layer_stack[script.current_layer()]<EOL>script.add_layer('<STR_LIT>'.format(current_layer_label, axis_name,<EOL>int(offset)))<EOL>if surface:<EOL><INDENT>script.add_layer('<STR_LIT>'.format(current_layer_label,<EOL>axis_name, int(offset)))<EOL><DEDENT><DEDENT>return None<EOL>

Compute the polyline representing a planar section (a slice) of a mesh.

    If the resulting polyline is closed the result can be filled with a
    triangular mesh representing the section.

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.
        axis (str): The slicing plane is perpendicular to this axis. Accepted
            values are 'x', 'y', or 'z'; any other input will be interpreted
            as a custom axis (although using 'custom' is recommended
            for clarity). Upper or lowercase values are accepted.
        offset (float): Specify an offset of the cross-plane. The offset
            corresponds to the distance along 'axis' from the point specified
            in 'planeref'.
        surface (bool): If True, in addition to a layer with the section
            polyline, also a layer with a triangulated version of the section
            polyline will be created. This only works if the section polyline
            is closed.
        custom_axis (3 component list or tuple): Specify a custom axis as
            a 3 component vector (x, y, z); this is ignored unless 'axis' is
            set  to 'custom'.
        planeref (int): Specify the reference from which the planes are
            shifted. Valid values are:
            0 - Bounding box center
            1 - Bounding box min
            2 - Origin (default)

    Layer stack:
        Creates a new layer '{label}_sect_{axis_name}_{offset}', where
            'axis_name' is one of [X, Y, Z, custom] and 'offest' is
            truncated 'offset'
        If surface is True, create a new layer '{label}_sect_{axis}_{offset}_mesh'
        Current layer is changed to the last (newly created) layer

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>script.parse_geometry = True<EOL><DEDENT>return None<EOL>

Compute a set of geometric measures of a mesh/pointcloud.

    Bounding box extents and diagonal, principal axis, thin shell barycenter
    (mesh only), vertex barycenter and quality-weighted barycenter (pointcloud
    only), surface area (mesh only), volume (closed mesh) and Inertia tensor
    Matrix (closed mesh).

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA

    Bugs:
        Bounding box extents not computed correctly for some volumes


filter_xml = '<STR_LIT>'<EOL>util.write_filter(script, filter_xml)<EOL>if isinstance(script, mlx.FilterScript):<EOL><INDENT>script.parse_topology = True<EOL><DEDENT>return None<EOL>

Compute a set of topological measures over a mesh

    Args:
        script: the mlx.FilterScript object or script filename to write
            the filter to.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def parse_geometry(ml_log, log=None, ml_version='<STR_LIT>', print_output=False):

<EOL>aabb = {}<EOL>geometry = {'<STR_LIT>':aabb}<EOL>with open(ml_log) as fread:<EOL><INDENT>for line in fread:<EOL><INDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>']['<STR_LIT>'] = (line.split()[<NUM_LIT:4>:<NUM_LIT:7>])<EOL>geometry['<STR_LIT>']['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>']['<STR_LIT>'] = (line.split()[<NUM_LIT:4>:<NUM_LIT:7>])<EOL>geometry['<STR_LIT>']['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>']['<STR_LIT:size>'] = (line.split()[<NUM_LIT:4>:<NUM_LIT:7>])<EOL>geometry['<STR_LIT>']['<STR_LIT:size>'] = [util.to_float(val) for val in geometry['<STR_LIT>']['<STR_LIT:size>']]<EOL><DEDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>']['<STR_LIT>'] = util.to_float(line.split()[<NUM_LIT:4>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = util.to_float(line.split()[<NUM_LIT:3>])<EOL>geometry['<STR_LIT>'] = geometry['<STR_LIT>'] * <NUM_LIT><EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>if ml_version == '<STR_LIT>':<EOL><INDENT>geometry['<STR_LIT>'] = util.to_float(line.split()[<NUM_LIT:3>])<EOL><DEDENT>else:<EOL><INDENT>geometry['<STR_LIT>'] = util.to_float(line.split()[<NUM_LIT:4>])<EOL><DEDENT>geometry['<STR_LIT>'] = geometry['<STR_LIT>'] * <NUM_LIT><EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = util.to_float(<EOL>line.split()[<NUM_LIT:7>])<EOL><DEDENT>else:<EOL><INDENT>geometry['<STR_LIT>'] = util.to_float(<EOL>line.split()[<NUM_LIT:7>])<EOL><DEDENT><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = (line.split()[<NUM_LIT:3>:<NUM_LIT:6>])<EOL>geometry['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>'] = (line.split()[<NUM_LIT:4>:<NUM_LIT:7>])<EOL>geometry['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line: <EOL><INDENT>geometry['<STR_LIT>'] = (line.split()[<NUM_LIT:2>:<NUM_LIT:5>])<EOL>geometry['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = (line.split()[<NUM_LIT:4>:<NUM_LIT:7>])<EOL>geometry['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']]<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = []<EOL>for val in range(<NUM_LIT:3>):<EOL><INDENT>row = (next(fread, val).split()[<NUM_LIT:1>:<NUM_LIT:4>])<EOL>row = [util.to_float(b) for b in row]<EOL>geometry['<STR_LIT>'].append(row)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = []<EOL>for val in range(<NUM_LIT:3>):<EOL><INDENT>row = (next(fread, val).split()[<NUM_LIT:1>:<NUM_LIT:4>])<EOL>row = [util.to_float(b) for b in row]<EOL>geometry['<STR_LIT>'].append(row)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>geometry['<STR_LIT>'] = (next(fread).split()[<NUM_LIT:1>:<NUM_LIT:4>])<EOL>geometry['<STR_LIT>'] = [util.to_float(val) for val in geometry['<STR_LIT>']]<EOL>break  <EOL><DEDENT><DEDENT><DEDENT>for key, value in geometry.items():<EOL><INDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>'.format(key, value))<EOL>log_file.close()<EOL><DEDENT>elif print_output:<EOL><INDENT>print('<STR_LIT>'.format(key, value))<EOL><DEDENT><DEDENT>return geometry<EOL>

Parse the ml_log file generated by the measure_geometry function.

    Warnings: Not all keys may exist if mesh is not watertight or manifold

    Args:
        ml_log (str): MeshLab log file to parse
        log (str): filename to log output


def parse_topology(ml_log, log=None, ml_version='<STR_LIT>', print_output=False):

topology = {'<STR_LIT>': True, '<STR_LIT>': <NUM_LIT:0>, '<STR_LIT>': <NUM_LIT:0>}<EOL>with open(ml_log) as fread:<EOL><INDENT>for line in fread:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>vert_edge_face = line.replace('<STR_LIT>', '<STR_LIT:U+0020>').replace('<STR_LIT>', '<STR_LIT:U+0020>').replace('<STR_LIT>', '<STR_LIT:U+0020>').split()<EOL>topology['<STR_LIT>'] = int(vert_edge_face[<NUM_LIT:0>])<EOL>topology['<STR_LIT>'] = int(vert_edge_face[<NUM_LIT:1>])<EOL>topology['<STR_LIT>'] = int(vert_edge_face[<NUM_LIT:2>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = int(line.split()[<NUM_LIT:2>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = int(line.split()[<NUM_LIT:2>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = int(line.split()[<NUM_LIT:4>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = False<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = int(line.split()[<NUM_LIT:2>])<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = int(line.split()[<NUM_LIT:2>])<EOL><DEDENT>if '<STR_LIT>' in line:  <EOL><INDENT>topology['<STR_LIT>'] = line.split()[<NUM_LIT:2>]<EOL>if topology['<STR_LIT>'] != '<STR_LIT>':<EOL><INDENT>topology['<STR_LIT>'] = int(topology['<STR_LIT>'])<EOL><DEDENT><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>topology['<STR_LIT>'] = line.split()[<NUM_LIT:2>]<EOL>if topology['<STR_LIT>'] == '<STR_LIT:a>':<EOL><INDENT>topology['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>topology['<STR_LIT>'] = int(topology['<STR_LIT>'])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>for key, value in topology.items():<EOL><INDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>'.format(key, value))<EOL>log_file.close()<EOL><DEDENT>elif print_output:<EOL><INDENT>print('<STR_LIT>'.format(key, value))<EOL><DEDENT><DEDENT>return topology<EOL>

Parse the ml_log file generated by the measure_topology function.

    Args:
        ml_log (str): MeshLab log file to parse
        log (str): filename to log output

    Returns:
        dict: dictionary with the following keys:
            vert_num (int): number of vertices
            edge_num (int): number of edges
            face_num (int): number of faces
            unref_vert_num (int): number or unreferenced vertices
            boundry_edge_num (int): number of boundary edges
            part_num (int): number of parts (components) in the mesh.
            manifold (bool): True if mesh is two-manifold, otherwise false.
            non_manifold_edge (int): number of non_manifold edges.
            non_manifold_vert (int): number of non-manifold verices
            genus (int or str): genus of the mesh, either a number or
                'undefined' if the mesh is non-manifold.
            holes (int or str): number of holes in the mesh, either a number
                or 'undefined' if the mesh is non-manifold.


def parse_hausdorff(ml_log, log=None, print_output=False):

hausdorff_distance = {"<STR_LIT>": <NUM_LIT:0.0>,<EOL>"<STR_LIT>": <NUM_LIT:0.0>,<EOL>"<STR_LIT>": <NUM_LIT:0.0>,<EOL>"<STR_LIT>": <NUM_LIT:0.0>,<EOL>"<STR_LIT>": <NUM_LIT:0>}<EOL>with open(ml_log) as fread:<EOL><INDENT>result = fread.readlines()<EOL>data = "<STR_LIT>"<EOL>for idx, line in enumerate(result):<EOL><INDENT>m = re.match(r"<STR_LIT>", line)<EOL>if m is not None:<EOL><INDENT>hausdorff_distance["<STR_LIT>"] = int(m.group(<NUM_LIT:1>))<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>data = result[idx + <NUM_LIT:2>]<EOL><DEDENT><DEDENT>m = re.match(r"<STR_LIT>", data)<EOL>hausdorff_distance["<STR_LIT>"] = float(m.group(<NUM_LIT:1>))<EOL>hausdorff_distance["<STR_LIT>"] = float(m.group(<NUM_LIT:2>))<EOL>hausdorff_distance["<STR_LIT>"] = float(m.group(<NUM_LIT:3>))<EOL>hausdorff_distance["<STR_LIT>"] = float(m.group(<NUM_LIT:4>))<EOL>for key, value in hausdorff_distance.items():<EOL><INDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>'.format(key, value))<EOL>log_file.close()<EOL><DEDENT>elif print_output:<EOL><INDENT>print('<STR_LIT>'.format(key, value))<EOL><DEDENT><DEDENT>return hausdorff_distance<EOL><DEDENT>

Parse the ml_log file generated by the hausdorff_distance function.

    Args:
        ml_log (str): MeshLab log file to parse
        log (str): filename to log output

    Returns:
        dict: dictionary with the following keys:
            number_points (int): number of points in mesh
            min_distance (float): minimum hausdorff distance
            max_distance (float): maximum hausdorff distance
            mean_distance (float): mean hausdorff distance
            rms_distance (float): root mean square distance


def handle_error(program_name, cmd, log=None):

print('<STR_LIT>',<EOL>'<STR_LIT>' % program_name,<EOL>'<STR_LIT>')<EOL>print('<STR_LIT>' % (program_name, cmd))<EOL>if log is not None:<EOL><INDENT>print('<STR_LIT>' % log)<EOL><DEDENT>print('<STR_LIT>')<EOL>print('<STR_LIT>' % program_name,<EOL>'<STR_LIT>')<EOL>print('<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>')<EOL>print('<STR_LIT>')<EOL>print('<STR_LIT>')<EOL>while True:<EOL><INDENT>choice = input('<STR_LIT>')<EOL>if choice not in ('<STR_LIT:r>', '<STR_LIT:c>', '<STR_LIT:x>', '<STR_LIT>'):<EOL><INDENT>choice = '<STR_LIT:x>'<EOL><DEDENT>break<EOL><DEDENT>if choice == '<STR_LIT:x>':<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>elif choice == '<STR_LIT>':<EOL><INDENT>print('<STR_LIT>')<EOL>util.delete_all('<STR_LIT>')<EOL>if log is not None:<EOL><INDENT>os.remove(log)<EOL><DEDENT>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>elif choice == '<STR_LIT:c>':<EOL><INDENT>print('<STR_LIT>')<EOL>break_now = True<EOL><DEDENT>elif choice == '<STR_LIT:r>':<EOL><INDENT>print('<STR_LIT>' % program_name)<EOL>break_now = False<EOL><DEDENT>return break_now<EOL>

Subprocess program error handling

    Args:
        program_name (str): name of the subprocess program

    Returns:
        break_now (bool): indicate whether calling program should break out of loop


def run(script='<STR_LIT>', log=None, ml_log=None,<EOL>mlp_in=None, mlp_out=None, overwrite=False, file_in=None,<EOL>file_out=None, output_mask=None, cmd=None, ml_version=ML_VERSION,<EOL>print_meshlabserver_output=True):

if cmd is None:<EOL><INDENT>cmd = '<STR_LIT>'<EOL>if ml_log is not None:<EOL><INDENT>ml_log_file = open(ml_log, '<STR_LIT:w>')<EOL>ml_log_file.close()<EOL>cmd += '<STR_LIT>' % ml_log<EOL><DEDENT>if mlp_in is not None:<EOL><INDENT>mlp_in = util.make_list(mlp_in)<EOL>for val in mlp_in:<EOL><INDENT>cmd += '<STR_LIT>' % val<EOL><DEDENT><DEDENT>if mlp_out is not None:<EOL><INDENT>cmd += '<STR_LIT>' % mlp_out<EOL>if overwrite:<EOL><INDENT>cmd += '<STR_LIT>'<EOL><DEDENT><DEDENT>if (mlp_in is None) and (file_in is None):<EOL><INDENT>file_in = ['<STR_LIT>']<EOL><DEDENT>if file_in is not None:<EOL><INDENT>file_in = util.make_list(file_in)<EOL>for val in file_in:<EOL><INDENT>if val == '<STR_LIT>':<EOL><INDENT>cmd += '<STR_LIT>' % os.path.join(THIS_MODULEPATH, os.pardir,<EOL>'<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>elif val == '<STR_LIT>':<EOL><INDENT>cmd += '<STR_LIT>' % os.path.join(THIS_MODULEPATH, os.pardir,<EOL>'<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>cmd += '<STR_LIT>' % val<EOL><DEDENT><DEDENT><DEDENT>if file_out is not None:<EOL><INDENT>file_out = util.make_list(file_out)<EOL>if output_mask is not None:<EOL><INDENT>output_mask = util.make_list(output_mask)<EOL><DEDENT>else:<EOL><INDENT>output_mask = []<EOL><DEDENT>for index, val in enumerate(file_out):<EOL><INDENT>cmd += '<STR_LIT>' % val<EOL>try:<EOL><INDENT>cmd += '<STR_LIT>' % output_mask[index]<EOL><DEDENT>except IndexError:  <EOL><INDENT>cmd += '<STR_LIT>' % default_output_mask(val, ml_version=ml_version)<EOL><DEDENT><DEDENT><DEDENT>if script is not None:<EOL><INDENT>cmd += '<STR_LIT>' % script<EOL><DEDENT><DEDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>' % cmd)<EOL>log_file.write('<STR_LIT>')<EOL>log_file.close()<EOL>log_file = open(log, '<STR_LIT:a>')<EOL><DEDENT>else:<EOL><INDENT>if print_meshlabserver_output:<EOL><INDENT>log_file = None<EOL>print('<STR_LIT>' % cmd)<EOL>print('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>log_file = open(os.devnull, '<STR_LIT:w>')<EOL><DEDENT><DEDENT>while True:<EOL><INDENT>return_code = subprocess.call(cmd, shell=True,<EOL>stdout=log_file, stderr=log_file,<EOL>universal_newlines=True)<EOL>if log is not None:<EOL><INDENT>log_file.close()<EOL><DEDENT>if (return_code == <NUM_LIT:0>) or handle_error(program_name='<STR_LIT>', cmd=cmd, log=log):<EOL><INDENT>break<EOL><DEDENT><DEDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>')<EOL>log_file.write('<STR_LIT>' % return_code)<EOL>log_file.close()<EOL><DEDENT>return return_code<EOL>

Run meshlabserver in a subprocess.

    Args:
        log (str): filename of the log file for meshlabxml. If not
            None, all meshlabserver stdout and stderr messages
            will be appended to this file.
        ml_log (str): filename of the log file output directly by
            meshlabserver.
        mlp_in (str or list): input meshlab project file. Can be a
            single filename or a list of filenames. Filenames will
            be loaded in the order given. All project files will
            be loaded before individual input files. If you want
            to load project and input files in a different order
            then you should use a custom cmd.
        mlp_out (str): output meshlab project file. Specify a
            single filename (meshlabserver accepts multiple output
            project filenames, however they will all be identical,
            so there is little use). When this option is used all
            layers will be saved as ply files.
        overwrite (bool): when specifying mlp_out, this determines
            whether any existing files will be overwritten (if
            True) or new filenames created (if False). If a new
            project file is created meshes will have '_out' added
            to their name.
        file_in (str or list): input mesh filename. Can be a single
            filename or a list of filenames. Filenames will be
            loaded in the order given. All project files will be
            loaded before individual input files. If you want to
            load project and input files in a different order then
            you should use a custom cmd.
        file_out (str or list): output mesh filename. Can be a
            single filename or a list of filenames. The current
            layer will be saved to this filename or filenames.
            Multiple filenames are useful for saving to multiple
            formats at the same time. Currently there is no way to
            output multiple layers except for saving a mlp project
            file.
        output_mask (str or list): output mask options for the
            output file. Values must include the flag, i.e. -m or
            -output_mask. If this is not provided for an output
            file then function "default_output_mask" is used to
            determine default values.
        script (str): the mlx filter script filename to execute.
        cmd (str): a full meshlabserver command line, such as
            "meshlabserver -input file.stl". If not None, this
            will override all other arguements except for log.
        print_meshlabserver_output (bool): Pass meshlabserver's output to stdout; useful for debugging.
                                           Only used if log is None.

    Notes:
        Meshlabserver can't handle spaces in paths or filenames (on Windows at least; haven't tested on other platforms). Enclosing the name in quotes or escaping the space has no effect.

    Returns:
        return code of meshlabserver process; 0 if successful


fext = os.path.splitext(fbasename)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower()<EOL>material_file = None<EOL>texture_files = []<EOL>vert_colors = False<EOL>face_colors = False<EOL>if fext == '<STR_LIT>':<EOL><INDENT>with open(fbasename, '<STR_LIT:r>') as fread:<EOL><INDENT>for line in fread:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>material_file = os.path.basename(line.split()[<NUM_LIT:1>])<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if material_file is not None:<EOL><INDENT>with open(material_file, '<STR_LIT:r>') as fread:<EOL><INDENT>for line in fread:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>texture_files.append(os.path.basename(line.split()[<NUM_LIT:1>]))<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>elif fext == '<STR_LIT>':<EOL><INDENT>face_element = False<EOL>with open(fbasename, '<STR_LIT:rb>') as fread:<EOL><INDENT>while True:<EOL><INDENT>line = fread.readline().strip().decode('<STR_LIT:ascii>')<EOL>if '<STR_LIT>' in line:<EOL><INDENT>face_element = True<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>if face_element:<EOL><INDENT>face_colors = True<EOL><DEDENT>else:<EOL><INDENT>vert_colors = True<EOL><DEDENT><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>texture_files.append(os.path.basename(line.split()[<NUM_LIT:2>]))<EOL><DEDENT>if '<STR_LIT>' in line:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif fext == '<STR_LIT>':  <EOL><INDENT>namespace = '<STR_LIT>'<EOL>tree = ET.parse(fbasename)<EOL>for elem in tree.findall(<EOL>'<STR_LIT>' % (namespace, namespace, namespace)):<EOL><INDENT>texture_files.append(elem.text)<EOL><DEDENT><DEDENT>elif fext == '<STR_LIT>':<EOL><INDENT>tree = ET.parse(fbasename)<EOL>for elem in tree.iter(tag='<STR_LIT>'):<EOL><INDENT>texture_files.append(elem.attrib['<STR_LIT:url>'])<EOL><DEDENT><DEDENT>elif fext == '<STR_LIT>':<EOL><INDENT>with open(fbasename, '<STR_LIT:r>') as fread:<EOL><INDENT>for line in fread:<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>texture_files.append(os.path.basename(line.split('<STR_LIT:">')[<NUM_LIT:1>]))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif fext != '<STR_LIT>':  <EOL><INDENT>print('<STR_LIT>' % fext)<EOL><DEDENT>texture_files_unique = list(set(texture_files))<EOL>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>')<EOL>log_file.write('<STR_LIT>' % fbasename)<EOL>log_file.write('<STR_LIT>' % texture_files)<EOL>log_file.write('<STR_LIT>' % texture_files_unique)<EOL>log_file.write('<STR_LIT>' % len(texture_files))<EOL>log_file.write(<EOL>'<STR_LIT>' %<EOL>len(texture_files_unique))<EOL>log_file.write('<STR_LIT>' % vert_colors)<EOL>log_file.write('<STR_LIT>' % face_colors)<EOL>log_file.close()<EOL><DEDENT>colors = {'<STR_LIT>':bool(texture_files), '<STR_LIT>':vert_colors, '<STR_LIT>':face_colors}<EOL>return texture_files, texture_files_unique, material_file, colors<EOL>

Finds the filenames of the referenced texture file(s) (and material
    file for obj) for the mesh.

    Args:
        fbasename (str): input filename. Supported file extensions:
            obj
            ply
            dae
            x3d
            wrl
        log (str): filename to log output

    Returns:
        list: list of all of the texture filenames referenced by the input file.
            May contain duplicates if the texture files are referenced more
            than once. List is empty if no texture files are found.
        list: list of all of the unique texture filenames, also empty if no
            texture files are found.
        str: for obj files only, returns the name of the referenced material file.
            Returns None if no material file is found.


def default_output_mask(file_out, texture=True, vert_normals=True, vert_colors=False,<EOL>face_colors=False, ml_version=ML_VERSION):

vn = '<STR_LIT>'<EOL>wt = '<STR_LIT>'<EOL>vc = '<STR_LIT>'<EOL>fc = '<STR_LIT>'<EOL>if ml_version < '<STR_LIT>':<EOL><INDENT>om = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>om = '<STR_LIT>'<EOL><DEDENT>fext = os.path.splitext(file_out)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower()<EOL>if fext in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>om = '<STR_LIT>'<EOL>texture = False<EOL>vert_normals = False<EOL>vert_colors = False<EOL>face_colors = False<EOL>

Set default output mask options based on file extension
Note: v1.34BETA changed -om switch to -m
Possible options (not all options are available for every format):
 vc -> vertex colors
 vf -> vertex flags
 vq -> vertex quality
 vn -> vertex normals
 vt -> vertex texture coords
 fc -> face colors
 ff -> face flags
 fq -> face quality
 fn -> face normals
 wc -> wedge colors
 wn -> wedge normals
 wt -> wedge texture coords


def begin(script='<STR_LIT>', file_in=None, mlp_in=None):

script_file = open(script, '<STR_LIT:w>')<EOL>script_file.write('<STR_LIT>'.join(['<STR_LIT>',<EOL>'<STR_LIT>']))<EOL>script_file.close()<EOL>current_layer = -<NUM_LIT:1><EOL>last_layer = -<NUM_LIT:1><EOL>stl = False<EOL>if mlp_in is not None:<EOL><INDENT>if not isinstance(mlp_in, list):<EOL><INDENT>mlp_in = [mlp_in]<EOL><DEDENT>for val in mlp_in:<EOL><INDENT>tree = ET.parse(val)<EOL>for elem in tree.iter(tag='<STR_LIT>'):<EOL><INDENT>filename = (elem.attrib['<STR_LIT:filename>'])<EOL>current_layer += <NUM_LIT:1><EOL>last_layer += <NUM_LIT:1><EOL>if os.path.splitext(filename)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower() == '<STR_LIT>':<EOL><INDENT>layers.change(script, current_layer)<EOL>clean.merge_vert(script)<EOL>stl = True<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if file_in is not None:<EOL><INDENT>if not isinstance(file_in, list):<EOL><INDENT>file_in = [file_in]<EOL><DEDENT>for val in file_in:<EOL><INDENT>current_layer += <NUM_LIT:1><EOL>last_layer += <NUM_LIT:1><EOL>if os.path.splitext(val)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower() == '<STR_LIT>':<EOL><INDENT>layers.change(script, current_layer)<EOL>clean.merge_vert(script)<EOL>stl = True<EOL><DEDENT><DEDENT><DEDENT>if stl:<EOL><INDENT>layers.change(script, last_layer)  <EOL><DEDENT>elif last_layer == -<NUM_LIT:1>:<EOL><INDENT>file_in = ['<STR_LIT>']<EOL>file_in_descriptor = open(file_in[<NUM_LIT:0>], '<STR_LIT:w>')<EOL>file_in_descriptor.write('<STR_LIT>')<EOL>file_in_descriptor.close()<EOL>layers.delete(script)<EOL><DEDENT>return current_layer, last_layer<EOL>

Create new mlx script and write opening tags.

    Performs special processing on stl files.

    If no input files are provided this will create a dummy
    file and delete it as the first filter. This works around
    the meshlab limitation that it must be provided an input
    file, even if you will be creating a mesh as the first
    filter.


script_file = open(script, '<STR_LIT:a>')<EOL>script_file.write('<STR_LIT>')<EOL>script_file.close()<EOL>


def create_mlp(file_out, mlp_mesh=None, mlp_raster=None):

<EOL>mlp_file = open(file_out, '<STR_LIT:w>')<EOL>mlp_file.write('<STR_LIT:\n>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>']))<EOL>mlp_file.close()<EOL>if mlp_mesh is not None:<EOL><INDENT>mlp_file = open(file_out, '<STR_LIT:a>')<EOL>mlp_file.write('<STR_LIT>')<EOL>for i, val in enumerate(mlp_mesh):<EOL><INDENT>if '<STR_LIT:label>' not in mlp_mesh[i]:<EOL><INDENT>mlp_mesh[i]['<STR_LIT:label>'] = mlp_mesh[i]['<STR_LIT:filename>']<EOL><DEDENT>if '<STR_LIT>' not in mlp_mesh[i]:<EOL><INDENT>mlp_mesh[i]['<STR_LIT>'] = [[<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>], [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>], [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:0>], [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>]]<EOL><DEDENT>mlp_file.write('<STR_LIT>'.format(mlp_mesh[i]['<STR_LIT:filename>'], mlp_mesh[i]['<STR_LIT:label>']))<EOL>mlp_file.write('<STR_LIT:\n>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(m=mlp_mesh[i]['<STR_LIT>'][<NUM_LIT:0>]),<EOL>'<STR_LIT>'.format(m=mlp_mesh[i]['<STR_LIT>'][<NUM_LIT:1>]),<EOL>'<STR_LIT>'.format(m=mlp_mesh[i]['<STR_LIT>'][<NUM_LIT:2>]),<EOL>'<STR_LIT>'.format(m=mlp_mesh[i]['<STR_LIT>'][<NUM_LIT:3>]),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>']))<EOL><DEDENT>mlp_file.write('<STR_LIT>')<EOL>mlp_file.close()<EOL><DEDENT>else:<EOL><INDENT>mlp_file = open(file_out, '<STR_LIT:a>')<EOL>mlp_file.write('<STR_LIT>')<EOL>mlp_file.close()<EOL><DEDENT>if mlp_raster is not None:<EOL><INDENT>mlp_file = open(file_out, '<STR_LIT:a>')<EOL>mlp_file.write('<STR_LIT>')<EOL>for i, val in enumerate(mlp_raster):<EOL><INDENT>if '<STR_LIT:label>' not in mlp_raster[i]:<EOL><INDENT>mlp_raster[i]['<STR_LIT:label>'] = mlp_raster[i]['<STR_LIT:filename>']<EOL><DEDENT>if '<STR_LIT>' not in mlp_raster[i]:<EOL><INDENT>mlp_raster[i]['<STR_LIT>'] = <NUM_LIT:1><EOL><DEDENT>if '<STR_LIT>' not in mlp_raster[i]['<STR_LIT>']:<EOL><INDENT>mlp_raster[i]['<STR_LIT>']['<STR_LIT>'] = [<NUM_LIT:0>, <NUM_LIT:0>]<EOL><DEDENT>if '<STR_LIT>' not in mlp_raster[i]['<STR_LIT>']:<EOL><INDENT>mlp_raster[i]['<STR_LIT>']['<STR_LIT>'] = [int(mlp_raster[i]['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>]/<NUM_LIT:2>), int(mlp_raster[i]['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:1>]/<NUM_LIT:2>)]<EOL><DEDENT>mlp_file.write('<STR_LIT>'.format(mlp_raster[i]['<STR_LIT:label>']))<EOL>mlp_file.write('<STR_LIT:U+0020>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>'.format(m=mlp_raster[i]['<STR_LIT>']['<STR_LIT>']),<EOL>'<STR_LIT>']))<EOL>mlp_file.write('<STR_LIT>'.format(mlp_raster[i]['<STR_LIT>'], mlp_raster[i]['<STR_LIT:filename>']))<EOL>mlp_file.write('<STR_LIT>')<EOL><DEDENT>mlp_file.write('<STR_LIT>')<EOL>mlp_file.close()<EOL><DEDENT>else:<EOL><INDENT>mlp_file = open(file_out, '<STR_LIT:a>')<EOL>mlp_file.write('<STR_LIT>')<EOL>mlp_file.close()<EOL><DEDENT>mlp_file = open(file_out, '<STR_LIT:a>')<EOL>mlp_file.write('<STR_LIT>')<EOL>mlp_file.close()<EOL>return<EOL>

Create mlp file
    mlp_mesh (list containing dictionary)
        filename*
        label
        matrix

    mlp_raster
        filename*
        label
        semantic
        camera
            trans_vector*
            rotation_matrix*
            focal_length*
            image_px*
            image_res_mm_per_px*
            lens_distortion
            center_px
    * Required

    http://vcg.isti.cnr.it/~cignoni/newvcglib/html/shot.html


<EOL>return len(self.layer_stack) - <NUM_LIT:2><EOL>

Returns the index number of the last layer


return self.layer_stack[len(self.layer_stack) - <NUM_LIT:1>]<EOL>

Returns the index number of the current layer


self.layer_stack[len(self.layer_stack) - <NUM_LIT:1>] = layer_num<EOL>return None<EOL>


def add_layer(self, label, change_layer=True):

self.layer_stack.insert(self.last_layer() + <NUM_LIT:1>, label)<EOL>if change_layer:<EOL><INDENT>self.set_current_layer(self.last_layer())<EOL><DEDENT>return None<EOL>

Add new mesh layer to the end of the stack

        Args:
            label (str): new label for the mesh layer
            change_layer (bool): change to the newly created layer


del self.layer_stack[layer_num]<EOL>if layer_num < self.current_layer():<EOL><INDENT>self.set_current_layer(self.current_layer() - <NUM_LIT:1>)<EOL><DEDENT>return None<EOL>


<EOL>if not self.filters:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>script_file_descriptor = open(script_file, '<STR_LIT:w>')<EOL>script_file_descriptor.write('<STR_LIT>'.join(self.opening + self.filters + self.closing))<EOL>script_file_descriptor.close()<EOL>


def run_script(self, log=None, ml_log=None, mlp_out=None, overwrite=False,<EOL>file_out=None, output_mask=None, script_file=None, print_meshlabserver_output=True):

temp_script = False<EOL>temp_ml_log = False<EOL>if self.__no_file_in:<EOL><INDENT>temp_file_in_file = tempfile.NamedTemporaryFile(delete=False, suffix='<STR_LIT>', dir=os.getcwd())<EOL>temp_file_in_file.write(b'<STR_LIT>')<EOL>temp_file_in_file.close()<EOL>self.file_in = [temp_file_in_file.name]<EOL><DEDENT>if not self.filters:<EOL><INDENT>script_file = None<EOL><DEDENT>elif script_file is None:<EOL><INDENT>temp_script = True<EOL>temp_script_file = tempfile.NamedTemporaryFile(delete=False, suffix='<STR_LIT>')<EOL>temp_script_file.close()<EOL>self.save_to_file(temp_script_file.name)<EOL>script_file = temp_script_file.name<EOL><DEDENT>if (self.parse_geometry or self.parse_topology or self.parse_hausdorff) and (ml_log is None):<EOL><INDENT>temp_ml_log = True<EOL>ml_log_file = tempfile.NamedTemporaryFile(delete=False, suffix='<STR_LIT>')<EOL>ml_log_file.close()<EOL>ml_log = ml_log_file.name<EOL><DEDENT>if file_out is None:<EOL><INDENT>file_out = self.file_out<EOL><DEDENT>run(script=script_file, log=log, ml_log=ml_log,<EOL>mlp_in=self.mlp_in, mlp_out=mlp_out, overwrite=overwrite,<EOL>file_in=self.file_in, file_out=file_out, output_mask=output_mask, ml_version=self.ml_version,<EOL>print_meshlabserver_output=print_meshlabserver_output)<EOL>if self.parse_geometry:<EOL><INDENT>self.geometry = compute.parse_geometry(ml_log, log, print_output=print_meshlabserver_output)<EOL><DEDENT>if self.parse_topology:<EOL><INDENT>self.topology = compute.parse_topology(ml_log, log, print_output=print_meshlabserver_output)<EOL><DEDENT>if self.parse_hausdorff:<EOL><INDENT>self.hausdorff_distance = compute.parse_hausdorff(ml_log, log, print_output=print_meshlabserver_output)<EOL><DEDENT>if self.__no_file_in:<EOL><INDENT>os.remove(temp_file_in_file.name)<EOL><DEDENT>if temp_script:<EOL><INDENT>os.remove(temp_script_file.name)<EOL><DEDENT>if temp_ml_log:<EOL><INDENT>os.remove(ml_log_file.name)<EOL><DEDENT>