예제 #1
0
    def calculateViewPlane(self, reptrans, planename=None, imgxi=0):
        '''
        Return the transform object representing the plane in space named by `planename' or by `reptrans' alone if
        this isn't provided. If `planename' names a representation object then its transform is used to define the
        plane, specifically if its a ImageSceneObjectRepr then getDefinedTransform() is called to get this transform.
        If `planename' is one of the standard plane names (XY, YZ, or XZ) then the transform is defined to represent
        this plane at image xi value `imgxi' in the direction normal to the plane (ie. this is Z axis xi value for
        plane XY). The `reptrans' transform represents the transformation from xi space to world of the object the
        plane bisects, thus if the object is a volume this is the transformation from texture coordinates to world
        coordinates. This used to transform the standard plane definitions to world coordinates, and to define the
        resulting transform if `planename' names neither a representation object nor a standard plane. The return
        value is a transform in world space with a (1,1,1) scale component.
        '''
        planerep = self.mgr.findObject(planename)

        if planerep != None:
            if isinstance(planerep, ImageSceneObjectRepr):
                planetrans = planerep.getDefinedTransform()
                planetrans.setScale(vec3(1))
            else:
                planept = planerep.getPosition(True)
                planerot = rotator(*planerep.getRotation(True))
                planetrans = transform(
                    planept - (planerot * vec3(0, 0, self.planeShift)),
                    vec3(1), planerot)
        elif self.isStdPlaneName(planename):
            xi = clamp(imgxi, epsilon * 100, 1.0 - epsilon * 100)

            # choose xi values in the volume representing the plane's center, normal, and right-hand direction
            if planename == 'XY':
                xipos = vec3(0.5, 0.5, xi)
                xinorm = xipos + vec3(0, 0, 1)
                xiright = xipos + vec3(1, 0, 0)
            elif planename == 'YZ':
                xipos = vec3(xi, 0.5, 0.5)
                xinorm = xipos + vec3(1, 0, 0)
                xiright = xipos + vec3(0, 1, 0)
            else:  # XZ
                xipos = vec3(0.5, xi, 0.5)
                xinorm = xipos + vec3(0, 1, 0)
                xiright = xipos + vec3(1, 0, 0)

            # calculate a world position and rotation by applying the transform to the xi values
            planept = reptrans * xipos
            planerot = rotator((reptrans * xiright) - planept,
                               (reptrans * xinorm) - planept, vec3(1, 0, 0),
                               vec3(0, 0, 1))
            planetrans = transform(planept, vec3(1), planerot)
        else:
            planetrans = transform(reptrans.getTranslation(), vec3(1),
                                   reptrans.getRotation())

        return planetrans
예제 #2
0
 def getBBTransform(self):
     '''
     Returns the boundbox transform which adjusts the figures to fit inside the selected viewing area based on the 
     scene bound box, scroll, and zoom parameters.
     '''
     bbw, bbh, bbd = self.sceneBB.getDimensions()
     bscale = self.getBoxFitScale(bbw, bbh)
     return transform(self.scroll - self.sceneBB.center * bscale,
                      vec3(self.zoom * bscale, self.zoom * bscale))
예제 #3
0
    def setPlaneIndicator(self, obj, planetrans):
        '''Set the plane indicator in the 3D view for object `obj' to be at transform `planetrans'.'''
        if isinstance(obj.parent, ImageSceneObject) and obj.parent.is2D:
            self.indicatorPlane.setVisible(False)
            self.indicatorTrans = transform()
        else:
            bb = obj.getAABB()
            trans = transform(planetrans.getTranslation(),
                              planetrans.getScale() * vec3(bb.radius * 1.5),
                              planetrans.getRotation())

            # needed to prevent update loops with _repaintDelay and _repaint3DDelay
            if trans != self.indicatorTrans or self.indicatorPlane.isVisible(
            ) != self.indicatorVisible:
                self.indicatorTrans = trans
                self.indicatorPlane.setTransform(trans)
                self.indicatorPlane.setVisible(self.indicatorVisible)
                self._repaint3DDelay()
예제 #4
0
    def getObjFigures(self, name, numfigs=1, ftype=FT_TRILIST):
        '''Get the Figure objects for the object `name', or create `numfigs' objects of type `ftype' if none found.'''
        if name not in self.objFigMap:
            self.objFigMap[name] = (transform(), [])

        trans, figs = self.objFigMap[name]
        lfigs = len(figs)
        if lfigs < numfigs:
            for i in range(numfigs - lfigs):
                figs.append(
                    self.createFigure('%s_2DFig%i' % (name, i + lfigs), ftype))

        for i, f in enumerate(figs):
            f.setVisible(i < numfigs)

        return trans, figs
