Example #1
0
    def setup(self,**kw):
        self.title = "SphereTreeMaker"
        #we need the helper
        if "helper" in kw:
            self.helper = kw["helper"]
        else :
            self.helper = upy.getHelperClass()()
        self.sc = self.helper.getCurrentScene()
        self.dock = False
        if "subdialog" in kw :
            if kw["subdialog"]:
                self.subdialog = True
                self.block = True      
        self.points = []
        self.seeds = []
        self.seedsCoords = []

        self.object_target_name = "ObjectName"
        self.object_target = self.helper.getCurrentSelection()[0]
        if self.object_target is not None :
            self.object_target_name = self.helper.getName(self.object_target)
            
        self.sphere = self.helper.getObject('Sphere')
        if self.sphere is None :
            self.sphere = self.helper.newEmpty('Sphere')
            self.helper.addObjectToScene(self.sc,self.sphere)
        
        self.baseSphere = self.helper.getObject('baseSphere')
        if self.baseSphere is None :       
            self.baseSphere = self.helper.Sphere('baseSphere',parent=self.sphere)[0]
        self.principal_axes = (1,0,0)
        self.principal_axes_cylinder = None
        self.clusterCenterSpheres=[]
        self.clusterSpheres=[]
        self.clusterCenterCyl={}
        
        self.root_cluster = self.helper.getObject('Cluster')
        if self.root_cluster is None :       
            self.root_cluster = self.helper.newEmpty("Cluster")
            self.helper.addObjectToScene(self.sc,self.root_cluster)
        
        self.Spheres = self.helper.getObject('Spheres')
        if self.Spheres is None :         
            self.Spheres=self.helper.newEmpty("Spheres")
            self.helper.addObjectToScene(self.sc,self.Spheres,parent =self.root_cluster)
        
        self.CenterSpheres = self.helper.getObject('CenterSpheres')
        if self.CenterSpheres is None : 
            self.CenterSpheres=self.helper.newEmpty("CenterSpheres")
            self.helper.addObjectToScene(self.sc,self.CenterSpheres,parent =self.root_cluster)
        
        self.keptCenters = []
        self.keptRadii = []
        
        self.factor = 0.5
        self.clusters = None
        self.initWidget(id=1005)
        self.setupLayout()
        self.isSetup = True
        self.io = IOingredientTool()
        self.ingr = None
        self.setTarget()
Example #2
0
    def setup(self, **kw):
        self.title = "SphereTreeMaker"
        #we need the helper
        if "helper" in kw:
            self.helper = kw["helper"]
        else:
            self.helper = upy.getHelperClass()()
        self.sc = self.helper.getCurrentScene()
        self.dock = False
        if "subdialog" in kw:
            if kw["subdialog"]:
                self.subdialog = True
                self.block = True
        self.points = []
        self.seeds = []
        self.seedsCoords = []

        self.object_target_name = "ObjectName"
        self.object_target = self.helper.getCurrentSelection()[0]
        if self.object_target is not None:
            self.object_target_name = self.helper.getName(self.object_target)

        self.sphere = self.helper.getObject('Sphere')
        if self.sphere is None:
            self.sphere = self.helper.newEmpty('Sphere')
            self.helper.addObjectToScene(self.sc, self.sphere)

        self.baseSphere = self.helper.getObject('baseSphere')
        if self.baseSphere is None:
            self.baseSphere = self.helper.Sphere('baseSphere',
                                                 parent=self.sphere)[0]
        self.principal_axes = (1, 0, 0)
        self.principal_axes_cylinder = None
        self.clusterCenterSpheres = []
        self.clusterSpheres = []
        self.clusterCenterCyl = {}

        self.root_cluster = self.helper.getObject('Cluster')
        if self.root_cluster is None:
            self.root_cluster = self.helper.newEmpty("Cluster")
            self.helper.addObjectToScene(self.sc, self.root_cluster)

        self.Spheres = self.helper.getObject('Spheres')
        if self.Spheres is None:
            self.Spheres = self.helper.newEmpty("Spheres")
            self.helper.addObjectToScene(self.sc,
                                         self.Spheres,
                                         parent=self.root_cluster)

        self.CenterSpheres = self.helper.getObject('CenterSpheres')
        if self.CenterSpheres is None:
            self.CenterSpheres = self.helper.newEmpty("CenterSpheres")
            self.helper.addObjectToScene(self.sc,
                                         self.CenterSpheres,
                                         parent=self.root_cluster)

        self.keptCenters = []
        self.keptRadii = []

        self.factor = 0.5
        self.clusters = None
        self.initWidget(id=1005)
        self.setupLayout()
        self.isSetup = True
        self.io = IOingredientTool()
        self.ingr = None
        self.setTarget()
Example #3
0
class SphereTreeUI(uiadaptor):   
    isSetup = False
#    def __init__(self,**kw):
    def setup(self,**kw):
        self.title = "SphereTreeMaker"
        #we need the helper
        if "helper" in kw:
            self.helper = kw["helper"]
        else :
            self.helper = upy.getHelperClass()()
        self.sc = self.helper.getCurrentScene()
        self.dock = False
        if "subdialog" in kw :
            if kw["subdialog"]:
                self.subdialog = True
                self.block = True      
        self.points = []
        self.seeds = []
        self.seedsCoords = []

        self.object_target_name = "ObjectName"
        self.object_target = self.helper.getCurrentSelection()[0]
        if self.object_target is not None :
            self.object_target_name = self.helper.getName(self.object_target)
            
        self.sphere = self.helper.getObject('Sphere')
        if self.sphere is None :
            self.sphere = self.helper.newEmpty('Sphere')
            self.helper.addObjectToScene(self.sc,self.sphere)
        
        self.baseSphere = self.helper.getObject('baseSphere')
        if self.baseSphere is None :       
            self.baseSphere = self.helper.Sphere('baseSphere',parent=self.sphere)[0]
        self.principal_axes = (1,0,0)
        self.principal_axes_cylinder = None
        self.clusterCenterSpheres=[]
        self.clusterSpheres=[]
        self.clusterCenterCyl={}
        
        self.root_cluster = self.helper.getObject('Cluster')
        if self.root_cluster is None :       
            self.root_cluster = self.helper.newEmpty("Cluster")
            self.helper.addObjectToScene(self.sc,self.root_cluster)
        
        self.Spheres = self.helper.getObject('Spheres')
        if self.Spheres is None :         
            self.Spheres=self.helper.newEmpty("Spheres")
            self.helper.addObjectToScene(self.sc,self.Spheres,parent =self.root_cluster)
        
        self.CenterSpheres = self.helper.getObject('CenterSpheres')
        if self.CenterSpheres is None : 
            self.CenterSpheres=self.helper.newEmpty("CenterSpheres")
            self.helper.addObjectToScene(self.sc,self.CenterSpheres,parent =self.root_cluster)
        
        self.keptCenters = []
        self.keptRadii = []
        
        self.factor = 0.5
        self.clusters = None
        self.initWidget(id=1005)
        self.setupLayout()
        self.isSetup = True
        self.io = IOingredientTool()
        self.ingr = None
        self.setTarget()
        
    def CreateLayout(self):
        self._createLayout()
        return 1

    def Command(self,*args):
