Beispiel #1
0
class Notes(ModelObject):
    info = ModelObjectInfo("plugins/basic/notes.svg")
    authors = [authors.toon_verstraelen]

    #
    # Properties
    #

    def set_notes(self, notes, init=False):
        self.notes = notes

    properties = [
        Property("notes", StringIO.StringIO(), lambda self: self.notes, set_notes)
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo("Basic", (0, 10), fields.edit.TextView(
            label_text="Notes",
            attribute_name="notes",
        ))
    ])
Beispiel #2
0
class SavedSelection(ReferentBase):
    info = ModelObjectInfo("plugins/basic/saved_selection.svg", "RestoreSavedSelection")
    authors = [authors.toon_verstraelen]

    def set_targets(self, targets, init=False):
        self.set_children([Reference(prefix="Selected") for target in targets])
        ReferentBase.set_targets(self, targets, init)
Beispiel #3
0
class ConscanResults(ReferentBase):
    info = ModelObjectInfo("plugins/builder/conscan_results.svg",
                           "ShowConscanResultsWindow")
    authors = [authors.toon_verstraelen]

    #
    # State
    #

    def initnonstate(self):
        ReferentBase.initnonstate(self)
        self.set_children(
            [Reference(prefix="First"),
             Reference(prefix="Second")])

    #
    # Properties
    #

    def get_connections(self):
        def get_index(node):
            if node is None: return -1
            node = node()
            if node is None: return -1
            if node.model != context.application.model: return -1
            return node.get_index()

        return [(quality, transformation, [
            (get_index(node1), get_index(node2)) for node1, node2 in pairs
        ], [(get_index(node1), get_index(node2))
            for node1, node2 in inverse_pairs]) for quality, transformation,
                pairs, inverse_pairs in self.connections]

    def set_connections(self, connections, init=False):
        def get_ref(frame_index, index):
            if index is -1:
                return None
            else:
                return weakref.ref(
                    self.children[frame_index].target.children[index])

        self.connections = [
            (quality, transformation, [(get_ref(0, index1), get_ref(1, index2))
                                       for index1, index2 in pairs],
             [(get_ref(0, index1), get_ref(1, index2))
              for index1, index2 in inverse_pairs])
            for quality, transformation, pairs, inverse_pairs in connections
        ]

    properties = [
        Property("connections", [], get_connections, set_connections),
    ]
Beispiel #4
0
class Frame(GLFrameBase, FrameAxes):
    info = ModelObjectInfo("plugins/basic/frame.svg")
    authors = [authors.toon_verstraelen]

    def initnonstate(self):
        GLFrameBase.initnonstate(self, Complete)

    #
    # Tree
    #

    @classmethod
    def check_add(Class, ModelObjectClass):
        if not GLFrameBase.check_add(ModelObjectClass): return False
        Universe = context.application.plugins.get_node("Universe")
        if issubclass(ModelObjectClass, Universe): return False
        return True

    #
    # Draw
    #

    def draw(self):
        FrameAxes.draw(self, self.selected)
        GLFrameBase.draw(self)

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLFrameBase.revalidate_bounding_box(self)
        FrameAxes.extend_bounding_box(self, self.bounding_box)

    #
    # Signal handlers
    #

    def on_select_changed(self, foo):
        GLFrameBase.on_select_changed(self, foo)
        self.invalidate_draw_list()
