3

My pyglet application to view 3-d objects in STL format is acting funny. when I load a stl file, it works fine, but then when I try to draw it, it acts funny. code doesn't crash, but the test file I loaded for a cube doesn't look right. I think it might be joining all of the points in the draw code that I don't want to join. the test file should appear 30 pixels by 30 instead of the whole upper right corner:

a picture showing that a chunk of the display is the cube.

at 150 degrees, looks almost right... the 150 degree attempt...

the red lines are the wireframe, green dots vertices, and gray is a face of the cube.

here is my code:

print("starting Wireframe Viewer")
import pyglet, wireframe
from pyglet.gl import *

verticeColor = (0, 100, 0)
verticeSize = 4
lineColor = (100, 0, 0)
lineSize = 2
faceColor = (200, 200, 200)
menuColor = (0, 0, 100)
backgroundColor = (0, 0, 50)
gridColor = (255, 255, 255)
mode = 'OBJ'  # normal viewing - see all faces and such

pos = [0, 0, -20]
rot_y = 0
rot_x = 0
rot_z = 0

if __name__ == "__main__":
    # good
    window = pyglet.window.Window(640, 480, resizable=True)
    wf = wireframe.Wireframe()

    # good
    wf.importStl('test.stl')
    wf.dumpData()


    @window.event
    def on_draw():
        # creating 3D viewport
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(10, 1, 0.1, 100)

        glTranslatef(*pos)
        glRotatef(rot_y, 0, 1, 0)
        glRotatef(rot_x, 1, 0, 0)
        glRotatef(rot_z, 0, 0, 1)

        glClearColor(0.0, 0.0, 0.15, 0.0)
        window.clear()

        # load line width and point size
        glLineWidth(lineSize)
        glPointSize(verticeSize)
        stlDrawDat = []
        for dat in wf.stlMesh:
            stlDrawDat.append([[dat[0], dat[1], dat[2]],
                               [dat[3], dat[4], dat[5]],
                               [dat[6], dat[7], dat[8]]])
        # drawing the image
        for dat in stlDrawDat:
            pyglet.graphics.draw(3, GL_TRIANGLES,
                                 ('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', faceColor * 3))
            pyglet.graphics.draw(3, GL_LINES,
                                 ('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3B', lineColor * 3))
            pyglet.graphics.draw(3, GL_POINTS,
                                 ('v3f', [*dat[0], *dat[1], *dat[2]]), ('c3b', verticeColor * 3))

        glFlush()


    @window.event
    def on_key_press(s, m):
        # good
        global pos, rot_y, rot_x, rot_z

        if m:
            pass
        if s == pyglet.window.key.W:
            rot_x += 5  # pos[2] -= 1
        if s == pyglet.window.key.S:
            rot_x -= 5  # pos[2] += 1
        if s == pyglet.window.key.A:
            rot_y += 5
        if s == pyglet.window.key.D:
            rot_y -= 5
        if s == pyglet.window.key.Q:
            rot_z += 5
        if s == pyglet.window.key.E:
            rot_z -= 5
        if s == pyglet.window.key.MINUS:
            pos[2] -= 1
        if s == pyglet.window.key.EQUAL:
            pos[2] += 1
        if s == pyglet.window.key.LEFT:
            pos[0] -= 1
        if s == pyglet.window.key.RIGHT:
            pos[0] += 1
        if s == pyglet.window.key.UP:
            pos[1] += 1
        if s == pyglet.window.key.DOWN:
            pos[1] -= 1


    pyglet.app.run()

and my outer file wireframe.py I can add if needed:

import numpy
from stl import mesh


class Wireframe:
    def __init__(self):
        self.stlMesh = numpy.zeros((0, 9))
        self.originalMesh = numpy.zeros((0, 9))
        self.backupMesh = numpy.zeros((0, 9))

    def importStl(self, fileName):
        print("importing ", fileName)
        self.stlMesh = mesh.Mesh.from_file(fileName)
        self.originalMesh = mesh.Mesh.from_file(fileName)
        self.backupMesh = mesh.Mesh.from_file(fileName)

    def dumpData(self):
        print('\nstl data:')
        for x in self.stlMesh:
            print(x)


if __name__ == "__main__":
    wf = Wireframe()
    wf.importStl('test.stl')
    wf.dumpData()

if someone could help me figure out the problem, I would be happy. I think the problem is somewhere in the drawing functions. if I need to shorten my code, tell me! it was working till I added the 3-D view code from another post: How do I make 3D in pyglet?

modules needed to run code:

python-utils
pyglet
numpy
numpy-stl
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
HennieP12
  • 33
  • 4
  • What do you mean by "funny"? The geometry seems to render correctly. Possibly you've expected something different, but it doesn't look "wrong". Note you use perspective projection, (0, 0) is in the center of the window. Your filed of view angle is very small (10°). Increase the filed of view angle, for instance `gluPerspective(90, 1, 0.1, 100)`. – Rabbid76 Jul 02 '20 at 19:49
  • I already tried that, I will try ```gluPerspective(180, 1, 0.1, 100)``` Thanks! – HennieP12 Jul 03 '20 at 00:09
  • At first, I had the ```gluPerspective()``` angle set to 90 – HennieP12 Jul 03 '20 at 00:12
  • angle of 150 worked kinda well, I will post picture of result... – HennieP12 Jul 03 '20 at 00:15
  • front face is rectangle, though. the faces still stretch... – HennieP12 Jul 03 '20 at 00:20
  • hold on... am I inside the cube?????? – HennieP12 Jul 03 '20 at 00:21
  • I just played with the controls, turns out I can move the cube, and almost looks like I am inside... – HennieP12 Jul 03 '20 at 00:21
  • I also just played with the pos value. If I set it to 0 or 1, the window looks like the 10 degree view port... – HennieP12 Jul 03 '20 at 00:25
  • setting pos[2] to 99 fixed it. now how do I make the image look like I'm editing it in a cad program. – HennieP12 Jul 03 '20 at 00:28
  • also, it appears my faces are see-through at certain angles... or is it just me? – HennieP12 Jul 03 '20 at 00:31

1 Answers1

2

gluPerspective defines a Viewing frustum.

In view space the origin of the view is the camera positions and all the points with the x and y coordinate (0, 0) are on the line of sight in the center of the view.
The 1st parameter of gluPerspective is the filed of view angle along the y axis in degrees. The angle has to 0° < fovAngle < 180°. Hence 0° and 180° a re not valid angles.

The 2nd parameter is the aspect ratio.

A field of view of 10° seems to be far to small. Since the size of the window is 640x480, the aspect ration has to be 640.0/480.0:

gluPerspective(10, 1, 0.1, 100)

gluPerspective(120.0, 640.0/480.0, 0.1, 100)

Furthermore I recommend to enable the Depth Test:

glEnable(GL_DEPTH_TEST)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174