#        print args
        self._command(args)
        return 1
        
    def initWidget(self,id=0):
        #getThelist of available ingredient
        self.id = id
        self.BTN={}
        self.BTN["keepS"]=self._addElemt(name="keep Geometry",width=100,height=10,
                                     action=self.keepSpheres,type="button",icon=None,
                                     variable=self.addVariable("int",0))
        self.BTN["delkeepS"]=self._addElemt(name="delete kept Geometry",width=100,height=10,
                         action=self.deleteSpheres,type="button",icon=None,
                                     variable=self.addVariable("int",0))
        self.BTN["saveS"]=self._addElemt(name="write File...",width=100,height=10,
                         action=self.save_cb,type="button",icon=None,
                                     variable=self.addVariable("int",0))
        self.BTN["close"]=self._addElemt(name="Close",width=100,height=10,
                         action=self.close,type="button",icon=None,
                                     variable=self.addVariable("int",0))
        self.BTN["gridify"]=self._addElemt(name="Gridify",width=100,height=10,
                         action=self.gridify,type="button",icon=None,
                                     variable=self.addVariable("int",0))
        self.BTN["clearPoint"]=self._addElemt(name="Clear Points",width=100,height=10,
                         action=self.clearPoints,type="button",icon=None,
                                     variable=self.addVariable("int",0))

        self.available_mode=["bhtree_dot","sdf_fixdimension","sdf_interpolate","jordan_raycast","jordan_3raycast"]
        self.mode=self._addElemt(name="gridify_mode",
                                    value=self.available_mode,
                                    width=180,height=10,action=None,
                                    variable=self.addVariable("int",0),
                                    type="pullMenu",)
        self.grid_step = self._addElemt(name='step',width=100,height=10,
                                              action=None,type="inputFloat",icon=None,
                                              value = 20.,
                                              variable=self.addVariable("float",1.),
                                              mini=0.00,maxi=1000.00,step=1.0)
        self.rt_display=self._addElemt(name='Display Real Time (debug)',width=80,height=10,
                                              action=None,type="checkbox",icon=None,
                                              variable=self.addVariable("int",1),value=0)
        self.useFix =self._addElemt(name='Use neighbours faces normals average fix',width=80,height=10,
                                              action=None,type="checkbox",icon=None,
                                              variable=self.addVariable("int",1),value=0)                                     
        self.LABELS={}
        
        self.LABELS["algo"] = self._addElemt(label="Using :",width=100)
        self.LABELS["scale"] = self._addElemt(label="Scale :",width=100)
        self.LABELS["nbS"] = self._addElemt(label="#sph :",width=100)  
        self.LABELS["geom"] = self._addElemt(label="enter a geom or nothing for selection :",width=100)
        self.LABELS["geomtype"] = self._addElemt(label="choose schem type",width=100)
        self.LABELS["ei"]= self._addElemt(label="bond cutoff",width=100)
        self.IN={}
        self.IN["scale"]= self._addElemt(name='scale',width=100,height=10,
                                              action=self.scale_cb,type="inputFloat",icon=None,
                                              value = 1.,
                                              variable=self.addVariable("float",1.),
                                              mini=0.00,maxi=10.00,step=0.01)
        self.IN["nbS"]= self._addElemt(name='nbsphere',width=100,height=10,
                                              action=self.clusterN,type="inputInt",icon=None,
                                              value = self.factor,
                                              variable=self.addVariable("int",2),
                                              mini=1,maxi=200,step=1)  
        self.IN["geom"]= self._addElemt(name='geometry',width=100,height=10,
                                              action=self.setTarget,type="inputStr",icon=None,
                                              value = self.object_target_name,
                                              variable=self.addVariable("str",self.object_target_name)) 
                                              
        self.eigenv= self._addElemt(name='eigen',width=100,height=10,
                                              action=self.cutoff_cb,type="inputFloat",icon=None,
                                              value = 1.0,
                                              variable=self.addVariable("float",1.0),
                                              mini=0.,maxi=500.,step=0.1)  
        self.available_type=["sphere","cylinder"]
        self.typegeom=self._addElemt(name="geomtype",
                                    value=self.available_type,
                                    width=180,height=10,action=None,
                                    variable=self.addVariable("int",0),
                                    type="pullMenu",)
        
                                                              
    def setupLayout(self):
        #this where we define the Layout
        #this wil make three button on a row
        self._layout = []
        self._layout.append([self.LABELS["geom"],self.IN["geom"],])
        self._layout.append([self.LABELS["geomtype"],self.typegeom])
        self._layout.append([self.BTN["keepS"],])
        self._layout.append([self.BTN["delkeepS"],])
        self._layout.append([self.BTN["saveS"],])
        self._layout.append([self.LABELS["scale"],self.IN["scale"]])
        self._layout.append([self.LABELS["nbS"],self.IN["nbS"]])
        self._layout.append([self.LABELS["ei"],self.eigenv])
        #separtor ?
        self._layout.append([self.grid_step,self.BTN["gridify"],])
        self._layout.append([self.LABELS["algo"],self.mode,])
        self._layout.append([self.rt_display,])
        self._layout.append([self.useFix,])
        self._layout.append([self.BTN["clearPoint"],])
        self._layout.append([self.BTN["close"],])

#===============================================================================
# callback
#===============================================================================
    def setTarget(self,*args):
        obj = self.getVal(self.IN["geom"])
        self.setTarget_cb(obj)
        
    def setTarget_cb(self,objname):
        self.object_target_name = objname
        if self.object_target_name == "" :
            self.object_target = None    
        else :
            self.object_target = self.helper.getObject(self.object_target_name)            
        coords= self.getCurrentSelectedPoints()
        #retrieve the principal axis of the object
        eivec,eival = principal_axes(coords,return_eigvals=True)
        #eivec[0] is the main
        self.principal_axes = eivec[0]
        w1,ax1 = self.helper.getAngleAxis(self.principal_axes,[0.,0.,1.])
        w2,ax2 = self.helper.getAngleAxis(self.principal_axes,[0.,0.,-1.])
        if w1 < w2 : #closest to [0.,0.,1.]
            self.principal_axes = [0.,0.,1.]
        else :
            self.principal_axes = [0.,0.,-1.]            
        #where does point the axis 0,0,1 or 0,0,-1
        head = numpy.array(self.principal_axes ) * 10.0
        tail = - numpy.array(self.principal_axes ) * 10.0
        if len(head) == 1 : head = head[0]
        if len(tail) == 1 : tail = tail[0]        
        if self.principal_axes_cylinder is None:
            self.principal_axes_cylinder=self.helper.oneCylinder("axis",head,tail,radius=1.0)
        else :
            self.helper.updateOneCylinder("axis",head,tail,radius=1.0)            
        
    def keepSpheres(self,*args):
        sph = self.clusterSpheres
        currentNum = len(self.keptRadii)
        #need to get the position of the current sphere instance
        # go throught them and get ther position
        listeCenter=[self.helper.ToVec(self.helper.getTranslation(x)) for x in sph]
        listeRadii =[self.helper.ToVec(self.helper.getScale(x)) for x in sph]
        self.keptCenters.extend( listeCenter[currentNum:] )
        self.keptRadii.extend( [r[0] for r in listeRadii[currentNum:]] )
        self.helper.clearSelection() #clear the current selection in the viewer??

    def deleteSpheres(self,*args):
        self.keptCenters = []
        self.keptRadii = []
        self.setLong(self.IN["nbS"],1)
        self.clusterN(None)

    def save_cb(self,*args):
        #get name
#        name = "default"
#        initialFile = name+'_%d.sph'%len(self.keptRadii)
#        self.saveDialog(label='autopack Sph files',callback=self.saveSphereModel)
        self.saveDialog(label='AutoPACK Ingredient files',callback=self.saveIngredent)
#        file = tkFileDialog.asksaveasfilename(
#            parent = master,
#            filetypes=[ ('autopack Sph files', '*.sph'),('All files', '*') ],
#            initialdir='.',
#            initialfile=initialFile,
#            title='save sphere file')
#        if file=='': file = None
#        if file:
#            self.saveSphereModel(file)

    def scale_cb(self,*args):
        self.factor = scale = self.getReal(self.IN["scale"])
        gtype = self.getVal(self.typegeom)
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=self.factor)
        else :
            ev = self.getVal(self.eigenv)
            self.displayClustersBonds(self.clusters, factor=self.factor,ev=ev)

    def cutoff_cb(self,*args):
        self.factor = scale = self.getReal(self.IN["scale"])
        gtype = self.getVal(self.typegeom)
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=self.factor)
        else :
            ev = self.getVal(self.eigenv)
            self.displayClustersBonds(self.clusters, factor=self.factor,ev=ev)

    def clusterN(self,*args):
        howMany = self.getLong(self.IN["nbS"])
        gtype = self.getVal(self.typegeom)
        ev = self.getVal(self.eigenv)
        scale = self.getReal(self.IN["scale"])
        self.clusterN_cb(howMany,gtype,scale,ev)

    def clusterN_cb(self,howMany,gtype,scale,ev):
        #global clusters, seeds, seedsCoords, points
        from random import uniform
        seedsInd = []
        self.seeds = []
        self.seedsCoords = []
        
        #get the currentpointSelected. use sphere or actual mesh points ?
        coords= self.getCurrentSelectedPoints()
#        allAtoms = self.getSelection().findType(Atom)
        self.points = [Point(c) for c in coords]
        for i in range(howMany):
            ind = int(uniform(0, len(self.points)))
            print ("uniform ",ind,len(self.points))
            self.seeds.append(self.points[ind])
            self.seedsCoords.append(self.points[ind])
            seedsInd.append( ind)
        t1 = time()
        self.clusters = self.kmeans(self.points, len(self.seeds), 0.5, self.seeds)
#        print 'time to cluster points', time()-t1
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=scale)
        else :
            self.displayClustersBonds(self.clusters, factor=scale,ev=ev)
