How to use the trimesh.util.unitize function in trimesh

To help you get started, we’ve selected a few trimesh examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github mikedh / trimesh / trimesh / scene / cameras.py View on Github external
Will return one ray per pixel, as set in camera.resolution.

    Parameters
    --------------
    camera : trimesh.scene.Camera

    Returns
    --------------
    vectors : (n, 3) float
      Ray direction vectors in camera frame with z == -1
    """
    # get the on-plane coordinates
    xy, pixels = ray_pixel_coords(camera)
    # convert vectors to 3D unit vectors
    vectors = util.unitize(
        np.column_stack((xy, -np.ones_like(xy[:, :1]))))
    return vectors, pixels
github mikedh / trimesh / trimesh / path / simplify.py View on Github external
if final and (angle > tol.seg_angle_min).sum() < 3:
        log.debug('final: angle %s', str(angle))
        return None

    # check segment length as a fraction of drawing scale
    scaled = segment / scale

    if (scaled > tol.seg_frac).any():
        if verbose:
            log.debug('circle fit error: segment %s', str(scaled))
        return None

    # check to make sure the line segments on the ends are actually
    # tangent with the candidate circle fit
    mid_pt = points[[0, -2]] + (vectors[[0, -1]] * .5)
    radial = util.unitize(mid_pt - C)
    ends = util.unitize(vectors[[0, -1]])
    tangent = np.abs(np.arccos(util.diagonal_dot(radial, ends)))
    tangent = np.abs(tangent - np.pi / 2).max()

    if tangent > tol.tangent:
        if verbose:
            log.debug('circle fit error: tangent %f',
                      np.degrees(tangent))
        return None

    result = {'center': C,
              'radius': R}

    return result
github mikedh / trimesh / trimesh / path / arc.py View on Github external
# it's a lot easier to treat 2D as 3D with a zero Z value
    points, is_2D = util.stack_3D(points, return_2D=True)

    # find the two edge vectors of the triangle
    edge_direction = np.diff(points, axis=0)
    edge_midpoints = (edge_direction * 0.5) + points[:2]

    # three points define a plane, so find signed normal
    plane_normal = np.cross(*edge_direction[::-1])
    plane_normal /= np.linalg.norm(plane_normal)

    # unit vector along edges
    vector_edge = util.unitize(edge_direction)

    # perpendicular cector to each segment
    vector_perp = util.unitize(np.cross(vector_edge, plane_normal))

    # run the line-line intersection to find the point
    intersects, center = line_line(origins=edge_midpoints,
                                   directions=vector_perp,
                                   plane_normal=plane_normal)

    if not intersects:
        raise ValueError('segments do not intersect:\n{}'.format(
            str(points)))

    # radius is euclidean distance
    radius = ((points[0] - center) ** 2).sum() ** .5

    # vectors from points on arc to center point
    vector = util.unitize(points - center)
github mikedh / trimesh / trimesh / path / exchange / dxf.py View on Github external
# if it's a closed segment modulus to start vertex
    if is_closed:
        tid %= len(lines)

    # the vector connecting the two ends of the arc
    vector = lines[tid[:, 0]] - lines[tid[:, 1]]

    # the length of the connector segment
    length = (np.linalg.norm(vector, axis=1))

    # perpendicular vectors by crossing vector with Z
    perp = np.cross(
        np.column_stack((vector, np.zeros(len(vector)))),
        np.ones((len(vector), 3)) * [0, 0, 1])
    # strip the zero Z
    perp = util.unitize(perp[:, :2])

    # midpoint of each line
    midpoint = lines[tid].mean(axis=1)

    # calculate the signed radius of each arc segment
    radius = (length / 2.0) / np.sin(angle / 2.0)

    # offset magnitude to point on arc
    offset = radius - np.cos(angle / 2) * radius

    # convert each arc to three points:
    # start, any point on arc, end
    three = np.column_stack((
        lines[tid[:, 0]],
        midpoint + perp * offset.reshape((-1, 1)),
        lines[tid[:, 1]])).reshape((-1, 3, 2))
github mikedh / trimesh / trimesh / creation.py View on Github external
# Compute 3D locations of those vertices
    verts_3d = np.c_[verts_2d, np.zeros(n)]
    verts_3d = tf.transform_points(verts_3d, tf_mat)
    base_verts_3d = np.c_[base_verts_2d,
                          np.zeros(len(base_verts_2d))]
    base_verts_3d = tf.transform_points(base_verts_3d,
                                        tf_mat)

    # keep matching sequence of vertices and 0- indexed faces
    vertices = [base_verts_3d]
    faces = [faces_2d]

    # Compute plane normals for each turn --
    # each turn induces a plane halfway between the two vectors
    v1s = util.unitize(path[1:-1] - path[:-2])
    v2s = util.unitize(path[1:-1] - path[2:])
    norms = np.cross(np.cross(v1s, v2s), v1s + v2s)
    norms[(norms == 0.0).all(1)] = v1s[(norms == 0.0).all(1)]
    norms = util.unitize(norms)
    final_v1 = util.unitize(path[-1] - path[-2])
    norms = np.vstack((norms, final_v1))
    v1s = np.vstack((v1s, final_v1))

    # Create all side walls by projecting the 3d vertices into each plane
    # in succession
    for i in range(len(norms)):
        verts_3d_prev = verts_3d

        # Rotate if needed
        if angles is not None:
            tf_mat = tf.rotation_matrix(angles[i],
                                        norms[i],
github mikedh / trimesh / trimesh / geometry.py View on Github external
# doing this with a sparse matrix
        summed = np.zeros((vertex_count, 3))
        for face, normal in zip(faces, face_normals):
            summed[face] += normal
        return summed

    try:
        summed = summed_sparse()
    except BaseException:
        log.warning(
            'unable to use sparse matrix, falling back!',
            exc_info=True)
        summed = summed_loop()

    # invalid normals will be returned as zero
    vertex_normals = util.unitize(summed)

    return vertex_normals
github mikedh / trimesh / trimesh / creation.py View on Github external
base_verts_3d = np.c_[base_verts_2d,
                          np.zeros(len(base_verts_2d))]
    base_verts_3d = tf.transform_points(base_verts_3d,
                                        tf_mat)

    # keep matching sequence of vertices and 0- indexed faces
    vertices = [base_verts_3d]
    faces = [faces_2d]

    # Compute plane normals for each turn --
    # each turn induces a plane halfway between the two vectors
    v1s = util.unitize(path[1:-1] - path[:-2])
    v2s = util.unitize(path[1:-1] - path[2:])
    norms = np.cross(np.cross(v1s, v2s), v1s + v2s)
    norms[(norms == 0.0).all(1)] = v1s[(norms == 0.0).all(1)]
    norms = util.unitize(norms)
    final_v1 = util.unitize(path[-1] - path[-2])
    norms = np.vstack((norms, final_v1))
    v1s = np.vstack((v1s, final_v1))

    # Create all side walls by projecting the 3d vertices into each plane
    # in succession
    for i in range(len(norms)):
        verts_3d_prev = verts_3d

        # Rotate if needed
        if angles is not None:
            tf_mat = tf.rotation_matrix(angles[i],
                                        norms[i],
                                        path[i])
            verts_3d_prev = tf.transform_points(verts_3d_prev,
                                                tf_mat)
github mikedh / trimesh / trimesh / graph.py View on Github external
# R = ------------------
    #     2 * sin(theta / 2)
    nonzero = mesh.face_adjacency_angles > np.radians(.01)
    denominator = np.abs(
        2.0 * np.sin(mesh.face_adjacency_angles[nonzero] / 1.0))

    # consider the distance between the non- shared vertices of the
    # face adjacency pair as the key distance
    point_pairs = mesh.vertices[mesh.face_adjacency_unshared]
    vectors = np.diff(point_pairs,
                      axis=1).reshape((-1, 3))

    # the vertex indices of the shared edge for the adjacency pairx
    edges = mesh.face_adjacency_edges
    # unit vector along shared the edge
    edges_vec = util.unitize(np.diff(mesh.vertices[edges],
                                     axis=1).reshape((-1, 3)))

    # the vector of the perpendicular projection to the shared edge
    perp = np.subtract(
        vectors, (util.diagonal_dot(
            vectors, edges_vec).reshape(
            (-1, 1)) * edges_vec))
    # the length of the perpendicular projection
    span = util.row_norm(perp)

    # complete the values for non- infinite radii
    radii = np.ones(len(mesh.face_adjacency)) * np.inf
    radii[nonzero] = span[nonzero] / denominator

    return radii, span
github mikedh / trimesh / trimesh / base.py View on Github external
matrix)[0]

        # preserve face normals if we have them stored
        new_face_normals = None
        if has_rotation and 'face_normals' in self._cache:
            # transform face normals by rotation component
            new_face_normals = util.unitize(
                transformations.transform_points(
                    self.face_normals,
                    matrix=matrix,
                    translate=False))

        # preserve vertex normals if we have them stored
        new_vertex_normals = None
        if has_rotation and 'vertex_normals' in self._cache:
            new_vertex_normals = util.unitize(
                transformations.transform_points(
                    self.vertex_normals,
                    matrix=matrix,
                    translate=False))

        # if transformation flips winding of triangles
        if has_rotation and transformations.flips_winding(matrix):
            log.debug('transform flips winding')
            # fliplr will make array non C contiguous
            # which will cause hashes to be more
            # expensive than necessary so wrap
            self.faces = np.ascontiguousarray(
                np.fliplr(self.faces))

        # assign the new values
        self.vertices = new_vertices