model-converter-python/viewer.py

229 lines
6.1 KiB
Python
Raw Permalink Normal View History

2016-11-22 11:55:13 +01:00
#!/usr/bin/env python3
import sys
import ctypes
2016-11-22 16:49:36 +01:00
import argparse
import os
2016-11-22 17:17:37 +01:00
import math
2016-11-22 11:55:13 +01:00
2016-12-01 13:50:04 +01:00
# Test dependencies
2017-02-27 15:00:30 +01:00
missing_dependencies = []
2016-12-02 21:37:20 +01:00
try:
import PIL
except:
2017-02-27 15:00:30 +01:00
missing_dependencies.append('pillow')
2016-12-02 21:37:20 +01:00
2016-12-01 13:50:04 +01:00
try:
import pygame as pg
import pygame.locals as pgl
except:
2017-02-27 15:00:30 +01:00
missing_dependencies.append('pygame')
2016-12-01 13:50:04 +01:00
try:
import OpenGL.GL as gl
import OpenGL.GLU as glu
except:
2017-02-27 15:00:30 +01:00
missing_dependencies.append('pyopengl')
2016-12-01 13:50:04 +01:00
try:
import numpy
except:
2017-02-27 15:00:30 +01:00
missing_dependencies.append('numpy')
if len(missing_dependencies) > 0:
print('You are missing the following dependencies :', file=sys.stderr)
for dep in missing_dependencies:
print(dep, file=sys.stderr)
2016-12-01 13:50:04 +01:00
2016-12-02 21:37:20 +01:00
from d3.model.tools import load_model
from d3.geometry import Vector
from d3.controls import TrackBallControls, OrbitControls
from d3.camera import Camera
2017-01-18 13:57:59 +01:00
from d3.shader import Shader
2018-02-23 11:31:58 +01:00
from d3.model.basemodel import BoundingBox
2016-12-02 21:37:20 +01:00
2016-11-22 11:55:13 +01:00
WINDOW_WIDTH = 1024
2016-12-01 10:55:41 +01:00
WINDOW_HEIGHT = 1024
2018-02-23 11:31:58 +01:00
CENTER_AND_SCALE = True
2016-12-01 10:55:41 +01:00
def resize(width, height):
length = min(width, height)
offset = int( math.fabs(width - height) / 2)
2016-12-01 11:47:18 +01:00
# Ugly AF
pg.display.set_mode((width, height), pg.DOUBLEBUF | pg.RESIZABLE | pg.OPENGL)
2016-12-01 10:55:41 +01:00
if width < height:
gl.glViewport(0, offset, length, length)
else:
gl.glViewport(offset, 0, length, length)
2016-11-22 11:55:13 +01:00
2016-11-22 16:49:36 +01:00
def main(args):
2016-11-22 11:55:13 +01:00
2016-11-30 15:37:58 +01:00
if (args.from_up is None) != (args.to_up is None):
raise Exception("from-up and to-up args should be both present or both absent")
up_conversion = None
if args.from_up is not None:
up_conversion = (args.from_up, args.to_up)
2016-12-02 10:13:16 +01:00
if args.verbose:
def log(*args, **kwargs):
print(*args, **kwargs)
else:
def log(*args, **kwargs):
pass
2016-11-30 15:37:58 +01:00
2017-01-13 14:39:03 +01:00
# Load and parse the model
sys.stderr.flush()
2018-02-23 11:31:58 +01:00
models = []
for path in args.input:
log('Loading model ' + path + '...', file=sys.stderr, end='')
model = load_model(path, up_conversion)
# Compute normals if not already computed
if len(model.normals) == 0:
log(' done! (' + str(sum(map(lambda x: len(x.faces), model.parts))) + ' faces)\nComputing normals...', file=sys.stderr, end='')
sys.stderr.flush()
model.generate_vertex_normals()
# Generate vbos for smooth rendering
log(' done!\nGenerating vbos...', file=sys.stderr, end='')
sys.stderr.flush()
2018-02-23 11:31:58 +01:00
model.generate_vbos()
2018-02-23 11:31:58 +01:00
models.append(model)
log(' done!\nInitialiazing OpenGL Context', file=sys.stderr, end='')
sys.stderr.flush()
2017-01-13 14:39:03 +01:00
2016-11-25 14:56:37 +01:00
camera = Camera(Vector(0,0,5), Vector(0,0,0))
2016-11-25 15:41:52 +01:00
controls = OrbitControls()
2016-11-22 17:17:37 +01:00
2016-11-25 15:03:03 +01:00
pg.init()
2016-12-01 13:50:04 +01:00
pg.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pgl.DOUBLEBUF | pgl.OPENGL | pgl.RESIZABLE)
2016-11-29 15:42:21 +01:00
pg.display.set_caption('Model-Converter')
2016-11-22 11:55:13 +01:00
# OpenGL init
2016-12-01 10:55:41 +01:00
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
2016-11-25 15:03:03 +01:00
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
glu.gluPerspective(45, (WINDOW_WIDTH / WINDOW_HEIGHT), 0.1, 50.0)
2016-11-22 11:55:13 +01:00
2016-11-25 15:03:03 +01:00
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glEnable(gl.GL_CULL_FACE)
gl.glEnable(gl.GL_BLEND)
gl.glClearColor(0, 0, 0, 0)
2016-11-22 11:55:13 +01:00
running = True
2018-02-23 11:31:58 +01:00
bounding_box = BoundingBox()
if CENTER_AND_SCALE:
for model in models:
for vertex in model.vertices:
bounding_box.add(vertex)
log(' done!\nComputing bounding box...', file=sys.stderr, end='')
2016-11-30 10:08:37 +01:00
2016-12-02 10:13:16 +01:00
log(' done!\nInitializing OpenGL textures...', file=sys.stderr, end='')
sys.stderr.flush()
2018-02-23 11:31:58 +01:00
2016-11-30 10:08:37 +01:00
# Initializes OpenGL textures
2018-02-23 11:31:58 +01:00
for model in models:
model.init_textures()
2016-11-30 10:08:37 +01:00
2017-01-18 13:57:59 +01:00
shader = Shader()
2016-11-25 11:27:05 +01:00
log(' done!\nReady!', file=sys.stderr)
sys.stderr.flush()
2016-12-01 13:50:04 +01:00
2016-11-22 11:55:13 +01:00
while running:
2016-11-25 15:03:03 +01:00
for event in pg.event.get():
2016-12-01 10:55:41 +01:00
controls.apply_event(event)
2016-11-25 15:03:03 +01:00
if event.type == pg.QUIT:
pg.quit()
2016-11-22 11:55:13 +01:00
quit()
2016-11-25 15:03:03 +01:00
elif event.type == pg.KEYUP:
if event.key == pg.K_ESCAPE:
pg.quit()
2016-11-22 11:55:13 +01:00
quit()
2016-11-25 15:03:03 +01:00
elif event.type == pg.MOUSEBUTTONDOWN:
2016-11-22 17:29:25 +01:00
if event.button == 1:
2016-11-25 15:03:03 +01:00
pg.mouse.get_rel()
2016-12-01 10:55:41 +01:00
elif event.type == pg.VIDEORESIZE:
resize(event.size[0], event.size[1])
2016-11-22 11:55:13 +01:00
2016-11-23 12:07:47 +01:00
# Update physics
controls.update()
2016-11-25 15:03:03 +01:00
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity()
2016-11-25 11:53:35 +01:00
camera.look()
2016-11-22 17:17:37 +01:00
2016-11-25 15:03:03 +01:00
gl.glPushMatrix()
2016-11-22 17:17:37 +01:00
controls.apply()
2016-12-01 10:55:41 +01:00
2016-12-01 11:48:32 +01:00
# gl.glBegin(gl.GL_LINES)
# gl.glColor3f (1.0,0.0,0.0)
# gl.glVertex3f(0.0,0.0,0.0)
# gl.glVertex3f(2.0,0.0,0.0)
# gl.glColor3f (0.0,1.0,0.0)
# gl.glVertex3f(0.0,0.0,0.0)
# gl.glVertex3f(0.0,2.0,0.0)
# gl.glColor3f (0.0,0.0,1.0)
# gl.glVertex3f(0.0,0.0,0.0)
# gl.glVertex3f(0.0,0.0,2.0)
# gl.glEnd()
2016-12-01 10:55:41 +01:00
2016-11-30 10:08:37 +01:00
shader.bind()
2018-02-23 11:31:58 +01:00
if CENTER_AND_SCALE:
center = bounding_box.get_center()
scale = bounding_box.get_scale() / 2
gl.glPushMatrix()
gl.glScalef(1/scale, 1/scale, 1/scale)
gl.glTranslatef(-center.x, -center.y, -center.z)
for model in models:
model.draw()
if CENTER_AND_SCALE:
gl.glPopMatrix()
2016-11-30 10:08:37 +01:00
shader.unbind()
2016-11-25 15:03:03 +01:00
gl.glPopMatrix()
2016-11-22 17:17:37 +01:00
2016-11-25 15:03:03 +01:00
gl.glFlush()
pg.display.flip()
2016-11-22 17:17:37 +01:00
2016-11-23 12:07:47 +01:00
# Sleep
2016-11-25 15:03:03 +01:00
pg.time.wait(10)
2016-11-22 11:55:13 +01:00
if __name__ == '__main__':
2016-12-01 13:50:04 +01:00
2016-11-22 16:49:36 +01:00
parser = argparse.ArgumentParser()
parser.set_defaults(func=main)
parser.add_argument('-v', '--version', action='version', version='1.0')
2018-02-23 11:31:58 +01:00
parser.add_argument('-i', '--input', metavar='input', nargs='+', default=None, help='Input model')
2016-11-30 15:37:58 +01:00
parser.add_argument('-fu', '--from-up', metavar='fup', default=None,
help="Initial up vector")
parser.add_argument('-tu', '--to-up', metavar='fup', default=None,
help="Output up vector")
2016-12-02 10:13:16 +01:00
parser.add_argument('-V', '--verbose', default=False, action='store_true',
help="Verbose output")
2016-11-30 15:37:58 +01:00
2016-11-22 16:49:36 +01:00
args = parser.parse_args()
args.func(args)