Example #1
0
    def drawEdgeSelection(self, edge, alpha=0.4):
        """Draw a hilight around the edge."""
        if isinstance(edge, SuperEdge):
            for subedge in edge.edgeOrder():
                self.drawEdgeSelection(subedge)
            for vx in edge.bends:
                self.drawVertexSelection(vx)
            return

        ctx = self.graph.parent
        # Multiply points if snapping to grid
        # for Netcli (has no parent)
        showG = False
        if not ctx == None:
            if ctx.showGrid:
                showG = True
        if showG:
            srcpos = utilities.mult3D(edge.source.pos, ctx.spacing)
            tgtpos = utilities.mult3D(edge.target.pos, ctx.spacing)
        else:
            srcpos = edge.source.pos
            tgtpos = edge.target.pos

        diff = utilities.diff3D(srcpos, tgtpos)
        dist = utilities.dist3D(c=diff)

        # Avoid dividing by zero -
        # don't draw anything for zero-length edges
        if dist <= 0:
            return

        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        glPushMatrix()

        pigment = edge.color + (alpha,)
        glColor4f(*pigment)

        # Figure out radius boost factor
        x = max(log(40 * edge.radius, 10), 0)

        phi = acos(diff[Z_AXIS] / dist) * 180 / pi
        theta = atan2(diff[Y_AXIS], diff[X_AXIS]) * 180 / pi
        glTranslatef(*srcpos)
        glRotatef(theta, 0.0, 0.0, 1.0)
        glRotatef(phi, 0.0, 1.0, 0.0)
        gluQuadricOrientation(self.quad, GLU_OUTSIDE)
        gluQuadricTexture(self.quad, GL_TRUE)
        gluQuadricDrawStyle(self.quad, GLU_FILL)
        gluQuadricNormals(self.quad, GLU_SMOOTH)
        # glRotated(90, 1, 0, 0)
        gluCylinder(self.quad, edge.radius + x, edge.radius + x, dist, config.current['global:draw-edge-sides'],
                    config.current['global:draw-edge-sides'])

        glPopMatrix()
        glDisable(GL_BLEND)
Example #2
0
    def realPosition(self, camera):
        """
        Figure out the world-space coordinates of this cursor
        relative to the camera given.
        """

        from utilities import mult3D, add3D
        from camera import X_AXIS, Y_AXIS, Z_AXIS

        x = mult3D(camera.yz, self.pos[X_AXIS])
        y = mult3D(camera.up, self.pos[Y_AXIS])
        z = mult3D(camera.vpn, self.pos[Z_AXIS])
        offset = add3D(x, y)
        offset = add3D(offset, z)
        return add3D(offset, camera.pos)
Example #3
0
    def InputPos(self, pos):
        """
        Translate an input device position for the cursor.
        """
        from utilities import add3D, diff3D, mult3D

        self.move = False
        #Initialize jitter last position
        if self.first:
            self.lastPos = self.posMap(*pos)
            self.first = False

        if self.calibrate:
            mapped = self.posMap(*pos)
            offset = mult3D(mapped, self.posScale)
            self.posOrigin = offset
            self.calibrate = False

        if not self.manager.contexts.active:
            return

        # Translate the cursor position for use
        mapped = self.posMap(*pos)
        #Check for jitter
        for i in range(0, 3):
            dif = abs(mapped[i] - self.lastPos[i])
            if dif < float(self.jitter):
                self.move = False or self.move
            else:
                self.move = True
        #Real Movement - not jitter!
        if self.move:
            offset = mult3D(mapped, self.posScale)
            offset = diff3D(self.posOrigin, offset)
            self.manager.contexts.active.cursor.inputPos(offset)
        self.manager.contexts.active.showCursor = True
        self.lastPos = mapped

        # Determine if cursor is below ground plane
        oldStatus = self.manager.contexts.active.HUDstatus
        if self.manager.contexts.active.graph.findGroundPlane() > \
                self.manager.contexts.active.cursor.realPosition( \
                        self.manager.contexts.active.camera)[1]:
            self.manager.contexts.active.HUDstatus = "Cursor below groundplane"
        else:
            if oldStatus == "Cursor below groundplane":
                oldStatus = ""
            self.manager.contexts.active.HUDstatus = oldStatus
