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
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))
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()
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
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
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)
def getTransform(self,isDerived=False): return transform(self.getPosition(isDerived),self.getScale(isDerived),rotator(*self.getRotation(isDerived)))