Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to automatically reload the active file #86

Closed
JulianGmp opened this issue Nov 29, 2021 · 36 comments · Fixed by #1308
Closed

Option to automatically reload the active file #86

JulianGmp opened this issue Nov 29, 2021 · 36 comments · Fixed by #1308
Assignees
Labels
type:enhancement New feature or request
Milestone

Comments

@JulianGmp
Copy link

Hello there,
thank you for your work to provide this tool.

I was looking into this as a preview tool for text based 3D Modeling/CAD, and I'm suggesting adding a command line option to enable an automatic reload of the active file.
This way, when the loaded file gets overwritten by the 3D modeling script, the preview refreshes immediately. Ideally the camera should keep its position as well.

Best regards,
Julian

@Meakk
Copy link
Contributor

Meakk commented Nov 29, 2021

Hi @JulianGmp
It's already possible, press the UP arrow key.
Unfortunately, the camera position is reset right now.

@JulianGmp
Copy link
Author

I know that the up arrow key reloads the file. I work around the camera reset by setting a decent initial camera position through the command line.
But I think it would be really nice to have a command line option and have the window just auto update as soon as the file gets updated, but I realize that this might be a very niche use case that I have.

@Meakk
Copy link
Contributor

Meakk commented Nov 29, 2021

I see. It's actually a good idea, and looks very useful, but it may be tricky to implement. How to know if a file write is complete? How to trigger a refresh?
Any idea @mwestphal ?

@mwestphal
Copy link
Contributor

That would require to monitor the writing time on the file with a dedicated thread, not something F3D should do imo.

@mwestphal
Copy link
Contributor

An alternative would be to reload the file every n seconds, that would be a much simpler approach, but could be done with a simple external script ?

@JulianGmp
Copy link
Author

JulianGmp commented Nov 29, 2021

Watching a file is dependant to the operating system, on Linux you would use inotify, but on other systems it's different. There are cross platform wrappers around like https://github.com/septag/dmon, but I agree that that sounds a bit overkill.

Checking if the file changed manually would be a much simpler solution, we could just poll it every second or so and reload the file if needed.

Using an external script does somewhat work, but it doesn't fix the problem with the reset camera on every load.

In fact, I started digging through the code (which is well documented I must say), and in F3DLoader::LoadFile(int) (F3DLoader.cxx:389) you actually create a new renderer object when loading a file.
I tried simply setting the camera object to the new renderer and it worked as I would expect, though all other render settings such as the grid enabled flag, were reset.
I think we could simply reuse the same renderer, and only reset the camera if we load in a new file.
Or, if reusing the same renderer object can't be done, copy over the options to the new renderer.
That way, when going through multiple files, options such as grid enabled or SSAO will stick even when switching files.
Edit: And it would make the auto reload easily done by just „pressing“ UP every n seconds.

This all might just be my personal opinion though :)

@mwestphal
Copy link
Contributor

mwestphal commented Nov 30, 2021

Indeed, we recreate a renderer because we want all the hotkeys and changes to be reset, this is an intentional behavior, so unlikely to change, at least in the context of using the UP key.

That being said I see why this would not be wanted, so adding an option to control this behavior could make sense.

I'm curious about your workflow though, which process is updating your file so frequently ?

@JulianGmp
Copy link
Author

Do you mean having an option for the reload file (UP arrow key) or an option to keep the renderer across files in general?

Right now I'm testing different text based 3D modeling projects. The most notable one is OpenSCAD, which I've used for a few smaller 3D prints. But I also want to try cadquery (Python based) and jscad.

These projects usually come with some sort of live preview window so you can see your changes while editing the model/text file, openscad has a nice one, but jscad's editor is still a work in progress.
So instead I thought I would just "compile" the 3D model to an STL file from my text editor and use a generic tool like f3d as a live preview, instead of relying on an entire IDE like environment.

@mwestphal
Copy link
Contributor

Do you mean having an option for the reload file (UP arrow key) or an option to keep the renderer across files in general?

In general

Live preview window

So after generating you have to press the up key and you would like not to. Got it. the solution for this seems overengineered though. IMO this could be covered by #52 and software like the one you mentionned (or your own software) could use the libf3d for this usecase.

Wdyt @Meakk ?

@Meakk
Copy link
Contributor

Meakk commented Dec 1, 2021

To be honest, I like the idea of listening to system events, and https://github.com/septag/dmon is a single header file, so it would make sense to integrate it to send a new VTK event F3DLoader::UpdatedFileEvent that we would be able to catch in vtkF3DInteractorStyle if we want to.

