EdwardChamberlain / PySimpleGUI-3D-Viewer

A basic 3D viewer built with PySimpleGUI
GNU General Public License v3.0
8 stars 1 forks source link

💗 this project! The screenshots are great...the topic is fantastic the visuals are top-notch! #1

Open PySimpleGUI opened 2 years ago

PySimpleGUI commented 2 years ago

Question for ya....

Would it be OK if I made an entity in the eCookbook using the Trinket of your code? You'll of course get full credit and I'll have a link back to your repo.

If you want to share the link to the Trinket that's there now, there's no problem doing that. https://trinket.io/pygame/5cb3229fe8

There's also a "Published" version that doesn't show the code but rather enables seeing the application in a larger window: https://pysimplegui.trinket.io/sites/teapot

If I'm able to add it as a real page http://eCookbook.PySimpleGUI.org then it'll have more text that will explain where it came from, etc.

For now I've added a comment header.

EdwardChamberlain commented 2 years ago

Absolutely! This was a really fun learning project for me and if it can help someone else out then even better!

I have actually just added a "shaded" render mode which adds some very basic shading incase you want to update your ticket! I would like to expand that out to a lights system but theres only so much time in the day!

PySimpleGUI commented 2 years ago

Any chance of convincing you to remove the match statements so I don't need to edit your code everytime?

EdwardChamberlain commented 2 years ago

Go on then!

I have just pushed new code using if statements.

PySimpleGUI commented 2 years ago

OK! We're live!

image

https://pysimplegui.trinket.io/demo-programs#/graph-element/utah-teapot

I made a couple of small changes.

  1. Made the Combo element readonly=True. This makes it possible to click on the text as well as the arrow
  2. Made the Graph element smaller. This was needed due to the size available on Trinket. A size of (350,350) worked out really well given the available space
  3. Location of the .obj file - my_object = obj_reader.import_obj('utah_teapot.obj', ('x', 90))
  4. Here's how it looks over on the site:

Teapot on Trinket

EdwardChamberlain commented 2 years ago

Thanks for the suggestions! I have cut in the changes to the Combo element and the Graph. They should be on the repo now.

I have also changed the default render mode to faces and added the ability to drag the object for rotation using the drag_submits capability of the graph!

Page looks awesome!

PySimpleGUI commented 2 years ago

ability to drag the object for rotation

I was going to experiment when "I found a moment" to see what was possible. Thrilled to hear you found a moment before I did, and that something worked! Way to go!

image

I needed to make the Graph size change again to be (350,350). Maybe consider making it a constant that is set to a different value when running n Trinket:

GRAPH_SIZE = (350,350) if sg.running_trinket() else (500,500)

layout = [
    [sg.Graph(GRAPH_SIZE, (-1, -1), (1, 1), 'black', float_values=True, enable_events=True, key='-GRAPH-', drag_submits=True)],

I got the folder thing wrong in my previous comment. I removed all folder references as it's a flat directory structure on this Trinket.

my_object = obj_reader.import_obj('utah_teapot.obj', rotation=('x', 90), translation=(0, 0, -1.5))

Anyway... I pulled in all your newest stuff and updated the page on Trinket with instructions to drag as well: https://pysimplegui.trinket.io/demo-programs#/graph-element/utah-teapot

PySimpleGUI commented 2 years ago

Suggestion..... bind the mouse wheel to "X"

[EDIT - NOTE... may be tricky]

PySimpleGUI commented 2 years ago

There is no get method for the Slider element, so had to access the underlying tkinter details.

I used keyboard events to do it. I've updated the Trinket so you can see my hack.

These are the scope f the changes:

window = sg.Window('3D Viewport', layout, return_keyboard_events=True)

drag_loc = None
while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break

    if event == 'MouseWheel:Up':
      window['-X-'].update(value=window['-X-'].TKIntVar.get()-1)
      event = '-X-'
    elif event == 'MouseWheel:Down':
      window['-X-'].update(value=window['-X-'].TKIntVar.get()+1)
      event = '-X-'      
EdwardChamberlain commented 2 years ago

Your code there doesn't seem to play nicely with the inertia scrolling in macOS (nothing ever does!). It seems like it only updates when the scroll event ends meaning you cant get a nice smooth scroll.

The other option is to bind "zoom" to vertical dragging:

    if event == '-GRAPH-':
        new_drag_location = values['-GRAPH-']

        if not drag_loc:
            drag_loc = new_drag_location

        my_object.orientation += (drag_loc[0] - new_drag_location[0]) * 360
        my_object.position[0] += (drag_loc[1] - new_drag_location[1]) * -10

        drag_loc = new_drag_location

        window['-O-'].update(my_object.orientation)
        window['-X-'].update(my_object.position[0])

    if event == '-GRAPH-+UP':
        drag_loc = None

This works quite nicely but does limit the ability to roll the model in the other rotation axis!

PySimpleGUI commented 2 years ago

I like being able to experiment with these kinds of interaces easily.

Makes it fun to play around using a variety of interfaces.