diff --git a/README.md b/README.md index 1612ea9..4fe7908 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,25 @@ test = Engine3D([[1, 1, 1], [0, 0, 0], [2, 2, 2]], [[0, 1, 2]]) # this will crea test = Engine3D([[1, 1, 1], [0, 0, 0], [2, 2, 2]], [[0, 1, 2, "green"]]) # you can also change the color of the triangle (the default is green) ``` -From your code, you can modify the display using the writePoints, writeTriangles, rotate, clear and render methods. +You can also define a list of folds that would be used to animate a multi-step folding. +Each folding step is itself composed of simultaneously done line folds. +Each line fold is defined by it's angle in degreee, two vertices that defines an oriented axe and a list of concerned vertices. + +```Python +vertices = [[-1, -1, 1], [-1, 1, 0], [1, -1, .5], [-1, -1, -.5]] +faces = [[0, 1, 2, "green"], [1, 2, 3, "red"]] +folds = [[(45, 1, 2, [3])]] +test = Engine3D(vertices, faces, folds) +``` + +From your code, you can modify the display using the writePoints, writeTriangles, rotate, free_rotate, part_free_rotate, clear and render methods. ```Python test.writePoints([[3, 3, 3], [0, 0, 0], [2, 2, 2]]) # change the points test.writeTriangles([[2, 1, 0, "blue"]]) # the order of the points does not matter test.rotate("y", 45) # rotate the object 45 degrees around the y axis +test.free_rotate(45, 1, 2) # rotate the object 45 degrees around vertices[1]vertices[2] axis +test.part_free_rotate(45, 1, 2, [3, 4]) # rotate vertices[3] and vertices[4] 45 degrees around (vertices[1],vertices[2]) axis test.clear() # clear the display test.render() # update the image ``` @@ -39,6 +52,7 @@ You can also use the following keys to interact with the display. 2. Up arrow -> Zoom in 3. Down arrow -> Zoom out 4. w, a, s, d -> Move the view up, left, down or right +5. n, p -> Animate the next or previous fold The module now also allows you to move points on the model (this is still a work in progress) @@ -48,4 +62,5 @@ The module now also allows you to move points on the model (this is still a work --- -If you would like to help me improve this project, you can contact me at code@henryhaefliger.com +Initial code: code@henryhaefliger.com +Folding and free rotation axis code: miq75@free.fr diff --git a/__pycache__/graphics.cpython-37.pyc b/__pycache__/graphics.cpython-37.pyc deleted file mode 100644 index b32dfca..0000000 Binary files a/__pycache__/graphics.cpython-37.pyc and /dev/null differ diff --git a/coords/GalleonT.txt b/coords/GalleonP.txt similarity index 100% rename from coords/GalleonT.txt rename to coords/GalleonP.txt diff --git a/coords/SharkP.txt b/coords/SharkP.txt new file mode 100644 index 0000000..3d53ede --- /dev/null +++ b/coords/SharkP.txt @@ -0,0 +1,734 @@ +3 0 1 2 cyan +3 3 2 4 cyan +3 5 6 7 cyan +3 8 9 10 cyan +3 11 12 9 cyan +3 13 14 15 cyan +3 16 17 14 cyan +3 18 19 20 cyan +3 21 22 23 cyan +3 24 25 21 cyan +3 26 27 24 cyan +3 28 29 26 cyan +3 30 31 28 cyan +3 32 33 30 cyan +3 34 35 32 cyan +3 36 37 34 cyan +3 38 39 36 cyan +3 40 41 38 cyan +3 42 43 44 cyan +3 44 45 46 cyan +3 46 47 48 cyan +3 48 49 50 cyan +3 50 51 52 cyan +3 52 53 54 cyan +3 54 55 56 cyan +3 56 57 58 cyan +3 58 59 60 cyan +3 60 61 7 cyan +3 62 63 64 cyan +3 64 65 66 cyan +3 66 67 68 cyan +3 68 69 70 cyan +3 70 71 72 cyan +3 72 73 74 cyan +3 75 76 77 cyan +3 78 79 75 cyan +3 80 81 78 cyan +3 82 83 80 cyan +3 74 84 82 cyan +3 85 86 87 cyan +3 88 89 85 cyan +3 90 91 88 cyan +3 92 93 90 cyan +3 94 95 92 cyan +3 96 97 94 cyan +3 98 99 96 cyan +3 100 101 102 cyan +3 102 103 104 cyan +3 104 105 106 cyan +3 106 107 108 cyan +3 108 109 110 cyan +3 110 111 112 cyan +3 112 113 114 cyan +3 115 116 117 cyan +3 115 117 118 cyan +3 118 119 115 cyan +3 120 117 116 cyan +3 120 118 117 cyan +3 120 119 118 cyan +3 121 122 116 cyan +3 121 123 122 cyan +3 121 124 123 cyan +3 121 125 124 cyan +3 116 122 126 cyan +3 127 125 121 cyan +3 127 125 121 cyan +3 127 128 125 cyan +3 116 129 121 cyan +3 129 130 121 cyan +3 130 131 121 cyan +3 131 132 121 cyan +3 133 129 116 cyan +3 134 132 121 cyan +3 121 132 134 cyan +3 132 128 134 cyan +3 135 136 137 cyan +3 137 136 138 cyan +3 139 140 135 cyan +3 136 135 141 cyan +3 141 135 140 cyan +3 138 142 139 cyan +3 143 138 136 cyan +3 142 138 143 cyan +3 144 145 146 cyan +3 144 146 147 cyan +3 148 144 147 cyan +3 149 148 147 cyan +3 149 147 150 cyan +3 146 145 151 cyan +3 151 145 152 cyan +3 151 152 153 cyan +3 151 153 150 cyan +3 153 149 150 cyan +3 154 155 148 cyan +3 156 157 158 cyan +3 159 157 156 cyan +3 160 161 162 cyan +3 163 160 162 cyan +3 163 162 164 cyan +3 163 164 165 cyan +3 159 163 165 cyan +3 157 161 160 cyan +3 166 161 157 cyan +3 167 166 157 cyan +3 159 167 157 cyan +3 159 165 167 cyan +3 164 168 169 cyan +3 170 146 160 cyan +3 170 160 171 cyan +3 172 146 151 cyan +3 172 151 173 cyan +3 147 174 175 cyan +3 147 175 150 cyan +3 174 176 177 cyan +3 174 177 175 cyan +3 176 178 179 cyan +3 176 179 177 cyan +3 178 180 181 cyan +3 178 181 179 cyan +3 180 182 183 cyan +3 180 183 181 cyan +3 182 163 159 cyan +3 182 159 183 cyan +3 160 184 185 cyan +3 160 185 157 cyan +3 157 185 186 cyan +3 157 186 158 cyan +3 183 159 156 cyan +3 183 156 187 cyan +3 181 183 187 cyan +3 181 187 188 cyan +3 179 181 188 cyan +3 179 188 189 cyan +3 177 179 189 cyan +3 177 189 190 cyan +3 175 177 190 cyan +3 175 190 191 cyan +3 150 175 191 cyan +3 150 191 192 cyan +3 151 150 192 cyan +3 151 192 193 cyan +3 173 151 193 cyan +3 173 193 194 cyan +3 170 195 147 cyan +3 170 147 146 cyan +3 195 196 174 cyan +3 195 174 147 cyan +3 196 197 176 cyan +3 196 176 174 cyan +3 197 198 178 cyan +3 197 178 176 cyan +3 198 199 180 cyan +3 198 180 178 cyan +3 199 200 182 cyan +3 199 182 180 cyan +3 200 201 163 cyan +3 200 163 182 cyan +3 201 171 160 cyan +3 201 160 163 cyan +3 201 195 170 cyan +3 201 170 171 cyan +3 196 195 201 cyan +3 196 201 200 cyan +3 197 196 200 cyan +3 197 200 199 cyan +3 198 197 199 cyan +3 202 203 204 cyan +3 204 203 205 cyan +3 203 202 206 cyan +3 207 205 203 cyan +3 208 209 186 cyan +3 158 186 209 cyan +3 158 209 210 cyan +3 156 158 210 cyan +3 156 210 211 cyan +3 187 156 211 cyan +3 187 211 212 cyan +3 213 209 214 cyan +3 213 214 215 cyan +3 216 213 215 cyan +3 216 215 217 cyan +3 212 216 217 cyan +3 212 217 218 cyan +3 219 214 208 cyan +3 219 208 220 cyan +3 221 219 220 cyan +3 221 220 222 cyan +3 218 221 222 cyan +3 218 222 223 cyan +3 224 208 225 cyan +3 224 225 226 cyan +3 224 226 227 cyan +3 224 227 228 cyan +3 228 227 229 cyan +3 228 229 223 cyan +3 230 225 206 cyan +3 230 206 231 cyan +3 232 233 234 cyan +3 232 234 229 cyan +3 230 231 233 cyan +3 230 233 232 cyan +3 187 229 234 cyan +3 187 223 229 cyan +3 187 218 223 cyan +3 187 212 218 cyan +3 206 208 186 cyan +3 206 225 208 cyan +3 194 235 236 cyan +3 237 235 194 cyan +3 237 194 193 cyan +3 238 237 193 cyan +3 238 193 192 cyan +3 239 238 192 cyan +3 239 192 191 cyan +3 240 241 235 cyan +3 240 235 242 cyan +3 243 240 242 cyan +3 243 242 244 cyan +3 245 243 244 cyan +3 245 244 239 cyan +3 246 236 241 cyan +3 246 241 247 cyan +3 248 246 247 cyan +3 248 247 249 cyan +3 250 248 249 cyan +3 250 249 245 cyan +3 251 252 236 cyan +3 251 236 253 cyan +3 254 255 251 cyan +3 254 251 253 cyan +3 250 256 255 cyan +3 250 255 254 cyan +3 257 258 252 cyan +3 257 252 259 cyan +3 256 260 261 cyan +3 256 261 262 cyan +3 262 261 257 cyan +3 262 257 259 cyan +3 260 256 191 cyan +3 256 250 191 cyan +3 250 245 191 cyan +3 245 239 191 cyan +3 194 236 258 cyan +3 236 252 258 cyan +3 204 205 263 cyan +3 204 263 264 cyan +3 265 204 264 cyan +3 265 264 266 cyan +3 267 265 266 cyan +3 267 266 268 cyan +3 140 267 268 cyan +3 140 268 141 cyan +3 269 142 143 cyan +3 269 143 270 cyan +3 271 269 270 cyan +3 271 270 272 cyan +3 273 271 272 cyan +3 273 272 274 cyan +3 275 273 274 cyan +3 275 274 276 cyan +3 277 278 271 cyan +3 277 271 273 cyan +3 278 260 269 cyan +3 278 269 271 cyan +3 260 279 142 cyan +3 260 142 269 cyan +3 279 280 139 cyan +3 279 139 142 cyan +3 280 281 140 cyan +3 280 140 139 cyan +3 281 234 267 cyan +3 281 267 140 cyan +3 234 282 265 cyan +3 234 265 267 cyan +3 282 202 204 cyan +3 282 204 265 cyan +3 188 187 234 cyan +3 188 234 281 cyan +3 189 188 281 cyan +3 189 281 280 cyan +3 190 189 280 cyan +3 190 280 279 cyan +3 191 190 279 cyan +3 191 279 260 cyan +3 235 241 236 cyan +3 214 209 208 cyan +3 273 283 277 cyan +3 275 283 273 cyan +3 258 277 283 cyan +3 283 275 284 cyan +3 285 286 287 cyan +3 288 289 290 cyan +3 291 288 290 cyan +3 291 290 292 cyan +3 293 294 295 cyan +3 296 297 298 cyan +3 299 296 298 cyan +3 299 298 300 cyan +3 301 302 303 cyan +3 301 303 304 cyan +3 305 301 304 cyan +3 276 274 306 cyan +3 276 306 307 cyan +3 274 272 308 cyan +3 274 308 306 cyan +3 272 270 309 cyan +3 272 309 308 cyan +3 270 143 310 cyan +3 270 310 309 cyan +3 143 136 311 cyan +3 143 311 310 cyan +3 136 141 312 cyan +3 136 312 311 cyan +3 141 268 313 cyan +3 141 313 312 cyan +3 268 266 314 cyan +3 268 314 313 cyan +3 266 264 315 cyan +3 266 315 314 cyan +3 264 263 316 cyan +3 264 316 315 cyan +3 307 306 317 cyan +3 307 317 318 cyan +3 306 308 319 cyan +3 306 319 317 cyan +3 308 309 320 cyan +3 308 320 319 cyan +3 309 310 321 cyan +3 309 321 320 cyan +3 310 311 322 cyan +3 310 322 321 cyan +3 311 312 323 cyan +3 311 323 322 cyan +3 312 313 324 cyan +3 312 324 323 cyan +3 313 314 325 cyan +3 313 325 324 cyan +3 314 315 326 cyan +3 314 326 325 cyan +3 315 316 327 cyan +3 315 327 326 cyan +3 326 327 328 cyan +3 326 328 329 cyan +3 325 326 329 cyan +3 325 329 330 cyan +3 324 325 330 cyan +3 324 330 331 cyan +3 323 324 331 cyan +3 323 331 332 cyan +3 322 323 332 cyan +3 322 332 333 cyan +3 321 322 333 cyan +3 321 333 334 cyan +3 320 321 334 cyan +3 320 334 335 cyan +3 319 320 335 cyan +3 319 335 336 cyan +3 317 319 336 cyan +3 317 336 337 cyan +3 318 317 337 cyan +3 318 337 338 cyan +3 339 340 129 cyan +3 339 129 133 cyan +3 340 341 130 cyan +3 340 130 129 cyan +3 341 342 131 cyan +3 341 131 130 cyan +3 342 343 132 cyan +3 342 132 131 cyan +3 343 302 128 cyan +3 343 128 132 cyan +3 302 344 125 cyan +3 302 125 128 cyan +3 344 345 124 cyan +3 344 124 125 cyan +3 345 346 123 cyan +3 345 123 124 cyan +3 346 347 122 cyan +3 346 122 123 cyan +3 347 348 126 cyan +3 347 126 122 cyan +3 329 328 348 cyan +3 329 348 347 cyan +3 330 329 347 cyan +3 330 347 346 cyan +3 331 330 346 cyan +3 331 346 345 cyan +3 332 331 345 cyan +3 332 345 344 cyan +3 333 332 344 cyan +3 333 344 302 cyan +3 334 333 302 cyan +3 334 302 343 cyan +3 335 334 343 cyan +3 335 343 342 cyan +3 336 335 342 cyan +3 336 342 341 cyan +3 337 336 341 cyan +3 337 341 340 cyan +3 338 337 340 cyan +3 338 340 339 cyan +3 116 126 349 cyan +3 116 349 120 cyan +3 350 133 116 cyan +3 115 350 116 cyan +3 351 352 353 cyan +3 351 353 354 cyan +3 352 172 173 cyan +3 352 173 353 cyan +3 184 355 356 cyan +3 184 356 185 cyan +3 355 357 358 cyan +3 355 358 356 cyan +3 357 359 360 cyan +3 357 360 358 cyan +3 359 351 354 cyan +3 359 354 360 cyan +3 360 354 361 cyan +3 360 361 362 cyan +3 358 360 362 cyan +3 358 362 363 cyan +3 356 358 363 cyan +3 356 363 364 cyan +3 185 356 364 cyan +3 185 364 186 cyan +3 353 173 194 cyan +3 353 194 365 cyan +3 354 353 365 cyan +3 354 365 361 cyan +3 366 367 352 cyan +3 366 352 351 cyan +3 367 40 172 cyan +3 367 172 352 cyan +3 7 368 355 cyan +3 7 355 184 cyan +3 368 369 357 cyan +3 368 357 355 cyan +3 369 370 359 cyan +3 369 359 357 cyan +3 370 366 351 cyan +3 370 351 359 cyan +3 367 366 370 cyan +3 367 370 369 cyan +3 367 369 368 cyan +3 371 372 373 cyan +3 206 373 372 cyan +3 205 372 371 cyan +3 374 375 376 cyan +3 374 376 377 cyan +3 186 364 373 cyan +3 186 373 206 cyan +3 378 377 376 cyan +3 378 376 379 cyan +3 371 378 379 cyan +3 371 379 380 cyan +3 205 371 380 cyan +3 205 380 263 cyan +3 381 275 276 cyan +3 381 276 382 cyan +3 374 381 382 cyan +3 374 382 375 cyan +3 383 384 381 cyan +3 383 381 374 cyan +3 373 385 378 cyan +3 373 378 371 cyan +3 385 386 377 cyan +3 385 377 378 cyan +3 386 383 374 cyan +3 386 374 377 cyan +3 362 361 383 cyan +3 362 383 386 cyan +3 363 362 386 cyan +3 363 386 385 cyan +3 364 363 385 cyan +3 364 385 373 cyan +3 365 194 258 cyan +3 365 258 384 cyan +3 361 365 384 cyan +3 361 384 383 cyan +3 384 387 381 cyan +3 381 387 275 cyan +3 387 384 258 cyan +3 98 172 23 cyan +3 114 42 184 cyan +3 375 382 388 cyan +3 375 388 389 cyan +3 382 276 307 cyan +3 382 307 388 cyan +3 263 380 390 cyan +3 263 390 316 cyan +3 380 379 391 cyan +3 380 391 390 cyan +3 379 376 392 cyan +3 379 392 391 cyan +3 376 375 389 cyan +3 376 389 392 cyan +3 389 388 393 cyan +3 389 393 394 cyan +3 388 307 318 cyan +3 388 318 393 cyan +3 316 390 395 cyan +3 316 395 327 cyan +3 390 391 396 cyan +3 390 396 395 cyan +3 391 392 397 cyan +3 391 397 396 cyan +3 392 389 394 cyan +3 392 394 397 cyan +3 397 394 398 cyan +3 397 398 399 cyan +3 396 397 399 cyan +3 396 399 400 cyan +3 395 396 400 cyan +3 395 400 401 cyan +3 327 395 401 cyan +3 327 401 328 cyan +3 393 318 338 cyan +3 393 338 402 cyan +3 394 393 402 cyan +3 394 402 398 cyan +3 403 404 350 cyan +3 403 350 115 cyan +3 404 339 133 cyan +3 404 133 350 cyan +3 348 405 349 cyan +3 348 349 126 cyan +3 405 406 120 cyan +3 405 120 349 cyan +3 406 407 119 cyan +3 406 119 120 cyan +3 407 403 115 cyan +3 407 115 119 cyan +3 399 398 403 cyan +3 399 403 407 cyan +3 400 399 407 cyan +3 400 407 406 cyan +3 401 400 406 cyan +3 401 406 405 cyan +3 328 401 405 cyan +3 328 405 348 cyan +3 402 338 339 cyan +3 402 339 404 cyan +3 398 402 404 cyan +3 398 404 403 cyan +3 127 408 128 cyan +3 127 409 408 cyan +3 127 410 409 cyan +3 127 411 410 cyan +3 127 412 411 cyan +3 127 413 412 cyan +3 127 414 413 cyan +3 127 121 414 cyan +3 128 408 134 cyan +3 408 409 134 cyan +3 409 410 134 cyan +3 410 411 134 cyan +3 411 412 134 cyan +3 412 413 134 cyan +3 413 414 134 cyan +3 414 121 134 cyan +3 415 139 135 cyan +3 416 415 135 cyan +3 417 416 135 cyan +3 418 417 135 cyan +3 419 418 135 cyan +3 420 419 135 cyan +3 421 420 135 cyan +3 422 421 135 cyan +3 423 422 135 cyan +3 424 423 135 cyan +3 135 137 424 cyan +3 138 139 415 cyan +3 138 415 416 cyan +3 138 416 417 cyan +3 138 417 418 cyan +3 138 418 419 cyan +3 138 419 420 cyan +3 138 420 421 cyan +3 138 421 422 cyan +3 138 422 423 cyan +3 138 423 424 cyan +3 424 137 138 cyan +3 155 425 144 cyan +3 425 426 144 cyan +3 426 427 145 cyan +3 427 428 145 cyan +3 428 429 152 cyan +3 429 430 152 cyan +3 430 431 153 cyan +3 431 432 153 cyan +3 432 433 149 cyan +3 433 434 149 cyan +3 434 154 148 cyan +3 144 426 145 cyan +3 145 428 152 cyan +3 152 430 153 cyan +3 153 432 149 cyan +3 149 434 148 cyan +3 155 144 148 cyan +3 162 435 168 cyan +3 162 436 435 cyan +3 161 437 436 cyan +3 161 438 437 cyan +3 166 439 438 cyan +3 166 440 439 cyan +3 167 441 440 cyan +3 167 442 441 cyan +3 165 443 442 cyan +3 165 444 443 cyan +3 164 169 444 cyan +3 161 436 162 cyan +3 166 438 161 cyan +3 167 440 166 cyan +3 165 442 167 cyan +3 164 444 165 cyan +3 164 162 168 cyan +3 160 445 446 cyan +3 146 445 160 cyan +3 146 447 445 cyan +3 146 172 447 cyan +3 160 446 184 cyan +3 40 367 368 cyan +3 40 368 7 cyan +3 445 447 446 cyan +3 40 7 184 cyan +3 40 184 172 cyan +3 184 446 447 cyan +3 184 447 172 cyan +3 233 231 202 cyan +3 233 202 282 cyan +3 233 282 234 cyan +3 227 232 229 cyan +3 226 225 230 cyan +3 226 230 232 cyan +3 226 232 227 cyan +3 222 220 224 cyan +3 222 224 228 cyan +3 220 208 224 cyan +3 217 221 218 cyan +3 217 215 219 cyan +3 217 219 221 cyan +3 215 214 219 cyan +3 210 209 213 cyan +3 222 228 223 cyan +3 211 216 212 cyan +3 211 210 213 cyan +3 211 213 216 cyan +3 231 206 202 cyan +3 278 277 257 cyan +3 278 257 261 cyan +3 260 278 261 cyan +3 256 262 255 cyan +3 259 252 251 cyan +3 255 262 259 cyan +3 255 259 251 cyan +3 254 253 246 cyan +3 254 246 248 cyan +3 253 236 246 cyan +3 245 249 243 cyan +3 249 247 240 cyan +3 249 240 243 cyan +3 247 241 240 cyan +3 242 235 237 cyan +3 250 254 248 cyan +3 239 244 238 cyan +3 244 242 237 cyan +3 244 237 238 cyan +3 277 258 257 cyan +3 448 449 372 cyan +3 449 206 372 cyan +3 450 448 372 cyan +3 451 450 372 cyan +3 452 451 372 cyan +3 453 452 372 cyan +3 454 453 372 cyan +3 455 454 372 cyan +3 456 455 372 cyan +3 457 456 372 cyan +3 372 205 207 cyan +3 372 207 457 cyan +3 457 207 203 cyan +3 203 456 457 cyan +3 203 455 456 cyan +3 203 454 455 cyan +3 203 453 454 cyan +3 203 452 453 cyan +3 203 451 452 cyan +3 203 450 451 cyan +3 203 448 450 cyan +3 203 449 448 cyan +3 203 206 449 cyan +3 430 429 428 cyan +3 430 428 427 cyan +3 430 427 426 cyan +3 430 426 425 cyan +3 430 425 155 cyan +3 430 155 154 cyan +3 430 154 434 cyan +3 430 434 433 cyan +3 430 433 432 cyan +3 430 432 431 cyan +3 441 442 443 cyan +3 441 443 444 cyan +3 441 444 169 cyan +3 441 169 168 cyan +3 441 168 435 cyan +3 441 435 436 cyan +3 441 436 437 cyan +3 441 437 438 cyan +3 441 438 439 cyan +3 441 439 440 cyan +3 458 284 387 cyan +3 284 275 387 cyan +3 387 459 458 cyan +3 387 460 459 cyan +3 387 461 460 cyan +3 387 462 461 cyan +3 387 463 462 cyan +3 387 464 463 cyan +3 387 465 464 cyan +3 387 466 465 cyan +3 387 467 466 cyan +3 387 258 467 cyan +3 283 284 458 cyan +3 458 459 283 cyan +3 459 460 283 cyan +3 460 461 283 cyan +3 461 462 283 cyan +3 462 463 283 cyan +3 463 464 283 cyan +3 464 465 283 cyan +3 465 466 283 cyan +3 466 467 283 cyan +3 467 258 283 cyan diff --git a/coords/SharkT.txt b/coords/SharkT.txt deleted file mode 100644 index a852979..0000000 --- a/coords/SharkT.txt +++ /dev/null @@ -1,734 +0,0 @@ -3 0 1 2 -3 3 2 4 -3 5 6 7 -3 8 9 10 -3 11 12 9 -3 13 14 15 -3 16 17 14 -3 18 19 20 -3 21 22 23 -3 24 25 21 -3 26 27 24 -3 28 29 26 -3 30 31 28 -3 32 33 30 -3 34 35 32 -3 36 37 34 -3 38 39 36 -3 40 41 38 -3 42 43 44 -3 44 45 46 -3 46 47 48 -3 48 49 50 -3 50 51 52 -3 52 53 54 -3 54 55 56 -3 56 57 58 -3 58 59 60 -3 60 61 7 -3 62 63 64 -3 64 65 66 -3 66 67 68 -3 68 69 70 -3 70 71 72 -3 72 73 74 -3 75 76 77 -3 78 79 75 -3 80 81 78 -3 82 83 80 -3 74 84 82 -3 85 86 87 -3 88 89 85 -3 90 91 88 -3 92 93 90 -3 94 95 92 -3 96 97 94 -3 98 99 96 -3 100 101 102 -3 102 103 104 -3 104 105 106 -3 106 107 108 -3 108 109 110 -3 110 111 112 -3 112 113 114 -3 115 116 117 -3 115 117 118 -3 118 119 115 -3 120 117 116 -3 120 118 117 -3 120 119 118 -3 121 122 116 -3 121 123 122 -3 121 124 123 -3 121 125 124 -3 116 122 126 -3 127 125 121 -3 127 125 121 -3 127 128 125 -3 116 129 121 -3 129 130 121 -3 130 131 121 -3 131 132 121 -3 133 129 116 -3 134 132 121 -3 121 132 134 -3 132 128 134 -3 135 136 137 -3 137 136 138 -3 139 140 135 -3 136 135 141 -3 141 135 140 -3 138 142 139 -3 143 138 136 -3 142 138 143 -3 144 145 146 -3 144 146 147 -3 148 144 147 -3 149 148 147 -3 149 147 150 -3 146 145 151 -3 151 145 152 -3 151 152 153 -3 151 153 150 -3 153 149 150 -3 154 155 148 -3 156 157 158 -3 159 157 156 -3 160 161 162 -3 163 160 162 -3 163 162 164 -3 163 164 165 -3 159 163 165 -3 157 161 160 -3 166 161 157 -3 167 166 157 -3 159 167 157 -3 159 165 167 -3 164 168 169 -3 170 146 160 -3 170 160 171 -3 172 146 151 -3 172 151 173 -3 147 174 175 -3 147 175 150 -3 174 176 177 -3 174 177 175 -3 176 178 179 -3 176 179 177 -3 178 180 181 -3 178 181 179 -3 180 182 183 -3 180 183 181 -3 182 163 159 -3 182 159 183 -3 160 184 185 -3 160 185 157 -3 157 185 186 -3 157 186 158 -3 183 159 156 -3 183 156 187 -3 181 183 187 -3 181 187 188 -3 179 181 188 -3 179 188 189 -3 177 179 189 -3 177 189 190 -3 175 177 190 -3 175 190 191 -3 150 175 191 -3 150 191 192 -3 151 150 192 -3 151 192 193 -3 173 151 193 -3 173 193 194 -3 170 195 147 -3 170 147 146 -3 195 196 174 -3 195 174 147 -3 196 197 176 -3 196 176 174 -3 197 198 178 -3 197 178 176 -3 198 199 180 -3 198 180 178 -3 199 200 182 -3 199 182 180 -3 200 201 163 -3 200 163 182 -3 201 171 160 -3 201 160 163 -3 201 195 170 -3 201 170 171 -3 196 195 201 -3 196 201 200 -3 197 196 200 -3 197 200 199 -3 198 197 199 -3 202 203 204 -3 204 203 205 -3 203 202 206 -3 207 205 203 -3 208 209 186 -3 158 186 209 -3 158 209 210 -3 156 158 210 -3 156 210 211 -3 187 156 211 -3 187 211 212 -3 213 209 214 -3 213 214 215 -3 216 213 215 -3 216 215 217 -3 212 216 217 -3 212 217 218 -3 219 214 208 -3 219 208 220 -3 221 219 220 -3 221 220 222 -3 218 221 222 -3 218 222 223 -3 224 208 225 -3 224 225 226 -3 224 226 227 -3 224 227 228 -3 228 227 229 -3 228 229 223 -3 230 225 206 -3 230 206 231 -3 232 233 234 -3 232 234 229 -3 230 231 233 -3 230 233 232 -3 187 229 234 -3 187 223 229 -3 187 218 223 -3 187 212 218 -3 206 208 186 -3 206 225 208 -3 194 235 236 -3 237 235 194 -3 237 194 193 -3 238 237 193 -3 238 193 192 -3 239 238 192 -3 239 192 191 -3 240 241 235 -3 240 235 242 -3 243 240 242 -3 243 242 244 -3 245 243 244 -3 245 244 239 -3 246 236 241 -3 246 241 247 -3 248 246 247 -3 248 247 249 -3 250 248 249 -3 250 249 245 -3 251 252 236 -3 251 236 253 -3 254 255 251 -3 254 251 253 -3 250 256 255 -3 250 255 254 -3 257 258 252 -3 257 252 259 -3 256 260 261 -3 256 261 262 -3 262 261 257 -3 262 257 259 -3 260 256 191 -3 256 250 191 -3 250 245 191 -3 245 239 191 -3 194 236 258 -3 236 252 258 -3 204 205 263 -3 204 263 264 -3 265 204 264 -3 265 264 266 -3 267 265 266 -3 267 266 268 -3 140 267 268 -3 140 268 141 -3 269 142 143 -3 269 143 270 -3 271 269 270 -3 271 270 272 -3 273 271 272 -3 273 272 274 -3 275 273 274 -3 275 274 276 -3 277 278 271 -3 277 271 273 -3 278 260 269 -3 278 269 271 -3 260 279 142 -3 260 142 269 -3 279 280 139 -3 279 139 142 -3 280 281 140 -3 280 140 139 -3 281 234 267 -3 281 267 140 -3 234 282 265 -3 234 265 267 -3 282 202 204 -3 282 204 265 -3 188 187 234 -3 188 234 281 -3 189 188 281 -3 189 281 280 -3 190 189 280 -3 190 280 279 -3 191 190 279 -3 191 279 260 -3 235 241 236 -3 214 209 208 -3 273 283 277 -3 275 283 273 -3 258 277 283 -3 283 275 284 -3 285 286 287 -3 288 289 290 -3 291 288 290 -3 291 290 292 -3 293 294 295 -3 296 297 298 -3 299 296 298 -3 299 298 300 -3 301 302 303 -3 301 303 304 -3 305 301 304 -3 276 274 306 -3 276 306 307 -3 274 272 308 -3 274 308 306 -3 272 270 309 -3 272 309 308 -3 270 143 310 -3 270 310 309 -3 143 136 311 -3 143 311 310 -3 136 141 312 -3 136 312 311 -3 141 268 313 -3 141 313 312 -3 268 266 314 -3 268 314 313 -3 266 264 315 -3 266 315 314 -3 264 263 316 -3 264 316 315 -3 307 306 317 -3 307 317 318 -3 306 308 319 -3 306 319 317 -3 308 309 320 -3 308 320 319 -3 309 310 321 -3 309 321 320 -3 310 311 322 -3 310 322 321 -3 311 312 323 -3 311 323 322 -3 312 313 324 -3 312 324 323 -3 313 314 325 -3 313 325 324 -3 314 315 326 -3 314 326 325 -3 315 316 327 -3 315 327 326 -3 326 327 328 -3 326 328 329 -3 325 326 329 -3 325 329 330 -3 324 325 330 -3 324 330 331 -3 323 324 331 -3 323 331 332 -3 322 323 332 -3 322 332 333 -3 321 322 333 -3 321 333 334 -3 320 321 334 -3 320 334 335 -3 319 320 335 -3 319 335 336 -3 317 319 336 -3 317 336 337 -3 318 317 337 -3 318 337 338 -3 339 340 129 -3 339 129 133 -3 340 341 130 -3 340 130 129 -3 341 342 131 -3 341 131 130 -3 342 343 132 -3 342 132 131 -3 343 302 128 -3 343 128 132 -3 302 344 125 -3 302 125 128 -3 344 345 124 -3 344 124 125 -3 345 346 123 -3 345 123 124 -3 346 347 122 -3 346 122 123 -3 347 348 126 -3 347 126 122 -3 329 328 348 -3 329 348 347 -3 330 329 347 -3 330 347 346 -3 331 330 346 -3 331 346 345 -3 332 331 345 -3 332 345 344 -3 333 332 344 -3 333 344 302 -3 334 333 302 -3 334 302 343 -3 335 334 343 -3 335 343 342 -3 336 335 342 -3 336 342 341 -3 337 336 341 -3 337 341 340 -3 338 337 340 -3 338 340 339 -3 116 126 349 -3 116 349 120 -3 350 133 116 -3 115 350 116 -3 351 352 353 -3 351 353 354 -3 352 172 173 -3 352 173 353 -3 184 355 356 -3 184 356 185 -3 355 357 358 -3 355 358 356 -3 357 359 360 -3 357 360 358 -3 359 351 354 -3 359 354 360 -3 360 354 361 -3 360 361 362 -3 358 360 362 -3 358 362 363 -3 356 358 363 -3 356 363 364 -3 185 356 364 -3 185 364 186 -3 353 173 194 -3 353 194 365 -3 354 353 365 -3 354 365 361 -3 366 367 352 -3 366 352 351 -3 367 40 172 -3 367 172 352 -3 7 368 355 -3 7 355 184 -3 368 369 357 -3 368 357 355 -3 369 370 359 -3 369 359 357 -3 370 366 351 -3 370 351 359 -3 367 366 370 -3 367 370 369 -3 367 369 368 -3 371 372 373 -3 206 373 372 -3 205 372 371 -3 374 375 376 -3 374 376 377 -3 186 364 373 -3 186 373 206 -3 378 377 376 -3 378 376 379 -3 371 378 379 -3 371 379 380 -3 205 371 380 -3 205 380 263 -3 381 275 276 -3 381 276 382 -3 374 381 382 -3 374 382 375 -3 383 384 381 -3 383 381 374 -3 373 385 378 -3 373 378 371 -3 385 386 377 -3 385 377 378 -3 386 383 374 -3 386 374 377 -3 362 361 383 -3 362 383 386 -3 363 362 386 -3 363 386 385 -3 364 363 385 -3 364 385 373 -3 365 194 258 -3 365 258 384 -3 361 365 384 -3 361 384 383 -3 384 387 381 -3 381 387 275 -3 387 384 258 -3 98 172 23 -3 114 42 184 -3 375 382 388 -3 375 388 389 -3 382 276 307 -3 382 307 388 -3 263 380 390 -3 263 390 316 -3 380 379 391 -3 380 391 390 -3 379 376 392 -3 379 392 391 -3 376 375 389 -3 376 389 392 -3 389 388 393 -3 389 393 394 -3 388 307 318 -3 388 318 393 -3 316 390 395 -3 316 395 327 -3 390 391 396 -3 390 396 395 -3 391 392 397 -3 391 397 396 -3 392 389 394 -3 392 394 397 -3 397 394 398 -3 397 398 399 -3 396 397 399 -3 396 399 400 -3 395 396 400 -3 395 400 401 -3 327 395 401 -3 327 401 328 -3 393 318 338 -3 393 338 402 -3 394 393 402 -3 394 402 398 -3 403 404 350 -3 403 350 115 -3 404 339 133 -3 404 133 350 -3 348 405 349 -3 348 349 126 -3 405 406 120 -3 405 120 349 -3 406 407 119 -3 406 119 120 -3 407 403 115 -3 407 115 119 -3 399 398 403 -3 399 403 407 -3 400 399 407 -3 400 407 406 -3 401 400 406 -3 401 406 405 -3 328 401 405 -3 328 405 348 -3 402 338 339 -3 402 339 404 -3 398 402 404 -3 398 404 403 -3 127 408 128 -3 127 409 408 -3 127 410 409 -3 127 411 410 -3 127 412 411 -3 127 413 412 -3 127 414 413 -3 127 121 414 -3 128 408 134 -3 408 409 134 -3 409 410 134 -3 410 411 134 -3 411 412 134 -3 412 413 134 -3 413 414 134 -3 414 121 134 -3 415 139 135 -3 416 415 135 -3 417 416 135 -3 418 417 135 -3 419 418 135 -3 420 419 135 -3 421 420 135 -3 422 421 135 -3 423 422 135 -3 424 423 135 -3 135 137 424 -3 138 139 415 -3 138 415 416 -3 138 416 417 -3 138 417 418 -3 138 418 419 -3 138 419 420 -3 138 420 421 -3 138 421 422 -3 138 422 423 -3 138 423 424 -3 424 137 138 -3 155 425 144 -3 425 426 144 -3 426 427 145 -3 427 428 145 -3 428 429 152 -3 429 430 152 -3 430 431 153 -3 431 432 153 -3 432 433 149 -3 433 434 149 -3 434 154 148 -3 144 426 145 -3 145 428 152 -3 152 430 153 -3 153 432 149 -3 149 434 148 -3 155 144 148 -3 162 435 168 -3 162 436 435 -3 161 437 436 -3 161 438 437 -3 166 439 438 -3 166 440 439 -3 167 441 440 -3 167 442 441 -3 165 443 442 -3 165 444 443 -3 164 169 444 -3 161 436 162 -3 166 438 161 -3 167 440 166 -3 165 442 167 -3 164 444 165 -3 164 162 168 -3 160 445 446 -3 146 445 160 -3 146 447 445 -3 146 172 447 -3 160 446 184 -3 40 367 368 -3 40 368 7 -3 445 447 446 -3 40 7 184 -3 40 184 172 -3 184 446 447 -3 184 447 172 -3 233 231 202 -3 233 202 282 -3 233 282 234 -3 227 232 229 -3 226 225 230 -3 226 230 232 -3 226 232 227 -3 222 220 224 -3 222 224 228 -3 220 208 224 -3 217 221 218 -3 217 215 219 -3 217 219 221 -3 215 214 219 -3 210 209 213 -3 222 228 223 -3 211 216 212 -3 211 210 213 -3 211 213 216 -3 231 206 202 -3 278 277 257 -3 278 257 261 -3 260 278 261 -3 256 262 255 -3 259 252 251 -3 255 262 259 -3 255 259 251 -3 254 253 246 -3 254 246 248 -3 253 236 246 -3 245 249 243 -3 249 247 240 -3 249 240 243 -3 247 241 240 -3 242 235 237 -3 250 254 248 -3 239 244 238 -3 244 242 237 -3 244 237 238 -3 277 258 257 -3 448 449 372 -3 449 206 372 -3 450 448 372 -3 451 450 372 -3 452 451 372 -3 453 452 372 -3 454 453 372 -3 455 454 372 -3 456 455 372 -3 457 456 372 -3 372 205 207 -3 372 207 457 -3 457 207 203 -3 203 456 457 -3 203 455 456 -3 203 454 455 -3 203 453 454 -3 203 452 453 -3 203 451 452 -3 203 450 451 -3 203 448 450 -3 203 449 448 -3 203 206 449 -3 430 429 428 -3 430 428 427 -3 430 427 426 -3 430 426 425 -3 430 425 155 -3 430 155 154 -3 430 154 434 -3 430 434 433 -3 430 433 432 -3 430 432 431 -3 441 442 443 -3 441 443 444 -3 441 444 169 -3 441 169 168 -3 441 168 435 -3 441 435 436 -3 441 436 437 -3 441 437 438 -3 441 438 439 -3 441 439 440 -3 458 284 387 -3 284 275 387 -3 387 459 458 -3 387 460 459 -3 387 461 460 -3 387 462 461 -3 387 463 462 -3 387 464 463 -3 387 465 464 -3 387 466 465 -3 387 467 466 -3 387 258 467 -3 283 284 458 -3 458 459 283 -3 459 460 283 -3 460 461 283 -3 461 462 283 -3 462 463 283 -3 463 464 283 -3 464 465 283 -3 465 466 283 -3 466 467 283 -3 467 258 283 \ No newline at end of file diff --git a/cubeExample.py b/cubeExample.py deleted file mode 100644 index 6123e64..0000000 --- a/cubeExample.py +++ /dev/null @@ -1,20 +0,0 @@ -### Cube ### - -import graphics.engine - -points = [[-1,-1,-1],[-1,-1,1],[-1,1,1],[-1,1,-1],[1,-1,-1],[1,-1,1],[1,1,1],[1,1,-1]] -triangles = [[0,1,2],[0,2,3],[2,3,7],[2,7,6],[1,2,5],[2,5,6],[0,1,4],[1,4,5],[4,5,6],[4,6,7],[3,7,4],[4,3,0]] - -test = graphics.engine.Engine3D(points, triangles, title='Cube') - -def animation(): - test.clear() - test.rotate('y', 0.1) - test.rotate('x', 0.1) - test.render() - test.screen.after(1, animation) - -animation() -test.screen.window.mainloop() - -############ diff --git a/dragExample.py b/dragExample.py old mode 100644 new mode 100755 index 86f66d1..d25fc19 --- a/dragExample.py +++ b/dragExample.py @@ -1,29 +1,13 @@ -### Shark ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""2 coordinates axes rotations with mouse.""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] +vertices = read_data_file('coords/SharkV.txt', 'V') +polygons = read_data_file('coords/SharkP.txt', 'P') +test = Engine3D(vertices, polygons, scale=100, title='Shark') -with open('coords/SharkV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0]), float(coords[1]), float(coords[2])]) - f.close() - -with open('coords/SharkT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, scale=100, title='Shark') -test.render() -test.screen.window.mainloop() - -############## +if __name__ == '__main__': + test.render() + test.screen.window.mainloop() diff --git a/foldExample.py b/foldExample.py new file mode 100755 index 0000000..1d5d0a9 --- /dev/null +++ b/foldExample.py @@ -0,0 +1,140 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Folding management example. + + +Origami pattern +--------------- + +Here we got an example of how graphical engine can use rotation around free +axis. We use those rotations on a rectangular paper sheet and fold it into +origami card box. + +The origami pattern is flat modelised with final card box dimensions, so +vertices coordinates are calculated accordly to few parameters. + +Folds are a bit complexe to describe: +- Parameter is a list of step-folds; +- Each step-fold is itself a list of line-folds moving together during the + folding step; +- Each line-fold is a 4 tuple composed by: + - The angle value in degrees; + - 2 vertices indexes that defines the rotation axe (oriented); + - A list of vertices indexes that rotates around this . + + +Commands +-------- + +A set of two new commmands are added to the keyboard binding: +-: forward animation of the next fold +-: backward animation of the previous fold + + +Technical remarks +----------------- + +- The current drawing engine uses a fast but simple ordering of faces on their +z-middle-coordinate. Then faces are drawn from far to close, and close faces +covers far ones. This way of rendering is quite good enougth to draw volumic +models with single grid faces, but is doesn't render perfect for faces that are +close and almost parallels like folded sheets of paper. So, until the render +engine is changed for a more complex and strict one, folded models may need to +be turn around to be correctly drawn and understood. + +- Some patterns contains faces that are not triangles. Patterns would use a uniq +color to show each rigid polygon (So 2 consecutive same color triangles do not +fold in beetween in the final model - but they can fold a bit during folding for +gaining light paper twist). + +- There is no management for polygons intersections during fold visualisation so +there might be vertices that moves a little through faces. During real paper +folding, paper polygons are flexibles so there is no problem. + +""" + +import graphics.engine + +# Flat pattern that folds into a parametric box. +W = 1.3 # box width +T = .5 # box thickness +S = .01 # paper thickness causing a little shift on some faces (pre calculated in flat pattern). + +vertices = [ + [-2.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-2*T+S, -.5*W, .5*T], [-1.5*W-T, -.5*W, .5*T], # 0 1 2 + [-.5*W-T, -.5*W, .5*T], [-.5*W, -.5*W, .5*T], [.5*W, -.5*W, .5*T+S/2], # 3 4 5 + [.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+T-S, -.5*W, .5*T+S/2], [1.5*W+2*T-3*S, -.5*W, .5*T+S/2], # 6 7 8 + [-2.5*W-2*T+S, .5*W, .5*T], [-1.5*W-2*T+S, .5*W, .5*T], [-1.5*W-T, .5*W, .5*T], # 9 10 11 + [-.5*W-T, .5*W, .5*T], [-.5*W, .5*W, .5*T], [.5*W, .5*W, .5*T-S/2], # 12 13 14 + [.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+T-S, .5*W, .5*T-S/2], [1.5*W+2*T-3*S, .5*W, .5*T-S/2], # 15 16 17 + [-2*W-2*T+S, 0, .5*T], [-1.5*W-1.5*T+S, 0, .5*T], [-1*W-T, 0, .5*T], # 18 19 20 + [-.5*W-.5*T, 0, .5*T], [0, 0, .5*T], [.5*W+.5*T, 0, .5*T], # 21 22 23 + [W+T-S, 0, .5*T], [1.5*W+1.5*T-S, 0, .5*T], # 24 25 +] + +polygons = [ + [0, 1, 18, 'pink'], [0, 9, 18, 'pink'], [1, 10, 18, 'pink'], [9, 10, 18, 'pink'], + [1, 2, 19, 'red'], [1, 10, 19, 'red'], [2, 11, 19, 'red'], [10, 11, 19, 'red'], + [2, 3, 20, 'orange'], [2, 11, 20, 'orange'], + [3, 12, 20, 'gold'], [11, 12, 20, 'gold'], + [3, 4, 21, 'lime'], [3, 12, 21, 'lime'], [4, 13, 21, 'lime'], [12, 13, 21, 'lime'], + [4, 5, 22, 'green'], [4, 13, 22, 'green'], [5, 14, 22, 'green'], [13, 14, 22, 'green'], + [5, 6, 23, 'cyan'], [5, 14, 23, 'cyan'], [6, 15, 23, 'cyan'], [14, 15, 23, 'cyan'], + [6, 15, 24, 'royal blue'], [15, 16, 24, 'royal blue'], + [6, 7, 24, 'blue'], [7, 16, 24, 'blue'], + [7, 8, 25, 'purple'], [7, 16, 25, 'purple'], [8, 17, 25, 'purple'], [16, 17, 25, 'purple'], +] + +PA = 15 # small angle to visualise paper marks in pre-fold + +folds = [ + [ # pre mark for any final fold + (PA, 1, 10, [0, 9, 18]), # pink/red + (PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + (PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # first step-fold: outside pre 90° folds for bottom + (90-PA, 1, 10, [0, 9, 18]), # pink/red + (90-PA, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 16, 7, [8, 17, 25]), # blue/purple + ], [ # second step-fold: diagonals for triangle crossing in front part + # (not 180° to avoid face identity when draw) + (179-PA, 11, 3, [0, 1, 2, 9, 10, 18, 19]), # orange/yellow + (179-PA, 6, 16, [7, 8, 17, 25]), # lightblue/blue + ], [ # third step-fold: face bottom parts, left "outside" side + (30, 1, 9, [0]), # pink/pink + (10, 1, 10, [0, 9, 18]), # pink/red + (30, 11, 2, [0, 1, 9, 10, 18, 19]), # red/orange + (90-PA, 12, 3, [0, 1, 2, 9, 10, 11, 18, 19, 20]), # yellow/lime + (60-PA, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + ], [ # fourth step-fold: face bottom parts, right "inside" side + (35, 5, 13, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45-PA, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 6, 14, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (75-PA, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 24, 7, [8, 16, 17, 25]), # blue/blue + (45, 16, 7, [8, 17, 25]), # blue/purple + ], [ # fifth step-fold: slide into bottom and complete box + (30, 9, 1, [0]), # pink/pink + (10, 10, 1, [0, 9, 18]), # pink/red + (30, 2, 11, [0, 1, 9, 10, 18, 19]), # red/orange + (30, 13, 4, [0, 1, 2, 3, 9, 10, 11, 12, 18, 19, 20, 21]), # lime/green + (35, 13, 5, [6, 7, 8, 14, 15, 16, 17, 23, 24, 25]), # green/green + (45, 5, 14, [6, 7, 8, 15, 16, 17, 23, 24, 25]), # green/cyan + (20, 14, 6, [7, 8, 15, 16, 17, 24, 25]), # cyan/cyan + (15, 6, 15, [7, 8, 16, 17, 24, 25]), # cyan/lightblue + (60, 7, 24, [8, 16, 17, 25]), # blue/blue + (45, 7, 16, [8, 17, 25]), # blue/purple + ] +] + +test = graphics.engine.Engine3D(vertices, polygons, folds, title='Fold') + +if __name__ == '__main__': + test.render() + test.screen.window.mainloop() diff --git a/galleonExample.py b/galleonExample.py old mode 100644 new mode 100755 index c020e01..8071e5e --- a/galleonExample.py +++ b/galleonExample.py @@ -1,28 +1,12 @@ -### Galleon ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Complex model example: Galleon""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] - -with open('coords/GalleonV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0])/150, float(coords[1])/150, float(coords[2])/150]) - f.close() - -with open('coords/GalleonT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, distance=100, title='Galleon') +vertices = read_data_file('coords/GalleonV.txt', 'V', scale=1/150) +polygons = read_data_file('coords/GalleonP.txt', 'P') +test = Engine3D(vertices, polygons, distance=100, title='Galleon') def animation(): test.clear() @@ -30,7 +14,6 @@ def animation(): test.render() test.screen.after(1, animation) -animation() -test.screen.window.mainloop() - -################ +if __name__ == '__main__': + animation() + test.screen.window.mainloop() diff --git a/graphics/__pycache__/__init__.cpython-37.pyc b/graphics/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 9d1dbf7..0000000 Binary files a/graphics/__pycache__/__init__.cpython-37.pyc and /dev/null differ diff --git a/graphics/__pycache__/engine.cpython-37.pyc b/graphics/__pycache__/engine.cpython-37.pyc deleted file mode 100644 index 3bb6a22..0000000 Binary files a/graphics/__pycache__/engine.cpython-37.pyc and /dev/null differ diff --git a/graphics/__pycache__/engine.cpython-38.pyc b/graphics/__pycache__/engine.cpython-38.pyc deleted file mode 100644 index 75ee649..0000000 Binary files a/graphics/__pycache__/engine.cpython-38.pyc and /dev/null differ diff --git a/graphics/__pycache__/face.cpython-37.pyc b/graphics/__pycache__/face.cpython-37.pyc deleted file mode 100644 index 9bf0ba7..0000000 Binary files a/graphics/__pycache__/face.cpython-37.pyc and /dev/null differ diff --git a/graphics/__pycache__/face.cpython-38.pyc b/graphics/__pycache__/face.cpython-38.pyc deleted file mode 100644 index 24f6528..0000000 Binary files a/graphics/__pycache__/face.cpython-38.pyc and /dev/null differ diff --git a/graphics/__pycache__/screen.cpython-37.pyc b/graphics/__pycache__/screen.cpython-37.pyc deleted file mode 100644 index f36a7c8..0000000 Binary files a/graphics/__pycache__/screen.cpython-37.pyc and /dev/null differ diff --git a/graphics/__pycache__/screen.cpython-38.pyc b/graphics/__pycache__/screen.cpython-38.pyc deleted file mode 100644 index 7d405f8..0000000 Binary files a/graphics/__pycache__/screen.cpython-38.pyc and /dev/null differ diff --git a/graphics/__pycache__/vertex.cpython-37.pyc b/graphics/__pycache__/vertex.cpython-37.pyc deleted file mode 100644 index ddfb3d5..0000000 Binary files a/graphics/__pycache__/vertex.cpython-37.pyc and /dev/null differ diff --git a/graphics/__pycache__/vertex.cpython-38.pyc b/graphics/__pycache__/vertex.cpython-38.pyc deleted file mode 100644 index f60ff84..0000000 Binary files a/graphics/__pycache__/vertex.cpython-38.pyc and /dev/null differ diff --git a/graphics/engine.py b/graphics/engine.py old mode 100644 new mode 100755 index 1725ce6..39f187d --- a/graphics/engine.py +++ b/graphics/engine.py @@ -1,12 +1,75 @@ import graphics.screen -import graphics.face -import graphics.vertex +import graphics.structures import copy + +def read_data_file(filename, data_type, scale=1): + """Open a data file and creates a list of corresponding datas. + + Data_type can be either 'V' for vertices coordinates (a line = 3 ints) + either 'P' for polygons (a line = an int for polygon size, n indexes of + vertices and an optional color name). + + Scale is an optional zoom factor for vertices coordinates. + """ + with open(filename, 'r') as f: + if data_type == 'V': + return [list(map(lambda c:float(c)*scale, l[:-1].strip().split())) for l in f.readlines()] + else: # data_type == 'P' + formated_lines = [l[:-1].strip().split() for l in f.readlines()] + return [list(map(int, fl[1:int(fl[0])+1])) + fl[int(fl[0])+1:] for fl in formated_lines] + + class Engine3D: - def __resetDrag(self, event): + # number of pictures in fold animations + anim_steps = 20 + # colors for show vectors in grabbing + axis_colors = ['red', 'green', 'blue'] + + def __init__(self, vertices, polygons, folds=[], width=1000, height=700, distance=6, scale=100, title='3D', background='white'): + # vertices + self.vertices = [graphics.structures.Vertex(v) for v in vertices] + # faces + self.polygons = [graphics.structures.Polygon(*p) for p in polygons] + # folds + self.folds = folds + + # initialize display + self.screen = graphics.screen.Screen(width, height, title, background) + + # viewing + self.distance = distance + self.scale = scale + self.screen.window.bind('', self.__zoom_in) + self.screen.window.bind('', self.__zoom_out) + self.screen.window.bind('', self.__camera_up) + self.screen.window.bind('', self.__camera_down) + self.screen.window.bind('', self.__camera_left) + self.screen.window.bind('', self.__camera_right) + + # folding animation + self.fold_index = 0 + self.screen.window.bind('n', self.__next_fold) + self.screen.window.bind('p', self.__prev_fold) + + # grabbing + self.__reset_drag() + self.screen.window.bind('', self.__drag) + self.screen.window.bind('', self.__reset_drag) + + # model edition + self.__selected = None + self.screen.window.bind('', self.__select) + self.screen.window.bind('', self.__deselect) + self.screen.window.bind('x', self.__select_x) + self.screen.window.bind('y', self.__select_y) + self.screen.window.bind('z', self.__select_z) + self.screen.window.bind('+', self.__move_down) + self.screen.window.bind('-', self.__move_up) + + def __reset_drag(self, event=None): self.__prev = [] - + def __drag(self, event): if self.__prev: self.rotate('y', (event.x - self.__prev[0]) / 20) @@ -15,164 +78,135 @@ def __drag(self, event): self.render() self.__prev = [event.x, event.y] + def __build_axis(self, selection, direction, orientation): + res = copy.deepcopy(selection) + setattr(res, direction, getattr(res, direction) + 40 * orientation / self.scale) + res.flatten(self.scale, self.distance) + return (res.get_flat()[0] + self.screen.zeros[0], res.get_flat()[1] + self.screen.zeros[1]) + def __select(self, event): zeros = self.screen.zeros - event = (event.x - zeros[0], event.y - zeros[1]) - - possibilities = [] - for a in range(-6, 5): - for b in range(-6, 5): - possibilities.append((event[0] + a, event[1] + b)) - - found = [e for e in possibilities if e in self.flattened] - if found != []: + ex, ey = event.x - zeros[0], event.y - zeros[1] + exm, exp, eym, eyp = ex - 6, ex + 5, ey - 6, ey + 5 + possible_vertices = [i for i,v in enumerate(self.vertices) + if exm < v.flat_x < exp and eym < v.flat_y < eyp] + if possible_vertices != []: self.__moveaxis = None - self.__selected = self.flattened.index(found[0]) - - i = self.points[self.__selected] - self.__axis = [[copy.deepcopy(i) for a in range(2)] for b in range(3)] - - self.__axis[0][0].x -= 40 / self.scale - self.__axis[0][1].x += 40 / self.scale - self.__axis[1][0].y -= 40 / self.scale - self.__axis[1][1].y += 40 / self.scale - self.__axis[2][0].z -= 40 / self.scale - self.__axis[2][1].z += 40 / self.scale - - self.__axis = [[point.flatten(self.scale, self.distance) for point in i] for i in self.__axis] - self.__axis = [[[i[0] + zeros[0], i[1] + zeros[1]] for i in j] for j in self.__axis] - self.__axis = [self.screen.createLine(self.__axis[0], 'red'), self.screen.createLine(self.__axis[1], 'green'), self.screen.createLine(self.__axis[2], 'blue')] - - def __selectx(self, event): + self.__selected = self.vertices[possible_vertices[0]] + axis = [[self.__build_axis(self.__selected, d, o) for o in [-1,1]] for d in 'xyz'] + self.__axis = [self.screen.create_arrow(a, self.axis_colors[i]) for i,a in enumerate(axis)] + + def __select_x(self, event): self.__moveaxis = 'x' - def __selecty(self, event): + def __select_y(self, event): self.__moveaxis = 'y' - def __selectz(self, event): + def __select_z(self, event): self.__moveaxis = 'z' - def __moveup(self, event): + def __move_up(self, event): if self.__selected != None and self.__moveaxis != None: - self.points[self.__selected].move(self.__moveaxis, 0.1) + self.__selected.move(self.__moveaxis, 0.1) self.clear() self.render() - def __movedown(self, event): + def __move_down(self, event): if self.__selected != None and self.__moveaxis != None: - self.points[self.__selected].move(self.__moveaxis, -0.1) + self.__selected.move(self.__moveaxis, -0.1) self.clear() self.render() - def __zoomin(self, event): + def __deselect(self, event): + if self.__selected != None: + self.__selected = None + for line in self.__axis: + self.screen.delete(line) + self.__axis = [] + + def __zoom_in(self, event): self.scale += 2.5 self.clear() self.render() - def __zoomout(self, event): + def __zoom_out(self, event): self.scale -= 2.5 self.clear() self.render() - def __deselect(self, event): - if self.__selected != None: - self.__selected = None - self.__axis = [self.screen.delete(line) for line in self.__axis] - self.__moveaxis = None - - def __cameraleft(self, event): + def __camera_left(self, event): self.screen.zeros[0] -= 5 self.clear() self.render() - def __cameraright(self, event): + def __camera_right(self, event): self.screen.zeros[0] += 5 self.clear() self.render() - def __cameraup(self, event): + def __camera_up(self, event): self.screen.zeros[1] -= 5 self.clear() self.render() - def __cameradown(self, event): + def __camera_down(self, event): self.screen.zeros[1] += 5 self.clear() self.render() - - def writePoints(self, points): - self.points = [] - for point in points: - self.points.append(graphics.vertex.Vertex(point)) - - def writeTriangles(self, triangles): - self.triangles = [] - for triangle in triangles: - if len(triangle) != 4: - triangle.append('gray') - self.triangles.append(graphics.face.Face(triangle)) - - def __init__(self, points, triangles, width=1000, height=700, distance=6, scale=100, title='3D', background='white'): - #object parameters - self.distance = distance - self.scale = scale - #initialize display - self.screen = graphics.screen.Screen(width, height, title, background) - self.screen.window.bind('', self.__drag) - self.__prev = [] - self.screen.window.bind('', self.__resetDrag) + def __next_fold(self, event): + if self.fold_index < len(self.folds): + for i in range(self.anim_steps): + self.screen.after(int(1000/self.anim_steps), self.__fold_animate(self.folds[self.fold_index])) + self.fold_index += 1 + + def __prev_fold(self, event): + if self.fold_index > 0: + for i in range(self.anim_steps): + self.screen.after(int(1000/self.anim_steps), self.__fold_animate(self.folds[self.fold_index-1],False)) + self.fold_index -= 1 + + def __fold_animate(self, folds, do=True): + for subfolds in folds: + angle, axe1, axe2, vertices = subfolds + if do == True: + angle = angle / self.anim_steps + else: + angle = -angle / self.anim_steps + self.part_free_rotate(angle, axe1, axe2, vertices) + self.clear() + self.render() + self.screen.window.update_idletasks() - self.screen.window.bind('', self.__zoomin) - self.screen.window.bind('', self.__zoomout) - self.screen.window.bind('w', self.__cameraup) - self.screen.window.bind('s', self.__cameradown) - self.screen.window.bind('a', self.__cameraleft) - self.screen.window.bind('d', self.__cameraright) + def rotate(self, axis, angle): + # rotate model around axis + for point in self.vertices: + point.rotate(axis, angle) - # this is for editing the model - self.__selected = None - self.__axis = [] - self.__moveaxis = None - self.screen.window.bind('', self.__select) - self.screen.window.bind('', self.__deselect) - self.screen.window.bind('x', self.__selectx) - self.screen.window.bind('y', self.__selecty) - self.screen.window.bind('z', self.__selectz) - self.screen.window.bind('', self.__movedown) - self.screen.window.bind('', self.__moveup) - - #store coordinates - self.writePoints(points) - self.flattened = [] - - #store faces - self.writeTriangles(triangles) + def part_free_rotate(self, angle, A, B, vertices): + # rotate part of model around free vector (from self.vertices[A] to self.vertices[B]) + for point in [self.vertices[index] for index in vertices]: + point.free_rotate(angle, self.vertices[A], self.vertices[B]) + + def free_rotate(self, angle, A, B): + # rotate model around free vector (from self.vertices[A] to self.vertices[B]) + for point in self.vertices: + point.free_rotate(angle, self.vertices[A], self.vertices[B]) def clear(self): - #clear display + # clear display self.screen.clear() - def rotate(self, axis, angle): - #rotate model around axis - for point in self.points: - point.rotate(axis, angle) - def render(self): - #calculate flattened coordinates (x, y) - self.flattened = [] - for point in self.points: - self.flattened.append(point.flatten(self.scale, self.distance)) - - #get coordinates to draw triangles - triangles = [] - for triangle in self.triangles: - avgZ = -(self.points[triangle.a].z + self.points[triangle.b].z + self.points[triangle.c].z) / 3 - triangles.append((self.flattened[triangle.a], self.flattened[triangle.b], self.flattened[triangle.c], triangle.color, avgZ)) - - #sort triangles from furthest back to closest - triangles = sorted(triangles,key=lambda x: x[4]) - - #draw triangles - for triangle in triangles: - self.screen.createTriangle(triangle[0:3], triangle[3]) + # flatten vertices into screen positions + for vert in self.vertices: + vert.flatten(self.scale, self.distance) + + # calculate polygons average depth (z) + for poly in self.polygons: + poly.depth = sum([self.vertices[v_i].z for v_i in poly.vertices]) + + # draw flattent polygons from furthest to closest + for poly in reversed(sorted(self.polygons, key=lambda x: x.depth)): + self.screen.create_polygon([self.vertices[v].get_flat() for v in poly.vertices], poly.color) + diff --git a/graphics/face.py b/graphics/face.py deleted file mode 100644 index 80fa5f3..0000000 --- a/graphics/face.py +++ /dev/null @@ -1,8 +0,0 @@ -class Face: - def __init__(self, vertices): - #store point indexes - (a, b, c, color) = vertices - self.a = a - self.b = b - self.c = c - self.color = color diff --git a/graphics/screen.py b/graphics/screen.py index f294120..52f3a71 100644 --- a/graphics/screen.py +++ b/graphics/screen.py @@ -1,4 +1,5 @@ import tkinter +import itertools class Screen: def __init__(self, width, height, title, background): @@ -10,15 +11,14 @@ def __init__(self, width, height, title, background): self.window.title(title) self.image = tkinter.Canvas(self.window, width=width, height=height, bg=background) self.image.pack() - - def createTriangle(self, points, color): - a, b, c = points[0], points[1], points[2] - #create coordinates starting in center of screen - coords = [a[0] + self.zeros[0], a[1] + self.zeros[1], b[0] + self.zeros[0], b[1] + self.zeros[1], c[0] + self.zeros[0], c[1] + self.zeros[1]] - #draw triangle on screen + + def create_polygon(self, vertices, color): + # create coordinates starting in center of screen + coords = list(itertools.chain(*[[v0 + self.zeros[0], v1 + self.zeros[1]] for v0,v1 in vertices])) + # draw triangle on screen self.image.create_polygon(coords, fill=color, outline="black") - def createLine(self, points, color): + def create_arrow(self, points, color): a, b = points[0], points[1] return self.image.create_line(a[0], a[1], b[0], b[1], fill=color, arrow=tkinter.BOTH) @@ -28,7 +28,6 @@ def clear(self): def delete(self, item): self.image.delete(item) - return None def after(self, time, function): #call tk.Tk's after() method diff --git a/graphics/structures.py b/graphics/structures.py new file mode 100644 index 0000000..2660d14 --- /dev/null +++ b/graphics/structures.py @@ -0,0 +1,92 @@ +import math + + +class Polygon: + def __init__(self, *args): + #store point indexes + if isinstance(args[-1], str): + self.vertices = args[:-1] + self.color = args[-1] + else: + self.vertices = args + self.color = "grey" + + +class Vertex: + def __init__(self, point): + #store x, y, z coordinates + (x,y,z) = point + self.x = x + self.y = y + self.z = z + + def flatten(self, scale, distance): + #calculate 2D coordinates from 3D point + self.flat_x = int(((self.x * distance) / (self.z + distance)) * scale) + self.flat_y = int(((self.y * distance) / (self.z + distance)) * scale) + + def get_flat(self): + return (self.flat_x, self.flat_y) + + def rotate(self, axis, angle): + #rotate point around axis + angle = angle / 450 * 180 / math.pi + #sqrt2 = math.sqrt(2) + if axis == 'z': + #rotate aroud Z axis + newX = self.x * math.cos(angle) - self.y * math.sin(angle) + newY = self.y * math.cos(angle) + self.x * math.sin(angle) + newZ = self.z + elif axis == 'x': + #rotate around X axis + newY = self.y * math.cos(angle) - self.z * math.sin(angle) + newZ = self.z * math.cos(angle) + self.y * math.sin(angle) + newX = self.x + elif axis == 'y': + #rotate around Y axis + newX = self.x * math.cos(angle) - self.z * math.sin(angle) + newZ = self.z * math.cos(angle) + self.x * math.sin(angle) + newY = self.y + else: + raise ValueError('invalid rotation axis') + self.x = newX + self.y = newY + self.z = newZ + + def move(self, axis, value): + if axis == 'x': + self.x += value + elif axis == 'y': + self.y += value + elif axis == 'z': + self.z += value + else: + raise ValueError('Invalid movement axis') + + def free_rotate(self, phi, A, B): + """Compute new coordinates for self as image of itself by the rotation R + of phi degrees around the AB vector.""" + # Define conjugate and * for Quaternions (4-tuples) + class Quaternion(tuple): + def conj(self): + return self[0], *[-self[i] for i in range(1,4)] + def __mul__(self, q2): + w1, x1, y1, z1 = self + w2, x2, y2, z2 = q2 + w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2 + x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2 + y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2 + z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2 + return w, x, y, z + # Compute "vector to rotate" quaternion using vector Aself. + p = Quaternion((0, self.x-A.x, self.y-A.y, self.z-A.z)) + # Compute "rotation" quaternion using vector of AB. + ABx, ABy, ABz = B.x-A.x, B.y-A.y, B.z-A.z + nAB = math.sqrt(ABx**2 + ABy**2 + ABz**2) + half_phi_rad = phi / 360 * math.pi + S = math.sin(half_phi_rad) + r = Quaternion((math.cos(half_phi_rad), S*ABx/nAB, S*ABy/nAB, S*ABz/nAB)) + # Calculate "image" quaternion using p and r conjugation (q = r⋅p⋅r^-1). + qw, qx, qy, qz = Quaternion(r * p) * r.conj() + # Get Q coordinates. + self.x, self.y, self.z = qx+A.x, qy+A.y, qz+A.z diff --git a/graphics/vertex.py b/graphics/vertex.py deleted file mode 100644 index 66dc6be..0000000 --- a/graphics/vertex.py +++ /dev/null @@ -1,51 +0,0 @@ -import math - -class Vertex: - def __init__(self, point): - #store x, y, z coordinates - (x,y,z) = point - self.x = x - self.y = y - self.z = z - - def flatten(self, scale, distance): - #calculate 2D coordinates from 3D point - projectedY = int(((self.y * distance) / (self.z + distance)) * scale) - projectedX = int(((self.x * distance) / (self.z + distance)) * scale) - return (projectedX, projectedY) - - def rotate(self, axis, angle): - #rotate point around axis - angle = angle / 450 * 180 / math.pi - sqrt2 = math.sqrt(2) - if axis == 'z': - #rotate aroud Z axis - newX = self.x * math.cos(angle) - self.y * math.sin(angle) - newY = self.y * math.cos(angle) + self.x * math.sin(angle) - newZ = self.z - elif axis == 'x': - #rotate around X axis - newY = self.y * math.cos(angle) - self.z * math.sin(angle) - newZ = self.z * math.cos(angle) + self.y * math.sin(angle) - newX = self.x - elif axis == 'y': - #rotate around Y axis - newX = self.x * math.cos(angle) - self.z * math.sin(angle) - newZ = self.z * math.cos(angle) + self.x * math.sin(angle) - newY = self.y - else: - raise ValueError('invalid rotation axis') - self.x = newX - self.y = newY - self.z = newZ - - def move(self, axis, value): - if axis == 'x': - self.x += value - elif axis == 'y': - self.y += value - elif axis == 'z': - self.z += value - else: - raise ValueError('Invalid movement axis') - diff --git a/pyramidExample.py b/pyramidExample.py new file mode 100755 index 0000000..dd7f790 --- /dev/null +++ b/pyramidExample.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Animated pyramid example""" + +from graphics.engine import Engine3D + +vertices = [[0,0,0],[0,-1,0],[-1,1,-1],[-1,1,1],[1,1,1],[1,1,-1]] +polygons = [[2,3,4,5],[1,2,3],[1,3,4],[1,4,5],[1,2,5]] +test = Engine3D(vertices, polygons, title='Cube') + +def animation(): + test.clear() + test.free_rotate(.75, 0, 1) # angle in degree, axe defined by 2 vertices + test.render() + test.screen.after(10, animation) + +if __name__ == '__main__': + animation() + test.screen.window.mainloop() diff --git a/sharkExample.py b/sharkExample.py old mode 100644 new mode 100755 index 895ceef..0d5bb3c --- a/sharkExample.py +++ b/sharkExample.py @@ -1,28 +1,12 @@ -### Shark ### +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +"""Complex model example: Shark""" -import graphics.engine +from graphics.engine import read_data_file, Engine3D -points = [] -triangles = [] - -with open('coords/SharkV.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - points.append([float(coords[0]), float(coords[1]), float(coords[2])]) - f.close() - -with open('coords/SharkT.txt', 'r') as f: - lines = f.readlines() - for line in lines: - coords = line[:-2].split(' ') - newCoords = [] - for coord in coords[1:4]: - newCoords.append(int(coord)) - triangles.append(newCoords) - f.close() - -test = graphics.engine.Engine3D(points, triangles, scale=100, title='Shark') +vertices = read_data_file('coords/SharkV.txt', 'V') +polygons = read_data_file('coords/SharkP.txt', 'P') +test = Engine3D(vertices, polygons, scale=100, title='Shark') def animation(): test.clear() @@ -30,7 +14,6 @@ def animation(): test.render() test.screen.after(1, animation) -animation() -test.screen.window.mainloop() - -############## +if __name__ == '__main__': + animation() + test.screen.window.mainloop()