Example #4
0
 def useTracker(self):
     """
     camera.useTracker() -> void
     Offsets the camera (should be called after use()) based
     on the current position of the tracker.
     """
     if self.trackPosOffset:
         # Calculate the offset relative to the camera - rather than relative to the world.
         x = mult3D(self.yz, self.trackPosOffset[X_AXIS])
         y = mult3D(self.up, self.trackPosOffset[Y_AXIS])
         z = mult3D(self.vpn, self.trackPosOffset[Z_AXIS])
         offset = add3D(x, y)
         offset = add3D(offset, z)
         GL.glTranslatef(*offset)
     if self.trackRotMatrix:
         GL.glMultMatrix(*self.trackRotMatrix)
Example #5
0
    def vertexWarp(self, vertex, refresh=None):
        """
        Warp to vertex, using the Animator.
        """
        from utilities import add3D, diff3D, mult3D

        offset = add3D(mult3D(self.camera.vpn, -10.0), (0.0, vertex.radius * 3.0, 0.0))

        if self.showGrid:
            npos = utilities.mult3D(vertex.pos, self.spacing)
        else:
            npos = vertex.pos

        targetpos = add3D(npos, offset)

        self.parent.animator.perspCameraMove(self.camera, newPos=targetpos, newLook=npos, duration=1.0)
Example #6
0
    def arrangeStepwise(self, graph, vertices, newPos, duration, wait=0.0, tween=True):
        """
        Arrange the vertices of the graph into a new layout
        specified by an indexed list of new positions newPos.
        The vertices will be positioned one at a time.
        """
        assert (len(newPos) == len(vertices))
        delay = float(duration) / len(vertices)

        from math import floor

        if tween:
            if delay > (1.0 / self.parent.fps):
                # No sense tweening faster than the frame rate can keep up
                stepsPerVert = int(floor(delay / (1.0 / self.parent.fps)))
                totalMove = [diff3D(a, b) for a, b in zip([x.pos for x in vertices], newPos)]
                partialMove = [div3D(x, stepsPerVert) for x in totalMove]
            else:
                tween = False

        accum = wait

        for i in range(len(vertices)):
            if tween:
                accum += delay / stepsPerVert
                for step in range(stepsPerVert - 1):
                    self.post(accum,
                              objects=(
                              vertices[i],
                              ),
                              props=(
                              (
                              'pos',
                              add3D(vertices[i].pos, mult3D(partialMove[i], (step + 1))),
                              ),
                              ),
                              changeGraph=graph,
                    )
                    accum += delay / stepsPerVert
            else:
                accum += delay
            self.post(accum,
                      objects=(
                      vertices[i],
                      ),
                      props=(
                      ('pos', newPos[i]),
                      ),
                      changeGraph=graph,
            )

        self.signal()
Example #7
0
    def lookAt(self, target, refresh=None):
        """
        Re-point the current camera to look at some object in the graph.
        Target can be:
        - a position in 3-space expressed as a 3-tuple of floats
        - a Vertex object
        - an Edge object (will look at the midpoint)
        """

        if isinstance(target, Vertex):
            if self.showGrid:
                tgt = target
                tgt.pos = utilities.mult3D(target.pos, self.spacing)
            else:
                tgt = target
        elif isinstance(target, Edge):
            if self.showGrid:
                tgt = target
                tgt.source.pos = utilities.mult3D(target.source.pos, self.spacing)
                tgt.target.pos = utilities.mult3D(target.target.pos, self.spacing)
            else:
                tgt = target
        elif self.showGrid:
            tgt = utilities.mult3D(target, self.spacing)
        else:
            tgt = target

        if self.orthoMode:
            # XXX# Do something
            pass
        else:
            self.parent.animator.perspCameraMove(
                camera=self.camera,
                newLook=tgt,
                duration=1.2,
            )
Example #8
0
    def InputPos(self, pos):
        """
        Translate an input device position for the cursor.
        """
        from utilities import add3D, diff3D, mult3D
        #Camera jitter: no move to start
        self.move = False
        #Initiate jitter last position
        if self.first:
            self.lastPos = self.posMap(*pos)
            self.first = False
            print "jitter:", self.jitter
        if self.calibrate:
            mapped = self.posMap(*pos)
            offset = mult3D(mapped, self.posScale)
            self.posOrigin = offset
            self.calibrate = False

        if not self.manager.contexts.active:
            return

        # Translate the cursor position for use
        mapped = self.posMap(*pos)
        #Check for jitter
        for i in range(0, 3):
            dif = abs(mapped[i] - self.lastPos[i])
            if dif < float(self.jitter):
                self.move = False or self.move
            else:
                self.move = True
        #Real Movement - not jitter!
        if self.move:
            offset = mult3D(mapped, self.posScale)
            offset = diff3D(self.posOrigin, offset)
            self.manager.contexts.active.camera.inputTrackPos(offset)
        self.lastPos = mapped
