with self.get_db_hook().get_conn() as cur:<EOL><INDENT>cur.execute(sql)<EOL>return cur.fetchone()<EOL><DEDENT>

Executes the druid sql to druid broker and returns the first resulting row.

:param sql: the sql statement to be executed (str)
:type sql: str


import sys<EOL>from airflow.plugins_manager import operators_modules<EOL>for operators_module in operators_modules:<EOL><INDENT>sys.modules[operators_module.__name__] = operators_module<EOL>globals()[operators_module._name] = operators_module<EOL><DEDENT>


self.log.info('<STR_LIT>', gettempdir())<EOL>if self.env is None:<EOL><INDENT>self.env = os.environ.copy()<EOL><DEDENT>airflow_context_vars = context_to_airflow_vars(context, in_env_var_format=True)<EOL>self.log.info('<STR_LIT>',<EOL>'<STR_LIT:\n>'.join(["<STR_LIT>".format(k, v)<EOL>for k, v in<EOL>airflow_context_vars.items()]))<EOL>self.env.update(airflow_context_vars)<EOL>self.lineage_data = self.bash_command<EOL>with TemporaryDirectory(prefix='<STR_LIT>') as tmp_dir:<EOL><INDENT>with NamedTemporaryFile(dir=tmp_dir, prefix=self.task_id) as tmp_file:<EOL><INDENT>tmp_file.write(bytes(self.bash_command, '<STR_LIT>'))<EOL>tmp_file.flush()<EOL>script_location = os.path.abspath(tmp_file.name)<EOL>self.log.info('<STR_LIT>', script_location)<EOL>def pre_exec():<EOL><INDENT>for sig in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if hasattr(signal, sig):<EOL><INDENT>signal.signal(getattr(signal, sig), signal.SIG_DFL)<EOL><DEDENT><DEDENT>os.setsid()<EOL><DEDENT>self.log.info('<STR_LIT>', self.bash_command)<EOL>sub_process = Popen(<EOL>['<STR_LIT>', tmp_file.name],<EOL>stdout=PIPE,<EOL>stderr=STDOUT,<EOL>cwd=tmp_dir,<EOL>env=self.env,<EOL>preexec_fn=pre_exec)<EOL>self.sub_process = sub_process<EOL>self.log.info('<STR_LIT>')<EOL>line = '<STR_LIT>'<EOL>for raw_line in iter(sub_process.stdout.readline, b'<STR_LIT>'):<EOL><INDENT>line = raw_line.decode(self.output_encoding).rstrip()<EOL>self.log.info(line)<EOL><DEDENT>sub_process.wait()<EOL>self.log.info('<STR_LIT>', sub_process.returncode)<EOL>if sub_process.returncode:<EOL><INDENT>raise AirflowException('<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>return line<EOL>

Execute the bash command in a temporary directory
which will be cleaned afterwards


modname, classname = fullname.rsplit("<STR_LIT:.>", <NUM_LIT:1>)<EOL>try:<EOL><INDENT>with mock(env.config.autodoc_mock_imports):<EOL><INDENT>mod = import_module(modname)<EOL><DEDENT><DEDENT>except ImportError:<EOL><INDENT>raise RoleException("<STR_LIT>" % (modname, ))<EOL><DEDENT>clazz = getattr(mod, classname)<EOL>if not clazz:<EOL><INDENT>raise RoleException("<STR_LIT>" % (classname, modname))<EOL><DEDENT>template_fields = getattr(clazz, "<STR_LIT>")<EOL>if not template_fields:<EOL><INDENT>raise RoleException(<EOL>"<STR_LIT>" % (classname, modname)<EOL>)<EOL><DEDENT>return list(template_fields)<EOL>

Gets template fields for specific operator class.

:param fullname: Full path to operator class.
    For example: ``airflow.contrib.operators.gcp_vision_operator.CloudVisionProductSetCreateOperator``
:return: List of template field
:rtype: list[str]


def template_field_role(app, typ, rawtext, text, lineno, inliner, options={}, content=[]):

text = utils.unescape(text)<EOL>try:<EOL><INDENT>template_fields = get_template_field(app.env, text)<EOL><DEDENT>except RoleException as e:<EOL><INDENT>msg = inliner.reporter.error("<STR_LIT>" % (text, e, ), line=lineno)<EOL>prb = inliner.problematic(rawtext, rawtext, msg)<EOL>return [prb], [msg]<EOL><DEDENT>node = nodes.inline(rawtext=rawtext)<EOL>for i, field in enumerate(template_fields):<EOL><INDENT>if i != <NUM_LIT:0>:<EOL><INDENT>node += nodes.Text("<STR_LIT:U+002CU+0020>")<EOL><DEDENT>node += nodes.literal(field, "<STR_LIT>", nodes.Text(field))<EOL><DEDENT>return [node], []<EOL>

A role that allows you to include a list of template fields in the middle of the text. This is especially
useful when writing guides describing how to use the operator.
The result is a list of fields where each field is shorted in the literal block.

Sample usage::

:template-fields:`airflow.contrib.operators.gcp_natural_language_operator.CloudLanguageAnalyzeSentimentOperator`

For further information look at:

* [http://docutils.sourceforge.net/docs/howto/rst-roles.html](Creating reStructuredText Interpreted
  Text Roles)


def cube(script, size=<NUM_LIT:1.0>, center=False, color=None):

"""<STR_LIT>"""<EOL>size = util.make_list(size, <NUM_LIT:3>)<EOL>if script.ml_version == '<STR_LIT>':<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>'.format(filter_name),<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>if isinstance(script, FilterScript):<EOL><INDENT>script.add_layer('<STR_LIT>', change_layer=True)<EOL><DEDENT>transform.scale(script, value=size)<EOL>if not center:<EOL><INDENT>transform.translate(script, value=[size[<NUM_LIT:0>]/<NUM_LIT:2>, size[<NUM_LIT:1>]/<NUM_LIT:2>, size[<NUM_LIT:2>]/<NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a cube primitive

    Note that this is made of 6 quads, not triangles


def cylinder(script, up='<STR_LIT:z>', height=<NUM_LIT:1.0>, radius=None, radius1=None,<EOL>radius2=None, diameter=None, diameter1=None, diameter2=None,<EOL>center=False, cir_segments=<NUM_LIT:32>, color=None):

if radius is not None and diameter is None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = radius<EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = radius<EOL><DEDENT><DEDENT>if diameter is not None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = diameter / <NUM_LIT:2><EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = diameter / <NUM_LIT:2><EOL><DEDENT><DEDENT>if diameter1 is not None:<EOL><INDENT>radius1 = diameter1 / <NUM_LIT:2><EOL><DEDENT>if diameter2 is not None:<EOL><INDENT>radius2 = diameter2 / <NUM_LIT:2><EOL><DEDENT>if radius1 is None:<EOL><INDENT>radius1 = <NUM_LIT:1.0><EOL><DEDENT>if radius2 is None:<EOL><INDENT>radius2 = radius1<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % height,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % radius1,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % radius2,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % cir_segments,<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>', change_layer=True)<EOL><DEDENT>if not center:<EOL><INDENT>transform.translate(script, [<NUM_LIT:0>, height / <NUM_LIT:2>, <NUM_LIT:0>])<EOL><DEDENT>if up.lower() == '<STR_LIT:z>':<EOL><INDENT>transform.rotate(script, axis='<STR_LIT:x>', angle=<NUM_LIT>)  <EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a cylinder or cone primitive. Usage is based on OpenSCAD.
    # height = height of the cylinder
    # radius1 = radius of the cone on bottom end
    # radius2 = radius of the cone on top end
    # center = If true will center the height of the cone/cylinder around
    # the origin. Default is false, placing the base of the cylinder or radius1
    # radius of cone at the origin.
    #
    cir_segments Number of sides of the polygonal approximation of the cone

    color = specify a color name to apply vertex colors to the newly
    # created mesh


def icosphere(script, radius=<NUM_LIT:1.0>, diameter=None, subdivisions=<NUM_LIT:3>, color=None):

if diameter is not None:<EOL><INDENT>radius = diameter / <NUM_LIT:2><EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % radius,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % subdivisions,<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>', change_layer=True)<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

create an icosphere mesh

    radius Radius of the sphere
    # subdivisions = Subdivision level; Number of the recursive subdivision of the
    # surface. Default is 3 (a sphere approximation composed by 1280 faces).
    # Admitted values are in the range 0 (an icosahedron) to 8 (a 1.3 MegaTris
    # approximation of a sphere). Formula for number of faces: F=20*4^subdiv
    # color = specify a color name to apply vertex colors to the newly
    # created mesh


def sphere_cap(script, angle=<NUM_LIT:1.0>, subdivisions=<NUM_LIT:3>, color=None):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % angle,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % subdivisions,<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>', change_layer=True)<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

angle = Angle of the cone subtending the cap. It must be <180 less than 180
   # subdivisions = Subdivision level; Number of the recursive subdivision of the
   # surface. Default is 3 (a sphere approximation composed by 1280 faces).
   # Admitted values are in the range 0 (an icosahedron) to 8 (a 1.3 MegaTris
   # approximation of a sphere). Formula for number of faces: F=20*4^subdivisions
   # color = specify a color name to apply vertex colors to the newly
   # created mesh


def torus(script, major_radius=<NUM_LIT>, minor_radius=<NUM_LIT:1.0>, inner_diameter=None,<EOL>outer_diameter=None, major_segments=<NUM_LIT>, minor_segments=<NUM_LIT:12>,<EOL>color=None):

if inner_diameter is not None and outer_diameter is not None:<EOL><INDENT>major_radius = (inner_diameter + outer_diameter) / <NUM_LIT:4><EOL>minor_radius = major_radius - inner_diameter / <NUM_LIT:2><EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % major_radius,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % minor_radius,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % major_segments,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % minor_segments,<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>', change_layer=True)<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a torus mesh

    Args:
        major_radius (float, (optional)): radius from the origin to the
            center of the cross sections
        minor_radius (float, (optional)): radius of the torus cross
            section
        inner_diameter (float, (optional)): inner diameter of torus. If
            both inner_diameter and outer_diameter are provided then
            these will override major_radius and minor_radius.,
        outer_diameter (float, (optional)): outer diameter of torus. If
            both inner_diameter and outer_diameter are provided then
            these will override major_radius and minor_radius.
        major_segments (int (optional)): number of segments for the main
            ring of the torus
        minor_segments (int (optional)): number of segments for the minor
            ring of the torus
        color (str (optional)): color name to apply vertex colors to the
            newly created mesh

    Returns:
        None


def grid(script, size=<NUM_LIT:1.0>, x_segments=<NUM_LIT:1>, y_segments=<NUM_LIT:1>, center=False,<EOL>color=None):

size = util.make_list(size, <NUM_LIT:2>)<EOL>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(size[<NUM_LIT:0>]),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(size[<NUM_LIT:1>]),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(x_segments + <NUM_LIT:1>),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(y_segments + <NUM_LIT:1>),<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>util.write_filter(script, filter_xml)<EOL>if isinstance(script, FilterScript):<EOL><INDENT>script.add_layer('<STR_LIT>', change_layer=True)<EOL><DEDENT>"""<STR_LIT>"""<EOL>transform.vert_function(script, z_func='<STR_LIT>')<EOL>"""<STR_LIT>"""<EOL>if center:<EOL><INDENT>transform.translate(script, value=[size[<NUM_LIT:0>]/<NUM_LIT:2>, -size[<NUM_LIT:1>]/<NUM_LIT:2>, <NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>transform.translate(script, value=[size[<NUM_LIT:0>], <NUM_LIT:0>, <NUM_LIT:0>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

2D square/plane/grid created on XY plane

    x_segments # Number of segments in the X direction.
    y_segments # Number of segments in the Y direction.
    center="false" # If true square will be centered on origin;
    otherwise it is place in the positive XY quadrant.


def annulus(script, radius=None, radius1=None, radius2=None, diameter=None,<EOL>diameter1=None, diameter2=None, cir_segments=<NUM_LIT:32>, color=None):

if radius is not None and diameter is None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = radius<EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter is not None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = diameter / <NUM_LIT:2><EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter1 is not None:<EOL><INDENT>radius1 = diameter1 / <NUM_LIT:2><EOL><DEDENT>if diameter2 is not None:<EOL><INDENT>radius2 = diameter2 / <NUM_LIT:2><EOL><DEDENT>if radius1 is None:<EOL><INDENT>radius1 = <NUM_LIT:1><EOL><DEDENT>if radius2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % radius1,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % radius2,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % cir_segments,<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>', change_layer=True)<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a 2D (surface) circle or annulus
    radius1=1 # Outer radius of the circle
    radius2=0 # Inner radius of the circle (if non-zero it creates an annulus)
    color="" # specify a color name to apply vertex colors to the newly created mesh

    OpenSCAD: parameters: diameter overrides radius, radius1 & radius2 override radius


def cylinder_open_hires(script, height=<NUM_LIT:1.0>, radius=<NUM_LIT:1>, diameter=None,<EOL>cir_segments=<NUM_LIT>, height_segments=<NUM_LIT:1>,<EOL>invert_normals=False, center=False, color=None):

if diameter is not None:<EOL><INDENT>radius = diameter / <NUM_LIT:2><EOL><DEDENT>if center:<EOL><INDENT>z_translate = -height / <NUM_LIT:2><EOL><DEDENT>else:<EOL><INDENT>z_translate = <NUM_LIT:0.0><EOL><DEDENT>grid(script,<EOL>[<NUM_LIT:2> * math.pi * radius, height],<EOL>x_segments=cir_segments,<EOL>y_segments=height_segments)<EOL>transform.rotate(script, '<STR_LIT:x>', <NUM_LIT>)<EOL>transform.translate(script, [math.pi * radius / <NUM_LIT:2>, <NUM_LIT:0>, z_translate])<EOL>if not invert_normals:<EOL><INDENT>transform.rotate(script, '<STR_LIT:z>', <NUM_LIT>)<EOL><DEDENT>transform.wrap2cylinder(script, radius)<EOL>clean.merge_vert(script, threshold=<NUM_LIT>)<EOL>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Creates a round open tube, e.g. a cylinder with no top or bottom.

    Useful if you want to wrap it around and join the open ends together, forming a torus.

    invert_normals (bool (optional)): if True normals point outward; in false normals point inward.


def cube_open_hires_old(script, size=<NUM_LIT:1.0>, x_segments=<NUM_LIT:1>, y_segments=<NUM_LIT:1>, z_segments=<NUM_LIT:1>,<EOL>center=False, color=None):

"""<STR_LIT>"""<EOL>size = util.make_list(size, <NUM_LIT:3>)<EOL>grid(script, [size[<NUM_LIT:0>], size[<NUM_LIT:2>]],<EOL>x_segments=x_segments,<EOL>y_segments=z_segments)<EOL>transform.rotate(script, '<STR_LIT:x>', <NUM_LIT>)<EOL>layers.duplicate(script)<EOL>transform.rotate(script, '<STR_LIT:z>', <NUM_LIT>)<EOL>transform.translate(script, [size[<NUM_LIT:0>], size[<NUM_LIT:1>], <NUM_LIT:0>])<EOL>grid(script, [size[<NUM_LIT:2>], size[<NUM_LIT:1>]],<EOL>x_segments=z_segments,<EOL>y_segments=y_segments)<EOL>transform.rotate(script, '<STR_LIT:y>', -<NUM_LIT>)<EOL>layers.duplicate(script)<EOL>transform.rotate(script, '<STR_LIT:z>', <NUM_LIT>)<EOL>transform.translate(script, [size[<NUM_LIT:0>], size[<NUM_LIT:1>], <NUM_LIT:0>])<EOL>layers.join(script)<EOL>clean.merge_vert(script, threshold=<NUM_LIT>)<EOL>if center:<EOL><INDENT>transform.translate(script, [-size[<NUM_LIT:0>] / <NUM_LIT:2>, -size[<NUM_LIT:1>] / <NUM_LIT:2>, -size[<NUM_LIT:2>] / <NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Creates a square open tube, e.g. a box with no top or bottom.

    Useful if you want to wrap it around and join the open ends together, forming a torus.


def cube_open_hires(script, size=<NUM_LIT:1.0>, x_segments=<NUM_LIT:1>, y_segments=<NUM_LIT:1>, z_segments=<NUM_LIT:1>,<EOL>center=False, color=None):

"""<STR_LIT>"""<EOL>size = util.make_list(size, <NUM_LIT:3>)<EOL>grid(script, [<NUM_LIT:2>*(x_segments + y_segments), z_segments],<EOL>x_segments=<NUM_LIT:2>*(x_segments + y_segments),<EOL>y_segments=z_segments)<EOL>transform.rotate(script, '<STR_LIT:x>', <NUM_LIT>)<EOL>if script.ml_version == '<STR_LIT>': <EOL><INDENT>transform.vert_function(script,<EOL>x_func='<STR_LIT>'.format(x_size=x_segments),<EOL>y_func='<STR_LIT>'.format(x_size=x_segments),<EOL>z_func='<STR_LIT:z>')<EOL>transform.vert_function(script,<EOL>x_func='<STR_LIT>'.format(x_size=x_segments, y_size=y_segments),<EOL>y_func='<STR_LIT>'.format(y_size=y_segments),<EOL>z_func='<STR_LIT:z>')<EOL>transform.vert_function(script,<EOL>x_func='<STR_LIT>',<EOL>y_func='<STR_LIT>'.format(y_size=y_segments),<EOL>z_func='<STR_LIT:z>')<EOL><DEDENT>else: <EOL><INDENT>transform.vert_function(script,<EOL>x_func='<STR_LIT>'.format(x_size=x_segments),<EOL>y_func='<STR_LIT>'.format(x_size=x_segments),<EOL>z_func='<STR_LIT:z>')<EOL>transform.vert_function(script,<EOL>x_func='<STR_LIT>'.format(x_size=x_segments, y_size=y_segments),<EOL>y_func='<STR_LIT>'.format(y_size=y_segments),<EOL>z_func='<STR_LIT:z>')<EOL>transform.vert_function(script,<EOL>x_func='<STR_LIT>',<EOL>y_func='<STR_LIT>'.format(y_size=y_segments),<EOL>z_func='<STR_LIT:z>')<EOL><DEDENT>clean.merge_vert(script, threshold=<NUM_LIT>)<EOL>transform.scale(script, [size[<NUM_LIT:0>]/x_segments, size[<NUM_LIT:1>]/y_segments, size[<NUM_LIT:2>]/z_segments])<EOL>if center:<EOL><INDENT>transform.translate(script, [-size[<NUM_LIT:0>] / <NUM_LIT:2>, -size[<NUM_LIT:1>] / <NUM_LIT:2>, -size[<NUM_LIT:2>] / <NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>


def plane_hires_edges(script, size=<NUM_LIT:1.0>, x_segments=<NUM_LIT:1>, y_segments=<NUM_LIT:1>,<EOL>center=False, color=None):

size = util.make_list(size, <NUM_LIT:2>)<EOL>grid(script, size=[x_segments + y_segments - <NUM_LIT:1>, <NUM_LIT:1>],<EOL>x_segments=(x_segments + y_segments - <NUM_LIT:1>), y_segments=<NUM_LIT:1>)<EOL>if ml_script1.ml_version == '<STR_LIT>':<EOL><INDENT>and_val = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>and_val = '<STR_LIT>'<EOL><DEDENT>if script.ml_version == '<STR_LIT>': <EOL><INDENT>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (y_segments),<EOL>y_func='<STR_LIT>' % (<EOL>y_segments, size[<NUM_LIT:1>] / y_segments))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>y_segments, y_segments, size[<NUM_LIT:0>] / x_segments),<EOL>y_func='<STR_LIT>' % (y_segments, size[<NUM_LIT:1>]))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>x_segments, size[<NUM_LIT:0>]),<EOL>y_func='<STR_LIT>' % (<EOL>x_segments, x_segments, size[<NUM_LIT:1>] / y_segments))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>x_segments, size[<NUM_LIT:0>] / x_segments),<EOL>y_func='<STR_LIT>' % (x_segments))<EOL><DEDENT>else: <EOL><INDENT>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>'.format(yseg=y_segments),<EOL>y_func='<STR_LIT>' % (<EOL>y_segments, size[<NUM_LIT:1>] / y_segments))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>y_segments, y_segments, size[<NUM_LIT:0>] / x_segments),<EOL>y_func='<STR_LIT>' % (y_segments, size[<NUM_LIT:1>]))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>x_segments, size[<NUM_LIT:0>]),<EOL>y_func='<STR_LIT>' % (<EOL>x_segments, x_segments, size[<NUM_LIT:1>] / y_segments))<EOL>transform.vert_function(<EOL>script,<EOL>x_func='<STR_LIT>' % (<EOL>x_segments, size[<NUM_LIT:0>] / x_segments),<EOL>y_func='<STR_LIT>' % (x_segments))<EOL><DEDENT>if center:<EOL><INDENT>transform.translate(script, [-size[<NUM_LIT:0>] / <NUM_LIT:2>, -size[<NUM_LIT:1>] / <NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Creates a plane with a specified number of vertices
    on it sides, but no vertices on the interior.

    Currently used to create a simpler bottom for cube_hires.


def cube_hires(script, size=<NUM_LIT:1.0>, x_segments=<NUM_LIT:1>, y_segments=<NUM_LIT:1>, z_segments=<NUM_LIT:1>,<EOL>simple_bottom=True, center=False, color=None):

"""<STR_LIT>"""<EOL>size = util.make_list(size, <NUM_LIT:3>)<EOL>grid(script,<EOL>size,<EOL>x_segments,<EOL>y_segments)<EOL>transform.translate(script, [<NUM_LIT:0>, <NUM_LIT:0>, size[<NUM_LIT:2>]])<EOL>if simple_bottom:<EOL><INDENT>plane_hires_edges(<EOL>script, size, x_segments, y_segments)<EOL><DEDENT>else:<EOL><INDENT>layers.duplicate(script)<EOL>transform.translate(script, [<NUM_LIT:0>, <NUM_LIT:0>, -size[<NUM_LIT:2>]])<EOL><DEDENT>transform.rotate(script, '<STR_LIT:x>', <NUM_LIT>)<EOL>transform.translate(script, [<NUM_LIT:0>, size[<NUM_LIT:1>], <NUM_LIT:0>])<EOL>cube_open_hires(<EOL>script=script, size=size, x_segments=x_segments,<EOL>y_segments=y_segments, z_segments=z_segments)<EOL>layers.join(script)<EOL>clean.merge_vert(script, threshold=<NUM_LIT>)<EOL>if center:<EOL><INDENT>transform.translate(script, [-size[<NUM_LIT:0>] / <NUM_LIT:2>, -size[<NUM_LIT:1>] / <NUM_LIT:2>, -size[<NUM_LIT:2>] / <NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a box with user defined number of segments in each direction.

    Grid spacing is the same as its dimensions (spacing = 1) and its
    thickness is one. Intended to be used for e.g. deforming using functions
    or a height map (lithopanes) and can be resized after creation.

    Warnings: function uses layers.join

    top_option
        0 open
        1 full
        2 simple
    bottom_option
        0 open
        1 full
        2 simple


def annulus_hires(script, radius=None, radius1=None, radius2=None,<EOL>diameter=None, diameter1=None, diameter2=None,<EOL>cir_segments=<NUM_LIT>, rad_segments=<NUM_LIT:1>, color=None):

if radius is not None and diameter is None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = radius<EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter is not None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = diameter / <NUM_LIT:2><EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter1 is not None:<EOL><INDENT>radius1 = diameter1 / <NUM_LIT:2><EOL><DEDENT>if diameter2 is not None:<EOL><INDENT>radius2 = diameter2 / <NUM_LIT:2><EOL><DEDENT>if radius1 is None:<EOL><INDENT>radius1 = <NUM_LIT:1><EOL><DEDENT>if radius2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT>ring = (radius1 - radius2) / rad_segments<EOL>for i in range(<NUM_LIT:0>, rad_segments):<EOL><INDENT>annulus(script,<EOL>radius1=radius1 - i * ring,<EOL>radius2=radius1 - (i + <NUM_LIT:1>) * ring,<EOL>cir_segments=cir_segments)<EOL><DEDENT>layers.join(script, merge_vert=True)<EOL>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>

Create a cylinder with user defined number of segments


def tube_hires(script, height=<NUM_LIT:1.0>, radius=None, radius1=None, radius2=None,<EOL>diameter=None, diameter1=None, diameter2=None, cir_segments=<NUM_LIT:32>,<EOL>rad_segments=<NUM_LIT:1>, height_segments=<NUM_LIT:1>, center=False,<EOL>simple_bottom=False, color=None):

<EOL>if radius is not None and diameter is None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = radius<EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter is not None:<EOL><INDENT>if radius1 is None and diameter1 is None:<EOL><INDENT>radius1 = diameter / <NUM_LIT:2><EOL><DEDENT>if radius2 is None and diameter2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT><DEDENT>if diameter1 is not None:<EOL><INDENT>radius1 = diameter1 / <NUM_LIT:2><EOL><DEDENT>if diameter2 is not None:<EOL><INDENT>radius2 = diameter2 / <NUM_LIT:2><EOL><DEDENT>if radius1 is None:<EOL><INDENT>radius1 = <NUM_LIT:1><EOL><DEDENT>if radius2 is None:<EOL><INDENT>radius2 = <NUM_LIT:0><EOL><DEDENT>annulus_hires(script,<EOL>radius1=radius1,<EOL>radius2=radius2,<EOL>cir_segments=cir_segments,<EOL>rad_segments=rad_segments)<EOL>transform.translate(script, [<NUM_LIT:0>, <NUM_LIT:0>, height])<EOL>if simple_bottom:<EOL><INDENT>annulus(script,<EOL>radius1=radius1,<EOL>radius2=radius2,<EOL>cir_segments=cir_segments)<EOL><DEDENT>else:<EOL><INDENT>layers.duplicate(script)<EOL>transform.translate(script, [<NUM_LIT:0>, <NUM_LIT:0>, -height])<EOL><DEDENT>transform.rotate(script, '<STR_LIT:x>', <NUM_LIT>)<EOL>cylinder_open_hires(script, height, radius1,<EOL>cir_segments=cir_segments,<EOL>height_segments=height_segments)<EOL>if radius2 != <NUM_LIT:0>:<EOL><INDENT>cylinder_open_hires(script, height, radius2,<EOL>cir_segments=cir_segments,<EOL>height_segments=height_segments,<EOL>invert_normals=True)<EOL><DEDENT>layers.join(script)<EOL>clean.merge_vert(script, threshold=<NUM_LIT>)<EOL>if center:<EOL><INDENT>transform.translate(script, [<NUM_LIT:0>, <NUM_LIT:0>, -height / <NUM_LIT:2>])<EOL><DEDENT>if color is not None:<EOL><INDENT>vert_color.function(script, color=color)<EOL><DEDENT>return None<EOL>


pass<EOL>

Create a triangle by specifying 3 points

    Under the hood: create a plane, delete one point, then move other vertices.


pass<EOL>

Create  doublehelix function, takes spacing between helixes and
    rungs, rung diameter


try:<EOL><INDENT>float(num)<EOL>return True<EOL><DEDENT>except:<EOL><INDENT>return False<EOL><DEDENT>

Check if a variable is a number by trying to convert it to a float.


try:<EOL><INDENT>float(num)<EOL>return float(num)<EOL><DEDENT>except ValueError:<EOL><INDENT>return float('<STR_LIT>')<EOL><DEDENT>


for fread in glob(filename):<EOL><INDENT>os.remove(fread)<EOL><DEDENT>

Delete all files in the current directory that match a pattern.

    Intended primarily for temp files, e.g. mlx.delete_all('TEMP3D*').


<EOL>this_dir = os.path.dirname(<EOL>os.path.realpath(<EOL>inspect.getsourcefile(<EOL>lambda: <NUM_LIT:0>)))<EOL>color_name_file = os.path.join(this_dir, '<STR_LIT>')<EOL>found = False<EOL>for line in open(color_name_file, '<STR_LIT:r>'):<EOL><INDENT>line = line.rstrip()<EOL>if color.lower() == line.split()[<NUM_LIT:0>]:<EOL><INDENT>red = line.split()[<NUM_LIT:2>]<EOL>green = line.split()[<NUM_LIT:3>]<EOL>blue = line.split()[<NUM_LIT:4>]<EOL>found = True<EOL>break<EOL><DEDENT><DEDENT>if not found:<EOL><INDENT>print('<STR_LIT>' % color)<EOL>red = <NUM_LIT:255><EOL>green = <NUM_LIT:255><EOL>blue = <NUM_LIT:255><EOL><DEDENT>return red, green, blue<EOL>

Read color_names.txt and find the red, green, and blue values
        for a named color.


if not isinstance(var, list):<EOL><INDENT>if isinstance(var, tuple):<EOL><INDENT>var = list(var)<EOL><DEDENT>else:<EOL><INDENT>var = [var]<EOL><DEDENT>for _ in range(<NUM_LIT:1>, num_terms):<EOL><INDENT>var.append(var[<NUM_LIT:0>])<EOL><DEDENT><DEDENT>if len(var) != num_terms:<EOL><INDENT>print(<EOL>'<STR_LIT>' %<EOL>(var, num_terms))<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>return var<EOL>

Check if a variable is a list and is the correct length.

    If variable is not a list it will make it a list of the correct length with
    all terms identical.


if not isinstance(var, list):<EOL><INDENT>if isinstance(var, tuple):<EOL><INDENT>var = list(var)<EOL><DEDENT>else:<EOL><INDENT>var = [var]<EOL>for _ in range(<NUM_LIT:1>, num_terms):<EOL><INDENT>var.append(var[<NUM_LIT:0>])<EOL><DEDENT><DEDENT><DEDENT>return var<EOL>

Make a variable a list if it is not already

    If variable is not a list it will make it a list of the correct length with
    all terms identical.


if isinstance(script, mlx.FilterScript):<EOL><INDENT>script.filters.append(filter_xml)<EOL><DEDENT>elif isinstance(script, str):<EOL><INDENT>script_file = open(script, '<STR_LIT:a>')<EOL>script_file.write(filter_xml)<EOL>script_file.close()<EOL><DEDENT>else:<EOL><INDENT>print(filter_xml)<EOL><DEDENT>return None<EOL>

Write filter to FilterScript object or filename

    Args:
        script (FilterScript object or filename str): the FilterScript object
            or script filename to write the filter to.
        filter_xml (str): the xml filter string


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

Re-orient in a consistent way all the faces of the mesh.

    The filter visits a mesh face to face, reorienting any unvisited face so
    that it is coherent to the already visited faces. If the surface is
    orientable it will end with a consistent orientation of all the faces. If
    the surface is not orientable (e.g. it is non manifold or non orientable
    like a moebius strip) the filter will not build a consistent orientation
    simply because it is not possible. The filter can end up in a consistent
    orientation that can be exactly the opposite of the expected one; in that
    case simply invert the whole mesh orientation.

    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 flip(script, force_flip=False, selected=False):

Invert faces orientation, flipping the normals of the mesh.

    If requested, it tries to guess the right orientation; mainly it decides to
    flip all the faces if the minimum/maximum vertexes have not outward point
    normals for a few directions. Works well for single component watertight
    objects.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        force_flip (bool): If selected, the normals will always be flipped;
            otherwise, the filter tries to set them outside.
        selected (bool): If selected, only selected faces will be affected.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


reorient(script)<EOL>flip(script)<EOL>return<EOL>

Will reorient normals & ensure they are oriented outwards

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def point_sets(script, neighbors=<NUM_LIT:10>, smooth_iteration=<NUM_LIT:0>, flip=False,<EOL>viewpoint_pos=(<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>)):

Compute the normals of the vertices of a mesh without exploiting the
        triangle connectivity, useful for dataset with no faces.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        neighbors (int): The number of neighbors used to estimate normals.
        smooth_iteration (int): The number of smoothing iteration done on the
            p used to estimate and propagate normals.
        flip (bool): Flip normals w.r.t. viewpoint. If the 'viewpoint' (i.e.
            scanner position) is known, it can be used to disambiguate normals
            orientation, so that all the normals will be oriented in the same
            direction.
        viewpoint_pos (single xyz point, tuple or list): Set the x, y, z
            coordinates of the viewpoint position.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def function(script, red=<NUM_LIT:255>, green=<NUM_LIT:255>, blue=<NUM_LIT:255>, alpha=<NUM_LIT:255>, color=None):

<EOL>if color is not None:<EOL><INDENT>red, green, blue, _ = color_name[color.lower()]<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(red).replace('<STR_LIT:&>', '<STR_LIT>').replace('<STR_LIT:<>', '<STR_LIT>')),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(green).replace('<STR_LIT:&>', '<STR_LIT>').replace('<STR_LIT:<>', '<STR_LIT>')),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(blue).replace('<STR_LIT:&>', '<STR_LIT>').replace('<STR_LIT:<>', '<STR_LIT>')),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(alpha).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>

Color function using muparser lib to generate new RGBA color for every
        vertex

    Red, Green, Blue and Alpha channels may be defined by specifying a function
    for each.

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

    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 (radius)
        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.
        red (str [0, 255]): function to generate red component
        green (str [0, 255]): function to generate green component
        blue (str [0, 255]): function to generate blue component
        alpha (str [0, 255]): function to generate alpha component
        color (str): name of one of the 140 HTML Color Names defined
            in CSS & SVG.
            Ref: https://en.wikipedia.org/wiki/Web_colors#X11_color_names
            If not None this will override the per component variables.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def voronoi(script, target_layer=<NUM_LIT:0>, source_layer=<NUM_LIT:1>, backward=True):

Given a Mesh 'M' and a Pointset 'P', the filter projects each vertex of
        P over M and color M according to the geodesic distance from these
        projected points. Projection and coloring are done on a per vertex
        basis.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        target_layer (int): The mesh layer whose surface is colored. For each
            vertex of this mesh we decide the color according to the following
            arguments.
        source_layer (int): The mesh layer whose vertexes are used as seed
            points for the color computation. These seeds point are projected
            onto the target_layer mesh.
        backward (bool): If True the mesh is colored according to the distance
            from the frontier of the voronoi diagram induced by the
            source_layer seeds.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def cyclic_rainbow(script, direction='<STR_LIT>', start_pt=(<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>),<EOL>amplitude=<NUM_LIT:255> / <NUM_LIT:2>, center=<NUM_LIT:255> / <NUM_LIT:2>, freq=<NUM_LIT>,<EOL>phase=(<NUM_LIT:0>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT:0>), alpha=False):

start_pt = util.make_list(start_pt, <NUM_LIT:3>)<EOL>amplitude = util.make_list(amplitude, <NUM_LIT:4>)<EOL>center = util.make_list(center, <NUM_LIT:4>)<EOL>freq = util.make_list(freq, <NUM_LIT:4>)<EOL>phase = util.make_list(phase, <NUM_LIT:4>)<EOL>if direction.lower() == '<STR_LIT>':<EOL><INDENT>increment = '<STR_LIT>'.format(<EOL>start_pt[<NUM_LIT:0>], start_pt[<NUM_LIT:1>], start_pt[<NUM_LIT:2>])<EOL><DEDENT>elif direction.lower() == '<STR_LIT:x>':<EOL><INDENT>increment = '<STR_LIT>'.format(start_pt[<NUM_LIT:0>])<EOL><DEDENT>elif direction.lower() == '<STR_LIT:y>':<EOL><INDENT>increment = '<STR_LIT>'.format(start_pt[<NUM_LIT:1>])<EOL><DEDENT>elif direction.lower() == '<STR_LIT:z>':<EOL><INDENT>increment = '<STR_LIT>'.format(start_pt[<NUM_LIT:2>])<EOL><DEDENT>else:<EOL><INDENT>increment = direction<EOL><DEDENT>red_func = '<STR_LIT>'.format(<EOL>f=freq[<NUM_LIT:0>], i=increment, p=math.radians(phase[<NUM_LIT:0>]),<EOL>a=amplitude[<NUM_LIT:0>], c=center[<NUM_LIT:0>])<EOL>green_func = '<STR_LIT>'.format(<EOL>f=freq[<NUM_LIT:1>], i=increment, p=math.radians(phase[<NUM_LIT:1>]),<EOL>a=amplitude[<NUM_LIT:1>], c=center[<NUM_LIT:1>])<EOL>blue_func = '<STR_LIT>'.format(<EOL>f=freq[<NUM_LIT:2>], i=increment, p=math.radians(phase[<NUM_LIT:2>]),<EOL>a=amplitude[<NUM_LIT:2>], c=center[<NUM_LIT:2>])<EOL>if alpha:<EOL><INDENT>alpha_func = '<STR_LIT>'.format(<EOL>f=freq[<NUM_LIT:3>], i=increment, p=math.radians(phase[<NUM_LIT:3>]),<EOL>a=amplitude[<NUM_LIT:3>], c=center[<NUM_LIT:3>])<EOL><DEDENT>else:<EOL><INDENT>alpha_func = <NUM_LIT:255><EOL><DEDENT>function(script, red=red_func, green=green_func, blue=blue_func,<EOL>alpha=alpha_func)<EOL>return None<EOL>

Color mesh vertices in a repeating sinusiodal rainbow pattern

    Sine wave follows the following equation for each color channel (RGBA):
    channel = sin(freq*increment + phase)*amplitude + center

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        direction (str) = the direction that the sine wave will travel; this
            and the start_pt determine the 'increment' of the sine function.
            Valid values are:
            'sphere' - radiate sine wave outward from start_pt (default)
            'x' - sine wave travels along the X axis
            'y' - sine wave travels along the Y axis
            'z' - sine wave travels along the Z axis
            or define the increment directly using a muparser function, e.g.
                '2x + y'. In this case start_pt will not be used; include it in
                the function directly.
    start_pt (3 coordinate tuple or list): start point of the sine wave. For a
        sphere this is the center of the sphere.
    amplitude (float [0, 255], single value or 4 term tuple or list): amplitude
        of the sine wave, with range between 0-255. If a single value is
        specified it will be used for all channels, otherwise specify each
        channel individually.
    center (float [0, 255], single value or 4 term tuple or list): center
        of the sine wave, with range between 0-255. If a single value is
        specified it will be used for all channels, otherwise specify each
        channel individually.
    freq (float, single value or 4 term tuple or list): frequency of the sine
        wave. If a single value is specified it will be used for all channels,
        otherwise specifiy each channel individually.
    phase (float [0, 360], single value or 4 term tuple or list): phase
        of the sine wave in degrees, with range between 0-360. If a single
        value is specified it will be used for all channels, otherwise specify
        each channel individually.
    alpha (bool): if False the alpha channel will be set to 255 (full opacity).

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Merge together all the vertices that are nearer than the specified
    threshold. Like a unify duplicate vertices but with some tolerance.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        threshold (float): Merging distance. All the vertices that are closer
            than this threshold are merged together. Use very small values,
            default is zero.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def close_holes(script, hole_max_edge=<NUM_LIT:30>, selected=False,<EOL>sel_new_face=True, self_intersection=True):

Close holes smaller than a given threshold

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        hole_max_edge (int): The size is expressed as number of edges composing
            the hole boundary.
        selected (bool): Only the holes with at least one of the boundary faces
            selected are closed.
        sel_new_face (bool): After closing a hole the faces that have been
            created are left selected. Any previous selection is lost. Useful
            for example for smoothing or subdividing the newly created holes.
        self_intersection (bool): When closing an holes it tries to prevent the
            creation of faces that intersect faces adjacent to the boundary of
            the hole. It is an heuristic, non intersecting hole filling can be
            NP-complete.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Split non-manifold vertices until it becomes two-manifold.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        vert_displacement_ratio (float): When a vertex is split it is moved
            along the average vector going from its position to the centroid
            of the FF connected faces sharing it.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Delete all the single folded faces.

    A face is considered folded if its normal is opposite to all the adjacent
    faces. It is removed by flipping it against the face f adjacent along the
    edge e such that the vertex opposite to e fall inside f.

    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 snap_mismatched_borders(script, edge_dist_ratio=<NUM_LIT>, unify_vert=True):

Try to snap together adjacent borders that are slightly mismatched.

    This situation can happen on badly triangulated adjacent patches defined by
    high order surfaces. For each border vertex the filter snaps it onto the
    closest boundary edge only if it is closest of edge_legth*threshold. When
    vertex is snapped the corresponding face it split and a new vertex is
    created.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        edge_dist_ratio (float): Collapse edge when the edge / distance ratio
            is greater than this value. E.g. for default value 1000 two
            straight border edges are collapsed if the central vertex dist from
            the straight line composed by the two edges less than a 1/1000 of
            the sum of the edges length. Larger values enforce that only
            vertexes very close to the line are removed.
        unify_vert (bool): If true the snap vertices are welded together.

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


Transfer texture colors to vertex colors

    BUG: this does not work correctly if the file has multiple textures; it
    only uses one texture and remaps all of the UVs to that
    https://github.com/cnr-isti-vclab/meshlab/issues/124
    should be fixed in post 2016.12 release


def vc2tex(script, tex_name='<STR_LIT>', tex_width=<NUM_LIT>,<EOL>tex_height=<NUM_LIT>, overwrite_tex=False, assign_tex=False,<EOL>fill_tex=True):

filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_name,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_width,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_height,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(overwrite_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(assign_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(fill_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Transfer vertex colors to texture colors

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        tex_name (str): The texture file to be created
        tex_width (int): The texture width
        tex_height (int): The texture height
        overwrite_tex (bool): If current mesh has a texture will be overwritten (with provided texture dimension)
        assign_tex (bool): Assign the newly created texture
        fill_tex (bool): If enabled the unmapped texture space is colored using a pull push filling algorithm, if false is set to black


Transfer face colors to vertex colors

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


Transfer vertex colors to face colors

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


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

Transfer mesh colors to face colors

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        all_visible_layers (bool): If true the color mapping is applied to all the meshes


def vert_attr_2_meshes(script, source_mesh=<NUM_LIT:0>, target_mesh=<NUM_LIT:1>,<EOL>geometry=False, normal=False, color=True,<EOL>quality=False, selection=False,<EOL>quality_distance=False, max_distance=<NUM_LIT:0.5>):

Vertex Attribute Transfer (between 2 meshes)

    Transfer the chosen per-vertex attributes from one mesh to another. Useful to transfer attributes to different representations of the same object. For each vertex of the target mesh the closest point (not vertex!) on the source mesh is computed, and the requested interpolated attributes from that source point are copied into the target vertex.

    The algorithm assumes that the two meshes are reasonably similar and aligned.

    UpperBound: absolute value (not percentage)

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        source_mesh (int): The mesh that contains the source data that we want to transfer
        target_mesh (int): The mesh whose vertexes will receive the data from the source
        geometry (bool): If enabled, the position of each vertex of the target mesh will be snapped onto the corresponding closest point on the source mesh
        normal (bool): If enabled, the normal of each vertex of the target mesh will get the (interpolated) normal of the corresponding closest point on the source mesh
        color (bool): If enabled, the color of each vertex of the target mesh will become the color of the corresponding closest point on the source mesh
        quality (bool): If enabled, the quality of each vertex of the target mesh will become the quality of the corresponding closest point on the source mesh
        selection (bool): If enabled, each vertex of the target mesh will be selected if the corresponding closest point on the source mesh falls in a selected face
        quality_distance (bool): If enabled, we store the distance of the transferred value as in the vertex quality
        max_distance (float): Sample points for which we do not find anything within this distance are rejected and not considered for recovering attributes


def vert_attr2tex_2_meshes(script, source_mesh=<NUM_LIT:0>, target_mesh=<NUM_LIT:1>, attribute=<NUM_LIT:0>,<EOL>max_distance=<NUM_LIT:0.5>, tex_name='<STR_LIT>',<EOL>tex_width=<NUM_LIT>, tex_height=<NUM_LIT>,<EOL>overwrite_tex=True, assign_tex=False,<EOL>fill_tex=True):

if script.ml_version == '<STR_LIT>':<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>'.format(filter_name),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % source_mesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % target_mesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % attribute,<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>' % max_distance,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_name,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_width,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % tex_height,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(overwrite_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(assign_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(fill_tex).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Transfer Vertex Attributes to Texture (between 2 meshes)

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        source_mesh (int): The mesh that contains the source data that we want to transfer
        target_mesh (int): The mesh whose texture will be filled according to source mesh data
        attribute (int): Choose what attribute has to be transferred onto the target texture. You can choose between Per vertex attributes (color, normal, quality) or to transfer color information from source mesh texture
        max_distance (float): Sample points for which we do not find anything within this distance are rejected and not considered for recovering data
        tex_name (str): The texture file to be created
        tex_width (int): The texture width
        tex_height (int): The texture height
        overwrite_tex (bool): If target mesh has a texture will be overwritten (with provided texture dimension)
        assign_tex (bool): Assign the newly created texture to target mesh
        fill_tex (bool): If enabled the unmapped texture space is colored using a pull push filling algorithm, if false is set to black

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def tex2vc_2_meshes(script, source_mesh=<NUM_LIT:0>, target_mesh=<NUM_LIT:1>, max_distance=<NUM_LIT:0.5>):

if script.ml_version == '<STR_LIT>':<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>filter_name = '<STR_LIT>'<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>'.format(filter_name),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % source_mesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % target_mesh,<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % max_distance,<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>

Transfer texture colors to vertex colors (between 2 meshes)

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        source_mesh (int): The mesh with associated texture that we want to sample from
        target_mesh (int): The mesh whose vertex color will be filled according to source mesh texture
        max_distance (float): Sample points for which we do not find anything within this distance are rejected and not considered for recovering color

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def measure_aabb(fbasename=None, log=None, coord_system='<STR_LIT>'):

<EOL>fext = os.path.splitext(fbasename)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower()<EOL>if fext != '<STR_LIT>':<EOL><INDENT>fin = '<STR_LIT>'<EOL>run(log=log, file_in=fbasename, file_out=fin, script=None)<EOL><DEDENT>else:<EOL><INDENT>fin = fbasename<EOL><DEDENT>fread = open(fin, '<STR_LIT:r>')<EOL>aabb = {'<STR_LIT>': [<NUM_LIT>, <NUM_LIT>, <NUM_LIT>], '<STR_LIT>': [-<NUM_LIT>, -<NUM_LIT>, -<NUM_LIT>]}<EOL>for line in fread:<EOL><INDENT>x_co, y_co, z_co = line.split()<EOL>x_co = util.to_float(x_co)<EOL>y_co = util.to_float(y_co)<EOL>z_co = util.to_float(z_co)<EOL>if coord_system == '<STR_LIT>':<EOL><INDENT>if x_co < aabb['<STR_LIT>'][<NUM_LIT:0>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:0>] = x_co<EOL><DEDENT>if y_co < aabb['<STR_LIT>'][<NUM_LIT:1>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:1>] = y_co<EOL><DEDENT>if z_co < aabb['<STR_LIT>'][<NUM_LIT:2>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:2>] = z_co<EOL><DEDENT>if x_co > aabb['<STR_LIT>'][<NUM_LIT:0>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:0>] = x_co<EOL><DEDENT>if y_co > aabb['<STR_LIT>'][<NUM_LIT:1>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:1>] = y_co<EOL><DEDENT>if z_co > aabb['<STR_LIT>'][<NUM_LIT:2>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:2>] = z_co<EOL><DEDENT><DEDENT>elif coord_system == '<STR_LIT>':<EOL><INDENT>radius = math.sqrt(x_co**<NUM_LIT:2> + y_co**<NUM_LIT:2>)<EOL>theta = math.degrees(math.atan2(y_co, x_co))<EOL>if radius < aabb['<STR_LIT>'][<NUM_LIT:0>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:0>] = radius<EOL><DEDENT>if theta < aabb['<STR_LIT>'][<NUM_LIT:1>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:1>] = theta<EOL><DEDENT>if z_co < aabb['<STR_LIT>'][<NUM_LIT:2>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:2>] = z_co<EOL><DEDENT>if radius > aabb['<STR_LIT>'][<NUM_LIT:0>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:0>] = radius<EOL><DEDENT>if theta > aabb['<STR_LIT>'][<NUM_LIT:1>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:1>] = theta<EOL><DEDENT>if z_co > aabb['<STR_LIT>'][<NUM_LIT:2>]:<EOL><INDENT>aabb['<STR_LIT>'][<NUM_LIT:2>] = z_co<EOL><DEDENT><DEDENT><DEDENT>fread.close()<EOL>try:<EOL><INDENT>aabb['<STR_LIT>'] = [(aabb['<STR_LIT>'][<NUM_LIT:0>] + aabb['<STR_LIT>'][<NUM_LIT:0>]) / <NUM_LIT:2>,<EOL>(aabb['<STR_LIT>'][<NUM_LIT:1>] + aabb['<STR_LIT>'][<NUM_LIT:1>]) / <NUM_LIT:2>,<EOL>(aabb['<STR_LIT>'][<NUM_LIT:2>] + aabb['<STR_LIT>'][<NUM_LIT:2>]) / <NUM_LIT:2>]<EOL>aabb['<STR_LIT:size>'] = [aabb['<STR_LIT>'][<NUM_LIT:0>] - aabb['<STR_LIT>'][<NUM_LIT:0>], aabb['<STR_LIT>'][<NUM_LIT:1>] - aabb['<STR_LIT>'][<NUM_LIT:1>],<EOL>aabb['<STR_LIT>'][<NUM_LIT:2>] - aabb['<STR_LIT>'][<NUM_LIT:2>]]<EOL>aabb['<STR_LIT>'] = math.sqrt(<EOL>aabb['<STR_LIT:size>'][<NUM_LIT:0>]**<NUM_LIT:2> +<EOL>aabb['<STR_LIT:size>'][<NUM_LIT:1>]**<NUM_LIT:2> +<EOL>aabb['<STR_LIT:size>'][<NUM_LIT:2>]**<NUM_LIT:2>)<EOL><DEDENT>except UnboundLocalError:<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>for key, value in aabb.items():<EOL><INDENT>if log is None:<EOL><INDENT>print('<STR_LIT>'.format(key, value))<EOL><DEDENT>else:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>'.format(key, value))<EOL>log_file.close()<EOL><DEDENT><DEDENT>"""<STR_LIT>"""<EOL>return aabb<EOL>

Measure the axis aligned bounding box (aabb) of a mesh
    in multiple coordinate systems.

    Args:
        fbasename (str): filename of input model
        log (str): filename of log file
        coord_system (enum in ['CARTESIAN', 'CYLINDRICAL']
            Coordinate system to use:
                'CARTESIAN': lists contain [x, y, z]
                'CYLINDRICAL': lists contain [r, theta, z]
    Returns:
        dict: dictionary with the following aabb properties
            min (3 element list): minimum values
            max (3 element list): maximum values
            center (3 element list): the center point
            size (3 element list): size of the aabb in each coordinate (max-min)
            diagonal (float): the diagonal of the aabb


def measure_section(fbasename=None, log=None, axis='<STR_LIT:z>', offset=<NUM_LIT:0.0>,<EOL>rotate_x_angle=None, ml_version=ml_version):

ml_script1_file = '<STR_LIT>'<EOL>file_out = '<STR_LIT>'<EOL>ml_script1 = mlx.FilterScript(file_in=fbasename, file_out=file_out, ml_version=ml_version)<EOL>if rotate_x_angle is not None:<EOL><INDENT>transform.rotate(ml_script1, axis='<STR_LIT:x>', angle=rotate_x_angle)<EOL><DEDENT>compute.section(ml_script1, axis=axis, offset=offset)<EOL>layers.delete_lower(ml_script1)<EOL>ml_script1.save_to_file(ml_script1_file)<EOL>ml_script1.run_script(log=log, script_file=ml_script1_file)<EOL>aabb = measure_aabb(file_out, log)<EOL>return aabb<EOL>

Measure a cross section of a mesh

    Perform a plane cut in one of the major axes (X, Y, Z). If you want to cut on
    a different plane you will need to rotate the model in place, perform the cut,
    and rotate it back.

    Args:
        fbasename (str): filename of input model
        log (str): filename of log file
        axis (str): axis perpendicular to the cutting plane, e.g. specify "z" to cut
            parallel to the XY plane.
        offset (float): amount to offset the cutting plane from the origin
        rotate_x_angle (float): degrees to rotate about the X axis. Useful for correcting "Up" direction: 90 to rotate Y to Z, and -90 to rotate Z to Y.

    Returns:
        dict: dictionary with the following keys for the aabb of the section:
            min (list): list of the x, y & z minimum values
            max (list): list of the x, y & z maximum values
            center (list): the x, y & z coordinates of the center of the aabb
            size (list): list of the x, y & z sizes (max - min)
            diagonal (float): the diagonal of the aabb


fext = os.path.splitext(fbasename)[<NUM_LIT:1>][<NUM_LIT:1>:].strip().lower()<EOL>if fext != '<STR_LIT>':<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>fread = open(fbasename, '<STR_LIT:r>')<EOL>first = True<EOL>polyline_vertices = []<EOL>line_segments = []<EOL>for line in fread:<EOL><INDENT>element, x_co, y_co, z_co = line.split()<EOL>if element == '<STR_LIT:v>':<EOL><INDENT>polyline_vertices.append(<EOL>[util.to_float(x_co), util.to_float(y_co), util.to_float(z_co)])<EOL><DEDENT>elif element == '<STR_LIT:l>':<EOL><INDENT>p1 = x_co<EOL>p2 = y_co<EOL>line_segments.append([int(p1), int(p2)])<EOL><DEDENT><DEDENT>fread.close()<EOL>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>"""<STR_LIT>"""<EOL>log_file.close()<EOL><DEDENT>return None<EOL>

Sort separate line segments in obj format into a continuous polyline or polylines.
    NOT FINISHED; DO NOT USE

    Also measures the length of each polyline

    Return polyline and polylineMeta (lengths)


def measure_geometry(fbasename=None, log=None, ml_version=ml_version):

ml_script1_file = '<STR_LIT>'<EOL>if ml_version == '<STR_LIT>':<EOL><INDENT>file_out = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>file_out = None<EOL><DEDENT>ml_script1 = mlx.FilterScript(file_in=fbasename, file_out=file_out, ml_version=ml_version)<EOL>compute.measure_geometry(ml_script1)<EOL>ml_script1.save_to_file(ml_script1_file)<EOL>ml_script1.run_script(log=log, script_file=ml_script1_file)<EOL>geometry = ml_script1.geometry<EOL>if ml_version == '<STR_LIT>':<EOL><INDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write(<EOL>'<STR_LIT>' %<EOL>fbasename)<EOL>log_file.close()<EOL><DEDENT>aabb = measure_aabb(file_out, log)<EOL><DEDENT>else:<EOL><INDENT>aabb = geometry['<STR_LIT>']<EOL><DEDENT>return aabb, geometry<EOL>


def measure_topology(fbasename=None, log=None, ml_version=ml_version):

ml_script1_file = '<STR_LIT>'<EOL>ml_script1 = mlx.FilterScript(file_in=fbasename, ml_version=ml_version)<EOL>compute.measure_topology(ml_script1)<EOL>ml_script1.save_to_file(ml_script1_file)<EOL>ml_script1.run_script(log=log, script_file=ml_script1_file)<EOL>topology = ml_script1.topology<EOL>return topology<EOL>

Measures mesh topology

    Args:
        fbasename (str): input filename.
        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 measure_all(fbasename=None, log=None, ml_version=ml_version):

ml_script1_file = '<STR_LIT>'<EOL>if ml_version == '<STR_LIT>':<EOL><INDENT>file_out = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>file_out = None<EOL><DEDENT>ml_script1 = mlx.FilterScript(file_in=fbasename, file_out=file_out, ml_version=ml_version)<EOL>compute.measure_geometry(ml_script1)<EOL>compute.measure_topology(ml_script1)<EOL>ml_script1.save_to_file(ml_script1_file)<EOL>ml_script1.run_script(log=log, script_file=ml_script1_file)<EOL>geometry = ml_script1.geometry<EOL>topology = ml_script1.topology<EOL>if ml_version == '<STR_LIT>':<EOL><INDENT>if log is not None:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write(<EOL>'<STR_LIT>' %<EOL>fbasename)<EOL>log_file.close()<EOL><DEDENT>aabb = measure_aabb(file_out, log)<EOL><DEDENT>else:<EOL><INDENT>aabb = geometry['<STR_LIT>']<EOL><DEDENT>return aabb, geometry, topology<EOL>

Measures mesh geometry, aabb and topology.


def measure_dimension(fbasename=None, log=None, axis1=None, offset1=<NUM_LIT:0.0>,<EOL>axis2=None, offset2=<NUM_LIT:0.0>, ml_version=ml_version):

axis1 = axis1.lower()<EOL>axis2 = axis2.lower()<EOL>ml_script1_file = '<STR_LIT>'<EOL>file_out = '<STR_LIT>'<EOL>ml_script1 = mlx.FilterScript(file_in=fbasename, file_out=file_out, ml_version=ml_version)<EOL>compute.section(ml_script1, axis1, offset1, surface=True)<EOL>compute.section(ml_script1, axis2, offset2, surface=False)<EOL>layers.delete_lower(ml_script1)<EOL>ml_script1.save_to_file(ml_script1_file)<EOL>ml_script1.run_script(log=log, script_file=ml_script1_file)<EOL>for val in ('<STR_LIT:x>', '<STR_LIT:y>', '<STR_LIT:z>'):<EOL><INDENT>if val not in (axis1, axis2):<EOL><INDENT>axis = val<EOL><DEDENT><DEDENT>axis_num = ord(axis) - ord('<STR_LIT:x>')<EOL>aabb = measure_aabb(file_out, log)<EOL>dimension = {'<STR_LIT>': aabb['<STR_LIT>'][axis_num], '<STR_LIT>': aabb['<STR_LIT>'][axis_num],<EOL>'<STR_LIT>': aabb['<STR_LIT:size>'][axis_num], '<STR_LIT>': axis}<EOL>if log is None:<EOL><INDENT>print('<STR_LIT>' % fbasename)<EOL>print('<STR_LIT>' % (axis, axis1, offset1,<EOL>axis2, offset2))<EOL>print('<STR_LIT>' % (dimension['<STR_LIT>'],<EOL>dimension['<STR_LIT>'], dimension['<STR_LIT>']))<EOL><DEDENT>else:<EOL><INDENT>log_file = open(log, '<STR_LIT:a>')<EOL>log_file.write('<STR_LIT>' % fbasename)<EOL>log_file.write('<STR_LIT>' % (axis, axis1, offset1,<EOL>axis2, offset2))<EOL>log_file.write('<STR_LIT>' % dimension['<STR_LIT>'])<EOL>log_file.write('<STR_LIT>' % dimension['<STR_LIT>'])<EOL>log_file.write('<STR_LIT>' % dimension['<STR_LIT>'])<EOL>log_file.close()<EOL><DEDENT>return dimension<EOL>


def translate2(script, value=(<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>), center=False, freeze=True,<EOL>all_layers=False):

<EOL>if not isinstance(value, list):<EOL><INDENT>value = list(value)<EOL><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:0>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:1>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:2>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(center).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(freeze).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(all_layers).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Args:
    script: the FilterScript object or script filename to write
        the filter to.
    value (vector, tuple or list): Absolute translation value along the X axis,
    center Translate center of bbox to the origin.
    freeze (bool): The transformation is explicitly applied and the  vertex coords are actually changed.
    all_layers (bool): The transformation is explicitly applied to all the mesh and raster layers in the project.


def translate(script, value=(<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>)):

<EOL>if not isinstance(value, list):<EOL><INDENT>value = list(value)<EOL><DEDENT>vert_function(script,<EOL>x_func='<STR_LIT>' % value[<NUM_LIT:0>],<EOL>y_func='<STR_LIT>' % value[<NUM_LIT:1>],<EOL>z_func='<STR_LIT>' % value[<NUM_LIT:2>])<EOL>return None<EOL>

An alternative translate implementation that uses a geometric function.
    This is more accurate than the built-in version.


def rotate2(script, axis='<STR_LIT:z>', angle=<NUM_LIT:0.0>, custom_axis=None, center_pt='<STR_LIT>',<EOL>custom_center_pt=None, freeze=True, all_layers=False):

<EOL>if axis.lower() == '<STR_LIT:x>':<EOL><INDENT>axis_num = <NUM_LIT:0><EOL><DEDENT>elif axis.lower() == '<STR_LIT:y>':<EOL><INDENT>axis_num = <NUM_LIT:1><EOL><DEDENT>elif axis.lower() == '<STR_LIT:z>':<EOL><INDENT>axis_num = <NUM_LIT:2><EOL><DEDENT>else:  <EOL><INDENT>axis_num = <NUM_LIT:3><EOL>if custom_axis is None:<EOL><INDENT>print('<STR_LIT>',<EOL>'<STR_LIT>')<EOL>custom_axis = [<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:1.0>]<EOL><DEDENT><DEDENT>if center_pt.lower() == '<STR_LIT>':<EOL><INDENT>center_pt_num = <NUM_LIT:0><EOL><DEDENT>elif center_pt.lower() == '<STR_LIT>':<EOL><INDENT>center_pt_num = <NUM_LIT:1><EOL><DEDENT>else:  <EOL><INDENT>center_pt_num = <NUM_LIT:2><EOL>if custom_center_pt is None:<EOL><INDENT>print('<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>')<EOL>custom_center_pt = [<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>]<EOL><DEDENT><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % 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>' % center_pt_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>' % angle,<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>',<EOL>'<STR_LIT>' % custom_axis[<NUM_LIT:0>],<EOL>'<STR_LIT>' % custom_axis[<NUM_LIT:1>],<EOL>'<STR_LIT>' % custom_axis[<NUM_LIT:2>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % custom_center_pt[<NUM_LIT:0>],<EOL>'<STR_LIT>' % custom_center_pt[<NUM_LIT:1>],<EOL>'<STR_LIT>' % custom_center_pt[<NUM_LIT:2>],<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(freeze).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(all_layers).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Args:
    script: the FilterScript object or script filename to write
        the filter to.
    axis (str): Choose a method.
    angle (float): "Angle of rotation (in degrees). If snapping is',
    ' enabled this value is rounded according to the snap',
    ' value.
    custom_axis (vector): This rotation axis is used only if the',
    ' _custom axis_ option is chosen.
    center_pt (str): Choose a method.
    custom_center_pt (bool): This rotation center is used only if the',
    ' _custom point_ option is chosen.
    freeze (bool): The transformation is explicitly applied and the',
    ' vertex coords are actually changed.
    all_layers (bool): The transformation is explicitly applied to all the',
    ' mesh and raster layers in the project.


def rotate(script, axis='<STR_LIT:z>', angle=<NUM_LIT:0.0>):

angle = math.radians(angle)<EOL>if axis.lower() == '<STR_LIT:x>':<EOL><INDENT>vert_function(script,<EOL>x_func='<STR_LIT:x>',<EOL>y_func='<STR_LIT>'.format(angle=angle),<EOL>z_func='<STR_LIT>'.format(angle=angle))<EOL><DEDENT>elif axis.lower() == '<STR_LIT:y>':<EOL><INDENT>vert_function(script,<EOL>x_func='<STR_LIT>'.format(angle=angle),<EOL>y_func='<STR_LIT:y>',<EOL>z_func='<STR_LIT>'.format(angle=angle))<EOL><DEDENT>elif axis.lower() == '<STR_LIT:z>':<EOL><INDENT>vert_function(script,<EOL>x_func='<STR_LIT>'.format(angle=angle),<EOL>y_func='<STR_LIT>'.format(angle=angle),<EOL>z_func='<STR_LIT:z>')<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>return None<EOL>

An alternative rotate implementation that uses a geometric function.
    This is more accurate than the built-in version.


def scale2(script, value=<NUM_LIT:1.0>, uniform=True, center_pt='<STR_LIT>',<EOL>custom_center_pt=None, unit=False, freeze=True, all_layers=False):

"""<STR_LIT>"""<EOL>value = util.make_list(value, <NUM_LIT:3>)<EOL>if center_pt.lower() == '<STR_LIT>':<EOL><INDENT>center_pt_num = <NUM_LIT:0><EOL><DEDENT>elif center_pt.lower() == '<STR_LIT>':<EOL><INDENT>center_pt_num = <NUM_LIT:1><EOL><DEDENT>else:  <EOL><INDENT>center_pt_num = <NUM_LIT:2><EOL>if custom_center_pt is None:<EOL><INDENT>print('<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>')<EOL>custom_center_pt = [<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>]<EOL><DEDENT><DEDENT>filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:0>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:1>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % value[<NUM_LIT:2>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(uniform).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % center_pt_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>' % custom_center_pt[<NUM_LIT:0>],<EOL>'<STR_LIT>' % custom_center_pt[<NUM_LIT:1>],<EOL>'<STR_LIT>' % custom_center_pt[<NUM_LIT:2>],<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(unit).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(freeze).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % str(all_layers).lower(),<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>util.write_filter(script, filter_xml)<EOL>return None<EOL>

Args:
    script: the FilterScript object or script filename to write
        the filter to.
    value (float): Scaling along the X axis.
    uniform (bool): If selected an uniform scaling (the same for all the',
    ' three axis) is applied (the X axis value is used).
    center_pt (str): Choose a method.
    custom_center_pt (point): This scaling center is used only if the',
    ' _custom point_ option is chosen.
    unit (bool): If selected, the object is scaled to a box whose',
    ' sides are at most 1 unit length.
    freeze (bool): The transformation is explicitly applied and the',
    ' vertex coords are actually changed.
    all_layers (bool): The transformation is explicitly applied to all the',
    ' mesh and raster layers in the project.


"""<STR_LIT>"""<EOL>value = util.make_list(value, <NUM_LIT:3>)<EOL>vert_function(script,<EOL>x_func='<STR_LIT>' % value[<NUM_LIT:0>],<EOL>y_func='<STR_LIT>' % value[<NUM_LIT:1>],<EOL>z_func='<STR_LIT>' % value[<NUM_LIT:2>])<EOL>return None<EOL>

An alternative scale implementation that uses a geometric function.
    This is more accurate than the built-in version.


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

Freeze the current transformation matrix into the coordinates of the
        vertices of the mesh (and set this matrix to the identity).

    In other words it applies in a definitive way the current matrix to the
    vertex coordinates.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        all_layers (bool): If selected the filter will be applied to all
            visible mesh layers.


def function(script, x_func='<STR_LIT:x>', y_func='<STR_LIT:y>', z_func='<STR_LIT:z>'):

Geometric function using muparser lib to generate new Coordinates

    You can change x, y, z for every vertex according to the function specified.

    See help(mlx.muparser_ref) for muparser reference documentation.
    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 (radius)
        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:
        x_func (str): function to generate new coordinates for x
        y_func (str): function to generate new coordinates for y
        z_func (str): function to generate new coordinates for z

    Layer stack:
        No impacts

    MeshLab versions:
        1.3.4BETA


def vert_function(script, x_func='<STR_LIT:x>', y_func='<STR_LIT:y>', z_func='<STR_LIT:z>', selected=False):

Geometric function using muparser lib to generate new Coordinates

    You can change x, y, z for every vertex according to the function specified.

    See help(mlx.muparser_ref) for muparser reference documentation.
    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 (radius)
        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:
        x_func (str): function to generate new coordinates for x
        y_func (str): function to generate new coordinates for y
        z_func (str): function to generate new coordinates for z
        selected (bool): if True, only affects selected vertices (ML ver 2016.12 & up)

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def function_cyl_co(script, r_func='<STR_LIT:r>', theta_func='<STR_LIT>', z_func='<STR_LIT:z>'):

r = '<STR_LIT>'<EOL>if isinstance(script, FilterScript) and script.ml_version >= '<STR_LIT>':<EOL><INDENT>theta = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>theta = mp_func.mp_atan2('<STR_LIT:y>', '<STR_LIT:x>')<EOL><DEDENT>r_func = re.sub(r"<STR_LIT>", r, r_func).replace('<STR_LIT>', theta)<EOL>theta_func = re.sub(r"<STR_LIT>", r, theta_func).replace('<STR_LIT>', theta)<EOL>z_func = re.sub(r"<STR_LIT>", r, z_func).replace('<STR_LIT>', theta)<EOL>x_func = '<STR_LIT>'.replace('<STR_LIT:r>', r_func).replace('<STR_LIT>', theta_func)<EOL>y_func = '<STR_LIT>'.replace('<STR_LIT:r>', r_func).replace('<STR_LIT>', theta_func)<EOL>vert_function(script, x_func, y_func, z_func)<EOL>return None<EOL>

Geometric function using cylindrical coordinates.

    Define functions in Z up cylindrical coordinates, with radius 'r',
    angle 'theta', and height 'z'

    See "function" docs for additional usage info and accepted parameters.

    Args:
        r_func (str): function to generate new coordinates for radius
        theta_func (str): function to generate new coordinates for angle.
            0 degrees is on the +X axis.
        z_func (str): function to generate new coordinates for height

    Layer stack:
        No impacts

    MeshLab versions:
        2016.12
        1.3.4BETA


def radial_flare2(script, flare_radius=None, start_radius=None, end_radius=None,<EOL>end_height=None):

<EOL>if (end_radius is not None) and (end_height is not None):<EOL><INDENT>if (end_radius - start_radius) < end_height:<EOL><INDENT>flare_radius = -((start_radius-end_radius)**<NUM_LIT:2> + end_height**<NUM_LIT:2>)/(<NUM_LIT:2>*(start_radius-end_radius))<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT><DEDENT>r_func = '<STR_LIT>'.replace('<STR_LIT>', str(flare_radius))<EOL>function_cyl_co(script, r_func)<EOL>return None<EOL>

flare_radius must be >= end_height (height)
end_radius max = flare_radius + r

end_radius (num): radius of mesh at end of flare

+15 r= 8.8205
-15 r= 1.1795

z=10, 5 +/-15 - +/-15*0.74535599249992989880305788957709


def radial_flare(script, flare_radius=None, start_radius=None, end_radius=None,<EOL>end_height=None):

<EOL>effective_radius = '<STR_LIT>'<EOL>r_func = '<STR_LIT>'<EOL>z_func = '<STR_LIT>'<EOL>r_func = r_func.replace('<STR_LIT>', str(effective_radius)).replace('<STR_LIT>', str(start_radius)).replace('<STR_LIT>', str(flare_radius))<EOL>z_func = z_func.replace('<STR_LIT>', str(effective_radius)).replace('<STR_LIT>', str(start_radius)).replace('<STR_LIT>', str(flare_radius))<EOL>function_cyl_co(script=script, r_func=r_func, z_func=z_func)<EOL>return None<EOL>


def curl_rim(script, curl_radius=None, start_radius=None, end_radius=None,<EOL>end_height=None):

<EOL>effective_radius = '<STR_LIT>'<EOL>r_func = '<STR_LIT>'<EOL>z_func = '<STR_LIT>'<EOL>r_func = r_func.replace('<STR_LIT>', str(effective_radius)).replace('<STR_LIT>', str(start_radius)).replace('<STR_LIT>', str(curl_radius))<EOL>z_func = z_func.replace('<STR_LIT>', str(effective_radius)).replace('<STR_LIT>', str(start_radius)).replace('<STR_LIT>', str(curl_radius))<EOL>function_cyl_co(script=script, r_func=r_func, z_func=z_func)<EOL>return None<EOL>


def wrap2cylinder(script, radius=<NUM_LIT:1>, pitch=<NUM_LIT:0>, taper=<NUM_LIT:0>, pitch_func=None,<EOL>taper_func=None):

"""<STR_LIT>"""<EOL>if pitch_func is None:<EOL><INDENT>pitch_func = '<STR_LIT>'<EOL><DEDENT>pitch_func = pitch_func.replace(<EOL>'<STR_LIT>', str(pitch)).replace(<EOL>'<STR_LIT>', str(math.pi)).replace(<EOL>'<STR_LIT>', str(radius))<EOL>if taper_func is None:<EOL><INDENT>taper_func = '<STR_LIT>'<EOL><DEDENT>taper_func = taper_func.replace(<EOL>'<STR_LIT>', str(taper)).replace(<EOL>'<STR_LIT>', str(pitch_func)).replace(<EOL>'<STR_LIT>', str(math.pi))<EOL>x_func = '<STR_LIT>'.replace(<EOL>'<STR_LIT>', str(radius)).replace('<STR_LIT>', str(taper_func))<EOL>y_func = '<STR_LIT>'.replace(<EOL>'<STR_LIT>', str(radius)).replace('<STR_LIT>', str(taper_func))<EOL>z_func = '<STR_LIT>'.replace('<STR_LIT>', str(pitch_func))<EOL>vert_function(script, x_func, y_func, z_func)<EOL>return None<EOL>

Deform mesh around cylinder of radius and axis z

    y = 0 will be on the surface of radius "radius"
    pitch != 0 will create a helix, with distance "pitch" traveled in z for each rotation
    taper = change in r over z. E.g. a value of 0.5 will shrink r by 0.5 for every z length of 1


def emboss_sphere(script, radius=<NUM_LIT:1>, radius_limit=None, angle=None):

if angle is not None:<EOL><INDENT>radius_limit = radius * math.sin(math.radians(angle / <NUM_LIT:2>))<EOL><DEDENT>if (radius_limit is None) or (radius_limit > radius):<EOL><INDENT>radius_limit = radius<EOL><DEDENT>r = '<STR_LIT>'<EOL>z_func = '<STR_LIT>'<EOL>z_func = re.sub(r"<STR_LIT>", r, z_func).replace(<EOL>'<STR_LIT>', str(radius_limit)).replace('<STR_LIT>', str(radius))<EOL>vert_function(script=script, z_func=z_func)<EOL>return None<EOL>


def bend(script, radius=<NUM_LIT:1>, pitch=<NUM_LIT:0>, taper=<NUM_LIT:0>, angle=<NUM_LIT:0>, straght_start=True,<EOL>straght_end=False, radius_limit=None, outside_limit_end=True):

if radius_limit is None:<EOL><INDENT>radius_limit = <NUM_LIT:2> * radius<EOL><DEDENT>angle = math.radians(angle)<EOL>segment = radius * angle<EOL>"""<STR_LIT>"""<EOL>pitch_func = '<STR_LIT>'.replace(<EOL>'<STR_LIT>', str(pitch)).replace(<EOL>'<STR_LIT>', str(math.pi)).replace(<EOL>'<STR_LIT>', str(radius))<EOL>taper_func = '<STR_LIT>'.replace(<EOL>'<STR_LIT>', str(taper)).replace(<EOL>'<STR_LIT>', str(pitch_func)).replace(<EOL>'<STR_LIT>', str(math.pi))<EOL>if outside_limit_end:<EOL><INDENT>x_func = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>x_func = '<STR_LIT>'<EOL><DEDENT>x_func = x_func.replace(<EOL>'<STR_LIT>', str(segment)).replace(<EOL>'<STR_LIT>', str(radius_limit)).replace(<EOL>'<STR_LIT>', str(radius)).replace(<EOL>'<STR_LIT>', str(taper_func)).replace(<EOL>'<STR_LIT>', str(angle))<EOL>if outside_limit_end:<EOL><INDENT>y_func = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>y_func = '<STR_LIT>'<EOL><DEDENT>y_func = y_func.replace(<EOL>'<STR_LIT>', str(segment)).replace(<EOL>'<STR_LIT>', str(radius_limit)).replace(<EOL>'<STR_LIT>', str(radius)).replace(<EOL>'<STR_LIT>', str(taper_func)).replace(<EOL>'<STR_LIT>', str(angle))<EOL>if straght_start:<EOL><INDENT>start = '<STR_LIT:z>'<EOL><DEDENT>else:<EOL><INDENT>start = '<STR_LIT>'<EOL><DEDENT>if straght_end:<EOL><INDENT>end = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>end = '<STR_LIT>'<EOL><DEDENT>if outside_limit_end:<EOL><INDENT>z_func = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>z_func = '<STR_LIT>'<EOL><DEDENT>z_func = z_func.replace(<EOL>'<STR_LIT:start>', str(start)).replace(<EOL>'<STR_LIT:end>', str(end)).replace(<EOL>'<STR_LIT>', str(segment)).replace(<EOL>'<STR_LIT>', str(radius_limit)).replace(<EOL>'<STR_LIT>', str(radius)).replace(<EOL>'<STR_LIT>', str(angle)).replace(<EOL>'<STR_LIT>', str(pitch_func)).replace(<EOL>'<STR_LIT>', str(pitch)).replace(<EOL>'<STR_LIT>', str(math.pi))<EOL>"""<STR_LIT>"""<EOL>"""<STR_LIT>"""<EOL>vert_function(script, x_func=x_func, y_func=y_func, z_func=z_func)<EOL>return None<EOL>

Bends mesh around cylinder of radius radius and axis z to a certain angle

    straight_ends: Only apply twist (pitch) over the area that is bent

    outside_limit_end (bool): should values outside of the bend radius_limit be considered part
        of the end (True) or the start (False)?


def deform2curve(script, curve=mp_func.torus_knot('<STR_LIT:t>'), step=<NUM_LIT>):

curve_step = []<EOL>for idx, val in enumerate(curve):<EOL><INDENT>curve[idx] = val.replace('<STR_LIT:t>', '<STR_LIT:z>')<EOL>curve_step.append(val.replace('<STR_LIT:t>', '<STR_LIT>'.format(step)))<EOL><DEDENT>tangent = mp_func.v_subtract(curve_step, curve)<EOL>normal1 = mp_func.v_add(curve_step, curve)<EOL>bee = mp_func.v_cross(tangent, normal1)<EOL>normal = mp_func.v_cross(bee, tangent)<EOL>bee = mp_func.v_normalize(bee)<EOL>normal = mp_func.v_normalize(normal)<EOL>new_point = mp_func.v_add(mp_func.v_multiply('<STR_LIT:x>', normal), mp_func.v_multiply('<STR_LIT:y>', bee))<EOL>function = mp_func.v_add(curve, new_point)<EOL>vert_function(script, x_func=function[<NUM_LIT:0>], y_func=function[<NUM_LIT:1>], z_func=function[<NUM_LIT:2>])<EOL>return function<EOL>

Deform a mesh along a parametric curve function

    Provide a parametric curve function with z as the parameter. This will
    deform the xy cross section of the mesh along the curve as z increases.

    Source: http://blackpawn.com/texts/pqtorus/

    Methodology:
    T  = P' - P
    N1 = P' + P
    B  = T x N1
    N  = B x T

    newPoint = point.x*N + point.y*B


def loop(script, iterations=<NUM_LIT:1>, loop_weight=<NUM_LIT:0>, edge_threshold=<NUM_LIT:0>,<EOL>selected=False):

Apply Loop's Subdivision Surface algorithm.

    It is an approximant subdivision method and it works for every triangle
    and has rules for extraordinary vertices.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): Number of times the model is subdivided.
        loop_weight (int): Change the weights used. Allow to optimize some
            behaviours in spite of others. Valid values are:
            0 - Loop (default)
            1 - Enhance regularity
            2 - Enhance continuity
        edge_threshold (float): All the edges longer than this threshold will
            be refined. Setting this value to zero will force a uniform
            refinement.
        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 ls3loop(script, iterations=<NUM_LIT:1>, loop_weight=<NUM_LIT:0>, edge_threshold=<NUM_LIT:0>,<EOL>selected=False):

Apply LS3 Subdivision Surface algorithm using Loop's weights.

    This refinement method take normals into account.
    See: Boye', S. Guennebaud, G. & Schlick, C.
    "Least squares subdivision surfaces"
    Computer Graphics Forum, 2010.

    Alternatives weighting schemes are based on the paper:
    Barthe, L. & Kobbelt, L.
    "Subdivision scheme tuning around extraordinary vertices"
    Computer Aided Geometric Design, 2004, 21, 561-583.

    The current implementation of these schemes don't handle vertices of
    valence > 12

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): Number of times the model is subdivided.
        loop_weight (int): Change the weights used. Allow to optimize some
            behaviours in spite of others. Valid values are:
            0 - Loop (default)
            1 - Enhance regularity
            2 - Enhance continuity
        edge_threshold (float): All the edges longer than this threshold will
            be refined. Setting this value to zero will force a uniform
            refinement.
        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 midpoint(script, iterations=<NUM_LIT:1>, edge_threshold=<NUM_LIT:0>, selected=False):

Apply a plain subdivision scheme where every edge is split on its
        midpoint.

    Useful to uniformly refine a mesh substituting each triangle with four
    smaller triangles.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): Number of times the model is subdivided.
        edge_threshold (float): All the edges longer than this threshold will
            be refined. Setting this value to zero will force a uniform
            refinement.
        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 butterfly(script, iterations=<NUM_LIT:1>, edge_threshold=<NUM_LIT:0>, selected=False):

Apply Butterfly Subdivision Surface algorithm.

    It is an interpolated method, defined on arbitrary triangular meshes.
    The scheme is known to be C1 but not C2 on regular meshes.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        iterations (int): Number of times the model is subdivided.
        edge_threshold (float): All the edges longer than this threshold will
            be refined. Setting this value to zero will force a uniform
            refinement.
        selected (bool): If selected the filter is performed only on the
            selected faces.

    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>

Apply the Catmull-Clark Subdivision Surfaces.

    Note that position of the new vertices is simply linearly interpolated.
    If the mesh is triangle based (no faux edges) it generates a quad mesh,
    otherwise it honors the faux-edge bits.

    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 simplify(script, texture=True, faces=<NUM_LIT>, target_perc=<NUM_LIT:0.0>,<EOL>quality_thr=<NUM_LIT>, preserve_boundary=False, boundary_weight=<NUM_LIT:1.0>,<EOL>optimal_placement=True, preserve_normal=False,<EOL>planar_quadric=False, selected=False, extra_tex_coord_weight=<NUM_LIT:1.0>,<EOL>preserve_topology=True, quality_weight=False, autoclean=True):

Simplify a mesh using a Quadric based Edge Collapse Strategy, better
        than clustering but slower. Optionally tries to preserve UV
        parametrization for textured meshes.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        texture (bool):
        faces (int): The desired final number of faces
        target_perc (float): If non zero, this parameter specifies the desired
            final size of the mesh as a percentage of the initial mesh size.
        quality_thr (float): Quality threshold for penalizing bad shaped faces.
            The value is in the range [0..1]0 accept any kind of face (no
            penalties), 0.5 penalize faces with quality less than 0.5,
            proportionally to their shape.
        preserve_boundary (bool): The simplification process tries not to
            affect mesh boundaries
        boundary_weight (float): The importance of the boundary during
            simplification. Default (1.0) means that the boundary has the same
            importance of the rest. Values greater than 1.0 raise boundary
            importance and has the effect of removing less vertices on the
            border. Admitted range of values (0,+inf).
        optimal_placement (bool): Each collapsed vertex is placed in the
            position minimizing the quadric error. It can fail (creating bad
            spikes) in case of very flat areas. If disabled edges are collapsed
            onto one of the two original vertices and the final mesh is
            composed by a subset of the original vertices.
        preserve_normal (bool): Try to avoid face flipping effects and try to
            preserve the original orientation of the surface.
        planar_quadric (bool): Add additional simplification constraints that
            improves the quality of the simplification of the planar portion of
            the mesh.
        selected (bool): The simplification is applied only to the selected set
            of faces. Take care of the target number of faces!
        extra_tex_coord_weight (float): Additional weight for each extra
            Texture Coordinates for every (selected) vertex. Ignored if texture
            is False.
        preserve_topology (bool): Avoid all the collapses that should cause a
            topology change in the mesh (like closing holes, squeezing handles,
            etc). If checked the genus of the mesh should stay unchanged.
        quality_weight (bool): Use the Per-Vertex quality as a weighting factor
            for the simplification. The weight is used as a error amplification
            value, so a vertex with a high quality value will not be simplified
            and a portion of the mesh with low quality values will be
            aggressively simplified.
        autoclean (bool): After the simplification an additional set of steps
            is performed to clean the mesh (unreferenced vertices, bad faces,
            etc).

    Layer stack:
        Unchanged; current mesh is simplified in place.

    MeshLab versions:
        2016.12 (different filter name)
        1.3.4BETA


def uniform_resampling(script, voxel=<NUM_LIT:1.0>, offset=<NUM_LIT:0.0>, merge_vert=True,<EOL>discretize=False, multisample=False, thicken=False):

Create a new mesh that is a resampled version of the current one.

    The resampling is done by building a uniform volumetric representation
    where each voxel contains the signed distance from the original surface.
    The resampled surface is reconstructed using the marching cube algorithm
    over this volume.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        voxel (float): voxel (cell) size for resampling. Smaller cells give
            better precision at a higher computational cost. Remember that
            halving the cell size means that you build a volume 8 times larger.
        offset (float): offset amount of the created surface (i.e. distance of
            the created surface from the original one). If offset is zero, the
            created surface passes on the original mesh itself. Values greater
            than zero mean an external surface (offset), and lower than zero
            mean an internal surface (inset). In practice this value is the
            threshold passed to the Marching Cube algorithm to extract the
            isosurface from the distance field representation.
        merge_vert (bool): if True the mesh generated by MC will be cleaned by
            unifying vertices that are almost coincident.
        discretize (bool): if True the position of the intersected edge of the
            marching cube grid is not computed by linear interpolation, but it
            is placed in fixed middle position. As a consequence the resampled
            object will look severely aliased by a stairstep appearance. Useful
            only for simulating the output of 3D printing devices.
        multisample (bool): if True the distance field is more accurately
            compute by multisampling the volume (7 sample for each voxel). Much
            slower but less artifacts.
        thicken (bool): if True, you have to choose a non zero Offset and a
            double surface is built around the original surface, inside and
            outside. Is useful to convert thin floating surfaces into solid,
            thick meshes.

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

    MeshLab versions:
        2016.12
        1.3.4BETA


filter_xml = '<STR_LIT>'.join([<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'.format(str(reorient_normal).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>

Calculate the convex hull with Qhull library
        http://www.qhull.org/html/qconvex.htm

    The convex hull of a set of points is the boundary of the minimal convex
    set containing the given non-empty finite set of points.

    Args:
        script: the FilterScript object or script filename to write
            the filter to.
        reorient_normal (bool): Re-orient all faces coherentely after hull
            operation.

    Layer stack:
        Creates 1 new layer 'Convex Hull'
        Current layer is changed to new layer

    MeshLab versions:
        2016.12
        1.3.4BETA