예제 #1
0
 def viewpoint(self, ):
     view_str = ''
     com = self._atoms.get_center_of_mass()
     positions = self._atoms.positions
     R = max(
         max(positions[:, 0]) - min(positions[:, 0]),
         max(positions[:, 1]) - min(positions[:, 1]))
     camera_persp = build_tag('Viewpoint',
                              id="camera_persp_%s" % self.uuid,
                              position=tuple(com + [0, 0, 3 * R]),
                              centerOfRotation=tuple(com),
                              orientation="0 0 0 0",
                              description="camera")
     camera_persp = build_tag('Transform',
                              id="t_camera_persp_%s" % self.uuid,
                              rotation='0 0 0 0',
                              body=camera_persp)
     camera_ortho = build_tag('OrthoViewpoint',
                              id="camera_ortho_%s" % self.uuid,
                              position=tuple(com + [0, 0, 3 * R]),
                              centerOfRotation=tuple(com),
                              orientation="0 0 0 0",
                              fieldOfView='-{0} -{0} {0} {0}'.format(R),
                              description="camera")
     camera_ortho = build_tag('Transform',
                              id="t_camera_ortho_%s" % self.uuid,
                              rotation='0 0 0 0',
                              body=camera_ortho)
     view_str = camera_persp + camera_ortho
     return view_str
예제 #2
0
    def write(self, filename, datatype=None, **kwargs):
        """
        """

        script = build_script(self.uuid, self.data)
        body = build_html(self.uuid)
        out, tail, datatype = write_header_tail(script, body, datatype,
                                                filename)
        #
        view_str = self.viewpoint()
        atomic_str = self.draw_atoms()
        cell_str = self.draw_cells()
        bond_str = self.draw_bonds()
        polyhedra_str = self.draw_polyhedras()
        iso_str = self.get_isosurface()
        marker_str = self.draw_marker()
        # animate
        ani_str = self.animate()
        scene_str = view_str + atomic_str + cell_str + bond_str + polyhedra_str + iso_str + marker_str + ani_str
        scene_str = build_tag('Scene', body=scene_str)

        if datatype == 'X3DOM':
            x3d_str = build_tag('X3D',
                                id="x3dase",
                                PrimitiveQuality=self.quality,
                                body=scene_str)
            x3d_str = build_tag('div',
                                dict={'class': 'column right'},
                                body=x3d_str)
        elif datatype == 'X3D':
            x3d_str = build_tag(
                'X3D',
                body=scene_str,
                profile='Immersive',
                version='3.0',
                dict={
                    'xmlns:xsd':
                    'http://www.w3.org/2001/XMLSchema-instance',
                    'xsd:noNamespaceSchemaLocation':
                    ' http://www.web3d.org/specifications/x3d-3.0.xsd'
                })
        out.extend(x3d_str)
        out.extend(tail)
        if isinstance(filename, str):
            with open(filename, 'w') as f:
                for line in out:
                    f.write(line)
        else:
            f = filename
            for line in out:
                f.write(''.join(line))
예제 #3
0
 def draw_cells(self, celllinewidth=0.05):
     """
     Draw unit cell
     """
     cell_str = []
     if self.cell_vertices is not None:
         # edges
         coordIndex = '0 1 -1 0 2 -1 0 4 -1 1 3 -1 1 5 -1 2 3 -1 2 6 -1 3 7 -1 4 5 -1 4 6 -1 5 7 -1 6 7 -1'
         # coordIndex = '0 1 2 3 0 -1 4 5 6 7 4 -1 0 4 -1 1 5 -1 2 6 -1 3 7'
         point = str(self.cell_vertices)
         # edge
         material = build_tag('Material',
                              diffuseColor=(0, 0, 0),
                              emissiveColor=(0, 0.5, 1))
         appearance = build_tag('Appearance', body=material)
         coord = build_tag('Coordinate', point=point)
         edge = build_tag('IndexedLineSet',
                          coordIndex=coordIndex,
                          body=coord)
         edge = build_tag('Shape', body=edge + appearance)
         cell_str.extend(edge)
     return cell_str