Beispiel #5
0
class Point(GLGeometricBase, ColorMixin):
    info = ModelObjectInfo("plugins/basic/point.svg")
    authors = [authors.toon_verstraelen]

    def initnonstate(self):
        GLGeometricBase.initnonstate(self, Translation)

    #
    # Properties
    #

    def set_spike_length(self, spike_length, init=False):
        self.spike_length = spike_length
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_spike_thickness(self, spike_thickness, init=False):
        self.spike_thickness = spike_thickness
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    properties = [
        Property("spike_length", 0.3, lambda self: self.spike_length,
                 set_spike_length),
        Property("spike_thickness", 0.1, lambda self: self.spike_thickness,
                 set_spike_thickness),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 7),
            fields.faulty.Length(label_text="Spike length",
                                 attribute_name="spike_length",
                                 low=0.0,
                                 low_inclusive=False)),
        DialogFieldInfo(
            "Geometry", (2, 8),
            fields.faulty.Length(label_text="Spike thickness",
                                 attribute_name="spike_thickness",
                                 low=0.0,
                                 low_inclusive=False))
    ])

    #
    # Draw
    #

    def draw_spike(self):
        ColorMixin.draw(self)
        vb = context.application.vis_backend
        vb.draw_quad_strip(
            (numpy.array([0.5773502692, -0.5773502692, -0.5773502692]), [
                numpy.array(
                    [self.spike_length, self.spike_length, self.spike_length])
            ]), (numpy.array([1, 0, 0
                              ]), [numpy.array([self.spike_thickness, 0, 0])]),
            (numpy.array([-0.5773502692, 0.5773502692, -0.5773502692]), [
                numpy.array(
                    [self.spike_length, self.spike_length, self.spike_length])
            ]), (numpy.array([0, 1, 0
                              ]), [numpy.array([0, self.spike_thickness, 0])]),
            (numpy.array([-0.5773502692, -0.5773502692, 0.5773502692]), [
                numpy.array(
                    [self.spike_length, self.spike_length, self.spike_length])
            ]), (numpy.array([0, 0, 1
                              ]), [numpy.array([0, 0, self.spike_thickness])]),
            (numpy.array([0.5773502692, -0.5773502692, -0.5773502692]), [
                numpy.array(
                    [self.spike_length, self.spike_length, self.spike_length])
            ]), (numpy.array([1, 0, 0
                              ]), [numpy.array([self.spike_thickness, 0, 0])]))

    def draw(self):
        GLGeometricBase.draw(self)
        vb = context.application.vis_backend
        vb.push_matrix()
        for i in range(2):
            for i in range(4):
                self.draw_spike()
                vb.rotate(90, 1.0, 0.0, 0.0)
            vb.rotate(180, 0.0, 1.0, 0.0)
        vb.pop_matrix()

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLGeometricBase.revalidate_bounding_box(self)
        self.bounding_box.extend_with_corners(
            numpy.array(
                [[-self.spike_length, -self.spike_length, -self.spike_length],
                 [self.spike_length, self.spike_length, self.spike_length]]))
Beispiel #6
0
class Arrow(Vector, ColorMixin):
    info = ModelObjectInfo("plugins/basic/arrow.svg")
    authors = [authors.toon_verstraelen]

    #
    # Properties
    #

    def set_radius(self, radius, init=False):
        self.radius = radius
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_quality(self, quality, init=False):
        self.quality = quality
        if not init:
            self.invalidate_draw_list()

    def set_arrow_length(self, arrow_length, init=False):
        self.arrow_length = arrow_length
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_arrow_radius(self, arrow_radius, init=False):
        self.arrow_radius = arrow_radius
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_arrow_position(self, arrow_position, init=False):
        self.arrow_position = arrow_position
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    properties = [
        Property("radius", 0.15, lambda self: self.radius, set_radius),
        Property("quality", 15, lambda self: self.quality, set_quality),
        Property("arrow_length", 0.6, lambda self: self.arrow_length,
                 set_arrow_length),
        Property("arrow_radius", 0.3, lambda self: self.arrow_radius,
                 set_arrow_radius),
        Property("arrow_position", 0.5, lambda self: self.arrow_position,
                 set_arrow_position)
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 2),
            fields.faulty.Length(
                label_text="Radius",
                attribute_name="radius",
                low=0.0,
                low_inclusive=False,
            )),
        DialogFieldInfo(
            "Geometry", (2, 3),
            fields.faulty.Length(
                label_text="Arrow length",
                attribute_name="arrow_length",
                low=0.0,
            )),
        DialogFieldInfo(
            "Geometry", (2, 4),
            fields.faulty.Length(
                label_text="Arrow radius",
                attribute_name="arrow_radius",
                low=0.0,
                low_inclusive=False,
            )),
        DialogFieldInfo(
            "Geometry", (2, 5),
            fields.faulty.Float(
                label_text="Arrow position",
                attribute_name="arrow_position",
                low=0.0,
                high=1.0,
            )),
        DialogFieldInfo(
            "Markup", (1, 3),
            fields.faulty.Int(
                label_text="Quality",
                attribute_name="quality",
                minimum=3,
            )),
    ])

    #
    # Draw
    #

    def draw(self):
        Vector.draw(self)
        ColorMixin.draw(self)
        vb = context.application.vis_backend
        if self.length == 0.0: return
        # usefull variable
        if self.arrow_radius <= 0:
            arrowtop_length = self.arrow_length
        else:
            arrowtop_length = self.arrow_length / self.arrow_radius * self.radius
        # stick and bottom
        if (self.length - arrowtop_length > 0) and (self.radius > 0):
            vb.draw_cylinder(self.radius, self.length - arrowtop_length,
                             self.quality)
            vb.set_quadric_inside()
            vb.draw_disk(self.radius, self.quality)
        # arrowtop
        if (self.radius > 0):
            if (arrowtop_length > 0):
                vb.push_matrix()
                vb.translate(0.0, 0.0, self.length - arrowtop_length)
                vb.set_quadric_outside()
                vb.draw_cone(self.radius, 0, arrowtop_length, self.quality)
                vb.pop_matrix()
            else:
                vb.push_matrix()
                vb.translate(0.0, 0.0, self.length)
                vb.set_quadric_outside()
                vb.draw_disk(self.radius, self.quality)
                vb.pop_matrix()
        # arrow
        if (self.arrow_radius - self.radius >
                0) and (self.arrow_length - arrowtop_length) > 0:
            vb.push_matrix()
            vb.translate(0.0, 0.0, (self.length - self.arrow_length) *
                         (self.arrow_position))
            vb.set_quadric_outside()
            vb.draw_cone(self.arrow_radius, self.radius,
                         self.arrow_length - arrowtop_length, self.quality)
            vb.set_quadric_inside()
            vb.draw_disk(self.arrow_radius, self.quality)
            vb.pop_matrix()
        vb.set_quadric_outside()

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        Vector.revalidate_bounding_box(self)
        if self.length > 0.0:
            self.bounding_box.extend_with_corners(
                numpy.array([[0.0, 0.0, 0.0], [0.0, 0.0, self.length]]))
            temp = {
                True: self.radius,
                False: self.arrow_radius
            }[self.radius > self.arrow_radius]
            self.bounding_box.extend_with_corners(
                numpy.array([[-temp, -temp, 0.0], [temp, temp, 0.0]]))
