/usr/share/kivy-examples/canvas/tesselate.py is in python-kivy-examples 1.9.1-1build3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | '''
Tesselate Demonstration
=======================
This demonstrates the experimental library for tesselating polygons. You
should see a hollow square with some buttons below it. You can click and
drag to create additional shapes, watching the number of vertexes and elements
at the top of the screen. The 'debug' button toggles showing the mesh in
different colors.
'''
from kivy.app import App
from kivy.graphics import Mesh, Color
from kivy.graphics.tesselator import Tesselator, WINDING_ODD, TYPE_POLYGONS
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.logger import Logger
Builder.load_string("""
<ShapeBuilder>:
BoxLayout:
size_hint_y: None
height: "48dp"
spacing: "2dp"
padding: "2dp"
ToggleButton:
text: "Debug"
id: debug
on_release: root.build()
Button:
text: "New shape"
on_release: root.push_shape()
Button:
text: "Build"
on_release: root.build()
Button:
text: "Reset"
on_release: root.reset()
BoxLayout:
size_hint_y: None
height: "48dp"
top: root.top
spacing: "2dp"
padding: "2dp"
Label:
id: status
text: "Status"
""")
class ShapeBuilder(FloatLayout):
def __init__(self, **kwargs):
super(ShapeBuilder, self).__init__(**kwargs)
self.shapes = [
[100, 100, 300, 100, 300, 300, 100, 300],
[150, 150, 250, 150, 250, 250, 150, 250]
] # the 'hollow square' shape
self.shape = []
self.build()
def on_touch_down(self, touch):
if super(ShapeBuilder, self).on_touch_down(touch):
return True
Logger.info('tesselate: on_touch_down (%5.2f, %5.2f)' % touch.pos)
self.shape.extend(touch.pos)
self.build()
return True
def on_touch_move(self, touch):
if super(ShapeBuilder, self).on_touch_move(touch):
return True
Logger.info('tesselate: on_touch_move (%5.2f, %5.2f)' % touch.pos)
self.shape.extend(touch.pos)
self.build()
return True
def on_touch_up(self, touch):
if super(ShapeBuilder, self).on_touch_up(touch):
return True
Logger.info('tesselate: on_touch_up (%5.2f, %5.2f)' % touch.pos)
self.push_shape()
self.build()
def push_shape(self):
self.shapes.append(self.shape)
self.shape = []
def build(self):
tess = Tesselator()
count = 0
for shape in self.shapes:
if len(shape) >= 3:
tess.add_contour(shape)
count += 1
if self.shape and len(self.shape) >= 3:
tess.add_contour(self.shape)
count += 1
if not count:
return
ret = tess.tesselate(WINDING_ODD, TYPE_POLYGONS)
Logger.info('tesselate: build: tess.tesselate returns {}'.format(ret))
self.canvas.after.clear()
debug = self.ids.debug.state == "down"
if debug:
from random import random
with self.canvas.after:
c = 0
for vertices, indices in tess.meshes:
Color(c, 1, 1, mode="hsv")
c += 0.3
indices = [0]
for i in range(1, len(vertices) // 4):
if i > 0:
indices.append(i)
indices.append(i)
indices.append(0)
indices.append(i)
indices.pop(-1)
Mesh(vertices=vertices, indices=indices, mode="lines")
else:
with self.canvas.after:
Color(1, 1, 1, 1)
for vertices, indices in tess.meshes:
Mesh(vertices=vertices, indices=indices,
mode="triangle_fan")
self.ids.status.text = "Shapes: {} - Vertex: {} - Elements: {}".format(
count, tess.vertex_count, tess.element_count)
def reset(self):
self.shapes = []
self.shape = []
self.ids.status.text = "Shapes: {} - Vertex: {} - Elements: {}".format(
0, 0, 0)
self.canvas.after.clear()
class TessApp(App):
def build(self):
return ShapeBuilder()
TessApp().run()
|