Sunday, June 8, 2014

19. Kivy Properties - Mesh Example


Kivy Properties are used with a Mesh example. Mesh is a vertex canvas instruction.




We can use Kivy properties to make our variables behave like regular Kivy variables. Whenever their value changes, Kivy will update any widgets that depend on them and call the on_property function if it exists.




The first two imports are the imports for the root class and the app class. We can see the root widget is RelativeLayout. The third line imports two classes from the kivy.properties module. These will allow our number and our list Python objects to become Kivy properties.




This is the first half of the root class. Here, num is a NumericProperty with an initial value of 0. When num is changed, the on_num function, will be called by Kivy. The first part of this function is shown here. Besides num, vert, and pts are also Properties, but they are ListProperties. We do not have any on_ functions for them as they only define properties of the Mesh, and Line canvas instructions, which will be updated by Kivy. The purpose of on_num function is to create the lists, vert, and pts. We use a nested function, addPoint to add, a x, and y coordinate to the two lists.




These are the possible coordinates of the Mesh. The first point is the common point of all triangles. A number of addPoint functions will be called depending on the value of num. For example if num, is 2, the first two lines are true, and executed.




The app class is very similar to the examples, we studied before. The title of the window is set to Mesh example.


# ex19.py

from kivy.uix.relativelayout import RelativeLayout
from kivy.app import App
from kivy.properties import NumericProperty, ListProperty

class Ex19(RelativeLayout):
    num = NumericProperty(0)
    vert = ListProperty()
    pts = ListProperty()
    def on_num(self,*args):
        self.vert = []
        self.pts = []
        def addPoint(x,y):
            self.vert.extend([x,y,0,0])
            self.pts.extend([x,y])
            
        if self.num>0: addPoint(400,300) # Common pt.
        if self.num>1: addPoint(300,500) # Upper triangle 1
        if self.num>2: addPoint(500,500) # Upper triangle 2
        if self.num>3: addPoint(600,400) # Right triangle 1
        if self.num>4: addPoint(600,200) # Right triangle 2
        if self.num>5: addPoint(500,100) # Down triangle 1
        if self.num>6: addPoint(300,100) # Down triangle 2
        if self.num>7: addPoint(200,200) # Left triangle 1
        if self.num>8: addPoint(200,400) # Left triangle 2
        if self.num>9: addPoint(300,500) # Back to Upper
       
class Ex19App(App):
    def build(self):
        self.title="Mesh example"
        return Ex19()

if __name__=='__main__':
    Ex19App().run()



In the kv file, first the background color is changed.




The color for the Mesh is set as purple. The particular mesh mode creates filled triangles. The vertices will be the List vert. Indices indicate how we transverse the vertices. In our case, it will be in the order provided, thus it will be a list like [0,1,2].




To show what we mean by the right-hand side of the Indices instruction, here is an interactive session. An empty class is created so we can create a variable like root.vert. In Python 2.7, range() returns a list so we don't have to use the list() function. Also, in Python 2.7, the default division, for integers, is integer, rather than floating-point, as in Python 3 versions. In Python 3, we have to use the integer division operator with 2 divisor signs.




Finally, we use the pts list to draw the points with a large pointsize.




These 2 buttons, when pressed, either increment or decrement num. Also notice, we did not have to keep track of ids as we did in the previous example. We did not even have to create any ids.


# ex19.kv

<Ex19>:
    canvas:
        Color:
            rgb: .9,.9,.9
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgb: .5, 0, .5
        Mesh:
            mode: 'triangle_fan'
            vertices: root.vert
            indices: list(range(len(root.vert)//4))
        Color:
            rgb: 1, 0, 0
        Point:
            points: root.pts
            pointsize: 5
    Button:
        text: 'Add a point'
        size_hint: None,None
        size: 100,100
        pos: 0,0
        on_press: root.num += 1
    Button:
        text: 'Remove a point'
        size_hint: None,None
        size: 150,100
        pos: 650,0
        on_press: root.num -= 1
    


Demo of App on Youtube

1 comment:

  1. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    Python Training in electronic city

    ReplyDelete