Beispiel #7
0
class Plane(GLReferentBase, ColorMixin):
    info = ModelObjectInfo("plugins/basic/plane.svg")
    authors = [authors.toon_verstraelen]

    #
    # State
    #

    def set_targets(self, targets, init=False):
        self.set_children([SpatialReference("Point") for target in targets])
        GLReferentBase.set_targets(self, targets, init)

    #
    # Properties
    #

    def set_margin(self, margin, init=False):
        self.margin = margin
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    properties = [
        Property("margin", 1.0, lambda self: self.margin, set_margin),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 10),
            fields.faulty.Length(
                label_text="Margin",
                attribute_name="margin",
                low=0.0,
                low_inclusive=True,
            )),
    ])

    #
    # Draw
    #

    def update_normal(self):
        self.points = numpy.array([
            child.target.get_frame_relative_to(self.parent).t
            for child in self.children if child.target is not None
        ], float)

        self.center = sum(self.points) / len(self.points)
        tmp = self.points - self.center
        tensor = (tmp.ravel()**2).sum() * numpy.identity(3) - numpy.dot(
            tmp.transpose(), tmp)
        evals, evecs = numpy.linalg.eigh(tensor)
        indices = evals.argsort()
        self.x = evecs[:, indices[0]]
        self.y = evecs[:, indices[1]]
        if numpy.linalg.det(evecs) < 0:
            self.normal = evecs[:, indices[2]]
        else:
            self.normal = -evecs[:, indices[2]]
        px = numpy.dot(tmp, self.x)
        py = numpy.dot(tmp, self.y)

        px_low = px.min() - self.margin
        px_high = px.max() + self.margin
        py_low = py.min() - self.margin
        py_high = py.max() + self.margin

        self.l_l = self.x * px_low + self.y * py_low + self.center
        self.l_h = self.x * px_low + self.y * py_high + self.center
        self.h_l = self.x * px_high + self.y * py_low + self.center
        self.h_h = self.x * px_high + self.y * py_high + self.center

    def draw(self):
        GLReferentBase.draw(self)
        ColorMixin.draw(self)
        self.update_normal()
        vb = context.application.vis_backend
        vb.draw_quads((
            self.normal,
            [
                self.l_l + 0.001 * self.normal,
                self.l_h + 0.001 * self.normal,
                self.h_h + 0.001 * self.normal,
                self.h_l + 0.001 * self.normal,
            ],
        ), (
            -self.normal,
            [
                self.h_l - 0.001 * self.normal,
                self.h_h - 0.001 * self.normal,
                self.l_h - 0.001 * self.normal,
                self.l_l - 0.001 * self.normal,
            ],
        ))

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLReferentBase.revalidate_bounding_box(self)
        self.update_normal()
        self.bounding_box.extend_with_point(self.l_l)
        self.bounding_box.extend_with_point(self.l_h)
        self.bounding_box.extend_with_point(self.h_l)
        self.bounding_box.extend_with_point(self.h_h)

    #
    # Vector
    #

    def define_target(self, reference, new_target):
        GLReferentBase.define_target(self, reference, new_target)
        self.invalidate_boundingbox_list()
        self.invalidate_draw_list()

    def target_moved(self, reference, target):
        GLReferentBase.target_moved(self, reference, target)
        self.invalidate_boundingbox_list()
        self.invalidate_draw_list()
