예제 #1
0
    def replace(self, gl_object):
        if not gl_object.get_fixed():
            state = gl_object.__getstate__()
            state.pop("name", None)
            state.pop("transformation", None)
            new = self.get_new(gl_object.transformation.t)

            if(self.current_object == "Fragment"): #fragments are inserted at frames - have no refs
                target_object = new.children[1]
            else:
                target_object = new
            for reference in gl_object.references[::-1]:
                if not reference.check_target(target_object):
                    return
            parent = gl_object.parent
            import copy
            primitive.Add(new, parent)
            if(self.current_object == "Fragment"):
                # rotation
                Bond = context.application.plugins.get_node("Bond")
                if len(gl_object.references) == 1 and isinstance(gl_object.references[0].parent, Bond):
                    bond1 = gl_object.references[0].parent
                    direction1 = bond1.shortest_vector_relative_to(parent)
                    if bond1.children[0].target != gl_object:
                        direction1 *= -1
                    bond2 = new.children[0].references[0].parent
                    direction2 = bond2.shortest_vector_relative_to(parent)
                    if bond2.children[0].target != target_object:
                        direction2 *= -1
                    axis = numpy.cross(direction2, direction1)
                    if numpy.linalg.norm(axis) < 1e-8:
                        axis = random_orthonormal(direction1)
                    angle = compute_angle(direction1, direction2)
                    rotation = Rotation()
                    rotation.set_rotation_properties(angle,axis,False)
                    primitive.Transform(new, rotation)
                else:
                    bond1 = None
                # tranlsation
                translation = Translation()
                pos_old = new.children[1].get_frame_relative_to(parent).t
                pos_new = gl_object.transformation.t
                translation.t = pos_new - pos_old
                primitive.Transform(new, translation)
                if bond1 != None:
                    # bond length
                    old_length = numpy.linalg.norm(direction1)
                    new_length = bonds.get_length(new.children[1].number, bond1.get_neighbor(gl_object).number)
                    translation = Translation()
                    translation.t = -direction1/old_length*(new_length-old_length)
                    primitive.Transform(new, translation)

            for reference in gl_object.references[::-1]:
                reference.set_target(target_object)
            primitive.Delete(gl_object)
            if(self.current_object == "Fragment"):
                primitive.Delete(new.children[0])
                # get rid of frame
                UnframeAbsolute = context.application.plugins.get_action("UnframeAbsolute")
                UnframeAbsolute([new])
예제 #2
0
 def __init__(self, send, geometry1, geometry2, action_radius,
              hit_tolerance, rotation2):
     Scanner.__init__(self, send, geometry1, geometry2, action_radius,
                      hit_tolerance)
     if rotation2 is None:
         self.rotation2 = Rotation.identity()
     else:
         self.rotation2 = rotation2
예제 #3
0
    def default_parameters(cls):
        rotation2 = Rotation()
        rotation2.set_rotation_properties(0.0, [1, 0, 0], False)

        result = Parameters()
        result.connect_description1 = (Expression("True"), Expression("node.get_radius()"))
        result.repulse_description1 = (Expression("True"), Expression("node.get_radius()"))
        result.connect_description2 = (Expression("True"), Expression("node.get_radius()"))
        result.repulse_description2 = (Expression("True"), Expression("node.get_radius()"))
        result.action_radius = 7*angstrom
        result.distance_tolerance = 0.1*angstrom
        result.hit_tolerance = 0.1*angstrom
        result.allow_inversions = True
        result.minimum_triangle_size = 0.1*angstrom
        result.rotation_tolerance = 0.05
        result.rotation2 = Undefined(rotation2)
        return result
예제 #4
0
 def reset(self):
     config = context.application.configuration
     self.rotation_center = Translation()
     self.rotation = Rotation()
     self.eye = Translation()
     self.eye.t[2] = config.viewer_distance
     self.opening_angle = config.opening_angle
     self.window_size = config.window_size
     self.window_depth = config.window_depth