Example #9
0
    def perspCameraLookatMove(self, camera, newPos, fixLook, duration, wait=0.0):
        """
        Moves the camera smoothly to a new position and orientation.
        If newLook is None, does not change the orientation of the camera.
        If newPos is None, does not change the position of the camera.
        """
        from camera import Camera, OrthoCamera, X_AXIS, Y_AXIS, Z_AXIS

        assert (not isinstance(camera, OrthoCamera))

        fixLook = self.normalizePos(fixLook)
        steps = int(duration * self.parent.fps)

        deltaPos = diff3D(camera.pos, newPos)
        stepPos = div3D(deltaPos, steps)

        accum = wait
        delay = 1.0 / self.parent.fps

        # Set up the animation
        for i in range(steps - 1):
            accum += delay

            self.post(accum,
                      objects=(camera,),
                      props=(
                      ( 'pos', add3D(camera.pos, mult3D(stepPos, i + 1)) ),
                      ( 'lookAt', fixLook),
                      ),
                      call=(
                      ('absrotate', (Y_AXIS, stepYaw), {}),
                      ('rotate', (X_AXIS, stepPitch), {}),
                      ),
            )

        # Finish up in the correct place
        accum += delay
        self.post(accum,
                  objects=(camera,),
                  props=(
                  ('pos', newPos),
                  ('lookAt', fixLook),
                  ),
        )

        self.signal()
Example #10
0
    def arrangeMorph(self, graph, vertices, newPos, duration, wait=0.0):
        """
        Arrange the vertices of the graph into a new layout
        specified by an indexed list of new positions newPos.
        The vertices will be positioned simultaneously (smooth morph)
        """
        assert (len(newPos) == len(vertices))

        accum = wait

        steps = int(duration * self.parent.fps)
        delay = 1.0 / self.parent.fps

        d = [div3D(diff3D(a.pos, b), steps) for a, b in zip(vertices, newPos)]

        for i in range(steps - 1):
            accum += delay
            self.post(accum,
                      objects=vertices,
                      multiprops=(
                      (
                      'pos',
                      [add3D(a.pos, mult3D(b, i + 1)) for a, b in zip(vertices, d)]
                      ),
                      ),
                      changeGraph=graph,
            )

        accum += delay
        self.post(accum,
                  objects=vertices,
                  multiprops=(
                  ('pos', newPos),
                  ),
                  changeGraph=graph,
        )
        self.signal()
Example #11
0
    def drawVertex(self, vertex, alpha=1.0):
        """
        draw a vertex in 3D
        """
        glPushMatrix()

        if config.current['global:enable-anaglyph']:
            pigment = (1.0, 1.0, 1.0, 1.0)
        else:
            pigment = vertex.color + (alpha,)

        glColor4f(*pigment)

        # For Netcli (has no parent)
        showG = False
        ctx = self.graph.parent
        if not ctx == None:
            if ctx.showGrid:
                showG = True

        if showG:
            vrtpos = utilities.mult3D(vertex.pos, ctx.spacing)
        else:
            vrtpos = vertex.pos

        glTranslatef(vrtpos[0], vrtpos[1], vrtpos[2])

        # glutSolidSphere(vertex.radius, config.current['global:draw-sphere-slices'], config.current['global:draw-sphere-stacks'])
        gluQuadricOrientation(self.quad, GLU_OUTSIDE)
        gluQuadricTexture(self.quad, GL_TRUE)
        gluQuadricDrawStyle(self.quad, GLU_FILL)
        gluQuadricNormals(self.quad, GLU_SMOOTH)
        glRotated(90, 1, 0, 0)
        gluSphere(self.quad, vertex.radius, config.current['global:draw-sphere-slices'],
                  config.current['global:draw-sphere-stacks'])

        glPopMatrix()
