Пример #1
0
def solidCone(translation=None,
              scaling=None,
              direction=None,
              rotation=None,
              N=16,
              M=16,
              axesAdjust=True,
              axes=None):
    """ solidCone(translation=None, scaling=None, direction=None, rotation=None,
                    N=16, M=16, axesAdjust=True, axes=None)
    
    Creates a solid cone with quad faces and its base at the origin.
    Returns an OrientableMesh instance.
    
    Parameters
    ----------
    Note that translation, scaling, and direction can also be given
    using a Point instance.
    translation : (dx, dy, dz), optional
        The translation in world units of the created world object.
    scaling: (sx, sy, sz), optional
        The scaling in world units of the created world object.
    direction: (nx, ny, nz), optional
        Normal vector that indicates the direction of the created world object.
    rotation: scalar, optional
        The anle (in degrees) to rotate the created world object around its
        direction vector.
    N : int
        The number of subdivisions around its axis. If smaller
        than 8, flat shading is used instead of smooth shading.
        With N=4, a pyramid is obtained.
    M : int
        The number of subdivisions along its axis. If smaller
        than 8, flat shading is used instead of smooth shading.
    axesAdjust : bool
        If True, this function will call axes.SetLimits(), and set
        the camera type to 3D. If daspectAuto has not been set yet,
        it is set to False.
    axes : Axes instance
        Display the bars in the given axes, or the current axes if not given.
    
    """

    # Note that the number of vertices around the axis is N+1. This
    # would not be necessary per see, but it helps create a nice closed
    # texture when it is mapped. There are N number of faces though.
    # Similarly, to obtain M faces along the axis, we need M+1
    # vertices.

    # Quick access
    pi2 = np.pi * 2
    cos = np.cos
    sin = np.sin
    sl = N + 1

    # Precalculate z component of the normal
    zn = 1.0

    # Calculate vertices, normals and texcords
    vertices = Pointset(3)
    normals = Pointset(3)
    texcords = Pointset(2)
    # Cone
    for m in range(M + 1):
        z = 1.0 - float(m) / M  # between 0 and 1
        v = float(m) / M
        #
        for n in range(N + 1):
            b = pi2 * float(n) / N
            u = float(n) / (N)
            x = cos(b) * (1.0 - z)
            y = sin(b) * (1.0 - z)
            vertices.append(x, y, z)
            normals.append(x, y, zn)
            texcords.append(u, v)
    # Bottom
    for m in range(2):
        for n in range(N + 1):
            b = pi2 * float(n) / N
            u = float(n) / (N)
            x = cos(b) * (1 - m)
            y = sin(b) * (1 - m)
            vertices.append(x, y, 0)
            normals.append(0, 0, -1)
            texcords.append(u, 1)

    # Calculate indices
    indices = []
    for j in range(M):
        for i in range(N):
            #indices.extend([j*sl+i, j*sl+i+1, (j+1)*sl+i+1, (j+1)*sl+i])
            indices.extend([(j + 1) * sl + i, (j + 1) * sl + i + 1,
                            j * sl + i + 1, j * sl + i])
    j = M + 1
    for i in range(N):
        indices.extend([(j + 1) * sl + i, (j + 1) * sl + i + 1, j * sl + i + 1,
                        j * sl + i])

    # Make indices a numpy array
    indices = np.array(indices, dtype=np.uint32)

    ## Visualization

    # Create axes
    if axes is None:
        axes = vv.gca()

    # Create mesh
    m = vv.OrientableMesh(axes,
                          vertices,
                          indices,
                          normals,
                          values=texcords,
                          verticesPerFace=4)
    #
    if translation is not None:
        m.translation = translation
    if scaling is not None:
        m.scaling = scaling
    if direction is not None:
        m.direction = direction
    if rotation is not None:
        m.rotation = rotation

    # Set flat shading?
    if N < 8 or M < 8:
        m.faceShading = 'flat'

    # Adjust axes
    if axesAdjust:
        if axes.daspectAuto is None:
            axes.daspectAuto = False
        axes.cameraType = '3d'
        axes.SetLimits()

    # Done
    axes.Draw()
    return m
