Esempio n. 1
0
def init_motors():
    ###data structure to construct the rotation sign for rotary motor
    numSeg = 20
    rotS = map((lambda n: pi / 2 + n * 2.0 * pi / numSeg),
               range(numSeg * 3 / 4 + 1))
    zOffset = 0.005
    scaleS = 0.4
    drawing_globals.rotS0n = rotS0n = map(
        (lambda a: (scaleS * cos(a), scaleS * sin(a), 0.0 - zOffset)), rotS)
    drawing_globals.rotS1n = rotS1n = map(
        (lambda a: (scaleS * cos(a), scaleS * sin(a), 1.0 + zOffset)), rotS)

    ###Linear motor arrow sign data structure
    drawing_globals.halfHeight = 0.45
    drawing_globals.halfEdge = halfEdge = 3.0 * scaleS * sin(pi / numSeg)

    arrow0Vertices = [(rotS0n[-1][0] - halfEdge, rotS0n[-1][1], rotS0n[-1][2]),
                      (rotS0n[-1][0] + halfEdge, rotS0n[-1][1], rotS0n[-1][2]),
                      (rotS0n[-1][0], rotS0n[-1][1] + 2.0 * halfEdge,
                       rotS0n[-1][2])]
    arrow0Vertices.reverse()
    drawing_globals.arrow0Vertices = arrow0Vertices

    drawing_globals.arrow1Vertices = [
        (rotS1n[-1][0] - halfEdge, rotS1n[-1][1], rotS1n[-1][2]),
        (rotS1n[-1][0] + halfEdge, rotS1n[-1][1], rotS1n[-1][2]),
        (rotS1n[-1][0], rotS1n[-1][1] + 2.0 * halfEdge, rotS1n[-1][2])
    ]

    drawing_globals.halfEdge = halfEdge = 1.0 / 3.0  ##1.0/8.0
    drawing_globals.linearArrowVertices = [(0.0, -halfEdge, 0.0),
                                           (0.0, halfEdge, 0.0),
                                           (0.0, 0.0, 2 * halfEdge)]

    return
Esempio n. 2
0
def init_motors():
    ###data structure to construct the rotation sign for rotary motor
    numSeg = 20
    rotS = map((lambda n: pi/2+n*2.0*pi/numSeg), range(numSeg*3/4 + 1))
    zOffset = 0.005
    scaleS = 0.4
    drawing_globals.rotS0n = rotS0n = map(
        (lambda a: (scaleS*cos(a), scaleS*sin(a), 0.0 - zOffset)), rotS)
    drawing_globals.rotS1n = rotS1n = map(
        (lambda a: (scaleS*cos(a), scaleS*sin(a), 1.0 + zOffset)), rotS)

    ###Linear motor arrow sign data structure
    drawing_globals.halfHeight = 0.45
    drawing_globals.halfEdge = halfEdge = 3.0 * scaleS * sin(pi/numSeg)

    arrow0Vertices = [
        (rotS0n[-1][0]-halfEdge, rotS0n[-1][1], rotS0n[-1][2]),
        (rotS0n[-1][0]+halfEdge, rotS0n[-1][1], rotS0n[-1][2]),
        (rotS0n[-1][0], rotS0n[-1][1] + 2.0*halfEdge, rotS0n[-1][2])]
    arrow0Vertices.reverse()
    drawing_globals.arrow0Vertices = arrow0Vertices

    drawing_globals.arrow1Vertices = [
        (rotS1n[-1][0]-halfEdge, rotS1n[-1][1], rotS1n[-1][2]),
        (rotS1n[-1][0]+halfEdge, rotS1n[-1][1], rotS1n[-1][2]),
        (rotS1n[-1][0], rotS1n[-1][1] + 2.0*halfEdge, rotS1n[-1][2])]

    drawing_globals.halfEdge = halfEdge = 1.0/3.0 ##1.0/8.0
    drawing_globals.linearArrowVertices = [
        (0.0, -halfEdge, 0.0), (0.0, halfEdge, 0.0), (0.0, 0.0,2*halfEdge)]

    return
Esempio n. 3
0
 def CalculateTorus(self, a, b, u, v):
     """calculate point on torus"""
     pi2 = 2 * pi
     #transformation function - torus
     cf = cos(pi2*u)
     sf = sin(pi2*u)
     ct = cos(pi2*v)
     st = sin(pi2*v)
     #point on torus
     return Triple((a+b*ct)*cf, (a+b*ct)*sf, b*st)
Esempio n. 4
0
 def CalculateTorus(self, a, b, u, v):
     """calculate point on torus"""
     pi2 = 2 * pi
     #transformation function - torus
     cf = cos(pi2 * u)
     sf = sin(pi2 * u)
     ct = cos(pi2 * v)
     st = sin(pi2 * v)
     #point on torus
     return Triple((a + b * ct) * cf, (a + b * ct) * sf, b * st)
Esempio n. 5
0
    def _compute_vertices(self):

        theta = 2*pi/self.numVertices*arange(self.numVertices) + \
                self.orientation

        self.xs = self.xy[0] + self.radius * cos(theta)
        self.ys = self.xy[1] + self.radius * sin(theta)
def _compute_ribbon_point(origin,
                          basesPerTurn, 
                          duplexRise, 
                          unitVectorAlongLength,
                          unitVectorAlongLadderStep,
                          unitDepthVector,
                          peakDeviationFromCenter,
                          numberOfBasesDrawn , 
                          theta_offset
                          ):
    """
    """
    ##handedness = -1    
    ##theta_offset = 0.0
    #turn_angle = twistPerBase
    ##turn_angle = (handedness * 2 * pi) / basesPerTurn
    turn_angle = (2 * pi) / basesPerTurn
##    axial_offset = unitVectorAlongLength * duplexRise 
    cY = unitVectorAlongLadderStep 
    cZ = unitDepthVector

    theta = turn_angle * numberOfBasesDrawn + theta_offset # in radians
    y = cos(theta) * peakDeviationFromCenter 
    z = sin(theta) * peakDeviationFromCenter
##    vx = axial_offset # a Vector
    p = origin + y * cY + z * cZ
    return p
Esempio n. 7
0
    def _compute_vertices(self):

        theta = 2*pi/self.numVertices*arange(self.numVertices) + \
                self.orientation

        self.xs = self.xy[0] + self.radius*cos(theta)
        self.ys = self.xy[1] + self.radius*sin(theta)
Esempio n. 8
0
def _compute_ribbon_point(origin,
                          basesPerTurn, 
                          duplexRise, 
                          unitVectorAlongLength,
                          unitVectorAlongLadderStep,
                          unitDepthVector,
                          peakDeviationFromCenter,
                          numberOfBasesDrawn , 
                          theta_offset
                          ):
    """
    """
    ##handedness = -1    
    ##theta_offset = 0.0
    #turn_angle = twistPerBase
    ##turn_angle = (handedness * 2 * pi) / basesPerTurn
    turn_angle = (2 * pi) / basesPerTurn
##    axial_offset = unitVectorAlongLength * duplexRise 
    cY = unitVectorAlongLadderStep 
    cZ = unitDepthVector

    theta = turn_angle * numberOfBasesDrawn + theta_offset # in radians
    y = cos(theta) * peakDeviationFromCenter 
    z = sin(theta) * peakDeviationFromCenter
##    vx = axial_offset # a Vector
    p = origin + y * cY + z * cZ
    return p
Esempio n. 9
0
def init_cyls():
    # generate two circles in space as 13-gons, one rotated half a segment with
    # respect to the other these are used as cylinder ends [not quite true
    # anymore, see comments just below]
    slices = 13
    circ1 = map((lambda n: n*2.0*pi/slices), range(slices+1))
    circ2 = map((lambda a: a+pi/slices), circ1)
    drawing_globals.drum0 = drum0 = map((lambda a: (cos(a), sin(a), 0.0)),
                                        circ1)
    drum1 = map((lambda a: (cos(a), sin(a), 1.0)), circ2)
    drum1n = map((lambda a: (cos(a), sin(a), 0.0)), circ2)

    #grantham 20051213 I finally decided the look of the oddly twisted cylinder
    # bonds was not pretty enough, so I made a "drum2" which is just drum0 with
    # a 1.0 Z coordinate, a la drum1.
    #bruce 060609: this apparently introduced the bug of the drum1 end-cap of a
    # cylinder being "ragged" (letting empty space show through), which I fixed
    # by using drum2 for that cap rather than drum1.  drum1 is no longer used
    # except as an intermediate value in the next few lines.
    drawing_globals.drum2 = drum2 = map((lambda a: (cos(a), sin(a), 1.0)),
                                        circ1)

    # This edge list zips up the "top" vertex and normal and then the "bottom"
    # vertex and normal.  Thus each tuple in the sequence would be (vtop, ntop,
    # vbot, nbot) [grantham 20051213]
    # (bruce 051215 simplified the python usage in a way which should create the
    # same list.)
    drawing_globals.cylinderEdges = zip(drum0, drum0, drum2, drum0)

    circle = zip(drum0[:-1],drum0[1:],drum1[:-1]) +\
           zip(drum1[:-1],drum0[1:],drum1[1:])
    circlen = zip(drum0[:-1],drum0[1:],drum1n[:-1]) +\
            zip(drum1n[:-1],drum0[1:],drum1n[1:])

    drawing_globals.cap0n = (0.0, 0.0, -1.0)
    drawing_globals.cap1n = (0.0, 0.0, 1.0)
    drum0.reverse()
    return
Esempio n. 10
0
def init_cyls():
    # generate two circles in space as 13-gons, one rotated half a segment with
    # respect to the other these are used as cylinder ends [not quite true
    # anymore, see comments just below]
    slices = 13
    circ1 = map((lambda n: n * 2.0 * pi / slices), range(slices + 1))
    circ2 = map((lambda a: a + pi / slices), circ1)
    drawing_globals.drum0 = drum0 = map((lambda a: (cos(a), sin(a), 0.0)),
                                        circ1)
    drum1 = map((lambda a: (cos(a), sin(a), 1.0)), circ2)
    drum1n = map((lambda a: (cos(a), sin(a), 0.0)), circ2)

    #grantham 20051213 I finally decided the look of the oddly twisted cylinder
    # bonds was not pretty enough, so I made a "drum2" which is just drum0 with
    # a 1.0 Z coordinate, a la drum1.
    #bruce 060609: this apparently introduced the bug of the drum1 end-cap of a
    # cylinder being "ragged" (letting empty space show through), which I fixed
    # by using drum2 for that cap rather than drum1.  drum1 is no longer used
    # except as an intermediate value in the next few lines.
    drawing_globals.drum2 = drum2 = map((lambda a: (cos(a), sin(a), 1.0)),
                                        circ1)

    # This edge list zips up the "top" vertex and normal and then the "bottom"
    # vertex and normal.  Thus each tuple in the sequence would be (vtop, ntop,
    # vbot, nbot) [grantham 20051213]
    # (bruce 051215 simplified the python usage in a way which should create the
    # same list.)
    drawing_globals.cylinderEdges = zip(drum0, drum0, drum2, drum0)

    circle = zip(drum0[:-1],drum0[1:],drum1[:-1]) +\
           zip(drum1[:-1],drum0[1:],drum1[1:])
    circlen = zip(drum0[:-1],drum0[1:],drum1n[:-1]) +\
            zip(drum1n[:-1],drum0[1:],drum1n[1:])

    drawing_globals.cap0n = (0.0, 0.0, -1.0)
    drawing_globals.cap1n = (0.0, 0.0, 1.0)
    drum0.reverse()
    return
Esempio n. 11
0
def vector_to_axis(line, point):
    """
    Returns the vector between a point and
    the closest point on a line (ie. the perpendicular
    projection of the point on the line).

    @type line: L{Vector}
    @param line: vector defining a line

    @type point: L{Vector}
    @param point: vector defining the point
    """
    line=line.normalized()
    np=point.norm()
    angle=line.angle(point)
    return point-line**(np*cos(angle))
Esempio n. 12
0
def rotaxis2m(theta, vector):
    """
    Calculate a left multiplying rotation matrix that rotates
    theta rad around vector.

    Example: 
    
        >>> m=rotaxis(pi, Vector(1,0,0))
        >>> rotated_vector=any_vector.left_multiply(m)

    @type theta: float
    @param theta: the rotation angle


    @type vector: L{Vector}
    @param vector: the rotation axis

    @return: The rotation matrix, a 3x3 Numeric array.
    """
    vector=vector.copy()
    vector.normalize()
    c=cos(theta)
    s=sin(theta)
    t=1-c
    x,y,z=vector.get_array()
    rot=zeros((3,3), "d")
    # 1st row
    rot[0,0]=t*x*x+c
    rot[0,1]=t*x*y-s*z
    rot[0,2]=t*x*z+s*y
    # 2nd row
    rot[1,0]=t*x*y+s*z
    rot[1,1]=t*y*y+c
    rot[1,2]=t*y*z-s*x
    # 3rd row
    rot[2,0]=t*x*z-s*y
    rot[2,1]=t*y*z+s*x
    rot[2,2]=t*z*z+c
    return rot