예제 #4
0
 def animate(self, ):
     '''
     <timeSensor DEF="time" cycleInterval="2" loop="true"> </timeSensor>
     <PositionInterpolator DEF="move" key="0 0.5 1" keyValue="0 0 0  0 3 0  0 0 0"> </PositionInterpolator>
     <Route fromNode="time" fromField ="fraction_changed" toNode="move" toField="set_fraction> </Route> 
     <Route fromNode="move" fromField ="value_changed" toNode="ball" toField="translation> </Route>  
     '''
     ani_str = []
     if self.nimage == 1: return ani_str
     ani_str.extend(
         build_tag('TimeSensor',
                   DEF='time',
                   cycleInterval=self.nimage,
                   loop='true'))
     for i in range(len(self._atoms)):
         route1 = build_tag('ROUTE',
                            fromNode='time',
                            fromField='fraction_changed',
                            toNode='move_%s' % i,
                            toField='set_fraction')
         route2 = build_tag('ROUTE',
                            fromNode="move_%s" % i,
                            fromField="value_changed",
                            toNode="at_%s_%s" % (i, self.uuid),
                            toField="translation")
         key = ""
         keyvalue = ""
         for j in range(self.nimage):
             key += " %s" % (j / self.nimage)
             keyvalue += '%s %s %s ' % tuple(self.images[j][i].position)
         pi = build_tag('PositionInterpolator',
                        DEF='move_%s' % i,
                        key=key,
                        keyValue=keyvalue)
         ani_str.extend(pi)
         ani_str.extend(route1)
         ani_str.extend(route2)
     return ani_str
예제 #5
0
 def draw_bonds(self):
     '''
     Draw atom bonds
     '''
     # build materials
     bond_str = []
     if not self.bond:
         return bond_str
     bondlist = get_bondpairs(self._atoms,
                              cutoff=self.bond,
                              rmbonds=self.rmbonds)
     self.bond_kinds = get_bond_kinds(self._atoms, self.atom_kinds,
                                      bondlist)
     group = []
     for kind, datas in self.bond_kinds.items():
         material = build_tag('Material', **datas['material'])
         sphere = build_tag('Cylinder',
                            height=1.0,
                            radius=0.1,
                            subdivision=8)
         appearance = build_tag('Appearance', body=material)
         shape = build_tag('Shape', DEF=kind, body=appearance + sphere)
         switch = build_tag('Switch', body=shape, whichChoice="-1")
         bond_str.extend(switch)
         for pos, height, rotation in zip(datas['centers'],
                                          datas['lengths'],
                                          datas['rotations']):
             shape1 = build_tag('Shape', USE=kind)
             bt = build_tag('Transform',
                            body=shape1,
                            translation=tuple(pos),
                            scale=(1, height, 1),
                            rotation=tuple(rotation))
             group.extend(bt)
     group = build_tag('Group', body=group)
     bond_str.extend(
         build_tag('Switch',
                   id="bs_%s" % self.uuid,
                   body=group,
                   whichChoice="-1"))
     return bond_str
예제 #6
0
 def draw_isosurface(self, vertices, faces, color):
     """ 
     """
     iso_str = []
     material = build_tag('Material', diffuseColor=color, transparency=0.4)
     appearance = build_tag('Appearance', body=material)
     facecoordIndex_str = ' '
     coordinate_str = ' '
     for face in faces:
         facecoordIndex_str += ' '.join(str(x) for x in face) + ' -1 '
     for coordinate in vertices:
         coordinate_str += ' '.join(str(x) for x in coordinate) + ' '
     coord = build_tag('Coordinate', point=coordinate_str)
     face = build_tag('IndexedFaceSet',
                      solid='false',
                      coordIndex=facecoordIndex_str,
                      body=coord)
     face = build_tag('Shape', body=face + appearance)
     iso_str.extend(face)
     iso_str = build_tag('Group',
                         onclick="handleGroupClick(event)",
                         body=iso_str)
     return iso_str
