def Draw(self): """ Draw method for this temporary mode. """ _superclass_for_GM.Draw(self) #This fixes NFR bug 2803 #Don't draw the Dna rubberband line if the cursor is over the confirmation #corner. But make sure to call superclass.Draw method before doing this #check because we need to draw the rest of the model in the graphics #mode!. @see: DnaLineMode_GM.Draw() which does similar thing to not #draw the rubberband line when the cursor is on the confirmation corner handler = self.o.mouse_event_handler if handler is not None and handler is self._ccinstance: self.update_cursor() return if self.endPoint2 is not None: if self.endPoint1: drawsphere(self.endPoint1_sphereColor, self.endPoint1, STARTPOINT_SPHERE_RADIUS, STARTPOINT_SPHERE_DRAWLEVEL, opacity=self.endPoint1_sphereOpacity) drawline(self.rubberband_line_color, self.endPoint1, self.endPoint2, width=self.rubberband_line_width, dashEnabled=True) self._drawSnapReferenceLines() if self._ok_to_render_cursor_text: self._drawCursorText()
def drawDihedralDimension(color, right, up, bpos, p0, p1, p2, p3, text, highlighted=False): # Draw a frame of lines that shows how the four atoms are connected # to the dihedral angle csys = CylindricalCoordinates(p1, p2 - p1, up, right) r1, theta1, z1 = csys.rtz(p0) r2, theta2, z2 = csys.rtz(p3) e0a = csys.xyz((r1, theta1, 0.5)) e1a = csys.xyz((r2, theta2, 0.5)) drawline(color, p1, p0) drawline(color, p0, e0a) drawline(color, p3, e1a) drawline(color, p2, p3) drawline(color, p1, p2) # Use the existing angle drawing routine to finish up drawAngleDimension(color, right, up, bpos, e0a, (p1 + p2) / 2, e1a, text, minR1=r1, minR2=r2, highlighted=highlighted)
def drawPeptideTrace(alphaCarbonProteinChunk): """ Draws a protein backbone trace using atoms stored in I{alphaCarbonProteinChunk}. @param alphaCarbonProteinChunk: a special (temporary) chunk that contains only the alpha carbon atoms in the peptide backbone @param alphaCarbonProteinChunk: Chunk @see PeptideLine_GraphicsMode.Draw_other(), PeptideGenerator.make_aligned() """ if alphaCarbonProteinChunk and alphaCarbonProteinChunk.atoms: last_pos = None atomitems = alphaCarbonProteinChunk.atoms.items() atomitems.sort() alphaCarbonAtomsList = [atom for (key, atom) in atomitems] for atom in alphaCarbonAtomsList: drawsphere(blue, atom.posn(), 0.2, 1) if last_pos: drawline(gray, last_pos, atom.posn(), width=2) last_pos = atom.posn() pass pass return
def draw(self): color = self.fix_color(self.color) end1, end2 = self.end1, self.end2 width = self.width dashed = self.dashed drawline(color[:3], end1, end2, width=width, dashEnabled=dashed) ###k dashEnabled untested here
def Draw_other(self): """ Do some custom drawing (in the model's abs coordsys), as well as whatever the superclass does. """ #print "start ExampleCommand2E Draw_other" super(ExampleCommand2E_GM, self).Draw_other() drawline(red, V(1, 0, 1), V(1, 1, 1), width=2) self.command._expr_instance.draw()
def Draw_other(self): """ Do some custom drawing (in the model's abs coordsys), as well as whatever the superclass does. """ #print "start ExampleCommand2E Draw_other" super(ExampleCommand2E_GM, self).Draw_other() drawline(red, V(1,0,1), V(1,1,1), width = 2) self.command._expr_instance.draw()
def Draw(self): """ Do some custom drawing (in the model's abs coordsys) after drawing the model. """ #print "start ExampleCommand2E Draw" glpane = self.glpane super(ExampleCommand2E_GM, self).Draw() drawline(red, V(1, 0, 1), V(1, 1, 1), width=2) self.command._expr_instance.draw()
def _draw_jig(self, glpane, color, highlighted=False): """ Draw a ESP Image jig as a plane with an edge and a bounding box. """ glPushMatrix() glTranslatef(self.center[0], self.center[1], self.center[2]) q = self.quat glRotatef(q.angle * 180.0 / math.pi, q.x, q.y, q.z) #bruce 060207 extensively revised texture code re fixing bug 1059 if self.tex_name is not None and self.image_obj: # self.image_obj condition is needed, for clear_esp_image() to work textureReady = True glBindTexture( GL_TEXTURE_2D, self.tex_name ) # maybe this belongs in draw_plane instead? Put it there later. ##e self._initTextureEnv() # sets texture params the way we want them else: textureReady = False drawPlane(self.fill_color, self.width, self.width, textureReady, self.opacity, SOLID=True, pickCheckOnly=self.pickCheckOnly) hw = self.width / 2.0 corners_pos = [ V(-hw, hw, 0.0), V(-hw, -hw, 0.0), V(hw, -hw, 0.0), V(hw, hw, 0.0) ] drawLineLoop(color, corners_pos) # Draw the ESP Image bbox. if self.show_esp_bbox: wo = self.image_offset eo = self.edge_offset drawwirecube(color, V(0.0, 0.0, 0.0), V(hw + eo, hw + eo, wo), 1.0) #drawwirebox # This is for debugging purposes. This draws a green normal vector using # local space coords. Mark 050930 if 0: from graphics.drawing.CS_draw_primitives import drawline drawline(green, V(0.0, 0.0, 0.0), V(0.0, 0.0, 1.0), 0, 3) glPopMatrix() # This is for debugging purposes. This draws a yellow normal vector using # model space coords. Mark 050930 if 0: from graphics.drawing.CS_draw_primitives import drawline from utilities.constants import yellow drawline(yellow, self.center, self.center + self.planeNorm, 0, 3)
def Draw(self): """ Do some custom drawing (in the model's abs coordsys) after drawing the model. """ #print "start ExampleCommand2E Draw" glpane = self.glpane super(ExampleCommand2E_GM, self).Draw() drawline(red, V(1,0,1), V(1,1,1), width = 2) self.command._expr_instance.draw()
def _draw_jig(self, glpane, color, highlighted = False): """ Draw an ESPImage jig (self) as a plane with an edge and a bounding box. @note: this is not called during graphicsMode.Draw_model as with most Jigs, but during graphicsMode.Draw_after_highlighting. """ glPushMatrix() glTranslatef( self.center[0], self.center[1], self.center[2]) q = self.quat glRotatef( q.angle*180.0/math.pi, q.x, q.y, q.z) #bruce 060207 extensively revised texture code re fixing bug 1059 if self.tex_name is not None and self.image_obj: # self.image_obj cond is needed, for clear_esp_image() to work textureReady = True glBindTexture(GL_TEXTURE_2D, self.tex_name) # review: maybe this belongs in draw_plane instead? self._initTextureEnv() # sets texture params the way we want them else: textureReady = False drawPlane(self.fill_color, self.width, self.width, textureReady, self.opacity, SOLID = True, pickCheckOnly = self.pickCheckOnly ) hw = self.width/2.0 corners_pos = [V(-hw, hw, 0.0), V(-hw, -hw, 0.0), V( hw, -hw, 0.0), V( hw, hw, 0.0)] drawLineLoop(color, corners_pos) # Draw the ESP Image bbox. if self.show_esp_bbox: wo = self.image_offset eo = self.edge_offset drawwirecube(color, V(0.0, 0.0, 0.0), V(hw + eo, hw + eo, wo), 1.0) #drawwirebox # This is for debugging purposes. This draws a green normal vector # using local space coords. [Mark 050930] if 0: from graphics.drawing.CS_draw_primitives import drawline drawline(green, V(0.0, 0.0, 0.0), V(0.0, 0.0, 1.0), 0, 3) glpane.kluge_reset_texture_mode_to_work_around_renderText_bug() glPopMatrix() # This is for debugging purposes. This draws a yellow normal vector # using model space coords. [Mark 050930] if 0: from graphics.drawing.CS_draw_primitives import drawline from utilities.constants import yellow drawline(yellow, self.center, self.center + self.planeNorm, 0, 3)
def Draw_other(self): """ """ _superclass_for_GM.Draw_other(self) if len(self.command.mouseClickPoints) >= 2: #Draw reference vector. drawline(env.prefs[DarkBackgroundContrastColor_prefs_key], self.command.mouseClickPoints[0], self.command.mouseClickPoints[1], width = 4, dashEnabled = True)
def draw(self): """ Draw two projections of the curve at the limits of the thickness that defines the crystal volume. The commented code is for debugging. [bruce 041214 adds comment: the code looks like it only draws one projection.] """ color = get_selCurve_color(self.selSense) pl = zip(self.ptlist[:-1],self.ptlist[1:]) for p in pl: drawline(color, p[0],p[1])
def Draw_other(self): """ """ _superclass_for_GM.Draw_other(self) if len(self.command.mouseClickPoints) >= 2: #Draw reference vector. drawline(env.prefs[DarkBackgroundContrastColor_prefs_key], self.command.mouseClickPoints[0], self.command.mouseClickPoints[1], width=4, dashEnabled=True)
def Draw_other(self): """ """ _superclass_for_GM.Draw_other(self) #This fixes NFR bug 2803 #Don't draw the Dna rubberband line if the cursor is over the confirmation #corner. But make sure to call superclass.Draw_other method before doing this #check because we need to draw the rest of the model in the graphics #mode!. @see: DnaLineMode_GM.Draw_other() which does similar thing to not #draw the rubberband line when the cursor is on the confirmation corner handler = self.o.mouse_event_handler if handler is not None and handler is self._ccinstance: ##### REVIEW: # # 1. This is probably incorrect in principle, as a way of # deciding what to draw. The mouse event handling methods # should set an attribute which directly specifies whether # the next call of Draw_other (or other Draw methods) # should draw the rubberband line or not. # (Or which affects the value of an access method, e.g. # something like self.should_draw_rubberband_lines().) # # 2. Why is update_cursor called here? Any call of update_cursor # inside a specific Draw method seems suspicious. # # 3. This needs refactoring to merge with common code in its # subclass DnaLineMode_GM, and to consider doing the same # thing in its other 3 subclasses. # # [bruce 090310 comments] self.update_cursor() return if self.endPoint2 is not None: if self.endPoint1: drawsphere(self.endPoint1_sphereColor, self.endPoint1, STARTPOINT_SPHERE_RADIUS, STARTPOINT_SPHERE_DRAWLEVEL, opacity = self.endPoint1_sphereOpacity ) drawline(env.prefs[DarkBackgroundContrastColor_prefs_key], self.endPoint1, self.endPoint2, width = self.rubberband_line_width, dashEnabled = True) self._drawSnapReferenceLines() if self._ok_to_render_cursor_text: self._drawCursorText()
def draw(self): """ Draw two projections of the curve at the limits of the thickness that defines the cookie volume. The commented code is for debugging. [bruce 041214 adds comment: the code looks like it only draws one projection.] """ color = get_selCurve_color(self.selSense) pl = zip(self.ptlist[:-1],self.ptlist[1:]) for p in pl: drawline(color, p[0],p[1])
def _draw_jig(self, glpane, color, highlighted = False): length = glpane.scale # approx. # print "%r got color = %r" % (self, color,) # it gets gray for atom in self.atoms: pos = atom.posn() drawline(color, pos, - glpane.pov, width = 2) # line from center of view, in case far off-screen # lines in diagonal directions (more likely to hit screen if off-screen) for direction in (glpane.up + glpane.right, glpane.right + glpane.down, glpane.down + glpane.left, glpane.left + glpane.up): endpoint = pos + direction * length drawline( color, pos, endpoint, width = 2) return
def _draw_jig(self, glpane, color, highlighted = False): length = glpane.scale # approx. # print "%r got color = %r" % (self, color,) # it gets gray for atom in self.atoms: pos = atom.posn() drawline(color, pos, - glpane.pov, width = 2) # line from center of view, in case far off-screen # lines in diagonal directions (more likely to hit screen if off-screen) for direction in (glpane.up + glpane.right, glpane.right + glpane.down, glpane.down + glpane.left, glpane.left + glpane.up): endpoint = pos + direction * length drawline( color, pos, endpoint, width = 2) return
def _bondDraw(self, color, p0, p1, carbonAt): if self.dispMode == "Tubes": drawcylinder(color, p0, p1, 0.2) else: if carbonAt < 0: drawsphere(color, p0, 0.5, 1) drawsphere(color, p1, 0.5, 1) elif carbonAt == 0: drawsphere(color, p0, 0.5, 1) drawsphere(color, p1, 0.2, 1) elif carbonAt == 1: drawsphere(color, p0, 0.2, 1) drawsphere(color, p1, 0.5, 1) drawline(white, p0, p1)
def _bondDraw(self, color, p0, p1, carbonAt): if self.dispMode == 'Tubes': drawcylinder(color, p0, p1, 0.2) else: if carbonAt < 0: drawsphere(color, p0, 0.5, 1) drawsphere(color, p1, 0.5, 1) elif carbonAt == 0: drawsphere(color, p0, 0.5, 1) drawsphere(color, p1, 0.2, 1) elif carbonAt == 1: drawsphere(color, p0, 0.2, 1) drawsphere(color, p1, 0.5, 1) drawline(white, p0, p1)
def xdraw(self): """ draw the actual grid of the matrix in 3-space. Used for debugging only. """ col = (0.0, 0.0, 0.0) dx = self.x/8.0 dy = self.y/8.0 for i in range(self.matrix.shape[0]): for j in range(self.matrix.shape[1]): if not self.matrix[i, j]: p = (V(i, j)+self.matbase)/8.0 p = p[0]*self.x + p[1]*self.y + self.z drawline(col, p, p + dx + dy) drawline(col, p + dx, p + dy)
def xdraw(self): """ draw the actual grid of the matrix in 3-space. Used for debugging only. """ col = (0.0, 0.0, 0.0) dx = self.x/8.0 dy = self.y/8.0 for i in range(self.matrix.shape[0]): for j in range(self.matrix.shape[1]): if not self.matrix[i, j]: p = (V(i, j)+self.matbase)/8.0 p = p[0]*self.x + p[1]*self.y + self.z drawline(col, p, p + dx + dy) drawline(col, p + dx, p + dy)
def draw_bondable_pairs(self): """ Draws bondable pairs of singlets and the bond lines between them. Singlets in the selected chunk(s) are colored green. Singlets in the unselected chunk(s) are colored blue. Singlets with more than one way to bond are colored magenta. """ # Color of bond lines -- bondline_color = get_selCurve_color(0,self.o.backgroundColor) for s1,s2 in self.command.bondable_pairs: color = (self.command.ways_of_bonding[s1.key] > 1) and magenta or green s1.overdraw_with_special_color(color) color = (self.command.ways_of_bonding[s2.key] > 1) and magenta or blue s2.overdraw_with_special_color(color) # Draw bond lines between singlets -- drawline(bondline_color, s1.posn(), s2.posn())
def _cellDraw(self, color, p0, p1): hasSinglet = False if type(p1) == type((1,)): v1 = p1[0] hasSinglet = True else: v1 = p1 if self.dispMode == 'Tubes': drawcylinder(color, p0, v1, 0.2) else: drawsphere(color, p0, 0.5, 1) if hasSinglet: drawsphere(color, v1, 0.2, 1) else: drawsphere(color, v1, 0.5, 1) drawline(white, p0, v1)
def _cellDraw(self, color, p0, p1): hasSinglet = False if type(p1) == type((1,)): v1 = p1[0] hasSinglet = True else: v1 = p1 if self.dispMode == "Tubes": drawcylinder(color, p0, v1, 0.2) else: drawsphere(color, p0, 0.5, 1) if hasSinglet: drawsphere(color, v1, 0.2, 1) else: drawsphere(color, v1, 0.5, 1) drawline(white, p0, v1)
def drawDihedralDimension(color, right, up, bpos, p0, p1, p2, p3, text, highlighted=False): # Draw a frame of lines that shows how the four atoms are connected # to the dihedral angle csys = CylindricalCoordinates(p1, p2 - p1, up, right) r1, theta1, z1 = csys.rtz(p0) r2, theta2, z2 = csys.rtz(p3) e0a = csys.xyz((r1, theta1, 0.5)) e1a = csys.xyz((r2, theta2, 0.5)) drawline(color, p1, p0) drawline(color, p0, e0a) drawline(color, p3, e1a) drawline(color, p2, p3) drawline(color, p1, p2) # Use the existing angle drawing routine to finish up drawAngleDimension( color, right, up, bpos, e0a, (p1 + p2) / 2, e1a, text, minR1=r1, minR2=r2, highlighted=highlighted )
def draw_debug_text(glpane, point, text): #bruce 080422, should refile """ """ from geometry.VQT import V from utilities.constants import white, red if point is None: point = - glpane.pov # todo: randomize offset using hash of text offset = glpane.right * glpane.scale / 2.0 + \ glpane.up * glpane.scale / 2.0 # todo: correct for aspect ratio, use min scale in each dimension offset2 = V( - offset[0], offset[1], 0.0 ) / 3.0 drawline( white, point, point + offset, width = 2) drawline( white, point - offset2, point + offset2 ) point_size = 12 drawtext( text, red, point + offset, point_size, glpane ) return
def draw_debug_text(glpane, point, text): #bruce 080422, should refile """ """ from geometry.VQT import V from utilities.constants import white, red if point is None: point = - glpane.pov # todo: randomize offset using hash of text offset = glpane.right * glpane.scale / 2.0 + \ glpane.up * glpane.scale / 2.0 # todo: correct for aspect ratio, use min scale in each dimension offset2 = V( - offset[0], offset[1], 0.0 ) / 3.0 drawline( white, point, point + offset, width = 2) drawline( white, point - offset2, point + offset2 ) point_size = 12 drawtext( text, red, point + offset, point_size, glpane ) return
def _draw_jig(self, glpane, color, highlighted = False): """ [overrides superclass method] """ # note: kluge: called directly from a specialized Chunk, not from self.draw! if self._should_draw(): sitepos = self.site_position() # or, should we assume the atom pos is up to date? yes, use that. ### FIX colors = [red, orange, yellow] for a in self.parent_atoms(): chunk = a.molecule dispdef = chunk.get_dispdef(glpane) disp, rad = a.howdraw(dispdef) if self.picked: rad *= 1.01 color = colors[0] drawwirecube(color, a.posn(), rad) # useful?? drawline( color, a.posn(), sitepos) # draw each atom in a different color (at least if there are no more than 3) colors = colors[1:] + [color] continue return
def _drawSnapReferenceLines(self): """ Draw the snap reference lines as dottedt lines. Example, if the moving end of the rubberband line is 'close enough' to a standard axis vector, that point is 'snapped' soi that it lies on the axis. When this is done, program draws a dotted line from origin to the endPoint2 indicating that the endpoint is snapped to that axis line. This method is called inside the self.Draw method. @see: self._snapEndPointToStandardAxis @see: self.Draw """ if self.endPoint2 is None: return if self._standardAxisVectorForDrawingSnapReference: drawline(blue, V(0, 0, 0), self.endPoint2, dashEnabled=True, stipleFactor=4, width=2)
def _drawSnapReferenceLines(self): """ Draw the snap reference lines as dottedt lines. Example, if the moving end of the rubberband line is 'close enough' to a standard axis vector, that point is 'snapped' soi that it lies on the axis. When this is done, program draws a dotted line from origin to the endPoint2 indicating that the endpoint is snapped to that axis line. This method is called inside the self.Draw method. @see: self._snapEndPointToStandardAxis @see: self.Draw """ if self.endPoint2 is None: return if self._standardAxisVectorForDrawingSnapReference: drawline(blue, V(0, 0, 0), self.endPoint2, dashEnabled = True, stipleFactor = 4, width = 2)
def _draw_jig(self, glpane, color, highlighted=False): """ [overrides superclass method] """ # note: kluge: called directly from a specialized Chunk, not from self.draw! if self._should_draw(): sitepos = self.site_position( ) # or, should we assume the atom pos is up to date? yes, use that. ### FIX colors = [red, orange, yellow] for a in self.parent_atoms(): chunk = a.molecule dispdef = chunk.get_dispdef(glpane) disp, rad = a.howdraw(dispdef) if self.picked: rad *= 1.01 color = colors[0] drawwirecube(color, a.posn(), rad) # useful?? drawline(color, a.posn(), sitepos) # draw each atom in a different color (at least if there are no more than 3) colors = colors[1:] + [color] continue return
def drawSequence(seq, tfm=tfmgen(i)): if len(seq) == 0: return # a space character has an empty sequence if type(seq[0][0]) is not types.IntType: # handle multi-stroke characters for x in seq: drawSequence(x) return seq = map(lambda tpl: apply(tfm,tpl), seq) for i in range(len(seq) - 1): pos1, pos2 = seq[i], seq[i+1] if self.glBegin: # This is what we do for grid planes, where "somebody" # is drawGPGrid in drawers.py. # Somebody has already taken care of glBegin(GL_LINES). # TODO: explain this in docstring. glVertex(pos1[0], pos1[1], pos1[2]) glVertex(pos2[0], pos2[1], pos2[2]) # Somebody has already taken care of glEnd(). else: # This is what we do for dimensions. drawline(color, seq[i], seq[i+1])
def drawSequence(seq, tfm=tfmgen(i)): if len(seq) == 0: return # a space character has an empty sequence if type(seq[0][0]) is not types.IntType: # handle multi-stroke characters for x in seq: drawSequence(x) return seq = map(lambda tpl: apply(tfm, tpl), seq) for i in range(len(seq) - 1): pos1, pos2 = seq[i], seq[i + 1] if self.glBegin: # This is what we do for grid planes, where "somebody" # is drawGPGrid in drawers.py. # Somebody has already taken care of glBegin(GL_LINES). # TODO: explain this in docstring. glVertex(pos1[0], pos1[1], pos1[2]) glVertex(pos2[0], pos2[1], pos2[2]) # Somebody has already taken care of glEnd(). else: # This is what we do for dimensions. drawline(color, seq[i], seq[i + 1])
def Draw(self): """ Draw method for this temporary mode. """ _superclass_for_GM.Draw(self) #This fixes NFR bug 2803 #Don't draw the Dna rubberband line if the cursor is over the confirmation #corner. But make sure to call superclass.Draw method before doing this #check because we need to draw the rest of the model in the graphics #mode!. @see: DnaLineMode_GM.Draw() which does similar thing to not #draw the rubberband line when the cursor is on the confirmation corner handler = self.o.mouse_event_handler if handler is not None and handler is self._ccinstance: self.update_cursor() return if self.endPoint2 is not None: if self.endPoint1: drawsphere(self.endPoint1_sphereColor, self.endPoint1, STARTPOINT_SPHERE_RADIUS, STARTPOINT_SPHERE_DRAWLEVEL, opacity = self.endPoint1_sphereOpacity ) drawline(self.rubberband_line_color, self.endPoint1, self.endPoint2, width = self.rubberband_line_width, dashEnabled = True) self._drawSnapReferenceLines() if self._ok_to_render_cursor_text: self._drawCursorText()
def drawLinearDimension(color, # what color are we drawing this in right, up, # screen directions mapped to xyz coords bpos, # position of the handle for moving the text p0, p1, # positions of the ends of the dimension text, highlighted=False): outOfScreen = cross(right, up) bdiff = bpos - 0.5 * (p0 + p1) csys = CylindricalCoordinates(p0, p1 - p0, bdiff, right) # This works OK until we want to keep the text right side up, then the # criterion for right-side-up-ness changes because we've changed 'up'. br, bt, bz = csys.rtz(bpos) e0 = csys.xyz((br + 0.5, 0, 0)) e1 = csys.xyz((br + 0.5, 0, 1)) drawline(color, p0, e0) drawline(color, p1, e1) v0 = csys.xyz((br, 0, 0)) v1 = csys.xyz((br, 0, 1)) if highlighted: drawline(color, v0, v1, width=THICKLINEWIDTH) else: drawline(color, v0, v1) # draw arrowheads at the ends a1, a2 = 0.25, 1.0 * csys.zinv arrow00 = csys.xyz((br + a1, 0, a2)) arrow01 = csys.xyz((br - a1, 0, a2)) drawline(color, v0, arrow00) drawline(color, v0, arrow01) arrow10 = csys.xyz((br + a1, 0, 1-a2)) arrow11 = csys.xyz((br - a1, 0, 1-a2)) drawline(color, v1, arrow10) drawline(color, v1, arrow11) # draw the text for the numerical measurement, make # sure it goes from left to right xflip = dot(csys.z, right) < 0 # then make sure it's right side up theoreticalRight = (xflip and -csys.z) or csys.z theoreticalOutOfScreen = cross(theoreticalRight, bdiff) yflip = dot(theoreticalOutOfScreen, outOfScreen) < 0 if debug_flags.atom_debug: print "DEBUG INFO FROM drawLinearDimension" print csys print theoreticalRight, theoreticalOutOfScreen print xflip, yflip if yflip: def fx(y): return br + 1.5 - y / (1. * HEIGHT) else: def fx(y): return br + 0.5 + y / (1. * HEIGHT) if xflip: def fz(x): return 0.9 - csys.zinv * x / (1. * WIDTH) else: def fz(x): return 0.1 + csys.zinv * x / (1. * WIDTH) def tfm(x, y, fx=fx, fz=fz): return csys.xyz((fx(y), 0, fz(x))) f3d = Font3D() f3d.drawString(text, tfm=tfm, color=color)
def drawAngleDimension(color, right, up, bpos, p0, p1, p2, text, minR1=0.0, minR2=0.0, highlighted=False): z = cross(p0 - p1, p2 - p1) try: csys = CylindricalCoordinates(p1, z, up, right) except ZeroLengthCylinder: len0 = vlen(p1 - p0) len2 = vlen(p1 - p2) # make sure it's really a zero-degree angle assert len0 > 1.0e-6 assert len2 > 1.0e-6 assert vlen(cross(p1 - p2, p1 - p0)) < 1.0e-6 # For an angle of zero degrees, there is no correct way to # orient the text, so just draw a line segment if len0 > len2: L = len0 end = p0 else: L = len2 end = p2 Lb = vlen(bpos - p1) if Lb > L: L = Lb end = p1 + (Lb / L) * (end - p1) drawline(color, p1, end) return br, bt, bz = csys.rtz(bpos) theta1 = csys.rtz(p0)[1] theta2 = csys.rtz(p2)[1] if theta2 < theta1 - math.pi: theta2 += 2 * math.pi elif theta2 > theta1 + math.pi: theta2 -= 2 * math.pi if theta2 < theta1: theta1, theta2 = theta2, theta1 e0 = csys.xyz((max(vlen(p0 - p1), br, minR1) + 0.5, theta1, 0)) e1 = csys.xyz((max(vlen(p2 - p1), br, minR2) + 0.5, theta2, 0)) drawline(color, p1, e0) drawline(color, p1, e1) if highlighted: csys.drawArc(color, br, theta1, theta2, 0, width=THICKLINEWIDTH) else: csys.drawArc(color, br, theta1, theta2, 0) # draw some arrowheads e00 = csys.xyz((br, theta1, 0)) e10 = csys.xyz((br, theta2, 0)) dr = 0.25 dtheta = 1 / br e0a = csys.xyz((br + dr, theta1 + dtheta, 0)) e0b = csys.xyz((br - dr, theta1 + dtheta, 0)) e1a = csys.xyz((br + dr, theta2 - dtheta, 0)) e1b = csys.xyz((br - dr, theta2 - dtheta, 0)) drawline(color, e00, e0a) drawline(color, e00, e0b) drawline(color, e10, e1a) drawline(color, e10, e1b) midangle = (theta1 + theta2) / 2 tmidpoint = csys.xyz((br + 0.5, midangle, 0)) h = 1.0e-3 textx = norm(csys.xyz((br + 0.5, midangle + h, 0)) - tmidpoint) texty = norm(csys.xyz((br + 0.5 + h, midangle, 0)) - tmidpoint) # make sure the text runs from left to right if dot(textx, right) < 0: textx = -textx # make sure the text isn't upside-down outOfScreen = cross(right, up) textForward = cross(textx, texty) if dot(outOfScreen, textForward) < 0: tmidpoint = csys.xyz((br + 1.5, midangle, 0)) texty = -texty textxyz = tmidpoint - (0.5 * len(text)) * textx def tfm(x, y): x = (x / (1. * WIDTH)) * textx y = (y / (1. * HEIGHT)) * texty return textxyz + x + y f3d = Font3D() f3d.drawString(text, tfm=tfm, color=color)
def drawNanotubeLadder(endCenter1, endCenter2, cntRise, glpaneScale, lineOfSightVector, ladderWidth = 6.8, # default diameter for 5x5 CNT beamThickness = 2.0, beam1Color = None, beam2Color = None, stepColor = None ): """ Draws the CNT in a ladder display. @param endCenter1: Nanotube center at end 1 @type endCenter1: B{V} @param endCenter2: Nanotube center at end 2 @type endCenter2: B{V} @param cntRise: Center to center distance between consecutive steps @type cntRise: 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 ladderWidth: width of the ladder @type ladderWidth: float @param beamThickness: Thickness of the two ladder beams @type beamThickness: float @param beam1Color: Color of beam1 @param beam2Color: Color of beam2 @see: B{DnaLineMode.Draw } (where it is used) for comments on color convention """ ladderLength = vlen(endCenter1 - endCenter2) # Don't draw the vertical line (step) passing through the startpoint unless # the ladderLength is atleast equal to the cntRise. # i.e. do the drawing only when there are atleast two ladder steps. # This prevents a 'revolving line' effect due to the single ladder step at # the first endpoint if ladderLength < cntRise: return unitVector = norm(endCenter2 - endCenter1) if beam1Color is None: beam1Color = env.prefs[DarkBackgroundContrastColor_prefs_key] if beam2Color is None: beam2Color = env.prefs[DarkBackgroundContrastColor_prefs_key] if stepColor is None: stepColor = env.prefs[DarkBackgroundContrastColor_prefs_key] glDisable(GL_LIGHTING) glPushMatrix() glTranslatef(endCenter1[0], endCenter1[1], endCenter1[2]) pointOnAxis = V(0, 0, 0) vectorAlongLadderStep = cross(-lineOfSightVector, unitVector) unitVectorAlongLadderStep = norm(vectorAlongLadderStep) ladderBeam1Point = pointOnAxis + \ unitVectorAlongLadderStep * 0.5 * ladderWidth ladderBeam2Point = pointOnAxis - \ unitVectorAlongLadderStep * 0.5 * ladderWidth # Following limits the arrowHead Size to the given value. When you zoom out, # the rest of ladder drawing becomes smaller (expected) and the following # check ensures that the arrowheads are drawn proportinately. (Not using a # 'constant' to do this as using glpaneScale gives better results) if glpaneScale > 40: arrowDrawingScale = 40 else: arrowDrawingScale = glpaneScale x = 0.0 while x < ladderLength: drawPoint(stepColor, pointOnAxis) drawCircle(stepColor, pointOnAxis, ladderWidth * 0.5, unitVector) previousPoint = pointOnAxis previousLadderBeam1Point = ladderBeam1Point previousLadderBeam2Point = ladderBeam2Point pointOnAxis = pointOnAxis + unitVector * cntRise x += cntRise ladderBeam1Point = previousPoint + \ unitVectorAlongLadderStep * 0.5 * ladderWidth ladderBeam2Point = previousPoint - \ unitVectorAlongLadderStep * 0.5 * ladderWidth if previousLadderBeam1Point: drawline(beam1Color, previousLadderBeam1Point, ladderBeam1Point, width = beamThickness, isSmooth = True ) drawline(beam2Color, previousLadderBeam2Point, ladderBeam2Point, width = beamThickness, isSmooth = True ) #drawline(stepColor, ladderBeam1Point, ladderBeam2Point) glPopMatrix() glEnable(GL_LIGHTING)
def _DEBUG_draw_avg_centerpairs_of_potential_crossovers(self): pairs = self._crossoverSite_marker.get_avg_center_pairs_of_potential_crossovers for pair in pairs: drawline(yellow, pair[0], pair[1], width=2)
def drawchunk(self, glpane, chunk, memo, highlighted): """ Draws reduced representation of a protein chunk. """ structure, total_length, ca_list, n_sec = memo style = self.proteinStyle scaleFactor = self.proteinStyleScaleFactor resolution = self.proteinStyleQuality scaling = self.proteinStyleScaling smooth = self.proteinStyleSmooth gleSetJoinStyle(TUBE_JN_ANGLE | TUBE_NORM_PATH_EDGE | TUBE_JN_CAP | TUBE_CONTOUR_CLOSED ) current_sec = 0 for sec, secondary in structure: # Number of atoms in SS element including dummy atoms. n_atoms = len(sec) # The length should be at least 3. if n_atoms >= 3: # Alpha carbon trace styles. Simple but fast. if style == PROTEIN_STYLE_CA_WIRE or \ style == PROTEIN_STYLE_CA_CYLINDER or \ style == PROTEIN_STYLE_CA_BALL_STICK: for n in range( 1, n_atoms-2 ): pos0, ss0, aa0, idx0, dpos0, cbpos0 = sec[n - 1] pos1, ss1, aa1, idx1, dpos1, cbpos1 = sec[n] pos2, ss2, aa2, idx2, dpos2, cbpos2 = sec[n + 1] color = self._get_aa_color(chunk, idx1, total_length, ss1, aa1, current_sec, n_sec) if style == PROTEIN_STYLE_CA_WIRE: if pos0: drawline(color, pos1 + 0.5 * (pos0 - pos1), pos1, width=5, isSmooth=True) if pos2: drawline(color, pos1, pos1 + 0.5 * (pos2 - pos1), width=5, isSmooth=True) else: if pos0: drawcylinder(color, pos1 + 0.5 * (pos0 - pos1), pos1, 0.25 * scaleFactor, capped=1) if style == PROTEIN_STYLE_CA_BALL_STICK: drawsphere(color, pos1, 0.5 * scaleFactor, 2) else: drawsphere(color, pos1, 0.25 * scaleFactor, 2) if pos2: drawcylinder(color, pos1, pos1 + 0.5 * (pos2 - pos1), 0.25 * scaleFactor, capped=1) elif style == PROTEIN_STYLE_PEPTIDE_TILES: for n in range( 1, n_atoms-2 ): pos0, ss0, aa0, idx0, dpos0, cbpos0 = sec[n - 1] pos1, ss1, aa1, idx1, dpos1, cbpos1 = sec[n] color = self._get_aa_color(chunk, idx1, total_length, ss1, aa1, current_sec, n_sec) tri = [] nor = [] col = [] elif style == PROTEIN_STYLE_TUBE or \ style == PROTEIN_STYLE_LADDER or \ style == PROTEIN_STYLE_ZIGZAG or \ style == PROTEIN_STYLE_FLAT_RIBBON or \ style == PROTEIN_STYLE_SOLID_RIBBON or \ style == PROTEIN_STYLE_SIMPLE_CARTOONS or \ style == PROTEIN_STYLE_FANCY_CARTOONS: tube_pos = [] tube_col = [] tube_rad = [] tube_dpos = [] for n in range( 2, n_atoms-2 ): pos00, ss00, a00, idx00, dpos00, cbpos00 = sec[n - 2] pos0, ss0, aa0, idx0, dpos0, cbpos0 = sec[n - 1] pos1, ss1, aa1, idx1, dpos1, cbpos1 = sec[n] pos2, ss2, aa2, idx2, dpos2, cbpos2 = sec[n + 1] pos22, ss22, aa22, idx22, dpos22, cbpos22 = sec[n + 2] color = self._get_aa_color(chunk, idx1, total_length, ss1, aa1, current_sec, n_sec) rad = 0.25 * scaleFactor if style == PROTEIN_STYLE_TUBE and \ scaling == 1: if secondary > 0: rad *= 2.0 if n == 2: if pos0: tube_pos.append(pos00) tube_col.append(V(color)) tube_rad.append(rad) tube_dpos.append(dpos1) tube_pos.append(pos0) tube_col.append(V(color)) tube_rad.append(rad) tube_dpos.append(dpos1) if style == PROTEIN_STYLE_LADDER: drawcylinder(color, pos1, cbpos1, rad * 0.75) drawsphere(color, cbpos1, rad * 1.5, 2) if pos1: tube_pos.append(pos1) tube_col.append(V(color)) tube_rad.append(rad) tube_dpos.append(dpos1) if n == n_atoms - 3: if pos2: tube_pos.append(pos2) tube_col.append(V(color)) tube_rad.append(rad) tube_dpos.append(dpos1) tube_pos.append(pos22) tube_col.append(V(color)) tube_rad.append(rad) tube_dpos.append(dpos1) # For smoothed helices we need to add virtual atoms # located approximately at the centers of peptide bonds # but slightly moved away from the helix axis. new_tube_pos = [] new_tube_col = [] new_tube_rad = [] new_tube_dpos = [] if smooth and \ secondary == 1: for p in range(len(tube_pos)): new_tube_pos.append(tube_pos[p]) new_tube_col.append(tube_col[p]) new_tube_rad.append(tube_rad[p]) new_tube_dpos.append(tube_dpos[p]) if p > 1 and p < len(tube_pos) - 3: pv = tube_pos[p-1] - tube_pos[p] nv = tube_pos[p+2] - tube_pos[p+1] mi = 0.5 * (tube_pos[p+1] + tube_pos[p]) # The coefficient below was handpicked to make # the helices approximately round. mi -= 0.75 * norm(nv+pv) new_tube_pos.append(mi) new_tube_col.append(0.5*(tube_col[p]+tube_col[p+1])) new_tube_rad.append(0.5*(tube_rad[p]+tube_rad[p+1])) new_tube_dpos.append(0.5*(tube_dpos[p]+tube_dpos[p+1])) tube_pos = new_tube_pos tube_col = new_tube_col tube_rad = new_tube_rad tube_dpos = new_tube_dpos if secondary != 1 or \ style != PROTEIN_STYLE_SIMPLE_CARTOONS: tube_pos, tube_col, tube_rad, tube_dpos = make_tube( tube_pos, tube_col, tube_rad, tube_dpos, resolution=resolution) if style == PROTEIN_STYLE_ZIGZAG or \ style == PROTEIN_STYLE_FLAT_RIBBON or \ style == PROTEIN_STYLE_SOLID_RIBBON or \ style == PROTEIN_STYLE_SIMPLE_CARTOONS or \ style == PROTEIN_STYLE_FANCY_CARTOONS: last_pos = None last_width = 1.0 reset = False # Find SS element widths and determine width increment. if secondary == 0: # Coils have a constant width. width = scaleFactor * 0.1 dw = 0.0 elif secondary == 1: # Helices expand and shrink at the ends. width = scaleFactor * 0.1 dw = (1.0 * scaleFactor) / (resolution - 3) else: # Strands just shrink at the C-terminal end. width = scaleFactor * 1.0 dw = (1.6 * scaleFactor) / (1.5 * resolution - 3) if style == PROTEIN_STYLE_FLAT_RIBBON or \ style == PROTEIN_STYLE_SOLID_RIBBON or \ style == PROTEIN_STYLE_SIMPLE_CARTOONS or \ style == PROTEIN_STYLE_FANCY_CARTOONS: tri_arr0 = [] nor_arr0 = [] col_arr0 = [] if style == PROTEIN_STYLE_SOLID_RIBBON or \ style == PROTEIN_STYLE_SIMPLE_CARTOONS or \ style == PROTEIN_STYLE_FANCY_CARTOONS: tri_arr1 = [] nor_arr1 = [] col_arr1 = [] tri_arr2 = [] nor_arr2 = [] col_arr2 = [] tri_arr3 = [] nor_arr3 = [] col_arr3 = [] from copy import copy new_tube_dpos = copy(tube_dpos) for n in range(1, len(tube_pos)-1): pos = tube_pos[n] col = tube_col[n][0] col2 = tube_col[n+1][0] if last_pos: next_pos = tube_pos[n+1] dpos1 = last_width * tube_dpos[n-1] dpos2 = width * tube_dpos[n] ddpos = dpos1-dpos2 if reset: dpos1 = dpos2 reset = False if self.proteinStyle == PROTEIN_STYLE_ZIGZAG: drawline(col, last_pos-dpos1, pos-dpos2, width=3) drawline(col, last_pos+dpos1, pos+dpos2, width=3) drawline(col, last_pos-dpos1, pos+dpos2, width=1) drawline(col, pos-dpos2, pos+dpos2, width=1) drawline(col, last_pos-dpos1, last_pos+dpos1, width=1) if self.proteinStyle == PROTEIN_STYLE_FLAT_RIBBON: if pos != last_pos: nvec1 = norm(cross(dpos1, pos-last_pos)) if next_pos != pos: nvec2 = norm(cross(dpos2, next_pos-pos)) else: nvec2 = nvec1 nor_arr0.append(nvec1) nor_arr0.append(nvec1) nor_arr0.append(nvec2) nor_arr0.append(nvec2) tri_arr0.append(last_pos-dpos1) tri_arr0.append(last_pos+dpos1) tri_arr0.append(pos-dpos2) tri_arr0.append(pos+dpos2) col_arr0.append(col) col_arr0.append(col) col_arr0.append(col2) col_arr0.append(col2) if self.proteinStyle == PROTEIN_STYLE_SOLID_RIBBON or \ self.proteinStyle == PROTEIN_STYLE_SIMPLE_CARTOONS or \ self.proteinStyle == PROTEIN_STYLE_FANCY_CARTOONS: if secondary > 0: col3 = col4 = V(gray) if pos != last_pos: nvec1 = norm(cross(dpos1, pos-last_pos)) if next_pos != pos: nvec2 = norm(cross(dpos2, next_pos-pos)) else: nvec2 = nvec1 nor_arr0.append(nvec1) nor_arr0.append(nvec1) nor_arr0.append(nvec2) nor_arr0.append(nvec2) if self.proteinStyle == PROTEIN_STYLE_FANCY_CARTOONS: dn1 = 0.15 * nvec1 * scaleFactor dn2 = 0.15 * nvec2 * scaleFactor else: dn1 = 0.15 * nvec1 * scaleFactor dn2 = 0.15 * nvec2 * scaleFactor tri_arr0.append(last_pos - dpos1 - dn1) tri_arr0.append(last_pos + dpos1 - dn1) tri_arr0.append(pos - dpos2 - dn2) tri_arr0.append(pos + dpos2 - dn2) col_arr0.append(col) col_arr0.append(col) col_arr0.append(col2) col_arr0.append(col2) nor_arr1.append(nvec1) nor_arr1.append(nvec1) nor_arr1.append(nvec2) nor_arr1.append(nvec2) tri_arr1.append(last_pos - dpos1 + dn1) tri_arr1.append(last_pos + dpos1 + dn1) tri_arr1.append(pos - dpos2 + dn2) tri_arr1.append(pos + dpos2 + dn2) if secondary == 1: col_arr1.append(0.5 * col + 0.5 * V(white)) col_arr1.append(0.5 * col + 0.5 * V(white)) col_arr1.append(0.5 * col2 + 0.5 * V(white)) col_arr1.append(0.5 * col2 + 0.5 * V(white)) else: col_arr1.append(col) col_arr1.append(col) col_arr1.append(col2) col_arr1.append(col2) nor_arr2.append(-dpos1) nor_arr2.append(-dpos1) nor_arr2.append(-dpos2) nor_arr2.append(-dpos2) tri_arr2.append(last_pos - dpos1 - dn1) tri_arr2.append(last_pos - dpos1 + dn1) tri_arr2.append(pos - dpos2 - dn2) tri_arr2.append(pos - dpos2 + dn2) col_arr2.append(col3) col_arr2.append(col3) col_arr2.append(col4) col_arr2.append(col4) nor_arr3.append(-dpos1) nor_arr3.append(-dpos1) nor_arr3.append(-dpos2) nor_arr3.append(-dpos2) tri_arr3.append(last_pos + dpos1 - dn1) tri_arr3.append(last_pos + dpos1 + dn1) tri_arr3.append(pos + dpos2 - dn2) tri_arr3.append(pos + dpos2 + dn2) col_arr3.append(col3) col_arr3.append(col3) col_arr3.append(col4) col_arr3.append(col4) last_pos = pos last_width = width if secondary == 1: if n > len(tube_pos) - resolution: width -= dw elif width < 1.0 * scaleFactor: width += dw if secondary == 2: if n == len(tube_pos) - 1.5 * resolution: width = scaleFactor * 1.6 reset = True if n > len(tube_pos) - 1.5 * resolution: width -= dw new_tube_dpos[n] = width * tube_dpos[n] ###drawcylinder(white, tube_pos[0], tube_pos[10], 1.0) if self.proteinStyle == PROTEIN_STYLE_FLAT_RIBBON: drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr0, nor_arr0, col_arr0) if self.proteinStyle == PROTEIN_STYLE_SOLID_RIBBON or \ self.proteinStyle == PROTEIN_STYLE_SIMPLE_CARTOONS or \ self.proteinStyle == PROTEIN_STYLE_FANCY_CARTOONS: if secondary == 0: drawpolycone_multicolor([0,0,0,-2], tube_pos, tube_col, tube_rad) else: if (secondary == 1 and self.proteinStyle == PROTEIN_STYLE_SOLID_RIBBON) or \ secondary == 2: drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr0, nor_arr0, col_arr0) drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr1, nor_arr1, col_arr1) drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr2, nor_arr2, col_arr2) drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr3, nor_arr3, col_arr3) # Fill in the strand N-terminal end. quad_tri = [] quad_nor = [] quad_col = [] quad_tri.append(tri_arr2[0]) quad_tri.append(tri_arr3[0]) quad_tri.append(tri_arr2[1]) quad_tri.append(tri_arr3[1]) quad_nor.append(nor_arr2[0]) quad_nor.append(nor_arr3[0]) quad_nor.append(nor_arr2[1]) quad_nor.append(nor_arr3[1]) quad_col.append(col_arr2[0]) quad_col.append(col_arr3[0]) quad_col.append(col_arr2[1]) quad_col.append(col_arr3[1]) drawtriangle_strip([1.0,1.0,1.0,-2.0],quad_tri,quad_nor,quad_col) if (secondary == 1 and self.proteinStyle == PROTEIN_STYLE_FANCY_CARTOONS): drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr0, nor_arr0, col_arr0) drawtriangle_strip([1.0,1.0,0.0,-2.0], tri_arr1, nor_arr1, col_arr1) tube_pos_left = [] tube_pos_right = [] new_tube_dpos[0] *= 0.1 new_tube_dpos[1] *= 0.2 new_tube_dpos[-1] *= 0.1 new_tube_dpos[-2] *= 0.2 for p in range(len(tube_pos)): tube_pos_left.append(tube_pos[p] - new_tube_dpos[p]) tube_pos_right.append(tube_pos[p] + new_tube_dpos[p]) tube_rad[p] *= 0.75 drawpolycone_multicolor([0,0,0,-2], tube_pos_left, tube_col, tube_rad) drawpolycone_multicolor([0,0,0,-2], tube_pos_right, tube_col, tube_rad) # else: if (secondary == 1 and style == PROTEIN_STYLE_SIMPLE_CARTOONS): drawcylinder(tube_col[0][0], tube_pos[1], tube_pos[-3], 2.5, capped=1) #print "hopsa" if style == PROTEIN_STYLE_LADDER or \ style == PROTEIN_STYLE_TUBE: # Draw tube. drawpolycone_multicolor([0,0,0,-2], tube_pos, tube_col, tube_rad) # increase Sec. Str. element counter current_sec += 1
def drawLinearDimension( color, # what color are we drawing this in right, up, # screen directions mapped to xyz coords bpos, # position of the handle for moving the text p0, p1, # positions of the ends of the dimension text, highlighted=False): outOfScreen = cross(right, up) bdiff = bpos - 0.5 * (p0 + p1) csys = CylindricalCoordinates(p0, p1 - p0, bdiff, right) # This works OK until we want to keep the text right side up, then the # criterion for right-side-up-ness changes because we've changed 'up'. br, bt, bz = csys.rtz(bpos) e0 = csys.xyz((br + 0.5, 0, 0)) e1 = csys.xyz((br + 0.5, 0, 1)) drawline(color, p0, e0) drawline(color, p1, e1) v0 = csys.xyz((br, 0, 0)) v1 = csys.xyz((br, 0, 1)) if highlighted: drawline(color, v0, v1, width=THICKLINEWIDTH) else: drawline(color, v0, v1) # draw arrowheads at the ends a1, a2 = 0.25, 1.0 * csys.zinv arrow00 = csys.xyz((br + a1, 0, a2)) arrow01 = csys.xyz((br - a1, 0, a2)) drawline(color, v0, arrow00) drawline(color, v0, arrow01) arrow10 = csys.xyz((br + a1, 0, 1 - a2)) arrow11 = csys.xyz((br - a1, 0, 1 - a2)) drawline(color, v1, arrow10) drawline(color, v1, arrow11) # draw the text for the numerical measurement, make # sure it goes from left to right xflip = dot(csys.z, right) < 0 # then make sure it's right side up theoreticalRight = (xflip and -csys.z) or csys.z theoreticalOutOfScreen = cross(theoreticalRight, bdiff) yflip = dot(theoreticalOutOfScreen, outOfScreen) < 0 if debug_flags.atom_debug: print "DEBUG INFO FROM drawLinearDimension" print csys print theoreticalRight, theoreticalOutOfScreen print xflip, yflip if yflip: def fx(y): return br + 1.5 - y / (1. * HEIGHT) else: def fx(y): return br + 0.5 + y / (1. * HEIGHT) if xflip: def fz(x): return 0.9 - csys.zinv * x / (1. * WIDTH) else: def fz(x): return 0.1 + csys.zinv * x / (1. * WIDTH) def tfm(x, y, fx=fx, fz=fz): return csys.xyz((fx(y), 0, fz(x))) f3d = Font3D() f3d.drawString(text, tfm=tfm, color=color)
def drawLine(self, color, rtz1, rtz2, width=1): drawline(color, self.xyz(rtz1), self.xyz(rtz2), width=width)
def 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 = None, ribbon1_direction = None, peakDeviationFromCenter = 9.5, ribbonThickness = 2.0, ribbon1Color = None, stepColor = None): """ @see: drawDnaRibbons (method in this file) @see: DnaStrand_GraphicsMode._drawHandles() """ if 0: # debug code, useful to see where the argument points are located # [bruce 080422] draw_debug_text(glpane, endCenter1, "endCenter1") draw_debug_text(glpane, endCenter2, "endCenter2") draw_debug_text(glpane, ribbon1_start_point, "ribbon1_start_point") #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 if stepColor is None: stepColor = env.prefs[DarkBackgroundContrastColor_prefs_key] 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. It also means the dna duplex axis can be determined # below from the two endpoints. if ribbonLength < duplexRise: return unitVectorAlongLength = norm(endCenter2 - endCenter1) glDisable(GL_LIGHTING) ##glPushMatrix() ##glTranslatef(endCenter1[0], endCenter1[1], endCenter1[2]) ##pointOnAxis = V(0, 0, 0) pointOnAxis = endCenter1 axial_shift = V(0.0, 0.0, 0.0) # might be changed below # [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 if ribbon1_start_point is not None: # [revise the meaning of these values to give the coordinate system # with the right phase in which to draw the ribbon. # bruce 080422 bugfix] vectorAlongLadderStep0 = ribbon1_start_point - endCenter1 # note: this might not be perpendicular to duplex axis. # fix by subtracting off the parallel component. # but add the difference back to every point below. vectorAlongLadderStep = vectorAlongLadderStep0 - \ dot( unitVectorAlongLength, vectorAlongLadderStep0 ) * unitVectorAlongLength axial_shift = (vectorAlongLadderStep0 - vectorAlongLadderStep) # note: even using this, there is still a small glitch in the # location of the first drawn sphere vs. the ribbon point... don't # know why. [bruce 080422] unitVectorAlongLadderStep = norm(vectorAlongLadderStep) unitDepthVector = cross(unitVectorAlongLength, unitVectorAlongLadderStep) ## * -1 pass del vectorAlongLadderStep ###=== #Following limits the arrowHead Size to the given value. When you zoom out, #the rest of ladder drawing becomes smaller (expected) and the following #check ensures that the arrowheads are drawn proportionately. # (Not using a 'constant' to do this as using glpaneScale gives better #results) if glpaneScale > 40: arrowDrawingScale = 40 else: arrowDrawingScale = glpaneScale #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. x = 0.0 T = duplexRise * basesPerTurn # The 'Period' of the sine wave # (i.e. peak to peak distance between consecutive crests) numberOfBasesDrawn = 0 theta_offset = 0 ## phase_angle_ribbon_1 = HALF_PI ## theta_ribbon_1 = (TWICE_PI * x / T) + phase_angle_ribbon_1 #Initialize ribbon1_point # [note: might not be needed, since identical to first point # computed during loop, but present code uses it to initialize # previous_ribbon1_point during loop [bruce 080422 comment]] ribbon1_point = _compute_ribbon_point(pointOnAxis + axial_shift, basesPerTurn, duplexRise, unitVectorAlongLength, unitVectorAlongLadderStep, unitDepthVector, peakDeviationFromCenter, numberOfBasesDrawn, theta_offset ) while x < ribbonLength: #Draw the axis point. drawPoint(stepColor, pointOnAxis) previousPointOnAxis = pointOnAxis previous_ribbon1_point = ribbon1_point ribbon1_point = _compute_ribbon_point(pointOnAxis + axial_shift, basesPerTurn, duplexRise, unitVectorAlongLength, unitVectorAlongLadderStep, unitDepthVector, peakDeviationFromCenter, numberOfBasesDrawn, theta_offset ) if x == duplexRise and ribbon1_direction == -1: # For ribbon_2 we need to draw an arrow head for y at x = 0. # To do this, we need the 'next ribbon_2' point in order to # compute the appropriate vectors. So when x = duplexRise, the # previous_ribbon2_point is nothing but y at x = 0. arrowLengthVector2 = norm(ribbon1_point - previous_ribbon1_point ) arrowHeightVector2 = cross(-lineOfSightVector, arrowLengthVector2) drawArrowHead( ribbon1Color, previous_ribbon1_point, arrowDrawingScale, -arrowHeightVector2, -arrowLengthVector2) # Draw sphere over previous_ribbon1_point and not ribbon1_point. # This is so we don't draw a sphere over the last point on ribbon1 # (instead, it is drawn as an arrowhead after the while loop). drawsphere(ribbon1Color, previous_ribbon1_point, SPHERE_RADIUS, SPHERE_DRAWLEVEL, opacity = SPHERE_OPACITY) drawline(stepColor, pointOnAxis, ribbon1_point) #Increment the pointOnAxis and x pointOnAxis = pointOnAxis + unitVectorAlongLength * duplexRise x += duplexRise numberOfBasesDrawn += 1 if previous_ribbon1_point: drawline(ribbon1Color, previous_ribbon1_point, ribbon1_point, width = ribbonThickness, isSmooth = True ) arrowLengthVector1 = norm(ribbon1_point - previous_ribbon1_point) arrowHeightVector1 = cross(-lineOfSightVector, arrowLengthVector1) pass continue # while x < ribbonLength if ribbon1_direction == 1: #Arrow head for endpoint of ribbon_1. drawArrowHead(ribbon1Color, ribbon1_point, arrowDrawingScale, arrowHeightVector1, arrowLengthVector1) #The second axis endpoint of the dna is drawn as a transparent sphere. #Note that the second axis endpoint is NOT NECESSARILY endCenter2 . In fact # those two are equal only at the ladder steps. In other case (when the # ladder step is not completed), the endCenter1 is ahead of the #'second axis endpoint of the dna' drawsphere(AXIS_ENDPOINT_SPHERE_COLOR, previousPointOnAxis, AXIS_ENDPOINT_SPHERE_RADIUS, AXIS_ENDPOINT_SPHERE_DRAWLEVEL, opacity = AXIS_ENDPOINT_SPHERE_OPACITY) ##glPopMatrix() glEnable(GL_LIGHTING) return # from drawDnaSingleRibbon
def drawAngleDimension(color, right, up, bpos, p0, p1, p2, text, minR1=0.0, minR2=0.0, highlighted=False): z = cross(p0 - p1, p2 - p1) try: csys = CylindricalCoordinates(p1, z, up, right) except ZeroLengthCylinder: len0 = vlen(p1 - p0) len2 = vlen(p1 - p2) # make sure it's really a zero-degree angle assert len0 > 1.0e-6 assert len2 > 1.0e-6 assert vlen(cross(p1 - p2, p1 - p0)) < 1.0e-6 # For an angle of zero degrees, there is no correct way to # orient the text, so just draw a line segment if len0 > len2: L = len0 end = p0 else: L = len2 end = p2 Lb = vlen(bpos - p1) if Lb > L: L = Lb end = p1 + (Lb / L) * (end - p1) drawline(color, p1, end) return br, bt, bz = csys.rtz(bpos) theta1 = csys.rtz(p0)[1] theta2 = csys.rtz(p2)[1] if theta2 < theta1 - math.pi: theta2 += 2 * math.pi elif theta2 > theta1 + math.pi: theta2 -= 2 * math.pi if theta2 < theta1: theta1, theta2 = theta2, theta1 e0 = csys.xyz((max(vlen(p0 - p1), br, minR1) + 0.5, theta1, 0)) e1 = csys.xyz((max(vlen(p2 - p1), br, minR2) + 0.5, theta2, 0)) drawline(color, p1, e0) drawline(color, p1, e1) if highlighted: csys.drawArc(color, br, theta1, theta2, 0, width=THICKLINEWIDTH) else: csys.drawArc(color, br, theta1, theta2, 0) # draw some arrowheads e00 = csys.xyz((br, theta1, 0)) e10 = csys.xyz((br, theta2, 0)) dr = 0.25 dtheta = 1 / br e0a = csys.xyz((br + dr, theta1 + dtheta, 0)) e0b = csys.xyz((br - dr, theta1 + dtheta, 0)) e1a = csys.xyz((br + dr, theta2 - dtheta, 0)) e1b = csys.xyz((br - dr, theta2 - dtheta, 0)) drawline(color, e00, e0a) drawline(color, e00, e0b) drawline(color, e10, e1a) drawline(color, e10, e1b) midangle = (theta1 + theta2) / 2 tmidpoint = csys.xyz((br + 0.5, midangle, 0)) h = 1.0e-3 textx = norm(csys.xyz((br + 0.5, midangle + h, 0)) - tmidpoint) texty = norm(csys.xyz((br + 0.5 + h, midangle, 0)) - tmidpoint) # make sure the text runs from left to right if dot(textx, right) < 0: textx = -textx # make sure the text isn't upside-down outOfScreen = cross(right, up) textForward = cross(textx, texty) if dot(outOfScreen, textForward) < 0: tmidpoint = csys.xyz((br + 1.5, midangle, 0)) texty = -texty textxyz = tmidpoint - (0.5 * len(text)) * textx def tfm(x, y): x = (x / (1. * WIDTH)) * textx y = (y / (1. * HEIGHT)) * texty return textxyz + x + y f3d = Font3D() f3d.drawString(text, tfm=tfm, color=color)
def drawLine(self, color, rtz1, rtz2, width=1): drawline(color, self.xyz(rtz1), self.xyz(rtz2), width=width)
def _DEBUG_draw_avg_centerpairs_of_potential_crossovers(self): pairs = self._crossoverSite_marker.get_avg_center_pairs_of_potential_crossovers for pair in pairs: drawline(yellow, pair[0], pair[1], width = 2)
def 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 = None, ribbon1_direction = None, peakDeviationFromCenter = 9.5, ribbonThickness = 2.0, ribbon1Color = None, stepColor = None): """ @see: drawDnaRibbons (method in this file) @see: DnaStrand_GraphicsMode._drawHandles() """ if 0: # debug code, useful to see where the argument points are located # [bruce 080422] draw_debug_text(glpane, endCenter1, "endCenter1") draw_debug_text(glpane, endCenter2, "endCenter2") draw_debug_text(glpane, ribbon1_start_point, "ribbon1_start_point") #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 if stepColor is None: stepColor = env.prefs[DarkBackgroundContrastColor_prefs_key] 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. It also means the dna duplex axis can be determined # below from the two endpoints. if ribbonLength < duplexRise: return unitVectorAlongLength = norm(endCenter2 - endCenter1) glDisable(GL_LIGHTING) ##glPushMatrix() ##glTranslatef(endCenter1[0], endCenter1[1], endCenter1[2]) ##pointOnAxis = V(0, 0, 0) pointOnAxis = endCenter1 axial_shift = V(0.0, 0.0, 0.0) # might be changed below # [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 if ribbon1_start_point is not None: # [revise the meaning of these values to give the coordinate system # with the right phase in which to draw the ribbon. # bruce 080422 bugfix] vectorAlongLadderStep0 = ribbon1_start_point - endCenter1 # note: this might not be perpendicular to duplex axis. # fix by subtracting off the parallel component. # but add the difference back to every point below. vectorAlongLadderStep = vectorAlongLadderStep0 - \ dot( unitVectorAlongLength, vectorAlongLadderStep0 ) * unitVectorAlongLength axial_shift = (vectorAlongLadderStep0 - vectorAlongLadderStep) # note: even using this, there is still a small glitch in the # location of the first drawn sphere vs. the ribbon point... don't # know why. [bruce 080422] unitVectorAlongLadderStep = norm(vectorAlongLadderStep) unitDepthVector = cross(unitVectorAlongLength, unitVectorAlongLadderStep) ## * -1 pass del vectorAlongLadderStep ###=== #Following limits the arrowHead Size to the given value. When you zoom out, #the rest of ladder drawing becomes smaller (expected) and the following #check ensures that the arrowheads are drawn proportionately. # (Not using a 'constant' to do this as using glpaneScale gives better #results) if glpaneScale > 40: arrowDrawingScale = 40 else: arrowDrawingScale = glpaneScale #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. x = 0.0 T = duplexRise * basesPerTurn # The 'Period' of the sine wave # (i.e. peak to peak distance between consecutive crests) numberOfBasesDrawn = 0 theta_offset = 0 ## phase_angle_ribbon_1 = HALF_PI ## theta_ribbon_1 = (TWICE_PI * x / T) + phase_angle_ribbon_1 #Initialize ribbon1_point # [note: might not be needed, since identical to first point # computed during loop, but present code uses it to initialize # previous_ribbon1_point during loop [bruce 080422 comment]] ribbon1_point = _compute_ribbon_point(pointOnAxis + axial_shift, basesPerTurn, duplexRise, unitVectorAlongLength, unitVectorAlongLadderStep, unitDepthVector, peakDeviationFromCenter, numberOfBasesDrawn, theta_offset ) while x < ribbonLength: #Draw the axis point. drawPoint(stepColor, pointOnAxis) previousPointOnAxis = pointOnAxis previous_ribbon1_point = ribbon1_point ribbon1_point = _compute_ribbon_point(pointOnAxis + axial_shift, basesPerTurn, duplexRise, unitVectorAlongLength, unitVectorAlongLadderStep, unitDepthVector, peakDeviationFromCenter, numberOfBasesDrawn, theta_offset ) if x == duplexRise and ribbon1_direction == -1: # For ribbon_2 we need to draw an arrow head for y at x = 0. # To do this, we need the 'next ribbon_2' point in order to # compute the appropriate vectors. So when x = duplexRise, the # previous_ribbon2_point is nothing but y at x = 0. arrowLengthVector2 = norm(ribbon1_point - previous_ribbon1_point ) arrowHeightVector2 = cross(-lineOfSightVector, arrowLengthVector2) drawArrowHead( ribbon1Color, previous_ribbon1_point, arrowDrawingScale, -arrowHeightVector2, -arrowLengthVector2) # Draw sphere over previous_ribbon1_point and not ribbon1_point. # This is so we don't draw a sphere over the last point on ribbon1 # (instead, it is drawn as an arrowhead after the while loop). drawsphere(ribbon1Color, previous_ribbon1_point, SPHERE_RADIUS, SPHERE_DRAWLEVEL, opacity = SPHERE_OPACITY) drawline(stepColor, pointOnAxis, ribbon1_point) #Increment the pointOnAxis and x pointOnAxis = pointOnAxis + unitVectorAlongLength * duplexRise x += duplexRise numberOfBasesDrawn += 1 if previous_ribbon1_point: drawline(ribbon1Color, previous_ribbon1_point, ribbon1_point, width = ribbonThickness, isSmooth = True ) arrowLengthVector1 = norm(ribbon1_point - previous_ribbon1_point) arrowHeightVector1 = cross(-lineOfSightVector, arrowLengthVector1) pass continue # while x < ribbonLength if ribbon1_direction == 1: #Arrow head for endpoint of ribbon_1. drawArrowHead(ribbon1Color, ribbon1_point, arrowDrawingScale, arrowHeightVector1, arrowLengthVector1) #The second axis endpoint of the dna is drawn as a transparent sphere. #Note that the second axis endpoint is NOT NECESSARILY endCenter2 . In fact # those two are equal only at the ladder steps. In other case (when the # ladder step is not completed), the endCenter1 is ahead of the #'second axis endpoint of the dna' drawsphere(AXIS_ENDPOINT_SPHERE_COLOR, previousPointOnAxis, AXIS_ENDPOINT_SPHERE_RADIUS, AXIS_ENDPOINT_SPHERE_DRAWLEVEL, opacity = AXIS_ENDPOINT_SPHERE_OPACITY) ##glPopMatrix() glEnable(GL_LIGHTING) return # from drawDnaSingleRibbon
def draw(self): color = self.fix_color(self.color) end1, end2 = self.end1, self.end2 width = self.width dashed = self.dashed drawline(color[:3], end1, end2, width = width, dashEnabled = dashed) ###k dashEnabled untested here