Source code for steps.API_1.visual.SimDisplay

####################################################################################
#
#    STEPS - STochastic Engine for Pathway Simulation
#    Copyright (C) 2007-2023 Okinawa Institute of Science and Technology, Japan.
#    Copyright (C) 2003-2006 University of Antwerp, Belgium.
#    
#    See the file AUTHORS for details.
#    This file is part of STEPS.
#    
#    STEPS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3,
#    as published by the Free Software Foundation.
#    
#    STEPS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#    
#    You should have received a copy of the GNU General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################   
###

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow
import numpy as np
import pyqtgraph.opengl as gl


import time

[docs]class SimDisplay(QMainWindow): """ Simulation Display Parameters: * id ID of the display * x X cordinate of the display * y Y cordinate of the display * w Width of the display * h Height of the display * scale Scaling between STEPS mesurement and display pixel """ num_display = 0 def __init__(self, id, x = 100, y = 100, w = 800, h = 600, scale = 1e6): """ Constructor. """ QMainWindow.__init__(self) self.id = id self.setGeometry(x, y, w, h) self.widget = gl.GLViewWidget(self) self.setCentralWidget(self.widget) self.scale = scale self.center = [0.0,0.0,0.0] self.rotate = 0 self.main_axis = 0 self.setWindowTitle(id) self.bound_min = [float('Inf'), float('Inf'), float('Inf')] self.bound_max = [-float('Inf'), -float('Inf'), -float('Inf')] self.show()
[docs] def closeEvent(self, event): self.hide() event.ignore()
[docs] def addItem(self, item): """ Add a visual component to the display. Parameters: * item The adding visual component Return: None """ self.widget.addItem(item) for i in range(3): if item.bound_min[i] < self.bound_min[i]: self.bound_min[i] = item.bound_min[i] if item.bound_max[i] > self.bound_max[i]: self.bound_max[i] = item.bound_max[i] self._updateView()
[docs] def addItems(self, items): """ Add a list of visual components to the display. Parameters: * items List of the adding visual components Return: None """ for item in items: self.widget.addItem(item) for i in range(3): if item.bound_min[i] < self.bound_min[i]: self.bound_min[i] = item.bound_min[i] if item.bound_max[i] > self.bound_max[i]: self.bound_max[i] = item.bound_max[i] self._updateView()
[docs] def getItems(self): """ Get a list of visual components in the display. Parameters: None Return: List of the visual components in the display """ return self.widget.items
[docs] def removeItem(self, item_id): """ Remove a visual components in the display. Parameters: * item_id ID of the removing component Return: None """ for item in self.widget.items: if item.id == item_id: self.widget.items.remove(item) break self.bound_min = [float('Inf'), float('Inf'), float('Inf')] self.bound_max = [-float('Inf'), -float('Inf'), -float('Inf')] for item in self.widget.items: for i in range(3): if item.bound_min[i] < self.bound_min[i]: self.bound_min[i] = item.bound_min[i] if item.bound_max[i] > self.bound_max[i]: self.bound_max[i] = item.bound_max[i] self._updateView()
[docs] def hideItem(self, item_id): """ Hide a visual components in the display. Parameters: * item_id ID of the hidding component Return: None """ for item in self.widget.items: if item.id == item_id: item.hide()
[docs] def showItem(self, item_id): """ Show a visual components in the display. Parameters: * item_id ID of the showing component Return: None """ for item in self.widget.items: if item.id == item_id: item.show()
def _updateView(self): axis = [0, 1, 2] new_center = [(self.bound_min[i] + self.bound_max[i]) / 2.0 for i in axis] pan_dist = [new_center[i] - self.center[i] for i in axis] self.widget.pan(pan_dist[0], pan_dist[1], pan_dist[2]) dist_x = self.bound_max[0] - self.bound_min[0] dist_y = self.bound_max[1] - self.bound_min[1] dist_z = self.bound_max[2] - self.bound_min[2] if dist_y >= dist_x and dist_y >= dist_z: self.main_axis = 1 self.widget.setCameraPosition(distance=dist_y * 2) elif dist_z >= dist_x and dist_z >= dist_y: self.widget.setCameraPosition(distance=dist_z * 2) self.main_axis = 2 else: self.widget.setCameraPosition(distance=dist_x * 2) self.main_axis = 0 self.center = new_center
[docs] def updateItems(self): """ Update visual components in the display. Parameters: None Return: None """ for item in self.widget.items: if item.display == self: item.updateItem() else: item.update()
[docs] def refresh(self): """ Refresh the display. Parameters: None Return: None """ self.widget.update()
[docs] def rotateItems(self, angle, x, y, z, local=False): """ Rotate all items in the display. Parameters: * angle Angle for the rotation * x X for the rotation vector * y Y for the rotation vector * z Z for the rotation vector * local True if the rotation is local, False if it is global Return: None """ for item in self.widget.items: item.rotate(angle, x, y, z, local)
[docs] def rotateItem(self, item_id, angle, x, y, z, local=False): """ Rotate all items in the display. Parameters: * item_id ID of the rotating component * angle Angle for the rotation * x X for the rotation vector * y Y for the rotation vector * z Z for the rotation vector * local True if the rotation is local, False if it is global Return: None """ for item in self.widget.items: if item.id == item_id: item.rotate(angle, x, y, z, local) break