#            ev = self.getVal(self.eigenv)
#            self.displayClustersCylinders(self.clusters, factor=self.factor,ev=ev)

    def saveIngredent(self,filename):
        name = self.getVal(self.IN["geom"])
        gtype = self.getVal(self.typegeom)
        self.saveIngredent_cb(filename,name,gtype)
        
    def saveIngredent_cb(self,filename,name,gtype,**kw):
        #use histoVol ?        
        #we needtype Sphere/Cylinder/MixSC
        #
        molarity=1.0
        color=[1,0,0]
        pdb=None
        sphereFile=filename+".sph"        
        geomFile=filename+"."+self.helper.hext
        if "geomFile" in kw :
            geomFile = kw["geomFile"]
        packingPriority=0
        jitterMax=(0.2,0.1,0.2)
        if "jitterMax" in kw :
            jitterMax = kw["jitterMax"]
        resolution=None
        if "resolution" in kw :
            resolution= kw["resolution"]
        resolution_dictionary = None
        if "resolution_dictionary" in kw:
            resolution_dictionary=kw["resolution_dictionary"]
        recipe_name = None
        if "recipe_name" in kw :
            recipe_name = kw["recipe_name"]
        principalVector=self.principal_axes
        packingMode="random"
        gftype = "host"
        rotAxis = [0.,2.,1.]
        useRotAxis = 1
        self.helper.write(geomFile,[self.object_target],gftype)
#        self.saveGeom(geomFile, gftype)
        if gtype == "sphere":
            self.saveSphereModel(sphereFile)
            self.ingr = MultiSphereIngr( molarity, color=color, pdb=pdb,
                                 name=name,
                                 sphereFile=sphereFile,#or directly sphere radius and pos
                                 meshFile=geomFile,
                                 packingPriority=packingPriority,
                                 jitterMax=jitterMax,
                                 principalVector=principalVector,
                                 packingMode=packingMode,
                                 rotAxis=rotAxis,useRotAxis = useRotAxis,
                                 resolution_dictionary=resolution_dictionary)
            if recipe_name is not None:
                self.ingr.sphereFile = autopack.autoPACKserver+os.sep+recipe_name+os.sep+"spheres"+os.sep+os.path.basename(sphereFile)
        else :
            positions=[]
            positions2=[]
            radius = []
#            axis = self.helper.getPropertyObject(child[0],key=["axis"])[0]
#            axis should be main eigen vector ? of all point
            for ioname in self.clusterCenterCyl:                
#            for io in child :
                #get the radius and the translation
                io = self.helper.getObject(ioname)
                if io is None :
                    continue
                head,tail,rad = self.clusterCenterCyl[ioname]
                positions.append(head)
                positions2.append(tail)
                radius.append(rad)
#                    self.helper.oneCylinder(self.helper.getName(io)+"_cyl",head,tail,radius=r)
            self.ingr = MultiCylindersIngr( molarity,
                                 name=name,color=color, pdb=pdb,
                                 radii=[radius],
                                 positions=[numpy.array(positions).tolist()], 
                                 positions2=[numpy.array(positions2).tolist()],
                                 meshFile=geomFile,
                                 packingPriority=packingPriority,
                                 jitterMax=jitterMax,
                                 principalVector=principalVector,
                                 packingMode=packingMode,
                                 rotAxis=rotAxis,useRotAxis = useRotAxis,
                                 resolution_dictionary=resolution_dictionary)
        #before saving can point meshfile and sphereFile to server
        if recipe_name is not None:
            self.ingr.meshFile = autopack.autoPACKserver+os.sep+recipe_name+os.sep+"geoms"+os.sep+str(resolution)+os.sep+os.path.basename(geomFile)                
        #save the ingredient
        self.io.write(self.ingr,filename,ingr_format="all")
        #should we replace by local directory ?
        #write it ? add it o exist file ?
        #python string ?
        #texture ?
                                
    def saveSphereModel(self,filename, minR=-1, maxR=-1 ):
        sph = self.clusterSpheres
        centers=[self.helper.ToVec(self.helper.getTranslation(x)) for x in sph]
        radii =[self.helper.ToVec(self.helper.getScale(x)) for x in sph]
        
        minR = self.radg #added by Graham 4/4/11
        maxR = self.radm #added by Graham 4/4/11
        
        f = open(filename, 'w')
        f.write("# rmin rmax\n")
        f.write("%6.2f  %6.2f\n"%(minR, maxR))
        f.write("\n")
        f.write("# number of levels\n")
        f.write("1\n")
        f.write("\n")
        f.write("# number of spheres in level 1\n")
        f.write("%d\n"%len(centers))
        f.write("\n")
        f.write("# x y z r of spheres in level 1\n")
        if not len(self.keptCenters):
            self.keepSpheres(None)
        for r,c in zip(self.keptRadii, self.keptCenters):
            x,y,z = c
            f.write("%6.2f %6.2f %6.2f %6.2f\n"%(x,y,z,r))
        f.write("\n")
        f.close()


        
    def displayClustersSpheres(self,clusters, factor=0.7):
        colors = [ getattr(upy_colors, name) for name in  upy_colors.cnames ]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        if clusters is None:
            return
        for i,cluster in enumerate(clusters):
            centers.append(cluster.centroid.coords)
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor*(radm-radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)
            
            ptCoords = [x.coords for x in cluster.points]

        nbc = len(clusters)
        #instancesSphere for center
        if not self.clusterCenterSpheres:
            self.clusterCenterSpheres=self.helper.instancesSphere("clcspheres",
                                    self.keptCenters+centers,[2.],
                                    self.sphere,colors[:nbc],self.sc,
                                    parent=self.CenterSpheres)
        else :
            self.clusterCenterSpheres=self.helper.updateInstancesSphere("clcspheres",
                                    self.clusterCenterSpheres,self.keptCenters+centers,
                                    self.keptRadii+radii,
                                    self.sphere,colors[:nbc],self.sc,
                                    parent=self.CenterSpheres,delete=True)
                            
#        print 'cluster with %d points rg:%.2f rM:%.2f ratio:%.2f %.2f'%(
#            len(cluster.points), radg, radm, radg/radm, rad)
        if not self.clusterSpheres:
            self.clusterSpheres=self.helper.instancesSphere("clspheres",
                                    self.keptCenters+centers,self.keptRadii+radii,
                                    self.sphere,colors[:nbc],self.sc,
                                    parent=self.Spheres)
        else :
            self.clusterSpheres=self.helper.updateInstancesSphere("clspheres",
                                    self.clusterSpheres,self.keptCenters+centers,
                                    self.keptRadii+radii,
                                    self.sphere,colors[:nbc],self.sc,
                                    parent=self.Spheres,delete=True)

    def displayClustersCylinders(self,clusters, factor=0.7,ev=0):
        colors = [ getattr(upy_colors, name) for name in  upy_colors.cnames ]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        self.clusterCenterCyl={}
        if clusters is None:
            return
        nbc = len(clusters)
        pinstance = self.helper.getObject("BC")
        if pinstance is None :
            pinstance=self.helper.Cylinder("BC",radius=1.,length=1.,res=10, pos = [0.,0.,0.],parent=None)[0]        
        for i,cluster in enumerate(clusters):
            centers = cluster.centroid.coords
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor*(radm-radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)
            
            ptCoords = [x.coords for x in cluster.points]
            delta = (numpy.array(ptCoords)-numpy.array(centers))
            delta *= delta
            distA = numpy.sqrt( delta.sum(1) )
            dmin = min(distA)
            dmax = max(distA)
            minInd = list(distA).index(dmin)
            maxInd = list(distA).index(dmax)

            eivec,eival = cluster.principal_axes(ptCoords,return_eigvals=True)
            cyl_direction = (ptCoords[maxInd]-numpy.array(centers))/dmax#eivec[ev]
            cyl_length = dmax
            cyl_radius = dmin
            head = numpy.array(centers) + numpy.array(cyl_direction) * cyl_length
            tail = numpy.array(centers) - numpy.array(cyl_direction) * cyl_length
            if len(head) == 1 : head = head[0]
            if len(tail) == 1 : tail = tail[0]
            for j in range(3):
                self.axe(i,numpy.array(centers),eivec[j]*cyl_length,j,colors[nbc])