It doesn't seem very complicated to implement, probably something like this in F3DLoader::LoadFile:

dmon_watch(
  filePath,
  [](dmon_watch_id watch_id, dmon_action action, const char* rootdir, const char* filepath, const char* oldfilepath, void* user) { 
    // invoke "F3DLoader::UpdatedFileEvent" event
  },
  DMON_WATCHFLAGS_RECURSIVE,
  nullptr);

@JulianGmp
Copy link
Author

So after generating you have to press the up key and you would like not to. Got it. the solution for this seems overengineered though. IMO this could be covered by #52 and software like the one you mentionned (or your own software) could use the libf3d for this usecase.

I don't think reloading the file would be over engineered. I think of Software like Okular (a pdf reader), it also automatically reloads the file on change. I've used it as a live preview before too.

Though I do get that pulling in a new dependency can be quite a hassle, and frankly I don't know how stable or unstable dmon is. Personally I think an interval to check if the file has changed is a fine compromise.

@jpouderoux
Copy link
Collaborator

Would be a great addition. Looks like dmon could be a simple thirdparty to manage. We should just add a new option to turn the feature on/off.

@SamuelTallet
Copy link

Even if I hope to manually reload active file via F3D API #52, an option like --watch=true could be handy to automatically reload.

In my use case, I would need a partial scene reload #216. For example, when one of models rendered in same 3D space changes #127: F3D reloads only this model.

And we can go further in watching... When one of separated texture file changes: F3D reloads only models using this texture.

@mwestphal
Copy link
Contributor

While I understand the needs, there is a lot of layers missing in VTK to be able to do that I'm afraid.

@SamuelTallet
Copy link

NP. Since feature requested by @JulianGmp is about automatic reload, I hope to use F3D API #52 to manually reload scene parts.

@kellyrm
Copy link

kellyrm commented Apr 7, 2022

I also came across f3d looking for a live model viewing program. I am generating solids with libfive scheme bindings and can use inotify to auto-compile, but I am still looking for a viewer that will reload automaticaly, similar to some pdf viewers in a TeX workflow. It's awfuly convenient to be able to just write a source file and see the output updated.

Edit: I can send a Up key event to the window with xdotool after re-compilation. Camera still resets though.

@mwestphal mwestphal added the type:enhancement New feature or request label May 20, 2022
@mwestphal
Copy link
Contributor

@kellyrm camera reset bug is fixed.

@cartesian-theatrics
Copy link

Camera is still resetting for me when reloading. I've been shopping for a while for a viewer that can reload the file without resetting the view, have not found one yet. Would be great if it was supported!

@mwestphal
Copy link
Contributor

Hi @cartesian-theatrics

Could you precise which version of F3D you are using and steps to reproduce the issue ?

Best,

@cartesian-theatrics
Copy link

cartesian-theatrics commented May 31, 2023

I'm using ubuntu 22.04. I tried with with apt package version (1.2.1), 2.0.0 and the nightly (2.0.0-81-g614264d). They all seem to work fine but the view resets when I reload (by pressing Up arrow). I've tried with .stl, .glb, and .3ds files. Reloading .stl and .3ds files resets the camera to look at the xz-plane, for .glb reloads look at the yz-plane (these may be artifacts of the exporting). I'm not running the app with any args other than giving it the file.

@mwestphal
Copy link
Contributor

my bad, it is indeed not fixed yet, waiting on #705

@mwestphal
Copy link
Contributor

@snoyer :)

@mwestphal
Copy link
Contributor

@cartesian-theatrics : #705 has been merged, please try the last nightly: https://github.com/f3d-app/f3d/releases/tag/nightly

@cartesian-theatrics
Copy link

It works! Wonderful, thanks @snoyer!

@snoyer
Copy link
Contributor

snoyer commented Jun 5, 2023

It works! Wonderful, thanks @snoyer!

Credit where credit is due: I got the ball rolling but it is @mwestphal who got it over the line in #788 :)

Also, better late than never:

I've been shopping for a while for a viewer that can reload the file without resetting the view, have not found one yet.

A bit more heavy-duty (not strictly a "viewer" really) than F3D but MeshLab can do it too (ctrl+shift+R)

.stl and .3ds files resets the camera to look at the xz-plane, for .glb reloads look at the yz-plane (these may be artifacts of the exporting).