Beispiel #8
0
class Spring(Vector, ColorMixin):
    info = ModelObjectInfo("plugins/builder/spring.svg")
    authors = [authors.toon_verstraelen]

    #
    # Properties
    #

    def set_radius(self, radius, init=False):
        self.radius = radius
        if not init:
            self.invalidate_draw_list()

    def set_quality(self, quality, init=False):
        self.quality = quality
        if not init:
            self.invalidate_draw_list()

    def set_rest_length(self, rest_length, init=False):
        self.rest_length = rest_length
        if not init:
            self.invalidate_draw_list()

    properties = [
        Property("radius", 0.5, lambda self: self.radius, set_radius),
        Property("quality", 15, lambda self: self.quality, set_quality),
        Property("rest_length", 0.0, lambda self: self.rest_length,
                 set_rest_length),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 2),
            fields.faulty.Length(
                label_text="Radius",
                attribute_name="radius",
                low=0.0,
                low_inclusive=False,
            )),
        DialogFieldInfo(
            "Markup", (1, 3),
            fields.faulty.Int(
                label_text="Quality",
                attribute_name="quality",
                minimum=3,
            )),
        DialogFieldInfo(
            "Basic", (0, 8),
            fields.faulty.Length(
                label_text="Rest length",
                attribute_name="rest_length",
                low=0.0,
                low_inclusive=True,
            )),
    ])

    #
    # Draw
    #

    def draw(self):
        Vector.draw(self)
        ColorMixin.draw(self)
        vb = context.application.vis_backend
        if self.length > self.rest_length:
            l_cyl = self.rest_length
            l_cone = 0.5 * (self.length - l_cyl)
            if l_cone > 0:
                vb.draw_cone(self.radius, 0.0, l_cone, self.quality)
                vb.translate(0.0, 0.0, l_cone)
            if l_cyl > 0:
                vb.draw_cone(0.5 * self.radius, 0.5 * self.radius, l_cyl,
                             self.quality)
                vb.translate(0.0, 0.0, l_cyl)
            if l_cone > 0:
                vb.draw_cone(0.0, self.radius, l_cone, self.quality)
        else:
            l_cyl = self.length
            l_cone = 0.5 * (self.rest_length - self.length)
            if l_cone > 0:
                vb.translate(0.0, 0.0, -l_cone)
                vb.draw_cone(0.0, self.radius, l_cone, self.quality)
                vb.translate(0.0, 0.0, l_cone)
            if l_cyl > 0:
                vb.draw_cylinder(0.5 * self.radius, l_cyl, self.quality)
                vb.translate(0.0, 0.0, l_cyl)
            if l_cone > 0:
                vb.draw_cone(self.radius, 0.0, l_cone, self.quality)

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        Vector.revalidate_bounding_box(self)
        if self.length > 0:
            self.bounding_box.extend_with_point(
                numpy.array([-self.radius, -self.radius, 0]))
            self.bounding_box.extend_with_point(
                numpy.array([self.radius, self.radius, self.length]))