예제 #5
0
    def do(self):
        universe = context.application.cache.node
        # first make sure the cell is right handed
        if numpy.linalg.det(universe.cell) < 0 and universe.cell_active.sum() == 3:
            new_cell = universe.cell.copy()
            temp = new_cell[:,0].copy()
            new_cell[:,0] = new_cell[:,1]
            new_cell[:,1] = temp
            primitive.SetProperty(universe, "cell", new_cell)

        # then rotate the unit cell box to the normalized frame:
        rotation = Rotation()
        rotation.r = numpy.array(universe.calc_align_rotation_matrix())
        new_cell = numpy.dot(rotation.r, universe.cell)
        old_cell_active = universe.cell_active.copy()
        universe.cell_active = numpy.array([False, False, False])
        primitive.SetProperty(universe, "cell", new_cell)
        for child in context.application.cache.transformed_children:
            primitive.Transform(child, rotation)
        universe.cell_active = old_cell_active
        primitive.SetProperty(universe, "cell", new_cell)
예제 #6
0
    def do_rotation(self, rotation_angle, rotation_axis):
        rotation_axis = numpy.dot(self.eye_rotation, rotation_axis)
        if self.rotation_axis is not None:
            if numpy.dot(self.rotation_axis, rotation_axis) > 0:
                rotation_axis = self.rotation_axis
            else:
                rotation_axis = -self.rotation_axis
        rotation = Rotation()
        rotation.set_rotation_properties(rotation_angle, rotation_axis, False)
        transformation = self.victim.transformation

        if isinstance(self.victim.transformation, Translation):
            transformation.t -= self.rotation_center
            transformation.t = numpy.dot(numpy.transpose(rotation.r), transformation.t)
            transformation.t += self.rotation_center
        if isinstance(self.victim.transformation, Rotation):
            transformation.r = numpy.dot(numpy.transpose(rotation.r), transformation.r)
        self.victim.revalidate_transformation_list()
        context.application.main.drawing_area.queue_draw()
        #self.victim.invalidate_transformation_list()
        self.changed = True
예제 #7
0
    def do(self):
        cache = context.application.cache

        # Translate where possible, if necessary
        translated_nodes = cache.translated_nodes
        if len(translated_nodes) > 0:
            if isinstance(cache.last, GLTransformationMixin) and \
               isinstance(cache.last.transformation, Translation):
                absolute_inversion_center = cache.last.get_absolute_frame().t
            else:
                absolute_inversion_center = numpy.zeros(3, float)
            victims_by_parent = list_by_parent(cache.transformed_nodes)
            for parent, victims in victims_by_parent.iteritems():
                local_inversion_center = parent.get_absolute_frame().vector_apply_inverse(absolute_inversion_center)
                for victim in victims:
                    translation = Translation()
                    translation.t = 2 * (local_inversion_center - victim.transformation.t)
                    primitive.Transform(victim, translation)

        # Apply an inversion rotation where possible
        r = Rotation()
        r.inversion_rotation()
        for victim in cache.rotated_nodes:
            primitive.Transform(victim, r, after=False)
예제 #8
0
    def alignment_a(self):
        """Computes the rotation matrix that aligns the unit cell with the
           Cartesian axes, starting with cell vector a.

           * a parallel to x
           * b in xy-plane with b_y positive
           * c with c_z positive
        """
        from molmod.transformations import Rotation
        new_x = self.matrix[:, 0].copy()
        new_x /= numpy.linalg.norm(new_x)
        new_z = numpy.cross(new_x, self.matrix[:, 1])
        new_z /= numpy.linalg.norm(new_z)
        new_y = numpy.cross(new_z, new_x)
        new_y /= numpy.linalg.norm(new_y)
        return Rotation(numpy.array([new_x, new_y, new_z]))