Example #12
0
    def drawVertexSelection(self, vertex, alpha=0.6):
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        glPushMatrix()

        pigment = vertex.color + (alpha,)
        glColor4f(*pigment)

        ctx = self.graph.parent
        # For Netcli (has no parent)
        showG = False
        if not ctx == None:
            if ctx.showGrid:
                showG = True
        if showG:
            vrtpos = utilities.mult3D(vertex.pos, ctx.spacing)
        else:
            vrtpos = vertex.pos

        glTranslatef(vrtpos[0], vrtpos[1], vrtpos[2])
        if vertex.radius > 0:
            x = max(log(40 * vertex.radius, 10), 0)
        else:
            x = 1

            #    glutSolidSphere(vertex.radius + x, config.current['global:draw-sphere-slices'], config.current['global:draw-sphere-stacks'])
        gluQuadricOrientation(self.quad, GLU_OUTSIDE)
        gluQuadricTexture(self.quad, GL_TRUE)
        gluQuadricDrawStyle(self.quad, GLU_FILL)
        gluQuadricNormals(self.quad, GLU_SMOOTH)
        glRotated(90, 1, 0, 0)
        gluSphere(self.quad, vertex.radius + x, config.current['global:draw-sphere-slices'],
                  config.current['global:draw-sphere-stacks'])

        glPopMatrix()
        glDisable(GL_BLEND)
Example #13
0
    def drawEdge(self, edge, alpha=1.0):
        """
        draw an edge in 3D.
        """

        # Superedge drawing is a no-op - all the parts will already have been
        # drawn.
        if isinstance(edge, SuperEdge):
            return

        if config.current['global:enable-anaglyph']:
            pigment = (1.0, 1.0, 1.0, alpha)
        else:
            pigment = edge.color + (alpha,)

        glColor4f(*pigment)

        # For Netcli (has no parent)
        ctx = self.graph.parent
        showG = False
        if not ctx == None:
            if ctx.showGrid:
                showG = True
        if showG:
            srcpos = utilities.mult3D(edge.source.pos, ctx.spacing)
            tgtpos = utilities.mult3D(edge.target.pos, ctx.spacing)
        else:
            srcpos = edge.source.pos
            tgtpos = edge.target.pos

        if config.current['global:draw-edge-cylinders']:
            diff = utilities.diff3D(srcpos, tgtpos)
            dist = utilities.dist3D(c=diff)

            # Avoid dividing by zero -
            # don't draw anything for zero-length edges
            if dist <= 0:
                return

            glPushMatrix()

            phi = acos(diff[Z_AXIS] / dist) * 180 / pi
            theta = atan2(diff[Y_AXIS], diff[X_AXIS]) * 180 / pi
            glTranslatef(*srcpos)
            glRotatef(theta, 0.0, 0.0, 1.0)
            glRotatef(phi, 0.0, 1.0, 0.0)
            gluQuadricOrientation(self.quad, GLU_OUTSIDE)
            gluQuadricTexture(self.quad, GL_TRUE)
            gluQuadricDrawStyle(self.quad, GLU_FILL)
            gluQuadricNormals(self.quad, GLU_SMOOTH)
            #glRotated(90, 1, 0, 0)
            gluCylinder(self.quad, edge.radius, edge.radius, dist, config.current['global:draw-edge-sides'],
                        config.current['global:draw-edge-sides'])
            glPopMatrix()

        else:  # not drawing edges as cylinders
            glDisable(GL_LIGHTING)
            glEnable(GL_LINE_SMOOTH)
            glLineWidth(config.current['global:draw-edge-linewidth'])
            glBegin(GL_LINES)
            glVertex3f(srcpos[0], srcpos[1], srcpos[2])
            glVertex3f(tgtpos[0], tgtpos[1], tgtpos[2])
            glEnd()
            glEnable(GL_LIGHTING)