#                self.axe("a"+str(i),numpy.array(centers),eivec[j],j,colors[nbc])
#            cyl = self.helper.getObject("clcyl"+str(i))
#            if cyl is None :
#                cyl=self.helper.oneCylinder("clcyl"+str(i),head,tail,radius=cyl_radius,instance=pinstance,material=None,
#                    parent = self.CenterSpheres,color=colors[nbc])
#                self.clusterCenterCyl.append(cyl)
#            else :
#                self.helper.updateOneCylinder("clcyl"+str(i),head,tail,radius=cyl_radius,color=colors[nbc])

            

    def axe(self,i,c,d,axe,color):
        head = c+d
        tail = c-d
        pinstance = self.helper.getObject("BC")
        if pinstance is None :
            pinstance=self.helper.Cylinder("BC",radius=2.,length=1.,res=10, pos = [0.,0.,0.],parent=None)[0]        
        cyl = self.helper.getObject("clcyl"+str(i)+str(axe))
        if cyl is None :
            cyl=self.helper.oneCylinder("clcyl"+str(i)+str(axe),head,tail,radius=1.,instance=pinstance,material=None,
                parent = self.CenterSpheres,color=color)
#            self.clusterCenterCyl.append(cyl)
        else :
            self.helper.updateOneCylinder("clcyl"+str(i)+str(axe),head,tail,radius=2.,color=color)


    def clear(self,*args):
        pass
    
    def clear_cb(self,gtype):
        if gtype == "sphere":
            [self.helper.deleteObject(o) for o in self.clusterCenterSpheres]
            [self.helper.deleteObject(o) for o in self.clusterSpheres]
        else :
            for j in range(len(self.clusterCenterCyl)):
                self.helper.deleteObject("clbond"+str(j))            

    def displayClustersBonds(self,clusters, factor=0.7,ev=1.0):
        colors = [ getattr(upy_colors, name) for name in  upy_colors.cnames ]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        if clusters is None:
            return
        
        for i,cluster in enumerate(clusters):
            centers.append(cluster.centroid.coords)
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor*(radm-radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)
            
            ptCoords = [x.coords for x in cluster.points]
        # Create a bhtree for the ptCoords using a granility of 10
        bht = bhtreelib.BHtree( centers, radiiM, 10)
        # find all pairs of atoms for which the distance is less than 1.1
        # times the sum of the radii
        print ("cutoff ",ev)
        pairs = bht.closePointsPairsInTree(ev)
        bhtreelib.freeBHtree(bht)
        # pairs is list of tuple of atom indices.
        nbc = len(clusters)
        bonds = {}
        for i,pair in enumerate(pairs):
            # 1- Get the atoms corresponding of the indices of the pair
            cl1 = clusters[int(pair[0])]
            cl2 = clusters[int(pair[1])]
            head = cl1.centroid.coords
            tail = cl2.centroid.coords
            rad = cl1.radiusOfGyration() + factor*(cl1.encapsualtingRadius()-cl1.radiusOfGyration())#or diameter ?
            pinstance = self.helper.getObject("BC")
            if pinstance is None :
                pinstance=self.helper.Cylinder("BC",radius=1.,length=1.,res=10, pos = [0.,0.,0.],parent=None)[0]        
            cyl = self.helper.getObject("clbond"+str(i))
            if cyl is None :
                cyl=self.helper.oneCylinder("clbond"+str(i),head,tail,radius=rad,instance=pinstance,material=None,
                    parent = self.CenterSpheres,color=colors[nbc])
            else :
                self.helper.updateOneCylinder("clbond"+str(i),head,tail,radius=rad,color=colors[nbc])
            self.clusterCenterCyl["clbond"+str(i)] = [head,tail,rad]
        if len(self.clusterCenterCyl) > len(pairs):
            for j in range(len(pairs),len(self.clusterCenterCyl)):
#            for cy in self.clusterCenterCyl[len(pair):]:
#                o=self.clusterCenterCyl[]   
                self.helper.deleteObject("clbond"+str(j))
#            self.clusterCenterCyl = self.clusterCenterCyl[:len(pairs)]
                                    
    def kmeans(self,points, k, cutoff, initial=None):
        # Randomly sample k Points from the points list, build Clusters around them
        if initial is None:
            # Randomly sample k Points from the points list, build Clusters around them
            initial = random.sample(self.points, k)
        else:
            assert len(initial)==k
    
        clusters = []
        for p in initial: clusters.append(Cluster([p]))
        # Enter the program loop
        while True:
            # Make a list for each Cluster
            lists = []
            for c in clusters: lists.append([])
            # For each Point:
            for p in points:
                # Figure out which Cluster's centroid is the nearest
                x1,y1,z1 = p.coords
                x2,y2,z2 = clusters[0].centroid.coords
                smallest_distance = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) +
                                          (z1-z2)*(z1-z2) )
                index = 0
                for i in range(len(clusters[1:])):
                    x2,y2,z2 = clusters[i+1].centroid.coords
                    distance = sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) +
                                     (z1-z2)*(z1-z2) )
                    if distance < smallest_distance:
                        smallest_distance = distance
                        index = i+1
                # Add this Point to that Cluster's corresponding list
                lists[index].append(p)
            # Update each Cluster with the corresponding list
            # Record the biggest centroid shift for any Cluster
            biggest_shift = 0.0
            for i in range(len(clusters)):
                if len(lists[i]):
                    shift = clusters[i].update(lists[i])
                    biggest_shift = max(biggest_shift, shift)
            # If the biggest centroid shift is less than the cutoff, stop
            if biggest_shift < cutoff: break
        # Return the list of Clusters
        return clusters

    def getCurrentSelectedPoints(self):
        #molkit ? sphere ?
        #lets first get the selection
        points = [] 
        if self.object_target is None :
            sel= self.helper.getCurrentSelection()
            if len(sel) == 1 :
                self.object_target = sel[0]
                self.object_target_name = self.helper.getName(self.object_target)
                #type of seletcted object ?
                for s in sel :
                    print ("type",self.helper.getType(s),self.helper.MESH,self.helper.POLYGON)
                if self.helper.getType(sel[0]) == self.helper.POLYGON or self.helper.getType(sel[0]) == self.helper.MESH:
#                    points,point_index= self.helper.getMeshVertices(sel[0],selected=True)#selected ? not working in maya for ow
#                    if not len(points) :
#                        points= self.helper.getMeshVertices(sel[0])
                    points = self.helper.getMeshVertices(sel[0],transform=True)
                    print ("pts ",len(points))
            else :
                points=[self.helper.ToVec(self.helper.getTranslation(x)) for x in sel]
        else :
           if self.helper.getType(self.object_target) == self.helper.POLYGON or self.helper.getType(self.object_target) == self.helper.MESH: 
                    points = self.helper.getMeshVertices(self.object_target,transform=True)               
        print ("pts ",len(points))
        return points

    def gridify(self,*args):
        #take the selected object and create a new object that are the point inside
        #use a default stepsize for the grid
        #use some usefull tools from histovol.grid ?
        #probably need the normal for that
        mode = self.getVal(self.mode)
        step = self.getVal(self.grid_step)
        if self.object_target is None :
            self.object_target = self.helper.getCurrentSelection()[0]
        mesh = self.object_target
        #canwe usethe ogranelle mesh system from autopack
        from autopack.Organelle import Organelle
        faces,vertices,vnormals,fn = self.helper.DecomposeMesh(mesh,
                                    edit=False,copy=False,tri=True,transform=True,fn=True)
        o1 = Organelle(self.helper.getName(mesh),vertices, faces, vnormals,fnormals=fn)
        o1.ref_obj = mesh
        o1.number = 1
        b=self.helper.getObject("BBOX")
        if b is None :
            b = self.helper.Box("BBOX", cornerPoints=o1.bb)
            bb=o1.bb
        else :
            bb=self.helper.getCornerPointCube(b)
        display = self.getVal(self.rt_display)
        useFix= self.getVal(self.useFix)
        if mode =="bhtree_dot":
            inner, surface = o1.getSurfaceInnerPoints(bb,step,display=display,useFix=useFix)
        elif mode ==  "sdf_fixdimension":
            inner, surface = o1.getSurfaceInnerPoints_sdf(bb,step,display=display,useFix=useFix)
        elif mode ==  "sdf_interpolate":
            inner, surface = o1.getSurfaceInnerPoints_sdf_interpolate(bb,step,display=display,useFix=useFix)
        elif mode ==  "jordan_raycast":
            inner, surface = o1.getSurfaceInnerPoints_jordan(bb,step,display=display,useFix=useFix)
        elif mode ==  "jordan_3raycast":
            inner, surface = o1.getSurfaceInnerPoints_jordan(bb,step,display=display,useFix=useFix,ray=3)
