def _build_grid(self): axes = 2 v_idx = 0 for axis in range(axes): # number of lines to draw num_lines = int(self.size[axis] / self.spacing) + 1 for line_idx in range(num_lines): # work out starting and ending positions start_x = -(self.size[axis] / 2) + (line_idx * self.spacing) start_y = -(self.size[1 - axis] / 2) end_x = start_x end_y = start_y + self.size[1 - axis] if axis == 0: v_front = Vector3(start_x, start_y, 0) v_back = Vector3(end_x, end_y, 0) elif axis == 1: v_front = Vector3(start_y, start_x, 0) v_back = Vector3(end_y, end_x, 0) self.vertices.append(v_front) self.vertices.append(v_back) self.lines.append(Line2(a=v_idx, b=v_idx + 1)) v_idx += 2
def test_sub(self): v1 = Vector3(4, 5, 6) v2 = Vector3(1, 2, 3) v = v1 - v2 self.assertEqual(v, [3, 3, 3]) v1.sub(v2) self.assertEqual(v1, [3, 3, 3]) self.assertEqual(v - 3, [0, 0, 0])
def test_minmax(self): v = Vector3(6, 7, 4) v1 = Vector3(3, 5, 8) v.min(v1) self.assertEqual(v, [3, 5, 4]) v2 = Vector3(1, 7, 6) v.max(v2) self.assertEqual(v, [3, 7, 6])
def test_add(self): v1 = Vector3(1, 2, 3) v2 = Vector3(4, 5, 6) v = v1 + v2 self.assertEqual(v, [5, 7, 9]) v1.add(v2) self.assertEqual(v1, [5, 7, 9]) self.assertEqual(v + 2, [7, 9, 11])
def test_angle(self): v1 = Vector3(0, 0, 1) v2 = Vector3(0, 1, 0) angle = v1.angle(v2) self.assertEqual(math.degrees(angle), 90.0) v1 = Vector3(0, 0, 1) v2 = Vector3(0, 0, -1) angle = v1.angle(v2) self.assertEqual(math.degrees(angle), 180.0)
def calculate_normal(self, face): """ Calculate and return the normal to the plane on a given face. Normal points in direction according right-hand rule. :param face: :return: """ vec_a = self.vertices[face.a] vec_b = self.vertices[face.b] vec_c = self.vertices[face.c] b_minus_a = Vector3.sub_vectors(vec_b, vec_a) c_minus_a = Vector3.sub_vectors(vec_c, vec_a) b_minus_a.cross(c_minus_a) normal = b_minus_a return normal
def __init__(self, material, size=(1, 1, 1), **kw): super(Cube, self).__init__(**kw) self.material = material self.vertex_format = kw.pop("vertex_format", DEFAULT_VERTEX_FORMAT) self.mode = kw.pop("mode", "lines") self.size = Vector3(size) self.create_mesh()
def _build_polygon(self, radius, z, segments=32, reverse_vertex_order=False): """ Generate a polygon given number of segments and radius :param radius: :param z: :param segments: :param reverse_vertex_order: :return: """ vertex_start_index = len(self.vertices) for i in range(segments): angle = (math.pi / 2) + (i / segments) * 2 * math.pi x = radius * math.cos(angle) y = radius * math.sin(angle) vertex = Vector3(x, y, z) self.vertices.append(vertex) if i >= 2: if reverse_vertex_order: face = Face3(vertex_start_index + i, vertex_start_index + i-1, vertex_start_index) else: face = Face3(vertex_start_index, vertex_start_index + i - 1, vertex_start_index + i) normal = self.calculate_normal(face) face.vertex_normals = [normal, normal, normal] self.faces.append(face)
def build_vertices_flat(self, radius, sectors, stacks): sector_step = 2 * math.pi / sectors stack_step = math.pi / stacks # compute all vertices first, each vertex contains (x, y, z) except normal for i in range(stacks): stack_angle = (math.pi / 2) - (i * stack_step ) # range: pi/2 -> -pi/2 xy = radius * math.cos(stack_angle) # r * cos(u) z = radius * math.sin(stack_angle) # r * sin(u) # add (sectors + 1) vertices per stack for j in range(sectors): sector_angle = j * sector_step # from 0 to 2pi vec = Vector3( xy * math.cos(sector_angle), # x = r * cos(u) * cos(v) xy * math.sin(sector_angle), # y = r * cos(u) * sin(v) z) # z = r * sin(u) self.vertices.append(vec) index = 0 for i in range(stacks): vi_1 = i * (sectors + 1) vi_2 = (i + 1) * (sectors + 1)
def _build_mesh(self, stl_mesh): for i in range(stl_mesh.attr.size): for j in range(3): v = Vector3(stl_mesh.vectors[i][j][0], stl_mesh.vectors[i][j][1], stl_mesh.vectors[i][j][2]) self.vertices.append(v) f_index = i * 3 face3 = Face3(f_index, f_index + 1, f_index + 2) face3.normal = Vector3(stl_mesh.normals[i][0], stl_mesh.normals[i][1], stl_mesh.normals[i][2]) face3.vertex_normals = [face3.normal, face3.normal, face3.normal] self.faces.append(face3)
def create_mesh(self): """ Create real mesh object from the geometry and material """ vertices = [] indices = [] idx = 0 for face in self.geometry.faces: for i, k in enumerate(['a', 'b', 'c']): v_idx = getattr(face, k) vertex = self.geometry.vertices[v_idx] vertices.extend(vertex) try: normal = face.vertex_normals[i] except IndexError: normal = Vector3([0, 0, 0]) vertices.extend(normal) try: tex_coords = self.geometry.face_vertex_uvs[0][idx] vertices.extend(tex_coords) except IndexError: vertices.extend([0, 0]) indices.append(idx) idx += 1 kw = { "vertices": vertices, "indices": indices, "fmt": self.vertex_format, "mode": self.mode } if self.material.map: kw["texture"] = self.material.map self._mesh = KivyMesh(**kw)
def create_mesh(self): """ Create real mesh object from the geometry and material """ vertices = [] indices = [] idx = 0 for face in self.geometry.faces: for i, k in enumerate(['a', 'b', 'c']): v_idx = getattr(face, k) vertex = self.geometry.vertices[v_idx] vertices.extend(vertex) try: normal = face.vertex_normals[i] except IndexError: normal = Vector3([0, 0, 0]) vertices.extend(normal) try: tex_coords = self.geometry.face_vertex_uvs[0][idx] vertices.extend(tex_coords) except IndexError: vertices.extend([0, 0]) indices.append(idx) idx += 1 if idx >= 65535 - 1: msg = 'Mesh must not contain more than 65535 indices, {} given' raise ValueError(msg.format(idx + 1)) kw = dict( vertices=vertices, indices=indices, fmt=self.vertex_format, mode=self.mesh_mode ) if self.material.map: kw['texture'] = self.material.map self._mesh = KivyMesh(**kw)
def build_sphere(self, radius, sectors, stacks): for i in range(stacks): stack_angle = math.pi * ((1 / 2) - (i / stacks)) xy = radius * math.cos(stack_angle) z = radius * math.sin(stack_angle) # add(sectorCount + 1) vertices per stack # the first and last vertices have same position and normal, but different tex coords for j in range(sectors): sector_angle = j * 2 * math.pi / sectors # vertex position x y z x = xy * math.cos(sector_angle) y = xy * math.sin(sector_angle) vec = Vector3(x, y, z) self.vertices.append(vec) # normals # length_inv = 1 / radius # nx = x * length_inv # ny = y * length_inv # nz = z * length_inv # normal = Vector3(nx, ny, nz) # self.normals.append(normal) # tex coords (s, t) range between [0, 1] # TODO: https://www.songho.ca/opengl/gl_sphere.html for i in range(stacks): k_1 = i * (sectors) # beginning of current stack k_2 = k_1 + sectors # beginning of next stack for j in range(sectors): # faces # # if i = 0: # face = Face3(0, k_2) # if i != 0: face = Face3(k_1, k_2, k_1 + 1) # normal = self.calculate_normal(face) # face.vertex_normals = [normal, normal, normal] self.faces.append(face) if i != (stacks - 1): face = Face3(k_1 + 1, k_2, k_2 + 1) # normal = self.calculate_normal(face) # face.vertex_normals = [normal, normal, normal] self.faces.append(face) k_1 += 1 k_2 += 1 for face in self.faces: if face.a > len(self.vertices) \ or face.b > len(self.vertices) \ or face.c > len(self.vertices): print(face)
def test_create(self): v = Vector3(1, 2, 3) self.assertEquals(v[0], 1) self.assertEquals(v[1], 2) self.assertEquals(v[2], 3) v = Vector3([4, 5, 6]) self.assertEquals(v[0], 4) self.assertEquals(v[1], 5) self.assertEquals(v[2], 6) try: Vector3(1, 2, 3, 4) assert False, "This shold not reached" except: pass try: Vector3([3, 4, 2, 1]) assert False, "This shold not reached" except: pass
def create_mesh(self): """ Create real mesh object from the geometry and material """ vertices = [Vector3([0, 0, 0])] indices = [0] a = math.radians(360 / self.num_points) for i in range(self.num_points): vertices.append( Vector3([ math.cos(a * i) * self.radius, 0, math.sin(a * i) * self.radius ])) indices.append(len(indices)) kw = { "vertices": vertices, "indices": indices, "fmt": self.vertex_format, "mode": "triangle_fan" } # if self.material.map: # kw["texture"] = self.material.map self._mesh = KivyMesh(**kw)
def _build_msh(self): for v in self.msh_vertices: v0 = Vector3(v[0] * 0.4, v[1] * 0.4, v[2] * 0.4) self.vertices.append((v0[0], v0[1], v0[2])) print len(self.vertices) n_idx = 0 for f in self.msh_faces: face3 = Face3(*f) normal = self.msh_normals[n_idx] #face3.vertex_normals = [normal, normal, normal] face3.normal = normal n_idx += 1 self.faces.append(face3)
def _build_tri(self): for v in self._tri_vertices: v = Vector3(0.5 * v[0] * self.w, 0.5 * v[1] * self.h, 0.5 * v[2] * self.d) self.vertices.append(v) n_idx = 0 for f in self._tri_faces: face3 = Face3(*f) normal = self._tri_normals[n_idx / 2] face3.vertex_normals = [normal, normal, normal] n_idx += 1 self.faces.append(face3)
def _build_box(self): for v in self._cube_vertices: v = Vector3(0.5 * v[0] * self.w, 0.5 * v[1] * self.h, 0.5 * v[2] * self.d) self.vertices.append(v) n_idx = 0 for f in self._cube_faces: face3 = Face3(*f) normal = self._cube_normals[floor(n_idx / 2)] face3.vertex_normals = [normal, normal, normal] n_idx += 1 self.faces.append(face3)
def test_attributes(self): v = Vector3(0, 0, 0) v.x = 4 self.assertEqual(v[0], v.x) self.assertEqual(v[0], 4) v.z = 6 self.assertEqual(v[2], v.z) self.assertEqual(v[2], 6) try: t = v.v assert False, "executing of this string is error" except AttributeError: pass
def __init__(self, **kwargs): super(My3DScreen, self).__init__(**kwargs) self.look_at = Vector3(0, 0, -1) self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down=self._on_keyboard_down) #root = FloatLayout() self.camera = PerspectiveCamera(75, 0.3, 1, 1000) self.radius = 10 self.phi = 90 self.theta = 0 self._touches = [] self.camera.pos.z = self.radius self.camera.look_at((0, 0, 0))
def create_mesh(self): """ Create real mesh object from the geometry and material """ vertices = [] indices = [0, 1, 2, 3] # define basis vectors if self.orientation == "x": bx = Vector3([0, 0, -1]) by = Vector3([0, -1, 0]) normal = Vector3([-1, 0, 0]) elif self.orientation == "y": bx = Vector3([-1, 0, 0]) by = Vector3([0, 0, -1]) normal = Vector3([0, 1, 0]) else: bx = Vector3([-1, 0, 0]) by = Vector3([0, -1, 0]) normal = Vector3([0, 0, 1]) bx = bx * 0.5 * self.width by = by * 0.5 * self.height vertices.extend(list(bx * -1 + by * -1) + list(normal) + [0, 0]) vertices.extend(list(bx * 1 + by * -1) + list(normal) + [1, 0]) vertices.extend(list(bx * 1 + by * 1) + list(normal) + [1, 1]) vertices.extend(list(bx * -1 + by * 1) + list(normal) + [0, 1]) kw = { "vertices": vertices, "indices": indices, "fmt": self.vertex_format, "mode": self.mode } if self.material.map: kw["texture"] = self.material.map self._mesh = KivyMesh(**kw)
def build(self): self.look_at = Vector3(0, 0, -1) root = FloatLayout() self.renderer = Renderer(shader_file=shader_file) scene = Scene() self.camera = PerspectiveCamera(75, 1, 1, 1000) self.camera.pos.z = 5 loader = OBJMTLLoader() obj = loader.load(obj_file, mtl_file) self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down=self._on_keyboard_down) scene.add(*obj.children) self.renderer.render(scene, self.camera) self.orion = scene.children[0] root.add_widget(self.renderer) self.renderer.bind(size=self._adjust_aspect) Clock.schedule_interval(self._rotate_obj, 1 / 20) return root
def test_divide(self): v1 = Vector3(6, 4, 8) v2 = Vector3(2, 2, 2) self.assertEqual(v1 / v2, [3., 2., 4.]) v1.divide(v2) self.assertEqual(v1, [3., 2., 4.])
def test_distance(self): v1 = Vector3(2, 1, 6) v2 = Vector3(2, 5, 6) self.assertEqual(v1.distance(v2), 4)
def __init__(self, a, b, c, normal=None): self.a = a self.b = b self.c = c self.normal = normal or Vector3(0, 0, 0) # face normal self.vertex_normals = [] # vertices normals
def test_multiply(self): v1 = Vector3(5, 6, 7) v2 = Vector3(2, 2, 2) self.assertEqual(v1 * v2, [10., 12., 14.]) v1.multiply(v2) self.assertEqual(v1, [10., 12., 14.])
def test_length(self): v = Vector3(3, 12, 4) v = Vector3(12, 4, 3) self.assertEqual(v.length(), 13) self.assertEqual(v.length_sq(), 13 * 13)
def test_negate(self): v = Vector3(2, 2, 2) v.negate() self.assertEqual(v, [-2, -2, -2])
def test_clamp(self): v1 = Vector3(1, 2, 3) v2 = Vector3(3, 4, 6) v = Vector3(0, 5, 4) v.clamp(v1, v2) self.assertEqual(v, [1, 4, 4])
def make_3d(self, clock=None): #self.root = FloatLayout() self.renderer = Renderer() self.renderer.set_clear_color((.2, .2, .2, 1.)) self.scene = Scene() #geometry = BoxGeometry(0.5, 0.5, 0.5) geometry = SphereGeometry(0.1) material = Material(color=(0., 0., 1.), diffuse=(1., 1., 0.), specular=(.35, .35, .35)) """ a = 5 liste = [] i = 0 for z in range(-5, -35, -1): for x in range(-5, 5): liste.append(Mesh(geometry, material)) liste[-1].pos.x = x liste[-1].pos.y = -i liste[-1].pos.z = z print(x, -i, z) self.scene.add(liste[-1]) i+=1 """ #!erster test für errecnete Daten liste = [] for z in range(0, int(Global.config["maxy"])): #for z in range(0, 10): #i = 0 test = calculationClass.find_mistakes_along_x_axis(z) #print(test) for x, y, rad in calculationClass.find_mistakes_along_x_axis(z): #for x, y in [[1, 2], [2, 0], [2.314, 5], [3, 0], [3.123, 4]]: #for x, y in [[1, 2], [2, 0], [3, 0]]: #for x in [8.06158101842821, 4.06158101842821, 0.09813725490196079]: #for x in test[:][0]: #for line in test[:10]: #x = line[0] x = float(x) y = float(y) #x = 8.06158101842821 #new_list.append([x, y, z, rad]) rad = 1 #y = 0 z += 5 liste.append(Mesh(geometry, material)) #liste[-1].pos.x = x - 8 liste[-1].pos.x = -z liste[-1].pos.y = y liste[-1].pos.z = x #print(x, y, z) self.scene.add(liste[-1]) #i += 1 self.renderer.render(self.scene, self.camera) self.renderer.bind(size=self._adjust_aspect) self.layout.add_widget(self.renderer) print(liste[0]) print(liste[0].pos) #self.look_at = liste[0].pos #self.look_at.x = liste[0][0] #self.look_at.y = liste[0][1] #self.look_at.z = liste[0][2] #self.camera.look_at(self.look_at) #test = (liste[0][0], liste[0][1], liste[0][2]) #a = tuple(liste[0].pos) #print(a) #self.camera.look_at(a) #self.look_at.x = liste[0].pos.x #self.look_at.y = liste[0].pos.y #self.look_at.z = liste[0].pos.z self.look_at = Vector3(0, 0, -1) #self.camera.look_at(self.look_at) #self.add_widget(self.root) print("here")