Changeset 831


Ignore:
Timestamp:
Jan 16, 2013 2:35:21 PM (9 years ago)
Author:
vondreele
Message:

more on rigid bodies

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASII.py

    r827 r831  
    12851285        if not G2gd.GetPatternTreeItemId(self,self.root,'Rigid bodies'):
    12861286            sub = self.PatternTree.AppendItem(parent=self.root,text='Rigid bodies')
    1287             self.PatternTree.SetItemPyData(sub,{})
     1287            self.PatternTree.SetItemPyData(sub,{'Vector':{},'Residue':{},'Z-matrix':{}})
    12881288               
    12891289    class CopyDialog(wx.Dialog):
  • trunk/GSASIIconstrGUI.py

    r828 r831  
    88# $Id: GSASIIconstrGUI.py 810 2012-12-05 21:38:26Z vondreele $
    99########### SVN repository information ###################
     10import sys
    1011import wx
     12import wx.grid as wg
    1113import time
     14import random as ran
    1215import numpy as np
    1316import numpy.ma as ma
     
    1518import GSASIIpath
    1619GSASIIpath.SetVersionNumber("$Revision: 810 $")
     20import GSASIIElem as G2elem
     21import GSASIIElemGUI as G2elemGUI
     22import GSASIIphsGUI as G2phG
    1723import GSASIIstruct as G2str
    1824import GSASIImapvars as G2mv
    1925import GSASIIgrid as G2gd
    20 
     26import GSASIIplot as G2plt
     27VERY_LIGHT_GREY = wx.Colour(235,235,235)
     28
     29class MultiIntegerDialog(wx.Dialog):
     30   
     31    def __init__(self,parent,title,prompts,values):
     32        wx.Dialog.__init__(self,parent,-1,title,
     33            pos=wx.DefaultPosition,style=wx.DEFAULT_DIALOG_STYLE)
     34        self.panel = wx.Panel(self)         #just a dummy - gets destroyed in Draw!
     35        self.values = values
     36        self.prompts = prompts
     37        self.Draw()
     38       
     39    def Draw(self):
     40       
     41        def OnValItem(event):
     42            Obj = event.GetEventObject()
     43            ind = Indx[Obj.GetId()]
     44            try:
     45                val = int(Obj.GetValue())
     46                if val <= 0:
     47                    raise ValueError
     48            except ValueError:
     49                val = self.values[ind]
     50            self.values[ind] = val
     51            Obj.SetValue('%d'%(val))
     52           
     53        self.panel.Destroy()
     54        self.panel = wx.Panel(self)
     55        mainSizer = wx.BoxSizer(wx.VERTICAL)
     56        Indx = {}
     57        for ival,[prompt,value] in enumerate(zip(self.prompts,self.values)):
     58            mainSizer.Add(wx.StaticText(self.panel,-1,prompt),0,wx.ALIGN_CENTER)
     59            valItem = wx.TextCtrl(self.panel,-1,value='%d'%(value),style=wx.TE_PROCESS_ENTER)
     60            mainSizer.Add(valItem,0,wx.ALIGN_CENTER)
     61            Indx[valItem.GetId()] = ival
     62            valItem.Bind(wx.EVT_TEXT_ENTER,OnValItem)
     63            valItem.Bind(wx.EVT_KILL_FOCUS,OnValItem)
     64        OkBtn = wx.Button(self.panel,-1,"Ok")
     65        OkBtn.Bind(wx.EVT_BUTTON, self.OnOk)
     66        CancelBtn = wx.Button(self.panel,-1,'Cancel')
     67        CancelBtn.Bind(wx.EVT_BUTTON, self.OnCancel)
     68        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
     69        btnSizer.Add((20,20),1)
     70        btnSizer.Add(OkBtn)
     71        btnSizer.Add(CancelBtn)
     72        btnSizer.Add((20,20),1)
     73        mainSizer.Add(btnSizer,0,wx.EXPAND|wx.BOTTOM|wx.TOP, 10)
     74        self.panel.SetSizer(mainSizer)
     75        self.panel.Fit()
     76        self.Fit()
     77
     78    def GetValues(self):
     79        return self.values
     80       
     81    def OnOk(self,event):
     82        parent = self.GetParent()
     83        parent.Raise()
     84        self.EndModal(wx.ID_OK)             
     85       
     86    def OnCancel(self,event):
     87        parent = self.GetParent()
     88        parent.Raise()
     89        self.EndModal(wx.ID_CANCEL)
     90       
    2191################################################################################
    2292#####  Constraints
     
    557627    if not data:
    558628        data.update({'Vector':{},'Residue':{},'Z-matrix':{}})       #empty dict - fill it
     629           
     630    Indx = {}
     631    plotDefaults = {'oldxy':[0.,0.],'Quaternion':[1.,0.,0.,0.],'cameraPos':20.,'viewDir':[0,0,1],}
    559632
    560633    def OnPageChanged(event):
     
    574647            G2frame.Page = [page,'zrb']
    575648            UpdateZMatrixRB()
     649           
     650    def OnAddRigidBody(event):
     651        page = G2frame.dataDisplay.GetSelection()
     652        if 'Vector' in G2frame.dataDisplay.GetPageText(page):
     653            AddVectorRB()
     654        elif 'Residue' in G2frame.dataDisplay.GetPageText(page):
     655            AddResidueRB()
     656        elif 'Z-matrix' in G2frame.dataDisplay.GetPageText(page):
     657            AddZMatrixRB()
     658           
     659    def AddVectorRB():
     660        dlg = MultiIntegerDialog(G2frame.dataDisplay,'New Rigid Body',['No. atoms','No. translations'],[1,1])
     661        if dlg.ShowModal() == wx.ID_OK:
     662            nAtoms,nTrans = dlg.GetValues()
     663            vectorRB = data['Vector']
     664            rbId = ran.randint(0,sys.maxint)
     665            vecMag = [1.0 for i in range(nTrans)]
     666            vecRef = [False for i in range(nTrans)]
     667            vecVal = [np.zeros((nAtoms,3)) for j in range(nTrans)]
     668            rbTypes = ['C' for i in range(nAtoms)]
     669            Info = G2elem.GetAtomInfo('C')
     670            AtInfo= {'C':[Info['Drad'],Info['Color']]}
     671            data['Vector'][rbId] = {'RBname':'UNKRB','VectMag':vecMag,
     672                'VectRef':vecRef,'rbTypes':rbTypes,'rbVect':vecVal,'AtInfo':AtInfo}
     673        dlg.Destroy()
     674        UpdateVectorRB()
     675       
     676    def AddResidueRB():
     677        pass
     678       
     679    def AddZMatrixRB():
     680        pass
    576681
    577682    def UpdateVectorRB():
     683        SetStatusLine(' You may use e.g. "sind(60)", "cos(60)", "c60" or "s60" for a vector entry')
     684        def rbNameSizer(rbId,rbData):
     685
     686            def OnRBName(event):
     687                Obj = event.GetEventObject()
     688                rbId = Indx[Obj.GetId()]
     689                rbData['RBname'] = Obj.GetValue()
     690               
     691            def OnDelRB(event):
     692                Obj = event.GetEventObject()
     693                rbId = Indx[Obj.GetId()]
     694                del data['Vector'][rbId]
     695                wx.CallAfter(UpdateVectorRB)
     696               
     697            def OnPlotRB(event):
     698                Obj = event.GetEventObject()
     699                rbId = Indx[Obj.GetId()]
     700                Obj.SetValue(False)
     701                G2plt.PlotRigidBody(G2frame,'Vector',data['Vector'][rbId],plotDefaults)
     702           
     703            nameSizer = wx.BoxSizer(wx.HORIZONTAL)
     704            nameSizer.Add(wx.StaticText(VectorRBDisplay,-1,'Rigid body name: '),
     705                0,wx.ALIGN_CENTER_VERTICAL)
     706            RBname = wx.TextCtrl(VectorRBDisplay,-1,rbData['RBname'])
     707            Indx[RBname.GetId()] = rbId
     708            RBname.Bind(wx.EVT_TEXT_ENTER,OnRBName)
     709            RBname.Bind(wx.EVT_KILL_FOCUS,OnRBName)
     710            nameSizer.Add(RBname,0,wx.ALIGN_CENTER_VERTICAL)
     711            nameSizer.Add((5,0),)
     712            plotRB = wx.CheckBox(VectorRBDisplay,-1,'Plot?')
     713            Indx[plotRB.GetId()] = rbId
     714            plotRB.Bind(wx.EVT_CHECKBOX,OnPlotRB)
     715            nameSizer.Add(plotRB,0,wx.ALIGN_CENTER_VERTICAL)
     716            nameSizer.Add((5,0),)
     717            delRB = wx.CheckBox(VectorRBDisplay,-1,'Delete?')
     718            Indx[delRB.GetId()] = rbId
     719            delRB.Bind(wx.EVT_CHECKBOX,OnDelRB)
     720            nameSizer.Add(delRB,0,wx.ALIGN_CENTER_VERTICAL)
     721            return nameSizer
     722           
     723        def rbVectMag(rbId,imag,rbData):
     724           
     725            def OnRBVectorMag(event):
     726                Obj = event.GetEventObject()
     727                rbId,imag = Indx[Obj.GetId()]
     728                try:
     729                    val = float(Obj.GetValue())
     730                    if val <= 0.:
     731                        raise ValueError
     732                    rbData['VectMag'][imag] = val
     733                except ValueError:
     734                    pass
     735                Obj.SetValue('%8.3f'%(val))
     736                UpdateVectorRB()
     737                G2plt.PlotRigidBody(G2frame,'Vector',data['Vector'][rbId],plotDefaults)
     738               
     739            def OnRBVectorRef(event):
     740                Obj = event.GetEventObject()
     741                rbId,imag = Indx[Obj.GetId()]
     742                rbData['VectRef'][imag] = Obj.GetValue()
     743                       
     744            magSizer = wx.wx.BoxSizer(wx.HORIZONTAL)
     745            magSizer.Add(wx.StaticText(VectorRBDisplay,-1,'Translation magnitude: '),
     746                0,wx.ALIGN_CENTER_VERTICAL)
     747            magValue = wx.TextCtrl(VectorRBDisplay,-1,'%8.3f'%(rbData['VectMag'][imag]))
     748            Indx[magValue.GetId()] = [rbId,imag]
     749            magValue.Bind(wx.EVT_TEXT_ENTER,OnRBVectorMag)
     750            magValue.Bind(wx.EVT_KILL_FOCUS,OnRBVectorMag)
     751            magSizer.Add(magValue,0,wx.ALIGN_CENTER_VERTICAL)
     752            magSizer.Add((5,0),)
     753            magref = wx.CheckBox(VectorRBDisplay,-1,label=' Refine?')
     754            magref.SetValue(rbData['VectRef'][imag])
     755            magref.Bind(wx.EVT_CHECKBOX,OnRBVectorRef)
     756            Indx[magref.GetId()] = [rbId,imag]
     757            magSizer.Add(magref,0,wx.ALIGN_CENTER_VERTICAL)
     758            return magSizer
     759           
     760        def OnRBVectorVal(event):
     761            Obj = event.GetEventObject()
     762            rbId,imag,i = Indx[Obj.GetId()]
     763            try:
     764                val = float(Obj.GetValue())
     765                data['Vector'][rbId]['rbVect'][imag][i] = val
     766            except ValueError:
     767                pass
     768            UpdateVectorRB()
     769            G2plt.PlotRigidBody(G2frame,'Vector',data['Vector'][rbId],plotDefaults)
     770           
     771        def rbVectors(rbId,imag,mag,XYZ,rbData):
     772
     773            def TypeSelect(event):
     774                r,c = event.GetRow(),event.GetCol()
     775                if vecGrid.GetColLabelValue(c) == 'Type':
     776                    PE = G2elemGUI.PickElement(G2frame,oneOnly=True)
     777                    if PE.ShowModal() == wx.ID_OK:
     778                        if PE.Elem != 'None':
     779                            El = PE.Elem.strip().lower().capitalize()
     780                            if El not in rbData['rbRadii']:
     781                                rbData['rbRadii'][El] = G2elem.GetAtomInfo(El)['Drad']                           
     782                            rbData['rbTypes'][r] = El
     783                            vecGrid.SetCellValue(r,c,El)
     784                    PE.Destroy()
     785
     786            def ChangeCell(event):
     787                r,c =  event.GetRow(),event.GetCol()
     788                if r >= 0 and (0 <= c < 3):
     789                    try:
     790                        val = float(vecGrid.GetCellValue(r,c))
     791                        rbData['rbVect'][imag][r][c] = val
     792                    except ValueError:
     793                        pass
     794                wx.CallAfter(UpdateVectorRB)
     795
     796            vecSizer = wx.BoxSizer()
     797            Types = 3*[wg.GRID_VALUE_FLOAT+':10,5',]+[wg.GRID_VALUE_STRING,]+3*[wg.GRID_VALUE_FLOAT+':10,5',]
     798            colLabels = ['Vector x','Vector y','Vector z','Type','Cart x','Cart y','Cart z']
     799            table = []
     800            rowLabels = []
     801            for ivec,xyz in enumerate(rbData['rbVect'][imag]):
     802                table.append(list(xyz)+[rbData['rbTypes'][ivec],]+list(XYZ[ivec]))
     803                rowLabels.append(str(ivec))
     804            vecTable = G2gd.Table(table,rowLabels=rowLabels,colLabels=colLabels,types=Types)
     805            vecGrid = G2gd.GSGrid(VectorRBDisplay)
     806            vecGrid.SetTable(vecTable, True)
     807            vecGrid.Bind(wg.EVT_GRID_CELL_CHANGE, ChangeCell)
     808            vecGrid.Bind(wg.EVT_GRID_CELL_LEFT_DCLICK, TypeSelect)
     809            attr = wx.grid.GridCellAttr()
     810            attr.SetEditor(G2phG.GridFractionEditor(vecGrid))
     811            for c in range(3):
     812                vecGrid.SetColAttr(c, attr)
     813            for row in range(vecTable.GetNumberRows()):
     814                for col in [4,5,6]:
     815                    vecGrid.SetCellStyle(row,col,VERY_LIGHT_GREY,True)
     816            vecSizer.Add(vecGrid)
     817            return vecSizer
     818       
    578819        VectorRB.DestroyChildren()
    579820        VectorRBDisplay = wx.Panel(VectorRB)
    580821        VectorRBSizer = wx.BoxSizer(wx.VERTICAL)
    581         VectorRBSizer.Add((5,5),0)       
    582 #        VectorRBSizer.Add(ConstSizer('Phase',PhaseDisplay))
     822        for rbId in data['Vector']:
     823            rbData = data['Vector'][rbId]
     824            VectorRBSizer.Add(rbNameSizer(rbId,rbData),0)
     825            XYZ = np.array([[0.,0.,0.] for Ty in rbData['rbTypes']])
     826            for imag,mag in enumerate(rbData['VectMag']):
     827                XYZ += mag*rbData['rbVect'][imag]
     828                VectorRBSizer.Add(rbVectMag(rbId,imag,rbData),0)
     829                VectorRBSizer.Add(rbVectors(rbId,imag,mag,XYZ,rbData),0)
     830            VectorRBSizer.Add((5,5),0)       
     831        VectorRBSizer.Layout()   
    583832        VectorRBDisplay.SetSizer(VectorRBSizer,True)
    584833        Size = VectorRBSizer.GetMinSize()
     
    587836        VectorRBDisplay.SetSize(Size)
    588837        VectorRB.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    589         Size[1] = min(Size[1],250)
     838#        Size[1] = min(Size[1],450)
    590839        G2frame.dataFrame.setSizePosLeft(Size)
    591840       
     
    596845        ResidueRBSizer.Add((5,5),0)       
    597846#        VectorRBSizer.Add(ConstSizer('Phase',PhaseDisplay))
     847        ResidueRBSizer.Layout()   
    598848        ResidueRBDisplay.SetSizer(ResidueRBSizer,True)
    599849        Size = ResidueRBSizer.GetMinSize()
     
    602852        ResidueRBDisplay.SetSize(Size)
    603853        ResidueRB.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    604         Size[1] = min(Size[1],250)
     854#        Size[1] = min(Size[1],250)
    605855        G2frame.dataFrame.setSizePosLeft(Size)
    606856       
     
    611861        ZMatrixRBSizer.Add((5,5),0)       
    612862#        ZMatrixRBSizer.Add(ConstSizer('Phase',PhaseDisplay))
     863        ZMatrixRBSizer.Layout()   
    613864        ZMatrixRBDisplay.SetSizer(ZMatrixRBSizer,True)
    614865        Size = ZMatrixRBSizer.GetMinSize()
     
    617868        ZMatrixRBDisplay.SetSize(Size)
    618869        ZMatrixRB.SetScrollbars(10,10,Size[0]/10-4,Size[1]/10-1)
    619         Size[1] = min(Size[1],250)
     870#        Size[1] = min(Size[1],250)
    620871        G2frame.dataFrame.setSizePosLeft(Size)
    621        
    622 
    623872
    624873    def SetStatusLine(text):
     
    634883
    635884    G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RigidBodyMenu)
    636 #    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRigidBody, id=G2gd.wxID_RIGIDBODYADD)   
     885    G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRigidBody, id=G2gd.wxID_RIGIDBODYADD)   
    637886    G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize())
    638887
  • trunk/GSASIIgrid.py

    r823 r831  
    104104] = [wx.NewId() for item in range(7)]
    105105
    106 [ wxID_RIGIDBODYADD,
    107 ] = [wx.NewId() for item in range(1)]
     106[ wxID_RIGIDBODYADD,wxID_DRAWDEFINERB,
     107] = [wx.NewId() for item in range(2)]
    108108
    109109[ wxID_SAVESEQSEL,
     
    460460       
    461461        self.PostfillDataMenu()
    462        
    463        
    464462           
    465463# Restraints
     
    758756        self.PostfillDataMenu(empty=True)
    759757       
    760 # Phase / Draw Atoms tab
     758# Phase / Draw Atoms tab 
    761759        self.DrawAtomsMenu = wx.MenuBar()
    762760        self.PrefillDataMenu(self.DrawAtomsMenu,helpType='Draw Atoms')
     
    764762        self.DrawAtomCompute = wx.Menu(title='')
    765763        self.DrawAtomRestraint = wx.Menu(title='')
     764        self.DrawAtomRigidBody = wx.Menu(title='')
    766765        self.DrawAtomsMenu.Append(menu=self.DrawAtomEdit, title='Edit')
    767766        self.DrawAtomsMenu.Append(menu=self.DrawAtomCompute,title='Compute')
    768767        self.DrawAtomsMenu.Append(menu=self.DrawAtomRestraint, title='Restraints')
     768        self.DrawAtomsMenu.Append(menu=self.DrawAtomRigidBody, title='Rigid body')
    769769        self.DrawAtomEdit.Append(id=wxID_DRAWATOMSTYLE, kind=wx.ITEM_NORMAL,text='Atom style',
    770770            help='Select atoms first')
     
    801801        self.DrawAtomRestraint.Append(id=wxID_DRAWRESTRCHIRAL, kind=wx.ITEM_NORMAL,text='Add chiral restraint',
    802802            help='Add chiral restraint for selected atoms (4: center atom 1st)')
     803        self.DrawAtomRigidBody.Append(id=wxID_DRAWDEFINERB, kind=wx.ITEM_NORMAL,text='Define rigid body',
     804            help='Define rigid body with selected atoms')
    803805        self.PostfillDataMenu()
    804806           
  • trunk/GSASIIphsGUI.py

    r823 r831  
    329329        changed = False
    330330
    331         val = self._tc.GetValue()
     331        val = self._tc.GetValue().lower()
    332332       
    333333        if val != self.startValue:
    334334            changed = True
     335            neg = False
     336            if '-' in val:
     337                neg = True
    335338            if '/' in val and '.' not in val:
    336339                val += '.'
     340            elif 's' in val and not 'sind(' in val:
     341                if neg:
     342                    val = '-sind('+val.strip('-s')+')'
     343                else:
     344                    val = 'sind('+val.strip('s')+')'
     345            elif 'c' in val and not 'cosd(' in val:
     346                if neg:
     347                    val = '-cosd('+val.strip('-c')+')'
     348                else:
     349                    val = 'cosd('+val.strip('c')+')'
    337350            try:
    338351                val = float(eval(val))
     
    17701783        G2frame.PatternTree.SetItemPyData(   
    17711784            G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Restraints'),restData)
     1785
     1786    def OnDefineRB(event):
     1787        indx = drawAtoms.GetSelectedRows()
     1788        RBData = G2frame.PatternTree.GetItemPyData(   
     1789            G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Rigid bodies'))
     1790        drawingData = data['Drawing']
     1791        generalData = data['General']
     1792        Amat,Bmat = G2lat.cell2AB(generalData['Cell'][1:7])           
     1793        cx,ct,cs,ci = drawingData['atomPtrs']
     1794        atomData = drawingData['Atoms']
     1795        rbXYZ = []
     1796        rbType = []
     1797        AtInfo = {}
     1798        for item in indx:
     1799            rbtype = atomData[item][ct]
     1800            rbType.append(rbtype)
     1801            if rbtype not in AtInfo:
     1802                Info = G2elem.GetAtomInfo(rbtype)
     1803                AtInfo[rbtype] = [Info['Drad'],Info['Color']]
     1804            rbXYZ.append(np.inner(np.array(atomData[item][cx:cx+3]),Amat))
     1805        rbXYZ = np.array(rbXYZ)
     1806        rbXYZ -= rbXYZ[0]
     1807        rbId = ran.randint(0,sys.maxint)
     1808        RBData['Vector'][rbId] = {'RBname':'UNKRB','VectMag':[1.0,],
     1809            'VectRef':[False,],'rbTypes':rbType,'rbVect':[rbXYZ,],'AtInfo':AtInfo}
     1810        print 'New rigid body added to set of rigid bodies'
     1811
    17721812
    17731813################################################################################
     
    45884628            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRPLANE)
    45894629            G2frame.dataFrame.Bind(wx.EVT_MENU, OnRestraint, id=G2gd.wxID_DRAWRESTRCHIRAL)
     4630            G2frame.dataFrame.Bind(wx.EVT_MENU, OnDefineRB, id=G2gd.wxID_DRAWDEFINERB)
    45904631            UpdateDrawAtoms()
    45914632            G2plt.PlotStructure(G2frame,data)
  • trunk/GSASIIplot.py

    r828 r831  
    33673367    Draw('main')
    33683368       
     3369################################################################################
     3370#### Plot Rigid Body
     3371################################################################################
     3372
     3373def PlotRigidBody(G2frame,rbType,rbData,defaults):
     3374    '''RB plotting package. Can show rigid body structures as balls & sticks
     3375    '''
     3376
     3377    def FindBonds(XYZ,rbData):                    #uses numpy & masks - very fast even for proteins!
     3378        import numpy.ma as ma
     3379        AtInfo = rbData['AtInfo']
     3380        rbTypes = rbData['rbTypes']
     3381        Radii = []
     3382        for Atype in rbTypes:
     3383            Radii.append(AtInfo[Atype][0])
     3384        Radii = np.array(Radii)
     3385        Bonds = [[] for i in range(len(Radii))]
     3386        for i,xyz in enumerate(XYZ):
     3387            Dx = XYZ-xyz
     3388            dist = np.sqrt(np.sum(Dx**2,axis=1))
     3389            sumR = Radii[i]+Radii
     3390            IndB = ma.nonzero(ma.masked_greater(dist-0.85*sumR,0.))
     3391            for j in IndB[0]:
     3392                Bonds[i].append(Dx[j]*Radii[i]/sumR[j])
     3393                Bonds[j].append(-Dx[j]*Radii[j]/sumR[j])
     3394        return Bonds
     3395                       
     3396    Wt = np.array([255,255,255])
     3397    Rd = np.array([255,0,0])
     3398    Gr = np.array([0,255,0])
     3399    Bl = np.array([0,0,255])
     3400    uBox = np.array([[0,0,0],[1,0,0],[0,1,0],[0,0,1]])
     3401    uEdges = np.array([[uBox[0],uBox[1]],[uBox[0],uBox[2]],[uBox[0],uBox[3]]])
     3402    uColors = [Rd,Gr,Bl]
     3403    if rbType == 'Vector':
     3404        XYZ = np.array([[0.,0.,0.] for Ty in rbData['rbTypes']])
     3405        for imag,mag in enumerate(rbData['VectMag']):
     3406            XYZ += mag*rbData['rbVect'][imag]
     3407        Bonds = FindBonds(XYZ,rbData)
     3408    elif rbType == 'Residue':
     3409        pass
     3410    elif rbType == 'Z-matrix':
     3411        pass
     3412
     3413    def OnMouseDown(event):
     3414        xy = event.GetPosition()
     3415        defaults['oldxy'] = list(xy)
     3416
     3417    def OnMouseMove(event):
     3418        newxy = event.GetPosition()
     3419                               
     3420        if event.Dragging():
     3421            if event.LeftIsDown():
     3422                SetRotation(newxy)
     3423                Q = defaults['Quaternion']
     3424                G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1)
     3425            elif event.MiddleIsDown():
     3426                SetRotationZ(newxy)
     3427                Q = defaults['Quaternion']
     3428                G2frame.G2plotNB.status.SetStatusText('New quaternion: %.2f+, %.2fi+ ,%.2fj+, %.2fk'%(Q[0],Q[1],Q[2],Q[3]),1)
     3429            Draw('move')
     3430       
     3431    def OnMouseWheel(event):
     3432        defaults['cameraPos'] += event.GetWheelRotation()/24
     3433        defaults['cameraPos'] = max(10,min(500,defaults['cameraPos']))
     3434        G2frame.G2plotNB.status.SetStatusText('New camera distance: %.2f'%(defaults['cameraPos']),1)
     3435        Draw('wheel')
     3436       
     3437    def SetBackground():
     3438        R,G,B,A = Page.camera['backColor']
     3439        glClearColor(R,G,B,A)
     3440        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
     3441       
     3442    def SetLights():
     3443        glEnable(GL_DEPTH_TEST)
     3444        glShadeModel(GL_SMOOTH)
     3445        glEnable(GL_LIGHTING)
     3446        glEnable(GL_LIGHT0)
     3447        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)
     3448        glLightfv(GL_LIGHT0,GL_AMBIENT,[1,1,1,.8])
     3449        glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
     3450       
     3451    def SetRotation(newxy):
     3452#first get rotation vector in screen coords. & angle increment       
     3453        oldxy = defaults['oldxy']
     3454        if not len(oldxy): oldxy = list(newxy)
     3455        dxy = newxy-oldxy
     3456        defaults['oldxy'] = list(newxy)
     3457        V = np.array([dxy[1],dxy[0],0.])
     3458        A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2)
     3459# next transform vector back to xtal coordinates via inverse quaternion
     3460# & make new quaternion
     3461        Q = defaults['Quaternion']
     3462        V = G2mth.prodQVQ(G2mth.invQ(Q),V)
     3463        DQ = G2mth.AVdeg2Q(A,V)
     3464        Q = G2mth.prodQQ(Q,DQ)
     3465        defaults['Quaternion'] = Q
     3466# finally get new view vector - last row of rotation matrix
     3467        VD = G2mth.Q2Mat(Q)[2]
     3468        VD /= np.sqrt(np.sum(VD**2))
     3469        defaults['viewDir'] = VD
     3470       
     3471    def SetRotationZ(newxy):                       
     3472#first get rotation vector (= view vector) in screen coords. & angle increment       
     3473        View = glGetIntegerv(GL_VIEWPORT)
     3474        cent = [View[2]/2,View[3]/2]
     3475        oldxy = defaults['oldxy']
     3476        if not len(oldxy): oldxy = list(newxy)
     3477        dxy = newxy-oldxy
     3478        defaults['oldxy'] = list(newxy)
     3479        V = defaults['viewDir']
     3480        A = [0,0]
     3481        A[0] = dxy[1]*.25
     3482        A[1] = dxy[0]*.25
     3483        if newxy[0] > cent[0]:
     3484            A[0] *= -1
     3485        if newxy[1] < cent[1]:
     3486            A[1] *= -1       
     3487# next transform vector back to xtal coordinates & make new quaternion
     3488        Q = defaults['Quaternion']
     3489        Qx = G2mth.AVdeg2Q(A[0],V)
     3490        Qy = G2mth.AVdeg2Q(A[1],V)
     3491        Q = G2mth.prodQQ(Q,Qx)
     3492        Q = G2mth.prodQQ(Q,Qy)
     3493        defaults['Quaternion'] = Q
     3494
     3495    def RenderUnitVectors(x,y,z):
     3496        xyz = np.array([x,y,z])
     3497        glEnable(GL_COLOR_MATERIAL)
     3498        glLineWidth(1)
     3499        glPushMatrix()
     3500        glTranslate(x,y,z)
     3501        glBegin(GL_LINES)
     3502        for line,color in zip(uEdges,uColors):
     3503            glColor3ubv(color)
     3504            glVertex3fv(-line[1])
     3505            glVertex3fv(line[1])
     3506        glEnd()
     3507        glPopMatrix()
     3508        glColor4ubv([0,0,0,0])
     3509        glDisable(GL_COLOR_MATERIAL)
     3510               
     3511    def RenderSphere(x,y,z,radius,color):
     3512        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
     3513        glPushMatrix()
     3514        glTranslate(x,y,z)
     3515        q = gluNewQuadric()
     3516        gluSphere(q,radius,20,10)
     3517        glPopMatrix()
     3518       
     3519    def RenderBonds(x,y,z,Bonds,radius,color,slice=20):
     3520        glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color)
     3521        glPushMatrix()
     3522        glTranslate(x,y,z)
     3523        for Dx in Bonds:
     3524            glPushMatrix()
     3525            Z = np.sqrt(np.sum(Dx**2))
     3526            if Z:
     3527                azm = atan2d(-Dx[1],-Dx[0])
     3528                phi = acosd(Dx[2]/Z)
     3529                glRotate(-azm,0,0,1)
     3530                glRotate(phi,1,0,0)
     3531                q = gluNewQuadric()
     3532                gluCylinder(q,radius,radius,Z,slice,2)
     3533            glPopMatrix()           
     3534        glPopMatrix()
     3535               
     3536    def RenderLabel(x,y,z,label,r):       
     3537        glPushMatrix()
     3538        glTranslate(x,y,z)
     3539        glDisable(GL_LIGHTING)
     3540        glColor3f(0,1.,0)
     3541        glRasterPos3f(r,r,r)
     3542        for c in list(label):
     3543            glutBitmapCharacter(GLUT_BITMAP_8_BY_13,ord(c))
     3544        glEnable(GL_LIGHTING)
     3545        glPopMatrix()
     3546       
     3547    def Draw(caller=''):
     3548#useful debug?       
     3549#        if caller:
     3550#            print caller
     3551# end of useful debug
     3552        cPos = defaults['cameraPos']
     3553        VS = np.array(Page.canvas.GetSize())
     3554        aspect = float(VS[0])/float(VS[1])
     3555        Zclip = 500.0
     3556        Q = defaults['Quaternion']
     3557        SetBackground()
     3558        glInitNames()
     3559        glPushName(0)
     3560       
     3561        glMatrixMode(GL_PROJECTION)
     3562        glLoadIdentity()
     3563        glViewport(0,0,VS[0],VS[1])
     3564        gluPerspective(20.,aspect,0.1,500.)
     3565        gluLookAt(0,0,cPos,0,0,0,0,1,0)
     3566        SetLights()           
     3567           
     3568        glMatrixMode(GL_MODELVIEW)
     3569        glLoadIdentity()
     3570        matRot = G2mth.Q2Mat(Q)
     3571        matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
     3572        glMultMatrixf(matRot.T)
     3573        RenderUnitVectors(0.,0.,0.)
     3574        radius = 0.4
     3575        for iat,atom in enumerate(XYZ):
     3576            x,y,z = atom
     3577            CL = rbData['AtInfo'][rbData['rbTypes'][iat]][1]
     3578            color = np.array(CL)/255.
     3579            RenderSphere(x,y,z,radius,color)
     3580            RenderBonds(x,y,z,Bonds[iat],0.1,color)
     3581            RenderLabel(x,y,z,str(iat),radius)
     3582        Page.canvas.SwapBuffers()
     3583
     3584    def OnSize(event):
     3585        Draw('size')
     3586       
     3587    try:
     3588        plotNum = G2frame.G2plotNB.plotList.index(rbData['RBname'])
     3589        Page = G2frame.G2plotNB.nb.GetPage(plotNum)       
     3590    except ValueError:
     3591        Plot = G2frame.G2plotNB.addOgl(rbData['RBname'])
     3592        plotNum = G2frame.G2plotNB.plotList.index(rbData['RBname'])
     3593        Page = G2frame.G2plotNB.nb.GetPage(plotNum)
     3594        Page.views = False
     3595        view = False
     3596        altDown = False
     3597    Page.SetFocus()
     3598    Page.canvas.Bind(wx.EVT_MOUSEWHEEL, OnMouseWheel)
     3599    Page.canvas.Bind(wx.EVT_LEFT_DOWN, OnMouseDown)
     3600    Page.canvas.Bind(wx.EVT_RIGHT_DOWN, OnMouseDown)
     3601    Page.canvas.Bind(wx.EVT_MIDDLE_DOWN, OnMouseDown)
     3602    Page.canvas.Bind(wx.EVT_MOTION, OnMouseMove)
     3603    Page.canvas.Bind(wx.EVT_SIZE, OnSize)
     3604    Page.camera['position'] = defaults['cameraPos']
     3605    Page.camera['backColor'] = np.array([0,0,0,0])
     3606    Page.canvas.SetCurrent()
     3607    Draw('main')
Note: See TracChangeset for help on using the changeset viewer.