summaryrefslogtreecommitdiff
path: root/cad/src/graphics/widgets/GLPane_csdl_collector.py
blob: 5b74fdcc6ce302933f659c5bd3078083c658abfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Copyright 2009 Nanorex, Inc.  See LICENSE file for details.
"""
GLPane_csdl_collector.py -- classes for use as a GLPane's csdl_collector

@author: Bruce
@version: $Id$
@copyright: 2009 Nanorex, Inc.  See LICENSE file for details.

History:

Bruce 090218 wrote this as part of Part_drawing_frame,
then realized it belonged elsewhere and split it into
a separate object on 090219
"""

from utilities.debug import print_compact_stack

from graphics.drawing.ColorSortedDisplayList import ColorSortedDisplayList
from graphics.drawing.ColorSorter import ColorSorter

# ==

class _GLPane_csdl_collector_superclass:
    """
    """
    use_drawingsets = False # whether to draw CSDLs using DrawingSets
    bare_primitives = None # None, or a CSDL for collecting bare primitives

    pass

# ==

class GLPane_csdl_collector(_GLPane_csdl_collector_superclass):
    """
    One of these is created whenever drawing a model,
    provided GLPane._before_drawing_csdls is called.

    It holds attributes needed for GLPane.draw_csdl to work
    (and helper methods for that as well).

    See superclass code comments for documentation of attributes.

    For more info, see docstring of GLPane._before_drawing_csdls.
    """
    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):
        # review: needed in fake_GLPane_csdl_collector too??
        """
        """
        self.use_drawingsets = True
        self._drawingset_contents = {}

    def setup_for_bare_primitives(self): #bruce 090220
        """
        """
        self.bare_primitives = ColorSortedDisplayList(reentrant = True)
        ColorSorter.start(self._glpane, self.bare_primitives)
        return

    def collect_csdl(self, csdl, intent):
        """
        When self.use_drawingsets is set, model component drawing code which
        wants to draw a CSDL should pass it to this method rather than
        drawing it directly.

        This method just collects it into a dict based on intent.

        At the end of the current drawing frame, all csdls passed to this method
        will be added to (or maintained in) an appropriate DrawingSet,
        and all DrawingSets will be drawn, by external code which calls
        grab_intent_to_csdls_dict.

        @param csdl: a CSDL to draw later
        @type csdl: ColorSortedDisplayList

        @param intent: specifies how the DrawingSet which csdl ends up in
                       should be drawn (transform, other GL state, draw options)
        @type intent: not defined here, but must be useable as a dict key

        @return: None

        This API requires that every csdl to be drawn must be passed here in
        every frame (though the DrawingSets themselves can be persistent
        and incrementally updated, depending on how the data accumulated here
        is used). A more incremental API would probably perform better
        but would be much more complex, having to deal with chunks which
        move in and out of self, get killed, or don't get drawn for any other
        reason, and also requiring chunks to "diff" their own drawing intents
        and do incremental update themselves.
        """
        try:
            csdl_dict = self._drawingset_contents[intent]
        except KeyError:
            csdl_dict = self._drawingset_contents[intent] = {}
        csdl_dict[csdl.csdl_id] = csdl
        return

    def finish_bare_primitives(self):
        assert self.bare_primitives
        csdl = self.bare_primitives
        self.bare_primitives = None # precaution
        assert ColorSorter._parent_csdl is csdl
        ColorSorter.finish( draw_now = False)
        return csdl

    def grab_intent_to_csdls_dict(self):
        """
        Return (with ownership) to the caller (and reset in self)
        a dict from intent (about how a csdl's drawingset should be drawn)
        to a set of csdls (as a dict from their csdl_id's),
        which includes exactly the CSDLs which should be drawn in this
        frame (whether or not they were drawn in the last frame).

        The intent and csdl pairs in what we return are just the ones
        which were passed to collect_csdl during this frame.
        """
        res = self._drawingset_contents
        self._drawingset_contents = {}
        return res

    pass

# ==

class fake_GLPane_csdl_collector(_GLPane_csdl_collector_superclass):
    """
    Use one of these "between draws" to avoid or mitigate bugs.
    """
    def __init__(self, glpane):
        print_compact_stack(
            "warning: fake_GLPane_csdl_collector is being instantiated: " )
        return

    pass

# end