#        inner, surface = o1.getSurfaceInnerPoints(bb,step,display=display,useFix=useFix)
        n1=n=o1.name+"_innerPts"
        n2=o1.name+"_surfacePts"
        if self.helper.host == "maya" :
            n=o1.name+"_innerPtsds"
        s = self.helper.getObject(n)
        if s is None :
            s = self.helper.PointCloudObject(n1, vertices=inner )
            s2 = self.helper.PointCloudObject(n2, vertices=surface )
        else :
            if self.helper.host == "c4d" :
                self.helper.updateMesh(s,vertices=inner)
            else :
                self.helper.updateParticle(s,inner,None)
#            self.helper.updateMesh(s2,vertices=surface)
            
    def clearPoints(self,*args):
        name = self.helper.getName(self.object_target)
#        n1 = name+"_innerPts"
#        n2 = name+"_surfacePts"
#        if self.helper.host == "maya" :
        n1 = name+"_innerPtsds"
        n2 = name+"_surfacePtsds"
        s = self.helper.getObject(n1)
        if s is not None :
            instances = self.helper.getChilds(s)
            [self.helper.deleteObject(o) for o in instances]
            self.helper.deleteObject(s) #is this dleete the child ?
            s2 = self.helper.getObject(n2)
            if s2 is not None :
                instances = self.helper.getChilds(s2)
                [self.helper.deleteObject(o) for o in instances]
                self.helper.deleteObject(s2) #is this dleete the child ?
Example #4
0
class SphereTreeUI(uiadaptor):
    isSetup = False

    #    def __init__(self,**kw):
    def setup(self, **kw):
        self.title = "SphereTreeMaker"
        #we need the helper
        if "helper" in kw:
            self.helper = kw["helper"]
        else:
            self.helper = upy.getHelperClass()()
        self.sc = self.helper.getCurrentScene()
        self.dock = False
        if "subdialog" in kw:
            if kw["subdialog"]:
                self.subdialog = True
                self.block = True
        self.points = []
        self.seeds = []
        self.seedsCoords = []

        self.object_target_name = "ObjectName"
        self.object_target = self.helper.getCurrentSelection()[0]
        if self.object_target is not None:
            self.object_target_name = self.helper.getName(self.object_target)

        self.sphere = self.helper.getObject('Sphere')
        if self.sphere is None:
            self.sphere = self.helper.newEmpty('Sphere')
            self.helper.addObjectToScene(self.sc, self.sphere)

        self.baseSphere = self.helper.getObject('baseSphere')
        if self.baseSphere is None:
            self.baseSphere = self.helper.Sphere('baseSphere',
                                                 parent=self.sphere)[0]
        self.principal_axes = (1, 0, 0)
        self.principal_axes_cylinder = None
        self.clusterCenterSpheres = []
        self.clusterSpheres = []
        self.clusterCenterCyl = {}

        self.root_cluster = self.helper.getObject('Cluster')
        if self.root_cluster is None:
            self.root_cluster = self.helper.newEmpty("Cluster")
            self.helper.addObjectToScene(self.sc, self.root_cluster)

        self.Spheres = self.helper.getObject('Spheres')
        if self.Spheres is None:
            self.Spheres = self.helper.newEmpty("Spheres")
            self.helper.addObjectToScene(self.sc,
                                         self.Spheres,
                                         parent=self.root_cluster)

        self.CenterSpheres = self.helper.getObject('CenterSpheres')
        if self.CenterSpheres is None:
            self.CenterSpheres = self.helper.newEmpty("CenterSpheres")
            self.helper.addObjectToScene(self.sc,
                                         self.CenterSpheres,
                                         parent=self.root_cluster)

        self.keptCenters = []
        self.keptRadii = []

        self.factor = 0.5
        self.clusters = None
        self.initWidget(id=1005)
        self.setupLayout()
        self.isSetup = True
        self.io = IOingredientTool()
        self.ingr = None
        self.setTarget()

    def CreateLayout(self):
        self._createLayout()
        return 1

    def Command(self, *args):
        #        print args
        self._command(args)
        return 1

    def initWidget(self, id=0):
        #getThelist of available ingredient
        self.id = id
        self.BTN = {}
        self.BTN["keepS"] = self._addElemt(name="keep Geometry",
                                           width=100,
                                           height=10,
                                           action=self.keepSpheres,
                                           type="button",
                                           icon=None,
                                           variable=self.addVariable("int", 0))
        self.BTN["delkeepS"] = self._addElemt(name="delete kept Geometry",
                                              width=100,
                                              height=10,
                                              action=self.deleteSpheres,
                                              type="button",
                                              icon=None,
                                              variable=self.addVariable(
                                                  "int", 0))
        self.BTN["saveS"] = self._addElemt(name="write File...",
                                           width=100,
                                           height=10,
                                           action=self.save_cb,
                                           type="button",
                                           icon=None,
                                           variable=self.addVariable("int", 0))
        self.BTN["close"] = self._addElemt(name="Close",
                                           width=100,
                                           height=10,
                                           action=self.close,
                                           type="button",
                                           icon=None,
                                           variable=self.addVariable("int", 0))
        self.BTN["gridify"] = self._addElemt(name="Gridify",
                                             width=100,
                                             height=10,
                                             action=self.gridify,
                                             type="button",
                                             icon=None,
                                             variable=self.addVariable(
                                                 "int", 0))
        self.BTN["clearPoint"] = self._addElemt(name="Clear Points",
                                                width=100,
                                                height=10,
                                                action=self.clearPoints,
                                                type="button",
                                                icon=None,
                                                variable=self.addVariable(
                                                    "int", 0))

        self.available_mode = [
            "bhtree_dot", "sdf_fixdimension", "sdf_interpolate",
            "jordan_raycast", "jordan_3raycast"
        ]
        self.mode = self._addElemt(
            name="gridify_mode",
            value=self.available_mode,
            width=180,
            height=10,
            action=None,
            variable=self.addVariable("int", 0),
            type="pullMenu",
        )
        self.grid_step = self._addElemt(name='step',
                                        width=100,
                                        height=10,
                                        action=None,
                                        type="inputFloat",
                                        icon=None,
                                        value=20.,
                                        variable=self.addVariable("float", 1.),
                                        mini=0.00,
                                        maxi=1000.00,
                                        step=1.0)
        self.rt_display = self._addElemt(name='Display Real Time (debug)',
                                         width=80,
                                         height=10,
                                         action=None,
                                         type="checkbox",
                                         icon=None,
                                         variable=self.addVariable("int", 1),
                                         value=0)
        self.useFix = self._addElemt(
            name='Use neighbours faces normals average fix',
            width=80,
            height=10,
            action=None,
            type="checkbox",
            icon=None,
            variable=self.addVariable("int", 1),
            value=0)
        self.LABELS = {}

        self.LABELS["algo"] = self._addElemt(label="Using :", width=100)
        self.LABELS["scale"] = self._addElemt(label="Scale :", width=100)
        self.LABELS["nbS"] = self._addElemt(label="#sph :", width=100)
        self.LABELS["geom"] = self._addElemt(
            label="enter a geom or nothing for selection :", width=100)
        self.LABELS["geomtype"] = self._addElemt(label="choose schem type",
                                                 width=100)
        self.LABELS["ei"] = self._addElemt(label="bond cutoff", width=100)
        self.IN = {}
        self.IN["scale"] = self._addElemt(name='scale',
                                          width=100,
                                          height=10,
                                          action=self.scale_cb,
                                          type="inputFloat",
                                          icon=None,
                                          value=1.,
                                          variable=self.addVariable(
                                              "float", 1.),
                                          mini=0.00,
                                          maxi=10.00,
                                          step=0.01)
        self.IN["nbS"] = self._addElemt(name='nbsphere',
                                        width=100,
                                        height=10,
                                        action=self.clusterN,
                                        type="inputInt",
                                        icon=None,
                                        value=self.factor,
                                        variable=self.addVariable("int", 2),
                                        mini=1,
                                        maxi=200,
                                        step=1)
        self.IN["geom"] = self._addElemt(name='geometry',
                                         width=100,
                                         height=10,
                                         action=self.setTarget,
                                         type="inputStr",
                                         icon=None,
                                         value=self.object_target_name,
                                         variable=self.addVariable(
                                             "str", self.object_target_name))

        self.eigenv = self._addElemt(name='eigen',
                                     width=100,
                                     height=10,
                                     action=self.cutoff_cb,
                                     type="inputFloat",
                                     icon=None,
                                     value=1.0,
                                     variable=self.addVariable("float", 1.0),
                                     mini=0.,
                                     maxi=500.,
                                     step=0.1)
        self.available_type = ["sphere", "cylinder"]
        self.typegeom = self._addElemt(
            name="geomtype",
            value=self.available_type,
            width=180,
            height=10,
            action=None,
            variable=self.addVariable("int", 0),
            type="pullMenu",
        )

    def setupLayout(self):
        #this where we define the Layout
        #this wil make three button on a row
        self._layout = []
        self._layout.append([
            self.LABELS["geom"],
            self.IN["geom"],
        ])
        self._layout.append([self.LABELS["geomtype"], self.typegeom])
        self._layout.append([
            self.BTN["keepS"],
        ])
        self._layout.append([
            self.BTN["delkeepS"],
        ])
        self._layout.append([
            self.BTN["saveS"],
        ])
        self._layout.append([self.LABELS["scale"], self.IN["scale"]])
        self._layout.append([self.LABELS["nbS"], self.IN["nbS"]])
        self._layout.append([self.LABELS["ei"], self.eigenv])
        #separtor ?
        self._layout.append([
            self.grid_step,
            self.BTN["gridify"],
        ])
        self._layout.append([
            self.LABELS["algo"],
            self.mode,
        ])
        self._layout.append([
            self.rt_display,
        ])
        self._layout.append([
            self.useFix,
        ])
        self._layout.append([
            self.BTN["clearPoint"],
        ])
        self._layout.append([
            self.BTN["close"],
        ])