예제 #7
0
 def draw_polyhedras(self, ):
     '''
     Draw polyhedras
     '''
     polyhedra_str = []
     if not self.polyhedra:
         return polyhedra_str
     bondlist = get_bondpairs(self._atoms,
                              cutoff=self.bond,
                              rmbonds=self.rmbonds)
     self.polyhedra_kinds = get_polyhedra_kinds(self._atoms,
                                                bondlist=bondlist,
                                                polyhedra=self.polyhedra)
     for kind, datas in self.polyhedra_kinds.items():
         material = build_tag('Material',
                              **datas['material'],
                              ambientIntensity=0)
         appearance = build_tag('Appearance', body=material)
         facecoordIndex_str = ' '
         coordinate_str = ' '
         edgecoordIndex_str = ' '
         for face in datas['faces']:
             facecoordIndex_str += ' '.join(str(x) for x in face) + ' -1 '
         for coordinate in datas['vertices']:
             coordinate_str += ' '.join(str(x) for x in coordinate) + ' '
         for edge in datas['edges']:
             edgecoordIndex_str += ' '.join(str(x) for x in edge) + ' -1 '
         coord = build_tag('Coordinate', point=coordinate_str)
         # face
         face = build_tag('IndexedFaceSet',
                          solid='false',
                          coordIndex=facecoordIndex_str,
                          body=coord)
         polyhedra_str.extend(build_tag('Shape', body=face + appearance))
         # edge
         material = build_tag('Material',
                              diffuseColor=(1, 1, 1),
                              emissiveColor=(0.8, 0.8, 0.8),
                              ambientIntensity=0)
         appearance = build_tag('Appearance', body=material)
         edge = build_tag('IndexedLineSet',
                          coordIndex=edgecoordIndex_str,
                          body=coord)
         polyhedra_str.extend(build_tag('Shape', body=edge + appearance))
     polyhedra_str = build_tag('Group', body=polyhedra_str)
     polyhedra_str = (build_tag('Switch',
                                id="ps_%s" % self.uuid,
                                body=polyhedra_str,
                                whichChoice="-1"))
     return polyhedra_str
