Beispiel #1
0
def measure_all(fbasename=None, log=None, ml_version=ml_version):
    """Measures mesh geometry, aabb and topology."""
    ml_script1_file = 'TEMP3D_measure_gAndT.mlx'
    if ml_version == '1.3.4BETA':
        file_out = 'TEMP3D_aabb.xyz'
    else:
        file_out = None

    ml_script1 = mlx.FilterScript(file_in=fbasename,
                                  file_out=file_out,
                                  ml_version=ml_version)
    compute.measure_geometry(ml_script1)
    compute.measure_topology(ml_script1)
    ml_script1.save_to_file(ml_script1_file)
    ml_script1.run_script(log=log, script_file=ml_script1_file)
    geometry = ml_script1.geometry
    topology = ml_script1.topology

    if ml_version == '1.3.4BETA':
        if log is not None:
            log_file = open(log, 'a')
            log_file.write(
                '***Axis Aligned Bounding Results for file "%s":\n' %
                fbasename)
            log_file.close()
        aabb = measure_aabb(file_out, log)
    else:
        aabb = geometry['aabb']
    return aabb, geometry, topology
Beispiel #2
0
    def create_debug_simple_mesh():

        # skip if cached
        if config.USE_CACHED_FILES and os.path.exists(debug_simple_mesh_file_path):

            # replace world with this new mesh (comment this out for prod)
            world_file_path = debug_simple_mesh_file_path
            world = trimesh.load(world_file_path)
            world_size = max(world.extents)
            return

        debug_simple_mesh_script = mlx.FilterScript(
            file_in=input_file_path, file_out=debug_simple_mesh_file_path)

        # clean / simplify mesh
        clean_mesh(debug_simple_mesh_script)
        mlx.remesh.simplify(debug_simple_mesh_script, texture=True, target_perc=0.5,
                            quality_thr=config.SIMPLIFICATION_MESH_QUALITY, preserve_boundary=True, boundary_weight=config.SIMPLIFICATION_EDGE_WEIGHT,
                            optimal_placement=True, preserve_normal=False,
                            planar_quadric=True, selected=False, extra_tex_coord_weight=config.SIMPLIFICATION_TEXTURE_WEIGHT,
                            preserve_topology=True, quality_weight=False, autoclean=True)
        selection_crop_to_mesh_bounds(debug_simple_mesh_script)
        clean_mesh(debug_simple_mesh_script)

        debug_simple_mesh_script.run_script()

        # replace world with this new mesh (comment this out for prod)
        world_file_path = debug_simple_mesh_file_path
        world = trimesh.load(world_file_path)
        world_size = max(world.extents)
Beispiel #3
0
def perform_simplify_mesh(original_mesh_path, simplified_mesh_path, num_faces):

    #Check the input mesh number of faces (so that we do not decimate to a higher number of faces than original mesh)
    MetricsMeshDictionary = {}
    MetricsMeshDictionary = mlx.files.measure_topology(original_mesh_path)
    if (MetricsMeshDictionary['face_num'] <= num_faces):
        copyfile(original_mesh_path, simplified_mesh_path)
        return False

    # simplify
    simplified_meshScript = mlx.FilterScript(
        file_in=original_mesh_path,
        file_out=simplified_mesh_path,
        ml_version='2016.12')  # Create FilterScript object
    mlx.remesh.simplify(simplified_meshScript,
                        texture=False,
                        faces=num_faces,
                        target_perc=0.0,
                        quality_thr=1.0,
                        preserve_boundary=True,
                        boundary_weight=1.0,
                        preserve_normal=True,
                        optimal_placement=True,
                        planar_quadric=True,
                        selected=False,
                        extra_tex_coord_weight=1.0)
    simplified_meshScript.run_script()

    return True
Beispiel #4
0
def measure_topology(fbasename=None, log=None, ml_version=ml_version):
    """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.

    """
    ml_script1_file = 'TEMP3D_measure_topology.mlx'
    ml_script1 = mlx.FilterScript(file_in=fbasename, ml_version=ml_version)
    compute.measure_topology(ml_script1)
    ml_script1.save_to_file(ml_script1_file)
    ml_script1.run_script(log=log, script_file=ml_script1_file)
    topology = ml_script1.topology
    return topology
