Beispiel #1
0
def test_to_obj():
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    mesh.to_obj('data/temp.obj')
    mesh = Mesh.from_obj(compas.get('temp.obj'))
    assert mesh.number_of_faces() == 25
    assert mesh.number_of_vertices() == 36
    assert mesh.number_of_edges() == 60
Beispiel #2
0
    def read_mesh_from_filename(self, filename, meshcls):
        if not os.path.isfile(filename):
            raise FileNotFoundError("No such file: '%s'" % filename)
        extension = filename[(filename.rfind(".") + 1):]
        if extension == "dae": # no dae support yet
            #mesh = Mesh.from_dae(filename)
            obj_filename = filename.replace(".dae", ".obj")
            if os.path.isfile(obj_filename):
                mesh = Mesh.from_obj(obj_filename)
                # former DAE files have yaxis and zaxis swapped
                # TODO: already fix in conversion to obj
                frame = Frame([0,0,0], [1,0,0], [0,0,1])
                T = Transformation.from_frame(frame)
                mesh_transform(mesh, T)
            else:
                raise FileNotFoundError("Please convert '%s' into an OBJ file, \
                                         since DAE is currently not supported \
                                         yet." % filename)
        elif extension == "obj":
            mesh = Mesh.from_obj(filename)
        elif extension == "stl":
            mesh = Mesh.from_stl(filename)
        else:
            raise ValueError("%s file types not yet supported" %
                extension.upper())

        return meshcls(mesh)
Beispiel #3
0
def test_to_obj():
    _, fname = tempfile.mkstemp(suffix='.obj', prefix='temp_mesh_test')
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    mesh.to_obj(fname)
    mesh = Mesh.from_obj(fname)
    assert mesh.number_of_faces() == 25
    assert mesh.number_of_vertices() == 36
    assert mesh.number_of_edges() == 60
Beispiel #4
0
def test_normal():
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    assert mesh.normal() == [0.0, 0.0, 1.0]

    mesh = Mesh.from_stl(compas.get('cube_binary.stl'))
    assert mesh.normal() == [0.0, 0.0, 0.0]

    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.normal() == [-2.380849234996509e-06, 4.1056122145028854e-05, 0.8077953732329284]
Beispiel #5
0
def test_centroid():
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    assert mesh.centroid() == [5.0, 5.0, 0.0]

    mesh = Mesh.from_stl(compas.get('cube_binary.stl'))
    assert mesh.centroid() == [0.0, 0.0, 0.5]

    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.centroid() == [2.508081952064351, 2.554046390557884, 1.2687133268242006]
Beispiel #6
0
def test_area():
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    assert mesh.area() == 100

    mesh = Mesh.from_stl(compas.get('cube_binary.stl'))
    assert mesh.area() == 6

    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.area() == 22.802429316496635
Beispiel #7
0
def test_vertices_on_boundary():
    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.vertices_on_boundary() == [
        0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 17, 33, 35, 37, 38, 39, 40, 41, 42, 43,
        44, 45, 53, 62, 71, 73, 74, 75, 76, 84, 85, 86, 87, 88, 89, 98
    ]

    mesh = Mesh.from_obj(compas.get('boxes.obj'))
    assert mesh.vertices_on_boundary() == []
def main():

    compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL))
    delta = get_param({}, key='delta',
                      defaults_type='gcode')  # boolean for delta printers
    print_volume_x = get_param({}, key='print_volume_x',
                               defaults_type='gcode')  # in mm
    print_volume_y = get_param({}, key='print_volume_y',
                               defaults_type='gcode')  # in mm
    if delta:
        move_mesh_to_point(compas_mesh, Point(0, 0, 0))
    else:
        move_mesh_to_point(compas_mesh,
                           Point(print_volume_x / 2, print_volume_y / 2, 0))

    # ----- slicing
    slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=4.5)
    slicer.slice_model()
    generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=4)
    simplify_paths_rdp_igl(slicer, threshold=0.6)
    seams_smooth(slicer, smooth_distance=10)
    slicer.printout_info()
    save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json')

    # ----- print organization
    print_organizer = PlanarPrintOrganizer(slicer)
    print_organizer.create_printpoints()
    # Set fabrication-related parameters
    set_extruder_toggle(print_organizer, slicer)
    print_organizer.printout_info()

    # create and output gcode
    gcode_parameters = {}  # leave all to default
    gcode_text = print_organizer.output_gcode(gcode_parameters)
    utils.save_to_text_file(gcode_text, OUTPUT_DIR, 'my_gcode.gcode')
