Esempio n. 1
0
def make_sphere(radius, slices, segments):
    profile = [V3.zero() for _ in range(segments)]
    dtheta = pi / (segments - 1)
    for i in range(segments):
        theta = dtheta * i
        R = Q.Ru(theta, V3.k())
        profile[i] = Q.rotate(R, V3.make(0.0, -radius, 0.0))
    return profile_sweep(profile, slices)
Esempio n. 2
0
def make_capsule(radius, height, slices, segments):
    profile = [V3.zero() for _ in range(segments)]
    dtheta = pi / (segments - 1)
    for i in range(segments):
        theta = dtheta * i
        R = Q.Ru(theta, V3.k())
        dh = -height / 2.0 if i < (segments / 2) else height / 2.0
        profile[i] = Q.rotate(R, V3.make(0.0, -radius, 0.0)) + V3.make(
            0.0, dh, 0.0)
    return profile_sweep(profile, slices)
Esempio n. 3
0
def concat(B, A):
    """
    Concatenate transformations.. First A then B, Hence, C = B*A
    :param B:
    :param A:
    :return:
    """
    C = CoordSys()
    C.q = Q.unit(Q.prod(B.q, A.q))
    C.r = Q.rotate(B.q, A.r) + B.r
    return C
Esempio n. 4
0
def make_coordsys_from_to(A, B):
    """
    Assumes that 'A' maps from bf_1 to wcs, and 'B' maps from bf_2 to wcs.
    Now compute the transform that maps from bf_1 to bf_2

    :param A:
    :param B:
    :return:
    """
    A2B = CoordSys()
    A2B.q = Q.unit(Q.prod(Q.conjugate(B.q), A.q))
    A2B.r = Q.rotate(Q.conjugate(B.q), A.r - B.r)
    return A2B
Esempio n. 5
0
def rotate(mesh, q):
    for vh in mesh.vertices():
        p = Q.rotate(q, get_vertex_coords(mesh, vh))
        mesh.set_point(vh, OM.TriMesh.Point(p[0], p[1], p[2]))
    return mesh
Esempio n. 6
0
def inverse(X):
    C = CoordSys()
    C.q = Q.conjugate(X.q)
    C.r = Q.rotate(C.q, -X.r)
    return C
Esempio n. 7
0
def xform_vector(X, v):
    return Q.rotate(X.q, v)
Esempio n. 8
0
def xform_point(X, p):
    return Q.rotate(X.q, p) + X.r
Esempio n. 9
0
def profile_sweep(profile, slices):
    mesh = OM.TriMesh()

    N = len(profile)
    J = slices

    if N <= 2:
        raise RuntimeError(
            'profile_sweep(): Profile must have at least 3 points')

    if J <= 2:
        raise RuntimeError(
            'profile_sweep(): Sweep must have at least 3 slices to be a proper volume.'
        )

    K = (N - 2) * J + 2  # Total number of vertices
    bottom = K - 1  # Index to bottom vertex
    top = K - 2  # Index to top vertex
    H = N - 2  # Number of latitude circles
    #F = 2*J*(N-1)     # Total number of triangle faces

    vhandles = []

    # Make a 2D grid of vertices by sweeping profile around y-axis
    dtheta = 2.0 * pi / J  # The angle of each slice

    for j in range(J):
        theta = j * dtheta
        R = Q.Ru(theta, V3.j())
        for i in range(H):
            p = Q.rotate(R, profile[i + 1])
            vh = mesh.add_vertex(OM.TriMesh.Point(p[0], p[1], p[2]))
            vhandles.append(vh)

    # Now fill in top and bottom vertices
    vh = mesh.add_vertex(
        OM.TriMesh.Point(profile[N - 1][0], profile[N - 1][1],
                         profile[N - 1][2]))
    vhandles.append(vh)

    vh = mesh.add_vertex(
        OM.TriMesh.Point(profile[0][0], profile[0][1], profile[0][2]))
    vhandles.append(vh)

    # Make faces for bottom-ring
    for j in range(J):
        #
        #  V  = {c1} {c2} ... {cJ}  b t
        #
        # b c1.0 c2.0 | b c2.0 c3.0| ... | b cJ.0 c1.0
        # b 0 (N-2) | b (N-2) 2*(N-2)
        #
        left = j
        right = ((j + 1) % J)
        vi = vhandles[bottom]
        vj = vhandles[H * right]
        vk = vhandles[H * left]
        mesh.add_face(vi, vj, vk)

    # Make faces for middle-rings
    for i in range(H - 1):  # ring number
        for j in range(J):  # slice number
            left = j
            right = (j + 1) % J
            up = i + 1
            down = i

            vi = vhandles[left * H + down]
            vj = vhandles[right * H + down]
            vk = vhandles[right * H + up]
            vm = vhandles[left * H + up]

            mesh.add_face(vi, vj, vk)
            mesh.add_face(vi, vk, vm)

    # Make faces for top - ring
    for j in range(J):
        offset = (N - 3)
        left = j
        right = (j + 1) % J

        vi = vhandles[top]
        vj = vhandles[left * H + offset]
        vk = vhandles[right * H + offset]

        mesh.add_face(vi, vj, vk)

    mesh.request_face_normals()
    mesh.update_face_normals()

    return mesh