Пример #2
0
def solidBox(translation=None,
             scaling=None,
             direction=None,
             rotation=None,
             axesAdjust=True,
             axes=None):
    """ solidBox(translation=None, scaling=None, direction=None, rotation=None,
                    axesAdjust=True, axes=None)
    
    Creates a solid cube (or box if you scale it) centered at the 
    origin. Returns an OrientableMesh.
    
    Parameters
    ----------
    Note that translation, scaling, and direction can also be given
    using a Point instance.
    translation : (dx, dy, dz), optional
        The translation in world units of the created world object.
    scaling: (sx, sy, sz), optional
        The scaling in world units of the created world object.
    direction: (nx, ny, nz), optional
        Normal vector that indicates the direction of the created world object.
    rotation: scalar, optional
        The anle (in degrees) to rotate the created world object around its
        direction vector.
    axesAdjust : bool
        If True, this function will call axes.SetLimits(), and set
        the camera type to 3D. If daspectAuto has not been set yet, 
        it is set to False.
    axes : Axes instance
        Display the bars in the given axes, or the current axes if not given.
    
    """

    # Create vertices of a cube
    pp = Pointset(3)
    # Bottom
    pp.append(-0.5, -0.5, -0.5)
    pp.append(+0.5, -0.5, -0.5)
    pp.append(+0.5, +0.5, -0.5)
    pp.append(-0.5, +0.5, -0.5)
    # Top
    pp.append(-0.5, -0.5, +0.5)
    pp.append(-0.5, +0.5, +0.5)
    pp.append(+0.5, +0.5, +0.5)
    pp.append(+0.5, -0.5, +0.5)

    # Init vertices and normals
    vertices = Pointset(3)
    normals = Pointset(3)

    # Create vertices
    for i in [3, 2, 1, 0]:  # Top
        vertices.append(pp[i])
        normals.append(0, 0, -1)
    for i in [7, 6, 5, 4]:  # Bottom
        vertices.append(pp[i])
        normals.append(0, 0, +1)
    for i in [5, 6, 2, 3]:  # Front
        vertices.append(pp[i])
        normals.append(0, +1, 0)
    for i in [1, 7, 4, 0]:  # Back
        vertices.append(pp[i])
        normals.append(0, -1, 0)
    for i in [4, 5, 3, 0]:  # Left
        vertices.append(pp[i])
        normals.append(-1, 0, 0)
    for i in [2, 6, 7, 1]:  # Right
        vertices.append(pp[i])
        normals.append(+1, 0, 0)

    ## Visualize

    # Create axes
    if axes is None:
        axes = vv.gca()

    # Create mesh and set orientation
    m = vv.OrientableMesh(axes, vertices, None, normals, verticesPerFace=4)
    #
    if translation is not None:
        m.translation = translation
    if scaling is not None:
        m.scaling = scaling
    if direction is not None:
        m.direction = direction
    if rotation is not None:
        m.rotation = rotation

    # Adjust axes
    if axesAdjust:
        if axes.daspectAuto is None:
            axes.daspectAuto = False
        axes.cameraType = '3d'
        axes.SetLimits()

    # Done
    axes.Draw()
    return m