Beispiel #9
0
def test_vertices_on_boundaries():
    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    print(mesh.vertices_on_boundaries())
    assert mesh.vertices_on_boundaries() == [[
        6, 5, 4, 3, 2, 1, 0, 15, 14, 85, 84, 86, 76, 75, 74, 73, 88, 87, 33,
        71, 17, 53, 89, 35, 62, 98, 44, 45, 37, 38, 39, 40, 41, 42, 43, 7
    ]]
def weld_mesh(mesh, OUTPUT_PATH, precision='2f'):
    """ Welds mesh and check that the result is valid. """
    for f_key in mesh.faces():
        if len(mesh.face_vertices(f_key)) < 3:
            mesh.delete_face(f_key)

    welded_mesh = compas.datastructures.mesh_weld(mesh, precision=precision)

    welded_mesh.to_obj(os.path.join(
        OUTPUT_PATH, 'temp.obj'))  # make sure there's no empty f_keys
    welded_mesh = Mesh.from_obj(os.path.join(
        OUTPUT_PATH, 'temp.obj'))  # TODO: find a better way to do this

    try:
        welded_mesh.unify_cycles()
        logger.info("Unified cycles of welded_mesh")
    except AssertionError:
        logger.error("Attention! Could NOT unify cycles of welded_mesh")

    if not welded_mesh.is_valid():  # and iteration < 3:
        logger.error("Attention! Welded mesh is INVALID")
    if not welded_mesh.is_manifold():
        logger.error("Attention! Welded mesh is NON-MANIFOLD")

    return welded_mesh
Beispiel #11
0
def get_mesh_info(object_dir='faces.obj'):
    """
    This function generates a mesh for an input object
    
    input: object_dir => the input object direction
    output: mesh_info_dict => all the detalies about the generated mesh inclding
            mesh instance, the vertices, vectecies on the boundary, and 
            non-boundary vertices
    """
    # create the mesh from .obj file
    mesh = Mesh.from_obj(cp.get(object_dir))
    # get all vertices of the mesh
    all_vertices = list(mesh.vertices())
    # get vertices on the boundary of the mesh
    on_boundry_vertices = list(mesh.vertices_on_boundary())
    # get vertices which are not on the boundary of the mesh
    non_on_boundry_vertices = list(
        set(all_vertices) - set(on_boundry_vertices))
    mesh_info_dict = {
        'mesh': mesh,
        'all_vertices': all_vertices,
        'on_boundry_vertices': on_boundry_vertices,
        'non_on_boundry_vertices': non_on_boundry_vertices
    }
    return mesh_info_dict
Beispiel #12
0
 def from_obj(self):
     filename, _ = get_obj_file()
     if filename:
         self.mesh = Mesh.from_obj(filename)
         # self.center_mesh()
         self.view.make_buffers()
         self.view.updateGL()
Beispiel #13
0
def main():
    compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL))
    move_mesh_to_point(compas_mesh, Point(0, 0, 0))

    # Slicing
    slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=5.0)
    slicer.slice_model()

    # Sorting into vertical layers and reordering
    sort_into_vertical_layers(slicer, max_paths_per_layer=10)
    reorder_vertical_layers(slicer, align_with="x_axis")

    # Post-processing
    generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=5)
    simplify_paths_rdp_igl(slicer, threshold=0.7)
    seams_smooth(slicer, smooth_distance=10)
    slicer.printout_info()
    save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json')

    # PlanarPrintOrganization
    print_organizer = PlanarPrintOrganizer(slicer)
    print_organizer.create_printpoints()

    set_extruder_toggle(print_organizer, slicer)
    add_safety_printpoints(print_organizer, z_hop=10.0)
    set_linear_velocity_constant(print_organizer, v=25.0)
    set_blend_radius(print_organizer, d_fillet=10.0)

    print_organizer.printout_info()

    printpoints_data = print_organizer.output_printpoints_dict()
    utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json')
Beispiel #14
0
def visualize_mesh_traversal() -> None:
    ''' Datastructures task
    '''

    mesh = Mesh.from_obj(get('faces.obj'))

    x_values = {}
    for vkey in mesh.vertices_on_boundary():
        x_values[vkey] = mesh.vertex_coordinates(vkey)[0]

    max_x = max(x_values.values())

    print("Vertices on the right edge of the mesh:")
    print([key for key in x_values if x_values[key] == max_x])

    start_key = int(input("\nSelect start vertex: "))

    path_verts = traverse_mesh(mesh, start_key)

    print('\nPath calculated, starting MeshPlotter.')

    plotter = MeshPlotter(mesh, figsize=(16, 10))
    plotter.draw_vertices(text={key: key
                                for key in path_verts},
                          radius=0.2,
                          facecolor={key: '#ff0000'
                                     for key in path_verts})

    plotter.draw_edges()
    plotter.draw_faces()

    plotter.show()
