Skip to content

Commit 2d8efb6

Browse files
author
Tamerlan Abilov
committed
load_obj load from url, readme update, example script
1 parent acec530 commit 2d8efb6

File tree

3 files changed

+36
-20
lines changed

3 files changed

+36
-20
lines changed

README.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@ blow_your_head = Plot(
203203
Wawefront format is widely used as a standard in 3D graphics
204204

205205
You can import your model here. Only vertices and faces supported.\
206-
`Model.load_OBJ(cls, path, wireframe=False, **all_model_kwargs)`
206+
`Model.load_OBJ(cls, path_or_url, wireframe=False, **all_model_kwargs)`
207207

208208
You can find examples here [github.com/alecjacobson/common-3d-test-models](https://github.com/alecjacobson/common-3d-test-models)
209209

210+
You might have to normalize(scale and etc.)each `.obj` sample differently \
211+
Only vertices and faces are supported.
212+
210213
```python
211214
Model.load_OBJ('beetle.obj.txt', wireframe=True, color=white, position=(-2, 2, -4), scale=3)
212215
```
@@ -299,7 +302,7 @@ import sys
299302
import pygame
300303

301304
from play3d.models import Model, Grid
302-
from pygame_utils import handle_camera_with_keys # your keyboard control management
305+
from pygame_utils import handle_camera_with_keys # custom keyboard handling - moving camera
303306
from play3d.three_d import Device, Camera
304307
from play3d.utils import capture_fps
305308

@@ -323,8 +326,14 @@ put_pixel = lambda x, y, color: pygame.draw.circle(screen, color, (x, y), 1)
323326
Device.set_renderer(put_pixel, line_renderer=line_adapter)
324327

325328
grid = Grid(color=(30, 140, 200), dimensions=(30, 30))
326-
suzanne = Model.load_OBJ('suzanne.obj.txt', position=(3, 2, -7), color=white, rasterize=True)
327-
beetle = Model.load_OBJ('beetle.obj.txt', wireframe=False, color=white, position=(0, 2, -11), scale=3)
329+
330+
# be aware of different scaling of .obj samples. Only vertices and faces supported!
331+
suzanne = Model.load_OBJ(
332+
'https://raw.githubusercontent.com/OpenGLInsights/OpenGLInsightsCode/master/Chapter%2026%20Indexing%20Multiple%20Vertex%20Arrays/article/suzanne.obj',
333+
position=(3, 2, -7), color=white, rasterize=True)
334+
beetle = Model.load_OBJ(
335+
'https://raw.githubusercontent.com/alecjacobson/common-3d-test-models/master/data/beetle.obj',
336+
wireframe=False, color=white, position=(0, 2, -11), scale=3)
328337
beetle.rotate(0, 45, 50)
329338

330339
camera = Camera.get_instance()
@@ -338,7 +347,7 @@ def frame():
338347
sys.exit(0)
339348

340349
screen.fill(black)
341-
handle_camera_with_keys() # we can move our camera
350+
handle_camera_with_keys() # to move our camera - walk, can be ignored
342351
grid.draw()
343352
beetle.draw()
344353
suzanne.rotate(0, 1, 0).draw()

example/main.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
Device.set_renderer(put_pixel, line_renderer=line_adapter)
3030

3131
grid = Grid(color=(30, 140, 200), dimensions=(30, 30))
32-
suzanne = Model.load_OBJ('suzanne.obj.txt', position=(3, 2, -7), color=white, rasterize=True)
33-
beetle = Model.load_OBJ('beetle.obj.txt', wireframe=False, color=white, position=(0, 2, -11), scale=3)
32+
33+
# be aware of different scaling of .obj samples. Only vertices and faces supported!
34+
suzanne = Model.load_OBJ('https://raw.githubusercontent.com/OpenGLInsights/OpenGLInsightsCode/master/Chapter%2026%20Indexing%20Multiple%20Vertex%20Arrays/article/suzanne.obj', position=(3, 2, -7), color=white, rasterize=True)
35+
beetle = Model.load_OBJ('https://raw.githubusercontent.com/alecjacobson/common-3d-test-models/master/data/beetle.obj', wireframe=False, color=white, position=(0, 2, -11), scale=3)
3436
beetle.rotate(0, 45, 50)
3537

3638
camera = Camera.get_instance()

play3d/models.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import copy
22
import math
33
import numbers
4+
import urllib.request
45
from collections import Iterable
56
from inspect import signature
67

@@ -31,28 +32,32 @@ class Model:
3132
def load_OBJ(cls, path, rasterize=False, **kwargs):
3233
"""
3334
34-
:param path:
35+
:param path: file path or download url
3536
:param rasterize: True - means turn off rasterization - use only mesh
3637
:param kwargs:
3738
:return:
3839
"""
3940
data = []
4041
faces = []
41-
with open(path) as f:
42-
l = f.readline()
43-
while l:
44-
if l.startswith('v '):
45-
v = [float(n) for n in l[2:].split()]
46-
if len(v) == 3: # add default w=1 coord if not given
47-
v += [1]
4842

49-
data.append(v)
43+
if 'http' in path:
44+
content = urllib.request.urlopen(path).read().decode('utf-8')
45+
else:
46+
content = open(path).read()
47+
for l in content.splitlines():
48+
49+
if l.startswith('v '):
50+
v = [float(n) for n in l[2:].split()]
51+
if len(v) == 3: # add default w=1 coord if not given
52+
v += [1]
53+
54+
data.append(v)
55+
56+
if l.startswith('f '):
57+
v = list(map(lambda face: int(face.split('/')[0]), l[2:].split()))
5058

51-
if l.startswith('f '):
52-
v = list(map(lambda face: int(face.split('/')[0]), l[2:].split()))
59+
faces.append(v)
5360

54-
faces.append(v)
55-
l = f.readline()
5661
obj = cls(**kwargs, data=data, faces=faces, rasterize=rasterize)
5762
return obj
5863

0 commit comments

Comments
 (0)