예제 #9
0
    def alignment_c(self):
        """Computes the rotation matrix that aligns the unit cell with the
           Cartesian axes, starting with cell vector c.

           * c parallel to z
           * b in zy-plane with b_y positive
           * a with a_x positive
        """
        from molmod.transformations import Rotation
        new_z = self.matrix[:, 2].copy()
        new_z /= np.linalg.norm(new_z)
        new_x = np.cross(self.matrix[:, 1], new_z)
        new_x /= np.linalg.norm(new_x)
        new_y = np.cross(new_z, new_x)
        new_y /= np.linalg.norm(new_y)
        return Rotation(np.array([new_x, new_y, new_z]))
예제 #10
0
 def do_rotation(self, drawing_area, rotation_angle, rotation_axis):
     camera = context.application.camera
     rotation = Rotation()
     rotation.set_rotation_properties(rotation_angle, rotation_axis, False)
     camera.rotation.apply_before(rotation)
     drawing_area.queue_draw()
예제 #11
0
 def do(self):
     cache = context.application.cache
     rotation = Rotation()
     rotation.r = copy.deepcopy(cache.node.transformation.r)
     CenterAlignBase.do(self, cache.parent, cache.transformed_neighbors, rotation)
예제 #12
0
파일: molecules.py 프로젝트: dhertsen/GauPy
 def rotate(self, center, axis, angle):
     self.transform(Translation(-np.array(center)))
     self.transform(Rotation.from_properties(angle, axis, invert=False))
     self.transform(Translation(center))
예제 #13
0
파일: molecules.py 프로젝트: dhertsen/GauPy
 def randomize(self, center):
     self.transform(Translation(-np.array(center)))
     self.transform(Rotation.random())
     self.transform(Translation(center))
예제 #14
0
파일: pair.py 프로젝트: molmod/zeobuilder
 def __init__(self, send, geometry1, geometry2, action_radius, hit_tolerance, rotation2):
     Scanner.__init__(self, send, geometry1, geometry2, action_radius, hit_tolerance)
     if rotation2 is None:
         self.rotation2 = Rotation.identity()
     else:
         self.rotation2 = rotation2
예제 #15
0
파일: molecules.py 프로젝트: dhertsen/GauPy
 def randomize(self, center):
     self.transform(Translation(-np.array(center)))
     self.transform(Rotation.random())
     self.transform(Translation(center))
예제 #16
0
파일: molecules.py 프로젝트: dhertsen/GauPy
 def rotate(self, center, axis, angle):
     self.transform(Translation(-np.array(center)))
     self.transform(Rotation.from_properties(angle, axis, invert=False))
     self.transform(Translation(center))