Beispiel #15
0
def test_face_coordinates():
    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.face_coordinates(0, 'xyz') == [
        [3.661179780960083, 2.32784628868103, 1.580246925354004], [3.775796413421631, 1.727785348892212, 1.382716059684753],
        [4.22069787979126, 1.696692585945129, 1.086419701576233], [4.109739303588867, 2.34430718421936, 1.283950567245483]]
    assert mesh.face_coordinates(0, 'zy') == [
        [1.580246925354004, 2.32784628868103], [1.382716059684753, 1.727785348892212], [1.086419701576233, 1.696692585945129],
        [1.283950567245483, 2.34430718421936]]
Beispiel #16
0
def test_vertex_faces():
    mesh = Mesh.from_obj(compas.get('faces.obj'))
    corners = list(mesh.vertices_where({'vertex_degree': 2}))
    boundary = list(mesh.vertices_where({'vertex_degree': 3}))
    internal = list(mesh.vertices_where({'vertex_degree': 4}))
    assert len(mesh.vertex_faces(corners[0])) == 1
    assert len(mesh.vertex_faces(boundary[0])) == 2
    assert len(mesh.vertex_faces(internal[0])) == 4
Beispiel #17
0
def test_vertex_normal():
    mesh = Mesh.from_obj(compas.get('quadmesh.obj'))
    assert mesh.vertex_normal(0) == [
        -0.7875436283909406, 0.07148692938164082, 0.6120985642103861
    ]
    assert mesh.vertex_normal(5) == [
        -0.482011312317331, -0.32250183520381565, 0.814651864963369
    ]
Beispiel #18
0
    def create_mesh(self, filepath):
        """
        creates a "compas" mesh from a Rhino mesh object (saved as .obj file)
        filepath: file path in string format
        saves: compas mesh object
        """
        mesh = Mesh.from_obj(filepath)

        self.dic_attr['mesh'] = mesh
Beispiel #19
0
def parse_collision_mesh_from_path(dir_path, filename, scale=1e-3):
    file_path = os.path.join(dir_path, filename)
    obj_name = filename.split('.')[0]
    if filename.endswith('.obj'):
        mesh = Mesh.from_obj(file_path)
    elif filename.endswith('.stl'):
        mesh = Mesh.from_stl(file_path)
    else:
        return None
    cm = CollisionMesh(mesh, obj_name)
    cm.scale(scale)
    return cm
Beispiel #20
0
    def load_model(self, xdraw_function=None):
        """Load the geometry (meshes) of the robot.

        Args:
            xdraw_function (function, ): The function to draw the
                meshes in the respective CAD environment. Defaults to None.
        """
        path = self.get_model_path()

        # the links loaded as meshes
        m0 = Mesh.from_obj(os.path.join(path, 'base_and_shoulder.obj'))
        m1 = Mesh.from_obj(os.path.join(path, 'upperarm.obj'))
        m2 = Mesh.from_obj(os.path.join(path, 'forearm.obj'))
        m3 = Mesh.from_obj(os.path.join(path, 'wrist1.obj'))
        m4 = Mesh.from_obj(os.path.join(path, 'wrist2.obj'))
        m5 = Mesh.from_obj(os.path.join(path, 'wrist3.obj'))

        # draw the geometry in the respective CAD environment
        if xdraw_function:
            m0 = xdraw_function(m0)
            m1 = xdraw_function(m1)
            m2 = xdraw_function(m2)
            m3 = xdraw_function(m3)
            m4 = xdraw_function(m4)
            m5 = xdraw_function(m5)

        self.model = [m0, m1, m2, m3, m4, m5]