Esempio n. 13
0
def getSphereTriStrips(level):
    steps = 2**level
    points = []                         # Triangle Strip vertices o be returned.

    # Construct an icosahedron with two vertices at the North and South Poles,
    # +-1 on the Y axis, as you look toward the X-Y plane with the Z axis
    # pointing out at you.  The "middle ring" vertices are all at the same
    # +-latitudes, on the intersection circles of the globe with a polar-axis
    # cylinder of the proper radius.
    #
    # The third "master vertex" of the icosahedron is placed on the X-Y plane,
    # which intersects the globe at the Greenwich Meridian (the semi-circle at
    # longitude 0, through Greenwich Observatory, 5 miles south-east of London.)
    #
    # The X (distance from the polar axis) and Y (height above the equatorial
    # plane) of the master vertex make a "golden rectangle", one unit high by
    # "phi" (1.6180339887498949) wide.  We normalize this to put it on the
    # unit-radius sphere, and take the distance from the axis as the cylinder
    # radius used to generate the rest of the vertices of the two middle rings.
    #
    # Plotted on the globe, the master vertex (first vertex of the North ring)
    # is lat-long 31.72,0 due south of London in Africa, about 45 miles
    # south-southwest of Benoud, Algeria.  The first vertex of the south ring is
    # rotated 1/10 of a circle east, at lat-long -31.72,36 in the south end of
    # the Indian Ocean, about 350 miles east-southeast of Durban, South Africa.
    #
    vert0 = norm(V(phi,1,0))   # Project the "master vertex" onto a unit sphere.
    cylRad = vert0[0]          # Icos vertex distance from the Y axis.
    ringLat = atan2(vert0[1], vert0[0]) * degreesPerRadian  # Latitude +-31.72 .

    # Basic triangle-strip icosahedron vertices.  Start and end with the Poles.
    # Reflect the master vertex into the southern hemisphere and rotate 5 copies
    # to make the middle rings of 5 vertices at North and South latitudes.
    p2_5 = 2*pi / 5.0
    # Simplify indexing by replicating the Poles, so everything is in fives.
    icosRings = [ 5 * [V(0.0, -1.0, 0.0)], # South Pole.

                  # South ring, first edge *centered on* the Greenwich Meridian.
                  [V(cylRad*cos((i-.5)*p2_5),-vert0[1], cylRad*sin((i-.5)*p2_5))
                   for i in range(5)],

                  # North ring, first vertex *on* the Greenwich Meridian.
                  [V(cylRad*cos(i*p2_5 ), vert0[1], cylRad*sin(i*p2_5))
                   for i in range(5)],

                  5 * [V(0.0, 1.0, 0.0)] ] # North Pole.


    # Three bands, going from bottom to top (South to North.)
    for band in range(3):
        lowerRing = icosRings[band]
        upperRing = icosRings[band+1]

        # Subdivide bands into sub-bands.  When level == 0, steps == 1,
        # subBand == 0, and we get just the icosahedron out.  (Really!)
        for subBand in range(steps):

            # Account for the tapering-in at the poles, making less points on
            # one edge of a sub-band than there are on the other edge.
            botOffset = 0
            if band is 0:      # South.
                botSteps = max(subBand, 1) # Don't divide by zero.
                topSteps = subBand + 1
                # Collapse the *first* triangle of south sub-band bottom edges.
                botOffset = -1
            elif band is 1:    # Middle.
                botSteps = topSteps = steps
            else:              # band is 2: North.
                botSteps = steps - subBand
                topSteps = max(steps - (subBand+1), 1)
                pass
            subBandSteps = max(botSteps, topSteps)

            # Do five segments, clockwise around the North Pole (East to West.)
            for seg in range(5):
                nextseg = (seg+1) % 5 # Wrap-around.

                # Interpolate ends of bottom & top edges of a sub-band segment.
                fractBot = float(subBand)/float(steps)
                fractTop = float(subBand+1)/float(steps)
                sbBotRight = fractBot * upperRing[seg] + \
                           (1.0-fractBot) * lowerRing[seg]
                sbTopRight = fractTop * upperRing[seg] + \
                           (1.0-fractTop) * lowerRing[seg]
                sbBotLeft = fractBot * upperRing[nextseg] + \
                          (1.0-fractBot) * lowerRing[nextseg]
                sbTopLeft = fractTop * upperRing[nextseg] + \
                          (1.0-fractTop) * lowerRing[nextseg]

                # Output the right end of the first segment of the sub-band.
                # We'll end up wrapping around to this same pair of points at
                # the left end of the last segment of the sub-band.
                if seg == 0:
                    # Project verts from icosahedron faces onto the unit sphere.
                    points += [norm(sbBotRight), norm(sbTopRight)]

                # Step across the sub-band edges from right to left,
                # stitching triangle pairs from their lower to upper edges.
                for step in range(1, subBandSteps+1):

                    # Interpolate step point pairs along the sub-band edges.
                    fractLower = float(step+botOffset)/float(botSteps)
                    lower = fractLower * sbBotLeft + \
                          (1.0-fractLower) * sbBotRight
                    # Collapse the *last* triangle of north sub-band top edges.
                    fractUpper = float(min(step, topSteps))/float(topSteps)
                    upper = fractUpper * sbTopLeft + \
                          (1.0-fractUpper) * sbTopRight

                    # Output verts, projected from icos faces onto unit sphere.
                    points += [norm(lower), norm(upper)]

                    continue # step
                continue # seg
            continue # subBand
        continue # band
    return points
Esempio n. 14
0
def setup_drawer():
    """
    Set up the usual constant display lists in the current OpenGL context.

    WARNING: THIS IS ONLY CORRECT IF ONLY ONE GL CONTEXT CONTAINS DISPLAY LISTS
    -- or more precisely, only the GL context this has last been called in (or
    one which shares its display lists) will work properly with the routines in
    drawer.py, since the allocated display list names are stored in globals set
    by this function, but in general those names might differ if this was called
    in different GL contexts.
    """
    spherelistbase = glGenLists(_NUM_SPHERE_SIZES)
    sphereList = []
    for i in range(_NUM_SPHERE_SIZES):
        sphereList += [spherelistbase+i]
        glNewList(sphereList[i], GL_COMPILE)
        glBegin(GL_TRIANGLE_STRIP) # GL_LINE_LOOP to see edges
        stripVerts = getSphereTriStrips(i)
        for vertNorm in stripVerts:
            glNormal3fv(vertNorm)
            glVertex3fv(vertNorm)
            continue
        glEnd()
        glEndList()
        continue
    drawing_globals.sphereList = sphereList

    # Sphere triangle-strip vertices for each level of detail.
    # (Cache and re-use the work of making them.)
    # Can use in converter-wrappered calls like glVertexPointerfv,
    # but the python arrays are re-copied to C each time.
    sphereArrays = []
    for i in range(_NUM_SPHERE_SIZES):
        sphereArrays += [getSphereTriStrips(i)]
        continue
    drawing_globals.sphereArrays = sphereArrays

    # Sphere glDrawArrays triangle-strip vertices for C calls.
    # (Cache and re-use the work of converting a C version.)
    # Used in thinly-wrappered calls like glVertexPointer.
    sphereCArrays = []
    for i in range(_NUM_SPHERE_SIZES):
        CArray = numpy.array(sphereArrays[i], dtype = numpy.float32)
        sphereCArrays += [CArray]
        continue
    drawing_globals.sphereCArrays = sphereCArrays

    # Sphere indexed vertices.
    # (Cache and re-use the work of making the indexes.)
    # Can use in converter-wrappered calls like glDrawElementsui,
    # but the python arrays are re-copied to C each time.
    sphereElements = []             # Pairs of lists (index, verts) .
    for i in range(_NUM_SPHERE_SIZES):
        sphereElements += [indexVerts(sphereArrays[i], .0001)]
        continue
    drawing_globals.sphereElements = sphereElements

    # Sphere glDrawElements index and vertex arrays for C calls.
    sphereCIndexTypes = []          # numpy index unsigned types.
    sphereGLIndexTypes = []         # GL index types for drawElements.
    sphereCElements = []            # Pairs of numpy arrays (Cindex, Cverts) .
    for i in range(_NUM_SPHERE_SIZES):
        (index, verts) = sphereElements[i]
        if len(index) < 256:
            Ctype = numpy.uint8
            GLtype = GL_UNSIGNED_BYTE
        else:
            Ctype = numpy.uint16
            GLtype = GL_UNSIGNED_SHORT
            pass
        sphereCIndexTypes += [Ctype]
        sphereGLIndexTypes += [GLtype]
        sphereCIndex = numpy.array(index, dtype = Ctype)
        sphereCVerts = numpy.array(verts, dtype = numpy.float32)
        sphereCElements += [(sphereCIndex, sphereCVerts)]
        continue
    drawing_globals.sphereCIndexTypes = sphereCIndexTypes
    drawing_globals.sphereGLIndexTypes = sphereGLIndexTypes
    drawing_globals.sphereCElements = sphereCElements

    if glGetString(GL_EXTENSIONS).find("GL_ARB_vertex_buffer_object") >= 0:

        # A GLBufferObject version for glDrawArrays.
        sphereArrayVBOs = []
        for i in range(_NUM_SPHERE_SIZES):
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB,
                                 sphereCArrays[i], GL_STATIC_DRAW)
            sphereArrayVBOs += [vbo]
            continue
        drawing_globals.sphereArrayVBOs = sphereArrayVBOs

        # A GLBufferObject version for glDrawElements indexed verts.
        sphereElementVBOs = []              # Pairs of (IBO, VBO)
        for i in range(_NUM_SPHERE_SIZES):
            ibo = GLBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB,
                                 sphereCElements[i][0], GL_STATIC_DRAW)
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB,
                                 sphereCElements[i][1], GL_STATIC_DRAW)
            sphereElementVBOs += [(ibo, vbo)]
            continue
        drawing_globals.sphereElementVBOs = sphereElementVBOs

        ibo.unbind()
        vbo.unbind()
        pass

    #bruce 060415
    drawing_globals.wiresphere1list = wiresphere1list = glGenLists(1)
    glNewList(wiresphere1list, GL_COMPILE)
    didlines = {} # don't draw each triangle edge more than once

    def shoulddoline(v1,v2):
        # make sure not list (unhashable) or Numeric array (bug in __eq__)
        v1 = tuple(v1)
        v2 = tuple(v2)
        if (v1,v2) not in didlines:
            didlines[(v1,v2)] = didlines[(v2,v1)] = None
            return True
        return False
    def doline(v1,v2):
        if shoulddoline(v1,v2):
            glVertex3fv(v1)
            glVertex3fv(v2)
        return
    glBegin(GL_LINES)
    ocdec = getSphereTriangles(1)
    for tri in ocdec:
        #e Could probably optim this more, e.g. using a vertex array or VBO or
        #  maybe GL_LINE_STRIP.
        doline(tri[0], tri[1])
        doline(tri[1], tri[2])
        doline(tri[2], tri[0])
    glEnd()
    glEndList()

    drawing_globals.CylList = CylList = glGenLists(1)
    glNewList(CylList, GL_COMPILE)
    glBegin(GL_TRIANGLE_STRIP)
    for (vtop, ntop, vbot, nbot) in drawing_globals.cylinderEdges:
        glNormal3fv(nbot)
        glVertex3fv(vbot)
        glNormal3fv(ntop)
        glVertex3fv(vtop)
    glEnd()
    glEndList()

    drawing_globals.CapList = CapList = glGenLists(1)
    glNewList(CapList, GL_COMPILE)
    glNormal3fv(drawing_globals.cap0n)
    glBegin(GL_POLYGON)
    for p in drawing_globals.drum0:
        glVertex3fv(p)
    glEnd()
    glNormal3fv(drawing_globals.cap1n)
    glBegin(GL_POLYGON)
    #bruce 060609 fix "ragged edge" bug in this endcap: drum1 -> drum2
    for p in drawing_globals.drum2:
        glVertex3fv(p)
    glEnd()
    glEndList()

    drawing_globals.diamondGridList = diamondGridList = glGenLists(1)
    glNewList(diamondGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.digrid:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.lonsGridList = lonsGridList = glGenLists(1)
    glNewList(lonsGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.lonsEdges:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.CubeList = CubeList = glGenLists(1)
    glNewList(CubeList, GL_COMPILE)
    glBegin(GL_QUAD_STRIP)
    # note: CubeList has only 4 faces of the cube; only suitable for use in
    # wireframes; see also solidCubeList [bruce 051215 comment reporting
    # grantham 20051213 observation]
    glVertex((-1,-1,-1))
    glVertex(( 1,-1,-1))
    glVertex((-1, 1,-1))
    glVertex(( 1, 1,-1))
    glVertex((-1, 1, 1))
    glVertex(( 1, 1, 1))
    glVertex((-1,-1, 1))
    glVertex(( 1,-1, 1))
    glVertex((-1,-1,-1))
    glVertex(( 1,-1,-1))
    glEnd()
    glEndList()

    drawing_globals.solidCubeList = solidCubeList = glGenLists(1)
    glNewList(solidCubeList, GL_COMPILE)
    glBegin(GL_QUADS)
    for i in xrange(len(drawing_globals.cubeIndices)):
        avenormals = V(0,0,0) #bruce 060302 fixed normals for flat shading
        for j in xrange(4) :
            nTuple = tuple(
                drawing_globals.cubeNormals[drawing_globals.cubeIndices[i][j]])
            avenormals += A(nTuple)
        avenormals = norm(avenormals)
        for j in xrange(4) :
            vTuple = tuple(
                drawing_globals.cubeVertices[drawing_globals.cubeIndices[i][j]])
            #bruce 060302 made size compatible with glut.glutSolidCube(1.0)
            vTuple = A(vTuple) * 0.5
            glNormal3fv(avenormals)
            glVertex3fv(vTuple)
    glEnd()
    glEndList()

    drawing_globals.rotSignList = rotSignList = glGenLists(1)
    glNewList(rotSignList, GL_COMPILE)
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS0n)):
        glVertex3fv(tuple(drawing_globals.rotS0n[ii]))
    glEnd()
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS1n)):
        glVertex3fv(tuple(drawing_globals.rotS1n[ii]))
    glEnd()
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.arrow0Vertices + drawing_globals.arrow1Vertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearArrowList = linearArrowList = glGenLists(1)
    glNewList(linearArrowList, GL_COMPILE)
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.linearArrowVertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearLineList = linearLineList = glGenLists(1)
    glNewList(linearLineList, GL_COMPILE)
    glEnable(GL_LINE_SMOOTH)
    glBegin(GL_LINES)
    glVertex3f(0.0, 0.0, -drawing_globals.halfHeight)
    glVertex3f(0.0, 0.0, drawing_globals.halfHeight)
    glEnd()
    glDisable(GL_LINE_SMOOTH)
    glEndList()

    drawing_globals.circleList = circleList = glGenLists(1)
    glNewList(circleList, GL_COMPILE)
    glBegin(GL_LINE_LOOP)
    for ii in range(60):
        x = cos(ii*2.0*pi/60)
        y = sin(ii*2.0*pi/60)
        glVertex3f(x, y, 0.0)
    glEnd()
    glEndList()

    # piotr 080405
    drawing_globals.filledCircleList = filledCircleList = glGenLists(1)
    glNewList(filledCircleList, GL_COMPILE)
    glBegin(GL_POLYGON)
    for ii in range(60):
        x = cos(ii*2.0*pi/60)
        y = sin(ii*2.0*pi/60)
        glVertex3f(x, y, 0.0)
    glEnd()
    glEndList()

    drawing_globals.lineCubeList = lineCubeList = glGenLists(1)
    glNewList(lineCubeList, GL_COMPILE)
    glBegin(GL_LINES)
    cvIndices = [0,1, 2,3, 4,5, 6,7, 0,3, 1,2, 5,6, 4,7, 0,4, 1,5, 2,6, 3,7]
    for i in cvIndices:
        glVertex3fv(tuple(drawing_globals.cubeVertices[i]))
    glEnd()
    glEndList()

    #initTexture('C:\\Huaicai\\atom\\temp\\newSample.png', 128,128)
    return # from setup_drawer