Beispiel #9
0
class Universe(GLPeriodicContainer, FrameAxes):
    info = ModelObjectInfo("plugins/basic/universe.svg")
    authors = [authors.toon_verstraelen]
    clip_margin = 0.1

    #
    # State
    #

    def initnonstate(self):
        GLPeriodicContainer.initnonstate(self)
        self.model_center = Translation.identity()

    def update_center(self):
        self.model_center = Translation(
            0.5 *
            numpy.dot(self.cell.matrix, self.repetitions * self.cell.active))

    #
    # Properties
    #

    def set_cell(self, cell, init=False):
        GLPeriodicContainer.set_cell(self, cell, init)
        if not init:
            self.update_clip_planes()
            self.update_center()
            self.invalidate_total_list()
            self.invalidate_box_list()

    def set_repetitions(self, repetitions, init=False):
        self.repetitions = repetitions
        if not init:
            self.update_clip_planes()
            self.update_center()
            self.invalidate_box_list()
            self.invalidate_total_list()

    def set_box_visible(self, box_visible, init=False):
        self.box_visible = box_visible
        if not init:
            self.invalidate_total_list()

    def set_clipping(self, clipping, init=False):
        self.clipping = clipping
        if not init:
            self.invalidate_total_list()
            self.invalidate_box_list()
            self.update_clip_planes()

    properties = [
        Property("repetitions", numpy.array([1, 1, 1], int),
                 lambda self: self.repetitions, set_repetitions),
        Property("box_visible", True, lambda self: self.box_visible,
                 set_box_visible),
        Property("clipping", False, lambda self: self.clipping, set_clipping),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Unit cell", (5, 2),
            fields.composed.Repetitions(
                label_text="Repetitions",
                attribute_name="repetitions",
            )),
        DialogFieldInfo(
            "Markup", (1, 5),
            fields.edit.CheckButton(
                label_text="Show periodic box (if active)",
                attribute_name="box_visible",
            )),
        DialogFieldInfo(
            "Markup", (1, 6),
            fields.edit.CheckButton(
                label_text="Clip the unit cell contents.",
                attribute_name="clipping",
            )),
    ])

    #
    # Tree
    #

    @classmethod
    def check_add(Class, ModelObjectClass):
        if not GLPeriodicContainer.check_add(ModelObjectClass): return False
        if issubclass(ModelObjectClass, Universe): return False
        return True

    #
    # OpenGL
    #

    def initialize_gl(self):
        vb = context.application.vis_backend
        self.set_clip_planes()
        self.update_center()
        self.box_list = vb.create_list()
        ##print "Created box list (%i): %s" % (self.box_list, self.get_name())
        self.box_list_valid = True
        GLPeriodicContainer.initialize_gl(self)

    def cleanup_gl(self):
        vb = context.application.vis_backend
        GLPeriodicContainer.cleanup_gl(self)
        ##print "Deleting box list (%i): %s" % (self.box_list, self.get_name())
        vb.delete_list(self.box_list)
        del self.box_list
        del self.box_list_valid
        self.unset_clip_planes()

    #
    # Clipping
    #

    def update_clip_planes(self):
        if self.gl_active > 0:
            self.unset_clip_planes()
            self.set_clip_planes()

    def set_clip_planes(self):
        if not self.clipping:
            return
        clip_planes = context.application.scene.clip_planes
        assert len(clip_planes) == 0
        active, inactive = self.cell.active_inactive
        for index in active:
            axis = self.cell.matrix[:, index]
            ortho = self.cell.reciprocal[index] / numpy.linalg.norm(
                self.cell.reciprocal[index])
            length = abs(numpy.dot(ortho, axis))
            repetitions = self.repetitions[index]
            clip_planes.append(numpy.array(list(ortho) + [self.clip_margin]))
            clip_planes.append(
                numpy.array(
                    list(-ortho) + [repetitions * length + self.clip_margin]))
        context.application.main.drawing_area.queue_draw()

    def unset_clip_planes(self):
        context.application.scene.clip_planes = []
        context.application.main.drawing_area.queue_draw()

    def shortest_vector(self, delta):
        return self.cell.shortest_vector(delta)

    #
    # Invalidation
    #

    def invalidate_box_list(self):
        if self.gl_active > 0 and self.box_list_valid:
            self.box_list_valid = False
            context.application.main.drawing_area.queue_draw()
            context.application.scene.add_revalidation(
                self.revalidate_box_list)
            ##print "EMIT %s: on-box-list-invalidated" % self.get_name()

    def invalidate_all_lists(self):
        self.invalidate_box_list()
        GLPeriodicContainer.invalidate_all_lists(self)

    #
    # Draw
    #

    def draw_box(self):
        vb = context.application.vis_backend
        vb.set_line_width(2)
        vb.set_specular(False)

        col = {True: 4.0, False: 2.5}[self.selected]
        sat = {True: 0.0, False: 0.5}[self.selected]
        gray = {True: 4.0, False: 2.5}[self.selected]

        def draw_three(origin):
            if self.cell.active[0]:
                vb.set_color(col, sat, sat)
                vb.draw_line(origin, origin + self.cell.matrix[:, 0])
            if self.cell.active[1]:
                vb.set_color(sat, col, sat)
                vb.draw_line(origin, origin + self.cell.matrix[:, 1])
            if self.cell.active[2]:
                vb.set_color(sat, sat, col)
                vb.draw_line(origin, origin + self.cell.matrix[:, 2])

        def draw_gray(origin, axis1, axis2, n1, n2, delta, nd):
            c = context.application.configuration.periodic_box_color
            vb.set_color(gray * c[0], gray * c[1], gray * c[2], c[3])
            if n1 == 0 and n2 == 0:
                return
            for i1 in xrange(n1 + 1):
                if i1 == 0:
                    b2 = 1
                    vb.draw_line(origin + delta, origin + nd * delta)
                else:
                    b2 = 0
                for i2 in xrange(b2, n2 + 1):
                    vb.draw_line(origin + i1 * axis1 + i2 * axis2,
                                 origin + i1 * axis1 + i2 * axis2 + nd * delta)

        def draw_ortho(origin, axis1, axis2, n1, n2, delta):
            c = context.application.configuration.periodic_box_color
            vb.set_color(gray * c[0], gray * c[1], gray * c[2], c[3])
            if n1 == 0 and n2 == 0:
                return
            for i1 in xrange(n1 + 1):
                for i2 in xrange(n2 + 1):
                    vb.draw_line(
                        origin + i1 * axis1 + i2 * axis2 - 0.5 * delta,
                        origin + i1 * axis1 + i2 * axis2 + 0.5 * delta)

        origin = numpy.zeros(3, float)
        draw_three(origin)
        repetitions = self.repetitions * self.cell.active

        if self.cell.active[2]:
            draw_gray(origin, self.cell.matrix[:, 0], self.cell.matrix[:, 1],
                      repetitions[0], repetitions[1], self.cell.matrix[:, 2],
                      repetitions[2])
        else:
            draw_ortho(origin, self.cell.matrix[:, 0], self.cell.matrix[:, 1],
                       repetitions[0], repetitions[1], self.cell.matrix[:, 2])

        if self.cell.active[0]:
            draw_gray(origin, self.cell.matrix[:, 1], self.cell.matrix[:, 2],
                      repetitions[1], repetitions[2], self.cell.matrix[:, 0],
                      repetitions[0])
        else:
            draw_ortho(origin, self.cell.matrix[:, 1], self.cell.matrix[:, 2],
                       repetitions[1], repetitions[2], self.cell.matrix[:, 0])

        if self.cell.active[1]:
            draw_gray(origin, self.cell.matrix[:, 2], self.cell.matrix[:, 0],
                      repetitions[2], repetitions[0], self.cell.matrix[:, 1],
                      repetitions[1])
        else:
            draw_ortho(origin, self.cell.matrix[:, 2], self.cell.matrix[:, 0],
                       repetitions[2], repetitions[0], self.cell.matrix[:, 1])

        vb.set_specular(True)

    def draw(self):
        FrameAxes.draw(self, self.selected)
        GLPeriodicContainer.draw(self)

    #
    # Revalidation
    #

    def revalidate_box_list(self):
        if self.gl_active > 0:
            ##print "Compiling box list (%i): %s" % (self.box_list,  self.get_name())
            vb = context.application.vis_backend
            vb.begin_list(self.box_list)
            if sum(self.cell.active) > 0:
                self.draw_box()
            vb.end_list()
            self.box_list_valid = True

    def revalidate_total_list(self):
        if self.gl_active > 0:
            ##print "Compiling total list (%i): %s" % (self.total_list, self.get_name())
            vb = context.application.vis_backend
            vb.begin_list(self.total_list)
            if self.visible:
                vb.push_name(self.draw_list)
                if sum(self.cell.active) == 0:
                    if self.selected:
                        vb.call_list(self.boundingbox_list)
                else:
                    if self.selected:
                        vb.set_bright(True)
                    else:
                        vb.set_bright(False)

                if self.box_visible: vb.call_list(self.box_list)

                # repeat the draw list for all the unit cell images.
                if self.clipping:
                    repetitions = (self.repetitions +
                                   2) * self.cell.active + 1 - self.cell.active
                else:
                    repetitions = self.repetitions * self.cell.active + 1 - self.cell.active
                for position in iter_all_positions(repetitions):
                    vb.push_matrix()
                    t = numpy.dot(
                        self.cell.matrix,
                        numpy.array(position) -
                        self.cell.active * self.clipping)
                    vb.translate(*t)
                    vb.call_list(self.draw_list)
                    vb.pop_matrix()

                vb.pop_name()
            vb.end_list()
            self.total_list_valid = True

    def revalidate_bounding_box(self):
        GLPeriodicContainer.revalidate_bounding_box(self)
        FrameAxes.extend_bounding_box(self, self.bounding_box)

    #
    # Signal handlers
    #

    def on_select_chaged(self, selected):
        GLPeriodicContainer.on_select_chaged(self, selected)
        self.invalidate_box_list()