#===============================================================================
# callback
#===============================================================================

    def setTarget(self, *args):
        obj = self.getVal(self.IN["geom"])
        self.setTarget_cb(obj)

    def setTarget_cb(self, objname):
        self.object_target_name = objname
        if self.object_target_name == "":
            self.object_target = None
        else:
            self.object_target = self.helper.getObject(self.object_target_name)
        coords = self.getCurrentSelectedPoints()
        #retrieve the principal axis of the object
        eivec, eival = principal_axes(coords, return_eigvals=True)
        #eivec[0] is the main
        self.principal_axes = eivec[0]
        w1, ax1 = self.helper.getAngleAxis(self.principal_axes, [0., 0., 1.])
        w2, ax2 = self.helper.getAngleAxis(self.principal_axes, [0., 0., -1.])
        if w1 < w2:  #closest to [0.,0.,1.]
            self.principal_axes = [0., 0., 1.]
        else:
            self.principal_axes = [0., 0., -1.]
        #where does point the axis 0,0,1 or 0,0,-1
        head = numpy.array(self.principal_axes) * 10.0
        tail = -numpy.array(self.principal_axes) * 10.0
        if len(head) == 1: head = head[0]
        if len(tail) == 1: tail = tail[0]
        if self.principal_axes_cylinder is None:
            self.principal_axes_cylinder = self.helper.oneCylinder("axis",
                                                                   head,
                                                                   tail,
                                                                   radius=1.0)
        else:
            self.helper.updateOneCylinder("axis", head, tail, radius=1.0)

    def keepSpheres(self, *args):
        sph = self.clusterSpheres
        currentNum = len(self.keptRadii)
        #need to get the position of the current sphere instance
        # go throught them and get ther position
        listeCenter = [
            self.helper.ToVec(self.helper.getTranslation(x)) for x in sph
        ]
        listeRadii = [self.helper.ToVec(self.helper.getScale(x)) for x in sph]
        self.keptCenters.extend(listeCenter[currentNum:])
        self.keptRadii.extend([r[0] for r in listeRadii[currentNum:]])
        self.helper.clearSelection(
        )  #clear the current selection in the viewer??

    def deleteSpheres(self, *args):
        self.keptCenters = []
        self.keptRadii = []
        self.setLong(self.IN["nbS"], 1)
        self.clusterN(None)

    def save_cb(self, *args):
        #get name
        #        name = "default"
        #        initialFile = name+'_%d.sph'%len(self.keptRadii)
        #        self.saveDialog(label='autopack Sph files',callback=self.saveSphereModel)
        self.saveDialog(label='AutoPACK Ingredient files',
                        callback=self.saveIngredent)
#        file = tkFileDialog.asksaveasfilename(
#            parent = master,
#            filetypes=[ ('autopack Sph files', '*.sph'),('All files', '*') ],
#            initialdir='.',
#            initialfile=initialFile,
#            title='save sphere file')
#        if file=='': file = None
#        if file:
#            self.saveSphereModel(file)

    def scale_cb(self, *args):
        self.factor = scale = self.getReal(self.IN["scale"])
        gtype = self.getVal(self.typegeom)
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=self.factor)
        else:
            ev = self.getVal(self.eigenv)
            self.displayClustersBonds(self.clusters, factor=self.factor, ev=ev)

    def cutoff_cb(self, *args):
        self.factor = scale = self.getReal(self.IN["scale"])
        gtype = self.getVal(self.typegeom)
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=self.factor)
        else:
            ev = self.getVal(self.eigenv)
            self.displayClustersBonds(self.clusters, factor=self.factor, ev=ev)

    def clusterN(self, *args):
        howMany = self.getLong(self.IN["nbS"])
        gtype = self.getVal(self.typegeom)
        ev = self.getVal(self.eigenv)
        scale = self.getReal(self.IN["scale"])
        self.clusterN_cb(howMany, gtype, scale, ev)

    def clusterN_cb(self, howMany, gtype, scale, ev):
        #global clusters, seeds, seedsCoords, points
        from random import uniform
        seedsInd = []
        self.seeds = []
        self.seedsCoords = []

        #get the currentpointSelected. use sphere or actual mesh points ?
        coords = self.getCurrentSelectedPoints()
        #        allAtoms = self.getSelection().findType(Atom)
        self.points = [Point(c) for c in coords]
        for i in range(howMany):
            ind = int(uniform(0, len(self.points)))
            print("uniform ", ind, len(self.points))
            self.seeds.append(self.points[ind])
            self.seedsCoords.append(self.points[ind])
            seedsInd.append(ind)
        t1 = time()
        self.clusters = self.kmeans(self.points, len(self.seeds), 0.5,
                                    self.seeds)
        #        print 'time to cluster points', time()-t1
        if gtype == "sphere":
            self.displayClustersSpheres(self.clusters, factor=scale)
        else:
            self.displayClustersBonds(self.clusters, factor=scale, ev=ev)
#            ev = self.getVal(self.eigenv)
#            self.displayClustersCylinders(self.clusters, factor=self.factor,ev=ev)

    def saveIngredent(self, filename):
        name = self.getVal(self.IN["geom"])
        gtype = self.getVal(self.typegeom)
        self.saveIngredent_cb(filename, name, gtype)

    def saveIngredent_cb(self, filename, name, gtype, **kw):
        #use histoVol ?
        #we needtype Sphere/Cylinder/MixSC
        #
        molarity = 1.0
        color = [1, 0, 0]
        pdb = None
        sphereFile = filename + ".sph"
        geomFile = filename + "." + self.helper.hext
        if "geomFile" in kw:
            geomFile = kw["geomFile"]
        packingPriority = 0
        jitterMax = (0.2, 0.1, 0.2)
        if "jitterMax" in kw:
            jitterMax = kw["jitterMax"]
        resolution = None
        if "resolution" in kw:
            resolution = kw["resolution"]
        resolution_dictionary = None
        if "resolution_dictionary" in kw:
            resolution_dictionary = kw["resolution_dictionary"]
        recipe_name = None
        if "recipe_name" in kw:
            recipe_name = kw["recipe_name"]
        principalVector = self.principal_axes
        packingMode = "random"
        gftype = "host"
        rotAxis = [0., 2., 1.]
        useRotAxis = 1
        self.helper.write(geomFile, [self.object_target], gftype)
        #        self.saveGeom(geomFile, gftype)
        if gtype == "sphere":
            self.saveSphereModel(sphereFile)
            self.ingr = MultiSphereIngr(
                molarity,
                color=color,
                pdb=pdb,
                name=name,
                sphereFile=sphereFile,  #or directly sphere radius and pos
                meshFile=geomFile,
                packingPriority=packingPriority,
                jitterMax=jitterMax,
                principalVector=principalVector,
                packingMode=packingMode,
                rotAxis=rotAxis,
                useRotAxis=useRotAxis,
                resolution_dictionary=resolution_dictionary)
            if recipe_name is not None:
                self.ingr.sphereFile = autopack.autoPACKserver + os.sep + recipe_name + os.sep + "spheres" + os.sep + os.path.basename(
                    sphereFile)
        else:
            positions = []
            positions2 = []
            radius = []
            #            axis = self.helper.getPropertyObject(child[0],key=["axis"])[0]
            #            axis should be main eigen vector ? of all point
            for ioname in self.clusterCenterCyl:
                #            for io in child :
                #get the radius and the translation
                io = self.helper.getObject(ioname)
                if io is None:
                    continue
                head, tail, rad = self.clusterCenterCyl[ioname]
                positions.append(head)
                positions2.append(tail)
                radius.append(rad)