Example #14
0
    def draw(self, edgeNameBase=None, vertNameBase=None):
        """Draw the elements of this context on the current GL canvas."""

        if not self.ready:
            self.init()

        # Set up the camera
        if self.orthoMode:
            activecam = self.orthocamera
        else:
            activecam = self.camera

        activecam.use()
        # Apply the tracker offsets.
        activecam.useTracker()

        if self.graph.vertices_selected:
            orbitCentre = self.graph.vertices_selected[0]
        else:
            orbitCentre = self.graph.centerOfMass()
        # Multiply points if snapping to grid
        if self.showGrid:
            ocp = utilities.mult3D(orbitCentre.pos, self.spacing)
        else:
            ocp = orbitCentre.pos

        if config.current['global:camera-orbit'] == "cw":
            self.camera.absorbit(ocp, Y_AXIS, -1)
        elif config.current['global:camera-orbit'] == "ccw":
            self.camera.absorbit(ocp, Y_AXIS, 1)


        # Only draw decorations if we're in render mode - not in
        # selection mode.
        if glGetInteger(GL_RENDER_MODE) == GL_RENDER:
            # Draw the ground plane if it's enabled, but not when we're
            # using ortho mode
            glEnable(GL_CULL_FACE)
            if self.showPlane and not self.orthoMode:
                self.decor.drawGroundPlane(height=self.graph.findGroundPlane(), color=self.planeColor,
                                           reference=self.camera.pos)
        #
        # Draw the graph
        #
        glEnable(GL_TEXTURE_2D)
        self.graphgl.draw(edgeNameBase=edgeNameBase, vertNameBase=vertNameBase)

        #
        # Draw A grid if the user wants one
        #
        if self.showGridLines:
            self.decor.drawGrid(parent=self, pos=self.pos, sizeX=self.sizeX, sizeY=self.sizeY, sizeZ=self.sizeZ,
                                spacing=self.spacing)

        # Only draw decorations if we're in render mode - not in
        # selection mode.
        if glGetInteger(GL_RENDER_MODE) == GL_RENDER:
            glEnable(GL_CULL_FACE)
            # Draw the coordinate axes if they're enabled
            if self.showAxes:
                self.decor.drawAxes()

                # Draw local axes if required
                # print "window:",wx.Window.FindFocus(), "\n canvas:", self.parent.canvas
            showA = False
            if not self.parent == None:
                if wx.Window.FindFocus() == self.parent.canvas:
                    showA = True

            if self.showLocalAxes and showA:
                localAxes = (X_AXIS, Y_AXIS, Z_AXIS)
                labels = ('Q', 'A', 'W', 'S', 'E', 'D')
                if self.orthoMode:
                    if self.orthoMode[0] == X_AXIS:
                        localAxes = (Y_AXIS, Z_AXIS)
                        if self.orthoMode[1] > 0:
                            labels = (None, None, 'W', 'S', 'D', 'A')
                        else:
                            labels = (None, None, 'W', 'S', 'A', 'D')
                    elif self.orthoMode[0] == Y_AXIS:
                        localAxes = (X_AXIS, Z_AXIS)
                        if self.orthoMode[1] > 0:
                            labels = ('A', 'D', None, None, 'S', 'W')
                        else:
                            labels = ('D', 'A', None, None, 'S', 'W')
                    elif self.orthoMode[0] == Z_AXIS:
                        localAxes = (X_AXIS, Y_AXIS)
                        if self.orthoMode[1] > 0:
                            labels = ('A', 'D', 'W', 'S', None, None)
                        else:
                            labels = ('D', 'A', 'W', 'S', None, None)

                for v in self.graph.vertices_selected:
                    if v.hidden:
                        continue
                    self.decor.draw_localaxes(self, v, axes=localAxes, labels=labels)

            # Draw vertex labels if selected.
            if self.showVertexLabels:
                if self.showDummyLabels:
                    vxlist = self.graph.vertices
                else:
                    vxlist = [x for x in self.graph.vertices if not isinstance(x, DummyVertex)]
                if len(vxlist) > 0:
                    if self.vertexLabelName:
                        labelFunc = lambda v: str(v.name)
                    else:
                        labelFunc = lambda v: str(v.id)
                    self.decor.drawVertexLabels(parent=self, vxlist=vxlist, labelFunc=labelFunc,
                                                labelStrokeWidth=self.vertexLabelStroke,
                                                labelColor=self.vertexLabelColor, shadowColor=self.vertexShadowColor)

            if self.showHUD:
                if self.showCursor:
                    self.decor.drawHUD(activecam, self.graph.vertices_selected, pos=self.cursor.realPosition(activecam),
                                       status=self.HUDstatus)
                else:
                    self.decor.drawHUD(activecam, self.graph.vertices_selected, status=self.HUDstatus)

            if self.showCursor:
                # First, draw the local grid around the cursor position.
                #		self.decor.drawLocalGrid(pos = self.cursor.realPosition(activecam), size=1, spacing=5.0, snap=5.0)
                glEnable(GL_CULL_FACE)
                glDisable(GL_TEXTURE_2D)
                glDisable(GL_POLYGON_SMOOTH)

                self.decor.drawCursor(camera=activecam, cursor=self.cursor)

            for d in self.drawList.values():
                d.draw()
