Tkinter - ZackWilde27/Z3dPy GitHub Wiki

I recommend PyGame since it's faster at drawing, but to use Tkinter:

Getting Started

I'll import the library and use Tkinter for the screen.

import tkinter as tk
import z3dpy as zp

root = tk.Tk()
canvas = tk.Canvas(width=1280, height=720, background="black")
canvas.pack()

Set the render size to match the output screen

zp.screenSize = (1280, 720)

Next create a camera, with the desired location.

# z3dpy.Cam(vPos)
myCamera = zp.Cam([0, 0, 0])

Now load a mesh to draw, I'll use the built-in susanne.

# LoadMesh(filename, *vPos, *VScale)
myMesh = zp.LoadMesh("z3dpy/mesh/susanne.obj", [0, 0, 2])
# Z is forward in this case, so it's placed in front of the camera

Rendering 3D in Z3dPy takes 3 steps:

  • Set the internal camera
  • Rastering
  • Drawing Triangles

Rastering and Drawing have different functions for certain use-cases

# Set the internal camera
zp.SetInternalCam(myCamera)

# Rastering
for tri in zp.RasterMeshList([myMesh]):
    # Drawing Triangles
    zp.TkDrawTriF(tri, 1.0, canvas)

In this case, I want the colour of the triangle to represent it's normal value:

for tri in zp.RasterMeshList([myMesh]):
    normal = zp.TriGetNormal(tri)
    zp.TkDrawTriRGBF(tri, normal, canvas)

Lastly, chuck it in a loop:

# Since the camera isn't going to move we can set the internal camera outside the loop
zp.SetInternalCam(myCamera)

while True:
    # Clear the screen
    canvas.delete("all")

    # Render 3D
    for tri in zp.RasterMeshList([myMesh]):
        zp.TkDrawTriRGBF(tri, zp.TriGetNormal(tri), canvas)

    # Update display afterwards
    root.update()

    # Rotate Mesh
    # MeshAddRot(mesh, vector)
    zp.MeshAddRot(myMesh, [1, 4, 5])

Final script:

import tkinter as tk
import z3dpy as zp

root = tk.Tk()
# TkScreen creates the canvas and sets the z3dpy screenSize at the same time
canvas = zp.TkScreen(1280, 720, "black", tk)

zp.screenSize(1280, 720)

# z3dpy.Cam(vPos)
myCamera = zp.Cam([0, 0, 0])

# Since the camera isn't going to move we can set the internal camera outside the loop
zp.SetInternalCam(myCamera)

# LoadMesh(filename, *vPos, *VScale)
myMesh = zp.LoadMesh("z3dpy/mesh/susanne.obj", [0, 0, 2])

while True:
    # Clear the screen
    canvas.delete("all")

    # Render 3D
    for tri in zp.RasterMeshList([myMesh]):
        zp.TkDrawTriRGBF(tri, zp.TriGetNormal(tri), canvas)

    # Update display afterwards
    root.update()
    
    # Rotate Mesh
    zp.MeshAddRot(myMesh, [1, 4, 5])