def create(self, angle=30, radius=1): self.angle = angle phi = theta = angle phi_step = theta_step = 0 while theta_step <= 180: while phi_step <= 360: face = [] x1, y1, z1 = self.angle_to_coords(theta_step, phi_step, radius) phi_step += phi x2, y2, z2 = self.angle_to_coords(theta_step, phi_step, radius) theta_step += theta x3, y3, z3 = self.angle_to_coords(theta_step, phi_step, radius) x4, y4, z4 = self.angle_to_coords(theta_step, phi_step - phi, radius) theta_step -= theta self.add_vertex(Vec3d(x1, y1, z1, 1)) self.add_vertex(Vec3d(x2, y2, z2, 1)) self.add_vertex(Vec3d(x3, y3, z3, 1)) self.add_vertex(Vec3d(x4, y4, z4, 1)) face.append(Vec3d(x1, y1, z1, 1)) face.append(Vec3d(x2, y2, z2, 1)) face.append(Vec3d(x3, y3, z3, 1)) face.append(Vec3d(x4, y4, z4, 1)) self.faces.append(face) phi_step = 0 theta_step += theta
def face_point(self): total = Vec3d.zero() size = 0 for vertex in self.vertices: total += vertex.position size += 1 return total / size
def setFrontX(self, new_front, Q): self.front = new_front #at the start if we rotate camera according to y , we can switch to other side with below code if (((-0.05 < self.front.x) and (self.front.x) < 0.05) and ((-0.05 < self.front.z) and (self.front.z) < 0.05)): #inside critical region if Q < 0: #if we are going upward if self.front.y < 0: self.worldUpAccel = abs(self.worldUpAccel) * -1 else: self.worldUpAccel = abs(self.worldUpAccel) else: #if we are going downward if self.front.y < 0: self.worldUpAccel = abs(self.worldUpAccel) else: self.worldUpAccel = abs(self.worldUpAccel) * -1 #print("front",self.front.x,self.front.y,self.front.z) worldUp = Vec3d(self.front.x, self.front.y + self.worldUpAccel, self.front.z) #print("worldUp",worldUp.x,worldUp.y,worldUp.z) self.right = (worldUp.cross_product(self.front)).get_unit_vector() self.up = self.front.cross_product(self.right)
def updateFrontFromYawPitch(self): x = cos(radians(self.pitch)) * cos(radians(self.yaw)) y = sin(radians(self.pitch)) z = cos(radians(self.pitch)) * sin(radians(self.yaw)) newfront = Vec3d(x, y, z) self.front = newfront.get_unit_vector()
def __init__(self, indexes): self.__indexes = None self.__edges = None self.normal = None self.face_point = None self.indexes = indexes self.color = Vec3d(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) / 255
def setFrontY(self, new_front): self.front = new_front worldUp = Vec3d(self.front.x, self.front.y + self.worldUpAccel, self.front.z) self.right = (worldUp.cross_product(self.front)).get_unit_vector() self.up = self.front.cross_product(self.right)
def InitGL(Width, Height): # We call this right after our OpenGL window is created. glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black glClearDepth(1.0) # Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS) # The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST) # Enables Depth Testing glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading # Below, we add vertices to the shapes triangle_shape.add_vertex(Vec3d(0.0, 1.0, 0.0, 1.0)) triangle_shape.add_vertex(Vec3d(1.0, -1.0, 0.0, 1.0)) triangle_shape.add_vertex(Vec3d(-1.0, -1.0, 0.0, 1.0)) square_shape.add_vertex(Vec3d(-1.0, 1.0, 0.0, 1.0)) square_shape.add_vertex(Vec3d(1.0, 1.0, 0.0, 1.0)) square_shape.add_vertex(Vec3d(1.0, -1.0, 0.0, 1.0)) square_shape.add_vertex(Vec3d(-1.0, -1.0, 0.0, 1.0)) # Add operations here to perform transformation square_shape.push_to_stack(mat3d_square.rotation(0, 0, 5)) triangle_shape.push_to_stack(mat3d_triangle.rotation(0, 0, 5)) glMatrixMode(GL_PROJECTION) glLoadIdentity() # Reset The Projection Matrix # Calculate The Aspect Ratio Of The Window gluPerspective(45.0, float(Width) / float(Height), 0.1, 100.0) glMatrixMode(GL_MODELVIEW)
def normal(self): normal = Vec3d.zero() e = start = self.edge while True: normal += e.face.normal e = e.prev.sys if e is start: break return normal.normalized
def get_avg_face_points(mesh: WingedMesh): avg_face_points = [] total = Vec3d.zero() count = 0 for vertex in mesh.vertices: for face in vertex.adjacent_faces: total += face.face_point count += 1 avg_face_points.append(total/count) return avg_face_points
def transform(shape, matrix): """Applies transformation to the vertices Arguments: Shape {Shape} -- Shape to change matrix {List} -- Transform matrix """ for j in range(len(shape.vertices_list)): temp = Mat3d.multipy_matrices(matrix, shape.vertices_list[j].homo_vector) shape.vertices_list[j] = Vec3d(temp[0][0], temp[1][0], temp[2][0], temp[3][0])
def normal(self): normal = Vec3d.zero() e = start = self.edge while True: v = e.vertex.position vnext = e.next.vertex.position normal += vnext.cross(v) if e is start: break return normal.normalized
def keyPressed(*args): global camera global lineVision global objVision key = glutGetModifiers() #print(args[0]) # If escape is pressed, kill everything. if args[0] == ESCAPE: sys.exit() elif args[0] == b'z': scene.objects[0].rotate_point_z(10, scene.objects[0].center) elif args[0] == b"x": scene.objects[0].rotate_point_x(10, scene.objects[0].center) elif args[0] == b"c": scene.objects[0].rotate_point_y(10, scene.objects[0].center) elif args[0] == b"b": scene.objects[0].increase_subdivisions() elif args[0] == b"n": scene.objects[0].decrease_subdivisions() elif args[0] == b"w": camera.move_forward(.1) elif args[0] == b"s": camera.move_backward(.1) elif args[0] == b"l": lineVision = True objVision = False elif args[0] == b"o": lineVision = False objVision = True elif args[0] == b"p": lineVision = True objVision = True elif args[0] == b"f": camera = Camera(Vec3d(0, 0, 8), Vec3d(0, 0, -1))
def get_avg_mid_edges(mesh: WingedMesh): avg_mid_edges = [] total = Vec3d.zero() count = 0 for vertex in mesh.vertices: for edge in vertex.edges: cp1 = edge.vertex.position cp2 = edge.next.vertex.position total += (cp1 + cp2) / 2.0 count += 1 avg_mid_edges .append(total/count) return avg_mid_edges
def add_subdivison(self): """ Function that add subdivisions. Finds all the vertices of a plane and get middle points. Then, repeats for left points. """ temp_sub_vertices = [] for plane in self.faces: center = Vec3d(float((plane[0].x + plane[2].x) / 2), float((plane[0].y + plane[2].y) / 2), float((plane[0].z + plane[2].z) / 2), 1) for index in range(len(plane)): v2 = Vec3d(0, 0, 0, 0) v4 = Vec3d(0, 0, 0, 0) temp_index = index + 1 if index + 1 == len(plane): temp_index = 0 v1 = plane[index] v2.x = float((plane[index].x + plane[temp_index].x) / 2) v2.y = float((plane[index].y + plane[temp_index].y) / 2) v2.z = float((plane[index].z + plane[temp_index].z) / 2) v2.w = plane[index].w v3 = center v4.x = float((plane[index].x + plane[index - 1].x) / 2) v4.y = float((plane[index].y + plane[index - 1].y) / 2) v4.z = float((plane[index].z + plane[index - 1].z) / 2) v4.w = plane[index].w temp_sub_vertices.append([v1, v2, v3, v4]) self.vertices_list.add(v1) self.vertices_list.add(v2) self.vertices_list.add(v3) self.vertices_list.add(v4) self.faces = temp_sub_vertices self.subdivision_level += 1
def __init__(self, camera_pos, camera_target, camera_up, camera_front): """ Constructor class for camera :param Vec3d camera_pos: The desired position of the camera :param Vec3d camera_target: The target point :param Vec3d camera_up: Up vector that points towards the y axis :param Vec3d camera_front: Front vector that shows front of the camera """ self.camera_pos = camera_pos temp_dir = Vec3d(0, 0, 0, 0) temp_dir.vector = list(np.array(camera_pos.vector) - np.array(camera_target.vector)) self.camera_dir = Vec3d(temp_dir.vector[0] / temp_dir.norm(), temp_dir.vector[1] / temp_dir.norm(), temp_dir.vector[2] / temp_dir.norm(), 0) temp_right_axis = Vec3d(0, 0, 0, 0) temp_right_axis.vector = (camera_up.cross_product(self.camera_dir)) self.camera_right = Vec3d(temp_right_axis.vector[0] / temp_right_axis.norm(), temp_right_axis.vector[1] / temp_right_axis.norm(), temp_right_axis.vector[2] / temp_right_axis.norm(), 0) temp_camera_up = Vec3d(0, 0, 0, 0) temp_camera_up.vector = self.camera_dir.cross_product(self.camera_right) self.camera_up = Vec3d(temp_camera_up.vector[0], temp_camera_up.vector[1], temp_camera_up.vector[2], 0) self.camera_front = camera_front
def rotate(self, yaw_angle, pitch_angle): cam_focus_vector = Vec3d(self.eye.x - self.center.x, self.eye.y - self.center.y, self.eye.z - self.center.z, 1.0) ymat = Mat3d() pmat = Mat3d() ymat.define_rotation_matrix(yaw_angle, "y") pmat.define_rotation_matrix(pitch_angle, "x") ymat.matmul(pmat) cam_focus_vector = ymat.vecmul(cam_focus_vector) cam_focus_vector += self.center self.eye = cam_focus_vector.copy() self.compute_camera_space()
def add_subdivision(self): temp_faces = [] center = None for face in self.faces: center = Vec3d((face[0].x + face[2].x) / 2, (face[0].y + face[2].y) / 2, (face[0].z + face[2].z) / 2, 1.0) for i in range(len(face)): v2 = Vec3d(0, 0, 0, 1.0) v4 = Vec3d(0, 0, 0, 1.0) next_index = i + 1 if i + 1 == len(face): next_index = 0 v1 = face[i] v2 = Vec3d((face[i].x + face[next_index].x) / 2, (face[i].y + face[next_index].y) / 2, (face[i].z + face[next_index].z) / 2, 1.0) v3 = center v4 = Vec3d((face[i].x + face[i - 1].x) / 2, (face[i].y + face[i - 1].y) / 2, (face[i].z + face[i - 1].z) / 2, 1.0) temp_faces.append([v1, v2, v3, v4]) if v1 not in self.vertices: self.vertices.append(v1) if v2 not in self.vertices: self.vertices.append(v2) if v3 not in self.vertices: self.vertices.append(v3) if v4 not in self.vertices: self.vertices.append(v4) self.faces = temp_faces self.subdivision_level += 1
def add_subdivison(self): """ Function that add subdivison. Finds all the vertices of a plane and get middle points. Then, repeats for left points. """ temp_sub_vertices = [] for plane in (self.subdivision_list): temp_plane = [] center = Vec3d((plane[0].x + plane[2].x) / 2, (plane[0].y + plane[2].y) / 2, (plane[0].z + plane[2].z) / 2, 1) for index in range(len(plane)): v1 = Vec3d(0, 0, 0, 0) v2 = Vec3d(0, 0, 0, 0) v3 = Vec3d(0, 0, 0, 0) v4 = Vec3d(0, 0, 0, 0) temp_index = index + 1 if index + 1 == len(plane): temp_index = 0 v1 = plane[index] v2.x = (plane[index].x + plane[temp_index].x) / 2 v2.y = (plane[index].y + plane[temp_index].y) / 2 v2.z = (plane[index].z + plane[temp_index].z) / 2 v2.w = plane[index].w v3 = center v4.x = (plane[index].x + plane[index - 1].x) / 2 v4.y = (plane[index].y + plane[index - 1].y) / 2 v4.z = (plane[index].z + plane[index - 1].z) / 2 v4.w = plane[index].w temp_sub_vertices.append([v1, v2, v3, v4]) self.subdivision_list = temp_sub_vertices
def vecmul(self, a_vec3d): """ Multiplies matrix with vector. Args: a_vec3d (Vec3d): Vec3d object Returns: Vec3d object """ vect = a_vec3d.vec3d result = [0, 0, 0, 0] for i in range(4): for j in range(4): result[i] += self.matrix[i][j] * vect[j] return Vec3d(result[0], result[1], result[2], result[3])
def create_new_points(mesh: WingedMesh): new_vertex_positions = [] for vertex in mesh.vertices: total = Vec3d.zero() count = 0 for face in vertex.adjacent_faces: total += face.face_point count += 1 avg_face_points = total / count total = Vec3d.zero() count = 0 for edge in vertex.edges: cp1 = edge.vertex.position cp2 = edge.next.vertex.position total += (cp1 + cp2) / 2.0 count += 1 avg_mid_edges = total / count n = len(list(vertex.adjacent_faces)) m1 = (n - 3) * vertex.position m2 = 2 * avg_mid_edges new_vertex_positions.append((avg_face_points + m2 + m1) / n) for i, vertex in enumerate(mesh.vertices): vertex.position = new_vertex_positions[i]
def create(self, radius=1, length=2, angle=30): self.angle = angle step_angle = angle while step_angle <= 360: face = [] a, b = self.angle_to_coords(step_angle, radius) step_angle += angle c, d = self.angle_to_coords(step_angle, radius) self.add_vertex(Vec3d(a, length / 2, b, 1)) self.add_vertex(Vec3d(c, length / 2, d, 1)) self.add_vertex(Vec3d(c, -length / 2, d, 1)) self.add_vertex(Vec3d(a, -length / 2, b, 1)) face.append(Vec3d(a, length / 2, b, 1)) face.append(Vec3d(c, length / 2, d, 1)) face.append(Vec3d(c, -length / 2, d, 1)) face.append(Vec3d(a, -length / 2, b, 1)) self.faces.append(face)
def create(self, radius=1.0, sectorCount=12, stackCount=12): # generate vertices vertices = [] sectorStep = 2 * math.pi / sectorCount stackStep = math.pi / stackCount for i in range(stackCount + 1): stackAngle = math.pi / 2 - i * stackStep xy = radius * math.cos(stackAngle) z = radius * math.sin(stackAngle) for j in range(sectorCount + 1): sectorAngle = j * sectorStep x = xy * math.cos(sectorAngle) y = xy * math.sin(sectorAngle) vertices.append(Vec3d(x, y, z, 1.0)) # generate faces faces = [] for i in range(stackCount): k1 = i * (sectorCount + 1) k2 = k1 + sectorCount + 1 for j in range(sectorCount + 1): if i != 0: faces.append([k1, k2, k1 + 1]) if i != (stackCount - 1): faces.append([k1 + 1, k2, k2 + 1]) k1 += 1 k2 += 1 # generate face colors faceColors = [] for i in range(len(faces)): faceColors.append([0.8, 0.8, 1.0]) return Model3D(Transform(), vertices, faces, faceColors)
def calculate_average_vertices(self, vertex_list): """ Calculate average for given vertices. """ counter = 0 average = Vec3d(0, 0, 0, 1.0) for vertex in vertex_list: # sum each vertex. average.x += vertex.x average.y += vertex.y average.z += vertex.z counter += 1 # divide by number of vertices. average.x /= counter average.y /= counter average.z /= counter return average
def __init__(self, position, front): #position ,front .. are vector self.yaw = -90 self.pitch = 0 #self.roll=0 self.worldUpAccel = 0.01 self.position = position self.front = front.get_unit_vector() #self.target=Vec3d(0,0,0) #self.direction=(self.position.substract(self.target)).get_unit_vector() worldUp = Vec3d(0, 1, 0) self.right = (worldUp.cross_product(self.front)).get_unit_vector() self.up = self.front.cross_product(self.right)
def parse(): vertices = [] faces = [] with open(sys.argv[1], 'r') as f: for line in f: if line.startswith('v'): values = line.split() vertex = Vec3d(float(values[1]), float(values[2]), float(values[3]), 1.0) vertices.append(vertex) elif line.startswith('f'): values = line.split() temp_list = [] for i in range(1, len(values)): temp_list.append(vertices[int(values[i]) - 1]) faces.append(temp_list) return vertices, faces
def parse(): vertices = [] faces = [] with open(sys.argv[1], 'r') as f: for line in f: if line.startswith('v'): values = line.split() vertex = Vec3d(float(values[1]), float(values[2]), float(values[3]), 1.0) vertices.append(vertex) elif line.startswith('f'): values = line.split() face = [] for i in values[1:]: face.append(int(i) - 1) faces.append(face) return vertices, faces
def create(self, subdivisionCount=1): vertices = [ Vec3d(1.0, -1.0, -1.0, 1.0), Vec3d(1.0, -1.0, 1.0, 1.0), Vec3d(-1.0, -1.0, 1.0, 1.0), Vec3d(-1.0, -1.0, -1.0, 1.0), Vec3d(1.0, 1.0, -1.0, 1.0), Vec3d(1.0, 1.0, 1.0, 1.0), Vec3d(-1.0, 1.0, 1.0, 1.0), Vec3d(-1.0, 1.0, -1.0, 1.0) ] faces = [[1, 2, 3, 4], [5, 8, 7, 6], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 8, 4], [5, 1, 4, 8]] faceColors = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 1.0, 0.0], [1.0, 0.0, 1.0], [0.0, 1.0, 1.0]] return Model3D(Transform(), vertices, faces, faceColors)
def parse_contents(self): vertices = [] faces = [] for line in self.contents: if line[0] == 'v': temp_line = line.split() vertices.append( Vec3d(float(temp_line[1]), float(temp_line[2]), float(temp_line[3]), 1.0)) elif line[0] == 'f': temp_faces = line.split() temp_list = [] for index, vertex in enumerate(temp_faces): if vertex == 'f': continue else: temp_list.append(vertices[int(vertex) - 1]) faces.append(temp_list) return Set(vertices), faces
def add_subdivision(self): """ Function that adds subdivison. Finds all the vertices of a plane and gets middle points. Then, repeats for left points. """ temp_sub_vertices = [] for plane in (self.subdivision_list): current_mids = [] mid_m_01 = Vec3d(0, 0, 0, 0) mid_m_12 = Vec3d(0, 0, 0, 0) mid_m_20 = Vec3d(0, 0, 0, 0) mid_m_01.x = (plane[0].x + plane[1].x) / 2 mid_m_01.y = (plane[0].y + plane[1].y) / 2 mid_m_01.z = (plane[0].z + plane[1].z) / 2 mid_m_01.w = plane[0].w mid_m_12.x = (plane[1].x + plane[2].x) / 2 mid_m_12.y = (plane[1].y + plane[2].y) / 2 mid_m_12.z = (plane[1].z + plane[2].z) / 2 mid_m_12.w = plane[1].w mid_m_20.x = (plane[2].x + plane[0].x) / 2 mid_m_20.y = (plane[2].y + plane[0].y) / 2 mid_m_20.z = (plane[2].z + plane[0].z) / 2 mid_m_20.w = plane[2].w current_mids = [mid_m_01, mid_m_12, mid_m_20] temp_sub_vertices.append(current_mids) for index in range(len(current_mids)): v0 = Vec3d(0, 0, 0, 0) v1 = Vec3d(0, 0, 0, 0) v2 = Vec3d(0, 0, 0, 0) v0.x = plane[index].x v0.y = plane[index].y v0.z = plane[index].z v1.x = current_mids[index].x v1.y = current_mids[index].y v1.z = current_mids[index].z v2.x = current_mids[index - 1].x v2.y = current_mids[index - 1].y v2.z = current_mids[index - 1].z temp_sub_vertices.append([v0, v1, v2]) self.subdivision_list = temp_sub_vertices
def InitGL(Width, Height): # We call this right after our OpenGL window is created. glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black glClearDepth(1.0) # Enables Clearing Of The Depth Buffer glDepthFunc(GL_LESS) # The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST) # Enables Depth Testing glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading # Add vertices to the object triangle.add_vertex(Vec3d(0.0, 1.0, 0.0, 1.0)) triangle.add_vertex(Vec3d(1.0, -1.0, 0.0, 1.0)) triangle.add_vertex(Vec3d(-1.0, -1.0, 0.0, 1.0)) square.add_vertex(Vec3d(-1.0, 1.0, 0.0, 1.0)) square.add_vertex(Vec3d(1.0, 1.0, 0.0, 1.0)) square.add_vertex(Vec3d(1.0, -1.0, 0.0, 1.0)) square.add_vertex(Vec3d(-1.0, -1.0, 0.0, 1.0)) # Add transformation matrices to the object first_matrix = Mat3d() second_matrix = Mat3d() third_matrix = Mat3d() square.add_transformation(first_matrix.define_translation_matrix(-1, -1, 0)) # To rotate around one vertex, we perform transformation as TRT^-1 square.add_transformation(second_matrix.define_rotation_matrix(5, "z")) square.add_transformation(third_matrix.define_translation_matrix(1, 1, 0)) fourth_matrix = Mat3d() fifth_matrix = Mat3d() sixth_matrix = Mat3d() triangle.add_transformation(fourth_matrix.define_translation_matrix(1, 1, 0)) triangle.add_transformation(fifth_matrix.define_rotation_matrix(5, "z")) triangle.add_transformation(sixth_matrix.define_translation_matrix(-1, -1, 0)) glMatrixMode(GL_PROJECTION) glLoadIdentity() # Reset The Projection Matrix # Calculate The Aspect Ratio Of The Window gluPerspective(45.0, float(Width) / float(Height), 0.1, 100.0) glMatrixMode(GL_MODELVIEW)