Example #15
0
    def perspCameraMove(self, camera, newPos=None, newLook=None, duration=1.0, wait=0.0):
        """
        Moves the camera smoothly to a new position and orientation.
        If newLook is None, does not change the orientation of the camera.
        If newPos is None, does not change the position of the camera.
        """
        from camera import Camera, OrthoCamera, X_AXIS, Y_AXIS, Z_AXIS

        assert (not isinstance(camera, OrthoCamera))

        newCam = Camera()
        if newPos != None:
            newCam.pos = self.normalizePos(newPos)
        else:
            newCam.pos = camera.pos
        if newLook != None:
            newCam.lookAt = self.normalizePos(newLook)
        else:
            newCam.lookAt = camera.lookAt

        steps = int(duration * self.parent.fps)

        (oldTheta, oldPhi) = camera.polar()
        (newTheta, newPhi) = newCam.polar()

        deltaYaw = newTheta - oldTheta
        deltaPitch = newPhi - oldPhi
        deltaPos = diff3D(camera.pos, newCam.pos)

        # Check to make sure we're coming around the short side
        if deltaYaw > 180.0:
            deltaYaw = deltaYaw - 360.0
        elif deltaYaw < -180.0:
            deltaYaw = deltaYaw + 360.0
        print "DeltaYaw", deltaYaw

        stepYaw = deltaYaw / steps
        stepPitch = deltaPitch / steps
        stepPos = div3D(deltaPos, steps)

        accum = wait
        delay = 1.0 / self.parent.fps

        # Set up the animation
        for i in range(steps - 1):
            accum += delay

            self.post(accum,
                      objects=(
                      camera,
                      ),
                      props=(
                      (
                      'pos',
                      add3D(camera.pos, mult3D(stepPos, i + 1)),
                      ),
                      ),
                      call=(
                      ('absrotate', (Y_AXIS, stepYaw), {}),
                      ('rotate', (X_AXIS, stepPitch), {}),
                      ),
            )

        # Finish up in the correct place
        accum += delay
        self.post(accum,
                  objects=(camera,),
                  props=(
                  ('pos', newCam.pos),
                  ('lookAt', newCam.lookAt),
                  ),
        )

        self.signal()
Example #16
0
    def drawVertexLabels(self, parent, vxlist, labelFunc, labelStrokeWidth, labelColor, shadowColor):
        """
        drawVertexLabels(vxlist, labelFunc, labelStrokeWidth, labelColor, shadowColor) -> void
        Draws labels for vertices in vxlist on an ortho projection layer.

        labelStrokeWidth: A float controlling the strokewidth for the label text.
        labelColor: A 3-tuple float color: the label text
        shadowColor: A 3-tuple float color: the label shadow
        labelFunc: A function that takes a vertex object and returns some value to use as the label for the vertex.
        """
        # model = glGetFloat(GL_MODELVIEW_MATRIX)
        model = glGetDouble(GL_MODELVIEW_MATRIX)
        proj = glGetDouble(GL_PROJECTION_MATRIX)
        view = glGetInteger(GL_VIEWPORT)
        coords = range(len(vxlist))
        ctx = parent

        for vnum in range(len(vxlist)):
            v = vxlist[vnum]
            # Multiply points if snapping to grid
            if ctx.showGrid:
                vpos = utilities.mult3D(v.pos, ctx.spacing)
            else:
                vpos = v.pos
            #print "not projected:", vpos
            coords[vnum] = gluProject(vpos[0], vpos[1], vpos[2], model, proj, view)

        # Switch to an orthogonal projection for drawing the labels
        glDisable(GL_LIGHTING)
        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()
        glOrtho(view[0], view[2], view[1], view[3], 0.0, 1.0)
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        glLineWidth(labelStrokeWidth)
        glDisable(GL_LINE_SMOOTH)
        gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

        # Unproject the screen coordinates into the new ortho projection
        model = glGetDouble(GL_MODELVIEW_MATRIX)
        proj = glGetDouble(GL_PROJECTION_MATRIX)
        view = glGetInteger(GL_VIEWPORT)

        for vnum in range(len(vxlist)):
            v = vxlist[vnum]
            label = str(labelFunc(v))
            if len(label) < 1 or v.hidden:
                continue

            x, y, z = coords[vnum]
            #print "BEFORE:", label, "at:", x, y, z
            trX, trY, trZ = gluUnProject(x, y, z, model, proj, view)
            #print "After:", label, "at:", trX, trY, trZ
            # Because we flatten the Z coordinate in the ortho project,
            # we have to manually discard Things Behind Us
            if trZ < 0.0:
                continue

            glPushMatrix()

            glTranslatef(trX, trY, 0.5)

            x = min(12.0 * trZ, 0.20)
            glScalef(x, x, x)
            offset = len(label) % 2 * -50.0 + -50.0 * (len(label) - 1)
            glTranslatef(offset, 0.0, 0.0)
            glTranslatef(0.0, 0.0, 0.0)

            # Draw the shadow
            glColor4f(shadowColor[0], shadowColor[1], shadowColor[2], 1.0)
            glPushMatrix()
            glTranslatef(7.5, -7.5, -0.5)
            for c in label:
                glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c))
            glPopMatrix()

            # Draw the label
            glColor4f(labelColor[0], labelColor[1], labelColor[2], 1.0)
            glPushMatrix()
            for c in label:
                glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c))
            glPopMatrix()

            glPopMatrix()

        glPopMatrix()
        glMatrixMode(GL_PROJECTION)
        glPopMatrix()
        glMatrixMode(GL_MODELVIEW)
        glEnable(GL_LIGHTING)
