Ejemplo n.º 1
0
    def visit(self, node):
        """Visit an individual node, search for self.desiredTypes

        This is a heavily trimmed version of the superclass method
        """
        todo = [(0, node)]
        currentStack = []
        childrenTypes = TRAVERSAL_TYPES + self.desiredTypes
        while todo:
            index, node = todo[0]
            del todo[0]
            del currentStack[index:]
            is_desired = isinstance(node, self.desiredTypes)
            try:
                children = self.children(node, types=childrenTypes)
            except:
                traceback.print_exc()
                log.error(
                    """exception in children method for node %s""",
                    node,
                )
            else:
                stack_length = len(currentStack)
                new_items = [(stack_length + 1, child) for child in children]
                if is_desired or new_items:
                    currentStack.append(node)
                    if is_desired:
                        self.result.append(
                            nodepath.NodePath(tuple(currentStack)))
                    if new_items:
                        todo[0:0] = new_items
Ejemplo n.º 2
0
    def __init__(self):
        """Initialise the visitor object

        calls self.buildVMethods() then builds the current
        stack.

        Attributes:
            currentStack -- nodepath describing the current
                processing stack for this visitor

            _vmethods -- mapping from class/superclass to
                methods to be applied on entry to any instance
                of the class, see the vmethods method,
                (multiple match)
        """
        self.buildVMethods()
        self.currentStack = nodepath.NodePath()
Ejemplo n.º 3
0
 def integrate(self, node, parentPath=None):
     """Integrate any children of node which are of interest"""
     if parentPath is None:
         parentPath = nodepath.NodePath([])
     todo = [(node, parentPath)]
     while todo:
         next, parents = todo.pop(0)
         path = parents + next
         np = self.npFor(next)
         np.append(path)
         if hasattr(next, 'bind'):
             for context in self.contexts:
                 context = context()
                 if context is not None:
                     next.bind(context)
         _ = self.npFor(next)
         for typ in self.INTERESTING_TYPES:
             if isinstance(next, typ):
                 self.paths.setdefault(typ, []).append(path)
         if hasattr(next, 'renderedChildren'):
             # watch for next's changes...
             for child in next.renderedChildren():
                 todo.append((child, path))
Ejemplo n.º 4
0
    def __call__( self ):
        """Render geometry once for each pick-event to be serviced

        This is the actual implementation of the glSelectBuffer-
        based selection code. It is fairly standard OpenGL
        selection code.

        We take all of the events which have the same picking-point
        and render them together (since they have the same picking
        characteristics).

        For each picking-point, we set up the constrained picking
        matrix and results array in our ContextSetupDisplay/
        PickProjection methods, which are visited by the standard
        RenderVisitor algorithm.

        The visiting code, particularly RenderVisitor.Grouping,
        pushes the appropriate names onto the name stack during
        rendering, filling the results array as appropriate.

        After visiting the entire scenegraph, we retrieve the results
        from the name-stack and dispatch the events to their
        appropriate handlers.

        XXX
            Really the event handling should not be going on here,
            instead the events should be added to a queue to be
            processed after the RenderPass has completely finished,
            and the ContextLock has been released (but the scenegraph
            lock has been re-acquired).
        """
        if self.shouldDraw( ):
            client = self.context
            events = client.getPickEvents().values()
            client.getPickEvents().clear()
            pickPoints = {}
            for event in events:
                key = tuple(event.getPickPoint())
                pickPoints.setdefault( key, []).append( event )

            for point, set in pickPoints.items():
                self.pickPoint = point
                self.selectable = {}
                self.visit( client )
                ## following two lines get the results of the render...
                nameStack = list(glRenderMode(GL_RENDER))
                ## and now update the event...
                for event in set:
                    ##print '%s items rendered'%( len(self.selectable), )
                    event.setNameStack( nameStack )
                    event.setObjectPaths([
                        nodepath.NodePath(filter(None,[
                            self.selectable.get(long(name))
                            for name in names
                        ]))
                        for (near,far,names) in nameStack
                    ])
                    event.modelViewMatrix = self.modelView
                    event.projectionMatrix = self.projection
                    event.viewport = self.viewport
                    if hasattr( client, 'ProcessEvent'):
                        client.ProcessEvent( event )
            return self.visible
        return 0