Пример #3
0
def solidRing(translation=None,
              scaling=None,
              direction=None,
              rotation=None,
              thickness=0.25,
              N=16,
              M=16,
              axesAdjust=True,
              axes=None):
    """ solidRing(translation=None, scaling=None, direction=None, rotation=None,
                thickness=0.25, N=16, M=16, axesAdjust=True, axes=None)
    
    Creates a solid ring with quad faces oriented at the origin. 
    Returns an OrientableMesh instance.
    
    Parameters
    ----------
    Note that translation, scaling, and direction can also be given
    using a Point instance.
    translation : (dx, dy, dz), optional
        The translation in world units of the created world object.
    scaling: (sx, sy, sz), optional
        The scaling in world units of the created world object.
    direction: (nx, ny, nz), optional
        Normal vector that indicates the direction of the created world object.
    rotation: scalar, optional
        The anle (in degrees) to rotate the created world object around its
        direction vector.
    thickness : scalar
        The tickness of the ring, represented as a fraction of the radius.
    N : int
        The number of subdivisions around its axis. If smaller
        than 8, flat shading is used instead of smooth shading. 
    M : int
        The number of subdivisions along its axis. If smaller
        than 8, flat shading is used instead of smooth shading. 
    axesAdjust : bool
        If True, this function will call axes.SetLimits(), and set
        the camera type to 3D. If daspectAuto has not been set yet, 
        it is set to False.
    axes : Axes instance
        Display the bars in the given axes, or the current axes if not given.
    
    """

    # Note that the number of vertices around the axis is N+1. This
    # would not be necessary per see, but it helps create a nice closed
    # texture when it is mapped. There are N number of faces though.
    # Similarly, to obtain M faces along the axis, we need M+1
    # vertices.

    # Quick access
    pi2 = np.pi * 2
    cos = np.cos
    sin = np.sin
    sl = M + 1

    # Determine where the stitch is, depending on M
    if M <= 8:
        rotOffset = 0.5 / M
    else:
        rotOffset = 0.0

    # Calculate vertices, normals and texcords
    vertices = Pointset(3)
    normals = Pointset(3)
    texcords = Pointset(2)
    # Cone
    for n in range(N + 1):
        v = float(n) / N
        a = pi2 * v
        # Obtain outer and center position of "tube"
        po = Point(sin(a), cos(a), 0)
        pc = po * (1.0 - 0.5 * thickness)
        # Create two vectors that span the the circle orthogonal to the tube
        p1 = (pc - po)
        p2 = Point(0, 0, 0.5 * thickness)
        # Sample around tube
        for m in range(M + 1):
            u = float(m) / (M)
            b = pi2 * (u + rotOffset)
            dp = cos(b) * p1 + sin(b) * p2
            vertices.append(pc + dp)
            normals.append(dp.normalize())
            texcords.append(v, u)

    # Calculate indices
    indices = []
    for j in range(N):
        for i in range(M):
            #indices.extend([j*sl+i, j*sl+i+1, (j+1)*sl+i+1, (j+1)*sl+i])
            indices.extend([(j + 1) * sl + i, (j + 1) * sl + i + 1,
                            j * sl + i + 1, j * sl + i])

    # Make indices a numpy array
    indices = np.array(indices, dtype=np.uint32)

    ## Visualize

    # Create axes
    if axes is None:
        axes = vv.gca()

    # Create mesh
    m = vv.OrientableMesh(axes,
                          vertices,
                          indices,
                          normals,
                          values=texcords,
                          verticesPerFace=4)
    #
    if translation is not None:
        m.translation = translation
    if scaling is not None:
        m.scaling = scaling
    if direction is not None:
        m.direction = direction
    if rotation is not None:
        m.rotation = rotation

    # If necessary, use flat shading
    if N < 8 or M < 8:
        m.faceShading = 'flat'

    # Adjust axes
    if axesAdjust:
        if axes.daspectAuto is None:
            axes.daspectAuto = False
        axes.cameraType = '3d'
        axes.SetLimits()

    # Done
    axes.Draw()
    return m
Пример #4
0
def solidTeapot(translation=None,
                scaling=None,
                direction=None,
                rotation=None,
                axesAdjust=True,
                axes=None):
    """ solidTeapot(
            translation=None, scaling=None, direction=None, rotation=None,
            axesAdjust=True, axes=None)
    
    Create a model of a teapot (a teapotahedron) with its bottom at the
    origin. Returns an OrientableMesh instance.
    
    Parameters
    ----------
    Note that translation, scaling, and direction can also be given
    using a Point instance.
    translation : (dx, dy, dz), optional
        The translation in world units of the created world object.
    scaling: (sx, sy, sz), optional
        The scaling in world units of the created world object.
    direction: (nx, ny, nz), optional
        Normal vector that indicates the direction of the created world object.
    rotation: scalar, optional
        The anle (in degrees) to rotate the created world object around its
        direction vector.
    axesAdjust : bool
        If True, this function will call axes.SetLimits(), and set
        the camera type to 3D. If daspectAuto has not been set yet, 
        it is set to False.
    axes : Axes instance
        Display the bars in the given axes, or the current axes if not given.
    
    """

    # Load mesh data
    bm = vv.meshRead('teapot.ssdf')

    # Use current axes?
    if axes is None:
        axes = vv.gca()

    # Create Mesh object
    m = vv.OrientableMesh(axes, bm)
    #
    if translation is not None:
        m.translation = translation
    if scaling is not None:
        m.scaling = scaling
    if direction is not None:
        m.direction = direction
    if rotation is not None:
        m.rotation = rotation

    # Adjust axes
    if axesAdjust:
        if axes.daspectAuto is None:
            axes.daspectAuto = False
        axes.cameraType = '3d'
        axes.SetLimits()

    # Done
    axes.Draw()
    return m