コード例 #1
0
def planarize_mesh(mesh,
                   fixed=None,
                   kmax=100,
                   d=1.0,
                   callback=None,
                   callback_args=None):
    """Planarise the faces of a mesh.

    Planarisation is implemented as a two-step iterative procedure. At every
    iteration, faces are first individually projected to their best-fit plane,
    and then the vertices are projected to the centroid of the disconnected
    corners of the faces.

    Parameters:
        mesh
        fixed
        kmax
        d
        callback
        callback_args

    Returns:
        None

    """
    # planarize every face individually
    # by projecting all vertices onto the best-fit plane
    # reconnect the corners of the faces
    # by mapping the vertices to the centroids of the face corners

    if callback:
        if not callable(callback):
            raise Exception('The callback is not callable.')

    fixed = fixed or []
    fixed = set(fixed)

    for k in range(kmax):

        key_xyz = {key: [] for key in mesh.vertices()}

        for fkey in mesh.faces():
            points = mesh.face_coordinates(fkey)
            plane = bestfit_plane_from_points(points)
            projections = project_points_plane(points, plane)

            for index, key in enumerate(mesh.face_vertices(fkey)):
                key_xyz[key].append(projections[index])

        for key, attr in mesh.vertices(data=True):
            if key in fixed:
                continue

            x, y, z = centroid_points(key_xyz[key])
            attr['x'] = x
            attr['y'] = y
            attr['z'] = z

        if callback:
            callback(mesh, k, callback_args)
コード例 #2
0
ファイル: planarisation.py プロジェクト: mpopescu/compas
def planarize_faces(vertices,
                    faces,
                    fixed=None,
                    kmax=100,
                    callback=None,
                    callback_args=None):
    """Planarise a set of connected faces.

    Planarisation is implemented as a two-step iterative procedure. At every
    iteration, faces are first individually projected to their best-fit plane,
    and then the vertices are projected to the centroid of the disconnected
    corners of the faces.

    Parameters
    ----------
    vertices : list
        The vertex coordinates.
    faces : list
        The vertex indices per face.
    fixed : list, optional [None]
        A list of fixed vertices.
    kmax : int, optional [100]
        The number of iterations.
    callback : callable, optional [None]
        A user-defined callback that is called after every iteration.
    callback_args : list, optional [None]
        A list of arguments to be passed to the callback function.

    """
    if callback:
        if not callable(callback):
            raise Exception('The callback is not callable.')

    fixed = fixed or []
    fixed = set(fixed)

    for k in range(kmax):

        positions = [[] for _ in range(len(vertices))]

        for face in iter(faces):
            points = [vertices[index] for index in face]
            plane = bestfit_plane(points)
            projections = project_points_plane(points, plane)

            for i, index in enumerate(face):
                positions[index].append(projections[i])

        for index, vertex in enumerate(vertices):
            if index in fixed:
                continue

            x, y, z = centroid_points(positions[index])
            vertex[0] = x
            vertex[1] = y
            vertex[2] = z

        if callback:
            callback(k, callback_args)
コード例 #3
0
def mesh_planarize_faces(mesh,
                         fixed=None,
                         kmax=100,
                         callback=None,
                         callback_args=None):
    """Planarise a set of connected faces.

    Planarisation is implemented as a two-step iterative procedure. At every
    iteration, faces are first individually projected to their best-fit plane,
    and then the vertices are projected to the centroid of the disconnected
    corners of the faces.

    Parameters
    ----------
    mesh : :class:`compas.datastructures.Mesh`
        A mesh object.
    fixed : list[int], optional
        A list of fixed vertices.
    kmax : int, optional
        The number of iterations.
    d : float, optional
        A damping factor.
    callback : callable, optional
        A user-defined callback that is called after every iteration.
    callback_args : list[Any], optional
        A list of arguments to be passed to the callback function.

    Returns
    -------
    None

    """
    if callback:
        if not callable(callback):
            raise Exception('The callback is not callable.')

    fixed = fixed or []
    fixed = set(fixed)

    for k in range(kmax):

        positions = {key: [] for key in mesh.vertices()}

        for fkey in mesh.faces():
            vertices = mesh.face_vertices(fkey)
            points = [mesh.vertex_coordinates(key) for key in vertices]
            plane = bestfit_plane(points)
            projections = project_points_plane(points, plane)

            for index, key in enumerate(vertices):
                positions[key].append(projections[index])

        for key, attr in mesh.vertices(True):
            if key in fixed:
                continue

            x, y, z = centroid_points(positions[key])
            attr['x'] = x
            attr['y'] = y
            attr['z'] = z

        if callback:
            callback(k, callback_args)