Example #17
0
    def onKey(self, evt):
        # Check to see if we have a valid context
        from utilities import mult3D

        ctx = self.parent.contexts.active
        if not ctx:
            evt.Skip()
            return
        # Mac compatibility: keycode is int.
        try:
            key = evt.KeyCode()
        except:
            key = evt.KeyCode
        print 'keycode:', key

        # Regular camera movement controls
        if not ctx.orthoMode:
            if ctx.graph.vertices_selected:
                orbitCentre = ctx.graph.vertices_selected[0]
            else:
                orbitCentre = ctx.graph.centerOfMass()
            # Multiply points if snapping to grid
            if ctx.showGrid:
                ocp = mult3D(orbitCentre.pos, ctx.spacing)
            else:
                ocp = orbitCentre.pos

            # Directional keys
            #
            if key == wx.WXK_LEFT:
                if evt.ShiftDown():
                    ctx.camera.absorbit(ocp, camera.Y_AXIS, -1)
                else:
                    if config.current['global:fly-mode']:
                        ctx.camera.rotate(camera.Y_AXIS, 1)
                    else:
                        ctx.camera.move(camera.X_AXIS, -1)
            elif key == wx.WXK_RIGHT:
                if evt.ShiftDown():
                    ctx.camera.absorbit(ocp, camera.Y_AXIS, 1)
                else:
                    if config.current['global:fly-mode']:
                        ctx.camera.rotate(camera.Y_AXIS, -1)
                    else:
                        ctx.camera.move(camera.X_AXIS, 1)
            elif key == wx.WXK_UP:
                if evt.ShiftDown():
                    ctx.camera.absmove(camera.Y_AXIS, 1)
                else:
                    ctx.camera.move(camera.Z_AXIS, 1)
            elif key == wx.WXK_DOWN:
                if evt.ShiftDown():
                    ctx.camera.absmove(camera.Y_AXIS, -1)
                else:
                    ctx.camera.move(camera.Z_AXIS, -1)

            #
            # Roll keys
            #
            elif key == ord(','):
                ctx.camera.rotate(camera.Z_AXIS, -1)
            elif key == ord('.'):
                ctx.camera.rotate(camera.Z_AXIS, 1)

            #
            # Normalize
            #
            elif key == ord('n') or key == ord('N'):
                ctx.camera.up = (0.0, 1.0, 0.0)

            #
            # Delete
            #
            elif key == wx.WXK_DELETE:
                if len(ctx.graph.vertices_selected) > 0:
                    self.parent.sidebar.OnVertexDelete(evt)
                if len(ctx.graph.edges_selected) > 0:
                    edge = ctx.graph.edges_selected[0]
                    if isinstance(edge.source, graph.DummyVertex) or isinstance(edge.target, graph.DummyVertex):
                        self.parent.sound.Error()
                    else:
                        self.parent.sidebar.OnEdgeDelete(evt)
            #
            # Vertex movement keys
            #
            elif key == ord('q') or key == ord('Q'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.X_AXIS, 1)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('a') or key == ord('A'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.X_AXIS, -1)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('w') or key == ord('W'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.Y_AXIS, 1)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('s') or key == ord('S'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.Y_AXIS, -1)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('e') or key == ord('E'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.Z_AXIS, 1)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('d') or key == ord('D'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v, 'shift').shift(graph.Z_AXIS, -1)
                    self.parent.sidebar.UpdateVertexPanel()

            # Undo / Redo Keys
            elif key == 26:
                print "shift down:", evt.ShiftDown()
                print "Stack size:", len(ctx.UndoStack.stack)
                if not evt.ShiftDown():
                    if ctx.UndoStack.stack:
                        print "Undo\n"
                        ctx.UndoStack.pop(ctx.RedoStack)
                    else:
                        self.parent.sound.Error()
                else:
                    if ctx.RedoStack.stack:
                        print "Redo\n"
                        ctx.RedoStack.pop(ctx.UndoStack)
                    else:
                        self.parent.sound.Error()

            #
            # Debugging keys
            #
            elif key == ord('z'):

                if ctx.graph.consistencyCheck():
                    print >> stderr, "Consistency check passed."
            elif key == ord('Z'):
                if evt.m_controlDown and evt.ShiftDown():
                    ctx.RedoStack.pop()
                    return
                ctx.graph.dump()
                print "Theta, Phi:", ctx.camera.polar()
            elif key == ord('x'):
                def ref_func():
                    # Yield to let the graph canvas refresh itself.
                    wx.Yield()

                if ctx.graph.vertices_selected:
                    ctx.vertexWarp(ctx.graph.vertices_selected[0], refresh=ref_func)
                else:
                    print >> stderr, "Nothing selected, not warping."
            elif key == ord('c'):
                self.vergence = self.vergence - 0.10
                glMatrixMode(GL_PROJECTION)
                glLoadIdentity()
                self.resizeProjection()
            elif key == ord('v'):
                self.vergence = self.vergence + 0.10
                glMatrixMode(GL_PROJECTION)
                glLoadIdentity()
                self.resizeProjection()
            elif key == ord('p'):
                self.parent.inputmgr.calibrateAll()
                print "calibrating!"
            elif key == ord('y'):
                self.parent.inputmgr.wandaInput2D(0, 20)
            elif key == ord('h'):
                self.parent.inputmgr.wandaInput2D(0, -20)
            elif key == ord('j'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonLeft(BUT_DOWN)
            elif key == ord('J'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonLeft(BUT_UP)
            elif key == ord('k'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonMid(BUT_DOWN)
            elif key == ord('K'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonMid(BUT_UP)
            elif key == ord('l'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonRight(BUT_DOWN)
            elif key == ord('L'):
                from flock import BUT_UP, BUT_DOWN

                self.parent.inputmgr.wandaButtonRight(BUT_UP)

            # Rotate around center of mass
            elif key == ord('O'):
                if config.current['global:camera-orbit'] == "cw":
                    config.current['global:camera-orbit'] = "ccw"
                elif config.current['global:camera-orbit'] == "ccw":
                    config.current['global:camera-orbit'] = None
                else:
                    config.current['global:camera-orbit'] = "cw"

            else:
                evt.Skip()
                return

        # Ortho camera movement controls.
        else:
            flipLR = 1
            flipUD = 1
            if ctx.orthoMode[0] == camera.X_AXIS:
                axisLR = camera.Z_AXIS
                axisUD = camera.Y_AXIS
                if ctx.orthoMode[1] < 0:
                    flipLR = -1
            elif ctx.orthoMode[0] == camera.Y_AXIS:
                axisLR = camera.X_AXIS
                axisUD = camera.Z_AXIS
                flipUD = -1
            elif ctx.orthoMode[0] == camera.Z_AXIS:
                axisLR = camera.X_AXIS
                axisUD = camera.Y_AXIS
                if ctx.orthoMode[1] > 0:
                    flipLR = -1

            if key == wx.WXK_LEFT:
                ctx.orthocamera.move(camera.X_AXIS, -1)
            elif key == wx.WXK_RIGHT:
                ctx.orthocamera.move(camera.X_AXIS, 1)
            elif key == wx.WXK_UP:
                if evt.ShiftDown():
                    ctx.orthocamera.move(camera.Z_AXIS, 1)
                else:
                    ctx.orthocamera.move(camera.Y_AXIS, 1)
            elif key == wx.WXK_DOWN:
                if evt.ShiftDown():
                    ctx.orthocamera.move(camera.Z_AXIS, -1)
                else:
                    ctx.orthocamera.move(camera.Y_AXIS, -1)
            elif key == ord('w') or key == ord('W'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v).shift(axisUD, 1 * flipUD)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('s') or key == ord('S'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v).shift(axisUD, -1 * flipUD)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('a') or key == ord('A'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v).shift(axisLR, -1 * flipLR)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('d') or key == ord('D'):
                for v in ctx.graph.vertices_selected:
                    ctx.graph.modVertex(v).shift(axisLR, 1 * flipLR)
                    self.parent.sidebar.UpdateVertexPanel()
            elif key == ord('x'):
                def ref_func():
                    # Yield to let the graph canvas refresh itself.
                    wx.Yield()

                if ctx.graph.vertices_selected:
                    ctx.vertexWarp(ctx.graph.vertices_selected[0], refresh=ref_func)
                else:
                    print >> stderr, "Nothing selected, not warping."
            else:
                evt.Skip()
                return