Beispiel #5
0
        def create_tile(tile_file_path, tile_mesh):

            # build the tile in meshlab
            tile_mesh_script = mlx.FilterScript(
                file_in=layer_file_path, file_out=tile_file_path)
            selection_crop_to_mesh_bounds(tile_mesh_script, mesh=tile_mesh)
            # mlx.remesh.simplify(tile_mesh_script, texture=True, target_perc=percentage,
            #                     quality_thr=config.SIMPLIFICATION_MESH_QUALITY, preserve_boundary=True, boundary_weight=config.SIMPLIFICATION_EDGE_WEIGHT,
            #                     optimal_placement=True, preserve_normal=True,
            #                     planar_quadric=True, selected=False, extra_tex_coord_weight=config.SIMPLIFICATION_TEXTURE_WEIGHT,
            #                     preserve_topology=True, quality_weight=False, autoclean=True)

            # sanity check
            selection_crop_to_mesh_bounds(tile_mesh_script)

            tile_mesh_script.run_script()

            # convert to gltf
            # gltf_raw_file_path = tile_file_path.replace('.obj', '_unprocessed.gltf')
            gltf_final_file_path = tile_file_path.replace('.obj', '.gltf')
            check_call([config.OBJ2GLTF_PATH, '-i',
                        tile_file_path, '-o', gltf_final_file_path], cwd=output_path)
            # check_call([config.GLTF_OPTIMIZE_PATH, '-i',
            # gltf_raw_file_path, '-o', gltf_final_file_path, '--binary', '--removeNormals', '--smoothNormals', '--cesium'], cwd=output_path)

            # cleanup residual files
            os.unlink(tile_file_path)
            os.unlink(tile_file_path + '.mtl')
Beispiel #6
0
def measure_dimension(fbasename=None,
                      log=None,
                      axis1=None,
                      offset1=0.0,
                      axis2=None,
                      offset2=0.0,
                      ml_version=ml_version):
    """Measure a dimension of a mesh"""
    axis1 = axis1.lower()
    axis2 = axis2.lower()
    ml_script1_file = 'TEMP3D_measure_dimension.mlx'
    file_out = 'TEMP3D_measure_dimension.xyz'

    ml_script1 = mlx.FilterScript(file_in=fbasename,
                                  file_out=file_out,
                                  ml_version=ml_version)
    compute.section(ml_script1, axis1, offset1, surface=True)
    compute.section(ml_script1, axis2, offset2, surface=False)
    layers.delete_lower(ml_script1)
    ml_script1.save_to_file(ml_script1_file)
    ml_script1.run_script(log=log, script_file=ml_script1_file)

    for val in ('x', 'y', 'z'):
        if val not in (axis1, axis2):
            axis = val
    # ord: Get number that represents letter in ASCII
    # Here we find the offset from 'x' to determine the list reference
    # i.e. 0 for x, 1 for y, 2 for z
    axis_num = ord(axis) - ord('x')
    aabb = measure_aabb(file_out, log)
    dimension = {
        'min': aabb['min'][axis_num],
        'max': aabb['max'][axis_num],
        'length': aabb['size'][axis_num],
        'axis': axis
    }
    if log is None:
        print('\nFor file "%s"' % fbasename)
        print('Dimension parallel to %s with %s=%s & %s=%s:' %
              (axis, axis1, offset1, axis2, offset2))
        print('  Min = %s, Max = %s, Total length = %s' %
              (dimension['min'], dimension['max'], dimension['length']))
    else:
        log_file = open(log, 'a')
        log_file.write('\nFor file "%s"\n' % fbasename)
        log_file.write('Dimension parallel to %s with %s=%s & %s=%s:\n' %
                       (axis, axis1, offset1, axis2, offset2))
        log_file.write('min = %s\n' % dimension['min'])
        log_file.write('max = %s\n' % dimension['max'])
        log_file.write('Total length = %s\n' % dimension['length'])
        log_file.close()
    return dimension
def pc2stl(file_in="input.asc", file_out='out.stl'):
    proj = mlx.FilterScript(file_in=file_in,
                            file_out=file_out,
                            ml_version='2016.12')
    mlx.normals.point_sets(proj, neighbors=32, smooth_iteration=10)
    mlx.remesh.surface_poisson_screened(proj)
    mlx.clean.close_holes(proj,
                          hole_max_edge=1000,
                          selected=False,
                          sel_new_face=True,
                          self_intersection=True)
    mlx.layers.delete(proj)
    proj.run_script()
def simplify_mesh(path, output_path, num_faces=2048):
    import meshlabxml as mlx
    topology = mlx.files.measure_topology(str(path))
    if topology["face_num"] <= num_faces:
        shutil.copy(path, output_path)
        return

    script = mlx.FilterScript(file_in=str(path), file_out=str(output_path))
    mlx.remesh.simplify(script,
                        texture=False,
                        faces=num_faces,
                        preserve_topology=False)
    script.run_script()