예제 #5
0
    def applyMeshMod(self,nodes,norms,inds,colors,uvs,trans=transform()):
        '''
        Applies modifiers to the mesh defined by the supplied vec3or index tuple lists and transform. This method is
        for meshes not defined in datasets. The lists `nodes', `norms', `colors', and `uvs' define the components of
        each node for this mesh while `inds' defines the topology as a list of element index tuples. The method
        `applyMeshMod' is called on each modifier with arguments (nodes,norms,inds,colors,uvs,trans). The method must
        return a tuple containing (nodes,norms,inds,colors,uvs) which may be the same lists modified or new ones. Once
        all modifiers have been applied a vertex and an index buffer are created from the lists and returned.
        '''
        for mod in self.mods:
            nodes,norms,inds,colors,uvs=mod.applyMeshMod(nodes,norms,inds,colors,uvs,trans)

        vbuff=PyVertexBuffer(nodes,norms,colors,uvs)
        ibuff=PyIndexBuffer(inds)

        return vbuff,ibuff
예제 #6
0
    def __init__(self,
                 mgr,
                 camera,
                 indicatorCol=color(1, 1, 1, 0.25),
                 parent=None):
        Base2DWidget.__init__(self, parent)
        self.mgr = mgr
        self.camera = camera
        self.camera.setOrtho(True)
        self.camera.setSecondaryCamera(True)

        self.camera.setPosition(vec3(0, 0, 0))
        self.camera.setLookAt(vec3(0, 0, -1))
        self.camera.setNearClip(epsilon * 100)
        self.camera.setFarClip(100.0)  # ensure the skybox is clipped out

        self.sourceName = None
        self.planeName = None

        self.scroll = vec3()
        self.zoom = 1.0
        self.viewplane = transform(
        )  # the plane in world space corresponding to the current 2D view

        self.objFigMap = {
        }  # maps representation names to (planetrans,figs) pairs

        self.handles = []  # list of handles in this view

        self.slicewidth = 0.2  # width in world units of 2D slices
        self.linewidth = 1.0  # width in world units of mesh lines
        self.planeShift = 0.00005  # amount to move slice position down by in world units so that slice planes don't cut out the image where we want to see it

        self.sceneBB = BoundBox(BaseCamera2DWidget.defaultQuad[0])

        self.indicatorCol = indicatorCol
        self.indicatorMaterial = self.mgr.scene.createMaterial(
            'IndicatorPlane')
        self.indicatorMaterial.setDiffuse(color(1, 1, 1, 1))
        self.indicatorMaterial.useLighting(False)

        self.indicatorTrans = transform()
        self.indicatorPlane = self.createFigure('PlaneIndicator%i' % id(self),
                                                FT_TRILIST, False)
        self.indicatorPlane.setMaterial(self.indicatorMaterial)
        self.indicatorPlane.setTransparent(True)
        self.indicatorPlane.setVisible(False)

        self.indicatorVisible = True

        # construct a quad with a cylinder rim for the indicator plane
        q = BaseCamera2DWidget.defaultQuad[0]
        mq = (q[0] + q[1]) * 0.5
        cnodes, cinds = SceneUtils.generateCylinder(
            [mq, q[1], q[3], q[2], q[0], mq], [0.0025] * 6, 1, 4, False)
        nodes = list(BaseCamera2DWidget.defaultQuad[0]) + cnodes
        inds = list(BaseCamera2DWidget.defaultQuad[1]) + cinds
        self.indicatorPlane.fillData(
            PyVertexBuffer(nodes, [vec3(0, 0, 1)] * len(nodes),
                           [indicatorCol] * len(nodes)), PyIndexBuffer(inds),
            False, True)

        delayedMethodWeak(
            self, '_repaintDelay'
        )  #delay method for repainting allows safe calling multiple times and from task threads

        mgr.addEventHandler(EventType._widgetPreDraw, self._repaintDelay)
예제 #7
0
 def getTransform(self,isDerived=False):
     return transform(self.getPosition(isDerived),self.getScale(isDerived),rotator(*self.getRotation(isDerived)))