|
29 | 29 | "metadata": {}, |
30 | 30 | "outputs": [], |
31 | 31 | "source": [ |
32 | | - "with open('monkey.obj', 'r') as fobj:\n", |
| 32 | + "with open(\"monkey.obj\", \"r\") as fobj:\n", |
33 | 33 | " lines = [line.strip() for line in fobj.readlines()]" |
34 | 34 | ] |
35 | 35 | }, |
|
53 | 53 | "source": [ |
54 | 54 | "# Extract vertices\n", |
55 | 55 | "for line in lines:\n", |
56 | | - " splitted = line.split(' ')\n", |
| 56 | + " splitted = line.split(\" \")\n", |
57 | 57 | "\n", |
58 | 58 | " # Vertex\n", |
59 | | - " if splitted[0] == 'v':\n", |
| 59 | + " if splitted[0] == \"v\":\n", |
60 | 60 | " _, v1, v2, v3 = splitted\n", |
61 | 61 | " vertices.append([float(v1), float(v2), float(v3)])\n", |
62 | 62 | "\n", |
63 | 63 | " # Normal\n", |
64 | | - " if splitted[0] == 'vn':\n", |
| 64 | + " if splitted[0] == \"vn\":\n", |
65 | 65 | " _, v1, v2, v3 = splitted\n", |
66 | 66 | " vertex_normals.append([float(v1), float(v2), float(v3)])\n", |
67 | 67 | "\n", |
68 | 68 | "# Extract faces\n", |
69 | 69 | "for line in lines:\n", |
70 | | - " splitted = line.split(' ')\n", |
| 70 | + " splitted = line.split(\" \")\n", |
71 | 71 | "\n", |
72 | 72 | " # Face\n", |
73 | | - " if splitted[0] == 'f':\n", |
| 73 | + " if splitted[0] == \"f\":\n", |
74 | 74 | " # This file is triangulated, so this is fine\n", |
75 | 75 | " _, v1, v2, v3 = splitted\n", |
76 | 76 | "\n", |
77 | | - " # It happens that this mesh is flat-shaded, so the normal is \n", |
| 77 | + " # It happens that this mesh is flat-shaded, so the normal is\n", |
78 | 78 | " # the same on all vertices\n", |
79 | | - " v1_index, _, v1_normal = v1.split('/')\n", |
80 | | - " v2_index, _, _ = v2.split('/')\n", |
81 | | - " v3_index, _, _ = v3.split('/')\n", |
| 79 | + " v1_index, _, v1_normal = v1.split(\"/\")\n", |
| 80 | + " v2_index, _, _ = v2.split(\"/\")\n", |
| 81 | + " v3_index, _, _ = v3.split(\"/\")\n", |
82 | 82 | "\n", |
83 | 83 | " faces.append([int(v1_index) - 1, int(v2_index) - 1, int(v3_index) - 1])\n", |
84 | 84 | " faces_normals.append(int(v1_normal) - 1)" |
|
152 | 152 | " super(MonkeyCloud, self).__init__(width=500, height=500)\n", |
153 | 153 | "\n", |
154 | 154 | " self.dragging = False\n", |
155 | | - " \n", |
156 | | - " self.x = vertices[:,0]\n", |
157 | | - " self.y = vertices[:,1]\n", |
158 | | - " self.z = vertices[:,2]\n", |
159 | | - " \n", |
| 155 | + "\n", |
| 156 | + " self.x = vertices[:, 0]\n", |
| 157 | + " self.y = vertices[:, 1]\n", |
| 158 | + " self.z = vertices[:, 2]\n", |
| 159 | + "\n", |
160 | 160 | " self.dx = 0\n", |
161 | 161 | " self.dy = 0\n", |
162 | 162 | " self.radius = 10\n", |
163 | 163 | "\n", |
164 | | - " self.camera = OrbitCamera(self.radius, [0, 0, 0], self.width/self.height)\n", |
165 | | - " self.x2, self.y2, self.z2 = project_vector(self.x, self.y, self.z, self.camera.matrix)\n", |
| 164 | + " self.camera = OrbitCamera(self.radius, [0, 0, 0], self.width / self.height)\n", |
| 165 | + " self.x2, self.y2, self.z2 = project_vector(\n", |
| 166 | + " self.x, self.y, self.z, self.camera.matrix\n", |
| 167 | + " )\n", |
166 | 168 | " self.draw()\n", |
167 | 169 | "\n", |
168 | 170 | " self.on_mouse_down(self.mouse_down_handler)\n", |
|
173 | 175 | " def update_matrix(self, dx=None, dy=None):\n", |
174 | 176 | " dx = dx if dx is not None else self.dx\n", |
175 | 177 | " dy = dy if dy is not None else self.dy\n", |
176 | | - " \n", |
| 178 | + "\n", |
177 | 179 | " self.camera.update_position(dy, dx)\n", |
178 | | - " self.x2, self.y2, self.z2 = project_vector(self.x, self.y, self.z, self.camera.matrix)\n", |
| 180 | + " self.x2, self.y2, self.z2 = project_vector(\n", |
| 181 | + " self.x, self.y, self.z, self.camera.matrix\n", |
| 182 | + " )\n", |
179 | 183 | " self.draw()\n", |
180 | 184 | "\n", |
181 | 185 | " def draw(self):\n", |
|
194 | 198 | " if self.dragging:\n", |
195 | 199 | " self.dx_new = self.dx + pixel_x - self.x_mouse\n", |
196 | 200 | " self.dy_new = self.dy + pixel_y - self.y_mouse\n", |
197 | | - " \n", |
| 201 | + "\n", |
198 | 202 | " self.update_matrix(self.dx_new, self.dy_new)\n", |
199 | | - " \n", |
| 203 | + "\n", |
200 | 204 | " def mouse_up_handler(self, pixel_x, pixel_y):\n", |
201 | 205 | " if self.dragging:\n", |
202 | 206 | " self.dragging = False\n", |
203 | 207 | " self.dx = self.dx_new\n", |
204 | 208 | " self.dy = self.dy_new\n", |
205 | | - " \n", |
| 209 | + "\n", |
206 | 210 | " def mouse_out_handler(self, pixel_x, pixel_y):\n", |
207 | 211 | " if self.dragging:\n", |
208 | 212 | " self.dragging = False\n", |
|
258 | 262 | " super(Monkey, self).__init__(width=500, height=500)\n", |
259 | 263 | "\n", |
260 | 264 | " self.dragging = False\n", |
261 | | - " \n", |
262 | | - " self.x = vertices[:,0]\n", |
263 | | - " self.y = vertices[:,1]\n", |
264 | | - " self.z = vertices[:,2]\n", |
265 | | - " \n", |
| 265 | + "\n", |
| 266 | + " self.x = vertices[:, 0]\n", |
| 267 | + " self.y = vertices[:, 1]\n", |
| 268 | + " self.z = vertices[:, 2]\n", |
| 269 | + "\n", |
266 | 270 | " self.dx = 0\n", |
267 | 271 | " self.dy = 0\n", |
268 | 272 | " self.radius = 10\n", |
269 | 273 | "\n", |
270 | | - " self.camera = OrbitCamera(self.radius, [0, 0, 0], self.width/self.height)\n", |
| 274 | + " self.camera = OrbitCamera(self.radius, [0, 0, 0], self.width / self.height)\n", |
271 | 275 | " self.update_matrix()\n", |
272 | 276 | "\n", |
273 | 277 | " self.on_mouse_down(self.mouse_down_handler)\n", |
|
282 | 286 | " self.camera.update_position(dy, dx)\n", |
283 | 287 | "\n", |
284 | 288 | " dist = np.linalg.norm(self.camera.position - triangles_positions, axis=1)\n", |
285 | | - " \n", |
| 289 | + "\n", |
286 | 290 | " # Face culling: Get rid of the triangles that are not facing the camera\n", |
287 | 291 | " triangles_facing_camera = np.dot(triangles_normals, self.camera.front) < 0\n", |
288 | 292 | "\n", |
289 | 293 | " self.triangles = triangles[triangles_facing_camera]\n", |
290 | 294 | " self.triangles_normals = triangles_normals[triangles_facing_camera]\n", |
291 | 295 | " self.dist = dist[triangles_facing_camera]\n", |
292 | | - " \n", |
| 296 | + "\n", |
293 | 297 | " # Face sorting: Sort triangle by depth (distance to camera) so we can draw further triangles first\n", |
294 | 298 | " self.order = np.flip(np.argsort(self.dist))\n", |
295 | | - " \n", |
| 299 | + "\n", |
296 | 300 | " # Project triangles\n", |
297 | | - " triangle_vertices = self.triangles.reshape(self.triangles.shape[0] * self.triangles.shape[1], 3)\n", |
298 | | - " proj_x, proj_y, _ = project_vector(triangle_vertices[:,0], triangle_vertices[:,1], triangle_vertices[:,2], self.camera.matrix)\n", |
| 301 | + " triangle_vertices = self.triangles.reshape(\n", |
| 302 | + " self.triangles.shape[0] * self.triangles.shape[1], 3\n", |
| 303 | + " )\n", |
| 304 | + " proj_x, proj_y, _ = project_vector(\n", |
| 305 | + " triangle_vertices[:, 0],\n", |
| 306 | + " triangle_vertices[:, 1],\n", |
| 307 | + " triangle_vertices[:, 2],\n", |
| 308 | + " self.camera.matrix,\n", |
| 309 | + " )\n", |
299 | 310 | " proj_x = proj_x * self.width + self.width / 2\n", |
300 | 311 | " proj_y = proj_y * self.height + self.height / 2\n", |
301 | 312 | "\n", |
302 | | - " self.proj_triangles = np.stack((proj_x, proj_y), axis=1).reshape(self.triangles.shape[0], self.triangles.shape[1], 2)\n", |
| 313 | + " self.proj_triangles = np.stack((proj_x, proj_y), axis=1).reshape(\n", |
| 314 | + " self.triangles.shape[0], self.triangles.shape[1], 2\n", |
| 315 | + " )\n", |
303 | 316 | "\n", |
304 | 317 | " self.draw()\n", |
305 | 318 | "\n", |
|
311 | 324 | " for i in self.order:\n", |
312 | 325 | " triangle = self.proj_triangles[i]\n", |
313 | 326 | " normal = self.triangles_normals[i]\n", |
314 | | - " \n", |
| 327 | + "\n", |
315 | 328 | " # Shading depending on light direction and face normal\n", |
316 | 329 | " light = np.dot(light_direction, normal)\n", |
317 | 330 | " if light < 0.4:\n", |
318 | 331 | " light = 0.4\n", |
319 | 332 | " elif light > 1:\n", |
320 | 333 | " light = 1\n", |
321 | 334 | " r, g, b = int(214 * light), int(224 * light), int(125 * light)\n", |
322 | | - " self.fill_style = 'rgb({}, {}, {})'.format(r, g, b)\n", |
323 | | - " \n", |
| 335 | + " self.fill_style = \"rgb({}, {}, {})\".format(r, g, b)\n", |
| 336 | + "\n", |
324 | 337 | " self.fill_polygon(triangle)\n", |
325 | 338 | "\n", |
326 | 339 | " def mouse_down_handler(self, pixel_x, pixel_y):\n", |
|
332 | 345 | " if self.dragging:\n", |
333 | 346 | " self.dx_new = self.dx + pixel_x - self.x_mouse\n", |
334 | 347 | " self.dy_new = self.dy + pixel_y - self.y_mouse\n", |
335 | | - " \n", |
| 348 | + "\n", |
336 | 349 | " self.update_matrix(self.dx_new, self.dy_new)\n", |
337 | | - " \n", |
| 350 | + "\n", |
338 | 351 | " def mouse_up_handler(self, pixel_x, pixel_y):\n", |
339 | 352 | " if self.dragging:\n", |
340 | 353 | " self.dragging = False\n", |
341 | 354 | " self.dx = self.dx_new\n", |
342 | 355 | " self.dy = self.dy_new\n", |
343 | | - " \n", |
| 356 | + "\n", |
344 | 357 | " def mouse_out_handler(self, pixel_x, pixel_y):\n", |
345 | 358 | " if self.dragging:\n", |
346 | 359 | " self.dragging = False\n", |
|
0 commit comments