def mesh_smoothing(ap):
    meshlabserver_path = 'C:\\Program Files\\VCG\\MeshLab'
    os.environ['PATH'] = meshlabserver_path + os.pathsep + os.environ['PATH']
    obj_in = ap["test_dir_path"]+ap["inp_name"]+"_c.obj"
    obj_out = ap["test_dir_path"]+ap["inp_name"]+"_smooth.obj"
    mesh0 = mlx.FilterScript(file_in=obj_in, file_out=obj_out, ml_version='2016.12')
    # mlx.select.vert_function(mesh0, function='(r==255)',strict_face_select=False)
    mlx.select.face_function(mesh0, function='(r0==255)||(r1==255)||(r2==255)')
    # mlx.select.face_function(mesh0, function='(fr==255)')
    # mlx.delete.selected(mesh0)
    # mlx.select.face_function(mesh0, function='(abs(fi-5000)<1000)')
    mlx.smooth.taubin(mesh0, iterations=10, selected=True)
    mlx.smooth.laplacian(mesh0,iterations=1,selected=True)
    mlx.smooth.taubin(mesh0,iterations=100,selected=True)
    # mlx.smooth.laplacian(mesh0,iterations=5,selected=True)
    mesh0.run_script(log=ap["test_dir_path"]+"mesh0Log.txt")
def smooth_ply(ply_data):
    # Store ply_data in temporary file
    tmp_ply_filename = tempfile.mktemp(suffix=".ply")
    with open(tmp_ply_filename, 'w') as tmp_ply_file:
        ply_data.write(tmp_ply_file)

    # Initialize meshlabserver and meshlabxml script
    unsmoothed_mesh = meshlabxml.FilterScript(file_in=tmp_ply_filename,
                                              file_out=tmp_ply_filename,
                                              ml_version="1.3.2")
    meshlabxml.smooth.laplacian(unsmoothed_mesh, iterations=6)
    unsmoothed_mesh.run_script(print_meshlabserver_output=False,
                               skip_error=True)

    # Read back and store new data
    with open(tmp_ply_filename, 'r') as tmp_ply_file:
        ply_data_smoothed = plyfile.PlyData.read(tmp_ply_file)
    return ply_data_smoothed
Beispiel #11
0
def measure_section(fbasename=None,
                    log=None,
                    axis='z',
                    offset=0.0,
                    rotate_x_angle=None,
                    ml_version=ml_version):
    """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
    """
    ml_script1_file = 'TEMP3D_measure_section.mlx'
    file_out = 'TEMP3D_sect_aabb.xyz'

    ml_script1 = mlx.FilterScript(file_in=fbasename,
                                  file_out=file_out,
                                  ml_version=ml_version)
    if rotate_x_angle is not None:
        transform.rotate(ml_script1, axis='x', angle=rotate_x_angle)
    compute.section(ml_script1, axis=axis, offset=offset)
    layers.delete_lower(ml_script1)
    ml_script1.save_to_file(ml_script1_file)
    ml_script1.run_script(log=log, script_file=ml_script1_file)
    aabb = measure_aabb(file_out, log)
    return aabb
Beispiel #12
0
        def create_layer(layer_file_path, percentage):

            # skip if cached
            if config.USE_CACHED_FILES and os.path.exists(layer_file_path):
                return

            layer_mesh_script = mlx.FilterScript(
                file_in=world_file_path, file_out=layer_file_path)

            # clean / simplify mesh
            clean_mesh(layer_mesh_script)
            mlx.remesh.simplify(layer_mesh_script, texture=True, target_perc=percentage,
                                quality_thr=config.SIMPLIFICATION_MESH_QUALITY, preserve_boundary=True, boundary_weight=config.SIMPLIFICATION_EDGE_WEIGHT,
                                optimal_placement=True, preserve_normal=False,
                                planar_quadric=True, selected=False, extra_tex_coord_weight=config.SIMPLIFICATION_TEXTURE_WEIGHT,
                                preserve_topology=True, quality_weight=False, autoclean=True)
            selection_crop_to_mesh_bounds(layer_mesh_script)
            clean_mesh(layer_mesh_script)

            layer_mesh_script.run_script()

            layer_gltf_file_path = layer_file_path.replace('.obj', '.gltf')
            check_call([config.OBJ2GLTF_PATH, '-i',
                        tile_file_path, '-o', layer_gltf_file_path], cwd=output_path)
Beispiel #13
0
    #exit the script and print a message about it
    print(
        "\n SORRY your decimated mesh can not have higher number of faces that the input mesh....."
    )
    print(
        "\n ......................................................................................"
    )
    sys.exit()

#Creating a folder named as the Number of faces: named '150000'
print('\n Creating a folder to store the decimated model ...........')
if not os.path.exists(str(Num_Of_Faces)):
    os.makedirs(str(Num_Of_Faces))

simplified_meshScript = mlx.FilterScript(
    file_in=original_mesh,
    file_out=str(Num_Of_Faces) + '/' + simplified_mesh,
    ml_version='2016.12')  # Create FilterScript object