#                    self.helper.oneCylinder(self.helper.getName(io)+"_cyl",head,tail,radius=r)
            self.ingr = MultiCylindersIngr(
                molarity,
                name=name,
                color=color,
                pdb=pdb,
                radii=[radius],
                positions=[numpy.array(positions).tolist()],
                positions2=[numpy.array(positions2).tolist()],
                meshFile=geomFile,
                packingPriority=packingPriority,
                jitterMax=jitterMax,
                principalVector=principalVector,
                packingMode=packingMode,
                rotAxis=rotAxis,
                useRotAxis=useRotAxis,
                resolution_dictionary=resolution_dictionary)
        #before saving can point meshfile and sphereFile to server
        if recipe_name is not None:
            self.ingr.meshFile = autopack.autoPACKserver + os.sep + recipe_name + os.sep + "geoms" + os.sep + str(
                resolution) + os.sep + os.path.basename(geomFile)
        #save the ingredient
        self.io.write(self.ingr, filename, ingr_format="all")
        #should we replace by local directory ?
        #write it ? add it o exist file ?
        #python string ?
        #texture ?

    def saveSphereModel(self, filename, minR=-1, maxR=-1):
        sph = self.clusterSpheres
        centers = [
            self.helper.ToVec(self.helper.getTranslation(x)) for x in sph
        ]
        radii = [self.helper.ToVec(self.helper.getScale(x)) for x in sph]

        minR = self.radg  #added by Graham 4/4/11
        maxR = self.radm  #added by Graham 4/4/11

        f = open(filename, 'w')
        f.write("# rmin rmax\n")
        f.write("%6.2f  %6.2f\n" % (minR, maxR))
        f.write("\n")
        f.write("# number of levels\n")
        f.write("1\n")
        f.write("\n")
        f.write("# number of spheres in level 1\n")
        f.write("%d\n" % len(centers))
        f.write("\n")
        f.write("# x y z r of spheres in level 1\n")
        if not len(self.keptCenters):
            self.keepSpheres(None)
        for r, c in zip(self.keptRadii, self.keptCenters):
            x, y, z = c
            f.write("%6.2f %6.2f %6.2f %6.2f\n" % (x, y, z, r))
        f.write("\n")
        f.close()

    def displayClustersSpheres(self, clusters, factor=0.7):
        colors = [getattr(upy_colors, name) for name in upy_colors.cnames]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        if clusters is None:
            return
        for i, cluster in enumerate(clusters):
            centers.append(cluster.centroid.coords)
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor * (radm - radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)

            ptCoords = [x.coords for x in cluster.points]

        nbc = len(clusters)
        #instancesSphere for center
        if not self.clusterCenterSpheres:
            self.clusterCenterSpheres = self.helper.instancesSphere(
                "clcspheres",
                self.keptCenters + centers, [2.],
                self.sphere,
                colors[:nbc],
                self.sc,
                parent=self.CenterSpheres)
        else:
            self.clusterCenterSpheres = self.helper.updateInstancesSphere(
                "clcspheres",
                self.clusterCenterSpheres,
                self.keptCenters + centers,
                self.keptRadii + radii,
                self.sphere,
                colors[:nbc],
                self.sc,
                parent=self.CenterSpheres,
                delete=True)

#        print 'cluster with %d points rg:%.2f rM:%.2f ratio:%.2f %.2f'%(
#            len(cluster.points), radg, radm, radg/radm, rad)
        if not self.clusterSpheres:
            self.clusterSpheres = self.helper.instancesSphere(
                "clspheres",
                self.keptCenters + centers,
                self.keptRadii + radii,
                self.sphere,
                colors[:nbc],
                self.sc,
                parent=self.Spheres)
        else:
            self.clusterSpheres = self.helper.updateInstancesSphere(
                "clspheres",
                self.clusterSpheres,
                self.keptCenters + centers,
                self.keptRadii + radii,
                self.sphere,
                colors[:nbc],
                self.sc,
                parent=self.Spheres,
                delete=True)

    def displayClustersCylinders(self, clusters, factor=0.7, ev=0):
        colors = [getattr(upy_colors, name) for name in upy_colors.cnames]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        self.clusterCenterCyl = {}
        if clusters is None:
            return
        nbc = len(clusters)
        pinstance = self.helper.getObject("BC")
        if pinstance is None:
            pinstance = self.helper.Cylinder("BC",
                                             radius=1.,
                                             length=1.,
                                             res=10,
                                             pos=[0., 0., 0.],
                                             parent=None)[0]
        for i, cluster in enumerate(clusters):
            centers = cluster.centroid.coords
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor * (radm - radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)

            ptCoords = [x.coords for x in cluster.points]
            delta = (numpy.array(ptCoords) - numpy.array(centers))
            delta *= delta
            distA = numpy.sqrt(delta.sum(1))
            dmin = min(distA)
            dmax = max(distA)
            minInd = list(distA).index(dmin)
            maxInd = list(distA).index(dmax)

            eivec, eival = cluster.principal_axes(ptCoords,
                                                  return_eigvals=True)
            cyl_direction = (ptCoords[maxInd] -
                             numpy.array(centers)) / dmax  #eivec[ev]
            cyl_length = dmax
            cyl_radius = dmin
            head = numpy.array(
                centers) + numpy.array(cyl_direction) * cyl_length
            tail = numpy.array(
                centers) - numpy.array(cyl_direction) * cyl_length
            if len(head) == 1: head = head[0]
            if len(tail) == 1: tail = tail[0]
            for j in range(3):
                self.axe(i, numpy.array(centers), eivec[j] * cyl_length, j,
                         colors[nbc])
#                self.axe("a"+str(i),numpy.array(centers),eivec[j],j,colors[nbc])
#            cyl = self.helper.getObject("clcyl"+str(i))
#            if cyl is None :
#                cyl=self.helper.oneCylinder("clcyl"+str(i),head,tail,radius=cyl_radius,instance=pinstance,material=None,
#                    parent = self.CenterSpheres,color=colors[nbc])
#                self.clusterCenterCyl.append(cyl)
#            else :
#                self.helper.updateOneCylinder("clcyl"+str(i),head,tail,radius=cyl_radius,color=colors[nbc])

    def axe(self, i, c, d, axe, color):
        head = c + d
        tail = c - d
        pinstance = self.helper.getObject("BC")
        if pinstance is None:
            pinstance = self.helper.Cylinder("BC",
                                             radius=2.,
                                             length=1.,
                                             res=10,
                                             pos=[0., 0., 0.],
                                             parent=None)[0]
        cyl = self.helper.getObject("clcyl" + str(i) + str(axe))
        if cyl is None:
            cyl = self.helper.oneCylinder("clcyl" + str(i) + str(axe),
                                          head,
                                          tail,
                                          radius=1.,
                                          instance=pinstance,
                                          material=None,
                                          parent=self.CenterSpheres,
                                          color=color)
