diff options
author | Bruce Smith <bruce@nanorex.com> | 2009-02-21 00:03:08 +0000 |
---|---|---|
committer | Bruce Smith <bruce@nanorex.com> | 2009-02-21 00:03:08 +0000 |
commit | 785402ce730379d9700bc0f6868f028159587498 (patch) | |
tree | 2b0b38c461cc06be81f5a8747a344988dfd3d802 | |
parent | 3a4954668b12d58b1eb47649d74b0940efcfcc17 (diff) | |
download | nanoengineer-785402ce730379d9700bc0f6868f028159587498.tar.gz nanoengineer-785402ce730379d9700bc0f6868f028159587498.zip |
ColorSorter.start & chunk.*Matrix want glpane arg, track transforms
-rwxr-xr-x | cad/src/commands/BuildCrystal/CrystalShape.py | 12 | ||||
-rw-r--r-- | cad/src/commands/TestGraphics/test_selection_redraw.py | 2 | ||||
-rwxr-xr-x | cad/src/graphics/drawing/ColorSorter.py | 91 | ||||
-rw-r--r-- | cad/src/graphics/model_drawing/ChunkDrawer.py | 16 | ||||
-rw-r--r-- | cad/src/graphics/model_drawing/ExternalBondSetDrawer.py | 4 | ||||
-rw-r--r-- | cad/src/graphics/model_drawing/special_drawing.py | 2 | ||||
-rw-r--r-- | cad/src/graphics/widgets/GLPane_csdl_collector.py | 10 | ||||
-rw-r--r-- | cad/src/graphics/widgets/GLPane_drawingset_methods.py | 26 | ||||
-rw-r--r-- | cad/src/graphics/widgets/GLPane_minimal.py | 14 | ||||
-rwxr-xr-x | cad/src/model/bonds.py | 4 | ||||
-rwxr-xr-x | cad/src/model/chem.py | 4 | ||||
-rwxr-xr-x | cad/src/model/chunk.py | 44 | ||||
-rw-r--r-- | cad/src/prototype/test_drawing.py | 4 |
13 files changed, 189 insertions, 44 deletions
diff --git a/cad/src/commands/BuildCrystal/CrystalShape.py b/cad/src/commands/BuildCrystal/CrystalShape.py index 6ba231ac8..9abd3d68e 100755 --- a/cad/src/commands/BuildCrystal/CrystalShape.py +++ b/cad/src/commands/BuildCrystal/CrystalShape.py @@ -778,19 +778,19 @@ class CrystalShape(shape): drawline(white, p0, p1) - def draw(self, win, layerColor): + def draw(self, glpane, layerColor): """ - Draw the shape. win, not used, is for consistency among - drawing functions (and may be used if drawing logic gets - more sophisticated. + Draw the shape. - Find the bounding box for the curve and check the position of each + Find the bounding box for the curve and check the position of each carbon atom in a lattice would occupy for being 'in' the shape. A tube representation of the atoms thus selected is saved as a GL call list for fast drawing. This method is only for crystal-cutter mode. --Huaicai """ + #bruce 090220 renamed first arg from win to glpane (which is what + # was actually passed) and used it in ColorSorter.start (required now). if 0: self._anotherDraw(layerColor) return @@ -802,7 +802,7 @@ class CrystalShape(shape): return #russ 080225: Moved glNewList into ColorSorter.start for displist re-org. #russ 080225: displist side effect allocates a ColorSortedDisplayList. - ColorSorter.start(self.displist) # grantham 20051205 + ColorSorter.start(glpane, self.displist) # grantham 20051205 try: for layer, bonds in self.bondLayers.items(): color = layerColor[layer] diff --git a/cad/src/commands/TestGraphics/test_selection_redraw.py b/cad/src/commands/TestGraphics/test_selection_redraw.py index 4405c71ce..6f07002f4 100644 --- a/cad/src/commands/TestGraphics/test_selection_redraw.py +++ b/cad/src/commands/TestGraphics/test_selection_redraw.py @@ -64,7 +64,7 @@ class CSDL_holder(object): def __init__(self, x, y, n): self.csdl = ColorSortedDisplayList() # draw into it, based on x, y, n - ColorSorter.start(self.csdl) + ColorSorter.start(None, self.csdl) for i in range(n): z = i - (_NUM_SPHERES_PER_CSDL - 1) / 2.0 color = (random.uniform(0.2, 0.8), diff --git a/cad/src/graphics/drawing/ColorSorter.py b/cad/src/graphics/drawing/ColorSorter.py index 03a5747e6..7d125b7b6 100755 --- a/cad/src/graphics/drawing/ColorSorter.py +++ b/cad/src/graphics/drawing/ColorSorter.py @@ -124,6 +124,10 @@ from graphics.drawing.gl_lighting import apply_material _csdl_id_counter = 0 _warned_del = False +_DEBUG = False + +# == + class ColorSortedDisplayList: #Russ 080225: Added. """ The ColorSorter's parent uses one of these to store color-sorted display @@ -350,7 +354,7 @@ class ColorSortedDisplayList: #Russ 080225: Added. Allocate a CSDL in the parent class and fill it with the ColorSorter: self.csdl = ColorSortedDisplayList() - ColorSorter.start(self.csdl) + ColorSorter.start(glpane, self.csdl) drawsphere(...), drawcylinder(...), drawpolycone(...), and so on. ColorSorter.finish() @@ -565,6 +569,12 @@ class ColorSortedDisplayList: #Russ 080225: Added. # == +class _fake_GLPane: #bruce 090220 + transforms = () # or make this [] if necessary, but value should never change + pass + +_the_fake_GLPane = _fake_GLPane() + class ColorSorter: """ State Sorter specializing in color (really any object that can be @@ -628,6 +638,10 @@ class ColorSorter: ColorSorter._parent_csdl = None # Passed from start() to finish() + ColorSorter.glpane = None #bruce 090220 + + ColorSorter._initial_transforms = None #bruce 090220 + # following are guesses by bruce 090220: ColorSorter.sorted_by_color = None ColorSorter._cur_shapelist = None @@ -645,12 +659,17 @@ class ColorSorter: class _attrholder: pass state = _attrholder() + + if len(ColorSorter._gl_name_stack) > 1: + print "fyi: name stack is non-null when suspended -- bug?", ColorSorter._gl_name_stack ##### state.sorting = ColorSorter.sorting state._sorted = ColorSorter._sorted state._immediate = ColorSorter._immediate state._gl_name_stack = ColorSorter._gl_name_stack state._parent_csdl = ColorSorter._parent_csdl + state.glpane = ColorSorter.glpane + state._initial_transforms = ColorSorter._initial_transforms state.sorted_by_color = ColorSorter.sorted_by_color state._cur_shapelist = ColorSorter._cur_shapelist state.sphereLevel = ColorSorter.sphereLevel @@ -664,6 +683,7 @@ class ColorSorter: def _unsuspend_if_needed(): # staticmethod """ If we're suspended, unsuspend. + Otherwise, reinit state as a precaution. """ if ColorSorter._suspended_states: state = ColorSorter._suspended_states.pop() @@ -673,16 +693,53 @@ class ColorSorter: ColorSorter._immediate = state._immediate ColorSorter._gl_name_stack = state._gl_name_stack ColorSorter._parent_csdl = state._parent_csdl + ColorSorter.glpane = state.glpane + ColorSorter._initial_transforms = state._initial_transforms ColorSorter.sorted_by_color = state.sorted_by_color ColorSorter._cur_shapelist = state._cur_shapelist ColorSorter.sphereLevel = state.sphereLevel pass + else: + #bruce 090220 guess precaution + assert len(ColorSorter._gl_name_stack) == 1 + ColorSorter._init_state() return _unsuspend_if_needed = staticmethod(_unsuspend_if_needed) # == + + def _relative_transforms(): # staticmethod #bruce 090220 + """ + Return a list or tuple (owned by caller) of the additional transforms + we're presently inside, relative to when start() was called. + + Also do related sanity checks (as assertions). + """ + t1 = ColorSorter._initial_transforms + n1 = len(t1) + + t2 = ColorSorter.glpane.transforms # should be same or more + n2 = len(t2) + + if n1 < n2: + assert t1 == t2[:n1] + return tuple(t2[n1:]) + else: + assert n1 <= n2 + return () + pass + + _relative_transforms = staticmethod(_relative_transforms) + + def _debug_transforms(): # staticmethod #bruce 090220 + return [ColorSorter._initial_transforms, + ColorSorter._relative_transforms()] + + _debug_transforms = staticmethod(_debug_transforms) + + # == def pushName(glname): """ @@ -794,6 +851,10 @@ class ColorSorter: Schedule a sphere for rendering whenever ColorSorter thinks is appropriate. """ + if _DEBUG and ColorSorter._parent_csdl and ColorSorter._parent_csdl.reentrant: + print "bare_prim sphere:", ColorSorter._gl_name_stack[-1], \ + color, pos, radius, ColorSorter._debug_transforms() ##### + if drawing_globals.use_c_renderer and ColorSorter.sorting: if len(color) == 3: lcolor = (color[0], color[1], color[2], opacity) @@ -850,6 +911,10 @@ class ColorSorter: Schedule a wiresphere for rendering whenever ColorSorter thinks is appropriate. """ + if _DEBUG and ColorSorter._parent_csdl and ColorSorter._parent_csdl.reentrant: + print "bare_prim wiresphere:", ColorSorter._gl_name_stack[-1], \ + color, pos, radius, ColorSorter._debug_transforms() ##### + if drawing_globals.use_c_renderer and ColorSorter.sorting: if len(color) == 3: lcolor = (color[0], color[1], color[2], 1.0) @@ -876,6 +941,10 @@ class ColorSorter: Schedule a cylinder for rendering whenever ColorSorter thinks is appropriate. """ + if _DEBUG and ColorSorter._parent_csdl and ColorSorter._parent_csdl.reentrant: + print "bare_prim cylinder:", ColorSorter._gl_name_stack[-1], \ + color, pos1, pos2, radius, capped, ColorSorter._debug_transforms() ##### + if drawing_globals.use_c_renderer and ColorSorter.sorting: if len(color) == 3: lcolor = (color[0], color[1], color[2], 1.0) @@ -1009,12 +1078,16 @@ class ColorSorter: # == - def start(csdl, pickstate = None): # staticmethod + def start(glpane, csdl, pickstate = None): # staticmethod """ Start sorting - objects provided to "schedule" and primitives such as "schedule_sphere" and "schedule_cylinder" will be stored for a sort at the time "finish" is called. + glpane is used for its transform stack. It can be None, but then + we will not notice whether primitives we collect are inside + any transforms beyond the ones current when we start. + csdl is a ColorSortedDisplayList or None, in which case immediate drawing is done. @@ -1023,6 +1096,7 @@ class ColorSorter: #russ 080225: Moved glNewList here for displist re-org. # (bruce 090114: removed support for use_color_sorted_vbos) #bruce 090220: support _parent_csdl.reentrant + #bruce 090220: added new required first argument glpane if ColorSorter._parent_csdl and ColorSorter._parent_csdl.reentrant: assert ColorSorter.sorting @@ -1035,6 +1109,15 @@ class ColorSorter: assert ColorSorter._parent_csdl is None #bruce 090105 ColorSorter._parent_csdl = csdl # used by finish() + assert ColorSorter.glpane is None + if glpane is None: + glpane = _the_fake_GLPane + assert not glpane.transforms + ColorSorter.glpane = glpane + ColorSorter._initial_transforms = list(glpane.transforms) + if _DEBUG: + print "CS.initial transforms:", ColorSorter._debug_transforms() ##### + if pickstate is not None: csdl.selectPick(pickstate) pass @@ -1090,6 +1173,7 @@ class ColorSorter: to not draw (the drawing has already happened). """ assert ColorSorter.sorting #bruce 090220, appears to be true from this code + assert ColorSorter.glpane #bruce 090220 if not ColorSorter._parent_csdl: #bruce 090220 revised, check _parent_csdl rather than sorting @@ -1098,6 +1182,7 @@ class ColorSorter: ### WARNING: DUPLICATE CODE with end of this method # (todo: split out some submethods to clean up) ColorSorter.sorting = False + ColorSorter.glpane = None ColorSorter._unsuspend_if_needed() return # Plain immediate-mode, nothing to do. @@ -1336,6 +1421,8 @@ class ColorSorter: # Use either the normal-color display list or the selected one. selected = parent_csdl.selected) + ColorSorter.glpane = None + ColorSorter._unsuspend_if_needed() return diff --git a/cad/src/graphics/model_drawing/ChunkDrawer.py b/cad/src/graphics/model_drawing/ChunkDrawer.py index 7af2b5160..39daf9e29 100644 --- a/cad/src/graphics/model_drawing/ChunkDrawer.py +++ b/cad/src/graphics/model_drawing/ChunkDrawer.py @@ -348,8 +348,8 @@ class ChunkDrawer(TransformedDisplayListsDrawer): # put it in its place glPushMatrix() - try: # do our glPopMatrix no matter what - self._chunk.applyMatrix() + try: # do our popMatrix no matter what + self._chunk.applyMatrix(glpane) ##delegate_selection_wireframe = False delegate_draw_atoms = False @@ -442,7 +442,7 @@ class ChunkDrawer(TransformedDisplayListsDrawer): if wantlist: ##print "Regenerating display list for %s" % self.name match_checking_code = self.begin_tracking_usage() - ColorSorter.start(self.displist) + ColorSorter.start(glpane, self.displist) # Note: passing self._chunk.picked was needed # when ColorSorter.finish (below) got # draw_now = True, but is not needed now @@ -524,7 +524,7 @@ class ChunkDrawer(TransformedDisplayListsDrawer): except: print_compact_traceback("exception in Chunk.draw, continuing: ") - glPopMatrix() + self._chunk.popMatrix(glpane) glPopName() # pops self._chunk.glname @@ -698,7 +698,7 @@ class ChunkDrawer(TransformedDisplayListsDrawer): if use_outer_colorsorter: # note: not used with ExternalBondSets - ColorSorter.start(None) + ColorSorter.start(glpane, None) # [why is this needed? bruce 080707 question] for bond in objects_to_draw: @@ -900,11 +900,11 @@ class ChunkDrawer(TransformedDisplayListsDrawer): ##### TODO: use glpane.draw_csdl. if self._has_displist(): apply_material(color) ### REVIEW: still needed? - self._chunk.pushMatrix() + self._chunk.pushMatrix(glpane) for csdl in ([self.displist] + [ed.csdl for ed in self.extra_displists.values()]): csdl.draw(highlighted = True, highlight_color = color) - self._chunk.popMatrix() + self._chunk.popMatrix(glpane) pass # piotr 080521: Get display mode for drawing external bonds and/or @@ -921,7 +921,7 @@ class ChunkDrawer(TransformedDisplayListsDrawer): # (as was done in older code). (Note that there will soon be # objects containing display lists for them, and our job will # be to not draw *those objects* twice, in any one frame.) - ColorSorter.start(None) + ColorSorter.start(glpane, None) for bond in self._chunk.externs: bond.draw(glpane, disp, color, drawLevel) continue diff --git a/cad/src/graphics/model_drawing/ExternalBondSetDrawer.py b/cad/src/graphics/model_drawing/ExternalBondSetDrawer.py index 43583e2e8..64564a7a7 100644 --- a/cad/src/graphics/model_drawing/ExternalBondSetDrawer.py +++ b/cad/src/graphics/model_drawing/ExternalBondSetDrawer.py @@ -86,7 +86,7 @@ class ExternalBondSetDrawer(TransformedDisplayListsDrawer): use_outer_colorsorter = True # not sure whether/why this is needed if use_outer_colorsorter: - ColorSorter.start(None) + ColorSorter.start(glpane, None) for bond in self._ebset._bonds.itervalues(): bond.draw(glpane, disp, color, drawLevel) @@ -232,7 +232,7 @@ class ExternalBondSetDrawer(TransformedDisplayListsDrawer): # print "Regenerating display list for %r (%d)" % \ # (self, env.redraw_counter) match_checking_code = self.begin_tracking_usage() - ColorSorter.start(self.displist, c1.picked and c2.picked) + ColorSorter.start(glpane, self.displist, c1.picked and c2.picked) # not sure whether picked arg needed # protect against exceptions while making display list, diff --git a/cad/src/graphics/model_drawing/special_drawing.py b/cad/src/graphics/model_drawing/special_drawing.py index d0fa02d67..f92659a22 100644 --- a/cad/src/graphics/model_drawing/special_drawing.py +++ b/cad/src/graphics/model_drawing/special_drawing.py @@ -446,7 +446,7 @@ class ExtraChunkDisplayList(object, SubUsageTrackingMixin): if wantlist: match_checking_code = self.begin_tracking_usage() # note: method defined in superclass, SubUsageTrackingMixin - ColorSorter.start(self.csdl, selected) + ColorSorter.start(glpane, self.csdl, selected) ### REVIEW: is selected arg needed? guess yes, # since .finish will draw it based on the csdl state # which is determined by that arg. If so, this point needs diff --git a/cad/src/graphics/widgets/GLPane_csdl_collector.py b/cad/src/graphics/widgets/GLPane_csdl_collector.py index b04910186..1ab8379f5 100644 --- a/cad/src/graphics/widgets/GLPane_csdl_collector.py +++ b/cad/src/graphics/widgets/GLPane_csdl_collector.py @@ -42,7 +42,11 @@ class GLPane_csdl_collector(_GLPane_csdl_collector_superclass): For more info, see docstring of GLPane.before_drawing_csdls. """ - def __init__(self): + def __init__(self, glpane): + ## print "\ninit GLPane_csdl_collector", glpane, glpane.drawing_phase + self._glpane = glpane + # note: this won't be a ref cycle once we're done with, + # since glpane won't refer to us anymore then return def setup_for_drawingsets(self): @@ -56,7 +60,7 @@ class GLPane_csdl_collector(_GLPane_csdl_collector_superclass): """ """ self.bare_primitives = ColorSortedDisplayList(reentrant = True) - ColorSorter.start(self.bare_primitives) + ColorSorter.start(self._glpane, self.bare_primitives) return def draw_csdl_in_drawingset(self, csdl, intent): @@ -118,7 +122,7 @@ class fake_GLPane_csdl_collector(_GLPane_csdl_collector_superclass): """ Use one of these "between draws" to avoid or mitigate bugs. """ - def __init__(self): + def __init__(self, glpane): print_compact_stack( "warning: fake_GLPane_csdl_collector is being instantiated: " ) return diff --git a/cad/src/graphics/widgets/GLPane_drawingset_methods.py b/cad/src/graphics/widgets/GLPane_drawingset_methods.py index f11d9928a..7aa559603 100644 --- a/cad/src/graphics/widgets/GLPane_drawingset_methods.py +++ b/cad/src/graphics/widgets/GLPane_drawingset_methods.py @@ -15,6 +15,8 @@ Part.after_drawing_model. from utilities.debug_prefs import debug_pref from utilities.debug_prefs import Choice_boolean_False +from utilities.debug import print_compact_traceback + from graphics.drawing.DrawingSet import DrawingSet from graphics.widgets.GLPane_csdl_collector import GLPane_csdl_collector @@ -44,10 +46,25 @@ class GLPane_drawingset_methods(object): Initialize self._csdl_collector if necessary, and return it. """ - if not self._csdl_collector: - self._csdl_collector = self._csdl_collector_class() - # note: self._csdl_collector_class changes dynamically - return self._csdl_collector + try: + ## print "__get_csdl_collector", self + if not self._csdl_collector: + ## print "alloc in __get_csdl_collector", self + self._csdl_collector = self._csdl_collector_class( self) + # note: self._csdl_collector_class changes dynamically + return self._csdl_collector + except: + # without this try/except, python will report any exception in here + # (or at least any AttributeError) as if it was an AttributeError + # on self.csdl_collector, discarding all info about the nature + # and code location of the actual error! [bruce 090220] + ### TODO: flush all output streams in print_compact_traceback; + # in current code, the following prints before we finish printing + # whatever print statement had the exception partway through, if one did + print_compact_traceback("\nfollowing exception is *really* this one, inside __get_csdl_collector: ") + print + raise + pass def __set_csdl_collector(self): """ @@ -59,6 +76,7 @@ class GLPane_drawingset_methods(object): """ del method for self.csdl_collector property """ + ## print "\ndel csdl_collector", self self._csdl_collector = None csdl_collector = property(__get_csdl_collector, __set_csdl_collector, __del_csdl_collector) diff --git a/cad/src/graphics/widgets/GLPane_minimal.py b/cad/src/graphics/widgets/GLPane_minimal.py index 317482d13..f693ee583 100644 --- a/cad/src/graphics/widgets/GLPane_minimal.py +++ b/cad/src/graphics/widgets/GLPane_minimal.py @@ -142,6 +142,9 @@ class GLPane_minimal(QGLWidget, GLPane_drawingset_methods, object): #bruce 07091 _resize_counter = 0 + drawing_phase = '?' # overridden in GLPane_rendering_methods, but needed for + # debug prints that might happen in any class of GLPane [bruce 090220] + # default values of subclass-specific constants permit_draw_bond_letters = True #bruce 071023 @@ -193,6 +196,17 @@ class GLPane_minimal(QGLWidget, GLPane_drawingset_methods, object): #bruce 07091 # piotr 080807 # Most recent quaternion to be used in animation timer. self.last_quat = None + + self.transforms = [] ### TODO: clear this at start of frame, complain if not clear + # stack of current transforms (or Nodes that generate them) + # [bruce 090220] + # Note: this may be revised once we have TransformNode, + # e.g. we might push their dt and st separately; + # note we might need to push a "slot" for them if they might + # change before being popped, or perhaps even if they might + # change between the time pushed and the time later used + # (by something that collects them from here in association + # with a ColorSortedDisplayList). return diff --git a/cad/src/model/bonds.py b/cad/src/model/bonds.py index 7538e75cd..276833b6b 100755 --- a/cad/src/model/bonds.py +++ b/cad/src/model/bonds.py @@ -2201,7 +2201,7 @@ class Bond(BondBase, StateMixin, Selobj_API): #bruce 041109 partial rewrite if mol is mol2: # internal bond; geometric info is stored in chunk-relative # coords; we need mol's help to use those - mol.pushMatrix() + mol.pushMatrix(glpane) self.draw(glpane, mol.get_dispdef(glpane), color, mol.assy.drawLevel, highlighted ) # sorry for all the kluges (e.g. 1 or 2 of those args) that beg for @@ -2218,7 +2218,7 @@ class Bond(BondBase, StateMixin, Selobj_API): #bruce 041109 partial rewrite #commit, same day, GLPane.py (sort selobj candidates) and this #file (don't shorten_tubes next to singlets [later moved to #bond_drawer.py]), this has been fixed. - mol.popMatrix() + mol.popMatrix(glpane) else: # external bond -- draw it at max dispdef of those from its mols disp = max( mol.get_dispdef(glpane), mol2.get_dispdef(glpane) ) diff --git a/cad/src/model/chem.py b/cad/src/model/chem.py index d125e20e6..a63ff4614 100755 --- a/cad/src/model/chem.py +++ b/cad/src/model/chem.py @@ -2530,7 +2530,7 @@ class Atom( PAM_Atom_methods, AtomBase, InvalMixin, StateMixin, Selobj_API): #does seem to work. Note that it needs testing for rotated chunks, #since until you next modify them, the wirespheres are also drawn #rotated.) - self.molecule.pushMatrix() + self.molecule.pushMatrix(glpane) try: # note: the following inlines self.drawing_radius(picked_Radius = True), # but makes further use of intermediate values which that method @@ -2551,7 +2551,7 @@ class Atom( PAM_Atom_methods, AtomBase, InvalMixin, StateMixin, Selobj_API): print_compact_traceback("exception in draw_wirespheres " \ "part of draw_in_abs_coords ignored: ") pass - self.molecule.popMatrix() + self.molecule.popMatrix(glpane) return def drawing_radius(self, picked_radius = False): diff --git a/cad/src/model/chunk.py b/cad/src/model/chunk.py index f9544bb43..068e6b8f0 100755 --- a/cad/src/model/chunk.py +++ b/cad/src/model/chunk.py @@ -566,36 +566,58 @@ class Chunk(Chunk_Dna_methods, Chunk_mmp_methods, # [bruce 090212 moved all these back to class Chunk; # they're often called externally] - def pushMatrix(self): + def pushMatrix(self, glpane): """ - Do glPushMatrix(), - then transform from (presumed) world coordinates - to self's private coordinates. + Do glPushMatrix(), then transform from (presumed) world coordinates + to self's private coordinates. Also tell glpane this was done + (for more info and requirements see docstring of applyMatrix). + @see: self.applyMatrix() @see: self.popMatrix() """ glPushMatrix() - self.applyMatrix() + self.applyMatrix(glpane) return - def applyMatrix(self): + def applyMatrix(self, glpane): """ - Without doing glPushMatrix(), - transform from (presumed) world coordinates - to self's private coordinates. + Without doing glPushMatrix(), transform the current GL matrix state + from (presumed) world coordinates to self's private coordinates. + + This is only permitted in 1-1 correspondence with a call + (just done by caller) of either self.pushMatrix(glpane) + or glPushMatrix(). I.e. two calls in a row of self.applyMatrix + are illegal. This is not checked; errors in this will + cause some things to be drawn in the wrong place. + + glpane must correspond to the current GL context. + + Also tell glpane that a push/apply of self's coordinate system has + just been done, in case deferred drawing done after this call + wants to know how to reproduce the current GL matrix state later + (or more precisely, the current *symbolic* state -- i.e. which local + coordinate systems are pushed, even if their value when used later + differs from their current value). (This is why we require 1-1 + correspondence between push and apply.) + @see: self.pushMatrix() """ origin = self.basecenter glTranslatef(origin[0], origin[1], origin[2]) q = self.quat glRotatef(q.angle * 180.0 / math.pi, q.x, q.y, q.z) + glpane.transforms += [self] return - def popMatrix(self): + def popMatrix(self, glpane): """ - Undo the effect of self.pushMatrix(). + Undo the effect of self.pushMatrix(glpane). Also tell glpane this was + done (for more info and requirements see docstring of applyMatrix). """ glPopMatrix() + assert glpane.transforms[-1] is self + glpane.transforms.pop() + return # == diff --git a/cad/src/prototype/test_drawing.py b/cad/src/prototype/test_drawing.py index 7b51fdcdd..f1e0d9b50 100644 --- a/cad/src/prototype/test_drawing.py +++ b/cad/src/prototype/test_drawing.py @@ -383,7 +383,7 @@ def test_drawing(glpane, initOnly = False): (nSpheres, "ColorSorter")) test_csdl = ColorSortedDisplayList() - ColorSorter.start(test_csdl) + ColorSorter.start(None, test_csdl) drawsphere([0.5, 0.5, 0.5], # color [0.0, 0.0, 0.0], # pos .5, # radius @@ -986,7 +986,7 @@ def test_drawing(glpane, initOnly = False): # Test selection using the CSDL glname. ColorSorter.pushName(csdl.glname) - ColorSorter.start(csdl) + ColorSorter.start(None, csdl) for (color, center, radius) in zip(colors, centers, radii): if not doCylinders: # Through ColorSorter to the sphere primitive buffer... |