Beispiel #21
0
def main():
    start_time = time.time()

    ### --- Load stl
    compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL))

    ### --- Move to origin
    move_mesh_to_point(compas_mesh, Point(0, 0, 0))

    ### --- Slicer
    # options: 'default' : Both for open and closed paths. But slow
    #          'cgal' : Very fast. Only for closed paths. Requires additional installation (compas_cgal).
    slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=1.5)
    slicer.slice_model()

    ### --- Generate brim
    generate_brim(slicer, layer_width=3.0, number_of_brim_paths=3)

    ### --- Simplify the paths by removing points with a certain threshold
    # change the threshold value to remove more or less points
    simplify_paths_rdp(slicer, threshold=0.7)

    ### --- Smooth the seams between layers
    # change the smooth_distance value to achieve smoother, or more abrupt seams
    seams_smooth(slicer, smooth_distance=10)

    ### --- Prints out the info of the slicer
    slicer.printout_info()

    viewer = ObjectViewer()
    viewer.view.use_shaders = False
    slicer.visualize_on_viewer(viewer)

    utils.save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json')

    ### --- Fabrication - related information
    print_organizer = PrintOrganizer(slicer)
    print_organizer.create_printpoints(compas_mesh)
    print_organizer.set_extruder_toggle()
    print_organizer.add_safety_printpoints(z_hop=20)
    print_organizer.set_linear_velocity("constant", v=25)

    ### --- Save printpoints dictionary to json file
    printpoints_data = print_organizer.output_printpoints_dict()
    utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json')

    print_organizer.visualize_on_viewer(viewer, visualize_polyline=True, visualize_printpoints=False)
    viewer.update()
    viewer.show()

    end_time = time.time()
    print("Total elapsed time", round(end_time - start_time, 2), "seconds")
def create_setup(filename):
    """ Setting up the stage for testing. """
    FILE = os.path.abspath(os.path.join(DATA, filename))
    compas_mesh = Mesh.from_obj(FILE)
    slicer = PlanarSlicer(compas_mesh, slicer_type="default", layer_height=20)
    slicer.slice_model()
    generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=3)
    simplify_paths_rdp(slicer, threshold=1.3)
    # seams_smooth(slicer, smooth_distance=10)
    slicer.printout_info()
    print_organizer = PlanarPrintOrganizer(slicer)
    print_organizer.create_printpoints()
    return slicer, print_organizer
Beispiel #23
0
    def load_model(self, xdraw_function=None):
        """Load the geometry (meshes) of the tool.

        Args:
            xdraw_function (function, optional): The function to draw the
                meshes in the respective CAD environment. Defaults to None.
        """
        datapath = get_data("robots/ur/tools/measurement_tool.obj")
        self.model = [Mesh.from_obj(datapath)]

        # draw the geometry in the respective CAD environment
        if xdraw_function:
            for i, m in enumerate(self.model):
                self.model[i] = xdraw_function(m)
Beispiel #24
0
def _mesh_import(url, filename):
    """Internal function to load meshes using the correct loader.

    Name and file might be the same but not always, e.g. temp files."""
    file_extension = _get_file_format(url)

    if file_extension not in SUPPORTED_FORMATS:
        raise NotImplementedError(
            'Mesh type not supported: {}'.format(file_extension))
    
    print(filename)
    
    if file_extension == "dae": # no dae support yet
        #mesh = Mesh.from_dae(filename)
        obj_filename = filename.replace(".dae", ".obj")
        if os.path.isfile(obj_filename):
            mesh = Mesh.from_obj(obj_filename)
            # former DAE files have yaxis and zaxis swapped
            # TODO: already fix in conversion to obj
            frame = Frame([0,0,0], [1,0,0], [0,0,1])
            T = Transformation.from_frame(frame)
            mesh_transform(mesh, T)
            return mesh
        else:
            raise FileNotFoundError("Please convert '%s' into an OBJ file, \
                                        since DAE is currently not supported \
                                        yet." % filename)

    if file_extension == 'obj':
        return Mesh.from_obj(filename)
    elif file_extension == 'stl':
        return Mesh.from_stl(filename)
    elif file_extension == 'ply':
        return Mesh.from_ply(filename)

    raise Exception
Beispiel #25
0
def main():
    start_time = time.time()

    ### --- Load stl
    compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL))

    ### --- Move to origin
    move_mesh_to_point(compas_mesh, Point(0, 0, 0))

    ### --- Slicer
    # try out different slicers by changing the slicer_type
    # options: 'default', 'meshcut', 'cgal'
    slicer = PlanarSlicer(compas_mesh, slicer_type="default", layer_height=1.5)
    slicer.slice_model()

    ### --- Generate brim
    generate_brim(slicer, layer_width=3.0, number_of_brim_paths=3)

    ### --- Simplify the printpaths by removing points with a certain threshold
    # change the threshold value to remove more or less points
    simplify_paths_rdp(slicer, threshold=0.9)

    ### --- Prints out the info of the slicer
    slicer.printout_info()

    viewer = ObjectViewer()
    viewer.view.use_shaders = False
    slicer.visualize_on_viewer(viewer)

    utils.save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json')

    ### --- Fabrication - related information
    print_organizer = PrintOrganizer(slicer)
    print_organizer.create_printpoints(compas_mesh)
    print_organizer.set_extruder_toggle()
    print_organizer.add_safety_printpoints(z_hop=20)
    print_organizer.set_linear_velocity("constant", v=25)

    ### --- Save printpoints dictionary to json file
    printpoints_data = print_organizer.output_printpoints_dict()
    utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json')

    # # print_organizer.visualize_on_viewer(viewer, visualize_polyline=True, visualize_printpoints=False)
    viewer.update()
    viewer.show()

    end_time = time.time()
    print("Total elapsed time", round(end_time - start_time, 2), "seconds")