예제 #17
0
        def add_hydrogens(atom):
            existing_bonds = list(atom.yield_bonds())
            num_bonds = len(existing_bonds)
            bond_length = bonds.get_length(atom.number, 1, BOND_SINGLE)

            if num_bonds == 0:
                H = Atom(name="auto H", number=1)
                H.transformation.t = atom.transformation.t + numpy.array([0,bond_length,0])
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                existing_bonds.append(bond)
                num_bonds = 1

            used_valence = 0
            oposite_direction = numpy.zeros(3, float)
            for bond in existing_bonds:
                shortest_vector = bond.shortest_vector_relative_to(atom.parent)
                if bond.children[1].target == atom:
                    shortest_vector *= -1
                oposite_direction -= shortest_vector

                if bond.bond_type == BOND_SINGLE:
                    used_valence += 1
                elif bond.bond_type == BOND_DOUBLE:
                    used_valence += 2
                elif bond.bond_type == BOND_TRIPLE:
                    used_valence += 3

            oposite_direction /= numpy.linalg.norm(oposite_direction)

            num_hydrogens = valence_el(atom.number) - 2*lone_pairs(atom.number) - used_valence
            if num_hydrogens <= 0:
                return

            hybride_count = num_hydrogens + lone_pairs(atom.number) + num_bonds - (used_valence - num_bonds)
            num_sites = num_hydrogens + lone_pairs(atom.number)
            rotation = Rotation()
            rotation.set_rotation_properties(2*math.pi / float(num_sites), oposite_direction, False)
            opening_key = (hybride_count, num_sites)
            opening_angle = self.opening_angles.get(opening_key)
            if opening_angle is None:
                return

            if num_bonds == 1:
                first_bond = existing_bonds[0]
                other_atom = first_bond.children[0].target
                if other_atom == atom:
                    other_atom = first_bond.children[1].target
                other_bonds = [bond for bond in other_atom.yield_bonds() if bond != first_bond]
                if len(other_bonds) > 0:
                    normal = other_bonds[0].shortest_vector_relative_to(atom.parent)
                    normal -= numpy.dot(normal, oposite_direction) * oposite_direction
                    normal /= numpy.linalg.norm(normal)
                    if other_bonds[0].children[0].target == other_atom:
                        normal *= -1
                else:
                    normal = random_orthonormal(oposite_direction)
            elif num_bonds == 2:
                normal = numpy.cross(oposite_direction, existing_bonds[0].shortest_vector_relative_to(atom.parent))
                normal /= numpy.linalg.norm(normal)
            elif num_bonds == 3:
                normal = random_orthonormal(oposite_direction)
            else:
                return

            h_pos = bond_length*(oposite_direction*math.cos(opening_angle) + normal*math.sin(opening_angle))

            for i in range(num_hydrogens):
                H = Atom(name="auto H", number=1)
                H.transformation.t = atom.transformation.t + h_pos
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                h_pos = rotation.vector_apply(h_pos)
예제 #18
0
class Camera(object):
    def __init__(self):
        # register configuration settings: default camera
        from zeobuilder.gui import fields
        from zeobuilder.gui.fields_dialogs import DialogFieldInfo
        config = context.application.configuration
        config.register_setting(
            "viewer_distance",
            100.0*angstrom,
            DialogFieldInfo("Default Viewer", (1, 0), fields.faulty.Length(
                label_text="Distance from origin",
                attribute_name="viewer_distance",
                low=0.0,
                low_inclusive=True,
            )),
        )
        config.register_setting(
            "opening_angle",
            0.0,
            DialogFieldInfo("Default Viewer", (1, 1), fields.faulty.MeasureEntry(
                measure="Angle",
                label_text="Camera opening angle",
                attribute_name="opening_angle",
                low=0.0,
                low_inclusive=True,
                high=0.5*numpy.pi,
                high_inclusive=False,
                show_popup=False,
            )),
        )
        config.register_setting(
            "window_size",
            25*angstrom,
            DialogFieldInfo("Default Viewer", (1, 2), fields.faulty.Length(
                label_text="Window size",
                attribute_name="window_size",
                low=0.0,
                low_inclusive=False,
            )),
        )
        config.register_setting(
            "window_depth",
            200.0*angstrom,
            DialogFieldInfo("Default Viewer", (1, 3), fields.faulty.Length(
                label_text="Window depth",
                attribute_name="window_depth",
                low=0.0,
                low_inclusive=False,
            )),
        )

        self.reset()

    def reset(self):
        config = context.application.configuration
        self.rotation_center = Translation()
        self.rotation = Rotation()
        self.eye = Translation()
        self.eye.t[2] = config.viewer_distance
        self.opening_angle = config.opening_angle
        self.window_size = config.window_size
        self.window_depth = config.window_depth

    def get_znear(self):
        if self.opening_angle > 0.0:
            return 0.5*self.window_size/numpy.tan(0.5*self.opening_angle)
        else:
            return 0.0
    znear = property(get_znear)

    # coordinate transformations

    def eye_to_camera(self, vector_e):
        tmp = numpy.ones(2, float)
        znear = self.znear
        if znear > 0:
            return -vector_e[:2]/vector_e[2]/self.window_size*znear
        else:
            return vector_e[:2]/self.window_size

    def camera_window_to_eye(self, vector_c):
        tmp = numpy.zeros(3, float)
        tmp[:2] = vector_c*self.window_size
        znear = self.znear
        if znear > 0:
            tmp[2] = -self.znear
        else:
            tmp[2] = -self.window_size/3.0
        return tmp

    def model_to_eye(self, vector_m):
        scene = context.application.scene
        tmp = scene.model_center.vector_apply_inverse(vector_m)
        tmp = self.rotation_center.vector_apply_inverse(tmp)
        tmp = self.rotation.vector_apply_inverse(tmp)
        tmp[2] -= self.znear
        tmp = self.eye.vector_apply_inverse(tmp)
        return tmp

    def eye_to_model(self, vector_e):
        scene = context.application.scene
        tmp = self.eye.vector_apply(vector_e)
        tmp[2] += self.znear
        tmp = self.rotation.vector_apply(tmp)
        tmp = self.rotation_center.vector_apply(tmp)
        tmp = scene.model_center.vector_apply(tmp)
        return tmp

    def model_to_camera(self, vector_m):
        return self.eye_to_camera(self.model_to_eye(vector_m))

    def camera_window_to_model(self, vector_c):
        return self.eye_to_model(self.camera_window_to_eye(vector_c))

    def object_to_depth(self, gl_object):
        result = -self.model_to_eye(gl_object.get_absolute_frame().t)[2]
        return result

    def object_to_camera(self, gl_object):
        return self.eye_to_camera(self.model_to_eye(gl_object.get_absolute_frame().t))

    def object_to_eye(self, gl_object):
        return self.model_to_eye(gl_object.get_absolute_frame().t)

    def object_eye_rotation(self, gl_object):
        """
            Returns a matrix that consists of the x, y and z axes of the
            eye frame in the coordinates of the parent frame of the given
            object.
        """
        if hasattr(gl_object, "parent") and \
           isinstance(gl_object.parent, GLTransformationMixin):
            parent_matrix = gl_object.parent.get_absolute_frame().r
        else:
            parent_matrix = numpy.identity(3, float)
        result = numpy.dot(self.rotation.r.transpose(), parent_matrix).transpose()
        return result

    def depth_to_scale(self, depth):
        """ transforms a depth into a scale (au/camcoords)"""
        znear = self.znear
        if znear > 0:
            return depth/znear*self.window_size
        else:
            return self.window_size

    def vector_in_plane(self, r, p_m):
        """Returns a vector at camera position r in a plane (through p, orthogonal to viewing direction)

        Arguments
            r  --  a two-dimensional vector in camera coordinates
            p_m  --  a three-dimensional vector in model coordinates

        Returns
            rp  --  a three-dimensional vector in model coordinates that lies
                    at the intersection of a plane and a line. The plane is
                    orthogonal to the viewing direction and goes through the
                    point p. The line connects the eye (eye_m below) with the
                    point r (r_m below) in the camera window.
        """

        eye_m = self.eye_to_model(numpy.zeros(3, float))
        r_m = self.camera_window_to_model(r)
        center_m = self.camera_window_to_model(numpy.zeros(2, float))

        normal = (eye_m - center_m)
        normal /= numpy.linalg.norm(normal)

        if self.znear > 0:
            # the line is defined as r = eye_m + d*t, where t = -infinity ... infinity
            d =  eye_m - r_m

            # t at the intersection:
            t = -numpy.dot(eye_m - p_m, normal)/numpy.dot(d, normal)

            return eye_m + d*t
        else:
            # the line is defined as r = r_m + d*t, where t = -infinity ... infinity
            d = normal

            # t at the intersection:
            t = -numpy.dot(r_m - p_m, normal)/numpy.dot(d, normal)

            return r_m + d*t