Example #1
0
 def pick(self, x, y, viewer):
     if viewer.getSceneData():
         if self.usePolytopeIntersector():
             picker = osgUtil.PolytopeIntersector(osgUtil.Intersector.WINDOW, x - 2.0, y - 2.0, x + 2.0, y + 2.0)
         else:
             picker = osgUtil.LineSegmentIntersector(osgUtil.Intersector.WINDOW, x, y)
         intersectionVisitor = osgUtil.IntersectionVisitor(picker)
         viewer.getCamera().accept(intersectionVisitor)
         if picker.containsIntersections():
             intersections = picker.getIntersections()
             
             # The PolytopeIntersector mis-calculates the eye distance for geometry nested under a transform, which is true for all UnitShapes.  (See the thread at http://www.mail-archive.com/[email protected]/msg29195.html for some discussion.)
             # Calculate the correct distance and re-sort.
             # This will probably still work correctly after that bug is fixed but will be inefficient.
             visibleHits = []
             eye, center, up = (osg.Vec3(), osg.Vec3(), osg.Vec3())
             viewer.getCamera().getViewMatrixAsLookAt(eye, center, up)
             eye = (eye.x(), eye.y(), eye.z())
             for i in range(0, len(intersections)):
                 intersection = intersections[i]
                 for j in range(0, len(intersection.nodePath)):
                     node = intersection.nodePath[j]
                     geode = osg.NodeToGeode(node)
                     if geode != None:
                         visibleID = int(geode.getName())
                         visible = self._display.visibleWithId(visibleID)
                         if geode.getOrCreateStateSet().getAttribute(osg.StateAttribute.DEPTH):
                             # If a geode has this attribute set then (currently) it is being rendered in front of all other nodes.  Simulate this here by placing the geode right at the eye.
                             # If depths other than the default or osg.Depth.ALWAYS are used in the future then this check will need to be modified.
                             eyeDistance = 0.0
                         else:
                             intersectionPoint = intersection.localIntersectionPoint
                             if isinstance(visible.shape(), UnitShape):
                                 position = visible.worldPosition()
                                 size = visible.worldSize()
                                 intersectionPoint = (position[0] + size[0] * intersectionPoint.x(), position[1] + size[1] * intersectionPoint.y(), position[2] + size[2] * intersectionPoint.z())
                             eyeDistance = (intersectionPoint[0] - eye[0]) ** 2 + (intersectionPoint[1] - eye[1]) ** 2 + (intersectionPoint[2] - eye[2]) ** 2
                         visibleHits += [(eyeDistance, visible)]
             visibleHits.sort()
             
             # Loop through all of the hits to find the "deepest" one in the sense of the visible hierarchy.  For example, a neuron in a region will be picked instead of the region even though the region hit is closer.
             if self._display.useGhosts():
                 # Make a first pass only picking non-ghosted items.
                 # TODO: this could be done with node masks...
                 deepestVisible = None
                 for distance_, visible in visibleHits:
                     if (visible in self._display.highlightedVisibles or visible in self._display.animatedVisibles) and (deepestVisible is None or deepestVisible in visible.ancestors()):
                         deepestVisible = visible
                 if deepestVisible is not None:
                     self._display.selectVisibles([deepestVisible], self._display.selectionShouldExtend, self._display.findShortestPath, fromclick=True)
                     return True
             deepestVisible = None
             for distance_, visible in visibleHits:
                 if deepestVisible is None or deepestVisible in visible.ancestors():
                     deepestVisible = visible
             self._display.selectVisibles([deepestVisible], self._display.selectionShouldExtend, self._display.findShortestPath, fromclick=True)
         else:
             self._display.selectVisibles([])
     return True
def createWireBox(node):
    """create a bounding box for the node """

    #create an empty bounding box
    bb = osg.BoundingBox()

    #if we have a geode, expand by the drawables bounding box, else use the bounding sphere
    geode = osg.NodeToGeode(node)
    if geode:
        print "geode found"
        for i in range(geode.getNumDrawables()):
            dwb = geode.getDrawable(0)
            bb.expandBy(dwb.getBound())
    else:
        bb.expandBy(node.getBound())

    center = node.getBound().center()

    #create a geode for the wirebox
    wbgeode = osg.Geode()
    wbgeode.setName("ExtentsGeode")

    #create a stateset for the wirebox
    stateset = osg.StateSet()
    wbgeode.setStateSet(stateset)
    #    stateset.thisown = 0

    #create a polygonmode state attribute
    polyModeObj = osg.PolygonMode()
    polyModeObj.setMode(osg.PolygonMode.FRONT_AND_BACK, osg.PolygonMode.LINE)
    stateset.setAttribute(polyModeObj)

    #create a linewidth state attribute
    lw = osg.LineWidth()
    lw.setWidth(2.0)
    stateset.setAttribute(lw)

    stateset.setAttribute(selmat)

    #create a drawablw box with the right position and size
    lx = bb._max.x() - bb._min.x()
    ly = bb._max.y() - bb._min.y()
    lz = bb._max.z() - bb._min.z()
    box = osg.Box(center, lx, ly, lz)
    shape = osg.ShapeDrawable(box)
    #shape.setColor(osg.Vec4(1.0, 0.0, 0.0, 1.0))

    #add the drawable to the wirebox geode
    wbgeode.addDrawable(shape)

    for pointer in [stateset, box, polyModeObj, lw, shape]:
        pointer.thisown = False

    #return the wirebox geode
    print "returning geode"
    return wbgeode
Example #3
0
 def pick(self, x, y, viewer):
     print "Picking"
     if not viewer.getSceneData():
         return False
     #create an intersector
     picker = osgUtil.LineSegmentIntersector(osgUtil.Intersector.PROJECTION,
                                             x, y)
     #create an intersectionVisitor
     iv = osgUtil.IntersectionVisitor(picker)
     #visit the sceneGraph
     viewer.getCamera().accept(iv)
     #check for intersections
     if picker.containsIntersections():
         print "Intersection Found"
         intersection = picker.getFirstIntersection()
         #find the first Transform node and make it the selected node
         for node in intersection.nodePath:
             mt = osg.NodeToMatrixTransform(node)
             if mt:
                 #if there is a previous selected node, 'deselect' it
                 if self._selectedNode:
                     self._selectedNode.setUpdateCallback(
                         osg.NodeCallback())
                     #remove the wirebox of the previous selection
                     if self.wb:
                         self._selectedNode.removeChild(self.wb)
                 self._selectedNode = mt
                 #show that the node is selected
                 mt.setUpdateCallback(RotateCB().__disown__())
             else:
                 pot = osg.NodeToPositionAttitudeTransform(node)
                 if pot:
                     #if there is a previous selected node, 'deselect' it
                     if self._selectedNode:
                         self._selectedNode.setUpdateCallback(None)
                         #remove the wirebox of the previous selection
                         if self.wb:
                             self._selectedNode.removeChild(self.wb)
                     self._selectedNode = pot
                     #show that the node is selected
                     pot.setUpdateCallback(RotateCB().__disown__())
                 else:
                     geode = osg.NodeToGeode(node)
                     if geode:
                         #create a wirebox and safe it, the wire box
                         #will be attached to the parental transform node
                         self.wb = createWireBox(geode)
                         self._selectedNode.addChild(self.wb)
                         self.wb.thisown = False
                         return True
         return False
     else:
         print "No Intersection Found"
     return False