#            self.clusterCenterCyl.append(cyl)
        else:
            self.helper.updateOneCylinder("clcyl" + str(i) + str(axe),
                                          head,
                                          tail,
                                          radius=2.,
                                          color=color)

    def clear(self, *args):
        pass

    def clear_cb(self, gtype):
        if gtype == "sphere":
            [self.helper.deleteObject(o) for o in self.clusterCenterSpheres]
            [self.helper.deleteObject(o) for o in self.clusterSpheres]
        else:
            for j in range(len(self.clusterCenterCyl)):
                self.helper.deleteObject("clbond" + str(j))

    def displayClustersBonds(self, clusters, factor=0.7, ev=1.0):
        colors = [getattr(upy_colors, name) for name in upy_colors.cnames]

        centers = []
        radiiG = []
        radiiM = []
        radii = []
        if clusters is None:
            return

        for i, cluster in enumerate(clusters):
            centers.append(cluster.centroid.coords)
            radg = cluster.radiusOfGyration()
            radm = cluster.encapsualtingRadius()
            self.radg = radg  #added by Graham 4/4/11
            self.radm = radm  #added by Graham 4/4/11
            #rad = radg/0.7
            rad = radg + factor * (radm - radg)
            radiiG.append(radg)
            radiiM.append(radm)
            radii.append(rad)

            ptCoords = [x.coords for x in cluster.points]
        # Create a bhtree for the ptCoords using a granility of 10
        bht = bhtreelib.BHtree(centers, radiiM, 10)
        # find all pairs of atoms for which the distance is less than 1.1
        # times the sum of the radii
        print("cutoff ", ev)
        pairs = bht.closePointsPairsInTree(ev)
        bhtreelib.freeBHtree(bht)
        # pairs is list of tuple of atom indices.
        nbc = len(clusters)
        bonds = {}
        for i, pair in enumerate(pairs):
            # 1- Get the atoms corresponding of the indices of the pair
            cl1 = clusters[int(pair[0])]
            cl2 = clusters[int(pair[1])]
            head = cl1.centroid.coords
            tail = cl2.centroid.coords
            rad = cl1.radiusOfGyration() + factor * (
                cl1.encapsualtingRadius() - cl1.radiusOfGyration()
            )  #or diameter ?
            pinstance = self.helper.getObject("BC")
            if pinstance is None:
                pinstance = self.helper.Cylinder("BC",
                                                 radius=1.,
                                                 length=1.,
                                                 res=10,
                                                 pos=[0., 0., 0.],
                                                 parent=None)[0]
            cyl = self.helper.getObject("clbond" + str(i))
            if cyl is None:
                cyl = self.helper.oneCylinder("clbond" + str(i),
                                              head,
                                              tail,
                                              radius=rad,
                                              instance=pinstance,
                                              material=None,
                                              parent=self.CenterSpheres,
                                              color=colors[nbc])
            else:
                self.helper.updateOneCylinder("clbond" + str(i),
                                              head,
                                              tail,
                                              radius=rad,
                                              color=colors[nbc])
            self.clusterCenterCyl["clbond" + str(i)] = [head, tail, rad]
        if len(self.clusterCenterCyl) > len(pairs):
            for j in range(len(pairs), len(self.clusterCenterCyl)):
                #            for cy in self.clusterCenterCyl[len(pair):]:
                #                o=self.clusterCenterCyl[]
                self.helper.deleteObject("clbond" + str(j))
#            self.clusterCenterCyl = self.clusterCenterCyl[:len(pairs)]

    def kmeans(self, points, k, cutoff, initial=None):
        # Randomly sample k Points from the points list, build Clusters around them
        if initial is None:
            # Randomly sample k Points from the points list, build Clusters around them
            initial = random.sample(self.points, k)
        else:
            assert len(initial) == k

        clusters = []
        for p in initial:
            clusters.append(Cluster([p]))
        # Enter the program loop
        while True:
            # Make a list for each Cluster
            lists = []
            for c in clusters:
                lists.append([])
            # For each Point:
            for p in points:
                # Figure out which Cluster's centroid is the nearest
                x1, y1, z1 = p.coords
                x2, y2, z2 = clusters[0].centroid.coords
                smallest_distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) *
                                         (y1 - y2) + (z1 - z2) * (z1 - z2))
                index = 0
                for i in range(len(clusters[1:])):
                    x2, y2, z2 = clusters[i + 1].centroid.coords
                    distance = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) *
                                    (y1 - y2) + (z1 - z2) * (z1 - z2))
                    if distance < smallest_distance:
                        smallest_distance = distance
                        index = i + 1
                # Add this Point to that Cluster's corresponding list
                lists[index].append(p)
            # Update each Cluster with the corresponding list
            # Record the biggest centroid shift for any Cluster
            biggest_shift = 0.0
            for i in range(len(clusters)):
                if len(lists[i]):
                    shift = clusters[i].update(lists[i])
                    biggest_shift = max(biggest_shift, shift)
            # If the biggest centroid shift is less than the cutoff, stop
            if biggest_shift < cutoff: break
        # Return the list of Clusters
        return clusters

    def getCurrentSelectedPoints(self):
        #molkit ? sphere ?
        #lets first get the selection
        points = []
        if self.object_target is None:
            sel = self.helper.getCurrentSelection()
            if len(sel) == 1:
                self.object_target = sel[0]
                self.object_target_name = self.helper.getName(
                    self.object_target)
                #type of seletcted object ?
                for s in sel:
                    print("type", self.helper.getType(s), self.helper.MESH,
                          self.helper.POLYGON)
                if self.helper.getType(
                        sel[0]) == self.helper.POLYGON or self.helper.getType(
                            sel[0]) == self.helper.MESH:
                    #                    points,point_index= self.helper.getMeshVertices(sel[0],selected=True)#selected ? not working in maya for ow
                    #                    if not len(points) :
                    #                        points= self.helper.getMeshVertices(sel[0])
                    points = self.helper.getMeshVertices(sel[0],
                                                         transform=True)
                    print("pts ", len(points))
            else:
                points = [
                    self.helper.ToVec(self.helper.getTranslation(x))
                    for x in sel
                ]
        else:
            if self.helper.getType(
                    self.object_target
            ) == self.helper.POLYGON or self.helper.getType(
                    self.object_target) == self.helper.MESH:
                points = self.helper.getMeshVertices(self.object_target,
                                                     transform=True)
        print("pts ", len(points))
        return points

    def gridify(self, *args):
        #take the selected object and create a new object that are the point inside
        #use a default stepsize for the grid
        #use some usefull tools from histovol.grid ?
        #probably need the normal for that
        mode = self.getVal(self.mode)
        step = self.getVal(self.grid_step)
        if self.object_target is None:
            self.object_target = self.helper.getCurrentSelection()[0]
        mesh = self.object_target
        #canwe usethe ogranelle mesh system from autopack
        from autopack.Organelle import Organelle
        faces, vertices, vnormals, fn = self.helper.DecomposeMesh(
            mesh, edit=False, copy=False, tri=True, transform=True, fn=True)
        o1 = Organelle(self.helper.getName(mesh),
                       vertices,
                       faces,
                       vnormals,
                       fnormals=fn)
        o1.ref_obj = mesh
        o1.number = 1
        b = self.helper.getObject("BBOX")
        if b is None:
            b = self.helper.Box("BBOX", cornerPoints=o1.bb)
            bb = o1.bb
        else:
            bb = self.helper.getCornerPointCube(b)
        display = self.getVal(self.rt_display)
        useFix = self.getVal(self.useFix)
        if mode == "bhtree_dot":
            inner, surface = o1.getSurfaceInnerPoints(bb,
                                                      step,
                                                      display=display,
                                                      useFix=useFix)
        elif mode == "sdf_fixdimension":
            inner, surface = o1.getSurfaceInnerPoints_sdf(bb,
                                                          step,
                                                          display=display,
                                                          useFix=useFix)
        elif mode == "sdf_interpolate":
            inner, surface = o1.getSurfaceInnerPoints_sdf_interpolate(
                bb, step, display=display, useFix=useFix)
        elif mode == "jordan_raycast":
            inner, surface = o1.getSurfaceInnerPoints_jordan(bb,
                                                             step,
                                                             display=display,
                                                             useFix=useFix)
        elif mode == "jordan_3raycast":
            inner, surface = o1.getSurfaceInnerPoints_jordan(bb,
                                                             step,
                                                             display=display,
                                                             useFix=useFix,
                                                             ray=3)
#        inner, surface = o1.getSurfaceInnerPoints(bb,step,display=display,useFix=useFix)
        n1 = n = o1.name + "_innerPts"
        n2 = o1.name + "_surfacePts"
        if self.helper.host == "maya":
            n = o1.name + "_innerPtsds"
        s = self.helper.getObject(n)
        if s is None:
            s = self.helper.PointCloudObject(n1, vertices=inner)
            s2 = self.helper.PointCloudObject(n2, vertices=surface)
        else:
            if self.helper.host == "c4d":
                self.helper.updateMesh(s, vertices=inner)
            else:
                self.helper.updateParticle(s, inner, None)
#            self.helper.updateMesh(s2,vertices=surface)

    def clearPoints(self, *args):
        name = self.helper.getName(self.object_target)
        #        n1 = name+"_innerPts"
        #        n2 = name+"_surfacePts"
        #        if self.helper.host == "maya" :
        n1 = name + "_innerPtsds"
        n2 = name + "_surfacePtsds"
        s = self.helper.getObject(n1)
        if s is not None:
            instances = self.helper.getChilds(s)
            [self.helper.deleteObject(o) for o in instances]
            self.helper.deleteObject(s)  #is this dleete the child ?
            s2 = self.helper.getObject(n2)
            if s2 is not None:
                instances = self.helper.getChilds(s2)
                [self.helper.deleteObject(o) for o in instances]
                self.helper.deleteObject(s2)  #is this dleete the child ?