예제 #8
0
 def draw_atoms(self):
     '''
     Draw atoms
     bsdf_inputs: dict
         The key and value for principled_bsdf node
     material_style: string
         Select materials type from ['blase', 'glass', 'ceramic', 'plastic'].
     '''
     # build materials
     atomic_str = []
     label_str = []
     group_ele = []
     group_ind = []
     for kind, datas in self.atom_kinds.items():
         material0 = build_tag('Material',
                               name='am_%s' % self.uuid,
                               **datas['material'])
         sphere0 = build_tag('Sphere',
                             DEF='asp_%s' % kind,
                             **datas['sphere'])
         appearance0 = build_tag('Appearance',
                                 DEF='app_%s' % kind,
                                 body=material0)
         shape0 = build_tag('Shape',
                            DEF='as_%s' % kind,
                            id='as_%s_%s' % (kind, self.uuid),
                            body=appearance0 + sphere0)
         atomic_str.extend(
             build_tag('Switch', body=shape0, whichChoice="-1"))
         # switch = build_tag('Switch', body = shape, whichChoice = "-1")
         material1 = build_tag('Material', diffuseColor=(0, 0, 0))
         appearance_text0 = build_tag('Appearance',
                                      DEF='text_app_%s' % kind,
                                      body=material1)
         fontstyle0 = build_tag('Fontstyle',
                                DEF='st_label',
                                family="SANS",
                                size="%s" %
                                (datas['sphere']['radius'] /
                                 2.0))  #, justify='"MIDDLE", "MIDDLE"')
         label_str.extend(fontstyle0)
         label_str.extend(appearance_text0)
         # label_str.extend(switch)
         # element text
         ele = build_tag('Text', string=kind, solid='true', body=fontstyle0)
         shape_ele0 = build_tag('Shape',
                                DEF=kind,
                                id='as_%s' % self.uuid,
                                body=appearance_text0 + ele)
         shape_ele0 = build_tag('Billboard',
                                DEF='billboard_%s' % kind,
                                axisOfRotation=(0, 0, 0),
                                body=shape_ele0)
         label_str.extend(
             build_tag('Switch', body=shape_ele0, whichChoice="-1"))
         iatom = 0
         for pos in datas['positions']:
             # atoms sphere
             sphere = build_tag('Sphere', USE='asp_%s' % kind)
             appearance = build_tag('Appearance', USE='app_%s' % kind)
             shape = build_tag('Shape',
                               kind=kind,
                               index=datas['indexs'][iatom],
                               uuid=self.uuid,
                               body=appearance + sphere)
             atomic_str.extend(
                 build_tag(
                     'Transform',
                     DEF="at_%s_%s" % (datas['indexs'][iatom], self.uuid),
                     uuid=self.uuid,
                     id="at_%s_%s" % (datas['indexs'][iatom], self.uuid),
                     radius=datas['sphere']['radius'],
                     name="at_%s" % (self.uuid),
                     body=shape,
                     translation=tuple(pos),
                     scale="1 1 1"))
             # index
             appearance = build_tag('Appearance', USE='text_app_%s' %
                                    kind)  #, justify='"MIDDLE", "MIDDLE"')
             ind = build_tag('Text',
                             string=datas['indexs'][iatom],
                             solid='true',
                             body=fontstyle0)
             shape_ind = build_tag('Shape', body=appearance + ind)
             shape_ind = build_tag('Billboard',
                                   axisOfRotation=(0, 0, 0),
                                   body=shape_ind)
             group_ind.extend(
                 build_tag('Transform',
                           body=shape_ind,
                           translation=tuple(pos)))
             # element text
             shape_ele = build_tag('Billboard',
                                   axisOfRotation=(0, 0, 0),
                                   USE='billboard_%s' % kind)
             group_ele.extend(
                 build_tag('Transform',
                           body=shape_ele,
                           translation=tuple(pos)))
             iatom += 1
     atomic_str = build_tag('Group',
                            body=atomic_str,
                            onclick="handleGroupClick(event, '%s')" %
                            self.uuid)
     if self.label:
         group_ele = build_tag('Group', body=group_ele)
         group_ind = build_tag('Group', body=group_ind)
         atomic_str.extend(label_str)
         atomic_str.extend(
             build_tag('Switch',
                       id="ele_%s" % self.uuid,
                       body=group_ele,
                       whichChoice="-1"))
         atomic_str.extend(
             build_tag('Switch',
                       id="ind_%s" % self.uuid,
                       body=group_ind,
                       whichChoice="-1"))
     return atomic_str
예제 #9
0
 def draw_marker(self, ):
     marker_str = []
     # sphere
     for i in range(5):
         material = build_tag('Material',
                              diffuseColor="#FFD966",
                              transparency=0.5)
         appearance = build_tag('Appearance', body=material)
         sphere = build_tag('Sphere', radius=1.0)
         shape = build_tag('Shape',
                           isPickable=False,
                           body=appearance + sphere)
         trans = build_tag('Transform',
                           id='marker_%s_%s' % (i, self.uuid),
                           body=shape,
                           scale=".1 .1 .1",
                           translation="5 0 0")
         marker_str.extend(
             build_tag('Switch',
                       id='switch_marker_%s_%s' % (i, self.uuid),
                       body=trans,
                       whichChoice="-1"))
     # lines
     for i in range(2):
         coordIndex = '0 1 -1'
         point = '0 0 0 0 0 1'
         material = build_tag('Material',
                              diffuseColor=(0, 0, 0),
                              emissiveColor=(0, 0.5, 1))
         appearance = build_tag('Appearance', body=material)
         coord = build_tag('Coordinate',
                           id='line_coor_%s_%s' % (i, self.uuid),
                           point=point)
         line = build_tag('IndexedLineSet',
                          id='line_ind_%s_%s' % (i, self.uuid),
                          solid='false',
                          coordIndex=coordIndex,
                          body=coord)
         line = build_tag('Shape', body=line + appearance)
         marker_str.extend(
             build_tag('Switch',
                       id='switch_line_%s_%s' % (i, self.uuid),
                       body=line,
                       whichChoice="-1"))
     return marker_str