mlx.remesh.simplify(simplified_meshScript,
                    texture=TexturesFlag,
                    faces=Num_Of_Faces,
                    target_perc=0.0,
                    quality_thr=1.0,
                    preserve_boundary=True,
                    boundary_weight=1.0,
                    preserve_normal=True,
                    optimal_placement=True,
                    planar_quadric=True,
                    selected=False,
                    extra_tex_coord_weight=1.0)
print('\n Beginning the process of Decimation ...........')
Beispiel #14
0
def quatrefoil():
    """ Rainbow colored voronoi quatrefoil (3,4) torus knot """
    start_time = time.time()

    os.chdir(THIS_SCRIPTPATH)
    #ml_version = '1.3.4BETA'
    ml_version = '2016.12'

    # Add meshlabserver directory to OS PATH; omit this if it is already in
    # your PATH
    #meshlabserver_path = 'C:\\Program Files\\VCG\\MeshLab'
    #"""
    if ml_version == '1.3.4BETA':
        meshlabserver_path = 'C:\\Program Files\\VCG\\MeshLab'
    elif ml_version == '2016.12':
        meshlabserver_path = 'C:\\Program Files\\VCG\\MeshLab_2016_12'
    #"""
    os.environ['PATH'] = meshlabserver_path + os.pathsep + os.environ['PATH']

    # Cross section parameters
    length = math.radians(360)
    tube_size = [10, 10, length]
    segments = [64, 64, 720 * 2]
    inner_radius = 2.0

    # Sinusoidal deformation parameters
    amplitude = 4.2
    freq = 4
    phase = 270
    center = 'r'
    start_pt = 0
    increment = 'z-{}'.format(start_pt)

    # Cyclic rainbow color parameters
    c_start_pt = 0
    c_freq = 5
    c_phase_shift = 0  #90 #300
    c_phase = (0 + c_phase_shift, 120 + c_phase_shift, 240 + c_phase_shift, 0)

    # Voronoi surface parameters
    holes = [2, 2,
             44]  # Number of holes in each axis; x are sides, y is outside
    web_thickness = 0.5
    solid_radius = 5.0  # If the mesh is smaller than this radius the holes will be closed
    faces_surface = 50000

    # Voronoi solid parameters
    voxel = 0.5
    thickness = 2.5
    faces_solid = 200000

    # Scaling parameters
    size = 75  # desired max size of the curve
    curve_max_size = 2 * (
        1 + 1.5)  # the 1.5 s/b inner_radius, but am keepng current scaling
    scale = (size - 2 *
             (thickness + amplitude) - tube_size[1]) / curve_max_size

    # File names
    file_color = 'quatrefoil_color.ply'
    file_voronoi_surf = 'quatrefoil_voronoi_surf.ply'
    file_voronoi_solid = 'quatrefoil_voronoi_solid.ply'
    file_voronoi_color = 'quatrefoil_voronoi_final.ply'

    # Create FilterScript objects for each step in the process
    quatrefoil_color = mlx.FilterScript(file_in=None,
                                        file_out=file_color,
                                        ml_version=ml_version)
    quatrefoil_voronoi_surf = mlx.FilterScript(file_in=file_color,
                                               file_out=file_voronoi_surf,
                                               ml_version=ml_version)
    quatrefoil_voronoi_solid = mlx.FilterScript(file_in=file_voronoi_surf,
                                                file_out=file_voronoi_solid,
                                                ml_version=ml_version)
    quatrefoil_voronoi_color = mlx.FilterScript(
        file_in=[file_color, file_voronoi_solid],
        file_out=file_voronoi_color,
        ml_version=ml_version)

    print('\n Create colored quatrefoil curve ...')
    mlx.create.cube_open_hires(quatrefoil_color,
                               size=tube_size,
                               x_segments=segments[0],
                               y_segments=segments[1],
                               z_segments=segments[2],
                               center=True)
    mlx.transform.translate(quatrefoil_color, [0, 0, length / 2])

    # Sinusoidal deformation
    r_func = '({a})*sin(({f})*({i}) + ({p})) + ({c})'.format(
        f=freq, i=increment, p=math.radians(phase), a=amplitude, c=center)
    mlx.transform.function_cyl_co(quatrefoil_color,
                                  r_func=r_func,
                                  theta_func='theta',
                                  z_func='z')

    # Save max radius in quality field so that we can save it with the file
    #  for use in the next step
    max_radius = math.sqrt(
        (tube_size[0] / 2)**2 + (tube_size[1] / 2)**2)  # at corners
    q_func = '({a})*sin(({f})*({i}) + ({p})) + ({c})'.format(
        f=freq, i=increment, p=math.radians(phase), a=amplitude, c=max_radius)
    mlx.mp_func.vq_function(quatrefoil_color, function=q_func)

    # Apply rainbow vertex colors
    mlx.vert_color.cyclic_rainbow(quatrefoil_color,
                                  direction='z',
                                  start_pt=c_start_pt,
                                  amplitude=255 / 2,
                                  center=255 / 2,
                                  freq=c_freq,
                                  phase=c_phase)

    # Deform mesh to quatrefoil curve. Merge vertices after, which
    # will weld the ends together so it becomes watertight
    quatrefoil_func = mlx.transform.deform2curve(quatrefoil_color,
                                                 curve=mlx.mp_func.torus_knot(
                                                     't',
                                                     p=3,
                                                     q=4,
                                                     scale=scale,
                                                     radius=inner_radius))
    mlx.clean.merge_vert(quatrefoil_color, threshold=0.0001)

    # Run script
    mlx.layers.delete_lower(quatrefoil_color)
    quatrefoil_color.run_script(output_mask='-m vc vq')

    print('\n Create Voronoi surface ...')
    # Move quality value into radius attribute
    mlx.mp_func.vert_attr(quatrefoil_voronoi_surf, name='radius', function='q')

    # Create seed vertices
    # For grid style holes, we will create a mesh similar to the original
    # but with fewer vertices.
    mlx.create.cube_open_hires(quatrefoil_voronoi_surf,
                               size=tube_size,
                               x_segments=holes[0] + 1,
                               y_segments=holes[1] + 1,
                               z_segments=holes[2] + 1,
                               center=True)
    mlx.select.all(quatrefoil_voronoi_surf, vert=False)
    mlx.delete.selected(quatrefoil_voronoi_surf, vert=False)
    mlx.select.cylindrical_vert(quatrefoil_voronoi_surf,
                                radius=max_radius - 0.0001,
                                inside=False)
    mlx.transform.translate(quatrefoil_voronoi_surf, [0, 0, 20])
    mlx.delete.selected(quatrefoil_voronoi_surf, face=False)

    mlx.transform.function_cyl_co(quatrefoil_voronoi_surf,
                                  r_func=r_func,
                                  theta_func='theta',
                                  z_func='z')
    mlx.transform.vert_function(quatrefoil_voronoi_surf,
                                x_func=quatrefoil_func[0],
                                y_func=quatrefoil_func[1],
                                z_func=quatrefoil_func[2])

    mlx.layers.change(quatrefoil_voronoi_surf, 0)
    mlx.vert_color.voronoi(quatrefoil_voronoi_surf)

    if quatrefoil_voronoi_surf.ml_version == '1.3.4BETA':
        sel_func = '(q <= {}) or ((radius)<={})'.format(
            web_thickness, solid_radius)
    else:
        sel_func = '(q <= {}) || ((radius)<={})'.format(
            web_thickness, solid_radius)
    mlx.select.vert_function(quatrefoil_voronoi_surf, function=sel_func)
    #mlx.select.face_function(quatrefoil_voronoi_surf, function='(vsel0 && vsel1 && vsel2)')
    mlx.select.invert(quatrefoil_voronoi_surf, face=False)
    mlx.delete.selected(quatrefoil_voronoi_surf, face=False)

    mlx.smooth.laplacian(quatrefoil_voronoi_surf, iterations=3)
    mlx.remesh.simplify(quatrefoil_voronoi_surf,
                        texture=False,
                        faces=faces_surface)

    mlx.layers.delete_lower(quatrefoil_voronoi_surf)
    #quatrefoil_voronoi_surf.save_to_file('temp_script.mlx')
    quatrefoil_voronoi_surf.run_script(script_file=None,
                                       output_mask='-m vc vq')

    print('\n Solidify Voronoi surface ...')
    mlx.remesh.uniform_resampling(quatrefoil_voronoi_solid,
                                  voxel=voxel,
                                  offset=thickness / 2,
                                  thicken=True)
    mlx.layers.delete_lower(quatrefoil_voronoi_solid)
    quatrefoil_voronoi_solid.run_script()

    print('\n Clean up & transfer color to final model ...')
    # Clean up from uniform mesh resamplng
    mlx.delete.small_parts(quatrefoil_voronoi_color)
    mlx.delete.unreferenced_vert(quatrefoil_voronoi_color)
    mlx.delete.faces_from_nonmanifold_edges(quatrefoil_voronoi_color)
    mlx.clean.split_vert_on_nonmanifold_face(quatrefoil_voronoi_color)
    mlx.clean.close_holes(quatrefoil_voronoi_color)

    # Simplify (to improve triangulation quality), refine, & smooth
    mlx.remesh.simplify(quatrefoil_voronoi_color,
                        texture=False,
                        faces=faces_solid)
    mlx.subdivide.ls3loop(quatrefoil_voronoi_color, iterations=1)
    mlx.smooth.laplacian(quatrefoil_voronoi_color, iterations=3)

    # Transfer colors from original curve
    mlx.transfer.vert_attr_2_meshes(quatrefoil_voronoi_color,
                                    source_mesh=0,
                                    target_mesh=1,
                                    color=True,
                                    max_distance=7)
    mlx.layers.delete_lower(quatrefoil_voronoi_color)
    quatrefoil_voronoi_color.run_script(script_file=None)
    print('    done! Took %.1f sec' % (time.time() - start_time))

    return None