Beispiel #26
0
def load_multiple_meshes(starts_with, ends_with, path, folder_name):
    """ Load all the meshes that have the specified name, and print them in different colors. """
    filenames = get_files_with_name(starts_with, ends_with,
                                    os.path.join(path, folder_name, 'output'))
    meshes = [
        Mesh.from_obj(os.path.join(path, folder_name, 'output', filename))
        for filename in filenames
    ]

    loaded_meshes = []
    for i, m in enumerate(meshes):
        artist = MeshArtist(m)
        color = get_color(i, total=len(meshes))
        mesh = artist.draw(color)
        loaded_meshes.append(mesh)

    return loaded_meshes
Beispiel #27
0
def _mesh_import(name, file):
    """Internal function to load meshes using the correct loader.

    Name and file might be the same but not always, e.g. temp files."""
    file_extension = _get_file_format(name)

    if file_extension not in SUPPORTED_FORMATS:
        raise NotImplementedError(
            'Mesh type not supported: {}'.format(file_extension))

    if file_extension == 'obj':
        return Mesh.from_obj(file)
    elif file_extension == 'stl':
        return Mesh.from_stl(file)
    elif file_extension == 'ply':
        return Mesh.from_ply(file)

    raise Exception
Beispiel #28
0
def fixed_waam_setup():
    HERE = os.path.dirname(__file__)
    package_path = os.path.abspath(
        os.path.join(HERE, "..", "..", "data", "robots", "abb_fixed_waam"))
    urdf_filename = os.path.join(package_path, "urdf", "abb_fixed_waam.urdf")
    srdf_filename = os.path.join(package_path, "srdf", "abb_fixed_waam.srdf")

    model = RobotModel.from_urdf_file(urdf_filename)
    semantics = RobotSemantics.from_srdf_file(srdf_filename, model)

    tool_frame_robotA = Frame.from_euler_angles(
        [0.591366, -0.000922, 1.570177],
        static=True,
        axes='xyz',
        point=[-0.002241, -0.000202, 0.505922])
    tool_mesh_robotA = Mesh.from_obj(
        os.path.join(package_path, "meshes", "collision", "waam_tool.obj"))
    robotA_tool = Tool(tool_mesh_robotA,
                       tool_frame_robotA,
                       collision=tool_mesh_robotA)
    return urdf_filename, semantics, robotA_tool
Beispiel #29
0
    return f, g


# ==============================================================================
# Main
# ==============================================================================

if __name__ == "__main__":

    import compas
    from compas.datastructures import Mesh
    from compas.plotters import MeshPlotter
    from compas.topology import mesh_quads_to_triangles

    mesh = Mesh.from_obj(compas.get('faces.obj'))

    mesh_quads_to_triangles(mesh)

    split = mesh.split_edge_tri(15, 20)

    facecolor = {
        key: '#cccccc' if key != split else '#ff0000'
        for key in mesh.vertices()
    }

    plotter = MeshPlotter(mesh, figsize=(10, 7))

    plotter.draw_vertices(text={key: key
                                for key in mesh.vertices()},
                          radius=0.2,
Beispiel #30
0
    return pymesh.slice_mesh(m, [0, 0, 1], 50)


# def mesh_contours_igl(mesh, levels=None, density=100):
#     pass

# ==============================================================================
# Main
# ==============================================================================

if __name__ == "__main__":

    import compas
    from compas.datastructures import Mesh
    from compas.datastructures import mesh_contours_numpy

    mesh = Mesh.from_obj(compas.get('saddle.obj'))

    # res = mesh_contours_pymesh(mesh)
    # print(res)

    levels, contours = mesh_contours_numpy(mesh)

    for i in range(len(contours)):
        level = levels[i]
        contour = contours[i]
        print(level)
        for path in contour:
            for polygon in path:
                print([point.tolist() for point in polygon])