Beispiel #10
0
class Sphere(GLGeometricBase, ColorMixin):
    info = ModelObjectInfo("plugins/basic/sphere.svg")
    authors = [authors.toon_verstraelen]

    def initnonstate(self):
        GLGeometricBase.initnonstate(self, Translation)

    #
    # Properties
    #

    def set_radius(self, radius, init=False):
        self.radius = radius
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_quality(self, quality, init=False):
        self.quality = quality
        if not init:
            self.invalidate_draw_list()

    properties = [
        Property("radius", 0.5, lambda self: self.radius, set_radius),
        Property("quality", 15, lambda self: self.quality, set_quality),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo("Geometry", (2, 2), fields.faulty.Length(
            label_text="Radius",
            attribute_name="radius",
            low=0.0,
            low_inclusive=False,
        )),
        DialogFieldInfo("Markup", (1, 3), fields.faulty.Int(
            label_text="Quality",
            attribute_name="quality",
            minimum=3,
        ))
    ])

    #
    # Draw
    #

    def draw(self):
        GLGeometricBase.draw(self)
        ColorMixin.draw(self)
        vb = context.application.vis_backend
        vb.draw_sphere(self.radius, self.quality)

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLGeometricBase.revalidate_bounding_box(self)
        self.bounding_box.extend_with_corners(numpy.array([
            [-self.radius, -self.radius, -self.radius],
            [ self.radius,  self.radius,  self.radius]
        ]))