Beispiel #15
0
def simplify(originalMeshName, SimplifiedMeshName, NumberOfFaces, WithTexture):
    # File names
    FilterScript = 'SimplificationFilter.mlx'  # script file
    original_mesh = originalMeshName  # input file
    simplified_mesh = SimplifiedMeshName  # output file
    Num_Of_Faces = int(NumberOfFaces)  # Final Number of Faces

    #Check the input mesh number of faces (so that we do not decimate to a higher number of faces than original mesh)
    MetricsMeshDictionary = {}
    MetricsMeshDictionary = mlx.files.measure_topology(original_mesh)
    #print (MetricsMeshDictionary)
    print('\n Number of faces of original mesh is: ' +
          str(MetricsMeshDictionary['face_num']))

    if (MetricsMeshDictionary['face_num'] <= Num_Of_Faces):
        #exit the script and print a message about it
        print(
            "\n SORRY your decimated mesh can not have higher number of faces that the input mesh....."
        )
        print(
            "\n ......................................................................................"
        )
        sys.exit()

    #Creating a folder named as the Number of faces: named '150000'
    print('\n Creating a folder to store the decimated model ...........')
    if not os.path.exists(str(Num_Of_Faces)):
        os.makedirs(str(Num_Of_Faces))

    simplified_meshScript = mlx.FilterScript(
        file_in=original_mesh,
        file_out=str(Num_Of_Faces) + '/' + simplified_mesh,
        ml_version='2016.12')  # Create FilterScript object

    mlx.remesh.simplify(simplified_meshScript,
                        texture=WithTexture,
                        faces=Num_Of_Faces,
                        target_perc=0.0,
                        quality_thr=1.0,
                        preserve_boundary=True,
                        boundary_weight=1.0,
                        preserve_normal=True,
                        optimal_placement=True,
                        planar_quadric=True,
                        selected=False,
                        extra_tex_coord_weight=1.0)
    print('\n Beginning the process of Decimation ...........')

    simplified_meshScript.run_script()  # Run the script
    os.chdir(str(Num_Of_Faces))
    print('\n Process of Decimation Finished ...')
    print(
        '\n Copying textures (PNG and JPEG) into the folder of decimated model....'
    )

    #go back to parent directory so we can copy the textures to the 3D Model folder
    os.chdir('..')

    #Now checking for textures in the folder of the input mesh.... (plz change if needed)
    allfilelist = os.listdir('.')

    for Afile in allfilelist[:]:
        if not (Afile.endswith(".png") or Afile.endswith(".PNG")
                or Afile.endswith(".jpg") or Afile.endswith(".JPG")):
            allfilelist.remove(Afile)
    print('\n Found the LIST of images in PNG and JPEG (textures): ')
    print(allfilelist)

    for file in allfilelist:
        shutil.copy(file, str(Num_Of_Faces))

    print('\n sleeping for 3 seconds.... ')
    time.sleep(3)