コード例 #4
0
def test_project_points_plane():
    assert allclose(
        project_points_plane([[0, 2.5, 2]], ([3, 4, 5], [6, 7, 8.8])),
        [[2.0278256587047525, 4.865796601822211, 4.974144299433638]])
コード例 #5
0
def RunCommand(is_interactive):

    #load Derivation and model
    derivation = Derivation.from_json(
        rhino_UI_utilities.get_json_file_location())
    model = derivation.get_next_step()

    #select beams
    selection_reference = []
    selection_reference.append(
        rs.GetObject(message="select start Beam", filter=32, preselect=True))
    selection_reference.extend(
        rs.GetObjects(message="select Beams to connect",
                      filter=32,
                      preselect=True))

    #load helpers
    helper = UI_helpers()

    #name search
    selected_beams = helper.extract_BeambyName(model, selection_reference)

    #check for parallel planes, uses the function above
    start_beam = selected_beams[0]
    beams_to_connect = selected_beams[1:]
    parallel_check = check_for_parallel_vectors(start_beam, beams_to_connect)
    if parallel_check != True:
        raise IndexError('beams are not parallel')
    else:
        print("beams are parallel")

    #check for coplanarity, uses the function above
    coplanar_planes = {}
    face_ids_coplanar_planes = {}
    for i in range(1, 5):
        start_beam_plane = start_beam.face_plane(i).copy()
        start_beam_origin = start_beam_plane.point
        a = get_coplanar_planes(start_beam_plane, start_beam_origin,
                                beams_to_connect)
        if a != False:
            coplanar_planes['' + str(i)] = a[0]
            face_ids_coplanar_planes['' + str(i)] = a[1]
        else:
            pass
    print("face_dictionary here", face_ids_coplanar_planes)
    if len(coplanar_planes.keys()) == 2:
        print("'success", coplanar_planes)
    else:
        raise IndexError('beams are not coplanar')

    #user inputs
    face_id = rs.GetInteger(("possible face connections " + "face_id " +
                             coplanar_planes.keys()[0] + " or face_id " +
                             coplanar_planes.keys()[1]), None, None, None)
    start_point = (helper.Get_SelectPointOnMeshEdge("Select mesh edge",
                                                    "Pick point on edge"))
    ext_start = rs.GetReal("extension length start", 200, None, None)
    ext_end = rs.GetReal("extension length end", 200, None, None)

    #list of coplanar planes extracted from coplanar_planes dict using face_id as key
    coplanar_planes_along_selected_face = []
    coplanar_planes_along_selected_face.append(
        start_beam.face_plane(face_id).copy())
    for key, value in coplanar_planes.items():
        if key == "" + str(face_id):
            coplanar_planes_along_selected_face.extend(value)

    #list of face_ids of coplanar planes
    coplanar_face_ids = []
    coplanar_face_ids.append(face_id)
    for key, value in face_ids_coplanar_planes.items():
        if key == "" + str(face_id):
            coplanar_face_ids.extend(value)

    #intersection points by passing a line from the origin of start beam to the adjacent planes of the coplanar planes of all beams
    points_to_compare = []
    for i in range(len(selected_beams)):
        beam = selected_beams[i]
        start_beam_selected_face_frame = selected_beams[0].face_frame(face_id)
        line_pt_a = start_beam_selected_face_frame.point
        normal = start_beam_selected_face_frame.normal
        line_pt_b = add_vectors(line_pt_a, scale_vector(normal, 0.3))
        line_to_intersect = Line(line_pt_a, line_pt_b)

        face_index = coplanar_face_ids[i]
        adjacent_planes = beam.neighbour_face_plane(face_index)
        for p in adjacent_planes:
            intersection_point = intersection_line_plane(line_to_intersect, p)
            points_to_compare.append(intersection_point)

    viz_pts = []
    #project distance from  points_to_compare to the plane of the start Beam
    distances = []
    start_beam_face_frame = start_beam.face_frame(face_id).copy()
    start_beam_Plane_perpendicular_to_face_id_Plane = Plane(
        start_beam_face_frame.point, start_beam_face_frame.normal)
    viz_pts.append(start_beam_Plane_perpendicular_to_face_id_Plane.point)
    for point in points_to_compare:
        viz_pts.append(point)
        vector = subtract_vectors(
            point, start_beam_Plane_perpendicular_to_face_id_Plane.point)
        distances.append(
            dot_vectors(
                vector,
                start_beam_Plane_perpendicular_to_face_id_Plane.normal))

    #search to find max point
    maximum_distance = max(distances)
    minimum_distance = min(distances)
    beam_length = (maximum_distance - minimum_distance) + ext_start + ext_end
    ext_len = maximum_distance + ext_start

    #project selected point to perpendicular planes of the beams to connect
    if coplanar_planes.keys()[0] == "1" or coplanar_planes.keys()[0] == "3":
        start_beam_perpendicular_plane = start_beam.face_plane(5).copy()

    elif coplanar_planes.keys()[0] == "2" or coplanar_planes.keys()[0] == "4":
        start_beam_perpendicular_plane = start_beam.face_plane(6).copy()

    tol = 1.0e-5
    # tol = 5.0
    perpendicular_plane = []
    for beam in beams_to_connect:
        for i in range(5, 7):
            beam_plane = beam.face_plane(i).copy()
            print("beam_plane", beam_plane)
            angle_check = start_beam_perpendicular_plane.normal.angle(
                beam_plane.normal)
            print("angle", angle_check)
            if (abs(angle_check) - 0) < tol or (abs(angle_check) - 180) < tol:
                perpendicular_plane.append(beam_plane)

    print(perpendicular_plane)
    print(len(perpendicular_plane))
    #project points
    projected_point_list = []
    new_start_point = project_points_plane([start_point],
                                           start_beam_perpendicular_plane)
    projected_point_list.extend(new_start_point)
    for plane in perpendicular_plane:
        new_point = project_points_plane(new_start_point, plane)
        projected_point_list.extend(new_point)

    #list of distance to move joints on match beam
    model.rule_Connect_90lap(selected_beams, projected_point_list,
                             coplanar_face_ids, beam_length, ext_len,
                             create_id())
    print(len(projected_point_list))
    print(projected_point_list)

    #Save Derivation (Model is also saved)
    derivation.to_json(rhino_UI_utilities.get_json_file_location(),
                       pretty=True)

    # Visualization
    viz_point = []
    for pt in projected_point_list:
        a = (pt[0], pt[1], pt[2])
        viz_point.append({'pos': a, 'color': (0, 255, 0)})

    artist = MeshArtist(None, layer='BEAM::Beams_out')
    artist.clear_layer()
    artist.draw_points(viz_point)
    for beam in model.beams:
        artist = MeshArtist(
            beam.mesh, layer='BEAM::Beams_out'
        )  #.mesh is not ideal fix in beam and assemble class
        artist.draw_faces(join_faces=True)
コード例 #6
0
ファイル: trans_fins.py プロジェクト: WWmore/AAG2018
pts_a = rs.DivideCurve(crv_a, div_r)

# ------------------------------
# compas geometry function

# create planes along the rail curve
planes = []
for i in range(div_r):
    vec = subtract_vectors(pts_a[i + 1], pts_a[i])
    planes.append([pts_a[i], vec])

# subsequentely project profile curve to all planes
pts_uv = []
pts = pts_p
for i in range(div_r - 1):
    pts = project_points_plane(pts, planes[i])
    pts_uv.append(pts)

# create mesh object
trans_mesh = Mesh()

# add vertices
for u in xrange(len(pts_uv)):
    for v in xrange(len(pts_uv[u])):
        x, y, z = pts_uv[u][v]
        trans_mesh.add_vertex((u, v), x=x, y=y, z=z)

# add faces
for u in xrange(len(pts_uv) - 1):
    for v in xrange(len(pts_uv[u]) - 1):
        trans_mesh.add_face([(u, v), (u + 1, v), (u + 1, v + 1), (u, v + 1)])