Beispiel #11
0
class Bond(Vector):
    info = ModelObjectInfo("plugins/molecular/bond.svg")
    authors = [authors.toon_verstraelen]

    #
    # State
    #

    def initnonstate(self):
        Vector.initnonstate(self)
        self.handlers = {}

    #
    # Properties
    #

    def set_quality(self, quality, init=False):
        self.quality = quality
        if not init:
            self.invalidate_draw_list()

    def set_bond_type(self, bond_type, init=False):
        self.bond_type = bond_type
        if not init:
            self.invalidate_draw_list()

    properties = [
        Property("quality", 15, lambda self: self.quality, set_quality),
        Property("bond_type", BOND_SINGLE, lambda self: self.bond_type, set_bond_type)
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo("Markup", (1, 3), fields.faulty.Int(
            label_text="Quality",
            attribute_name="quality",
            minimum=3,
        )),
        DialogFieldInfo("Molecular", (6, 1), fields.edit.ComboBox(
            choices=[
                (BOND_SINGLE, "Single bond"),
                (BOND_DOUBLE, "Double bond"),
                (BOND_TRIPLE, "Triple bond"),
                (BOND_HYBRID, "Hybrid bond"),
                (BOND_HYDROGEN, "Hydrogen bond"),
            ],
            label_text="Bond type",
            attribute_name="bond_type",
        )),
    ])

    #
    # References
    #

    def define_target(self, reference, new_target):
        Vector.define_target(self, reference, new_target)
        self.handlers[new_target] = [
            new_target.connect("on_number_changed", self.atom_property_changed),
            new_target.connect("on_user_radius_changed", self.atom_property_changed),
            new_target.connect("on_user_color_changed", self.atom_property_changed),
        ]

    def undefine_target(self, reference, old_target):
        Vector.undefine_target(self, reference, old_target)
        for handler in self.handlers[old_target]:
            old_target.disconnect(handler)

    def check_target(self, reference, target):
        return isinstance(target, context.application.plugins.get_node("Atom"))

    def atom_property_changed(self, atom):
        self.invalidate_boundingbox_list()
        self.invalidate_draw_list()

    #
    # Draw
    #

    def draw(self):
        Vector.draw(self)
        if self.length <= 0: return
        half_length = 0.5 * (self.end_position - self.begin_position)
        if half_length <= 0: return
        half_radius = 0.5 * (self.begin_radius + self.end_radius)

        begin = self.children[0].target
        end = self.children[1].target

        vb = context.application.vis_backend
        vb.set_color(*begin.get_color())
        vb.translate(0.0, 0.0, self.begin_position)
        vb.draw_cone(self.begin_radius, half_radius, half_length, self.quality)
        vb.translate(0.0, 0.0, half_length)
        vb.set_color(*end.get_color())
        vb.draw_cone(half_radius, self.end_radius, half_length, self.quality)

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        Vector.revalidate_bounding_box(self)
        if self.length > 0:
            temp = {True: self.begin_radius, False: self.end_radius}[self.begin_radius > self.end_radius]
            self.bounding_box.extend_with_point(numpy.array([-temp, -temp, self.begin_position]))
            self.bounding_box.extend_with_point(numpy.array([temp, temp, self.end_position]))

    def calc_vector_dimensions(self):
        Vector.calc_vector_dimensions(self)
        begin = self.children[0].target
        end = self.children[1].target
        if self.length <= 0.0: return
        c = (begin.get_radius() - end.get_radius()) / self.length
        if abs(c) > 1:
            self.begin_radius = 0
            self.end_radius = 0
            self.begin_position = 0
            self.end_position = 0
        else:
            scale = 0.4
            s = numpy.sqrt(1 - c**2)
            self.begin_radius = scale * begin.get_radius() * s
            self.end_radius = scale * end.get_radius() * s
            self.begin_position = scale * c * begin.get_radius()
            self.end_position = self.length + scale * c * end.get_radius()
Beispiel #12
0
class Folder(ContainerBase):
    info = ModelObjectInfo("plugins/basic/folder.svg")
    authors = [authors.toon_verstraelen]