F3D picks the "up direction" on a file format basis to hopefully match their respective convention which is why it would be looking at different planes depending on the file extension (in the recent versions it should not be looking straight ahead by default but have a better three-quarter-ish view)

@cartesian-theatrics
Copy link

Ah, well thanks to be of you then!

I did not know Meshlab could reload, I'll keep that in mind. Also, the OpenSCAD designers seem to have mastered auto-reload. I've never once had an issue with it. It might be worth taking a look at it if you ever want to revisit auto-reload. Currently to get auto-reload I use xdotool programmatically to update after writing the file. For those interested, you can do that with something like this:

import subprocess

def send_key_to_process(process_name, key):
    window_id_result = subprocess.run(["xdotool", "search", "--name", process_name], capture_output=True, text=True)
    
    if window_id_result.returncode == 0:
        window_ids = window_id_result.stdout.splitlines()
        
        for window_id in window_ids:
            subprocess.run(["xdotool", "key", "--window", window_id, key])
    else:
        print(f"No window found with name: {process_name}")

send_key_to_process("f3d", "Up")

I'm sure something similar could be done in windows or osx.

@snoyer
Copy link
Contributor

snoyer commented Jun 5, 2023

Thanks for the code sample! I didn't know about xdotool, looks like it could come in handy sometimes.

According to the documentation it supports %1, %2, ..., and %@ to refer to the windows found by the search command so you could skip the python loop altogether and call xdotool search --name "F3D" key --window %@ "Up" for the same result

edit: Ideally you'd want xdotool search --all --classname "Vtk" --name "F3D" key --window %@ "Up" to narrow it down but unfortunately the search isn't that good :(

xdotool search --classname "Vtk" key --window %@ "Up" would likely find fewer false positives (eg. this issue page open in a browser matches with --name f3d) unless you've got other VTK based apps running

@cartesian-theatrics
Copy link

Ah, good to know.

Yes you occasionally hit a false positive. Linux doesn't have a good way to name processes unfortunately. At least in this case sending an "Up" key is rarely catastrophic (also I've updated to just use the last matched window-id and it works for now). If you really wanted to you could set the process name internally to include some more global unique identifier, but probably not worth it. xdotool probably uses pgrep under the hood to look for matches.

@isidroas
Copy link

A workaround to avoid pressing UP key each time the file is modified

echo some.stl | entr -r f3d  cut.stl

Source: https://superuser.com/a/665208

The problem is that the window is re-spawn. That might not be wanted because you adjusted the size of the window.

@mwestphal
Copy link
Contributor

This one seems definitely needed, multiple users wants it, lts consider it :)

@mwestphal mwestphal added this to the 2.2.0 milestone Jul 5, 2023
@mwestphal mwestphal modified the milestones: 2.2.0, 2.3.0 Sep 17, 2023
@mwestphal mwestphal modified the milestones: 2.3.0, 2.4.0 Dec 21, 2023
@mwestphal mwestphal added the help wanted Please help with this issue! label Jan 7, 2024
@mwestphal mwestphal added workflow:discussion and removed help wanted Please help with this issue! labels Jan 22, 2024
@mwestphal
Copy link
Contributor

@Meakk @snoyer : I think adding an new option "auto-reload" using https://github.com/septag/dmon to detect file change seems to me a viable solution, wdyt ?

@mwestphal mwestphal removed this from the 2.4.0 milestone Feb 3, 2024
@mwestphal mwestphal added this to the 2.4.0 milestone Feb 4, 2024
@mwestphal mwestphal self-assigned this Mar 10, 2024
@mwestphal
Copy link
Contributor

So I tried dmon and it seems to be working (on Linux at least):

Peek.2024-03-10.11-15.mp4

The one problem I have is that if I trigger a Render() in the dmon callback, VTK OpenGL stack crashes completely, so I have to interact with the F3D window to trigger the render. I do not know if this is fixable.

@mwestphal
Copy link
Contributor

Draft PR: #1308

@mwestphal
Copy link
Contributor

@JulianGmp @isidroas @cartesian-theatrics @jpouderoux : The last nightly release now contains that feature, using the --watch option!

@JulianGmp
Copy link
Author

Really nice to see this niche feature being worked on and implemented! Thank you all for your work :)

@isidroas
Copy link

isidroas commented Apr 3, 2024

It is perfect. In my case, I use it to create a simple and customized openscad IDE.

openscad

Thank you @mwestphal !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:enhancement New feature or request
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

9 participants