Beispiel #16
0
def stack_to_mesh(input_folder, mesh_folder, sigma=3):
    basename = os.path.basename(input_folder)

    # VTK
    imgdata = vtk_functions.folder_to_imgdata(input_folder)

    if sigma > 0:
        padding = sigma * 4
        imgdata = vtk_functions.pad_imgdata(imgdata, padding)
        imgdata = vtk_functions.gauss_imgdata(imgdata, sigma=sigma)
        print("Applied Gaussian smoothing with s=%s" % sigma)
        basename = basename + "_g_%s" % sigma

    ply_file_name = "%s/%s.ply" % (mesh_folder, basename)
    polydata = vtk_functions.imgdata_to_pd(imgdata)
    vtk_functions.write_ply(polydata, ply_file_name)

    # MESHLAB
    input_mesh = ply_file_name
    output_mesh = "%s/%s_MLX.ply" % (mesh_folder, basename)

    mesh_topology = mlx.files.measure_topology(input_mesh)
    target_faces = int(np.round(mesh_topology["face_num"] * target_reduction))

    simplified_mesh = mlx.FilterScript(file_in=input_mesh,
                                       file_out=output_mesh)

    # Apply decimation

    t_faces = int(np.round(mesh_topology["face_num"] * 0.5**1))
    mlx.remesh.simplify(simplified_mesh,
                        texture=False,
                        faces=t_faces,
                        quality_thr=1,
                        preserve_topology=False,
                        preserve_boundary=True)

    t_faces = int(np.round(mesh_topology["face_num"] * 0.5**2))
    mlx.remesh.simplify(simplified_mesh,
                        texture=False,
                        faces=t_faces,
                        quality_thr=1,
                        preserve_topology=False,
                        preserve_boundary=True)

    t_faces = int(np.round(mesh_topology["face_num"] * 0.5**3))
    mlx.remesh.simplify(simplified_mesh,
                        texture=False,
                        faces=t_faces,
                        quality_thr=1,
                        preserve_topology=False,
                        preserve_boundary=True)

    t_faces = int(np.round(mesh_topology["face_num"] * 0.5**4))
    mlx.remesh.simplify(simplified_mesh,
                        texture=False,
                        faces=t_faces,
                        quality_thr=1,
                        preserve_topology=False,
                        preserve_boundary=True)

    # Apply Taubin smoothing
    mlx.smooth.taubin(simplified_mesh, iterations=smoothing_iterations)

    simplified_mesh.run_script()