Beispiel #13
0
class Box(GLGeometricBase, ColorMixin):
    info = ModelObjectInfo("plugins/basic/box.svg")
    authors = [authors.toon_verstraelen]

    def initnonstate(self):
        GLGeometricBase.initnonstate(self, Complete)

    #
    # Properties
    #

    def set_size(self, size, init=False):
        self.size = size
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    properties = [
        Property("size", numpy.array([1.0, 1.0, 1.0]), lambda self: self.size,
                 set_size),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 6),
            fields.composed.ComposedArray(
                FieldClass=fields.faulty.Length,
                array_name="%s",
                suffices=["Width", "Height", "Depth"],
                label_text="Box size",
                attribute_name="size",
            ))
    ])

    #
    # Draw
    #

    def draw(self):
        GLGeometricBase.draw(self)
        ColorMixin.draw(self)
        vb = context.application.vis_backend

        x, y, z = numpy.identity(3)
        sides = numpy.array([(x, y, z, z), (x, y, -z, -z), (y, z, x, x),
                             (y, z, -x, -x), (z, x, y, y), (z, x, -y, -y)],
                            float)
        sides[:, :3] *= 0.5 * self.size

        vb.draw_quads(*[(normal, [
            a + b + c,
            a - b + c,
            -a - b + c,
            -a + b + c,
        ]) for a, b, c, normal in sides])

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLGeometricBase.revalidate_bounding_box(self)
        self.bounding_box.extend_with_corners(
            numpy.array([-0.5 * self.size, 0.5 * self.size]))
Beispiel #14
0
class Atom(GLGeometricBase, UserColorMixin):
    info = ModelObjectInfo("plugins/molecular/atom.svg")
    authors = [authors.toon_verstraelen]

    #
    # State
    #

    def initnonstate(self):
        GLGeometricBase.initnonstate(self, Translation)

    #
    # Properties
    #

    def set_user_radius(self, user_radius, init=False):
        self.user_radius = user_radius
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    def set_quality(self, quality, init=False):
        self.quality = quality
        if not init:
            self.invalidate_draw_list()

    def set_number(self, number, init=False):
        self.number = number
        atom_info = periodic[number]
        if atom_info.vdw_radius is not None:
            self.default_radius = atom_info.vdw_radius * 0.2
        else:
            self.default_radius = 1.0
        color = [atom_info.red, atom_info.green, atom_info.blue, 1.0]
        if None in color:
            self.default_color = numpy.array([0.7, 0.7, 0.7, 1.0], float)
        else:
            self.default_color = numpy.array(color, float)
        if not init:
            self.invalidate_draw_list()
            self.invalidate_boundingbox_list()

    properties = [
        Property("user_radius",
                 Undefined(0.5),
                 lambda self: self.user_radius,
                 set_user_radius,
                 signal=True),
        Property("quality", 15, lambda self: self.quality, set_quality),
        Property("number",
                 6,
                 lambda self: self.number,
                 set_number,
                 signal=True),
    ]

    #
    # Dialog fields (see action EditProperties)
    #

    dialog_fields = set([
        DialogFieldInfo(
            "Geometry", (2, 9),
            fields.optional.CheckOptional(
                fields.faulty.Length(
                    label_text="User defined radius",
                    attribute_name="user_radius",
                    low=0.0,
                    low_inclusive=False,
                ))),
        DialogFieldInfo(
            "Markup", (1, 3),
            fields.faulty.Int(
                label_text="Quality",
                attribute_name="quality",
                minimum=3,
            )),
        DialogFieldInfo(
            "Molecular", (6, 0),
            fields.edit.Element(
                attribute_name="number",
                show_popup=False,
            )),
    ])

    #
    # Draw
    #

    def get_radius(self):
        if isinstance(self.user_radius, Undefined):
            return self.default_radius
        else:
            return self.user_radius

    def draw(self):
        GLGeometricBase.draw(self)
        UserColorMixin.draw(self)
        vb = context.application.vis_backend
        vb.draw_sphere(self.get_radius(), self.quality)

    #
    # Revalidation
    #

    def revalidate_bounding_box(self):
        GLGeometricBase.revalidate_bounding_box(self)
        radius = self.get_radius()
        self.bounding_box.extend_with_corners(
            numpy.array([[-radius, -radius, -radius], [radius, radius,
                                                       radius]]))

    #
    # Tools
    #

    def num_bonds(self):
        Bond = context.application.plugins.get_node("Bond")
        return sum(
            isinstance(reference.parent, Bond)
            for reference in self.references)

    def iter_bonds(self):
        Bond = context.application.plugins.get_node("Bond")
        for reference in self.references:
            referent = reference.parent
            if isinstance(referent, Bond):
                yield referent

    def iter_neighbors(self):
        for bond in self.iter_bonds():
            first = bond.children[0].target
            if first == self:
                neighbor = bond.children[1].target
            else:
                neighbor = first
            if isinstance(neighbor, Atom):
                yield neighbor