Esempio n. 15
0
 def func(x):
     return ((2*x*cos(x) - sin(x))*cos(x) - x + pi/4.0)
Esempio n. 16
0
def drawDnaRibbons(glpane,
                   endCenter1,  
                   endCenter2,
                   basesPerTurn,
                   duplexRise, 
                   glpaneScale,                   
                   lineOfSightVector,
                   displayStyle,
                   ribbon1_start_point = None,
                   ribbon2_start_point = None,
                   ribbon1_direction = None,
                   ribbon2_direction = None,
                   peakDeviationFromCenter = 9.5,
                   ribbonThickness = 2.0,
                   ribbon1Color = None, 
                   ribbon2Color = None,
                   stepColor = None):
    """
    Draw DNA ribbons where each strand is represented as a ribbon. DNA ribbons
    are drawn as sine waves with appropriate phase angles, with the phase
    angles computed in this method.

    @param endCenter1: Axis end 1
    @type  endCenter1: B{V}
    @param endCenter2: Axis end 2
    @type  endCenter2: B{V}
    @param basesPerTurn: Number of bases in a full turn.
    @type  basesPerTurn: float
    @param duplexRise: Center to center distance between consecutive steps
    @type  duplexRise: float
    @param glpaneScale: GLPane scale used in scaling arrow head drawing 
    @type  glpaneScale: float
    @param lineOfSightVector: Glpane lineOfSight vector, used to compute the 
                              the vector along the ladder step. 
    @type: B{V}    
    @param displayStyle: Rubberband display style (specified as an integer)
                         see comment in the method below. 
                         See also GLPane.displayMode.
    @type  displayStyle: int
    @param peakDeviationFromCenter: Distance of a peak from the axis 
                                    Also known as 'Amplitude' of a sine wave. 
    @type peakDeviationFromCenter: float
    @param ribbonThickness: Thickness of each of the the two ribbons
    @type ribbonThickness: float
    @param ribbon1Color: Color of ribbon1
    @param ribbon2Color: Color of ribbon2
    @see: B{DnaLineMode.Draw } (where it is used) for comments on color 
          convention

    TODO: as of 2008-04-22
      - Need more documentation
      -  This method is long mainly because of a number of custom drawing 
         See if that can be refactored e.g. methods like _drawRibbon1/strand1, 
         drawRibbon2 / strand2 etc. 
      - Further optimization / refactoring (low priority) 
    """

    #Try to match the rubberband display style as closely as possible to 
    #either the glpane's current display or the chunk display of the segment 
    #being edited. The caller should do the job of specifying the display style
    #it desires. As of 2008-02-20, this method only supports following display 
    #styles --Tubes, Ball and Stick, CPK and lines. the sphere radius 
    #for ball and stick or CPK is calculated approximately. 

    if displayStyle == diTrueCPK:
        SPHERE_RADIUS = 3.5
        ribbonThickness = 2.0
    elif displayStyle == diTUBES:
        SPHERE_RADIUS = 0.01
        ribbonThickness = 5.0
    elif displayStyle == diLINES:
        #Lines display and all other unsupported display styles
        SPHERE_RADIUS = 0.01
        ribbonThickness = 1.0
    else:
        #ball and stick display style. All other unsupported displays 
        #will be rendered in ball and stick display style
        SPHERE_RADIUS = 1.0
        ribbonThickness = 3.0
        
    



    ribbonLength = vlen(endCenter1 - endCenter2)

    #Don't draw the vertical line (step) passing through the startpoint unless 
    #the ribbonLength is at least equal to the duplexRise. 
    # i.e. do the drawing only when there are at least two ladder steps. 
    # This prevents a 'revolving line' effect due to the single ladder step at 
    # the first endpoint 
    if ribbonLength < duplexRise:
        return

    unitVectorAlongLength = norm(endCenter2 - endCenter1)
     
    ###===
    pointOnAxis = endCenter1

    axial_shift_1 = V(0.0, 0.0, 0.0) # might be changed below
    axial_shift_2 = V(0.0, 0.0, 0.0)
    
    # [these might be discarded and recomputed just below;
    #  the case where they aren't is (and I think was) untested.
    #  -- bruce 080422 comment]
    vectorAlongLadderStep =  cross(-lineOfSightVector, unitVectorAlongLength)
    unitVectorAlongLadderStep = norm(vectorAlongLadderStep)
    unitDepthVector = cross(unitVectorAlongLength,
                            unitVectorAlongLadderStep) ## * -1 
    
    numberOfBasesDrawn = 0
    theta_offset = 0
    x = 0
    ###
    #Formula .. Its a Sine Wave.
    # y(x) = A.sin(2*pi*f*x + phase_angle)  ------[1]
    # where --
    #      f = 1/T 
    #      A = Amplitude of the sine wave (or 'peak deviation from center') 
    #      y = y coordinate  of the sine wave -- distance is in Angstroms
    #      x = the x coordinate
    # phase_angle is computed for each wave. We know y at x =0. For example, 
    # for ribbon_1, , at x = 0, y = A. Putting these values in equation [1] 
    # we get the phase_angle. Similarly, for ribbon_2, at x = 0, y = -6 
    # Putting these values will give use the phase_angle_2. 
    # Note that for ribbon2_point, we subtract the value of equation [1] from 
    # the point on axis. 

    x = 0.0
    T =  duplexRise * basesPerTurn 
        # The 'Period' of the sine wave
        # (i.e. peak to peak distance between consecutive crests)

    amplitude = peakDeviationFromCenter
    amplitudeVector = unitVectorAlongLadderStep * amplitude
    depthVector = unitDepthVector * amplitude
        # Note: to reduce the effect of perspective view on rung direction,
        # we could multiply depthVector by 0.1 or 0.01. But this would lessen
        # the depth realism of line/sphere intersections. [bruce 080216]
    ###
    

    if ribbon1_start_point is not None:
        ribbon1_point = ribbon1_start_point        
    else:
        if ribbon2_start_point is not None:
            ribbon1_point = _get_ribbon_point_on_other_ribbon(
                ribbon2_start_point,
                ribbon2_direction,
                endCenter1,
                unitVectorAlongLength) 
            
        else:
            phase_angle_ribbon_1 = HALF_PI    
            theta_ribbon_1 = (TWICE_PI * x / T) + phase_angle_ribbon_1
            
            #Initialize ribbon1_point and ribbon2_point
            ribbon1_point = pointOnAxis + \
                            amplitudeVector * sin(theta_ribbon_1) + \
                            depthVector * cos(theta_ribbon_1)
            ribbon1_direction = +1
            
    drawDnaSingleRibbon(glpane,
                        endCenter1,  
                        endCenter2,
                        basesPerTurn,
                        duplexRise, 
                        # maybe: don't pass these three args, get from glpane
                        # instead? [bruce 080422 comment]
                        glpaneScale,
                        lineOfSightVector,
                        displayStyle,
                        ribbon1_start_point = ribbon1_point,
                        ribbon1_direction = ribbon1_direction,
                        peakDeviationFromCenter = peakDeviationFromCenter,
                        ribbonThickness = ribbonThickness,
                        ribbon1Color = ribbon1Color, 
                        stepColor = stepColor)

    if ribbon2_start_point is not None:
        ribbon2_point = ribbon2_start_point        
    else:
        if ribbon1_start_point is not None:
            ribbon2_point = _get_ribbon_point_on_other_ribbon(
                ribbon1_start_point,
                ribbon1_direction,
                endCenter1,
                unitVectorAlongLength)
            
        else:
            phase_angle_ribbon_2 = asin(-6.0/(amplitude))
            theta_ribbon_2 = (TWICE_PI * x / T) - phase_angle_ribbon_2    
            ribbon2_point = pointOnAxis - \
                            amplitudeVector * sin(theta_ribbon_2) + \
                            depthVector * cos(theta_ribbon_2)
            ribbon2_direction = -1
            
    drawDnaSingleRibbon(glpane,
                        endCenter1,  
                        endCenter2,
                        basesPerTurn,
                        duplexRise, 
                        # maybe: don't pass these three args, get from glpane
                        # instead? [bruce 080422 comment]
                        glpaneScale,
                        lineOfSightVector,
                        displayStyle,
                        ribbon1_start_point = ribbon2_point,
                        ribbon1_direction = ribbon2_direction,
                        peakDeviationFromCenter = peakDeviationFromCenter,
                        ribbonThickness = ribbonThickness,
                        ribbon1Color = ribbon2Color, 
                        stepColor = stepColor)
    
    del vectorAlongLadderStep
    
    return