Beispiel #17
0
    
    #Remesh ohne Meshlab (zum teil)
    #data_in = ("D:\Programmierung\Poisson_Recon\testing\hole.ply")
    data_in = os.path.join(pointcloud_filename + '.ply')
    #data_out = ("D:\Programmierung\Poisson_Recon\testing\holeneu.ply")
    data_out = os.path.join(pointcloud_filename + '_mesh.ply')
    depth = 10
    scale = 1.003
    samplePerNode = 3
    pointWeight = 2
    iters = 9
    cmd = Path_poisson_recon + " --in " + data_in + ' --out '+ data_out + ' --depth '+ str(depth) + ' --scale '+ str(scale) + ' --samplePerNode '+ str(samplePerNode) + ' --pointWeight '+ str(pointWeight) + ' --iters '+ str(iters)
    sp.call(cmd)
        
    #Pointcloud_test_out = mlx.FilterScript(file_in = 'Pointcloud_test.ply', file_out = 'Pointcloud_remesh.stl', ml_version='2016.12')
    Pointcloud_test_out = mlx.FilterScript(file_in = data_out, file_out = os.path.join(remesh_filename + '.stl'), ml_version='2016.12')
#    mlx.remesh.surface_poisson_screened(Pointcloud_test_out,depth=10,
#                                 full_depth=5, cg_depth=0, scale=1.0092,
#                                 samples_per_node=3, point_weight=2.0,
#                                 iterations=8, confidence=False, pre_clean=False)
#    mlx.layers.delete(Pointcloud_test_out)
    mlx.remesh.simplify(Pointcloud_test_out, texture=False, faces=10000, target_perc=0.0,
                  quality_thr=0.95, preserve_boundary=True, boundary_weight=10.0,
                  optimal_placement=True, preserve_normal=True,
                  planar_quadric=False, selected=False, extra_tex_coord_weight=1.0,              
                  preserve_topology=True, quality_weight=False, autoclean=True)
    Pointcloud_test_out.run_script()
    delta_time_remesh = round(time.time() - start_time_tracen, 6)
    os.remove(data_out)
    
    #convert to ascii encoding
Beispiel #18
0
import meshlabxml as mlx
import sys

original_mesh = sys.argv[1]  # input file
simplified_mesh = sys.argv[2]  # output file

simplified_mesh = mlx.FilterScript(
    file_in=original_mesh, file_out=simplified_mesh,
    ml_version='2016.12')  # Create FilterScript object
mlx.remesh.simplify(simplified_mesh,
                    texture=False,
                    faces=1000,
                    target_perc=0.0,
                    quality_thr=0.3)
simplified_mesh.run_script()  # Run the script
Beispiel #19
0
os.environ['DYLD_FRAMEWORK_PATH'] = meshlabserver_path + "/../Frameworks"

# Example 1
#orange_cube = mlx.FilterScript(file_out='orange_cube.ply',
#        ml_version='2016.12')
#mlx.create.cube(orange_cube, size=[3.0, 4.0, 5.0], center=True, color='orange')
#mlx.transform.rotate(orange_cube, axis='x', angle=90)
#mlx.transform.rotate(orange_cube, axis='y', angle=50)
#mlx.transform.translate(orange_cube, value=[5.0, 5.0, 0])
#orange_cube.run_script()

