Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/perspectives/simulation/SimCanvas.py

    r959eb01 r34f23c8  
    22This software was developed by the University of Tennessee as part of the 
    33Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    4 project funded by the US National Science Foundation.  
     4project funded by the US National Science Foundation. 
    55 
    66See the license text in license.txt 
     
    3232except ImportError: 
    3333    haveOpenGL = False 
    34      
     34 
    3535# Color set 
    36 DEFAULT_COLOR = [1.0, 1.0, 0.0, .2]     
     36DEFAULT_COLOR = [1.0, 1.0, 0.0, .2] 
    3737COLOR_RED     = [1.0, 0.0, 0.0, .2] 
    3838COLOR_GREEN   = [0.0, 1.0, 0.0, .2] 
     
    4848class SimPanel(wx.Panel): 
    4949    """ 
    50         3D viewer to support real-space simulation.  
     50        3D viewer to support real-space simulation. 
    5151    """ 
    5252    window_name = "3dview" 
    5353    window_caption = "3D viewer" 
    54      
     54 
    5555    def __init__(self, parent, id = -1, plots = None, standalone=False, **kwargs): 
    5656        wx.Panel.__init__(self, parent, id = id, **kwargs) 
    5757        self.parent = parent 
    58      
     58 
    5959        #Add a sizer 
    6060        mainSizer = wx.BoxSizer(wx.VERTICAL) 
    6161        sliderSizer = wx.BoxSizer(wx.HORIZONTAL) 
    62      
    63         self.canvas    = CanvasBase(self)  
     62 
     63        self.canvas    = CanvasBase(self) 
    6464        self.canvas.SetMinSize((200,2100)) 
    6565 
     
    7272        self.SetSizer(mainSizer) 
    7373        self.Bind(wx.EVT_CONTEXT_MENU, self._on_context_menu) 
    74          
    75   
     74 
     75 
    7676    def _on_context_menu(self, event): 
    7777        """ 
     
    8383        slicerpop.Append(id, '&Reset 3D View') 
    8484        wx.EVT_MENU(self, id, self.canvas.resetView) 
    85         
     85 
    8686        pos = event.GetPosition() 
    8787        pos = self.ScreenToClient(pos) 
    88         self.PopupMenu(slicerpop, pos)         
    89      
     88        self.PopupMenu(slicerpop, pos) 
     89 
    9090class CanvasBase(glcanvas.GLCanvas): 
    9191    """ 
     
    9494    window_name = "Simulation" 
    9595    window_caption = "Simulation" 
    96      
     96 
    9797    def __init__(self, parent): 
    9898        glcanvas.GLCanvas.__init__(self, parent, -1) 
     
    113113        self.Bind(wx.EVT_MOTION, self.OnMouseMotion) 
    114114        self.Bind(wx.EVT_MOUSEWHEEL, self._onMouseWheel) 
    115          
     115 
    116116        self.initialized = False 
    117117        self.shapes = [] 
    118118        self.parent = parent 
    119          
     119 
    120120        # Reference vectors 
    121121        self.x_vec = [1,0,0] 
    122122        self.y_vec = [0,1,0] 
    123          
     123 
    124124        self.mouse_down = False 
    125125        self.scale = 1.0 
    126126        self.zoom  = 1.0 
    127127        self.translation = [0,0,0] 
    128          
     128 
    129129        # Bind to Edit events 
    130130        self.parent.Bind(ShapeParameters.EVT_EDIT_SHAPE, self._onEditShape) 
    131          
     131 
    132132    def resetView(self, evt=None): 
    133133        """ 
     
    140140        glLoadIdentity() 
    141141        self.Refresh() 
    142                  
     142 
    143143    def _onEditShape(self, evt): 
    144144        evt.Skip() 
     
    158158        event.Skip() 
    159159 
    160     def OnPaint(self, event):      
     160    def OnPaint(self, event): 
    161161        size = self.GetClientSize() 
    162162        side = size.width 
    163163        if size.height<size.width: 
    164164            side = size.height 
    165          
     165 
    166166        if self.GetContext(): 
    167167            glViewport(0, 0, side, side) 
    168168            self.SetMinSize((side,side)) 
    169              
     169 
    170170        dc = wx.PaintDC(self) 
    171171        self.SetCurrent() 
     
    174174            self.init = True 
    175175        self.OnDraw() 
    176         event.Skip()         
    177          
     176        event.Skip() 
     177 
    178178    def _onMouseWheel(self, evt): 
    179179        # Initialize mouse position so we don't have unwanted rotation 
    180180        self.x, self.y = self.lastx, self.lasty = evt.GetPosition() 
    181181        self.tr_x, self.tr_y = self.tr_lastx, self.tr_lasty = evt.GetPosition() 
    182          
     182 
    183183        scale = 1.15 
    184184        if evt.GetWheelRotation()<0: 
    185185            scale = 1.0/scale 
    186               
    187         self.zoom *= scale              
    188               
     186 
     187        self.zoom *= scale 
     188 
    189189        glScale(scale, scale, scale) 
    190190        self.Refresh(False) 
    191          
     191 
    192192    def OnMouseDown(self, evt): 
    193193        self.SetFocus() 
     
    214214        slicerpop.Append(id, '&Reset 3D View') 
    215215        wx.EVT_MENU(self, id, self.resetView) 
    216         
     216 
    217217        pos = event.GetPosition() 
    218218        #pos = self.ScreenToClient(pos) 
    219         self.PopupMenu(slicerpop, pos)         
     219        self.PopupMenu(slicerpop, pos) 
    220220 
    221221    def OnMouseMotion(self, evt): 
     
    223223            self.tr_lastx, self.tr_lasty = self.tr_x, self.tr_y 
    224224            x, y = evt.GetPosition() 
    225              
     225 
    226226            # Min distance to do anything 
    227227            if math.fabs(self.lastx-x)>10 or math.fabs(self.lasty-y)>10: 
    228                  
     228 
    229229                self.lastx, self.lasty = self.x, self.y 
    230          
    231                  
     230 
     231 
    232232                if math.fabs(self.lastx-x)>math.fabs(self.lasty-y): 
    233233                    self.x = x 
    234234                else: 
    235235                    self.y = y 
    236                  
     236 
    237237                #self.x, self.y = evt.GetPosition() 
    238238                self.Refresh(False) 
    239                  
     239 
    240240        elif evt.Dragging() and evt.RightIsDown(): 
    241241            self.lastx, self.lasty = self.x, self.y 
     
    243243            self.tr_x, self.tr_y = evt.GetPosition() 
    244244            self.Refresh(False) 
    245              
    246     def InitGL( self ):       
     245 
     246    def InitGL( self ): 
    247247        glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA) 
    248248        #glShadeModel(GL_FLAT); 
    249          
     249 
    250250        glMatrixMode(GL_PROJECTION) 
    251          
     251 
    252252        glLight(GL_LIGHT0, GL_AMBIENT, [.2, .2, .2, 0]) 
    253          
     253 
    254254        # Object color 
    255255        #glLight(GL_LIGHT0, GL_DIFFUSE, COLOR_BLUE) 
    256          
     256 
    257257        glLight(GL_LIGHT0, GL_POSITION, [1.0, 1.0, -1.0, 0.0]) 
    258          
    259          
     258 
     259 
    260260        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [1, 1, 1, 0]) 
    261261        glEnable(GL_LIGHTING) 
     
    263263        glEnable(GL_BLEND) 
    264264        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    265          
     265 
    266266        glEnable ( GL_ALPHA_TEST ) ; 
    267267        glAlphaFunc ( GL_GREATER, 0 ) ; 
    268268        glPixelStorei(GL_PACK_ALIGNMENT, 1) 
    269269        glPixelStorei(GL_UNPACK_ALIGNMENT, 1) 
    270          
     270 
    271271        glEnable(GL_NORMALIZE) 
    272272        glDepthFunc(GL_LESS) 
     
    276276        #glClear (GL_COLOR_BUFFER_BIT); 
    277277        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    278          
    279          
     278 
     279 
    280280        gluPerspective(0, 1.0, 0.1, 60.0); 
    281281 
     
    296296        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    297297        # use a fresh transformation matrix 
    298          
     298 
    299299        # get the max object size to re-scale 
    300300        max_size = 1.0 
     
    305305            if l>max_size: 
    306306                max_size = l 
    307          
     307 
    308308        max_size *= 1.05 
    309309        scale = self.scale/max_size 
    310310        glScale(scale, scale, scale) 
    311311        self.scale = max_size 
    312          
     312 
    313313        self.drawAxes() 
    314          
     314 
    315315        if self.mouse_down: 
    316316            if math.fabs((self.x - self.lastx))>math.fabs((self.y - self.lasty)): 
    317                 angle = 10.0*(self.x - self.lastx) / math.fabs(self.x - self.lastx)  
     317                angle = 10.0*(self.x - self.lastx) / math.fabs(self.x - self.lastx) 
    318318                glRotate(angle, self.y_vec[0], self.y_vec[1], self.y_vec[2]); 
    319319                self._rot_y(angle) 
    320320            elif math.fabs(self.y - self.lasty)>0: 
    321                 angle = 10.0*(self.y - self.lasty) / math.fabs(self.y - self.lasty)  
     321                angle = 10.0*(self.y - self.lasty) / math.fabs(self.y - self.lasty) 
    322322                glRotate(angle, self.x_vec[0], self.x_vec[1], self.x_vec[2]); 
    323323                self._rot_x(angle) 
     
    325325            self.lasty = self.y 
    326326            self.lastx = self.x 
    327          
    328             w,h = self.GetVirtualSizeTuple() 
    329          
     327 
     328            w, h = self.GetVirtualSize() 
     329 
    330330            # Translate in the x-y plane 
    331331            vx = self.x_vec[0] * 2.0*float(self.tr_x - self.tr_lastx)/w \ 
     
    335335            vz = self.x_vec[2] * 2.0*float(self.tr_x - self.tr_lastx)/w \ 
    336336               + self.y_vec[2] * 2.0*float(self.tr_lasty - self.tr_y)/h 
    337              
    338             glTranslate(self.scale*vx/self.zoom, self.scale*vy/self.zoom, self.scale*vz/self.zoom)     
    339                  
     337 
     338            glTranslate(self.scale*vx/self.zoom, self.scale*vy/self.zoom, self.scale*vz/self.zoom) 
     339 
    340340        # push into visible buffer 
    341341        self.SwapBuffers() 
    342          
     342 
    343343    def _matrix_mult(self, v, axis, angle): 
    344344        c = math.cos(angle) 
    345         s = math.sin(angle)  
     345        s = math.sin(angle) 
    346346        x = axis[0] 
    347347        y = axis[1] 
     
    351351        vz = v[0]*(x*z*(1-c)-y*s) + v[1]*(y*z*(1-c)+x*s) + v[2]*(z*z*(1-c)+c) 
    352352        return [vx, vy, vz] 
    353      
     353 
    354354    def _rot_y(self, theta): 
    355355        """ 
    356356            Rotate the view by theta around the y-axis 
    357357        """ 
    358         angle = theta/180.0*math.pi  
     358        angle = theta/180.0*math.pi 
    359359        axis = self.y_vec 
    360360        self.x_vec = self._matrix_mult(self.x_vec, self.y_vec, -angle) 
    361          
     361 
    362362    def _rot_x(self, theta): 
    363363        """ 
     
    366366        angle = theta/180.0*math.pi 
    367367        self.y_vec = self._matrix_mult(self.y_vec, self.x_vec, -angle) 
    368          
    369          
     368 
     369 
    370370    def addShape(self, shape, name=None): 
    371371        """ 
     
    403403 
    404404    def drawAxes(self): 
    405         """  
     405        """ 
    406406            Draw 3D axes 
    407407        """ 
    408408        pos = self.scale * 0.7 
    409         
     409 
    410410        # Z-axis is red 
    411         zaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01,  
     411        zaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01, 
    412412                     l_cyl=self.scale*0.1, l_cone=self.scale*0.05) 
    413413        zaxis.color = COLOR_RED 
    414414        zaxis.draw() 
    415          
     415 
    416416        # Y-axis is yellow 
    417         yaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01,  
     417        yaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01, 
    418418                     l_cyl=self.scale*0.1, l_cone=self.scale*0.05) 
    419419        yaxis.color = COLOR_YELLOW 
    420420        yaxis.rotate(-90,0,0) 
    421421        yaxis.draw() 
    422          
     422 
    423423        # X-axis is green 
    424         xaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01,  
     424        xaxis= Arrow(x=pos, y=-pos, z=0, r_cyl=self.scale*0.005, r_cone=self.scale*0.01, 
    425425                     l_cyl=self.scale*0.1, l_cone=self.scale*0.05) 
    426426        xaxis.color = COLOR_GREEN 
    427427        xaxis.rotate(0,-90,0) 
    428428        xaxis.draw() 
    429          
     429 
    430430        glLight(GL_LIGHT0, GL_DIFFUSE, DEFAULT_COLOR) 
    431431 
     
    445445        self.theta_y = 0 
    446446        self.theta_z = 0 
    447          
     447 
    448448        # Params 
    449449        self.params = {} 
     
    453453        self.details['contrast'] = 'A-2' 
    454454        self.details['order']    = ' ' 
    455          
     455 
    456456        self.highlighted = False 
    457457        self.color = DEFAULT_COLOR 
    458      
     458 
    459459    def get_volume(self): 
    460460        return 0 
    461      
     461 
    462462    def get_length(self): 
    463463        return 1.0 
    464      
     464 
    465465    def highlight(self, value=False): 
    466466        self.highlighted = value 
    467          
     467 
    468468    def rotate(self, alpha, beta, gamma): 
    469         """  
     469        """ 
    470470            Set the rotation angles of the shape 
    471471            @param alpha: angle around the x-axis [degrees] 
     
    476476        self.theta_y = beta 
    477477        self.theta_z = gamma 
    478          
     478 
    479479    def _rotate(self): 
    480480        """ 
    481481            Perform the OpenGL rotation 
    482              
     482 
    483483            Note that the rotation order is reversed. 
    484484            We do Y, X, Z do be compatible with simulation... 
    485485        """ 
    486          
     486 
    487487        glRotated(self.theta_z, 0, 0, 1) 
    488488        glRotated(self.theta_x, 1, 0, 0) 
    489489        glRotated(self.theta_y, 0, 1, 0) 
    490          
     490 
    491491    def _pre_draw(self): 
    492492        if self.highlighted: 
     
    506506        self.l_cyl = l_cyl 
    507507        self.l_cone = l_cone 
    508             
     508 
    509509    def draw(self): 
    510510        self._pre_draw() 
    511511        glPushMatrix() 
    512512        glTranslate(self.x, self.y, self.z) 
    513          
     513 
    514514        # Perform rotation 
    515515        glRotate(self.theta_x, 1, 0, 0) 
     
    520520        qobj = gluNewQuadric(); 
    521521        gluCylinder(qobj, self.r_cyl, self.r_cyl, self.l_cyl, 15, 5); 
    522                  
     522 
    523523        glTranslate(0, 0, self.z+self.l_cyl) 
    524          
     524 
    525525        # Draw cone of the arrow 
    526526        glutSolidCone(self.r_cone, self.l_cone, 30, 5) 
    527          
     527 
    528528        # Translate back to original position 
    529529        glTranslate(-self.x, -self.y, -self.z) 
     
    538538        self.radius = radius 
    539539        self.height = height 
    540          
     540 
    541541    def draw(self): 
    542542        glPushMatrix() 
     
    556556        self.params['radius'] = radius 
    557557        self.details['radius'] = 'A' 
    558          
     558 
    559559    def get_volume(self): 
    560560        return 4.0/3.0*math.pi*self.params['radius']*self.params['radius']*self.params['radius'] 
    561          
     561 
    562562    def get_length(self): 
    563563        return 2.0*self.params['radius'] 
    564      
     564 
    565565    def draw(self): 
    566566        self._pre_draw() 
     
    584584    """ 
    585585        Cylinder shape, by default the cylinder is oriented along 
    586         the z-axis.  
    587          
     586        the z-axis. 
     587 
    588588        The reference point of the cylinder is the center of the 
    589589        bottom circle. 
     
    596596        self.details['radius'] = 'A' 
    597597        self.details['length'] = 'A' 
    598          
     598 
    599599    def get_volume(self): 
    600600        return math.pi*self.params['radius']*self.params['radius']*self.params['length'] 
    601          
     601 
    602602    def get_length(self): 
    603603        if self.params['length']>2.0*self.params['radius']: 
     
    605605        else: 
    606606            return 2.0*self.params['radius'] 
    607          
     607 
    608608    def draw(self): 
    609609        self._pre_draw() 
    610610        glPushMatrix() 
    611          
     611 
    612612        glTranslate(self.x, self.y, self.z) 
    613         self._rotate()  
     613        self._rotate() 
    614614        qobj = gluNewQuadric(); 
    615615        # gluCylinder(qobj, r_base, r_top, L, div around z, div along z) 
     
    619619        glPopMatrix() 
    620620        glLight(GL_LIGHT0, GL_DIFFUSE, DEFAULT_COLOR) 
    621          
     621 
    622622    def accept(self, visitor): 
    623623        return visitor.fromCylinder(self) 
    624          
     624 
    625625    def accept_update(self, visitor): 
    626626        return visitor.update_cylinder(self) 
    627          
     627 
    628628# Fill the shape list 
    629629SHAPE_LIST.append(dict(name='Sphere',   id=wx.NewId(), cl=Sphere)) 
    630630SHAPE_LIST.append(dict(name='Cylinder', id=wx.NewId(), cl=Cylinder)) 
    631          
     631 
    632632def getShapes(): 
    633633    """ 
     
    635635    """ 
    636636    return SHAPE_LIST 
    637      
     637 
    638638def getShapeClass(id): 
    639639    """ 
     
    647647        return shape[0]['cl'] 
    648648    return None 
    649      
     649 
    650650def getShapeClassByName(name): 
    651651    """ 
Note: See TracChangeset for help on using the changeset viewer.