Esempio n. 17
0
    def _buildResiduum(self, mol, zmatrix, n_atoms, phi, psi, init_pos, symbol):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        mol is a chunk to which the amino acid will be added.

        zmatrix is an internal coordinates array corresponding to a given amino acid.
        n_atoms is a number of atoms to be build + 3 dummy atoms.

        phi is a peptide bond PHI angle.
        psi is a peptide bond PSI angle.

        init_pos are optional postions of previous CA, C and O atoms.

        symbol is a current amino acid symbol (used for proline case)

        Note: currently, it doesn't rebuild bonds, so inferBonds has to be called after.
        Unfortunately, the proper bond order can not be correctly recognized this way.
        """

        if mol == None:
            return

        if not init_pos: # assign three previous atom positions
            for i in range (0,3):
                self.coords[i][0] = self.prev_coords[i][0]
                self.coords[i][1] = self.prev_coords[i][1]
                self.coords[i][2] = self.prev_coords[i][2]
        else: # if no prev_coords are given, compute the first three atom positions
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            self.coords[0][0] = 0.0;
            self.coords[0][1] = 0.0;
            self.coords[0][2] = 0.0;
            self.coords[1][0] = r;
            self.coords[1][1] = 0.0;
            self.coords[1][2] = 0.0;
            ccos = cos(DEG2RAD*a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                self.coords[2][0] = self.coords[0][0] + r*ccos
            else:
                self.coords[2][0] = self.coords[0][0] - r*ccos
            self.coords[2][1] = r * sin(DEG2RAD*a)
            self.coords[2][2] = 0.0
            for i in range (0, 3):
                self.prev_coords[i][0] = self.coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = self.coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = self.coords[i][2] + init_pos[2]

        for n in range (3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            cosa = cos(DEG2RAD * a)
            xb = self.coords[atom_b][0] - self.coords[atom_c][0]
            yb = self.coords[atom_b][1] - self.coords[atom_c][1]
            zb = self.coords[atom_b][2] - self.coords[atom_c][2]
            rbc = 1.0 / sqrt(xb*xb + yb*yb + zb*zb)

            if abs(cosa) >= 0.999:
                # Linear bond case
                # Skip angles, just extend along the bond.
                rbc = r * rbc * cosa
                self.coords[n][0] = self.coords[atom_c][0] + xb*rbc
                self.coords[n][1] = self.coords[atom_c][1] + yb*rbc
                self.coords[n][2] = self.coords[atom_c][2] + zb*rbc
            else:
                xa = self.coords[atom_a][0] - self.coords[atom_c][0]
                ya = self.coords[atom_a][1] - self.coords[atom_c][1]
                za = self.coords[atom_a][2] - self.coords[atom_c][2]

                xyb = sqrt(xb*xb + yb*yb)

                inv = False
                if xyb < 0.001:
                    xpa = za
                    za = -xa
                    xa = xpa
                    xpb = zb
                    zb = -xb
                    xb = xpb
                    xyb = sqrt(xb*xb + yb*yb)
                    inv = True

                costh = xb / xyb
                sinth = yb / xyb
                xpa = xa * costh + ya * sinth
                ypa = ya * costh - xa * sinth
                sinph = zb * rbc
                cosph = sqrt(abs(1.0- sinph * sinph))
                xqa = xpa * cosph + za * sinph
                zqa = za * cosph - xpa * sinph
                yza = sqrt(ypa * ypa + zqa * zqa)
                if yza < 1e-8:
                    coskh = 1.0
                    sinkh = 0.0
                else:
                    coskh = ypa / yza
                    sinkh = zqa / yza

                # Apply the peptide bond conformation
                if symbol != "P":
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "HA " or name == "HA2":
                        t = 120.0 + phi
                    if name == "CB " or name == "HA3":
                        t = 240.0 + phi
                    if name == "C  ":
                        t = phi
                else:
                    # proline
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "CA ":
                        t = phi - 120.0
                    if name == "CD ":
                        t = phi + 60.0

                sina = sin(DEG2RAD * a)
                sind = -sin(DEG2RAD * t)
                cosd = cos(DEG2RAD * t)

                # Apply the bond length.
                xd = r * cosa
                yd = r * sina * cosd
                zd = r * sina * sind

                # Compute the atom position using bond and torsional angles.
                ypd = yd * coskh - zd * sinkh
                zpd = zd * coskh + yd * sinkh
                xpd = xd * cosph - zpd * sinph
                zqd = zpd * cosph + xd * sinph
                xqd = xpd * costh - ypd * sinth
                yqd = ypd * costh + xpd * sinth

                if inv:
                    tmp = -zqd
                    zqd = xqd
                    xqd = tmp

                self.coords[n][0] = xqd + self.coords[atom_c][0]
                self.coords[n][1] = yqd + self.coords[atom_c][1]
                self.coords[n][2] = zqd + self.coords[atom_c][2]

                if self.nterm_hydrogen:
                    # It is a hack for the first hydrogen atom
                    # to make sure the bond length is correct.
                    self.nterm_hydrogen.setposn(
                        self.nterm_hydrogen.posn() + 0.325 * norm(V(xqd, yqd, zqd)))
                    self.nterm_hydrogen = None

                ax = self.coords[n][0]
                ay = self.coords[n][1]
                az = self.coords[n][2]

                # Store previous coordinates for the next building step
                if not init_pos:
                    if name=="N  ":
                        self.prev_coords[0][0] = self.coords[n][0]
                        self.prev_coords[0][1] = self.coords[n][1]
                        self.prev_coords[0][2] = self.coords[n][2]
                    if name=="CA ":
                        self.prev_coords[1][0] = self.coords[n][0]
                        self.prev_coords[1][1] = self.coords[n][1]
                        self.prev_coords[1][2] = self.coords[n][2]
                    if name=="C  ":
                        self.prev_coords[2][0] = self.coords[n][0]
                        self.prev_coords[2][1] = self.coords[n][1]
                        self.prev_coords[2][2] = self.coords[n][2]

                # Add a new atom to the molecule
                atom = Atom(
                    atom_name,
                    V(self.coords[n][0], self.coords[n][1], self.coords[n][2]),
                    mol)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                if name == "CA ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_ca = True
                else:
                    atom._protein_ca = False

                if name == "CB ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_cb = True
                else:
                    atom._protein_cb = False

                if name == "N  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_n = True
                else:
                    atom._protein_n = False

                if name == "C  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_c = True
                else:
                    atom._protein_c = False

                if name == "O  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_o = True
                else:
                    atom._protein_o = False

                # debug - output in PDB format	
                # print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, coords[n][0], coords[n][1], coords[n][2])	

        self.prev_psi = psi # Remember previous psi angle.

        self.length += 1 # Increase the amino acid counter.

        return
Esempio n. 18
0
def getSphereTriStrips(level):
    steps = 2**level
    points = []  # Triangle Strip vertices o be returned.

    # Construct an icosahedron with two vertices at the North and South Poles,
    # +-1 on the Y axis, as you look toward the X-Y plane with the Z axis
    # pointing out at you.  The "middle ring" vertices are all at the same
    # +-latitudes, on the intersection circles of the globe with a polar-axis
    # cylinder of the proper radius.
    #
    # The third "master vertex" of the icosahedron is placed on the X-Y plane,
    # which intersects the globe at the Greenwich Meridian (the semi-circle at
    # longitude 0, through Greenwich Observatory, 5 miles south-east of London.)
    #
    # The X (distance from the polar axis) and Y (height above the equatorial
    # plane) of the master vertex make a "golden rectangle", one unit high by
    # "phi" (1.6180339887498949) wide.  We normalize this to put it on the
    # unit-radius sphere, and take the distance from the axis as the cylinder
    # radius used to generate the rest of the vertices of the two middle rings.
    #
    # Plotted on the globe, the master vertex (first vertex of the North ring)
    # is lat-long 31.72,0 due south of London in Africa, about 45 miles
    # south-southwest of Benoud, Algeria.  The first vertex of the south ring is
    # rotated 1/10 of a circle east, at lat-long -31.72,36 in the south end of
    # the Indian Ocean, about 350 miles east-southeast of Durban, South Africa.
    #
    vert0 = norm(V(phi, 1,
                   0))  # Project the "master vertex" onto a unit sphere.
    cylRad = vert0[0]  # Icos vertex distance from the Y axis.
    ringLat = atan2(vert0[1],
                    vert0[0]) * degreesPerRadian  # Latitude +-31.72 .

    # Basic triangle-strip icosahedron vertices.  Start and end with the Poles.
    # Reflect the master vertex into the southern hemisphere and rotate 5 copies
    # to make the middle rings of 5 vertices at North and South latitudes.
    p2_5 = 2 * pi / 5.0
    # Simplify indexing by replicating the Poles, so everything is in fives.
    icosRings = [
        5 * [V(0.0, -1.0, 0.0)],  # South Pole.

        # South ring, first edge *centered on* the Greenwich Meridian.
        [
            V(cylRad * cos((i - .5) * p2_5), -vert0[1],
              cylRad * sin((i - .5) * p2_5)) for i in range(5)
        ],

        # North ring, first vertex *on* the Greenwich Meridian.
        [
            V(cylRad * cos(i * p2_5), vert0[1], cylRad * sin(i * p2_5))
            for i in range(5)
        ],
        5 * [V(0.0, 1.0, 0.0)]
    ]  # North Pole.

    # Three bands, going from bottom to top (South to North.)
    for band in range(3):
        lowerRing = icosRings[band]
        upperRing = icosRings[band + 1]

        # Subdivide bands into sub-bands.  When level == 0, steps == 1,
        # subBand == 0, and we get just the icosahedron out.  (Really!)
        for subBand in range(steps):

            # Account for the tapering-in at the poles, making less points on
            # one edge of a sub-band than there are on the other edge.
            botOffset = 0
            if band is 0:  # South.
                botSteps = max(subBand, 1)  # Don't divide by zero.
                topSteps = subBand + 1
                # Collapse the *first* triangle of south sub-band bottom edges.
                botOffset = -1
            elif band is 1:  # Middle.
                botSteps = topSteps = steps
            else:  # band is 2: North.
                botSteps = steps - subBand
                topSteps = max(steps - (subBand + 1), 1)
                pass
            subBandSteps = max(botSteps, topSteps)

            # Do five segments, clockwise around the North Pole (East to West.)
            for seg in range(5):
                nextseg = (seg + 1) % 5  # Wrap-around.

                # Interpolate ends of bottom & top edges of a sub-band segment.
                fractBot = float(subBand) / float(steps)
                fractTop = float(subBand + 1) / float(steps)
                sbBotRight = fractBot * upperRing[seg] + \
                           (1.0-fractBot) * lowerRing[seg]
                sbTopRight = fractTop * upperRing[seg] + \
                           (1.0-fractTop) * lowerRing[seg]
                sbBotLeft = fractBot * upperRing[nextseg] + \
                          (1.0-fractBot) * lowerRing[nextseg]
                sbTopLeft = fractTop * upperRing[nextseg] + \
                          (1.0-fractTop) * lowerRing[nextseg]

                # Output the right end of the first segment of the sub-band.
                # We'll end up wrapping around to this same pair of points at
                # the left end of the last segment of the sub-band.
                if seg == 0:
                    # Project verts from icosahedron faces onto the unit sphere.
                    points += [norm(sbBotRight), norm(sbTopRight)]

                # Step across the sub-band edges from right to left,
                # stitching triangle pairs from their lower to upper edges.
                for step in range(1, subBandSteps + 1):

                    # Interpolate step point pairs along the sub-band edges.
                    fractLower = float(step + botOffset) / float(botSteps)
                    lower = fractLower * sbBotLeft + \
                          (1.0-fractLower) * sbBotRight
                    # Collapse the *last* triangle of north sub-band top edges.
                    fractUpper = float(min(step, topSteps)) / float(topSteps)
                    upper = fractUpper * sbTopLeft + \
                          (1.0-fractUpper) * sbTopRight

                    # Output verts, projected from icos faces onto unit sphere.
                    points += [norm(lower), norm(upper)]

                    continue  # step
                continue  # seg
            continue  # subBand
        continue  # band
    return points
    def _buildResiduum(self, mol, zmatrix, n_atoms, phi, psi, init_pos,
                       symbol):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        mol is a chunk to which the amino acid will be added.

        zmatrix is an internal coordinates array corresponding to a given amino acid.
        n_atoms is a number of atoms to be build + 3 dummy atoms.

        phi is a peptide bond PHI angle.
        psi is a peptide bond PSI angle.

        init_pos are optional postions of previous CA, C and O atoms.

        symbol is a current amino acid symbol (used for proline case)

        Note: currently, it doesn't rebuild bonds, so inferBonds has to be called after.
        Unfortunately, the proper bond order can not be correctly recognized this way.
        """

        if mol == None:
            return

        if not init_pos:  # assign three previous atom positions
            for i in range(0, 3):
                self.coords[i][0] = self.prev_coords[i][0]
                self.coords[i][1] = self.prev_coords[i][1]
                self.coords[i][2] = self.prev_coords[i][2]
        else:  # if no prev_coords are given, compute the first three atom positions
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            self.coords[0][0] = 0.0
            self.coords[0][1] = 0.0
            self.coords[0][2] = 0.0
            self.coords[1][0] = r
            self.coords[1][1] = 0.0
            self.coords[1][2] = 0.0
            ccos = cos(DEG2RAD * a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                self.coords[2][0] = self.coords[0][0] + r * ccos
            else:
                self.coords[2][0] = self.coords[0][0] - r * ccos
            self.coords[2][1] = r * sin(DEG2RAD * a)
            self.coords[2][2] = 0.0
            for i in range(0, 3):
                self.prev_coords[i][0] = self.coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = self.coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = self.coords[i][2] + init_pos[2]

        for n in range(3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            cosa = cos(DEG2RAD * a)
            xb = self.coords[atom_b][0] - self.coords[atom_c][0]
            yb = self.coords[atom_b][1] - self.coords[atom_c][1]
            zb = self.coords[atom_b][2] - self.coords[atom_c][2]
            rbc = 1.0 / sqrt(xb * xb + yb * yb + zb * zb)

            if abs(cosa) >= 0.999:
                # Linear bond case
                # Skip angles, just extend along the bond.
                rbc = r * rbc * cosa
                self.coords[n][0] = self.coords[atom_c][0] + xb * rbc
                self.coords[n][1] = self.coords[atom_c][1] + yb * rbc
                self.coords[n][2] = self.coords[atom_c][2] + zb * rbc
            else:
                xa = self.coords[atom_a][0] - self.coords[atom_c][0]
                ya = self.coords[atom_a][1] - self.coords[atom_c][1]
                za = self.coords[atom_a][2] - self.coords[atom_c][2]

                xyb = sqrt(xb * xb + yb * yb)

                inv = False
                if xyb < 0.001:
                    xpa = za
                    za = -xa
                    xa = xpa
                    xpb = zb
                    zb = -xb
                    xb = xpb
                    xyb = sqrt(xb * xb + yb * yb)
                    inv = True

                costh = xb / xyb
                sinth = yb / xyb
                xpa = xa * costh + ya * sinth
                ypa = ya * costh - xa * sinth
                sinph = zb * rbc
                cosph = sqrt(abs(1.0 - sinph * sinph))
                xqa = xpa * cosph + za * sinph
                zqa = za * cosph - xpa * sinph
                yza = sqrt(ypa * ypa + zqa * zqa)
                if yza < 1e-8:
                    coskh = 1.0
                    sinkh = 0.0
                else:
                    coskh = ypa / yza
                    sinkh = zqa / yza

                # Apply the peptide bond conformation
                if symbol != "P":
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "HA " or name == "HA2":
                        t = 120.0 + phi
                    if name == "CB " or name == "HA3":
                        t = 240.0 + phi
                    if name == "C  ":
                        t = phi
                else:
                    # proline
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "CA ":
                        t = phi - 120.0
                    if name == "CD ":
                        t = phi + 60.0

                sina = sin(DEG2RAD * a)
                sind = -sin(DEG2RAD * t)
                cosd = cos(DEG2RAD * t)

                # Apply the bond length.
                xd = r * cosa
                yd = r * sina * cosd
                zd = r * sina * sind

                # Compute the atom position using bond and torsional angles.
                ypd = yd * coskh - zd * sinkh
                zpd = zd * coskh + yd * sinkh
                xpd = xd * cosph - zpd * sinph
                zqd = zpd * cosph + xd * sinph
                xqd = xpd * costh - ypd * sinth
                yqd = ypd * costh + xpd * sinth

                if inv:
                    tmp = -zqd
                    zqd = xqd
                    xqd = tmp

                self.coords[n][0] = xqd + self.coords[atom_c][0]
                self.coords[n][1] = yqd + self.coords[atom_c][1]
                self.coords[n][2] = zqd + self.coords[atom_c][2]

                if self.nterm_hydrogen:
                    # It is a hack for the first hydrogen atom
                    # to make sure the bond length is correct.
                    self.nterm_hydrogen.setposn(self.nterm_hydrogen.posn() +
                                                0.325 * norm(V(xqd, yqd, zqd)))
                    self.nterm_hydrogen = None

                ax = self.coords[n][0]
                ay = self.coords[n][1]
                az = self.coords[n][2]

                # Store previous coordinates for the next building step
                if not init_pos:
                    if name == "N  ":
                        self.prev_coords[0][0] = self.coords[n][0]
                        self.prev_coords[0][1] = self.coords[n][1]
                        self.prev_coords[0][2] = self.coords[n][2]
                    if name == "CA ":
                        self.prev_coords[1][0] = self.coords[n][0]
                        self.prev_coords[1][1] = self.coords[n][1]
                        self.prev_coords[1][2] = self.coords[n][2]
                    if name == "C  ":
                        self.prev_coords[2][0] = self.coords[n][0]
                        self.prev_coords[2][1] = self.coords[n][1]
                        self.prev_coords[2][2] = self.coords[n][2]

                # Add a new atom to the molecule
                atom = Atom(
                    atom_name,
                    V(self.coords[n][0], self.coords[n][1], self.coords[n][2]),
                    mol)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                if name == "CA ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_ca = True
                else:
                    atom._protein_ca = False

                if name == "CB ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_cb = True
                else:
                    atom._protein_cb = False

                if name == "N  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_n = True
                else:
                    atom._protein_n = False

                if name == "C  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_c = True
                else:
                    atom._protein_c = False

                if name == "O  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_o = True
                else:
                    atom._protein_o = False

                # debug - output in PDB format
                # print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, coords[n][0], coords[n][1], coords[n][2])

        self.prev_psi = psi  # Remember previous psi angle.

        self.length += 1  # Increase the amino acid counter.

        return
def drawDnaRibbons(glpane,
                   endCenter1,  
                   endCenter2,
                   basesPerTurn,
                   duplexRise, 
                   glpaneScale,                   
                   lineOfSightVector,
                   displayStyle,
                   ribbon1_start_point = None,
                   ribbon2_start_point = None,
                   ribbon1_direction = None,
                   ribbon2_direction = None,
                   peakDeviationFromCenter = 9.5,
                   ribbonThickness = 2.0,
                   ribbon1Color = None, 
                   ribbon2Color = None,
                   stepColor = None):
    """
    Draw DNA ribbons where each strand is represented as a ribbon. DNA ribbons
    are drawn as sine waves with appropriate phase angles, with the phase
    angles computed in this method.

    @param endCenter1: Axis end 1
    @type  endCenter1: B{V}
    @param endCenter2: Axis end 2
    @type  endCenter2: B{V}
    @param basesPerTurn: Number of bases in a full turn.
    @type  basesPerTurn: float
    @param duplexRise: Center to center distance between consecutive steps
    @type  duplexRise: float
    @param glpaneScale: GLPane scale used in scaling arrow head drawing 
    @type  glpaneScale: float
    @param lineOfSightVector: Glpane lineOfSight vector, used to compute the 
                              the vector along the ladder step. 
    @type: B{V}    
    @param displayStyle: Rubberband display style (specified as an integer)
                         see comment in the method below. 
                         See also GLpane.displayStyle.
    @type  displayStyle: int
    @param peakDeviationFromCenter: Distance of a peak from the axis 
                                    Also known as 'Amplitude' of a sine wave. 
    @type peakDeviationFromCenter: float
    @param ribbonThickness: Thickness of each of the the two ribbons
    @type ribbonThickness: float
    @param ribbon1Color: Color of ribbon1
    @param ribbon2Color: Color of ribbon2
    @see: B{DnaLineMode.Draw } (where it is used) for comments on color 
          convention

    TODO: as of 2008-04-22
      - Need more documentation
      -  This method is long mainly because of a number of custom drawing 
         See if that can be refactored e.g. methods like _drawRibbon1/strand1, 
         drawRibbon2 / strand2 etc. 
      - Further optimization / refactoring (low priority) 
    """

    #Try to match the rubberband display style as closely as possible to 
    #either the glpane's current display or the chunk display of the segment 
    #being edited. The caller should do the job of specifying the display style
    #it desires. As of 2008-02-20, this method only supports following display 
    #styles --Tubes, Ball and Stick, CPK and lines. the sphere radius 
    #for ball and stick or CPK is calculated approximately. 

    if displayStyle == diTrueCPK:
        SPHERE_RADIUS = 3.5
        ribbonThickness = 2.0
    elif displayStyle == diTUBES:
        SPHERE_RADIUS = 0.01
        ribbonThickness = 5.0
    elif displayStyle == diLINES:
        #Lines display and all other unsupported display styles
        SPHERE_RADIUS = 0.01
        ribbonThickness = 1.0
    else:
        #ball and stick display style. All other unsupported displays 
        #will be rendered in ball and stick display style
        SPHERE_RADIUS = 1.0
        ribbonThickness = 3.0
        
    



    ribbonLength = vlen(endCenter1 - endCenter2)

    #Don't draw the vertical line (step) passing through the startpoint unless 
    #the ribbonLength is at least equal to the duplexRise. 
    # i.e. do the drawing only when there are at least two ladder steps. 
    # This prevents a 'revolving line' effect due to the single ladder step at 
    # the first endpoint 
    if ribbonLength < duplexRise:
        return

    unitVectorAlongLength = norm(endCenter2 - endCenter1)
     
    ##############
    pointOnAxis = endCenter1

    axial_shift_1 = V(0.0, 0.0, 0.0) # might be changed below
    axial_shift_2 = V(0.0, 0.0, 0.0)
    
    # [these might be discarded and recomputed just below;
    #  the case where they aren't is (and I think was) untested.
    #  -- bruce 080422 comment]
    vectorAlongLadderStep =  cross(-lineOfSightVector, unitVectorAlongLength)
    unitVectorAlongLadderStep = norm(vectorAlongLadderStep)
    unitDepthVector = cross(unitVectorAlongLength,
                            unitVectorAlongLadderStep) ## * -1 
    
    numberOfBasesDrawn = 0
    theta_offset = 0
    x = 0
    ###
    #Formula .. Its a Sine Wave.
    # y(x) = A.sin(2*pi*f*x + phase_angle)  ------[1]
    # where --
    #      f = 1/T 
    #      A = Amplitude of the sine wave (or 'peak deviation from center') 
    #      y = y coordinate  of the sine wave -- distance is in Angstroms
    #      x = the x coordinate
    # phase_angle is computed for each wave. We know y at x =0. For example, 
    # for ribbon_1, , at x = 0, y = A. Putting these values in equation [1] 
    # we get the phase_angle. Similarly, for ribbon_2, at x = 0, y = -6 
    # Putting these values will give use the phase_angle_2. 
    # Note that for ribbon2_point, we subtract the value of equation [1] from 
    # the point on axis. 

    x = 0.0
    T =  duplexRise * basesPerTurn 
        # The 'Period' of the sine wave
        # (i.e. peak to peak distance between consecutive crests)

    amplitude = peakDeviationFromCenter
    amplitudeVector = unitVectorAlongLadderStep * amplitude
    depthVector = unitDepthVector * amplitude
        # Note: to reduce the effect of perspective view on rung direction,
        # we could multiply depthVector by 0.1 or 0.01. But this would lessen
        # the depth realism of line/sphere intersections. [bruce 080216]
    ###
    

    if ribbon1_start_point is not None:
        ribbon1_point = ribbon1_start_point        
    else:
        if ribbon2_start_point is not None:
            ribbon1_point = _get_ribbon_point_on_other_ribbon(
                ribbon2_start_point,
                ribbon2_direction,
                endCenter1,
                unitVectorAlongLength) 
            
        else:
            phase_angle_ribbon_1 = HALF_PI    
            theta_ribbon_1 = (TWICE_PI * x / T) + phase_angle_ribbon_1
            
            #Initialize ribbon1_point and ribbon2_point
            ribbon1_point = pointOnAxis + \
                            amplitudeVector * sin(theta_ribbon_1) + \
                            depthVector * cos(theta_ribbon_1)
            ribbon1_direction = +1
            
    drawDnaSingleRibbon(glpane,
                        endCenter1,  
                        endCenter2,
                        basesPerTurn,
                        duplexRise, 
                        # maybe: don't pass these three args, get from glpane
                        # instead? [bruce 080422 comment]
                        glpaneScale,
                        lineOfSightVector,
                        displayStyle,
                        ribbon1_start_point = ribbon1_point,
                        ribbon1_direction = ribbon1_direction,
                        peakDeviationFromCenter = peakDeviationFromCenter,
                        ribbonThickness = ribbonThickness,
                        ribbon1Color = ribbon1Color, 
                        stepColor = stepColor)

    if ribbon2_start_point is not None:
        ribbon2_point = ribbon2_start_point        
    else:
        if ribbon1_start_point is not None:
            ribbon2_point = _get_ribbon_point_on_other_ribbon(
                ribbon1_start_point,
                ribbon1_direction,
                endCenter1,
                unitVectorAlongLength)
            
        else:
            phase_angle_ribbon_2 = asin(-6.0/(amplitude))
            theta_ribbon_2 = (TWICE_PI * x / T) - phase_angle_ribbon_2    
            ribbon2_point = pointOnAxis - \
                            amplitudeVector * sin(theta_ribbon_2) + \
                            depthVector * cos(theta_ribbon_2)
            ribbon2_direction = -1
            
    drawDnaSingleRibbon(glpane,
                        endCenter1,  
                        endCenter2,
                        basesPerTurn,
                        duplexRise, 
                        # maybe: don't pass these three args, get from glpane
                        # instead? [bruce 080422 comment]
                        glpaneScale,
                        lineOfSightVector,
                        displayStyle,
                        ribbon1_start_point = ribbon2_point,
                        ribbon1_direction = ribbon2_direction,
                        peakDeviationFromCenter = peakDeviationFromCenter,
                        ribbonThickness = ribbonThickness,
                        ribbon1Color = ribbon2Color, 
                        stepColor = stepColor)
    
    del vectorAlongLadderStep
    
    return
    def _buildResidue(self, mol, zmatrix, n_atoms, idx, phi, psi, secondary, init_pos, residue_name, fake_chain=False):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        @param mol: a chunk to which the amino acid will be added.
        @type mol: Chunk

        @param zmatrix: is an internal coordinates array corresponding to a
        given amino acid.
        @type zmatrix: list

        @param n_atoms: size of z-matrix (a number of atoms to be build + 3
        dummy atoms)
        @type n_atoms: int

        @param idx: is a residue index (1..length).
        @type idx: integer

        @param phi, psi: peptide bond phi and psi angles
        @type phi, psi: float

        @param init_pos: optional postions of previous CA, C and O atoms.
        @type init_pos: V

        @param symbol: current amino acid symbol (used to derermine proline case)
        @type symbol: string

        """

        # note: currently, it doesn't rebuild bonds, so inferBonds has to be
        # called after this method. Unfortunately, the proper bond order can
        # not be correctly recognized this way. Therefore, temporary atom flags
        # _is_aromatic and _is_single are used.

        #this code was re-factored by EricM and internal-to-cartesian
        # conversion method was moved to geometry.InternalCoordinatesToCartesian

        if mol is None:
            return

        if not init_pos: # assign three previous atom positions
            coords = self.prev_coords
        else:
            # if no prev_coords are given, compute the first three atom positions
            coords = zeros([3,3], Float)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            coords[0][0] = 0.0;
            coords[0][1] = 0.0;
            coords[0][2] = 0.0;
            coords[1][0] = r;
            coords[1][1] = 0.0;
            coords[1][2] = 0.0;
            ccos = cos(DEG2RAD*a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                coords[2][0] = coords[0][0] + r*ccos
            else:
                coords[2][0] = coords[0][0] - r*ccos
            coords[2][1] = r * sin(DEG2RAD*a)
            coords[2][2] = 0.0
            for i in range (0, 3):
                self.prev_coords[i][0] = coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = coords[i][2] + init_pos[2]

        translator = InternalCoordinatesToCartesian(n_atoms, coords)

        for n in range (3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            # Apply the peptide bond conformation
            if residue_name != "PRO":
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "HA " or name == "HA2":
                    t = 120.0 + phi
                if name == "CB " or name == "HA3":
                    t = 240.0 + phi
                if name == "C  ":
                    t = phi
            else:
                # proline
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "CA ":
                    t = phi - 120.0
                if name == "CD ":
                    t = phi + 60.0

            translator.addInternal(n+1, atom_c+1, atom_b+1, atom_a+1, r, a, t)
            xyz = translator.getCartesian(n+1)

            if self.nterm_hydrogen:
                # This is a hack for the first hydrogen atom
                # to make sure the bond length is correct.
                self.nterm_hydrogen.setposn(
                    self.nterm_hydrogen.posn() + \
                    0.325 * norm(xyz))
                self.nterm_hydrogen = None

            # Store previous coordinates for the next building step
            if not init_pos:
                if name=="N  ":
                    self.prev_coords[0][0] = xyz[0]
                    self.prev_coords[0][1] = xyz[1]
                    self.prev_coords[0][2] = xyz[2]
                if name=="CA ":
                    self.prev_coords[1][0] = xyz[0]
                    self.prev_coords[1][1] = xyz[1]
                    self.prev_coords[1][2] = xyz[2]
                if name=="C  ":
                    self.prev_coords[2][0] = xyz[0]
                    self.prev_coords[2][1] = xyz[1]
                    self.prev_coords[2][2] = xyz[2]

            # Add a new atom to the molecule
            if not fake_chain or \
               name == "CA ":
                atom = Atom(
                    atom_name,
                    xyz,
                    mol)

                if not self.init_ca and \
                   name == "CA ":
                    self.init_ca = atom

                if mol.protein:
                    aa = mol.protein.add_pdb_atom(atom,
                                             name.replace(' ',''),
                                             idx,
                                             AA_3_TO_1[residue_name])
                    atom.pdb_info = {}
                    atom.pdb_info['atom_name'] = name.replace(' ','')
                    atom.pdb_info['residue_name'] = residue_name
                    residue_id = "%3d " % idx
                    atom.pdb_info['residue_id'] = residue_id
                    atom.pdb_info['standard_atom'] = True
                    atom.pdb_info['chain_id'] = True
                    if aa:
                        aa.set_secondary_structure(secondary)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                ### debug - output in PDB format
                ### print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, xyz[0], xyz[1], xyz[2])

        self.prev_psi = psi # Remember previous psi angle.

        return
Esempio n. 22
0
def setup_drawer():
    """
    Set up the usual constant display lists in the current OpenGL context.

    WARNING: THIS IS ONLY CORRECT IF ONLY ONE GL CONTEXT CONTAINS DISPLAY LISTS
    -- or more precisely, only the GL context this has last been called in (or
    one which shares its display lists) will work properly with the routines in
    drawer.py, since the allocated display list names are stored in globals set
    by this function, but in general those names might differ if this was called
    in different GL contexts.
    """
    #bruce 060613 added docstring, cleaned up display list name allocation
    # bruce 071030 renamed from setup to setup_drawer

    spherelistbase = glGenLists(numSphereSizes)
    sphereList = []
    for i in range(numSphereSizes):
        sphereList += [spherelistbase+i]
        glNewList(sphereList[i], GL_COMPILE)
        glBegin(GL_TRIANGLE_STRIP) # GL_LINE_LOOP to see edges.
        stripVerts = getSphereTriStrips(i)
        for vertNorm in stripVerts:
            glNormal3fv(vertNorm)
            glVertex3fv(vertNorm)
            continue
        glEnd()
        glEndList()
        continue
    drawing_globals.sphereList = sphereList

    # Sphere triangle-strip vertices for each level of detail.
    # (Cache and re-use the work of making them.)
    # Can use in converter-wrappered calls like glVertexPointerfv,
    # but the python arrays are re-copied to C each time.
    sphereArrays = []
    for i in range(numSphereSizes):
        sphereArrays += [getSphereTriStrips(i)]
        continue
    drawing_globals.sphereArrays = sphereArrays

    # Sphere glDrawArrays triangle-strip vertices for C calls.
    # (Cache and re-use the work of converting a C version.)
    # Used in thinly-wrappered calls like glVertexPointer.
    sphereCArrays = []
    for i in range(numSphereSizes):
        CArray = numpy.array(sphereArrays[i], dtype=numpy.float32)
        sphereCArrays += [CArray]
        continue
    drawing_globals.sphereCArrays = sphereCArrays

    # Sphere indexed vertices.
    # (Cache and re-use the work of making the indexes.)
    # Can use in converter-wrappered calls like glDrawElementsui,
    # but the python arrays are re-copied to C each time.
    sphereElements = []             # Pairs of lists (index, verts) .
    for i in range(numSphereSizes):
        sphereElements += [indexVerts(sphereArrays[i], .0001)]
        continue
    drawing_globals.sphereElements = sphereElements

    # Sphere glDrawElements index and vertex arrays for C calls.
    sphereCIndexTypes = []          # numpy index unsigned types.
    sphereGLIndexTypes = []         # GL index types for drawElements.
    sphereCElements = []            # Pairs of numpy arrays (Cindex, Cverts) .
    for i in range(numSphereSizes):
        (index, verts) = sphereElements[i]
        if len(index) < 256:
            Ctype = numpy.uint8
            GLtype = GL_UNSIGNED_BYTE
        else:
            Ctype = numpy.uint16
            GLtype = GL_UNSIGNED_SHORT
            pass
        sphereCIndexTypes += [Ctype]
        sphereGLIndexTypes += [GLtype]
        sphereCIndex = numpy.array(index, dtype=Ctype)
        sphereCVerts = numpy.array(verts, dtype=numpy.float32)
        sphereCElements += [(sphereCIndex, sphereCVerts)]
        continue
    drawing_globals.sphereCIndexTypes = sphereCIndexTypes
    drawing_globals.sphereGLIndexTypes = sphereGLIndexTypes
    drawing_globals.sphereCElements = sphereCElements

    if glGetString(GL_EXTENSIONS).find("GL_ARB_vertex_buffer_object") >= 0:

        # A GLBufferObject version for glDrawArrays.
        sphereArrayVBOs = []
        for i in range(numSphereSizes):
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB,
                                 sphereCArrays[i], GL_STATIC_DRAW)
            sphereArrayVBOs += [vbo]
            continue
        drawing_globals.sphereArrayVBOs = sphereArrayVBOs

        # A GLBufferObject version for glDrawElements indexed verts.
        sphereElementVBOs = []              # Pairs of (IBO, VBO)
        for i in range(numSphereSizes):
            ibo = GLBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB,
                                 sphereCElements[i][0], GL_STATIC_DRAW)
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB,
                                 sphereCElements[i][1], GL_STATIC_DRAW)
            sphereElementVBOs += [(ibo, vbo)]
            continue
        drawing_globals.sphereElementVBOs = sphereElementVBOs

        ibo.unbind()
        vbo.unbind()
        pass

    #bruce 060415
    drawing_globals.wiresphere1list = wiresphere1list = glGenLists(1)
    glNewList(wiresphere1list, GL_COMPILE)
    didlines = {} # don't draw each triangle edge more than once

    def shoulddoline(v1,v2):
        # make sure not list (unhashable) or Numeric array (bug in __eq__)
        v1 = tuple(v1)
        v2 = tuple(v2)
        if (v1,v2) not in didlines:
            didlines[(v1,v2)] = didlines[(v2,v1)] = None
            return True
        return False
    def doline(v1,v2):
        if shoulddoline(v1,v2):
            glVertex3fv(v1)
            glVertex3fv(v2)
        return
    glBegin(GL_LINES)
    ocdec = getSphereTriangles(1)
    for tri in ocdec:
        #e Could probably optim this more, e.g. using a vertex array or VBO or
        #  maybe GL_LINE_STRIP.
        doline(tri[0], tri[1])
        doline(tri[1], tri[2])
        doline(tri[2], tri[0])
    glEnd()
    glEndList()

    drawing_globals.CylList = CylList = glGenLists(1)
    glNewList(CylList, GL_COMPILE)
    glBegin(GL_TRIANGLE_STRIP)
    for (vtop, ntop, vbot, nbot) in drawing_globals.cylinderEdges:
        glNormal3fv(nbot)
        glVertex3fv(vbot)
        glNormal3fv(ntop)
        glVertex3fv(vtop)
    glEnd()
    glEndList()

    drawing_globals.CapList = CapList = glGenLists(1)
    glNewList(CapList, GL_COMPILE)
    glNormal3fv(drawing_globals.cap0n)
    glBegin(GL_POLYGON)
    for p in drawing_globals.drum0:
        glVertex3fv(p)
    glEnd()
    glNormal3fv(drawing_globals.cap1n)
    glBegin(GL_POLYGON)
    #bruce 060609 fix "ragged edge" bug in this endcap: drum1 -> drum2
    for p in drawing_globals.drum2:
        glVertex3fv(p)
    glEnd()
    glEndList()

    drawing_globals.diamondGridList = diamondGridList = glGenLists(1)
    glNewList(diamondGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.digrid:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.lonsGridList = lonsGridList = glGenLists(1)
    glNewList(lonsGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.lonsEdges:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.CubeList = CubeList = glGenLists(1)
    glNewList(CubeList, GL_COMPILE)
    glBegin(GL_QUAD_STRIP)
    # note: CubeList has only 4 faces of the cube; only suitable for use in
    # wireframes; see also solidCubeList [bruce 051215 comment reporting
    # grantham 20051213 observation]
    glVertex((-1,-1,-1))
    glVertex(( 1,-1,-1))
    glVertex((-1, 1,-1))
    glVertex(( 1, 1,-1))
    glVertex((-1, 1, 1))
    glVertex(( 1, 1, 1))
    glVertex((-1,-1, 1))
    glVertex(( 1,-1, 1))
    glVertex((-1,-1,-1))
    glVertex(( 1,-1,-1))
    glEnd()
    glEndList()

    drawing_globals.solidCubeList = solidCubeList = glGenLists(1)
    glNewList(solidCubeList, GL_COMPILE)
    glBegin(GL_QUADS)
    for i in xrange(len(drawing_globals.cubeIndices)):
        avenormals = V(0,0,0) #bruce 060302 fixed normals for flat shading 
        for j in xrange(4) :    
            nTuple = tuple(
                drawing_globals.cubeNormals[drawing_globals.cubeIndices[i][j]])
            avenormals += A(nTuple)
        avenormals = norm(avenormals)
        for j in xrange(4) :    
            vTuple = tuple(
                drawing_globals.cubeVertices[drawing_globals.cubeIndices[i][j]])
            #bruce 060302 made size compatible with glut.glutSolidCube(1.0)
            vTuple = A(vTuple) * 0.5
            glNormal3fv(avenormals)
            glVertex3fv(vTuple)
    glEnd()
    glEndList()                

    drawing_globals.rotSignList = rotSignList = glGenLists(1)
    glNewList(rotSignList, GL_COMPILE)
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS0n)):
        glVertex3fv(tuple(drawing_globals.rotS0n[ii]))
    glEnd()
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS1n)):
        glVertex3fv(tuple(drawing_globals.rotS1n[ii]))
    glEnd()
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.arrow0Vertices + drawing_globals.arrow1Vertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearArrowList = linearArrowList = glGenLists(1)
    glNewList(linearArrowList, GL_COMPILE)
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.linearArrowVertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearLineList = linearLineList = glGenLists(1)
    glNewList(linearLineList, GL_COMPILE)
    glEnable(GL_LINE_SMOOTH)
    glBegin(GL_LINES)
    glVertex3f(0.0, 0.0, -drawing_globals.halfHeight)
    glVertex3f(0.0, 0.0, drawing_globals.halfHeight)
    glEnd()
    glDisable(GL_LINE_SMOOTH)
    glEndList()

    drawing_globals.circleList = circleList = glGenLists(1)
    glNewList(circleList, GL_COMPILE)
    glBegin(GL_LINE_LOOP)
    for ii in range(60):
        x = cos(ii*2.0*pi/60)
        y = sin(ii*2.0*pi/60)
        glVertex3f(x, y, 0.0)
    glEnd()    
    glEndList()

    # piotr 080405
    drawing_globals.filledCircleList = filledCircleList = glGenLists(1)
    glNewList(filledCircleList, GL_COMPILE)
    glBegin(GL_POLYGON)
    for ii in range(60):
        x = cos(ii*2.0*pi/60)
        y = sin(ii*2.0*pi/60)
        glVertex3f(x, y, 0.0)
    glEnd()    
    glEndList()

    drawing_globals.lineCubeList = lineCubeList = glGenLists(1)
    glNewList(lineCubeList, GL_COMPILE)
    glBegin(GL_LINES)
    cvIndices = [0,1, 2,3, 4,5, 6,7, 0,3, 1,2, 5,6, 4,7, 0,4, 1,5, 2,6, 3,7]
    for i in cvIndices:
        glVertex3fv(tuple(drawing_globals.cubeVertices[i]))
    glEnd()    
    glEndList()

    # Debug Preferences
    from utilities.debug_prefs import debug_pref, Choice_boolean_True
    from utilities.debug_prefs import Choice_boolean_False
    choices = [Choice_boolean_False, Choice_boolean_True]

    # 20060314 grantham
    initial_choice = choices[drawing_globals.allow_color_sorting_default]
    drawing_globals.allow_color_sorting_pref = debug_pref(
        "Use Color Sorting?", initial_choice,
        prefs_key = drawing_globals.allow_color_sorting_prefs_key)
        #bruce 060323 removed non_debug = True for A7 release, changed default
        #value to False (far above), and changed its prefs_key so developers
        #start with the new default value.
    #russ 080225: Added.
    initial_choice = choices[drawing_globals.use_color_sorted_dls_default]
    drawing_globals.use_color_sorted_dls_pref = debug_pref(
        "Use Color-sorted Display Lists?", initial_choice,
        prefs_key = drawing_globals.use_color_sorted_dls_prefs_key)
    #russ 080225: Added.
    initial_choice = choices[drawing_globals.use_color_sorted_vbos_default]
    drawing_globals.use_color_sorted_vbos_pref = debug_pref(
        "Use Color-sorted Vertex Buffer Objects?", initial_choice,
        prefs_key = drawing_globals.use_color_sorted_vbos_prefs_key)

    #russ 080403: Added drawing variant selection
    variants = [
        "0. OpenGL 1.0 - glBegin/glEnd tri-strips vertex-by-vertex.",
        "1. OpenGL 1.1 - glDrawArrays from CPU RAM.",
        "2. OpenGL 1.1 - glDrawElements indexed arrays from CPU RAM.",
        "3. OpenGL 1.5 - glDrawArrays from graphics RAM VBO.",
        "4. OpenGL 1.5 - glDrawElements, verts in VBO, index in CPU.",
        "5. OpenGL 1.5 - VBO/IBO buffered glDrawElements."]
    drawing_globals.use_drawing_variant = debug_pref(
        "GLPane: drawing method",
        Choice(names = variants, values = range(len(variants)),
               defaultValue = drawing_globals.use_drawing_variant_default),
        prefs_key = drawing_globals.use_drawing_variant_prefs_key)

    # temporarily always print this, while default setting might be in flux,
    # and to avoid confusion if the two necessary prefs are set differently
    # [bruce 080305]
    if (drawing_globals.allow_color_sorting_pref and
        drawing_globals.use_color_sorted_dls_pref):
        print "\nnote: this session WILL use color sorted display lists"
    else:
        print "\nnote: this session will NOT use color sorted display lists"
    if (drawing_globals.allow_color_sorting_pref and
        drawing_globals.use_color_sorted_vbos_pref):
        print "note: this session WILL use", \
              "color sorted Vertex Buffer Objects\n"
    else:
        print "note: this session will NOT use", \
              "color sorted Vertex Buffer Objects\n"

    # 20060313 grantham Added use_c_renderer debug pref, can
    # take out when C renderer used by default.
    if drawing_globals.quux_module_import_succeeded:
        initial_choice = choices[drawing_globals.use_c_renderer_default]
        drawing_globals.use_c_renderer = (
            debug_pref("Use native C renderer?",
                       initial_choice,
                       prefs_key = drawing_globals.use_c_renderer_prefs_key))
            #bruce 060323 removed non_debug = True for A7 release, and changed
            # its prefs_key so developers start over with the default value.

    #initTexture('C:\\Huaicai\\atom\\temp\\newSample.png', 128,128)
    return # from setup_drawer
Esempio n. 23
0
 def func(x):
     return ((2 * x * cos(x) - sin(x)) * cos(x) - x + pi / 4.0)
Esempio n. 24
0
    def _buildResidue(self,
                      mol,
                      zmatrix,
                      n_atoms,
                      idx,
                      phi,
                      psi,
                      secondary,
                      init_pos,
                      residue_name,
                      fake_chain=False):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        @param mol: a chunk to which the amino acid will be added.
        @type mol: Chunk

        @param zmatrix: is an internal coordinates array corresponding to a
        given amino acid.
        @type zmatrix: list

        @param n_atoms: size of z-matrix (a number of atoms to be build + 3
        dummy atoms)
        @type n_atoms: int

        @param idx: is a residue index (1..length).
        @type idx: integer

        @param phi, psi: peptide bond phi and psi angles
        @type phi, psi: float

        @param init_pos: optional postions of previous CA, C and O atoms.
        @type init_pos: V

        @param symbol: current amino acid symbol (used to derermine proline case)
        @type symbol: string

        """

        # note: currently, it doesn't rebuild bonds, so inferBonds has to be
        # called after this method. Unfortunately, the proper bond order can
        # not be correctly recognized this way. Therefore, temporary atom flags
        # _is_aromatic and _is_single are used.

        #this code was re-factored by EricM and internal-to-cartesian
        # conversion method was moved to geometry.InternalCoordinatesToCartesian

        if mol is None:
            return

        if not init_pos:  # assign three previous atom positions
            coords = self.prev_coords
        else:
            # if no prev_coords are given, compute the first three atom positions
            coords = zeros([3, 3], Float)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            coords[0][0] = 0.0
            coords[0][1] = 0.0
            coords[0][2] = 0.0
            coords[1][0] = r
            coords[1][1] = 0.0
            coords[1][2] = 0.0
            ccos = cos(DEG2RAD * a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                coords[2][0] = coords[0][0] + r * ccos
            else:
                coords[2][0] = coords[0][0] - r * ccos
            coords[2][1] = r * sin(DEG2RAD * a)
            coords[2][2] = 0.0
            for i in range(0, 3):
                self.prev_coords[i][0] = coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = coords[i][2] + init_pos[2]

        translator = InternalCoordinatesToCartesian(n_atoms, coords)

        for n in range(3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            # Apply the peptide bond conformation
            if residue_name != "PRO":
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "HA " or name == "HA2":
                    t = 120.0 + phi
                if name == "CB " or name == "HA3":
                    t = 240.0 + phi
                if name == "C  ":
                    t = phi
            else:
                # proline
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "CA ":
                    t = phi - 120.0
                if name == "CD ":
                    t = phi + 60.0

            translator.addInternal(n + 1, atom_c + 1, atom_b + 1, atom_a + 1,
                                   r, a, t)
            xyz = translator.getCartesian(n + 1)

            if self.nterm_hydrogen:
                # This is a hack for the first hydrogen atom
                # to make sure the bond length is correct.
                self.nterm_hydrogen.setposn(
                    self.nterm_hydrogen.posn() + \
                    0.325 * norm(xyz))
                self.nterm_hydrogen = None

            # Store previous coordinates for the next building step
            if not init_pos:
                if name == "N  ":
                    self.prev_coords[0][0] = xyz[0]
                    self.prev_coords[0][1] = xyz[1]
                    self.prev_coords[0][2] = xyz[2]
                if name == "CA ":
                    self.prev_coords[1][0] = xyz[0]
                    self.prev_coords[1][1] = xyz[1]
                    self.prev_coords[1][2] = xyz[2]
                if name == "C  ":
                    self.prev_coords[2][0] = xyz[0]
                    self.prev_coords[2][1] = xyz[1]
                    self.prev_coords[2][2] = xyz[2]

            # Add a new atom to the molecule
            if not fake_chain or \
               name == "CA ":
                atom = Atom(atom_name, xyz, mol)

                if not self.init_ca and \
                   name == "CA ":
                    self.init_ca = atom

                if mol.protein:
                    aa = mol.protein.add_pdb_atom(atom, name.replace(' ', ''),
                                                  idx, AA_3_TO_1[residue_name])
                    atom.pdb_info = {}
                    atom.pdb_info['atom_name'] = name.replace(' ', '')
                    atom.pdb_info['residue_name'] = residue_name
                    residue_id = "%3d " % idx
                    atom.pdb_info['residue_id'] = residue_id
                    atom.pdb_info['standard_atom'] = True
                    atom.pdb_info['chain_id'] = True
                    if aa:
                        aa.set_secondary_structure(secondary)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                ### debug - output in PDB format
                ### print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, xyz[0], xyz[1], xyz[2])

        self.prev_psi = psi  # Remember previous psi angle.

        return
Esempio n. 25
0
def setup_drawer():
    """
    Set up the usual constant display lists in the current OpenGL context.

    WARNING: THIS IS ONLY CORRECT IF ONLY ONE GL CONTEXT CONTAINS DISPLAY LISTS
    -- or more precisely, only the GL context this has last been called in (or
    one which shares its display lists) will work properly with the routines in
    drawer.py, since the allocated display list names are stored in globals set
    by this function, but in general those names might differ if this was called
    in different GL contexts.
    """
    #bruce 060613 added docstring, cleaned up display list name allocation
    # bruce 071030 renamed from setup to setup_drawer

    spherelistbase = glGenLists(numSphereSizes)
    sphereList = []
    for i in range(numSphereSizes):
        sphereList += [spherelistbase + i]
        glNewList(sphereList[i], GL_COMPILE)
        glBegin(GL_TRIANGLE_STRIP)  # GL_LINE_LOOP to see edges.
        stripVerts = getSphereTriStrips(i)
        for vertNorm in stripVerts:
            glNormal3fv(vertNorm)
            glVertex3fv(vertNorm)
            continue
        glEnd()
        glEndList()
        continue
    drawing_globals.sphereList = sphereList

    # Sphere triangle-strip vertices for each level of detail.
    # (Cache and re-use the work of making them.)
    # Can use in converter-wrappered calls like glVertexPointerfv,
    # but the python arrays are re-copied to C each time.
    sphereArrays = []
    for i in range(numSphereSizes):
        sphereArrays += [getSphereTriStrips(i)]
        continue
    drawing_globals.sphereArrays = sphereArrays

    # Sphere glDrawArrays triangle-strip vertices for C calls.
    # (Cache and re-use the work of converting a C version.)
    # Used in thinly-wrappered calls like glVertexPointer.
    sphereCArrays = []
    for i in range(numSphereSizes):
        CArray = numpy.array(sphereArrays[i], dtype=numpy.float32)
        sphereCArrays += [CArray]
        continue
    drawing_globals.sphereCArrays = sphereCArrays

    # Sphere indexed vertices.
    # (Cache and re-use the work of making the indexes.)
    # Can use in converter-wrappered calls like glDrawElementsui,
    # but the python arrays are re-copied to C each time.
    sphereElements = []  # Pairs of lists (index, verts) .
    for i in range(numSphereSizes):
        sphereElements += [indexVerts(sphereArrays[i], .0001)]
        continue
    drawing_globals.sphereElements = sphereElements

    # Sphere glDrawElements index and vertex arrays for C calls.
    sphereCIndexTypes = []  # numpy index unsigned types.
    sphereGLIndexTypes = []  # GL index types for drawElements.
    sphereCElements = []  # Pairs of numpy arrays (Cindex, Cverts) .
    for i in range(numSphereSizes):
        (index, verts) = sphereElements[i]
        if len(index) < 256:
            Ctype = numpy.uint8
            GLtype = GL_UNSIGNED_BYTE
        else:
            Ctype = numpy.uint16
            GLtype = GL_UNSIGNED_SHORT
            pass
        sphereCIndexTypes += [Ctype]
        sphereGLIndexTypes += [GLtype]
        sphereCIndex = numpy.array(index, dtype=Ctype)
        sphereCVerts = numpy.array(verts, dtype=numpy.float32)
        sphereCElements += [(sphereCIndex, sphereCVerts)]
        continue
    drawing_globals.sphereCIndexTypes = sphereCIndexTypes
    drawing_globals.sphereGLIndexTypes = sphereGLIndexTypes
    drawing_globals.sphereCElements = sphereCElements

    if glGetString(GL_EXTENSIONS).find("GL_ARB_vertex_buffer_object") >= 0:

        # A GLBufferObject version for glDrawArrays.
        sphereArrayVBOs = []
        for i in range(numSphereSizes):
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB, sphereCArrays[i],
                                 GL_STATIC_DRAW)
            sphereArrayVBOs += [vbo]
            continue
        drawing_globals.sphereArrayVBOs = sphereArrayVBOs

        # A GLBufferObject version for glDrawElements indexed verts.
        sphereElementVBOs = []  # Pairs of (IBO, VBO)
        for i in range(numSphereSizes):
            ibo = GLBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB,
                                 sphereCElements[i][0], GL_STATIC_DRAW)
            vbo = GLBufferObject(GL_ARRAY_BUFFER_ARB, sphereCElements[i][1],
                                 GL_STATIC_DRAW)
            sphereElementVBOs += [(ibo, vbo)]
            continue
        drawing_globals.sphereElementVBOs = sphereElementVBOs

        ibo.unbind()
        vbo.unbind()
        pass

    #bruce 060415
    drawing_globals.wiresphere1list = wiresphere1list = glGenLists(1)
    glNewList(wiresphere1list, GL_COMPILE)
    didlines = {}  # don't draw each triangle edge more than once

    def shoulddoline(v1, v2):
        # make sure not list (unhashable) or Numeric array (bug in __eq__)
        v1 = tuple(v1)
        v2 = tuple(v2)
        if (v1, v2) not in didlines:
            didlines[(v1, v2)] = didlines[(v2, v1)] = None
            return True
        return False

    def doline(v1, v2):
        if shoulddoline(v1, v2):
            glVertex3fv(v1)
            glVertex3fv(v2)
        return

    glBegin(GL_LINES)
    ocdec = getSphereTriangles(1)
    for tri in ocdec:
        #e Could probably optim this more, e.g. using a vertex array or VBO or
        #  maybe GL_LINE_STRIP.
        doline(tri[0], tri[1])
        doline(tri[1], tri[2])
        doline(tri[2], tri[0])
    glEnd()
    glEndList()

    drawing_globals.CylList = CylList = glGenLists(1)
    glNewList(CylList, GL_COMPILE)
    glBegin(GL_TRIANGLE_STRIP)
    for (vtop, ntop, vbot, nbot) in drawing_globals.cylinderEdges:
        glNormal3fv(nbot)
        glVertex3fv(vbot)
        glNormal3fv(ntop)
        glVertex3fv(vtop)
    glEnd()
    glEndList()

    drawing_globals.CapList = CapList = glGenLists(1)
    glNewList(CapList, GL_COMPILE)
    glNormal3fv(drawing_globals.cap0n)
    glBegin(GL_POLYGON)
    for p in drawing_globals.drum0:
        glVertex3fv(p)
    glEnd()
    glNormal3fv(drawing_globals.cap1n)
    glBegin(GL_POLYGON)
    #bruce 060609 fix "ragged edge" bug in this endcap: drum1 -> drum2
    for p in drawing_globals.drum2:
        glVertex3fv(p)
    glEnd()
    glEndList()

    drawing_globals.diamondGridList = diamondGridList = glGenLists(1)
    glNewList(diamondGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.digrid:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.lonsGridList = lonsGridList = glGenLists(1)
    glNewList(lonsGridList, GL_COMPILE)
    glBegin(GL_LINES)
    for p in drawing_globals.lonsEdges:
        glVertex(p[0])
        glVertex(p[1])
    glEnd()
    glEndList()

    drawing_globals.CubeList = CubeList = glGenLists(1)
    glNewList(CubeList, GL_COMPILE)
    glBegin(GL_QUAD_STRIP)
    # note: CubeList has only 4 faces of the cube; only suitable for use in
    # wireframes; see also solidCubeList [bruce 051215 comment reporting
    # grantham 20051213 observation]
    glVertex((-1, -1, -1))
    glVertex((1, -1, -1))
    glVertex((-1, 1, -1))
    glVertex((1, 1, -1))
    glVertex((-1, 1, 1))
    glVertex((1, 1, 1))
    glVertex((-1, -1, 1))
    glVertex((1, -1, 1))
    glVertex((-1, -1, -1))
    glVertex((1, -1, -1))
    glEnd()
    glEndList()

    drawing_globals.solidCubeList = solidCubeList = glGenLists(1)
    glNewList(solidCubeList, GL_COMPILE)
    glBegin(GL_QUADS)
    for i in xrange(len(drawing_globals.cubeIndices)):
        avenormals = V(0, 0, 0)  #bruce 060302 fixed normals for flat shading
        for j in xrange(4):
            nTuple = tuple(
                drawing_globals.cubeNormals[drawing_globals.cubeIndices[i][j]])
            avenormals += A(nTuple)
        avenormals = norm(avenormals)
        for j in xrange(4):
            vTuple = tuple(drawing_globals.cubeVertices[
                drawing_globals.cubeIndices[i][j]])
            #bruce 060302 made size compatible with glut.glutSolidCube(1.0)
            vTuple = A(vTuple) * 0.5
            glNormal3fv(avenormals)
            glVertex3fv(vTuple)
    glEnd()
    glEndList()

    drawing_globals.rotSignList = rotSignList = glGenLists(1)
    glNewList(rotSignList, GL_COMPILE)
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS0n)):
        glVertex3fv(tuple(drawing_globals.rotS0n[ii]))
    glEnd()
    glBegin(GL_LINE_STRIP)
    for ii in xrange(len(drawing_globals.rotS1n)):
        glVertex3fv(tuple(drawing_globals.rotS1n[ii]))
    glEnd()
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.arrow0Vertices + drawing_globals.arrow1Vertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearArrowList = linearArrowList = glGenLists(1)
    glNewList(linearArrowList, GL_COMPILE)
    glBegin(GL_TRIANGLES)
    for v in drawing_globals.linearArrowVertices:
        glVertex3f(v[0], v[1], v[2])
    glEnd()
    glEndList()

    drawing_globals.linearLineList = linearLineList = glGenLists(1)
    glNewList(linearLineList, GL_COMPILE)
    glEnable(GL_LINE_SMOOTH)
    glBegin(GL_LINES)
    glVertex3f(0.0, 0.0, -drawing_globals.halfHeight)
    glVertex3f(0.0, 0.0, drawing_globals.halfHeight)
    glEnd()
    glDisable(GL_LINE_SMOOTH)
    glEndList()

    drawing_globals.circleList = circleList = glGenLists(1)
    glNewList(circleList, GL_COMPILE)
    glBegin(GL_LINE_LOOP)
    for ii in range(60):
        x = cos(ii * 2.0 * pi / 60)
        y = sin(ii * 2.0 * pi / 60)
        glVertex3f(x, y, 0.0)
    glEnd()
    glEndList()

    # piotr 080405
    drawing_globals.filledCircleList = filledCircleList = glGenLists(1)
    glNewList(filledCircleList, GL_COMPILE)
    glBegin(GL_POLYGON)
    for ii in range(60):
        x = cos(ii * 2.0 * pi / 60)
        y = sin(ii * 2.0 * pi / 60)
        glVertex3f(x, y, 0.0)
    glEnd()
    glEndList()

    drawing_globals.lineCubeList = lineCubeList = glGenLists(1)
    glNewList(lineCubeList, GL_COMPILE)
    glBegin(GL_LINES)
    cvIndices = [
        0, 1, 2, 3, 4, 5, 6, 7, 0, 3, 1, 2, 5, 6, 4, 7, 0, 4, 1, 5, 2, 6, 3, 7
    ]
    for i in cvIndices:
        glVertex3fv(tuple(drawing_globals.cubeVertices[i]))
    glEnd()
    glEndList()

    # Debug Preferences
    from utilities.debug_prefs import debug_pref, Choice_boolean_True
    from utilities.debug_prefs import Choice_boolean_False
    choices = [Choice_boolean_False, Choice_boolean_True]

    # 20060314 grantham
    initial_choice = choices[drawing_globals.allow_color_sorting_default]
    drawing_globals.allow_color_sorting_pref = debug_pref(
        "Use Color Sorting?",
        initial_choice,
        prefs_key=drawing_globals.allow_color_sorting_prefs_key)
    #bruce 060323 removed non_debug = True for A7 release, changed default
    #value to False (far above), and changed its prefs_key so developers
    #start with the new default value.
    #russ 080225: Added.
    initial_choice = choices[drawing_globals.use_color_sorted_dls_default]
    drawing_globals.use_color_sorted_dls_pref = debug_pref(
        "Use Color-sorted Display Lists?",
        initial_choice,
        prefs_key=drawing_globals.use_color_sorted_dls_prefs_key)
    #russ 080225: Added.
    initial_choice = choices[drawing_globals.use_color_sorted_vbos_default]
    drawing_globals.use_color_sorted_vbos_pref = debug_pref(
        "Use Color-sorted Vertex Buffer Objects?",
        initial_choice,
        prefs_key=drawing_globals.use_color_sorted_vbos_prefs_key)

    #russ 080403: Added drawing variant selection
    variants = [
        "0. OpenGL 1.0 - glBegin/glEnd tri-strips vertex-by-vertex.",
        "1. OpenGL 1.1 - glDrawArrays from CPU RAM.",
        "2. OpenGL 1.1 - glDrawElements indexed arrays from CPU RAM.",
        "3. OpenGL 1.5 - glDrawArrays from graphics RAM VBO.",
        "4. OpenGL 1.5 - glDrawElements, verts in VBO, index in CPU.",
        "5. OpenGL 1.5 - VBO/IBO buffered glDrawElements."
    ]
    drawing_globals.use_drawing_variant = debug_pref(
        "GLPane: drawing method",
        Choice(names=variants,
               values=range(len(variants)),
               defaultValue=drawing_globals.use_drawing_variant_default),
        prefs_key=drawing_globals.use_drawing_variant_prefs_key)

    # temporarily always print this, while default setting might be in flux,
    # and to avoid confusion if the two necessary prefs are set differently
    # [bruce 080305]
    if (drawing_globals.allow_color_sorting_pref
            and drawing_globals.use_color_sorted_dls_pref):
        print "\nnote: this session WILL use color sorted display lists"
    else:
        print "\nnote: this session will NOT use color sorted display lists"
    if (drawing_globals.allow_color_sorting_pref
            and drawing_globals.use_color_sorted_vbos_pref):
        print "note: this session WILL use", \
              "color sorted Vertex Buffer Objects\n"
    else:
        print "note: this session will NOT use", \
              "color sorted Vertex Buffer Objects\n"

    # 20060313 grantham Added use_c_renderer debug pref, can
    # take out when C renderer used by default.
    if drawing_globals.quux_module_import_succeeded:
        initial_choice = choices[drawing_globals.use_c_renderer_default]
        drawing_globals.use_c_renderer = (debug_pref(
            "Use native C renderer?",
            initial_choice,
            prefs_key=drawing_globals.use_c_renderer_prefs_key))
        #bruce 060323 removed non_debug = True for A7 release, and changed
        # its prefs_key so developers start over with the default value.

    #initTexture('C:\\Huaicai\\atom\\temp\\newSample.png', 128,128)
    return  # from setup_drawer
Esempio n. 26
0
    def addInternal(self, i, na, nb, nc, r, theta, phi):
        """
        Add another point, given its internal coordinates.  Once added
        via this routine, the cartesian coordinates for the point can
        be retrieved with getCartesian().

        @param i: Index of the point being added.  After this call, a
                  call to getCartesian with this index value will
                  succeed.  Index values less than 4 are ignored.
                  Index values should be presented here in sequence
                  beginning with 4.

        @param na: Index value for point A.  Point 'i' will be 'r'
                   distance units from point A.

        @param nb: Index value for point B.  Point 'i' will be located
                   such that the angle i-A-B is 'theta' degrees.

        @param nc: Index value for point C.  Point 'i' will be located
                      such that the torsion angle i-A-B-C is 'torsion'
                      degrees.

        @param r: Radial distance (in same units as resulting
                  cartesian coordinates) between A and i.

        @param theta: Angle in degrees of i-A-B.

        @param phi: Torsion angle in degrees of i-A-B-C
        """

        if (i < 4):
            return

        if (i != self._nextIndex):
            raise IndexError, "next index is %d not %r" % (self._nextIndex, i)

        cos_theta = cos(DEG2RAD * theta)
        xb = self._coords[nb][0] - self._coords[na][0]
        yb = self._coords[nb][1] - self._coords[na][1]
        zb = self._coords[nb][2] - self._coords[na][2]
        rba = 1.0 / sqrt(xb*xb + yb*yb + zb*zb)

        if abs(cos_theta) >= 0.999:
            # Linear case
            # Skip angles, just extend along A-B.
            rba = r * rba * cos_theta
            xqd = xb * rba
            yqd = yb * rba
            zqd = zb * rba
        else:
            xc = self._coords[nc][0] - self._coords[na][0]
            yc = self._coords[nc][1] - self._coords[na][1]
            zc = self._coords[nc][2] - self._coords[na][2]

            xyb = sqrt(xb*xb + yb*yb)

            inv = False
            if xyb < 0.001:
                # A-B points along the z axis.
                tmp = zc
                zc = -xc
                xc = tmp
                tmp = zb
                zb = -xb
                xb = tmp
                xyb = sqrt(xb*xb + yb*yb)
                inv = True

            costh = xb / xyb
            sinth = yb / xyb
            xpc = xc * costh + yc * sinth
            ypc = yc * costh - xc * sinth
            sinph = zb * rba
            cosph = sqrt(abs(1.0- sinph * sinph))
            xqa = xpc * cosph + zc * sinph
            zqa = zc * cosph - xpc * sinph
            yzc = sqrt(ypc * ypc + zqa * zqa)
            if yzc < 1e-8:
                coskh = 1.0
                sinkh = 0.0
            else:
                coskh = ypc / yzc
                sinkh = zqa / yzc

            sin_theta = sin(DEG2RAD * theta)
            sin_phi = -sin(DEG2RAD * phi)
            cos_phi = cos(DEG2RAD * phi)

            # Apply the bond length.
            xd = r * cos_theta
            yd = r * sin_theta * cos_phi
            zd = r * sin_theta * sin_phi

            # Compute the atom position using bond and torsional angles.
            ypd = yd * coskh - zd * sinkh
            zpd = zd * coskh + yd * sinkh
            xpd = xd * cosph - zpd * sinph
            zqd = zpd * cosph + xd * sinph
            xqd = xpd * costh - ypd * sinth
            yqd = ypd * costh + xpd * sinth

            if inv:
                tmp = -zqd
                zqd = xqd
                xqd = tmp

        self._coords[i][0] = xqd + self._coords[na][0]
        self._coords[i][1] = yqd + self._coords[na][1]
        self._coords[i][2] = zqd + self._coords[na][2]
        self._nextIndex = self._nextIndex + 1