# Open a mesh -> implicit in the FilterScript
# 2.) Define filters... 
# 3.) Find filters in the https://github.com/3DLIRIOUS/MeshLabXML repo 
#     or in Python console import the package and use help, eg. help(mlx.clean) 
import_mesh = mlx.FilterScript(file_in='3D_human_mesh.ply',
        file_out='new_3D_human_mesh.obj')

# First, some cleaning
mlx.clean.merge_vert(import_mesh, threshold=0.003)

mlx.delete.faces_from_nonmanifold_edges(import_mesh)
mlx.delete.nonmanifold_edge(import_mesh)
mlx.delete.nonmanifold_vert(import_mesh)
#duplicate_verts() not found??? Some weird error
#mlx.delete.duplicate_verts(import_mesh)
mlx.delete.duplicate_faces(import_mesh)

import_mesh.run_script()


Beispiel #20
0
def main():
    """Run main script"""
    # segments = number of segments to use for circles
    segments = 50
    # star_points = number of points (or sides) of the star
    star_points = 5
    # star_radius = radius of circle circumscribing the star
    star_radius = 2
    # ring_thickness = thickness of the colored rings
    ring_thickness = 1
    # sphere_radius = radius of sphere the shield will be deformed to
    sphere_radius = 2 * (star_radius + 3 * ring_thickness)

    # Star calculations:
    # Visually approximate a star by using multiple diamonds (i.e. scaled
    # squares) which overlap in the center. For the star calculations,
    # consider a central polygon with triangles attached to the edges, all
    # circumscribed by a circle.
    # polygon_radius = distance from center of circle to polygon edge midpoint
    polygon_radius = star_radius / \
        (1 + math.tan(math.radians(180 / star_points)) /
         math.tan(math.radians(90 / star_points)))
    # width = 1/2 width of polygon edge/outer triangle bottom
    width = polygon_radius * math.tan(math.radians(180 / star_points))
    # height = height of outer triangle
    height = width / math.tan(math.radians(90 / star_points))

    shield = mlx.FilterScript(file_out="shield.ply")

    # Create the colored front of the shield using several concentric
    # annuluses; combine them together and subdivide so we have more vertices
    # to give a smoother deformation later.
    mlx.create.annulus(shield,
                       radius=star_radius,
                       cir_segments=segments,
                       color='blue')
    mlx.create.annulus(shield,
                       radius1=star_radius + ring_thickness,
                       radius2=star_radius,
                       cir_segments=segments,
                       color='red')
    mlx.create.annulus(shield,
                       radius1=star_radius + 2 * ring_thickness,
                       radius2=star_radius + ring_thickness,
                       cir_segments=segments,
                       color='white')
    mlx.create.annulus(shield,
                       radius1=star_radius + 3 * ring_thickness,
                       radius2=star_radius + 2 * ring_thickness,
                       cir_segments=segments,
                       color='red')
    mlx.layers.join(shield)
    mlx.subdivide.midpoint(shield, iterations=2)

    # Create the inside surface of the shield & translate down slightly so it
    # doesn't overlap the front.
    mlx.create.annulus(shield,
                       radius1=star_radius + 3 * ring_thickness,
                       cir_segments=segments,
                       color='silver')
    mlx.transform.rotate(shield, axis='y', angle=180)
    mlx.transform.translate(shield, value=[0, 0, -0.005])
    mlx.subdivide.midpoint(shield, iterations=4)

    # Create a diamond for the center star. First create a plane, specifying
    # extra vertices to support the final deformation. The length from the
    # center of the plane to the corners should be 1 for ease of scaling, so
    # we use a side length of sqrt(2) (thanks Pythagoras!). Rotate the plane
    # by 45 degrees and scale it to stretch it out per the calculations above,
    # then translate it into place (including moving it up in z slightly so
    # that it doesn't overlap the shield front).
    mlx.create.grid(shield,
                    size=math.sqrt(2),
                    x_segments=10,
                    y_segments=10,
                    center=True,
                    color='white')
    mlx.transform.rotate(shield, axis='z', angle=45)
    mlx.transform.scale(shield, value=[width, height, 1])
    mlx.transform.translate(shield, value=[0, polygon_radius, 0.001])

    # Duplicate the diamond and rotate the duplicates around, generating the
    # star.
    for _ in range(1, star_points):
        mlx.layers.duplicate(shield)
        mlx.transform.rotate(shield, axis='z', angle=360 / star_points)

    # Combine everything together and deform using a spherical function.
    mlx.layers.join(shield)
    mlx.transform.vert_function(shield,
                                z_func='sqrt(%s-x^2-y^2)-%s+z' %
                                (sphere_radius**2, sphere_radius))

    # Run the script using meshlabserver and generate the model
    shield.run_script()
    return None